diff -Nru a/CREDITS b/CREDITS
--- a/CREDITS	Sat Aug 10 18:42:21 2002
+++ b/CREDITS	Sat Aug 10 18:42:21 2002
@@ -433,6 +433,7 @@
 E: lars@nocrew.org
 W: http://lars.nocrew.org/
 D: dsp56k device driver
+D: ptrace proxy in user mode kernel port
 S: Kopmansg 2
 S: 411 13  Goteborg
 S: Sweden
@@ -713,6 +714,11 @@
 S: Warrendale, Pennsylvania 15086
 S: USA
 
+N: Martin Devera
+E: devik@cdi.cz
+W: http://luxik.cdi.cz/~devik/qos/
+D: HTB qdisc and random networking hacks
+
 N: Alex deVries
 E: adevries@thepuffingroup.com
 D: Various SGI parts, bits of HAL2 and Newport, PA-RISC Linux.
@@ -725,7 +731,7 @@
 E: jdike@karaya.com
 W: http://user-mode-linux.sourceforge.net
 D: User mode kernel port
-S: RR1 Box 67C
+S: 375 Tubbs Hill Rd
 S: Deering NH 03244
 S: USA
 
@@ -2185,7 +2191,7 @@
 S: South Australia
 
 N. Wolfgang Muees
-E: wmues@nexgo.de
+E: wolfgang@iksw-muees.de
 D: Auerswald USB driver
 
 N: Ian A. Murdock
diff -Nru a/Documentation/filesystems/driverfs.txt b/Documentation/filesystems/driverfs.txt
--- a/Documentation/filesystems/driverfs.txt	Sat Aug 10 18:42:23 2002
+++ b/Documentation/filesystems/driverfs.txt	Sat Aug 10 18:42:23 2002
@@ -3,175 +3,294 @@
 
 Patrick Mochel	<mochel@osdl.org>
 
-3 December 2001
+2 August 2002
 
 
 What it is:
 ~~~~~~~~~~~
-driverfs is a unified means for device drivers to export interfaces to
-userspace.
+driverfs is a ram-based filesystem. It was created by copying
+ramfs/inode.c to driverfs/inode.c and doing a little search-and-replace. 
 
-Some drivers have a need for exporting interfaces for things like
-setting device-specific parameters, or tuning the device performance.
-For example, wireless networking cards export a file in procfs to set
-their SSID.
+driverfs is a means to export kernel data structures, their
+attributes, and the linkages between them to userspace. 
 
-Other times, the bus on which a device resides may export other
-information about the device. For example, PCI and USB both export
-device information via procfs or usbdevfs.
+driverfs provides a unified interface for exporting attributes to
+userspace. Currently, this interface is available only to device and
+bus drivers. 
 
-In these cases, the files or directories are in nearly random places
-in /proc. One benefit of driverfs is that it can consolidate all of
-these interfaces to one standard location.
 
+Using driverfs
+~~~~~~~~~~~~~~
+driverfs is always compiled in. You can access it by doing something like:
+
+    mount -t driverfs driverfs /devices 
+
+
+Top Level Directory Layout
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+The driverfs directory arrangement exposes the relationship of kernel
+data structures. 
+
+The top level driverfs diretory looks like:
+
+bus/
+root/
+
+root/ contains a filesystem representation of the device tree. It maps
+directly to the internal kernel device tree, which is a hierarchy of
+struct device. 
 
-Why it's better than procfs:
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-This of course can't happen without changing every single driver that
-exports a procfs interface, and having some coordination between all
-of them as to what the proper place for their files is. Or can it?
+bus/ contains flat directory layout of the various bus types in the
+kernel. Each bus's directory contains two subdirectories:
 
+	devices/
+	drivers/
 
-driverfs was developed in conjunction with the new driver model for
-the 2.5 kernel. In that model, the system has one unified tree of all
-the devices that are present in the system. It follows naturally that
-this tree can be exported to userspace in the same order.
+devices/ contains symlinks for each device discovered in the system
+that point to the device's directory under root/.
 
-So, every bus and every device gets a directory in the filesystem.
-This directory is created when the device is registered in the tree;
-before the driver actually gets a initialised. The dentry for this
-directory is stored in the struct device for this driver, so the
-driver has access to it.
+drivers/ contains a directory for each device driver that is loaded
+for devices on that particular bus (this assmumes that drivers do not
+span multiple bus types).
 
-Now, every driver has one standard place to export its files.
 
-Granted, the location of the file is not as intuitive as it may have
-been under procfs. But, I argue that with the exception of
-/proc/bus/pci, none of the files had intuitive locations. I also argue
-that the development of userspace tools can help cope with these
-changes and inconsistencies in locations.
+More information can device-model specific features can be found in
+Documentation/device-model/. 
 
 
-Why we're not just using procfs:
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-When developing the new driver model, it was initially implemented
-with a procfs tree. In explaining the concept to Linus, he said "Don't
-use proc."
+Directory Contents
+~~~~~~~~~~~~~~~~~~
+Each object that is represented in driverfs gets a directory, rather
+than a file, to make it simple to export attributes of that object. 
+Attributes are exported via ASCII text files. The programming
+interface is discussed below. 
 
-I was a little shocked (especially considering I had already
-implemented it using procfs). "What do you mean 'don't use proc'?"
+Instead of having monolithic files that are difficult to parse, all
+files are intended to export one attribute. The name of the attribute
+is the name of the file. The value of the attribute are the contents
+of the file. 
 
-His argument was that too many things use proc that shouldn't. And
-even more things misuse proc that shouldn't. On top of that, procfs
-was written before the VFS layer was written, so it doesn't use the
-dcache. It reimplements many of the same features that the dcache
-does, and is in general, crufty.
+There should be few, if any, exceptions to this rule. You should not
+violate it, for fear of public humilation.
 
-So, he told me to write my own. Soon after, he pointed me at ramfs,
-the simplest filesystem known to man.
 
-Consequently, we have a virtual fileystem based heavily on ramfs, and
-borrowing some conceptual functionality from procfs.
+The Two-Tier Model
+~~~~~~~~~~~~~~~~~~
 
-It may suck, but it does what it was designed to. At least so far.
+driverfs is a very simple, low-level interface. In order for kernel
+objects to use it, there must be an intermediate layer in place for
+each object type. 
 
+All calls in driverfs are intended to be as type-safe as possible. 
+In order to extend driverfs to support multiple data types, a layer of
+abstraction was required. This intermediate layer converts between the
+generic calls and data structures of the driverfs core to the
+subsystem-specific objects and calls. 
 
-How it works:
-~~~~~~~~~~~~~
 
-Directories are encapsulated like this:
+The Subsystem Interface
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The subsystems bear the responsibility of implementing driverfs
+extensions for the objects they control. Fortunately, it's intended to
+be really easy to do so. 
+
+It's divided into three sections: directories, files, and operations.
+
+
+Directories
+~~~~~~~~~~~
 
 struct driver_dir_entry {
-	char                    * name;
-	struct dentry           * dentry;
-	mode_t                  mode;
-	struct list_head        files;
+        char                    * name;
+        struct dentry           * dentry;
+        mode_t                  mode;
+        struct driverfs_ops     * ops;
+};
+
+
+int
+driverfs_create_dir(struct driver_dir_entry *, struct driver_dir_entry *);
+
+void
+driverfs_remove_dir(struct driver_dir_entry * entry);
+
+The directory structure should be statically allocated, and reside in
+a subsystem-specific data structure:
+
+struct device {
+       ...
+       struct driver_dir_entry	dir;
+};
+
+The subsystem is responsible for initializing the name, mode, and ops
+fields of the directory entry. (More on struct driverfs_ops later)
+
+
+Files
+~~~~~
+
+struct attribute {
+        char                    * name;
+        mode_t                  mode;
+};
+
+
+int
+driverfs_create_file(struct attribute * attr, struct driver_dir_entry * parent);
+
+void
+driverfs_remove_file(struct driver_dir_entry *, const char * name);
+
+
+The attribute structure is a simple, common token that the driverfs
+core handles. It has little use on its own outside of the
+core. Objects cannot use a plain struct attribute to export
+attributes, since there are no callbacks for reading and writing data.
+
+Therefore, the subsystem is required to define a data structure that
+encapsulates the attribute structure, and provides type-safe callbacks
+for reading and writing data.
+
+An example looks like this:
+
+struct device_attribute {
+        struct attribute        attr;
+        ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off);
+        ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off);
+};
+
+
+Note that there is a struct attribute embedded in the structure. In
+order to relieve pain in declaring attributes, the subsystem should
+also define a macro, like:
+
+#define DEVICE_ATTR(_name,_str,_mode,_show,_store)      \
+struct device_attribute dev_attr_##_name = {            \
+        .attr = {.name  = _str, .mode   = _mode },      \
+        .show   = _show,                                \
+        .store  = _store,                               \
 };
 
-name:
-	Name of the directory.
-dentry:
-	Dentry for the directory.
-mode:
-	Permissions of the directory.
-files:
-	Linked list of driver_file_entry's that are in the directory.
+This hides the initialization of the embedded struct, and in general,
+the internals of each structure. It yields a structure by the name of
+dev_attr_<name>.
+
+In order for objects to create files, the subsystem should create
+wrapper functions, like this:
+
+int device_create_file(struct device *device, struct device_attribute * entry);
+void device_remove_file(struct device * dev, struct device_attribute * attr);
+
+..and forward the call on to the driverfs functions.
 
+Note that there is no unique information in the attribute structures,
+so the same structure can be used to describe files of several
+different object instances. 
 
-To create a directory, one first calls
 
-struct driver_dir_entry *
-driverfs_create_dir_entry(const char * name, mode_t mode);
+Operations
+~~~~~~~~~~
+
+struct driverfs_ops {
+        int     (*open)(struct driver_dir_entry *);
+        int     (*close)(struct driver_dir_entry *);
+        ssize_t (*show)(struct driver_dir_entry *, struct attribute *,char *, size_t, loff_t);
+        ssize_t (*store)(struct driver_dir_entry *,struct attribute *,const char *, size_t, loff_t);
+};
+
 
-which allocates and initialises a struct driver_dir_entry. Then to actually
-create the directory:
+Subsystems are required to implement this set of callbacks. Their
+purpose is to translate the generic data structures into the specific
+objects, and operate on them. This can be done by defining macros like
+this:
 
-int driverfs_create_dir(struct driver_dir_entry *, struct driver_dir_entry *);
+#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
 
-To remove a directory:
+#define to_device(d) container_of(d, struct device, dir)
 
-void driverfs_remove_dir(struct driver_dir_entry * entry);
 
+Since the directories are statically allocated in the object, you can
+derive the pointer to the object that owns the file. Ditto for the
+attribute structures. 
 
-Files are encapsulated like this:
+Current Interfaces
+~~~~~~~~~~~~~~~~~~
 
-struct driver_file_entry {
-	struct driver_dir_entry * parent;
-	struct list_head        node;
-	char                    * name;
-	mode_t                  mode;
-	struct dentry           * dentry;
-	void                    * data;
-	struct driverfs_operations      * ops;
+The following interface layers currently exist in driverfs:
+
+
+- devices (include/linux/device.h)
+----------------------------------
+Structure:
+
+struct device_attribute {
+        struct attribute        attr;
+        ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off);
+        ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off);
 };
 
-struct driverfs_operations {
-	ssize_t (*read) (char *, size_t, loff_t, void *);
-	ssize_t (*write)(const char *, size_t, loff_t, void*);
+Declaring:
+
+DEVICE_ATTR(_name,_str,_mode,_show,_store);
+
+Creation/Removal:
+
+int device_create_file(struct device *device, struct device_attribute * entry);
+void device_remove_file(struct device * dev, struct device_attribute * attr);
+
+
+- bus drivers (include/linux/device.h)
+--------------------------------------
+Structure:
+
+struct bus_attribute {
+        struct attribute        attr;
+        ssize_t (*show)(struct bus_type *, char * buf, size_t count, loff_t off);
+        ssize_t (*store)(struct bus_type *, const char * buf, size_t count, loff_t off);
 };
 
-node:
-	Node in its parent directory's list of files.
+Declaring:
 
-name:
-	The name of the file.
+BUS_ATTR(_name,_str,_mode,_show,_store)
 
-dentry:
-	The dentry for the file.
+Creation/Removal:
 
-data:
-	Caller specific data that is passed to the callbacks when they
-	are called.
+int bus_create_file(struct bus_type *, struct bus_attribute *);
+void bus_remove_file(struct bus_type *, struct bus_attribute *);
 
-ops:
-	Operations for the file. Currently, this only contains read() and write()
-	callbacks for the file.
 
-To create a file, one first calls
+- device drivers (include/linux/device.h)
+-----------------------------------------
 
-struct driver_file_entry *
-driverfs_create_entry (const char * name, mode_t mode,
-			struct driverfs_operations * ops, void * data);
+Structure:
 
-That allocates and initialises a struct driver_file_entry. Then, to actually
-create a file, one calls
+struct driver_attribute {
+        struct attribute        attr;
+        ssize_t (*show)(struct device_driver *, char * buf, size_t count, loff_t off);
+        ssize_t (*store)(struct device_driver *, const char * buf, size_t count, loff_t off);
+};
 
-int driverfs_create_file(struct driver_file_entry * entry,
-			struct driver_dir_entry * parent);
+Declaring:
 
+DRIVER_ATTR(_name,_str,_mode,_show,_store)
 
-To remove a file, one calls
+Creation/Removal:
 
-void driverfs_remove_file(struct driver_dir_entry *, const char * name);
+int driver_create_file(struct device_driver *, struct driver_attribute *);
+void driver_remove_file(struct device_driver *, struct driver_attribute *);
 
 
+Reading/Writing Data
+~~~~~~~~~~~~~~~~~~~~
 The callback functionality is similar to the way procfs works. When a
 user performs a read(2) or write(2) on the file, it first calls a
-driverfs function. This function then checks for a non-NULL pointer in
-the file->private_data field, which it assumes to be a pointer to a
-struct driver_file_entry.
+driverfs function. This calls to the subsystem, which then calls to
+the object's show() or store() function.
 
-It then checks for the appropriate callback and calls it.
+The buffer pointer, offset, and length should be passed to each
+function. The downstream callback should fill the buffer and return
+the number of bytes read/written.
 
 
 What driverfs is not:
@@ -194,18 +313,24 @@
 The driverfs functions assume that at most a page is being either read
 or written each time.
 
+There is a race condition that is really, really hard to fix; if not 
+impossible. There exists a race between a driverfs file being opened
+and the object that owns the file going away. During the driverfs
+open() callback, the reference count for the owning object needs to be
+incremented. 
+
+For drivers, we can put a struct module * owner in struct driver_dir_entry 
+and do try_inc_mod_count() when we open a file. However, this won't
+work for devices, that aren't tied to a module. And, it is still not
+guaranteed to solve the race. 
+
+I'm looking into fixing this, but it may not be doable without making
+a separate filesystem instance for each object. It's fun stuff. Please
+mail me with creative ideas that you know will work. 
+
 
 Possible bugs:
 ~~~~~~~~~~~~~~
 It may not deal with offsets and/or seeks very well, especially if
 they cross a page boundary.
-
-There may be locking issues when dynamically adding/removing files and
-directories rapidly (like if you have a hot plug device).
-
-There are some people that believe that filesystems which add
-files/directories dynamically based on the presence of devices are
-inherently flawed. Though not as technically versed in this area as
-some of those people, I like to believe that they can be made to work,
-with the right guidance.
 
diff -Nru a/Documentation/filesystems/jfs.txt b/Documentation/filesystems/jfs.txt
--- a/Documentation/filesystems/jfs.txt	Sat Aug 10 18:42:23 2002
+++ b/Documentation/filesystems/jfs.txt	Sat Aug 10 18:42:23 2002
@@ -17,11 +17,16 @@
 		translations.  This requires CONFIG_NLS_UTF8 to be set
 		in the kernel .config file.
 
+resize=value	Resize the volume to <value> blocks.  JFS only supports
+		growing a volume, not shrinking it.  This option is only
+		valid during a remount, when the volume is mounted
+		read-write.  The resize keyword with no value will grow
+		the volume to the full size of the partition.
+
 JFS TODO list:
 
 Plans for our near term development items
 
-   - implement online resize for extending JFS volumes
    - enhance support for logfile on dedicated partition
    - get access control list functionality operational
    - get extended attributes functionality operational
diff -Nru a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt
--- a/Documentation/filesystems/ntfs.txt	Sat Aug 10 18:42:23 2002
+++ b/Documentation/filesystems/ntfs.txt	Sat Aug 10 18:42:23 2002
@@ -247,6 +247,19 @@
 
 Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
 
+2.0.24:
+	- Small internal cleanups.
+	- Support for sendfile system call. (Christoph Hellwig)
+2.0.23:
+	- Massive internal locking changes to mft record locking. Fixes
+	  various race conditions and deadlocks.
+	- Fix ntfs over loopback for compressed files by adding an
+	  optimization barrier. (gcc was screwing up otherwise ?)
+	Thanks go to Christoph Hellwig for pointing these two out:
+	- Remove now unused function fs/ntfs/malloc.h::vmalloc_nofs().
+	- Fix ntfs_free() for ia64 and parisc.
+2.0.22:
+	- Small internal cleanups.
 2.0.21:
 	These only affect 32-bit architectures:
 	- Check for, and refuse to mount too large volumes (maximum is 2TiB).
diff -Nru a/Documentation/networking/e1000.txt b/Documentation/networking/e1000.txt
--- a/Documentation/networking/e1000.txt	Sat Aug 10 18:42:22 2002
+++ b/Documentation/networking/e1000.txt	Sat Aug 10 18:42:22 2002
@@ -1,7 +1,7 @@
 Linux* Base Driver for the Intel(R) PRO/1000 Family of Adapters
 ===============================================================
 
-April 23, 2002
+June 11, 2002
 
 
 Contents
@@ -95,8 +95,8 @@
 Command Line Parameters
 =======================
 
-If the driver is built as a module, the following parameters are used by 
-entering them on the command line with the modprobe or insmod command. 
+If the driver is built as a module, the following optional parameters are 
+used by entering them on the command line with the modprobe or insmod command. 
 For example, with two PRO/1000 PCI adapters, entering:
 
     insmod e1000 TxDescriptors=80,128
@@ -141,7 +141,7 @@
 
 RxIntDelay
 Valid Range: 0-65535 (0=off)
-Default Value: 64 (82542, 82543, and 82544-based adapters)
+Default Value: 0 (82542, 82543, and 82544-based adapters)
                128 (82540, 82545, and 82546-based adapters)
     This value delays the generation of receive interrupts in units of 1.024
     microseconds.  Receive interrupt reduction can improve CPU efficiency if
@@ -151,6 +151,14 @@
     may be set too high, causing the driver to run out of available receive
     descriptors.
 
+    CAUTION: When setting RxIntDelay to a value other than 0, adapters based
+             on the Intel 82543 and 82544 LAN controllers may hang (stop
+             transmitting) under certain network conditions. If this occurs a
+             message is logged in the system event log. In addition, the
+             controller is automatically reset, restoring the network
+             connection. To eliminate the potential for the hang ensure that
+             RxIntDelay is set to 0.
+
 Speed (adapters using copper connections only)
 Valid Settings: 0, 10, 100, 1000
 Default Value: 0 (auto-negotiate at all supported speeds)
@@ -228,16 +236,6 @@
 
 Known Issues
 ============
-
-  Inconsistent Driver Behavior Under Heavy Traffic Loads
-  ------------------------------------------------------
-
-  Adapters based on the Intel 82543 and 82544 LAN controllers may hang (stop
-  transmitting) under certain network conditions. If this occurs a message
-  is logged in the system event log. In addition, the controller is
-  automatically reset, restoring the network connection. To eliminate the
-  potential for the hang change the RxIntDelay parameter to zero. For details
-  on the RxIntDelay parameter see the Command Line Parameters section.
 
   Jumbo Frames System Requirement
   -------------------------------
diff -Nru a/Documentation/usb/auerswald.txt b/Documentation/usb/auerswald.txt
--- a/Documentation/usb/auerswald.txt	Sat Aug 10 18:42:23 2002
+++ b/Documentation/usb/auerswald.txt	Sat Aug 10 18:42:23 2002
@@ -27,4 +27,4 @@
 ============
 - Connection to ISDN4LINUX (the hisax interface)
 
-The maintainer of this driver is wmues@nexgo.de
+The maintainer of this driver is wolfgang@iksw-muees.de
diff -Nru a/MAINTAINERS b/MAINTAINERS
--- a/MAINTAINERS	Sat Aug 10 18:42:23 2002
+++ b/MAINTAINERS	Sat Aug 10 18:42:23 2002
@@ -1696,12 +1696,6 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
-USB EHCI DRIVER
-P:	David Brownell
-M:	dbrownell@users.sourceforge.net
-L:	linux-usb-devel@lists.sourceforge.net
-S:	Maintained
-
 USB HID/HIDBP/INPUT DRIVERS
 P:	Vojtech Pavlik
 M:	vojtech@suse.cz
@@ -1816,7 +1810,7 @@
 
 USB AUERSWALD DRIVER
 P:	Wolfgang Muees
-M:	wmues@nexgo.de
+M:	wolfgang@iksw-muees.de
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
@@ -1858,6 +1852,14 @@
 L:	linux-usb-devel@lists.sourceforge.net
 S:	Maintained
 
+USER-MODE LINUX
+P:	Jeff Dike
+M:	jdike@karaya.com
+L:	user-mode-linux-devel@lists.sourceforge.net
+L:	user-mode-linux-user@lists.sourceforge.net
+W:	http://user-mode-linux.sourceforge.net
+S:	Maintained
+	
 VFAT FILESYSTEM:
 P:	Gordon Chaffee
 M:	chaffee@cs.berkeley.edu
diff -Nru a/Makefile b/Makefile
--- a/Makefile	Sat Aug 10 18:42:21 2002
+++ b/Makefile	Sat Aug 10 18:42:21 2002
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 5
-SUBLEVEL = 30
+SUBLEVEL = 31
 EXTRAVERSION =
 
 # *DOCUMENTATION*
@@ -27,7 +27,15 @@
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
-ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+# SUBARCH tells the usermode build what the underlying arch is.  That is set
+# first, and if a usermode build is happening, the "ARCH=um" on the command
+# line overrides the setting of ARCH below.  If a native build is happening,
+# then ARCH is assigned, getting whatever value it gets normally, and 
+# SUBARCH is subsequently ignored.
+
+SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
+ARCH := $(SUBARCH)
+
 KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
 
 CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
diff -Nru a/arch/alpha/Config.help b/arch/alpha/Config.help
--- a/arch/alpha/Config.help	Sat Aug 10 18:42:21 2002
+++ b/arch/alpha/Config.help	Sat Aug 10 18:42:21 2002
@@ -438,6 +438,12 @@
   because some crucial programs on your system might still be in A.OUT
   format.
 
+OSF/1 v4 readv/writev compatibility
+CONFIG_OSF4_COMPAT
+  Say Y if you are using OSF/1 binaries (like Netscape and Acrobat)
+  with v4 shared libraries freely available from Compaq. If you're
+  going to use shared libraries from Tru64 version 5.0 or later, say N.
+
 CONFIG_BINFMT_EM86
   Say Y here if you want to be able to execute Linux/Intel ELF
   binaries just like native Alpha binaries on your Alpha machine. For
diff -Nru a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile
--- a/arch/alpha/boot/Makefile	Sat Aug 10 18:42:21 2002
+++ b/arch/alpha/boot/Makefile	Sat Aug 10 18:42:21 2002
@@ -20,6 +20,7 @@
 TARGETS = vmlinux.gz tools/objstrip # also needed by aboot & milo
 VMLINUX = $(TOPDIR)/vmlinux
 OBJSTRIP = tools/objstrip
+LIBS := $(patsubst lib/%,$(TOPDIR)/lib/%,$(LIBS))
 
 all:	$(TARGETS)
 	@echo Ready to install kernel in $(shell pwd)/vmlinux.gz
diff -Nru a/arch/alpha/config.in b/arch/alpha/config.in
--- a/arch/alpha/config.in	Sat Aug 10 18:42:21 2002
+++ b/arch/alpha/config.in	Sat Aug 10 18:42:21 2002
@@ -7,11 +7,12 @@
 define_bool CONFIG_UID16 n
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
+define_bool CONFIG_GENERIC_ISA_DMA y
 
 source init/Config.in
 
 mainmenu_option next_comment
-comment 'General setup'
+comment 'System setup'
 
 choice 'Alpha system type' \
 	"Generic		CONFIG_ALPHA_GENERIC		\
@@ -264,6 +265,10 @@
 fi
  
 tristate 'Kernel support for a.out (ECOFF) binaries' CONFIG_BINFMT_AOUT
+if [ "$CONFIG_BINFMT_AOUT" != "n" ]; then
+	bool '  OSF/1 v4 readv/writev compatibility' CONFIG_OSF4_COMPAT
+fi
+
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 tristate 'Kernel support for Linux/Intel ELF binaries' CONFIG_BINFMT_EM86
diff -Nru a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
--- a/arch/alpha/kernel/Makefile	Sat Aug 10 18:42:22 2002
+++ b/arch/alpha/kernel/Makefile	Sat Aug 10 18:42:22 2002
@@ -23,7 +23,7 @@
 obj-y	 += console.o
 endif
 
-obj-$(CONFIG_SMP)    += smp.o irq_smp.o
+obj-$(CONFIG_SMP)    += smp.o
 obj-$(CONFIG_PCI)    += pci.o pci_iommu.o
 obj-$(CONFIG_SRM_ENV)	+= srm_env.o
 
diff -Nru a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
--- a/arch/alpha/kernel/alpha_ksyms.c	Sat Aug 10 18:42:21 2002
+++ b/arch/alpha/kernel/alpha_ksyms.c	Sat Aug 10 18:42:21 2002
@@ -31,6 +31,8 @@
 #include <asm/machvec.h>
 #include <asm/pgalloc.h>
 #include <asm/semaphore.h>
+#include <asm/tlbflush.h>
+#include <asm/cacheflush.h>
 
 #define __KERNEL_SYSCALLS__
 #include <asm/unistd.h>
@@ -213,15 +215,9 @@
 EXPORT_SYMBOL(flush_tlb_page);
 EXPORT_SYMBOL(smp_imb);
 EXPORT_SYMBOL(cpu_data);
-EXPORT_SYMBOL(__cpu_number_map);
 EXPORT_SYMBOL(smp_num_cpus);
 EXPORT_SYMBOL(smp_call_function);
 EXPORT_SYMBOL(smp_call_function_on_cpu);
-EXPORT_SYMBOL(global_irq_holder);
-EXPORT_SYMBOL(__global_cli);
-EXPORT_SYMBOL(__global_sti);
-EXPORT_SYMBOL(__global_save_flags);
-EXPORT_SYMBOL(__global_restore_flags);
 EXPORT_SYMBOL(atomic_dec_and_lock);
 #ifdef CONFIG_DEBUG_SPINLOCK
 EXPORT_SYMBOL(spin_unlock);
diff -Nru a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
--- a/arch/alpha/kernel/core_cia.c	Sat Aug 10 18:42:23 2002
+++ b/arch/alpha/kernel/core_cia.c	Sat Aug 10 18:42:23 2002
@@ -370,7 +370,7 @@
 }
 
 static inline void
-cia_prepare_tbia_workaround(void)
+cia_prepare_tbia_workaround(int cia_rev, int is_pyxis)
 {
 	unsigned long *ppte, pte;
 	long i;
@@ -382,10 +382,20 @@
 	for (i = 0; i < CIA_BROKEN_TBIA_SIZE / sizeof(unsigned long); ++i)
 		ppte[i] = pte;
 
-	*(vip)CIA_IOC_PCI_W1_BASE = CIA_BROKEN_TBIA_BASE | 3;
-	*(vip)CIA_IOC_PCI_W1_MASK = (CIA_BROKEN_TBIA_SIZE*1024 - 1)
-				    & 0xfff00000;
-	*(vip)CIA_IOC_PCI_T1_BASE = virt_to_phys(ppte) >> 2;
+	if (is_pyxis || cia_rev != 1) {
+		/* We can use W1 for SG on PYXIS/CIA rev 2. */
+		*(vip)CIA_IOC_PCI_W1_BASE = CIA_BROKEN_TBIA_BASE | 3;
+		*(vip)CIA_IOC_PCI_W1_MASK = (CIA_BROKEN_TBIA_SIZE*1024 - 1)
+					    & 0xfff00000;
+		*(vip)CIA_IOC_PCI_T1_BASE = virt_to_phys(ppte) >> 2;
+	} else {
+		/* CIA rev 1 can't use W1 or W2 for SG, apparently,
+		   so use W3, which we made sure is not used for DAC. */
+		*(vip)CIA_IOC_PCI_W3_BASE = CIA_BROKEN_TBIA_BASE | 3;
+		*(vip)CIA_IOC_PCI_W3_MASK = (CIA_BROKEN_TBIA_SIZE*1024 - 1)
+					    & 0xfff00000;
+		*(vip)CIA_IOC_PCI_T3_BASE = virt_to_phys(ppte) >> 2;
+	}
 }
 
 static void __init
@@ -684,10 +694,10 @@
 	/*
 	 * Set up the PCI to main memory translation windows.
 	 *
-	 * Window 0 is scatter-gather 8MB at 8MB (for isa)
-	 * Window 1 is scatter-gather 1MB at 768MB (for tbia)
+	 * Window 0 is S/G 8MB at 8MB (for isa)
+	 * Window 1 is S/G 1MB at 768MB (for tbia) (unused for CIA rev 1)
 	 * Window 2 is direct access 2GB at 2GB
-	 * Window 3 is DAC access 4GB at 8GB
+	 * Window 3 is DAC access 4GB at 8GB (or S/G for tbia if CIA rev 1)
 	 *
 	 * ??? NetBSD hints that page tables must be aligned to 32K,
 	 * possibly due to a hardware bug.  This is over-aligned
@@ -697,6 +707,7 @@
 
 	hose->sg_pci = NULL;
 	hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 32768);
+
 	__direct_map_base = 0x80000000;
 	__direct_map_size = 0x80000000;
 
@@ -715,8 +726,14 @@
 	   are compared against W_DAC.  We can, however, directly map 4GB,
 	   which is better than before.  However, due to assumptions made
 	   elsewhere, we should not claim that we support DAC unless that
-	   4GB covers all of physical memory.  */
-	if (is_pyxis || max_low_pfn > (0x100000000 >> PAGE_SHIFT)) {
+	   4GB covers all of physical memory.
+
+	   Also, don't do DAC on CIA rev 1, it has other problems and is
+	   unlikely to have more than 2GB of memory anyway, so direct is
+	   fine.
+	*/
+	if (cia_rev == 1 || is_pyxis ||
+	    max_low_pfn > (0x100000000UL >> PAGE_SHIFT)) {
 		*(vip)CIA_IOC_PCI_W3_BASE = 0;
 	} else {
 		*(vip)CIA_IOC_PCI_W3_BASE = 0x00000000 | 1 | 8;
@@ -728,7 +745,7 @@
 	}
 
 	/* Prepare workaround for apparently broken tbia. */
-	cia_prepare_tbia_workaround();
+	cia_prepare_tbia_workaround(cia_rev, is_pyxis);
 }
 
 void __init
diff -Nru a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
--- a/arch/alpha/kernel/entry.S	Sat Aug 10 18:42:19 2002
+++ b/arch/alpha/kernel/entry.S	Sat Aug 10 18:42:19 2002
@@ -851,8 +851,13 @@
 	.quad osf_getrusage
 	.quad sys_getsockopt
 	.quad alpha_ni_syscall
+#ifdef CONFIG_OSF4_COMPAT
+	.quad osf_readv				/* 120 */
+	.quad osf_writev
+#else
 	.quad sys_readv				/* 120 */
 	.quad sys_writev
+#endif
 	.quad osf_settimeofday
 	.quad sys_fchown
 	.quad sys_fchmod
diff -Nru a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
--- a/arch/alpha/kernel/irq.c	Sat Aug 10 18:42:23 2002
+++ b/arch/alpha/kernel/irq.c	Sat Aug 10 18:42:23 2002
@@ -75,13 +75,7 @@
 handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
 		 struct irqaction *action)
 {
-	int status;
-	int cpu = smp_processor_id();
-
-	kstat.irqs[cpu][irq]++;
-	irq_enter(cpu, irq);
-
-	status = 1;	/* Force the "do bottom halves" bit */
+	int status = 1;	/* Force the "do bottom halves" bit */
 
 	do {
 		if (!(action->flags & SA_INTERRUPT))
@@ -97,8 +91,6 @@
 		add_interrupt_randomness(irq);
 	local_irq_disable();
 
-	irq_exit(cpu, irq);
-
 	return status;
 }
 
@@ -130,12 +122,7 @@
 disable_irq(unsigned int irq)
 {
 	disable_irq_nosync(irq);
-
-	if (!local_irq_count(smp_processor_id())) {
-		do {
-			barrier();
-		} while (irq_desc[irq].status & IRQ_INPROGRESS);
-	}
+	synchronize_irq(irq);
 }
 
 void
@@ -525,12 +512,9 @@
 
 #ifdef CONFIG_SMP
 	seq_puts(p, "           ");
-	for (i = 0; i < smp_num_cpus; i++)
-		seq_printf(p, "CPU%d       ", i);
-#ifdef DO_BROADCAST_INTS
-	for (i = 0; i < smp_num_cpus; i++)
-		seq_printf(p, "TRY%d       ", i);
-#endif
+	for (i = 0; i < NR_CPUS; i++)
+		if (cpu_online(i))
+			seq_printf(p, "CPU%d       ", i);
 	seq_putc(p, '\n');
 #endif
 
@@ -542,14 +526,9 @@
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
-		for (j = 0; j < smp_num_cpus; j++)
-			seq_printf(p, "%10u ",
-				     kstat.irqs[cpu_logical_map(j)][i]);
-#ifdef DO_BROADCAST_INTS
-		for (j = 0; j < smp_num_cpus; j++)
-			seq_printf(p, "%10lu ",
-				     irq_attempt(cpu_logical_map(j), i));
-#endif
+		for (j = 0; j < NR_CPUS; j++)
+			if (cpu_online(j))
+				seq_printf(p, "%10u ", kstat.irqs[j][i]);
 #endif
 		seq_printf(p, " %14s", irq_desc[i].handler->typename);
 		seq_printf(p, "  %c%s",
@@ -565,9 +544,9 @@
 	}
 #if CONFIG_SMP
 	seq_puts(p, "IPI: ");
-	for (j = 0; j < smp_num_cpus; j++)
-		seq_printf(p, "%10lu ",
-			     cpu_data[cpu_logical_map(j)].ipi_count);
+	for (i = 0; i < NR_CPUS; i++)
+		if (cpu_online(i))
+			seq_printf(p, "%10lu ", cpu_data[i].ipi_count);
 	seq_putc(p, '\n');
 #endif
 	seq_printf(p, "ERR: %10lu\n", irq_err_count);
@@ -610,7 +589,8 @@
 		return;
 	}
 
-	irq_attempt(cpu, irq)++;
+	irq_enter();
+	kstat.irqs[cpu][irq]++;
 	spin_lock_irq(&desc->lock); /* mask also the higher prio events */
 	desc->handler->ack(irq);
 	/*
@@ -669,8 +649,7 @@
 	desc->handler->end(irq);
 	spin_unlock(&desc->lock);
 
-	if (softirq_pending(cpu))
-		do_softirq();
+	irq_exit();
 }
 
 /*
@@ -702,7 +681,7 @@
 
 	/* Wait for longstanding interrupts to trigger. */
 	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
-		/* about 20ms delay */ synchronize_irq();
+		/* about 20ms delay */ barrier();
 
 	/* enable any unassigned irqs (we must startup again here because
 	   if a longstanding irq happened in the previous stage, it may have
@@ -723,7 +702,7 @@
 	 * Wait for spurious interrupts to trigger
 	 */
 	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
-		/* about 100ms delay */ synchronize_irq();
+		/* about 100ms delay */ barrier();
 
 	/*
 	 * Now filter out any obviously spurious interrupts
@@ -821,3 +800,15 @@
 		irq_found = -irq_found;
 	return irq_found;
 }
+
+#ifdef CONFIG_SMP
+void synchronize_irq(unsigned int irq)
+{
+        /* is there anything to synchronize with? */
+	if (!irq_desc[irq].action)
+		return;
+
+	while (irq_desc[irq].status & IRQ_INPROGRESS)
+		barrier();
+}
+#endif
diff -Nru a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
--- a/arch/alpha/kernel/irq_alpha.c	Sat Aug 10 18:42:21 2002
+++ b/arch/alpha/kernel/irq_alpha.c	Sat Aug 10 18:42:21 2002
@@ -14,10 +14,6 @@
 #include "proto.h"
 #include "irq_impl.h"
 
-#ifndef CONFIG_SMP
-unsigned long __irq_attempt[NR_IRQS];
-#endif
-
 /* Hack minimum IPL during interrupt processing for broken hardware.  */
 #ifdef CONFIG_ALPHA_BROKEN_IRQ_MASK
 int __min_ipl;
@@ -63,7 +59,6 @@
 		smp_percpu_timer_interrupt(&regs);
 		cpu = smp_processor_id();
 		if (cpu != boot_cpuid) {
-		        irq_attempt(cpu, RTC_IRQ)++;
 		        kstat.irqs[cpu][RTC_IRQ]++;
 		} else {
 			handle_irq(RTC_IRQ, &regs);
diff -Nru a/arch/alpha/kernel/irq_smp.c b/arch/alpha/kernel/irq_smp.c
--- a/arch/alpha/kernel/irq_smp.c	Sat Aug 10 18:42:21 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,250 +0,0 @@
-/*
- *	linux/arch/alpha/kernel/irq_smp.c
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/random.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-
-#include <asm/system.h>
-#include <asm/io.h>
-
-
-/* Who has global_irq_lock. */
-int global_irq_holder = NO_PROC_ID;
-
-/* This protects IRQ's. */
-spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED;
-
-/* Global IRQ locking depth. */
-static void *previous_irqholder = NULL;
-
-#define MAXCOUNT 100000000
-
-
-static void
-show(char * str, void *where)
-{
-#if 0
-	int i;
-        unsigned long *stack;
-#endif
-        int cpu = smp_processor_id();
-
-        printk("\n%s, CPU %d: %p\n", str, cpu, where);
-        printk("irq:  %d [%d %d]\n",
-	       irqs_running(),
-               local_irq_count(0),
-               local_irq_count(1));
-
-        printk("bh:   %d [%d %d]\n",
-	       spin_is_locked(&global_bh_lock) ? 1 : 0,
-	       local_bh_count(0),
-	       local_bh_count(1));
-#if 0
-        stack = (unsigned long *) &str;
-        for (i = 40; i ; i--) {
-		unsigned long x = *++stack;
-                if (x > (unsigned long) &init_task_union &&
-		    x < (unsigned long) &vsprintf) {
-			printk("<[%08lx]> ", x);
-                }
-        }
-#endif
-}
-
-static inline void
-wait_on_irq(int cpu, void *where)
-{
-	int count = MAXCOUNT;
-
-	for (;;) {
-
-		/*
-		 * Wait until all interrupts are gone. Wait
-		 * for bottom half handlers unless we're
-		 * already executing in one..
-		 */
-		if (!irqs_running()) {
-			if (local_bh_count(cpu)
-			    || !spin_is_locked(&global_bh_lock))
-				break;
-		}
-
-		/* Duh, we have to loop. Release the lock to avoid deadlocks */
-		spin_unlock(&global_irq_lock);
-
-		for (;;) {
-			if (!--count) {
-				show("wait_on_irq", where);
-				count = MAXCOUNT;
-			}
-			local_irq_enable();
-			udelay(1); /* make sure to run pending irqs */
-			local_irq_disable();
-
-			if (irqs_running())
-				continue;
-			if (spin_is_locked(&global_irq_lock))
-				continue;
-			if (!local_bh_count(cpu)
-			    && spin_is_locked(&global_bh_lock))
-				continue;
-			if (spin_trylock(&global_irq_lock))
-				break;
-		}
-	}
-}
-
-static inline void
-get_irqlock(int cpu, void* where)
-{
-	if (!spin_trylock(&global_irq_lock)) {
-		/* Do we already hold the lock?  */
-		if (cpu == global_irq_holder)
-			return;
-		/* Uhhuh.. Somebody else got it.  Wait.  */
-		spin_lock(&global_irq_lock);
-	}
-
-	/*
-	 * Ok, we got the lock bit.
-	 * But that's actually just the easy part.. Now
-	 * we need to make sure that nobody else is running
-	 * in an interrupt context. 
-	 */
-	wait_on_irq(cpu, where);
-
-	/*
-	 * Finally.
-	 */
-#ifdef CONFIG_DEBUG_SPINLOCK
-	global_irq_lock.task = current;
-	global_irq_lock.previous = where;
-#endif
-	global_irq_holder = cpu;
-	previous_irqholder = where;
-}
-
-void
-__global_cli(void)
-{
-	int cpu = smp_processor_id();
-	void *where = __builtin_return_address(0);
-
-	/*
-	 * Maximize ipl.  If ipl was previously 0 and if this thread
-	 * is not in an irq, then take global_irq_lock.
-	 */
-	if (swpipl(IPL_MAX) == IPL_MIN && !local_irq_count(cpu))
-		get_irqlock(cpu, where);
-}
-
-void
-__global_sti(void)
-{
-        int cpu = smp_processor_id();
-
-        if (!local_irq_count(cpu))
-		release_irqlock(cpu);
-	local_irq_enable();
-}
-
-/*
- * SMP flags value to restore to:
- * 0 - global cli
- * 1 - global sti
- * 2 - local cli
- * 3 - local sti
- */
-unsigned long
-__global_save_flags(void)
-{
-        int retval;
-        int local_enabled;
-        unsigned long flags;
-	int cpu = smp_processor_id();
-
-        local_save_flags(flags);
-        local_enabled = (!(flags & 7));
-        /* default to local */
-        retval = 2 + local_enabled;
-
-        /* Check for global flags if we're not in an interrupt.  */
-        if (!local_irq_count(cpu)) {
-                if (local_enabled)
-                        retval = 1;
-                if (global_irq_holder == cpu)
-                        retval = 0;
-	}
-	return retval;
-}
-
-void
-__global_restore_flags(unsigned long flags)
-{
-        switch (flags) {
-        case 0:
-                __global_cli();
-                break;
-        case 1:
-                __global_sti();
-                break;
-        case 2:
-                local_irq_disable();
-                break;
-        case 3:
-                local_irq_enable();
-                break;
-        default:
-                printk(KERN_ERR "global_restore_flags: %08lx (%p)\n",
-                        flags, __builtin_return_address(0));
-        }
-}
-
-/*
- * From its use, I infer that synchronize_irq() stalls a thread until
- * the effects of a command to an external device are known to have
- * taken hold.  Typically, the command is to stop sending interrupts.
- * The strategy here is wait until there is at most one processor
- * (this one) in an irq.  The memory barrier serializes the write to
- * the device and the subsequent accesses of global_irq_count.
- * --jmartin
- */
-#define DEBUG_SYNCHRONIZE_IRQ 0
-
-void
-synchronize_irq(void)
-{
-#if 0
-	/* Joe's version.  */
-	int cpu = smp_processor_id();
-	int local_count;
-	int global_count;
-	int countdown = 1<<24;
-	void *where = __builtin_return_address(0);
-
-	mb();
-	do {
-		local_count = local_irq_count(cpu);
-		global_count = atomic_read(&global_irq_count);
-		if (DEBUG_SYNCHRONIZE_IRQ && (--countdown == 0)) {
-			printk("%d:%d/%d\n", cpu, local_count, global_count);
-			show("synchronize_irq", where);
-			break;
-		}
-	} while (global_count != local_count);
-#else
-	/* Jay's version.  */
-	if (irqs_running()) {
-		cli();
-		sti();
-	}
-#endif
-}
diff -Nru a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
--- a/arch/alpha/kernel/osf_sys.c	Sat Aug 10 18:42:19 2002
+++ b/arch/alpha/kernel/osf_sys.c	Sat Aug 10 18:42:19 2002
@@ -33,6 +33,7 @@
 #include <linux/file.h>
 #include <linux/types.h>
 #include <linux/ipc.h>
+#include <linux/namei.h>
 
 #include <asm/fpu.h>
 #include <asm/io.h>
@@ -956,6 +957,13 @@
 		 __put_user(i->it_value.tv_usec, &o->it_value.tv_usec)));
 }
 
+static inline void
+jiffies_to_timeval32(unsigned long jiffies, struct timeval32 *value)
+{
+	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
+	value->tv_sec = jiffies / HZ;
+}
+
 asmlinkage int osf_gettimeofday(struct timeval32 *tv, struct timezone *tz)
 {
 	if (tv) {
@@ -1163,32 +1171,24 @@
 	memset(&r, 0, sizeof(r));
 	switch (who) {
 	case RUSAGE_SELF:
-		r.ru_utime.tv_sec = CT_TO_SECS(current->times.tms_utime);
-		r.ru_utime.tv_usec = CT_TO_USECS(current->times.tms_utime);
-		r.ru_stime.tv_sec = CT_TO_SECS(current->times.tms_stime);
-		r.ru_stime.tv_usec = CT_TO_USECS(current->times.tms_stime);
+		jiffies_to_timeval32(current->utime, &r.ru_utime);
+		jiffies_to_timeval32(current->stime, &r.ru_stime);
 		r.ru_minflt = current->min_flt;
 		r.ru_majflt = current->maj_flt;
 		r.ru_nswap = current->nswap;
 		break;
 	case RUSAGE_CHILDREN:
-		r.ru_utime.tv_sec = CT_TO_SECS(current->times.tms_cutime);
-		r.ru_utime.tv_usec = CT_TO_USECS(current->times.tms_cutime);
-		r.ru_stime.tv_sec = CT_TO_SECS(current->times.tms_cstime);
-		r.ru_stime.tv_usec = CT_TO_USECS(current->times.tms_cstime);
+		jiffies_to_timeval32(current->cutime, &r.ru_utime);
+		jiffies_to_timeval32(current->cstime, &r.ru_stime);
 		r.ru_minflt = current->cmin_flt;
 		r.ru_majflt = current->cmaj_flt;
 		r.ru_nswap = current->cnswap;
 		break;
 	default:
-		r.ru_utime.tv_sec = CT_TO_SECS(current->times.tms_utime +
-					       current->times.tms_cutime);
-		r.ru_utime.tv_usec = CT_TO_USECS(current->times.tms_utime +
-						 current->times.tms_cutime);
-		r.ru_stime.tv_sec = CT_TO_SECS(current->times.tms_stime +
-					       current->times.tms_cstime);
-		r.ru_stime.tv_usec = CT_TO_USECS(current->times.tms_stime +
-						 current->times.tms_cstime);
+		jiffies_to_timeval32(current->utime + current->cutime,
+				   &r.ru_utime);
+		jiffies_to_timeval32(current->stime + current->cstime,
+				   &r.ru_stime);
 		r.ru_minflt = current->min_flt + current->cmin_flt;
 		r.ru_majflt = current->maj_flt + current->cmaj_flt;
 		r.ru_nswap = current->nswap + current->cnswap;
@@ -1390,3 +1390,44 @@
 
 	return addr;
 }
+
+#ifdef CONFIG_OSF4_COMPAT
+extern ssize_t sys_readv(unsigned long, const struct iovec *, unsigned long);
+extern ssize_t sys_writev(unsigned long, const struct iovec *, unsigned long);
+
+/* Clear top 32 bits of iov_len in the user's buffer for
+   compatibility with old versions of OSF/1 where iov_len
+   was defined as int. */
+static int
+osf_fix_iov_len(const struct iovec *iov, unsigned long count)
+{
+	unsigned long i;
+
+	for (i = 0 ; i < count ; i++) {
+		int *iov_len_high = (int *)&iov[i].iov_len + 1;
+
+		if (put_user(0, iov_len_high))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+asmlinkage ssize_t
+osf_readv(unsigned long fd, const struct iovec * vector, unsigned long count)
+{
+	if (unlikely(personality(current->personality) == PER_OSF4))
+		if (osf_fix_iov_len(vector, count))
+			return -EFAULT;
+	return sys_readv(fd, vector, count);
+}
+
+asmlinkage ssize_t
+osf_writev(unsigned long fd, const struct iovec * vector, unsigned long count)
+{
+	if (unlikely(personality(current->personality) == PER_OSF4))
+		if (osf_fix_iov_len(vector, count))
+			return -EFAULT;
+	return sys_writev(fd, vector, count);
+}
+
+#endif
diff -Nru a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
--- a/arch/alpha/kernel/pci.c	Sat Aug 10 18:42:21 2002
+++ b/arch/alpha/kernel/pci.c	Sat Aug 10 18:42:21 2002
@@ -190,12 +190,12 @@
 #undef MB
 #undef GB
 
-static void __init
+static int __init
 pcibios_init(void)
 {
-	if (!alpha_mv.init_pci)
-		return;
-	alpha_mv.init_pci();
+	if (alpha_mv.init_pci)
+		alpha_mv.init_pci();
+	return 0;
 }
 
 subsys_initcall(pcibios_init);
diff -Nru a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
--- a/arch/alpha/kernel/setup.c	Sat Aug 10 18:42:21 2002
+++ b/arch/alpha/kernel/setup.c	Sat Aug 10 18:42:21 2002
@@ -1109,7 +1109,7 @@
 #ifdef CONFIG_SMP
 	seq_printf(f, "cpus active\t\t: %d\n"
 		      "cpu active mask\t\t: %016lx\n",
-		       smp_num_cpus, cpu_present_mask);
+		       num_online_cpus(), cpu_present_mask);
 #endif
 
 	return 0;
diff -Nru a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
--- a/arch/alpha/kernel/signal.c	Sat Aug 10 18:42:22 2002
+++ b/arch/alpha/kernel/signal.c	Sat Aug 10 18:42:22 2002
@@ -18,6 +18,7 @@
 #include <linux/smp_lock.h>
 #include <linux/stddef.h>
 #include <linux/tty.h>
+#include <linux/binfmts.h>
 
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
diff -Nru a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
--- a/arch/alpha/kernel/smp.c	Sat Aug 10 18:42:22 2002
+++ b/arch/alpha/kernel/smp.c	Sat Aug 10 18:42:22 2002
@@ -37,6 +37,7 @@
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
 #include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
 
 #define __KERNEL_SYSCALLS__
 #include <asm/unistd.h>
@@ -62,7 +63,6 @@
 
 enum ipi_message_type {
 	IPI_RESCHEDULE,
-	IPI_MIGRATION,
 	IPI_CALL_FUNC,
 	IPI_CPU_STOP,
 };
@@ -85,9 +85,6 @@
 cycles_t cacheflush_time;
 unsigned long cache_decay_ticks;
 
-int __cpu_number_map[NR_CPUS];
-int __cpu_logical_map[NR_CPUS];
-
 extern void calibrate_delay(void);
 extern asmlinkage void entInt(void);
 
@@ -120,8 +117,6 @@
 	cpu_data[cpuid].last_asn = ASN_FIRST_VERSION;
 	cpu_data[cpuid].need_new_asn = 0;
 	cpu_data[cpuid].asn_lock = 0;
-	local_irq_count(cpuid) = 0;
-	local_bh_count(cpuid) = 0;
 }
 
 /*
@@ -446,7 +441,7 @@
  * Bring one cpu online.
  */
 static int __init
-smp_boot_one_cpu(int cpuid, int cpunum)
+smp_boot_one_cpu(int cpuid)
 {
 	struct task_struct *idle;
 	long timeout;
@@ -464,9 +459,6 @@
 	init_idle(idle, cpuid);
 	unhash_process(idle);
 
-	__cpu_logical_map[cpunum] = cpuid;
-	__cpu_number_map[cpuid] = cpunum;
-
 	DBGS(("smp_boot_one_cpu: CPU %d state 0x%lx flags 0x%lx\n",
 	      cpuid, idle->state, idle->flags));
 
@@ -491,9 +483,7 @@
 		barrier();
 	}
 
-	/* We must invalidate our stuff as we failed to boot the CPU.  */
-	__cpu_logical_map[cpunum] = -1;
-	__cpu_number_map[cpuid] = -1;
+	/* We failed to boot the CPU.  */
 
 	printk(KERN_ERR "SMP: Processor %d is stuck.\n", cpuid);
 	return -1;
@@ -563,12 +553,8 @@
 	unsigned long bogosum;
 
 	/* Take care of some initial bookkeeping.  */
-	memset(__cpu_number_map, -1, sizeof(__cpu_number_map));
-	memset(__cpu_logical_map, -1, sizeof(__cpu_logical_map));
 	memset(ipi_data, 0, sizeof(ipi_data));
 
-	__cpu_number_map[boot_cpuid] = 0;
-	__cpu_logical_map[0] = boot_cpuid;
 	current_thread_info()->cpu = boot_cpuid;
 
 	smp_store_cpu_info(boot_cpuid);
@@ -592,7 +578,7 @@
 		if (((hwrpb_cpu_present_mask >> i) & 1) == 0)
 			continue;
 
-		if (smp_boot_one_cpu(i, cpu_count))
+		if (smp_boot_one_cpu(i))
 			continue;
 
 		cpu_present_mask |= 1UL << i;
@@ -617,14 +603,22 @@
 	smp_num_cpus = cpu_count;
 }
 
-/*
- * Called by smp_init to release the blocking online cpus once they 
- * are all started.
- */
 void __init
-smp_commence(void)
+smp_prepare_cpus(unsigned int max_cpus)
 {
-	/* smp_init sets smp_threads_ready -- that's enough.  */
+	smp_boot_cpus();
+}
+
+int __devinit
+__cpu_up(unsigned int cpu)
+{
+	return cpu_online(cpu) ? 0 : -ENOSYS;
+}
+
+void __init
+smp_cpus_done(unsigned int max_cpus)
+{
+	smp_threads_ready = 1;
 	mb();
 }
 
@@ -644,15 +638,13 @@
 		/* We need to make like a normal interrupt -- otherwise
 		   timer interrupts ignore the global interrupt lock,
 		   which would be a Bad Thing.  */
-		irq_enter(cpu, RTC_IRQ);
+		irq_enter();
 
 		update_process_times(user);
 
 		data->prof_counter = data->prof_multiplier;
-		irq_exit(cpu, RTC_IRQ);
 
-		if (softirq_pending(cpu))
-			do_softirq();
+		irq_exit();
 	}
 }
 
@@ -668,33 +660,21 @@
 {
 	unsigned long i, set, n;
 
-	set = to_whom & -to_whom;
-	if (to_whom == set) {
+	mb();
+	for (i = to_whom; i ; i &= ~set) {
+		set = i & -i;
 		n = __ffs(set);
-		mb();
 		set_bit(operation, &ipi_data[n].bits);
-		mb();
-		wripir(n);
-	} else {
-		mb();
-		for (i = to_whom; i ; i &= ~set) {
-			set = i & -i;
-			n = __ffs(set);
-			set_bit(operation, &ipi_data[n].bits);
-		}
+	}
 
-		mb();
-		for (i = to_whom; i ; i &= ~set) {
-			set = i & -i;
-			n = __ffs(set);
-			wripir(n);
-		}
+	mb();
+	for (i = to_whom; i ; i &= ~set) {
+		set = i & -i;
+		n = __ffs(set);
+		wripir(n);
 	}
 }
 
-/* Data for IPI_MIGRATION.  */
-static task_t *migration_task;
-
 /* Structure and data for smp_call_function.  This is designed to 
    minimize static memory requirements.  Plus it looks cleaner.  */
 
@@ -768,15 +748,6 @@
 			   is done by the interrupt return path.  */
 			break;
 
-		case IPI_MIGRATION:
-		    {
-			task_t *t = migration_task;
-			mb();
-			migration_task = 0;
-			sched_task_migrated(t);
-			break;
-		    }
-
 		case IPI_CALL_FUNC:
 		    {
 			struct smp_call_struct *data;
@@ -835,19 +806,6 @@
 }
 
 void
-smp_migrate_task(int cpu, task_t *t)
-{
-#if DEBUG_IPI_MSG
-	if (cpu == hard_smp_processor_id())
-		printk(KERN_WARNING
-		       "smp_migrate_task: Sending IPI to self.\n");
-#endif
-	/* Acquire the migration_task mutex.  */
-	pointer_lock(&migration_task, t, 1);
-	send_ipi_message(1UL << cpu, IPI_MIGRATION);
-}
-
-void
 smp_send_stop(void)
 {
 	unsigned long to_whom = cpu_present_mask & ~(1UL << smp_processor_id());
@@ -977,10 +935,9 @@
 	if (mm == current->active_mm) {
 		flush_tlb_current(mm);
 		if (atomic_read(&mm->mm_users) <= 1) {
-			int i, cpu, this_cpu = smp_processor_id();
-			for (i = 0; i < smp_num_cpus; i++) {
-				cpu = cpu_logical_map(i);
-				if (cpu == this_cpu)
+			int cpu, this_cpu = smp_processor_id();
+			for (cpu = 0; cpu < NR_CPUS; cpu++) {
+				if (!cpu_online(cpu) || cpu == this_cpu)
 					continue;
 				if (mm->context[cpu])
 					mm->context[cpu] = 0;
@@ -1021,10 +978,9 @@
 	if (mm == current->active_mm) {
 		flush_tlb_current_page(mm, vma, addr);
 		if (atomic_read(&mm->mm_users) <= 1) {
-			int i, cpu, this_cpu = smp_processor_id();
-			for (i = 0; i < smp_num_cpus; i++) {
-				cpu = cpu_logical_map(i);
-				if (cpu == this_cpu)
+			int cpu, this_cpu = smp_processor_id();
+			for (cpu = 0; cpu < NR_CPUS; cpu++) {
+				if (!cpu_online(cpu) || cpu == this_cpu)
 					continue;
 				if (mm->context[cpu])
 					mm->context[cpu] = 0;
@@ -1071,10 +1027,9 @@
 	if (mm == current->active_mm) {
 		__load_new_mm_context(mm);
 		if (atomic_read(&mm->mm_users) <= 1) {
-			int i, cpu, this_cpu = smp_processor_id();
-			for (i = 0; i < smp_num_cpus; i++) {
-				cpu = cpu_logical_map(i);
-				if (cpu == this_cpu)
+			int cpu, this_cpu = smp_processor_id();
+			for (cpu = 0; cpu < NR_CPUS; cpu++) {
+				if (!cpu_online(cpu) || cpu == this_cpu)
 					continue;
 				if (mm->context[cpu])
 					mm->context[cpu] = 0;
diff -Nru a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
--- a/arch/alpha/kernel/traps.c	Sat Aug 10 18:42:22 2002
+++ b/arch/alpha/kernel/traps.c	Sat Aug 10 18:42:22 2002
@@ -182,7 +182,7 @@
 
 	if (test_and_set_thread_flag (TIF_DIE_IF_KERNEL)) {
 		printk("die_if_kernel recursion detected.\n");
-		sti();
+		local_irq_enable();
 		while (1);
 	}
 	do_exit(SIGSEGV);
@@ -613,7 +613,7 @@
 
 	if (test_and_set_thread_flag (TIF_DIE_IF_KERNEL)) {
 		printk("die_if_kernel recursion detected.\n");
-		sti();
+		local_irq_enable();
 		while (1);
 	}
 	do_exit(SIGSEGV);
diff -Nru a/arch/alpha/lib/ev6-strncpy_from_user.S b/arch/alpha/lib/ev6-strncpy_from_user.S
--- a/arch/alpha/lib/ev6-strncpy_from_user.S	Sat Aug 10 18:42:23 2002
+++ b/arch/alpha/lib/ev6-strncpy_from_user.S	Sat Aug 10 18:42:23 2002
@@ -27,7 +27,7 @@
 
 
 #include <asm/errno.h>
-#include <alpha/regdef.h>
+#include <asm/regdef.h>
 
 
 /* Allow an exception for an insn; exit if we get one.  */
diff -Nru a/arch/alpha/lib/ev6-stxcpy.S b/arch/alpha/lib/ev6-stxcpy.S
--- a/arch/alpha/lib/ev6-stxcpy.S	Sat Aug 10 18:42:19 2002
+++ b/arch/alpha/lib/ev6-stxcpy.S	Sat Aug 10 18:42:19 2002
@@ -30,7 +30,7 @@
  * Try not to change the actual algorithm if possible for consistency.
  */
 
-#include <alpha/regdef.h>
+#include <asm/regdef.h>
 
 	.set noat
 	.set noreorder
diff -Nru a/arch/alpha/lib/ev6-stxncpy.S b/arch/alpha/lib/ev6-stxncpy.S
--- a/arch/alpha/lib/ev6-stxncpy.S	Sat Aug 10 18:42:23 2002
+++ b/arch/alpha/lib/ev6-stxncpy.S	Sat Aug 10 18:42:23 2002
@@ -38,7 +38,7 @@
  * Try not to change the actual algorithm if possible for consistency.
  */
 
-#include <alpha/regdef.h>
+#include <asm/regdef.h>
 
 	.set noat
 	.set noreorder
diff -Nru a/arch/alpha/lib/ev67-strchr.S b/arch/alpha/lib/ev67-strchr.S
--- a/arch/alpha/lib/ev67-strchr.S	Sat Aug 10 18:42:23 2002
+++ b/arch/alpha/lib/ev67-strchr.S	Sat Aug 10 18:42:23 2002
@@ -16,7 +16,7 @@
  * Try not to change the actual algorithm if possible for consistency.
  */
 
-#include <alpha/regdef.h>
+#include <asm/regdef.h>
 
 	.set noreorder
 	.set noat
diff -Nru a/arch/alpha/lib/ev67-strlen_user.S b/arch/alpha/lib/ev67-strlen_user.S
--- a/arch/alpha/lib/ev67-strlen_user.S	Sat Aug 10 18:42:22 2002
+++ b/arch/alpha/lib/ev67-strlen_user.S	Sat Aug 10 18:42:22 2002
@@ -23,7 +23,7 @@
  * Try not to change the actual algorithm if possible for consistency.
  */
 
-#include <alpha/regdef.h>
+#include <asm/regdef.h>
 
 
 /* Allow an exception for an insn; exit if we get one.  */
diff -Nru a/arch/alpha/lib/ev67-strrchr.S b/arch/alpha/lib/ev67-strrchr.S
--- a/arch/alpha/lib/ev67-strrchr.S	Sat Aug 10 18:42:23 2002
+++ b/arch/alpha/lib/ev67-strrchr.S	Sat Aug 10 18:42:23 2002
@@ -19,7 +19,7 @@
  */
 
 
-#include <alpha/regdef.h>
+#include <asm/regdef.h>
 
 	.set noreorder
 	.set noat
diff -Nru a/arch/alpha/lib/strchr.S b/arch/alpha/lib/strchr.S
--- a/arch/alpha/lib/strchr.S	Sat Aug 10 18:42:22 2002
+++ b/arch/alpha/lib/strchr.S	Sat Aug 10 18:42:22 2002
@@ -6,7 +6,7 @@
  * string, or null if it is not found.
  */
 
-#include <alpha/regdef.h>
+#include <asm/regdef.h>
 
 	.set noreorder
 	.set noat
diff -Nru a/arch/alpha/lib/strlen_user.S b/arch/alpha/lib/strlen_user.S
--- a/arch/alpha/lib/strlen_user.S	Sat Aug 10 18:42:23 2002
+++ b/arch/alpha/lib/strlen_user.S	Sat Aug 10 18:42:23 2002
@@ -12,7 +12,7 @@
  * boundary when doing so.
  */
 
-#include <alpha/regdef.h>
+#include <asm/regdef.h>
 
 
 /* Allow an exception for an insn; exit if we get one.  */
diff -Nru a/arch/alpha/lib/strncpy_from_user.S b/arch/alpha/lib/strncpy_from_user.S
--- a/arch/alpha/lib/strncpy_from_user.S	Sat Aug 10 18:42:21 2002
+++ b/arch/alpha/lib/strncpy_from_user.S	Sat Aug 10 18:42:21 2002
@@ -12,7 +12,7 @@
 
 
 #include <asm/errno.h>
-#include <alpha/regdef.h>
+#include <asm/regdef.h>
 
 
 /* Allow an exception for an insn; exit if we get one.  */
diff -Nru a/arch/alpha/lib/strrchr.S b/arch/alpha/lib/strrchr.S
--- a/arch/alpha/lib/strrchr.S	Sat Aug 10 18:42:23 2002
+++ b/arch/alpha/lib/strrchr.S	Sat Aug 10 18:42:23 2002
@@ -6,7 +6,7 @@
  * within a null-terminated string, or null if it is not found.
  */
 
-#include <alpha/regdef.h>
+#include <asm/regdef.h>
 
 	.set noreorder
 	.set noat
diff -Nru a/arch/alpha/lib/stxcpy.S b/arch/alpha/lib/stxcpy.S
--- a/arch/alpha/lib/stxcpy.S	Sat Aug 10 18:42:21 2002
+++ b/arch/alpha/lib/stxcpy.S	Sat Aug 10 18:42:21 2002
@@ -20,7 +20,7 @@
  * Furthermore, v0, a3-a5, t11, and t12 are untouched.
  */
 
-#include <alpha/regdef.h>
+#include <asm/regdef.h>
 
 	.set noat
 	.set noreorder
diff -Nru a/arch/alpha/lib/stxncpy.S b/arch/alpha/lib/stxncpy.S
--- a/arch/alpha/lib/stxncpy.S	Sat Aug 10 18:42:23 2002
+++ b/arch/alpha/lib/stxncpy.S	Sat Aug 10 18:42:23 2002
@@ -28,7 +28,7 @@
  * Furthermore, v0, a3-a5, t11, t12, and $at are untouched.
  */
 
-#include <alpha/regdef.h>
+#include <asm/regdef.h>
 
 	.set noat
 	.set noreorder
diff -Nru a/arch/alpha/vmlinux.lds.in b/arch/alpha/vmlinux.lds.in
--- a/arch/alpha/vmlinux.lds.in	Sat Aug 10 18:42:23 2002
+++ b/arch/alpha/vmlinux.lds.in	Sat Aug 10 18:42:23 2002
@@ -58,6 +58,11 @@
 	__initcall_end = .;
   }
 
+  . = ALIGN(64);
+  __per_cpu_start = .;
+  .data.percpu  : { *(.data.percpu) }
+  __per_cpu_end = .;
+
   /* The initial task and kernel stack */
   .data.init_thread ALIGN(2*8192) : {
 	__init_end = .;
diff -Nru a/arch/arm/Makefile b/arch/arm/Makefile
--- a/arch/arm/Makefile	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/Makefile	Sat Aug 10 18:42:22 2002
@@ -123,6 +123,10 @@
 MACHINE		 = sa1100
 endif
 
+ifeq ($(CONFIG_ARCH_PXA),y)
+MACHINE		 = pxa
+endif
+
 ifeq ($(CONFIG_ARCH_L7200),y)
 MACHINE		 = l7200
 endif
diff -Nru a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
--- a/arch/arm/boot/Makefile	Sat Aug 10 18:42:21 2002
+++ b/arch/arm/boot/Makefile	Sat Aug 10 18:42:21 2002
@@ -87,6 +87,10 @@
 endif
 endif
 
+ifeq ($(CONFIG_ARCH_PXA),y)
+ZRELADDR	 = 0xa0008000
+endif
+
 ifeq ($(CONFIG_ARCH_ANAKIN),y)
 ZRELADDR	 = 0x20008000
 endif
diff -Nru a/arch/arm/config.in b/arch/arm/config.in
--- a/arch/arm/config.in	Sat Aug 10 18:42:21 2002
+++ b/arch/arm/config.in	Sat Aug 10 18:42:21 2002
@@ -26,6 +26,7 @@
 	 Cirrus-CL-PS7500FE     CONFIG_ARCH_CLPS7500 \
  	 CLPS711x/EP721x-based	CONFIG_ARCH_CLPS711X \
 	 Co-EBSA285		CONFIG_ARCH_CO285 \
+	 PXA250/210-based	CONFIG_ARCH_PXA \
 	 EBSA-110		CONFIG_ARCH_EBSA110 \
  	 Epxa10db               CONFIG_ARCH_CAMELOT \
 	 FootBridge		CONFIG_ARCH_FOOTBRIDGE \
@@ -126,6 +127,16 @@
 endmenu
 
 mainmenu_option next_comment
+comment 'Intel PXA250/210 Implementations'
+dep_bool '  Intel DBPXA250 Development Platform' CONFIG_ARCH_LUBBOCK $CONFIG_ARCH_PXA
+dep_bool '  Accelent Xscale IDP' CONFIG_ARCH_PXA_IDP $CONFIG_ARCH_PXA
+
+if [ "$CONFIG_ARCH_LUBBOCK" = "y" ]; then
+   define_bool CONFIG_SA1111 y
+fi
+endmenu
+
+mainmenu_option next_comment
 comment 'CLPS711X/EP721X Implementations'
 dep_bool '  AUTCPU12' CONFIG_ARCH_AUTCPU12 $CONFIG_ARCH_CLPS711X
 dep_bool '  CDB89712' CONFIG_ARCH_CDB89712 $CONFIG_ARCH_CLPS711X
@@ -227,7 +238,9 @@
 else
    define_bool CONFIG_CPU_32v4 n
 fi
-if [ "$CONFIG_ARCH_IOP310" = "y" -o "$CONFIG_ARCH_ADIFCC" = "y" ]; then
+if [ "$CONFIG_ARCH_IOP310" = "y" -o \
+     "$CONFIG_ARCH_ADIFCC" = "y" -o \
+     "$CONFIG_ARCH_PXA" = "y" ]; then
    define_bool CONFIG_CPU_32v5 y
 else
    define_bool CONFIG_CPU_32v5 n
@@ -317,7 +330,9 @@
 fi
 
 # XScale
-if [ "$CONFIG_ARCH_IOP310" = "y" -o "$CONFIG_ARCH_ADIFCC" = "y" ]; then
+if [ "$CONFIG_ARCH_IOP310" = "y" -o \
+     "$CONFIG_ARCH_ADIFCC" = "y" -o \
+     "$CONFIG_ARCH_PXA" = "y" ]; then
    define_bool CONFIG_CPU_XSCALE y
 else
    define_bool CONFIG_CPU_XSCALE n
@@ -467,6 +482,8 @@
      "$CONFIG_ARCH_SHARK" = "y" -o      \
      "$CONFIG_ARCH_CO285" = "y" -o      \
      "$CONFIG_ARCH_SA1100" = "y" -o     \
+     "$CONFIG_ARCH_LUBBOCK" = "y" -o    \
+     "$CONFIG_ARCH_PXA_IDP" = "y" -o \
      "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
      "$CONFIG_ARCH_CDB89712" = "y" -o   \
      "$CONFIG_ARCH_P720T" = "y" ]; then
@@ -477,6 +494,8 @@
 	   "$CONFIG_ARCH_SHARK" = "y" -o      \
 	   "$CONFIG_ARCH_CO285" = "y" -o      \
 	   "$CONFIG_ARCH_SA1100" = "y" -o     \
+          "$CONFIG_ARCH_LUBBOCK" = "y" -o    \
+	   "$CONFIG_ARCH_PXA_IDP" = "y" -o    \
            "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
 	   "$CONFIG_ARCH_P720T" = "y" ]; then
          bool '  Timer LED' CONFIG_LEDS_TIMER
diff -Nru a/arch/arm/def-configs/lubbock b/arch/arm/def-configs/lubbock
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/def-configs/lubbock	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,881 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_UID16=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_GENERIC_BUST_SPINLOCK is not set
+# CONFIG_GENERIC_ISA_DMA is not set
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# General setup
+#
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ADIFCC is not set
+# CONFIG_ARCH_ANAKIN is not set
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+CONFIG_ARCH_PXA=y
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_CAMELOT is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_IOP310 is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_SHARK is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Archimedes/A5000 Implementations (select only ONE)
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+
+#
+# Footbridge Implementations
+#
+# CONFIG_ARCH_CATS is not set
+# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_EBSA285_ADDIN is not set
+# CONFIG_ARCH_EBSA285_HOST is not set
+# CONFIG_ARCH_NETWINDER is not set
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_ASSABET_NEPONSET is not set
+# CONFIG_SA1100_ADSBITSY is not set
+# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_H3100 is not set
+# CONFIG_SA1100_H3600 is not set
+# CONFIG_SA1100_H3800 is not set
+# CONFIG_SA1100_H3XXX is not set
+# CONFIG_SA1100_EXTENEX1 is not set
+# CONFIG_SA1100_FLEXANET is not set
+# CONFIG_SA1100_FREEBIRD is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_GRAPHICSMASTER is not set
+# CONFIG_SA1100_BADGE4 is not set
+# CONFIG_SA1100_JORNADA720 is not set
+# CONFIG_SA1100_HUW_WEBPANEL is not set
+# CONFIG_SA1100_ITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_NANOENGINE is not set
+# CONFIG_SA1100_OMNIMETER is not set
+# CONFIG_SA1100_PANGOLIN is not set
+# CONFIG_SA1100_PLEB is not set
+# CONFIG_SA1100_PT_SYSTEM3 is not set
+# CONFIG_SA1100_SHANNON is not set
+# CONFIG_SA1100_SHERMAN is not set
+# CONFIG_SA1100_SIMPAD is not set
+# CONFIG_SA1100_PFS168 is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_SA1100_XP860 is not set
+# CONFIG_SA1100_YOPY is not set
+# CONFIG_SA1100_STORK is not set
+# CONFIG_SA1100_USB is not set
+# CONFIG_SA1100_USB_NETLINK is not set
+# CONFIG_SA1100_USB_CHAR is not set
+# CONFIG_H3600_SLEEVE is not set
+
+#
+# Intel PXA250/210 Implementations
+#
+CONFIG_ARCH_LUBBOCK=y
+# CONFIG_ARCH_PXA_IDP is not set
+CONFIG_SA1111=y
+
+#
+# CLPS711X/EP721X Implementations
+#
+# CONFIG_ARCH_AUTCPU12 is not set
+# CONFIG_ARCH_CDB89712 is not set
+# CONFIG_ARCH_CLEP7312 is not set
+# CONFIG_ARCH_EDB7211 is not set
+# CONFIG_ARCH_P720T is not set
+# CONFIG_ARCH_FORTUNET is not set
+# CONFIG_ARCH_EP7211 is not set
+# CONFIG_ARCH_EP7212 is not set
+
+#
+# IOP310 Implementation Options
+#
+# CONFIG_ARCH_IQ80310 is not set
+
+#
+# IOP310 Chipset Features
+#
+# CONFIG_IOP310_AAU is not set
+# CONFIG_IOP310_DMA is not set
+# CONFIG_IOP310_MU is not set
+# CONFIG_IOP310_PMON is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_32v3 is not set
+# CONFIG_CPU_32v4 is not set
+CONFIG_CPU_32v5=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM922T is not set
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
+CONFIG_CPU_XSCALE=y
+CONFIG_XSCALE_CACHE_ERRATA=y
+CONFIG_XSCALE_PMU=y
+
+#
+# Processor Features
+#
+# CONFIG_ARM_THUMB is not set
+
+#
+# General setup
+#
+# CONFIG_DISCONTIGMEM is not set
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+# CONFIG_FIQ is not set
+# CONFIG_ZBOOT_ROM is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_PROBE=y
+# CONFIG_I82092 is not set
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+# CONFIG_PCMCIA_CLPS6700 is not set
+# CONFIG_PCMCIA_SA1100 is not set
+CONFIG_PCMCIA_PXA=y
+
+#
+# At least one math emulation must be selected
+#
+CONFIG_FPE_NWFPE=y
+# CONFIG_FPE_FASTFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_APM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=/dev/nfs ip=bootp console=ttyS0,115200 mem=64M"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+# CONFIG_MTD_BOOTLDR_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_CFI_B1 is not set
+# CONFIG_MTD_CFI_B2 is not set
+CONFIG_MTD_CFI_B4=y
+# CONFIG_MTD_CFI_I1 is not set
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+# CONFIG_MTD_AMDSTD is not set
+# CONFIG_MTD_SHARP is not set
+# CONFIG_MTD_JEDEC is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_CDB89712 is not set
+# CONFIG_MTD_SA1100 is not set
+# CONFIG_MTD_2PARTS_IPAQ is not set
+# CONFIG_MTD_DC21285 is not set
+# CONFIG_MTD_IQ80310 is not set
+CONFIG_MTD_LUBBOCK=y
+# CONFIG_MTD_EPXA10DB is not set
+# CONFIG_MTD_FORTUNET is not set
+# CONFIG_MTD_PCI is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLKMTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+# CONFIG_IP_PNP_DHCP is not set
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A is not set
+# CONFIG_SUNLANCE is not set
+# CONFIG_SUNBMAC is not set
+# CONFIG_SUNQE is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+CONFIG_NET_VENDOR_SMC=y
+# CONFIG_WD80x3 is not set
+# CONFIG_ULTRAMCA is not set
+# CONFIG_ULTRA is not set
+# CONFIG_ULTRA32 is not set
+CONFIG_SMC9194=y
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+
+#
+# PCMCIA network device support
+#
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_ARCNET_COM20020_CS is not set
+# CONFIG_PCMCIA_IBMTR is not set
+# CONFIG_NET_PCMCIA_RADIO is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN_BOOL is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_KEYBDEV is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_GAMEPORT_PCIGAME is not set
+# CONFIG_GAMEPORT_FM801 is not set
+# CONFIG_GAMEPORT_CS461x is not set
+# CONFIG_SERIO is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
+# CONFIG_JOYSTICK_IFORCE_USB is not set
+# CONFIG_JOYSTICK_IFORCE_232 is not set
+# CONFIG_JOYSTICK_WARRIOR is not set
+# CONFIG_JOYSTICK_MAGELLAN is not set
+# CONFIG_JOYSTICK_SPACEORB is not set
+# CONFIG_JOYSTICK_SPACEBALL is not set
+# CONFIG_JOYSTICK_STINGER is not set
+# CONFIG_JOYSTICK_DB9 is not set
+# CONFIG_JOYSTICK_GAMECON is not set
+# CONFIG_JOYSTICK_TURBOGRAFX is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_CS is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_ATOMWIDE_SERIAL is not set
+# CONFIG_DUALSP_SERIAL is not set
+# CONFIG_SERIAL_ANAKIN is not set
+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
+# CONFIG_SERIAL_AMBA is not set
+# CONFIG_SERIAL_AMBA_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X is not set
+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
+# CONFIG_SERIAL_CLPS711X_OLD_NAME is not set
+# CONFIG_SERIAL_21285 is not set
+# CONFIG_SERIAL_21285_OLD is not set
+# CONFIG_SERIAL_21285_CONSOLE is not set
+# CONFIG_SERIAL_UART00 is not set
+# CONFIG_SERIAL_UART00_CONSOLE is not set
+# CONFIG_SERIAL_SA1100 is not set
+# CONFIG_SERIAL_SA1100_CONSOLE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# L3 serial bus support
+#
+# CONFIG_L3 is not set
+# CONFIG_L3_ALGOBIT is not set
+# CONFIG_L3_BIT_SA1100_GPIO is not set
+
+#
+# Other L3 adapters
+#
+# CONFIG_L3_SA1111 is not set
+# CONFIG_BIT_SA1100_GPIO is not set
+
+#
+# Mice
+#
+CONFIG_BUSMOUSE=y
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_LOGIBUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+# CONFIG_JFFS2_FS_NAND is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_TMPFS is not set
+CONFIG_RAMFS=y
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_DEBUG is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_EXPORTFS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+# CONFIG_SMB_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=y
+# CONFIG_SOUND_BT878 is not set
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_MIDI_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_RME96XX is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_MIDI_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+# CONFIG_SOUND_PXA_AC97 is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
+# Advanced Linux Sound Architecture
+#
+# CONFIG_SND is not set
+
+#
+# Multimedia Capabilities Port drivers
+#
+# CONFIG_MCP is not set
+# CONFIG_MCP_SA1100 is not set
+# CONFIG_MCP_UCB1200 is not set
+# CONFIG_MCP_UCB1200_AUDIO is not set
+# CONFIG_MCP_UCB1200_TS is not set
+# CONFIG_MCP_UCB1400_TS is not set
+
+#
+# Console Switches
+#
+# CONFIG_SWITCHES is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Bluetooth support
+#
+# CONFIG_BLUEZ is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_NO_FRAME_POINTER is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_WAITQ is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+# CONFIG_DEBUG_DC21285_PORT is not set
+# CONFIG_DEBUG_CLPS711X_UART2 is not set
+
+#
+# Library routines
+#
+CONFIG_CRC32=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
diff -Nru a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
--- a/arch/arm/kernel/debug.S	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/kernel/debug.S	Sat Aug 10 18:42:22 2002
@@ -215,8 +215,8 @@
 		.macro	addruart,rx
 		mrc	p15, 0, \rx, c1, c0
 		tst	\rx, #1			@ MMU enabled?
-		moveq	\rx, #0x40000000	@ physical
-		movne	\rx, #0xfc000000	@ virtual
+		moveq	\rx, #0x40000000		@ physical
+		movne	\rx, #io_p2v(0x40000000)	@ virtual
 		orr	\rx, \rx, #0x00100000
 		.endm
 
diff -Nru a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
--- a/arch/arm/kernel/dma-isa.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/kernel/dma-isa.c	Sat Aug 10 18:42:22 2002
@@ -133,10 +133,10 @@
 }
 
 static struct dma_ops isa_dma_ops = {
-	type:		"ISA",
-	enable:		isa_enable_dma,
-	disable:	isa_disable_dma,
-	residue:	isa_get_dma_residue,
+	.type		= "ISA",
+	.enable		= isa_enable_dma,
+	.disable	= isa_disable_dma,
+	.residue	= isa_get_dma_residue,
 };
 
 static struct resource dma_resources[] = {
diff -Nru a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
--- a/arch/arm/kernel/ecard.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/kernel/ecard.c	Sat Aug 10 18:42:23 2002
@@ -407,7 +407,7 @@
 }
 
 static struct notifier_block ecard_reboot_notifier = {
-	notifier_call:	ecard_reboot,
+	.notifier_call	= ecard_reboot,
 };
 
 
@@ -571,9 +571,9 @@
 }
 
 static struct irqchip ecard_chip = {
-	ack:	ecard_irq_mask,
-	mask:	ecard_irq_mask,
-	unmask:	ecard_irq_unmask,
+	.ack	= ecard_irq_mask,
+	.mask	= ecard_irq_mask,
+	.unmask = ecard_irq_unmask,
 };
 
 void ecard_enablefiq(unsigned int fiqnr)
diff -Nru a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S
--- a/arch/arm/kernel/entry-armo.S	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/kernel/entry-armo.S	Sat Aug 10 18:42:22 2002
@@ -244,7 +244,7 @@
 		tst	lr, #3
 		bne	__pabt_invalid
 		save_user_regs
-		teqp	pc, #0x00000003		@ NOT a problem - doesnt change mode
+		teqp	pc, #0x00000003		@ NOT a problem - doesn't change mode
 		mask_pc	r0, lr			@ Address of abort
 		mov	r1, sp			@ Tasks registers
 		bl	do_PrefetchAbort
@@ -295,7 +295,7 @@
 		and	r2, lr, #3
 		teq	r2, #3
 		bne	Laddrexcptn_illegal_mode
-		teqp	pc, #0x00000003		@ NOT a problem - doesnt change mode
+		teqp	pc, #0x00000003		@ NOT a problem - doesn't change mode
 		mask_pc	r0, lr
 		mov	r1, sp
 		orr	r2, r2, #0x400
@@ -399,7 +399,7 @@
 		tst	lr, #3
 		bne	Ldata_not_user
 		save_user_regs
-		teqp	pc, #0x00000003		@ NOT a problem - doesnt change mode
+		teqp	pc, #0x00000003		@ NOT a problem - doesn't change mode
 		mask_pc	r0, lr
 		bl	Ldata_do
 		b	ret_from_exception
@@ -410,7 +410,7 @@
 		teq	r2, #3
 		bne	Ldata_illegal_mode
 		tst	lr, #0x08000000
-		teqeqp	pc, #0x00000003		@ NOT a problem - doesnt change mode
+		teqeqp	pc, #0x00000003		@ NOT a problem - doesn't change mode
 		mask_pc	r0, lr
 		bl	Ldata_do
 		SVC_RESTORE_ALL
diff -Nru a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
--- a/arch/arm/kernel/entry-armv.S	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/kernel/entry-armv.S	Sat Aug 10 18:42:22 2002
@@ -590,7 +590,7 @@
 		.endm
 
 		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		mov	\base, #0xfc000000		@ IIR Ctl = 0xfcd00000
+		mov	\base, #io_p2v(0x40000000)	@ IIR Ctl = 0x40d00000
 		add	\base, \base, #0x00d00000
 		ldr	\irqstat, [\base, #0]		@ ICIP
 		ldr	\irqnr, [\base, #4]		@ ICMR
diff -Nru a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
--- a/arch/arm/kernel/fiq.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/kernel/fiq.c	Sat Aug 10 18:42:23 2002
@@ -87,8 +87,8 @@
 }
 
 static struct fiq_handler default_owner = {
-	name:	"default",
-	fiq_op:	fiq_def_op,
+	.name	= "default",
+	.fiq_op = fiq_def_op,
 };
 
 static struct fiq_handler *current_fiq = &default_owner;
diff -Nru a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
--- a/arch/arm/kernel/irq.c	Sat Aug 10 18:42:19 2002
+++ b/arch/arm/kernel/irq.c	Sat Aug 10 18:42:19 2002
@@ -64,15 +64,15 @@
 }
 
 static struct irqchip bad_chip = {
-	ack:	dummy_mask_unmask_irq,
-	mask:	dummy_mask_unmask_irq,
-	unmask:	dummy_mask_unmask_irq,
+	.ack	= dummy_mask_unmask_irq,
+	.mask	= dummy_mask_unmask_irq,
+	.unmask = dummy_mask_unmask_irq,
 };
 
 static struct irqdesc bad_irq_desc = {
-	chip:	&bad_chip,
-	handle:	do_bad_IRQ,
-	depth:	1,
+	.chip	= &bad_chip,
+	.handle = do_bad_IRQ,
+	.depth	= 1,
 };
 
 /**
diff -Nru a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
--- a/arch/arm/kernel/setup.c	Sat Aug 10 18:42:20 2002
+++ b/arch/arm/kernel/setup.c	Sat Aug 10 18:42:20 2002
@@ -803,8 +803,8 @@
 }
 
 struct seq_operations cpuinfo_op = {
-	start:	c_start,
-	next:	c_next,
-	stop:	c_stop,
-	show:	c_show
+	.start	= c_start,
+	.next	= c_next,
+	.stop	= c_stop,
+	.show	= c_show
 };
diff -Nru a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
--- a/arch/arm/kernel/time.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/kernel/time.c	Sat Aug 10 18:42:23 2002
@@ -205,7 +205,7 @@
 }
 
 static struct irqaction timer_irq = {
-	name: "timer",
+	.name	= "timer",
 };
 
 /*
diff -Nru a/arch/arm/mach-anakin/irq.c b/arch/arm/mach-anakin/irq.c
--- a/arch/arm/mach-anakin/irq.c	Sat Aug 10 18:42:20 2002
+++ b/arch/arm/mach-anakin/irq.c	Sat Aug 10 18:42:20 2002
@@ -49,9 +49,9 @@
 }
 
 static struct irqaction anakin_irq = {
-	name:		"Anakin IRQ",
-	handler:	anakin_interrupt,
-	flags:		SA_INTERRUPT
+	.name		= "Anakin IRQ",
+	.handler	= anakin_interrupt,
+	.flags		= SA_INTERRUPT
 };
  
 void __init
diff -Nru a/arch/arm/mach-arc/dma.c b/arch/arm/mach-arc/dma.c
--- a/arch/arm/mach-arc/dma.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-arc/dma.c	Sat Aug 10 18:42:23 2002
@@ -110,23 +110,23 @@
 }
 
 static struct dma_ops arc_floppy_data_dma_ops = {
-	type:		"FIQDMA",
-	enable:		arc_floppy_data_enable_dma,
-	disable:	arc_disable_dma,
-	residue:	arc_floppy_data_get_dma_residue,
+	.type		= "FIQDMA",
+	.enable		= arc_floppy_data_enable_dma,
+	.disable	= arc_disable_dma,
+	.residue	= arc_floppy_data_get_dma_residue,
 };
 
 static struct dma_ops arc_floppy_cmdend_dma_ops = {
-	type:		"FIQCMD",
-	enable:		arc_floppy_cmdend_enable_dma,
-	disable:	arc_disable_dma,
-	residue:	arc_floppy_cmdend_get_dma_residue,
+	.type		= "FIQCMD",
+	.enable		= arc_floppy_cmdend_enable_dma,
+	.disable	= arc_disable_dma,
+	.residue	= arc_floppy_cmdend_get_dma_residue,
 };
 #endif
 
 #ifdef CONFIG_ARCH_A5K
 static struct fiq_handler fh = {
-	name:	"floppydata"
+	.name	= "floppydata"
 };
 
 static int a5k_floppy_get_dma_residue(dmach_t channel, dma_t *dma)
@@ -175,10 +175,10 @@
 }
 
 static struct dma_ops a5k_floppy_dma_ops = {
-	type:		"FIQDMA",
-	enable:		a5k_floppy_enable_dma,
-	disable:	a5k_floppy_disable_dma,
-	residue:	a5k_floppy_get_dma_residue,
+	.type		= "FIQDMA",
+	.enable		= a5k_floppy_enable_dma,
+	.disable	= a5k_floppy_disable_dma,
+	.residue	= a5k_floppy_get_dma_residue,
 };
 #endif
 
@@ -190,9 +190,9 @@
 }
 
 static struct dma_ops sound_dma_ops = {
-	type:		"VIRTUAL",
-	enable:		sound_enable_disable_dma,
-	disable:	sound_enable_disable_dma,
+	.type		= "VIRTUAL",
+	.enable		= sound_enable_disable_dma,
+	.disable	= sound_enable_disable_dma,
 };
 
 void __init arch_dma_init(dma_t *dma)
diff -Nru a/arch/arm/mach-clps711x/irq.c b/arch/arm/mach-clps711x/irq.c
--- a/arch/arm/mach-clps711x/irq.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-clps711x/irq.c	Sat Aug 10 18:42:23 2002
@@ -63,9 +63,9 @@
 }
 
 static struct irqchip int1_chip = {
-	ack:	int1_ack,
-	mask:	int1_mask,
-	unmask:	int1_unmask,
+	.ack	= int1_ack,
+	.mask	= int1_mask,
+	.unmask = int1_unmask,
 };
 
 static void int2_mask(unsigned int irq)
@@ -100,9 +100,9 @@
 }
 
 static struct irqchip int2_chip = {
-	ack:	int2_ack,
-	mask:	int2_mask,
-	unmask:	int2_unmask,
+	.ack	= int2_ack,
+	.mask	= int2_mask,
+	.unmask = int2_unmask,
 };
 
 void __init clps711x_init_irq(void)
diff -Nru a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
--- a/arch/arm/mach-ebsa110/core.c	Sat Aug 10 18:42:21 2002
+++ b/arch/arm/mach-ebsa110/core.c	Sat Aug 10 18:42:21 2002
@@ -42,9 +42,9 @@
 }
 
 static struct irqchip ebsa110_irq_chip = {
-	ack:	ebsa110_mask_irq,
-	mask:	ebsa110_mask_irq,
-	unmask:	ebsa110_unmask_irq,
+	.ack	= ebsa110_mask_irq,
+	.mask	= ebsa110_mask_irq,
+	.unmask = ebsa110_unmask_irq,
 };
  
 static void __init ebsa110_init_irq(void)
diff -Nru a/arch/arm/mach-epxa10db/irq.c b/arch/arm/mach-epxa10db/irq.c
--- a/arch/arm/mach-epxa10db/irq.c	Sat Aug 10 18:42:21 2002
+++ b/arch/arm/mach-epxa10db/irq.c	Sat Aug 10 18:42:21 2002
@@ -39,15 +39,15 @@
  
 
 static struct irqchip epxa_irq_chip = {
-	ack:		epxa_mask_irq,
-	mask:		epxa_mask_irq,
-	unmask:		epxa_unmask_irq,
+	.ack		= epxa_mask_irq,
+	.mask		= epxa_mask_irq,
+	.unmask		= epxa_unmask_irq,
 };
 
 static struct resource irq_resource = {
-	name:	"irq_handler",
-	start:	IO_ADDRESS(EXC_INT_CTRL00_BASE),
-	end:	IO_ADDRESS(INT_PRIORITY_FC(EXC_INT_CTRL00_BASE))+4,
+	.name	= "irq_handler",
+	.start	= IO_ADDRESS(EXC_INT_CTRL00_BASE),
+	.end	= IO_ADDRESS(INT_PRIORITY_FC(EXC_INT_CTRL00_BASE))+4,
 };
 
 void __init epxa10db_init_irq(void)
diff -Nru a/arch/arm/mach-footbridge/cats-pci.c b/arch/arm/mach-footbridge/cats-pci.c
--- a/arch/arm/mach-footbridge/cats-pci.c	Sat Aug 10 18:42:21 2002
+++ b/arch/arm/mach-footbridge/cats-pci.c	Sat Aug 10 18:42:21 2002
@@ -36,13 +36,13 @@
  * cards being used (ie, pci-pci bridge based cards)?
  */
 static struct hw_pci cats_pci __initdata = {
-	swizzle:		NULL,
-	map_irq:		cats_map_irq,
-	nr_controllers:		1,
-	setup:			dc21285_setup,
-	scan:			dc21285_scan_bus,
-	preinit:		dc21285_preinit,
-	postinit:		dc21285_postinit,
+	.swizzle		= NULL,
+	.map_irq		= cats_map_irq,
+	.nr_controllers		= 1,
+	.setup			= dc21285_setup,
+	.scan			= dc21285_scan_bus,
+	.preinit		= dc21285_preinit,
+	.postinit		= dc21285_postinit,
 };
 
 static int cats_pci_init(void)
diff -Nru a/arch/arm/mach-footbridge/dma.c b/arch/arm/mach-footbridge/dma.c
--- a/arch/arm/mach-footbridge/dma.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-footbridge/dma.c	Sat Aug 10 18:42:22 2002
@@ -35,10 +35,10 @@
 }
 
 static struct dma_ops fb_dma_ops = {
-	type:		"fb",
-	request:	fb_dma_request,
-	enable:		fb_dma_enable,
-	disable:	fb_dma_disable,
+	.type		= "fb",
+	.request	= fb_dma_request,
+	.enable		= fb_dma_enable,
+	.disable	= fb_dma_disable,
 };
 #endif
 
diff -Nru a/arch/arm/mach-footbridge/ebsa285-pci.c b/arch/arm/mach-footbridge/ebsa285-pci.c
--- a/arch/arm/mach-footbridge/ebsa285-pci.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-footbridge/ebsa285-pci.c	Sat Aug 10 18:42:23 2002
@@ -29,13 +29,13 @@
 }
 
 static struct hw_pci ebsa285_pci __initdata = {
-	swizzle:		pci_std_swizzle,
-	map_irq:		ebsa285_map_irq,
-	nr_controllers:		1,
-	setup:			dc21285_setup,
-	scan:			dc21285_scan_bus,
-	preinit:		dc21285_preinit,
-	postinit:		dc21285_postinit,
+	.swizzle		= pci_std_swizzle,
+	.map_irq		= ebsa285_map_irq,
+	.nr_controllers		= 1,
+	.setup			= dc21285_setup,
+	.scan			= dc21285_scan_bus,
+	.preinit		= dc21285_preinit,
+	.postinit		= dc21285_postinit,
 };
 
 static int __init ebsa285_init_pci(void)
diff -Nru a/arch/arm/mach-footbridge/irq.c b/arch/arm/mach-footbridge/irq.c
--- a/arch/arm/mach-footbridge/irq.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-footbridge/irq.c	Sat Aug 10 18:42:22 2002
@@ -67,9 +67,9 @@
 }
 
 static struct irqchip fb_chip = {
-	ack:	fb_mask_irq,
-	mask:	fb_mask_irq,
-	unmask:	fb_unmask_irq,
+	.ack	= fb_mask_irq,
+	.mask	= fb_mask_irq,
+	.unmask = fb_unmask_irq,
 };
 
 static void __init __fb_init_irq(void)
diff -Nru a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c
--- a/arch/arm/mach-footbridge/isa-irq.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-footbridge/isa-irq.c	Sat Aug 10 18:42:23 2002
@@ -50,9 +50,9 @@
 }
 
 static struct irqchip isa_lo_chip = {
-	ack:	isa_ack_pic_lo_irq,
-	mask:	isa_mask_pic_lo_irq,
-	unmask:	isa_unmask_pic_lo_irq,
+	.ack	= isa_ack_pic_lo_irq,
+	.mask	= isa_mask_pic_lo_irq,
+	.unmask = isa_unmask_pic_lo_irq,
 };
 
 static void isa_mask_pic_hi_irq(unsigned int irq)
@@ -79,9 +79,9 @@
 }
 
 static struct irqchip isa_hi_chip = {
-	ack:	isa_ack_pic_hi_irq,
-	mask:	isa_mask_pic_hi_irq,
-	unmask:	isa_unmask_pic_hi_irq,
+	.ack	= isa_ack_pic_hi_irq,
+	.mask	= isa_mask_pic_hi_irq,
+	.unmask = isa_unmask_pic_hi_irq,
 };
 
 static void no_action(int irq, void *dev_id, struct pt_regs *regs)
diff -Nru a/arch/arm/mach-footbridge/netwinder-pci.c b/arch/arm/mach-footbridge/netwinder-pci.c
--- a/arch/arm/mach-footbridge/netwinder-pci.c	Sat Aug 10 18:42:20 2002
+++ b/arch/arm/mach-footbridge/netwinder-pci.c	Sat Aug 10 18:42:20 2002
@@ -43,13 +43,13 @@
 }
 
 static struct hw_pci netwinder_pci __initdata = {
-	swizzle:		pci_std_swizzle,
-	map_irq:		netwinder_map_irq,
-	nr_controllers:		1,
-	setup:			dc21285_setup,
-	scan:			dc21285_scan_bus,
-	preinit:		dc21285_preinit,
-	postinit:		dc21285_postinit,
+	.swizzle		= pci_std_swizzle,
+	.map_irq		= netwinder_map_irq,
+	.nr_controllers		= 1,
+	.setup			= dc21285_setup,
+	.scan			= dc21285_scan_bus,
+	.preinit		= dc21285_preinit,
+	.postinit		= dc21285_postinit,
 };
 
 static int __init netwinder_pci_init(void)
diff -Nru a/arch/arm/mach-footbridge/personal-pci.c b/arch/arm/mach-footbridge/personal-pci.c
--- a/arch/arm/mach-footbridge/personal-pci.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-footbridge/personal-pci.c	Sat Aug 10 18:42:22 2002
@@ -38,12 +38,12 @@
 }
 
 static struct hw_pci personal_server_pci __initdata = {
-	map_irq:		personal_server_map_irq,
-	nr_controllers:		1,
-	setup:			dc21285_setup,
-	scan:			dc21285_scan_bus,
-	preinit:		dc21285_preinit,
-	postinit:		dc21285_postinit,
+	.map_irq		= personal_server_map_irq,
+	.nr_controllers		= 1,
+	.setup			= dc21285_setup,
+	.scan			= dc21285_scan_bus,
+	.preinit		= dc21285_preinit,
+	.postinit		= dc21285_postinit,
 };
 
 static int __init personal_pci_init(void)
diff -Nru a/arch/arm/mach-ftvpci/pci.c b/arch/arm/mach-ftvpci/pci.c
--- a/arch/arm/mach-ftvpci/pci.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-ftvpci/pci.c	Sat Aug 10 18:42:23 2002
@@ -45,9 +45,9 @@
 
 /* ftv host-specific stuff */
 static struct hw_pci ftv_pci __initdata = {
-	init:		plx90x0_init,
-	swizzle:	ftv_swizzle,
-	map_irq:	ftv_map_irq,
+	.init		= plx90x0_init,
+	.swizzle	= ftv_swizzle,
+	.map_irq	= ftv_map_irq,
 };
 
 static int __init ftv_pci_init(void)
diff -Nru a/arch/arm/mach-integrator/arch.c b/arch/arm/mach-integrator/arch.c
--- a/arch/arm/mach-integrator/arch.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-integrator/arch.c	Sat Aug 10 18:42:23 2002
@@ -36,17 +36,17 @@
 
 #ifdef CONFIG_KMI_KEYB
 static struct kmi_info integrator_keyboard __initdata = {
-	base:	IO_ADDRESS(KMI0_BASE),
-	irq:	IRQ_KMIINT0,
-	divisor: 24 / 8 - 1,
-	type:	KMI_KEYBOARD,
+	.base		= IO_ADDRESS(KMI0_BASE),
+	.irq		= IRQ_KMIINT0,
+	.divisor	= 24 / 8 - 1,
+	.type		= KMI_KEYBOARD,
 };
 
 static struct kmi_info integrator_mouse __initdata = {
-	base:	IO_ADDRESS(KMI1_BASE),
-	irq:	IRQ_KMIINT1,
-	divisor: 24 / 8 - 1,
-	type:	KMI_MOUSE,
+	.base		= IO_ADDRESS(KMI1_BASE),
+	.irq		= IRQ_KMIINT1,
+	.divisor	= 24 / 8 - 1,
+	.type		= KMI_MOUSE,
 };
 #endif
 
diff -Nru a/arch/arm/mach-integrator/irq.c b/arch/arm/mach-integrator/irq.c
--- a/arch/arm/mach-integrator/irq.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-integrator/irq.c	Sat Aug 10 18:42:23 2002
@@ -48,9 +48,9 @@
 }
 
 static struct irqchip sc_chip = {
-	ack:	sc_mask_irq,
-	mask:	sc_mask_irq,
-	unmask:	sc_unmask_irq,
+	.ack	= sc_mask_irq,
+	.mask	= sc_mask_irq,
+	.unmask = sc_unmask_irq,
 };
  
 void __init integrator_init_irq(void)
diff -Nru a/arch/arm/mach-integrator/pci.c b/arch/arm/mach-integrator/pci.c
--- a/arch/arm/mach-integrator/pci.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-integrator/pci.c	Sat Aug 10 18:42:22 2002
@@ -114,13 +114,13 @@
 extern void pci_v3_init(void *);
 
 static struct hw_pci integrator_pci __initdata = {
-	swizzle:		integrator_swizzle,
-	map_irq:		integrator_map_irq,
-	setup:			pci_v3_setup,
-	nr_controllers:		1,
-	scan:			pci_v3_scan_bus,
-	preinit:		pci_v3_preinit,
-	postinit:		pci_v3_postinit,
+	.swizzle		= integrator_swizzle,
+	.map_irq		= integrator_map_irq,
+	.setup			= pci_v3_setup,
+	.nr_controllers		= 1,
+	.scan			= pci_v3_scan_bus,
+	.preinit		= pci_v3_preinit,
+	.postinit		= pci_v3_postinit,
 };
 
 static int __init integrator_pci_init(void)
diff -Nru a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
--- a/arch/arm/mach-integrator/pci_v3.c	Sat Aug 10 18:42:21 2002
+++ b/arch/arm/mach-integrator/pci_v3.c	Sat Aug 10 18:42:21 2002
@@ -382,26 +382,26 @@
 }
 
 static struct pci_ops pci_v3_ops = {
-	read_byte:	v3_read_config_byte,
-	read_word:	v3_read_config_word,
-	read_dword:	v3_read_config_dword,
-	write_byte:	v3_write_config_byte,
-	write_word:	v3_write_config_word,
-	write_dword:	v3_write_config_dword,
+	.read_byte	= v3_read_config_byte,
+	.read_word	= v3_read_config_word,
+	.read_dword	= v3_read_config_dword,
+	.write_byte	= v3_write_config_byte,
+	.write_word	= v3_write_config_word,
+	.write_dword	= v3_write_config_dword,
 };
 
 static struct resource non_mem = {
-	name:	"PCI non-prefetchable",
-	start:	PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START,
-	end:	PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
-	flags:	IORESOURCE_MEM,
+	.name	= "PCI non-prefetchable",
+	.start	= PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START,
+	.end	= PHYS_PCI_MEM_BASE + PCI_BUS_NONMEM_START + PCI_BUS_NONMEM_SIZE - 1,
+	.flags	= IORESOURCE_MEM,
 };
 
 static struct resource pre_mem = {
-	name:	"PCI prefetchable",
-	start:	PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START,
-	end:	PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
-	flags:	IORESOURCE_MEM | IORESOURCE_PREFETCH,
+	.name	= "PCI prefetchable",
+	.start	= PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START,
+	.end	= PHYS_PCI_MEM_BASE + PCI_BUS_PREMEM_START + PCI_BUS_PREMEM_SIZE - 1,
+	.flags	= IORESOURCE_MEM | IORESOURCE_PREFETCH,
 };
 
 static int __init pci_v3_setup_resources(struct resource **resource)
diff -Nru a/arch/arm/mach-iop310/iop310-irq.c b/arch/arm/mach-iop310/iop310-irq.c
--- a/arch/arm/mach-iop310/iop310-irq.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-iop310/iop310-irq.c	Sat Aug 10 18:42:23 2002
@@ -58,9 +58,9 @@
 }
 
 struct irqchip ext_chip = {
-	ack:	iop310_irq_mask,
-	mask:	iop310_irq_mask,
-	unmask:	iop310_irq_unmask,
+	.ack	= iop310_irq_mask,
+	.mask	= iop310_irq_mask,
+	.unmask = iop310_irq_unmask,
 };
 
 void
diff -Nru a/arch/arm/mach-iop310/iq80310-irq.c b/arch/arm/mach-iop310/iq80310-irq.c
--- a/arch/arm/mach-iop310/iq80310-irq.c	Sat Aug 10 18:42:21 2002
+++ b/arch/arm/mach-iop310/iq80310-irq.c	Sat Aug 10 18:42:21 2002
@@ -41,9 +41,9 @@
 }
 
 static struct irqchip iq80310_irq_chip = {
-	ack:	iq80310_irq_mask,
-	mask:	iq80310_irq_mask,
-	unmask:	iq80310_irq_unmask,
+	.ack	= iq80310_irq_mask,
+	.mask	= iq80310_irq_mask,
+	.unmask = iq80310_irq_unmask,
 };
 
 extern struct irqchip ext_chip;
diff -Nru a/arch/arm/mach-iop310/iq80310-pci.c b/arch/arm/mach-iop310/iq80310-pci.c
--- a/arch/arm/mach-iop310/iq80310-pci.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-iop310/iq80310-pci.c	Sat Aug 10 18:42:22 2002
@@ -147,11 +147,11 @@
 }
 
 static struct hw_pci iq80310_pci __initdata = {
-	swizzle:	pci_std_swizzle,
-	nr_controllers:	2,
-	setup:		iq80310_setup,
-	scan:		iop310_scan_bus,
-	preinit:	iq80310_preinit,
+	.swizzle	= pci_std_swizzle,
+	.nr_controllers = 2,
+	.setup		= iq80310_setup,
+	.scan		= iop310_scan_bus,
+	.preinit	= iq80310_preinit,
 };
 
 static int __init iq80310_pci_init(void)
diff -Nru a/arch/arm/mach-iop310/iq80310-time.c b/arch/arm/mach-iop310/iq80310-time.c
--- a/arch/arm/mach-iop310/iq80310-time.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-iop310/iq80310-time.c	Sat Aug 10 18:42:23 2002
@@ -119,8 +119,8 @@
 extern unsigned long (*gettimeoffset)(void);
 
 static struct irqaction timer_irq = {
-	name:		"timer",
-	handler:	iq80310_timer_interrupt,
+	.name		= "timer",
+	.handler	= iq80310_timer_interrupt,
 };
 
 
diff -Nru a/arch/arm/mach-iop310/xs80200-irq.c b/arch/arm/mach-iop310/xs80200-irq.c
--- a/arch/arm/mach-iop310/xs80200-irq.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-iop310/xs80200-irq.c	Sat Aug 10 18:42:23 2002
@@ -47,9 +47,9 @@
 }
 
 static struct irqchip xs80200_chip = {
-	ack:	xs80200_irq_mask,
-	mask:	xs80200_irq_mask,
-	unmask:	xs80200_irq_unmask,
+	.ack	= xs80200_irq_mask,
+	.mask	= xs80200_irq_mask,
+	.unmask = xs80200_irq_unmask,
 };
 
 void __init xs80200_init_irq(void)
diff -Nru a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
--- a/arch/arm/mach-pxa/Makefile	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-pxa/Makefile	Sat Aug 10 18:42:23 2002
@@ -29,4 +29,7 @@
 
 obj-$(CONFIG_LEDS) += $(leds-y)
 
+# Misc features
+obj-$(CONFIG_PM) += pm.o sleep.o
+
 include $(TOPDIR)/Rules.make
diff -Nru a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
--- a/arch/arm/mach-pxa/generic.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-pxa/generic.c	Sat Aug 10 18:42:22 2002
@@ -91,9 +91,10 @@
  /* virtual     physical    length      type */
   { 0xf6000000, 0x20000000, 0x01000000, MT_DEVICE }, /* PCMCIA0 IO */
   { 0xf7000000, 0x30000000, 0x01000000, MT_DEVICE }, /* PCMCIA1 IO */
-  { 0xfc000000, 0x40000000, 0x01400000, MT_DEVICE }, /* Devs */
-  { 0xfe000000, 0x44000000, 0x00200000, MT_DEVICE }, /* LCD */
-  { 0xff000000, 0x48000000, 0x00200000, MT_DEVICE }  /* Mem Ctl */
+  { 0xf8000000, 0x40000000, 0x01400000, MT_DEVICE }, /* Devs */
+  { 0xfa000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */
+  { 0xfc000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */
+  { 0xff000000, 0x00000000, 0x00100000, MT_DEVICE }  /* UNCACHED_PHYS_0 */
 };
 
 void __init pxa_map_io(void)
diff -Nru a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
--- a/arch/arm/mach-pxa/irq.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-pxa/irq.c	Sat Aug 10 18:42:22 2002
@@ -40,9 +40,9 @@
 }
 
 static struct irqchip pxa_internal_chip = {
-	ack:		pxa_mask_irq,
-	mask:		pxa_mask_irq,
-	unmask:		pxa_unmask_irq,
+	.ack		= pxa_mask_irq,
+	.mask		= pxa_mask_irq,
+	.unmask		= pxa_unmask_irq,
 };
 
 /*
@@ -109,11 +109,11 @@
 }
 
 static struct irqchip pxa_low_gpio_chip = {
-	ack:		pxa_ack_low_gpio,
-	mask:           pxa_mask_irq,
-	unmask:         pxa_unmask_irq,
-	rerun:          pxa_manual_rerun,
-	type:           pxa_gpio_irq_type,
+	.ack		= pxa_ack_low_gpio,
+	.mask		= pxa_mask_irq,
+	.unmask		= pxa_unmask_irq,
+	.rerun		= pxa_manual_rerun,
+	.type		= pxa_gpio_irq_type,
 };
 
 /*
@@ -201,11 +201,11 @@
 }
 
 static struct irqchip pxa_muxed_gpio_chip = {
-	ack:		pxa_ack_muxed_gpio,
-	mask:		pxa_mask_muxed_gpio,
-	unmask:		pxa_unmask_muxed_gpio,
-	rerun:		pxa_manual_rerun,
-	type:		pxa_gpio_irq_type,
+	.ack		= pxa_ack_muxed_gpio,
+	.mask		= pxa_mask_muxed_gpio,
+	.unmask		= pxa_unmask_muxed_gpio,
+	.rerun		= pxa_manual_rerun,
+	.type		= pxa_gpio_irq_type,
 };
 
 
diff -Nru a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
--- a/arch/arm/mach-pxa/lubbock.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-pxa/lubbock.c	Sat Aug 10 18:42:22 2002
@@ -54,9 +54,9 @@
 }
 
 static struct irqchip lubbock_irq_chip = {
-	ack:		lubbock_ack_irq,
-	mask:		lubbock_mask_irq,
-	unmask:		lubbock_unmask_irq,
+	.ack		= lubbock_ack_irq,
+	.mask		= lubbock_mask_irq,
+	.unmask		= lubbock_unmask_irq,
 };
 
 void lubbock_irq_handler(unsigned int irq, struct irqdesc *desc,
@@ -142,11 +142,20 @@
 
 	/* This is for the SMC chip select */
 	pxa_gpio_mode(GPIO79_nCS_3_MD);
+
+	/* setup sleep mode values */
+	PWER  = 0x00000002;
+	PFER  = 0x00000000;
+	PRER  = 0x00000002;
+	PGSR0 = 0x00008000;
+	PGSR1 = 0x003F0202;
+	PGSR2 = 0x0001C000;
+	PCFR |= PCFR_OPDE;
 }
 
 MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform")
 	MAINTAINER("MontaVista Software Inc.")
-	BOOT_MEM(0xa0000000, 0x40000000, 0xfc000000)
+	BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
 	MAPIO(lubbock_map_io)
 	INITIRQ(lubbock_init_irq)
 MACHINE_END
diff -Nru a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/mach-pxa/pm.c	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,265 @@
+/*
+ * PXA250/210 Power Management Routines
+ *
+ * Original code for the SA11x0:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * Modified for the PXA250 by Nicolas Pitre:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/sysctl.h>
+#include <linux/errno.h>
+
+#include <asm/hardware.h>
+#include <asm/memory.h>
+#include <asm/system.h>
+#include <asm/leds.h>
+
+
+/*
+ * Debug macros
+ */
+#undef DEBUG
+
+extern void pxa_cpu_suspend(void);
+extern void pxa_cpu_resume(void);
+
+#define SAVE(x)		sleep_save[SLEEP_SAVE_##x] = x
+#define RESTORE(x)	x = sleep_save[SLEEP_SAVE_##x]
+
+/*
+ * List of global PXA peripheral registers to preserve.
+ * More ones like CP and general purpose register values are preserved
+ * with the stack pointer in sleep.S.
+ */
+enum {	SLEEP_SAVE_START = 0,
+
+	SLEEP_SAVE_OSCR, SLEEP_SAVE_OIER,
+	SLEEP_SAVE_OSMR0, SLEEP_SAVE_OSMR1, SLEEP_SAVE_OSMR2, SLEEP_SAVE_OSMR3,
+
+	SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2,
+	SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2,
+	SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2,
+	SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR2_L,
+	SLEEP_SAVE_GAFR0_U, SLEEP_SAVE_GAFR1_U, SLEEP_SAVE_GAFR2_U,
+
+	SLEEP_SAVE_FFIER, SLEEP_SAVE_FFLCR, SLEEP_SAVE_FFMCR,
+	SLEEP_SAVE_FFSPR, SLEEP_SAVE_FFISR,
+	SLEEP_SAVE_FFDLL, SLEEP_SAVE_FFDLH,
+
+	SLEEP_SAVE_ICMR,
+	SLEEP_SAVE_CKEN,
+
+	SLEEP_SAVE_CKSUM,
+
+	SLEEP_SAVE_SIZE
+};
+
+
+int pm_do_suspend(void)
+{
+	unsigned long sleep_save[SLEEP_SAVE_SIZE];
+	unsigned long checksum = 0;
+	int i;
+
+	cli();
+	clf();
+
+	leds_event(led_stop);
+
+	/* preserve current time */
+	RCNR = xtime.tv_sec;
+
+	/*
+	 * Temporary solution.  This won't be necessary once
+	 * we move pxa support into the serial/* driver
+	 * Save the FF UART
+	 */
+	SAVE(FFIER);
+	SAVE(FFLCR);
+	SAVE(FFMCR);
+	SAVE(FFSPR);
+	SAVE(FFISR);
+	FFLCR |= 0x80;
+	SAVE(FFDLL);
+	SAVE(FFDLH);
+	FFLCR &= 0xef;
+
+	/* save vital registers */
+	SAVE(OSCR);
+	SAVE(OSMR0);
+	SAVE(OSMR1);
+	SAVE(OSMR2);
+	SAVE(OSMR3);
+	SAVE(OIER);
+
+	SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
+	SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
+	SAVE(GFER0); SAVE(GFER1); SAVE(GFER2);
+	SAVE(GAFR0_L); SAVE(GAFR0_U);
+	SAVE(GAFR1_L); SAVE(GAFR1_U);
+	SAVE(GAFR2_L); SAVE(GAFR2_U);
+
+	SAVE(ICMR);
+	ICMR = 0;
+
+	SAVE(CKEN);
+	CKEN = 0;
+
+	/* Note: wake up source are set up in each machine specific files */
+
+	/* clear GPIO transition detect  bits */
+	GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2;
+
+	/* Clear sleep reset status */
+	RCSR = RCSR_SMR;
+
+	/* set resume return address */
+	PSPR = virt_to_phys(pxa_cpu_resume);
+
+	/* before sleeping, calculate and save a checksum */
+	for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
+		checksum += sleep_save[i];
+	sleep_save[SLEEP_SAVE_CKSUM] = checksum;
+
+	/* *** go zzz *** */
+	pxa_cpu_suspend();
+
+	/* after sleeping, validate the checksum */
+	checksum = 0;
+	for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
+		checksum += sleep_save[i];
+
+	/* if invalid, display message and wait for a hardware reset */
+	if (checksum != sleep_save[SLEEP_SAVE_CKSUM]) {
+#ifdef CONFIG_ARCH_LUBBOCK
+		LUB_HEXLED = 0xbadbadc5;
+#endif
+		while (1);
+	}
+
+	/* ensure not to come back here if it wasn't intended */
+	PSPR = 0;
+
+	/* restore registers */
+	RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
+	RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2);
+	RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2);
+	RESTORE(GAFR0_L); RESTORE(GAFR0_U);
+	RESTORE(GAFR1_L); RESTORE(GAFR1_U);
+	RESTORE(GAFR2_L); RESTORE(GAFR2_U);
+
+	PSSR = PSSR_PH;
+
+	RESTORE(OSMR0);
+	RESTORE(OSMR1);
+	RESTORE(OSMR2);
+	RESTORE(OSMR3);
+	RESTORE(OSCR);
+	RESTORE(OIER);
+
+	RESTORE(CKEN);
+
+	ICLR = 0;
+	ICCR = 1;
+	RESTORE(ICMR);
+
+	/*
+	 * Temporary solution.  This won't be necessary once
+	 * we move pxa support into the serial/* driver.
+	 * Restore the FF UART.
+	 */
+	RESTORE(FFMCR);
+	RESTORE(FFSPR);
+	RESTORE(FFLCR);
+	FFLCR |= 0x80;
+	RESTORE(FFDLH);
+	RESTORE(FFDLL);
+	RESTORE(FFLCR);
+	RESTORE(FFISR);
+	FFFCR = 0x07;
+	RESTORE(FFIER);
+
+	/* restore current time */
+	xtime.tv_sec = RCNR;
+
+#ifdef DEBUG
+	printk(KERN_DEBUG "*** made it back from resume\n");
+#endif
+
+	leds_event(led_start);
+
+	sti();
+
+	return 0;
+}
+
+unsigned long sleep_phys_sp(void *sp)
+{
+	return virt_to_phys(sp);
+}
+
+#ifdef CONFIG_SYSCTL
+/*
+ * ARGH!  ACPI people defined CTL_ACPI in linux/acpi.h rather than
+ * linux/sysctl.h.
+ *
+ * This means our interface here won't survive long - it needs a new
+ * interface.  Quick hack to get this working - use sysctl id 9999.
+ */
+#warning ACPI broke the kernel, this interface needs to be fixed up.
+#define CTL_ACPI 9999
+#define ACPI_S1_SLP_TYP 19
+
+/*
+ * Send us to sleep.
+ */
+static int sysctl_pm_do_suspend(void)
+{
+	int retval;
+
+	retval = pm_send_all(PM_SUSPEND, (void *)3);
+
+	if (retval == 0) {
+		retval = pm_do_suspend();
+
+		pm_send_all(PM_RESUME, (void *)0);
+	}
+
+	return retval;
+}
+
+static struct ctl_table pm_table[] =
+{
+	{ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, (proc_handler *)&sysctl_pm_do_suspend},
+	{0}
+};
+
+static struct ctl_table pm_dir_table[] =
+{
+	{CTL_ACPI, "pm", NULL, 0, 0555, pm_table},
+	{0}
+};
+
+/*
+ * Initialize power interface
+ */
+static int __init pm_init(void)
+{
+	register_sysctl_table(pm_dir_table, 1);
+	return 0;
+}
+
+__initcall(pm_init);
+
+#endif
diff -Nru a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/mach-pxa/sleep.S	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,150 @@
+/*
+ * Low-level PXA250/210 sleep/wakeUp support
+ *
+ * Initial SA1110 code:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * Adapted for PXA by Nicolas Pitre:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ */
+
+#include <linux/config.h>
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/hardware.h>
+
+		.text
+
+/*
+ * pxa_cpu_suspend()
+ *
+ * Forces CPU into sleep state
+ */
+
+ENTRY(pxa_cpu_suspend)
+
+	mra	r2, r3, acc0
+	stmfd	sp!, {r2 - r12, lr}		@ save registers on stack
+
+	@ get coprocessor registers
+	mrc	p15, 0, r4, c15, c1, 0		@ CP access reg
+	mrc	p15, 0, r5, c13, c0, 0		@ PID
+	mrc 	p15, 0, r6, c3, c0, 0		@ domain ID
+	mrc 	p15, 0, r7, c2, c0, 0		@ translation table base addr
+	mrc	p15, 0, r8, c1, c1, 0           @ auxiliary control reg
+	mrc 	p15, 0, r9, c1, c0, 0		@ control reg
+
+	@ store them plus current virtual stack ptr on stack
+	mov	r10, sp
+	stmfd	sp!, {r4 - r10}
+
+	@ preserve phys address of stack
+	mov	r0, sp
+	bl	sleep_phys_sp
+	ldr	r1, =sleep_save_sp
+	str	r0, [r1]
+
+	@ clean data cache
+	bl	cpu_xscale_cache_clean_invalidate_all
+
+	@ Put the processor to sleep
+	@ (also workaround for sighting 28071)
+
+	@ prepare value for sleep mode
+	mov	r1, #3				@ sleep mode
+
+	@ prepare to put SDRAM into self-refresh manually
+	ldr	r4, =MDREFR
+	ldr	r5, [r4]
+	orr	r5, r5, #MDREFR_SLFRSH
+
+	@ prepare pointer to physical address 0 (virtual mapping in generic.c)
+	mov	r2, #UNCACHED_PHYS_0
+
+	@ align execution to a cache line
+	b	1f
+
+	.ltorg
+	.align	5
+1:
+
+	@ All needed values are now in registers.
+	@ These last instructions should be in cache
+
+	@ put SDRAM into self-refresh
+	str	r5, [r4]
+
+	@ force address lines low by reading at physical address 0
+	ldr	r3, [r2]
+
+	@ enter sleep mode
+	mcr	p14, 0, r1, c7, c0, 0
+
+20:	nop
+	b	20b				@ loop waiting for sleep
+
+/*
+ * cpu_pxa_resume()
+ *
+ * entry point from bootloader into kernel during resume
+ *
+ * Note: Yes, part of the following code is located into the .data section.
+ *       This is to allow sleep_save_sp to be accessed with a relative load
+ *       while we can't rely on any MMU translation.  We could have put
+ *       sleep_save_sp in the .text section as well, but some setups might
+ *       insist on it to be truely read-only.
+ */
+
+	.data
+	.align 5
+ENTRY(pxa_cpu_resume)
+	mov	r0, #I_BIT | F_BIT | MODE_SVC	@ set SVC, irqs off
+	msr	cpsr_c, r0
+
+	ldr	r0, sleep_save_sp		@ stack phys addr
+	ldr	r2, =resume_after_mmu		@ its absolute virtual address
+	ldmfd	r0, {r4 - r9, sp}		@ CP regs + virt stack ptr
+
+	mov	r1, #0
+	mcr	p15, 0, r1, c8, c7, 0   	@ invalidate I & D TLBs
+	mcr	p15, 0, r1, c7, c7, 0		@ invalidate I & D caches, BTB
+
+#ifdef CONFIG_XSCALE_CACHE_ERRATA
+	bic     r9, r9, #0x0004			@ see cpu_xscale_proc_init
+#endif
+
+	mcr	p15, 0, r4, c15, c1, 0		@ CP access reg
+	mcr	p15, 0, r5, c13, c0, 0		@ PID
+	mcr 	p15, 0, r6, c3, c0, 0		@ domain ID
+	mcr 	p15, 0, r7, c2, c0, 0		@ translation table base addr
+	mcr	p15, 0, r8, c1, c1, 0           @ auxiliary control reg
+	b	resume_turn_on_mmu		@ cache align execution
+
+	.align 5
+resume_turn_on_mmu:
+	mcr 	p15, 0, r9, c1, c0, 0		@ turn on MMU, caches, etc.
+
+	@ Let us ensure we jump to resume_after_mmu only when the mcr above
+	@ actually took effect.  They call it the "cpwait" operation.
+	mrc	p15, 0, r1, c2, c0, 0		@ queue a dependency on CP15
+	sub	pc, r2, r1, lsr #32		@ jump to virtual addr
+	nop
+	nop
+	nop
+
+sleep_save_sp:
+	.word	0				@ preserve stack phys ptr here
+
+	.text
+resume_after_mmu:
+#ifdef CONFIG_XSCALE_CACHE_ERRATA
+	bl	cpu_xscale_proc_init
+#endif
+	ldmfd	sp!, {r2, r3}
+	mar	acc0, r2, r3
+	ldmfd	sp!, {r4 - r12, pc}		@ return to caller
+
+
diff -Nru a/arch/arm/mach-rpc/dma.c b/arch/arm/mach-rpc/dma.c
--- a/arch/arm/mach-rpc/dma.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-rpc/dma.c	Sat Aug 10 18:42:22 2002
@@ -216,16 +216,16 @@
 }
 
 static struct dma_ops iomd_dma_ops = {
-	type:		"IOMD",
-	request:	iomd_request_dma,
-	free:		iomd_free_dma,
-	enable:		iomd_enable_dma,
-	disable:	iomd_disable_dma,
-	setspeed:	iomd_set_dma_speed,
+	.type		= "IOMD",
+	.request	= iomd_request_dma,
+	.free		= iomd_free_dma,
+	.enable		= iomd_enable_dma,
+	.disable	= iomd_disable_dma,
+	.setspeed	= iomd_set_dma_speed,
 };
 
 static struct fiq_handler fh = {
-	name: "floppydma"
+	.name	= "floppydma"
 };
 
 static void floppy_enable_dma(dmach_t channel, dma_t *dma)
@@ -275,10 +275,10 @@
 }
 
 static struct dma_ops floppy_dma_ops = {
-	type:		"FIQDMA",
-	enable:		floppy_enable_dma,
-	disable:	floppy_disable_dma,
-	residue:	floppy_get_residue,
+	.type		= "FIQDMA",
+	.enable		= floppy_enable_dma,
+	.disable	= floppy_disable_dma,
+	.residue	= floppy_get_residue,
 };
 
 /*
@@ -289,9 +289,9 @@
 }
 
 static struct dma_ops sound_dma_ops = {
-	type:		"VIRTUAL",
-	enable:		sound_enable_disable_dma,
-	disable:	sound_enable_disable_dma,
+	.type		= "VIRTUAL",
+	.enable		= sound_enable_disable_dma,
+	.disable	= sound_enable_disable_dma,
 };
 
 void __init arch_dma_init(dma_t *dma)
diff -Nru a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
--- a/arch/arm/mach-rpc/irq.c	Sat Aug 10 18:42:21 2002
+++ b/arch/arm/mach-rpc/irq.c	Sat Aug 10 18:42:21 2002
@@ -34,9 +34,9 @@
 }
 
 static struct irqchip iomd_a_chip = {
-	ack:	iomd_ack_irq_a,
-	mask:	iomd_mask_irq_a,
-	unmask:	iomd_unmask_irq_a,
+	.ack	= iomd_ack_irq_a,
+	.mask	= iomd_mask_irq_a,
+	.unmask = iomd_unmask_irq_a,
 };
 
 static void iomd_mask_irq_b(unsigned int irq)
@@ -58,9 +58,9 @@
 }
 
 static struct irqchip iomd_b_chip = {
-	ack:	iomd_mask_irq_b,
-	mask:	iomd_mask_irq_b,
-	unmask:	iomd_unmask_irq_b,
+	.ack	= iomd_mask_irq_b,
+	.mask	= iomd_mask_irq_b,
+	.unmask = iomd_unmask_irq_b,
 };
 
 static void iomd_mask_irq_dma(unsigned int irq)
@@ -82,9 +82,9 @@
 }
 
 static struct irqchip iomd_dma_chip = {
-	ack:	iomd_mask_irq_dma,
-	mask:	iomd_mask_irq_dma,
-	unmask:	iomd_unmask_irq_dma,
+	.ack	= iomd_mask_irq_dma,
+	.mask	= iomd_mask_irq_dma,
+	.unmask = iomd_unmask_irq_dma,
 };
 
 static void iomd_mask_irq_fiq(unsigned int irq)
@@ -106,9 +106,9 @@
 }
 
 static struct irqchip iomd_fiq_chip = {
-	ack:	iomd_mask_irq_fiq,
-	mask:	iomd_mask_irq_fiq,
-	unmask:	iomd_unmask_irq_fiq,
+	.ack	= iomd_mask_irq_fiq,
+	.mask	= iomd_mask_irq_fiq,
+	.unmask = iomd_unmask_irq_fiq,
 };
 
 void __init rpc_init_irq(void)
diff -Nru a/arch/arm/mach-sa1100/adsbitsy.c b/arch/arm/mach-sa1100/adsbitsy.c
--- a/arch/arm/mach-sa1100/adsbitsy.c	Sat Aug 10 18:42:20 2002
+++ b/arch/arm/mach-sa1100/adsbitsy.c	Sat Aug 10 18:42:20 2002
@@ -100,7 +100,7 @@
 }
 
 static struct sa1100_port_fns adsbitsy_port_fns __initdata = {
-	open:	adsbitsy_uart_open,
+	.open	= adsbitsy_uart_open,
 };
 
 static void __init adsbitsy_map_io(void)
diff -Nru a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
--- a/arch/arm/mach-sa1100/assabet.c	Sat Aug 10 18:42:20 2002
+++ b/arch/arm/mach-sa1100/assabet.c	Sat Aug 10 18:42:20 2002
@@ -254,9 +254,9 @@
 }
 
 static struct sa1100_port_fns assabet_port_fns __initdata = {
-	set_mctrl:	assabet_set_mctrl,
-	get_mctrl:	assabet_get_mctrl,
-	pm:		assabet_uart_pm,
+	.set_mctrl	= assabet_set_mctrl,
+	.get_mctrl	= assabet_get_mctrl,
+	.pm		= assabet_uart_pm,
 };
 
 static struct map_desc assabet_io_desc[] __initdata = {
diff -Nru a/arch/arm/mach-sa1100/cpu-sa1100.c b/arch/arm/mach-sa1100/cpu-sa1100.c
--- a/arch/arm/mach-sa1100/cpu-sa1100.c	Sat Aug 10 18:42:21 2002
+++ b/arch/arm/mach-sa1100/cpu-sa1100.c	Sat Aug 10 18:42:21 2002
@@ -216,7 +216,7 @@
 
 
 static struct notifier_block sa1100_dram_block = {
-	notifier_call: sa1100_dram_notifier,
+	.notifier_call	= sa1100_dram_notifier,
 };
 
 
diff -Nru a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c
--- a/arch/arm/mach-sa1100/cpu-sa1110.c	Sat Aug 10 18:42:20 2002
+++ b/arch/arm/mach-sa1100/cpu-sa1110.c	Sat Aug 10 18:42:20 2002
@@ -51,53 +51,53 @@
 };
 
 static struct sdram_params tc59sm716_cl2_params __initdata = {
-	rows:		    12,
-	tck:		    10,
-	trcd:		    20,
-	trp:		    20,
-	twr:		    10,
-	refresh:	 64000,
-	cas_latency:	     2,
+	.rows			= 12,
+	.tck			= 10,
+	.trcd			= 20,
+	.trp			= 20,
+	.twr			= 10,
+	.refresh		= 64000,
+	.cas_latency		= 2,
 };
 
 static struct sdram_params tc59sm716_cl3_params __initdata = {
-	rows:		    12,
-	tck:		     8,
-	trcd:		    20,
-	trp:		    20,
-	twr:		     8,
-	refresh:	 64000,
-	cas_latency:	     3,
+	.rows			= 12,
+	.tck			= 8,
+	.trcd			= 20,
+	.trp			= 20,
+	.twr			= 8,
+	.refresh		= 64000,
+	.cas_latency		= 3,
 };
 
 static struct sdram_params samsung_k4s641632d_tc75 __initdata = {
-	rows:		    14,
-	tck:		     9,
-	trcd:		    27,
-	trp:		    20,
-	twr:		     9,
-	refresh:	 64000,
-	cas_latency:	     3,
+	.rows			= 14,
+	.tck			= 9,
+	.trcd			= 27,
+	.trp			= 20,
+	.twr			= 9,
+	.refresh		= 64000,
+	.cas_latency		= 3,
 };
 
 static struct sdram_params samsung_km416s4030ct __initdata = {
-	rows:		    13,
-	tck:		     8,
-	trcd:		    24,	/* 3 CLKs */
-	trp:		    24,	/* 3 CLKs */
-	twr:		    16,	/* Trdl: 2 CLKs */
-	refresh:	 64000,
-	cas_latency:	     3,
+	.rows			= 13,
+	.tck			= 8,
+	.trcd			= 24,	/* 3 CLKs */
+	.trp			= 24,	/* 3 CLKs */
+	.twr			= 16,	/* Trdl: 2 CLKs */
+	.refresh		= 64000,
+	.cas_latency		= 3,
 };
 
 static struct sdram_params wbond_w982516ah75l_cl3_params __initdata = {
-	rows:		    16,
-	tck:		     8,
-	trcd:		    20,
-	trp:		    20,
-	twr:		     8,
-	refresh:	 64000,
-	cas_latency:	     3,
+	.rows			= 16,
+	.tck			= 8,
+	.trcd			= 20,
+	.trp			= 20,
+	.twr			= 8,
+	.refresh		= 64000,
+	.cas_latency		= 3,
 };
 
 static struct sdram_params sdram_params;
diff -Nru a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
--- a/arch/arm/mach-sa1100/generic.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-sa1100/generic.c	Sat Aug 10 18:42:22 2002
@@ -84,7 +84,7 @@
 /*
  * We still need to provide this so building without cpufreq works.
  */ 
-unsigned int cpufreq_get(int cpu)
+unsigned int cpufreq_get(unsigned int cpu)
 {
 	return cclk_frequency_100khz[PPCR & 0xf] * 100;
 }
diff -Nru a/arch/arm/mach-sa1100/graphicsclient.c b/arch/arm/mach-sa1100/graphicsclient.c
--- a/arch/arm/mach-sa1100/graphicsclient.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-sa1100/graphicsclient.c	Sat Aug 10 18:42:23 2002
@@ -67,9 +67,9 @@
 }
 
 static struct irqchip gc_irq1_chip = {
-	ack:	gc_mask_irq1,
-	mask:	gc_mask_irq1,
-	unmask:	gc_unmask_irq1,
+	.ack	= gc_mask_irq1,
+	.mask	= gc_mask_irq1,
+	.unmask = gc_unmask_irq1,
 };
 
 static void gc_mask_irq2(unsigned int irq)
@@ -85,9 +85,9 @@
 }
 
 static struct irqchip gc_irq2_chip = {
-	ack:	gc_mask_irq2,
-	mask:	gc_mask_irq2,
-	unmask:	gc_unmask_irq2,
+	.ack	= gc_mask_irq2,
+	.mask	= gc_mask_irq2,
+	.unmask = gc_unmask_irq2,
 };
 
 static void __init graphicsclient_init_irq(void)
@@ -178,9 +178,9 @@
 }
 
 static struct sa1100_port_fns graphicsclient_port_fns __initdata = {
-	get_mctrl:	graphicsclient_get_mctrl,
-	set_mctrl:	graphicsclient_set_mctrl,
-	pm:		graphicsclient_uart_pm,
+	.get_mctrl	= graphicsclient_get_mctrl,
+	.set_mctrl	= graphicsclient_set_mctrl,
+	.pm		= graphicsclient_uart_pm,
 };
 
 static void __init graphicsclient_map_io(void)
diff -Nru a/arch/arm/mach-sa1100/graphicsmaster.c b/arch/arm/mach-sa1100/graphicsmaster.c
--- a/arch/arm/mach-sa1100/graphicsmaster.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-sa1100/graphicsmaster.c	Sat Aug 10 18:42:22 2002
@@ -100,9 +100,9 @@
 }
 
 static struct irqchip gm_irq1_chip = {
-	ack:	gm_mask_irq1,
-	mask:	gm_mask_irq1,
-	unmask:	gm_unmask_irq1,
+	.ack	= gm_mask_irq1,
+	.mask	= gm_mask_irq1,
+	.unmask = gm_unmask_irq1,
 };
 
 static void gm_mask_irq2(unsigned int irq)
@@ -118,9 +118,9 @@
 }
 
 static struct irqchip gm_irq2_chip = {
-	ack:	gm_mask_irq2,
-	mask:	gm_mask_irq2,
-	unmask:	gm_unmask_irq2,
+	.ack	= gm_mask_irq2,
+	.mask	= gm_mask_irq2,
+	.unmask = gm_unmask_irq2,
 };
 
 static void __init graphicsmaster_init_irq(void)
@@ -236,9 +236,9 @@
 }
 
 static struct sa1100_port_fns graphicsmaster_port_fns __initdata = {
-	get_mctrl:	graphicsmaster_get_mctrl,
-	set_mctrl:	graphicsmaster_set_mctrl,
-	pm:		graphicsmaster_uart_pm,
+	.get_mctrl	= graphicsmaster_get_mctrl,
+	.set_mctrl	= graphicsmaster_set_mctrl,
+	.pm		= graphicsmaster_uart_pm,
 };
 
 static void __init graphicsmaster_map_io(void)
diff -Nru a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
--- a/arch/arm/mach-sa1100/h3600.c	Sat Aug 10 18:42:21 2002
+++ b/arch/arm/mach-sa1100/h3600.c	Sat Aug 10 18:42:21 2002
@@ -428,10 +428,10 @@
 }
 
 static struct sa1100_port_fns h3600_port_fns __initdata = {
-	set_mctrl:	h3600_uart_set_mctrl,
-	get_mctrl:	h3600_uart_get_mctrl,
-	pm:		h3600_uart_pm,
-	set_wake:	h3600_uart_set_wake,
+	.set_mctrl	= h3600_uart_set_mctrl,
+	.get_mctrl	= h3600_uart_get_mctrl,
+	.pm		= h3600_uart_pm,
+	.set_wake	= h3600_uart_set_wake,
 };
 
 static struct map_desc h3600_io_desc[] __initdata = {
diff -Nru a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
--- a/arch/arm/mach-sa1100/irq.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-sa1100/irq.c	Sat Aug 10 18:42:23 2002
@@ -95,11 +95,11 @@
 }
 
 static struct irqchip sa1100_low_gpio_chip = {
-	ack:		sa1100_low_gpio_ack,
-	mask:		sa1100_low_gpio_mask,
-	unmask:		sa1100_low_gpio_unmask,
-	rerun:		sa1100_manual_rerun,
-	type:		sa1100_gpio_type,
+	.ack		= sa1100_low_gpio_ack,
+	.mask		= sa1100_low_gpio_mask,
+	.unmask		= sa1100_low_gpio_unmask,
+	.rerun		= sa1100_manual_rerun,
+	.type		= sa1100_gpio_type,
 };
 
 /*
@@ -169,11 +169,11 @@
 }
 
 static struct irqchip sa1100_high_gpio_chip = {
-	ack:		sa1100_high_gpio_ack,
-	mask:		sa1100_high_gpio_mask,
-	unmask:		sa1100_high_gpio_unmask,
-	rerun:		sa1100_manual_rerun,
-	type:		sa1100_gpio_type,
+	.ack		= sa1100_high_gpio_ack,
+	.mask		= sa1100_high_gpio_mask,
+	.unmask		= sa1100_high_gpio_unmask,
+	.rerun		= sa1100_manual_rerun,
+	.type		= sa1100_gpio_type,
 };
 
 /*
@@ -191,16 +191,16 @@
 }
 
 static struct irqchip sa1100_normal_chip = {
-	ack:		sa1100_mask_irq,
-	mask:		sa1100_mask_irq,
-	unmask:		sa1100_unmask_irq,
+	.ack		= sa1100_mask_irq,
+	.mask		= sa1100_mask_irq,
+	.unmask		= sa1100_unmask_irq,
 	/* rerun should never be called */
 };
 
 static struct resource irq_resource = {
-	name:	"irqs",
-	start:	0x90050000,
-	end:	0x9005ffff,
+	.name	= "irqs",
+	.start	= 0x90050000,
+	.end	= 0x9005ffff,
 };
 
 void __init sa1100_init_irq(void)
diff -Nru a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
--- a/arch/arm/mach-sa1100/neponset.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-sa1100/neponset.c	Sat Aug 10 18:42:22 2002
@@ -26,8 +26,8 @@
 #include "sa1111.h"
 
 static struct device neponset_device = {
-	name:	"Neponset",
-	bus_id:	"nep_bus",
+	.name	= "Neponset",
+	.bus_id	= "nep_bus",
 };
 
 /*
@@ -159,8 +159,8 @@
 }
 
 static struct sa1100_port_fns neponset_port_fns __initdata = {
-	set_mctrl:	neponset_set_mctrl,
-	get_mctrl:	neponset_get_mctrl,
+	.set_mctrl	= neponset_set_mctrl,
+	.get_mctrl	= neponset_get_mctrl,
 };
 
 static int __init neponset_init(void)
diff -Nru a/arch/arm/mach-sa1100/sa1111.c b/arch/arm/mach-sa1100/sa1111.c
--- a/arch/arm/mach-sa1100/sa1111.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-sa1100/sa1111.c	Sat Aug 10 18:42:22 2002
@@ -133,11 +133,11 @@
 }
 
 static struct irqchip sa1111_low_chip = {
-	ack:		sa1111_ack_lowirq,
-	mask:		sa1111_mask_lowirq,
-	unmask:		sa1111_unmask_lowirq,
-	rerun:		sa1111_rerun_lowirq,
-	type:		sa1111_type_lowirq,
+	.ack		= sa1111_ack_lowirq,
+	.mask		= sa1111_mask_lowirq,
+	.unmask		= sa1111_unmask_lowirq,
+	.rerun		= sa1111_rerun_lowirq,
+	.type		= sa1111_type_lowirq,
 };
 
 static void sa1111_ack_highirq(unsigned int irq)
@@ -198,11 +198,11 @@
 }
 
 static struct irqchip sa1111_high_chip = {
-	ack:		sa1111_ack_highirq,
-	mask:		sa1111_mask_highirq,
-	unmask:		sa1111_unmask_highirq,
-	rerun:		sa1111_rerun_highirq,
-	type:		sa1111_type_highirq,
+	.ack		= sa1111_ack_highirq,
+	.mask		= sa1111_mask_highirq,
+	.unmask		= sa1111_unmask_highirq,
+	.rerun		= sa1111_rerun_highirq,
+	.type		= sa1111_type_highirq,
 };
 
 static void __init sa1111_init_irq(int irq_nr)
@@ -257,8 +257,8 @@
 }
 
 static struct device_driver sa1111_device_driver = {
-	suspend:	sa1111_suspend,
-	resume:		sa1111_resume,
+	.suspend	= sa1111_suspend,
+	.resume		= sa1111_resume,
 };
 
 /**
diff -Nru a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
--- a/arch/arm/mach-sa1100/simpad.c	Sat Aug 10 18:42:21 2002
+++ b/arch/arm/mach-sa1100/simpad.c	Sat Aug 10 18:42:21 2002
@@ -57,7 +57,7 @@
 }
 
 static struct sa1100_port_fns simpad_port_fns __initdata = {
-	pm:	simpad_uart_pm,
+	.pm	= simpad_uart_pm,
 };
 
 static void __init simpad_map_io(void)
diff -Nru a/arch/arm/mach-sa1100/system3.c b/arch/arm/mach-sa1100/system3.c
--- a/arch/arm/mach-sa1100/system3.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-sa1100/system3.c	Sat Aug 10 18:42:23 2002
@@ -100,13 +100,13 @@
 };
 
 static struct sa1100_port_fns system3_port_fns __initdata = {
-	set_mctrl:	system3_set_mctrl,
-	get_mctrl:	system3_get_mctrl,
-	pm:		system3_uart_pm,
+	.set_mctrl	= system3_set_mctrl,
+	.get_mctrl	= system3_get_mctrl,
+	.pm		= system3_uart_pm,
 };
 
 static struct notifier_block system3_clkchg_block = {
-	notifier_call:	sdram_notifier,
+	.notifier_call	= sdram_notifier,
 };
 
 /**********************************************************************
diff -Nru a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c
--- a/arch/arm/mach-shark/irq.c	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mach-shark/irq.c	Sat Aug 10 18:42:23 2002
@@ -69,9 +69,9 @@
 static struct irqaction cascade;
 
 static struct irqchip fb_chip = {
-	ack:	shark_ack_8259A_irq,
-	mask:	shark_disable_8259A_irq,
-	unmask:	shark_enable_8259A_irq,
+	.ack	= shark_ack_8259A_irq,
+	.mask	= shark_disable_8259A_irq,
+	.unmask = shark_enable_8259A_irq,
 };
 
 void __init shark_init_irq(void)
diff -Nru a/arch/arm/mach-shark/pci.c b/arch/arm/mach-shark/pci.c
--- a/arch/arm/mach-shark/pci.c	Sat Aug 10 18:42:22 2002
+++ b/arch/arm/mach-shark/pci.c	Sat Aug 10 18:42:22 2002
@@ -24,12 +24,12 @@
 extern void __init via82c505_preinit(void *sysdata);
 
 static struct hw_pci shark_pci __initdata = {
-	setup:		via82c505_setup,
-	swizzle:       	pci_std_swizzle,
-	map_irq:	shark_map_irq,
-	nr_controllers:	1,
-	scan:		via82c505_scan_bus,
-	preinit:	via82c505_preinit
+	.setup		= via82c505_setup,
+	.swizzle     	= pci_std_swizzle,
+	.map_irq	= shark_map_irq,
+	.nr_controllers = 1,
+	.scan		= via82c505_scan_bus,
+	.preinit	= via82c505_preinit
 };
 
 static int __init shark_pci_init(void)
diff -Nru a/arch/arm/mm/fault.h b/arch/arm/mm/fault.h
--- a/arch/arm/mm/fault.h	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mm/fault.h	Sat Aug 10 18:42:23 2002
@@ -6,3 +6,5 @@
 int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
 
 int do_translation_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
+
+unsigned long search_exception_table(unsigned long addr);
diff -Nru a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
--- a/arch/arm/mm/proc-xscale.S	Sat Aug 10 18:42:23 2002
+++ b/arch/arm/mm/proc-xscale.S	Sat Aug 10 18:42:23 2002
@@ -156,7 +156,7 @@
 	msr	cpsr_c, r1			@ reset CPSR
 	mrc	p15, 0, r1, c1, c0, 0		@ ctrl register
 	bic	r1, r1, #0x0086			@ ........B....CA.
-	bic	r1, r1, #0x1900			@ ...IZ..S........
+	bic	r1, r1, #0x3900			@ ..VIZ..S........
 	mcr	p15, 0, r1, c1, c0, 0		@ ctrl register
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches & BTB
 	bic	r1, r1, #0x0001			@ ...............M
diff -Nru a/arch/i386/config.in b/arch/i386/config.in
--- a/arch/i386/config.in	Sat Aug 10 18:42:22 2002
+++ b/arch/i386/config.in	Sat Aug 10 18:42:22 2002
@@ -9,6 +9,7 @@
 define_bool CONFIG_SBUS n
 
 define_bool CONFIG_UID16 y
+define_bool CONFIG_GENERIC_ISA_DMA y
 
 source init/Config.in
 
diff -Nru a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
--- a/arch/i386/kernel/cpu/intel.c	Sat Aug 10 18:42:22 2002
+++ b/arch/i386/kernel/cpu/intel.c	Sat Aug 10 18:42:22 2002
@@ -232,15 +232,19 @@
 	if (c->x86 == 6) {
 		switch (c->x86_model) {
 		case 5:
-			if (l2 == 0)
-				p = "Celeron (Covington)";
-			if (l2 == 256)
-				p = "Mobile Pentium II (Dixon)";
+			if (c->x86_mask == 0) {
+				if (l2 == 0)
+					p = "Celeron (Covington)";
+				else if (l2 == 256)
+					p = "Mobile Pentium II (Dixon)";
+			}
 			break;
 			
 		case 6:
 			if (l2 == 128)
 				p = "Celeron (Mendocino)";
+			else if (c->x86_mask == 0 || c->x86_mask == 5)
+				p = "Celeron-A";
 			break;
 			
 		case 8:
@@ -348,6 +352,26 @@
 			  [4] "Pentium MMX",
 			  [7] "Mobile Pentium 75 - 200", 
 			  [8] "Mobile Pentium MMX"
+		  }
+		},
+		{ X86_VENDOR_INTEL,     6,
+		  { 
+			  [0] "Pentium Pro A-step",
+			  [1] "Pentium Pro", 
+			  [3] "Pentium II (Klamath)", 
+			  [4] "Pentium II (Deschutes)", 
+			  [5] "Pentium II (Deschutes)", 
+			  [6] "Mobile Pentium II",
+			  [7] "Pentium III (Katmai)", 
+			  [8] "Pentium III (Coppermine)", 
+			  [10] "Pentium III (Cascades)",
+			  [11] "Pentium III (Tualatin)",
+		  }
+		},
+		{ X86_VENDOR_INTEL,     15,
+		  {
+			  [1] "Pentium 4 (Unknown)",
+			  [5] "Pentium 4 (Foster)",
 		  }
 		},
 	},
diff -Nru a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
--- a/arch/i386/kernel/process.c	Sat Aug 10 18:42:18 2002
+++ b/arch/i386/kernel/process.c	Sat Aug 10 18:42:19 2002
@@ -313,11 +313,6 @@
 	memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
 		sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
 
-	/* Make sure the first page is mapped to the start of physical memory.
-	   It is normally not mapped, to trap kernel NULL pointer dereferences. */
-
-	pg0[0] = _PAGE_RW | _PAGE_PRESENT;
-
 	/*
 	 * Use `swapper_pg_dir' as our page directory.
 	 */
diff -Nru a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
--- a/arch/i386/mm/fault.c	Sat Aug 10 18:42:20 2002
+++ b/arch/i386/mm/fault.c	Sat Aug 10 18:42:20 2002
@@ -181,10 +181,10 @@
 	info.si_code = SEGV_MAPERR;
 
 	/*
-	 * If we're in an interrupt or have no user
-	 * context, we must not take the fault..
+	 * If we're in an interrupt, have no user context or are running in an
+	 * atomic region then we must not take the fault..
 	 */
-	if (in_interrupt() || !mm)
+	if (preempt_count() || !mm)
 		goto no_context;
 
 	down_read(&mm->mmap_sem);
diff -Nru a/arch/m68k/config.in b/arch/m68k/config.in
--- a/arch/m68k/config.in	Sat Aug 10 18:42:23 2002
+++ b/arch/m68k/config.in	Sat Aug 10 18:42:23 2002
@@ -6,6 +6,7 @@
 define_bool CONFIG_UID16 y
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_GENERIC_ISA_DMA y
 
 mainmenu_name "Linux/68k Kernel Configuration"
 
diff -Nru a/arch/mips/config.in b/arch/mips/config.in
--- a/arch/mips/config.in	Sat Aug 10 18:42:23 2002
+++ b/arch/mips/config.in	Sat Aug 10 18:42:23 2002
@@ -4,6 +4,7 @@
 #
 define_bool CONFIG_MIPS y
 define_bool CONFIG_SMP n
+define_bool CONFIG_GENERIC_ISA_DMA y
 
 mainmenu_name "Linux Kernel Configuration"
 
diff -Nru a/arch/mips64/config.in b/arch/mips64/config.in
--- a/arch/mips64/config.in	Sat Aug 10 18:42:21 2002
+++ b/arch/mips64/config.in	Sat Aug 10 18:42:21 2002
@@ -26,6 +26,7 @@
 
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_GENERIC_ISA_DMA y
 
 #
 # Select some configuration options automatically based on user selections
diff -Nru a/arch/parisc/config.in b/arch/parisc/config.in
--- a/arch/parisc/config.in	Sat Aug 10 18:42:23 2002
+++ b/arch/parisc/config.in	Sat Aug 10 18:42:23 2002
@@ -9,6 +9,7 @@
 define_bool CONFIG_UID16 n
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_GENERIC_ISA_DMA y
 
 source init/Config.in
 
diff -Nru a/arch/ppc/config.in b/arch/ppc/config.in
--- a/arch/ppc/config.in	Sat Aug 10 18:42:20 2002
+++ b/arch/ppc/config.in	Sat Aug 10 18:42:20 2002
@@ -7,6 +7,7 @@
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
 define_bool CONFIG_HAVE_DEC_LOCK y
+define_bool CONFIG_GENERIC_ISA_DMA y
 
 mainmenu_name "Linux/PowerPC Kernel Configuration"
 
diff -Nru a/arch/ppc/configs/lopec_defconfig b/arch/ppc/configs/lopec_defconfig
--- a/arch/ppc/configs/lopec_defconfig	Sat Aug 10 18:42:21 2002
+++ b/arch/ppc/configs/lopec_defconfig	Sat Aug 10 18:42:21 2002
@@ -1,9 +1,10 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -11,6 +12,14 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# General setup
+#
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
 # Loadable module support
 #
 CONFIG_MODULES=y
@@ -23,7 +32,7 @@
 CONFIG_PPC=y
 CONFIG_PPC32=y
 CONFIG_6xx=y
-# CONFIG_4xx is not set
+# CONFIG_40x is not set
 # CONFIG_POWER3 is not set
 # CONFIG_8xx is not set
 # CONFIG_PPC_ISERIES is not set
@@ -31,49 +40,58 @@
 CONFIG_PPC_STD_MMU=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_APUS is not set
-# CONFIG_SPRUCE is not set
+# CONFIG_WILLOW is not set
 # CONFIG_PCORE is not set
+# CONFIG_POWERPMC250 is not set
+# CONFIG_EV64260 is not set
+# CONFIG_SPRUCE is not set
 # CONFIG_MENF1 is not set
 CONFIG_LOPEC=y
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
+# CONFIG_PPLUS is not set
 # CONFIG_PRPMC750 is not set
+# CONFIG_PRPMC800 is not set
 # CONFIG_SANDPOINT is not set
+# CONFIG_ADIR is not set
 # CONFIG_K2 is not set
 # CONFIG_GEMINI is not set
 # CONFIG_ZX4500 is not set
-# CONFIG_PPC601_SYNC_FIX is not set
+CONFIG_EPIC_SERIAL_MODE=y
 # CONFIG_SMP is not set
-# CONFIG_ALTIVEC is not set
+# CONFIG_PREEMPT is not set
+CONFIG_ALTIVEC=y
 # CONFIG_TAU is not set
 
 #
 # General setup
 #
 # CONFIG_HIGHMEM is not set
+# CONFIG_HIGHPTE is not set
+# CONFIG_ADVANCED_OPTIONS is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
 # CONFIG_MCA is not set
 CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_SYSCTL=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
 CONFIG_KERNEL_ELF=y
 CONFIG_BINFMT_MISC=m
-# CONFIG_PCI_NAMES is not set
-# CONFIG_HOTPLUG is not set
+CONFIG_PCI_NAMES=y
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
 # CONFIG_PCMCIA is not set
 
 #
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
-# CONFIG_PPC_RTC is not set
-# CONFIG_CMDLINE_BOOL is not set
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="ip=on"
 
 #
 # Memory Technology Devices (MTD)
@@ -91,15 +109,17 @@
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
-# CONFIG_VIODASD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_UMEM is not set
+CONFIG_BLK_DEV_LOOP=m
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_INITRD is not set
 
 #
@@ -111,6 +131,7 @@
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_BLK_DEV_LVM is not set
 
 #
@@ -118,11 +139,8 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
@@ -130,27 +148,29 @@
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
+CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 CONFIG_SYN_COOKIES=y
-
-#
-#   IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
+
+#
+#  
+#
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -170,22 +190,97 @@
 #
 # ATA/IDE/MFM/RLL support
 #
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
+CONFIG_IDE=y
+
+#
+# ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_IDEDISK_STROKE is not set
+# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# ATA host chip set support
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+
+#
+#   PCI host chip set support
+#
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_IDEDMA_PCI_AUTO=y
+CONFIG_IDEDMA_ONLYDISK=y
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_BLK_DEV_IDE_TCQ is not set
+# CONFIG_BLK_DEV_IDE_TCQ_DEFAULT is not set
+# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_AEC6280_BURST is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_WDC_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_HPT34X_AUTODMA is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_PDC202XX_BURST is not set
+# CONFIG_PDC202XX_FORCE is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIS5513 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_SL82C105=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_ATAPI=y
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_ATARAID is not set
+# CONFIG_BLK_DEV_ATARAID_PDC is not set
+# CONFIG_BLK_DEV_ATARAID_HPT is not set
 
 #
 # SCSI support
 #
 CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
 # CONFIG_CHR_DEV_SG is not set
-# CONFIG_SCSI_DEBUG_QUEUES is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
 # CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_REPORT_LUNS is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
 
@@ -195,11 +290,9 @@
 # CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
 # CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
@@ -218,15 +311,11 @@
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_NCR53C8XX is not set
-CONFIG_SCSI_SYM53C8XX=y
-CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
-CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
-CONFIG_SCSI_NCR53C8XX_SYNC=20
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
-# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
 # CONFIG_SCSI_PCI2220I is not set
@@ -235,14 +324,16 @@
 # CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_SIM710 is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_MESH is not set
-# CONFIG_SCSI_MAC53C94 is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -250,6 +341,16 @@
 # CONFIG_IEEE1394 is not set
 
 #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -258,7 +359,7 @@
 # ARCnet devices
 #
 # CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
+CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
@@ -268,17 +369,13 @@
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
-# CONFIG_GMAC is not set
-# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -291,42 +388,41 @@
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
-# CONFIG_TULIP is not set
-# CONFIG_TULIP_MWI is not set
-# CONFIG_TULIP_MMIO is not set
-# CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
-# CONFIG_DM9102 is not set
-CONFIG_EEPRO100=y
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
+# CONFIG_8139CP is not set
 # CONFIG_8139TOO is not set
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_WINBOND_840 is not set
+# CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_NET_POCKET is not set
 
 #
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
+# CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
-# CONFIG_VETH is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -352,6 +448,11 @@
 # CONFIG_WAN is not set
 
 #
+# Tulip family network device support
+#
+# CONFIG_NET_TULIP is not set
+
+#
 # Amateur Radio support
 #
 # CONFIG_HAMRADIO is not set
@@ -364,7 +465,7 @@
 #
 # ISDN subsystem
 #
-# CONFIG_ISDN is not set
+# CONFIG_ISDN_BOOL is not set
 
 #
 # Old CD-ROM drivers (not SCSI, not IDE)
@@ -379,12 +480,86 @@
 #
 # Frame-buffer support
 #
-# CONFIG_FB is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_OF is not set
+# CONFIG_FB_CONTROL is not set
+# CONFIG_FB_PLATINUM is not set
+# CONFIG_FB_VALKYRIE is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S3TRIO is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_RIVA is not set
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+# CONFIG_FB_MATROX_MYSTIQUE is not set
+# CONFIG_FB_MATROX_G100 is not set
+# CONFIG_FB_MATROX_G450 is not set
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 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_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Input device support
+#
+CONFIG_INPUT=m
+CONFIG_INPUT_KEYBDEV=m
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_GAMEPORT_PCIGAME is not set
+# CONFIG_GAMEPORT_FM801 is not set
+# CONFIG_GAMEPORT_CS461x is not set
+# CONFIG_SERIO is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
+# CONFIG_JOYSTICK_IFORCE_USB is not set
+# CONFIG_JOYSTICK_IFORCE_232 is not set
+# CONFIG_JOYSTICK_WARRIOR is not set
+# CONFIG_JOYSTICK_MAGELLAN is not set
+# CONFIG_JOYSTICK_SPACEORB is not set
+# CONFIG_JOYSTICK_SPACEBALL is not set
+# CONFIG_JOYSTICK_STINGER is not set
+# CONFIG_JOYSTICK_DB9 is not set
+# CONFIG_JOYSTICK_GAMECON is not set
+# CONFIG_JOYSTICK_TURBOGRAFX is not set
 
 #
 # Macintosh device drivers
@@ -393,14 +568,14 @@
 #
 # Character devices
 #
-# CONFIG_VT is not set
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
 CONFIG_SERIAL=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
-# CONFIG_VIOCONS is not set
 
 #
 # I2C support
@@ -412,13 +587,7 @@
 #
 # CONFIG_BUSMOUSE is not set
 # CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_JOYSTICK is not set
 # CONFIG_QIC02_TAPE is not set
-# CONFIG_VIOTAPE is not set
 
 #
 # Watchdog Cards
@@ -427,10 +596,11 @@
 # CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
 
 #
 # Ftape, the floppy tape device driver
@@ -442,32 +612,71 @@
 #
 # Multimedia devices
 #
-# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+CONFIG_VIDEO_PROC_FS=y
+# CONFIG_I2C_PARPORT is not set
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_ZORAN_BUZ is not set
+# CONFIG_VIDEO_ZORAN_DC10 is not set
+# CONFIG_VIDEO_ZORAN_LML33 is not set
+# CONFIG_VIDEO_ZR36120 is not set
+# CONFIG_VIDEO_MEYE is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
 
 #
 # File systems
 #
 # CONFIG_QUOTA is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 # CONFIG_FAT_FS is not set
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
 # CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
+# CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 CONFIG_TMPFS=y
-# CONFIG_RAMFS is not set
+CONFIG_RAMFS=y
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -481,7 +690,7 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
-# CONFIG_EXT2_FS is not set
+CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_UDF_FS is not set
 # CONFIG_UDF_RW is not set
@@ -492,14 +701,17 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
+# CONFIG_EXPORTFS is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
@@ -510,6 +722,7 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
 
 #
 # Partition Types
@@ -527,39 +740,134 @@
 #
 # USB support
 #
-CONFIG_USB=y
+CONFIG_USB=m
 # CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
 CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_LONG_TIMEOUT is not set
 # CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_EHCI_HCD is not set
+CONFIG_USB_OHCI_HCD=m
+# CONFIG_USB_UHCI_HCD is not set
+# CONFIG_USB_UHCI_HCD_ALT is not set
+
+#
+# USB Device Class drivers
+#
 # CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_ACM is not set
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_MIDI is not set
+CONFIG_USB_ACM=m
 # CONFIG_USB_PRINTER is not set
-# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_HP8200e is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+CONFIG_USB_HID=m
+CONFIG_USB_HIDINPUT=y
+# CONFIG_USB_HIDDEV is not set
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+
+#
+# USB Imaging devices
+#
 # CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
+CONFIG_USB_SCANNER=m
 # CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_HPUSBSCSI is not set
+
+#
+# USB Multimedia devices
+#
+# CONFIG_USB_DABUSB is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
 # CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
 # CONFIG_USB_OV511 is not set
 # CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_PLUSB is not set
-# CONFIG_USB_PEGASUS is not set
+CONFIG_USB_SE401=m
+# CONFIG_USB_STV680 is not set
+
+#
+# USB Network adaptors
+#
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_NET1080 is not set
+# CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+
+#
+# USB port drivers
+#
 # CONFIG_USB_USS720 is not set
 
 #
 # USB Serial Converter support
 #
-# CONFIG_USB_SERIAL is not set
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_SERIAL_GENERIC is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+CONFIG_USB_SERIAL_VISOR=m
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SAFE_PADDED is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_TIGL is not set
+# CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_BRLVGER is not set
 
 #
 # Bluetooth support
@@ -567,9 +875,17 @@
 # CONFIG_BLUEZ is not set
 
 #
+# Library routines
+#
+# CONFIG_CRC32 is not set
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
+
+#
 # Kernel hacking
 #
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_KGDB is not set
-CONFIG_XMON=y
+# CONFIG_XMON is not set
 # CONFIG_BDI_SWITCH is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
diff -Nru a/arch/ppc/configs/sandpoint_defconfig b/arch/ppc/configs/sandpoint_defconfig
--- a/arch/ppc/configs/sandpoint_defconfig	Sat Aug 10 18:42:22 2002
+++ b/arch/ppc/configs/sandpoint_defconfig	Sat Aug 10 18:42:22 2002
@@ -4,6 +4,7 @@
 # CONFIG_UID16 is not set
 # CONFIG_RWSEM_GENERIC_SPINLOCK is not set
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_HAVE_DEC_LOCK=y
 
 #
 # Code maturity level options
@@ -11,10 +12,18 @@
 CONFIG_EXPERIMENTAL=y
 
 #
+# General setup
+#
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+
+#
 # Loadable module support
 #
 CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
+# CONFIG_MODVERSIONS is not set
 CONFIG_KMOD=y
 
 #
@@ -23,7 +32,7 @@
 CONFIG_PPC=y
 CONFIG_PPC32=y
 CONFIG_6xx=y
-# CONFIG_4xx is not set
+# CONFIG_40x is not set
 # CONFIG_POWER3 is not set
 # CONFIG_8xx is not set
 # CONFIG_PPC_ISERIES is not set
@@ -31,25 +40,29 @@
 CONFIG_PPC_STD_MMU=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_APUS is not set
-# CONFIG_SPRUCE is not set
+# CONFIG_WILLOW is not set
 # CONFIG_PCORE is not set
 # CONFIG_POWERPMC250 is not set
+# CONFIG_EV64260 is not set
+# CONFIG_SPRUCE is not set
 # CONFIG_MENF1 is not set
 # CONFIG_LOPEC is not set
 # CONFIG_MCPN765 is not set
 # CONFIG_MVME5100 is not set
+# CONFIG_PPLUS is not set
 # CONFIG_PRPMC750 is not set
 # CONFIG_PRPMC800 is not set
 CONFIG_SANDPOINT=y
 # CONFIG_ADIR is not set
 # CONFIG_K2 is not set
+# CONFIG_PAL4 is not set
 # CONFIG_GEMINI is not set
-# CONFIG_WILLOW is not set
 # CONFIG_ZX4500 is not set
-# CONFIG_MPC10X_STORE_GATHERING is not set
 CONFIG_SANDPOINT_X3=y
 CONFIG_EPIC_SERIAL_MODE=y
+# CONFIG_MPC10X_STORE_GATHERING is not set
 # CONFIG_SMP is not set
+# CONFIG_PREEMPT is not set
 CONFIG_ALTIVEC=y
 # CONFIG_TAU is not set
 
@@ -57,28 +70,28 @@
 # General setup
 #
 # CONFIG_HIGHMEM is not set
+# CONFIG_ADVANCED_OPTIONS is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
 # CONFIG_MCA is not set
 CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_SYSCTL=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
 CONFIG_KERNEL_ELF=y
-CONFIG_BINFMT_MISC=y
+CONFIG_BINFMT_MISC=m
 # CONFIG_PCI_NAMES is not set
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCMCIA/CardBus support
+#
 # CONFIG_PCMCIA is not set
 
 #
 # Parallel port support
 #
 # CONFIG_PARPORT is not set
-CONFIG_PPC_RTC=y
 # CONFIG_CMDLINE_BOOL is not set
 
 #
@@ -91,6 +104,7 @@
 #
 # CONFIG_PNP is not set
 # CONFIG_ISAPNP is not set
+# CONFIG_PNPBIOS is not set
 
 #
 # Block devices
@@ -100,7 +114,9 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
@@ -124,14 +140,12 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_DHCP is not set
@@ -139,10 +153,11 @@
 # CONFIG_IP_PNP_RARP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
 # CONFIG_VLAN_8021Q is not set
 
@@ -151,6 +166,11 @@
 #
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_DEV_APPLETALK is not set
 # CONFIG_DECNET is not set
 # CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
@@ -171,50 +191,51 @@
 # ATA/IDE/MFM/RLL support
 #
 CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
 CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDECS is not set
+# CONFIG_IDEDISK_STROKE is not set
+CONFIG_ATAPI=y
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_IDECS is not set
 
 #
-# IDE chipset support/bugfixes
+# ATA host controller support
 #
+# CONFIG_BLK_DEV_RZ1000 is not set
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
+
+#
+#   PCI host controller support
+#
+# CONFIG_BLK_DEV_OFFBOARD is not set
 CONFIG_IDEPCI_SHARE_IRQ=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
 # CONFIG_IDEDMA_PCI_AUTO is not set
+# CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_BLK_DEV_IDE_TCQ is not set
+# CONFIG_BLK_DEV_IDE_TCQ_DEFAULT is not set
 # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_AEC62XX_TUNING is not set
+# CONFIG_AEC6280_BURST is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
 # CONFIG_WDC_ALI15X3 is not set
 # CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_AMD74XX_OVERRIDE is not set
 # CONFIG_BLK_DEV_CMD64X is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
 # CONFIG_HPT34X_AUTODMA is not set
 # CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_PIIX is not set
 # CONFIG_BLK_DEV_NS87415 is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_PDC202XX is not set
@@ -226,9 +247,8 @@
 # CONFIG_BLK_DEV_VIA82CXXX is not set
 CONFIG_BLK_DEV_SL82C105=y
 # CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
 # CONFIG_IDEDMA_IVB is not set
-CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_IDEDMA_AUTO is not set
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
 # CONFIG_BLK_DEV_ATARAID_HPT is not set
@@ -239,11 +259,30 @@
 # CONFIG_SCSI is not set
 
 #
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+# CONFIG_FUSION_BOOT is not set
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
+# CONFIG_FUSION_LAN is not set
+
+#
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
 #
 # CONFIG_IEEE1394 is not set
 
 #
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -252,7 +291,7 @@
 # ARCnet devices
 #
 # CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
+CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
@@ -264,14 +303,20 @@
 CONFIG_NET_ETHERNET=y
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
-# CONFIG_GMAC is not set
+# CONFIG_OAKNET is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
+CONFIG_NET_VENDOR_3COM=y
+# CONFIG_EL1 is not set
+# CONFIG_EL2 is not set
+# CONFIG_ELPLUS is not set
+# CONFIG_EL16 is not set
+# CONFIG_ELMC is not set
+# CONFIG_ELMC_II is not set
+CONFIG_VORTEX=y
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
@@ -282,13 +327,9 @@
 # CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
-CONFIG_TULIP=y
-# CONFIG_TULIP_MWI is not set
-# CONFIG_TULIP_MMIO is not set
-# CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
-# CONFIG_DM9102 is not set
-CONFIG_EEPRO100=y
+# CONFIG_EEPRO100 is not set
+CONFIG_E100=y
 # CONFIG_LNE390 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -300,12 +341,13 @@
 # CONFIG_8139TOO_PIO is not set
 # CONFIG_8139TOO_TUNE_TWISTER is not set
 # CONFIG_8139TOO_8129 is not set
+# CONFIG_8139_NEW_RX_RESET is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_WINBOND_840 is not set
+# CONFIG_VIA_RHINE_MMIO is not set
 # CONFIG_NET_POCKET is not set
 
 #
@@ -313,15 +355,24 @@
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
+# CONFIG_TIGON3 is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
-# CONFIG_PPP is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPPOE is not set
 # CONFIG_SLIP is not set
 
 #
@@ -343,6 +394,18 @@
 # CONFIG_WAN is not set
 
 #
+# Tulip family network device support
+#
+CONFIG_NET_TULIP=y
+# CONFIG_DE2104X is not set
+CONFIG_TULIP=y
+# CONFIG_TULIP_MWI is not set
+# CONFIG_TULIP_MMIO is not set
+# CONFIG_DE4X5 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_DM9102 is not set
+
+#
 # Amateur Radio support
 #
 # CONFIG_HAMRADIO is not set
@@ -355,12 +418,7 @@
 #
 # ISDN subsystem
 #
-# CONFIG_ISDN is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
+# CONFIG_ISDN_BOOL is not set
 
 #
 # Console drivers
@@ -370,16 +428,129 @@
 #
 # Frame-buffer support
 #
-# CONFIG_FB is not set
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_OF is not set
+# CONFIG_FB_CONTROL is not set
+# CONFIG_FB_PLATINUM is not set
+# CONFIG_FB_VALKYRIE is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_S3TRIO is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_RIVA is not set
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+# CONFIG_FB_MATROX_MYSTIQUE is not set
+# CONFIG_FB_MATROX_G100 is not set
+# CONFIG_FB_MATROX_G450 is not set
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 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_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
 
 #
-# Input core support
+# Userland interfaces
 #
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_TSDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+CONFIG_INPUT_UINPUT=m
+
+#
+# Input I/O drivers
+#
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+# CONFIG_GAMEPORT_NS558 is not set
+# CONFIG_GAMEPORT_L4 is not set
+# CONFIG_GAMEPORT_EMU10K1 is not set
+# CONFIG_GAMEPORT_VORTEX is not set
+# CONFIG_GAMEPORT_FM801 is not set
+# CONFIG_GAMEPORT_CS461x is not set
+CONFIG_SERIO=y
+CONFIG_SERIO_I8042=y
+CONFIG_I8042_REG_BASE=60
+CONFIG_I8042_KBD_IRQ=1
+CONFIG_I8042_AUX_IRQ=12
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PARKBD is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_JOYSTICK_ANALOG is not set
+# CONFIG_JOYSTICK_A3D is not set
+# CONFIG_JOYSTICK_ADI is not set
+# CONFIG_JOYSTICK_COBRA is not set
+# CONFIG_JOYSTICK_GF2K is not set
+# CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_GRIP_MP is not set
+# CONFIG_JOYSTICK_GUILLEMOT is not set
+# CONFIG_JOYSTICK_INTERACT is not set
+# CONFIG_JOYSTICK_SIDEWINDER is not set
+# CONFIG_JOYSTICK_TMDC is not set
+# CONFIG_JOYSTICK_IFORCE is not set
+# CONFIG_JOYSTICK_WARRIOR is not set
+# CONFIG_JOYSTICK_MAGELLAN is not set
+# CONFIG_JOYSTICK_SPACEORB is not set
+# CONFIG_JOYSTICK_SPACEBALL is not set
+# CONFIG_JOYSTICK_STINGER is not set
+# CONFIG_JOYSTICK_TWIDDLER is not set
+# CONFIG_JOYSTICK_DB9 is not set
+# CONFIG_JOYSTICK_GAMECON is not set
+# CONFIG_JOYSTICK_TURBOGRAFX is not set
+# CONFIG_INPUT_JOYDUMP is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
 
 #
 # Macintosh device drivers
@@ -388,46 +559,51 @@
 #
 # Character devices
 #
-# CONFIG_VT is not set
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-# CONFIG_SERIAL_EXTENDED is not set
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
 # CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
 
 #
-# I2C support
-#
-# CONFIG_I2C is not set
-
+# Serial drivers
 #
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_CS is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
 
 #
-# Joysticks
+# Non-8250 serial port support
 #
-# CONFIG_INPUT_GAMEPORT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
 
 #
-# Input core support is needed for gameports
+# I2C support
 #
+# CONFIG_I2C is not set
 
 #
-# Input core support is needed for joysticks
+# Mice
 #
+# CONFIG_BUSMOUSE is not set
+CONFIG_PSMOUSE=y
 # CONFIG_QIC02_TAPE is not set
 
 #
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
+CONFIG_GEN_RTC=y
+# CONFIG_GEN_RTC_X is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -438,25 +614,59 @@
 # CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
+CONFIG_RAW_DRIVER=m
 
 #
 # Multimedia devices
 #
-# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+CONFIG_VIDEO_PROC_FS=y
+
+#
+# Video Adapters
+#
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_ZORAN_BUZ is not set
+# CONFIG_VIDEO_ZORAN_DC10 is not set
+# CONFIG_VIDEO_ZORAN_LML33 is not set
+# CONFIG_VIDEO_ZR36120 is not set
+# CONFIG_VIDEO_MEYE is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
 
 #
 # File systems
 #
 # CONFIG_QUOTA is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_CHECK is not set
+# CONFIG_REISERFS_PROC_INFO is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_JBD is not set
+# CONFIG_JBD_DEBUG is not set
 # CONFIG_FAT_FS is not set
 # CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
@@ -466,9 +676,13 @@
 # CONFIG_JFFS2_FS is not set
 # CONFIG_CRAMFS is not set
 CONFIG_TMPFS=y
-# CONFIG_RAMFS is not set
+CONFIG_RAMFS=y
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -493,13 +707,17 @@
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
+# CONFIG_NFSD_TCP is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+# CONFIG_EXPORTFS is not set
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
@@ -510,12 +728,27 @@
 # CONFIG_NCPFS_SMALLDOS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
+# CONFIG_ZISOFS_FS is not set
 
 #
 # Partition Types
 #
-# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
 CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
 # CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
@@ -527,20 +760,36 @@
 #
 # USB support
 #
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_LONG_TIMEOUT is not set
+# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
 
 #
-# USB Controllers
+# USB Host Controller Drivers
 #
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
+# CONFIG_USB_EHCI_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_UHCI_HCD_ALT=m
 
 #
 # USB Device Class drivers
 #
 # CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH is not set
+# CONFIG_USB_BLUETOOTH_TTY is not set
+# CONFIG_USB_MIDI is not set
+CONFIG_USB_ACM=m
+# CONFIG_USB_PRINTER is not set
+
+#
+#   SCSI support is needed for USB Storage
+#
 # CONFIG_USB_STORAGE is not set
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_DATAFAB is not set
@@ -549,42 +798,52 @@
 # CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_STORAGE_HP8200e is not set
 # CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
 
 #
 # USB Human Interface Devices (HID)
 #
-
-#
-#   Input core support is needed for USB HID
-#
+CONFIG_USB_HID=y
+CONFIG_USB_HIDINPUT=y
+# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
+# CONFIG_LOGITECH_FF is not set
+CONFIG_USB_HIDDEV=y
+# CONFIG_USB_AIPTEK is not set
+# CONFIG_USB_WACOM is not set
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_XPAD is not set
 
 #
 # USB Imaging devices
 #
-# CONFIG_USB_DC2XX is not set
 # CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
+CONFIG_USB_SCANNER=m
 # CONFIG_USB_MICROTEK is not set
 # CONFIG_USB_HPUSBSCSI is not set
 
 #
 # USB Multimedia devices
 #
-
-#
-#   Video4Linux support is needed for USB Multimedia device support
-#
+# CONFIG_USB_DABUSB is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_PWC is not set
+CONFIG_USB_SE401=m
+# CONFIG_USB_STV680 is not set
 
 #
 # USB Network adaptors
 #
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_CDCETHER is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
 # CONFIG_USB_USBNET is not set
 
 #
@@ -595,16 +854,18 @@
 #
 # USB Serial Converter support
 #
-# CONFIG_USB_SERIAL is not set
+CONFIG_USB_SERIAL=m
 # CONFIG_USB_SERIAL_GENERIC is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
 # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
+CONFIG_USB_SERIAL_VISOR=m
+# CONFIG_USB_SERIAL_IPAQ is not set
 # CONFIG_USB_SERIAL_IR is not set
 # CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
 # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
 # CONFIG_USB_SERIAL_KEYSPAN is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
@@ -614,9 +875,14 @@
 # CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QW is not set
+# CONFIG_USB_SERIAL_KEYSPAN_USA19QI is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
+# CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SAFE_PADDED is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
 # CONFIG_USB_SERIAL_OMNINET is not set
@@ -624,7 +890,11 @@
 #
 # USB Miscellaneous drivers
 #
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_TIGL is not set
+# CONFIG_USB_AUERSWALD is not set
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_BRLVGER is not set
 
 #
 # Bluetooth support
@@ -632,10 +902,23 @@
 # CONFIG_BLUEZ is not set
 
 #
+# Library routines
+#
+# CONFIG_CRC32 is not set
+CONFIG_ZLIB_INFLATE=m
+CONFIG_ZLIB_DEFLATE=m
+
+#
 # Kernel hacking
 #
 # CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_SPINLOCK is not set
 # CONFIG_KGDB is not set
 # CONFIG_XMON is not set
 # CONFIG_BDI_SWITCH is not set
-# CONFIG_DEBUG_TEXT is not set
+# CONFIG_SERIAL_TEXT_DEBUG is not set
+
+#
+# Security options
+#
+CONFIG_SECURITY_CAPABILITIES=y
diff -Nru a/arch/ppc/kernel/i8259.c b/arch/ppc/kernel/i8259.c
--- a/arch/ppc/kernel/i8259.c	Sat Aug 10 18:42:22 2002
+++ b/arch/ppc/kernel/i8259.c	Sat Aug 10 18:42:22 2002
@@ -130,7 +130,8 @@
 
 static void i8259_end_irq(unsigned int irq)
 {
-	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+	    && irq_desc[irq].action)
 		i8259_unmask_irq(irq);
 }
 
diff -Nru a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
--- a/arch/ppc/kernel/irq.c	Sat Aug 10 18:42:22 2002
+++ b/arch/ppc/kernel/irq.c	Sat Aug 10 18:42:22 2002
@@ -443,7 +443,7 @@
 	 * use the action we have.
 	 */
 	action = NULL;
-	if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+	if (likely(!(status & (IRQ_DISABLED | IRQ_INPROGRESS)))) {
 		action = desc->action;
 		if (!action || !action->handler) {
 			ppc_spurious_interrupts++;
@@ -468,7 +468,7 @@
 	   a different instance of this same irq, the other processor
 	   will take care of it.
 	 */
-	if (!action)
+	if (unlikely(!action))
 		goto out;
 
 
@@ -487,12 +487,12 @@
 		handle_irq_event(irq, regs, action);
 		spin_lock(&desc->lock);
 		
-		if (!(desc->status & IRQ_PENDING))
+		if (likely(!(desc->status & IRQ_PENDING)))
 			break;
 		desc->status &= ~IRQ_PENDING;
 	}
-	desc->status &= ~IRQ_INPROGRESS;
 out:
+	desc->status &= ~IRQ_INPROGRESS;
 	/*
 	 * The ->end() handler has to deal with interrupts which got
 	 * disabled while the handler was running.
@@ -561,10 +561,6 @@
 #ifdef CONFIG_SMP
 void synchronize_irq(unsigned int irq)
 {
-        /* is there anything to synchronize with? */
-	if (!irq_desc[irq].action)
-		return;
-
 	while (irq_desc[irq].status & IRQ_INPROGRESS)
 		barrier();
 }
diff -Nru a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
--- a/arch/ppc/kernel/misc.S	Sat Aug 10 18:42:22 2002
+++ b/arch/ppc/kernel/misc.S	Sat Aug 10 18:42:22 2002
@@ -1296,6 +1296,9 @@
 	.long sys_futex
 	.long sys_sched_setaffinity
 	.long sys_sched_getaffinity
+	.long sys_security
+	.long sys_ni_syscall	/* 225 - reserved for Tux */
+
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long sys_ni_syscall
 	.endr
diff -Nru a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c
--- a/arch/ppc/kernel/open_pic.c	Sat Aug 10 18:42:23 2002
+++ b/arch/ppc/kernel/open_pic.c	Sat Aug 10 18:42:23 2002
@@ -25,6 +25,7 @@
 #include <asm/sections.h>
 #include <asm/open_pic.h>
 #include <asm/i8259.h>
+#include <asm/hardirq.h>
 
 #include "open_pic_defs.h"
 
@@ -148,16 +149,15 @@
  * data has probably been corrupted and we're going to panic or deadlock later
  * anyway --Troy
  */
-extern unsigned long* _get_SP(void);
 #define check_arg_irq(irq) \
     if (irq < open_pic_irq_offset || irq >= NumSources+open_pic_irq_offset \
 	|| ISR[irq - open_pic_irq_offset] == 0) { \
       printk("open_pic.c:%d: illegal irq %d\n", __LINE__, irq); \
-      print_backtrace(_get_SP()); }
+      show_stack(NULL); }
 #define check_arg_cpu(cpu) \
     if (cpu < 0 || cpu >= NumProcessors){ \
 	printk("open_pic.c:%d: illegal cpu %d\n", __LINE__, cpu); \
-	print_backtrace(_get_SP()); }
+	show_stack(NULL); }
 #else
 #define check_arg_ipi(ipi)	do {} while (0)
 #define check_arg_timer(timer)	do {} while (0)
@@ -798,7 +798,8 @@
 
 static void openpic_end_irq(unsigned int irq_nr)
 {
-	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+	    && irq_desc[irq_nr].action)
 		openpic_enable_irq(irq_nr);
 }
 
diff -Nru a/arch/ppc/kernel/ppc4xx_pic.c b/arch/ppc/kernel/ppc4xx_pic.c
--- a/arch/ppc/kernel/ppc4xx_pic.c	Sat Aug 10 18:42:19 2002
+++ b/arch/ppc/kernel/ppc4xx_pic.c	Sat Aug 10 18:42:19 2002
@@ -236,7 +236,8 @@
 		}
 	}
 
-	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))
+	    && irq_desc[irq].action) {
 		ppc_cached_irq_mask[word] |= 1 << (31 - bit);
 		switch (word){
 			case 0:
diff -Nru a/arch/ppc/kernel/ppc8260_pic.c b/arch/ppc/kernel/ppc8260_pic.c
--- a/arch/ppc/kernel/ppc8260_pic.c	Sat Aug 10 18:42:20 2002
+++ b/arch/ppc/kernel/ppc8260_pic.c	Sat Aug 10 18:42:20 2002
@@ -90,7 +90,8 @@
 	int	bit, word;
 	volatile uint	*simr;
 
-	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+			&& irq_desc[irq_nr].action) {
 
 		bit = irq_to_siubit[irq_nr];
 		word = irq_to_siureg[irq_nr];
diff -Nru a/arch/ppc/kernel/ppc8xx_pic.c b/arch/ppc/kernel/ppc8xx_pic.c
--- a/arch/ppc/kernel/ppc8xx_pic.c	Sat Aug 10 18:42:22 2002
+++ b/arch/ppc/kernel/ppc8xx_pic.c	Sat Aug 10 18:42:22 2002
@@ -46,7 +46,8 @@
 
 static void m8xx_end_irq(unsigned int irq_nr)
 {
-	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+			&& irq_desc[irq_nr].action) {
 		int bit, word;
 
 		bit = irq_nr & 0x1f;
diff -Nru a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
--- a/arch/ppc/kernel/process.c	Sat Aug 10 18:42:22 2002
+++ b/arch/ppc/kernel/process.c	Sat Aug 10 18:42:22 2002
@@ -44,6 +44,7 @@
 #include <asm/processor.h>
 #include <asm/mmu.h>
 #include <asm/prom.h>
+#include <asm/hardirq.h>
 #ifdef CONFIG_PPC_ISERIES
 #include <asm/iSeries/Paca.h>
 #endif
@@ -293,7 +294,7 @@
 			break;
 	}
 	printk("\n");
-	print_backtrace((unsigned long *)regs->gpr[1]);
+	show_stack((unsigned long *)regs->gpr[1]);
 }
 
 void exit_thread(void)
@@ -418,7 +419,6 @@
 #endif /* CONFIG_ALTIVEC */
 }
 
-#if 0
 int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
 {
 	struct pt_regs *regs = tsk->thread.regs;
@@ -431,7 +431,14 @@
 			| tsk->thread.fpexc_mode;
 	return 0;
 }
-#endif
+
+int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
+{
+	unsigned int val;
+
+	val = __unpack_fe01(tsk->thread.fpexc_mode);
+	return put_user(val, (unsigned int *) adr);
+}
 
 int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6,
 	      struct pt_regs *regs)
@@ -486,20 +493,25 @@
 }
 
 void
-print_backtrace(unsigned long *sp)
+show_stack(unsigned long *sp)
 {
 	int cnt = 0;
 	unsigned long i;
 
+	if (sp == NULL)
+		sp = (unsigned long *)_get_SP();
 	printk("Call backtrace: ");
-	while (sp) {
-		if (__get_user( i, &sp[1] ))
+	for (;;) {
+		if (__get_user(sp, (unsigned long **)sp))
+			break;
+		if (sp == NULL)
+			break;
+		if (__get_user(i, &sp[1]))
 			break;
 		if (cnt++ % 7 == 0)
 			printk("\n");
 		printk("%08lX ", i);
-		if (cnt > 32) break;
-		if (__get_user(sp, (unsigned long **)sp))
+		if (cnt > 32)
 			break;
 	}
 	printk("\n");
diff -Nru a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c
--- a/arch/ppc/kernel/ptrace.c	Sat Aug 10 18:42:22 2002
+++ b/arch/ppc/kernel/ptrace.c	Sat Aug 10 18:42:22 2002
@@ -28,6 +28,7 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/user.h>
+#include <linux/security.h>
 
 #include <asm/uaccess.h>
 #include <asm/page.h>
@@ -167,6 +168,9 @@
 	if (request == PTRACE_TRACEME) {
 		/* are we already being traced? */
 		if (current->ptrace & PT_PTRACED)
+			goto out;
+		ret = security_ops->ptrace(current->parent, current);
+		if (ret)
 			goto out;
 		/* set the ptrace bit in the process flags. */
 		current->ptrace |= PT_PTRACED;
diff -Nru a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
--- a/arch/ppc/kernel/setup.c	Sat Aug 10 18:42:23 2002
+++ b/arch/ppc/kernel/setup.c	Sat Aug 10 18:42:23 2002
@@ -66,7 +66,7 @@
 
 /* Used with the BI_MEMSIZE bootinfo parameter to store the memory
    size value reported by the boot loader. */ 
-unsigned int boot_mem_size;
+unsigned long boot_mem_size;
 
 unsigned long ISA_DMA_THRESHOLD;
 unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
diff -Nru a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
--- a/arch/ppc/kernel/smp.c	Sat Aug 10 18:42:23 2002
+++ b/arch/ppc/kernel/smp.c	Sat Aug 10 18:42:23 2002
@@ -289,273 +289,6 @@
 		atomic_inc(&call_data->finished);
 }
 
-#if 0 /* Old boot code. */
-void __init smp_boot_cpus(void)
-{
-	int i, cpu_nr;
-	struct task_struct *p;
-
-	printk("Entering SMP Mode...\n");
-        smp_store_cpu_info(0);
-	cpu_online_map = 1UL;
-
-	/*
-	 * assume for now that the first cpu booted is
-	 * cpu 0, the master -- Cort
-	 */
-	cpu_callin_map[0] = 1;
-
-	for (i = 0; i < NR_CPUS; i++) {
-		prof_counter[i] = 1;
-		prof_multiplier[i] = 1;
-	}
-
-	/*
-	 * XXX very rough.
-	 */
-	cache_decay_ticks = HZ/100;
-
-	smp_ops = ppc_md.smp_ops;
-	if (smp_ops == NULL) {
-		printk("SMP not supported on this machine.\n");
-		return;
-	}
-
-	/* Probe platform for CPUs */
-	cpu_nr = smp_ops->probe();
-
-	/*
-	 * only check for cpus we know exist.  We keep the callin map
-	 * with cpus at the bottom -- Cort
-	 */
-	if (cpu_nr > max_cpus)
-		cpu_nr = max_cpus;
-#ifdef CONFIG_PPC_ISERIES
-	smp_iSeries_space_timers( cpu_nr );
-#endif
-	for (i = 1; i < cpu_nr; i++) {
-		int c;
-		struct pt_regs regs;
-		
-		/* create a process for the processor */
-		/* only regs.msr is actually used, and 0 is OK for it */
-		memset(&regs, 0, sizeof(struct pt_regs));
-		p = do_fork(CLONE_VM|CLONE_IDLETASK, 0, &regs, 0);
-		if (IS_ERR(p))
-			panic("failed fork for CPU %d", i);
-		init_idle(p, i);
-		unhash_process(p);
-
-		secondary_ti = p->thread_info;
-		p->thread_info->cpu = i;
-
-		/*
-		 * There was a cache flush loop here to flush the cache
-		 * to memory for the first 8MB of RAM.  The cache flush
-		 * has been pushed into the kick_cpu function for those
-		 * platforms that need it.
-		 */
-
-		/* wake up cpus */
-		smp_ops->kick_cpu(i);
-		
-		/*
-		 * wait to see if the cpu made a callin (is actually up).
-		 * use this value that I found through experimentation.
-		 * -- Cort
-		 */
-		for (c = 1000; c && !cpu_callin_map[i]; c--)
-			udelay(100);
-		
-		if (cpu_callin_map[i]) {
-			char buf[32];
-			sprintf(buf, "found cpu %d", i);
-			if (ppc_md.progress) ppc_md.progress(buf, 0x350+i);
-			printk("Processor %d found.\n", i);
-		} else {
-			char buf[32];
-			sprintf(buf, "didn't find cpu %d", i);
-			if (ppc_md.progress) ppc_md.progress(buf, 0x360+i);
-			printk("Processor %d is stuck.\n", i);
-		}
-	}
-
-	/* Setup CPU 0 last (important) */
-	smp_ops->setup_cpu(0);
-	
-	/* FIXME: Not with hotplug CPUS --RR */
-	if (num_online_cpus() < 2)
-		smp_tb_synchronized = 1;
-}
-
-void __init smp_software_tb_sync(int cpu)
-{
-#define PASSES 4	/* 4 passes.. */
-	int pass;
-	int i, j;
-
-	/* stop - start will be the number of timebase ticks it takes for cpu0
-	 * to send a message to all others and the first reponse to show up.
-	 *
-	 * ASSUMPTION: this time is similiar for all cpus
-	 * ASSUMPTION: the time to send a one-way message is ping/2
-	 */
-	register unsigned long start = 0;
-	register unsigned long stop = 0;
-	register unsigned long temp = 0;
-
-	set_tb(0, 0);
-
-	/* multiple passes to get in l1 cache.. */
-	for (pass = 2; pass < 2+PASSES; pass++){
-		if (cpu == 0){
-			mb();
-			for (i = j = 1; i < NR_CPUS; i++, j++){
-				/* skip stuck cpus */
-				while (!cpu_callin_map[j])
-					++j;
-				while (cpu_callin_map[j] != pass)
-					barrier();
-			}
-			mb();
-			tb_sync_flag = pass;
-			start = get_tbl();	/* start timing */
-			while (tb_sync_flag)
-				mb();
-			stop = get_tbl();	/* end timing */
-			/* theoretically, the divisor should be 2, but
-			 * I get better results on my dual mtx. someone
-			 * please report results on other smp machines..
-			 */
-			tb_offset = (stop-start)/4;
-			mb();
-			tb_sync_flag = pass;
-			udelay(10);
-			mb();
-			tb_sync_flag = 0;
-			mb();
-			set_tb(0,0);
-			mb();
-		} else {
-			cpu_callin_map[cpu] = pass;
-			mb();
-			while (!tb_sync_flag)
-				mb();		/* wait for cpu0 */
-			mb();
-			tb_sync_flag = 0;	/* send response for timing */
-			mb();
-			while (!tb_sync_flag)
-				mb();
-			temp = tb_offset;	/* make sure offset is loaded */
-			while (tb_sync_flag)
-				mb();
-			set_tb(0,temp);		/* now, set the timebase */
-			mb();
-		}
-	}
-	if (cpu == 0) {
-		smp_tb_synchronized = 1;
-		printk("smp_software_tb_sync: %d passes, final offset: %ld\n",
-			PASSES, tb_offset);
-	}
-	/* so time.c doesn't get confused */
-	set_dec(tb_ticks_per_jiffy);
-	last_jiffy_stamp(cpu) = 0;
-}
-
-void __init smp_commence(void)
-{
-	/*
-	 *	Lets the callin's below out of their loop.
-	 */
-	if (ppc_md.progress) ppc_md.progress("smp_commence", 0x370);
-	wmb();
-	smp_commenced = 1;
-
-	/* if the smp_ops->setup_cpu function has not already synched the
-	 * timebases with a nicer hardware-based method, do so now
-	 *
-	 * I am open to suggestions for improvements to this method
-	 * -- Troy <hozer@drgw.net>
-	 *
-	 * NOTE: if you are debugging, set smp_tb_synchronized for now
-	 * since if this code runs pretty early and needs all cpus that
-	 * reported in in smp_callin_map to be working
-	 *
-	 * NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus/BenH
-	 */
-	/* FIXME: This doesn't work with hotplug CPUs --RR */
-	if (!smp_tb_synchronized && num_online_cpus() == 2) {
-		unsigned long flags;
-		local_irq_save(flags);	
-		smp_software_tb_sync(0);
-		local_irq_restore(flags);
-	}
-}
-
-void __init smp_callin(void)
-{
-	int cpu = smp_processor_id();
-	
-        smp_store_cpu_info(cpu);
-	set_dec(tb_ticks_per_jiffy);
-	/* Set online before we acknowledge. */
-	set_bit(cpu, &cpu_online_map);
-	wmb();
-	cpu_callin_map[cpu] = 1;
-
-	smp_ops->setup_cpu(cpu);
-
-	while (!smp_commenced)
-		barrier();
-
-	/* see smp_commence for more info */
-	if (!smp_tb_synchronized && num_online_cpus() == 2) {
-		smp_software_tb_sync(cpu);
-	}
-	local_irq_enable();
-}
-
-/* intel needs this */
-void __init initialize_secondary(void)
-{
-}
-
-/* Activate a secondary processor. */
-int __init start_secondary(void *unused)
-{
-	atomic_inc(&init_mm.mm_count);
-	current->active_mm = &init_mm;
-	smp_callin();
-	return cpu_idle(NULL);
-}
-
-void __init smp_setup(char *str, int *ints)
-{
-}
-
-int __init setup_profiling_timer(unsigned int multiplier)
-{
-	return 0;
-}
-
-void __init smp_store_cpu_info(int id)
-{
-        struct cpuinfo_PPC *c = &cpu_data[id];
-
-	/* assume bogomips are same for everything */
-        c->loops_per_jiffy = loops_per_jiffy;
-        c->pvr = mfspr(PVR);
-}
-
-static int __init maxcpus(char *str)
-{
-	get_option(&str, &max_cpus);
-	return 1;
-}
-
-__setup("maxcpus=", maxcpus);
-#else /* New boot code */
 /* FIXME: Do this properly for all archs --RR */
 static spinlock_t timebase_lock = SPIN_LOCK_UNLOCKED;
 static unsigned int timebase_upper = 0, timebase_lower = 0;
@@ -643,6 +376,7 @@
 	printk("CPU %i done callin...\n", cpu);
 	smp_ops->setup_cpu(cpu);
 	printk("CPU %i done setup...\n", cpu);
+	local_irq_enable();
 	smp_ops->take_timebase();
 	printk("CPU %i done timebase take...\n", cpu);
 
@@ -707,4 +441,3 @@
 {
 	smp_ops->setup_cpu(0);
 }
-#endif
diff -Nru a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
--- a/arch/ppc/mm/init.c	Sat Aug 10 18:42:21 2002
+++ b/arch/ppc/mm/init.c	Sat Aug 10 18:42:21 2002
@@ -45,6 +45,7 @@
 #include <asm/machdep.h>
 #include <asm/btext.h>
 #include <asm/tlb.h>
+#include <asm/bootinfo.h>
 
 #include "mem_pieces.h"
 #include "mmu_decl.h"
@@ -242,9 +243,14 @@
 
 	/*
 	 * Figure out how much memory we have, how much
-	 * is lowmem, and how much is highmem.
+	 * is lowmem, and how much is highmem.  If we were
+	 * passed the total memory size from the bootloader,
+	 * just use it.
 	 */
-	total_memory = ppc_md.find_end_of_memory();
+	if (boot_mem_size)
+		total_memory = boot_mem_size;
+	else
+		total_memory = ppc_md.find_end_of_memory();
 
 	if (__max_memory && total_memory > __max_memory)
 		total_memory = __max_memory;
diff -Nru a/arch/ppc/platforms/apus_setup.c b/arch/ppc/platforms/apus_setup.c
--- a/arch/ppc/platforms/apus_setup.c	Sat Aug 10 18:42:23 2002
+++ b/arch/ppc/platforms/apus_setup.c	Sat Aug 10 18:42:23 2002
@@ -602,8 +602,7 @@
 {
 	unsigned long flags;
 
-	save_flags (flags);
-	cli();
+	local_irq_save(flags);
 
 	/* turn off Rx and Tx interrupts */
 	custom.intena = IF_RBF | IF_TBE;
@@ -611,7 +610,7 @@
 	/* clear any pending interrupt */
 	custom.intreq = IF_RBF | IF_TBE;
 
-	restore_flags (flags);
+	local_irq_restore(flags);
 
 	/*
 	 * set the appropriate directions for the modem control flags,
diff -Nru a/arch/ppc/platforms/chrp_smp.c b/arch/ppc/platforms/chrp_smp.c
--- a/arch/ppc/platforms/chrp_smp.c	Sat Aug 10 18:42:22 2002
+++ b/arch/ppc/platforms/chrp_smp.c	Sat Aug 10 18:42:22 2002
@@ -77,25 +77,20 @@
 	spin_unlock(&timebase_lock);
 
 	while (timebase_upper || timebase_lower)
-		rmb();
+		barrier();
 	call_rtas("thaw-time-base", 0, 1, NULL);
 }
 
 void __devinit
 smp_chrp_take_timebase(void)
 {
-	int done = 0;
-
-	while (!done) {
-		spin_lock(&timebase_lock);
-		if (timebase_upper || timebase_lower) {
-			set_tb(timebase_upper, timebase_lower);
-			timebase_upper = 0;
-			timebase_lower = 0;
-			done = 1;
-		}
-		spin_unlock(&timebase_lock);
-	}
+	while (!(timebase_upper || timebase_lower))
+		barrier();
+	spin_lock(&timebase_lock);
+	set_tb(timebase_upper, timebase_lower);
+	timebase_upper = 0;
+	timebase_lower = 0;
+	spin_unlock(&timebase_lock);
 	printk("CPU %i taken timebase\n", smp_processor_id());
 }
 
diff -Nru a/arch/ppc/platforms/lopec_setup.c b/arch/ppc/platforms/lopec_setup.c
--- a/arch/ppc/platforms/lopec_setup.c	Sat Aug 10 18:42:20 2002
+++ b/arch/ppc/platforms/lopec_setup.c	Sat Aug 10 18:42:20 2002
@@ -301,12 +301,6 @@
 }
 #endif	/* CONFIG_SERIAL_TEXT_DEBUG */
 
-static unsigned long __init
-lopec_find_end_of_memory(void)
-{
-	return mpc10x_get_mem_size(MPC10X_MEM_MAP_B);
-}
-
 TODC_ALLOC();
 
 static void __init
@@ -376,7 +370,6 @@
 	ppc_md.power_off = lopec_power_off;
 	ppc_md.halt = lopec_halt;
 
-	ppc_md.find_end_of_memory = lopec_find_end_of_memory;
 	ppc_md.setup_io_mappings = lopec_map_io;
 
 	ppc_md.time_init = todc_time_init;
diff -Nru a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c
--- a/arch/ppc/platforms/pmac_pic.c	Sat Aug 10 18:42:22 2002
+++ b/arch/ppc/platforms/pmac_pic.c	Sat Aug 10 18:42:22 2002
@@ -149,7 +149,8 @@
 
 static void __pmac pmac_end_irq(unsigned int irq_nr)
 {
-	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) {
+	if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))
+	    && irq_desc[irq_nr].action) {
         	set_bit(irq_nr, ppc_cached_irq_mask);
 	        pmac_set_irq_mask(irq_nr, 1);
 	}
diff -Nru a/arch/ppc/platforms/pplus_setup.c b/arch/ppc/platforms/pplus_setup.c
--- a/arch/ppc/platforms/pplus_setup.c	Sat Aug 10 18:42:23 2002
+++ b/arch/ppc/platforms/pplus_setup.c	Sat Aug 10 18:42:23 2002
@@ -191,11 +191,8 @@
 static void
 pplus_halt(void)
 {
-	unsigned long flags;
-	local_irq_disable();
 	/* set exception prefix high - to the prom */
-	save_flags( flags );
-	restore_flags( flags|MSR_IP );
+	_nmask_and_or_msr(MSR_EE, MSR_IP);
 
 	/* make sure bit 0 (reset) is a 0 */
 	outb( inb(0x92) & ~1L , 0x92 );
diff -Nru a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c
--- a/arch/ppc/platforms/prep_setup.c	Sat Aug 10 18:42:23 2002
+++ b/arch/ppc/platforms/prep_setup.c	Sat Aug 10 18:42:23 2002
@@ -458,10 +458,6 @@
 
 	/* If we didn't get it from the residual data, try this. */
 	if ( res ) {
-		unsigned long flags;
-
-		save_flags(flags);
-
 #define TIMER0_COUNT 0x40
 #define TIMER_CONTROL 0x43
 		/* set timer to periodic mode */
@@ -476,7 +472,7 @@
 		/* wait for calibrate */
 		while ( calibrate_steps )
 			;
-		restore_flags(flags);
+		local_irq_disable();
 		free_irq( 0, NULL);
 	}
 }
@@ -581,11 +577,8 @@
 static void __prep
 prep_halt(void)
 {
-	unsigned long flags;
-	local_irq_disable();
 	/* set exception prefix high - to the prom */
-	save_flags( flags );
-	restore_flags( flags|MSR_IP );
+	_nmask_and_or_msr(MSR_EE, MSR_IP);
 
 	/* make sure bit 0 (reset) is a 0 */
 	outb( inb(0x92) & ~1L , 0x92 );
@@ -648,11 +641,8 @@
 prep_power_off(void)
 {
 	if ( _prep_type == _PREP_IBM) {
-		unsigned long flags;
-		local_irq_disable();
 		/* set exception prefix high - to the prom */
-		save_flags( flags );
-		restore_flags( flags|MSR_IP );
+		_nmask_and_or_msr(MSR_EE, MSR_IP);
 
 		utah_sig87c750_setbit(21, 5, 1); /* set bit 21.5, "PMEXEC_OFF" */
 
@@ -762,37 +752,6 @@
 #endif /* CONFIG_SMP */
 
 /*
- * This finds the amount of physical ram and does necessary
- * setup for prep.  This is pretty architecture specific so
- * this will likely stay separate from the pmac.
- * -- Cort
- */
-static unsigned long __init
-prep_find_end_of_memory(void)
-{
-	unsigned long total = 0;
-	extern unsigned int boot_mem_size;
-
-#ifdef CONFIG_PREP_RESIDUAL	
-	total = res->TotalMemory;
-#endif	
-
-	if (total == 0 && boot_mem_size != 0)
-		total = boot_mem_size;
-	else if (total == 0) {
-		/*
-		 * I need a way to probe the amount of memory if the residual
-		 * data doesn't contain it. -- Cort
-		 */
-		total = 0x02000000;
-		printk(KERN_INFO "Ramsize from residual data was 0"
-			 " -- defaulting to %ldM\n", total>>20);
-	}
-
-	return (total);
-}
-
-/*
  * Setup the bat mappings we're going to load that cover
  * the io areas.  RAM was mapped by mapin_ram().
  * -- Cort
@@ -807,13 +766,15 @@
 static int __init
 prep_request_io(void)
 {
+	if (_machine == _MACH_prep) {
 #ifdef CONFIG_NVRAM
-	request_region(PREP_NVRAM_AS0, 0x8, "nvram");
+		request_region(PREP_NVRAM_AS0, 0x8, "nvram");
 #endif
-	request_region(0x00,0x20,"dma1");
-	request_region(0x40,0x20,"timer");
-	request_region(0x80,0x10,"dma page reg");
-	request_region(0xc0,0x20,"dma2");
+		request_region(0x00,0x20,"dma1");
+		request_region(0x40,0x20,"timer");
+		request_region(0x80,0x10,"dma page reg");
+		request_region(0xc0,0x20,"dma2");
+	}
 
 	return 0;
 }
@@ -879,7 +840,6 @@
 		ppc_md.time_init      = mk48t59_init;
 	}
 
-	ppc_md.find_end_of_memory = prep_find_end_of_memory;
 	ppc_md.setup_io_mappings = prep_map_io;
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
diff -Nru a/arch/ppc/platforms/spruce_setup.c b/arch/ppc/platforms/spruce_setup.c
--- a/arch/ppc/platforms/spruce_setup.c	Sat Aug 10 18:42:21 2002
+++ b/arch/ppc/platforms/spruce_setup.c	Sat Aug 10 18:42:21 2002
@@ -187,12 +187,6 @@
 
 extern int boot_mem_size;
 
-static unsigned long __init
-spruce_find_end_of_memory(void)
-{
-	return boot_mem_size;
-}
-
 static void __init
 spruce_map_io(void)
 {
@@ -214,7 +208,6 @@
 	ppc_md.init_IRQ = cpc700_init_IRQ;
 	ppc_md.get_irq = cpc700_get_irq;
 
-	ppc_md.find_end_of_memory = spruce_find_end_of_memory;
 	ppc_md.setup_io_mappings = spruce_map_io;
 
 	ppc_md.restart = spruce_restart;
diff -Nru a/arch/sh/config.in b/arch/sh/config.in
--- a/arch/sh/config.in	Sat Aug 10 18:42:23 2002
+++ b/arch/sh/config.in	Sat Aug 10 18:42:23 2002
@@ -9,6 +9,7 @@
 define_bool CONFIG_UID16 y
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_GENERIC_ISA_DMA y
 
 source init/Config.in
 
diff -Nru a/arch/sparc/Config.help b/arch/sparc/Config.help
--- a/arch/sparc/Config.help	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc/Config.help	Sat Aug 10 18:42:23 2002
@@ -910,34 +910,6 @@
 
   If unsure, say Y.
 
-CONFIG_SERIAL
-  This selects whether you want to include the driver for the standard
-  serial ports.  The standard answer is Y.  People who might say N
-  here are those that are setting up dedicated Ethernet WWW/FTP
-  servers, or users that have one of the various bus mice instead of a
-  serial mouse and don't intend to use their machine's standard serial
-  port for anything.  (Note that the Cyclades and Stallion multi
-  serial port drivers do not need this driver built in for them to
-  work.)
-
-  If you want to compile this driver as a module, say M here and read
-  <file:Documentation/modules.txt>.  The module will be called
-  serial.o.
-  [WARNING: Do not compile this driver as a module if you are using
-  non-standard serial ports, since the configuration information will
-  be lost when the driver is unloaded.  This limitation may be lifted
-  in the future.]
-
-  BTW1: If you have a mouseman serial mouse which is not recognized by
-  the X window system, try running gpm first.
-
-  BTW2: If you intend to use a software modem (also called Winmodem)
-  under Linux, forget it.  These modems are crippled and require
-  proprietary drivers which are only available under Windows.
-
-  Most people will say Y or M here, so that they can use serial mice,
-  modems and similar devices connecting to the standard serial ports.
-
 CONFIG_SERIAL_CONSOLE
   If you say Y here, it will be possible to use a serial port as the
   system console (the system console is the device which receives all
@@ -1018,25 +990,6 @@
   If you have more than 8 printers, you need to increase the LP_NO
   macro in lp.c and the PARPORT_MAX macro in parport.h.
 
-CONFIG_BUSMOUSE
-  Say Y here if your machine has a bus mouse as opposed to a serial
-  mouse. Most people have a regular serial MouseSystem or
-  Microsoft mouse (made by Logitech) that plugs into a COM port
-  (rectangular with 9 or 25 pins). These people say N here. 
-
-  If you have a laptop, you either have to check the documentation or
-  experiment a bit to find out whether the trackball is a serial mouse
-  or not; it's best to say Y here for you.
-
-  This is the generic bus mouse driver code. If you have a bus mouse,
-  you will have to say Y here and also to the specific driver for your
-  mouse below.
-
-  This code 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 busmouse.o. If you want to compile it as a
-  module, say M here and read <file:Documentation/modules.txt>.
-
 CONFIG_SOFT_WATCHDOG
   A software monitoring watchdog. This will fail to reboot your system
   from some situations that the hardware watchdog will recover
@@ -1105,12 +1058,4 @@
   <http://www.ultralinux.org/faq.html> for more information.  If you
   want to run SunOS binaries on an Ultra you must also say Y to
   "Kernel support for 32-bit a.out binaries" above.
-
-CONFIG_SUN_KEYBOARD
-  Say Y here to support the keyboard found on Sun 3 and 3x
-  workstations.  It can also be used support Sun Type-5 keyboards
-  through an adaptor.  See
-  <http://www.suse.cz/development/input/adapters.html> and
-  <http://sourceforge.net/projects/linuxconsole/> for details on the
-  latter.
 
diff -Nru a/arch/sparc/Makefile b/arch/sparc/Makefile
--- a/arch/sparc/Makefile	Sat Aug 10 18:42:21 2002
+++ b/arch/sparc/Makefile	Sat Aug 10 18:42:21 2002
@@ -41,15 +41,16 @@
 CORE_FILES := arch/sparc/kernel/kernel.o arch/sparc/mm/mm.o $(CORE_FILES) \
 	arch/sparc/math-emu/math-emu.o
 
-LIBS := $(TOPDIR)/lib/lib.a $(LIBS) $(TOPDIR)/arch/sparc/prom/promlib.a \
-	$(TOPDIR)/arch/sparc/lib/lib.a
+LIBS := $(LIBS) arch/sparc/prom/promlib.a arch/sparc/lib/lib.a
 
 # This one has to come last
 SUBDIRS += arch/sparc/boot
 CORE_FILES_NO_BTFIX := $(CORE_FILES)
 CORE_FILES += arch/sparc/boot/btfix.o
 
+# Export what is needed by arch/sparc/boot/Makefile
 export	CORE_FILES_NO_BTFIX
+export INIT
 
 archclean:
 	rm -f $(TOPDIR)/vmlinux.aout
@@ -60,7 +61,7 @@
 
 prepare: check_asm
 
-check_asm: include/linux/version.h include/linux/asm include/config/MARKER
+check_asm: include/linux/version.h include/asm include/config/MARKER
 	$(MAKE) -C arch/sparc/kernel check_asm
 
 tftpboot.img:
diff -Nru a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile
--- a/arch/sparc/boot/Makefile	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc/boot/Makefile	Sat Aug 10 18:42:23 2002
@@ -22,8 +22,9 @@
 clean:
 	rm -f btfixupprep piggyback tftpboot.img btfix.o btfix.s
 
-BTOBJS := $(HEAD) init/main.o init/version.o
-BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
+#BTOBJS := $(HEAD) init/main.o init/version.o
+BTOBJS := $(HEAD) $(INIT)
+BTLIBS := $(CORE_FILES_NO_BTFIX) $(LIBS) \
 	$(DRIVERS) $(NETWORKS)
 
 # I wanted to make this depend upon BTOBJS so that a parallel
@@ -34,7 +35,6 @@
 	$(LD) $(LDFLAGS) -r $(patsubst %,$(TOPDIR)/%,$(BTOBJS)) \
 		--start-group \
 		$(patsubst %,$(TOPDIR)/%,$(BTLIBS)) \
-		$(LIBS) \
 		--end-group -o vmlinux.o
 
 btfix.s: btfixupprep vmlinux.o
diff -Nru a/arch/sparc/config.in b/arch/sparc/config.in
--- a/arch/sparc/config.in	Sat Aug 10 18:42:21 2002
+++ b/arch/sparc/config.in	Sat Aug 10 18:42:21 2002
@@ -6,6 +6,7 @@
 
 define_bool CONFIG_UID16 y
 define_bool CONFIG_HIGHMEM y
+define_bool CONFIG_GENERIC_ISA_DMA y
 
 source init/Config.in
 
@@ -27,13 +28,7 @@
 define_bool CONFIG_PCMCIA n
 define_bool CONFIG_SBUS y
 define_bool CONFIG_SBUSCHAR y
-define_bool CONFIG_BUSMOUSE y
-define_bool CONFIG_SUN_MOUSE y
-define_bool CONFIG_SERIAL y
-define_bool CONFIG_SUN_SERIAL y
 define_bool CONFIG_SERIAL_CONSOLE y
-define_bool CONFIG_SUN_KEYBOARD y
-define_bool CONFIG_SUN_CONSOLE y
 define_bool CONFIG_SUN_AUXIO y
 define_bool CONFIG_SUN_IO y
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
@@ -68,6 +63,7 @@
 
 source drivers/mtd/Config.in
 
+source drivers/serial/Config.in
 if [ "$CONFIG_SUN4" != "y" ]; then
    source drivers/sbus/char/Config.in
    source drivers/sbus/audio/Config.in
@@ -81,11 +77,6 @@
 tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
 dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
 
-#tristate 'Logical volume manager (LVM) support' CONFIG_BLK_DEV_LVM N
-#if [ "$CONFIG_BLK_DEV_LVM" != "n" ]; then
-#   bool '   LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y
-#fi
-
 source drivers/md/Config.in
 
 tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
@@ -239,7 +230,10 @@
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
+bool 'Debug memory allocations' CONFIG_DEBUG_SLAB
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+bool 'Spinlock debugging' CONFIG_DEBUG_SPINLOCK
+
 endmenu
 
 source security/Config.in
diff -Nru a/arch/sparc/kernel/apc.c b/arch/sparc/kernel/apc.c
--- a/arch/sparc/kernel/apc.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/kernel/apc.c	Sat Aug 10 18:42:22 2002
@@ -115,9 +115,9 @@
 }
 
 static struct file_operations apc_fops = {
-	ioctl:		apc_ioctl,
-	open:		apc_open,
-	release:	apc_release,
+	.ioctl =	apc_ioctl,
+	.open =		apc_open,
+	.release =	apc_release,
 };
 
 static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops };
diff -Nru a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
--- a/arch/sparc/kernel/entry.S	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/kernel/entry.S	Sat Aug 10 18:42:22 2002
@@ -31,6 +31,7 @@
 #include <asm/signal.h>
 #include <asm/obio.h>
 #include <asm/mxcc.h>
+#include <asm/thread_info.h>
 
 #include <asm/asmmacro.h>
 
@@ -1234,7 +1235,8 @@
 	call	C_LABEL(do_ptrace)
 	 add	%sp, REGWIN_SZ, %o0
 
-	ld	[%curptr + AOFF_task_ptrace], %l5
+	ld	[%curptr + TI_TASK], %l5
+	ld	[%l5 + AOFF_task_ptrace], %l5
 	andcc	%l5, 0x02, %g0
 	be	1f
 	 nop
@@ -1284,7 +1286,8 @@
 	call	C_LABEL(do_sigpause)
 	 add	%sp, REGWIN_SZ, %o1
 
-	ld	[%curptr + AOFF_task_ptrace], %l5
+	ld	[%curptr + TI_TASK], %l5
+	ld	[%l5 + AOFF_task_ptrace], %l5
 	andcc	%l5, 0x02, %g0
 	be	1f
 	 nop
@@ -1302,7 +1305,8 @@
 	call	C_LABEL(do_sigsuspend)
 	 add	%sp, REGWIN_SZ, %o0
 
-	ld	[%curptr + AOFF_task_ptrace], %l5
+	ld	[%curptr + TI_TASK], %l5
+	ld	[%l5 + AOFF_task_ptrace], %l5
 	andcc	%l5, 0x02, %g0
 	be	1f
 	 nop
@@ -1321,7 +1325,8 @@
 	call	C_LABEL(do_rt_sigsuspend)
 	 add	%sp, REGWIN_SZ, %o2
 
-	ld	[%curptr + AOFF_task_ptrace], %l5
+	ld	[%curptr + TI_TASK], %l5
+	ld	[%l5 + AOFF_task_ptrace], %l5
 	andcc	%l5, 0x02, %g0
 	be	1f
 	 nop
@@ -1339,7 +1344,8 @@
 	call	C_LABEL(do_sigreturn)
 	 add	%sp, REGWIN_SZ, %o0
 
-	ld	[%curptr + AOFF_task_ptrace], %l5
+	ld	[%curptr + TI_TASK], %l5
+	ld	[%l5 + AOFF_task_ptrace], %l5
 	andcc	%l5, 0x02, %g0
 	be	1f
 	 nop
@@ -1359,7 +1365,8 @@
 	call	C_LABEL(do_rt_sigreturn)
 	 add	%sp, REGWIN_SZ, %o0
 
-	ld	[%curptr + AOFF_task_ptrace], %l5
+	ld	[%curptr + TI_TASK], %l5
+	ld	[%l5 + AOFF_task_ptrace], %l5
 	andcc	%l5, 0x02, %g0
 	be	1f
 	 nop
@@ -1384,24 +1391,26 @@
 	mov	%o7, %l5
 flush_patch_two:
 	FLUSH_ALL_KERNEL_WINDOWS;
+	ld	[%curptr + TI_TASK], %o4
 	rd	%psr, %g4
 	WRITE_PAUSE
 	mov	SIGCHLD, %o0			! arg0:	clone flags
 	rd	%wim, %g5
 	WRITE_PAUSE
 	mov	%fp, %o1			! arg1:	usp
-	std	%g4, [%curptr + AOFF_task_thread + AOFF_thread_fork_kpsr]
+	std	%g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
 	add	%sp, REGWIN_SZ, %o2		! arg2:	pt_regs ptr
 	mov	0, %o3
-	call	C_LABEL(do_fork_FIXME_NOW_RETURNS_TASK_STRUCT)
+	call	C_LABEL(sparc_do_fork)
 	 mov	%l5, %o7
-	
+
 	/* Whee, kernel threads! */
 	.globl	C_LABEL(sys_clone), flush_patch_three
 C_LABEL(sys_clone):
 	mov	%o7, %l5
 flush_patch_three:
 	FLUSH_ALL_KERNEL_WINDOWS;
+	ld	[%curptr + TI_TASK], %o4
 	rd	%psr, %g4
 	WRITE_PAUSE
 
@@ -1413,11 +1422,10 @@
 	 mov	%fp, %o1			! yes, use callers usp
 	andn	%o1, 7, %o1			! no, align to 8 bytes
 1:
-	std	%g4, [%curptr + AOFF_task_thread + AOFF_thread_fork_kpsr]
+	std	%g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
 	add	%sp, REGWIN_SZ, %o2		! arg2:	pt_regs ptr
 	mov	0, %o3
-	/* FIXME:	remove CLONE_IDLETASK from flags first */
-	call	C_LABEL(do_fork_WITHOUT_CLONE_IDLETASK)
+	call	C_LABEL(sparc_do_fork)
 	 mov	%l5, %o7
 
 	/* Whee, real vfork! */
@@ -1425,17 +1433,18 @@
 C_LABEL(sys_vfork):
 flush_patch_four:
 	FLUSH_ALL_KERNEL_WINDOWS;
+	ld	[%curptr + TI_TASK], %o4
 	rd	%psr, %g4
 	WRITE_PAUSE
 	rd	%wim, %g5
 	WRITE_PAUSE
-	std	%g4, [%curptr + AOFF_task_thread + AOFF_thread_fork_kpsr]
+	std	%g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
 	sethi	%hi(0x4000 | 0x0100 | SIGCHLD), %o0
 	mov	%fp, %o1
 	or	%o0, %lo(0x4000 | 0x0100 | SIGCHLD), %o0
-	sethi	%hi(C_LABEL(do_fork_FIXME_NOW_RETURNS_TASK_STRUCT)), %l1
+	sethi	%hi(C_LABEL(sparc_do_fork)), %l1
 	mov	0, %o3
-	jmpl	%l1 + %lo(C_LABEL(do_fork_FIXME_NOW_RETURNS_TASK_STRUCT)), %g0
+	jmpl	%l1 + %lo(C_LABEL(sparc_do_fork)), %g0
 	 add	%sp, REGWIN_SZ, %o2
 
         .align  4
@@ -1464,8 +1473,11 @@
 
 	.globl	C_LABEL(ret_from_fork)
 C_LABEL(ret_from_fork):
+#if CONFIG_SMP || CONFIG_PREEMPT
+/* XXX Wrong location: call schedule_tail in every ret_sys_call. */
 	call	schedule_tail
 	 mov	%g3, %o0
+#endif
 	b	C_LABEL(ret_sys_call)
 	 ld	[%sp + REGWIN_SZ + PT_I0], %o0
 
@@ -1492,7 +1504,8 @@
 	mov	%i1, %o1
 	mov	%i2, %o2
 
-	ld	[%curptr + AOFF_task_ptrace], %l5
+	ld	[%curptr + TI_TASK], %l5
+	ld	[%l5 + AOFF_task_ptrace], %l5
 	mov	%i3, %o3
 	andcc	%l5, 0x02, %g0
 	mov	%i4, %o4
@@ -1506,7 +1519,8 @@
 
 	.globl	C_LABEL(ret_sys_call)
 C_LABEL(ret_sys_call):
-	ld	[%curptr + AOFF_task_ptrace], %l6
+	ld	[%curptr + TI_TASK], %l6
+	ld	[%l6 + AOFF_task_ptrace], %l6
 	cmp	%o0, -ENOIOCTLCMD
 	ld	[%sp + REGWIN_SZ + PT_PSR], %g3
 	set	PSR_C, %g2
@@ -1858,7 +1872,7 @@
 	 * traps with the old method of just doing flush_user_windows().
 	 */
 C_LABEL(kill_user_windows):
-	ld	[%g6 + AOFF_task_thread + AOFF_thread_uwinmask], %o0	! get current umask
+	ld	[%g6 + TI_UWINMASK], %o0	! get current umask
 	orcc	%g0, %o0, %g0			! if no bits set, we are done
 	be	3f				! nothing to do
 	 rd	%psr, %o5			! must clear interrupts
@@ -1866,7 +1880,7 @@
 	wr	%o4, 0x0, %psr			! the uwinmask state
 	WRITE_PAUSE				! burn them cycles
 1:
-	ld	[%g6 + AOFF_task_thread + AOFF_thread_uwinmask], %o0	! get consistant state
+	ld	[%g6 + TI_UWINMASK], %o0	! get consistant state
 	orcc	%g0, %o0, %g0			! did an interrupt come in?
 	be	4f				! yep, we are done
 	 rd	%wim, %o3			! get current wim
@@ -1878,13 +1892,14 @@
 	bne	kuw_patch1			! not done yet
 	 srl	%o3, 1, %o4			! begin another save simulation
 	wr	%o3, 0x0, %wim			! set the new wim
-	st	%g0, [%g6 + AOFF_task_thread + AOFF_thread_uwinmask]	! clear uwinmask
+	st	%g0, [%g6 + TI_UWINMASK]	! clear uwinmask
 4:
 	wr	%o5, 0x0, %psr			! re-enable interrupts
 	WRITE_PAUSE				! burn baby burn
 3:
+	ld	[%g6 + TI_TASK], %o4
 	retl					! return
-	 st	%g0, [%g6 + AOFF_task_thread + AOFF_thread_w_saved]	! no windows saved
+	 st	%g0, [%o4 + AOFF_task_thread + AOFF_thread_w_saved]	! no windows saved
 
 	.align	4
 	.globl	C_LABEL(restore_current)
diff -Nru a/arch/sparc/kernel/etrap.S b/arch/sparc/kernel/etrap.S
--- a/arch/sparc/kernel/etrap.S	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/kernel/etrap.S	Sat Aug 10 18:42:22 2002
@@ -14,6 +14,7 @@
 #include <asm/ptrace.h>
 #include <asm/winmacro.h>
 #include <asm/asmmacro.h>
+#include <asm/thread_info.h>
 
 /* Registers to not touch at all. */
 #define t_psr        l0 /* Set by caller */
@@ -101,7 +102,7 @@
 	 mov	%t_kstack, %sp		! jump onto new stack
 
 trap_setup_kernel_spill:
-	ld	[%curptr + AOFF_task_thread + AOFF_thread_uwinmask], %g1
+	ld	[%curptr + TI_UWINMASK], %g1
 	orcc	%g0, %g1, %g0
 	bne	trap_setup_user_spill	! there are some user windows, yuck
 	/* Spill from kernel, but only kernel windows, adjust
@@ -127,7 +128,8 @@
 	jmpl	%t_retpc + 0x8, %g0	! return to caller
 	 mov	%t_kstack, %sp		! and onto new kernel stack
 
-#define STACK_OFFSET (TASK_UNION_SIZE - (TRACEREG_SZ + REGWIN_SZ))
+#define STACK_OFFSET (THREAD_SIZE - (TRACEREG_SZ + REGWIN_SZ))
+
 trap_setup_from_user:
 	/* We can't use %curptr yet. */
 	LOAD_CURRENT(t_kstack, t_twinmask)
@@ -143,18 +145,19 @@
 	STORE_PT_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
 
 #if 0
-	/* If we're sure every task_struct is TASK_UNION_SIZE aligned,
+	/* If we're sure every task_struct is THREAD_SIZE aligned,
 	   we can speed this up. */
 	sethi	%hi(STACK_OFFSET), %curptr
 	or	%curptr, %lo(STACK_OFFSET), %curptr
 	sub	%t_kstack, %curptr, %curptr
 #else
-	sethi	%hi(~(TASK_UNION_SIZE - 1)), %curptr
+	sethi	%hi(~(THREAD_SIZE - 1)), %curptr
 	and	%t_kstack, %curptr, %curptr
 #endif
 
 	/* Clear current->thread.w_saved */
-	st	%g0, [%curptr + AOFF_task_thread + AOFF_thread_w_saved]
+	ld	[%curptr + TI_TASK], %g2
+	st	%g0, [%g2 + AOFF_task_thread + AOFF_thread_w_saved]
 
 	/* See if we are in the trap window. */
 	andcc	%t_twinmask, %t_wim, %g0
@@ -185,7 +188,7 @@
 	andn	%g2, %t_twinmask, %g2
 tsetup_patch3:
 	and	%g2, 0xff, %g2			! patched on 7win Sparcs
-	st	%g2, [%curptr + AOFF_task_thread + AOFF_thread_uwinmask]	! store new umask
+	st	%g2, [%curptr + TI_UWINMASK]	! store new umask
 
 	jmpl	%t_retpc + 0x8, %g0		! return to caller
 	 mov	%t_kstack, %sp			! and onto kernel stack
@@ -206,7 +209,7 @@
 tsetup_patch6:
 	and	%g2, 0xff, %g2		! patched on 7win Sparcs
 	andn	%g1, %g2, %g1		! clear this bit in %g1
-	st	%g1, [%curptr + AOFF_task_thread + AOFF_thread_uwinmask]
+	st	%g1, [%curptr + TI_UWINMASK]
 
 	save	%g0, %g0, %g0
 
@@ -288,7 +291,8 @@
 	/* From user/kernel into invalid window w/bad user
 	 * stack. Save bad user stack, and return to caller.
 	 */
-	SAVE_BOLIXED_USER_STACK(curptr, g3)
+	ld	[%curptr + TI_TASK], %glob_tmp
+	SAVE_BOLIXED_USER_STACK(glob_tmp, g3)
 	restore	%g0, %g0, %g0
 
 	jmpl	%t_retpc + 0x8, %g0
diff -Nru a/arch/sparc/kernel/head.S b/arch/sparc/kernel/head.S
--- a/arch/sparc/kernel/head.S	Sat Aug 10 18:42:21 2002
+++ b/arch/sparc/kernel/head.S	Sat Aug 10 18:42:21 2002
@@ -23,6 +23,7 @@
 #include <asm/page.h>
 #include <asm/kdebug.h>
 #include <asm/winmacro.h>
+#include <asm/thread_info.h>	/* TI_UWINMASK */
 #include <asm/errno.h>
 
 	.data
@@ -749,7 +750,7 @@
 		jmpl	%g1, %g0
 		 nop
 
-	/* This is to align init_task_union properly, be careful. -DaveM */
+	/* This is to align init_thread_union properly, be careful. -DaveM */
 	.align	8192
 
 /* The code above should be at beginning and we have to take care about
@@ -1010,8 +1011,8 @@
 		WRITE_PAUSE
 
 		/* I want a kernel stack NOW! */
-		set	C_LABEL(init_task_union), %g1
-		set	(TASK_UNION_SIZE - REGWIN_SZ), %g2
+		set	C_LABEL(init_thread_union), %g1
+		set	(THREAD_SIZE - REGWIN_SZ), %g2
 		add	%g1, %g2, %sp
 		mov	0, %fp			/* And for good luck */
 
@@ -1025,10 +1026,10 @@
 		bl	1b
 		 add	%o0, 0x1, %o0
 
-		/* Initialize the umask value for init_task just in case.
+		/* Initialize the uwinmask value for init task just in case.
 		 * But first make current_set[boot_cpu_id] point to something useful.
 		 */
-		set	C_LABEL(init_task_union), %g6
+		set	C_LABEL(init_thread_union), %g6
 		set	C_LABEL(current_set), %g2
 #ifdef CONFIG_SMP
 		sethi	%hi(C_LABEL(boot_cpu_id4)), %g3
@@ -1038,7 +1039,7 @@
 #endif
 		st	%g6, [%g2]
 
-		st	%g0, [%g6 + AOFF_task_thread + AOFF_thread_uwinmask]
+		st	%g0, [%g6 + TI_UWINMASK]
 
 /* Compute NWINDOWS and stash it away. Now uses %wim trick explained
  * in the V8 manual. Ok, this method seems to work, Sparc is cool...
diff -Nru a/arch/sparc/kernel/init_task.c b/arch/sparc/kernel/init_task.c
--- a/arch/sparc/kernel/init_task.c	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc/kernel/init_task.c	Sat Aug 10 18:42:23 2002
@@ -9,12 +9,12 @@
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS;
 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
- * right after that so that the init_task_union is aligned properly as well.
+ * 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.
  */
 __asm__(".section \".text\",#alloc\n");
-union task_union init_task_union =
-		{ INIT_TASK(init_task_union.task) };
+union thread_union init_thread_union = { INIT_THREAD_INFO(init_task) };
diff -Nru a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
--- a/arch/sparc/kernel/ioport.c	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc/kernel/ioport.c	Sat Aug 10 18:42:23 2002
@@ -530,7 +530,7 @@
 		}
 	}
 
-	*pba = virt_to_bus(va);
+	*pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */
 	return (void *) res->start;
 }
 
@@ -565,7 +565,7 @@
 		return;
 	}
 
-	pgp = (unsigned long) bus_to_virt(ba);
+	pgp = (unsigned long) phys_to_virt(ba);	/* bus_to_virt actually */
 	mmu_inval_dma_area(pgp, n);
 	{
 		int x;
@@ -592,7 +592,7 @@
 	if (direction == PCI_DMA_NONE)
 		BUG();
 	/* IIep is write-through, not flushing. */
-	return virt_to_bus(ptr);
+	return virt_to_phys(ptr);
 }
 
 /* Unmap a single streaming mode DMA translation.  The dma_addr and size
@@ -608,7 +608,7 @@
 	if (direction == PCI_DMA_NONE)
 		BUG();
 	if (direction != PCI_DMA_TODEVICE) {
-		mmu_inval_dma_area((unsigned long)bus_to_virt(ba),
+		mmu_inval_dma_area((unsigned long)phys_to_virt(ba),
 		    (size + PAGE_SIZE-1) & PAGE_MASK);
 	}
 }
@@ -637,7 +637,8 @@
 		BUG();
 	/* IIep is write-through, not flushing. */
 	for (n = 0; n < nents; n++) {
-		sg->dvma_address = virt_to_bus(sg->address);
+		if (page_address(sg->page) == NULL) BUG();
+		sg->dvma_address = virt_to_phys(page_address(sg->page));
 		sg->dvma_length = sg->length;
 		sg++;
 	}
@@ -657,7 +658,9 @@
 		BUG();
 	if (direction != PCI_DMA_TODEVICE) {
 		for (n = 0; n < nents; n++) {
-			mmu_inval_dma_area((unsigned long)sg->address,
+			if (page_address(sg->page) == NULL) BUG();
+			mmu_inval_dma_area(
+			    (unsigned long) page_address(sg->page),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 			sg++;
 		}
@@ -678,7 +681,7 @@
 	if (direction == PCI_DMA_NONE)
 		BUG();
 	if (direction != PCI_DMA_TODEVICE) {
-		mmu_inval_dma_area((unsigned long)bus_to_virt(ba),
+		mmu_inval_dma_area((unsigned long)phys_to_virt(ba),
 		    (size + PAGE_SIZE-1) & PAGE_MASK);
 	}
 }
@@ -697,7 +700,9 @@
 		BUG();
 	if (direction != PCI_DMA_TODEVICE) {
 		for (n = 0; n < nents; n++) {
-			mmu_inval_dma_area((unsigned long)sg->address,
+			if (page_address(sg->page) == NULL) BUG();
+			mmu_inval_dma_area(
+			    (unsigned long) page_address(sg->page),
 			    (sg->length + PAGE_SIZE-1) & PAGE_MASK);
 			sg++;
 		}
diff -Nru a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
--- a/arch/sparc/kernel/irq.c	Sat Aug 10 18:42:20 2002
+++ b/arch/sparc/kernel/irq.c	Sat Aug 10 18:42:20 2002
@@ -6,7 +6,7 @@
  *
  *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  *  Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
- *  Copyright (C) 1995 Pete A. Zaitcev (zaitcev@yahoo.com)
+ *  Copyright (C) 1995,2002 Pete A. Zaitcev (zaitcev@yahoo.com)
  *  Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
  *  Copyright (C) 1998-2000 Anton Blanchard (anton@samba.org)
  */
@@ -46,6 +46,7 @@
 #include <asm/hardirq.h>
 #include <asm/softirq.h>
 #include <asm/pcic.h>
+#include <asm/cacheflush.h>
 
 /*
  * Dave Redman (djhr@tadpole.co.uk)
@@ -119,9 +120,11 @@
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
-		for (j = 0; j < smp_num_cpus; j++)
-			seq_printf(p, "%10u ",
-				kstat.irqs[cpu_logical_map(j)][i]);
+		for (j = 0; j < NR_CPUS; j++) {
+			if (cpu_online(j))
+				seq_printf(p, "%10u ",
+				    kstat.irqs[cpu_logical_map(j)][i]);
+		}
 #endif
 		seq_printf(p, " %c %s",
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
@@ -214,12 +217,16 @@
 
 	printk("\n%s, CPU %d:\n", str, cpu);
 	printk("irq:  %d [ ", irqs_running());
-	for (i = 0; i < smp_num_cpus; i++)
-		printk("%u ", __brlock_array[i][BR_GLOBALIRQ_LOCK]);
+	for (i = 0; i < NR_CPUS; i++) {
+		if (cpu_online(i))
+			printk("%u ", __brlock_array[i][BR_GLOBALIRQ_LOCK]);
+	}
 	printk("]\nbh:   %d [ ",
 	       (spin_is_locked(&global_bh_lock) ? 1 : 0));
-	for (i = 0; i < smp_num_cpus; i++)
-		printk("%u ", local_bh_count(i));
+	for (i = 0; i < NR_CPUS; i++) {
+		if (cpu_online(i))
+			printk("%u ", local_bh_count(i));
+	}
 	printk("]\n");
 
 #ifdef VERBOSE_DEBUG_IRQLOCK
diff -Nru a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
--- a/arch/sparc/kernel/process.c	Sat Aug 10 18:42:21 2002
+++ b/arch/sparc/kernel/process.c	Sat Aug 10 18:42:21 2002
@@ -57,7 +57,14 @@
 extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
 
 struct task_struct *last_task_used_math = NULL;
-struct task_struct *current_set[NR_CPUS] = {&init_task, };
+struct thread_info *current_set[NR_CPUS];
+
+/*
+ * default_idle is new in 2.5. XXX Review, currently stolen from sparc64.
+ */
+void default_idle(void)
+{
+}
 
 #ifndef CONFIG_SMP
 
@@ -106,8 +113,8 @@
 			restore_flags(flags);
 		}
 
-		while((!current->need_resched) && pm_idle) {
-				(*pm_idle)();
+		while((!need_resched()) && pm_idle) {
+			(*pm_idle)();		/* XXX Huh? On sparc?! */
 		}
 
 		schedule();
@@ -139,19 +146,15 @@
 
 extern int serial_console;
 
-#ifdef CONFIG_SUN_CONSOLE
 extern void (*prom_palette)(int);
-#endif
 
 void machine_halt(void)
 {
 	sti();
 	mdelay(8);
 	cli();
-#ifdef CONFIG_SUN_CONSOLE
 	if (!serial_console && prom_palette)
 		prom_palette (1);
-#endif
 	prom_halt();
 	panic("Halt failed!");
 }
@@ -166,10 +169,8 @@
 
 	p = strchr (reboot_command, '\n');
 	if (p) *p = 0;
-#ifdef CONFIG_SUN_CONSOLE
 	if (!serial_console && prom_palette)
 		prom_palette (1);
-#endif
 	if (cmd)
 		prom_reboot(cmd);
 	if (*reboot_command)
@@ -306,7 +307,7 @@
 	if (!tsk)
 		return;
 
-	fp = tsk->thread.ksp;
+	fp = tsk->thread_info->ksp;
 	do {
 		/* Bogus frame pointer? */
 		if (fp < (task_base + sizeof(struct task_struct)) ||
@@ -321,6 +322,14 @@
 }
 
 /*
+ * Note: sparc64 has a pretty intricated thread_saved_pc, check it out.
+ */
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+	return tsk->thread_info->kpc;
+}
+
+/*
  * Free current thread data structures etc..
  */
 void exit_thread(void)
@@ -372,7 +381,7 @@
 		/* We must fixup kregs as well. */
 		current->thread.kregs = (struct pt_regs *)
 			(((unsigned long)current) +
-			 (TASK_UNION_SIZE - TRACEREG_SZ));
+			 (THREAD_SIZE - TRACEREG_SZ));
 	}
 }
 
@@ -445,6 +454,22 @@
 	return sp;
 }
 
+asmlinkage int sparc_do_fork(unsigned long clone_flags,
+                             unsigned long stack_start,
+                             struct pt_regs *regs,
+                             unsigned long stack_size)
+{
+	struct task_struct *p;
+
+	/* XXX This was spelled in DaveM's will and testament. Why? */
+	if (clone_flags & CLONE_IDLETASK) {
+		printk(KERN_DEBUG "Userland clone with CLONE_IDLETASK\n");
+		clone_flags &= ~CLONE_IDLETASK;
+	}
+
+	p = do_fork(clone_flags, stack_start, regs, stack_size);
+	return IS_ERR(p) ? PTR_ERR(p) : p->pid;
+}
 
 /* Copy a Sparc thread.  The fork() return value conventions
  * under SunOS are nothing short of bletcherous:
@@ -457,6 +482,7 @@
  *       if the parent should sleep while trying to
  *       allocate the task_struct and kernel stack in
  *       do_fork().
+ * XXX See comment above sys_vfork in sparc64. todo.
  */
 extern void ret_from_fork(void);
 
@@ -464,6 +490,7 @@
 		unsigned long unused,
 		struct task_struct *p, struct pt_regs *regs)
 {
+	struct thread_info *ti = p->thread_info;
 	struct pt_regs *childregs;
 	struct reg_window *new_stack;
 	unsigned long stack_offset;
@@ -482,19 +509,19 @@
 	}
 
 	/* Calculate offset to stack_frame & pt_regs */
-	stack_offset = TASK_UNION_SIZE - TRACEREG_SZ;
+	stack_offset = THREAD_SIZE - TRACEREG_SZ;
 
 	if(regs->psr & PSR_PS)
 		stack_offset -= REGWIN_SZ;
-	childregs = ((struct pt_regs *) (((unsigned long)p) + stack_offset));
+	childregs = ((struct pt_regs *) (((unsigned long)ti) + stack_offset));
 	copy_regs(childregs, regs);
 	new_stack = (((struct reg_window *) childregs) - 1);
 	copy_regwin(new_stack, (((struct reg_window *) regs) - 1));
 
-	p->thread.ksp = (unsigned long) new_stack;
-	p->thread.kpc = (((unsigned long) ret_from_fork) - 0x8);
-	p->thread.kpsr = current->thread.fork_kpsr;
-	p->thread.kwim = current->thread.fork_kwim;
+	ti->ksp = (unsigned long) new_stack;
+	ti->kpc = (((unsigned long) ret_from_fork) - 0x8);
+	ti->kpsr = current->thread.fork_kpsr;
+	ti->kwim = current->thread.fork_kwim;
 
 	/* This is used for sun4c only */
 	atomic_set(&p->thread.refcount, 1);
@@ -504,16 +531,14 @@
 
 		p->thread.kregs = &fake_swapper_regs;
 		new_stack = (struct reg_window *)
-			((((unsigned long)p) +
-			  (TASK_UNION_SIZE)) -
-			 (REGWIN_SZ));
+			((((unsigned long)ti) + (THREAD_SIZE)) - REGWIN_SZ);
 		childregs->u_regs[UREG_FP] = (unsigned long) new_stack;
 		p->thread.flags |= SPARC_FLAG_KTHREAD;
 		p->thread.current_ds = KERNEL_DS;
 		memcpy((void *)new_stack,
 		       (void *)regs->u_regs[UREG_FP],
 		       sizeof(struct reg_window));
-		childregs->u_regs[UREG_G6] = (unsigned long) p;
+		childregs->u_regs[UREG_G6] = (unsigned long) ti;
 	} else {
 		p->thread.kregs = childregs;
 		childregs->u_regs[UREG_FP] = sp;
diff -Nru a/arch/sparc/kernel/ptrace.c b/arch/sparc/kernel/ptrace.c
--- a/arch/sparc/kernel/ptrace.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/kernel/ptrace.c	Sat Aug 10 18:42:22 2002
@@ -92,16 +92,16 @@
 	}
 	switch(offset) {
 	case 0:
-		v = t->ksp;
+		v = tsk->thread_info->ksp;
 		break;
 	case 4:
-		v = t->kpc;
+		v = tsk->thread_info->kpc;
 		break;
 	case 8:
-		v = t->kpsr;
+		v = tsk->thread_info->kpsr;
 		break;
 	case 12:
-		v = t->uwinmask;
+		v = tsk->thread_info->uwinmask;
 		break;
 	case 832:
 		v = t->w_saved;
@@ -530,9 +530,9 @@
 		}
 
 		if (request == PTRACE_SYSCALL)
-			child->ptrace |= PT_TRACESYS;
+			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		else
-			child->ptrace &= ~PT_TRACESYS;
+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 
 		child->exit_code = data;
 #ifdef DEBUG_PTRACE
@@ -581,7 +581,7 @@
 	}
 out_tsk:
 	if (child)
-		free_task_struct(child);
+		put_task_struct(child);
 out:
 	unlock_kernel();
 }
@@ -591,8 +591,9 @@
 #ifdef DEBUG_PTRACE
 	printk("%s [%d]: syscall_trace\n", current->comm, current->pid);
 #endif
-	if ((current->ptrace & (PT_PTRACED|PT_TRACESYS))
-			!= (PT_PTRACED|PT_TRACESYS))
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		return;
+	if (!(current->ptrace & PT_PTRACED))
 		return;
 	current->exit_code = SIGTRAP;
 	current->state = TASK_STOPPED;
diff -Nru a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S
--- a/arch/sparc/kernel/rtrap.S	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/kernel/rtrap.S	Sat Aug 10 18:42:22 2002
@@ -13,6 +13,7 @@
 #include <asm/contregs.h>
 #include <asm/winmacro.h>
 #include <asm/asmmacro.h>
+#include <asm/thread_info.h>
 
 #define t_psr     l0
 #define t_pc      l1
@@ -58,17 +59,17 @@
 	 nop
 
 1:
-#error	ld	[%curptr + AOFF_task_need_resched], %g2
-	orcc	%g2, %g0, %g0
+	ld	[%curptr + TI_FLAGS], %g2
+	andcc	%g2, (_TIF_NEED_RESCHED), %g0
 	be	signal_p
-#error	 ld	[%curptr + AOFF_task_sigpending], %g2
+	 nop
 
 	call	C_LABEL(schedule)
 	 nop
 
-#error	ld	[%curptr + AOFF_task_sigpending], %g2
+	ld	[%curptr + TI_FLAGS], %g2
 signal_p:
-	cmp	%g2, 0
+	andcc	%g2, (_TIF_NOTIFY_RESUME|_TIF_SIGPENDING), %g0
 	bz,a	ret_trap_continue
 	 ld	[%sp + REGWIN_SZ + PT_PSR], %t_psr
 
@@ -98,7 +99,7 @@
 	 add	%sp, REGWIN_SZ, %o0
 
 	b	signal_p
-#error	 ld	[%curptr + AOFF_task_sigpending], %g2
+	 ld	[%curptr + TI_FLAGS], %g2
 
 ret_trap_nobufwins:
 	/* Load up the user's out registers so we can pull
@@ -109,11 +110,11 @@
 	/* If there are already live user windows in the
 	 * set we can return from trap safely.
 	 */
-	ld	[%curptr + AOFF_task_thread + AOFF_thread_uwinmask], %twin_tmp1
+	ld	[%curptr + TI_UWINMASK], %twin_tmp1
 	orcc	%g0, %twin_tmp1, %g0
 	bne	ret_trap_userwins_ok
 	 nop
-	
+
 		/* Calculate new %wim, we have to pull a register
 		 * window from the users stack.
 		 */
@@ -168,7 +169,7 @@
 	 nop
 
 	b	signal_p
-#error	 ld	[%curptr + AOFF_task_sigpending], %g2
+	 ld	[%curptr + TI_FLAGS], %g2
 
 ret_trap_kernel:
 		/* Will the rett land us in the invalid window? */
@@ -218,7 +219,8 @@
 	 add	%sp, REGWIN_SZ, %o0
 
 	b	signal_p
-#error	 ld	[%curptr + AOFF_task_sigpending], %g2
+	 ld	[%curptr + TI_FLAGS], %g2
+
 
 	.globl	C_LABEL(sun4c_rett_stackchk)
 C_LABEL(sun4c_rett_stackchk):
diff -Nru a/arch/sparc/kernel/sclow.S b/arch/sparc/kernel/sclow.S
--- a/arch/sparc/kernel/sclow.S	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc/kernel/sclow.S	Sat Aug 10 18:42:23 2002
@@ -10,6 +10,7 @@
 #include <asm/ptrace.h>
 #include <asm/errno.h>
 #include <asm/winmacro.h>
+#include <asm/thread_info.h>
 #include <asm/psr.h>
 #include <asm/page.h>
 
@@ -40,6 +41,7 @@
 	.globl	LABEL(sunosgetpid)
 LABEL(sunosgetpid):
 	LOAD_CURRENT(l4, l5)
+	ld	[%l4 + TI_TASK], %l4
 	ld	[%l4 + AOFF_task_pid], %i0
 	ld	[%l4 + AOFF_task_p_opptr], %l5
 	ld	[%l5 + AOFF_task_pid], %i1
@@ -50,6 +52,7 @@
 	.globl	LABEL(sunosgetuid)
 LABEL(sunosgetuid):
 	LOAD_CURRENT(l4, l5)
+	ld	[%l4 + TI_TASK], %l4
 	lduh	[%l4 + AOFF_task_uid], %i0
 	lduh	[%l4 + AOFF_task_euid], %i1
 	CC_AND_RETT
@@ -59,6 +62,7 @@
 	.globl	LABEL(sunosgetgid)
 LABEL(sunosgetgid):
 	LOAD_CURRENT(l4, l5)
+	ld	[%l4 + TI_TASK], %l4
 	lduh	[%l4 + AOFF_task_gid], %i0
 	lduh	[%l4 + AOFF_task_egid], %i1
 	CC_AND_RETT
@@ -77,6 +81,7 @@
 	.globl	LABEL(sunossblock)
 LABEL(sunossblock):
 	LOAD_CURRENT(l4, l5)
+	ld	[%l4 + TI_TASK], %l4
 	set	-65793, %l5
 	and	%i0, %l5, %l5
 	ld	[%l4 + AOFF_task_blocked], %i0
@@ -87,6 +92,7 @@
 	.globl	LABEL(sunossmask)
 LABEL(sunossmask):
 	LOAD_CURRENT(l4, l5)
+	ld	[%l4 + TI_TASK], %l4
 	set	-65793, %l5
 	and	%i0, %l5, %l5
 	ld	[%l4 + AOFF_task_blocked], %i0
diff -Nru a/arch/sparc/kernel/semaphore.c b/arch/sparc/kernel/semaphore.c
--- a/arch/sparc/kernel/semaphore.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/kernel/semaphore.c	Sat Aug 10 18:42:22 2002
@@ -3,6 +3,7 @@
 /* sparc32 semaphore implementation, based on i386 version */
 
 #include <linux/sched.h>
+#include <linux/errno.h>
 
 #include <asm/semaphore.h>
 
diff -Nru a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
--- a/arch/sparc/kernel/setup.c	Sat Aug 10 18:42:20 2002
+++ b/arch/sparc/kernel/setup.c	Sat Aug 10 18:42:20 2002
@@ -69,9 +69,7 @@
 extern unsigned long trapbase;
 extern int serial_console;
 extern void breakpoint(void);
-#if CONFIG_SUN_CONSOLE
 void (*prom_palette)(int);
-#endif
 asmlinkage void sys_sync(void);	/* it's really int */
 
 /* Pretty sick eh? */
@@ -87,10 +85,8 @@
 			     "nop\n\t"
 			     "nop\n\t" : : "r" (&trapbase));
 
-#ifdef CONFIG_SUN_CONSOLE
 	if (prom_palette)
 		prom_palette(1);
-#endif
 	prom_printf("PROM SYNC COMMAND...\n");
 	show_free_areas();
 	if(current->pid != 0) {
@@ -118,9 +114,7 @@
 #define BOOTME_KGDBB  0x8
 #define BOOTME_KGDB   0xc
 
-#ifdef CONFIG_SUN_CONSOLE
 static int console_fb __initdata = 0;
-#endif
 
 /* Exported for mm/init.c:paging_init. */
 unsigned long cmdline_memory_size __initdata = 0;
@@ -140,10 +134,10 @@
 }
 
 static struct console prom_debug_console = {
-	name:		"debug",
-	write:		prom_console_write,
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
+	.name =		"debug",
+	.write =	prom_console_write,
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
 };
 
 int obp_system_intr(void)
@@ -221,7 +215,6 @@
 			}
 			commands += 9;
 		} else {
-#if CONFIG_SUN_CONSOLE
 			if (!strncmp(commands, "console=", 8)) {
 				commands += 8;
 				if (!strncmp (commands, "ttya", 4)) {
@@ -242,9 +235,7 @@
 				} else {
 					console_fb = 1;
 				}
-			} else
-#endif
-			if (!strncmp(commands, "mem=", 4)) {
+			} else if (!strncmp(commands, "mem=", 4)) {
 				/*
 				 * "mem=XXX[kKmM] overrides the PROM-reported
 				 * memory size.
@@ -481,7 +472,7 @@
 		   (short) romvec->pv_printrev,
 		   &cputypval,
 		   linux_num_cpus,
-		   smp_num_cpus
+		   num_online_cpus()
 #ifndef CONFIG_SMP
 		   , loops_per_jiffy/(500000/HZ),
 		   (loops_per_jiffy/(5000/HZ)) % 100
@@ -518,8 +509,8 @@
 }
 
 struct seq_operations cpuinfo_op = {
-	start:	c_start,
-	next:	c_next,
-	stop:	c_stop,
-	show:	show_cpuinfo,
+	.start =c_start,
+	.next =	c_next,
+	.stop =	c_stop,
+	.show =	show_cpuinfo,
 };
diff -Nru a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
--- a/arch/sparc/kernel/signal.c	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc/kernel/signal.c	Sat Aug 10 18:42:23 2002
@@ -19,6 +19,7 @@
 #include <linux/tty.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/binfmts.h>	/* do_coredum */
 
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
@@ -26,6 +27,7 @@
 #include <asm/svr4.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
+#include <asm/cacheflush.h>	/* flush_sig_insns */
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
@@ -34,7 +36,7 @@
 extern void fpload(unsigned long *fpregs, unsigned long *fsr);
 
 asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
-			 unsigned long orig_o0, int ret_from_syscall);
+			 unsigned long orig_o0, int restart_syscall);
 
 /* This turned off for production... */
 /* #define DEBUG_SIGNALS 1 */
@@ -229,7 +231,7 @@
 {
 	int err;
 #ifdef CONFIG_SMP
-	if (current->flags & PF_USEDFPU)
+	if (test_tsk_thread_flag(current, TIF_USEDFPU))
 		regs->psr &= ~PSR_EF;
 #else
 	if (current == last_task_used_math) {
@@ -238,8 +240,8 @@
 	}
 #endif
 	current->used_math = 1;
-	current->flags &= ~PF_USEDFPU;
-	
+	clear_tsk_thread_flag(current, TIF_USEDFPU);
+
 	if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
 		return -EFAULT;
 
@@ -586,12 +588,12 @@
 {
 	int err = 0;
 #ifdef CONFIG_SMP
-	if (current->flags & PF_USEDFPU) {
+	if (test_tsk_thread_flag(current, TIF_USEDFPU)) {
 		put_psr(get_psr() | PSR_EF);
 		fpsave(&current->thread.float_regs[0], &current->thread.fsr,
 		       &current->thread.fpqueue[0], &current->thread.fpqdepth);
 		regs->psr &= ~(PSR_EF);
-		current->flags &= ~(PF_USEDFPU);
+		clear_tsk_thread_flag(current, TIF_USEDFPU);
 	}
 #else
 	if (current == last_task_used_math) {
@@ -1295,7 +1297,7 @@
 				/* fall through */
 			default:
 				sigaddset(&current->pending.signal, signr);
-				recalc_sigpending(current);
+				recalc_sigpending();
 				current->flags |= PF_SIGNALED;
 				do_exit(exit_code);
 				/* NOT REACHED */
diff -Nru a/arch/sparc/kernel/sparc-stub.c b/arch/sparc/kernel/sparc-stub.c
--- a/arch/sparc/kernel/sparc-stub.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/kernel/sparc-stub.c	Sat Aug 10 18:42:22 2002
@@ -109,6 +109,8 @@
 #include <asm/kgdb.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
+#include <asm/cacheflush.h>
+
 /*
  *
  * external low-level support routines
diff -Nru a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
--- a/arch/sparc/kernel/sparc_ksyms.c	Sat Aug 10 18:42:21 2002
+++ b/arch/sparc/kernel/sparc_ksyms.c	Sat Aug 10 18:42:21 2002
@@ -142,7 +142,6 @@
 EXPORT_SYMBOL(__global_restore_flags);
 
 /* Misc SMP information */
-EXPORT_SYMBOL(smp_num_cpus);
 EXPORT_SYMBOL(__cpu_number_map);
 EXPORT_SYMBOL(__cpu_logical_map);
 #endif
diff -Nru a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
--- a/arch/sparc/kernel/sun4d_irq.c	Sat Aug 10 18:42:19 2002
+++ b/arch/sparc/kernel/sun4d_irq.c	Sat Aug 10 18:42:19 2002
@@ -99,9 +99,11 @@
 #ifndef CONFIG_SMP
 		seq_printf(p, "%10u ", kstat_irqs(i));
 #else
-		for (x = 0; x < smp_num_cpus; x++)
-			seq_printf(p, "%10u ",
+		for (x = 0; x < NR_CPUS; x++) {
+			if (cpu_online)
+				seq_printf(p, "%10u ",
 				       kstat.irqs[cpu_logical_map(x)][i]);
+		}
 #endif
 		seq_printf(p, "%c %s",
 			(action->flags & SA_INTERRUPT) ? '+' : ' ',
diff -Nru a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
--- a/arch/sparc/kernel/sun4d_smp.c	Sat Aug 10 18:42:21 2002
+++ b/arch/sparc/kernel/sun4d_smp.c	Sat Aug 10 18:42:21 2002
@@ -43,7 +43,6 @@
 
 extern void calibrate_delay(void);
 
-extern struct task_struct *current_set[NR_CPUS];
 extern volatile int smp_processors_ready;
 extern unsigned long cpu_present_map;
 extern int smp_num_cpus;
diff -Nru a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
--- a/arch/sparc/kernel/sun4m_smp.c	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc/kernel/sun4m_smp.c	Sat Aug 10 18:42:23 2002
@@ -40,7 +40,6 @@
 
 extern void calibrate_delay(void);
 
-extern struct task_struct *current_set[NR_CPUS];
 extern volatile int smp_processors_ready;
 extern unsigned long cpu_present_map;
 extern int smp_num_cpus;
diff -Nru a/arch/sparc/kernel/trampoline.S b/arch/sparc/kernel/trampoline.S
--- a/arch/sparc/kernel/trampoline.S	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/kernel/trampoline.S	Sat Aug 10 18:42:22 2002
@@ -63,8 +63,8 @@
 	and	%g4, 0xc, %g4
 	ld	[%g5 + %g4], %g6
 
-	sethi	%hi(TASK_UNION_SIZE - REGWIN_SZ), %sp
-	or	%sp, %lo(TASK_UNION_SIZE - REGWIN_SZ), %sp
+	sethi	%hi(THREAD_SIZE - REGWIN_SZ), %sp
+	or	%sp, %lo(THREAD_SIZE - REGWIN_SZ), %sp
 	add	%g6, %sp, %sp
 
 	/* Turn on traps (PSR_ET). */
@@ -142,8 +142,8 @@
 	srl	%g3, 1, %g4
 	ld	[%g5 + %g4], %g6
 
-	sethi	%hi(TASK_UNION_SIZE - REGWIN_SZ), %sp
-	or	%sp, %lo(TASK_UNION_SIZE - REGWIN_SZ), %sp
+	sethi	%hi(THREAD_SIZE - REGWIN_SZ), %sp
+	or	%sp, %lo(THREAD_SIZE - REGWIN_SZ), %sp
 	add	%g6, %sp, %sp
 
 	/* Turn on traps (PSR_ET). */
diff -Nru a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
--- a/arch/sparc/kernel/traps.c	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc/kernel/traps.c	Sat Aug 10 18:42:23 2002
@@ -475,6 +475,23 @@
 
 void trap_init(void)
 {
+	extern void thread_info_offsets_are_bolixed_pete(void);
+
+	/* Force linker to barf if mismatched */
+	if (TI_UWINMASK    != offsetof(struct thread_info, uwinmask) ||
+	    TI_TASK        != offsetof(struct thread_info, task) ||
+	    TI_EXECDOMAIN  != offsetof(struct thread_info, exec_domain) ||
+	    TI_FLAGS       != offsetof(struct thread_info, flags) ||
+	    TI_CPU         != offsetof(struct thread_info, cpu) ||
+	    TI_PREEMPT     != offsetof(struct thread_info, preempt_count) ||
+	    TI_SOFTIRQ     != offsetof(struct thread_info, softirq_count) ||
+	    TI_HARDIRQ     != offsetof(struct thread_info, hardirq_count) ||
+	    TI_KSP         != offsetof(struct thread_info, ksp) ||
+	    TI_KPC         != offsetof(struct thread_info, kpc) ||
+	    TI_KPSR        != offsetof(struct thread_info, kpsr) ||
+	    TI_KWIM        != offsetof(struct thread_info, kwim))
+		thread_info_offsets_are_bolixed_pete();
+
 	/* Attach to the address space of init_task. */
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
diff -Nru a/arch/sparc/kernel/windows.c b/arch/sparc/kernel/windows.c
--- a/arch/sparc/kernel/windows.c	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc/kernel/windows.c	Sat Aug 10 18:42:23 2002
@@ -32,7 +32,7 @@
 		" restore %%g0, %%g0, %%g0\n"
 	: "=&r" (ctr)
 	: "0" (ctr),
-	  "i" ((const unsigned long)(&(((struct task_struct *)0)->thread.uwinmask)))
+	  "i" ((const unsigned long)TI_UWINMASK)
 	: "g4", "cc");
 }
 
diff -Nru a/arch/sparc/kernel/wof.S b/arch/sparc/kernel/wof.S
--- a/arch/sparc/kernel/wof.S	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc/kernel/wof.S	Sat Aug 10 18:42:23 2002
@@ -13,6 +13,7 @@
 #include <asm/asi.h>
 #include <asm/winmacro.h>
 #include <asm/asmmacro.h>
+#include <asm/thread_info.h>
 
 /* WARNING: This routine is hairy and _very_ complicated, but it
  *          must be as fast as possible as it handles the allocation
@@ -62,7 +63,7 @@
 	 * andcc %l0, PSR_PS, %g0
 	 */
 
-	/* Datum current->thread.uwinmask contains at all times a bitmask
+	/* Datum current_thread_info->uwinmask contains at all times a bitmask
 	 * where if any user windows are active, at least one bit will
 	 * be set in to mask.  If no user windows are active, the bitmask
 	 * will be all zeroes.
@@ -96,10 +97,10 @@
 	 save	%g0, %g0, %g0				! Go where saving will occur
 	
 	/* See if any user windows are active in the set. */
-	ld	[%curptr + AOFF_task_thread + AOFF_thread_uwinmask], %twin_tmp	! grab win mask
+	ld	[%curptr + TI_UWINMASK], %twin_tmp	! grab win mask
 	orcc	%g0, %twin_tmp, %g0			! check for set bits
 	bne	spwin_exist_uwins			! yep, there are some
-	 andn	%twin_tmp, %glob_tmp, %twin_tmp		! compute new umask
+	 andn	%twin_tmp, %glob_tmp, %twin_tmp		! compute new uwinmask
 
 	/* Save into the window which must be saved and do it.
 	 * Basically if we are here, this means that we trapped
@@ -139,7 +140,7 @@
 	 * But first, store the new user window mask calculated
 	 * above.
 	 */
-	st	%twin_tmp, [%curptr + AOFF_task_thread + AOFF_thread_uwinmask]
+	st	%twin_tmp, [%curptr + TI_UWINMASK]
 	save	%g0, %g0, %g0		! Go to where the saving will occur
 
 spwin_fromuser:
@@ -209,18 +210,20 @@
 	bne	spwin_bad_ustack_from_kernel
 	 nop
 
+	ld	[%curptr + TI_TASK], %glob_tmp
+
 	/* Oh well, throw this one window into the per-task window
 	 * buffer, the first one.
 	 */
-	st	%sp, [%curptr + AOFF_task_thread + AOFF_thread_rwbuf_stkptrs]
-	STORE_WINDOW(curptr + AOFF_task_thread + AOFF_thread_reg_window)
+	st	%sp, [%glob_tmp + AOFF_task_thread + AOFF_thread_rwbuf_stkptrs]
+	STORE_WINDOW(glob_tmp + AOFF_task_thread + AOFF_thread_reg_window)
 	restore	%g0, %g0, %g0
 
 	/* LOCATION: Trap Window */
 
 	/* Back in the trap window, update winbuffer save count. */
-	mov	1, %glob_tmp
-	st	%glob_tmp, [%curptr + AOFF_task_thread + AOFF_thread_w_saved]
+	mov	1, %twin_tmp
+	st	%twin_tmp, [%glob_tmp + AOFF_task_thread + AOFF_thread_w_saved]
 
 		/* Compute new user window mask.  What we are basically
 		 * doing is taking two windows, the invalid one at trap
@@ -232,9 +235,9 @@
 		or	%twin_tmp, %t_wim, %twin_tmp
 		not	%twin_tmp
 spnwin_patch3:	and	%twin_tmp, 0xff, %twin_tmp	! patched on 7win Sparcs
-		st	%twin_tmp, [%curptr + AOFF_task_thread + AOFF_thread_uwinmask]
+		st	%twin_tmp, [%curptr + TI_UWINMASK]
 
-#define STACK_OFFSET	(TASK_UNION_SIZE - TRACEREG_SZ - REGWIN_SZ)
+#define STACK_OFFSET	(THREAD_SIZE - TRACEREG_SZ - REGWIN_SZ)
 
 	sethi	%hi(STACK_OFFSET), %sp
 	or	%sp, %lo(STACK_OFFSET), %sp
@@ -247,7 +250,7 @@
 
 	sethi	%hi(STACK_OFFSET), %g6
 	or	%g6, %lo(STACK_OFFSET), %g6
-	sub	%sp, %g6, %g6
+	sub	%sp, %g6, %g6		! curptr
 
 	/* Turn on traps and call c-code to deal with it. */
 	wr	%t_psr, PSR_ET, %psr
@@ -271,7 +274,8 @@
 	 * a per-process window buffer until we can properly handle
 	 * this later on.
 	 */
-	SAVE_BOLIXED_USER_STACK(curptr, glob_tmp)
+	ld	[%curptr + TI_TASK], %glob_tmp	/* Using curptr one last time */
+	SAVE_BOLIXED_USER_STACK(glob_tmp, g6)	/* ...now using g6 as scratch */
 	restore	%g0, %g0, %g0
 
 	/* LOCATION: Trap window */
diff -Nru a/arch/sparc/kernel/wuf.S b/arch/sparc/kernel/wuf.S
--- a/arch/sparc/kernel/wuf.S	Sat Aug 10 18:42:19 2002
+++ b/arch/sparc/kernel/wuf.S	Sat Aug 10 18:42:19 2002
@@ -13,6 +13,7 @@
 #include <asm/asi.h>
 #include <asm/winmacro.h>
 #include <asm/asmmacro.h>
+#include <asm/thread_info.h>
 
 /* Just like the overflow handler we define macros for registers
  * with fixed meanings in this routine.
@@ -40,7 +41,7 @@
 	 * andcc %l0, PSR_PS, %g0
 	 */
 
-	/* Datum current->thread.uwinmask contains at all times a bitmask
+	/* Datum current_thread_info->uwinmask contains at all times a bitmask
 	 * where if any user windows are active, at least one bit will
 	 * be set in to mask.  If no user windows are active, the bitmask
 	 * will be all zeroes.
@@ -138,7 +139,7 @@
 C_LABEL(fwin_mmu_patchme):	b	C_LABEL(sun4c_fwin_stackchk)
 				 andcc	%sp, 0x7, %g0
 
-#define STACK_OFFSET (TASK_UNION_SIZE - TRACEREG_SZ - REGWIN_SZ)
+#define STACK_OFFSET (THREAD_SIZE - TRACEREG_SZ - REGWIN_SZ)
 
 fwin_user_stack_is_bolixed:
 	/* LOCATION: Window 'W' */
@@ -184,8 +185,9 @@
 	/* Fix users window mask and buffer save count. */
 	mov	0x1, %g5
 	sll	%g5, %g3, %g5
-	st	%g5, [%curptr + AOFF_task_thread + AOFF_thread_uwinmask]		! one live user window still
-	st	%g0, [%curptr + AOFF_task_thread + AOFF_thread_w_saved]		! no windows in the buffer
+	st	%g5, [%curptr + TI_UWINMASK]		! one live user window still
+	ld	[%curptr + TI_TASK], %g5
+	st	%g0, [%g5 + AOFF_task_thread + AOFF_thread_w_saved]		! no windows in the buffer
 
 	wr	%t_psr, PSR_ET, %psr			! enable traps
 	nop
diff -Nru a/arch/sparc/mm/btfixup.c b/arch/sparc/mm/btfixup.c
--- a/arch/sparc/mm/btfixup.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/mm/btfixup.c	Sat Aug 10 18:42:22 2002
@@ -15,6 +15,7 @@
 #include <asm/pgtable.h>
 #include <asm/oplib.h>
 #include <asm/system.h>
+#include <asm/cacheflush.h>
 
 #define BTFIXUP_OPTIMIZE_NOP
 #define BTFIXUP_OPTIMIZE_OTHER
diff -Nru a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
--- a/arch/sparc/mm/fault.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/mm/fault.c	Sat Aug 10 18:42:22 2002
@@ -138,8 +138,8 @@
                      struct pt_regs *regs)
 {
 	if((unsigned long) address < PAGE_SIZE) {
-		printk(KERN_ALERT "Unable to handle kernel NULL "
-		       "pointer dereference");
+		printk(KERN_ALERT
+		    "Unable to handle kernel NULL pointer dereference\n");
 	} else {
 		printk(KERN_ALERT "Unable to handle kernel paging request "
 		       "at virtual address %08lx\n", address);
@@ -401,7 +401,7 @@
 {
 	extern void sun4c_update_mmu_cache(struct vm_area_struct *,
 					   unsigned long,pte_t);
-	extern pte_t *sun4c_pte_offset(pmd_t *,unsigned long);
+	extern pte_t *sun4c_pte_offset_kernel(pmd_t *,unsigned long);
 	struct task_struct *tsk = current;
 	struct mm_struct *mm = tsk->mm;
 	pgd_t *pgdp;
@@ -421,7 +421,7 @@
 	}
 
 	pgdp = pgd_offset(mm, address);
-	ptep = sun4c_pte_offset((pmd_t *) pgdp, address);
+	ptep = sun4c_pte_offset_kernel((pmd_t *) pgdp, address);
 
 	if (pgd_val(*pgdp)) {
 	    if (write) {
diff -Nru a/arch/sparc/mm/generic.c b/arch/sparc/mm/generic.c
--- a/arch/sparc/mm/generic.c	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc/mm/generic.c	Sat Aug 10 18:42:23 2002
@@ -16,6 +16,7 @@
 
 static inline void forget_pte(pte_t page)
 {
+#if 0 /* old 2.4 code */
 	if (pte_none(page))
 		return;
 	if (pte_present(page)) {
@@ -30,6 +31,12 @@
 		return;
 	}
 	swap_free(pte_to_swp_entry(page));
+#else
+	if (!pte_none(page)) {
+		printk("forget_pte: old mapping existed!\n");
+		BUG();
+	}
+#endif
 }
 
 /* Remap IO memory, the same way as remap_page_range(), but use
@@ -69,7 +76,7 @@
 		end = PGDIR_SIZE;
 	offset -= address;
 	do {
-		pte_t * pte = pte_alloc(current->mm, pmd, address);
+		pte_t * pte = pte_alloc_map(current->mm, pmd, address);
 		if (!pte)
 			return -ENOMEM;
 		io_remap_pte_range(pte, address, end - address, address + offset, prot, space);
diff -Nru a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
--- a/arch/sparc/mm/init.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/mm/init.c	Sat Aug 10 18:42:22 2002
@@ -31,6 +31,7 @@
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/vaddrs.h>
+#include <asm/pgalloc.h>	/* bug in asm-generic/tlb.h: check_pgt_cache */
 #include <asm/tlb.h>
 
 mmu_gather_t mmu_gathers[NR_CPUS];
@@ -59,7 +60,7 @@
 pgprot_t kmap_prot;
 
 #define kmap_get_fixed_pte(vaddr) \
-	pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+	pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
 
 void __init kmap_init(void)
 {
@@ -76,11 +77,13 @@
 	       nr_swap_pages << (PAGE_SHIFT-10));
 	printk("%ld pages of RAM\n", totalram_pages);
 	printk("%d free pages\n", nr_free_pages());
+#if 0 /* undefined pgtable_cache_size, pgd_cache_size */
 	printk("%ld pages in page table cache\n",pgtable_cache_size);
 #ifndef CONFIG_SMP
 	if (sparc_cpu_model == sun4m || sparc_cpu_model == sun4d)
 		printk("%ld entries in page dir cache\n",pgd_cache_size);
 #endif	
+#endif
 }
 
 extern pgprot_t protection_map[16];
@@ -306,6 +309,23 @@
 	*pages_avail -= PAGE_ALIGN(size) >> PAGE_SHIFT;
 
 	return max_pfn;
+}
+
+/*
+ * check_pgt_cache
+ *
+ * This is called at the end of unmapping of VMA (zap_page_range),
+ * to rescan the page cache for architecture specific things,
+ * presumably something like sun4/sun4c PMEGs. Most architectures
+ * define check_pgt_cache empty.
+ *
+ * We simply copy the 2.4 implementation for now.
+ */
+int pgt_cache_water[2] = { 25, 50 };
+
+void check_pgt_cache(void)
+{
+	do_check_pgt_cache(pgt_cache_water[0], pgt_cache_water[1]);
 }
 
 /*
diff -Nru a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
--- a/arch/sparc/mm/io-unit.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/mm/io-unit.c	Sat Aug 10 18:42:22 2002
@@ -9,6 +9,9 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/highmem.h>	/* pte_offset_map => kmap_atomic */
+
 #include <asm/scatterlist.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
@@ -17,6 +20,8 @@
 #include <asm/io-unit.h>
 #include <asm/mxcc.h>
 #include <asm/bitops.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
 
 /* #define IOUNIT_DEBUG */
 #ifdef IOUNIT_DEBUG
@@ -188,7 +193,7 @@
 
 			pgdp = pgd_offset(init_task.mm, addr);
 			pmdp = pmd_offset(pgdp, addr);
-			ptep = pte_offset(pmdp, addr);
+			ptep = pte_offset_map(pmdp, addr);
 
 			set_pte(ptep, pte_val(mk_pte(virt_to_page(page), dvma_prot)));
 			
diff -Nru a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
--- a/arch/sparc/mm/iommu.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc/mm/iommu.c	Sat Aug 10 18:42:22 2002
@@ -1,8 +1,8 @@
-/* $Id: iommu.c,v 1.22 2001/12/17 07:05:09 davem Exp $
+/*
  * iommu.c:  IOMMU specific routines for memory management.
  *
  * Copyright (C) 1995 David S. Miller  (davem@caip.rutgers.edu)
- * Copyright (C) 1995 Pete Zaitcev
+ * Copyright (C) 1995,2002 Pete Zaitcev     (zaitcev@yahoo.com)
  * Copyright (C) 1996 Eddie C. Dost    (ecd@skynet.be)
  * Copyright (C) 1997,1998 Jakub Jelinek    (jj@sunsite.mff.cuni.cz)
  */
@@ -12,6 +12,8 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/highmem.h>	/* pte_offset_map => kmap_atomic */
+
 #include <asm/scatterlist.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
@@ -19,6 +21,8 @@
 #include <asm/io.h>
 #include <asm/mxcc.h>
 #include <asm/mbus.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
 
 /* srmmu.c */
 extern int viking_mxcc_present;
@@ -245,7 +249,8 @@
 
 			pgdp = pgd_offset(&init_mm, addr);
 			pmdp = pmd_offset(pgdp, addr);
-			ptep = pte_offset(pmdp, addr);
+			ptep = pte_offset_map(pmdp, addr);
+			/* XXX What if we run out of atomic maps above */
 
 			set_pte(ptep, mk_pte(virt_to_page(page), dvma_prot));
 			if (ipte_cache != 0) {
diff -Nru a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
--- a/arch/sparc/mm/srmmu.c	Sat Aug 10 18:42:20 2002
+++ b/arch/sparc/mm/srmmu.c	Sat Aug 10 18:42:20 2002
@@ -1,8 +1,8 @@
-/* $Id: srmmu.c,v 1.234 2001/12/21 04:56:15 davem Exp $
+/*
  * srmmu.c:  SRMMU specific routines for memory management.
  *
  * Copyright (C) 1995 David S. Miller  (davem@caip.rutgers.edu)
- * Copyright (C) 1995 Pete Zaitcev
+ * Copyright (C) 1995,2002 Pete Zaitcev (zaitcev@yahoo.com)
  * Copyright (C) 1996 Eddie C. Dost    (ecd@skynet.be)
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  * Copyright (C) 1999,2000 Anton Blanchard (anton@samba.org)
@@ -132,11 +132,32 @@
 static inline unsigned long srmmu_pgd_page(pgd_t pgd)
 { return srmmu_device_memory(pgd_val(pgd))?~0:(unsigned long)__nocache_va((pgd_val(pgd) & SRMMU_PTD_PMASK) << 4); }
 
-static inline unsigned long srmmu_pmd_page(pmd_t pmd)
-{ return srmmu_device_memory(pmd_val(pmd))?~0:(unsigned long)__nocache_va((pmd_val(pmd) & SRMMU_PTD_PMASK) << 4); }
+static inline unsigned long srmmu_pmd_page_kernel(pmd_t pmd)
+{
+	return (unsigned long)
+	    __nocache_va((pmd_val(pmd) & SRMMU_PTD_PMASK) << 4);
+}
 
-static inline struct page *srmmu_pte_page(pte_t pte)
-{ return (mem_map + (unsigned long)(srmmu_device_memory(pte_val(pte))?~0:(((pte_val(pte) & SRMMU_PTE_PMASK) << 4) >> PAGE_SHIFT))); }
+static struct page *srmmu_pmd_page(pmd_t pmd)	/* XXX inline later */
+{
+
+	if (srmmu_device_memory(pmd_val(pmd))) {
+		/* XXX Anton obviously had something in mind when he did this.
+		 * But what?
+		 */
+		/* return (struct page *)~0; */
+		BUG();	/* NO WAY */
+	}
+	return virt_to_page(srmmu_pmd_page_kernel(pmd));
+}
+
+static inline unsigned long srmmu_pte_pfn(pte_t pte)
+{
+	if (srmmu_device_memory(pte_val(pte)))
+		BUG();
+	return (unsigned long)
+	    (((pte_val(pte) & SRMMU_PTE_PMASK) << 4) >> PAGE_SHIFT);
+}
 
 static inline int srmmu_pte_none(pte_t pte)
 { return !(pte_val(pte) & 0xFFFFFFF); }
@@ -219,7 +240,16 @@
 { srmmu_set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) pmdp) >> 4))); }
 
 static inline void srmmu_pmd_set(pmd_t * pmdp, pte_t * ptep)
-{ srmmu_set_pte((pte_t *)pmdp, (SRMMU_ET_PTD | (__nocache_pa((unsigned long) ptep) >> 4))); }
+{
+	srmmu_set_pte((pte_t *)pmdp,
+	    (SRMMU_ET_PTD | (__nocache_pa((unsigned long) ptep) >> 4)));
+}
+
+static inline void srmmu_pmd_populate(pmd_t * pmdp, struct page * ptep)
+{
+	srmmu_set_pte((pte_t *)pmdp,
+	    (SRMMU_ET_PTD | (((ptep - mem_map) << PAGE_SHIFT) >> 4)));
+}
 
 static inline pte_t srmmu_pte_modify(pte_t pte, pgprot_t newprot)
 { return __pte((pte_val(pte) & SRMMU_CHG_MASK) | pgprot_val(newprot)); }
@@ -234,7 +264,13 @@
 
 /* Find an entry in the third-level page table.. */ 
 static inline pte_t *srmmu_pte_offset(pmd_t * dir, unsigned long address)
-{ return (pte_t *) srmmu_pmd_page(*dir) + ((address >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE - 1)); }
+{
+	unsigned long pte;
+
+	pte = srmmu_pmd_page_kernel(*dir);
+	return (pte_t *) pte +
+			((address >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE - 1));
+}
 
 unsigned long __srmmu_get_nocache(int size, int align)
 {
@@ -387,14 +423,14 @@
 	srmmu_free_nocache((unsigned long)pgd, SRMMU_PGD_TABLE_SIZE);
 }
 
-static pte_t *srmmu_pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
+static pte_t *srmmu_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
 	return (pte_t *)srmmu_get_nocache(SRMMU_PTE_TABLE_SIZE, SRMMU_PTE_TABLE_SIZE);
 }
 
-static pte_t *srmmu_pte_alloc_one(struct mm_struct *mm, unsigned long address)
+static struct page *srmmu_pte_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-	return NULL;
+	return virt_to_page(srmmu_pte_alloc_one_kernel(mm, address));
 }
 
 static void srmmu_free_pte_fast(pte_t *pte)
@@ -402,6 +438,11 @@
 	srmmu_free_nocache((unsigned long)pte, SRMMU_PTE_TABLE_SIZE);
 }
 
+static void srmmu_pte_free(struct page *pte)
+{
+	srmmu_free_nocache((unsigned long)page_address(pte), SRMMU_PTE_TABLE_SIZE);
+}
+
 static pmd_t *srmmu_pmd_alloc_one_fast(struct mm_struct *mm, unsigned long address)
 {
 	return (pmd_t *)srmmu_get_nocache(SRMMU_PMD_TABLE_SIZE, SRMMU_PMD_TABLE_SIZE);
@@ -517,19 +558,15 @@
  * mappings on the kernel stack without any special code as we did
  * need on the sun4c.
  */
-struct task_struct *srmmu_alloc_task_struct(void)
-{
-	return (struct task_struct *) __get_free_pages(GFP_KERNEL, 1);
-}
-
-static void srmmu_free_task_struct(struct task_struct *tsk)
+struct thread_info *srmmu_alloc_thread_info(void)
 {
-	free_pages((unsigned long)tsk, 1);
+	return (struct thread_info *)
+	    __get_free_pages(GFP_KERNEL, THREAD_INFO_ORDER);
 }
 
-static void srmmu_get_task_struct(struct task_struct *tsk)
+static void srmmu_free_thread_info(struct thread_info *ti)
 {
-	atomic_inc(&virt_to_page(tsk)->count);
+	free_pages((unsigned long)ti, THREAD_INFO_ORDER);
 }
 
 /* tsunami.S */
@@ -1170,8 +1207,8 @@
 	srmmu_allocate_ptable_skeleton(PKMAP_BASE, PKMAP_BASE_END);
 
 	pgd = pgd_offset_k(PKMAP_BASE);
-	pmd = pmd_offset(pgd, PKMAP_BASE);
-	pte = pte_offset(pmd, PKMAP_BASE);
+	pmd = srmmu_pmd_offset(pgd, PKMAP_BASE);
+	pte = srmmu_pte_offset(pmd, PKMAP_BASE);
 	pkmap_page_table = pte;
 
 	flush_cache_all();
@@ -1209,6 +1246,10 @@
 		free_area_init_node(0, NULL, NULL, zones_size,
 				    phys_base, zholes_size);
 	}
+
+/* P3: easy to fix, todo. Current code is utterly broken, though. */
+	if (phys_base != 0)
+		panic("phys_base nonzero");
 }
 
 static void srmmu_mmu_info(struct seq_file *m)
@@ -1282,7 +1323,7 @@
 			if(vac_line_size < min_line_size)
 				min_line_size = vac_line_size;
 			cpu++;
-			if(cpu == smp_num_cpus)
+			if (cpu >= NR_CPUS || !cpu_online(cpu))
 				break;
 #else
 			break;
@@ -1944,9 +1985,8 @@
 }
 
 /* dont laugh, static pagetables */
-static int srmmu_check_pgt_cache(int low, int high)
+static void srmmu_check_pgt_cache(int low, int high)
 {
-	return 0;
 }
 
 extern unsigned long spwin_mmu_patchme, fwin_mmu_patchme,
@@ -2017,16 +2057,16 @@
 #ifndef CONFIG_SMP	
 	BTFIXUPSET_CALL(___xchg32, ___xchg32_sun4md, BTFIXUPCALL_SWAPG1G2);
 #endif
-	BTFIXUPSET_CALL(do_check_pgt_cache, srmmu_check_pgt_cache, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(do_check_pgt_cache, srmmu_check_pgt_cache, BTFIXUPCALL_NOP);
 
 	BTFIXUPSET_CALL(set_pte, srmmu_set_pte, BTFIXUPCALL_SWAPO0O1);
 	BTFIXUPSET_CALL(switch_mm, srmmu_switch_mm, BTFIXUPCALL_NORM);
 
-	BTFIXUPSET_CALL(pte_page, srmmu_pte_page, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(pte_pfn, srmmu_pte_pfn, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM);
 
-	BTFIXUPSET_SETHI(none_mask, 0xF0000000); /* XXX P3: is it used? */
+	BTFIXUPSET_SETHI(none_mask, 0xF0000000);
 
 	BTFIXUPSET_CALL(pte_present, srmmu_pte_present, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_SWAPO0G0);
@@ -2041,16 +2081,18 @@
 	BTFIXUPSET_CALL(pgd_clear, srmmu_pgd_clear, BTFIXUPCALL_SWAPO0G0);
 
 	BTFIXUPSET_CALL(mk_pte, srmmu_mk_pte, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(pfn_pte, srmmu_pfn_pte, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(mk_pte_phys, srmmu_mk_pte_phys, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(mk_pte_io, srmmu_mk_pte_io, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(pgd_set, srmmu_pgd_set, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(pmd_set, srmmu_pmd_set, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(pmd_populate, srmmu_pmd_populate, BTFIXUPCALL_NORM);
 	
 	BTFIXUPSET_INT(pte_modify_mask, SRMMU_CHG_MASK);
 	BTFIXUPSET_CALL(pmd_offset, srmmu_pmd_offset, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(pte_offset, srmmu_pte_offset, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(pte_offset_kernel, srmmu_pte_offset, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(free_pte_fast, srmmu_free_pte_fast, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(pte_alloc_one_fast, srmmu_pte_alloc_one_fast, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(pte_free, srmmu_pte_free, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(pte_alloc_one_kernel, srmmu_pte_alloc_one_kernel, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(pte_alloc_one, srmmu_pte_alloc_one, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(free_pmd_fast, srmmu_free_pmd_fast, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(pmd_alloc_one_fast, srmmu_pmd_alloc_one_fast, BTFIXUPCALL_NORM);
@@ -2071,10 +2113,8 @@
 	
 	BTFIXUPSET_CALL(mmu_info, srmmu_mmu_info, BTFIXUPCALL_NORM);
 
-	/* Task struct and kernel stack allocating/freeing. */
-	BTFIXUPSET_CALL(alloc_task_struct, srmmu_alloc_task_struct, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(free_task_struct, srmmu_free_task_struct, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(get_task_struct, srmmu_get_task_struct, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(alloc_thread_info, srmmu_alloc_thread_info, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(free_thread_info, srmmu_free_thread_info, BTFIXUPCALL_NORM);
 
 	get_srmmu_type();
 	patch_window_trap_handlers();
diff -Nru a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
--- a/arch/sparc/mm/sun4c.c	Sat Aug 10 18:42:21 2002
+++ b/arch/sparc/mm/sun4c.c	Sat Aug 10 18:42:21 2002
@@ -36,6 +36,8 @@
 #include <asm/sun4paddr.h>
 #include <asm/highmem.h>
 #include <asm/btfixup.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
 
 /* Because of our dynamic kernel TLB miss strategy, and how
  * our DVMA mapping allocation works, you _MUST_:
@@ -43,7 +45,7 @@
  * 1) Disable interrupts _and_ not touch any dynamic kernel
  *    memory while messing with kernel MMU state.  By
  *    dynamic memory I mean any object which is not in
- *    the kernel image itself or a task_struct (both of
+ *    the kernel image itself or a thread_union (both of
  *    which are locked into the MMU).
  * 2) Disable interrupts while messing with user MMU state.
  */
@@ -1015,27 +1017,21 @@
 	free_locked_segment(BUCKET_ADDR(entry));
 }
 
-#ifdef CONFIG_SUN4
-#define TASK_STRUCT_ORDER	0
-#else
-#define TASK_STRUCT_ORDER	1
-#endif
-
-static struct task_struct *sun4c_alloc_task_struct(void)
+static struct thread_info *sun4c_alloc_thread_info(void)
 {
 	unsigned long addr, pages;
 	int entry;
 
-	pages = __get_free_pages(GFP_KERNEL, TASK_STRUCT_ORDER);
+	pages = __get_free_pages(GFP_KERNEL, THREAD_INFO_ORDER);
 	if (!pages)
-		return (struct task_struct *) 0;
+		return NULL;
 
 	for (entry = sun4c_lowbucket_avail; entry < NR_TASK_BUCKETS; entry++)
 		if (sun4c_bucket[entry] == BUCKET_EMPTY)
 			break;
 	if (entry == NR_TASK_BUCKETS) {
-		free_pages(pages, TASK_STRUCT_ORDER);
-		return (struct task_struct *) 0;
+		free_pages(pages, THREAD_INFO_ORDER);
+		return NULL;
 	}
 	if (entry >= sun4c_lowbucket_avail)
 		sun4c_lowbucket_avail = entry + 1;
@@ -1057,46 +1053,43 @@
 #ifndef CONFIG_SUN4	
 	sun4c_put_pte(addr + PAGE_SIZE, BUCKET_PTE(pages + PAGE_SIZE));
 #endif
-	return (struct task_struct *) addr;
+	return (struct thread_info *) addr;
 }
 
-static void sun4c_free_task_struct(struct task_struct *tsk)
+static void sun4c_free_thread_info(struct thread_info *ti)
 {
-	unsigned long tsaddr = (unsigned long) tsk;
-	unsigned long pages = BUCKET_PTE_PAGE(sun4c_get_pte(tsaddr));
-	int entry = BUCKET_NUM(tsaddr);
+	unsigned long tiaddr = (unsigned long) ti;
+	unsigned long pages = BUCKET_PTE_PAGE(sun4c_get_pte(tiaddr));
+	int entry = BUCKET_NUM(tiaddr);
 
-	if (atomic_dec_and_test(&(tsk)->thread.refcount)) {
+	if (atomic_dec_and_test(&ti->task->thread.refcount)) {
 		/* We are deleting a mapping, so the flush here is mandatory. */
-		sun4c_flush_page(tsaddr);
+		sun4c_flush_page(tiaddr);
 #ifndef CONFIG_SUN4	
-		sun4c_flush_page(tsaddr + PAGE_SIZE);
+		sun4c_flush_page(tiaddr + PAGE_SIZE);
 #endif
-		sun4c_put_pte(tsaddr, 0);
+		sun4c_put_pte(tiaddr, 0);
 #ifndef CONFIG_SUN4	
-		sun4c_put_pte(tsaddr + PAGE_SIZE, 0);
+		sun4c_put_pte(tiaddr + PAGE_SIZE, 0);
 #endif
 		sun4c_bucket[entry] = BUCKET_EMPTY;
 		if (entry < sun4c_lowbucket_avail)
 			sun4c_lowbucket_avail = entry;
 
-		free_pages(pages, TASK_STRUCT_ORDER);
+		free_pages(pages, THREAD_INFO_ORDER);
 		garbage_collect(entry);
 	}
 }
 
-static void sun4c_get_task_struct(struct task_struct *tsk)
-{
-		atomic_inc(&(tsk)->thread.refcount);
-}
-
 static void __init sun4c_init_buckets(void)
 {
 	int entry;
 
-	if (sizeof(union task_union) != (PAGE_SIZE << TASK_STRUCT_ORDER)) {
-		prom_printf("task union not %d page(s)!\n", 1 << TASK_STRUCT_ORDER);
+	if (sizeof(union thread_union) != (PAGE_SIZE << THREAD_INFO_ORDER)) {
+		extern void thread_info_size_is_bolixed_pete(void);
+		thread_info_size_is_bolixed_pete();
 	}
+
 	for (entry = 0; entry < NR_TASK_BUCKETS; entry++)
 		sun4c_bucket[entry] = BUCKET_EMPTY;
 	sun4c_lowbucket_avail = 0;
@@ -1375,7 +1368,7 @@
 	}
 }
 
-static void sun4c_flush_cache_range_sw(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+static void sun4c_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
 {
 	struct mm_struct *mm = vma->vm_mm;
 	int new_ctx = mm->context;
@@ -1530,7 +1523,7 @@
 	}
 }
 
-static void sun4c_flush_tlb_range_sw(struct vm_area_struct *vma, unsigned long start, unsigned long end)
+static void sun4c_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
 {
 	struct mm_struct *mm = vma->vm_mm;
 	int new_ctx = mm->context;
@@ -1720,6 +1713,12 @@
 	*pmdp = __pmd(PGD_TABLE | (unsigned long) ptep);
 }
 
+static void sun4c_pmd_populate(pmd_t * pmdp, struct page * ptep)
+{
+	if (page_address(ptep) == NULL) BUG();	/* No highmem on sun4c */
+	*pmdp = __pmd(PGD_TABLE | (unsigned long) page_address(ptep));
+}
+
 static int sun4c_pte_present(pte_t pte)
 {
 	return ((pte_val(pte) & (_SUN4C_PAGE_PRESENT | _SUN4C_PAGE_PRIV)) != 0);
@@ -1790,16 +1789,21 @@
 	return __pte(((page - PAGE_OFFSET) >> PAGE_SHIFT) | pgprot_val(pgprot));
 }
 
-static struct page *sun4c_pte_page(pte_t pte)
+static unsigned long sun4c_pte_pfn(pte_t pte)
 {
-	return (mem_map + (unsigned long)(pte_val(pte) & SUN4C_PFN_MASK));
+	return (unsigned long)(pte_val(pte) & SUN4C_PFN_MASK);
 }
 
-static inline unsigned long sun4c_pmd_page(pmd_t pmd)
+static __inline__ unsigned long sun4c_pmd_page_v(pmd_t pmd)
 {
 	return (pmd_val(pmd) & PAGE_MASK);
 }
 
+static struct page *sun4c_pmd_page(pmd_t pmd)
+{
+	return virt_to_page(sun4c_pmd_page_v(pmd));
+}
+
 static unsigned long sun4c_pgd_page(pgd_t pgd) { return 0; }
 
 /* to find an entry in a page-table-directory */
@@ -1815,9 +1819,10 @@
 }
 
 /* Find an entry in the third-level page table.. */ 
-pte_t *sun4c_pte_offset(pmd_t * dir, unsigned long address)
+pte_t *sun4c_pte_offset_kernel(pmd_t * dir, unsigned long address)
 {
-	return (pte_t *) sun4c_pmd_page(*dir) +	((address >> PAGE_SHIFT) & (SUN4C_PTRS_PER_PTE - 1));
+	return (pte_t *) sun4c_pmd_page_v(*dir) +
+			((address >> PAGE_SHIFT) & (SUN4C_PTRS_PER_PTE - 1));
 }
 
 static void sun4c_free_pte_slow(pte_t *pte)
@@ -1857,15 +1862,9 @@
 	pgtable_cache_size++;
 }
 
-static pte_t *sun4c_pte_alloc_one(struct mm_struct *mm, unsigned long address)
-{
-	pte_t *pte = (pte_t *)__get_free_page(GFP_KERNEL);
-	if (pte)
-		memset(pte, 0, PAGE_SIZE);
-	return pte;
-}
 
-pte_t *sun4c_pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
+static __inline__ pte_t *
+sun4c_pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
 {
 	unsigned long *ret;
 
@@ -1877,6 +1876,27 @@
 	return (pte_t *)ret;
 }
 
+static pte_t *sun4c_pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+{
+	pte_t *pte;
+
+	if ((pte = sun4c_pte_alloc_one_fast(mm, address)) != NULL)
+		return pte;
+
+	pte = (pte_t *)__get_free_page(GFP_KERNEL);
+	if (pte)
+		memset(pte, 0, PAGE_SIZE);
+	return pte;
+}
+
+static struct page *sun4c_pte_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+	pte_t *pte = sun4c_pte_alloc_one_kernel(mm, address);
+	if (pte == NULL)
+		return NULL;
+	return virt_to_page(pte);
+}
+
 static __inline__ void sun4c_free_pte_fast(pte_t *pte)
 {
 	*(unsigned long *)pte = (unsigned long) pte_quicklist;
@@ -1884,6 +1904,11 @@
 	pgtable_cache_size++;
 }
 
+static void sun4c_pte_free(struct page *pte)
+{
+	sun4c_free_pte_fast(page_address(pte));
+}
+
 /*
  * allocating and freeing a pmd is trivial: the 1-entry pmd is
  * inside the pgd, so has no extra memory associated with it.
@@ -1896,18 +1921,16 @@
 
 static void sun4c_free_pmd_fast(pmd_t * pmd) { }
 
-static int sun4c_check_pgt_cache(int low, int high)
+static void sun4c_check_pgt_cache(int low, int high)
 {
-	int freed = 0;
 	if (pgtable_cache_size > high) {
 		do {
 			if (pgd_quicklist)
-				sun4c_free_pgd_slow(sun4c_get_pgd_fast()), freed++;
+				sun4c_free_pgd_slow(sun4c_get_pgd_fast());
 			if (pte_quicklist)
-				sun4c_free_pte_slow(sun4c_pte_alloc_one_fast(NULL, 0)), freed++;
+				sun4c_free_pte_slow(sun4c_pte_alloc_one_fast(NULL, 0));
 		} while (pgtable_cache_size > low);
 	}
-	return freed;
 }
 
 /* An experiment, turn off by default for now... -DaveM */
@@ -1937,7 +1960,7 @@
 
 			if (!pgdp)
 				goto no_mapping;
-			ptep = sun4c_pte_offset((pmd_t *) pgdp, start);
+			ptep = sun4c_pte_offset_kernel((pmd_t *) pgdp, start);
 			if (!ptep || !(pte_val(*ptep) & _SUN4C_PAGE_PRESENT))
 				goto no_mapping;
 			sun4c_put_pte(start, pte_val(*ptep));
@@ -2110,7 +2133,6 @@
 	BTFIXUPSET_CALL(flush_tlb_page, sun4c_flush_tlb_page, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(flush_tlb_range, sun4c_flush_tlb_range, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(flush_cache_range, sun4c_flush_cache_range, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(free_task_struct, sun4c_free_task_struct, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(__flush_page_to_ram, sun4c_flush_page_to_ram, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(flush_tlb_all, sun4c_flush_tlb_all, BTFIXUPCALL_NORM);
 
@@ -2118,13 +2140,17 @@
 
 	BTFIXUPSET_CALL(set_pte, sun4c_set_pte, BTFIXUPCALL_STO1O0);
 
-	BTFIXUPSET_CALL(pte_page, sun4c_pte_page, BTFIXUPCALL_NORM);
-#if PAGE_SHIFT <= 12	
+	/* The 2.4.18 code does not set this on sun4c, how does it work? XXX */
+	/* BTFIXUPSET_SETHI(none_mask, 0x00000000); */	/* Defaults to zero? */
+
+	BTFIXUPSET_CALL(pte_pfn, sun4c_pte_pfn, BTFIXUPCALL_NORM);
+#if 0 /* PAGE_SHIFT <= 12 */ /* Eek. Investigate. XXX */
 	BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_ANDNINT(PAGE_SIZE - 1));
 #else
 	BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_NORM);
 #endif
 	BTFIXUPSET_CALL(pmd_set, sun4c_pmd_set, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(pmd_populate, sun4c_pmd_populate, BTFIXUPCALL_NORM);
 
 	BTFIXUPSET_CALL(pte_present, sun4c_pte_present, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(pte_clear, sun4c_pte_clear, BTFIXUPCALL_STG0O0);
@@ -2139,15 +2165,16 @@
 	BTFIXUPSET_CALL(pgd_clear, sun4c_pgd_clear, BTFIXUPCALL_NOP);
 
 	BTFIXUPSET_CALL(mk_pte, sun4c_mk_pte, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(pfn_pte, sun4c_pfn_pte, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(mk_pte_phys, sun4c_mk_pte_phys, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(mk_pte_io, sun4c_mk_pte_io, BTFIXUPCALL_NORM);
-	
+
 	BTFIXUPSET_INT(pte_modify_mask, _SUN4C_PAGE_CHG_MASK);
 	BTFIXUPSET_CALL(pmd_offset, sun4c_pmd_offset, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(pte_offset, sun4c_pte_offset, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(pte_offset_kernel, sun4c_pte_offset_kernel, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(free_pte_fast, sun4c_free_pte_fast, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(pte_free, sun4c_pte_free, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(pte_alloc_one_kernel, sun4c_pte_alloc_one_kernel, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(pte_alloc_one, sun4c_pte_alloc_one, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(pte_alloc_one_fast, sun4c_pte_alloc_one_fast, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(free_pmd_fast, sun4c_free_pmd_fast, BTFIXUPCALL_NOP);
 	BTFIXUPSET_CALL(pmd_alloc_one_fast, sun4c_pmd_alloc_one_fast, BTFIXUPCALL_RETO0);
 	BTFIXUPSET_CALL(free_pgd_fast, sun4c_free_pgd_fast, BTFIXUPCALL_NORM);
@@ -2176,9 +2203,8 @@
 	BTFIXUPSET_CALL(mmu_unmap_dma_area, sun4c_unmap_dma_area, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(mmu_translate_dvma, sun4c_translate_dvma, BTFIXUPCALL_NORM);
 
-	/* Task struct and kernel stack allocating/freeing. */
-	BTFIXUPSET_CALL(alloc_task_struct, sun4c_alloc_task_struct, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(get_task_struct, sun4c_get_task_struct, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(alloc_thread_info, sun4c_alloc_thread_info, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(free_thread_info, sun4c_free_thread_info, BTFIXUPCALL_NORM);
 
 	BTFIXUPSET_CALL(mmu_info, sun4c_mmu_info, BTFIXUPCALL_NORM);
 
diff -Nru a/arch/sparc/prom/misc.c b/arch/sparc/prom/misc.c
--- a/arch/sparc/prom/misc.c	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc/prom/misc.c	Sat Aug 10 18:42:23 2002
@@ -46,10 +46,8 @@
 }
 
 /* We want to do this more nicely some day. */
-#ifdef CONFIG_SUN_CONSOLE
 extern void (*prom_palette)(int);
 extern int serial_console;
-#endif
 
 /* Drop into the prom, with the chance to continue with the 'go'
  * prom command.
@@ -63,10 +61,8 @@
 	unsigned long flags;
     
 	kernel_enter_debugger();
-#ifdef CONFIG_SUN_CONSOLE
 	if(!serial_console && prom_palette)
 		prom_palette (1);
-#endif
 	install_obp_ticker();
 	spin_lock_irqsave(&prom_lock, flags);
 	(*(romvec->pv_abort))();
@@ -76,10 +72,8 @@
 #ifdef CONFIG_SUN_AUXIO
 	TURN_ON_LED;
 #endif
-#ifdef CONFIG_SUN_CONSOLE
 	if(!serial_console && prom_palette)
 		prom_palette (0);
-#endif
 }
 
 /* Drop into the prom, but completely terminate the program.
diff -Nru a/arch/sparc64/Config.help b/arch/sparc64/Config.help
--- a/arch/sparc64/Config.help	Sat Aug 10 18:42:24 2002
+++ b/arch/sparc64/Config.help	Sat Aug 10 18:42:24 2002
@@ -949,34 +949,6 @@
 
   If unsure, say Y.
 
-CONFIG_SERIAL
-  This selects whether you want to include the driver for the standard
-  serial ports.  The standard answer is Y.  People who might say N
-  here are those that are setting up dedicated Ethernet WWW/FTP
-  servers, or users that have one of the various bus mice instead of a
-  serial mouse and don't intend to use their machine's standard serial
-  port for anything.  (Note that the Cyclades and Stallion multi
-  serial port drivers do not need this driver built in for them to
-  work.)
-
-  If you want to compile this driver as a module, say M here and read
-  <file:Documentation/modules.txt>.  The module will be called
-  serial.o.
-  [WARNING: Do not compile this driver as a module if you are using
-  non-standard serial ports, since the configuration information will
-  be lost when the driver is unloaded.  This limitation may be lifted
-  in the future.]
-
-  BTW1: If you have a mouseman serial mouse which is not recognized by
-  the X window system, try running gpm first.
-
-  BTW2: If you intend to use a software modem (also called Winmodem)
-  under Linux, forget it.  These modems are crippled and require
-  proprietary drivers which are only available under Windows.
-
-  Most people will say Y or M here, so that they can use serial mice,
-  modems and similar devices connecting to the standard serial ports.
-
 CONFIG_SERIAL_CONSOLE
   If you say Y here, it will be possible to use a serial port as the
   system console (the system console is the device which receives all
@@ -1065,25 +1037,6 @@
   temperature sensors.  The second controller also connects to the
   smartcard reader, if present.  Say Y to enable support for these.
 
-CONFIG_BUSMOUSE
-  Say Y here if your machine has a bus mouse as opposed to a serial
-  mouse. Most people have a regular serial MouseSystem or
-  Microsoft mouse (made by Logitech) that plugs into a COM port
-  (rectangular with 9 or 25 pins). These people say N here. 
-
-  If you have a laptop, you either have to check the documentation or
-  experiment a bit to find out whether the trackball is a serial mouse
-  or not; it's best to say Y here for you.
-
-  This is the generic bus mouse driver code. If you have a bus mouse,
-  you will have to say Y here and also to the specific driver for your
-  mouse below.
-
-  This code 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 busmouse.o. If you want to compile it as a
-  module, say M here and read <file:Documentation/modules.txt>.
-
 CONFIG_DRM
   Kernel-level support for the Direct Rendering Infrastructure (DRI)
   introduced in XFree86 4.0. If you say Y here, you need to select
@@ -1208,14 +1161,6 @@
   <http://www.ultralinux.org/faq.html> for more information.  If you
   want to run SunOS binaries on an Ultra you must also say Y to
   "Kernel support for 32-bit a.out binaries" above.
-
-CONFIG_SUN_KEYBOARD
-  Say Y here to support the keyboard found on Sun 3 and 3x
-  workstations.  It can also be used support Sun Type-5 keyboards
-  through an adaptor.  See
-  <http://www.suse.cz/development/input/adapters.html> and
-  <http://sourceforge.net/projects/linuxconsole/> for details on the
-  latter.
 
 CONFIG_VIDEO_DEV
   Support for audio/video capture and overlay devices and FM radio
diff -Nru a/arch/sparc64/config.in b/arch/sparc64/config.in
--- a/arch/sparc64/config.in	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/config.in	Sat Aug 10 18:42:22 2002
@@ -26,6 +26,7 @@
 define_bool CONFIG_HAVE_DEC_LOCK y
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
+define_bool CONFIG_GENERIC_ISA_DMA y
 define_bool CONFIG_ISA n
 define_bool CONFIG_ISAPNP n
 define_bool CONFIG_EISA n
@@ -33,13 +34,6 @@
 define_bool CONFIG_PCMCIA n
 define_bool CONFIG_SBUS y
 define_bool CONFIG_SBUSCHAR y
-define_bool CONFIG_BUSMOUSE y
-define_bool CONFIG_SUN_MOUSE y
-define_bool CONFIG_SERIAL y
-define_bool CONFIG_SUN_SERIAL y
-define_bool CONFIG_SERIAL_CONSOLE y
-define_bool CONFIG_SUN_KEYBOARD y
-define_bool CONFIG_SUN_CONSOLE y
 define_bool CONFIG_SUN_AUXIO y
 define_bool CONFIG_SUN_IO y
 bool 'PCI support' CONFIG_PCI
@@ -79,6 +73,7 @@
 source drivers/video/Config.in
 endmenu
 
+source drivers/serial/Config.in
 source drivers/sbus/char/Config.in
 source drivers/sbus/audio/Config.in
 source drivers/mtd/Config.in
diff -Nru a/arch/sparc64/defconfig b/arch/sparc64/defconfig
--- a/arch/sparc64/defconfig	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/defconfig	Sat Aug 10 18:42:22 2002
@@ -42,13 +42,6 @@
 # CONFIG_PCMCIA is not set
 CONFIG_SBUS=y
 CONFIG_SBUSCHAR=y
-CONFIG_BUSMOUSE=y
-CONFIG_SUN_MOUSE=y
-CONFIG_SERIAL=y
-CONFIG_SUN_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-CONFIG_SUN_KEYBOARD=y
-CONFIG_SUN_CONSOLE=y
 CONFIG_SUN_AUXIO=y
 CONFIG_SUN_IO=y
 CONFIG_PCI=y
@@ -101,9 +94,7 @@
 # CONFIG_FB_CYBER2000 is not set
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-CONFIG_FB_ATY=y
-# CONFIG_FB_ATY_GX is not set
-CONFIG_FB_ATY_CT=y
+# CONFIG_FB_ATY is not set
 # CONFIG_FB_RADEON is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_SIS is not set
@@ -119,24 +110,42 @@
 # CONFIG_FB_CGTHREE is not set
 # CONFIG_FB_LEO is not set
 CONFIG_FB_PCI=y
-CONFIG_FB_ATY=y
-CONFIG_FB_ATY_CT=y
+# CONFIG_FB_ATY is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_CFB8=y
-CONFIG_FBCON_CFB16=y
-CONFIG_FBCON_CFB24=y
-CONFIG_FBCON_CFB32=y
 CONFIG_FBCON_FONTWIDTH8_ONLY=y
 CONFIG_FONT_SUN8x16=y
 # CONFIG_FBCON_FONTS is not set
 
 #
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+# CONFIG_SERIAL_8250_CONSOLE is not set
+# CONFIG_SERIAL_8250_CS is not set
+# CONFIG_SERIAL_8250_EXTENDED is not set
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_MULTIPORT is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SUNCORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_SUNZILOG=y
+CONFIG_SERIAL_SUNSU=y
+# CONFIG_SERIAL_SUNSAB is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+
+#
 # Misc Linux/SPARC drivers
 #
 CONFIG_SUN_OPENPROMIO=m
 CONFIG_SUN_MOSTEK_RTC=y
-CONFIG_SAB82532=y
 CONFIG_OBP_FLASH=m
 # CONFIG_SUN_BPP is not set
 # CONFIG_SUN_VIDEOPIX is not set
@@ -194,7 +203,6 @@
 CONFIG_INET_ECN=y
 # CONFIG_SYN_COOKIES is not set
 CONFIG_IPV6=m
-# CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
 CONFIG_VLAN_8021Q=m
 
@@ -249,39 +257,32 @@
 CONFIG_NET_CLS_POLICE=y
 
 #
-# ATA/IDE/MFM/RLL support
+# ATA/ATAPI/MFM/RLL device support
 #
 CONFIG_IDE=y
-
-#
-# ATA and ATAPI Block devices
-#
 CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
 # CONFIG_BLK_DEV_HD_IDE is not set
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
 # CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_ATAPI=y
 CONFIG_BLK_DEV_IDECD=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_IDECS is not set
 
 #
-# ATA host chip set support
+# ATA host controller support
 #
+# CONFIG_BLK_DEV_RZ1000 is not set
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
 
 #
-#   PCI host chip set support
+#   PCI host controller support
 #
 # CONFIG_BLK_DEV_OFFBOARD is not set
 # CONFIG_IDEPCI_SHARE_IRQ is not set
@@ -316,7 +317,6 @@
 # CONFIG_BLK_DEV_SL82C105 is not set
 # CONFIG_IDE_CHIPSETS is not set
 # CONFIG_IDEDMA_IVB is not set
-CONFIG_ATAPI=y
 CONFIG_IDEDMA_AUTO=y
 # CONFIG_BLK_DEV_ATARAID is not set
 # CONFIG_BLK_DEV_ATARAID_PDC is not set
@@ -403,9 +403,7 @@
 #
 # Device Drivers
 #
-CONFIG_IEEE1394_PCILYNX=m
-# CONFIG_IEEE1394_PCILYNX_LOCALRAM is not set
-# CONFIG_IEEE1394_PCILYNX_PORTS is not set
+# CONFIG_IEEE1394_PCILYNX is not set
 CONFIG_IEEE1394_OHCI1394=m
 
 #
@@ -413,6 +411,7 @@
 #
 # CONFIG_IEEE1394_VIDEO1394 is not set
 CONFIG_IEEE1394_SBP2=m
+# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
 CONFIG_IEEE1394_ETH1394=m
 CONFIG_IEEE1394_DV1394=m
 CONFIG_IEEE1394_RAWIO=m
@@ -489,12 +488,11 @@
 #
 # Ethernet (1000 Mbit)
 #
-CONFIG_ACENIC=m
-# CONFIG_ACENIC_OMIT_TIGON_I is not set
-CONFIG_DL2K=m
-CONFIG_E1000=m
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
 CONFIG_MYRI_SBUS=m
-CONFIG_NS83820=m
+# CONFIG_NS83820 is not set
 CONFIG_HAMACHI=m
 CONFIG_YELLOWFIN=m
 CONFIG_SK98LIN=m
@@ -586,6 +584,7 @@
 # CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_UINPUT is not set
 
 #
 # Input I/O drivers
@@ -594,11 +593,11 @@
 CONFIG_SOUND_GAMEPORT=y
 # CONFIG_GAMEPORT_NS558 is not set
 # CONFIG_GAMEPORT_L4 is not set
-# CONFIG_INPUT_EMU10K1 is not set
+# CONFIG_GAMEPORT_EMU10K1 is not set
 # CONFIG_GAMEPORT_VORTEX is not set
 # CONFIG_GAMEPORT_FM801 is not set
 # CONFIG_GAMEPORT_CS461x is not set
-# CONFIG_SERIO is not set
+CONFIG_SERIO=y
 # CONFIG_SERIO_I8042 is not set
 # CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_CT82C710 is not set
@@ -609,12 +608,12 @@
 #
 CONFIG_INPUT_KEYBOARD=y
 # CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_PS2SERKBD is not set
+CONFIG_KEYBOARD_SUNKBD=y
 # CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
 CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
-# CONFIG_MOUSE_SERIAL is not set
+CONFIG_MOUSE_SERIAL=y
 # CONFIG_MOUSE_INPORT is not set
 # CONFIG_MOUSE_LOGIBM is not set
 # CONFIG_MOUSE_PC110PAD is not set
@@ -625,12 +624,12 @@
 # CONFIG_JOYSTICK_COBRA is not set
 # CONFIG_JOYSTICK_GF2K is not set
 # CONFIG_JOYSTICK_GRIP is not set
+# CONFIG_JOYSTICK_GRIP_MP is not set
 # CONFIG_JOYSTICK_GUILLEMOT is not set
 # CONFIG_JOYSTICK_INTERACT is not set
 # CONFIG_JOYSTICK_SIDEWINDER is not set
 # CONFIG_JOYSTICK_TMDC is not set
-# CONFIG_JOYSTICK_IFORCE_USB is not set
-# CONFIG_JOYSTICK_IFORCE_232 is not set
+# CONFIG_JOYSTICK_IFORCE is not set
 # CONFIG_JOYSTICK_WARRIOR is not set
 # CONFIG_JOYSTICK_MAGELLAN is not set
 # CONFIG_JOYSTICK_SPACEORB is not set
@@ -837,9 +836,14 @@
 #
 CONFIG_USB_HID=y
 CONFIG_USB_HIDINPUT=y
+# CONFIG_HID_FF is not set
+# CONFIG_HID_PID is not set
+# CONFIG_LOGITECH_FF is not set
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 CONFIG_USB_WACOM=m
+# CONFIG_USB_POWERMATE is not set
+# CONFIG_USB_XPAD is not set
 
 #
 # USB Imaging devices
@@ -891,6 +895,7 @@
 CONFIG_USB_SERIAL_IPAQ=m
 # CONFIG_USB_SERIAL_IR is not set
 CONFIG_USB_SERIAL_EDGEPORT=m
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
 CONFIG_USB_SERIAL_KEYSPAN_PDA=m
 CONFIG_USB_SERIAL_KEYSPAN=m
 # CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
@@ -955,6 +960,11 @@
 # CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_DEBUG_DCFLUSH is not set
 # CONFIG_STACK_DEBUG is not set
+
+#
+# Security options
+#
+CONFIG_SECURITY_CAPABILITIES=y
 
 #
 # Library routines
diff -Nru a/arch/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c
--- a/arch/sparc64/kernel/devices.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/kernel/devices.c	Sat Aug 10 18:42:22 2002
@@ -10,12 +10,18 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/string.h>
+#include <linux/spinlock.h>
 
 #include <asm/page.h>
 #include <asm/oplib.h>
 #include <asm/system.h>
 #include <asm/smp.h>
 #include <asm/spitfire.h>
+
+/* Used to synchronize acceses to NatSemi SUPER I/O chip configure
+ * operations in asm/ns87303.h
+ */
+spinlock_t ns87303_lock = SPIN_LOCK_UNLOCKED;
 
 struct prom_cpuinfo linux_cpus[NR_CPUS] __initdata = { { 0 } };
 unsigned prom_cpu_nodes[NR_CPUS];
diff -Nru a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S
--- a/arch/sparc64/kernel/etrap.S	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/kernel/etrap.S	Sat Aug 10 18:42:22 2002
@@ -27,17 +27,9 @@
 		.text		
 		.align	64
 		.globl	etrap, etrap_irq, etraptl1
-#ifdef CONFIG_PREEMPT
-etrap_irq:	ldsw	[%g6 + TI_PRE_COUNT], %g1
-		add	%g1, 1, %g1
-		ba,pt	%xcc, etrap_irq2
-		 stw	%g1, [%g6 + TI_PRE_COUNT]
-#endif
 etrap:		rdpr	%pil, %g2						! Single 	Group
-#ifndef CONFIG_PREEMPT
 etrap_irq:
-#endif
-etrap_irq2:	rdpr	%tstate, %g1						! Single 	Group
+		rdpr	%tstate, %g1						! Single 	Group
 		sllx	%g2, 20, %g3						! IEU0		Group
 		andcc	%g1, TSTATE_PRIV, %g0					! IEU1
 		or	%g1, %g3, %g1						! IEU0		Group
diff -Nru a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
--- a/arch/sparc64/kernel/ioctl32.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/kernel/ioctl32.c	Sat Aug 10 18:42:22 2002
@@ -4857,13 +4857,15 @@
 	    (unsigned long)t < ((unsigned long)additional_ioctls) + PAGE_SIZE) {
 		ioctl32_hash_table[hash] = t->next;
 		t->cmd = 0;
+		t->next = 0;
 		return 0;
 	} else while (t->next) {
 		t1 = (struct ioctl_trans *)(long)t->next;
 		if (t1->cmd == cmd && t1 >= additional_ioctls &&
 		    (unsigned long)t1 < ((unsigned long)additional_ioctls) + PAGE_SIZE) {
-			t1->cmd = 0;
 			t->next = t1->next;
+			t1->cmd = 0;
+			t1->next = 0;
 			return 0;
 		}
 		t = t1;
diff -Nru a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
--- a/arch/sparc64/kernel/irq.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/kernel/irq.c	Sat Aug 10 18:42:22 2002
@@ -90,6 +90,13 @@
 	  NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL
 };
 
+/* This only synchronizes entities which modify IRQ handler
+ * state and some selected user-level spots that want to
+ * read things in the table.  IRQ handler processing orders
+ * its' accesses such that no locking is needed.
+ */
+static spinlock_t irq_action_lock = SPIN_LOCK_UNLOCKED;
+
 static void register_irq_proc (unsigned int irq);
 
 /*
@@ -109,14 +116,16 @@
 
 int show_interrupts(struct seq_file *p, void *v)
 {
+	unsigned long flags;
 	int i;
 	struct irqaction *action;
 #ifdef CONFIG_SMP
 	int j;
 #endif
 
-	for(i = 0; i < (NR_IRQS + 1); i++) {
-		if(!(action = *(i + irq_action)))
+	spin_lock_irqsave(&irq_action_lock, flags);
+	for (i = 0; i < (NR_IRQS + 1); i++) {
+		if (!(action = *(i + irq_action)))
 			continue;
 		seq_printf(p, "%3d: ", i);
 #ifndef CONFIG_SMP
@@ -131,12 +140,14 @@
 #endif
 		seq_printf(p, " %s:%lx", action->name,
 			   get_ino_in_irqaction(action));
-		for(action = action->next; action; action = action->next) {
+		for (action = action->next; action; action = action->next) {
 			seq_printf(p, ", %s:%lx", action->name,
 				   get_ino_in_irqaction(action));
 		}
 		seq_putc(p, '\n');
 	}
+	spin_unlock_irqrestore(&irq_action_lock, flags);
+
 	return 0;
 }
 
@@ -222,8 +233,8 @@
 	struct ino_bucket *bucket;
 	int ino;
 
-	if(pil == 0) {
-		if(iclr != 0UL || imap != 0UL) {
+	if (pil == 0) {
+		if (iclr != 0UL || imap != 0UL) {
 			prom_printf("Invalid dummy bucket for PIL0 (%lx:%lx)\n",
 				    iclr, imap);
 			prom_halt();
@@ -239,7 +250,7 @@
 	}
 	
 	ino = (upa_readl(imap) & (IMAP_IGN | IMAP_INO)) + inofixup;
-	if(ino > NUM_IVECS) {
+	if (ino > NUM_IVECS) {
 		prom_printf("Invalid INO %04x (%d:%d:%016lx:%016lx)\n",
 			    ino, pil, inofixup, iclr, imap);
 		prom_halt();
@@ -302,7 +313,7 @@
 		       "from %p, irq %08x.\n", caller, irq);
 		return -EINVAL;
 	}	
-	if(!handler)
+	if (!handler)
 	    return -EINVAL;
 
 	if ((bucket != &pil0_dummy_bucket) && (irqflags & SA_SAMPLE_RANDOM)) {
@@ -319,15 +330,15 @@
 		rand_initialize_irq(irq);
 	}
 
-	save_and_cli(flags);
+	spin_lock_irqsave(&irq_action_lock, flags);
 
 	action = *(bucket->pil + irq_action);
-	if(action) {
-		if((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ))
+	if (action) {
+		if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ))
 			for (tmp = action; tmp->next; tmp = tmp->next)
 				;
 		else {
-			restore_flags(flags);
+			spin_unlock_irqrestore(&irq_action_lock, flags);
 			return -EBUSY;
 		}
 		action = NULL;		/* Or else! */
@@ -336,19 +347,19 @@
 	/* If this is flagged as statically allocated then we use our
 	 * private struct which is never freed.
 	 */
-	if(irqflags & SA_STATIC_ALLOC) {
-	    if(static_irq_count < MAX_STATIC_ALLOC)
+	if (irqflags & SA_STATIC_ALLOC) {
+	    if (static_irq_count < MAX_STATIC_ALLOC)
 		action = &static_irqaction[static_irq_count++];
 	    else
 		printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed "
 		       "using kmalloc\n", irq, name);
 	}	
-	if(action == NULL)
+	if (action == NULL)
 	    action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
 						 GFP_KERNEL);
 	
-	if(!action) { 
-		restore_flags(flags);
+	if (!action) { 
+		spin_unlock_irqrestore(&irq_action_lock, flags);
 		return -ENOMEM;
 	}
 
@@ -356,17 +367,17 @@
 		bucket->irq_info = action;
 		bucket->flags |= IBF_ACTIVE;
 	} else {
-		if((bucket->flags & IBF_ACTIVE) != 0) {
+		if ((bucket->flags & IBF_ACTIVE) != 0) {
 			void *orig = bucket->irq_info;
 			void **vector = NULL;
 
-			if((bucket->flags & IBF_PCI) == 0) {
+			if ((bucket->flags & IBF_PCI) == 0) {
 				printk("IRQ: Trying to share non-PCI bucket.\n");
 				goto free_and_ebusy;
 			}
-			if((bucket->flags & IBF_MULTI) == 0) {
+			if ((bucket->flags & IBF_MULTI) == 0) {
 				vector = kmalloc(sizeof(void *) * 4, GFP_KERNEL);
-				if(vector == NULL)
+				if (vector == NULL)
 					goto free_and_enomem;
 
 				/* We might have slept. */
@@ -395,8 +406,8 @@
 				int ent;
 
 				vector = (void **)orig;
-				for(ent = 0; ent < 4; ent++) {
-					if(vector[ent] == NULL) {
+				for (ent = 0; ent < 4; ent++) {
+					if (vector[ent] == NULL) {
 						vector[ent] = action;
 						break;
 					}
@@ -409,7 +420,7 @@
 			bucket->flags |= IBF_ACTIVE;
 		}
 		pending = bucket->pending;
-		if(pending)
+		if (pending)
 			bucket->pending = 0;
 	}
 
@@ -421,7 +432,7 @@
 	put_ino_in_irqaction(action, irq);
 	put_smpaff_in_irqaction(action, 0);
 
-	if(tmp)
+	if (tmp)
 		tmp->next = action;
 	else
 		*(bucket->pil + irq_action) = action;
@@ -429,11 +440,11 @@
 	enable_irq(irq);
 
 	/* We ate the IVEC already, this makes sure it does not get lost. */
-	if(pending) {
+	if (pending) {
 		atomic_bucket_insert(bucket);
 		set_softint(1 << bucket->pil);
 	}
-	restore_flags(flags);
+	spin_unlock_irqrestore(&irq_action_lock, flags);
 	if ((bucket != &pil0_dummy_bucket) && (!(irqflags & SA_STATIC_ALLOC)))
 		register_irq_proc(__irq_ino(irq));
 
@@ -444,12 +455,12 @@
 
 free_and_ebusy:
 	kfree(action);
-	restore_flags(flags);
+	spin_unlock_irqrestore(&irq_action_lock, flags);
 	return -EBUSY;
 
 free_and_enomem:
 	kfree(action);
-	restore_flags(flags);
+	spin_unlock_irqrestore(&irq_action_lock, flags);
 	return -ENOMEM;
 }
 
@@ -471,38 +482,48 @@
 		return;
 	}
 	
+	spin_lock_irqsave(&irq_action_lock, flags);
+
 	action = *(bucket->pil + irq_action);
-	if(!action->handler) {
+	if (!action->handler) {
 		printk("Freeing free IRQ %d\n", bucket->pil);
 		return;
 	}
-	if(dev_id) {
-		for( ; action; action = action->next) {
-			if(action->dev_id == dev_id)
+	if (dev_id) {
+		for ( ; action; action = action->next) {
+			if (action->dev_id == dev_id)
 				break;
 			tmp = action;
 		}
-		if(!action) {
+		if (!action) {
 			printk("Trying to free free shared IRQ %d\n", bucket->pil);
+			spin_unlock_irqrestore(&irq_action_lock, flags);
 			return;
 		}
-	} else if(action->flags & SA_SHIRQ) {
+	} else if (action->flags & SA_SHIRQ) {
 		printk("Trying to free shared IRQ %d with NULL device ID\n", bucket->pil);
+		spin_unlock_irqrestore(&irq_action_lock, flags);
 		return;
 	}
 
-	if(action->flags & SA_STATIC_ALLOC) {
+	if (action->flags & SA_STATIC_ALLOC) {
 		printk("Attempt to free statically allocated IRQ %d (%s)\n",
 		       bucket->pil, action->name);
+		spin_unlock_irqrestore(&irq_action_lock, flags);
 		return;
 	}
 
-	save_and_cli(flags);
-	if(action && tmp)
+	if (action && tmp)
 		tmp->next = action->next;
 	else
 		*(bucket->pil + irq_action) = action->next;
 
+	spin_unlock_irqrestore(&irq_action_lock, flags);
+
+	synchronize_irq(irq);
+
+	spin_lock_irqsave(&irq_action_lock, flags);
+
 	if (bucket != &pil0_dummy_bucket) {
 		unsigned long imap = bucket->imap;
 		void **vector, *orig;
@@ -514,10 +535,10 @@
 		if ((bucket->flags & IBF_MULTI) != 0) {
 			int other = 0;
 			void *orphan = NULL;
-			for(ent = 0; ent < 4; ent++) {
-				if(vector[ent] == action)
+			for (ent = 0; ent < 4; ent++) {
+				if (vector[ent] == action)
 					vector[ent] = NULL;
-				else if(vector[ent] != NULL) {
+				else if (vector[ent] != NULL) {
 					orphan = vector[ent];
 					other++;
 				}
@@ -526,7 +547,7 @@
 			/* Only free when no other shared irq
 			 * uses this bucket.
 			 */
-			if(other) {
+			if (other) {
 				if (other == 1) {
 					/* Convert back to non-shared bucket. */
 					bucket->irq_info = orphan;
@@ -545,11 +566,11 @@
 		/* See if any other buckets share this bucket's IMAP
 		 * and are still active.
 		 */
-		for(ent = 0; ent < NUM_IVECS; ent++) {
+		for (ent = 0; ent < NUM_IVECS; ent++) {
 			bp = &ivector_table[ent];
-			if(bp != bucket		&&
-			   bp->imap == imap	&&
-			   (bp->flags & IBF_ACTIVE) != 0)
+			if (bp != bucket	&&
+			    bp->imap == imap	&&
+			    (bp->flags & IBF_ACTIVE) != 0)
 				break;
 		}
 
@@ -562,151 +583,40 @@
 
 out:
 	kfree(action);
-	restore_flags(flags);
+	spin_unlock_irqrestore(&irq_action_lock, flags);
 }
 
 #ifdef CONFIG_SMP
-
-/* Who has the global irq brlock */
-unsigned char global_irq_holder = NO_PROC_ID;
-
-static void show(char * str)
+void synchronize_irq(unsigned int irq)
 {
-	int cpu = smp_processor_id();
-	int i;
-
-	printk("\n%s, CPU %d:\n", str, cpu);
-	printk("irq:  %d [ ", irqs_running());
-	for (i = 0; i < NR_CPUS; i++) {
-		if (!cpu_online(i))
-			continue;
-		printk("%u ", __brlock_array[i][BR_GLOBALIRQ_LOCK]);
-	}
-	printk("]\nbh:   %d [ ",
-	       (spin_is_locked(&global_bh_lock) ? 1 : 0));
-	for (i = 0; i < NR_CPUS; i++) {
-		if (!cpu_online(i))
-			continue;
-		printk("%u ", local_bh_count(i));
-	}
-	printk("]\n");
-}
-
-#define MAXCOUNT 100000000
+	struct ino_bucket *bucket = __bucket(irq);
 
 #if 0
-#define SYNC_OTHER_ULTRAS(x)	udelay(x+1)
-#else
-#define SYNC_OTHER_ULTRAS(x)	membar("#Sync");
-#endif
-
-void synchronize_irq(void)
-{
-	if (irqs_running()) {
-		cli();
-		sti();
-	}
-}
-
-static inline void get_irqlock(int cpu)
-{
-	int count;
-
-	if ((unsigned char)cpu == global_irq_holder)
-		return;
+	/* The following is how I wish I could implement this.
+	 * Unfortunately the ICLR registers are read-only, you can
+	 * only write ICLR_foo values to them.  To get the current
+	 * IRQ status you would need to get at the IRQ diag registers
+	 * in the PCI/SBUS controller and the layout of those vary
+	 * from one controller to the next, sigh... -DaveM
+	 */
+	unsigned long iclr = bucket->iclr;
 
-	count = MAXCOUNT;
-again:
-	br_write_lock(BR_GLOBALIRQ_LOCK);
-	for (;;) {
-		spinlock_t *lock;
-
-		if (!irqs_running() &&
-		    (local_bh_count(smp_processor_id()) || !spin_is_locked(&global_bh_lock)))
-			break;
-
-		br_write_unlock(BR_GLOBALIRQ_LOCK);
-		lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock;
-		while (irqs_running() ||
-		       spin_is_locked(lock) ||
-		       (!local_bh_count(smp_processor_id()) && spin_is_locked(&global_bh_lock))) {
-			if (!--count) {
-				show("get_irqlock");
-				count = (~0 >> 1);
-			}
-			local_irq_enable();
-			SYNC_OTHER_ULTRAS(cpu);
-			local_irq_disable();
+	while (1) {
+		u32 tmp = upa_readl(iclr);
+		
+		if (tmp == ICLR_TRANSMIT ||
+		    tmp == ICLR_PENDING) {
+			cpu_relax();
+			continue;
 		}
-		goto again;
-	}
-
-	global_irq_holder = cpu;
-}
-
-void __global_cli(void)
-{
-	unsigned long flags;
-
-	local_save_flags(flags);
-	if(flags == 0) {
-		int cpu = smp_processor_id();
-		local_irq_disable();
-		if (! local_irq_count(cpu))
-			get_irqlock(cpu);
-	}
-}
-
-void __global_sti(void)
-{
-	int cpu = smp_processor_id();
-
-	if (! local_irq_count(cpu))
-		release_irqlock(cpu);
-	local_irq_enable();
-}
-
-unsigned long __global_save_flags(void)
-{
-	unsigned long flags, local_enabled, retval;
-
-	local_save_flags(flags);
-	local_enabled = ((flags == 0) ? 1 : 0);
-	retval = 2 + local_enabled;
-	if (! local_irq_count(smp_processor_id())) {
-		if (local_enabled)
-			retval = 1;
-		if (global_irq_holder == (unsigned char) smp_processor_id())
-			retval = 0;
-	}
-	return retval;
-}
-
-void __global_restore_flags(unsigned long flags)
-{
-	switch (flags) {
-	case 0:
-		__global_cli();
-		break;
-	case 1:
-		__global_sti();
-		break;
-	case 2:
-		local_irq_disable();
-		break;
-	case 3:
-		local_irq_enable();
 		break;
-	default:
-	{
-		unsigned long pc;
-		__asm__ __volatile__("mov %%i7, %0" : "=r" (pc));
-		printk("global_restore_flags: Bogon flags(%016lx) caller %016lx\n",
-		       flags, pc);
-	}
 	}
+#else
+	/* So we have to do this with a INPROGRESS bit just like x86.  */
+	while (bucket->flags & IBF_INPROGRESS)
+		cpu_relax();
+#endif
 }
-
 #endif /* CONFIG_SMP */
 
 void catch_disabled_ivec(struct pt_regs *regs)
@@ -827,13 +737,11 @@
 	clear_softint(1 << irq);
 #endif
 
-	irq_enter(cpu, irq);
+	irq_enter();
 	kstat.irqs[cpu][irq]++;
 
-#ifdef CONFIG_PCI
 	if (irq == 9)
 		kbd_pt_regs = regs;
-#endif
 
 	/* Sliiiick... */
 #ifndef CONFIG_SMP
@@ -850,6 +758,8 @@
 		nbp = __bucket(bp->irq_chain);
 		bp->irq_chain = 0;
 
+		bp->flags |= IBF_INPROGRESS;
+
 		if ((flags & IBF_ACTIVE) != 0) {
 #ifdef CONFIG_PCI
 			if ((flags & IBF_DMA_SYNC) != 0) {
@@ -887,8 +797,10 @@
 			}
 		} else
 			bp->pending = 1;
+
+		bp->flags &= ~IBF_INPROGRESS;
 	}
-	irq_exit(cpu, irq);
+	irq_exit();
 }
 
 #ifdef CONFIG_BLK_DEV_FD
@@ -900,16 +812,20 @@
 	struct ino_bucket *bucket;
 	int cpu = smp_processor_id();
 
-	irq_enter(cpu, irq);
+	irq_enter();
 	kstat.irqs[cpu][irq]++;
 
 	*(irq_work(cpu, irq)) = 0;
 	bucket = get_ino_in_irqaction(action) + ivector_table;
 
+	bucket->flags |= IBF_INPROGRESS;
+
 	floppy_interrupt(irq, dev_cookie, regs);
 	upa_writel(ICLR_IDLE, bucket->iclr);
 
-	irq_exit(cpu, irq);
+	bucket->flags &= ~IBF_INPROGRESS;
+
+	irq_exit();
 }
 #endif
 
@@ -957,7 +873,7 @@
 		return -EINVAL;
 	}	
 	
-	if(!handler)
+	if (!handler)
 		return -EINVAL;
 
 	if ((bucket->pil == 0) || (bucket->pil == 14)) {
@@ -965,13 +881,16 @@
 		return -EBUSY;
 	}
 
+	spin_lock_irqsave(&irq_action_lock, flags);
+
 	action = *(bucket->pil + irq_action);
-	if(action) {
-		if(action->flags & SA_SHIRQ)
+	if (action) {
+		if (action->flags & SA_SHIRQ)
 			panic("Trying to register fast irq when already shared.\n");
-		if(irqflags & SA_SHIRQ)
+		if (irqflags & SA_SHIRQ)
 			panic("Trying to register fast irq as shared.\n");
 		printk("request_fast_irq: Trying to register yet already owned.\n");
+		spin_unlock_irqrestore(&irq_action_lock, flags);
 		return -EBUSY;
 	}
 
@@ -979,19 +898,18 @@
 	 * We do not check for SA_SAMPLE_RANDOM in this path. Neither do we
 	 * support smp intr affinity in this path.
 	 */
-	save_and_cli(flags);
-	if(irqflags & SA_STATIC_ALLOC) {
-		if(static_irq_count < MAX_STATIC_ALLOC)
+	if (irqflags & SA_STATIC_ALLOC) {
+		if (static_irq_count < MAX_STATIC_ALLOC)
 			action = &static_irqaction[static_irq_count++];
 		else
 			printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed "
 			       "using kmalloc\n", bucket->pil, name);
 	}
-	if(action == NULL)
+	if (action == NULL)
 		action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
 						     GFP_KERNEL);
-	if(!action) {
-		restore_flags(flags);
+	if (!action) {
+		spin_unlock_irqrestore(&irq_action_lock, flags);
 		return -ENOMEM;
 	}
 	install_fast_irq(bucket->pil, handler);
@@ -1010,7 +928,7 @@
 	*(bucket->pil + irq_action) = action;
 	enable_irq(irq);
 
-	restore_flags(flags);
+	spin_unlock_irqrestore(&irq_action_lock, flags);
 
 #ifdef CONFIG_SMP
 	distribute_irqs();
@@ -1058,7 +976,7 @@
 	err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, SA_STATIC_ALLOC,
 			  "timer", NULL);
 
-	if(err) {
+	if (err) {
 		prom_printf("Serious problem, cannot register TICK_INT\n");
 		prom_halt();
 	}
@@ -1135,7 +1053,7 @@
 			     : /* no outputs */
 			     : "r" (pstate));
 
-	sti();
+	local_irq_enable();
 }
 
 #ifdef CONFIG_SMP
@@ -1176,14 +1094,14 @@
 	unsigned long flags;
 	int cpu, level;
 
-	save_and_cli(flags);
+	spin_lock_irqsave(&irq_action_lock, flags);
 	cpu = 0;
 
 	/*
 	 * Skip the timer at [0], and very rare error/power intrs at [15].
 	 * Also level [12], it causes problems on Ex000 systems.
 	 */
-	for(level = 1; level < NR_IRQS; level++) {
+	for (level = 1; level < NR_IRQS; level++) {
 		struct irqaction *p = irq_action[level];
 		if (level == 12) continue;
 		while(p) {
@@ -1191,7 +1109,7 @@
 			p = p->next;
 		}
 	}
-	restore_flags(flags);
+	spin_unlock_irqrestore(&irq_action_lock, flags);
 }
 #endif
 
@@ -1210,14 +1128,14 @@
 	/* Assume if node is not present, PROM uses different tick mechanism
 	 * which we should not care about.
 	 */
-	if(tnode == 0 || tnode == -1) {
+	if (tnode == 0 || tnode == -1) {
 		prom_timers = (struct sun5_timer *) 0;
 		return;
 	}
 
 	/* If PROM is really using this, it must be mapped by him. */
 	err = prom_getproperty(tnode, "address", (char *)addr, sizeof(addr));
-	if(err == -1) {
+	if (err == -1) {
 		prom_printf("PROM does not have timer mapped, trying to continue.\n");
 		prom_timers = (struct sun5_timer *) 0;
 		return;
@@ -1227,7 +1145,7 @@
 
 static void kill_prom_timer(void)
 {
-	if(!prom_timers)
+	if (!prom_timers)
 		return;
 
 	/* Save them away for later. */
@@ -1254,7 +1172,7 @@
 
 void enable_prom_timer(void)
 {
-	if(!prom_timers)
+	if (!prom_timers)
 		return;
 
 	/* Set it to whatever was there before. */
diff -Nru a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
--- a/arch/sparc64/kernel/pci.c	Sat Aug 10 18:42:19 2002
+++ b/arch/sparc64/kernel/pci.c	Sat Aug 10 18:42:19 2002
@@ -177,7 +177,6 @@
 	}
 }
 
-extern void rs_init(void);
 extern void clock_probe(void);
 extern void power_init(void);
 
@@ -194,7 +193,6 @@
 
 	isa_init();
 	ebus_init();
-	rs_init();
 	clock_probe();
 	power_init();
 
diff -Nru a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
--- a/arch/sparc64/kernel/process.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/kernel/process.c	Sat Aug 10 18:42:22 2002
@@ -107,35 +107,16 @@
 
 #endif
 
-#ifdef CONFIG_PREEMPT
-void kpreempt_maybe(void)
-{
-	int cpu = smp_processor_id();
-
-	if (local_irq_count(cpu) == 0 &&
-	    local_bh_count(cpu) == 0 &&
-	    test_thread_flag(TIF_NEED_RESCHED))
-		schedule();
-}
-#endif
-
 extern char reboot_command [];
 
-#ifdef CONFIG_SUN_CONSOLE
 extern void (*prom_palette)(int);
 extern int serial_console;
-#endif
 extern void (*prom_keyboard)(void);
 
 void machine_halt(void)
 {
-	sti();
-	mdelay(8);
-	cli();
-#ifdef CONFIG_SUN_CONSOLE
 	if (!serial_console && prom_palette)
 		prom_palette (1);
-#endif
 	if (prom_keyboard)
 		prom_keyboard();
 	prom_halt();
@@ -144,13 +125,8 @@
 
 void machine_alt_power_off(void)
 {
-	sti();
-	mdelay(8);
-	cli();
-#ifdef CONFIG_SUN_CONSOLE
 	if (!serial_console && prom_palette)
 		prom_palette(1);
-#endif
 	if (prom_keyboard)
 		prom_keyboard();
 	prom_halt_power_off();
@@ -161,16 +137,10 @@
 {
 	char *p;
 	
-	sti();
-	mdelay(8);
-	cli();
-
 	p = strchr (reboot_command, '\n');
 	if (p) *p = 0;
-#ifdef CONFIG_SUN_CONSOLE
 	if (!serial_console && prom_palette)
 		prom_palette (1);
-#endif
 	if (prom_keyboard)
 		prom_keyboard();
 	if (cmd)
@@ -311,10 +281,6 @@
 			     : "=r" (flags)
 			     : "i" (PSTATE_IE));
 	spin_lock(&regdump_lock);
-	printk("CPU[%d]: local_irq_count[%u] irqs_running[%d]\n",
-	       smp_processor_id(),
-	       local_irq_count(smp_processor_id()),
-	       irqs_running());
 #endif
 	printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x    %s\n", regs->tstate,
 	       regs->tpc, regs->tnpc, regs->y, print_tainted());
diff -Nru a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S
--- a/arch/sparc64/kernel/rtrap.S	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/kernel/rtrap.S	Sat Aug 10 18:42:22 2002
@@ -151,11 +151,6 @@
 		.align			64
 		.globl			rtrap_irq, rtrap_clr_l6, rtrap, irqsz_patchme, rtrap_xcall
 rtrap_irq:
-#ifdef CONFIG_PREEMPT
-		ldsw			[%g6 + TI_PRE_COUNT], %l0
-		sub			%l0, 1, %l0
-		stw			%l0, [%g6 + TI_PRE_COUNT]
-#endif
 rtrap_clr_l6:	clr			%l6
 rtrap:		ldub			[%g6 + TI_CPU], %l0
 		sethi			%hi(irq_stat), %l2	! &softirq_active
@@ -276,7 +271,7 @@
 		brnz			%l5, kern_fpucheck
 		 sethi			%hi(PREEMPT_ACTIVE), %l6
 		stw			%l6, [%g6 + TI_PRE_COUNT]
-		call			kpreempt_maybe
+		call			schedule
 		 nop
 		ba,pt			%xcc, rtrap
 		 stw			%g0, [%g6 + TI_PRE_COUNT]
diff -Nru a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
--- a/arch/sparc64/kernel/setup.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/kernel/setup.c	Sat Aug 10 18:42:22 2002
@@ -29,6 +29,7 @@
 #include <linux/inet.h>
 #include <linux/console.h>
 #include <linux/root_dev.h>
+#include <linux/interrupt.h>
 
 #include <asm/segment.h>
 #include <asm/system.h>
@@ -65,9 +66,7 @@
  * prints out pretty messages and returns.
  */
 
-#if CONFIG_SUN_CONSOLE
 void (*prom_palette)(int);
-#endif
 void (*prom_keyboard)(void);
 asmlinkage void sys_sync(void);	/* it's really int */
 
@@ -78,10 +77,10 @@
 }
 
 static struct console prom_console = {
-	name:		"prom",
-	write:		prom_console_write,
-	flags:		CON_CONSDEV | CON_ENABLED,
-	index:		-1,
+	.name =		"prom",
+	.write =	prom_console_write,
+	.flags =	CON_CONSDEV | CON_ENABLED,
+	.index =	-1,
 };
 
 #define PROM_TRUE	-1
@@ -107,8 +106,13 @@
 	 * administrator has done a switch-cpu inside obp. In either 
 	 * case, the cpu is marked as in-interrupt. Drop IRQ locks.
 	 */
-	irq_exit(smp_processor_id(), 0);
-	save_and_cli(flags);
+	irq_exit();
+
+	/* XXX Revisit the locking here someday.  This is a debugging
+	 * XXX feature so it isnt all that critical.  -DaveM
+	 */
+	local_irq_save(flags);
+
 	spin_unlock(&prom_entry_lock);
 	cons = console_drivers;
 	while (cons) {
@@ -122,10 +126,10 @@
 	if (!strcmp(cmd, "sync")) {
 		prom_printf("PROM `%s' command...\n", cmd);
 		show_free_areas();
-		if(current->pid != 0) {
-			sti();
+		if (current->pid != 0) {
+			local_irq_enable();
 			sys_sync();
-			cli();
+			local_irq_disable();
 		}
 		args[2] = 0;
 		args[args[1] + 3] = -1;
@@ -301,11 +305,12 @@
 		register_console(cons);
 	}
 	spin_lock(&prom_entry_lock);
-	restore_flags(flags);
+	local_irq_restore(flags);
+
 	/*
 	 * Restore in-interrupt status for a resume from obp.
 	 */
-	irq_enter(smp_processor_id(), 0);
+	irq_enter();
 	return 0;
 }
 
@@ -316,18 +321,16 @@
 #define BOOTME_SINGLE 0x2
 #define BOOTME_KGDB   0x4
 
-#ifdef CONFIG_SUN_CONSOLE
 static int console_fb __initdata = 0;
-#endif
 
 /* Exported for mm/init.c:paging_init. */
 unsigned long cmdline_memory_size = 0;
 
 static struct console prom_debug_console = {
-	name:		"debug",
-	write:		prom_console_write,
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
+	.name =		"debug",
+	.write =	prom_console_write,
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
 };
 
 /* XXX Implement this at some point... */
@@ -407,7 +410,6 @@
 			}
 			commands += 9;
 		} else {
-#if CONFIG_SUN_CONSOLE
 			if (!strncmp(commands, "console=", 8)) {
 				commands += 8;
 				if (!strncmp (commands, "ttya", 4)) {
@@ -428,9 +430,7 @@
 				} else {
 					console_fb = 1;
 				}
-			} else
-#endif
-			if (!strncmp(commands, "mem=", 4)) {
+			} else if (!strncmp(commands, "mem=", 4)) {
 				/*
 				 * "mem=XXX[kKmM]" overrides the PROM-reported
 				 * memory size.
@@ -686,8 +686,38 @@
 }
 
 struct seq_operations cpuinfo_op = {
-	start:	c_start,
-	next:	c_next,
-	stop:	c_stop,
-	show:	show_cpuinfo,
+	.start =c_start,
+	.next =	c_next,
+	.stop =	c_stop,
+	.show =	show_cpuinfo,
 };
+
+extern int stop_a_enabled;
+
+void sun_do_break(void)
+{
+	if (!stop_a_enabled)
+		return;
+
+	printk("\n");
+	flush_user_windows();
+
+	prom_cmdline();
+}
+
+#ifdef CONFIG_MAGIC_SYSRQ
+/* Because we use the generic input layer keyboard drivers for
+ * everything, this PC sysrq translation table is all we need.
+ */
+unsigned char kbd_sysrq_xlate[128] =
+	"\000\0331234567890-=\177\t"			/* 0x00 - 0x0f */
+	"qwertyuiop[]\r\000as"				/* 0x10 - 0x1f */
+	"dfghjkl;'`\000\\zxcv"				/* 0x20 - 0x2f */
+	"bnm,./\000*\000 \000\201\202\203\204\205"	/* 0x30 - 0x3f */
+	"\206\207\210\211\212\000\000789-456+1"		/* 0x40 - 0x4f */
+	"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
+	"\r\000/";					/* 0x60 - 0x6f */
+#endif
+
+int serial_console;
+int stop_a_enabled = 1;
diff -Nru a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
--- a/arch/sparc64/kernel/smp.c	Sat Aug 10 18:42:19 2002
+++ b/arch/sparc64/kernel/smp.c	Sat Aug 10 18:42:19 2002
@@ -45,29 +45,16 @@
 
 /* Please don't make this stuff initdata!!!  --DaveM */
 static unsigned char boot_cpu_id;
-static int smp_activated;
 
 /* Kernel spinlock */
 spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
 
-volatile int smp_processors_ready = 0;
 atomic_t sparc64_num_cpus_online = ATOMIC_INIT(0);
 unsigned long cpu_online_map = 0;
-int smp_threads_ready = 0;
-
-void __init smp_setup(char *str, int *ints)
-{
-	/* XXX implement me XXX */
-}
-
-static int max_cpus = NR_CPUS;
-static int __init maxcpus(char *str)
-{
-	get_option(&str, &max_cpus);
-	return 1;
-}
-
-__setup("maxcpus=", maxcpus);
+atomic_t sparc64_num_cpus_possible = ATOMIC_INIT(0);
+unsigned long phys_cpu_present_map = 0;
+static unsigned long smp_commenced_mask;
+static unsigned long cpu_callout_map;
 
 void smp_info(struct seq_file *m)
 {
@@ -121,10 +108,6 @@
 		cpu_data[id].irq_worklists[i] = 0;
 }
 
-void __init smp_commence(void)
-{
-}
-
 static void smp_setup_percpu_timer(void);
 
 static volatile unsigned long callin_flag = 0;
@@ -216,8 +199,11 @@
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
 
-	while (!smp_threads_ready)
+	while (!test_bit(cpuid, &smp_commenced_mask))
 		membar("#LoadLoad");
+
+	set_bit(cpuid, &cpu_online_map);
+	atomic_inc(&sparc64_num_cpus_online);
 }
 
 void cpu_panic(void)
@@ -236,103 +222,46 @@
  */
 static struct thread_info *cpu_new_thread = NULL;
 
-static void smp_tune_scheduling(void);
-
-void __init smp_boot_cpus(void)
+static int __devinit smp_boot_one_cpu(unsigned int cpu)
 {
-	int cpucount = 0, i;
+	unsigned long entry =
+		(unsigned long)(&sparc64_cpu_startup);
+	unsigned long cookie =
+		(unsigned long)(&cpu_new_thread);
+	struct task_struct *p;
+	int timeout, no, ret;
 
-	printk("Entering UltraSMPenguin Mode...\n");
-	local_irq_enable();
-	smp_store_cpu_info(boot_cpu_id);
+	kernel_thread(NULL, NULL, CLONE_IDLETASK);
 
-	if (linux_num_cpus == 1) {
-		smp_tune_scheduling();
-		return;
-	}
+	p = prev_task(&init_task);
 
-	for (i = 0; i < NR_CPUS; i++) {
-		if (i == boot_cpu_id)
-			continue;
+	init_idle(p, cpu);
 
-		if ((cpucount + 1) == max_cpus)
-			goto ignorecpu;
-		if (cpu_online(i)) {
-			unsigned long entry =
-				(unsigned long)(&sparc64_cpu_startup);
-			unsigned long cookie =
-				(unsigned long)(&cpu_new_thread);
-			struct task_struct *p;
-			int timeout;
-			int no;
-
-			prom_printf("Starting CPU %d... ", i);
-			kernel_thread(NULL, NULL, CLONE_IDLETASK);
-			cpucount++;
-
-			p = prev_task(&init_task);
-
-			init_idle(p, i);
-
-			unhash_process(p);
-
-			callin_flag = 0;
-			for (no = 0; no < linux_num_cpus; no++)
-				if (linux_cpus[no].mid == i)
-					break;
-			cpu_new_thread = p->thread_info;
-			prom_startcpu(linux_cpus[no].prom_node,
-				      entry, cookie);
-			for (timeout = 0; timeout < 5000000; timeout++) {
-				if (callin_flag)
-					break;
-				udelay(100);
-			}
-			if (callin_flag) {
-				atomic_inc(&sparc64_num_cpus_online);
-				prom_cpu_nodes[i] = linux_cpus[no].prom_node;
-				prom_printf("OK\n");
-			} else {
-				cpucount--;
-				printk("Processor %d is stuck.\n", i);
-				prom_printf("FAILED\n");
-			}
-			if (!callin_flag) {
-ignorecpu:
-				clear_bit(i, &cpu_online_map);
-			}
+	unhash_process(p);
 
-		}
+	callin_flag = 0;
+	for (no = 0; no < linux_num_cpus; no++)
+		if (linux_cpus[no].mid == cpu)
+			break;
+	cpu_new_thread = p->thread_info;
+	set_bit(cpu, &cpu_callout_map);
+	prom_startcpu(linux_cpus[no].prom_node, entry, cookie);
+	for (timeout = 0; timeout < 5000000; timeout++) {
+		if (callin_flag)
+			break;
+		udelay(100);
 	}
-	cpu_new_thread = NULL;
-	if (cpucount == 0) {
-		if (max_cpus != 1)
-			printk("Error: only one processor found.\n");
-		memset(&cpu_online_map, 0, sizeof(cpu_online_map));
-		set_bit(smp_processor_id(), &cpu_online_map);
-		atomic_set(&sparc64_num_cpus_online, 1);
+	if (callin_flag) {
+		prom_cpu_nodes[cpu] = linux_cpus[no].prom_node;
+		ret = 0;
 	} else {
-		unsigned long bogosum = 0;
-
-		for (i = 0; i < NR_CPUS; i++) {
-			if (cpu_online(i))
-				bogosum += cpu_data[i].udelay_val;
-		}
-		printk("Total of %d processors activated "
-		       "(%lu.%02lu BogoMIPS).\n",
-		       cpucount + 1,
-		       bogosum/(500000/HZ),
-		       (bogosum/(5000/HZ))%100);
-		smp_activated = 1;
+		printk("Processor %d is stuck.\n", cpu);
+		clear_bit(cpu, &cpu_callout_map);
+		ret = -ENODEV;
 	}
+	cpu_new_thread = NULL;
 
-	/* We want to run this with all the other cpus spinning
-	 * in the kernel.
-	 */
-	smp_tune_scheduling();
-
-	smp_processors_ready = 1;
-	membar("#StoreStore | #StoreLoad");
+	return ret;
 }
 
 static void spitfire_xcall_helper(u64 data0, u64 data1, u64 data2, u64 pstate, unsigned long cpu)
@@ -532,19 +461,16 @@
  */
 static void smp_cross_call_masked(unsigned long *func, u32 ctx, u64 data1, u64 data2, unsigned long mask)
 {
-	if (smp_processors_ready) {
-		u64 data0 = (((u64)ctx)<<32 | (((u64)func) & 0xffffffff));
-
-		mask &= cpu_online_map;
-		mask &= ~(1UL<<smp_processor_id());
+	u64 data0 = (((u64)ctx)<<32 | (((u64)func) & 0xffffffff));
 
-		if (tlb_type == spitfire)
-			spitfire_xcall_deliver(data0, data1, data2, mask);
-		else
-			cheetah_xcall_deliver(data0, data1, data2, mask);
+	mask &= cpu_online_map;
+	mask &= ~(1UL<<smp_processor_id());
 
-		/* NOTE: Caller runs local copy on master. */
-	}
+	if (tlb_type == spitfire)
+		spitfire_xcall_deliver(data0, data1, data2, mask);
+	else
+		cheetah_xcall_deliver(data0, data1, data2, mask);
+	/* NOTE: Caller runs local copy on master. */
 }
 
 /* Send cross call to all processors except self. */
@@ -660,54 +586,19 @@
 
 void smp_flush_dcache_page_impl(struct page *page, int cpu)
 {
-	if (smp_processors_ready) {
-		unsigned long mask = 1UL << cpu;
+	unsigned long mask = 1UL << cpu;
 
 #ifdef CONFIG_DEBUG_DCFLUSH
-		atomic_inc(&dcpage_flushes);
+	atomic_inc(&dcpage_flushes);
 #endif
-		if (cpu == smp_processor_id()) {
-			__local_flush_dcache_page(page);
-		} else if ((cpu_online_map & mask) != 0) {
-			u64 data0;
-
-			if (tlb_type == spitfire) {
-				data0 =
-				  ((u64)&xcall_flush_dcache_page_spitfire);
-				if (page->mapping != NULL)
-					data0 |= ((u64)1 << 32);
-				spitfire_xcall_deliver(data0,
-						       __pa(page->virtual),
-						       (u64) page->virtual,
-						       mask);
-			} else {
-				data0 =
-				  ((u64)&xcall_flush_dcache_page_cheetah);
-				cheetah_xcall_deliver(data0,
-						      __pa(page->virtual),
-						      0, mask);
-			}
-#ifdef CONFIG_DEBUG_DCFLUSH
-			atomic_inc(&dcpage_flushes_xcall);
-#endif
-		}
-	}
-}
-
-void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
-{
-	if (smp_processors_ready) {
-		unsigned long mask =
-			cpu_online_map & ~(1UL << smp_processor_id());
+	if (cpu == smp_processor_id()) {
+		__local_flush_dcache_page(page);
+	} else if ((cpu_online_map & mask) != 0) {
 		u64 data0;
 
-#ifdef CONFIG_DEBUG_DCFLUSH
-		atomic_inc(&dcpage_flushes);
-#endif
-		if (mask == 0UL)
-			goto flush_self;
 		if (tlb_type == spitfire) {
-			data0 = ((u64)&xcall_flush_dcache_page_spitfire);
+			data0 =
+				((u64)&xcall_flush_dcache_page_spitfire);
 			if (page->mapping != NULL)
 				data0 |= ((u64)1 << 32);
 			spitfire_xcall_deliver(data0,
@@ -715,7 +606,8 @@
 					       (u64) page->virtual,
 					       mask);
 		} else {
-			data0 = ((u64)&xcall_flush_dcache_page_cheetah);
+			data0 =
+				((u64)&xcall_flush_dcache_page_cheetah);
 			cheetah_xcall_deliver(data0,
 					      __pa(page->virtual),
 					      0, mask);
@@ -723,25 +615,51 @@
 #ifdef CONFIG_DEBUG_DCFLUSH
 		atomic_inc(&dcpage_flushes_xcall);
 #endif
-	flush_self:
-		__local_flush_dcache_page(page);
 	}
 }
 
+void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
+{
+	unsigned long mask = cpu_online_map & ~(1UL << smp_processor_id());
+	u64 data0;
+
+#ifdef CONFIG_DEBUG_DCFLUSH
+	atomic_inc(&dcpage_flushes);
+#endif
+	if (mask == 0UL)
+		goto flush_self;
+	if (tlb_type == spitfire) {
+		data0 = ((u64)&xcall_flush_dcache_page_spitfire);
+		if (page->mapping != NULL)
+			data0 |= ((u64)1 << 32);
+		spitfire_xcall_deliver(data0,
+				       __pa(page->virtual),
+				       (u64) page->virtual,
+				       mask);
+	} else {
+		data0 = ((u64)&xcall_flush_dcache_page_cheetah);
+		cheetah_xcall_deliver(data0,
+				      __pa(page->virtual),
+				      0, mask);
+	}
+#ifdef CONFIG_DEBUG_DCFLUSH
+	atomic_inc(&dcpage_flushes_xcall);
+#endif
+ flush_self:
+	__local_flush_dcache_page(page);
+}
+
 void smp_receive_signal(int cpu)
 {
-	if (smp_processors_ready) {
-		unsigned long mask = 1UL << cpu;
+	unsigned long mask = 1UL << cpu;
 
-		if ((cpu_online_map & mask) != 0) {
-			u64 data0 =
-			  (((u64)&xcall_receive_signal) & 0xffffffff);
-
-			if (tlb_type == spitfire)
-				spitfire_xcall_deliver(data0, 0, 0, mask);
-			else
-				cheetah_xcall_deliver(data0, 0, 0, mask);
-		}
+	if ((cpu_online_map & mask) != 0) {
+		u64 data0 = (((u64)&xcall_receive_signal) & 0xffffffff);
+
+		if (tlb_type == spitfire)
+			spitfire_xcall_deliver(data0, 0, 0, mask);
+		else
+			cheetah_xcall_deliver(data0, 0, 0, mask);
 	}
 }
 
@@ -934,43 +852,39 @@
 
 void smp_capture(void)
 {
-	if (smp_processors_ready) {
-		int result = __atomic_add(1, &smp_capture_depth);
+	int result = __atomic_add(1, &smp_capture_depth);
 
-		membar("#StoreStore | #LoadStore");
-		if (result == 1) {
-			int ncpus = num_online_cpus();
+	membar("#StoreStore | #LoadStore");
+	if (result == 1) {
+		int ncpus = num_online_cpus();
 
 #ifdef CAPTURE_DEBUG
-			printk("CPU[%d]: Sending penguins to jail...",
-			       smp_processor_id());
+		printk("CPU[%d]: Sending penguins to jail...",
+		       smp_processor_id());
 #endif
-			penguins_are_doing_time = 1;
-			membar("#StoreStore | #LoadStore");
-			atomic_inc(&smp_capture_registry);
-			smp_cross_call(&xcall_capture, 0, 0, 0);
-			while (atomic_read(&smp_capture_registry) != ncpus)
-				membar("#LoadLoad");
+		penguins_are_doing_time = 1;
+		membar("#StoreStore | #LoadStore");
+		atomic_inc(&smp_capture_registry);
+		smp_cross_call(&xcall_capture, 0, 0, 0);
+		while (atomic_read(&smp_capture_registry) != ncpus)
+			membar("#LoadLoad");
 #ifdef CAPTURE_DEBUG
-			printk("done\n");
+		printk("done\n");
 #endif
-		}
 	}
 }
 
 void smp_release(void)
 {
-	if (smp_processors_ready) {
-		if (atomic_dec_and_test(&smp_capture_depth)) {
+	if (atomic_dec_and_test(&smp_capture_depth)) {
 #ifdef CAPTURE_DEBUG
-			printk("CPU[%d]: Giving pardon to "
-			       "imprisoned penguins\n",
-			       smp_processor_id());
+		printk("CPU[%d]: Giving pardon to "
+		       "imprisoned penguins\n",
+		       smp_processor_id());
 #endif
-			penguins_are_doing_time = 0;
-			membar("#StoreStore | #StoreLoad");
-			atomic_dec(&smp_capture_registry);
-		}
+		penguins_are_doing_time = 0;
+		membar("#StoreStore | #StoreLoad");
+		atomic_dec(&smp_capture_registry);
 	}
 }
 
@@ -1006,8 +920,7 @@
 
 void smp_promstop_others(void)
 {
-	if (smp_processors_ready)
-		smp_cross_call(&xcall_promstop, 0, 0, 0);
+	smp_cross_call(&xcall_promstop, 0, 0, 0);
 }
 
 extern void sparc64_do_profile(unsigned long pc, unsigned long o7);
@@ -1049,12 +962,12 @@
 					   regs->u_regs[UREG_RETPC]);
 		if (!--prof_counter(cpu)) {
 			if (cpu == boot_cpu_id) {
-				irq_enter(cpu, 0);
+				irq_enter();
 
 				kstat.irqs[cpu][0]++;
 				timer_tick_interrupt(regs);
 
-				irq_exit(cpu, 0);
+				irq_exit();
 			}
 
 			update_process_times(user);
@@ -1166,8 +1079,6 @@
 
 void __init smp_tick_init(void)
 {
-	int i;
-	
 	boot_cpu_id = hard_smp_processor_id();
 	current_tick_offset = timer_tick_offset;
 
@@ -1176,13 +1087,8 @@
 		prom_halt();
 	}
 
-	atomic_set(&sparc64_num_cpus_online, 1);
-	memset(&cpu_online_map, 0, sizeof(cpu_online_map));
-	for (i = 0; i < linux_num_cpus; i++) {
-		if (linux_cpus[i].mid < NR_CPUS)
-			set_bit(linux_cpus[i].mid, &cpu_online_map);
-	}
-
+	atomic_inc(&sparc64_num_cpus_online);
+	set_bit(boot_cpu_id, &cpu_online_map);
 	prom_cpu_nodes[boot_cpu_id] = linux_cpus[0].prom_node;
 	prof_counter(boot_cpu_id) = prof_multiplier(boot_cpu_id) = 1;
 }
@@ -1294,6 +1200,8 @@
 }
 
 /* /proc/profile writes can call this, don't __init it please. */
+static spinlock_t prof_setup_lock = SPIN_LOCK_UNLOCKED;
+
 int setup_profiling_timer(unsigned int multiplier)
 {
 	unsigned long flags;
@@ -1302,11 +1210,72 @@
 	if ((!multiplier) || (timer_tick_offset / multiplier) < 1000)
 		return -EINVAL;
 
-	save_and_cli(flags);
+	spin_lock_irqsave(&prof_setup_lock, flags);
 	for (i = 0; i < NR_CPUS; i++)
 		prof_multiplier(i) = multiplier;
 	current_tick_offset = (timer_tick_offset / multiplier);
-	restore_flags(flags);
+	spin_unlock_irqrestore(&prof_setup_lock, flags);
 
 	return 0;
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+	int i;
+
+	for (i = 0; i < linux_num_cpus; i++) {
+		if (linux_cpus[i].mid < max_cpus) {
+			set_bit(linux_cpus[i].mid,
+				&phys_cpu_present_map);
+			atomic_inc(&sparc64_num_cpus_possible);
+		}
+	}
+	if (atomic_read(&sparc64_num_cpus_possible) > max_cpus) {
+		for (i = linux_num_cpus - 1; i >= 0; i--) {
+			if (linux_cpus[i].mid != boot_cpu_id) {
+				clear_bit(linux_cpus[i].mid,
+					  &phys_cpu_present_map);
+				atomic_dec(&sparc64_num_cpus_possible);
+				if (atomic_read(&sparc64_num_cpus_possible) <= max_cpus)
+					break;
+			}
+		}
+	}
+
+	smp_store_cpu_info(boot_cpu_id);
+}
+
+int __devinit __cpu_up(unsigned int cpu)
+{
+	int ret = smp_boot_one_cpu(cpu);
+
+	if (!ret) {
+		set_bit(cpu, &smp_commenced_mask);
+		while (!test_bit(cpu, &cpu_online_map))
+			mb();
+		if (!test_bit(cpu, &cpu_online_map))
+			ret = -ENODEV;
+	}
+	return ret;
+}
+
+void __init smp_cpus_done(unsigned int max_cpus)
+{
+	unsigned long bogosum = 0;
+	int i;
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (cpu_online(i))
+			bogosum += cpu_data[i].udelay_val;
+	}
+	printk("Total of %d processors activated "
+	       "(%lu.%02lu BogoMIPS).\n",
+	       num_online_cpus(),
+	       bogosum/(500000/HZ),
+	       (bogosum/(5000/HZ))%100);
+
+	/* We want to run this with all the other cpus spinning
+	 * in the kernel.
+	 */
+	smp_tune_scheduling();
 }
diff -Nru a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
--- a/arch/sparc64/kernel/sparc64_ksyms.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/kernel/sparc64_ksyms.c	Sat Aug 10 18:42:22 2002
@@ -52,6 +52,7 @@
 #include <asm/isa.h>
 #endif
 #include <asm/a.out.h>
+#include <asm/ns87303.h>
 
 struct poll {
 	int fd;
@@ -130,14 +131,9 @@
 EXPORT_SYMBOL(kernel_flag);
 
 /* Hard IRQ locking */
-EXPORT_SYMBOL(global_irq_holder);
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(synchronize_irq);
 #endif
-EXPORT_SYMBOL(__global_cli);
-EXPORT_SYMBOL(__global_sti);
-EXPORT_SYMBOL(__global_save_flags);
-EXPORT_SYMBOL(__global_restore_flags);
 
 #if defined(CONFIG_MCOUNT)
 extern void mcount(void);
@@ -150,6 +146,8 @@
 /* CPU online map and active count.  */
 EXPORT_SYMBOL(cpu_online_map);
 EXPORT_SYMBOL(sparc64_num_cpus_online);
+EXPORT_SYMBOL(phys_cpu_present_map);
+EXPORT_SYMBOL(sparc64_num_cpus_possible);
 
 /* Spinlock debugging library, optional. */
 #ifdef CONFIG_DEBUG_SPINLOCK
@@ -367,10 +365,15 @@
 /* RAID code needs this */
 EXPORT_SYMBOL_NOVERS(VISenter);
 
-extern void batten_down_hatches(void);
 /* for input/keybdev */
-EXPORT_SYMBOL(batten_down_hatches);
+EXPORT_SYMBOL(sun_do_break);
+EXPORT_SYMBOL(serial_console);
+EXPORT_SYMBOL(stop_a_enabled);
+EXPORT_SYMBOL(kbd_pt_regs);
 
 #ifdef CONFIG_DEBUG_BUGVERBOSE
 EXPORT_SYMBOL(do_BUG);
 #endif
+
+/* for ns8703 */
+EXPORT_SYMBOL(ns87303_lock);
diff -Nru a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
--- a/arch/sparc64/kernel/sys_sparc32.c	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc64/kernel/sys_sparc32.c	Sat Aug 10 18:42:23 2002
@@ -3886,14 +3886,14 @@
 
 typedef __kernel_ssize_t32 ssize_t32;
 
-asmlinkage ssize_t32 sys32_pread(unsigned int fd, char *ubuf,
-				 __kernel_size_t32 count, u32 poshi, u32 poslo)
+asmlinkage ssize_t32 sys32_pread64(unsigned int fd, char *ubuf,
+				   __kernel_size_t32 count, u32 poshi, u32 poslo)
 {
 	return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
 
-asmlinkage ssize_t32 sys32_pwrite(unsigned int fd, char *ubuf,
-				  __kernel_size_t32 count, u32 poshi, u32 poslo)
+asmlinkage ssize_t32 sys32_pwrite64(unsigned int fd, char *ubuf,
+				    __kernel_size_t32 count, u32 poshi, u32 poslo)
 {
 	return sys_pwrite64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo));
 }
diff -Nru a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
--- a/arch/sparc64/kernel/systbls.S	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/kernel/systbls.S	Sat Aug 10 18:42:22 2002
@@ -91,7 +91,7 @@
 /*50*/	.word sys_getegid, sys_acct, sys_memory_ordering, sys_nis_syscall, sys_ioctl
 	.word sys_reboot, sys_nis_syscall, sys_symlink, sys_readlink, sys_execve
 /*60*/	.word sys_umask, sys_chroot, sys_newfstat, sys_nis_syscall, sys_getpagesize
-	.word sys_msync, sys_vfork, sys_pread, sys_pwrite, sys_nis_syscall
+	.word sys_msync, sys_vfork, sys_pread64, sys_pwrite64, sys_nis_syscall
 /*70*/	.word sys_nis_syscall, sys_mmap, sys_nis_syscall, sys64_munmap, sys_mprotect
 	.word sys_madvise, sys_vhangup, sys_nis_syscall, sys_mincore, sys_getgroups
 /*80*/	.word sys_setgroups, sys_getpgrp, sys_nis_syscall, sys_setitimer, sys_nis_syscall
diff -Nru a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c
--- a/arch/sparc64/kernel/unaligned.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/kernel/unaligned.c	Sat Aug 10 18:42:22 2002
@@ -320,15 +320,19 @@
 	store_common(dst_addr, size, src_val, asi, errh);			\
 })
 
-/* XXX Need to capture/release other cpu's for SMP around this. */
+extern void smp_capture(void);
+extern void smp_release(void);
+
 #define do_atomic(srcdest_reg, mem, errh) ({					\
 	unsigned long flags, tmp;						\
 										\
-	save_and_cli(flags);							\
+	smp_capture();								\
+	local_irq_save(flags);							\
 	tmp = *srcdest_reg;							\
 	do_integer_load(srcdest_reg, 4, mem, 0, errh);				\
 	store_common(mem, 4, &tmp, errh);					\
-	restore_flags(flags);							\
+	local_irq_restore(flags);						\
+	smp_release();								\
 })
 
 static inline void advance(struct pt_regs *regs)
diff -Nru a/arch/sparc64/prom/misc.c b/arch/sparc64/prom/misc.c
--- a/arch/sparc64/prom/misc.c	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc64/prom/misc.c	Sat Aug 10 18:42:23 2002
@@ -16,28 +16,24 @@
 #include <asm/oplib.h>
 
 /* Reset and reboot the machine with the command 'bcommand'. */
-void
-prom_reboot(char *bcommand)
+void prom_reboot(char *bcommand)
 {
-	p1275_cmd ("boot", P1275_ARG(0,P1275_ARG_IN_STRING)|
-		           P1275_INOUT(1,0), bcommand);
+	p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) |
+		  P1275_INOUT(1, 0), bcommand);
 }
 
 /* Forth evaluate the expression contained in 'fstring'. */
-void
-prom_feval(char *fstring)
+void prom_feval(char *fstring)
 {
-	if(!fstring || fstring[0] == 0)
+	if (!fstring || fstring[0] == 0)
 		return;
-	p1275_cmd ("interpret", P1275_ARG(0,P1275_ARG_IN_STRING)|
-				P1275_INOUT(1,1), fstring);
+	p1275_cmd("interpret", P1275_ARG(0, P1275_ARG_IN_STRING) |
+		  P1275_INOUT(1, 1), fstring);
 }
 
 /* We want to do this more nicely some day. */
-#ifdef CONFIG_SUN_CONSOLE
 extern void (*prom_palette)(int);
 extern int serial_console;
-#endif
 
 #ifdef CONFIG_SMP
 extern void smp_capture(void);
@@ -47,33 +43,27 @@
 /* Drop into the prom, with the chance to continue with the 'go'
  * prom command.
  */
-void
-prom_cmdline(void)
+void prom_cmdline(void)
 {
 	unsigned long flags;
 
 	local_irq_save(flags);
 
-#ifdef CONFIG_SUN_CONSOLE
-	if(!serial_console && prom_palette)
-		prom_palette (1);
-#endif
+	if (!serial_console && prom_palette)
+		prom_palette(1);
 
 #ifdef CONFIG_SMP
 	smp_capture();
 #endif
 
-	p1275_cmd ("enter", P1275_INOUT(0,0));
+	p1275_cmd("enter", P1275_INOUT(0, 0));
 
 #ifdef CONFIG_SMP
 	smp_release();
-	spin_unlock_wait(&__br_write_locks[BR_GLOBALIRQ_LOCK].lock);
 #endif
 
-#ifdef CONFIG_SUN_CONSOLE
-	if(!serial_console && prom_palette)
-		prom_palette (0);
-#endif
+	if (!serial_console && prom_palette)
+		prom_palette(0);
 
 	local_irq_restore(flags);
 }
@@ -85,74 +75,69 @@
 /* Drop into the prom, but completely terminate the program.
  * No chance of continuing.
  */
-void
-prom_halt(void)
+void prom_halt(void)
 {
 #ifdef CONFIG_SMP
 	smp_promstop_others();
 	udelay(8000);
 #endif
 again:
-	p1275_cmd ("exit", P1275_INOUT(0,0));
+	p1275_cmd("exit", P1275_INOUT(0, 0));
 	goto again; /* PROM is out to get me -DaveM */
 }
 
-void
-prom_halt_power_off(void)
+void prom_halt_power_off(void)
 {
 #ifdef CONFIG_SMP
 	smp_promstop_others();
 	udelay(8000);
 #endif
-	p1275_cmd ("SUNW,power-off", P1275_INOUT(0,0));
+	p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0));
 
 	/* if nothing else helps, we just halt */
-	prom_halt ();
+	prom_halt();
 }
 
 /* Set prom sync handler to call function 'funcp'. */
-void
-prom_setcallback(callback_func_t funcp)
+void prom_setcallback(callback_func_t funcp)
 {
-	if(!funcp) return;
-	p1275_cmd ("set-callback", P1275_ARG(0,P1275_ARG_IN_FUNCTION)|
-				   P1275_INOUT(1,1), funcp);
+	if (!funcp)
+		return;
+	p1275_cmd("set-callback", P1275_ARG(0, P1275_ARG_IN_FUNCTION) |
+		  P1275_INOUT(1, 1), funcp);
 }
 
 /* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
  * format type.  'num_bytes' is the number of bytes that your idbuf
  * has space for.  Returns 0xff on error.
  */
-unsigned char
-prom_get_idprom(char *idbuf, int num_bytes)
+unsigned char prom_get_idprom(char *idbuf, int num_bytes)
 {
 	int len;
 
 	len = prom_getproplen(prom_root_node, "idprom");
-	if((len>num_bytes) || (len==-1)) return 0xff;
-	if(!prom_getproperty(prom_root_node, "idprom", idbuf, num_bytes))
+	if ((len >num_bytes) || (len == -1))
+		return 0xff;
+	if (!prom_getproperty(prom_root_node, "idprom", idbuf, num_bytes))
 		return idbuf[0];
 
 	return 0xff;
 }
 
 /* Get the major prom version number. */
-int
-prom_version(void)
+int prom_version(void)
 {
 	return PROM_P1275;
 }
 
 /* Get the prom plugin-revision. */
-int
-prom_getrev(void)
+int prom_getrev(void)
 {
 	return prom_rev;
 }
 
 /* Get the prom firmware print revision. */
-int
-prom_getprev(void)
+int prom_getprev(void)
 {
 	return prom_prev;
 }
@@ -174,7 +159,7 @@
 
 	node = prom_finddevice("/chosen");
 	ret = prom_getint(node, "mmu");
-	if(ret == -1 || ret == 0)
+	if (ret == -1 || ret == 0)
 		mmu_ihandle_cache = -1;
 	else
 		mmu_ihandle_cache = ret;
@@ -285,7 +270,7 @@
 	/* If align is zero, the pa_low/pa_high args are passed,
 	 * else they are not.
 	 */
-	if(align == 0)
+	if (align == 0)
 		return p1275_cmd("SUNW,retain",
 				 (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 2)),
 				 name, pa_low, pa_high, size, align);
diff -Nru a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
--- a/arch/sparc64/solaris/fs.c	Sat Aug 10 18:42:21 2002
+++ b/arch/sparc64/solaris/fs.c	Sat Aug 10 18:42:21 2002
@@ -669,18 +669,18 @@
 
 asmlinkage int solaris_pread(unsigned int fd, char *buf, u32 count, u32 pos)
 {
-	ssize_t (*sys_pread)(unsigned int, char *, size_t, loff_t) =
-		(ssize_t (*)(unsigned int, char *, size_t, loff_t))SYS(pread);
-		
-	return sys_pread(fd, buf, count, (loff_t)pos);
+	ssize_t (*sys_pread64)(unsigned int, char *, size_t, loff_t) =
+		(ssize_t (*)(unsigned int, char *, size_t, loff_t))SYS(pread64);
+
+	return sys_pread64(fd, buf, count, (loff_t)pos);
 }
 
 asmlinkage int solaris_pwrite(unsigned int fd, char *buf, u32 count, u32 pos)
 {
-	ssize_t (*sys_pwrite)(unsigned int, char *, size_t, loff_t) =
-		(ssize_t (*)(unsigned int, char *, size_t, loff_t))SYS(pwrite);
-		
-	return sys_pwrite(fd, buf, count, (loff_t)pos);
+	ssize_t (*sys_pwrite64)(unsigned int, char *, size_t, loff_t) =
+		(ssize_t (*)(unsigned int, char *, size_t, loff_t))SYS(pwrite64);
+
+	return sys_pwrite64(fd, buf, count, (loff_t)pos);
 }
 
 /* POSIX.1 names */
diff -Nru a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
--- a/arch/sparc64/solaris/misc.c	Sat Aug 10 18:42:23 2002
+++ b/arch/sparc64/solaris/misc.c	Sat Aug 10 18:42:23 2002
@@ -708,14 +708,14 @@
 extern long solaris_to_linux_signals[], linux_to_solaris_signals[];
 
 struct exec_domain solaris_exec_domain = {
-	name:		"Solaris",
-	handler:	NULL,
-	pers_low:	1,		/* PER_SVR4 personality */
-	pers_high:	1,
-	signal_map:	solaris_to_linux_signals,
-	signal_invmap:	linux_to_solaris_signals,
-	module:		THIS_MODULE,
-	next:		NULL
+	.name =		"Solaris",
+	.handler =	NULL,
+	.pers_low =	1,		/* PER_SVR4 personality */
+	.pers_high =	1,
+	.signal_map =	solaris_to_linux_signals,
+	.signal_invmap =linux_to_solaris_signals,
+	.module =	THIS_MODULE,
+	.next =		NULL
 };
 
 extern int init_socksys(void);
diff -Nru a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c
--- a/arch/sparc64/solaris/socksys.c	Sat Aug 10 18:42:22 2002
+++ b/arch/sparc64/solaris/socksys.c	Sat Aug 10 18:42:22 2002
@@ -165,8 +165,8 @@
 }
 	
 static struct file_operations socksys_fops = {
-	open:		socksys_open,
-	release:	socksys_release,
+	.open =		socksys_open,
+	.release =	socksys_release,
 };
 
 static devfs_handle_t devfs_handle;
diff -Nru a/arch/sparc64/solaris/systbl.S b/arch/sparc64/solaris/systbl.S
--- a/arch/sparc64/solaris/systbl.S	Sat Aug 10 18:42:20 2002
+++ b/arch/sparc64/solaris/systbl.S	Sat Aug 10 18:42:20 2002
@@ -250,8 +250,8 @@
 	.word solaris_fstatvfs64	/* fstatvfs64	dP	219	*/
 	.word solaris_setrlimit64	/* setrlimit64	dP	220	*/
 	.word solaris_getrlimit64	/* getrlimit64	dP	221	*/
-	.word CHAIN(pread)		/* pread64	dpdD	222	*/
-	.word CHAIN(pwrite)		/* pwrite64	dpdD	223	*/
+	.word CHAIN(pread64)		/* pread64	dpdD	222	*/
+	.word CHAIN(pwrite64)		/* pwrite64	dpdD	223	*/
 	.word CHAIN(creat)		/* creat64	so	224	*/
 	.word solaris_open		/* open64	soo	225	*/
 	.word solaris_unimplemented	/* 			226	*/
diff -Nru a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c
--- a/drivers/acorn/block/fd1772.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/acorn/block/fd1772.c	Sat Aug 10 18:42:22 2002
@@ -379,21 +379,21 @@
 /************************* End of Prototypes **************************/
 
 static struct timer_list motor_off_timer = {
-	function:	fd_motor_off_timer,
+	.function	= fd_motor_off_timer,
 };
 
 #ifdef TRACKBUFFER
 static struct timer_list readtrack_timer = {
-	function: 	fd_readtrack_check,
+	.function 	= fd_readtrack_check,
 };
 #endif
 
 static struct timer_list timeout_timer = {
-	function:	fd_times_out,
+	.function	= fd_times_out,
 };
 
 static struct timer_list fd_timer = {
-	function:	check_change,
+	.function	= check_change,
 };
 
 /* DAG: Haven't got a clue what this is? */
@@ -1324,37 +1324,25 @@
 #endif
 
 	set_bit(rdev & 3, &fake_change);
-	check_disk_change(rdev);
 	return 0;
 }
 
 static int fd_ioctl(struct inode *inode, struct file *filp,
 		    unsigned int cmd, unsigned long param)
 {
-	int drive, device;
+	struct block_device *bdev = inode->i_bdev;
+	int drive = MINOR(bdev->bd_dev);
 
-	device = inode->i_rdev;
-	drive = minor(device);
 	switch (cmd) {
-	case FDFMTBEG:
-		return 0;
-		/* case FDC1772LRPRM:  ??? DAG what does this do?? 
-		   unit[drive].disktype = NULL;
-		   floppy_sizes[drive] = MAX_DISK_SIZE;
-		   return invalidate_drive (device); */
 	case FDFMTEND:
 	case FDFLUSH:
-		return invalidate_drive(drive);
-	}
-	if (!capable(CAP_SYS_ADMIN))
-		return -EPERM;
-	if (drive < 0 || drive > 3)
-		return -EINVAL;
-	switch (cmd) {
+		invalidate_drive(drive);
+		check_disk_change(bdev);
+	case FDFMTBEG:
+		return 0;
 	default:
 		return -EINVAL;
 	}
-	return 0;
 }
 
 
@@ -1520,7 +1508,7 @@
 		return 0;
 
 	if (filp->f_mode & 3) {
-		check_disk_change(inode->i_rdev);
+		check_disk_change(inode->i_bdev);
 		if (filp->f_mode & 2) {
 			if (unit[drive].wpstat) {
 				floppy_release(inode, filp);
@@ -1548,11 +1536,11 @@
 
 static struct block_device_operations floppy_fops =
 {
-	open:			floppy_open,
-	release:		floppy_release,
-	ioctl:			fd_ioctl,
-	check_media_change:	check_floppy_change,
-	revalidate:		floppy_revalidate,
+	.open			= floppy_open,
+	.release		= floppy_release,
+	.ioctl			= fd_ioctl,
+	.check_media_change	= check_floppy_change,
+	.revalidate		= floppy_revalidate,
 };
 
 
diff -Nru a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
--- a/drivers/acorn/block/mfmhd.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/acorn/block/mfmhd.c	Sat Aug 10 18:42:21 2002
@@ -226,7 +226,6 @@
 static void mfm_seek(void);
 static void mfm_rerequest(void);
 static void mfm_request(void);
-static int mfm_reread_partitions(kdev_t dev);
 static void mfm_specify (void);
 static void issue_request(int dev, unsigned int block, unsigned int nsect,
 			  struct request *req);
@@ -1165,40 +1164,30 @@
 {
 	struct hd_geometry *geo = (struct hd_geometry *) arg;
 	kdev_t dev;
-	int device, major, minor, err;
+	int device, minor, err;
 
 	if (!inode || !(dev = inode->i_rdev))
 		return -EINVAL;
 
-	major = major(dev);
 	minor = minor(dev);
 
 	device = DEVICE_NR(minor(inode->i_rdev)), err;
 	if (device >= mfm_drives)
 		return -EINVAL;
 
-	switch (cmd) {
-	case HDIO_GETGEO:
-		if (!arg)
-			return -EINVAL;
-		if (put_user (mfm_info[device].heads, &geo->heads))
-			return -EFAULT;
-		if (put_user (mfm_info[device].sectors, &geo->sectors))
-			return -EFAULT;
-		if (put_user (mfm_info[device].cylinders, &geo->cylinders))
-			return -EFAULT;
-		if (put_user (mfm[minor].start_sect, &geo->start))
-			return -EFAULT;
-		return 0;
-
-	case BLKRRPART:
-		if (!capable(CAP_SYS_ADMIN))
-			return -EACCES;
-		return mfm_reread_partitions(dev);
-
-	default:
+	if (cmd != HDIO_GETGEO)
 		return -EINVAL;
-	}
+	if (!arg)
+		return -EINVAL;
+	if (put_user (mfm_info[device].heads, &geo->heads))
+		return -EFAULT;
+	if (put_user (mfm_info[device].sectors, &geo->sectors))
+		return -EFAULT;
+	if (put_user (mfm_info[device].cylinders, &geo->cylinders))
+		return -EFAULT;
+	if (put_user (mfm[minor].start_sect, &geo->start))
+		return -EFAULT;
+	return 0;
 }
 
 static int mfm_open(struct inode *inode, struct file *file)
@@ -1255,25 +1244,25 @@
 
 static struct gendisk mfm_gendisk[2] = {
 {
-	major:		MAJOR_NR,
-	first_minor:	0,
-	major_name:	"mfm",
-	minor_shift:	6,
-	part:		mfm,
+	.major		= MAJOR_NR,
+	.first_minor	= 0,
+	.major_name	= "mfma",
+	.minor_shift	= 6,
+	.part		= mfm,
 },
 {
-	major:		MAJOR_NR,
-	first_minor:	64,
-	major_name:	"mfm",
-	minor_shift:	6,
-	part:		mfm + 64,
+	.major		= MAJOR_NR,
+	.first_minor	= 64,
+	.major_name	= "mfmb",
+	.minor_shift	= 6,
+	.part		= mfm + 64,
 };
 
 static struct block_device_operations mfm_fops =
 {
-	owner:		THIS_MODULE,
-	open:		mfm_open,
-	ioctl:		mfm_ioctl,
+	.owner		= THIS_MODULE,
+	.open		= mfm_open,
+	.ioctl		= mfm_ioctl,
 };
 
 static void mfm_geninit (void)
@@ -1393,25 +1382,6 @@
 	lastspecifieddrive = -1;
 
 	mfm_geninit();
-	return 0;
-}
-
-/*
- * This routine is called to flush all partitions and partition tables
- * for a changed MFM disk, and then re-read the new partition table.
- */
-static int mfm_reread_partitions(kdev_t dev)
-{
-	unsigned int unit = DEVICE_NR(minor(dev));
-	kdev_t device = mk_kdev(MAJOR_NR, unit << mfm_gendisk.minor_shift);
-	int err = dev_lock_part(device);
-	if (err)
-		return err;
-	wipe_partitions(device);
-	/* Divide by 2, since sectors are 2 times smaller than usual ;-) */
-	grok_partitions(device, mfm_info[unit].heads *
-		    mfm_info[unit].cylinders * mfm_info[unit].sectors / 2);
-	dev_unlock_part(device);
 	return 0;
 }
 
diff -Nru a/drivers/acorn/char/i2c.c b/drivers/acorn/char/i2c.c
--- a/drivers/acorn/char/i2c.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/acorn/char/i2c.c	Sat Aug 10 18:42:23 2002
@@ -200,13 +200,13 @@
 }
 
 static struct file_operations rtc_fops = {
-	ioctl:	rtc_ioctl,
+	.ioctl	= rtc_ioctl,
 };
 
 static struct miscdevice rtc_dev = {
-	minor:	RTC_MINOR,
-	name:	"rtc",
-	fops:	&rtc_fops,
+	.minor	= RTC_MINOR,
+	.name	= "rtc",
+	.fops	= &rtc_fops,
 };
 
 /* IOC / IOMD i2c driver */
@@ -264,13 +264,13 @@
 }
 
 static struct i2c_algo_bit_data ioc_data = {
-	setsda:		ioc_setsda,
-	setscl:		ioc_setscl,
-	getsda:		ioc_getsda,
-	getscl:		ioc_getscl,
-	udelay:		 80,
-	mdelay:		 80,
-	timeout:	100
+	.setsda		= ioc_setsda,
+	.setscl		= ioc_setscl,
+	.getsda		= ioc_getsda,
+	.getscl		= ioc_getscl,
+	.udelay		= 80,
+	.mdelay		= 80,
+	.timeout	= 100
 };
 
 static int ioc_client_reg(struct i2c_client *client)
@@ -303,11 +303,11 @@
 }
 
 static struct i2c_adapter ioc_ops = {
-	name:			"IOC/IOMD",
-	id:			I2C_HW_B_IOC,
-	algo_data:		&ioc_data,
-	client_register:	ioc_client_reg,
-	client_unregister:	ioc_client_unreg
+	.name			= "IOC/IOMD",
+	.id			= I2C_HW_B_IOC,
+	.algo_data		= &ioc_data,
+	.client_register	= ioc_client_reg,
+	.client_unregister	= ioc_client_unreg
 };
 
 static int __init i2c_ioc_init(void)
diff -Nru a/drivers/acorn/char/mouse_ps2.c b/drivers/acorn/char/mouse_ps2.c
--- a/drivers/acorn/char/mouse_ps2.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/acorn/char/mouse_ps2.c	Sat Aug 10 18:42:21 2002
@@ -250,12 +250,12 @@
 }
 
 struct file_operations psaux_fops = {
-	read:		read_aux,
-	write:		write_aux,
-	poll:		aux_poll,
-	open:		open_aux,
-	release:	release_aux,
-	fasync:		fasync_aux,
+	.read		= read_aux,
+	.write		= write_aux,
+	.poll		= aux_poll,
+	.open		= open_aux,
+	.release	= release_aux,
+	.fasync		= fasync_aux,
 };
 
 /*
diff -Nru a/drivers/acorn/char/pcf8583.c b/drivers/acorn/char/pcf8583.c
--- a/drivers/acorn/char/pcf8583.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/acorn/char/pcf8583.c	Sat Aug 10 18:42:23 2002
@@ -23,13 +23,13 @@
 static unsigned short normal_addr[] = { 0x50, I2C_CLIENT_END };
 
 static struct i2c_client_address_data addr_data = {
-	normal_i2c:		normal_addr,
-	normal_i2c_range:	ignore,
-	probe:			ignore,
-	probe_range:		ignore,
-	ignore:			ignore,
-	ignore_range:		ignore,
-	force:			ignore,
+	.normal_i2c		= normal_addr,
+	.normal_i2c_range	= ignore,
+	.probe			= ignore,
+	.probe_range		= ignore,
+	.ignore			= ignore,
+	.ignore_range		= ignore,
+	.force			= ignore,
 };
 
 #define DAT(x) ((unsigned int)(x->data))
@@ -224,12 +224,12 @@
 }
 
 static struct i2c_driver pcf8583_driver = {
-	name:		"PCF8583",
-	id:		I2C_DRIVERID_PCF8583,
-	flags:		I2C_DF_NOTIFY,
-	attach_adapter:	pcf8583_probe,
-	detach_client:	pcf8583_detach,
-	command:	pcf8583_command
+	.name		= "PCF8583",
+	.id		= I2C_DRIVERID_PCF8583,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= pcf8583_probe,
+	.detach_client	= pcf8583_detach,
+	.command	= pcf8583_command
 };
 
 static __init int pcf8583_init(void)
diff -Nru a/drivers/acorn/net/etherh.c b/drivers/acorn/net/etherh.c
--- a/drivers/acorn/net/etherh.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/acorn/net/etherh.c	Sat Aug 10 18:42:23 2002
@@ -141,8 +141,8 @@
 }
 
 static expansioncard_ops_t etherh_ops = {
-	irqenable:	etherh_irq_enable,
-	irqdisable:	etherh_irq_disable,
+	.irqenable	= etherh_irq_enable,
+	.irqdisable	= etherh_irq_disable,
 };
 
 
diff -Nru a/drivers/acorn/scsi/acornscsi.c b/drivers/acorn/scsi/acornscsi.c
--- a/drivers/acorn/scsi/acornscsi.c	Sat Aug 10 18:42:19 2002
+++ b/drivers/acorn/scsi/acornscsi.c	Sat Aug 10 18:42:19 2002
@@ -3120,22 +3120,22 @@
 }
 
 static Scsi_Host_Template acornscsi_template = {
-	module:			THIS_MODULE,
-	proc_info:		acornscsi_proc_info,
-	name:			"AcornSCSI",
-	detect:			acornscsi_detect,
-	release:		acornscsi_release,
-	info:			acornscsi_info,
-	queuecommand:		acornscsi_queuecmd,
-	abort:			acornscsi_abort,
-	reset:			acornscsi_reset,
-	bios_param:		scsicam_bios_param,
-	can_queue:		16,
-	this_id:		7,
-	sg_tablesize:		SG_ALL,
-	cmd_per_lun:		2,
-	unchecked_isa_dma:	0,
-	use_clustering:		DISABLE_CLUSTERING
+	.module			= THIS_MODULE,
+	.proc_info		= acornscsi_proc_info,
+	.name			= "AcornSCSI",
+	.detect			= acornscsi_detect,
+	.release		= acornscsi_release,
+	.info			= acornscsi_info,
+	.queuecommand		= acornscsi_queuecmd,
+	.abort			= acornscsi_abort,
+	.reset			= acornscsi_reset,
+	.bios_param		= scsicam_bios_param,
+	.can_queue		= 16,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 2,
+	.unchecked_isa_dma	= 0,
+	.use_clustering		= DISABLE_CLUSTERING
 };
 
 static int __init acornscsi_init(void)
diff -Nru a/drivers/acorn/scsi/cumana_1.c b/drivers/acorn/scsi/cumana_1.c
--- a/drivers/acorn/scsi/cumana_1.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/acorn/scsi/cumana_1.c	Sat Aug 10 18:42:21 2002
@@ -389,21 +389,21 @@
 #include "../../scsi/NCR5380.c"
 
 static Scsi_Host_Template cumanascsi_template = {
-	module:			THIS_MODULE,
-	name:			"Cumana 16-bit SCSI",
-	detect:			cumanascsi_detect,
-	release:		cumanascsi_release,
-	info:			cumanascsi_info,
-	queuecommand:		cumanascsi_queue_command,
-	abort:			cumanascsi_abort,
-	reset:			cumanascsi_reset,
-	bios_param:		scsicam_bios_param,
-	can_queue:		16,
-	this_id:		7,
-	sg_tablesize:		SG_ALL,
-	cmd_per_lun:		2,
-	unchecked_isa_dma:	0,
-	use_clustering:		DISABLE_CLUSTERING
+	.module			= THIS_MODULE,
+	.name			= "Cumana 16-bit SCSI",
+	.detect			= cumanascsi_detect,
+	.release		= cumanascsi_release,
+	.info			= cumanascsi_info,
+	.queuecommand		= cumanascsi_queue_command,
+	.abort			= cumanascsi_abort,
+	.reset			= cumanascsi_reset,
+	.bios_param		= scsicam_bios_param,
+	.can_queue		= 16,
+	.this_id		= 7,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 2,
+	.unchecked_isa_dma	= 0,
+	.use_clustering		= DISABLE_CLUSTERING
 };
 
 static int __init cumanascsi_init(void)
diff -Nru a/drivers/acorn/scsi/cumana_2.c b/drivers/acorn/scsi/cumana_2.c
--- a/drivers/acorn/scsi/cumana_2.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/acorn/scsi/cumana_2.c	Sat Aug 10 18:42:23 2002
@@ -557,24 +557,24 @@
 }
 
 static Scsi_Host_Template cumanascsi2_template = {
-	module:				THIS_MODULE,
-	proc_info:			cumanascsi_2_proc_info,
-	name:				"Cumana SCSI II",
-	detect:				cumanascsi_2_detect,
-	release:			cumanascsi_2_release,
-	info:				cumanascsi_2_info,
-	bios_param:			scsicam_bios_param,
-	can_queue:			1,
-	this_id:			7,
-	sg_tablesize:			SG_ALL,
-	cmd_per_lun:			1,
-	use_clustering:			DISABLE_CLUSTERING,
-	command:			fas216_command,
-	queuecommand:			fas216_queue_command,
-	eh_host_reset_handler:		fas216_eh_host_reset,
-	eh_bus_reset_handler:		fas216_eh_bus_reset,
-	eh_device_reset_handler:	fas216_eh_device_reset,
-	eh_abort_handler:		fas216_eh_abort,
+	.module				= THIS_MODULE,
+	.proc_info			= cumanascsi_2_proc_info,
+	.name				= "Cumana SCSI II",
+	.detect				= cumanascsi_2_detect,
+	.release			= cumanascsi_2_release,
+	.info				= cumanascsi_2_info,
+	.bios_param			= scsicam_bios_param,
+	.can_queue			= 1,
+	.this_id			= 7,
+	.sg_tablesize			= SG_ALL,
+	.cmd_per_lun			= 1,
+	.use_clustering			= DISABLE_CLUSTERING,
+	.command			= fas216_command,
+	.queuecommand			= fas216_queue_command,
+	.eh_host_reset_handler		= fas216_eh_host_reset,
+	.eh_bus_reset_handler		= fas216_eh_bus_reset,
+	.eh_device_reset_handler	= fas216_eh_device_reset,
+	.eh_abort_handler		= fas216_eh_abort,
 };
 
 static int __init cumanascsi2_init(void)
diff -Nru a/drivers/acorn/scsi/ecoscsi.c b/drivers/acorn/scsi/ecoscsi.c
--- a/drivers/acorn/scsi/ecoscsi.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/acorn/scsi/ecoscsi.c	Sat Aug 10 18:42:23 2002
@@ -262,19 +262,19 @@
 #include "../../scsi/NCR5380.c"
 
 static Scsi_Host_Template ecoscsi_template =  {
-	module:		THIS_MODULE,
-	name:		"Serial Port EcoSCSI NCR5380",
-	detect:		ecoscsi_detect,
-	release:	ecoscsi_release,
-	info:		ecoscsi_info,
-	queuecommand:	ecoscsi_queue_command,
-	abort:		ecoscsi_abort,
-	reset:		ecoscsi_reset,
-	can_queue:	16,
-	this_id:	7,
-	sg_tablesize:	SG_ALL,
-	cmd_per_lun:	2,
-	use_clustering:	DISABLE_CLUSTERING
+	.module		= THIS_MODULE,
+	.name		= "Serial Port EcoSCSI NCR5380",
+	.detect		= ecoscsi_detect,
+	.release	= ecoscsi_release,
+	.info		= ecoscsi_info,
+	.queuecommand	= ecoscsi_queue_command,
+	.abort		= ecoscsi_abort,
+	.reset		= ecoscsi_reset,
+	.can_queue	= 16,
+	.this_id	= 7,
+	.sg_tablesize	= SG_ALL,
+	.cmd_per_lun	= 2,
+	.use_clustering	= DISABLE_CLUSTERING
 };
 
 static int __init ecoscsi_init(void)
diff -Nru a/drivers/acorn/scsi/eesox.c b/drivers/acorn/scsi/eesox.c
--- a/drivers/acorn/scsi/eesox.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/acorn/scsi/eesox.c	Sat Aug 10 18:42:23 2002
@@ -554,24 +554,24 @@
 }
 
 static Scsi_Host_Template eesox_template = {
-	module:				THIS_MODULE,
-	proc_info:			eesoxscsi_proc_info,
-	name:				"EESOX SCSI",
-	detect:				eesoxscsi_detect,
-	release:			eesoxscsi_release,
-	info:				eesoxscsi_info,
-	bios_param:			scsicam_bios_param,
-	can_queue:			1,
-	this_id:			7,
-	sg_tablesize:			SG_ALL,
-	cmd_per_lun:			1,
-	use_clustering:			DISABLE_CLUSTERING,
-	command:			fas216_command,
-	queuecommand:			fas216_queue_command,
-	eh_host_reset_handler:		fas216_eh_host_reset,
-	eh_bus_reset_handler:		fas216_eh_bus_reset,
-	eh_device_reset_handler:	fas216_eh_device_reset,
-	eh_abort_handler:		fas216_eh_abort,
+	.module				= THIS_MODULE,
+	.proc_info			= eesoxscsi_proc_info,
+	.name				= "EESOX SCSI",
+	.detect				= eesoxscsi_detect,
+	.release			= eesoxscsi_release,
+	.info				= eesoxscsi_info,
+	.bios_param			= scsicam_bios_param,
+	.can_queue			= 1,
+	.this_id			= 7,
+	.sg_tablesize			= SG_ALL,
+	.cmd_per_lun			= 1,
+	.use_clustering			= DISABLE_CLUSTERING,
+	.command			= fas216_command,
+	.queuecommand			= fas216_queue_command,
+	.eh_host_reset_handler		= fas216_eh_host_reset,
+	.eh_bus_reset_handler		= fas216_eh_bus_reset,
+	.eh_device_reset_handler	= fas216_eh_device_reset,
+	.eh_abort_handler		= fas216_eh_abort,
 };
 
 static int __init eesox_init(void)
diff -Nru a/drivers/acorn/scsi/oak.c b/drivers/acorn/scsi/oak.c
--- a/drivers/acorn/scsi/oak.c	Sat Aug 10 18:42:19 2002
+++ b/drivers/acorn/scsi/oak.c	Sat Aug 10 18:42:19 2002
@@ -252,20 +252,20 @@
 #include "../../scsi/NCR5380.c"
 
 static Scsi_Host_Template oakscsi_template = {
-	module:		THIS_MODULE,
-	proc_info:	oakscsi_proc_info,
-	name:		"Oak 16-bit SCSI",
-	detect:		oakscsi_detect,
-	release:	oakscsi_release,
-	info:		oakscsi_info,
-	queuecommand:	oakscsi_queue_command,
-	abort:		oakscsi_abort,
-	reset:		oakscsi_reset,
-	can_queue:	16,
-	this_id:	7,
-	sg_tablesize:	SG_ALL,
-	cmd_per_lun:	2,
-	use_clustering:	DISABLE_CLUSTERING
+	.module		= THIS_MODULE,
+	.proc_info	= oakscsi_proc_info,
+	.name		= "Oak 16-bit SCSI",
+	.detect		= oakscsi_detect,
+	.release	= oakscsi_release,
+	.info		= oakscsi_info,
+	.queuecommand	= oakscsi_queue_command,
+	.abort		= oakscsi_abort,
+	.reset		= oakscsi_reset,
+	.can_queue	= 16,
+	.this_id	= 7,
+	.sg_tablesize	= SG_ALL,
+	.cmd_per_lun	= 2,
+	.use_clustering	= DISABLE_CLUSTERING
 };
 
 static int __init oakscsi_init(void)
diff -Nru a/drivers/acorn/scsi/powertec.c b/drivers/acorn/scsi/powertec.c
--- a/drivers/acorn/scsi/powertec.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/acorn/scsi/powertec.c	Sat Aug 10 18:42:23 2002
@@ -454,24 +454,24 @@
 }
 
 static Scsi_Host_Template powertecscsi_template = {
-	module:				THIS_MODULE,
-	proc_info:			powertecscsi_proc_info,
-	name:				"PowerTec SCSI",
-	detect:				powertecscsi_detect,
-	release:			powertecscsi_release,
-	info:				powertecscsi_info,
-	bios_param:			scsicam_bios_param,
-	can_queue:			1,
-	this_id:			7,
-	sg_tablesize:			SG_ALL,
-	cmd_per_lun:			1,
-	use_clustering:			ENABLE_CLUSTERING,
-	command:			fas216_command,
-	queuecommand:			fas216_queue_command,
-	eh_host_reset_handler:		fas216_eh_host_reset,
-	eh_bus_reset_handler:		fas216_eh_bus_reset,
-	eh_device_reset_handler:	fas216_eh_device_reset,
-	eh_abort_handler:		fas216_eh_abort,
+	.module				= THIS_MODULE,
+	.proc_info			= powertecscsi_proc_info,
+	.name				= "PowerTec SCSI",
+	.detect				= powertecscsi_detect,
+	.release			= powertecscsi_release,
+	.info				= powertecscsi_info,
+	.bios_param			= scsicam_bios_param,
+	.can_queue			= 1,
+	.this_id			= 7,
+	.sg_tablesize			= SG_ALL,
+	.cmd_per_lun			= 1,
+	.use_clustering			= ENABLE_CLUSTERING,
+	.command			= fas216_command,
+	.queuecommand			= fas216_queue_command,
+	.eh_host_reset_handler		= fas216_eh_host_reset,
+	.eh_bus_reset_handler		= fas216_eh_bus_reset,
+	.eh_device_reset_handler	= fas216_eh_device_reset,
+	.eh_abort_handler		= fas216_eh_abort,
 };
 
 static int __init powertecscsi_init(void)
diff -Nru a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c
--- a/drivers/atm/ambassador.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/atm/ambassador.c	Sat Aug 10 18:42:21 2002
@@ -1695,12 +1695,12 @@
 /********** Operation Structure **********/
 
 static const struct atmdev_ops amb_ops = {
-  open:		amb_open,
-  close:	amb_close,
-  send:		amb_send,
-  sg_send:	amb_sg_send,
-  proc_read:	amb_proc_read,
-  owner:	THIS_MODULE,
+  .open	= amb_open,
+  .close	= amb_close,
+  .send	= amb_send,
+  .sg_send	= amb_sg_send,
+  .proc_read	= amb_proc_read,
+  .owner	= THIS_MODULE,
 };
 
 /********** housekeeping **********/
diff -Nru a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c
--- a/drivers/atm/atmtcp.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/atm/atmtcp.c	Sat Aug 10 18:42:23 2002
@@ -293,13 +293,13 @@
 
 
 static struct atmdev_ops atmtcp_v_dev_ops = {
-	dev_close:	atmtcp_v_dev_close,
-	open:		atmtcp_v_open,
-	close:		atmtcp_v_close,
-	ioctl:		atmtcp_v_ioctl,
-	send:		atmtcp_v_send,
-	proc_read:	atmtcp_v_proc,
-	owner:		THIS_MODULE
+	.dev_close	= atmtcp_v_dev_close,
+	.open		= atmtcp_v_open,
+	.close		= atmtcp_v_close,
+	.ioctl		= atmtcp_v_ioctl,
+	.send		= atmtcp_v_send,
+	.proc_read	= atmtcp_v_proc,
+	.owner		= THIS_MODULE
 };
 
 
@@ -309,8 +309,8 @@
 
 
 static struct atmdev_ops atmtcp_c_dev_ops = {
-	close:		atmtcp_c_close,
-	send:		atmtcp_c_send
+	.close		= atmtcp_c_close,
+	.send		= atmtcp_c_send
 };
 
 
diff -Nru a/drivers/atm/eni.c b/drivers/atm/eni.c
--- a/drivers/atm/eni.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/atm/eni.c	Sat Aug 10 18:42:21 2002
@@ -2226,17 +2226,17 @@
 
 
 static const struct atmdev_ops ops = {
-	open:		eni_open,
-	close:		eni_close,
-	ioctl:		eni_ioctl,
-	getsockopt:	eni_getsockopt,
-	setsockopt:	eni_setsockopt,
-	send:		eni_send,
-	sg_send:	eni_sg_send,
-	phy_put:	eni_phy_put,
-	phy_get:	eni_phy_get,
-	change_qos:	eni_change_qos,
-	proc_read:	eni_proc_read
+	.open		= eni_open,
+	.close		= eni_close,
+	.ioctl		= eni_ioctl,
+	.getsockopt	= eni_getsockopt,
+	.setsockopt	= eni_setsockopt,
+	.send		= eni_send,
+	.sg_send	= eni_sg_send,
+	.phy_put	= eni_phy_put,
+	.phy_get	= eni_phy_get,
+	.change_qos	= eni_change_qos,
+	.proc_read	= eni_proc_read
 };
 
 
@@ -2306,10 +2306,10 @@
 
 
 static struct pci_driver eni_driver = {
-	name:		DEV_LABEL,
-	id_table:	eni_pci_tbl,
-	probe:		eni_init_one,
-	remove:		__devexit_p(eni_remove_one),
+	.name		= DEV_LABEL,
+	.id_table	= eni_pci_tbl,
+	.probe		= eni_init_one,
+	.remove		= __devexit_p(eni_remove_one),
 };
 
 
diff -Nru a/drivers/atm/firestream.c b/drivers/atm/firestream.c
--- a/drivers/atm/firestream.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/atm/firestream.c	Sat Aug 10 18:42:21 2002
@@ -1286,11 +1286,11 @@
 
 
 static const struct atmdev_ops ops = {
-	open:           fs_open,
-	close:          fs_close,
-	send:           fs_send,
+	.open =         fs_open,
+	.close =        fs_close,
+	.send =         fs_send,
 #if 0
-	owner:          THIS_MODULE,
+	.owner =        THIS_MODULE,
 #endif
 	/*                 fs_sg_send */
 	/* ioctl:          fs_ioctl, */
@@ -2099,10 +2099,10 @@
 MODULE_DEVICE_TABLE(pci, firestream_pci_tbl);
 
 static struct pci_driver firestream_driver = {
-	name:           "firestream",
-	id_table:       firestream_pci_tbl,
-	probe:          firestream_init_one,
-	remove:         __devexit_p(firestream_remove_one),
+	.name		= "firestream",
+	.id_table	= firestream_pci_tbl,
+	.probe		= firestream_init_one,
+	.remove		= __devexit_p(firestream_remove_one),
 };
 
 static int __init firestream_init_module (void)
diff -Nru a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c
--- a/drivers/atm/fore200e.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/atm/fore200e.c	Sat Aug 10 18:42:22 2002
@@ -2931,15 +2931,15 @@
 
 static const struct atmdev_ops fore200e_ops =
 {
-	open:         fore200e_open,
-	close:        fore200e_close,
-	ioctl:        fore200e_ioctl,
-	getsockopt:   fore200e_getsockopt,
-	setsockopt:   fore200e_setsockopt,
-	send:         fore200e_send,
-	change_qos:   fore200e_change_qos,
-	proc_read:    fore200e_proc_read,
-	owner:        THIS_MODULE,
+	.open       = fore200e_open,
+	.close      = fore200e_close,
+	.ioctl      = fore200e_ioctl,
+	.getsockopt = fore200e_getsockopt,
+	.setsockopt = fore200e_setsockopt,
+	.send       = fore200e_send,
+	.change_qos = fore200e_change_qos,
+	.proc_read  = fore200e_proc_read,
+	.owner      = THIS_MODULE,
 };
 
 
diff -Nru a/drivers/atm/horizon.c b/drivers/atm/horizon.c
--- a/drivers/atm/horizon.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/atm/horizon.c	Sat Aug 10 18:42:20 2002
@@ -2739,12 +2739,12 @@
 }
 
 static const struct atmdev_ops hrz_ops = {
-  open:		hrz_open,
-  close:	hrz_close,
-  send:		hrz_send,
-  sg_send:	hrz_sg_send,
-  proc_read:	hrz_proc_read,
-  owner:	THIS_MODULE,
+  .open	= hrz_open,
+  .close	= hrz_close,
+  .send	= hrz_send,
+  .sg_send	= hrz_sg_send,
+  .proc_read	= hrz_proc_read,
+  .owner	= THIS_MODULE,
 };
 
 static int __init hrz_probe (void) {
diff -Nru a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
--- a/drivers/atm/idt77252.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/atm/idt77252.c	Sat Aug 10 18:42:22 2002
@@ -141,15 +141,15 @@
 
 static struct atmdev_ops idt77252_ops =
 {
-	dev_close:	idt77252_dev_close,
-	open:		idt77252_open,
-	close:		idt77252_close,
-	send:		idt77252_send,
-	send_oam:	idt77252_send_oam,
-	phy_put:	idt77252_phy_put,
-	phy_get:	idt77252_phy_get,
-	change_qos:	idt77252_change_qos,
-	proc_read:	idt77252_proc_read
+	.dev_close	= idt77252_dev_close,
+	.open		= idt77252_open,
+	.close		= idt77252_close,
+	.send		= idt77252_send,
+	.send_oam	= idt77252_send_oam,
+	.phy_put	= idt77252_phy_put,
+	.phy_get	= idt77252_phy_get,
+	.change_qos	= idt77252_change_qos,
+	.proc_read	= idt77252_proc_read
 };
 
 static struct idt77252_dev *idt77252_chain = NULL;
@@ -3843,9 +3843,9 @@
 };
 
 static struct pci_driver idt77252_driver = {
-	name:		"idt77252",
-	id_table:	idt77252_pci_tbl,
-	probe:		idt77252_init_one,
+	.name		= "idt77252",
+	.id_table	= idt77252_pci_tbl,
+	.probe		= idt77252_init_one,
 };
 
 static int __init idt77252_init(void)
diff -Nru a/drivers/atm/iphase.c b/drivers/atm/iphase.c
--- a/drivers/atm/iphase.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/atm/iphase.c	Sat Aug 10 18:42:23 2002
@@ -3148,18 +3148,18 @@
 }
   
 static const struct atmdev_ops ops = {  
-	open:		ia_open,  
-	close:		ia_close,  
-	ioctl:		ia_ioctl,  
-	getsockopt:	ia_getsockopt,  
-	setsockopt:	ia_setsockopt,  
-	send:		ia_send,  
-	sg_send:	ia_sg_send,  
-	phy_put:	ia_phy_put,  
-	phy_get:	ia_phy_get,  
-	change_qos:	ia_change_qos,  
-	proc_read:	ia_proc_read,
-	owner:		THIS_MODULE,
+	.open		= ia_open,  
+	.close		= ia_close,  
+	.ioctl		= ia_ioctl,  
+	.getsockopt	= ia_getsockopt,  
+	.setsockopt	= ia_setsockopt,  
+	.send		= ia_send,  
+	.sg_send	= ia_sg_send,  
+	.phy_put	= ia_phy_put,  
+	.phy_get	= ia_phy_get,  
+	.change_qos	= ia_change_qos,  
+	.proc_read	= ia_proc_read,
+	.owner		= THIS_MODULE,
 };  
 	  
   
diff -Nru a/drivers/atm/lanai.c b/drivers/atm/lanai.c
--- a/drivers/atm/lanai.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/atm/lanai.c	Sat Aug 10 18:42:21 2002
@@ -2829,21 +2829,21 @@
 /* -------------------- HOOKS: */
 
 static const struct atmdev_ops ops = {
-	dev_close:	lanai_dev_close,
-	open:		lanai_open,
-	close:		lanai_close,
-	ioctl:		lanai_ioctl,
-	getsockopt:	NULL,
-	setsockopt:	NULL,
-	send:		lanai_send,
-	sg_send:	NULL,		/* no scatter-gather on card */
-	send_oam:	NULL,		/* OAM support not in linux yet */
-	phy_put:	NULL,
-	phy_get:	NULL,
-	feedback:	NULL,
-	change_qos:	lanai_change_qos,
-	free_rx_skb:	NULL,
-	proc_read:	lanai_proc_read
+	.dev_close	= lanai_dev_close,
+	.open		= lanai_open,
+	.close		= lanai_close,
+	.ioctl		= lanai_ioctl,
+	.getsockopt	= NULL,
+	.setsockopt	= NULL,
+	.send		= lanai_send,
+	.sg_send	= NULL,		/* no scatter-gather on card */
+	.send_oam	= NULL,		/* OAM support not in linux yet */
+	.phy_put	= NULL,
+	.phy_get	= NULL,
+	.feedback	= NULL,
+	.change_qos	= lanai_change_qos,
+	.free_rx_skb	= NULL,
+	.proc_read	= lanai_proc_read
 };
 
 /* detect one type of card LANAI2 or LANAIHB */
diff -Nru a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c
--- a/drivers/atm/nicstar.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/atm/nicstar.c	Sat Aug 10 18:42:21 2002
@@ -259,14 +259,14 @@
 static unsigned num_cards;
 static struct atmdev_ops atm_ops =
 {
-   open:	ns_open,
-   close:	ns_close,
-   ioctl:	ns_ioctl,
-   send:	ns_send,
-   phy_put:	ns_phy_put,
-   phy_get:	ns_phy_get,
-   proc_read:	ns_proc_read,
-   owner:	THIS_MODULE,
+   .open	= ns_open,
+   .close	= ns_close,
+   .ioctl	= ns_ioctl,
+   .send	= ns_send,
+   .phy_put	= ns_phy_put,
+   .phy_get	= ns_phy_get,
+   .proc_read	= ns_proc_read,
+   .owner	= THIS_MODULE,
 };
 static struct timer_list ns_timer;
 static char *mac[NS_MAX_CARDS];
diff -Nru a/drivers/atm/suni.c b/drivers/atm/suni.c
--- a/drivers/atm/suni.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/atm/suni.c	Sat Aug 10 18:42:22 2002
@@ -286,10 +286,10 @@
 
 
 static const struct atmphy_ops suni_ops = {
-	start:		suni_start,
-	ioctl:		suni_ioctl,
-	interrupt:	suni_int,
-	stop:		suni_stop,
+	.start		= suni_start,
+	.ioctl		= suni_ioctl,
+	.interrupt	= suni_int,
+	.stop		= suni_stop,
 };
 
 
diff -Nru a/drivers/atm/uPD98402.c b/drivers/atm/uPD98402.c
--- a/drivers/atm/uPD98402.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/atm/uPD98402.c	Sat Aug 10 18:42:22 2002
@@ -239,10 +239,10 @@
 
 
 static const struct atmphy_ops uPD98402_ops = {
-	start:		uPD98402_start,
-	ioctl:		uPD98402_ioctl,
-	interrupt:	uPD98402_int,
-	stop:		uPD98402_stop,
+	.start		= uPD98402_start,
+	.ioctl		= uPD98402_ioctl,
+	.interrupt	= uPD98402_int,
+	.stop		= uPD98402_stop,
 };
 
 
diff -Nru a/drivers/atm/zatm.c b/drivers/atm/zatm.c
--- a/drivers/atm/zatm.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/atm/zatm.c	Sat Aug 10 18:42:21 2002
@@ -1793,17 +1793,17 @@
 
 
 static const struct atmdev_ops ops = {
-	open:		zatm_open,
-	close:		zatm_close,
-	ioctl:		zatm_ioctl,
-	getsockopt:	zatm_getsockopt,
-	setsockopt:	zatm_setsockopt,
-	send:		zatm_send,
+	.open		= zatm_open,
+	.close		= zatm_close,
+	.ioctl		= zatm_ioctl,
+	.getsockopt	= zatm_getsockopt,
+	.setsockopt	= zatm_setsockopt,
+	.send		= zatm_send,
 	/*zatm_sg_send*/
-	phy_put:	zatm_phy_put,
-	phy_get:	zatm_phy_get,
-	feedback:	zatm_feedback,
-	change_qos:	zatm_change_qos,
+	.phy_put	= zatm_phy_put,
+	.phy_get	= zatm_phy_get,
+	.feedback	= zatm_feedback,
+	.change_qos	= zatm_change_qos,
 };
 
 
diff -Nru a/drivers/base/Makefile b/drivers/base/Makefile
--- a/drivers/base/Makefile	Sat Aug 10 18:42:22 2002
+++ b/drivers/base/Makefile	Sat Aug 10 18:42:22 2002
@@ -1,8 +1,10 @@
 # Makefile for the Linux device tree
 
-obj-y		:= core.o sys.o interface.o fs.o power.o bus.o \
+obj-y		:= core.o sys.o interface.o power.o bus.o \
 			driver.o 
 
-export-objs	:= core.o fs.o power.o sys.o bus.o driver.o
+obj-y		+= fs/
+
+export-objs	:= core.o power.o sys.o bus.o driver.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/base/base.h b/drivers/base/base.h
--- a/drivers/base/base.h	Sat Aug 10 18:42:22 2002
+++ b/drivers/base/base.h	Sat Aug 10 18:42:22 2002
@@ -12,9 +12,14 @@
 extern int bus_add_device(struct device * dev);
 extern void bus_remove_device(struct device * dev);
 
-extern int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * parent);
 extern int device_make_dir(struct device * dev);
 extern void device_remove_dir(struct device * dev);
+
+extern int bus_make_dir(struct bus_type * bus);
+extern void bus_remove_dir(struct bus_type * bus);
+
+extern int driver_make_dir(struct device_driver * drv);
+extern void driver_remove_dir(struct device_driver * drv);
 
 extern int device_bus_link(struct device * dev);
 extern void device_remove_symlink(struct driver_dir_entry * dir, const char * name);
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/base/bus.c	Sat Aug 10 18:42:21 2002
@@ -12,17 +12,10 @@
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/errno.h>
-#include <linux/stat.h>
-#include <linux/init.h>
 #include "base.h"
 
 static LIST_HEAD(bus_driver_list);
 
-static struct driver_dir_entry bus_dir = {
-	name:	"bus",
-	mode:	(S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO),
-};
-
 /**
  * bus_for_each_dev - walk list of devices and do something to each
  * @bus:	bus in question
@@ -148,23 +141,6 @@
 	}
 }
 
-static int bus_make_dir(struct bus_type * bus)
-{
-	int error;
-	bus->dir.name = bus->name;
-
-	error = device_create_dir(&bus->dir,&bus_dir);
-	if (!error) {
-		bus->device_dir.name = "devices";
-		device_create_dir(&bus->device_dir,&bus->dir);
-
-		bus->driver_dir.name = "drivers";
-		device_create_dir(&bus->driver_dir,&bus->dir);
-	}
-	return error;
-}
-
-
 int bus_register(struct bus_type * bus)
 {
 	rwlock_init(&bus->lock);
@@ -191,20 +167,8 @@
 		return;
 	list_del_init(&bus->node);
 	spin_unlock(&device_lock);
-
-	/* remove driverfs entries */
-	driverfs_remove_dir(&bus->driver_dir);
-	driverfs_remove_dir(&bus->device_dir);
-	driverfs_remove_dir(&bus->dir);
+	bus_remove_dir(bus);
 }
-
-static int __init bus_init(void)
-{
-	/* make 'bus' driverfs directory */
-	return driverfs_create_dir(&bus_dir,NULL);
-}
-
-core_initcall(bus_init);
 
 EXPORT_SYMBOL(bus_for_each_dev);
 EXPORT_SYMBOL(bus_for_each_drv);
diff -Nru a/drivers/base/driver.c b/drivers/base/driver.c
--- a/drivers/base/driver.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/base/driver.c	Sat Aug 10 18:42:23 2002
@@ -44,16 +44,6 @@
 }
 
 /**
- * driver_make_dir - create a driverfs directory for a driver
- * @drv:	driver in question
- */
-static int driver_make_dir(struct device_driver * drv)
-{
-	drv->dir.name = drv->name;
-	return device_create_dir(&drv->dir,&drv->bus->driver_dir);
-}
-
-/**
  * driver_register - register driver with bus
  * @drv:	driver to register
  * 
@@ -83,7 +73,7 @@
 {
 	pr_debug("Unregistering driver '%s' from bus '%s'\n",drv->name,drv->bus->name);
 	driver_detach(drv);
-	driverfs_remove_dir(&drv->dir);
+	driver_remove_dir(drv);
 	if (drv->release)
 		drv->release(drv);
 	put_bus(drv->bus);
diff -Nru a/drivers/base/fs/Makefile b/drivers/base/fs/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/base/fs/Makefile	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,5 @@
+obj-y		:= device.o bus.o driver.o
+
+export-objs	:= device.o bus.o driver.o
+
+include $(TOPDIR)/Rules.make
diff -Nru a/drivers/base/fs/bus.c b/drivers/base/fs/bus.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/base/fs/bus.c	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,123 @@
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include "fs.h"
+
+static struct driver_dir_entry bus_dir;
+
+#define to_bus_attr(_attr) container_of(_attr,struct bus_attribute,attr)
+
+#define to_bus(dir) container_of(dir,struct bus_type,dir)
+
+
+/* driverfs ops for device attribute files */
+
+static int
+bus_attr_open(struct driver_dir_entry * dir)
+{
+	struct bus_type * bus = to_bus(dir);
+	get_bus(bus);
+	return 0;
+}
+
+static int
+bus_attr_close(struct driver_dir_entry * dir)
+{
+	struct bus_type * bus = to_bus(dir);
+	put_bus(bus);
+	return 0;
+}
+
+static ssize_t
+bus_attr_show(struct driver_dir_entry * dir, struct attribute * attr,
+	      char * buf, size_t count, loff_t off)
+{
+	struct bus_attribute * bus_attr = to_bus_attr(attr);
+	struct bus_type * bus = to_bus(dir);
+	ssize_t ret = 0;
+
+	if (bus_attr->show)
+		ret = bus_attr->show(bus,buf,count,off);
+	return ret;
+}
+
+static ssize_t
+bus_attr_store(struct driver_dir_entry * dir, struct attribute * attr,
+	       const char * buf, size_t count, loff_t off)
+{
+	struct bus_attribute * bus_attr = to_bus_attr(attr);
+	struct bus_type * bus = to_bus(dir);
+	ssize_t ret = 0;
+
+	if (bus_attr->store)
+		ret = bus_attr->store(bus,buf,count,off);
+	return ret;
+}
+
+static struct driverfs_ops bus_attr_ops = {
+	open:	bus_attr_open,
+	close:	bus_attr_close,
+	show:	bus_attr_show,
+	store:	bus_attr_store,
+};
+
+int bus_create_file(struct bus_type * bus, struct bus_attribute * attr)
+{
+	int error;
+	if (get_bus(bus)) {
+		error = driverfs_create_file(&attr->attr,&bus->dir);
+		put_bus(bus);
+	} else
+		error = -EINVAL;
+	return error;
+}
+
+void bus_remove_file(struct bus_type * bus, struct bus_attribute * attr)
+{
+	if (get_bus(bus)) {
+		driverfs_remove_file(&bus->dir,attr->attr.name);
+		put_bus(bus);
+	}
+}
+
+int bus_make_dir(struct bus_type * bus)
+{
+	int error;
+	bus->dir.name = bus->name;
+	bus->dir.ops = &bus_attr_ops;
+
+	error = device_create_dir(&bus->dir,&bus_dir);
+	if (!error) {
+		bus->device_dir.name = "devices";
+		device_create_dir(&bus->device_dir,&bus->dir);
+
+		bus->driver_dir.name = "drivers";
+		device_create_dir(&bus->driver_dir,&bus->dir);
+	}
+	return error;
+}
+
+void bus_remove_dir(struct bus_type * bus)
+{
+	/* remove driverfs entries */
+	driverfs_remove_dir(&bus->driver_dir);
+	driverfs_remove_dir(&bus->device_dir);
+	driverfs_remove_dir(&bus->dir);
+}
+
+static struct driver_dir_entry bus_dir = {
+	name:	"bus",
+	mode:	(S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO),
+};
+
+static int __init bus_init(void)
+{
+	/* make 'bus' driverfs directory */
+	return driverfs_create_dir(&bus_dir,NULL);
+}
+
+core_initcall(bus_init);
+
+EXPORT_SYMBOL(bus_create_file);
+EXPORT_SYMBOL(bus_remove_file);
diff -Nru a/drivers/base/fs/device.c b/drivers/base/fs/device.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/base/fs/device.c	Sat Aug 10 18:42:23 2002
@@ -0,0 +1,234 @@
+/*
+ * drivers/base/fs.c - driver model interface to driverfs 
+ *
+ * Copyright (c) 2002 Patrick Mochel
+ *		 2002 Open Source Development Lab
+ */
+
+#define DEBUG 0
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/stat.h>
+#include <linux/limits.h>
+
+extern struct device_attribute * device_default_files[];
+
+#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
+
+#define to_device(d) container_of(d, struct device, dir)
+
+
+/* driverfs ops for device attribute files */
+
+static int
+dev_attr_open(struct driver_dir_entry * dir)
+{
+	struct device * dev = to_device(dir);
+	get_device(dev);
+	return 0;
+}
+
+static int
+dev_attr_close(struct driver_dir_entry * dir)
+{
+	struct device * dev = to_device(dir);
+	put_device(dev);
+	return 0;
+}
+
+static ssize_t
+dev_attr_show(struct driver_dir_entry * dir, struct attribute * attr,
+	      char * buf, size_t count, loff_t off)
+{
+	struct device_attribute * dev_attr = to_dev_attr(attr);
+	struct device * dev = to_device(dir);
+	ssize_t ret = 0;
+
+	if (dev_attr->show)
+		ret = dev_attr->show(dev,buf,count,off);
+	return ret;
+}
+
+static ssize_t
+dev_attr_store(struct driver_dir_entry * dir, struct attribute * attr,
+	       const char * buf, size_t count, loff_t off)
+{
+	struct device_attribute * dev_attr = to_dev_attr(attr);
+	struct device * dev = to_device(dir);
+	ssize_t ret = 0;
+
+	if (dev_attr->store)
+		ret = dev_attr->store(dev,buf,count,off);
+	return ret;
+}
+
+static struct driverfs_ops dev_attr_ops = {
+	open:	dev_attr_open,
+	close:	dev_attr_close,
+	show:	dev_attr_show,
+	store:	dev_attr_store,
+};
+
+/**
+ * device_create_file - create a driverfs file for a device
+ * @dev:	device requesting file
+ * @entry:	entry describing file
+ *
+ * Allocate space for file entry, copy descriptor, and create.
+ */
+int device_create_file(struct device * dev, struct device_attribute * entry)
+{
+	int error = -EINVAL;
+
+	if (dev) {
+		get_device(dev);
+		error = driverfs_create_file(&entry->attr,&dev->dir);
+		put_device(dev);
+	}
+	return error;
+}
+
+/**
+ * device_remove_file - remove a device's file by name
+ * @dev:	device requesting removal
+ * @name:	name of the file
+ *
+ */
+void device_remove_file(struct device * dev, struct device_attribute * attr)
+{
+	if (dev) {
+		get_device(dev);
+		driverfs_remove_file(&dev->dir,attr->attr.name);
+		put_device(dev);
+	}
+}
+
+/**
+ * device_remove_dir - remove a device's directory
+ * @dev:	device in question
+ */
+void device_remove_dir(struct device * dev)
+{
+	if (dev)
+		driverfs_remove_dir(&dev->dir);
+}
+
+static int get_devpath_length(struct device * dev)
+{
+	int length = 1;
+	struct device * parent = dev;
+
+	/* walk up the ancestors until we hit the root.
+	 * Add 1 to strlen for leading '/' of each level.
+	 */
+	do {
+		length += strlen(parent->bus_id) + 1;
+		parent = parent->parent;
+	} while (parent);
+	return length;
+}
+
+static void fill_devpath(struct device * dev, char * path, int length)
+{
+	struct device * parent;
+	--length;
+	for (parent = dev; parent; parent = parent->parent) {
+		int cur = strlen(parent->bus_id);
+
+		/* back up enough to print this bus id with '/' */
+		length -= cur;
+		strncpy(path + length,parent->bus_id,cur);
+		*(path + --length) = '/';
+	}
+
+	pr_debug("%s: path = '%s'\n",__FUNCTION__,path);
+}
+
+int device_bus_link(struct device * dev)
+{
+	char * path;
+	int length;
+	int error = 0;
+
+	if (!dev->bus)
+		return 0;
+
+	length = get_devpath_length(dev);
+
+	/* now add the path from the bus directory
+	 * It should be '../../..' (one to get to the bus's directory,
+	 * one to get to the 'bus' directory, and one to get to the root 
+	 * of the fs.)
+	 */
+	length += strlen("../../..");
+
+	if (length > PATH_MAX)
+		return -ENAMETOOLONG;
+
+	if (!(path = kmalloc(length,GFP_KERNEL)))
+		return -ENOMEM;
+	memset(path,0,length);
+
+	/* our relative position */
+	strcpy(path,"../../..");
+
+	fill_devpath(dev,path,length);
+	error = driverfs_create_symlink(&dev->bus->device_dir,dev->bus_id,path);
+	kfree(path);
+	return error;
+}
+
+void device_remove_symlink(struct driver_dir_entry * dir, const char * name)
+{
+	driverfs_remove_file(dir,name);
+}
+
+int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * parent)
+{
+	dir->mode  = (S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO);
+	return driverfs_create_dir(dir,parent);
+}
+
+/**
+ * device_make_dir - create a driverfs directory
+ * @name:	name of directory
+ * @parent:	dentry for the parent directory
+ *
+ * Do the initial creation of the device's driverfs directory
+ * and populate it with the one default file.
+ *
+ * This is just a helper for device_register(), as we
+ * don't export this function. (Yes, that means we don't allow
+ * devices to create subdirectories).
+ */
+int device_make_dir(struct device * dev)
+{
+	struct driver_dir_entry * parent = NULL;
+	struct device_attribute * entry;
+	int error;
+	int i;
+
+	if (dev->parent)
+		parent = &dev->parent->dir;
+	dev->dir.name = dev->bus_id;
+	dev->dir.ops = &dev_attr_ops;
+
+	if ((error = device_create_dir(&dev->dir,parent)))
+		return error;
+
+	for (i = 0; (entry = *(device_default_files + i)); i++) {
+		if ((error = device_create_file(dev,entry))) {
+			device_remove_dir(dev);
+			break;
+		}
+	}
+	return error;
+}
+
+EXPORT_SYMBOL(device_create_file);
+EXPORT_SYMBOL(device_remove_file);
+
diff -Nru a/drivers/base/fs/driver.c b/drivers/base/fs/driver.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/base/fs/driver.c	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,100 @@
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/stat.h>
+#include <linux/err.h>
+#include "fs.h"
+
+#define to_drv_attr(_attr) container_of(_attr,struct driver_attribute,attr)
+
+#define to_drv(d) container_of(d, struct device_driver, dir)
+
+
+/* driverfs ops for device attribute files */
+
+static int
+drv_attr_open(struct driver_dir_entry * dir)
+{
+	struct device_driver * drv = to_drv(dir);
+	get_driver(drv);
+	return 0;
+}
+
+static int
+drv_attr_close(struct driver_dir_entry * dir)
+{
+	struct device_driver * drv = to_drv(dir);
+	put_driver(drv);
+	return 0;
+}
+
+static ssize_t
+drv_attr_show(struct driver_dir_entry * dir, struct attribute * attr,
+	      char * buf, size_t count, loff_t off)
+{
+	struct driver_attribute * drv_attr = to_drv_attr(attr);
+	struct device_driver * drv = to_drv(dir);
+	ssize_t ret = 0;
+
+	if (drv_attr->show)
+		ret = drv_attr->show(drv,buf,count,off);
+	return ret;
+}
+
+static ssize_t
+drv_attr_store(struct driver_dir_entry * dir, struct attribute * attr,
+	       const char * buf, size_t count, loff_t off)
+{
+	struct driver_attribute * drv_attr = to_drv_attr(attr);
+	struct device_driver * drv = to_drv(dir);
+	ssize_t ret = 0;
+
+	if (drv_attr->store)
+		ret = drv_attr->store(drv,buf,count,off);
+	return ret;
+}
+
+static struct driverfs_ops drv_attr_ops = {
+	open:	drv_attr_open,
+	close:	drv_attr_close,
+	show:	drv_attr_show,
+	store:	drv_attr_store,
+};
+
+int driver_create_file(struct device_driver * drv, struct driver_attribute * attr)
+{
+	int error;
+	if (get_driver(drv)) {
+		error = driverfs_create_file(&attr->attr,&drv->dir);
+		put_driver(drv);
+	} else
+		error = -EINVAL;
+	return error;
+}
+
+void driver_remove_file(struct device_driver * drv, struct driver_attribute * attr)
+{
+	if (get_driver(drv)) {
+		driverfs_remove_file(&drv->dir,attr->attr.name);
+		put_driver(drv);
+	}
+}
+
+/**
+ * driver_make_dir - create a driverfs directory for a driver
+ * @drv:	driver in question
+ */
+int driver_make_dir(struct device_driver * drv)
+{
+	drv->dir.name = drv->name;
+	drv->dir.ops = &drv_attr_ops;
+
+	return device_create_dir(&drv->dir,&drv->bus->driver_dir);
+}
+
+void driver_remove_dir(struct device_driver * drv)
+{
+	driverfs_remove_dir(&drv->dir);
+}
+
+EXPORT_SYMBOL(driver_create_file);
+EXPORT_SYMBOL(driver_remove_file);
diff -Nru a/drivers/base/fs/fs.h b/drivers/base/fs/fs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/base/fs/fs.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,2 @@
+
+extern int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * parent);
diff -Nru a/drivers/base/fs.c b/drivers/base/fs.c
--- a/drivers/base/fs.c	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,234 +0,0 @@
-/*
- * drivers/base/fs.c - driver model interface to driverfs 
- *
- * Copyright (c) 2002 Patrick Mochel
- *		 2002 Open Source Development Lab
- */
-
-#define DEBUG 0
-
-#include <linux/device.h>
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/stat.h>
-#include <linux/limits.h>
-
-extern struct device_attribute * device_default_files[];
-
-#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
-
-#define to_device(d) container_of(d, struct device, dir)
-
-
-/* driverfs ops for device attribute files */
-
-static int
-dev_attr_open(struct driver_dir_entry * dir)
-{
-	struct device * dev = to_device(dir);
-	get_device(dev);
-	return 0;
-}
-
-static int
-dev_attr_close(struct driver_dir_entry * dir)
-{
-	struct device * dev = to_device(dir);
-	put_device(dev);
-	return 0;
-}
-
-static ssize_t
-dev_attr_show(struct driver_dir_entry * dir, struct attribute * attr,
-	      char * buf, size_t count, loff_t off)
-{
-	struct device_attribute * dev_attr = to_dev_attr(attr);
-	struct device * dev = to_device(dir);
-	ssize_t ret = 0;
-
-	if (dev_attr->show)
-		ret = dev_attr->show(dev,buf,count,off);
-	return ret;
-}
-
-static ssize_t
-dev_attr_store(struct driver_dir_entry * dir, struct attribute * attr,
-	       const char * buf, size_t count, loff_t off)
-{
-	struct device_attribute * dev_attr = to_dev_attr(attr);
-	struct device * dev = to_device(dir);
-	ssize_t ret = 0;
-
-	if (dev_attr->store)
-		ret = dev_attr->store(dev,buf,count,off);
-	return ret;
-}
-
-static struct driverfs_ops dev_attr_ops = {
-	open:	dev_attr_open,
-	close:	dev_attr_close,
-	show:	dev_attr_show,
-	store:	dev_attr_store,
-};
-
-/**
- * device_create_file - create a driverfs file for a device
- * @dev:	device requesting file
- * @entry:	entry describing file
- *
- * Allocate space for file entry, copy descriptor, and create.
- */
-int device_create_file(struct device * dev, struct device_attribute * entry)
-{
-	int error = -EINVAL;
-
-	if (dev) {
-		get_device(dev);
-		error = driverfs_create_file(&entry->attr,&dev->dir);
-		put_device(dev);
-	}
-	return error;
-}
-
-/**
- * device_remove_file - remove a device's file by name
- * @dev:	device requesting removal
- * @name:	name of the file
- *
- */
-void device_remove_file(struct device * dev, struct device_attribute * attr)
-{
-	if (dev) {
-		get_device(dev);
-		driverfs_remove_file(&dev->dir,attr->attr.name);
-		put_device(dev);
-	}
-}
-
-/**
- * device_remove_dir - remove a device's directory
- * @dev:	device in question
- */
-void device_remove_dir(struct device * dev)
-{
-	if (dev)
-		driverfs_remove_dir(&dev->dir);
-}
-
-static int get_devpath_length(struct device * dev)
-{
-	int length = 1;
-	struct device * parent = dev;
-
-	/* walk up the ancestors until we hit the root.
-	 * Add 1 to strlen for leading '/' of each level.
-	 */
-	do {
-		length += strlen(parent->bus_id) + 1;
-		parent = parent->parent;
-	} while (parent);
-	return length;
-}
-
-static void fill_devpath(struct device * dev, char * path, int length)
-{
-	struct device * parent;
-	--length;
-	for (parent = dev; parent; parent = parent->parent) {
-		int cur = strlen(parent->bus_id);
-
-		/* back up enough to print this bus id with '/' */
-		length -= cur;
-		strncpy(path + length,parent->bus_id,cur);
-		*(path + --length) = '/';
-	}
-
-	pr_debug("%s: path = '%s'\n",__FUNCTION__,path);
-}
-
-int device_bus_link(struct device * dev)
-{
-	char * path;
-	int length;
-	int error = 0;
-
-	if (!dev->bus)
-		return 0;
-
-	length = get_devpath_length(dev);
-
-	/* now add the path from the bus directory
-	 * It should be '../../..' (one to get to the bus's directory,
-	 * one to get to the 'bus' directory, and one to get to the root 
-	 * of the fs.)
-	 */
-	length += strlen("../../..");
-
-	if (length > PATH_MAX)
-		return -ENAMETOOLONG;
-
-	if (!(path = kmalloc(length,GFP_KERNEL)))
-		return -ENOMEM;
-	memset(path,0,length);
-
-	/* our relative position */
-	strcpy(path,"../../..");
-
-	fill_devpath(dev,path,length);
-	error = driverfs_create_symlink(&dev->bus->device_dir,dev->bus_id,path);
-	kfree(path);
-	return error;
-}
-
-void device_remove_symlink(struct driver_dir_entry * dir, const char * name)
-{
-	driverfs_remove_file(dir,name);
-}
-
-int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * parent)
-{
-	dir->mode  = (S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO);
-	return driverfs_create_dir(dir,parent);
-}
-
-/**
- * device_make_dir - create a driverfs directory
- * @name:	name of directory
- * @parent:	dentry for the parent directory
- *
- * Do the initial creation of the device's driverfs directory
- * and populate it with the one default file.
- *
- * This is just a helper for device_register(), as we
- * don't export this function. (Yes, that means we don't allow
- * devices to create subdirectories).
- */
-int device_make_dir(struct device * dev)
-{
-	struct driver_dir_entry * parent = NULL;
-	struct device_attribute * entry;
-	int error;
-	int i;
-
-	if (dev->parent)
-		parent = &dev->parent->dir;
-	dev->dir.name = dev->bus_id;
-	dev->dir.ops = &dev_attr_ops;
-
-	if ((error = device_create_dir(&dev->dir,parent)))
-		return error;
-
-	for (i = 0; (entry = *(device_default_files + i)); i++) {
-		if ((error = device_create_file(dev,entry))) {
-			device_remove_dir(dev);
-			break;
-		}
-	}
-	return error;
-}
-
-EXPORT_SYMBOL(device_create_file);
-EXPORT_SYMBOL(device_remove_file);
-
diff -Nru a/drivers/block/acsi.c b/drivers/block/acsi.c
--- a/drivers/block/acsi.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/block/acsi.c	Sat Aug 10 18:42:22 2002
@@ -369,7 +369,6 @@
 static int acsi_change_blk_size( int target, int lun);
 static int acsi_mode_sense( int target, int lun, SENSE_DATA *sd );
 static void acsi_geninit(void);
-static int revalidate_acsidisk( kdev_t dev, int maxusage );
 static int acsi_revalidate (kdev_t);
 
 /************************* End of Prototypes **************************/
@@ -1108,19 +1107,12 @@
 		put_user(get_start_sect(inode->i_bdev), &geo->start);
 		return 0;
 	  }
-		
 	  case SCSI_IOCTL_GET_IDLUN:
 		/* SCSI compatible GET_IDLUN call to get target's ID and LUN number */
 		put_user( acsi_info[dev].target | (acsi_info[dev].lun << 8),
 				  &((Scsi_Idlun *) arg)->dev_id );
 		put_user( 0, &((Scsi_Idlun *) arg)->host_unique_id );
 		return 0;
-		
-	  case BLKRRPART: /* Re-read partition tables */
-	        if (!capable(CAP_SYS_ADMIN)) 
-			return -EACCES;
-		return revalidate_acsidisk(inode->i_rdev, 1);
-
 	  default:
 		return -EINVAL;
 	}
@@ -1156,7 +1148,7 @@
 #if 0
 		aip->changed = 1;	/* safety first */
 #endif
-		check_disk_change( inode->i_rdev );
+		check_disk_change( inode->i_bdev );
 		if (aip->changed)	/* revalidate was not successful (no medium) */
 			return -ENXIO;
 		acsi_prevent_removal(device, 1);
@@ -1164,7 +1156,7 @@
 	access_count[device]++;
 
 	if (filp && filp->f_mode) {
-		check_disk_change( inode->i_rdev );
+		check_disk_change( inode->i_bdev );
 		if (filp->f_mode & 2) {
 			if (aip->read_only) {
 				acsi_release( inode, filp );
@@ -1809,20 +1801,11 @@
  *
  */
 
-static int revalidate_acsidisk(kdev_t dev, int maxusage )
+static int acsi_revalidate(kdev_t dev)
 {
 	int unit = DEVICE_NR(minor(dev));
 	struct acsi_info_struct *aip = &acsi_info[unit];
-	kdev_t device = mk_kdev(MAJOR_NR, unit<<4);
-	int res = dev_lock_part(device);
-
-	if (res < 0)
-		return res;
-
-	res = wipe_partitions(device);
-
 	stdma_lock( NULL, NULL );
-
 	if (acsi_devinit(aip) != DEV_SUPPORTED) {
 		printk( KERN_ERR "ACSI: revalidate failed for target %d lun %d\n",
 		       aip->target, aip->lun);
@@ -1834,16 +1817,6 @@
 
 	ENABLE_IRQ();
 	stdma_release();
-
-	if (!res)
-		grok_partitions(device, aip->size);
-
-	dev_unlock_part(device);
-	return res;
-}
-
-
-static int acsi_revalidate (kdev_t dev)
-{
-  return revalidate_acsidisk (dev, 0);
+	acsi_part[minor(dev)].nr_sects = aip->size;
+	return 0;
 }
diff -Nru a/drivers/block/amiflop.c b/drivers/block/amiflop.c
--- a/drivers/block/amiflop.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/block/amiflop.c	Sat Aug 10 18:42:22 2002
@@ -1621,7 +1621,7 @@
 		return -ENODEV;
 
 	if (filp && filp->f_mode & 3) {
-		check_disk_change(inode->i_rdev);
+		check_disk_change(inode->i_bdev);
 		if (filp->f_mode & 2 ) {
 			int wrprot;
 
diff -Nru a/drivers/block/ataflop.c b/drivers/block/ataflop.c
--- a/drivers/block/ataflop.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/block/ataflop.c	Sat Aug 10 18:42:21 2002
@@ -382,7 +382,6 @@
 static __inline__ void copy_buffer( void *from, void *to);
 static void setup_req_params( int drive );
 static void redo_fd_request( void);
-static int invalidate_drive(kdev_t rdev);
 static int fd_ioctl( struct inode *inode, struct file *filp, unsigned int
                      cmd, unsigned long param);
 static void fd_probe( int drive );
@@ -1531,16 +1530,6 @@
 	atari_enable_irq( IRQ_MFP_FDC );
 }
 
-
-static int invalidate_drive(kdev_t rdev)
-{
-	/* invalidate the buffer track to force a reread */
-	BufferDrive = -1;
-	set_bit(minor(rdev) & 3, &fake_change);
-	check_disk_change(rdev);
-	return 0;
-}
-
 static int fd_ioctl(struct inode *inode, struct file *filp,
 		    unsigned int cmd, unsigned long param)
 {
@@ -1719,12 +1708,16 @@
 		/* MSch: invalidate default_params */
 		default_params[drive].blocks  = 0;
 		floppy_sizes[drive] = MAX_DISK_SIZE;
-		return invalidate_drive (device);
 	case FDFMTEND:
 	case FDFLUSH:
-		return invalidate_drive(device);
+		/* invalidate the buffer track to force a reread */
+		BufferDrive = -1;
+		set_bit(drive, &fake_change);
+		check_disk_change(inode->i_bdev);
+		return 0;
+	default:
+		return -EINVAL;
 	}
-	return -EINVAL;
 }
 
 
@@ -1901,7 +1894,7 @@
 		return 0;
 
 	if (filp->f_mode & 3) {
-		check_disk_change(inode->i_rdev);
+		check_disk_change(inode->i_bdev);
 		if (filp->f_mode & 2) {
 			if (UD.wpstat) {
 				floppy_release(inode, filp);
diff -Nru a/drivers/block/blkpg.c b/drivers/block/blkpg.c
--- a/drivers/block/blkpg.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/block/blkpg.c	Sat Aug 10 18:42:20 2002
@@ -269,12 +269,6 @@
 			/* size in bytes */
 			ullval = bdev->bd_inode->i_size;
 			return put_user(ullval, (u64 *) arg);
-#if 0
-		case BLKRRPART: /* Re-read partition tables */
-			if (!capable(CAP_SYS_ADMIN)) 
-				return -EACCES;
-			return reread_partitions(dev, 1);
-#endif
 
 		case BLKPG:
 			return blkpg_ioctl(bdev, (struct blkpg_ioctl_arg *) arg);
diff -Nru a/drivers/block/cciss.c b/drivers/block/cciss.c
--- a/drivers/block/cciss.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/block/cciss.c	Sat Aug 10 18:42:23 2002
@@ -106,7 +106,7 @@
 
 static int revalidate_allvol(kdev_t dev);
 static int revalidate_logvol(kdev_t dev, int maxusage);
-static int frevalidate_logvol(kdev_t dev);
+static int cciss_revalidate(kdev_t dev);
 static int deregister_disk(int ctlr, int logvol);
 static int register_new_disk(kdev_t dev, int cltr);
 
@@ -130,7 +130,7 @@
 	open:			cciss_open, 
 	release:        	cciss_release,
         ioctl:			cciss_ioctl,
-	revalidate:		frevalidate_logvol,
+	revalidate:		cciss_revalidate,
 };
 
 #include "cciss_scsi.c"		/* For SCSI tape support */
@@ -437,8 +437,6 @@
                 return(0);
 	}
 
-	case BLKRRPART:
-		return revalidate_logvol(inode->i_rdev, 1);
 	case CCISS_GETPCIINFO:
 	{
 		cciss_pci_info_struct pciinfo;
@@ -724,6 +722,15 @@
 	
 }
 
+static int cciss_revalidate(kdev_t dev)
+{
+        int ctlr = major(dev) - MAJOR_NR;
+	int target = minor(dev) >> NWD_SHIFT;
+        struct gendisk *gdev = &(hba[ctlr]->gendisk);
+	gdev->part[minor(dev)].nr_sects = hba[ctlr]->drv[target].nr_blocks;
+	return 0;
+}
+
 /* Borrowed and adapted from sd.c */
 /*
  * FIXME: we are missing the exclusion with ->open() here - it can happen
@@ -760,14 +767,6 @@
 leave:
         hba[ctlr]->drv[target].usage_count--;
         return res;
-}
-
-static int frevalidate_logvol(kdev_t dev)
-{
-#ifdef CCISS_DEBUG
-	printk(KERN_DEBUG "cciss: frevalidate has been called\n");
-#endif /* CCISS_DEBUG */ 
-	return revalidate_logvol(dev, 0);
 }
 
 /*
diff -Nru a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
--- a/drivers/block/cpqarray.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/block/cpqarray.c	Sat Aug 10 18:42:21 2002
@@ -104,7 +104,8 @@
 };
 
 static struct hd_struct * ida;
-static struct gendisk ida_gendisk[MAX_CTLR];
+static char *ida_names;
+static struct gendisk ida_gendisk[MAX_CTLR * NWD];
 
 static struct proc_dir_entry *proc_array;
 
@@ -153,8 +154,7 @@
 
 static void do_ida_intr(int irq, void *dev_id, struct pt_regs * regs);
 static void ida_timer(unsigned long tdata);
-static int frevalidate_logvol(kdev_t dev);
-static int revalidate_logvol(kdev_t dev, int maxusage);
+static int ida_revalidate(kdev_t dev);
 static int revalidate_allvol(kdev_t dev);
 
 #ifdef CONFIG_PROC_FS
@@ -166,29 +166,12 @@
 			     int length, int *eof, void *data) { return 0;}
 #endif
 
-static void ida_geninit(int ctlr)
-{
-	int i;
-	drv_info_t *drv;
-
-	for(i=0; i<NWD; i++) {
-		drv = &hba[ctlr]->drv[i];
-		if (!drv->nr_blks)
-			continue;
-		ida[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)].nr_sects = drv->nr_blks;
-
-		(BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->blk_size;
-		ida_gendisk[ctlr].nr_real++;
-	}
-
-}
-
 static struct block_device_operations ida_fops  = {
 	owner:		THIS_MODULE,
 	open:		ida_open,
 	release:	ida_release,
 	ioctl:		ida_ioctl,
-	revalidate:	frevalidate_logvol,
+	revalidate:	ida_revalidate,
 };
 
 
@@ -307,7 +290,7 @@
 
 void cleanup_module(void)
 {
-	int i;
+	int i, j;
 	char buff[4]; 
 
 	for(i=0; i<nr_ctlr; i++) {
@@ -331,11 +314,15 @@
 			hba[i]->cmd_pool_dhandle);
 		kfree(hba[i]->cmd_pool_bits);
 
-		del_gendisk(&ida_gendisk[i]);
+		for (j = 0; j < NWD; j++) {
+			if (ida_gendisk[i*NWD+j].major_name)
+				del_gendisk(&ida_gendisk[i*NWD+j]);
+		}
 	}
 	devfs_find_and_unregister(NULL, "ida", 0, 0, 0, 0);
 	remove_proc_entry("cpqarray", proc_root_driver);
 	kfree(ida);
+	kfree(ida_names);
 }
 #endif /* MODULE */
 
@@ -349,7 +336,6 @@
 	request_queue_t *q;
 	int i,j;
 	int num_cntlrs_reg = 0;
-
 	/* detect controllers */
 	cpqarray_pci_detect();
 	cpqarray_eisa_detect();
@@ -362,16 +348,15 @@
 
 	/* allocate space for disk structs */
 	ida = kmalloc(sizeof(struct hd_struct)*nr_ctlr*NWD*16, GFP_KERNEL);
-	if(ida==NULL)
-	{
+	ida_names = kmalloc(nr_ctlr*NWD*10, GFP_KERNEL);
+	if (!ida || !ida_names) {
 		printk( KERN_ERR "cpqarray: out of memory");
+		kfree(ida);
+		kfree(ida_names);
 		return(num_cntlrs_reg);
 	}
-	
 	memset(ida, 0, sizeof(struct hd_struct)*nr_ctlr*NWD*16);
-	memset(ida_gendisk, 0, sizeof(struct gendisk)*MAX_CTLR);
-
-		/* 
+	/* 
 	 * register block devices
 	 * Find disks and fill in structs
 	 * Get an interrupt, set the Q depth and get into /proc
@@ -424,6 +409,7 @@
 			if (num_cntlrs_reg == 0) 
 			{
 				kfree(ida);
+				kfree(ida_names);
 			}
                 	return(num_cntlrs_reg);
 	
@@ -450,30 +436,34 @@
 
 		/* This is a driver limit and could be eliminated. */
 		blk_queue_max_phys_segments(q, SG_MAX);
-
-		ida_gendisk[i].major = MAJOR_NR + i;
-		ida_gendisk[i].major_name = "ida";
-		ida_gendisk[i].minor_shift = NWD_SHIFT;
-		ida_gendisk[i].part = ida + (i*256);
-		ida_gendisk[i].nr_real = 0; 
-		ida_gendisk[i].de_arr = de_arr[i]; 
-		ida_gendisk[i].fops = &ida_fops; 
 	
-		/* Get on the disk list */
-		add_gendisk(&ida_gendisk[i]);
-
 		init_timer(&hba[i]->timer);
 		hba[i]->timer.expires = jiffies + IDA_TIMER;
 		hba[i]->timer.data = (unsigned long)hba[i];
 		hba[i]->timer.function = ida_timer;
 		add_timer(&hba[i]->timer);
 
-		ida_geninit(i);
-		for(j=0; j<NWD; j++)	
-			register_disk(&ida_gendisk[i], 
-				mk_kdev(MAJOR_NR+i,j<<4),
-				16, &ida_fops, hba[i]->drv[j].nr_blks);
-
+		for(j=0; j<NWD; j++) {
+			struct gendisk *disk = ida_gendisk + i*NWD + j;
+			drv_info_t *drv = &hba[i]->drv[j];
+			sprintf(ida_names + (i*NWD+j)*10, "ida/c%dd%d", i, j);
+			disk->major = MAJOR_NR + i;
+			disk->first_minor = j<<NWD_SHIFT;
+			disk->minor_shift = NWD_SHIFT;
+			disk->part = ida + i*256 + (j<<NWD_SHIFT);
+			disk->nr_real = 1; 
+			disk->de_arr = &de_arr[i][j]; 
+			disk->fops = &ida_fops; 
+			if (!drv->nr_blks)
+				continue;
+			disk->major_name = ida_names + (i*NWD+j)*10;
+			(BLK_DEFAULT_QUEUE(MAJOR_NR + i))->hardsect_size = drv->blk_size;
+			add_gendisk(disk);
+			register_disk(disk,
+				      mk_kdev(disk->major,disk->first_minor),
+				      1<<disk->minor_shift, disk->fops,
+				      drv->nr_blks);
+		}
 	}
 	/* done ! */
 	return(num_cntlrs_reg);
@@ -755,21 +745,19 @@
 	if (ctlr > MAX_CTLR || hba[ctlr] == NULL)
 		return -ENXIO;
 
-	if (!capable(CAP_SYS_RAWIO) && inode->i_bdev->bd_inode->i_size == 0)
-		return -ENXIO;
-
 	/*
 	 * Root is allowed to open raw volume zero even if its 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".
 	 */
-	if (capable(CAP_SYS_ADMIN)
-		&& inode->i_bdev->bd_inode->i_size == 0
-		&& minor(inode->i_rdev) != 0)
-		return -ENXIO;
-
-	hba[ctlr]->drv[dsk].usage_count++;
+	if (!hba[ctlr]->drv[dsk].nr_blks) {
+		if (!capable(CAP_SYS_RAWIO))
+			return -ENXIO;
+		/* Huh??? */
+		if (capable(CAP_SYS_ADMIN) && minor(inode->i_rdev) != 0)
+			return -ENXIO;
+	}
 	hba[ctlr]->usage_count++;
 	return 0;
 }
@@ -780,11 +768,6 @@
 static int ida_release(struct inode *inode, struct file *filep)
 {
 	int ctlr = major(inode->i_rdev) - MAJOR_NR;
-	int dsk  = minor(inode->i_rdev) >> NWD_SHIFT;
-
-	DBGINFO(printk("ida_release %x (%x:%x)\n", inode->i_rdev, ctlr, dsk) );
-
-	hba[ctlr]->drv[dsk].usage_count--;
 	hba[ctlr]->usage_count--;
 	return 0;
 }
@@ -1107,8 +1090,6 @@
 				 sizeof(drv_info_t)))
 			return -EFAULT;
 		return 0;
-	case BLKRRPART:
-		return revalidate_logvol(inode->i_rdev, 1);
 	case IDAPASSTHRU:
 		if (!capable(CAP_SYS_RAWIO)) return -EPERM;
 		if (copy_from_user(&my_io, io, sizeof(my_io)))
@@ -1441,11 +1422,6 @@
 	return (IO_OK);
 }
 
-static int frevalidate_logvol(kdev_t dev)
-{
-	return revalidate_logvol(dev, 0);
-}
-
 /*
  * revalidate_allvol is for online array config utilities.  After a
  * utility reconfigures the drives in the array, it can use this function
@@ -1481,9 +1457,16 @@
 	 * Set the partition and block size structures for all volumes
 	 * on this controller to zero.  We will reread all of this data
 	 */
+	for (i = 0; i < NWD; i++) {
+		struct gendisk *disk = ida_gendisk + ctlr*NWD + i;
+		if (!disk->major_name)
+			continue;
+		wipe_partitions(mk_kdev(disk->major, disk->first_minor));
+		del_gendisk(disk);
+		disk->major_name = NULL;
+	}
 	memset(ida+(ctlr*256),            0, sizeof(struct hd_struct)*NWD*16);
 	memset(hba[ctlr]->drv,            0, sizeof(drv_info_t)*NWD);
-	ida_gendisk[ctlr].nr_real = 0;
 
 	/*
 	 * Tell the array controller not to give us any interrupts while
@@ -1494,52 +1477,31 @@
 	getgeometry(ctlr);
 	hba[ctlr]->access.set_intr_mask(hba[ctlr], FIFO_NOT_EMPTY);
 
-	ida_geninit(ctlr);
 	for(i=0; i<NWD; i++) {
-		kdev_t kdev = mk_kdev(major(dev), i << NWD_SHIFT);
-		if (ida[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)].nr_sects)
-			revalidate_logvol(kdev, 2);
+		struct gendisk *disk = ida_gendisk + ctlr*NWD + i;
+		drv_info_t *drv = &hba[ctlr]->drv[i];
+		if (!drv->nr_blks)
+			continue;
+		(BLK_DEFAULT_QUEUE(MAJOR_NR + ctlr))->hardsect_size = drv->blk_size;
+		add_gendisk(disk);
+		register_disk(disk,
+			      mk_kdev(disk->major,disk->first_minor),
+			      1<<disk->minor_shift, disk->fops,
+			      drv->nr_blks);
 	}
 
 	hba[ctlr]->usage_count--;
 	return 0;
 }
 
-/* Borrowed and adapted from sd.c */
-/*
- * FIXME: exclusion with ->open()
- */
-static int revalidate_logvol(kdev_t dev, int maxusage)
+static int ida_revalidate(kdev_t dev)
 {
-	int ctlr, target;
-	struct gendisk *gdev;
-	unsigned long flags;
-	int res;
-
-	target = DEVICE_NR(dev);
-	ctlr = major(dev) - MAJOR_NR;
-	gdev = &ida_gendisk[ctlr];
-	
-	spin_lock_irqsave(IDA_LOCK(ctlr), flags);
-	if (hba[ctlr]->drv[target].usage_count > maxusage) {
-		spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);
-		printk(KERN_WARNING "cpqarray: Device busy for "
-			"revalidation (usage=%d)\n",
-			hba[ctlr]->drv[target].usage_count);
-		return -EBUSY;
-	}
-
-	hba[ctlr]->drv[target].usage_count++;
-	spin_unlock_irqrestore(IDA_LOCK(ctlr), flags);
-
-	res = wipe_partitions(dev);
-	if (!res)
-		grok_partitions(dev, hba[ctlr]->drv[target].nr_blks);
-
-	hba[ctlr]->drv[target].usage_count--;
-	return res;
+        int ctlr = major(dev) - MAJOR_NR;
+	int target = DEVICE_NR(dev);
+        struct gendisk *gdev = &ida_gendisk[ctlr*NWD+target];
+	gdev->part[minor(dev)].nr_sects = hba[ctlr]->drv[target].nr_blks;
+	return 0;
 }
-
 
 /********************************************************************
     name: pollcomplete
diff -Nru a/drivers/block/elevator.c b/drivers/block/elevator.c
--- a/drivers/block/elevator.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/block/elevator.c	Sat Aug 10 18:42:23 2002
@@ -482,5 +482,6 @@
 EXPORT_SYMBOL(__elv_add_request);
 EXPORT_SYMBOL(elv_next_request);
 EXPORT_SYMBOL(elv_remove_request);
+EXPORT_SYMBOL(elv_queue_empty);
 EXPORT_SYMBOL(elevator_exit);
 EXPORT_SYMBOL(elevator_init);
diff -Nru a/drivers/block/floppy.c b/drivers/block/floppy.c
--- a/drivers/block/floppy.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/block/floppy.c	Sat Aug 10 18:42:21 2002
@@ -3308,12 +3308,12 @@
 	return ret;
 }
 
-static int invalidate_drive(kdev_t rdev)
+static int invalidate_drive(struct block_device *bdev)
 {
 	/* invalidate the buffer track to force a reread */
-	set_bit(DRIVE(rdev), &fake_change);
+	set_bit(DRIVE(to_kdev_t(bdev->bd_dev)), &fake_change);
 	process_fd_request();
-	check_disk_change(rdev);
+	check_disk_change(bdev);
 	return 0;
 }
 
@@ -3324,7 +3324,7 @@
 }
 
 static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
-			       int drive, int type, kdev_t device)
+			       int drive, int type, struct block_device *bdev)
 {
 	int cnt;
 
@@ -3354,8 +3354,8 @@
 		for (cnt = 0; cnt < N_DRIVE; cnt++){
 			if (ITYPE(drive_state[cnt].fd_device) == type &&
 			    drive_state[cnt].fd_ref)
-				check_disk_change(
-					mk_kdev(FLOPPY_MAJOR,
+				__check_disk_change(
+					MKDEV(FLOPPY_MAJOR,
 					      drive_state[cnt].fd_device));
 		}
 	} else {
@@ -3379,7 +3379,7 @@
 		 * mtools often changes the geometry of the disk after
 		 * looking at the boot block */
 		if (DRS->maxblock > user_params[drive].sect || DRS->maxtrack)
-			invalidate_drive(device);
+			invalidate_drive(bdev);
 		else
 			process_fd_request();
 	}
@@ -3544,11 +3544,11 @@
 			current_type[drive] = NULL;
 			floppy_sizes[drive] = MAX_DISK_SIZE;
 			UDRS->keep_data = 0;
-			return invalidate_drive(device);
+			return invalidate_drive(inode->i_bdev);
 		case FDSETPRM:
 		case FDDEFPRM:
 			return set_geometry(cmd, & inparam.g,
-					    drive, type, device);
+					    drive, type, inode->i_bdev);
 		case FDGETPRM:
 			ECALL(get_floppy_geometry(drive, type, 
 						  (struct floppy_struct**)
@@ -3579,7 +3579,7 @@
 		case FDFMTEND:
 		case FDFLUSH:
 			LOCK_FDC(drive,1);
-			return invalidate_drive(device);
+			return invalidate_drive(inode->i_bdev);
 
 		case FDSETEMSGTRESH:
 			UDP->max_errors.reporting =
@@ -3805,7 +3805,7 @@
 		return 0;
 	if (filp->f_mode & 3) {
 		UDRS->last_checked = 0;
-		check_disk_change(inode->i_rdev);
+		check_disk_change(inode->i_bdev);
 		if (UTESTF(FD_DISK_CHANGED))
 			RETERR(ENXIO);
 	}
diff -Nru a/drivers/block/genhd.c b/drivers/block/genhd.c
--- a/drivers/block/genhd.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/block/genhd.c	Sat Aug 10 18:42:22 2002
@@ -166,7 +166,7 @@
 			continue;
 		seq_printf(part, "%4d  %4d %10ld %s\n",
 			sgp->major, n + sgp->first_minor,
-			sgp->part[n].nr_sects << 1,
+			sgp->part[n].nr_sects >> 1 ,
 			disk_name(sgp, n + sgp->first_minor, buf));
 	}
 
diff -Nru a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
--- a/drivers/block/paride/pd.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/block/paride/pd.c	Sat Aug 10 18:42:23 2002
@@ -327,14 +327,6 @@
 
 extern struct block_device_operations pd_fops;
 
-static struct gendisk pd_gendisk = {
-	major:		PD_MAJOR,
-	major_name:	PD_NAME,
-	minor_shift:	PD_BITS,
-	fops:		&pd_fops,
-	nr_real:	1,
-};
-
 static struct block_device_operations pd_fops = {
 	owner:			THIS_MODULE,
         open:			pd_open,
@@ -412,10 +404,6 @@
 		}
 		put_user(get_start_sect(inode->i_bdev), (long *)&geo->start);
 		return 0;
-	    case BLKRRPART:
-		if (!capable(CAP_SYS_ADMIN))
-			return -EACCES;
-		return pd_revalidate(inode->i_rdev);
 	    default:
 		return -EINVAL;
 	}
@@ -447,23 +435,13 @@
 static int pd_revalidate(kdev_t dev)
 {
 	int unit = DEVICE_NR(dev);
-	kdev_t device = mk_kdev(MAJOR_NR, unit << PD_BITS);
-	int res;
-
 	if ((unit >= PD_UNITS) || !PD.present)
 		return -ENODEV;
-
-	res = dev_lock_part(device);
-	if (res < 0)
-		return res;
-	res = wipe_partitions(device);
-
-	if (res == 0 && pd_identify(unit))
-		grok_partitions(device, PD.capacity);
-
-	dev_unlock_part(device);
- 
-        return res;
+	if (pd_identify(unit))
+		pd_hd[minor(dev)].nr_sects = PD.capacity;
+	else
+		pd_hd[minor(dev)].nr_sects = 0;
+        return 0;
 }
 
 #define	WR(c,r,v)	pi_write_regr(PI,c,r,v)
@@ -706,7 +684,11 @@
             }
 	for (unit=0;unit<PD_UNITS;unit++) {
 		if (PD.present) {
-			PD.gd = pd_gendisk;
+			PD.gd.major_name = PD.name;
+			PD.gd.minor_shift = PD_BITS;
+			PD.gd.fops = &pd_fops;
+			PD.gd.nr_real = 1;
+			PD.gd.major = major;
 			PD.gd.first_minor = unit << PD_BITS;
 			PD.gd.part = pd_hd + (unit << PD_BITS);
 			add_gendisk(&PD.gd);
@@ -947,8 +929,6 @@
 	blk_init_queue(q, do_pd_request, &pd_lock);
 	blk_queue_max_sectors(q, cluster);
 
-	pd_gendisk.major = major;
-	pd_gendisk.major_name = name;
 	printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
 		name,name,PD_VERSION,major,cluster,nice);
 	pd_init_units();
diff -Nru a/drivers/block/ps2esdi.c b/drivers/block/ps2esdi.c
--- a/drivers/block/ps2esdi.c	Sat Aug 10 18:42:19 2002
+++ b/drivers/block/ps2esdi.c	Sat Aug 10 18:42:19 2002
@@ -95,8 +95,6 @@
 static int ps2esdi_ioctl(struct inode *inode, struct file *file,
 			 u_int cmd, u_long arg);
 
-static int ps2esdi_reread_partitions(kdev_t dev);
-
 static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);
 
 static void dump_cmd_complete_status(u_int int_ret_code);
@@ -148,13 +146,24 @@
 	ioctl:		ps2esdi_ioctl,
 };
 
-static struct gendisk ps2esdi_gendisk =
+static struct gendisk ps2esdi_gendisk[2] = {
 {
 	major:		MAJOR_NR,
-	major_name:	"ed",
+	major_name:	"eda",
+	first_minor:	0,
 	minor_shift:	6,
 	part:		ps2esdi,
 	fops:		&ps2esdi_fops,
+	nr_real:	1
+},{
+	major:		MAJOR_NR,
+	first_minor:	64
+	major_name:	"edb",
+	minor_shift:	6,
+	part:		ps2esdi+64,
+	fops:		&ps2esdi_fops,
+	nr_real:	1
+}
 };
 
 /* initialization routine called by ll_rw_blk.c   */
@@ -174,14 +183,12 @@
 			&ps2esdi_lock);
 
 	/* some minor housekeeping - setup the global gendisk structure */
-	add_gendisk(&ps2esdi_gendisk);
 	error = ps2esdi_geninit();
 	if (error) {
 		printk(KERN_WARNING "PS2ESDI: error initialising"
 			" device, releasing resources\n");
 		unregister_blkdev(MAJOR_NR, "ed");
 		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-		del_gendisk(&ps2esdi_gendisk);
 		blk_clear(MAJOR_NR);
 		return error;
 	}
@@ -232,7 +239,8 @@
 	free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk);
 	unregister_blkdev(MAJOR_NR, "ed");
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-	del_gendisk(&ps2esdi_gendisk);
+	for (i = 0; i < ps2esdi_drives; i++)
+		del_gendisk(ps2esdi_gendisk + i);
 	blk_clear(MAJOR_NR);
 }
 #endif /* MODULE */
@@ -422,8 +430,6 @@
 
 	current_int_handler = ps2esdi_normal_interrupt_handler;
 
-	ps2esdi_gendisk.nr_real = ps2esdi_drives;
-
 	if (request_dma(dma_arb_level, "ed") !=0) {
 		printk(KERN_WARNING "PS2ESDI: Can't request dma-channel %d\n"
 			,(int) dma_arb_level);
@@ -432,11 +438,14 @@
 	}
 	blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), 128);
 
-	for (i = 0; i < ps2esdi_drives; i++)
-		register_disk(&ps2esdi_gendisk,mk_kdev(MAJOR_NR,i<<6),1<<6,
-				&ps2esdi_fops,
+	for (i = 0; i < ps2esdi_drives; i++) {
+		struct gendisk *disk = ps2esdi_gendisk + i;
+		add_gendisk(disk);
+		register_disk(disk, mk_kdev(disk->major,disk->first_minor),
+				1<<disk->minor_shift, disk->fops,
 				ps2esdi_info[i].head * ps2esdi_info[i].sect *
 				ps2esdi_info[i].cyl);
+	}
 	return 0;
 
 err_out3:
@@ -1080,53 +1089,18 @@
 static int ps2esdi_ioctl(struct inode *inode,
 			 struct file *file, u_int cmd, u_long arg)
 {
-
 	struct ps2esdi_geometry *geometry = (struct ps2esdi_geometry *) arg;
 	int dev = DEVICE_NR(inode->i_rdev), err;
 
-	if (inode && (dev < ps2esdi_drives))
-		switch (cmd) {
-		case HDIO_GETGEO:
-			if (arg) {
-				if ((err = verify_area(VERIFY_WRITE, geometry, sizeof(*geometry))))
-					return (err);
-				put_user(ps2esdi_info[dev].head, (char *) &geometry->heads);
-				put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors);
-				put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders);
-				put_user(get_start_sect(inode->b_rdev),
-					    (long *) &geometry->start);
-
-				return 0;
-			}
-			break;
-
-		case BLKRRPART:
-                        if (!capable(CAP_SYS_ADMIN)) 
-				return -EACCES;
-			return (ps2esdi_reread_partitions(inode->i_rdev));
-		}
-	return (-EINVAL);
-}
-
-
-
-static int ps2esdi_reread_partitions(kdev_t dev)
-{
-	int target = DEVICE_NR(dev);
-	kdev_t device = mk_kdev(MAJOR_NR, target << 6);
-	int res = dev_lock_part(device);
-
-	if (res < 0)
-		return res;
-
-	res = wipe_partitions(device);
-	if (res == 0)
-		grok_partitions(device, ps2esdi_info[target].head
-				* ps2esdi_info[target].cyl
-				* ps2esdi_info[target].sect);
- 
-	dev_unlock_part(device);
-	return res;
+	if (cmd != HDIO_GETGEO)
+		return -EINVAL;
+	if ((err = verify_area(VERIFY_WRITE, geometry, sizeof(*geometry))))
+		return (err);
+	put_user(ps2esdi_info[dev].head, (char *) &geometry->heads);
+	put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors);
+	put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders);
+	put_user(get_start_sect(inode->b_rdev), (long *) &geometry->start);
+	return 0;
 }
 
 static void ps2esdi_reset_timer(unsigned long unused)
diff -Nru a/drivers/block/swim3.c b/drivers/block/swim3.c
--- a/drivers/block/swim3.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/block/swim3.c	Sat Aug 10 18:42:22 2002
@@ -897,7 +897,7 @@
 
 	if (err == 0 && (filp->f_flags & O_NDELAY) == 0
 	    && (filp->f_mode & 3)) {
-		check_disk_change(inode->i_rdev);
+		check_disk_change(inode->i_bdev);
 		if (fs->ejected)
 			err = -ENXIO;
 	}
diff -Nru a/drivers/block/swim_iop.c b/drivers/block/swim_iop.c
--- a/drivers/block/swim_iop.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/block/swim_iop.c	Sat Aug 10 18:42:20 2002
@@ -387,7 +387,7 @@
 
 	if (err == 0 && (filp->f_flags & O_NDELAY) == 0
 	    && (filp->f_mode & 3)) {
-		check_disk_change(inode->i_rdev);
+		check_disk_change(inode->i_bdev);
 		if (fs->ejected)
 			err = -ENXIO;
 	}
diff -Nru a/drivers/block/umem.c b/drivers/block/umem.c
--- a/drivers/block/umem.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/block/umem.c	Sat Aug 10 18:42:23 2002
@@ -818,14 +818,7 @@
 static int mm_revalidate(kdev_t i_rdev)
 {
 	int card_number = DEVICE_NR(i_rdev);
-	kdev_t device = mk_kdev(MAJOR_NR, card_number << MM_SHIFT);
-	int res = dev_lock_part(device);
-	if (res < 0)
-		return res;
-	wipe_partitions(device);
-	printk(KERN_INFO "mm partition check: (%d)\n", card_number);
-	grok_partitions(device, cards[card_number].mm_size << 1);
-	dev_unlock_part(device);
+	mm_partitions[minor(i_rdev)] = cards[card_number].mm_size << 1;
 	return 0;
 }
 /*
@@ -835,22 +828,10 @@
 */
 static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
 {
-	int err, size, card_number;
-	struct hd_geometry geo;
-	unsigned int minor;
-
-	if (!i)
-		return -EINVAL;
-
-	minor       = minor(i->i_rdev);
-	card_number = (minor >> MM_SHIFT);
-
-
-	switch(cmd) {
-	case BLKRRPART:
-		return (mm_revalidate(i->i_rdev));
-
-	case HDIO_GETGEO:
+	if (cmd == case HDIO_GETGEO) {
+		unsigned int minor = minor(i->i_rdev);
+		int err, size, card_number = (minor >> MM_SHIFT);
+		struct hd_geometry geo;
 		/*
 		 * get geometry: we have to fake one...  trim the size to a
 		 * multiple of 2048 (1M): tell we have 32 sectors, 64 heads,
@@ -867,12 +848,9 @@
 		if (copy_to_user((void *) arg, &geo, sizeof(geo)))
 			return -EFAULT;
 		return 0;
-
-	default:
-		return -EINVAL;
 	}
 
-	return -ENOTTY; /* unknown command */
+	return -EINVAL;
 }
 /*
 -----------------------------------------------------------------------------------
diff -Nru a/drivers/block/xd.c b/drivers/block/xd.c
--- a/drivers/block/xd.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/block/xd.c	Sat Aug 10 18:42:22 2002
@@ -166,7 +166,7 @@
 		printk("xd: Unable to get major number %d\n",MAJOR_NR);
 		return -1;
 	}
-	devfs_handle = devfs_mk_dir (NULL, xd_gendisk.major_name, NULL);
+	devfs_handle = devfs_mk_dir (NULL, "xd", NULL);
 	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_xd_request, &xd_lock);
 	add_gendisk(&xd_gendisk);
 	xd_geninit();
@@ -330,35 +330,9 @@
 			return put_user(!nodma, (long *) arg);
 		case HDIO_GET_MULTCOUNT:
 			return put_user(xd_maxsectors, (long *) arg);
-		case BLKRRPART:
-			if (!capable(CAP_SYS_ADMIN)) 
-				return -EACCES;
-			return xd_reread_partitions(inode->i_rdev);
-
 		default:
 			return -EINVAL;
 	}
-}
-
-/* xd_reread_partitions: rereads the partition table from a drive */
-static int xd_reread_partitions(kdev_t dev)
-{
-	int target = DEVICE_NR(dev);
-	kdev_t device = mk_kdev(MAJOR_NR, target << 6);
-	int res = dev_lock_part(device);
-	
-	if (res < 0)
-		return 0;
-
-	res = wipe_partitions(device);
-	if (!res)
-		grok_partitions(device, xd_info[target].heads
-				* xd_info[target].cylinders
-				* xd_info[target].sectors);
-
-	dev_unlock_part(device);
-
-	return res;
 }
 
 /* xd_readwrite: handle a read/write request */
diff -Nru a/drivers/block/xd.h b/drivers/block/xd.h
--- a/drivers/block/xd.h	Sat Aug 10 18:42:22 2002
+++ b/drivers/block/xd.h	Sat Aug 10 18:42:22 2002
@@ -113,7 +113,6 @@
 static int xd_open (struct inode *inode,struct file *file);
 static void do_xd_request (request_queue_t * q);
 static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);
-static int xd_reread_partitions (kdev_t dev);
 static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count);
 static void xd_recalibrate (u_char drive);
 
diff -Nru a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
--- a/drivers/cdrom/cdrom.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/cdrom/cdrom.c	Sat Aug 10 18:42:21 2002
@@ -432,11 +432,6 @@
 		topCdromPtr = cdi->next;
 	cdi->ops->n_minors--;
 	devfs_unregister (cdi->de);
-	if (atomic_read (&cdi->cdrom_driverfs_dev.refcount)) {
-		device_remove_file (&cdi->cdrom_driverfs_dev, "name");
-		device_remove_file (&cdi->cdrom_driverfs_dev, "kdev");
-		put_device (&cdi->cdrom_driverfs_dev);
-	}
 	devfs_dealloc_unique_number (&cdrom_numspace, cdi->number);
 	cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
 	return 0;
@@ -486,7 +481,7 @@
 	cdinfo(CD_OPEN, "Use count for \"/dev/%s\" now %d\n", cdi->name, cdi->use_count);
 	/* Do this on open.  Don't wait for mount, because they might
 	    not be mounting, but opening with O_NONBLOCK */
-	check_disk_change(dev);
+	check_disk_change(ip->i_bdev);
 	return ret;
 }
 
diff -Nru a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
--- a/drivers/cdrom/sonycd535.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/cdrom/sonycd535.c	Sat Aug 10 18:42:22 2002
@@ -1402,9 +1402,7 @@
 		sony_inuse = 0;
 		return -EIO;
 	}
-	if (inode) {
-		check_disk_change(inode->i_rdev);
-	}
+	check_disk_change(inode->i_bdev);
 	sony_usage++;
 
 #ifdef LOCK_DOORS
diff -Nru a/drivers/char/Makefile b/drivers/char/Makefile
--- a/drivers/char/Makefile	Sat Aug 10 18:42:23 2002
+++ b/drivers/char/Makefile	Sat Aug 10 18:42:23 2002
@@ -65,6 +65,12 @@
   endif
 endif
 
+ifeq ($(ARCH),um)
+  KEYMAP   =
+  KEYBD    =
+  CONSOLE  =
+endif
+
 ifeq ($(ARCH),sh)
   KEYMAP   =
   KEYBD    =
@@ -108,14 +114,18 @@
   KEYMAP   = qtronixmap.o
 endif
 
+ifeq ($(CONFIG_SPARC32),y)
+  KEYBD    =
+endif
+
+ifeq ($(CONFIG_SPARC64),y)
+  KEYBD    =
+endif
+
 obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o
 #obj-$(CONFIG_SERIAL) += $(SERIAL) # Fix for decserial.o
 
-ifndef CONFIG_SUN_KEYBOARD
-  obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD)
-else
-  obj-$(CONFIG_PCI) += keyboard.o $(KEYMAP)
-endif
+obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD)
 
 obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
 obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
diff -Nru a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
--- a/drivers/char/drm/drm.h	Sat Aug 10 18:42:21 2002
+++ b/drivers/char/drm/drm.h	Sat Aug 10 18:42:21 2002
@@ -38,10 +38,27 @@
 #if defined(__linux__)
 #include <linux/config.h>
 #include <asm/ioctl.h>		/* For _IO* macros */
-#define DRM_IOCTL_NR(n)	     _IOC_NR(n)
-#elif defined(__FreeBSD__)
+#define DRM_IOCTL_NR(n)		_IOC_NR(n)
+#define DRM_IOC_VOID		_IOC_NONE
+#define DRM_IOC_READ		_IOC_READ
+#define DRM_IOC_WRITE		_IOC_WRITE
+#define DRM_IOC_READWRITE	_IOC_READ|_IOC_WRITE
+#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
+#elif defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) && defined(XFree86Server)
+/* Prevent name collision when including sys/ioccom.h */
+#undef ioctl
 #include <sys/ioccom.h>
-#define DRM_IOCTL_NR(n)	     ((n) & 0xff)
+#define ioctl(a,b,c)		xf86ioctl(a,b,c)
+#else
+#include <sys/ioccom.h>
+#endif /* __FreeBSD__ && xf86ioctl */
+#define DRM_IOCTL_NR(n)		((n) & 0xff)
+#define DRM_IOC_VOID		IOC_VOID
+#define DRM_IOC_READ		IOC_OUT
+#define DRM_IOC_WRITE		IOC_IN
+#define DRM_IOC_READWRITE	IOC_INOUT
+#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
 #endif
 
 #define XFREE86_VERSION(major,minor,patch,snap) \
@@ -367,10 +384,9 @@
 
 #define DRM_IOCTL_BASE			'd'
 #define DRM_IO(nr)			_IO(DRM_IOCTL_BASE,nr)
-#define DRM_IOR(nr,size)		_IOR(DRM_IOCTL_BASE,nr,size)
-#define DRM_IOW(nr,size)		_IOW(DRM_IOCTL_BASE,nr,size)
-#define DRM_IOWR(nr,size)		_IOWR(DRM_IOCTL_BASE,nr,size)
-
+#define DRM_IOR(nr,type)		_IOR(DRM_IOCTL_BASE,nr,type)
+#define DRM_IOW(nr,type)		_IOW(DRM_IOCTL_BASE,nr,type)
+#define DRM_IOWR(nr,type)		_IOWR(DRM_IOCTL_BASE,nr,type)
 
 #define DRM_IOCTL_VERSION		DRM_IOWR(0x00, drm_version_t)
 #define DRM_IOCTL_GET_UNIQUE		DRM_IOWR(0x01, drm_unique_t)
diff -Nru a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
--- a/drivers/char/drm/drmP.h	Sat Aug 10 18:42:23 2002
+++ b/drivers/char/drm/drmP.h	Sat Aug 10 18:42:23 2002
@@ -71,6 +71,8 @@
 #include <asm/pgalloc.h>
 #include "drm.h"
 
+#include "drm_os_linux.h"
+
 /* DRM template customization defaults
  */
 #ifndef __HAVE_AGP
@@ -101,7 +103,7 @@
 #define __REALLY_HAVE_AGP	(__HAVE_AGP && (defined(CONFIG_AGP) || \
 						defined(CONFIG_AGP_MODULE)))
 #define __REALLY_HAVE_MTRR	(__HAVE_MTRR && defined(CONFIG_MTRR))
-
+#define __REALLY_HAVE_SG	(__HAVE_SG)
 
 /* Begin the DRM...
  */
diff -Nru a/drivers/char/drm/drm_drv.h b/drivers/char/drm/drm_drv.h
--- a/drivers/char/drm/drm_drv.h	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/drm/drm_drv.h	Sat Aug 10 18:42:22 2002
@@ -127,6 +127,22 @@
 }
 #endif
 
+#ifndef MODULE
+/* DRM(options) is called by the kernel to parse command-line options
+ * passed via the boot-loader (e.g., LILO).  It calls the insmod option
+ * routine, drm_parse_drm.
+ */
+/* Use an additional macro to avoid preprocessor troubles */
+#define DRM_OPTIONS_FUNC DRM(options)
+static int __init DRM(options)( char *str )
+{
+	DRM(parse_options)( str );
+	return 1;
+}
+
+__setup( DRIVER_NAME "=", DRM_OPTIONS_FUNC );
+#undef DRM_OPTIONS_FUNC
+#endif
 
 /*
  * The default number of instances (minor numbers) to initialize.
diff -Nru a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/char/drm/drm_os_linux.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,56 @@
+#define __NO_VERSION__
+
+#include <linux/interrupt.h>	/* For task queue support */
+#include <linux/delay.h>
+
+#define DRM_IOCTL_ARGS			struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data
+#define DRM_ERR(d)			-(d)
+#define DRM_CURRENTPID			current->pid
+#define DRM_UDELAY(d)			udelay(d)
+#define DRM_READ8(addr)			readb(addr)
+#define DRM_READ32(addr)		readl(addr)
+#define DRM_WRITE8(addr, val)		writeb(val, addr)
+#define DRM_WRITE32(addr, val)		writel(val, addr)
+#define DRM_READMEMORYBARRIER()		mb()
+#define DRM_WRITEMEMORYBARRIER()	wmb()
+#define DRM_DEVICE	drm_file_t	*priv	= filp->private_data; \
+			drm_device_t	*dev	= priv->dev
+
+/* For data going from/to the kernel through the ioctl argument */
+#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3)	\
+	if ( copy_from_user(&arg1, arg2, arg3) )	\
+		return -EFAULT
+#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3)	\
+	if ( copy_to_user(arg1, &arg2, arg3) )		\
+		return -EFAULT
+/* Other copying of data from/to kernel space */
+#define DRM_COPY_FROM_USER(arg1, arg2, arg3)		\
+	copy_from_user(arg1, arg2, arg3)
+#define DRM_COPY_TO_USER(arg1, arg2, arg3)		\
+	copy_to_user(arg1, arg2, arg3)
+/* Macros for copyfrom user, but checking readability only once */
+#define DRM_VERIFYAREA_READ( uaddr, size ) 		\
+	verify_area( VERIFY_READ, uaddr, size )
+#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) 	\
+	__copy_from_user(arg1, arg2, arg3)
+#define DRM_GET_USER_UNCHECKED(val, uaddr)		\
+	__get_user(val, uaddr)
+
+
+/* malloc/free without the overhead of DRM(alloc) */
+#define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL)
+#define DRM_FREE(x) kfree(x)
+
+#define DRM_GETSAREA()								 \
+do { 										 \
+	struct list_head *list;							 \
+	list_for_each( list, &dev->maplist->head ) {				 \
+		drm_map_list_t *entry = (drm_map_list_t *)list;			 \
+		if ( entry->map &&						 \
+		     entry->map->type == _DRM_SHM &&				 \
+		     (entry->map->flags & _DRM_CONTAINS_LOCK) ) {		 \
+			dev_priv->sarea = entry->map;				 \
+ 			break;							 \
+ 		}								 \
+ 	}									 \
+} while (0)
diff -Nru a/drivers/char/drm/gamma.h b/drivers/char/drm/gamma.h
--- a/drivers/char/drm/gamma.h	Sat Aug 10 18:42:20 2002
+++ b/drivers/char/drm/gamma.h	Sat Aug 10 18:42:20 2002
@@ -38,6 +38,31 @@
  */
 #define __HAVE_MTRR			1
 
+#define DRIVER_AUTHOR		"VA Linux Systems Inc."
+
+#define DRIVER_NAME		"gamma"
+#define DRIVER_DESC		"3DLabs gamma"
+#define DRIVER_DATE		"20010624"
+
+#define DRIVER_MAJOR		2
+#define DRIVER_MINOR		0
+#define DRIVER_PATCHLEVEL	0
+
+#define DRIVER_IOCTLS							  \
+	[DRM_IOCTL_NR(DRM_IOCTL_DMA)]	     = { gamma_dma,	  1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_GAMMA_INIT)] = { gamma_dma_init,  1, 1 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_GAMMA_COPY)] = { gamma_dma_copy,  1, 1 }
+
+#define IOCTL_TABLE_NAME	DRM(ioctls)
+#define IOCTL_FUNC_NAME 	DRM(ioctl)
+
+#define __HAVE_COUNTERS		5
+#define __HAVE_COUNTER6		_DRM_STAT_IRQ
+#define __HAVE_COUNTER7		_DRM_STAT_DMA
+#define __HAVE_COUNTER8		_DRM_STAT_PRIMARY
+#define __HAVE_COUNTER9		_DRM_STAT_SPECIAL
+#define __HAVE_COUNTER10	_DRM_STAT_MISSED
+
 /* DMA customization:
  */
 #define __HAVE_DMA			1
diff -Nru a/drivers/char/drm/gamma_drv.c b/drivers/char/drm/gamma_drv.c
--- a/drivers/char/drm/gamma_drv.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/char/drm/gamma_drv.c	Sat Aug 10 18:42:23 2002
@@ -36,32 +36,6 @@
 #include "gamma_drm.h"
 #include "gamma_drv.h"
 
-#define DRIVER_AUTHOR		"VA Linux Systems Inc."
-
-#define DRIVER_NAME		"gamma"
-#define DRIVER_DESC		"3DLabs gamma"
-#define DRIVER_DATE		"20010624"
-
-#define DRIVER_MAJOR		2
-#define DRIVER_MINOR		0
-#define DRIVER_PATCHLEVEL	0
-
-#define DRIVER_IOCTLS							  \
-	[DRM_IOCTL_NR(DRM_IOCTL_DMA)]	     = { gamma_dma,	  1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_GAMMA_INIT)] = { gamma_dma_init,  1, 1 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_GAMMA_COPY)] = { gamma_dma_copy,  1, 1 }
-
-#define IOCTL_TABLE_NAME	DRM(ioctls)
-#define IOCTL_FUNC_NAME 	DRM(ioctl)
-
-#define __HAVE_COUNTERS		5
-#define __HAVE_COUNTER6		_DRM_STAT_IRQ
-#define __HAVE_COUNTER7		_DRM_STAT_DMA
-#define __HAVE_COUNTER8		_DRM_STAT_PRIMARY
-#define __HAVE_COUNTER9		_DRM_STAT_SPECIAL
-#define __HAVE_COUNTER10	_DRM_STAT_MISSED
-
-
 #include "drm_auth.h"
 #include "drm_agpsupport.h"
 #include "drm_bufs.h"
@@ -69,25 +43,6 @@
 #include "drm_dma.h"
 #include "drm_drawable.h"
 #include "drm_drv.h"
-
-#ifndef MODULE
-/* DRM(options) is called by the kernel to parse command-line options
- * passed via the boot-loader (e.g., LILO).  It calls the insmod option
- * routine, drm_parse_drm.
- */
-
-/* JH- We have to hand expand the string ourselves because of the cpp.  If
- * anyone can think of a way that we can fit into the __setup macro without
- * changing it, then please send the solution my way.
- */
-static int __init gamma_options( char *str )
-{
-	DRM(parse_options)( str );
-	return 1;
-}
-
-__setup( DRIVER_NAME "=", gamma_options );
-#endif
 
 #include "drm_fops.h"
 #include "drm_init.h"
diff -Nru a/drivers/char/drm/i810.h b/drivers/char/drm/i810.h
--- a/drivers/char/drm/i810.h	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/drm/i810.h	Sat Aug 10 18:42:22 2002
@@ -41,6 +41,47 @@
 #define __HAVE_MTRR		1
 #define __HAVE_CTX_BITMAP	1
 
+#define DRIVER_AUTHOR		"VA Linux Systems Inc."
+
+#define DRIVER_NAME		"i810"
+#define DRIVER_DESC		"Intel i810"
+#define DRIVER_DATE		"20020211"
+
+/* Interface history
+ *
+ * 1.1   - XFree86 4.1
+ * 1.2   - XvMC interfaces
+ *       - XFree86 4.2
+ * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility)
+ *       - Remove requirement for interrupt (leave stubs again)
+ */
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		2
+#define DRIVER_PATCHLEVEL	1
+
+#define DRIVER_IOCTLS							    \
+	[DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)]   = { i810_dma_init,    1, 1 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex,  1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)]  = { i810_clear_bufs,  1, 0 }, \
+      	[DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)]  = { i810_flush_ioctl, 1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage,      1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf,      1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)]   = { i810_swap_bufs,   1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)]   = { i810_copybuf,     1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy,      1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info,   1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus,    1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip,   1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I810_MC)]      = { i810_dma_mc,     1, 1 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus,    1, 0 }
+
+
+#define __HAVE_COUNTERS         4
+#define __HAVE_COUNTER6         _DRM_STAT_IRQ
+#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
+#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
+#define __HAVE_COUNTER9         _DRM_STAT_DMA
+
 /* Driver customization:
  */
 #define __HAVE_RELEASE		1
diff -Nru a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
--- a/drivers/char/drm/i810_drv.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/char/drm/i810_drv.c	Sat Aug 10 18:42:23 2002
@@ -37,48 +37,6 @@
 #include "i810_drm.h"
 #include "i810_drv.h"
 
-#define DRIVER_AUTHOR		"VA Linux Systems Inc."
-
-#define DRIVER_NAME		"i810"
-#define DRIVER_DESC		"Intel i810"
-#define DRIVER_DATE		"20020211"
-
-/* Interface history
- *
- * 1.1   - XFree86 4.1
- * 1.2   - XvMC interfaces
- *       - XFree86 4.2
- * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility)
- *       - Remove requirement for interrupt (leave stubs again)
- */
-#define DRIVER_MAJOR		1
-#define DRIVER_MINOR		2
-#define DRIVER_PATCHLEVEL	1
-
-#define DRIVER_IOCTLS							    \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)]   = { i810_dma_init,    1, 1 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex,  1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)]  = { i810_clear_bufs,  1, 0 }, \
-      	[DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)]  = { i810_flush_ioctl, 1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage,      1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf,      1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)]   = { i810_swap_bufs,   1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)]   = { i810_copybuf,     1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy,      1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus,    1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_MC)]      = { i810_dma_mc,     1, 1 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus,    1, 0 }
-
-
-#define __HAVE_COUNTERS         4
-#define __HAVE_COUNTER6         _DRM_STAT_IRQ
-#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
-#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
-#define __HAVE_COUNTER9         _DRM_STAT_DMA
-
-
 #include "drm_agpsupport.h"
 #include "drm_auth.h"
 #include "drm_bufs.h"
@@ -86,25 +44,6 @@
 #include "drm_dma.h"
 #include "drm_drawable.h"
 #include "drm_drv.h"
-
-#ifndef MODULE
-/* DRM(options) is called by the kernel to parse command-line options
- * passed via the boot-loader (e.g., LILO).  It calls the insmod option
- * routine, drm_parse_drm.
- */
-
-/* JH- We have to hand expand the string ourselves because of the cpp.  If
- * anyone can think of a way that we can fit into the __setup macro without
- * changing it, then please send the solution my way.
- */
-static int __init i810_options( char *str )
-{
-	DRM(parse_options)( str );
-	return 1;
-}
-
-__setup( DRIVER_NAME "=", i810_options );
-#endif
 
 #include "drm_fops.h"
 #include "drm_init.h"
diff -Nru a/drivers/char/drm/i830.h b/drivers/char/drm/i830.h
--- a/drivers/char/drm/i830.h	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/drm/i830.h	Sat Aug 10 18:42:22 2002
@@ -41,6 +41,33 @@
 #define __HAVE_MTRR		1
 #define __HAVE_CTX_BITMAP	1
 
+#define DRIVER_AUTHOR		"VA Linux Systems Inc."
+
+#define DRIVER_NAME		"i830"
+#define DRIVER_DESC		"Intel 830M"
+#define DRIVER_DATE		"20011004"
+
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		2
+#define DRIVER_PATCHLEVEL	0
+
+#define DRIVER_IOCTLS							    \
+	[DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)]   = { i830_dma_init,    1, 1 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex,  1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)]  = { i830_clear_bufs,  1, 0 }, \
+      	[DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)]  = { i830_flush_ioctl, 1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage,      1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf,      1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)]   = { i830_swap_bufs,   1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)]   = { i830_copybuf,     1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy,      1, 0 },
+
+#define __HAVE_COUNTERS         4
+#define __HAVE_COUNTER6         _DRM_STAT_IRQ
+#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
+#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
+#define __HAVE_COUNTER9         _DRM_STAT_DMA
+
 /* Driver customization:
  */
 #define __HAVE_RELEASE		1
diff -Nru a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
--- a/drivers/char/drm/i830_drv.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/drm/i830_drv.c	Sat Aug 10 18:42:22 2002
@@ -38,34 +38,6 @@
 #include "i830_drm.h"
 #include "i830_drv.h"
 
-#define DRIVER_AUTHOR		"VA Linux Systems Inc."
-
-#define DRIVER_NAME		"i830"
-#define DRIVER_DESC		"Intel 830M"
-#define DRIVER_DATE		"20011004"
-
-#define DRIVER_MAJOR		1
-#define DRIVER_MINOR		2
-#define DRIVER_PATCHLEVEL	0
-
-#define DRIVER_IOCTLS							    \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)]   = { i830_dma_init,    1, 1 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex,  1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)]  = { i830_clear_bufs,  1, 0 }, \
-      	[DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)]  = { i830_flush_ioctl, 1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage,      1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf,      1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)]   = { i830_swap_bufs,   1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)]   = { i830_copybuf,     1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy,      1, 0 },
-
-#define __HAVE_COUNTERS         4
-#define __HAVE_COUNTER6         _DRM_STAT_IRQ
-#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
-#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
-#define __HAVE_COUNTER9         _DRM_STAT_DMA
-
-
 #include "drm_agpsupport.h"
 #include "drm_auth.h"
 #include "drm_bufs.h"
@@ -73,25 +45,6 @@
 #include "drm_dma.h"
 #include "drm_drawable.h"
 #include "drm_drv.h"
-
-#ifndef MODULE
-/* DRM(options) is called by the kernel to parse command-line options
- * passed via the boot-loader (e.g., LILO).  It calls the insmod option
- * routine, drm_parse_drm.
- */
-
-/* JH- We have to hand expand the string ourselves because of the cpp.  If
- * anyone can think of a way that we can fit into the __setup macro without
- * changing it, then please send the solution my way.
- */
-static int __init i830_options( char *str )
-{
-   DRM(parse_options)( str );
-   return 1;
-}
-
-__setup( DRIVER_NAME "=", i830_options );
-#endif
 
 #include "drm_fops.h"
 #include "drm_init.h"
diff -Nru a/drivers/char/drm/mga.h b/drivers/char/drm/mga.h
--- a/drivers/char/drm/mga.h	Sat Aug 10 18:42:20 2002
+++ b/drivers/char/drm/mga.h	Sat Aug 10 18:42:20 2002
@@ -41,6 +41,33 @@
 #define __HAVE_MTRR		1
 #define __HAVE_CTX_BITMAP	1
 
+#define DRIVER_AUTHOR		"Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME		"mga"
+#define DRIVER_DESC		"Matrox G200/G400"
+#define DRIVER_DATE		"20010321"
+
+#define DRIVER_MAJOR		3
+#define DRIVER_MINOR		0
+#define DRIVER_PATCHLEVEL	2
+
+#define DRIVER_IOCTLS							   \
+	[DRM_IOCTL_NR(DRM_IOCTL_DMA)]	      = { mga_dma_buffers, 1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)]    = { mga_dma_init,    1, 1 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)]   = { mga_dma_flush,   1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)]   = { mga_dma_reset,   1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)]    = { mga_dma_swap,    1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)]   = { mga_dma_clear,   1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)]  = { mga_dma_vertex,  1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)]   = { mga_dma_iload,   1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)]    = { mga_dma_blit,    1, 0 },
+
+#define __HAVE_COUNTERS         3
+#define __HAVE_COUNTER6         _DRM_STAT_IRQ
+#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
+#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
+
 /* Driver customization:
  */
 #define DRIVER_PRETAKEDOWN() do {					\
diff -Nru a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
--- a/drivers/char/drm/mga_dma.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/drm/mga_dma.c	Sat Aug 10 18:42:22 2002
@@ -33,16 +33,12 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "mga.h"
 #include "drmP.h"
 #include "drm.h"
 #include "mga_drm.h"
 #include "mga_drv.h"
 
-#include <linux/interrupt.h>	/* For task queue support */
-#include <linux/delay.h>
-
 #define MGA_DEFAULT_USEC_TIMEOUT	10000
 #define MGA_FREELIST_DEBUG		0
 
@@ -55,7 +51,7 @@
 {
 	u32 status = 0;
 	int i;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
 		status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
@@ -63,32 +59,32 @@
 			MGA_WRITE8( MGA_CRTC_INDEX, 0 );
 			return 0;
 		}
-		udelay( 1 );
+		DRM_UDELAY( 1 );
 	}
 
 #if MGA_DMA_DEBUG
 	DRM_ERROR( "failed!\n" );
 	DRM_INFO( "   status=0x%08x\n", status );
 #endif
-	return -EBUSY;
+	return DRM_ERR(EBUSY);
 }
 
 int mga_do_dma_idle( drm_mga_private_t *dev_priv )
 {
 	u32 status = 0;
 	int i;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
 		status = MGA_READ( MGA_STATUS ) & MGA_DMA_IDLE_MASK;
 		if ( status == MGA_ENDPRDMASTS ) return 0;
-		udelay( 1 );
+		DRM_UDELAY( 1 );
 	}
 
 #if MGA_DMA_DEBUG
 	DRM_ERROR( "failed! status=0x%08x\n", status );
 #endif
-	return -EBUSY;
+	return DRM_ERR(EBUSY);
 }
 
 int mga_do_dma_reset( drm_mga_private_t *dev_priv )
@@ -96,7 +92,7 @@
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
 
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	/* The primary DMA stream should look like new right about now.
 	 */
@@ -117,13 +113,13 @@
 
 int mga_do_engine_reset( drm_mga_private_t *dev_priv )
 {
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	/* Okay, so we've completely screwed up and locked the engine.
 	 * How about we clean up after ourselves?
 	 */
 	MGA_WRITE( MGA_RST, MGA_SOFTRESET );
-	udelay( 15 );				/* Wait at least 10 usecs */
+	DRM_UDELAY( 15 );				/* Wait at least 10 usecs */
 	MGA_WRITE( MGA_RST, 0 );
 
 	/* Initialize the registers that get clobbered by the soft
@@ -162,7 +158,7 @@
 	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
 	u32 head, tail;
 	DMA_LOCALS;
-	DRM_DEBUG( "%s:\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	if ( primary->tail == primary->last_flush ) {
 		DRM_DEBUG( "   bailing out...\n" );
@@ -201,7 +197,7 @@
 	mga_flush_write_combine();
 	MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER );
 
-	DRM_DEBUG( "%s: done.\n", __FUNCTION__ );
+	DRM_DEBUG( "done.\n" );
 }
 
 void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv )
@@ -209,7 +205,7 @@
 	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
 	u32 head, tail;
 	DMA_LOCALS;
-	DRM_DEBUG( "%s:\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	BEGIN_DMA_WRAP();
 
@@ -244,7 +240,7 @@
 	MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER );
 
 	set_bit( 0, &primary->wrapped );
-	DRM_DEBUG( "%s: done.\n", __FUNCTION__ );
+	DRM_DEBUG( "done.\n" );
 }
 
 void mga_do_dma_wrap_end( drm_mga_private_t *dev_priv )
@@ -252,7 +248,7 @@
 	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	u32 head = dev_priv->primary->offset;
-	DRM_DEBUG( "%s:\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	sarea_priv->last_wrap++;
 	DRM_DEBUG( "   wrap = %d\n", sarea_priv->last_wrap );
@@ -261,7 +257,7 @@
 	MGA_WRITE( MGA_PRIMADDRESS, head | MGA_DMA_GENERAL );
 
 	clear_bit( 0, &primary->wrapped );
-	DRM_DEBUG( "%s: done.\n", __FUNCTION__ );
+	DRM_DEBUG( "done.\n" );
 }
 
 
@@ -301,13 +297,12 @@
 	drm_mga_buf_priv_t *buf_priv;
 	drm_mga_freelist_t *entry;
 	int i;
-	DRM_DEBUG( "%s: count=%d\n",
-		   __FUNCTION__, dma->buf_count );
+	DRM_DEBUG( "count=%d\n", dma->buf_count );
 
 	dev_priv->head = DRM(alloc)( sizeof(drm_mga_freelist_t),
 				     DRM_MEM_DRIVER );
 	if ( dev_priv->head == NULL )
-		return -ENOMEM;
+		return DRM_ERR(ENOMEM);
 
 	memset( dev_priv->head, 0, sizeof(drm_mga_freelist_t) );
 	SET_AGE( &dev_priv->head->age, MGA_BUFFER_USED, 0 );
@@ -319,7 +314,7 @@
 		entry = DRM(alloc)( sizeof(drm_mga_freelist_t),
 				    DRM_MEM_DRIVER );
 		if ( entry == NULL )
-			return -ENOMEM;
+			return DRM_ERR(ENOMEM);
 
 		memset( entry, 0, sizeof(drm_mga_freelist_t) );
 
@@ -348,7 +343,7 @@
 	drm_mga_private_t *dev_priv = dev->dev_private;
 	drm_mga_freelist_t *entry;
 	drm_mga_freelist_t *next;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	entry = dev_priv->head;
 	while ( entry ) {
@@ -386,7 +381,7 @@
 	drm_mga_freelist_t *prev;
 	drm_mga_freelist_t *tail = dev_priv->tail;
 	u32 head, wrap;
-	DRM_DEBUG( "%s:\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	head = MGA_READ( MGA_PRIMADDRESS );
 	wrap = dev_priv->sarea_priv->last_wrap;
@@ -418,8 +413,7 @@
 	drm_mga_buf_priv_t *buf_priv = buf->dev_private;
 	drm_mga_freelist_t *head, *entry, *prev;
 
-	DRM_DEBUG( "%s: age=0x%06lx wrap=%d\n",
-		   __FUNCTION__,
+	DRM_DEBUG( "age=0x%06lx wrap=%d\n",
 		   buf_priv->list_entry->age.head -
 		   dev_priv->primary->offset,
 		   buf_priv->list_entry->age.wrap );
@@ -452,13 +446,12 @@
 static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
 {
 	drm_mga_private_t *dev_priv;
-	struct list_head *list;
 	int ret;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	dev_priv = DRM(alloc)( sizeof(drm_mga_private_t), DRM_MEM_DRIVER );
 	if ( !dev_priv )
-		return -ENOMEM;
+		return DRM_ERR(ENOMEM);
 
 	memset( dev_priv, 0, sizeof(drm_mga_private_t) );
 
@@ -488,21 +481,14 @@
 	dev_priv->texture_offset = init->texture_offset[0];
 	dev_priv->texture_size = init->texture_size[0];
 
-	list_for_each( list, &dev->maplist->head ) {
-		drm_map_list_t *entry = (drm_map_list_t *)list;
-		if ( entry->map &&
-		     entry->map->type == _DRM_SHM &&
-		     (entry->map->flags & _DRM_CONTAINS_LOCK) ) {
-			dev_priv->sarea = entry->map;
- 			break;
- 		}
- 	}
+	DRM_GETSAREA();
+
 	if(!dev_priv->sarea) {
 		DRM_ERROR( "failed to find sarea!\n" );
 		/* Assign dev_private so we can do cleanup. */
 		dev->dev_private = (void *)dev_priv;
 		mga_do_cleanup_dma( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
@@ -511,7 +497,7 @@
 		/* Assign dev_private so we can do cleanup. */
 		dev->dev_private = (void *)dev_priv;
 		mga_do_cleanup_dma( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
 	if(!dev_priv->mmio) {
@@ -519,7 +505,7 @@
 		/* Assign dev_private so we can do cleanup. */
 		dev->dev_private = (void *)dev_priv;
 		mga_do_cleanup_dma( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	DRM_FIND_MAP( dev_priv->status, init->status_offset );
 	if(!dev_priv->status) {
@@ -527,7 +513,7 @@
 		/* Assign dev_private so we can do cleanup. */
 		dev->dev_private = (void *)dev_priv;
 		mga_do_cleanup_dma( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	DRM_FIND_MAP( dev_priv->warp, init->warp_offset );
@@ -536,7 +522,7 @@
 		/* Assign dev_private so we can do cleanup. */
 		dev->dev_private = (void *)dev_priv;
 		mga_do_cleanup_dma( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	DRM_FIND_MAP( dev_priv->primary, init->primary_offset );
 	if(!dev_priv->primary) {
@@ -544,7 +530,7 @@
 		/* Assign dev_private so we can do cleanup. */
 		dev->dev_private = (void *)dev_priv;
 		mga_do_cleanup_dma( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );
 	if(!dev_priv->buffers) {
@@ -552,7 +538,7 @@
 		/* Assign dev_private so we can do cleanup. */
 		dev->dev_private = (void *)dev_priv;
 		mga_do_cleanup_dma( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	dev_priv->sarea_priv =
@@ -570,7 +556,7 @@
 		/* Assign dev_private so we can do cleanup. */
 		dev->dev_private = (void *)dev_priv;
 		mga_do_cleanup_dma( dev );
-		return -ENOMEM;
+		return DRM_ERR(ENOMEM);
 	}
 
 	ret = mga_warp_install_microcode( dev_priv );
@@ -620,8 +606,6 @@
 
 	dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE;
 
-	spin_lock_init( &dev_priv->prim.list_lock );
-
 	dev_priv->prim.status[0] = dev_priv->primary->offset;
 	dev_priv->prim.status[1] = 0;
 
@@ -634,7 +618,7 @@
 		/* Assign dev_private so we can do cleanup. */
 		dev->dev_private = (void *)dev_priv;
 		mga_do_cleanup_dma( dev );
-		return -ENOMEM;
+		return DRM_ERR(ENOMEM);
 	}
 
 	/* Make dev_private visable to others. */
@@ -644,7 +628,7 @@
 
 int mga_do_cleanup_dma( drm_device_t *dev )
 {
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	if ( dev->dev_private ) {
 		drm_mga_private_t *dev_priv = dev->dev_private;
@@ -665,15 +649,12 @@
 	return 0;
 }
 
-int mga_dma_init( struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg )
+int mga_dma_init( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_mga_init_t init;
 
-	if ( copy_from_user( &init, (drm_mga_init_t *)arg, sizeof(init) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( init, (drm_mga_init_t *)data, sizeof(init) );
 
 	switch ( init.func ) {
 	case MGA_INIT_DMA:
@@ -682,7 +663,7 @@
 		return mga_do_cleanup_dma( dev );
 	}
 
-	return -EINVAL;
+	return DRM_ERR(EINVAL);
 }
 
 
@@ -690,21 +671,17 @@
  * Primary DMA stream management
  */
 
-int mga_dma_flush( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
+int mga_dma_flush( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
 	drm_lock_t lock;
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &lock, (drm_lock_t *)arg, sizeof(lock) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( lock, (drm_lock_t *)data, sizeof(lock) );
 
-	DRM_DEBUG( "%s: %s%s%s\n",
-		   __FUNCTION__,
+	DRM_DEBUG( "%s%s%s\n",
 		   (lock.flags & _DRM_LOCK_FLUSH) ?	"flush, " : "",
 		   (lock.flags & _DRM_LOCK_FLUSH_ALL) ?	"flush all, " : "",
 		   (lock.flags & _DRM_LOCK_QUIESCENT) ?	"idle, " : "" );
@@ -719,7 +696,7 @@
 #if MGA_DMA_DEBUG
 		int ret = mga_do_wait_for_idle( dev_priv );
 		if ( ret < 0 )
-			DRM_INFO( __FUNCTION__": -EBUSY\n" );
+			DRM_INFO( "%s: -EBUSY\n", __func__ );
 		return ret;
 #else
 		return mga_do_wait_for_idle( dev_priv );
@@ -729,11 +706,9 @@
 	}
 }
 
-int mga_dma_reset( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
+int mga_dma_reset( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
 
 	LOCK_TEST_WITH_RETURN( dev );
@@ -753,27 +728,25 @@
 
 	for ( i = d->granted_count ; i < d->request_count ; i++ ) {
 		buf = mga_freelist_get( dev );
-		if ( !buf ) return -EAGAIN;
+		if ( !buf ) return DRM_ERR(EAGAIN);
 
-		buf->pid = current->pid;
+		buf->pid = DRM_CURRENTPID;
 
-		if ( copy_to_user( &d->request_indices[i],
+		if ( DRM_COPY_TO_USER( &d->request_indices[i],
 				   &buf->idx, sizeof(buf->idx) ) )
-			return -EFAULT;
-		if ( copy_to_user( &d->request_sizes[i],
+			return DRM_ERR(EFAULT);
+		if ( DRM_COPY_TO_USER( &d->request_sizes[i],
 				   &buf->total, sizeof(buf->total) ) )
-			return -EFAULT;
+			return DRM_ERR(EFAULT);
 
 		d->granted_count++;
 	}
 	return 0;
 }
 
-int mga_dma_buffers( struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg )
+int mga_dma_buffers( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_device_dma_t *dma = dev->dma;
 	drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
 	drm_dma_t d;
@@ -781,23 +754,22 @@
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) );
 
 	/* Please don't send us buffers.
 	 */
 	if ( d.send_count != 0 ) {
 		DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
-			   current->pid, d.send_count );
-		return -EINVAL;
+			   DRM_CURRENTPID, d.send_count );
+		return DRM_ERR(EINVAL);
 	}
 
 	/* We'll send you buffers.
 	 */
 	if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
 		DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
-			   current->pid, d.request_count, dma->buf_count );
-		return -EINVAL;
+			   DRM_CURRENTPID, d.request_count, dma->buf_count );
+		return DRM_ERR(EINVAL);
 	}
 
 	WRAP_TEST_WITH_RETURN( dev_priv );
@@ -808,8 +780,7 @@
 		ret = mga_dma_get_buffers( dev, &d );
 	}
 
-	if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) )
-		return -EFAULT;
+	DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) );
 
 	return ret;
 }
diff -Nru a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
--- a/drivers/char/drm/mga_drv.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/drm/mga_drv.c	Sat Aug 10 18:42:22 2002
@@ -35,36 +35,6 @@
 #include "drm.h"
 #include "mga_drm.h"
 #include "mga_drv.h"
-
-#define DRIVER_AUTHOR		"Gareth Hughes, VA Linux Systems Inc."
-
-#define DRIVER_NAME		"mga"
-#define DRIVER_DESC		"Matrox G200/G400"
-#define DRIVER_DATE		"20010321"
-
-#define DRIVER_MAJOR		3
-#define DRIVER_MINOR		0
-#define DRIVER_PATCHLEVEL	2
-
-#define DRIVER_IOCTLS							   \
-	[DRM_IOCTL_NR(DRM_IOCTL_DMA)]	      = { mga_dma_buffers, 1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)]    = { mga_dma_init,    1, 1 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_FLUSH)]   = { mga_dma_flush,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_RESET)]   = { mga_dma_reset,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)]    = { mga_dma_swap,    1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)]   = { mga_dma_clear,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)]  = { mga_dma_vertex,  1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_INDICES)] = { mga_dma_indices, 1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)]   = { mga_dma_iload,   1, 0 }, \
-	[DRM_IOCTL_NR(DRM_IOCTL_MGA_BLIT)]    = { mga_dma_blit,    1, 0 },
-
-
-#define __HAVE_COUNTERS         3
-#define __HAVE_COUNTER6         _DRM_STAT_IRQ
-#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
-#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
-
-
 #include "drm_agpsupport.h"
 #include "drm_auth.h"
 #include "drm_bufs.h"
@@ -72,27 +42,6 @@
 #include "drm_dma.h"
 #include "drm_drawable.h"
 #include "drm_drv.h"
-
-#ifndef MODULE
-/* DRM(options) is called by the kernel to parse command-line options
- * passed via the boot-loader (e.g., LILO).  It calls the insmod option
- * routine, drm_parse_drm.
- */
-
-/* JH- We have to hand expand the string ourselves because of the cpp.  If
- * anyone can think of a way that we can fit into the __setup macro without
- * changing it, then please send the solution my way.
- */
-static int __init mga_options( char *str )
-{
-	DRM(parse_options)( str );
-	return 1;
-}
-
-__setup( DRIVER_NAME "=", mga_options );
-#endif
-
-
 #include "drm_fops.h"
 #include "drm_init.h"
 #include "drm_ioctl.h"
diff -Nru a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
--- a/drivers/char/drm/mga_drv.h	Sat Aug 10 18:42:23 2002
+++ b/drivers/char/drm/mga_drv.h	Sat Aug 10 18:42:23 2002
@@ -38,7 +38,7 @@
 
 	u32 tail;
 	int space;
-	volatile long wrapped;
+	int wrapped;
 
 	volatile u32 *status;
 
@@ -46,8 +46,6 @@
 	u32 last_wrap;
 
 	u32 high_mark;
-
-	spinlock_t list_lock;
 } drm_mga_primary_buffer_t;
 
 typedef struct drm_mga_freelist {
@@ -103,14 +101,10 @@
 } drm_mga_private_t;
 
 				/* mga_dma.c */
-extern int mga_dma_init( struct inode *inode, struct file *filp,
-			 unsigned int cmd, unsigned long arg );
-extern int mga_dma_flush( struct inode *inode, struct file *filp,
-			  unsigned int cmd, unsigned long arg );
-extern int mga_dma_reset( struct inode *inode, struct file *filp,
-			  unsigned int cmd, unsigned long arg );
-extern int mga_dma_buffers( struct inode *inode, struct file *filp,
-			    unsigned int cmd, unsigned long arg );
+extern int mga_dma_init( DRM_IOCTL_ARGS );
+extern int mga_dma_flush( DRM_IOCTL_ARGS );
+extern int mga_dma_reset( DRM_IOCTL_ARGS );
+extern int mga_dma_buffers( DRM_IOCTL_ARGS );
 
 extern int mga_do_wait_for_idle( drm_mga_private_t *dev_priv );
 extern int mga_do_dma_idle( drm_mga_private_t *dev_priv );
@@ -125,24 +119,18 @@
 extern int mga_freelist_put( drm_device_t *dev, drm_buf_t *buf );
 
 				/* mga_state.c */
-extern int  mga_dma_clear( struct inode *inode, struct file *filp,
-			   unsigned int cmd, unsigned long arg );
-extern int  mga_dma_swap( struct inode *inode, struct file *filp,
-			  unsigned int cmd, unsigned long arg );
-extern int  mga_dma_vertex( struct inode *inode, struct file *filp,
-			    unsigned int cmd, unsigned long arg );
-extern int  mga_dma_indices( struct inode *inode, struct file *filp,
-			     unsigned int cmd, unsigned long arg );
-extern int  mga_dma_iload( struct inode *inode, struct file *filp,
-			   unsigned int cmd, unsigned long arg );
-extern int  mga_dma_blit( struct inode *inode, struct file *filp,
-			  unsigned int cmd, unsigned long arg );
+extern int  mga_dma_clear( DRM_IOCTL_ARGS );
+extern int  mga_dma_swap( DRM_IOCTL_ARGS );
+extern int  mga_dma_vertex( DRM_IOCTL_ARGS );
+extern int  mga_dma_indices( DRM_IOCTL_ARGS );
+extern int  mga_dma_iload( DRM_IOCTL_ARGS );
+extern int  mga_dma_blit( DRM_IOCTL_ARGS );
 
 				/* mga_warp.c */
 extern int mga_warp_install_microcode( drm_mga_private_t *dev_priv );
 extern int mga_warp_init( drm_mga_private_t *dev_priv );
 
-#define mga_flush_write_combine()	mb()
+#define mga_flush_write_combine()	DRM_WRITEMEMORYBARRIER()
 
 
 #define MGA_BASE( reg )		((unsigned long)(dev_priv->mmio->handle))
@@ -153,12 +141,12 @@
 
 #ifdef __alpha__
 #define MGA_READ( reg )		(_MGA_READ((u32 *)MGA_ADDR(reg)))
-#define MGA_WRITE( reg, val )	do { wmb(); MGA_DEREF( reg ) = val; } while (0)
-#define MGA_WRITE8( reg, val )  do { wmb(); MGA_DEREF8( reg ) = val; } while (0)
+#define MGA_WRITE( reg, val )	do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0)
+#define MGA_WRITE8( reg, val )  do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
 
 static inline u32 _MGA_READ(u32 *addr)
 {
-	mb();
+	DRM_READMEMORYBARRIER();
 	return *(volatile u32 *)addr;
 }
 
@@ -198,10 +186,10 @@
 #define LOCK_TEST_WITH_RETURN( dev )					\
 do {									\
 	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||		\
-	     dev->lock.pid != current->pid ) {				\
+	     dev->lock.pid != DRM_CURRENTPID ) {				\
 		DRM_ERROR( "%s called without lock held\n",		\
-			   __FUNCTION__ );				\
-		return -EINVAL;						\
+			   __func__ );					\
+		return DRM_ERR(EINVAL);				\
 	}								\
 } while (0)
 
@@ -213,8 +201,8 @@
 		} else if ( dev_priv->prim.space <			\
 			    dev_priv->prim.high_mark ) {		\
 			if ( MGA_DMA_DEBUG )				\
-				DRM_INFO( __FUNCTION__": wrap...\n" );	\
-			return -EBUSY;					\
+				DRM_INFO( "%s: wrap...\n", __func__ );	\
+			return DRM_ERR(EBUSY);			\
 		}							\
 	}								\
 } while (0)
@@ -224,8 +212,8 @@
 	if ( test_bit( 0, &dev_priv->prim.wrapped ) ) {			\
 		if ( mga_do_wait_for_idle( dev_priv ) < 0 ) {		\
 			if ( MGA_DMA_DEBUG )				\
-				DRM_INFO( __FUNCTION__": wrap...\n" );	\
-			return -EBUSY;					\
+				DRM_INFO( "%s: wrap...\n", __func__ );	\
+			return DRM_ERR(EBUSY);			\
 		}							\
 		mga_do_dma_wrap_end( dev_priv );			\
 	}								\
@@ -246,7 +234,7 @@
 do {									\
 	if ( MGA_VERBOSE ) {						\
 		DRM_INFO( "BEGIN_DMA( %d ) in %s\n",			\
-			  (n), __FUNCTION__ );				\
+			  (n), __func__ );				\
 		DRM_INFO( "   space=0x%x req=0x%x\n",			\
 			  dev_priv->prim.space, (n) * DMA_BLOCK_SIZE );	\
 	}								\
@@ -257,7 +245,7 @@
 #define BEGIN_DMA_WRAP()						\
 do {									\
 	if ( MGA_VERBOSE ) {						\
-		DRM_INFO( "BEGIN_DMA() in %s\n", __FUNCTION__ );	\
+		DRM_INFO( "BEGIN_DMA() in %s\n", __func__ );		\
 		DRM_INFO( "   space=0x%x\n", dev_priv->prim.space );	\
 	}								\
 	prim = dev_priv->prim.start;					\
@@ -276,7 +264,7 @@
 #define FLUSH_DMA()							\
 do {									\
 	if ( 0 ) {							\
-		DRM_INFO( __FUNCTION__ ":\n" );				\
+		DRM_INFO( "%s:\n", __func__ );				\
 		DRM_INFO( "   tail=0x%06x head=0x%06lx\n",		\
 			  dev_priv->prim.tail,				\
 			  MGA_READ( MGA_PRIMADDRESS ) -			\
@@ -634,7 +622,7 @@
 
 /* Simple idle test.
  */
-static inline int mga_is_idle( drm_mga_private_t *dev_priv )
+static __inline__ int mga_is_idle( drm_mga_private_t *dev_priv )
 {
 	u32 status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
 	return ( status == MGA_ENDPRDMASTS );
diff -Nru a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c
--- a/drivers/char/drm/mga_state.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/drm/mga_state.c	Sat Aug 10 18:42:22 2002
@@ -32,7 +32,6 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "mga.h"
 #include "drmP.h"
 #include "drm.h"
@@ -71,7 +70,7 @@
 	ADVANCE_DMA();
 }
 
-static inline void mga_g200_emit_context( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g200_emit_context( drm_mga_private_t *dev_priv )
 {
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
@@ -97,7 +96,7 @@
 	ADVANCE_DMA();
 }
 
-static inline void mga_g400_emit_context( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g400_emit_context( drm_mga_private_t *dev_priv )
 {
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
@@ -128,7 +127,7 @@
 	ADVANCE_DMA();
 }
 
-static inline void mga_g200_emit_tex0( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g200_emit_tex0( drm_mga_private_t *dev_priv )
 {
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
@@ -159,7 +158,7 @@
 	ADVANCE_DMA();
 }
 
-static inline void mga_g400_emit_tex0( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g400_emit_tex0( drm_mga_private_t *dev_priv )
 {
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
@@ -203,7 +202,7 @@
 	ADVANCE_DMA();
 }
 
-static inline void mga_g400_emit_tex1( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g400_emit_tex1( drm_mga_private_t *dev_priv )
 {
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1];
@@ -244,7 +243,7 @@
 	ADVANCE_DMA();
 }
 
-static inline void mga_g200_emit_pipe( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g200_emit_pipe( drm_mga_private_t *dev_priv )
 {
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	unsigned int pipe = sarea_priv->warp_pipe;
@@ -274,7 +273,7 @@
 	ADVANCE_DMA();
 }
 
-static inline void mga_g400_emit_pipe( drm_mga_private_t *dev_priv )
+static __inline__ void mga_g400_emit_pipe( drm_mga_private_t *dev_priv )
 {
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	unsigned int pipe = sarea_priv->warp_pipe;
@@ -422,7 +421,7 @@
 			   ctx->dstorg, dev_priv->front_offset,
 			   dev_priv->back_offset );
 		ctx->dstorg = 0;
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	return 0;
@@ -442,7 +441,7 @@
 		DRM_ERROR( "*** bad TEXORG: 0x%x, unit %d\n",
 			   tex->texorg, unit );
 		tex->texorg = 0;
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	return 0;
@@ -484,13 +483,13 @@
 	     dstorg + length > (dev_priv->texture_offset +
 				dev_priv->texture_size) ) {
 		DRM_ERROR( "*** bad iload DSTORG: 0x%x\n", dstorg );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	if ( length & MGA_ILOAD_MASK ) {
 		DRM_ERROR( "*** bad iload length: 0x%x\n",
 			   length & MGA_ILOAD_MASK );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	return 0;
@@ -503,7 +502,7 @@
 	     (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ) {
 		DRM_ERROR( "*** bad blit: src=0x%x dst=0x%x\n",
 			   srcorg, dstorg );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	return 0;
 }
@@ -523,7 +522,7 @@
 	int nbox = sarea_priv->nbox;
 	int i;
 	DMA_LOCALS;
-	DRM_DEBUG( __FUNCTION__ ":\n" );
+	DRM_DEBUG( "\n" );
 
 	BEGIN_DMA( 1 );
 
@@ -617,7 +616,7 @@
 	int nbox = sarea_priv->nbox;
 	int i;
 	DMA_LOCALS;
-	DRM_DEBUG( __FUNCTION__ ":\n" );
+	DRM_DEBUG( "\n" );
 
 	sarea_priv->last_frame.head = dev_priv->prim.tail;
 	sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap;
@@ -663,7 +662,7 @@
 
 	FLUSH_DMA();
 
-	DRM_DEBUG( "%s... done.\n", __FUNCTION__ );
+	DRM_DEBUG( "%s... done.\n", __func__ );
 }
 
 static void mga_dma_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf )
@@ -771,8 +770,7 @@
 	u32 srcorg = buf->bus_address | MGA_SRCACC_AGP | MGA_SRCMAP_SYSMEM;
 	u32 y2;
 	DMA_LOCALS;
-	DRM_DEBUG( "%s: buf=%d used=%d\n",
-		   __FUNCTION__, buf->idx, buf->used );
+	DRM_DEBUG( "buf=%d used=%d\n", buf->idx, buf->used );
 
 	y2 = length / 64;
 
@@ -826,7 +824,7 @@
 	int nbox = sarea_priv->nbox;
 	u32 scandir = 0, i;
 	DMA_LOCALS;
-	DRM_DEBUG( __FUNCTION__ ":\n" );
+	DRM_DEBUG( "\n" );
 
 	BEGIN_DMA( 4 + nbox );
 
@@ -883,19 +881,16 @@
  *
  */
 
-int mga_dma_clear( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
+int mga_dma_clear( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_mga_private_t *dev_priv = dev->dev_private;
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_mga_clear_t clear;
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &clear, (drm_mga_clear_t *) arg, sizeof(clear) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( clear, (drm_mga_clear_t *)data, sizeof(clear) );
 
 	if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
 		sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
@@ -911,11 +906,9 @@
 	return 0;
 }
 
-int mga_dma_swap( struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg )
+int mga_dma_swap( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_mga_private_t *dev_priv = dev->dev_private;
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 
@@ -935,11 +928,9 @@
 	return 0;
 }
 
-int mga_dma_vertex( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
+int mga_dma_vertex( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_mga_private_t *dev_priv = dev->dev_private;
 	drm_device_dma_t *dma = dev->dma;
 	drm_buf_t *buf;
@@ -948,12 +939,11 @@
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &vertex,
-			     (drm_mga_vertex_t *)arg,
-			     sizeof(vertex) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( vertex,
+			     (drm_mga_vertex_t *)data,
+			     sizeof(vertex) );
 
-        if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;
+        if(vertex.idx < 0 || vertex.idx > dma->buf_count) return DRM_ERR(EINVAL);
 	buf = dma->buflist[vertex.idx];
 	buf_priv = buf->dev_private;
 
@@ -967,7 +957,7 @@
 			buf_priv->dispatched = 0;
 			mga_freelist_put( dev, buf );
 		}
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	WRAP_TEST_WITH_RETURN( dev_priv );
@@ -977,11 +967,9 @@
 	return 0;
 }
 
-int mga_dma_indices( struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg )
+int mga_dma_indices( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_mga_private_t *dev_priv = dev->dev_private;
 	drm_device_dma_t *dma = dev->dma;
 	drm_buf_t *buf;
@@ -990,12 +978,11 @@
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &indices,
-			     (drm_mga_indices_t *)arg,
-			     sizeof(indices) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( indices,
+			     (drm_mga_indices_t *)data,
+			     sizeof(indices) );
 
-        if(indices.idx < 0 || indices.idx > dma->buf_count) return -EINVAL;
+        if(indices.idx < 0 || indices.idx > dma->buf_count) return DRM_ERR(EINVAL);
 
 	buf = dma->buflist[indices.idx];
 	buf_priv = buf->dev_private;
@@ -1009,7 +996,7 @@
 			buf_priv->dispatched = 0;
 			mga_freelist_put( dev, buf );
 		}
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	WRAP_TEST_WITH_RETURN( dev_priv );
@@ -1019,38 +1006,35 @@
 	return 0;
 }
 
-int mga_dma_iload( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
+int mga_dma_iload( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_device_dma_t *dma = dev->dma;
 	drm_mga_private_t *dev_priv = dev->dev_private;
 	drm_buf_t *buf;
 	drm_mga_buf_priv_t *buf_priv;
 	drm_mga_iload_t iload;
-	DRM_DEBUG( __FUNCTION__ ":\n" );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &iload, (drm_mga_iload_t *)arg, sizeof(iload) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( iload, (drm_mga_iload_t *)data, sizeof(iload) );
 
 #if 0
 	if ( mga_do_wait_for_idle( dev_priv ) < 0 ) {
 		if ( MGA_DMA_DEBUG )
-			DRM_INFO( __FUNCTION__": -EBUSY\n" );
-		return -EBUSY;
+			DRM_INFO( "%s: -EBUSY\n", __func__ );
+		return DRM_ERR(EBUSY);
 	}
 #endif
-        if(iload.idx < 0 || iload.idx > dma->buf_count) return -EINVAL;
+        if(iload.idx < 0 || iload.idx > dma->buf_count) return DRM_ERR(EINVAL);
 
 	buf = dma->buflist[iload.idx];
 	buf_priv = buf->dev_private;
 
 	if ( mga_verify_iload( dev_priv, iload.dstorg, iload.length ) ) {
 		mga_freelist_put( dev, buf );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	WRAP_TEST_WITH_RETURN( dev_priv );
@@ -1064,26 +1048,23 @@
 	return 0;
 }
 
-int mga_dma_blit( struct inode *inode, struct file *filp,
-		  unsigned int cmd, unsigned long arg )
+int mga_dma_blit( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_mga_private_t *dev_priv = dev->dev_private;
 	drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_mga_blit_t blit;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &blit, (drm_mga_blit_t *)arg, sizeof(blit) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( blit, (drm_mga_blit_t *)data, sizeof(blit) );
 
 	if ( sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS )
 		sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
 
 	if ( mga_verify_blit( dev_priv, blit.srcorg, blit.dstorg ) )
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 
 	WRAP_TEST_WITH_RETURN( dev_priv );
 
diff -Nru a/drivers/char/drm/mga_warp.c b/drivers/char/drm/mga_warp.c
--- a/drivers/char/drm/mga_warp.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/drm/mga_warp.c	Sat Aug 10 18:42:22 2002
@@ -107,7 +107,7 @@
 	if ( size > dev_priv->warp->size ) {
 		DRM_ERROR( "microcode too large! (%u > %lu)\n",
 			   size, dev_priv->warp->size );
-		return -ENOMEM;
+		return DRM_ERR(ENOMEM);
 	}
 
 	memset( dev_priv->warp_pipe_phys, 0,
@@ -144,7 +144,7 @@
 	if ( size > dev_priv->warp->size ) {
 		DRM_ERROR( "microcode too large! (%u > %lu)\n",
 			   size, dev_priv->warp->size );
-		return -ENOMEM;
+		return DRM_ERR(ENOMEM);
 	}
 
 	memset( dev_priv->warp_pipe_phys, 0,
@@ -170,7 +170,7 @@
 	case MGA_CARD_TYPE_G200:
 		return mga_warp_install_g200_microcode( dev_priv );
 	default:
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 }
 
@@ -195,7 +195,7 @@
 		MGA_WRITE( MGA_WVRTXSZ, 7 );
 		break;
 	default:
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	MGA_WRITE( MGA_WMISC, (MGA_WUCODECACHE_ENABLE |
@@ -205,7 +205,7 @@
 	if ( wmisc != WMISC_EXPECTED ) {
 		DRM_ERROR( "WARP engine config failed! 0x%x != 0x%x\n",
 			   wmisc, WMISC_EXPECTED );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	return 0;
diff -Nru a/drivers/char/drm/r128.h b/drivers/char/drm/r128.h
--- a/drivers/char/drm/r128.h	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/drm/r128.h	Sat Aug 10 18:42:22 2002
@@ -43,6 +43,35 @@
 #define __HAVE_SG		1
 #define __HAVE_PCI_DMA		1
 
+#define DRIVER_AUTHOR		"Gareth Hughes, VA Linux Systems Inc."
+
+#define DRIVER_NAME		"r128"
+#define DRIVER_DESC		"ATI Rage 128"
+#define DRIVER_DATE		"20010917"
+
+#define DRIVER_MAJOR		2
+#define DRIVER_MINOR		2
+#define DRIVER_PATCHLEVEL	0
+
+
+#define DRIVER_IOCTLS							    \
+   [DRM_IOCTL_NR(DRM_IOCTL_DMA)]             = { r128_cce_buffers,  1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)]       = { r128_cce_init,     1, 1 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)]  = { r128_cce_start,    1, 1 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)]   = { r128_cce_stop,     1, 1 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)]  = { r128_cce_reset,    1, 1 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)]   = { r128_cce_idle,     1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)]      = { r128_engine_reset, 1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen,   1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)]       = { r128_cce_swap,     1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)]      = { r128_cce_clear,    1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)]     = { r128_cce_vertex,   1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)]    = { r128_cce_indices,  1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)]       = { r128_cce_blit,     1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)]      = { r128_cce_depth,    1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)]    = { r128_cce_stipple,  1, 0 }, \
+   [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)]   = { r128_cce_indirect, 1, 1 },
+
 /* Driver customization:
  */
 #define DRIVER_PRERELEASE() do {					\
diff -Nru a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
--- a/drivers/char/drm/r128_cce.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/char/drm/r128_cce.c	Sat Aug 10 18:42:21 2002
@@ -28,19 +28,14 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "r128.h"
 #include "drmP.h"
 #include "drm.h"
 #include "r128_drm.h"
 #include "r128_drv.h"
 
-#include <linux/interrupt.h>	/* For task queue support */
-#include <linux/delay.h>
-
 #define R128_FIFO_DEBUG		0
 
-
 /* CCE microcode (from ATI) */
 static u32 r128_cce_microcode[] = {
 	0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0,
@@ -86,6 +81,7 @@
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
+int r128_do_wait_for_idle( drm_r128_private_t *dev_priv );
 
 int R128_READ_PLL(drm_device_t *dev, int addr)
 {
@@ -130,13 +126,13 @@
 		if ( !(R128_READ( R128_PC_NGUI_CTLSTAT ) & R128_PC_BUSY) ) {
 			return 0;
 		}
-		udelay( 1 );
+		DRM_UDELAY( 1 );
 	}
 
 #if R128_FIFO_DEBUG
-	DRM_ERROR( "%s failed!\n", __FUNCTION__ );
+	DRM_ERROR( "failed!\n" );
 #endif
-	return -EBUSY;
+	return DRM_ERR(EBUSY);
 }
 
 static int r128_do_wait_for_fifo( drm_r128_private_t *dev_priv, int entries )
@@ -146,13 +142,13 @@
 	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
 		int slots = R128_READ( R128_GUI_STAT ) & R128_GUI_FIFOCNT_MASK;
 		if ( slots >= entries ) return 0;
-		udelay( 1 );
+		DRM_UDELAY( 1 );
 	}
 
 #if R128_FIFO_DEBUG
-	DRM_ERROR( "%s failed!\n", __FUNCTION__ );
+	DRM_ERROR( "failed!\n" );
 #endif
-	return -EBUSY;
+	return DRM_ERR(EBUSY);
 }
 
 int r128_do_wait_for_idle( drm_r128_private_t *dev_priv )
@@ -160,20 +156,20 @@
 	int i, ret;
 
 	ret = r128_do_wait_for_fifo( dev_priv, 64 );
-	if ( ret < 0 ) return ret;
+	if ( ret ) return ret;
 
 	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
 		if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) {
 			r128_do_pixcache_flush( dev_priv );
 			return 0;
 		}
-		udelay( 1 );
+		DRM_UDELAY( 1 );
 	}
 
 #if R128_FIFO_DEBUG
-	DRM_ERROR( "%s failed!\n", __FUNCTION__ );
+	DRM_ERROR( "failed!\n" );
 #endif
-	return -EBUSY;
+	return DRM_ERR(EBUSY);
 }
 
 
@@ -186,7 +182,7 @@
 {
 	int i;
 
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	r128_do_wait_for_idle( dev_priv );
 
@@ -227,14 +223,14 @@
 				return r128_do_pixcache_flush( dev_priv );
 			}
 		}
-		udelay( 1 );
+		DRM_UDELAY( 1 );
 	}
 
 #if R128_FIFO_DEBUG
 	DRM_ERROR( "failed!\n" );
 	r128_status( dev_priv );
 #endif
-	return -EBUSY;
+	return DRM_ERR(EBUSY);
 }
 
 /* Start the Concurrent Command Engine.
@@ -322,7 +318,7 @@
 	u32 ring_start;
 	u32 tmp;
 
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	/* The manual (p. 2) says this address is in "VM space".  This
 	 * means it's an offset from the start of AGP space.
@@ -377,13 +373,12 @@
 static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
 {
 	drm_r128_private_t *dev_priv;
-	struct list_head *list;
 
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	dev_priv = DRM(alloc)( sizeof(drm_r128_private_t), DRM_MEM_DRIVER );
 	if ( dev_priv == NULL )
-		return -ENOMEM;
+		return DRM_ERR(ENOMEM);
 
 	memset( dev_priv, 0, sizeof(drm_r128_private_t) );
 
@@ -393,7 +388,7 @@
 		DRM_ERROR( "PCI GART memory not allocated!\n" );
 		dev->dev_private = (void *)dev_priv;
 		r128_do_cleanup_cce( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	dev_priv->usec_timeout = init->usec_timeout;
@@ -402,7 +397,7 @@
 		DRM_DEBUG( "TIMEOUT problem!\n" );
 		dev->dev_private = (void *)dev_priv;
 		r128_do_cleanup_cce( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	dev_priv->cce_mode = init->cce_mode;
@@ -422,7 +417,7 @@
 		DRM_DEBUG( "Bad cce_mode!\n" );
 		dev->dev_private = (void *)dev_priv;
 		r128_do_cleanup_cce( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	switch ( init->cce_mode ) {
@@ -484,20 +479,13 @@
 	dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) |
 					 (dev_priv->span_offset >> 5));
 
-	list_for_each(list, &dev->maplist->head) {
-		drm_map_list_t *r_list = (drm_map_list_t *)list;
-		if( r_list->map &&
-		    r_list->map->type == _DRM_SHM &&
-		    r_list->map->flags & _DRM_CONTAINS_LOCK ) {
-			dev_priv->sarea = r_list->map;
- 			break;
- 		}
- 	}
+	DRM_GETSAREA();
+	
 	if(!dev_priv->sarea) {
 		DRM_ERROR("could not find sarea!\n");
 		dev->dev_private = (void *)dev_priv;
 		r128_do_cleanup_cce( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
@@ -505,35 +493,35 @@
 		DRM_ERROR("could not find framebuffer!\n");
 		dev->dev_private = (void *)dev_priv;
 		r128_do_cleanup_cce( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
 	if(!dev_priv->mmio) {
 		DRM_ERROR("could not find mmio region!\n");
 		dev->dev_private = (void *)dev_priv;
 		r128_do_cleanup_cce( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	DRM_FIND_MAP( dev_priv->cce_ring, init->ring_offset );
 	if(!dev_priv->cce_ring) {
 		DRM_ERROR("could not find cce ring region!\n");
 		dev->dev_private = (void *)dev_priv;
 		r128_do_cleanup_cce( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );
 	if(!dev_priv->ring_rptr) {
 		DRM_ERROR("could not find ring read pointer!\n");
 		dev->dev_private = (void *)dev_priv;
 		r128_do_cleanup_cce( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );
 	if(!dev_priv->buffers) {
 		DRM_ERROR("could not find dma buffer region!\n");
 		dev->dev_private = (void *)dev_priv;
 		r128_do_cleanup_cce( dev );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	if ( !dev_priv->is_pci ) {
@@ -543,7 +531,7 @@
 			DRM_ERROR("could not find agp texture region!\n");
 			dev->dev_private = (void *)dev_priv;
 			r128_do_cleanup_cce( dev );
-			return -EINVAL;
+			return DRM_ERR(EINVAL);
 		}
 	}
 
@@ -561,7 +549,7 @@
 			DRM_ERROR("Could not ioremap agp regions!\n");
 			dev->dev_private = (void *)dev_priv;
 			r128_do_cleanup_cce( dev );
-			return -ENOMEM;
+			return DRM_ERR(ENOMEM);
 		}
 	} else {
 		dev_priv->cce_ring->handle =
@@ -599,16 +587,18 @@
 	R128_WRITE( R128_LAST_DISPATCH_REG,
 		    dev_priv->sarea_priv->last_dispatch );
 
+#if __REALLY_HAVE_SG
 	if ( dev_priv->is_pci ) {
 		if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
      					    &dev_priv->bus_pci_gart) ) {
 			DRM_ERROR( "failed to init PCI GART!\n" );
 			dev->dev_private = (void *)dev_priv;
 			r128_do_cleanup_cce( dev );
-			return -ENOMEM;
+			return DRM_ERR(ENOMEM);
 		}
 		R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart );
 	}
+#endif
 
 	r128_cce_init_ring_buffer( dev, dev_priv );
 	r128_cce_load_microcode( dev_priv );
@@ -625,16 +615,20 @@
 	if ( dev->dev_private ) {
 		drm_r128_private_t *dev_priv = dev->dev_private;
 
+#if __REALLY_HAVE_SG
 		if ( !dev_priv->is_pci ) {
+#endif
 			DRM_IOREMAPFREE( dev_priv->cce_ring );
 			DRM_IOREMAPFREE( dev_priv->ring_rptr );
 			DRM_IOREMAPFREE( dev_priv->buffers );
+#if __REALLY_HAVE_SG
 		} else {
 			if (!DRM(ati_pcigart_cleanup)( dev,
 						dev_priv->phys_pci_gart,
 						dev_priv->bus_pci_gart ))
 				DRM_ERROR( "failed to cleanup PCI GART!\n" );
 		}
+#endif
 
 		DRM(free)( dev->dev_private, sizeof(drm_r128_private_t),
 			   DRM_MEM_DRIVER );
@@ -644,17 +638,14 @@
 	return 0;
 }
 
-int r128_cce_init( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
+int r128_cce_init( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_init_t init;
 
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
-	if ( copy_from_user( &init, (drm_r128_init_t *)arg, sizeof(init) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( init, (drm_r128_init_t *)data, sizeof(init) );
 
 	switch ( init.func ) {
 	case R128_INIT_CCE:
@@ -663,21 +654,19 @@
 		return r128_do_cleanup_cce( dev );
 	}
 
-	return -EINVAL;
+	return DRM_ERR(EINVAL);
 }
 
-int r128_cce_start( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
+int r128_cce_start( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_private_t *dev_priv = dev->dev_private;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4 ) {
-		DRM_DEBUG( "%s while CCE running\n", __FUNCTION__ );
+		DRM_DEBUG( "%s while CCE running\n", __func__ );
 		return 0;
 	}
 
@@ -689,20 +678,17 @@
 /* Stop the CCE.  The engine must have been idled before calling this
  * routine.
  */
-int r128_cce_stop( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
+int r128_cce_stop( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_r128_cce_stop_t stop;
 	int ret;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &stop, (drm_r128_init_t *)arg, sizeof(stop) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL(stop, (drm_r128_cce_stop_t *)data, sizeof(stop) );
 
 	/* Flush any pending CCE commands.  This ensures any outstanding
 	 * commands are exectuted by the engine before we turn it off.
@@ -716,7 +702,7 @@
 	 */
 	if ( stop.idle ) {
 		ret = r128_do_cce_idle( dev_priv );
-		if ( ret < 0 ) return ret;
+		if ( ret ) return ret;
 	}
 
 	/* Finally, we can turn off the CCE.  If the engine isn't idle,
@@ -733,19 +719,17 @@
 
 /* Just reset the CCE ring.  Called as part of an X Server engine reset.
  */
-int r128_cce_reset( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
+int r128_cce_reset( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_private_t *dev_priv = dev->dev_private;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( !dev_priv ) {
-		DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
-		return -EINVAL;
+		DRM_DEBUG( "%s called before init done\n", __func__ );
+		return DRM_ERR(EINVAL);
 	}
 
 	r128_do_cce_reset( dev_priv );
@@ -756,13 +740,11 @@
 	return 0;
 }
 
-int r128_cce_idle( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
+int r128_cce_idle( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_private_t *dev_priv = dev->dev_private;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
@@ -773,12 +755,10 @@
 	return r128_do_cce_idle( dev_priv );
 }
 
-int r128_engine_reset( struct inode *inode, struct file *filp,
-		       unsigned int cmd, unsigned long arg )
+int r128_engine_reset( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEVICE;
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
@@ -793,7 +773,7 @@
 static int r128_do_init_pageflip( drm_device_t *dev )
 {
 	drm_r128_private_t *dev_priv = dev->dev_private;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	dev_priv->crtc_offset =      R128_READ( R128_CRTC_OFFSET );
 	dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL );
@@ -811,7 +791,7 @@
 int r128_do_cleanup_pageflip( drm_device_t *dev )
 {
 	drm_r128_private_t *dev_priv = dev->dev_private;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	R128_WRITE( R128_CRTC_OFFSET,      dev_priv->crtc_offset );
 	R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
@@ -822,17 +802,14 @@
 	return 0;
 }
 
-int r128_fullscreen( struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg )
+int r128_fullscreen( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_fullscreen_t fs;
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &fs, (drm_r128_fullscreen_t *)arg, sizeof(fs) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( fs, (drm_r128_fullscreen_t *)data, sizeof(fs) );
 
 	switch ( fs.func ) {
 	case R128_INIT_FULLSCREEN:
@@ -841,7 +818,7 @@
 		return r128_do_cleanup_pageflip( dev );
 	}
 
-	return -EINVAL;
+	return DRM_ERR(EINVAL);
 }
 
 
@@ -864,7 +841,7 @@
 	dev_priv->head = DRM(alloc)( sizeof(drm_r128_freelist_t),
 				     DRM_MEM_DRIVER );
 	if ( dev_priv->head == NULL )
-		return -ENOMEM;
+		return DRM_ERR(ENOMEM);
 
 	memset( dev_priv->head, 0, sizeof(drm_r128_freelist_t) );
 	dev_priv->head->age = R128_BUFFER_USED;
@@ -875,7 +852,7 @@
 
 		entry = DRM(alloc)( sizeof(drm_r128_freelist_t),
 				    DRM_MEM_DRIVER );
-		if ( !entry ) return -ENOMEM;
+		if ( !entry ) return DRM_ERR(ENOMEM);
 
 		entry->age = R128_BUFFER_FREE;
 		entry->buf = buf;
@@ -930,7 +907,7 @@
 				return buf;
 			}
 		}
-		udelay( 1 );
+		DRM_UDELAY( 1 );
 	}
 
 	DRM_ERROR( "returning NULL!\n" );
@@ -963,12 +940,12 @@
 		r128_update_ring_snapshot( ring );
 		if ( ring->space >= n )
 			return 0;
-		udelay( 1 );
+		DRM_UDELAY( 1 );
 	}
 
 	/* FIXME: This is being ignored... */
 	DRM_ERROR( "failed!\n" );
-	return -EBUSY;
+	return DRM_ERR(EBUSY);
 }
 
 static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d )
@@ -978,50 +955,47 @@
 
 	for ( i = d->granted_count ; i < d->request_count ; i++ ) {
 		buf = r128_freelist_get( dev );
-		if ( !buf ) return -EAGAIN;
+		if ( !buf ) return DRM_ERR(EAGAIN);
 
-		buf->pid = current->pid;
+		buf->pid = DRM_CURRENTPID;
 
-		if ( copy_to_user( &d->request_indices[i], &buf->idx,
+		if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx,
 				   sizeof(buf->idx) ) )
-			return -EFAULT;
-		if ( copy_to_user( &d->request_sizes[i], &buf->total,
+			return DRM_ERR(EFAULT);
+		if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total,
 				   sizeof(buf->total) ) )
-			return -EFAULT;
+			return DRM_ERR(EFAULT);
 
 		d->granted_count++;
 	}
 	return 0;
 }
 
-int r128_cce_buffers( struct inode *inode, struct file *filp,
-		      unsigned int cmd, unsigned long arg )
+int r128_cce_buffers( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_device_dma_t *dma = dev->dma;
 	int ret = 0;
 	drm_dma_t d;
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *) data, sizeof(d) );
 
 	/* Please don't send us buffers.
 	 */
 	if ( d.send_count != 0 ) {
 		DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
-			   current->pid, d.send_count );
-		return -EINVAL;
+			   DRM_CURRENTPID, d.send_count );
+		return DRM_ERR(EINVAL);
 	}
 
 	/* We'll send you buffers.
 	 */
 	if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
 		DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
-			   current->pid, d.request_count, dma->buf_count );
-		return -EINVAL;
+			   DRM_CURRENTPID, d.request_count, dma->buf_count );
+		return DRM_ERR(EINVAL);
 	}
 
 	d.granted_count = 0;
@@ -1030,8 +1004,7 @@
 		ret = r128_cce_get_buffers( dev, &d );
 	}
 
-	if ( copy_to_user( (drm_dma_t *) arg, &d, sizeof(d) ) )
-		return -EFAULT;
+	DRM_COPY_TO_USER_IOCTL((drm_dma_t *) data, d, sizeof(d) );
 
 	return ret;
 }
diff -Nru a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
--- a/drivers/char/drm/r128_drv.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/drm/r128_drv.c	Sat Aug 10 18:42:22 2002
@@ -37,45 +37,6 @@
 #include "r128_drv.h"
 #include "ati_pcigart.h"
 
-#define DRIVER_AUTHOR		"Gareth Hughes, VA Linux Systems Inc."
-
-#define DRIVER_NAME		"r128"
-#define DRIVER_DESC		"ATI Rage 128"
-#define DRIVER_DATE		"20010917"
-
-#define DRIVER_MAJOR		2
-#define DRIVER_MINOR		2
-#define DRIVER_PATCHLEVEL	0
-
-#define DRIVER_IOCTLS							    \
-   [DRM_IOCTL_NR(DRM_IOCTL_DMA)]             = { r128_cce_buffers,  1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)]       = { r128_cce_init,     1, 1 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)]  = { r128_cce_start,    1, 1 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)]   = { r128_cce_stop,     1, 1 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)]  = { r128_cce_reset,    1, 1 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)]   = { r128_cce_idle,     1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)]      = { r128_engine_reset, 1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)] = { r128_fullscreen,   1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)]       = { r128_cce_swap,     1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)]      = { r128_cce_clear,    1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)]     = { r128_cce_vertex,   1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)]    = { r128_cce_indices,  1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)]       = { r128_cce_blit,     1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)]      = { r128_cce_depth,    1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)]    = { r128_cce_stipple,  1, 0 }, \
-   [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)]   = { r128_cce_indirect, 1, 1 },
-
-
-#if 0
-/* GH: Count data sent to card via ring or vertex/indirect buffers.
- */
-#define __HAVE_COUNTERS         3
-#define __HAVE_COUNTER6         _DRM_STAT_IRQ
-#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
-#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
-#endif
-
-
 #include "drm_agpsupport.h"
 #include "drm_auth.h"
 #include "drm_bufs.h"
@@ -83,26 +44,6 @@
 #include "drm_dma.h"
 #include "drm_drawable.h"
 #include "drm_drv.h"
-
-#ifndef MODULE
-/* DRM(options) is called by the kernel to parse command-line options
- * passed via the boot-loader (e.g., LILO).  It calls the insmod option
- * routine, drm_parse_drm.
- */
-
-/* JH- We have to hand expand the string ourselves because of the cpp.  If
- * anyone can think of a way that we can fit into the __setup macro without
- * changing it, then please send the solution my way.
- */
-static int __init r128_options( char *str )
-{
-	DRM(parse_options)( str );
-	return 1;
-}
-
-__setup( DRIVER_NAME "=", r128_options );
-#endif
-
 #include "drm_fops.h"
 #include "drm_init.h"
 #include "drm_ioctl.h"
diff -Nru a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
--- a/drivers/char/drm/r128_drv.h	Sat Aug 10 18:42:23 2002
+++ b/drivers/char/drm/r128_drv.h	Sat Aug 10 18:42:23 2002
@@ -34,8 +34,8 @@
 #ifndef __R128_DRV_H__
 #define __R128_DRV_H__
 
-#define GET_RING_HEAD(ring)		readl( (volatile u32 *) (ring)->head )
-#define SET_RING_HEAD(ring,val)		writel( (val), (volatile u32 *) (ring)->head )
+#define GET_RING_HEAD(ring)		DRM_READ32(  (volatile u32 *) (ring)->head )
+#define SET_RING_HEAD(ring,val)		DRM_WRITE32( (volatile u32 *) (ring)->head, (val) )
 
 typedef struct drm_r128_freelist {
    	unsigned int age;
@@ -116,29 +116,21 @@
 } drm_r128_buf_priv_t;
 
 				/* r128_cce.c */
-extern int r128_cce_init( struct inode *inode, struct file *filp,
-			  unsigned int cmd, unsigned long arg );
-extern int r128_cce_start( struct inode *inode, struct file *filp,
-			   unsigned int cmd, unsigned long arg );
-extern int r128_cce_stop( struct inode *inode, struct file *filp,
-			  unsigned int cmd, unsigned long arg );
-extern int r128_cce_reset( struct inode *inode, struct file *filp,
-			   unsigned int cmd, unsigned long arg );
-extern int r128_cce_idle( struct inode *inode, struct file *filp,
-			  unsigned int cmd, unsigned long arg );
-extern int r128_engine_reset( struct inode *inode, struct file *filp,
-			      unsigned int cmd, unsigned long arg );
-extern int r128_fullscreen( struct inode *inode, struct file *filp,
-			    unsigned int cmd, unsigned long arg );
-extern int r128_cce_buffers( struct inode *inode, struct file *filp,
-			     unsigned int cmd, unsigned long arg );
+extern int r128_cce_init( DRM_IOCTL_ARGS );
+extern int r128_cce_start( DRM_IOCTL_ARGS );
+extern int r128_cce_stop( DRM_IOCTL_ARGS );
+extern int r128_cce_reset( DRM_IOCTL_ARGS );
+extern int r128_cce_idle( DRM_IOCTL_ARGS );
+extern int r128_engine_reset( DRM_IOCTL_ARGS );
+extern int r128_fullscreen( DRM_IOCTL_ARGS );
+extern int r128_cce_buffers( DRM_IOCTL_ARGS );
 
 extern void r128_freelist_reset( drm_device_t *dev );
 extern drm_buf_t *r128_freelist_get( drm_device_t *dev );
 
 extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n );
 
-static inline void
+static __inline__ void
 r128_update_ring_snapshot( drm_r128_ring_buffer_t *ring )
 {
 	ring->space = (GET_RING_HEAD( ring ) - ring->tail) * sizeof(u32);
@@ -151,22 +143,14 @@
 extern int r128_do_cleanup_pageflip( drm_device_t *dev );
 
 				/* r128_state.c */
-extern int r128_cce_clear( struct inode *inode, struct file *filp,
-			   unsigned int cmd, unsigned long arg );
-extern int r128_cce_swap( struct inode *inode, struct file *filp,
-			  unsigned int cmd, unsigned long arg );
-extern int r128_cce_vertex( struct inode *inode, struct file *filp,
-			    unsigned int cmd, unsigned long arg );
-extern int r128_cce_indices( struct inode *inode, struct file *filp,
-			     unsigned int cmd, unsigned long arg );
-extern int r128_cce_blit( struct inode *inode, struct file *filp,
-			  unsigned int cmd, unsigned long arg );
-extern int r128_cce_depth( struct inode *inode, struct file *filp,
-			   unsigned int cmd, unsigned long arg );
-extern int r128_cce_stipple( struct inode *inode, struct file *filp,
-			     unsigned int cmd, unsigned long arg );
-extern int r128_cce_indirect( struct inode *inode, struct file *filp,
-			      unsigned int cmd, unsigned long arg );
+extern int r128_cce_clear( DRM_IOCTL_ARGS );
+extern int r128_cce_swap( DRM_IOCTL_ARGS );
+extern int r128_cce_vertex( DRM_IOCTL_ARGS );
+extern int r128_cce_indices( DRM_IOCTL_ARGS );
+extern int r128_cce_blit( DRM_IOCTL_ARGS );
+extern int r128_cce_depth( DRM_IOCTL_ARGS );
+extern int r128_cce_stipple( DRM_IOCTL_ARGS );
+extern int r128_cce_indirect( DRM_IOCTL_ARGS );
 
 
 /* Register definitions, register access macros and drmAddMap constants
@@ -384,11 +368,11 @@
 #define R128_BASE(reg)		((unsigned long)(dev_priv->mmio->handle))
 #define R128_ADDR(reg)		(R128_BASE( reg ) + reg)
 
-#define R128_READ(reg)		readl( (volatile u32 *) R128_ADDR(reg) )
-#define R128_WRITE(reg,val)	writel( (val), (volatile u32 *) R128_ADDR(reg) )
+#define R128_READ(reg)		DRM_READ32(  (volatile u32 *) R128_ADDR(reg) )
+#define R128_WRITE(reg,val)	DRM_WRITE32( (volatile u32 *) R128_ADDR(reg), (val) )
 
-#define R128_READ8(reg)		readb( (volatile u8 *) R128_ADDR(reg) )
-#define R128_WRITE8(reg,val)	writeb( (val), (volatile u8 *) R128_ADDR(reg) )
+#define R128_READ8(reg)		DRM_READ8(  (volatile u8 *) R128_ADDR(reg) )
+#define R128_WRITE8(reg,val)	DRM_WRITE8( (volatile u8 *) R128_ADDR(reg), (val) )
 
 #define R128_WRITE_PLL(addr,val)					\
 do {									\
@@ -416,10 +400,9 @@
 #define LOCK_TEST_WITH_RETURN( dev )					\
 do {									\
 	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||		\
-	     dev->lock.pid != current->pid ) {				\
-		DRM_ERROR( "%s called without lock held\n",		\
-			   __FUNCTION__ );				\
-		return -EINVAL;						\
+	     dev->lock.pid != DRM_CURRENTPID ) {			\
+		DRM_ERROR( "%s called without lock held\n", __func__ );	\
+		return DRM_ERR(EINVAL);				\
 	}								\
 } while (0)
 
@@ -431,12 +414,13 @@
 			r128_update_ring_snapshot( ring );		\
 			if ( ring->space >= ring->high_mark )		\
 				goto __ring_space_done;			\
-			udelay( 1 );					\
+			DRM_UDELAY(1);				\
 		}							\
 		DRM_ERROR( "ring space check failed!\n" );		\
-		return -EBUSY;						\
+		return DRM_ERR(EBUSY);				\
 	}								\
  __ring_space_done:							\
+	;								\
 } while (0)
 
 #define VB_AGE_TEST_WITH_RETURN( dev_priv )				\
@@ -444,7 +428,7 @@
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;		\
 	if ( sarea_priv->last_dispatch >= R128_MAX_VB_AGE ) {		\
 		int __ret = r128_do_cce_idle( dev_priv );		\
-		if ( __ret < 0 ) return __ret;				\
+		if ( __ret ) return __ret;				\
 		sarea_priv->last_dispatch = 0;				\
 		r128_freelist_reset( dev );				\
 	}								\
@@ -463,7 +447,7 @@
 #if defined(__powerpc__)
 #define r128_flush_write_combine()	(void) GET_RING_HEAD( &dev_priv->ring )
 #else
-#define r128_flush_write_combine()	mb()
+#define r128_flush_write_combine()	DRM_WRITEMEMORYBARRIER()
 #endif
 
 
@@ -475,7 +459,7 @@
 #define BEGIN_RING( n ) do {						\
 	if ( R128_VERBOSE ) {						\
 		DRM_INFO( "BEGIN_RING( %d ) in %s\n",			\
-			   (n), __FUNCTION__ );				\
+			   (n), __func__ );				\
 	}								\
 	if ( dev_priv->ring.space <= (n) * sizeof(u32) ) {		\
 		r128_wait_ring( dev_priv, (n) * sizeof(u32) );		\
diff -Nru a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
--- a/drivers/char/drm/r128_state.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/char/drm/r128_state.c	Sat Aug 10 18:42:21 2002
@@ -27,14 +27,11 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "r128.h"
 #include "drmP.h"
 #include "drm.h"
 #include "r128_drm.h"
 #include "r128_drv.h"
-#include "drm.h"
-#include <linux/delay.h>
 
 
 /* ================================================================
@@ -46,7 +43,7 @@
 {
 	u32 aux_sc_cntl = 0x00000000;
 	RING_LOCALS;
-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
+	DRM_DEBUG( "    %s\n", __func__ );
 
 	BEGIN_RING( 17 );
 
@@ -84,12 +81,12 @@
 	ADVANCE_RING();
 }
 
-static inline void r128_emit_core( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_core( drm_r128_private_t *dev_priv )
 {
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
 	RING_LOCALS;
-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
+	DRM_DEBUG( "    %s\n", __func__ );
 
 	BEGIN_RING( 2 );
 
@@ -99,12 +96,12 @@
 	ADVANCE_RING();
 }
 
-static inline void r128_emit_context( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_context( drm_r128_private_t *dev_priv )
 {
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
 	RING_LOCALS;
-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
+	DRM_DEBUG( "    %s\n", __func__ );
 
 	BEGIN_RING( 13 );
 
@@ -125,12 +122,12 @@
 	ADVANCE_RING();
 }
 
-static inline void r128_emit_setup( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_setup( drm_r128_private_t *dev_priv )
 {
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
 	RING_LOCALS;
-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
+	DRM_DEBUG( "    %s\n", __func__ );
 
 	BEGIN_RING( 3 );
 
@@ -141,12 +138,12 @@
 	ADVANCE_RING();
 }
 
-static inline void r128_emit_masks( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_masks( drm_r128_private_t *dev_priv )
 {
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
 	RING_LOCALS;
-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
+	DRM_DEBUG( "    %s\n", __func__ );
 
 	BEGIN_RING( 5 );
 
@@ -160,12 +157,12 @@
 	ADVANCE_RING();
 }
 
-static inline void r128_emit_window( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_window( drm_r128_private_t *dev_priv )
 {
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
 	RING_LOCALS;
-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
+	DRM_DEBUG( "    %s\n", __func__ );
 
 	BEGIN_RING( 2 );
 
@@ -175,14 +172,14 @@
 	ADVANCE_RING();
 }
 
-static inline void r128_emit_tex0( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_tex0( drm_r128_private_t *dev_priv )
 {
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
 	drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0];
 	int i;
 	RING_LOCALS;
-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
+	DRM_DEBUG( "    %s\n", __func__ );
 
 	BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS );
 
@@ -202,13 +199,13 @@
 	ADVANCE_RING();
 }
 
-static inline void r128_emit_tex1( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_tex1( drm_r128_private_t *dev_priv )
 {
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1];
 	int i;
 	RING_LOCALS;
-	DRM_DEBUG( "    %s\n", __FUNCTION__ );
+	DRM_DEBUG( "    %s\n", __func__ );
 
 	BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS );
 
@@ -226,12 +223,12 @@
 	ADVANCE_RING();
 }
 
-static inline void r128_emit_state( drm_r128_private_t *dev_priv )
+static __inline__ void r128_emit_state( drm_r128_private_t *dev_priv )
 {
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	unsigned int dirty = sarea_priv->dirty;
 
-	DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty );
+	DRM_DEBUG( "%s: dirty=0x%08x\n", __func__, dirty );
 
 	if ( dirty & R128_UPLOAD_CORE ) {
 		r128_emit_core( dev_priv );
@@ -372,7 +369,7 @@
 	unsigned int flags = clear->flags;
 	int i;
 	RING_LOCALS;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "%s\n", __func__ );
 
 	if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
 		unsigned int tmp = flags;
@@ -475,7 +472,7 @@
 	drm_clip_rect_t *pbox = sarea_priv->boxes;
 	int i;
 	RING_LOCALS;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "%s\n", __func__ );
 
 #if R128_PERFORMANCE_BOXES
 	/* Do some trivial performance monitoring...
@@ -531,7 +528,7 @@
 {
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	RING_LOCALS;
-	DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page );
+	DRM_DEBUG( "page=%d\n", dev_priv->current_page );
 
 #if R128_PERFORMANCE_BOXES
 	/* Do some trivial performance monitoring...
@@ -580,8 +577,7 @@
 	int prim = buf_priv->prim;
 	int i = 0;
 	RING_LOCALS;
-	DRM_DEBUG( "%s: buf=%d nbox=%d\n",
-		   __FUNCTION__, buf->idx, sarea_priv->nbox );
+	DRM_DEBUG( "buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox );
 
 	if ( 0 )
 		r128_print_dirty( "dispatch_vertex", sarea_priv->dirty );
@@ -792,7 +788,7 @@
 	u32 *data;
 	int dword_shift, dwords;
 	RING_LOCALS;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	/* The compiler won't optimize away a division by a variable,
 	 * even if the only legal values are powers of two.  Thus, we'll
@@ -813,7 +809,7 @@
 		break;
 	default:
 		DRM_ERROR( "invalid blit format %d\n", blit->format );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	/* Flush the pixel cache, and mark the contents as Read Invalid.
@@ -833,14 +829,14 @@
 	buf = dma->buflist[blit->idx];
 	buf_priv = buf->dev_private;
 
-	if ( buf->pid != current->pid ) {
+	if ( buf->pid != DRM_CURRENTPID ) {
 		DRM_ERROR( "process %d using buffer owned by %d\n",
-			   current->pid, buf->pid );
-		return -EINVAL;
+			   DRM_CURRENTPID, buf->pid );
+		return DRM_ERR(EINVAL);
 	}
 	if ( buf->pending ) {
 		DRM_ERROR( "sending pending buffer %d\n", blit->idx );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	buf_priv->discard = 1;
@@ -902,36 +898,36 @@
 	u8 *mask;
 	int i;
 	RING_LOCALS;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	count = depth->n;
-	if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {
-		return -EFAULT;
+	if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
+		return DRM_ERR(EFAULT);
 	}
-	if ( copy_from_user( &y, depth->y, sizeof(y) ) ) {
-		return -EFAULT;
+	if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) {
+		return DRM_ERR(EFAULT);
 	}
 
-	buffer = kmalloc( depth->n * sizeof(u32), GFP_KERNEL );
+	buffer = DRM_MALLOC( depth->n * sizeof(u32) );
 	if ( buffer == NULL )
-		return -ENOMEM;
-	if ( copy_from_user( buffer, depth->buffer,
+		return DRM_ERR(ENOMEM);
+	if ( DRM_COPY_FROM_USER( buffer, depth->buffer,
 			     depth->n * sizeof(u32) ) ) {
-		kfree( buffer );
-		return -EFAULT;
+		DRM_FREE( buffer );
+		return DRM_ERR(EFAULT);
 	}
 
 	if ( depth->mask ) {
-		mask = kmalloc( depth->n * sizeof(u8), GFP_KERNEL );
+		mask = DRM_MALLOC( depth->n * sizeof(u8) );
 		if ( mask == NULL ) {
-			kfree( buffer );
-			return -ENOMEM;
+			DRM_FREE( buffer );
+			return DRM_ERR(ENOMEM);
 		}
-		if ( copy_from_user( mask, depth->mask,
+		if ( DRM_COPY_FROM_USER( mask, depth->mask,
 				     depth->n * sizeof(u8) ) ) {
-			kfree( buffer );
-			kfree( mask );
-			return -EFAULT;
+			DRM_FREE( buffer );
+			DRM_FREE( mask );
+			return DRM_ERR(EFAULT);
 		}
 
 		for ( i = 0 ; i < count ; i++, x++ ) {
@@ -957,7 +953,7 @@
 			}
 		}
 
-		kfree( mask );
+		DRM_FREE( mask );
 	} else {
 		for ( i = 0 ; i < count ; i++, x++ ) {
 			BEGIN_RING( 6 );
@@ -981,7 +977,7 @@
 		}
 	}
 
-	kfree( buffer );
+	DRM_FREE( buffer );
 
 	return 0;
 }
@@ -995,59 +991,59 @@
 	u8 *mask;
 	int i;
 	RING_LOCALS;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	count = depth->n;
 
-	x = kmalloc( count * sizeof(*x), GFP_KERNEL );
+	x = DRM_MALLOC( count * sizeof(*x) );
 	if ( x == NULL ) {
-		return -ENOMEM;
+		return DRM_ERR(ENOMEM);
 	}
-	y = kmalloc( count * sizeof(*y), GFP_KERNEL );
+	y = DRM_MALLOC( count * sizeof(*y) );
 	if ( y == NULL ) {
-		kfree( x );
-		return -ENOMEM;
+		DRM_FREE( x );
+		return DRM_ERR(ENOMEM);
 	}
-	if ( copy_from_user( x, depth->x, count * sizeof(int) ) ) {
-		kfree( x );
-		kfree( y );
-		return -EFAULT;
+	if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
+		return DRM_ERR(EFAULT);
 	}
-	if ( copy_from_user( y, depth->y, count * sizeof(int) ) ) {
-		kfree( x );
-		kfree( y );
-		return -EFAULT;
+	if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
+		return DRM_ERR(EFAULT);
 	}
 
-	buffer = kmalloc( depth->n * sizeof(u32), GFP_KERNEL );
+	buffer = DRM_MALLOC( depth->n * sizeof(u32) );
 	if ( buffer == NULL ) {
-		kfree( x );
-		kfree( y );
-		return -ENOMEM;
+		DRM_FREE( x );
+		DRM_FREE( y );
+		return DRM_ERR(ENOMEM);
 	}
-	if ( copy_from_user( buffer, depth->buffer,
+	if ( DRM_COPY_FROM_USER( buffer, depth->buffer,
 			     depth->n * sizeof(u32) ) ) {
-		kfree( x );
-		kfree( y );
-		kfree( buffer );
-		return -EFAULT;
+		DRM_FREE( x );
+		DRM_FREE( y );
+		DRM_FREE( buffer );
+		return DRM_ERR(EFAULT);
 	}
 
 	if ( depth->mask ) {
-		mask = kmalloc( depth->n * sizeof(u8), GFP_KERNEL );
+		mask = DRM_MALLOC( depth->n * sizeof(u8) );
 		if ( mask == NULL ) {
-			kfree( x );
-			kfree( y );
-			kfree( buffer );
-			return -ENOMEM;
+			DRM_FREE( x );
+			DRM_FREE( y );
+			DRM_FREE( buffer );
+			return DRM_ERR(ENOMEM);
 		}
-		if ( copy_from_user( mask, depth->mask,
+		if ( DRM_COPY_FROM_USER( mask, depth->mask,
 				     depth->n * sizeof(u8) ) ) {
-			kfree( x );
-			kfree( y );
-			kfree( buffer );
-			kfree( mask );
-			return -EFAULT;
+			DRM_FREE( x );
+			DRM_FREE( y );
+			DRM_FREE( buffer );
+			DRM_FREE( mask );
+			return DRM_ERR(EFAULT);
 		}
 
 		for ( i = 0 ; i < count ; i++ ) {
@@ -1073,7 +1069,7 @@
 			}
 		}
 
-		kfree( mask );
+		DRM_FREE( mask );
 	} else {
 		for ( i = 0 ; i < count ; i++ ) {
 			BEGIN_RING( 6 );
@@ -1097,9 +1093,9 @@
 		}
 	}
 
-	kfree( x );
-	kfree( y );
-	kfree( buffer );
+	DRM_FREE( x );
+	DRM_FREE( y );
+	DRM_FREE( buffer );
 
 	return 0;
 }
@@ -1110,14 +1106,14 @@
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	int count, x, y;
 	RING_LOCALS;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	count = depth->n;
-	if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {
-		return -EFAULT;
+	if ( DRM_COPY_FROM_USER( &x, depth->x, sizeof(x) ) ) {
+		return DRM_ERR(EFAULT);
 	}
-	if ( copy_from_user( &y, depth->y, sizeof(y) ) ) {
-		return -EFAULT;
+	if ( DRM_COPY_FROM_USER( &y, depth->y, sizeof(y) ) ) {
+		return DRM_ERR(EFAULT);
 	}
 
 	BEGIN_RING( 7 );
@@ -1152,31 +1148,31 @@
 	int count, *x, *y;
 	int i;
 	RING_LOCALS;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "%s\n", __func__ );
 
 	count = depth->n;
 	if ( count > dev_priv->depth_pitch ) {
 		count = dev_priv->depth_pitch;
 	}
 
-	x = kmalloc( count * sizeof(*x), GFP_KERNEL );
+	x = DRM_MALLOC( count * sizeof(*x) );
 	if ( x == NULL ) {
-		return -ENOMEM;
+		return DRM_ERR(ENOMEM);
 	}
-	y = kmalloc( count * sizeof(*y), GFP_KERNEL );
+	y = DRM_MALLOC( count * sizeof(*y) );
 	if ( y == NULL ) {
-		kfree( x );
-		return -ENOMEM;
+		DRM_FREE( x );
+		return DRM_ERR(ENOMEM);
 	}
-	if ( copy_from_user( x, depth->x, count * sizeof(int) ) ) {
-		kfree( x );
-		kfree( y );
-		return -EFAULT;
-	}
-	if ( copy_from_user( y, depth->y, count * sizeof(int) ) ) {
-		kfree( x );
-		kfree( y );
-		return -EFAULT;
+	if ( DRM_COPY_FROM_USER( x, depth->x, count * sizeof(int) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
+		return DRM_ERR(EFAULT);
+	}
+	if ( DRM_COPY_FROM_USER( y, depth->y, count * sizeof(int) ) ) {
+		DRM_FREE( x );
+		DRM_FREE( y );
+		return DRM_ERR(EFAULT);
 	}
 
 	for ( i = 0 ; i < count ; i++ ) {
@@ -1203,8 +1199,8 @@
 		ADVANCE_RING();
 	}
 
-	kfree( x );
-	kfree( y );
+	DRM_FREE( x );
+	DRM_FREE( y );
 
 	return 0;
 }
@@ -1219,7 +1215,7 @@
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	int i;
 	RING_LOCALS;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "%s\n", __func__ );
 
 	BEGIN_RING( 33 );
 
@@ -1236,21 +1232,18 @@
  * IOCTL functions
  */
 
-int r128_cce_clear( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
+int r128_cce_clear( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_r128_clear_t clear;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &clear, (drm_r128_clear_t *) arg,
-			     sizeof(clear) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( clear, (drm_r128_clear_t *) data,
+			     sizeof(clear) );
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
 
@@ -1266,14 +1259,12 @@
 	return 0;
 }
 
-int r128_cce_swap( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
+int r128_cce_swap( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "%s\n", __func__ );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
@@ -1293,11 +1284,9 @@
 	return 0;
 }
 
-int r128_cce_vertex( struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg )
+int r128_cce_vertex( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_device_dma_t *dma = dev->dma;
 	drm_buf_t *buf;
@@ -1307,27 +1296,26 @@
 	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( !dev_priv ) {
-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
-		return -EINVAL;
+		DRM_ERROR( "%s called with no initialization\n", __func__ );
+		return DRM_ERR(EINVAL);
 	}
 
-	if ( copy_from_user( &vertex, (drm_r128_vertex_t *)arg,
-			     sizeof(vertex) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( vertex, (drm_r128_vertex_t *) data,
+			     sizeof(vertex) );
 
-	DRM_DEBUG( "%s: pid=%d index=%d count=%d discard=%d\n",
-		   __FUNCTION__, current->pid,
+	DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n",
+		   DRM_CURRENTPID,
 		   vertex.idx, vertex.count, vertex.discard );
 
 	if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
 		DRM_ERROR( "buffer index %d (of %d max)\n",
 			   vertex.idx, dma->buf_count - 1 );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	if ( vertex.prim < 0 ||
 	     vertex.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) {
 		DRM_ERROR( "buffer prim %d\n", vertex.prim );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
@@ -1336,14 +1324,14 @@
 	buf = dma->buflist[vertex.idx];
 	buf_priv = buf->dev_private;
 
-	if ( buf->pid != current->pid ) {
+	if ( buf->pid != DRM_CURRENTPID ) {
 		DRM_ERROR( "process %d using buffer owned by %d\n",
-			   current->pid, buf->pid );
-		return -EINVAL;
+			   DRM_CURRENTPID, buf->pid );
+		return DRM_ERR(EINVAL);
 	}
 	if ( buf->pending ) {
 		DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	buf->used = vertex.count;
@@ -1355,11 +1343,9 @@
 	return 0;
 }
 
-int r128_cce_indices( struct inode *inode, struct file *filp,
-		      unsigned int cmd, unsigned long arg )
+int r128_cce_indices( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_device_dma_t *dma = dev->dma;
 	drm_buf_t *buf;
@@ -1370,27 +1356,25 @@
 	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( !dev_priv ) {
-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
-		return -EINVAL;
+		DRM_ERROR( "%s called with no initialization\n", __func__ );
+		return DRM_ERR(EINVAL);
 	}
 
-	if ( copy_from_user( &elts, (drm_r128_indices_t *)arg,
-			     sizeof(elts) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( elts, (drm_r128_indices_t *) data,
+			     sizeof(elts) );
 
-	DRM_DEBUG( "%s: pid=%d buf=%d s=%d e=%d d=%d\n",
-		   __FUNCTION__, current->pid,
+	DRM_DEBUG( "pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
 		   elts.idx, elts.start, elts.end, elts.discard );
 
 	if ( elts.idx < 0 || elts.idx >= dma->buf_count ) {
 		DRM_ERROR( "buffer index %d (of %d max)\n",
 			   elts.idx, dma->buf_count - 1 );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	if ( elts.prim < 0 ||
 	     elts.prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) {
 		DRM_ERROR( "buffer prim %d\n", elts.prim );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
@@ -1399,14 +1383,14 @@
 	buf = dma->buflist[elts.idx];
 	buf_priv = buf->dev_private;
 
-	if ( buf->pid != current->pid ) {
+	if ( buf->pid != DRM_CURRENTPID ) {
 		DRM_ERROR( "process %d using buffer owned by %d\n",
-			   current->pid, buf->pid );
-		return -EINVAL;
+			   DRM_CURRENTPID, buf->pid );
+		return DRM_ERR(EINVAL);
 	}
 	if ( buf->pending ) {
 		DRM_ERROR( "sending pending buffer %d\n", elts.idx );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	count = (elts.end - elts.start) / sizeof(u16);
@@ -1414,11 +1398,11 @@
 
 	if ( elts.start & 0x7 ) {
 		DRM_ERROR( "misaligned buffer 0x%x\n", elts.start );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	if ( elts.start < buf->used ) {
 		DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	buf->used = elts.end;
@@ -1430,28 +1414,24 @@
 	return 0;
 }
 
-int r128_cce_blit( struct inode *inode, struct file *filp,
-		   unsigned int cmd, unsigned long arg )
+int r128_cce_blit( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_device_dma_t *dma = dev->dma;
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_r128_blit_t blit;
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &blit, (drm_r128_blit_t *)arg,
-			     sizeof(blit) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( blit, (drm_r128_blit_t *) data,
+			     sizeof(blit) );
 
-	DRM_DEBUG( "%s: pid=%d index=%d\n",
-		   __FUNCTION__, current->pid, blit.idx );
+	DRM_DEBUG( "pid=%d index=%d\n", DRM_CURRENTPID, blit.idx );
 
 	if ( blit.idx < 0 || blit.idx >= dma->buf_count ) {
 		DRM_ERROR( "buffer index %d (of %d max)\n",
 			   blit.idx, dma->buf_count - 1 );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
@@ -1460,19 +1440,16 @@
 	return r128_cce_dispatch_blit( dev, &blit );
 }
 
-int r128_cce_depth( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
+int r128_cce_depth( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_r128_depth_t depth;
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &depth, (drm_r128_depth_t *)arg,
-			     sizeof(depth) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( depth, (drm_r128_depth_t *) data,
+			     sizeof(depth) );
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
 
@@ -1487,27 +1464,24 @@
 		return r128_cce_dispatch_read_pixels( dev, &depth );
 	}
 
-	return -EINVAL;
+	return DRM_ERR(EINVAL);
 }
 
-int r128_cce_stipple( struct inode *inode, struct file *filp,
-		      unsigned int cmd, unsigned long arg )
+int r128_cce_stipple( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_r128_stipple_t stipple;
 	u32 mask[32];
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &stipple, (drm_r128_stipple_t *)arg,
-			     sizeof(stipple) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( stipple, (drm_r128_stipple_t *) data,
+			     sizeof(stipple) );
 
-	if ( copy_from_user( &mask, stipple.mask,
+	if ( DRM_COPY_FROM_USER( &mask, stipple.mask,
 			     32 * sizeof(u32) ) )
-		return -EFAULT;
+		return DRM_ERR( EFAULT );
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
 
@@ -1516,11 +1490,9 @@
 	return 0;
 }
 
-int r128_cce_indirect( struct inode *inode, struct file *filp,
-		       unsigned int cmd, unsigned long arg )
+int r128_cce_indirect( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_r128_private_t *dev_priv = dev->dev_private;
 	drm_device_dma_t *dma = dev->dma;
 	drm_buf_t *buf;
@@ -1533,13 +1505,12 @@
 	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( !dev_priv ) {
-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
-		return -EINVAL;
+		DRM_ERROR( "%s called with no initialization\n", __func__ );
+		return DRM_ERR(EINVAL);
 	}
 
-	if ( copy_from_user( &indirect, (drm_r128_indirect_t *)arg,
-			     sizeof(indirect) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( indirect, (drm_r128_indirect_t *) data,
+			     sizeof(indirect) );
 
 	DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
 		   indirect.idx, indirect.start,
@@ -1548,26 +1519,26 @@
 	if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) {
 		DRM_ERROR( "buffer index %d (of %d max)\n",
 			   indirect.idx, dma->buf_count - 1 );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	buf = dma->buflist[indirect.idx];
 	buf_priv = buf->dev_private;
 
-	if ( buf->pid != current->pid ) {
+	if ( buf->pid != DRM_CURRENTPID ) {
 		DRM_ERROR( "process %d using buffer owned by %d\n",
-			   current->pid, buf->pid );
-		return -EINVAL;
+			   DRM_CURRENTPID, buf->pid );
+		return DRM_ERR(EINVAL);
 	}
 	if ( buf->pending ) {
 		DRM_ERROR( "sending pending buffer %d\n", indirect.idx );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	if ( indirect.start < buf->used ) {
 		DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
 			   indirect.start, buf->used );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
diff -Nru a/drivers/char/drm/radeon.h b/drivers/char/drm/radeon.h
--- a/drivers/char/drm/radeon.h	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/drm/radeon.h	Sat Aug 10 18:42:22 2002
@@ -25,6 +25,7 @@
  *
  * Authors:
  *    Gareth Hughes <gareth@valinux.com>
+ *    Keith Whitwell <keith@tungstengraphics.com>
  */
 
 #ifndef __RADEON_H__
@@ -43,6 +44,51 @@
 #define __HAVE_SG		1
 #define __HAVE_PCI_DMA		1
 
+#define DRIVER_AUTHOR		"Gareth Hughes, Keith Whitwell, others."
+
+#define DRIVER_NAME		"radeon"
+#define DRIVER_DESC		"ATI Radeon"
+#define DRIVER_DATE		"20020611"
+
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		4
+#define DRIVER_PATCHLEVEL	0
+
+/* Interface history:
+ *
+ * 1.1 - ??
+ * 1.2 - Add vertex2 ioctl (keith)
+ *     - Add stencil capability to clear ioctl (gareth, keith)
+ *     - Increase MAX_TEXTURE_LEVELS (brian)
+ * 1.3 - Add cmdbuf ioctl (keith)
+ *     - Add support for new radeon packets (keith)
+ *     - Add getparam ioctl (keith)
+ *     - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
+ * 1.4 - Add r200 packets to cmdbuf ioctl
+ *     - Add r200 function to init ioctl
+ *     - Add 'scalar2' hack to cmdbuf ioctl (must die)
+ */
+#define DRIVER_IOCTLS							     \
+ [DRM_IOCTL_NR(DRM_IOCTL_DMA)]               = { radeon_cp_buffers,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)]    = { radeon_cp_init,     1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)]   = { radeon_cp_start,    1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)]    = { radeon_cp_stop,     1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)]   = { radeon_cp_reset,    1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)]    = { radeon_cp_idle,     1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)]    = { radeon_engine_reset,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)]       = { radeon_cp_swap,     1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)]      = { radeon_cp_clear,    1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)]     = { radeon_cp_vertex,   1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)]    = { radeon_cp_indices,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)]    = { radeon_cp_texture,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)]    = { radeon_cp_stipple,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]   = { radeon_cp_indirect, 1, 1 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)]    = { radeon_cp_vertex2,  1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)]     = { radeon_cp_cmdbuf,   1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)]   = { radeon_cp_getparam, 1, 0 }, \
+ [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)]       = { radeon_cp_flip,     1, 0 }, 
+
 /* Driver customization:
  */
 #define DRIVER_PRERELEASE() do {					\
@@ -61,15 +107,6 @@
 /* DMA customization:
  */
 #define __HAVE_DMA		1
-
-#if 0
-/* GH: Remove this for now... */
-#define __HAVE_DMA_QUIESCENT	1
-#define DRIVER_DMA_QUIESCENT() do {					\
-	drm_radeon_private_t *dev_priv = dev->dev_private;		\
-	return radeon_do_cp_idle( dev_priv );				\
-} while (0)
-#endif
 
 /* Buffer customization:
  */
diff -Nru a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
--- a/drivers/char/drm/radeon_cp.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/char/drm/radeon_cp.c	Sat Aug 10 18:42:21 2002
@@ -28,16 +28,12 @@
  *    Gareth Hughes <gareth@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
 #include "radeon_drv.h"
 
-#include <linux/interrupt.h>	/* For task queue support */
-#include <linux/delay.h>
-
 #define RADEON_FIFO_DEBUG	0
 
 #if defined(__alpha__) || defined(__powerpc__)
@@ -48,6 +44,266 @@
 
 
 /* CP microcode (from ATI) */
+static u32 R200_cp_microcode[][2] = {
+	{ 0x21007000, 0000000000 },        
+	{ 0x20007000, 0000000000 }, 
+	{ 0x000000ab, 0x00000004 },
+	{ 0x000000af, 0x00000004 },
+	{ 0x66544a49, 0000000000 },
+	{ 0x49494174, 0000000000 },
+	{ 0x54517d83, 0000000000 },
+	{ 0x498d8b64, 0000000000 },
+	{ 0x49494949, 0000000000 },
+	{ 0x49da493c, 0000000000 },
+	{ 0x49989898, 0000000000 },
+	{ 0xd34949d5, 0000000000 },
+	{ 0x9dc90e11, 0000000000 },
+	{ 0xce9b9b9b, 0000000000 },
+	{ 0x000f0000, 0x00000016 },
+	{ 0x352e232c, 0000000000 },
+	{ 0x00000013, 0x00000004 },
+	{ 0x000f0000, 0x00000016 },
+	{ 0x352e272c, 0000000000 },
+	{ 0x000f0001, 0x00000016 },
+	{ 0x3239362f, 0000000000 },
+	{ 0x000077ef, 0x00000002 },
+	{ 0x00061000, 0x00000002 },
+	{ 0x00000020, 0x0000001a },
+	{ 0x00004000, 0x0000001e },
+	{ 0x00061000, 0x00000002 },
+	{ 0x00000020, 0x0000001a },
+	{ 0x00004000, 0x0000001e },
+	{ 0x00061000, 0x00000002 },
+	{ 0x00000020, 0x0000001a },
+	{ 0x00004000, 0x0000001e },
+	{ 0x00000016, 0x00000004 },
+	{ 0x0003802a, 0x00000002 },
+	{ 0x040067e0, 0x00000002 },
+	{ 0x00000016, 0x00000004 },
+	{ 0x000077e0, 0x00000002 },
+	{ 0x00065000, 0x00000002 },
+	{ 0x000037e1, 0x00000002 },
+	{ 0x040067e1, 0x00000006 },
+	{ 0x000077e0, 0x00000002 },
+	{ 0x000077e1, 0x00000002 },
+	{ 0x000077e1, 0x00000006 },
+	{ 0xffffffff, 0000000000 },
+	{ 0x10000000, 0000000000 },
+	{ 0x0003802a, 0x00000002 },
+	{ 0x040067e0, 0x00000006 },
+	{ 0x00007675, 0x00000002 },
+	{ 0x00007676, 0x00000002 },
+	{ 0x00007677, 0x00000002 },
+	{ 0x00007678, 0x00000006 },
+	{ 0x0003802b, 0x00000002 },
+	{ 0x04002676, 0x00000002 },
+	{ 0x00007677, 0x00000002 },
+	{ 0x00007678, 0x00000006 },
+	{ 0x0000002e, 0x00000018 },
+	{ 0x0000002e, 0x00000018 },
+	{ 0000000000, 0x00000006 },
+	{ 0x0000002f, 0x00000018 },
+	{ 0x0000002f, 0x00000018 },
+	{ 0000000000, 0x00000006 },
+	{ 0x01605000, 0x00000002 },
+	{ 0x00065000, 0x00000002 },
+	{ 0x00098000, 0x00000002 },
+	{ 0x00061000, 0x00000002 },
+	{ 0x64c0603d, 0x00000004 },
+	{ 0x00080000, 0x00000016 },
+	{ 0000000000, 0000000000 },
+	{ 0x0400251d, 0x00000002 },
+	{ 0x00007580, 0x00000002 },
+	{ 0x00067581, 0x00000002 },
+	{ 0x04002580, 0x00000002 },
+	{ 0x00067581, 0x00000002 },
+	{ 0x00000046, 0x00000004 },
+	{ 0x00005000, 0000000000 },
+	{ 0x00061000, 0x00000002 },
+	{ 0x0000750e, 0x00000002 },
+	{ 0x00019000, 0x00000002 },
+	{ 0x00011055, 0x00000014 },
+	{ 0x00000055, 0x00000012 },
+	{ 0x0400250f, 0x00000002 },
+	{ 0x0000504a, 0x00000004 },
+	{ 0x00007565, 0x00000002 },
+	{ 0x00007566, 0x00000002 },
+	{ 0x00000051, 0x00000004 },
+	{ 0x01e655b4, 0x00000002 },
+	{ 0x4401b0dc, 0x00000002 },
+	{ 0x01c110dc, 0x00000002 },
+	{ 0x2666705d, 0x00000018 },
+	{ 0x040c2565, 0x00000002 },
+	{ 0x0000005d, 0x00000018 },
+	{ 0x04002564, 0x00000002 },
+	{ 0x00007566, 0x00000002 },
+	{ 0x00000054, 0x00000004 },
+	{ 0x00401060, 0x00000008 },
+	{ 0x00101000, 0x00000002 },
+	{ 0x000d80ff, 0x00000002 },
+	{ 0x00800063, 0x00000008 },
+	{ 0x000f9000, 0x00000002 },
+	{ 0x000e00ff, 0x00000002 },
+	{ 0000000000, 0x00000006 },
+	{ 0x00000080, 0x00000018 },
+	{ 0x00000054, 0x00000004 },
+	{ 0x00007576, 0x00000002 },
+	{ 0x00065000, 0x00000002 },
+	{ 0x00009000, 0x00000002 },
+	{ 0x00041000, 0x00000002 },
+	{ 0x0c00350e, 0x00000002 },
+	{ 0x00049000, 0x00000002 },
+	{ 0x00051000, 0x00000002 },
+	{ 0x01e785f8, 0x00000002 },
+	{ 0x00200000, 0x00000002 },
+	{ 0x00600073, 0x0000000c },
+	{ 0x00007563, 0x00000002 },
+	{ 0x006075f0, 0x00000021 },
+	{ 0x20007068, 0x00000004 },
+	{ 0x00005068, 0x00000004 },
+	{ 0x00007576, 0x00000002 },
+	{ 0x00007577, 0x00000002 },
+	{ 0x0000750e, 0x00000002 },
+	{ 0x0000750f, 0x00000002 },
+	{ 0x00a05000, 0x00000002 },
+	{ 0x00600076, 0x0000000c },
+	{ 0x006075f0, 0x00000021 },
+	{ 0x000075f8, 0x00000002 },
+	{ 0x00000076, 0x00000004 },
+	{ 0x000a750e, 0x00000002 },
+	{ 0x0020750f, 0x00000002 },
+	{ 0x00600079, 0x00000004 },
+	{ 0x00007570, 0x00000002 },
+	{ 0x00007571, 0x00000002 },
+	{ 0x00007572, 0x00000006 },
+	{ 0x00005000, 0x00000002 },
+	{ 0x00a05000, 0x00000002 },
+	{ 0x00007568, 0x00000002 },
+	{ 0x00061000, 0x00000002 },
+	{ 0x00000084, 0x0000000c },
+	{ 0x00058000, 0x00000002 },
+	{ 0x0c607562, 0x00000002 },
+	{ 0x00000086, 0x00000004 },
+	{ 0x00600085, 0x00000004 },
+	{ 0x400070dd, 0000000000 },
+	{ 0x000380dd, 0x00000002 },
+	{ 0x00000093, 0x0000001c },
+	{ 0x00065095, 0x00000018 },
+	{ 0x040025bb, 0x00000002 },
+	{ 0x00061096, 0x00000018 },
+	{ 0x040075bc, 0000000000 },
+	{ 0x000075bb, 0x00000002 },
+	{ 0x000075bc, 0000000000 },
+	{ 0x00090000, 0x00000006 },
+	{ 0x00090000, 0x00000002 },
+	{ 0x000d8002, 0x00000006 },
+	{ 0x00005000, 0x00000002 },
+	{ 0x00007821, 0x00000002 },
+	{ 0x00007800, 0000000000 },
+	{ 0x00007821, 0x00000002 },
+	{ 0x00007800, 0000000000 },
+	{ 0x01665000, 0x00000002 },
+	{ 0x000a0000, 0x00000002 },
+	{ 0x000671cc, 0x00000002 },
+	{ 0x0286f1cd, 0x00000002 },
+	{ 0x000000a3, 0x00000010 },
+	{ 0x21007000, 0000000000 },
+	{ 0x000000aa, 0x0000001c },
+	{ 0x00065000, 0x00000002 },
+	{ 0x000a0000, 0x00000002 },
+	{ 0x00061000, 0x00000002 },
+	{ 0x000b0000, 0x00000002 },
+	{ 0x38067000, 0x00000002 },
+	{ 0x000a00a6, 0x00000004 },
+	{ 0x20007000, 0000000000 },
+	{ 0x01200000, 0x00000002 },
+	{ 0x20077000, 0x00000002 },
+	{ 0x01200000, 0x00000002 },
+	{ 0x20007000, 0000000000 },
+	{ 0x00061000, 0x00000002 },
+	{ 0x0120751b, 0x00000002 },
+	{ 0x8040750a, 0x00000002 },
+	{ 0x8040750b, 0x00000002 },
+	{ 0x00110000, 0x00000002 },
+	{ 0x000380dd, 0x00000002 },
+	{ 0x000000bd, 0x0000001c },
+	{ 0x00061096, 0x00000018 },
+	{ 0x844075bd, 0x00000002 },
+	{ 0x00061095, 0x00000018 },
+	{ 0x840075bb, 0x00000002 },
+	{ 0x00061096, 0x00000018 },
+	{ 0x844075bc, 0x00000002 },
+	{ 0x000000c0, 0x00000004 },
+	{ 0x804075bd, 0x00000002 },
+	{ 0x800075bb, 0x00000002 },
+	{ 0x804075bc, 0x00000002 },
+	{ 0x00108000, 0x00000002 },
+	{ 0x01400000, 0x00000002 },
+	{ 0x006000c4, 0x0000000c },
+	{ 0x20c07000, 0x00000020 },
+	{ 0x000000c6, 0x00000012 },
+	{ 0x00800000, 0x00000006 },
+	{ 0x0080751d, 0x00000006 },
+	{ 0x000025bb, 0x00000002 },
+	{ 0x000040c0, 0x00000004 },
+	{ 0x0000775c, 0x00000002 },
+	{ 0x00a05000, 0x00000002 },
+	{ 0x00661000, 0x00000002 },
+	{ 0x0460275d, 0x00000020 },
+	{ 0x00004000, 0000000000 },
+	{ 0x00007999, 0x00000002 },
+	{ 0x00a05000, 0x00000002 },
+	{ 0x00661000, 0x00000002 },
+	{ 0x0460299b, 0x00000020 },
+	{ 0x00004000, 0000000000 },
+	{ 0x01e00830, 0x00000002 },
+	{ 0x21007000, 0000000000 },
+	{ 0x00005000, 0x00000002 },
+	{ 0x00038042, 0x00000002 },
+	{ 0x040025e0, 0x00000002 },
+	{ 0x000075e1, 0000000000 },
+	{ 0x00000001, 0000000000 },
+	{ 0x000380d9, 0x00000002 },
+	{ 0x04007394, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+	{ 0000000000, 0000000000 },
+};
+
+
 static u32 radeon_cp_microcode[][2] = {
 	{ 0x21007000, 0000000000 },
 	{ 0x20007000, 0000000000 },
@@ -349,6 +605,8 @@
 	u32 tmp;
 	int i;
 
+	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
 	tmp  = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT );
 	tmp |= RADEON_RB2D_DC_FLUSH_ALL;
 	RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp );
@@ -358,14 +616,14 @@
 		       & RADEON_RB2D_DC_BUSY) ) {
 			return 0;
 		}
-		udelay( 1 );
+		DRM_UDELAY( 1 );
 	}
 
 #if RADEON_FIFO_DEBUG
 	DRM_ERROR( "failed!\n" );
 	radeon_status( dev_priv );
 #endif
-	return -EBUSY;
+	return DRM_ERR(EBUSY);
 }
 
 static int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv,
@@ -373,26 +631,30 @@
 {
 	int i;
 
+	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
 	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
 		int slots = ( RADEON_READ( RADEON_RBBM_STATUS )
 			      & RADEON_RBBM_FIFOCNT_MASK );
 		if ( slots >= entries ) return 0;
-		udelay( 1 );
+		DRM_UDELAY( 1 );
 	}
 
 #if RADEON_FIFO_DEBUG
 	DRM_ERROR( "failed!\n" );
 	radeon_status( dev_priv );
 #endif
-	return -EBUSY;
+	return DRM_ERR(EBUSY);
 }
 
 static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv )
 {
 	int i, ret;
 
+	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
 	ret = radeon_do_wait_for_fifo( dev_priv, 64 );
-	if ( ret < 0 ) return ret;
+	if ( ret ) return ret;
 
 	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
 		if ( !(RADEON_READ( RADEON_RBBM_STATUS )
@@ -400,14 +662,14 @@
 			radeon_do_pixcache_flush( dev_priv );
 			return 0;
 		}
-		udelay( 1 );
+		DRM_UDELAY( 1 );
 	}
 
 #if RADEON_FIFO_DEBUG
 	DRM_ERROR( "failed!\n" );
 	radeon_status( dev_priv );
 #endif
-	return -EBUSY;
+	return DRM_ERR(EBUSY);
 }
 
 
@@ -419,16 +681,31 @@
 static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv )
 {
 	int i;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	radeon_do_wait_for_idle( dev_priv );
 
 	RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 );
-	for ( i = 0 ; i < 256 ; i++ ) {
-		RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
-			      radeon_cp_microcode[i][1] );
-		RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
-			      radeon_cp_microcode[i][0] );
+
+	if (dev_priv->is_r200)
+	{
+		DRM_INFO("Loading R200 Microcode\n");
+		for ( i = 0 ; i < 256 ; i++ ) 
+		{
+			RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
+				      R200_cp_microcode[i][1] );
+			RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
+				      R200_cp_microcode[i][0] );
+		}
+	}
+	else
+	{
+		for ( i = 0 ; i < 256 ; i++ ) {
+			RADEON_WRITE( RADEON_CP_ME_RAM_DATAH,
+				      radeon_cp_microcode[i][1] );
+			RADEON_WRITE( RADEON_CP_ME_RAM_DATAL,
+				      radeon_cp_microcode[i][0] );
+		}
 	}
 }
 
@@ -438,7 +715,7 @@
  */
 static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv )
 {
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 #if 0
 	u32 tmp;
 
@@ -452,7 +729,7 @@
 int radeon_do_cp_idle( drm_radeon_private_t *dev_priv )
 {
 	RING_LOCALS;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	BEGIN_RING( 6 );
 
@@ -471,7 +748,7 @@
 static void radeon_do_cp_start( drm_radeon_private_t *dev_priv )
 {
 	RING_LOCALS;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	radeon_do_wait_for_idle( dev_priv );
 
@@ -496,7 +773,7 @@
 static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv )
 {
 	u32 cur_read_ptr;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR );
 	RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr );
@@ -510,7 +787,7 @@
  */
 static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv )
 {
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS );
 
@@ -523,7 +800,7 @@
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	radeon_do_pixcache_flush( dev_priv );
 
@@ -632,6 +909,34 @@
 			   entry->handle + tmp_ofs );
 	}
 
+	/* Initialize the scratch register pointer.  This will cause
+	 * the scratch register values to be written out to memory
+	 * whenever they are updated.
+	 *
+	 * We simply put this behind the ring read pointer, this works
+	 * with PCI GART as well as (whatever kind of) AGP GART
+	 */
+	RADEON_WRITE( RADEON_SCRATCH_ADDR, RADEON_READ( RADEON_CP_RB_RPTR_ADDR )
+					 + RADEON_SCRATCH_REG_OFFSET );
+
+	dev_priv->scratch = ((__volatile__ u32 *)
+			     dev_priv->ring.head +
+			     (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
+
+	RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 );
+
+	dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0;
+	RADEON_WRITE( RADEON_LAST_FRAME_REG,
+		      dev_priv->sarea_priv->last_frame );
+
+	dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0;
+	RADEON_WRITE( RADEON_LAST_DISPATCH_REG,
+		      dev_priv->sarea_priv->last_dispatch );
+
+	dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0;
+	RADEON_WRITE( RADEON_LAST_CLEAR_REG,
+		      dev_priv->sarea_priv->last_clear );
+
 	/* Set ring buffer size */
 #ifdef __BIG_ENDIAN
 	RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw | RADEON_BUF_SWAP_32BIT );
@@ -656,13 +961,12 @@
 static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
 {
 	drm_radeon_private_t *dev_priv;
-	struct list_head *list;
 	u32 tmp;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
 	if ( dev_priv == NULL )
-		return -ENOMEM;
+		return DRM_ERR(ENOMEM);
 
 	memset( dev_priv, 0, sizeof(drm_radeon_private_t) );
 
@@ -675,7 +979,7 @@
 		DRM_ERROR( "PCI GART not yet supported for Radeon!\n" );
 		dev->dev_private = (void *)dev_priv;
 		radeon_do_cleanup_cp(dev);
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 #endif
 
@@ -683,7 +987,7 @@
 		DRM_ERROR( "PCI GART memory not allocated!\n" );
 		dev->dev_private = (void *)dev_priv;
 		radeon_do_cleanup_cp(dev);
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	dev_priv->usec_timeout = init->usec_timeout;
@@ -692,15 +996,13 @@
 		DRM_DEBUG( "TIMEOUT problem!\n" );
 		dev->dev_private = (void *)dev_priv;
 		radeon_do_cleanup_cp(dev);
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
+	dev_priv->is_r200 = (init->func == RADEON_INIT_R200_CP);
+	dev_priv->do_boxes = 1;
 	dev_priv->cp_mode = init->cp_mode;
 
-	/* Simple idle check.
-	 */
-	atomic_set( &dev_priv->idle_count, 0 );
-
 	/* We don't support anything other than bus-mastering ring mode,
 	 * but the ring can be in either AGP or PCI space for the ring
 	 * read pointer.
@@ -710,7 +1012,7 @@
 		DRM_DEBUG( "BAD cp_mode (%x)!\n", init->cp_mode );
 		dev->dev_private = (void *)dev_priv;
 		radeon_do_cleanup_cp(dev);
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	switch ( init->fb_bpp ) {
@@ -776,20 +1078,13 @@
 					 RADEON_ROUND_MODE_TRUNC |
 					 RADEON_ROUND_PREC_8TH_PIX);
 
-	list_for_each(list, &dev->maplist->head) {
-		drm_map_list_t *r_list = (drm_map_list_t *)list;
-		if( r_list->map &&
-		    r_list->map->type == _DRM_SHM &&
-		    r_list->map->flags & _DRM_CONTAINS_LOCK ) {
-			dev_priv->sarea = r_list->map;
- 			break;
- 		}
- 	}
+	DRM_GETSAREA();
+	
 	if(!dev_priv->sarea) {
 		DRM_ERROR("could not find sarea!\n");
 		dev->dev_private = (void *)dev_priv;
 		radeon_do_cleanup_cp(dev);
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	DRM_FIND_MAP( dev_priv->fb, init->fb_offset );
@@ -797,35 +1092,35 @@
 		DRM_ERROR("could not find framebuffer!\n");
 		dev->dev_private = (void *)dev_priv;
 		radeon_do_cleanup_cp(dev);
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	DRM_FIND_MAP( dev_priv->mmio, init->mmio_offset );
 	if(!dev_priv->mmio) {
 		DRM_ERROR("could not find mmio region!\n");
 		dev->dev_private = (void *)dev_priv;
 		radeon_do_cleanup_cp(dev);
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	DRM_FIND_MAP( dev_priv->cp_ring, init->ring_offset );
 	if(!dev_priv->cp_ring) {
 		DRM_ERROR("could not find cp ring region!\n");
 		dev->dev_private = (void *)dev_priv;
 		radeon_do_cleanup_cp(dev);
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	DRM_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset );
 	if(!dev_priv->ring_rptr) {
 		DRM_ERROR("could not find ring read pointer!\n");
 		dev->dev_private = (void *)dev_priv;
 		radeon_do_cleanup_cp(dev);
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset );
 	if(!dev_priv->buffers) {
 		DRM_ERROR("could not find dma buffer region!\n");
 		dev->dev_private = (void *)dev_priv;
 		radeon_do_cleanup_cp(dev);
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	if ( !dev_priv->is_pci ) {
@@ -835,7 +1130,7 @@
 			DRM_ERROR("could not find agp texture region!\n");
 			dev->dev_private = (void *)dev_priv;
 			radeon_do_cleanup_cp(dev);
-			return -EINVAL;
+			return DRM_ERR(EINVAL);
 		}
 	}
 
@@ -853,7 +1148,7 @@
 			DRM_ERROR("could not find ioremap agp regions!\n");
 			dev->dev_private = (void *)dev_priv;
 			radeon_do_cleanup_cp(dev);
-			return -EINVAL;
+			return DRM_ERR(EINVAL);
 		}
 	} else {
 		dev_priv->cp_ring->handle =
@@ -905,41 +1200,14 @@
 
 	dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
 
-#if 0
-	/* Initialize the scratch register pointer.  This will cause
-	 * the scratch register values to be written out to memory
-	 * whenever they are updated.
-	 * FIXME: This doesn't quite work yet, so we're disabling it
-	 * for the release.
-	 */
-	RADEON_WRITE( RADEON_SCRATCH_ADDR, (dev_priv->ring_rptr->offset +
-					    RADEON_SCRATCH_REG_OFFSET) );
-	RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 );
-#endif
-
-	dev_priv->scratch = ((__volatile__ u32 *)
-			     dev_priv->ring_rptr->handle +
-			     (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
-
-	dev_priv->sarea_priv->last_frame = 0;
-	RADEON_WRITE( RADEON_LAST_FRAME_REG,
-		      dev_priv->sarea_priv->last_frame );
-
-	dev_priv->sarea_priv->last_dispatch = 0;
-	RADEON_WRITE( RADEON_LAST_DISPATCH_REG,
-		      dev_priv->sarea_priv->last_dispatch );
-
-	dev_priv->sarea_priv->last_clear = 0;
-	RADEON_WRITE( RADEON_LAST_CLEAR_REG,
-		      dev_priv->sarea_priv->last_clear );
-
+#if __REALLY_HAVE_SG
 	if ( dev_priv->is_pci ) {
 		if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
 					    &dev_priv->bus_pci_gart)) {
 			DRM_ERROR( "failed to init PCI GART!\n" );
 			dev->dev_private = (void *)dev_priv;
 			radeon_do_cleanup_cp(dev);
-			return -ENOMEM;
+			return DRM_ERR(ENOMEM);
 		}
 		/* Turn on PCI GART
 		 */
@@ -962,12 +1230,15 @@
 		RADEON_WRITE( RADEON_MC_AGP_LOCATION, 0xffffffc0 ); /* ?? */
 		RADEON_WRITE( RADEON_AGP_COMMAND, 0 ); /* clear AGP_COMMAND */
 	} else {
+#endif /* __REALLY_HAVE_SG */
 		/* Turn off PCI GART
 		 */
 		tmp = RADEON_READ( RADEON_AIC_CNTL )
 		      & ~RADEON_PCIGART_TRANSLATE_EN;
 		RADEON_WRITE( RADEON_AIC_CNTL, tmp );
+#if __REALLY_HAVE_SG
 	}
+#endif /* __REALLY_HAVE_SG */
 
 	radeon_cp_load_microcode( dev_priv );
 	radeon_cp_init_ring_buffer( dev, dev_priv );
@@ -983,7 +1254,7 @@
 
 int radeon_do_cleanup_cp( drm_device_t *dev )
 {
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	if ( dev->dev_private ) {
 		drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -993,10 +1264,12 @@
 			DRM_IOREMAPFREE( dev_priv->ring_rptr );
 			DRM_IOREMAPFREE( dev_priv->buffers );
 		} else {
+#if __REALLY_HAVE_SG
 			if (!DRM(ati_pcigart_cleanup)( dev,
 						dev_priv->phys_pci_gart,
 						dev_priv->bus_pci_gart ))
 				DRM_ERROR( "failed to cleanup PCI GART!\n" );
+#endif /* __REALLY_HAVE_SG */
 		}
 
 		DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
@@ -1007,43 +1280,39 @@
 	return 0;
 }
 
-int radeon_cp_init( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
+int radeon_cp_init( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_init_t init;
 
-	if ( copy_from_user( &init, (drm_radeon_init_t *)arg, sizeof(init) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( init, (drm_radeon_init_t *)data, sizeof(init) );
 
 	switch ( init.func ) {
 	case RADEON_INIT_CP:
+	case RADEON_INIT_R200_CP:
 		return radeon_do_init_cp( dev, &init );
 	case RADEON_CLEANUP_CP:
 		return radeon_do_cleanup_cp( dev );
 	}
 
-	return -EINVAL;
+	return DRM_ERR(EINVAL);
 }
 
-int radeon_cp_start( struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg )
+int radeon_cp_start( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( dev_priv->cp_running ) {
-		DRM_DEBUG( "%s while CP running\n", __FUNCTION__ );
+		DRM_DEBUG( "%s while CP running\n", __func__ );
 		return 0;
 	}
 	if ( dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS ) {
 		DRM_DEBUG( "%s called with bogus CP mode (%d)\n",
-			   __FUNCTION__, dev_priv->cp_mode );
+			   __func__, dev_priv->cp_mode );
 		return 0;
 	}
 
@@ -1055,20 +1324,17 @@
 /* Stop the CP.  The engine must have been idled before calling this
  * routine.
  */
-int radeon_cp_stop( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
+int radeon_cp_stop( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_radeon_cp_stop_t stop;
 	int ret;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &stop, (drm_radeon_init_t *)arg, sizeof(stop) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( stop, (drm_radeon_cp_stop_t *)data, sizeof(stop) );
 
 	/* Flush any pending CP commands.  This ensures any outstanding
 	 * commands are exectuted by the engine before we turn it off.
@@ -1082,7 +1348,7 @@
 	 */
 	if ( stop.idle ) {
 		ret = radeon_do_cp_idle( dev_priv );
-		if ( ret < 0 ) return ret;
+		if ( ret ) return ret;
 	}
 
 	/* Finally, we can turn off the CP.  If the engine isn't idle,
@@ -1099,19 +1365,17 @@
 
 /* Just reset the CP ring.  Called as part of an X Server engine reset.
  */
-int radeon_cp_reset( struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg )
+int radeon_cp_reset( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( !dev_priv ) {
-		DRM_DEBUG( "%s called before init done\n", __FUNCTION__ );
-		return -EINVAL;
+		DRM_DEBUG( "%s called before init done\n", __func__ );
+		return DRM_ERR(EINVAL);
 	}
 
 	radeon_do_cp_reset( dev_priv );
@@ -1122,25 +1386,21 @@
 	return 0;
 }
 
-int radeon_cp_idle( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
+int radeon_cp_idle( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
 	return radeon_do_cp_idle( dev_priv );
 }
 
-int radeon_engine_reset( struct inode *inode, struct file *filp,
-			 unsigned int cmd, unsigned long arg )
+int radeon_engine_reset( DRM_IOCTL_ARGS )
 {
-        drm_file_t *priv = filp->private_data;
-        drm_device_t *dev = priv->dev;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEVICE;
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
@@ -1154,8 +1414,7 @@
 
 /* KW: Deprecated to say the least:
  */
-int radeon_fullscreen( struct inode *inode, struct file *filp,
-		       unsigned int cmd, unsigned long arg )
+int radeon_fullscreen( DRM_IOCTL_ARGS )
 {
 	return 0;
 }
@@ -1172,6 +1431,14 @@
  *   completed rendering.  
  *
  * KW:  It's also a good way to find free buffers quickly.
+ *
+ * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't
+ * sleep.  However, bugs in older versions of radeon_accel.c mean that
+ * we essentially have to do this, else old clients will break.
+ * 
+ * However, it does leave open a potential deadlock where all the
+ * buffers are held by other clients, which can't release them because
+ * they can't get the lock.  
  */
 
 drm_buf_t *radeon_freelist_get( drm_device_t *dev )
@@ -1189,23 +1456,63 @@
 	start = dev_priv->last_buf;
 
 	for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
-		u32 done_age = RADEON_READ( RADEON_LAST_DISPATCH_REG );
+		u32 done_age = DRM_READ32(&dev_priv->scratch[1]);
+
 		for ( i = start ; i < dma->buf_count ; i++ ) {
 			buf = dma->buflist[i];
 			buf_priv = buf->dev_private;
 			if ( buf->pid == 0 || (buf->pending && 
 					       buf_priv->age <= done_age) ) {
+				dev_priv->stats.requested_bufs++;
 				buf->pending = 0;
 				return buf;
 			}
 			start = 0;
 		}
-		udelay( 1 );
+
+		if (t) {
+			DRM_UDELAY( 1 );
+			dev_priv->stats.freelist_loops++;
+		}
 	}
 
 	DRM_ERROR( "returning NULL!\n" );
 	return NULL;
 }
+#if 0
+drm_buf_t *radeon_freelist_get( drm_device_t *dev )
+{
+	drm_device_dma_t *dma = dev->dma;
+	drm_radeon_private_t *dev_priv = dev->dev_private;
+	drm_radeon_buf_priv_t *buf_priv;
+	drm_buf_t *buf;
+	int i, t;
+	int start;
+	u32 done_age = DRM_READ32(&dev_priv->scratch[1]);
+
+	if ( ++dev_priv->last_buf >= dma->buf_count )
+		dev_priv->last_buf = 0;
+
+	start = dev_priv->last_buf;
+	dev_priv->stats.freelist_loops++;
+	
+	for ( t = 0 ; t < 2 ; t++ ) {
+		for ( i = start ; i < dma->buf_count ; i++ ) {
+			buf = dma->buflist[i];
+			buf_priv = buf->dev_private;
+			if ( buf->pid == 0 || (buf->pending && 
+					       buf_priv->age <= done_age) ) {
+				dev_priv->stats.requested_bufs++;
+				buf->pending = 0;
+				return buf;
+			}
+		}
+		start = 0;
+	}
+
+	return NULL;
+}
+#endif
 
 void radeon_freelist_reset( drm_device_t *dev )
 {
@@ -1230,12 +1537,24 @@
 {
 	drm_radeon_ring_buffer_t *ring = &dev_priv->ring;
 	int i;
+	u32 last_head = GET_RING_HEAD(ring);
 
 	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
-		radeon_update_ring_snapshot( ring );
+		u32 head = GET_RING_HEAD(ring);
+
+		ring->space = (head - ring->tail) * sizeof(u32);
+		if ( ring->space <= 0 )
+			ring->space += ring->size;
 		if ( ring->space > n )
 			return 0;
-		udelay( 1 );
+		
+		dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
+		if (head != last_head)
+			i = 0;
+		last_head = head;
+
+		DRM_UDELAY( 1 );
 	}
 
 	/* FIXME: This return value is ignored in the BEGIN_RING macro! */
@@ -1243,7 +1562,7 @@
 	radeon_status( dev_priv );
 	DRM_ERROR( "failed!\n" );
 #endif
-	return -EBUSY;
+	return DRM_ERR(EBUSY);
 }
 
 static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d )
@@ -1253,50 +1572,47 @@
 
 	for ( i = d->granted_count ; i < d->request_count ; i++ ) {
 		buf = radeon_freelist_get( dev );
-		if ( !buf ) return -EAGAIN;
+		if ( !buf ) return DRM_ERR(EBUSY); /* NOTE: broken client */
 
-		buf->pid = current->pid;
+		buf->pid = DRM_CURRENTPID;
 
-		if ( copy_to_user( &d->request_indices[i], &buf->idx,
+		if ( DRM_COPY_TO_USER( &d->request_indices[i], &buf->idx,
 				   sizeof(buf->idx) ) )
-			return -EFAULT;
-		if ( copy_to_user( &d->request_sizes[i], &buf->total,
+			return DRM_ERR(EFAULT);
+		if ( DRM_COPY_TO_USER( &d->request_sizes[i], &buf->total,
 				   sizeof(buf->total) ) )
-			return -EFAULT;
+			return DRM_ERR(EFAULT);
 
 		d->granted_count++;
 	}
 	return 0;
 }
 
-int radeon_cp_buffers( struct inode *inode, struct file *filp,
-		       unsigned int cmd, unsigned long arg )
+int radeon_cp_buffers( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_device_dma_t *dma = dev->dma;
 	int ret = 0;
 	drm_dma_t d;
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &d, (drm_dma_t *)arg, sizeof(d) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( d, (drm_dma_t *)data, sizeof(d) );
 
 	/* Please don't send us buffers.
 	 */
 	if ( d.send_count != 0 ) {
 		DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n",
-			   current->pid, d.send_count );
-		return -EINVAL;
+			   DRM_CURRENTPID, d.send_count );
+		return DRM_ERR(EINVAL);
 	}
 
 	/* We'll send you buffers.
 	 */
 	if ( d.request_count < 0 || d.request_count > dma->buf_count ) {
 		DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n",
-			   current->pid, d.request_count, dma->buf_count );
-		return -EINVAL;
+			   DRM_CURRENTPID, d.request_count, dma->buf_count );
+		return DRM_ERR(EINVAL);
 	}
 
 	d.granted_count = 0;
@@ -1305,8 +1621,7 @@
 		ret = radeon_cp_get_buffers( dev, &d );
 	}
 
-	if ( copy_to_user( (drm_dma_t *)arg, &d, sizeof(d) ) )
-		return -EFAULT;
+	DRM_COPY_TO_USER_IOCTL( (drm_dma_t *)data, d, sizeof(d) );
 
 	return ret;
 }
diff -Nru a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
--- a/drivers/char/drm/radeon_drm.h	Sat Aug 10 18:42:23 2002
+++ b/drivers/char/drm/radeon_drm.h	Sat Aug 10 18:42:23 2002
@@ -89,7 +89,47 @@
 #define RADEON_EMIT_SE_ZBIAS_FACTOR                 18 /* zbias/2 */
 #define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT           19 /* tcl/11 */
 #define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED   20 /* material/17 */
-#define RADEON_MAX_STATE_PACKETS                    21
+#define R200_EMIT_PP_TXCBLEND_0                     21 /* tex0/4 */
+#define R200_EMIT_PP_TXCBLEND_1                     22 /* tex1/4 */
+#define R200_EMIT_PP_TXCBLEND_2                     23 /* tex2/4 */
+#define R200_EMIT_PP_TXCBLEND_3                     24 /* tex3/4 */
+#define R200_EMIT_PP_TXCBLEND_4                     25 /* tex4/4 */
+#define R200_EMIT_PP_TXCBLEND_5                     26 /* tex5/4 */
+#define R200_EMIT_PP_TXCBLEND_6                     27 /* /4 */
+#define R200_EMIT_PP_TXCBLEND_7                     28 /* /4 */
+#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0             29 /* tcl/7 */
+#define R200_EMIT_TFACTOR_0                         30 /* tf/7 */
+#define R200_EMIT_VTX_FMT_0                         31 /* vtx/5 */
+#define R200_EMIT_VAP_CTL                           32 /* vap/1 */
+#define R200_EMIT_MATRIX_SELECT_0                   33 /* msl/5 */
+#define R200_EMIT_TEX_PROC_CTL_2                    34 /* tcg/5 */
+#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL            35 /* tcl/1 */
+#define R200_EMIT_PP_TXFILTER_0                     36 /* tex0/6 */
+#define R200_EMIT_PP_TXFILTER_1                     37 /* tex1/6 */
+#define R200_EMIT_PP_TXFILTER_2                     38 /* tex2/6 */
+#define R200_EMIT_PP_TXFILTER_3                     39 /* tex3/6 */
+#define R200_EMIT_PP_TXFILTER_4                     40 /* tex4/6 */
+#define R200_EMIT_PP_TXFILTER_5                     41 /* tex5/6 */
+#define R200_EMIT_PP_TXOFFSET_0                     42 /* tex0/1 */
+#define R200_EMIT_PP_TXOFFSET_1                     43 /* tex1/1 */
+#define R200_EMIT_PP_TXOFFSET_2                     44 /* tex2/1 */
+#define R200_EMIT_PP_TXOFFSET_3                     45 /* tex3/1 */
+#define R200_EMIT_PP_TXOFFSET_4                     46 /* tex4/1 */
+#define R200_EMIT_PP_TXOFFSET_5                     47 /* tex5/1 */
+#define R200_EMIT_VTE_CNTL                          48 /* vte/1 */
+#define R200_EMIT_OUTPUT_VTX_COMP_SEL               49 /* vtx/1 */
+#define R200_EMIT_PP_TAM_DEBUG3                     50 /* tam/1 */
+#define R200_EMIT_PP_CNTL_X                         51 /* cst/1 */
+#define R200_EMIT_RB3D_DEPTHXY_OFFSET               52 /* cst/1 */
+#define R200_EMIT_RE_AUX_SCISSOR_CNTL               53 /* cst/1 */
+#define R200_EMIT_RE_SCISSOR_TL_0                   54 /* cst/2 */
+#define R200_EMIT_RE_SCISSOR_TL_1                   55 /* cst/2 */
+#define R200_EMIT_RE_SCISSOR_TL_2                   56 /* cst/2 */
+#define R200_EMIT_SE_VAP_CNTL_STATUS                57 /* cst/1 */
+#define R200_EMIT_SE_VTX_STATE_CNTL                 58 /* cst/1 */
+#define R200_EMIT_RE_POINTSIZE                      59 /* cst/1 */
+#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0       60 /* cst/4 */
+#define RADEON_MAX_STATE_PACKETS                    61
 
 
 /* Commands understood by cmd_buffer ioctl.  More can be added but
@@ -101,24 +141,25 @@
 #define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */
 #define RADEON_CMD_PACKET3     5 /* emit hw packet */
 #define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
+#define RADEON_CMD_SCALARS2     7 /* r200 stopgap */
 
 
 typedef union {
 	int i;
 	struct { 
-		char cmd_type, pad0, pad1, pad2;
+		unsigned char cmd_type, pad0, pad1, pad2;
 	} header;
 	struct { 
-		char cmd_type, packet_id, pad0, pad1;
+		unsigned char cmd_type, packet_id, pad0, pad1;
 	} packet;
 	struct { 
-		char cmd_type, offset, stride, count; 
+		unsigned char cmd_type, offset, stride, count; 
 	} scalars;
 	struct { 
-		char cmd_type, offset, stride, count; 
+		unsigned char cmd_type, offset, stride, count; 
 	} vectors;
 	struct { 
-		char cmd_type, buf_idx, pad0, pad1; 
+		unsigned char cmd_type, buf_idx, pad0, pad1; 
 	} dma;
 } drm_radeon_cmd_header_t;
 
@@ -327,7 +368,8 @@
 typedef struct drm_radeon_init {
 	enum {
 		RADEON_INIT_CP    = 0x01,
-		RADEON_CLEANUP_CP = 0x02
+		RADEON_CLEANUP_CP = 0x02,
+		RADEON_INIT_R200_CP = 0x03,	
 	} func;
 	unsigned long sarea_priv_offset;
 	int is_pci;
@@ -458,6 +500,9 @@
  * client any other way.  
  */
 #define RADEON_PARAM_AGP_BUFFER_OFFSET 0x1
+#define RADEON_PARAM_LAST_FRAME 0x2
+#define RADEON_PARAM_LAST_DISPATCH 0x3
+#define RADEON_PARAM_LAST_CLEAR 0x4
 
 typedef struct drm_radeon_getparam {
 	int param;
diff -Nru a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
--- a/drivers/char/drm/radeon_drv.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/char/drm/radeon_drv.c	Sat Aug 10 18:42:21 2002
@@ -35,49 +35,6 @@
 #include "radeon_drv.h"
 #include "ati_pcigart.h"
 
-#define DRIVER_AUTHOR		"Gareth Hughes, VA Linux Systems Inc."
-
-#define DRIVER_NAME		"radeon"
-#define DRIVER_DESC		"ATI Radeon"
-#define DRIVER_DATE		"20020611"
-
-#define DRIVER_MAJOR		1
-#define DRIVER_MINOR		3
-#define DRIVER_PATCHLEVEL	1
-
-/* Interface history:
- *
- * 1.1 - ??
- * 1.2 - Add vertex2 ioctl (keith)
- *     - Add stencil capability to clear ioctl (gareth, keith)
- *     - Increase MAX_TEXTURE_LEVELS (brian)
- * 1.3 - Add cmdbuf ioctl (keith)
- *     - Add support for new radeon packets (keith)
- *     - Add getparam ioctl (keith)
- *     - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
- */
-#define DRIVER_IOCTLS							     \
- [DRM_IOCTL_NR(DRM_IOCTL_DMA)]               = { radeon_cp_buffers,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)]    = { radeon_cp_init,     1, 1 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)]   = { radeon_cp_start,    1, 1 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)]    = { radeon_cp_stop,     1, 1 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)]   = { radeon_cp_reset,    1, 1 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)]    = { radeon_cp_idle,     1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)]    = { radeon_engine_reset,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)]       = { radeon_cp_swap,     1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)]      = { radeon_cp_clear,    1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)]     = { radeon_cp_vertex,   1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)]    = { radeon_cp_indices,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_TEXTURE)]    = { radeon_cp_texture,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)]    = { radeon_cp_stipple,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]   = { radeon_cp_indirect, 1, 1 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)]    = { radeon_cp_vertex2,  1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)]     = { radeon_cp_cmdbuf,   1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)]   = { radeon_cp_getparam, 1, 0 }, \
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FLIP)]       = { radeon_cp_flip,     1, 0 }, 
-
-
 #include "drm_agpsupport.h"
 #include "drm_auth.h"
 #include "drm_bufs.h"
@@ -85,26 +42,6 @@
 #include "drm_dma.h"
 #include "drm_drawable.h"
 #include "drm_drv.h"
-
-#ifndef MODULE
-/* DRM(options) is called by the kernel to parse command-line options
- * passed via the boot-loader (e.g., LILO).  It calls the insmod option
- * routine, drm_parse_drm.
- */
-
-/* JH- We have to hand expand the string ourselves because of the cpp.  If
- * anyone can think of a way that we can fit into the __setup macro without
- * changing it, then please send the solution my way.
- */
-static int __init radeon_options( char *str )
-{
-	DRM(parse_options)( str );
-	return 1;
-}
-
-__setup( DRIVER_NAME "=", radeon_options );
-#endif
-
 #include "drm_fops.h"
 #include "drm_init.h"
 #include "drm_ioctl.h"
diff -Nru a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
--- a/drivers/char/drm/radeon_drv.h	Sat Aug 10 18:42:23 2002
+++ b/drivers/char/drm/radeon_drv.h	Sat Aug 10 18:42:23 2002
@@ -31,8 +31,8 @@
 #ifndef __RADEON_DRV_H__
 #define __RADEON_DRV_H__
 
-#define GET_RING_HEAD(ring)		readl( (volatile u32 *) (ring)->head )
-#define SET_RING_HEAD(ring,val)		writel( (val), (volatile u32 *) (ring)->head )
+#define GET_RING_HEAD(ring)		DRM_READ32(  (volatile u32 *) (ring)->head )
+#define SET_RING_HEAD(ring,val)		DRM_WRITE32( (volatile u32 *) (ring)->head , (val))
 
 typedef struct drm_radeon_freelist {
    	unsigned int age;
@@ -78,12 +78,25 @@
 	volatile u32 *scratch;
 
 	int usec_timeout;
+
+	int is_r200;
+
 	int is_pci;
 	unsigned long phys_pci_gart;
 	dma_addr_t bus_pci_gart;
 
-	atomic_t idle_count;
+	struct {
+		u32 boxes;
+		int freelist_timeouts;
+		int freelist_loops;
+		int requested_bufs;
+		int last_frame_reads;
+		int last_clear_reads;
+		int clears;
+		int texture_uploads;
+	} stats;
 
+	int do_boxes;
 	int page_flipping;
 	int current_page;
 	u32 crtc_offset;
@@ -119,63 +132,44 @@
 } drm_radeon_buf_priv_t;
 
 				/* radeon_cp.c */
-extern int radeon_cp_init( struct inode *inode, struct file *filp,
-			   unsigned int cmd, unsigned long arg );
-extern int radeon_cp_start( struct inode *inode, struct file *filp,
-			    unsigned int cmd, unsigned long arg );
-extern int radeon_cp_stop( struct inode *inode, struct file *filp,
-			   unsigned int cmd, unsigned long arg );
-extern int radeon_cp_reset( struct inode *inode, struct file *filp,
-			    unsigned int cmd, unsigned long arg );
-extern int radeon_cp_idle( struct inode *inode, struct file *filp,
-			   unsigned int cmd, unsigned long arg );
-extern int radeon_engine_reset( struct inode *inode, struct file *filp,
-				unsigned int cmd, unsigned long arg );
-extern int radeon_fullscreen( struct inode *inode, struct file *filp,
-			      unsigned int cmd, unsigned long arg );
-extern int radeon_cp_buffers( struct inode *inode, struct file *filp,
-			      unsigned int cmd, unsigned long arg );
+extern int radeon_cp_init( DRM_IOCTL_ARGS );
+extern int radeon_cp_start( DRM_IOCTL_ARGS );
+extern int radeon_cp_stop( DRM_IOCTL_ARGS );
+extern int radeon_cp_reset( DRM_IOCTL_ARGS );
+extern int radeon_cp_idle( DRM_IOCTL_ARGS );
+extern int radeon_engine_reset( DRM_IOCTL_ARGS );
+extern int radeon_fullscreen( DRM_IOCTL_ARGS );
+extern int radeon_cp_buffers( DRM_IOCTL_ARGS );
 
 extern void radeon_freelist_reset( drm_device_t *dev );
 extern drm_buf_t *radeon_freelist_get( drm_device_t *dev );
 
 extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n );
 
-static inline void
-radeon_update_ring_snapshot( drm_radeon_ring_buffer_t *ring )
-{
-	ring->space = (GET_RING_HEAD(ring) - ring->tail) * sizeof(u32);
-	if ( ring->space <= 0 )
-		ring->space += ring->size;
-}
-
 extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv );
 extern int radeon_do_cleanup_cp( drm_device_t *dev );
 extern int radeon_do_cleanup_pageflip( drm_device_t *dev );
 
 				/* radeon_state.c */
-extern int radeon_cp_clear( struct inode *inode, struct file *filp,
-			    unsigned int cmd, unsigned long arg );
-extern int radeon_cp_swap( struct inode *inode, struct file *filp,
-			   unsigned int cmd, unsigned long arg );
-extern int radeon_cp_vertex( struct inode *inode, struct file *filp,
-			     unsigned int cmd, unsigned long arg );
-extern int radeon_cp_indices( struct inode *inode, struct file *filp,
-			      unsigned int cmd, unsigned long arg );
-extern int radeon_cp_texture( struct inode *inode, struct file *filp,
-			      unsigned int cmd, unsigned long arg );
-extern int radeon_cp_stipple( struct inode *inode, struct file *filp,
-			      unsigned int cmd, unsigned long arg );
-extern int radeon_cp_indirect( struct inode *inode, struct file *filp,
-			       unsigned int cmd, unsigned long arg );
-extern int radeon_cp_vertex2( struct inode *inode, struct file *filp,
-			      unsigned int cmd, unsigned long arg );
-extern int radeon_cp_cmdbuf( struct inode *inode, struct file *filp,
-			      unsigned int cmd, unsigned long arg );
-extern int radeon_cp_getparam( struct inode *inode, struct file *filp,
-			      unsigned int cmd, unsigned long arg );
-extern int radeon_cp_flip( struct inode *inode, struct file *filp,
-			   unsigned int cmd, unsigned long arg );
+extern int radeon_cp_clear( DRM_IOCTL_ARGS );
+extern int radeon_cp_swap( DRM_IOCTL_ARGS );
+extern int radeon_cp_vertex( DRM_IOCTL_ARGS );
+extern int radeon_cp_indices( DRM_IOCTL_ARGS );
+extern int radeon_cp_texture( DRM_IOCTL_ARGS );
+extern int radeon_cp_stipple( DRM_IOCTL_ARGS );
+extern int radeon_cp_indirect( DRM_IOCTL_ARGS );
+extern int radeon_cp_vertex2( DRM_IOCTL_ARGS );
+extern int radeon_cp_cmdbuf( DRM_IOCTL_ARGS );
+extern int radeon_cp_getparam( DRM_IOCTL_ARGS );
+extern int radeon_cp_flip( DRM_IOCTL_ARGS );
+
+/* Flags for stats.boxes
+ */
+#define RADEON_BOX_DMA_IDLE      0x1
+#define RADEON_BOX_RING_FULL     0x2
+#define RADEON_BOX_FLIP          0x4
+#define RADEON_BOX_WAIT_IDLE     0x8
+#define RADEON_BOX_TEXTURE_LOAD  0x10
 
 
 
@@ -296,6 +290,7 @@
 #	define RADEON_STENCIL_ENABLE		(1 << 7)
 #	define RADEON_Z_ENABLE			(1 << 8)
 #define RADEON_RB3D_DEPTHOFFSET		0x1c24
+#define RADEON_RB3D_DEPTHPITCH		0x1c28
 #define RADEON_RB3D_PLANEMASK		0x1d84
 #define RADEON_RB3D_STENCILREFMASK	0x1d7c
 #define RADEON_RB3D_ZCACHE_MODE		0x3250
@@ -527,6 +522,62 @@
 #define RADEON_TXFORMAT_ARGB8888	6
 #define RADEON_TXFORMAT_RGBA8888	7
 
+#define R200_PP_TXCBLEND_0                0x2f00
+#define R200_PP_TXCBLEND_1                0x2f10
+#define R200_PP_TXCBLEND_2                0x2f20
+#define R200_PP_TXCBLEND_3                0x2f30
+#define R200_PP_TXCBLEND_4                0x2f40
+#define R200_PP_TXCBLEND_5                0x2f50
+#define R200_PP_TXCBLEND_6                0x2f60
+#define R200_PP_TXCBLEND_7                0x2f70
+#define R200_SE_TCL_LIGHT_MODEL_CTL_0     0x2268 
+#define R200_PP_TFACTOR_0                 0x2ee0
+#define R200_SE_VTX_FMT_0                 0x2088
+#define R200_SE_VAP_CNTL                  0x2080
+#define R200_SE_TCL_MATRIX_SEL_0          0x2230
+#define R200_SE_TCL_TEX_PROC_CTL_2        0x22a8 
+#define R200_SE_TCL_UCP_VERT_BLEND_CTL    0x22c0 
+#define R200_PP_TXFILTER_5                0x2ca0 
+#define R200_PP_TXFILTER_4                0x2c80 
+#define R200_PP_TXFILTER_3                0x2c60 
+#define R200_PP_TXFILTER_2                0x2c40 
+#define R200_PP_TXFILTER_1                0x2c20 
+#define R200_PP_TXFILTER_0                0x2c00 
+#define R200_PP_TXOFFSET_5                0x2d78
+#define R200_PP_TXOFFSET_4                0x2d60
+#define R200_PP_TXOFFSET_3                0x2d48
+#define R200_PP_TXOFFSET_2                0x2d30
+#define R200_PP_TXOFFSET_1                0x2d18
+#define R200_PP_TXOFFSET_0                0x2d00
+#define R200_RE_AUX_SCISSOR_CNTL          0x26f0
+#define R200_SE_VTE_CNTL                  0x20b0
+#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL   0x2250
+#define R200_PP_TAM_DEBUG3                0x2d9c
+#define R200_PP_CNTL_X                    0x2cc4
+#define R200_SE_VAP_CNTL_STATUS           0x2140
+#define R200_RE_SCISSOR_TL_0              0x1cd8
+#define R200_RE_SCISSOR_TL_1              0x1ce0
+#define R200_RE_SCISSOR_TL_2              0x1ce8
+#define R200_RB3D_DEPTHXY_OFFSET          0x1d60 
+#define R200_RE_AUX_SCISSOR_CNTL          0x26f0
+#define R200_SE_VTX_STATE_CNTL            0x2180
+#define R200_RE_POINTSIZE                 0x2648
+#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254
+
+
+#define SE_VAP_CNTL__TCL_ENA_MASK                          0x00000001
+#define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK                   0x00010000
+#define SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT                 0x00000012
+#define SE_VTE_CNTL__VTX_XY_FMT_MASK                       0x00000100
+#define SE_VTE_CNTL__VTX_Z_FMT_MASK                        0x00000200
+#define SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK                  0x00000001
+#define SE_VTX_FMT_0__VTX_W0_PRESENT_MASK                  0x00000002
+#define SE_VTX_FMT_0__VTX_COLOR_0_FMT__SHIFT               0x0000000b
+#define R200_3D_DRAW_IMMD_2      0xC0003500
+#define R200_SE_VTX_FMT_1                 0x208c
+#define R200_RE_CNTL                      0x1c50 
+
+
 /* Constants */
 #define RADEON_MAX_USEC_TIMEOUT		100000	/* 100 ms */
 
@@ -544,11 +595,11 @@
 #define RADEON_BASE(reg)	((unsigned long)(dev_priv->mmio->handle))
 #define RADEON_ADDR(reg)	(RADEON_BASE( reg ) + reg)
 
-#define RADEON_READ(reg)	readl( (volatile u32 *) RADEON_ADDR(reg) )
-#define RADEON_WRITE(reg,val)	writel( (val), (volatile u32 *) RADEON_ADDR(reg) )
+#define RADEON_READ(reg)	DRM_READ32(  (volatile u32 *) RADEON_ADDR(reg) )
+#define RADEON_WRITE(reg,val)	DRM_WRITE32( (volatile u32 *) RADEON_ADDR(reg), (val) )
 
-#define RADEON_READ8(reg)	readb( (volatile u8 *) RADEON_ADDR(reg) )
-#define RADEON_WRITE8(reg,val)	writeb( (val), (volatile u8 *) RADEON_ADDR(reg) )
+#define RADEON_READ8(reg)	DRM_READ8(  (volatile u8 *) RADEON_ADDR(reg) )
+#define RADEON_WRITE8(reg,val)	DRM_WRITE8( (volatile u8 *) RADEON_ADDR(reg), (val) )
 
 #define RADEON_WRITE_PLL( addr, val )					\
 do {									\
@@ -628,36 +679,22 @@
 #define LOCK_TEST_WITH_RETURN( dev )					\
 do {									\
 	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||		\
-	     dev->lock.pid != current->pid ) {				\
-		DRM_ERROR( "%s called without lock held\n",		\
-			   __FUNCTION__ );				\
-		return -EINVAL;						\
+	     dev->lock.pid != DRM_CURRENTPID ) {			\
+		DRM_ERROR( "%s called without lock held\n", __func__ );	\
+		return DRM_ERR(EINVAL);				\
 	}								\
 } while (0)
 
+
+/* Perfbox functionality only.  
+ */
 #define RING_SPACE_TEST_WITH_RETURN( dev_priv )				\
 do {									\
-	drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i;	\
-	if ( ring->space < ring->high_mark ) {				\
-		for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {	\
-			radeon_update_ring_snapshot( ring );		\
-			if ( ring->space >= ring->high_mark )		\
-				goto __ring_space_done;			\
-			udelay( 1 );					\
-		}							\
-		DRM_ERROR( "ring space check from memory failed, reading register...\n" );	\
-		/* If ring space check fails from RAM, try reading the	\
-		   register directly */					\
-		ring->space = 4 * ( RADEON_READ( RADEON_CP_RB_RPTR ) - ring->tail );	\
-		if ( ring->space <= 0 )					\
-			ring->space += ring->size;			\
-		if ( ring->space >= ring->high_mark )			\
-			goto __ring_space_done;				\
-									\
-		DRM_ERROR( "ring space check failed!\n" );		\
-		return -EBUSY;						\
+	if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) {		\
+		u32 head = GET_RING_HEAD(&dev_priv->ring);		\
+		if (head == dev_priv->ring.tail)			\
+			dev_priv->stats.boxes |= RADEON_BOX_DMA_IDLE;	\
 	}								\
- __ring_space_done:							\
 } while (0)
 
 #define VB_AGE_TEST_WITH_RETURN( dev_priv )				\
@@ -665,7 +702,7 @@
 	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;		\
 	if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) {		\
 		int __ret = radeon_do_cp_idle( dev_priv );		\
-		if ( __ret < 0 ) return __ret;				\
+		if ( __ret ) return __ret;				\
 		sarea_priv->last_dispatch = 0;				\
 		radeon_freelist_reset( dev );				\
 	}								\
@@ -694,18 +731,18 @@
 #if defined(__powerpc__)
 #define radeon_flush_write_combine()	(void) GET_RING_HEAD( &dev_priv->ring )
 #else
-#define radeon_flush_write_combine()	mb()
+#define radeon_flush_write_combine()	DRM_WRITEMEMORYBARRIER()
 #endif
 
 
 #define RADEON_VERBOSE	0
 
-#define RING_LOCALS	int write, _nr; unsigned int mask; volatile u32 *ring;
+#define RING_LOCALS	int write, _nr; unsigned int mask; u32 *ring;
 
 #define BEGIN_RING( n ) do {						\
 	if ( RADEON_VERBOSE ) {						\
 		DRM_INFO( "BEGIN_RING( %d ) in %s\n",			\
-			   n, __FUNCTION__ );				\
+			   n, __func__ );				\
 	}								\
 	if ( dev_priv->ring.space <= (n) * sizeof(u32) ) {		\
                 COMMIT_RING();						\
@@ -724,16 +761,15 @@
 	}								\
 	if (((dev_priv->ring.tail + _nr) & mask) != write) {		\
 		DRM_ERROR( 						\
-			"ADVANCE_RING(): mismatch: nr: %x write: %x\n",	\
+			"ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n",	\
 			((dev_priv->ring.tail + _nr) & mask),		\
-			write);						\
+			write, __LINE__);						\
 	} else								\
 		dev_priv->ring.tail = write;				\
 } while (0)
 
-#define COMMIT_RING() do {						\
-	radeon_flush_write_combine();					\
-	RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail );		\
+#define COMMIT_RING() do {					    \
+	RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail );		    \
 } while (0)
 
 #define OUT_RING( x ) do {						\
@@ -757,23 +793,21 @@
 								\
 	if (write + _size > mask) {				\
 		int i = (mask+1) - write;			\
-		if (__copy_from_user( (int *)(ring+write),	\
+		if (DRM_COPY_FROM_USER_UNCHECKED( (int *)(ring+write),	\
 				      _tab, i*4 ))		\
-			return -EFAULT;				\
+			return DRM_ERR(EFAULT);		\
 		write = 0;					\
 		_size -= i;					\
 		_tab += i;					\
 	}							\
 								\
-	if (_size && __copy_from_user( (int *)(ring+write),	\
+	if (_size && DRM_COPY_FROM_USER_UNCHECKED( (int *)(ring+write),	\
 			               _tab, _size*4 ))		\
-		return -EFAULT;					\
+		return DRM_ERR(EFAULT);			\
 								\
 	write += _size;						\
 	write &= mask;						\
 } while (0)
 
-
-#define RADEON_PERFORMANCE_BOXES	0
 
 #endif /* __RADEON_DRV_H__ */
diff -Nru a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
--- a/drivers/char/drm/radeon_state.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/char/drm/radeon_state.c	Sat Aug 10 18:42:23 2002
@@ -27,20 +27,18 @@
  *    Kevin E. Martin <martin@valinux.com>
  */
 
-#define __NO_VERSION__
 #include "radeon.h"
 #include "drmP.h"
 #include "drm.h"
 #include "radeon_drm.h"
 #include "radeon_drv.h"
-#include <linux/delay.h>
 
 
 /* ================================================================
  * CP hardware state programming functions
  */
 
-static inline void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv,
+static __inline__ void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv,
 					  drm_clip_rect_t *box )
 {
 	RING_LOCALS;
@@ -48,10 +46,12 @@
 	DRM_DEBUG( "   box:  x1=%d y1=%d  x2=%d y2=%d\n",
 		   box->x1, box->y1, box->x2, box->y2 );
 
-	BEGIN_RING( 3 );
-	OUT_RING( CP_PACKET3( RADEON_CNTL_SET_SCISSORS, 1 ));
+	BEGIN_RING( 4 );
+	OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) );
 	OUT_RING( (box->y1 << 16) | box->x1 );
-	OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );
+	OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) );
+/*     OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );*/
+	OUT_RING( (box->y2 << 16) | box->x2 );
 	ADVANCE_RING();
 }
 
@@ -63,7 +63,7 @@
 			       unsigned int dirty )
 {
 	RING_LOCALS;
-	DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty );
+	DRM_DEBUG( "dirty=0x%08x\n", dirty );
 
 	if ( dirty & RADEON_UPLOAD_CONTEXT ) {
 		BEGIN_RING( 14 );
@@ -240,18 +240,50 @@
 	{ RADEON_SE_ZBIAS_FACTOR,2,"RADEON_SE_ZBIAS_FACTOR" },
 	{ RADEON_SE_TCL_OUTPUT_VTX_FMT,11,"RADEON_SE_TCL_OUTPUT_VTX_FMT" },
 	{ RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED,17,"RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED" },
+	{ R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0" },
+	{ R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1" },
+	{ R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2" },
+	{ R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3" },
+	{ R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4" },
+	{ R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5" },
+	{ R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6" },
+	{ R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7" },
+	{ R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0" },
+	{ R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0" },
+	{ R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0" },
+	{ R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL" },
+	{ R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0" },
+	{ R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2" },
+	{ R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL" },
+	{ R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0" },
+	{ R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1" },
+	{ R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2" },
+	{ R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3" },
+	{ R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4" },
+	{ R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5" },
+	{ R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0" },
+	{ R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1" },
+	{ R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2" },
+	{ R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3" },
+	{ R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4" },
+	{ R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5" },
+	{ R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL" },
+	{ R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1, "R200_SE_TCL_OUTPUT_VTX_COMP_SEL" },
+	{ R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3" },
+	{ R200_PP_CNTL_X, 1, "R200_PP_CNTL_X" }, 
+	{ R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET" }, 
+	{ R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL" }, 
+	{ R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0" }, 
+	{ R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1" }, 
+	{ R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2" }, 
+	{ R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS" }, 
+	{ R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL" }, 
+	{ R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE" }, 
+	{ R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4, "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0" },
 };
 
 
 
-
-
-
-
-
-
-
-#if RADEON_PERFORMANCE_BOXES
 /* ================================================================
  * Performance monitoring functions
  */
@@ -260,10 +292,12 @@
 			      int x, int y, int w, int h,
 			      int r, int g, int b )
 {
-	u32 pitch, offset;
 	u32 color;
 	RING_LOCALS;
 
+	x += dev_priv->sarea_priv->boxes[0].x1;
+	y += dev_priv->sarea_priv->boxes[0].y1;
+
 	switch ( dev_priv->color_fmt ) {
 	case RADEON_COLOR_FORMAT_RGB565:
 		color = (((r & 0xf8) << 8) |
@@ -276,8 +310,11 @@
 		break;
 	}
 
-	offset = dev_priv->back_offset;
-	pitch = dev_priv->back_pitch >> 3;
+	BEGIN_RING( 4 );
+	RADEON_WAIT_UNTIL_3D_IDLE();		
+	OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );
+	OUT_RING( 0xffffffff );
+	ADVANCE_RING();
 
 	BEGIN_RING( 6 );
 
@@ -289,7 +326,12 @@
 		  RADEON_ROP3_P |
 		  RADEON_GMC_CLR_CMP_CNTL_DIS );
 
-	OUT_RING( (pitch << 22) | (offset >> 5) );
+ 	if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { 
+		OUT_RING( dev_priv->front_pitch_offset );
+ 	} else {	 
+		OUT_RING( dev_priv->back_pitch_offset );
+ 	} 
+
 	OUT_RING( color );
 
 	OUT_RING( (x << 16) | y );
@@ -300,16 +342,57 @@
 
 static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv )
 {
-	if ( atomic_read( &dev_priv->idle_count ) == 0 ) {
-		radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 );
-	} else {
-		atomic_set( &dev_priv->idle_count, 0 );
+	/* Collapse various things into a wait flag -- trying to
+	 * guess if userspase slept -- better just to have them tell us.
+	 */
+	if (dev_priv->stats.last_frame_reads > 1 ||
+	    dev_priv->stats.last_clear_reads > dev_priv->stats.clears) {
+		dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
 	}
-}
 
-#endif
+	if (dev_priv->stats.freelist_loops) {
+		dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+	}
 
+	/* Purple box for page flipping
+	 */
+	if ( dev_priv->stats.boxes & RADEON_BOX_FLIP ) 
+		radeon_clear_box( dev_priv, 4, 4, 8, 8, 255, 0, 255 );
+
+	/* Red box if we have to wait for idle at any point
+	 */
+	if ( dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE ) 
+		radeon_clear_box( dev_priv, 16, 4, 8, 8, 255, 0, 0 );
 
+	/* Blue box: lost context?
+	 */
+
+	/* Yellow box for texture swaps
+	 */
+	if ( dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD ) 
+		radeon_clear_box( dev_priv, 40, 4, 8, 8, 255, 255, 0 );
+
+	/* Green box if hardware never idles (as far as we can tell)
+	 */
+	if ( !(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE) ) 
+		radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 );
+
+
+	/* Draw bars indicating number of buffers allocated 
+	 * (not a great measure, easily confused)
+	 */
+	if (dev_priv->stats.requested_bufs) {
+		if (dev_priv->stats.requested_bufs > 100)
+			dev_priv->stats.requested_bufs = 100;
+
+		radeon_clear_box( dev_priv, 4, 16,  
+				  dev_priv->stats.requested_bufs, 4,
+				  196, 128, 128 );
+	}
+
+	memset( &dev_priv->stats, 0, sizeof(dev_priv->stats) );
+
+}
 /* ================================================================
  * CP command dispatch functions
  */
@@ -327,7 +410,10 @@
 	u32 rb3d_cntl = 0, rb3d_stencilrefmask= 0;
 	int i;
 	RING_LOCALS;
-	DRM_DEBUG( __FUNCTION__": flags = 0x%x\n", flags );
+	DRM_DEBUG( "flags = 0x%x\n", flags );
+
+
+	dev_priv->stats.clears++;
 
 	if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) {
 		unsigned int tmp = flags;
@@ -337,120 +423,251 @@
 		if ( tmp & RADEON_BACK )  flags |= RADEON_FRONT;
 	}
 
+	if ( flags & (RADEON_FRONT | RADEON_BACK) ) {
+
+		BEGIN_RING( 4 );
+
+		/* Ensure the 3D stream is idle before doing a
+		 * 2D fill to clear the front or back buffer.
+		 */
+		RADEON_WAIT_UNTIL_3D_IDLE();
+		
+		OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );
+		OUT_RING( clear->color_mask );
+
+		ADVANCE_RING();
+
+		/* Make sure we restore the 3D state next time.
+		 */
+		dev_priv->sarea_priv->ctx_owner = 0;
+
+		for ( i = 0 ; i < nbox ; i++ ) {
+			int x = pbox[i].x1;
+			int y = pbox[i].y1;
+			int w = pbox[i].x2 - x;
+			int h = pbox[i].y2 - y;
+
+			DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
+				   x, y, w, h, flags );
+
+			if ( flags & RADEON_FRONT ) {
+				BEGIN_RING( 6 );
+				
+				OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
+				OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+					  RADEON_GMC_BRUSH_SOLID_COLOR |
+					  (dev_priv->color_fmt << 8) |
+					  RADEON_GMC_SRC_DATATYPE_COLOR |
+					  RADEON_ROP3_P |
+					  RADEON_GMC_CLR_CMP_CNTL_DIS );
+
+				OUT_RING( dev_priv->front_pitch_offset );
+				OUT_RING( clear->clear_color );
+				
+				OUT_RING( (x << 16) | y );
+				OUT_RING( (w << 16) | h );
+				
+				ADVANCE_RING();
+			}
+			
+			if ( flags & RADEON_BACK ) {
+				BEGIN_RING( 6 );
+				
+				OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
+				OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+					  RADEON_GMC_BRUSH_SOLID_COLOR |
+					  (dev_priv->color_fmt << 8) |
+					  RADEON_GMC_SRC_DATATYPE_COLOR |
+					  RADEON_ROP3_P |
+					  RADEON_GMC_CLR_CMP_CNTL_DIS );
+				
+				OUT_RING( dev_priv->back_pitch_offset );
+				OUT_RING( clear->clear_color );
+
+				OUT_RING( (x << 16) | y );
+				OUT_RING( (w << 16) | h );
+
+				ADVANCE_RING();
+			}
+		}
+	}
+
 	/* We have to clear the depth and/or stencil buffers by
 	 * rendering a quad into just those buffers.  Thus, we have to
 	 * make sure the 3D engine is configured correctly.
 	 */
-	if ( flags & (RADEON_DEPTH | RADEON_STENCIL) ) {
-		rb3d_cntl = depth_clear->rb3d_cntl;
+	if ( dev_priv->is_r200 &&
+	     (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) {
 
-		if ( flags & RADEON_DEPTH ) {
-			rb3d_cntl |=  RADEON_Z_ENABLE;
-		} else {
-			rb3d_cntl &= ~RADEON_Z_ENABLE;
-		}
+		int tempPP_CNTL;
+		int tempRE_CNTL;
+		int tempRB3D_CNTL;
+		int tempRB3D_ZSTENCILCNTL;
+		int tempRB3D_STENCILREFMASK;
+		int tempRB3D_PLANEMASK;
+		int tempSE_CNTL;
+		int tempSE_VTE_CNTL;
+		int tempSE_VTX_FMT_0;
+		int tempSE_VTX_FMT_1;
+		int tempSE_VAP_CNTL;
+		int tempRE_AUX_SCISSOR_CNTL;
 
-		if ( flags & RADEON_STENCIL ) {
-			rb3d_cntl |=  RADEON_STENCIL_ENABLE;
-			rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */
-		} else {
-			rb3d_cntl &= ~RADEON_STENCIL_ENABLE;
-			rb3d_stencilrefmask = 0x00000000;
-		}
-	}
+		tempPP_CNTL = 0;
+		tempRE_CNTL = 0;
 
-	for ( i = 0 ; i < nbox ; i++ ) {
-		int x = pbox[i].x1;
-		int y = pbox[i].y1;
-		int w = pbox[i].x2 - x;
-		int h = pbox[i].y2 - y;
+		tempRB3D_CNTL = depth_clear->rb3d_cntl;
+		tempRB3D_CNTL &= ~(1<<15); /* unset radeon magic flag */
 
-		DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n",
-			   x, y, w, h, flags );
+		tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
+		tempRB3D_STENCILREFMASK = 0x0;
 
-		if ( flags & (RADEON_FRONT | RADEON_BACK) ) {
-			BEGIN_RING( 4 );
+		tempSE_CNTL = depth_clear->se_cntl;
 
-			/* Ensure the 3D stream is idle before doing a
-			 * 2D fill to clear the front or back buffer.
-			 */
-			RADEON_WAIT_UNTIL_3D_IDLE();
 
-			OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );
-			OUT_RING( clear->color_mask );
 
-			ADVANCE_RING();
+		/* Disable TCL */
 
-			/* Make sure we restore the 3D state next time.
-			 */
-			dev_priv->sarea_priv->ctx_owner = 0;
-		}
+		tempSE_VAP_CNTL = (/* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK |  */
+				   (0x9 << SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT));
 
-		if ( flags & RADEON_FRONT ) {
-			BEGIN_RING( 6 );
+		tempRB3D_PLANEMASK = 0x0;
 
-			OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
-			OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
-				  RADEON_GMC_BRUSH_SOLID_COLOR |
-				  (dev_priv->color_fmt << 8) |
-				  RADEON_GMC_SRC_DATATYPE_COLOR |
-				  RADEON_ROP3_P |
-				  RADEON_GMC_CLR_CMP_CNTL_DIS );
+		tempRE_AUX_SCISSOR_CNTL = 0x0;
 
-			OUT_RING( dev_priv->front_pitch_offset );
-			OUT_RING( clear->clear_color );
+		tempSE_VTE_CNTL =
+			SE_VTE_CNTL__VTX_XY_FMT_MASK |
+			SE_VTE_CNTL__VTX_Z_FMT_MASK;
 
-			OUT_RING( (x << 16) | y );
-			OUT_RING( (w << 16) | h );
+		/* Vertex format (X, Y, Z, W)*/
+		tempSE_VTX_FMT_0 =
+			SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK |
+			SE_VTX_FMT_0__VTX_W0_PRESENT_MASK;
+		tempSE_VTX_FMT_1 = 0x0;
 
-			ADVANCE_RING();
+
+		/* 
+		 * Depth buffer specific enables 
+		 */
+		if (flags & RADEON_DEPTH) {
+			/* Enable depth buffer */
+			tempRB3D_CNTL |= RADEON_Z_ENABLE;
+		} else {
+			/* Disable depth buffer */
+			tempRB3D_CNTL &= ~RADEON_Z_ENABLE;
 		}
 
-		if ( flags & RADEON_BACK ) {
-			BEGIN_RING( 6 );
+		/* 
+		 * Stencil buffer specific enables
+		 */
+		if ( flags & RADEON_STENCIL ) {
+			tempRB3D_CNTL |=  RADEON_STENCIL_ENABLE;
+			tempRB3D_STENCILREFMASK = clear->depth_mask; 
+		} else {
+			tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE;
+			tempRB3D_STENCILREFMASK = 0x00000000;
+		}
 
-			OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) );
-			OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL |
-				  RADEON_GMC_BRUSH_SOLID_COLOR |
-				  (dev_priv->color_fmt << 8) |
-				  RADEON_GMC_SRC_DATATYPE_COLOR |
-				  RADEON_ROP3_P |
-				  RADEON_GMC_CLR_CMP_CNTL_DIS );
+		BEGIN_RING( 26 );
+		RADEON_WAIT_UNTIL_2D_IDLE();
 
-			OUT_RING( dev_priv->back_pitch_offset );
-			OUT_RING( clear->clear_color );
+		OUT_RING_REG( RADEON_PP_CNTL, tempPP_CNTL );
+		OUT_RING_REG( R200_RE_CNTL, tempRE_CNTL );
+		OUT_RING_REG( RADEON_RB3D_CNTL, tempRB3D_CNTL );
+		OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL,
+			      tempRB3D_ZSTENCILCNTL );
+		OUT_RING_REG( RADEON_RB3D_STENCILREFMASK, 
+			      tempRB3D_STENCILREFMASK );
+		OUT_RING_REG( RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK );
+		OUT_RING_REG( RADEON_SE_CNTL, tempSE_CNTL );
+		OUT_RING_REG( R200_SE_VTE_CNTL, tempSE_VTE_CNTL );
+		OUT_RING_REG( R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0 );
+		OUT_RING_REG( R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1 );
+		OUT_RING_REG( R200_SE_VAP_CNTL, tempSE_VAP_CNTL );
+		OUT_RING_REG( R200_RE_AUX_SCISSOR_CNTL, 
+			      tempRE_AUX_SCISSOR_CNTL );
+		ADVANCE_RING();
 
-			OUT_RING( (x << 16) | y );
-			OUT_RING( (w << 16) | h );
+		/* Make sure we restore the 3D state next time.
+		 */
+		dev_priv->sarea_priv->ctx_owner = 0;
+
+		for ( i = 0 ; i < nbox ; i++ ) {
+			
+			/* Funny that this should be required -- 
+			 *  sets top-left?
+			 */
+			radeon_emit_clip_rect( dev_priv,
+					       &sarea_priv->boxes[i] );
 
+			BEGIN_RING( 14 );
+			OUT_RING( CP_PACKET3( R200_3D_DRAW_IMMD_2, 12 ) );
+			OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST |
+				   RADEON_PRIM_WALK_RING |
+				   (3 << RADEON_NUM_VERTICES_SHIFT)) );
+			OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
+			OUT_RING( depth_boxes[i].ui[CLEAR_Y1] );
+			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
+			OUT_RING( 0x3f800000 );
+			OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
+			OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
+			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
+			OUT_RING( 0x3f800000 );
+			OUT_RING( depth_boxes[i].ui[CLEAR_X2] );
+			OUT_RING( depth_boxes[i].ui[CLEAR_Y2] );
+			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
+			OUT_RING( 0x3f800000 );
 			ADVANCE_RING();
 		}
+	} 
+	else if ( (flags & (RADEON_DEPTH | RADEON_STENCIL)) ) {
 
-		if ( flags & (RADEON_DEPTH | RADEON_STENCIL) ) {
+		rb3d_cntl = depth_clear->rb3d_cntl;
 
-			radeon_emit_clip_rect( dev_priv,
-					       &sarea_priv->boxes[i] );
+		if ( flags & RADEON_DEPTH ) {
+			rb3d_cntl |=  RADEON_Z_ENABLE;
+		} else {
+			rb3d_cntl &= ~RADEON_Z_ENABLE;
+		}
 
-			BEGIN_RING( 28 );
+		if ( flags & RADEON_STENCIL ) {
+			rb3d_cntl |=  RADEON_STENCIL_ENABLE;
+			rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */
+		} else {
+			rb3d_cntl &= ~RADEON_STENCIL_ENABLE;
+			rb3d_stencilrefmask = 0x00000000;
+		}
 
-			RADEON_WAIT_UNTIL_2D_IDLE();
+		BEGIN_RING( 13 );
+		RADEON_WAIT_UNTIL_2D_IDLE();
 
-			OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) );
-			OUT_RING( 0x00000000 );
-			OUT_RING( rb3d_cntl );
-
-			OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL,
-				      depth_clear->rb3d_zstencilcntl );
-			OUT_RING_REG( RADEON_RB3D_STENCILREFMASK,
-				      rb3d_stencilrefmask );
-			OUT_RING_REG( RADEON_RB3D_PLANEMASK,
-				      0x00000000 );
-			OUT_RING_REG( RADEON_SE_CNTL,
-				      depth_clear->se_cntl );
+		OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) );
+		OUT_RING( 0x00000000 );
+		OUT_RING( rb3d_cntl );
+		
+		OUT_RING_REG( RADEON_RB3D_ZSTENCILCNTL,
+			      depth_clear->rb3d_zstencilcntl );
+		OUT_RING_REG( RADEON_RB3D_STENCILREFMASK,
+			      rb3d_stencilrefmask );
+		OUT_RING_REG( RADEON_RB3D_PLANEMASK,
+			      0x00000000 );
+		OUT_RING_REG( RADEON_SE_CNTL,
+			      depth_clear->se_cntl );
+		ADVANCE_RING();
+
+		/* Make sure we restore the 3D state next time.
+		 */
+		dev_priv->sarea_priv->ctx_owner = 0;
 
-			/* Radeon 7500 doesn't like vertices without
-			 * color.
+		for ( i = 0 ; i < nbox ; i++ ) {
+			
+			/* Funny that this should be required -- 
+			 *  sets top-left?
 			 */
+			radeon_emit_clip_rect( dev_priv,
+					       &sarea_priv->boxes[i] );
+
+			BEGIN_RING( 15 );
+
 			OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 13 ) );
 			OUT_RING( RADEON_VTX_Z_PRESENT |
 				  RADEON_VTX_PKCOLOR_PRESENT);
@@ -460,6 +677,7 @@
 				   RADEON_VTX_FMT_RADEON_MODE |
 				   (3 << RADEON_NUM_VERTICES_SHIFT)) );
 
+
 			OUT_RING( depth_boxes[i].ui[CLEAR_X1] );
 			OUT_RING( depth_boxes[i].ui[CLEAR_Y1] );
 			OUT_RING( depth_boxes[i].ui[CLEAR_DEPTH] );
@@ -476,10 +694,6 @@
 			OUT_RING( 0x0 );
 
 			ADVANCE_RING();
-
-			/* Make sure we restore the 3D state next time.
-			 */
-			dev_priv->sarea_priv->ctx_owner = 0;
 		}
 	}
 
@@ -505,13 +719,14 @@
 	drm_clip_rect_t *pbox = sarea_priv->boxes;
 	int i;
 	RING_LOCALS;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
+
 
-#if RADEON_PERFORMANCE_BOXES
 	/* Do some trivial performance monitoring...
 	 */
-	radeon_cp_performance_boxes( dev_priv );
-#endif
+	if (dev_priv->do_boxes)
+		radeon_cp_performance_boxes( dev_priv );
+
 
 	/* Wait for the 3D stream to idle before dispatching the bitblt.
 	 * This will prevent data corruption between the two streams.
@@ -580,13 +795,17 @@
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	RING_LOCALS;
-	DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page );
+	DRM_DEBUG( "%s: page=%d pfCurrentPage=%d\n", 
+		__FUNCTION__, 
+		dev_priv->current_page,
+		dev_priv->sarea_priv->pfCurrentPage);
 
-#if RADEON_PERFORMANCE_BOXES
 	/* Do some trivial performance monitoring...
 	 */
-	radeon_cp_performance_boxes( dev_priv );
-#endif
+	if (dev_priv->do_boxes) {
+		dev_priv->stats.boxes |= RADEON_BOX_FLIP;
+		radeon_cp_performance_boxes( dev_priv );
+	}
 
 	BEGIN_RING( 4 );
 
@@ -668,8 +887,7 @@
 	int i = 0;
 	RING_LOCALS;
 
-	DRM_DEBUG("%s: hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
-		  __FUNCTION__,
+	DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
 		  prim->prim,
 		  prim->vc_format,
 		  prim->start,
@@ -685,7 +903,7 @@
 	do {
 		/* Emit the next cliprect */
 		if ( i < nbox ) {
-			if (__copy_from_user( &box, &boxes[i], sizeof(box) ))
+			if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) ))
 				return;
 
 			radeon_emit_clip_rect( dev_priv, &box );
@@ -780,8 +998,7 @@
 	int start = prim->start + RADEON_INDEX_PRIM_OFFSET;
 	int count = (prim->finish - start) / sizeof(u16);
 
-	DRM_DEBUG("%s: hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
-		  __FUNCTION__,
+	DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
 		  prim->prim,
 		  prim->vc_format,
 		  prim->start,
@@ -819,7 +1036,7 @@
 
 	do {
 		if ( i < nbox ) {
-			if (__copy_from_user( &box, &boxes[i], sizeof(box) ))
+			if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) ))
 				return;
 			
 			radeon_emit_clip_rect( dev_priv, &box );
@@ -844,16 +1061,18 @@
 	drm_buf_t *buf;
 	u32 format;
 	u32 *buffer;
-	u8 *data;
+	const u8 *data;
 	int size, dwords, tex_width, blit_width;
 	u32 y, height;
 	int ret = 0, i;
 	RING_LOCALS;
 
+	dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD;
+
 	/* FIXME: Be smarter about this...
 	 */
 	buf = radeon_freelist_get( dev );
-	if ( !buf ) return -EAGAIN;
+	if ( !buf ) return DRM_ERR(EAGAIN);
 
 	DRM_DEBUG( "tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
 		   tex->offset >> 10, tex->pitch, tex->format,
@@ -886,7 +1105,7 @@
 		break;
 	default:
 		DRM_ERROR( "invalid texture format %d\n", tex->format );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	DRM_DEBUG( "   tex=%dx%d  blit=%d\n",
@@ -918,13 +1137,13 @@
 	 */
 	y = image->y;
 	height = image->height;
-	data = (u8 *)image->data;
+	data = (const u8 *)image->data;
 
 	size = height * blit_width;
 
 	if ( size > RADEON_MAX_TEXTURE_SIZE ) {
 		/* Texture image is too large, do a multipass upload */
-		ret = -EAGAIN;
+		ret = DRM_ERR(EAGAIN);
 
 		/* Adjust the blit size to fit the indirect buffer */
 		height = RADEON_MAX_TEXTURE_SIZE / blit_width;
@@ -933,11 +1152,11 @@
 		/* Update the input parameters for next time */
 		image->y += height;
 		image->height -= height;
-		image->data = (char *)image->data + size;
+		image->data = (const char *)image->data + size;
 
-		if ( copy_to_user( tex->image, image, sizeof(*image) ) ) {
+		if ( DRM_COPY_TO_USER( tex->image, image, sizeof(*image) ) ) {
 			DRM_ERROR( "EFAULT on tex->image\n" );
-			return -EFAULT;
+			return DRM_ERR(EFAULT);
 		}
 	} else if ( size < 4 && size > 0 ) {
 		size = 4;
@@ -972,9 +1191,9 @@
 		/* Texture image width is larger than the minimum, so we
 		 * can upload it directly.
 		 */
-		if ( copy_from_user( buffer, data, dwords * sizeof(u32) ) ) {
+		if ( DRM_COPY_FROM_USER( buffer, data, dwords * sizeof(u32) ) ) {
 			DRM_ERROR( "EFAULT on data, %d dwords\n", dwords );
-			return -EFAULT;
+			return DRM_ERR(EFAULT);
 		}
 	} else {
 		/* Texture image width is less than the minimum, so we
@@ -982,17 +1201,17 @@
 		 * width.
 		 */
 		for ( i = 0 ; i < tex->height ; i++ ) {
-			if ( copy_from_user( buffer, data, tex_width ) ) {
+			if ( DRM_COPY_FROM_USER( buffer, data, tex_width ) ) {
 				DRM_ERROR( "EFAULT on pad, %d bytes\n",
 					   tex_width );
-				return -EFAULT;
+				return DRM_ERR(EFAULT);
 			}
 			buffer += 8;
 			data += tex_width;
 		}
 	}
 
-	buf->pid = current->pid;
+	buf->pid = DRM_CURRENTPID;
 	buf->used = (dwords + 8) * sizeof(u32);
 
 	radeon_cp_dispatch_indirect( dev, buf, 0, buf->used );
@@ -1017,7 +1236,7 @@
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	int i;
 	RING_LOCALS;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	BEGIN_RING( 35 );
 
@@ -1037,31 +1256,28 @@
  * IOCTL functions
  */
 
-int radeon_cp_clear( struct inode *inode, struct file *filp,
-		     unsigned int cmd, unsigned long arg )
+int radeon_cp_clear( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_radeon_clear_t clear;
 	drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &clear, (drm_radeon_clear_t *)arg,
-			     sizeof(clear) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( clear, (drm_radeon_clear_t *)data,
+			     sizeof(clear) );
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
 
 	if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS )
 		sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
 
-	if ( copy_from_user( &depth_boxes, clear.depth_boxes,
+	if ( DRM_COPY_FROM_USER( &depth_boxes, clear.depth_boxes,
 			     sarea_priv->nbox * sizeof(depth_boxes[0]) ) )
-		return -EFAULT;
+		return DRM_ERR(EFAULT);
 
 	radeon_cp_dispatch_clear( dev, &clear, depth_boxes );
 
@@ -1076,15 +1292,17 @@
 static int radeon_do_init_pageflip( drm_device_t *dev )
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	RING_LOCALS;
+
+	DRM_DEBUG( "\n" );
 
-	dev_priv->crtc_offset =      RADEON_READ( RADEON_CRTC_OFFSET );
 	dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL );
 
-	RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset );
-	RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL,
-		      dev_priv->crtc_offset_cntl |
-		      RADEON_CRTC_OFFSET_FLIP_CNTL );
+	BEGIN_RING( 4 );
+	RADEON_WAIT_UNTIL_3D_IDLE();
+	OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET_CNTL, 0 ) );
+	OUT_RING( dev_priv->crtc_offset_cntl | RADEON_CRTC_OFFSET_FLIP_CNTL );
+	ADVANCE_RING();
 
 	dev_priv->page_flipping = 1;
 	dev_priv->current_page = 0;
@@ -1096,28 +1314,27 @@
 int radeon_do_cleanup_pageflip( drm_device_t *dev )
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
-	RADEON_WRITE( RADEON_CRTC_OFFSET,      dev_priv->crtc_offset );
-	RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl );
+	if (dev_priv->current_page != 0)
+		radeon_cp_dispatch_flip( dev );
 
+	/* FIXME: If the X server changes screen resolution, it
+	 * clobbers the value of RADEON_CRTC_OFFSET_CNTL, above,
+	 * leading to a flashing efect.
+	 */
 	dev_priv->page_flipping = 0;
-	dev_priv->current_page = 0;
-	dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
-
 	return 0;
 }
 
 /* Swapping and flipping are different operations, need different ioctls.
  * They can & should be intermixed to support multiple 3d windows.  
  */
-int radeon_cp_flip( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
+int radeon_cp_flip( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
@@ -1132,14 +1349,12 @@
 	return 0;
 }
 
-int radeon_cp_swap( struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg )
+int radeon_cp_swap( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
-	DRM_DEBUG( "%s\n", __FUNCTION__ );
+	DRM_DEBUG( "\n" );
 
 	LOCK_TEST_WITH_RETURN( dev );
 
@@ -1155,11 +1370,9 @@
 	return 0;
 }
 
-int radeon_cp_vertex( struct inode *inode, struct file *filp,
-		      unsigned int cmd, unsigned long arg )
+int radeon_cp_vertex( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_device_dma_t *dma = dev->dma;
@@ -1170,27 +1383,26 @@
 	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( !dev_priv ) {
-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
-		return -EINVAL;
+		DRM_ERROR( "%s called with no initialization\n", __func__ );
+		return DRM_ERR(EINVAL);
 	}
 
-	if ( copy_from_user( &vertex, (drm_radeon_vertex_t *)arg,
-			     sizeof(vertex) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex_t *)data,
+			     sizeof(vertex) );
 
-	DRM_DEBUG( "%s: pid=%d index=%d count=%d discard=%d\n",
-		   __FUNCTION__, current->pid,
+	DRM_DEBUG( "pid=%d index=%d count=%d discard=%d\n",
+		   DRM_CURRENTPID,
 		   vertex.idx, vertex.count, vertex.discard );
 
 	if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
 		DRM_ERROR( "buffer index %d (of %d max)\n",
 			   vertex.idx, dma->buf_count - 1 );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	if ( vertex.prim < 0 ||
 	     vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
 		DRM_ERROR( "buffer prim %d\n", vertex.prim );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
@@ -1198,14 +1410,14 @@
 
 	buf = dma->buflist[vertex.idx];
 
-	if ( buf->pid != current->pid ) {
+	if ( buf->pid != DRM_CURRENTPID ) {
 		DRM_ERROR( "process %d using buffer owned by %d\n",
-			   current->pid, buf->pid );
-		return -EINVAL;
+			   DRM_CURRENTPID, buf->pid );
+		return DRM_ERR(EINVAL);
 	}
 	if ( buf->pending ) {
 		DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	/* Build up a prim_t record:
@@ -1244,11 +1456,9 @@
 	return 0;
 }
 
-int radeon_cp_indices( struct inode *inode, struct file *filp,
-		       unsigned int cmd, unsigned long arg )
+int radeon_cp_indices( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_device_dma_t *dma = dev->dma;
@@ -1260,27 +1470,26 @@
 	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( !dev_priv ) {
-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
-		return -EINVAL;
+		DRM_ERROR( "%s called with no initialization\n", __func__ );
+		return DRM_ERR(EINVAL);
 	}
 
-	if ( copy_from_user( &elts, (drm_radeon_indices_t *)arg,
-			     sizeof(elts) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( elts, (drm_radeon_indices_t *)data,
+			     sizeof(elts) );
 
-	DRM_DEBUG( "%s: pid=%d index=%d start=%d end=%d discard=%d\n",
-		   __FUNCTION__, current->pid,
+	DRM_DEBUG( "pid=%d index=%d start=%d end=%d discard=%d\n",
+		   DRM_CURRENTPID,
 		   elts.idx, elts.start, elts.end, elts.discard );
 
 	if ( elts.idx < 0 || elts.idx >= dma->buf_count ) {
 		DRM_ERROR( "buffer index %d (of %d max)\n",
 			   elts.idx, dma->buf_count - 1 );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	if ( elts.prim < 0 ||
 	     elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
 		DRM_ERROR( "buffer prim %d\n", elts.prim );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
@@ -1288,14 +1497,14 @@
 
 	buf = dma->buflist[elts.idx];
 
-	if ( buf->pid != current->pid ) {
+	if ( buf->pid != DRM_CURRENTPID ) {
 		DRM_ERROR( "process %d using buffer owned by %d\n",
-			   current->pid, buf->pid );
-		return -EINVAL;
+			   DRM_CURRENTPID, buf->pid );
+		return DRM_ERR(EINVAL);
 	}
 	if ( buf->pending ) {
 		DRM_ERROR( "sending pending buffer %d\n", elts.idx );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	count = (elts.end - elts.start) / sizeof(u16);
@@ -1303,11 +1512,11 @@
 
 	if ( elts.start & 0x7 ) {
 		DRM_ERROR( "misaligned buffer 0x%x\n", elts.start );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	if ( elts.start < buf->used ) {
 		DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	buf->used = elts.end;
@@ -1345,11 +1554,9 @@
 	return 0;
 }
 
-int radeon_cp_texture( struct inode *inode, struct file *filp,
-		       unsigned int cmd, unsigned long arg )
+int radeon_cp_texture( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_radeon_texture_t tex;
 	drm_radeon_tex_image_t image;
@@ -1357,18 +1564,17 @@
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &tex, (drm_radeon_texture_t *)arg, sizeof(tex) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( tex, (drm_radeon_texture_t *)data, sizeof(tex) );
 
 	if ( tex.image == NULL ) {
 		DRM_ERROR( "null texture image!\n" );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
-	if ( copy_from_user( &image,
+	if ( DRM_COPY_FROM_USER( &image,
 			     (drm_radeon_tex_image_t *)tex.image,
 			     sizeof(image) ) )
-		return -EFAULT;
+		return DRM_ERR(EFAULT);
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
 	VB_AGE_TEST_WITH_RETURN( dev_priv );
@@ -1379,23 +1585,20 @@
 	return ret;
 }
 
-int radeon_cp_stipple( struct inode *inode, struct file *filp,
-		       unsigned int cmd, unsigned long arg )
+int radeon_cp_stipple( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_radeon_stipple_t stipple;
 	u32 mask[32];
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	if ( copy_from_user( &stipple, (drm_radeon_stipple_t *)arg,
-			     sizeof(stipple) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( stipple, (drm_radeon_stipple_t *)data,
+			     sizeof(stipple) );
 
-	if ( copy_from_user( &mask, stipple.mask, 32 * sizeof(u32) ) )
-		return -EFAULT;
+	if ( DRM_COPY_FROM_USER( &mask, stipple.mask, 32 * sizeof(u32) ) )
+		return DRM_ERR(EFAULT);
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
 
@@ -1405,11 +1608,9 @@
 	return 0;
 }
 
-int radeon_cp_indirect( struct inode *inode, struct file *filp,
-			unsigned int cmd, unsigned long arg )
+int radeon_cp_indirect( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_device_dma_t *dma = dev->dma;
 	drm_buf_t *buf;
@@ -1419,13 +1620,12 @@
 	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( !dev_priv ) {
-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
-		return -EINVAL;
+		DRM_ERROR( "%s called with no initialization\n", __func__ );
+		return DRM_ERR(EINVAL);
 	}
 
-	if ( copy_from_user( &indirect, (drm_radeon_indirect_t *)arg,
-			     sizeof(indirect) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( indirect, (drm_radeon_indirect_t *)data,
+			     sizeof(indirect) );
 
 	DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
 		   indirect.idx, indirect.start,
@@ -1434,25 +1634,25 @@
 	if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) {
 		DRM_ERROR( "buffer index %d (of %d max)\n",
 			   indirect.idx, dma->buf_count - 1 );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	buf = dma->buflist[indirect.idx];
 
-	if ( buf->pid != current->pid ) {
+	if ( buf->pid != DRM_CURRENTPID ) {
 		DRM_ERROR( "process %d using buffer owned by %d\n",
-			   current->pid, buf->pid );
-		return -EINVAL;
+			   DRM_CURRENTPID, buf->pid );
+		return DRM_ERR(EINVAL);
 	}
 	if ( buf->pending ) {
 		DRM_ERROR( "sending pending buffer %d\n", indirect.idx );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	if ( indirect.start < buf->used ) {
 		DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
 			   indirect.start, buf->used );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
@@ -1483,11 +1683,9 @@
 	return 0;
 }
 
-int radeon_cp_vertex2( struct inode *inode, struct file *filp,
-		      unsigned int cmd, unsigned long arg )
+int radeon_cp_vertex2( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
 	drm_device_dma_t *dma = dev->dma;
@@ -1499,21 +1697,21 @@
 	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( !dev_priv ) {
-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
-		return -EINVAL;
+		DRM_ERROR( "%s called with no initialization\n", __func__ );
+		return DRM_ERR(EINVAL);
 	}
 
-	if ( copy_from_user( &vertex, (drm_radeon_vertex_t *)arg,
-			     sizeof(vertex) ) )
-		return -EFAULT;
+	DRM_COPY_FROM_USER_IOCTL( vertex, (drm_radeon_vertex2_t *)data,
+			     sizeof(vertex) );
 
-	DRM_DEBUG( __FUNCTION__": pid=%d index=%d discard=%d\n",
-		   current->pid, vertex.idx, vertex.discard );
+	DRM_DEBUG( "pid=%d index=%d discard=%d\n",
+		   DRM_CURRENTPID,
+		   vertex.idx, vertex.discard );
 
 	if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
 		DRM_ERROR( "buffer index %d (of %d max)\n",
 			   vertex.idx, dma->buf_count - 1 );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
@@ -1521,34 +1719,34 @@
 
 	buf = dma->buflist[vertex.idx];
 
-	if ( buf->pid != current->pid ) {
+	if ( buf->pid != DRM_CURRENTPID ) {
 		DRM_ERROR( "process %d using buffer owned by %d\n",
-			   current->pid, buf->pid );
-		return -EINVAL;
+			   DRM_CURRENTPID, buf->pid );
+		return DRM_ERR(EINVAL);
 	}
 
 	if ( buf->pending ) {
 		DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 	
 	if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 
 	for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) {
 		drm_radeon_prim_t prim;
 		drm_radeon_tcl_prim_t tclprim;
 		
-		if ( copy_from_user( &prim, &vertex.prim[i], sizeof(prim) ) )
-			return -EFAULT;
+		if ( DRM_COPY_FROM_USER( &prim, &vertex.prim[i], sizeof(prim) ) )
+			return DRM_ERR(EFAULT);
 		
 		if ( prim.stateidx != laststate ) {
 			drm_radeon_state_t state;			       
 				
-			if ( copy_from_user( &state, 
+			if ( DRM_COPY_FROM_USER( &state, 
 					     &vertex.state[prim.stateidx], 
 					     sizeof(state) ) )
-				return -EFAULT;
+				return DRM_ERR(EFAULT);
 
 			radeon_emit_state2( dev_priv, &state );
 
@@ -1601,7 +1799,7 @@
 	RING_LOCALS;
    
 	if (sz * sizeof(int) > cmdbuf->bufsz) 
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 
 	BEGIN_RING(sz+1);
 	OUT_RING( CP_PACKET0( reg, (sz-1) ) );
@@ -1613,7 +1811,7 @@
 	return 0;
 }
 
-static inline int radeon_emit_scalars( 
+static __inline__ int radeon_emit_scalars( 
 	drm_radeon_private_t *dev_priv,
 	drm_radeon_cmd_header_t header,
 	drm_radeon_cmd_buffer_t *cmdbuf )
@@ -1635,7 +1833,31 @@
 	return 0;
 }
 
-static inline int radeon_emit_vectors( 
+/* God this is ugly
+ */
+static __inline__ int radeon_emit_scalars2( 
+	drm_radeon_private_t *dev_priv,
+	drm_radeon_cmd_header_t header,
+	drm_radeon_cmd_buffer_t *cmdbuf )
+{
+	int sz = header.scalars.count;
+	int *data = (int *)cmdbuf->buf;
+	int start = ((unsigned int)header.scalars.offset) + 0x100;
+	int stride = header.scalars.stride;
+	RING_LOCALS;
+
+	BEGIN_RING( 3+sz );
+	OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) );
+	OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
+	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) );
+	OUT_RING_USER_TABLE( data, sz );
+	ADVANCE_RING();
+	cmdbuf->buf += sz * sizeof(int);
+	cmdbuf->bufsz -= sz * sizeof(int);
+	return 0;
+}
+
+static __inline__ int radeon_emit_vectors( 
 	drm_radeon_private_t *dev_priv,
 	drm_radeon_cmd_header_t header,
 	drm_radeon_cmd_buffer_t *cmdbuf )
@@ -1668,16 +1890,16 @@
 	RING_LOCALS;
 
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
+	DRM_DEBUG("\n");
 
-	if (__get_user( tmp, &cmd[0]))
-		return -EFAULT;
+	if (DRM_GET_USER_UNCHECKED( tmp, &cmd[0]))
+		return DRM_ERR(EFAULT);
 
 	cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16);
 
 	if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 ||
 	    cmdsz * 4 > cmdbuf->bufsz)
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 
 	BEGIN_RING( cmdsz );
 	OUT_RING_USER_TABLE( cmd, cmdsz );
@@ -1690,7 +1912,8 @@
 
 
 static int radeon_emit_packet3_cliprect( drm_device_t *dev,
-					 drm_radeon_cmd_buffer_t *cmdbuf )
+					 drm_radeon_cmd_buffer_t *cmdbuf,
+					 int orig_nbox )
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_clip_rect_t box;
@@ -1700,21 +1923,24 @@
 	int i = 0;
 	RING_LOCALS;
 
-	DRM_DEBUG("%s\n", __FUNCTION__);
+	DRM_DEBUG("\n");
 
-	if (__get_user( tmp, &cmd[0]))
-		return -EFAULT;
+	if (DRM_GET_USER_UNCHECKED( tmp, &cmd[0]))
+		return DRM_ERR(EFAULT);
 
 	cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16);
 
 	if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 ||
 	    cmdsz * 4 > cmdbuf->bufsz)
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
+
+	if (!orig_nbox)
+		goto out;
 
 	do {
 		if ( i < cmdbuf->nbox ) {
-			if (__copy_from_user( &box, &boxes[i], sizeof(box) ))
-				return -EFAULT;
+			if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) ))
+				return DRM_ERR(EFAULT);
 			radeon_emit_clip_rect( dev_priv, &box );
 		}
 		
@@ -1727,6 +1953,7 @@
  	if (cmdbuf->nbox == 1)
 		cmdbuf->nbox = 0;
 
+ out:
 	cmdbuf->buf += cmdsz * 4;
 	cmdbuf->bufsz -= cmdsz * 4;
 	return 0;
@@ -1734,49 +1961,47 @@
 
 
 
-int radeon_cp_cmdbuf( struct inode *inode, struct file *filp,
-		      unsigned int cmd, unsigned long arg )
+int radeon_cp_cmdbuf( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_device_dma_t *dma = dev->dma;
 	drm_buf_t *buf = 0;
 	int idx;
 	drm_radeon_cmd_buffer_t cmdbuf;
 	drm_radeon_cmd_header_t header;
+	int orig_nbox;
 
 	LOCK_TEST_WITH_RETURN( dev );
 
 	if ( !dev_priv ) {
-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
-		return -EINVAL;
+		DRM_ERROR( "%s called with no initialization\n", __func__ );
+		return DRM_ERR(EINVAL);
 	}
 
-	if ( copy_from_user( &cmdbuf, (drm_radeon_cmd_buffer_t *)arg,
-			     sizeof(cmdbuf) ) ) {
-		DRM_ERROR("copy_from_user\n");
-		return -EFAULT;
-	}
+	DRM_COPY_FROM_USER_IOCTL( cmdbuf, (drm_radeon_cmd_buffer_t *)data,
+			     sizeof(cmdbuf) );
 
-	DRM_DEBUG( __FUNCTION__": pid=%d\n", current->pid );
+	DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
 	RING_SPACE_TEST_WITH_RETURN( dev_priv );
 	VB_AGE_TEST_WITH_RETURN( dev_priv );
 
 
-	if (verify_area( VERIFY_READ, cmdbuf.buf, cmdbuf.bufsz ))
-		return -EFAULT;
+	if (DRM_VERIFYAREA_READ( cmdbuf.buf, cmdbuf.bufsz ))
+		return DRM_ERR(EFAULT);
 
 	if (cmdbuf.nbox &&
-	    verify_area( VERIFY_READ, cmdbuf.boxes, 
+	    DRM_VERIFYAREA_READ(cmdbuf.boxes, 
 			 cmdbuf.nbox * sizeof(drm_clip_rect_t)))
-		return -EFAULT;
+		return DRM_ERR(EFAULT);
+
+	orig_nbox = cmdbuf.nbox;
 
 	while ( cmdbuf.bufsz >= sizeof(header) ) {
 		
-		if (__get_user( header.i, (int *)cmdbuf.buf )) {
+		if (DRM_GET_USER_UNCHECKED( header.i, (int *)cmdbuf.buf )) {
 			DRM_ERROR("__get_user %p\n", cmdbuf.buf);
-			return -EFAULT;
+			return DRM_ERR(EFAULT);
 		}
 
 		cmdbuf.buf += sizeof(header);
@@ -1784,105 +2009,125 @@
 
 		switch (header.header.cmd_type) {
 		case RADEON_CMD_PACKET: 
+			DRM_DEBUG("RADEON_CMD_PACKET\n");
 			if (radeon_emit_packets( dev_priv, header, &cmdbuf )) {
 				DRM_ERROR("radeon_emit_packets failed\n");
-				return -EINVAL;
+				return DRM_ERR(EINVAL);
 			}
 			break;
 
 		case RADEON_CMD_SCALARS:
+			DRM_DEBUG("RADEON_CMD_SCALARS\n");
 			if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) {
 				DRM_ERROR("radeon_emit_scalars failed\n");
-				return -EINVAL;
+				return DRM_ERR(EINVAL);
 			}
 			break;
 
 		case RADEON_CMD_VECTORS:
+			DRM_DEBUG("RADEON_CMD_VECTORS\n");
 			if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) {
 				DRM_ERROR("radeon_emit_vectors failed\n");
-				return -EINVAL;
+				return DRM_ERR(EINVAL);
 			}
 			break;
 
 		case RADEON_CMD_DMA_DISCARD:
+			DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
 			idx = header.dma.buf_idx;
 			if ( idx < 0 || idx >= dma->buf_count ) {
 				DRM_ERROR( "buffer index %d (of %d max)\n",
 					   idx, dma->buf_count - 1 );
-				return -EINVAL;
+				return DRM_ERR(EINVAL);
 			}
 
 			buf = dma->buflist[idx];
-			if ( buf->pid != current->pid || buf->pending ) {
+			if ( buf->pid != DRM_CURRENTPID || buf->pending ) {
 				DRM_ERROR( "bad buffer\n" );
-				return -EINVAL;
+				return DRM_ERR(EINVAL);
 			}
 
 			radeon_cp_discard_buffer( dev, buf );
 			break;
 
 		case RADEON_CMD_PACKET3:
+			DRM_DEBUG("RADEON_CMD_PACKET3\n");
 			if (radeon_emit_packet3( dev, &cmdbuf )) {
 				DRM_ERROR("radeon_emit_packet3 failed\n");
-				return -EINVAL;
+				return DRM_ERR(EINVAL);
 			}
 			break;
 
 		case RADEON_CMD_PACKET3_CLIP:
-			if (radeon_emit_packet3_cliprect( dev, &cmdbuf )) {
+			DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
+			if (radeon_emit_packet3_cliprect( dev, &cmdbuf, orig_nbox )) {
 				DRM_ERROR("radeon_emit_packet3_clip failed\n");
-				return -EINVAL;
+				return DRM_ERR(EINVAL);
 			}
 			break;
 
+		case RADEON_CMD_SCALARS2:
+			DRM_DEBUG("RADEON_CMD_SCALARS2\n");
+			if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) {
+				DRM_ERROR("radeon_emit_scalars2 failed\n");
+				return DRM_ERR(EINVAL);
+			}
+			break;
 		default:
 			DRM_ERROR("bad cmd_type %d at %p\n", 
 				  header.header.cmd_type,
 				  cmdbuf.buf - sizeof(header));
-			return -EINVAL;
+			return DRM_ERR(EINVAL);
 		}
 	}
 
 
+	DRM_DEBUG("DONE\n");
 	COMMIT_RING();
 	return 0;
 }
 
 
 
-int radeon_cp_getparam( struct inode *inode, struct file *filp,
-		      unsigned int cmd, unsigned long arg )
+int radeon_cp_getparam( DRM_IOCTL_ARGS )
 {
-	drm_file_t *priv = filp->private_data;
-	drm_device_t *dev = priv->dev;
+	DRM_DEVICE;
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	drm_radeon_getparam_t param;
 	int value;
 
 	if ( !dev_priv ) {
-		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
-		return -EINVAL;
+		DRM_ERROR( "%s called with no initialization\n", __func__ );
+		return DRM_ERR(EINVAL);
 	}
 
-	if ( copy_from_user( &param, (drm_radeon_getparam_t *)arg,
-			     sizeof(param) ) ) {
-		DRM_ERROR("copy_from_user\n");
-		return -EFAULT;
-	}
+	DRM_COPY_FROM_USER_IOCTL( param, (drm_radeon_getparam_t *)data,
+			     sizeof(param) );
 
-	DRM_DEBUG( __FUNCTION__": pid=%d\n", current->pid );
+	DRM_DEBUG( "pid=%d\n", DRM_CURRENTPID );
 
 	switch( param.param ) {
 	case RADEON_PARAM_AGP_BUFFER_OFFSET:
 		value = dev_priv->agp_buffers_offset;
 		break;
+	case RADEON_PARAM_LAST_FRAME:
+		dev_priv->stats.last_frame_reads++;
+		value = DRM_READ32(&dev_priv->scratch[0]);
+		break;
+	case RADEON_PARAM_LAST_DISPATCH:
+		value = DRM_READ32(&dev_priv->scratch[1]);
+		break;
+	case RADEON_PARAM_LAST_CLEAR:
+		dev_priv->stats.last_clear_reads++;
+		value = DRM_READ32(&dev_priv->scratch[2]);
+		break;
 	default:
-		return -EINVAL;
+		return DRM_ERR(EINVAL);
 	}
 
-	if ( copy_to_user( param.value, &value, sizeof(int) ) ) {
+	if ( DRM_COPY_TO_USER( param.value, &value, sizeof(int) ) ) {
 		DRM_ERROR( "copy_to_user\n" );
-		return -EFAULT;
+		return DRM_ERR(EFAULT);
 	}
 	
 	return 0;
diff -Nru a/drivers/char/drm/sis.h b/drivers/char/drm/sis.h
--- a/drivers/char/drm/sis.h	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/drm/sis.h	Sat Aug 10 18:42:22 2002
@@ -42,6 +42,31 @@
 #define __HAVE_MTRR		1
 #define __HAVE_CTX_BITMAP	1
 
+#define DRIVER_AUTHOR	 "SIS"
+#define DRIVER_NAME	 "sis"
+#define DRIVER_DESC	 "SIS 300/630/540"
+#define DRIVER_DATE	 "20010503"
+#define DRIVER_MAJOR	 1
+#define DRIVER_MINOR	 0
+#define DRIVER_PATCHLEVEL  0
+
+#define DRIVER_IOCTLS \
+        [DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)]   = { sis_fb_alloc,	  1, 0 }, \
+        [DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)]    = { sis_fb_free,	  1, 0 }, \
+        /* AGP Memory Management */					  \
+        [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)]   = { sisp_agp_init,	  1, 0 }, \
+        [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)]  = { sisp_agp_alloc,  1, 0 }, \
+        [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)]   = { sisp_agp_free,	  1, 0 }
+#if 0 /* these don't appear to be defined */
+	/* SIS Stereo */						 
+	[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)]    = { sis_control,	  1, 1 }, 
+        [DRM_IOCTL_NR(SIS_IOCTL_FLIP)]       = { sis_flip,	  1, 1 }, 
+        [DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)]  = { sis_flip_init,	  1, 1 }, 
+        [DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final,  1, 1 }
+#endif
+
+#define __HAVE_COUNTERS		5
+
 /* Buffer customization:
  */
 #define DRIVER_AGP_BUFFERS_MAP( dev )					\
diff -Nru a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
--- a/drivers/char/drm/sis_drv.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/char/drm/sis_drv.c	Sat Aug 10 18:42:20 2002
@@ -31,31 +31,6 @@
 #include "sis_drm.h"
 #include "sis_drv.h"
 
-#define DRIVER_AUTHOR	 "SIS"
-#define DRIVER_NAME	 "sis"
-#define DRIVER_DESC	 "SIS 300/630/540"
-#define DRIVER_DATE	 "20010503"
-#define DRIVER_MAJOR	 1
-#define DRIVER_MINOR	 0
-#define DRIVER_PATCHLEVEL  0
-
-#define DRIVER_IOCTLS \
-        [DRM_IOCTL_NR(SIS_IOCTL_FB_ALLOC)]   = { sis_fb_alloc,	  1, 0 }, \
-        [DRM_IOCTL_NR(SIS_IOCTL_FB_FREE)]    = { sis_fb_free,	  1, 0 }, \
-        /* AGP Memory Management */					  \
-        [DRM_IOCTL_NR(SIS_IOCTL_AGP_INIT)]   = { sisp_agp_init,	  1, 0 }, \
-        [DRM_IOCTL_NR(SIS_IOCTL_AGP_ALLOC)]  = { sisp_agp_alloc,  1, 0 }, \
-        [DRM_IOCTL_NR(SIS_IOCTL_AGP_FREE)]   = { sisp_agp_free,	  1, 0 }
-#if 0 /* these don't appear to be defined */
-	/* SIS Stereo */						 
-	[DRM_IOCTL_NR(DRM_IOCTL_CONTROL)]    = { sis_control,	  1, 1 }, 
-        [DRM_IOCTL_NR(SIS_IOCTL_FLIP)]       = { sis_flip,	  1, 1 }, 
-        [DRM_IOCTL_NR(SIS_IOCTL_FLIP_INIT)]  = { sis_flip_init,	  1, 1 }, 
-        [DRM_IOCTL_NR(SIS_IOCTL_FLIP_FINAL)] = { sis_flip_final,  1, 1 }
-#endif
-
-#define __HAVE_COUNTERS		5
-
 #include "drm_auth.h"
 #include "drm_agpsupport.h"
 #include "drm_bufs.h"
diff -Nru a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c
--- a/drivers/char/drm/tdfx_drv.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/char/drm/tdfx_drv.c	Sat Aug 10 18:42:23 2002
@@ -82,25 +82,6 @@
 #include "drm_drawable.h"
 #include "drm_drv.h"
 
-#ifndef MODULE
-/* DRM(options) is called by the kernel to parse command-line options
- * passed via the boot-loader (e.g., LILO).  It calls the insmod option
- * routine, drm_parse_drm.
- */
-
-/* JH- We have to hand expand the string ourselves because of the cpp.  If
- * anyone can think of a way that we can fit into the __setup macro without
- * changing it, then please send the solution my way.
- */
-static int __init tdfx_options( char *str )
-{
-	DRM(parse_options)( str );
-	return 1;
-}
-
-__setup( DRIVER_NAME "=", tdfx_options );
-#endif
-
 #include "drm_fops.h"
 #include "drm_init.h"
 #include "drm_ioctl.h"
diff -Nru a/drivers/char/rtc.c b/drivers/char/rtc.c
--- a/drivers/char/rtc.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/rtc.c	Sat Aug 10 18:42:22 2002
@@ -870,7 +870,9 @@
 
 	if (misc_register(&rtc_dev))
 		{
+#if RTC_IRQ
 		free_irq(RTC_IRQ, NULL);
+#endif
 		release_region(RTC_PORT(0), RTC_IO_EXTENT);
 		return -ENODEV;
 		}
diff -Nru a/drivers/char/wdt977.c b/drivers/char/wdt977.c
--- a/drivers/char/wdt977.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/char/wdt977.c	Sat Aug 10 18:42:22 2002
@@ -39,7 +39,7 @@
 
 static	int timeout = DEFAULT_TIMEOUT*60;	/* TO in seconds from user */
 static	int timeoutM = DEFAULT_TIMEOUT;		/* timeout in minutes */
-static	int timer_alive;
+static	unsigned long timer_alive;
 static	int testmode;
 
 MODULE_PARM(timeout, "i");
diff -Nru a/drivers/ide/hd.c b/drivers/ide/hd.c
--- a/drivers/ide/hd.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/ide/hd.c	Sat Aug 10 18:42:21 2002
@@ -108,8 +108,6 @@
 
 static spinlock_t hd_lock = SPIN_LOCK_UNLOCKED;
 
-static int revalidate_hddisk(kdev_t, int);
-
 #define TIMEOUT_VALUE	(6*HZ)
 #define	HD_DELAY	0
 
@@ -683,11 +681,6 @@
 			return copy_to_user(loc, &g, sizeof g) ? -EFAULT : 0; 
 		}
 
-		case BLKRRPART: /* Re-read partition tables */
-			if (!capable(CAP_SYS_ADMIN))
-				return -EACCES;
-			return revalidate_hddisk(inode->i_rdev, 1);
-
 		default:
 			return -EINVAL;
 	}
@@ -712,14 +705,14 @@
 {
 	.major =	MAJOR_NR,
 	.first_minor =	0,
-	.major_name =	"hd",
+	.major_name =	"hda",
 	.minor_shift =	6,
 	.part =		hd,
 	.fops =		&hd_fops,
 },{
 	.major =	MAJOR_NR,
 	.first_minor =	64,
-	.major_name =	"hd",
+	.major_name =	"hdb",
 	.minor_shift =	6,
 	.part =		hd + 64,
 	.fops =		&hd_fops,
@@ -877,32 +870,6 @@
 	device_timer.function = hd_times_out;
 	hd_geninit();
 	return 0;
-}
-
-#define CAPACITY (hd_info[target].head*hd_info[target].sect*hd_info[target].cyl)
-/* We assume that the BIOS parameters do not change, so the disk capacity
-   will not change */
-
-/*
- * This routine is called to flush all partitions and partition tables
- * for a changed disk, and then re-read the new partition table.
- * If we are revalidating a disk because of a media change, then we
- * enter with usage == 0.  If we are using an ioctl, we automatically have
- * usage == 1 (we need an open channel to use an ioctl :-), so this
- * is our limit.
- */
-static int revalidate_hddisk(kdev_t dev, int maxusage)
-{
-	int target = DEVICE_NR(dev);
-	kdev_t device = mk_kdev(MAJOR_NR, target << 6);
-	int res = dev_lock_part(device);
-	if (res < 0)
-		return res;
-	res = wipe_partitions(device);
-	if (!res)
-		grok_partitions(device, CAPACITY);
-	dev_unlock_part(device);
-	return res;
 }
 
 static int parse_hd_setup (char *line) {
diff -Nru a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
--- a/drivers/ide/ide-cd.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/ide/ide-cd.c	Sat Aug 10 18:42:22 2002
@@ -2875,19 +2875,8 @@
 static
 void ide_cdrom_revalidate(struct ata_device *drive)
 {
-	struct cdrom_info *info = drive->driver_data;
-	struct atapi_toc *toc;
 	struct request_sense sense;
-
 	cdrom_read_toc(drive, &sense);
-
-	if (!CDROM_STATE_FLAGS(drive)->toc_valid)
-		return;
-
-	toc = info->toc;
-
-	/* for general /dev/cdrom like mounting, one big disc */
-	drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;
 }
 
 static sector_t ide_cdrom_capacity(struct ata_device *drive)
@@ -2946,6 +2935,7 @@
 	struct cdrom_info *info;
 	char *req;
 	struct ata_channel *channel;
+	struct gendisk *disk;
 	int unit;
 
 	if (drive->type != ATA_ROM)
@@ -2983,8 +2973,12 @@
 
 	channel = drive->channel;
 	unit = drive - channel->drives;
-
-	ata_revalidate(mk_kdev(channel->major, unit << PARTN_BITS));
+	disk = channel->gd[unit];
+	disk->minor_shift = 0;
+	ide_cdrom_revalidate(drive);
+	register_disk(disk, mk_kdev(disk->major, disk->first_minor),
+			1<<disk->minor_shift, disk->fops,
+			ide_cdrom_capacity(drive));
 }
 
 MODULE_PARM(ignore, "s");
diff -Nru a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
--- a/drivers/ide/ide-disk.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/ide/ide-disk.c	Sat Aug 10 18:42:20 2002
@@ -659,7 +659,7 @@
 {
 	MOD_INC_USE_COUNT;
 	if (drive->removable && drive->usage == 1) {
-		check_disk_change(inode->i_rdev);
+		check_disk_change(inode->i_bdev);
 
 		/*
 		 * Ignore the return code from door_lock, since the open() has
@@ -1462,6 +1462,7 @@
 {
 	char *req;
 	struct ata_channel *channel;
+	struct gendisk *disk;
 	int unit;
 
 	if (drive->type != ATA_DISK)
@@ -1485,8 +1486,10 @@
 
 	channel = drive->channel;
 	unit = drive - channel->drives;
-
-	ata_revalidate(mk_kdev(channel->major, unit << PARTN_BITS));
+	disk = channel->gd[unit];
+	disk->minor_shift = PARTN_BITS;
+	register_disk(disk, mk_kdev(disk->major, disk->first_minor),
+			1<<disk->minor_shift, disk->fops, drive->capacity);
 }
 
 static void __exit idedisk_exit(void)
diff -Nru a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
--- a/drivers/ide/ide-floppy.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/ide/ide-floppy.c	Sat Aug 10 18:42:21 2002
@@ -1496,7 +1496,7 @@
 			idefloppy_create_prevent_cmd (&pc, 1);
 			(void) idefloppy_queue_pc_tail (drive, &pc);
 		}
-		check_disk_change(inode->i_rdev);
+		check_disk_change(inode->i_bdev);
 	}
 	else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags))
 	{
@@ -1755,6 +1755,7 @@
 	idefloppy_floppy_t *floppy;
 	char *req;
 	struct ata_channel *channel;
+	struct gendisk *disk;
 	int unit;
 
 	if (drive->type != ATA_FLOPPY)
@@ -1790,8 +1791,11 @@
 
 	channel = drive->channel;
 	unit = drive - channel->drives;
-
-	ata_revalidate(mk_kdev(channel->major, unit << PARTN_BITS));
+	disk = channel->gd[unit];
+	disk->minor_shift = PARTN_BITS;
+	register_disk(disk, mk_kdev(disk->major, disk->first_minor),
+			1<<disk->minor_shift, disk->fops,
+			idefloppy_capacity(drive));
 }
 
 MODULE_DESCRIPTION("ATAPI FLOPPY Driver");
diff -Nru a/drivers/ide/ide-pmac.c b/drivers/ide/ide-pmac.c
--- a/drivers/ide/ide-pmac.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/ide/ide-pmac.c	Sat Aug 10 18:42:23 2002
@@ -1558,7 +1558,7 @@
 		ata_ops(drive)->check_media_change(drive);
 
 	/* We kick the VFS too (see fix in ide.c revalidate) */
-	check_disk_change(mk_kdev(drive->channel->major, (drive->select.b.unit) << PARTN_BITS));
+	__check_disk_change(MKDEV(drive->channel->major, (drive->select.b.unit) << PARTN_BITS));
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
 	/* We re-enable DMA on the drive if it was active. */
diff -Nru a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
--- a/drivers/ide/ide-tape.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/ide/ide-tape.c	Sat Aug 10 18:42:21 2002
@@ -5537,13 +5537,6 @@
 	return 0;
 }
 
-static void idetape_revalidate(struct ata_device *_dummy)
-{
-	/* We don't have to handle any partition information here, which is the
-	 * default behaviour of this method.
-	 */
-}
-
 static void idetape_attach(struct ata_device *);
 
 static struct ata_operations idetape_driver = {
@@ -5556,8 +5549,6 @@
 	.ioctl =		idetape_blkdev_ioctl,
 	.open =			idetape_blkdev_open,
 	.release =		idetape_blkdev_release,
-	.check_media_change =	NULL,
-	.revalidate =		idetape_revalidate,
 };
 
 
@@ -5641,13 +5632,6 @@
 		unregister_chrdev (IDETAPE_MAJOR, "ht");
 	} else
 		idetape_chrdev_present = 1;
-
-	/* Feel free to use partitions even on tapes... */
-
-	channel = drive->channel;
-	unit = drive - channel->drives;
-
-	ata_revalidate(mk_kdev(channel->major, unit << PARTN_BITS));
 }
 
 MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver");
diff -Nru a/drivers/ide/ide.c b/drivers/ide/ide.c
--- a/drivers/ide/ide.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/ide/ide.c	Sat Aug 10 18:42:23 2002
@@ -251,7 +251,7 @@
 
 static struct ata_bit_messages ata_error_msgs[] = {
 	{ ICRC_ERR|ABRT_ERR,	ABRT_ERR,		"drive status error"	},
-	{ ICRC_ERR|ABRT_ERR,	ICRC_ERR,		"bad sectorr"		},
+	{ ICRC_ERR|ABRT_ERR,	ICRC_ERR,		"bad sector"		},
 	{ ICRC_ERR|ABRT_ERR,	ICRC_ERR|ABRT_ERR,	"invalid checksum"	},
 	{ ECC_ERR,		ECC_ERR,		"uncorrectable error"	},
 	{ ID_ERR,		ID_ERR,			"sector id not found"   },
@@ -1106,7 +1106,7 @@
 	.release =		ide_release,
 	.ioctl =		ata_ioctl,
 	.check_media_change =	ide_check_media_change,
-	.revalidate =		ata_revalidate
+	.revalidate =		ide_revalidate
 }};
 
 EXPORT_SYMBOL(ide_fops);
diff -Nru a/drivers/ide/ioctl.c b/drivers/ide/ioctl.c
--- a/drivers/ide/ioctl.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/ide/ioctl.c	Sat Aug 10 18:42:22 2002
@@ -349,9 +349,6 @@
 		case CDROMCLOSETRAY:
 			return block_ioctl(inode->i_bdev, cmd, arg);
 
-		case BLKRRPART: /* Re-read partition tables */
-			return ata_revalidate(inode->i_rdev);
-
 		/* Now check whatever this particular ioctl has a device type
 		 * specific implementation.
 		 */
diff -Nru a/drivers/ide/main.c b/drivers/ide/main.c
--- a/drivers/ide/main.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/ide/main.c	Sat Aug 10 18:42:20 2002
@@ -260,65 +260,25 @@
  * usage == 1 (we need an open channel to use an ioctl :-), so this
  * is our limit.
  */
-int ata_revalidate(kdev_t i_rdev)
+int ide_revalidate(kdev_t dev)
 {
-	kdev_t device = mk_kdev(major(i_rdev), minor(i_rdev) & ~PARTN_MASK);
 	struct ata_device *drive;
-	int res;
+	struct ata_channel *channel;
+	struct gendisk *disk;
+	int unit;
 
-	if ((drive = get_info_ptr(device)) == NULL)
+	if ((drive = get_info_ptr(dev)) == NULL)
 		return -ENODEV;
-
-	MOD_INC_USE_COUNT;
-
-	res = dev_lock_part(device);
-	if (res < 0) {
-		MOD_DEC_USE_COUNT;
-		return res;
-	}
-
-	res = wipe_partitions(device);
-	if (!res) {
-		if (ata_ops(drive) && ata_ops(drive)->revalidate) {
-			ata_get(ata_ops(drive));
-
-			/* This is expected to be a no-op for tapes and SCSI
-			 * based access.
-			 */
-			ata_ops(drive)->revalidate(drive);
-			ata_put(ata_ops(drive));
-		} else
-			grok_partitions(device, ata_capacity(drive));
-	}
-
-	dev_unlock_part(device);
-	MOD_DEC_USE_COUNT;
-	return res;
-}
-
-/*
- * FIXME: this is most propably just totally unnecessary.
- *
- * Look again for all drives in the system on all interfaces.
- */
-static void revalidate_drives(void)
-{
-	int i;
-
-	for (i = 0; i < MAX_HWIFS; ++i) {
-		int unit;
-		struct ata_channel *ch = &ide_hwifs[i];
-
-		for (unit = 0; unit < MAX_DRIVES; ++unit) {
-			struct ata_device *drive = &ch->drives[unit];
-
-			if (drive->revalidate) {
-				drive->revalidate = 0;
-				if (!initializing)
-					ata_revalidate(mk_kdev(ch->major, unit<<PARTN_BITS));
-			}
-		}
-	}
+	if (ata_ops(drive) && ata_ops(drive)->revalidate) {
+		ata_get(ata_ops(drive));
+		ata_ops(drive)->revalidate(drive);
+		ata_put(ata_ops(drive));
+	}
+	channel = drive->channel;
+	unit = drive - channel->drives;
+	disk = channel->gd[unit];
+	disk->part[0].nr_sects = ata_capacity(drive);
+	return 0;
 }
 
 void ide_driver_module(void)
@@ -328,13 +288,10 @@
 	/* Don't reinit the probe if there is already one channel detected. */
 	for (i = 0; i < MAX_HWIFS; ++i) {
 		if (ide_hwifs[i].present)
-			goto revalidate;
+			return;
 	}
 
 	ideprobe_init();
-
-revalidate:
-	revalidate_drives();
 }
 
 /*
@@ -493,6 +450,7 @@
 		int i;
 		for (i = 0; i < MAX_DRIVES; i++)
 			del_gendisk(gd + i);
+		kfree(gd->major_name);
 		kfree(gd->part);
 		if (gd->de_arr)
 			kfree (gd->de_arr);
@@ -613,7 +571,6 @@
 
 	if (!initializing) {
 		ideprobe_init();
-		revalidate_drives();
 		/* FIXME: Do we really have to call it second time here?! */
 		ide_driver_module();
 	}
@@ -1093,8 +1050,6 @@
 			drive->dsc_overlap = 0;
 
 	}
-	drive->revalidate = 1;
-
 	return 0;
 }
 
@@ -1169,8 +1124,6 @@
 	}
 }
 
-EXPORT_SYMBOL(unregister_ata_driver);
-
 EXPORT_SYMBOL(ide_hwifs);
 EXPORT_SYMBOL(ide_lock);
 
@@ -1178,7 +1131,6 @@
 
 EXPORT_SYMBOL(ata_register_device);
 EXPORT_SYMBOL(ata_unregister_device);
-EXPORT_SYMBOL(ata_revalidate);
 EXPORT_SYMBOL(ide_register_hw);
 EXPORT_SYMBOL(ide_unregister);
 EXPORT_SYMBOL(get_info_ptr);
diff -Nru a/drivers/ide/probe.c b/drivers/ide/probe.c
--- a/drivers/ide/probe.c	Sat Aug 10 18:42:19 2002
+++ b/drivers/ide/probe.c	Sat Aug 10 18:42:19 2002
@@ -1048,6 +1048,7 @@
 	char *flags;
 	unsigned int unit;
 	extern devfs_handle_t ide_devfs_handle;
+	char *names;
 
 	if (!ch->present)
 		return;
@@ -1127,6 +1128,11 @@
 		goto err_kmalloc_gd_flags;
 	memset(flags, 0, sizeof(char) * MAX_DRIVES);
 
+	names = kmalloc (4 * MAX_DRIVES, GFP_KERNEL);
+	if (!names)
+		goto err_kmalloc_gd_names;
+	memset(names, 0, 4 * MAX_DRIVES);
+
 	for (unit = 0; unit < MAX_DRIVES; ++unit) {
 		gd[unit].part = part + (unit << PARTN_BITS);
 		gd[unit].de_arr = de_arr + unit;
@@ -1134,8 +1140,8 @@
 		ch->drives[unit].part = gd[unit].part;
 		gd[unit].major	= ch->major;
 		gd[unit].first_minor = unit << PARTN_BITS;
-		/* treated special in genhd.c */
-		gd[unit].major_name = IDE_MAJOR_NAME;
+		sprintf(names + 4*unit, "hd%c", 'a'+ch->index*MAX_DRIVES+unit);
+		gd[unit].major_name = names + 4*unit;
 		gd[unit].minor_shift = PARTN_BITS;
 		gd[unit].nr_real = 1;
 		gd[unit].fops = ide_fops;
@@ -1161,6 +1167,8 @@
 
 	return;
 
+err_kmalloc_gd_names:
+	kfree(names);
 err_kmalloc_gd_flags:
 	kfree(de_arr);
 err_kmalloc_gd_de_arr:
diff -Nru a/drivers/ieee1394/Makefile b/drivers/ieee1394/Makefile
--- a/drivers/ieee1394/Makefile	Sat Aug 10 18:42:23 2002
+++ b/drivers/ieee1394/Makefile	Sat Aug 10 18:42:23 2002
@@ -24,4 +24,4 @@
 include $(TOPDIR)/Rules.make
 
 ieee1394.o: $(ieee1394-objs)
-	$(LD) -r -o $@ $(ieee1394-objs)
+	$(LD) $(LDFLAGS) -r -o $@ $(ieee1394-objs)
diff -Nru a/drivers/input/keybdev.c b/drivers/input/keybdev.c
--- a/drivers/input/keybdev.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/input/keybdev.c	Sat Aug 10 18:42:23 2002
@@ -49,7 +49,6 @@
 static int x86_sysrq_alt = 0;
 #ifdef CONFIG_SPARC64
 static int sparc_l1_a_state = 0;
-extern void batten_down_hatches(void);
 #endif
 
 static unsigned short x86_keycodes[256] =
@@ -99,7 +98,7 @@
 #ifdef CONFIG_SPARC64
 	if (keycode == KEY_A && sparc_l1_a_state) {
 		sparc_l1_a_state = 0;
-		batten_down_hatches();
+		sun_do_break();
 	}
 #endif
 
diff -Nru a/drivers/isdn/act2000/capi.h b/drivers/isdn/act2000/capi.h
--- a/drivers/isdn/act2000/capi.h	Sat Aug 10 18:42:23 2002
+++ b/drivers/isdn/act2000/capi.h	Sat Aug 10 18:42:23 2002
@@ -138,7 +138,7 @@
 
 typedef struct actcapi_msg {
 	actcapi_msghdr hdr;
-	union msg {
+	union {
 		__u16 manuf_msg;
 		struct manufacturer_req_net {
 			__u16 manuf_msg;
diff -Nru a/drivers/isdn/i4l/isdn_audio.c b/drivers/isdn/i4l/isdn_audio.c
--- a/drivers/isdn/i4l/isdn_audio.c	Sat Aug 10 18:42:19 2002
+++ b/drivers/isdn/i4l/isdn_audio.c	Sat Aug 10 18:42:19 2002
@@ -564,8 +564,8 @@
 			ISDN_AUDIO_SKB_LOCK(skb) = 0;
 			save_flags(flags);
 			cli();
-			di = info->isdn_driver;
-			ch = info->isdn_channel;
+			di = isdn_slot_driver(info->isdn_slot);
+			ch = isdn_slot_channel(info->isdn_slot);
 			__skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb);
 			dev->drv[di]->rcvcount[ch] += 2;
 			restore_flags(flags);
@@ -685,8 +685,8 @@
 	ISDN_AUDIO_SKB_LOCK(skb) = 0;
 	save_flags(flags);
 	cli();
-	di = info->isdn_driver;
-	ch = info->isdn_channel;
+	di = isdn_slot_driver(info->isdn_slot);
+	ch = isdn_slot_channel(info->isdn_slot);
 	__skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb);
 	dev->drv[di]->rcvcount[ch] += 2;
 	restore_flags(flags);
diff -Nru a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
--- a/drivers/isdn/i4l/isdn_common.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/isdn/i4l/isdn_common.c	Sat Aug 10 18:42:22 2002
@@ -19,6 +19,7 @@
 #include <linux/vmalloc.h>
 #include <linux/isdn.h>
 #include <linux/smp_lock.h>
+#include <linux/ctype.h>
 #include "isdn_common.h"
 #include "isdn_tty.h"
 #include "isdn_net.h"
@@ -26,24 +27,31 @@
 #ifdef CONFIG_ISDN_AUDIO
 #include "isdn_audio.h"
 #endif
-#ifdef CONFIG_ISDN_DIVERSION_MODULE
-#define CONFIG_ISDN_DIVERSION
-#endif
-#ifdef CONFIG_ISDN_DIVERSION
 #include <linux/isdn_divertif.h>
-#endif /* CONFIG_ISDN_DIVERSION */
 #include "isdn_v110.h"
 #include <linux/devfs_fs_kernel.h>
 
-/* Debugflags */
-#undef ISDN_DEBUG_STATCALLB
-
 MODULE_DESCRIPTION("ISDN4Linux: link layer");
 MODULE_AUTHOR("Fritz Elfert");
 MODULE_LICENSE("GPL");
 
 isdn_dev *dev;
 
+struct isdn_slot {
+	int               di;                  /* driver index               */
+	int               ch;                  /* channel index (per driver) */
+	int               usage;               /* how is it used             */
+	char              num[ISDN_MSNLEN];    /* the current phone number   */
+	unsigned long     ibytes;              /* Statistics incoming bytes  */
+	unsigned long     obytes;              /* Statistics outgoing bytes  */
+	struct isdn_v110  iv110;               /* For V.110                  */
+	int               m_idx;               /* Index for mdm....          */
+	isdn_net_dev      *rx_netdev;          /* rx netdev-pointers         */
+	isdn_net_dev      *st_netdev;          /* stat netdev-pointers       */
+};
+
+static struct isdn_slot slot[ISDN_MAX_CHANNELS]; 
+
 static char *isdn_revision = "$Revision: 1.114.6.16 $";
 
 extern char *isdn_net_revision;
@@ -60,15 +68,18 @@
 #endif
 extern char *isdn_v110_revision;
 
-#ifdef CONFIG_ISDN_DIVERSION
+#if defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE)
 static isdn_divert_if *divert_if; /* = NULL */
-#endif /* CONFIG_ISDN_DIVERSION */
+#else
+#define divert_if ((isdn_divert_if *) NULL)
+#endif
 
 
 static void set_global_features(void);
 static void isdn_register_devfs(int);
 static void isdn_unregister_devfs(int);
 static int isdn_wildmat(char *s, char *p);
+static int isdn_command(isdn_ctrl *cmd);
 
 void
 isdn_lock_drivers(void)
@@ -230,12 +241,11 @@
 {
 	int i;
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-		if (dev->chanmap[i] == ch && dev->drvmap[i] == di)
+		if (slot[i].ch == ch && slot[i].di == di)
 			return i;
 	return -1;
 }
 
-static int isdn_timer_cnt1 = 0;
 static int isdn_timer_cnt2 = 0;
 static int isdn_timer_cnt3 = 0;
 
@@ -252,11 +262,6 @@
 			isdn_tty_modem_xmit();
 	}
 	if (tf & ISDN_TIMER_SLOW) {
-		if (++isdn_timer_cnt1 >= ISDN_TIMER_02SEC) {
-			isdn_timer_cnt1 = 0;
-			if (tf & ISDN_TIMER_NETDIAL)
-				isdn_net_dial();
-		}
 		if (++isdn_timer_cnt2 >= ISDN_TIMER_1SEC) {
 			isdn_timer_cnt2 = 0;
 			if (tf & ISDN_TIMER_NETHANGUP)
@@ -291,7 +296,6 @@
 	cli();
 	if ((tf & ISDN_TIMER_SLOW) && (!(dev->tflags & ISDN_TIMER_SLOW))) {
 		/* If the slow-timer wasn't activated until now */
-		isdn_timer_cnt1 = 0;
 		isdn_timer_cnt2 = 0;
 	}
 	old_tflags = dev->tflags;
@@ -317,7 +321,7 @@
 		return;
 	}
 	/* Update statistics */
-	dev->ibytes[i] += skb->len;
+	slot[i].ibytes += skb->len;
 	
 	/* First, try to deliver data to network-device */
 	if (isdn_net_rcv_skb(i, skb))
@@ -327,10 +331,10 @@
 	 * makes sense for async streams only, so it is
 	 * called after possible net-device delivery.
 	 */
-	if (dev->v110[i]) {
-		atomic_inc(&dev->v110use[i]);
-		skb = isdn_v110_decode(dev->v110[i], skb);
-		atomic_dec(&dev->v110use[i]);
+	if (slot[i].iv110.v110) {
+		atomic_inc(&slot[i].iv110.v110use);
+		skb = isdn_v110_decode(slot[i].iv110.v110, skb);
+		atomic_dec(&slot[i].iv110.v110use);
 		if (!skb)
 			return;
 	}
@@ -350,15 +354,16 @@
  * lowlevel-driver, use driver's transparent mode and handle V.110 in
  * linklevel instead.
  */
-int
+static int
 isdn_command(isdn_ctrl *cmd)
 {
+	int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255);
+
 	if (cmd->driver == -1) {
 		printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command);
 		return(1);
 	}
 	if (cmd->command == ISDN_CMD_SETL2) {
-		int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255);
 		unsigned long l2prot = (cmd->arg >> 8) & 255;
 		unsigned long features = (dev->drv[cmd->driver]->interface->features
 						>> ISDN_FEATURE_L2_SHIFT) &
@@ -374,30 +379,38 @@
 			 * Layer-2 to transparent
 			 */
 				if (!(features & l2_feature)) {
-					dev->v110emu[idx] = l2prot;
+					slot[idx].iv110.v110emu = l2prot;
 					cmd->arg = (cmd->arg & 255) |
 						(ISDN_PROTO_L2_TRANS << 8);
 				} else
-					dev->v110emu[idx] = 0;
+					slot[idx].iv110.v110emu = 0;
 		}
 	}
+#ifdef ISDN_DEBUG_COMMAND
+	switch (cmd->command) {
+	case ISDN_CMD_SETL2: 
+		printk(KERN_DEBUG "ISDN_CMD_SETL2 %d\n", idx); break;
+	case ISDN_CMD_SETL3: 
+		printk(KERN_DEBUG "ISDN_CMD_SETL3 %d\n", idx); break;
+	case ISDN_CMD_DIAL: 
+		printk(KERN_DEBUG "ISDN_CMD_DIAL %d\n", idx); break;
+	case ISDN_CMD_ACCEPTD: 
+		printk(KERN_DEBUG "ISDN_CMD_ACCEPTD %d\n", idx); break;
+	case ISDN_CMD_ACCEPTB: 
+		printk(KERN_DEBUG "ISDN_CMD_ACCEPTB %d\n", idx); break;
+	case ISDN_CMD_HANGUP: 
+		printk(KERN_DEBUG "ISDN_CMD_HANGUP %d\n", idx); break;
+	case ISDN_CMD_CLREAZ: 
+		printk(KERN_DEBUG "ISDN_CMD_CLREAZ %d\n", idx); break;
+	case ISDN_CMD_SETEAZ: 
+		printk(KERN_DEBUG "ISDN_CMD_SETEAZ %d\n", idx); break;
+	default:
+		printk(KERN_DEBUG "%s: cmd = %d\n", __FUNCTION__, cmd->command);
+	}
+#endif
 	return dev->drv[cmd->driver]->interface->command(cmd);
 }
 
-void
-isdn_all_eaz(int di, int ch)
-{
-	isdn_ctrl cmd;
-
-	if (di < 0)
-		return;
-	cmd.driver = di;
-	cmd.arg = ch;
-	cmd.command = ISDN_CMD_SETEAZ;
-	cmd.parm.num[0] = '\0';
-	isdn_command(&cmd);
-}
-
 /*
  * Begin of a CAPI like LL<->HL interface, currently used only for 
  * supplementary service (CAPI 2.0 part III)
@@ -430,7 +443,7 @@
 	int r;
 	int retval = 0;
 	isdn_ctrl cmd;
-	isdn_net_dev *p;
+	struct list_head *l;
 
 	di = c->driver;
 	i = isdn_dc2minor(di, c->arg);
@@ -442,7 +455,7 @@
 				return 0;
 			if (isdn_net_stat_callback(i, c))
 				return 0;
-			if (isdn_v110_stat_callback(i, c))
+			if (isdn_v110_stat_callback(&slot[i].iv110, c))
 				return 0;
 			if (isdn_tty_stat_callback(i, c))
 				return 0;
@@ -458,8 +471,8 @@
 		case ISDN_STAT_RUN:
 			dev->drv[di]->flags |= DRV_FLAG_RUNNING;
 			for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-				if (dev->drvmap[i] == di)
-					isdn_all_eaz(di, dev->chanmap[i]);
+				if (slot[i].di == di)
+					isdn_slot_all_eaz(i);
 			set_global_features();
 			break;
 		case ISDN_STAT_STOP:
@@ -468,9 +481,7 @@
 		case ISDN_STAT_ICALL:
 			if (i < 0)
 				return -1;
-#ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "ICALL (net): %d %ld %s\n", di, c->arg, c->parm.num);
-#endif
+			dbg_statcallb("ICALL: %d (%d,%ld) %s\n", i, di, c->arg, c->parm.num);
 			if (dev->global_flags & ISDN_GLOBAL_STOPPED) {
 				cmd.driver = di;
 				cmd.arg = c->arg;
@@ -488,12 +499,10 @@
 					 * 3 on eventually match, if CID is longer.
 					 */
                                         if (c->command == ISDN_STAT_ICALL)
-					  if ((retval = isdn_tty_find_icall(di, c->arg, &c->parm.setup))) return(retval);
-#ifdef CONFIG_ISDN_DIVERSION 
+						if ((retval = isdn_tty_find_icall(di, c->arg, &c->parm.setup))) return(retval);
                                          if (divert_if)
-                 	                  if ((retval = divert_if->stat_callback(c))) 
-					    return(retval); /* processed */
-#endif /* CONFIG_ISDN_DIVERSION */                       
+						 if ((retval = divert_if->stat_callback(c))) 
+							 return(retval); /* processed */
 					if ((!retval) && (dev->drv[di]->flags & DRV_FLAG_REJBUS)) {
 						/* No tty responding */
 						cmd.driver = di;
@@ -504,19 +513,15 @@
 					}
 					break;
 				case 1:
-					/* Schedule connection-setup */
-					isdn_net_dial();
-					cmd.driver = di;
-					cmd.arg = c->arg;
-					cmd.command = ISDN_CMD_ACCEPTD;
-					for ( p = dev->netdev; p; p = p->next )
-						if ( p->local->isdn_channel == cmd.arg )
-						{
-							strcpy( cmd.parm.setup.eazmsn, p->local->msn );
-							isdn_command(&cmd);
+					list_for_each(l, &isdn_net_devs) {
+						isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
+						if (p->local.isdn_slot == i) {
+							strcpy(cmd.parm.setup.eazmsn, p->local.msn);
+							isdn_slot_command(i, ISDN_CMD_ACCEPTD, &cmd);
 							retval = 1;
 							break;
 						}
+					}
 					break;
 
 				case 2:	/* For calling back, first reject incoming call ... */
@@ -532,24 +537,19 @@
 					/* Fall through */
 				case 4:
 					/* ... then start callback. */
-					isdn_net_dial();
 					break;
 				case 5:
 					/* Number would eventually match, if longer */
 					retval = 3;
 					break;
 			}
-#ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "ICALL: ret=%d\n", retval);
-#endif
+			dbg_statcallb("ICALL: ret=%d\n", retval);
 			return retval;
 			break;
 		case ISDN_STAT_CINF:
 			if (i < 0)
 				return -1;
-#ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "CINF: %ld %s\n", c->arg, c->parm.num);
-#endif
+			dbg_statcallb("CINF: %d %s\n", i, c->parm.num);
 			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
 				return 0;
 			if (strcmp(c->parm.num, "0"))
@@ -557,39 +557,29 @@
 			isdn_tty_stat_callback(i, c);
 			break;
 		case ISDN_STAT_CAUSE:
-#ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "CAUSE: %ld %s\n", c->arg, c->parm.num);
-#endif
+			dbg_statcallb("CAUSE: %d %s\n", i, c->parm.num);
 			printk(KERN_INFO "isdn: %s,ch%ld cause: %s\n",
 			       dev->drvid[di], c->arg, c->parm.num);
 			isdn_tty_stat_callback(i, c);
-#ifdef CONFIG_ISDN_DIVERSION
                         if (divert_if)
-                         divert_if->stat_callback(c); 
-#endif /* CONFIG_ISDN_DIVERSION */
+				divert_if->stat_callback(c); 
 			break;
 		case ISDN_STAT_DISPLAY:
-#ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "DISPLAY: %ld %s\n", c->arg, c->parm.display);
-#endif
+			dbg_statcallb("DISPLAY: %d %s\n", i, c->parm.display);
 			isdn_tty_stat_callback(i, c);
-#ifdef CONFIG_ISDN_DIVERSION
                         if (divert_if)
-                         divert_if->stat_callback(c); 
-#endif /* CONFIG_ISDN_DIVERSION */
+				divert_if->stat_callback(c); 
 			break;
 		case ISDN_STAT_DCONN:
 			if (i < 0)
 				return -1;
-#ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "DCONN: %ld\n", c->arg);
-#endif
+			dbg_statcallb("DCONN: %d\n", i);
 			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
 				return 0;
 			/* Find any net-device, waiting for D-channel setup */
 			if (isdn_net_stat_callback(i, c))
 				break;
-			isdn_v110_stat_callback(i, c);
+			isdn_v110_stat_callback(&slot[i].iv110, c);
 			/* Find any ttyI, waiting for D-channel setup */
 			if (isdn_tty_stat_callback(i, c)) {
 				cmd.driver = di;
@@ -602,9 +592,7 @@
 		case ISDN_STAT_DHUP:
 			if (i < 0)
 				return -1;
-#ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "DHUP: %ld\n", c->arg);
-#endif
+			dbg_statcallb("DHUP: %d\n", i);
 			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
 				return 0;
 			dev->drv[di]->online &= ~(1 << (c->arg));
@@ -612,21 +600,16 @@
 			/* Signal hangup to network-devices */
 			if (isdn_net_stat_callback(i, c))
 				break;
-			isdn_v110_stat_callback(i, c);
+			isdn_v110_stat_callback(&slot[i].iv110, c);
 			if (isdn_tty_stat_callback(i, c))
 				break;
-#ifdef CONFIG_ISDN_DIVERSION
                         if (divert_if)
-                         divert_if->stat_callback(c); 
-#endif /* CONFIG_ISDN_DIVERSION */
-			break;
+				divert_if->stat_callback(c); 
 			break;
 		case ISDN_STAT_BCONN:
 			if (i < 0)
 				return -1;
-#ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "BCONN: %ld\n", c->arg);
-#endif
+			dbg_statcallb("BCONN: %ld\n", c->arg);
 			/* Signal B-channel-connect to network-devices */
 			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
 				return 0;
@@ -634,16 +617,14 @@
 			isdn_info_update();
 			if (isdn_net_stat_callback(i, c))
 				break;
-			isdn_v110_stat_callback(i, c);
+			isdn_v110_stat_callback(&slot[i].iv110, c);
 			if (isdn_tty_stat_callback(i, c))
 				break;
 			break;
 		case ISDN_STAT_BHUP:
 			if (i < 0)
 				return -1;
-#ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "BHUP: %ld\n", c->arg);
-#endif
+			dbg_statcallb("BHUP: %d\n", i);
 			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
 				return 0;
 			dev->drv[di]->online &= ~(1 << (c->arg));
@@ -653,16 +634,14 @@
 			if (isdn_net_stat_callback(i, c))
 				break;
 #endif
-			isdn_v110_stat_callback(i, c);
+			isdn_v110_stat_callback(&slot[i].iv110, c);
 			if (isdn_tty_stat_callback(i, c))
 				break;
 			break;
 		case ISDN_STAT_NODCH:
 			if (i < 0)
 				return -1;
-#ifdef ISDN_DEBUG_STATCALLB
-			printk(KERN_DEBUG "NODCH: %ld\n", c->arg);
-#endif
+			dbg_statcallb("NODCH: %ld\n", c->arg);
 			if (dev->global_flags & ISDN_GLOBAL_STOPPED)
 				return 0;
 			if (isdn_net_stat_callback(i, c))
@@ -679,20 +658,17 @@
 			save_flags(flags);
 			cli();
 			for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-				if ((dev->drvmap[i] == di) &&
-				    (dev->chanmap[i] == c->arg)) {
-				    if (c->parm.num[0])
-				      dev->usage[i] &= ~ISDN_USAGE_DISABLED;
-				    else
-				      if (USG_NONE(dev->usage[i])) {
-					dev->usage[i] |= ISDN_USAGE_DISABLED;
-				      }
-				      else 
-					retval = -1;
-				    break;
+				if ((slot[i].di == di) &&
+				    (slot[i].ch == c->arg)) {
+					if (c->parm.num[0])
+						isdn_slot_set_usage(i, isdn_slot_usage(i) & ~ISDN_USAGE_DISABLED);
+					else if (USG_NONE(isdn_slot_usage(i)))
+						isdn_slot_set_usage(i, isdn_slot_usage(i) | ISDN_USAGE_DISABLED);
+					else 
+						retval = -1;
+					break;
 				}
 			restore_flags(flags);
-			isdn_info_update();
 			break;
 		case ISDN_STAT_UNLOAD:
 			while (dev->drv[di]->locks > 0) {
@@ -707,10 +683,10 @@
 			cli();
 			isdn_tty_stat_callback(i, c);
 			for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-				if (dev->drvmap[i] == di) {
-					dev->drvmap[i] = -1;
-					dev->chanmap[i] = -1;
-					dev->usage[i] &= ~ISDN_USAGE_DISABLED;
+				if (slot[i].di == di) {
+					slot[i].di = -1;
+					slot[i].ch = -1;
+					slot[i].usage &= ~ISDN_USAGE_DISABLED;
 					isdn_unregister_devfs(i);
 				}
 			dev->drivers--;
@@ -742,12 +718,10 @@
 			isdn_tty_stat_callback(i, c);
 			break;
 #endif
-#ifdef CONFIG_ISDN_DIVERSION
 	        case ISDN_STAT_PROT:
 	        case ISDN_STAT_REDIR:
                         if (divert_if)
-                          return(divert_if->stat_callback(c));
-#endif /* CONFIG_ISDN_DIVERSION */
+				return(divert_if->stat_callback(c));
 		default:
 			return -1;
 	}
@@ -770,50 +744,40 @@
 #define DLE 0x10
 
 /*
- * isdn_readbchan() tries to get data from the read-queue.
+ * isdn_slot_readbchan() tries to get data from the read-queue.
  * It MUST be called with interrupts off.
- *
- * Be aware that this is not an atomic operation when sleep != 0, even though 
- * interrupts are turned off! Well, like that we are currently only called
- * on behalf of a read system call on raw device files (which are documented
- * to be dangerous and for for debugging purpose only). The inode semaphore
- * takes care that this is not called for the same minor device number while
- * we are sleeping, but access is not serialized against simultaneous read()
- * from the corresponding ttyI device. Can other ugly events, like changes
- * of the mapping (di,ch)<->minor, happen during the sleep? --he 
  */
 int
-isdn_readbchan(int di, int channel, u_char * buf, u_char * fp, int len, wait_queue_head_t *sleep)
+isdn_slot_readbchan(int sl, u_char * buf, u_char * fp, int len)
 {
 	int count;
 	int count_pull;
 	int count_put;
 	int dflag;
+	int di = isdn_slot_driver(sl);
+	int ch = isdn_slot_channel(sl);
 	struct sk_buff *skb;
 	u_char *cp;
 
 	if (!dev->drv[di])
 		return 0;
-	if (skb_queue_empty(&dev->drv[di]->rpqueue[channel])) {
-		if (sleep)
-			interruptible_sleep_on(sleep);
-		else
-			return 0;
-	}
-	if (len > dev->drv[di]->rcvcount[channel])
-		len = dev->drv[di]->rcvcount[channel];
+	if (skb_queue_empty(&dev->drv[di]->rpqueue[ch]))
+		return 0;
+
+	if (len > dev->drv[di]->rcvcount[ch])
+		len = dev->drv[di]->rcvcount[ch];
 	cp = buf;
 	count = 0;
 	while (len) {
-		if (!(skb = skb_peek(&dev->drv[di]->rpqueue[channel])))
+		if (!(skb = skb_peek(&dev->drv[di]->rpqueue[ch])))
 			break;
 #ifdef CONFIG_ISDN_AUDIO
 		if (ISDN_AUDIO_SKB_LOCK(skb))
 			break;
 		ISDN_AUDIO_SKB_LOCK(skb) = 1;
-		if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << channel))) {
+		if ((ISDN_AUDIO_SKB_DLECOUNT(skb)) || (dev->drv[di]->DLEflag & (1 << ch))) {
 			char *p = skb->data;
-			unsigned long DLEmask = (1 << channel);
+			unsigned long DLEmask = (1 << ch);
 
 			dflag = 0;
 			count_pull = count_put = 0;
@@ -864,7 +828,7 @@
 #ifdef CONFIG_ISDN_AUDIO
 			ISDN_AUDIO_SKB_LOCK(skb) = 0;
 #endif
-			skb = skb_dequeue(&dev->drv[di]->rpqueue[channel]);
+			skb = skb_dequeue(&dev->drv[di]->rpqueue[ch]);
 			dev_kfree_skb(skb);
 		} else {
 			/* Not yet emptied this buff, so it
@@ -876,7 +840,7 @@
 			ISDN_AUDIO_SKB_LOCK(skb) = 0;
 #endif
 		}
-		dev->drv[di]->rcvcount[channel] -= count_put;
+		dev->drv[di]->rcvcount[ch] -= count_put;
 	}
 	return count;
 }
@@ -884,13 +848,13 @@
 static __inline int
 isdn_minor2drv(int minor)
 {
-	return (dev->drvmap[minor]);
+	return slot[minor].di;
 }
 
 static __inline int
 isdn_minor2chan(int minor)
 {
-	return (dev->chanmap[minor]);
+	return slot[minor].ch;
 }
 
 static char *
@@ -903,25 +867,25 @@
 	sprintf(istatbuf, "idmap:\t");
 	p = istatbuf + strlen(istatbuf);
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		sprintf(p, "%s ", (dev->drvmap[i] < 0) ? "-" : dev->drvid[dev->drvmap[i]]);
+		sprintf(p, "%s ", (slot[i].di < 0) ? "-" : dev->drvid[slot[i].di]);
 		p = istatbuf + strlen(istatbuf);
 	}
 	sprintf(p, "\nchmap:\t");
 	p = istatbuf + strlen(istatbuf);
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		sprintf(p, "%d ", dev->chanmap[i]);
+		sprintf(p, "%d ", slot[i].ch);
 		p = istatbuf + strlen(istatbuf);
 	}
 	sprintf(p, "\ndrmap:\t");
 	p = istatbuf + strlen(istatbuf);
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		sprintf(p, "%d ", dev->drvmap[i]);
+		sprintf(p, "%d ", slot[i].di);
 		p = istatbuf + strlen(istatbuf);
 	}
 	sprintf(p, "\nusage:\t");
 	p = istatbuf + strlen(istatbuf);
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		sprintf(p, "%d ", dev->usage[i]);
+		sprintf(p, "%d ", slot[i].usage);
 		p = istatbuf + strlen(istatbuf);
 	}
 	sprintf(p, "\nflags:\t");
@@ -938,7 +902,7 @@
 	sprintf(p, "\nphone:\t");
 	p = istatbuf + strlen(istatbuf);
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		sprintf(p, "%s ", dev->num[i]);
+		sprintf(p, "%s ", isdn_slot_num(i));
 		p = istatbuf + strlen(istatbuf);
 	}
 	sprintf(p, "\n");
@@ -1095,8 +1059,8 @@
 					       sizeof(ulong) * ISDN_MAX_CHANNELS * 2)))
 				return ret;
 			for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-				put_user(dev->ibytes[i], p++);
-				put_user(dev->obytes[i], p++);
+				put_user(slot[i].ibytes, p++);
+				put_user(slot[i].obytes, p++);
 			}
 			return 0;
 		} else
@@ -1279,10 +1243,9 @@
 	int ret;
 	int i;
 	char *p;
-	char *s;
 	union iocpar {
 		char name[10];
-		char bname[22];
+		char bname[20];
 		isdn_ioctl_struct iocts;
 		isdn_net_ioctl_phone phone;
 		isdn_net_ioctl_cfg cfg;
@@ -1310,42 +1273,24 @@
 #ifdef CONFIG_NETDEVICES
 	case IIOCNETAIF:
 		/* Add a network-interface */
-		if (arg) {
-			if (copy_from_user(name, (char *) arg, sizeof(name)))
-				return -EFAULT;
-			s = name;
-		} else {
-			s = NULL;
-		}
+		if (copy_from_user(name, (char *) arg, sizeof(name) - 1))
+			return -EFAULT;
+		name[sizeof(name)-1] = 0;
 		ret = down_interruptible(&dev->sem);
-		if( ret ) return ret;
-		if ((s = isdn_net_new(s, NULL))) {
-			if (copy_to_user((char *) arg, s, strlen(s) + 1)){
-				ret = -EFAULT;
-			} else {
-				ret = 0;
-			}
-		} else
-			ret = -ENODEV;
+		if (ret)
+			return ret;
+		ret = isdn_net_new(name, NULL);
 		up(&dev->sem);
 		return ret;
 	case IIOCNETASL:
 		/* Add a slave to a network-interface */
-		if (arg) {
-			if (copy_from_user(bname, (char *) arg, sizeof(bname) - 1))
-				return -EFAULT;
-		} else
-			return -EINVAL;
+		if (copy_from_user(bname, (char *) arg, sizeof(bname) - 1))
+			return -EFAULT;
+		bname[sizeof(bname)-1] = 0;
 		ret = down_interruptible(&dev->sem);
-		if( ret ) return ret;
-		if ((s = isdn_net_newslave(bname))) {
-			if (copy_to_user((char *) arg, s, strlen(s) + 1)){
-				ret = -EFAULT;
-			} else {
-				ret = 0;
-			}
-		} else
-			ret = -ENODEV;
+		if (ret)
+			return ret;
+		ret = isdn_net_newslave(bname);
 		up(&dev->sem);
 		return ret;
 	case IIOCNETDIF:
@@ -1742,8 +1687,8 @@
 #define L2V (~(ISDN_FEATURE_L2_V11096|ISDN_FEATURE_L2_V11019|ISDN_FEATURE_L2_V11038))
 
 int
-isdn_get_free_channel(int usage, int l2_proto, int l3_proto, int pre_dev
-		      ,int pre_chan, char *msn)
+isdn_get_free_slot(int usage, int l2_proto, int l3_proto,
+		   int pre_dev, int pre_chan, char *msn)
 {
 	int i;
 	ulong flags;
@@ -1760,34 +1705,28 @@
 	 * because we can emulate this in linklevel.
 	 */
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-		if (USG_NONE(dev->usage[i]) &&
-		    (dev->drvmap[i] != -1)) {
-			int d = dev->drvmap[i];
-			if ((dev->usage[i] & ISDN_USAGE_EXCLUSIVE) &&
-			((pre_dev != d) || (pre_chan != dev->chanmap[i])))
+		if (USG_NONE(slot[i].usage) &&
+		    (slot[i].di != -1)) {
+			int d = slot[i].di;
+			if ((slot[i].usage & ISDN_USAGE_EXCLUSIVE) &&
+			((pre_dev != d) || (pre_chan != slot[i].ch)))
 				continue;
 			if (!strcmp(isdn_map_eaz2msn(msn, d), "-"))
 				continue;
-			if (dev->usage[i] & ISDN_USAGE_DISABLED)
+			if (slot[i].usage & ISDN_USAGE_DISABLED)
 			        continue; /* usage not allowed */
 			if (dev->drv[d]->flags & DRV_FLAG_RUNNING) {
 				if (((dev->drv[d]->interface->features & features) == features) ||
 				    (((dev->drv[d]->interface->features & vfeatures) == vfeatures) &&
 				     (dev->drv[d]->interface->features & ISDN_FEATURE_L2_TRANS))) {
 					if ((pre_dev < 0) || (pre_chan < 0)) {
-						dev->usage[i] &= ISDN_USAGE_EXCLUSIVE;
-						dev->usage[i] |= usage;
-						isdn_info_update();
+						isdn_slot_set_usage(i, (isdn_slot_usage(i) & ISDN_USAGE_EXCLUSIVE) | usage);
+						restore_flags(flags);
+						return i;
+					} else if ((pre_dev == d) && (pre_chan == slot[i].ch)) {
+						isdn_slot_set_usage(i, (isdn_slot_usage(i) & ISDN_USAGE_EXCLUSIVE) | usage);
 						restore_flags(flags);
 						return i;
-					} else {
-						if ((pre_dev == d) && (pre_chan == dev->chanmap[i])) {
-							dev->usage[i] &= ISDN_USAGE_EXCLUSIVE;
-							dev->usage[i] |= usage;
-							isdn_info_update();
-							restore_flags(flags);
-							return i;
-						}
 					}
 				}
 			}
@@ -1802,28 +1741,32 @@
 void
 isdn_free_channel(int di, int ch, int usage)
 {
-	int i;
-	ulong flags;
+	int sl;
+
+	sl = isdn_dc2minor(di, ch);
+	isdn_slot_free(sl, usage);
+}
+
+void
+isdn_slot_free(int sl, int usage)
+{
+	unsigned long flags;
 
 	save_flags(flags);
 	cli();
-	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-		if (((!usage) || ((dev->usage[i] & ISDN_USAGE_MASK) == usage)) &&
-		    (dev->drvmap[i] == di) &&
-		    (dev->chanmap[i] == ch)) {
-			dev->usage[i] &= (ISDN_USAGE_NONE | ISDN_USAGE_EXCLUSIVE);
-			strcpy(dev->num[i], "???");
-			dev->ibytes[i] = 0;
-			dev->obytes[i] = 0;
+	if (!usage || (slot[sl].usage & ISDN_USAGE_MASK) == usage) {
+		strcpy(isdn_slot_num(sl), "???");
+		slot[sl].ibytes = 0;
+		slot[sl].obytes = 0;
 // 20.10.99 JIM, try to reinitialize v110 !
-			dev->v110emu[i] = 0;
-			atomic_set(&(dev->v110use[i]), 0);
-			isdn_v110_close(dev->v110[i]);
-			dev->v110[i] = NULL;
+		slot[sl].iv110.v110emu = 0;
+		atomic_set(&slot[sl].iv110.v110use, 0);
+		isdn_v110_close(slot[sl].iv110.v110);
+		slot[sl].iv110.v110 = NULL;
 // 20.10.99 JIM, try to reinitialize v110 !
-			isdn_info_update();
-			skb_queue_purge(&dev->drv[di]->rpqueue[ch]);
-		}
+		isdn_slot_set_usage(sl, isdn_slot_usage(sl) & (ISDN_USAGE_NONE | ISDN_USAGE_EXCLUSIVE));
+		skb_queue_purge(&dev->drv[isdn_slot_driver(sl)]->rpqueue[isdn_slot_channel(sl)]);
+	}
 	restore_flags(flags);
 }
 
@@ -1839,10 +1782,9 @@
 	save_flags(flags);
 	cli();
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-		if ((dev->drvmap[i] == di) &&
-		    (dev->chanmap[i] == ch)) {
-			dev->usage[i] &= ~ISDN_USAGE_EXCLUSIVE;
-			isdn_info_update();
+		if ((slot[i].di == di) &&
+		    (slot[i].ch == ch)) {
+			isdn_slot_set_usage(i, isdn_slot_usage(i) & ~ISDN_USAGE_EXCLUSIVE);
 			restore_flags(flags);
 			return;
 		}
@@ -1853,17 +1795,20 @@
  * Return: length of data on success, -ERRcode on failure.
  */
 int
-isdn_writebuf_skb_stub(int drvidx, int chan, int ack, struct sk_buff *skb)
+isdn_slot_write(int sl, struct sk_buff *skb)
 {
 	int ret;
 	struct sk_buff *nskb = NULL;
 	int v110_ret = skb->len;
-	int idx = isdn_dc2minor(drvidx, chan);
+	int di = isdn_slot_driver(sl);
+	int ch = isdn_slot_channel(sl);
 
-	if (dev->v110[idx]) {
-		atomic_inc(&dev->v110use[idx]);
-		nskb = isdn_v110_encode(dev->v110[idx], skb);
-		atomic_dec(&dev->v110use[idx]);
+	BUG_ON(sl < 0);
+
+	if (slot[sl].iv110.v110) {
+		atomic_inc(&slot[sl].iv110.v110use);
+		nskb = isdn_v110_encode(slot[sl].iv110.v110, skb);
+		atomic_dec(&slot[sl].iv110.v110use);
 		if (!nskb)
 			return 0;
 		v110_ret = *((int *)nskb->data);
@@ -1873,10 +1818,9 @@
 			return v110_ret;
 		}
 		/* V.110 must always be acknowledged */
-		ack = 1;
-		ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, nskb);
+		ret = dev->drv[di]->interface->writebuf_skb(di, ch, 1, nskb);
 	} else {
-		int hl = dev->drv[drvidx]->interface->hl_hdrlen;
+		int hl = isdn_slot_hdrlen(sl);
 
 		if( skb_headroom(skb) < hl ){
 			/* 
@@ -1892,22 +1836,22 @@
 			skb_tmp = skb_realloc_headroom(skb, hl);
 			printk(KERN_DEBUG "isdn_writebuf_skb_stub: reallocating headroom%s\n", skb_tmp ? "" : " failed");
 			if (!skb_tmp) return -ENOMEM; /* 0 better? */
-			ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, skb_tmp);
+			ret = dev->drv[di]->interface->writebuf_skb(di, ch, 1, skb_tmp);
 			if( ret > 0 ){
 				dev_kfree_skb(skb);
 			} else {
 				dev_kfree_skb(skb_tmp);
 			}
 		} else {
-			ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, ack, skb);
+			ret = dev->drv[di]->interface->writebuf_skb(di, ch, 1, skb);
 		}
 	}
 	if (ret > 0) {
-		dev->obytes[idx] += ret;
-		if (dev->v110[idx]) {
-			atomic_inc(&dev->v110use[idx]);
-			dev->v110[idx]->skbuser++;
-			atomic_dec(&dev->v110use[idx]);
+		slot[sl].obytes += ret;
+		if (slot[sl].iv110.v110) {
+			atomic_inc(&slot[sl].iv110.v110use);
+			slot[sl].iv110.v110->skbuser++;
+			atomic_dec(&slot[sl].iv110.v110use);
 			/* For V.110 return unencoded data length */
 			ret = v110_ret;
 			/* if the complete frame was send we free the skb;
@@ -1916,7 +1860,7 @@
 				dev_kfree_skb(skb);
 		}
 	} else
-		if (dev->v110[idx])
+		if (slot[sl].iv110.v110)
 			dev_kfree_skb(nskb);
 	return ret;
 }
@@ -1997,9 +1941,9 @@
 	cli();
 	for (j = d->channels; j < m; j++)
 		for (k = 0; k < ISDN_MAX_CHANNELS; k++)
-			if (dev->chanmap[k] < 0) {
-				dev->chanmap[k] = j;
-				dev->drvmap[k] = drvidx;
+			if (slot[k].ch < 0) {
+				slot[k].ch = j;
+				slot[k].di = drvidx;
 				isdn_register_devfs(k);
 				break;
 			}
@@ -2026,7 +1970,7 @@
 	}
 }
 
-#ifdef CONFIG_ISDN_DIVERSION
+#if defined(CONFIG_ISDN_DIVERSION) || defined(CONFIG_ISDN_DIVERSION_MODULE)
 
 static char *map_drvname(int di)
 {
@@ -2075,7 +2019,7 @@
 
 EXPORT_SYMBOL(DIVERT_REG_NAME);
 
-#endif /* CONFIG_ISDN_DIVERSION */
+#endif
 
 
 EXPORT_SYMBOL(register_isdn);
@@ -2140,6 +2084,186 @@
 	return 1;
 }
 
+int
+isdn_slot_driver(int sl)
+{
+	BUG_ON(sl < 0);
+
+	return slot[sl].di;
+}
+
+int
+isdn_slot_channel(int sl)
+{
+	BUG_ON(sl < 0);
+
+	return slot[sl].ch;
+}
+
+int
+isdn_slot_hdrlen(int sl)
+{
+	int di = isdn_slot_driver(sl);
+	
+	return dev->drv[di]->interface->hl_hdrlen;
+}
+
+char *
+isdn_slot_map_eaz2msn(int sl, char *msn)
+{
+	int di = isdn_slot_driver(sl);
+
+	return isdn_map_eaz2msn(msn, di);
+}
+
+int
+isdn_slot_command(int sl, int cmd, isdn_ctrl *ctrl)
+{
+	ctrl->command = cmd;
+	ctrl->driver = isdn_slot_driver(sl);
+	switch (cmd) {
+	case ISDN_CMD_SETL2:
+	case ISDN_CMD_SETL3:
+	case ISDN_CMD_PROT_IO:
+		ctrl->arg &= ~0xff; ctrl->arg |= isdn_slot_channel(sl);
+		break;
+	default:
+		ctrl->arg = isdn_slot_channel(sl);
+		break;
+	}
+
+	return isdn_command(ctrl);
+}
+
+int
+isdn_slot_dial(int sl, struct dial_info *dial)
+{
+	isdn_ctrl cmd;
+	int retval;
+	char *msn = isdn_slot_map_eaz2msn(sl, dial->msn);
+
+	/* check for DOV */
+	if (dial->si1 == 7 && tolower(dial->phone[0]) == 'v') { /* DOV call */
+		dial->si1 = 1;
+		dial->phone++; /* skip v/V */
+	}
+
+	strcpy(isdn_slot_num(sl), dial->phone);
+	isdn_slot_set_usage(sl, isdn_slot_usage(sl) | ISDN_USAGE_OUTGOING);
+
+	retval = isdn_slot_command(sl, ISDN_CMD_CLREAZ, &cmd);
+	if (retval)
+		return retval;
+
+	strcpy(cmd.parm.num, msn);
+	retval = isdn_slot_command(sl, ISDN_CMD_SETEAZ, &cmd);
+
+	cmd.arg = dial->l2_proto << 8;
+	cmd.parm.fax = dial->fax;
+	retval = isdn_slot_command(sl, ISDN_CMD_SETL2, &cmd);
+	if (retval)
+		return retval;
+
+	cmd.arg = dial->l3_proto << 8;
+	retval = isdn_slot_command(sl, ISDN_CMD_SETL3, &cmd);
+	if (retval)
+		return retval;
+
+	cmd.parm.setup.si1 = dial->si1;
+	cmd.parm.setup.si2 = dial->si2;
+	strcpy(cmd.parm.setup.eazmsn, msn);
+	strcpy(cmd.parm.setup.phone, dial->phone);
+
+	printk(KERN_INFO "ISDN: slot %d: Dialing %s -> %s (SI %d/%d) (B %d/%d)\n",
+	       sl, cmd.parm.setup.eazmsn, cmd.parm.setup.phone,
+	       cmd.parm.setup.si1, cmd.parm.setup.si2,
+	       dial->l2_proto, dial->l3_proto);
+
+	return isdn_slot_command(sl, ISDN_CMD_DIAL, &cmd);
+}
+
+void
+isdn_slot_all_eaz(int sl)
+{
+	isdn_ctrl cmd;
+
+	cmd.parm.num[0] = '\0';
+	isdn_slot_command(sl, ISDN_CMD_SETEAZ, &cmd);
+}
+
+int
+isdn_slot_usage(int sl)
+{
+	BUG_ON(sl < 0);
+
+	return slot[sl].usage;
+}
+
+void
+isdn_slot_set_usage(int sl, int usage)
+{
+	BUG_ON(sl < 0);
+
+	slot[sl].usage = usage;
+	isdn_info_update();
+}
+
+int
+isdn_slot_m_idx(int sl)
+{
+	BUG_ON(sl < 0);
+
+	return slot[sl].m_idx;
+}
+
+void
+isdn_slot_set_m_idx(int sl, int midx)
+{
+	BUG_ON(sl < 0);
+
+	slot[sl].m_idx = midx;
+}
+
+char *
+isdn_slot_num(int sl)
+{
+	BUG_ON(sl < 0);
+
+	return slot[sl].num;
+}
+
+void
+isdn_slot_set_rx_netdev(int sl, isdn_net_dev *nd)
+{
+	BUG_ON(sl < 0);
+
+	slot[sl].rx_netdev = nd;
+}
+
+isdn_net_dev *
+isdn_slot_rx_netdev(int sl)
+{
+	BUG_ON(sl < 0);
+
+	return slot[sl].rx_netdev;
+}
+
+void
+isdn_slot_set_st_netdev(int sl, isdn_net_dev *nd)
+{
+	BUG_ON(sl < 0);
+
+	slot[sl].st_netdev = nd;
+}
+
+isdn_net_dev *
+isdn_slot_st_netdev(int sl)
+{
+	BUG_ON(sl < 0);
+
+	return slot[sl].st_netdev;
+}
+
 /*
  *****************************************************************************
  * And now the modules code.
@@ -2247,53 +2371,43 @@
 static int __init isdn_init(void)
 {
 	int i;
+	int retval;
 	char tmprev[50];
 
-	if (!(dev = (isdn_dev *) vmalloc(sizeof(isdn_dev)))) {
-		printk(KERN_WARNING "isdn: Could not allocate device-struct.\n");
-		return -EIO;
+	dev = vmalloc(sizeof(*dev));
+	if (!dev) {
+		retval = -ENOMEM;
+		goto err;
 	}
-	memset((char *) dev, 0, sizeof(isdn_dev));
+	memset(dev, 0, sizeof(*dev));
 	init_timer(&dev->timer);
 	dev->timer.function = isdn_timer_funct;
 	init_MUTEX(&dev->sem);
 	init_waitqueue_head(&dev->info_waitq);
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		dev->drvmap[i] = -1;
-		dev->chanmap[i] = -1;
-		dev->m_idx[i] = -1;
-		strcpy(dev->num[i], "???");
+		slot[i].di = -1;
+		slot[i].ch = -1;
+		slot[i].m_idx = -1;
+		strcpy(isdn_slot_num(i), "???");
 		init_waitqueue_head(&dev->mdm.info[i].open_wait);
 		init_waitqueue_head(&dev->mdm.info[i].close_wait);
 	}
-	if (register_chrdev(ISDN_MAJOR, "isdn", &isdn_fops)) {
+	retval = register_chrdev(ISDN_MAJOR, "isdn", &isdn_fops);
+	if (retval) {
 		printk(KERN_WARNING "isdn: Could not register control devices\n");
-		vfree(dev);
-		return -EIO;
+		goto err_vfree;
 	}
 	isdn_init_devfs();
-	if ((i = isdn_tty_modem_init()) < 0) {
+	retval = isdn_tty_init();
+	if (retval < 0) {
 		printk(KERN_WARNING "isdn: Could not register tty devices\n");
-		if (i == -3)
-			tty_unregister_driver(&dev->mdm.cua_modem);
-		if (i <= -2)
-			tty_unregister_driver(&dev->mdm.tty_modem);
-		vfree(dev);
-		isdn_cleanup_devfs();
-		unregister_chrdev(ISDN_MAJOR, "isdn");
-		return -EIO;
+		goto err_cleanup_devfs;
 	}
 #ifdef CONFIG_ISDN_PPP
-	if (isdn_ppp_init() < 0) {
+	retval = isdn_ppp_init();
+	if (retval < 0) {
 		printk(KERN_WARNING "isdn: Could not create PPP-device-structs\n");
-		tty_unregister_driver(&dev->mdm.tty_modem);
-		tty_unregister_driver(&dev->mdm.cua_modem);
-		for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-			kfree(dev->mdm.info[i].xmit_buf - 4);
-		isdn_cleanup_devfs();
-		unregister_chrdev(ISDN_MAJOR, "isdn");
-		vfree(dev);
-		return -EIO;
+		goto err_tty_modem;
 	}
 #endif                          /* CONFIG_ISDN_PPP */
 
@@ -2317,6 +2431,16 @@
 #endif
 	isdn_info_update();
 	return 0;
+
+ err_tty_modem:
+	isdn_tty_exit();
+ err_cleanup_devfs:
+	isdn_cleanup_devfs();
+	unregister_chrdev(ISDN_MAJOR, "isdn");
+ err_vfree:
+	vfree(dev);
+ err:
+	return retval;
 }
 
 /*
@@ -2325,46 +2449,24 @@
 static void __exit isdn_exit(void)
 {
 	unsigned long flags;
-	int i;
 
 #ifdef CONFIG_ISDN_PPP
 	isdn_ppp_cleanup();
 #endif
 	save_flags(flags);
 	cli();
-	if (isdn_net_rmall() < 0) {
-		printk(KERN_WARNING "isdn: net-device busy, remove cancelled\n");
-		restore_flags(flags);
-		return;
-	}
-	if (tty_unregister_driver(&dev->mdm.tty_modem)) {
-		printk(KERN_WARNING "isdn: ttyI-device busy, remove cancelled\n");
-		restore_flags(flags);
-		return;
-	}
-	if (tty_unregister_driver(&dev->mdm.cua_modem)) {
-		printk(KERN_WARNING "isdn: cui-device busy, remove cancelled\n");
-		restore_flags(flags);
-		return;
-	}
-	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		isdn_tty_cleanup_xmit(&dev->mdm.info[i]);
-		kfree(dev->mdm.info[i].xmit_buf - 4);
-#ifdef CONFIG_ISDN_TTY_FAX
-		kfree(dev->mdm.info[i].fax);
-#endif
-	}
-	if (unregister_chrdev(ISDN_MAJOR, "isdn") != 0) {
-		printk(KERN_WARNING "isdn: controldevice busy, remove cancelled\n");
-		restore_flags(flags);
-	} else {
-		isdn_cleanup_devfs();
-		del_timer(&dev->timer);
-		restore_flags(flags);
-		/* call vfree with interrupts enabled, else it will hang */
-		vfree(dev);
-		printk(KERN_NOTICE "ISDN-subsystem unloaded\n");
-	}
+	if (isdn_net_rmall() < 0)
+		BUG();
+
+	isdn_tty_exit();
+	if (unregister_chrdev(ISDN_MAJOR, "isdn"))
+		BUG();
+
+	isdn_cleanup_devfs();
+	del_timer(&dev->timer);
+	restore_flags(flags);
+	/* call vfree with interrupts enabled, else it will hang */
+	vfree(dev);
 }
 
 module_init(isdn_init);
diff -Nru a/drivers/isdn/i4l/isdn_common.h b/drivers/isdn/i4l/isdn_common.h
--- a/drivers/isdn/i4l/isdn_common.h	Sat Aug 10 18:42:21 2002
+++ b/drivers/isdn/i4l/isdn_common.h	Sat Aug 10 18:42:21 2002
@@ -23,6 +23,32 @@
 #undef  ISDN_DEBUG_NET_DUMP
 #undef  ISDN_DEBUG_NET_DIAL
 #undef  ISDN_DEBUG_NET_ICALL
+#undef  ISDN_DEBUG_STATCALLB
+#undef  ISDN_DEBUG_COMMAND
+
+#ifdef ISDN_DEBUG_NET_DIAL
+#define dbg_net_dial(arg...) printk(KERN_DEBUG arg)
+#else
+#define dbg_net_dial(arg...) do {} while (0)
+#endif
+
+#ifdef ISDN_DEBUG_NET_ICALL
+#define dbg_net_icall(arg...) printk(KERN_DEBUG arg)
+#else
+#define dbg_net_icall(arg...) do {} while (0)
+#endif
+
+#ifdef ISDN_DEBUG_STATCALLB
+#define dbg_statcallb(arg...) printk(KERN_DEBUG arg)
+#else
+#define dbg_statcallb(arg...) do {} while (0)
+#endif
+
+#define isdn_BUG() \
+do { printk(KERN_WARNING "ISDN Bug at %s:%d\n", __FILE__, __LINE__); \
+} while(0)
+
+#define HERE printk("%s:%d (%s)\n", __FILE__, __LINE__, __FUNCTION__)
 
 /* Prototypes */
 extern void isdn_MOD_INC_USE_COUNT(void);
@@ -30,20 +56,50 @@
 extern void isdn_lock_drivers(void);
 extern void isdn_unlock_drivers(void);
 extern void isdn_free_channel(int di, int ch, int usage);
-extern void isdn_all_eaz(int di, int ch);
-extern int isdn_command(isdn_ctrl *);
 extern int isdn_dc2minor(int di, int ch);
 extern void isdn_info_update(void);
 extern char *isdn_map_eaz2msn(char *msn, int di);
 extern void isdn_timer_ctrl(int tf, int onoff);
 extern void isdn_unexclusive_channel(int di, int ch);
 extern int isdn_getnum(char **);
-extern int isdn_readbchan(int, int, u_char *, u_char *, int, wait_queue_head_t *);
-extern int isdn_get_free_channel(int, int, int, int, int, char *);
-extern int isdn_writebuf_skb_stub(int, int, int, struct sk_buff *);
-extern int register_isdn(isdn_if * i);
 extern int isdn_msncmp( const char *,  const char *);
 extern int isdn_add_channels(driver *, int, int, int);
 #if defined(ISDN_DEBUG_NET_DUMP) || defined(ISDN_DEBUG_MODEM_DUMP)
 extern void isdn_dumppkt(char *, u_char *, int, int);
+#else
+static inline void isdn_dumppkt(char *s, u_char *d, int l, int m) { }
 #endif
+
+struct dial_info {
+	int            l2_proto;
+	int            l3_proto;
+	struct T30_s  *fax;
+	unsigned char  si1;
+	unsigned char  si2;
+	unsigned char *msn;
+	unsigned char *phone;
+};
+
+extern struct list_head isdn_net_devs;
+
+extern int   isdn_get_free_slot(int, int, int, int, int, char *);
+extern void  isdn_slot_free(int slot, int usage);
+extern void  isdn_slot_all_eaz(int slot);
+extern int   isdn_slot_command(int slot, int cmd, isdn_ctrl *);
+extern int   isdn_slot_dial(int slot, struct dial_info *dial);
+extern char *isdn_slot_map_eaz2msn(int slot, char *msn);
+extern int   isdn_slot_write(int slot, struct sk_buff *);
+extern int   isdn_slot_readbchan(int slot, u_char *, u_char *, int);
+extern int   isdn_slot_hdrlen(int slot);
+extern int   isdn_slot_driver(int slot);
+extern int   isdn_slot_channel(int slot);
+extern int   isdn_slot_usage(int slot);
+extern void  isdn_slot_set_usage(int slot, int usage);
+extern char *isdn_slot_num(int slot);
+extern int   isdn_slot_m_idx(int slot);
+extern void  isdn_slot_set_m_idx(int slot, int midx);
+extern void  isdn_slot_set_rx_netdev(int sl, isdn_net_dev *nd);
+extern void  isdn_slot_set_st_netdev(int sl, isdn_net_dev *nd);
+extern isdn_net_dev *isdn_slot_rx_netdev(int sl);
+extern isdn_net_dev *isdn_slot_st_netdev(int sl);
+
diff -Nru a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
--- a/drivers/isdn/i4l/isdn_net.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/isdn/i4l/isdn_net.c	Sat Aug 10 18:42:22 2002
@@ -38,6 +38,27 @@
 #include "isdn_concap.h"
 #endif
 
+enum {
+	ST_NULL,
+	ST_OUT_WAIT_DCONN,
+	ST_OUT_WAIT_BCONN,
+	ST_IN_WAIT_DCONN,
+	ST_IN_WAIT_BCONN,
+	ST_ACTIVE,
+	ST_WAIT_BEFORE_CB,
+};
+
+/* keep clear of ISDN_CMD_* and ISDN_STAT_* */
+enum {
+	EV_NET_DIAL            = 0x200,
+	EV_NET_TIMER_IN_DCONN  = 0x201,
+	EV_NET_TIMER_IN_BCONN  = 0x202,
+	EV_NET_TIMER_OUT_DCONN = 0x203,
+	EV_NET_TIMER_OUT_BCONN = 0x204,
+	EV_NET_TIMER_CB        = 0x205,
+};
+
+LIST_HEAD(isdn_net_devs); /* Linked list of isdn_net_dev's */
 
 /*
  * Outline of new tbusy handling: 
@@ -72,7 +93,7 @@
  */
 static __inline__ int isdn_net_device_started(isdn_net_dev *n)
 {
-	isdn_net_local *lp = n->local;
+	isdn_net_local *lp = &n->local;
 	struct net_device *dev;
 	
 	if (lp->master) 
@@ -179,10 +200,13 @@
 
 int isdn_net_force_dial_lp(isdn_net_local *);
 static int isdn_net_start_xmit(struct sk_buff *, struct net_device *);
+static int do_dialout(isdn_net_local *lp);
 
 static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
 static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp);
 
+static int isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg);
+
 char *isdn_net_revision = "$Revision: 1.140.6.11 $";
 
  /*
@@ -280,10 +304,9 @@
 	save_flags(flags);
 	cli();
 	lp->flags |= ISDN_NET_CONNECTED;
-	lp->isdn_device = dev->drvmap[idx];
-	lp->isdn_channel = dev->chanmap[idx];
-	dev->rx_netdev[idx] = lp->netdev;
-	dev->st_netdev[idx] = lp->netdev;
+	lp->isdn_slot = idx;
+	isdn_slot_set_rx_netdev(lp->isdn_slot, lp->netdev);
+	isdn_slot_set_st_netdev(lp->isdn_slot, lp->netdev);
 	restore_flags(flags);
 }
 
@@ -306,13 +329,14 @@
 		 */
 		qdisc_reset(lp->netdev->dev.qdisc);
 	}
-	lp->dialstate = 0;
-	dev->rx_netdev[isdn_dc2minor(lp->isdn_device, lp->isdn_channel)] = NULL;
-	dev->st_netdev[isdn_dc2minor(lp->isdn_device, lp->isdn_channel)] = NULL;
-	isdn_free_channel(lp->isdn_device, lp->isdn_channel, ISDN_USAGE_NET);
+	lp->dialstate = ST_NULL;
+	if (lp->isdn_slot >= 0) {
+		isdn_slot_set_rx_netdev(lp->isdn_slot, NULL);
+		isdn_slot_set_st_netdev(lp->isdn_slot, NULL);
+		isdn_slot_free(lp->isdn_slot, ISDN_USAGE_NET);
+	}
 	lp->flags &= ~ISDN_NET_CONNECTED;
-	lp->isdn_device = -1;
-	lp->isdn_channel = -1;
+	lp->isdn_slot = -1;
 
 	restore_flags(flags);
 }
@@ -335,12 +359,13 @@
 void
 isdn_net_autohup()
 {
-	isdn_net_dev *p = dev->netdev;
+	struct list_head *l;
 	int anymore;
 
 	anymore = 0;
-	while (p) {
-		isdn_net_local *l = p->local;
+	list_for_each(l, &isdn_net_devs) {
+		isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
+		isdn_net_local *l = &p->local;
 		if (jiffies == last_jiffies)
 			l->cps = l->transcount;
 		else
@@ -348,9 +373,10 @@
 		l->transcount = 0;
 		if (dev->net_verbose > 3)
 			printk(KERN_DEBUG "%s: %d bogocps\n", l->name, l->cps);
-		if ((l->flags & ISDN_NET_CONNECTED) && (!l->dialstate)) {
+		if ((l->flags & ISDN_NET_CONNECTED) && (l->dialstate == ST_ACTIVE)) {
 			anymore = 1;
 			l->huptimer++;
+			printk("huptimer %d, onhtime %d, chargetime %d, chargeint %d\n", l->huptimer, l->onhtime, l->chargetime, l->chargeint);
 			/*
 			 * if there is some dialmode where timeout-hangup
 			 * should _not_ be done, check for that here
@@ -363,8 +389,10 @@
 					while (time_after(jiffies, l->chargetime + l->chargeint))
 						l->chargetime += l->chargeint;
 					if (time_after(jiffies, l->chargetime + l->chargeint - 2 * HZ))
-						if (l->outgoing || l->hupflags & ISDN_INHUP)
+						if (l->outgoing || l->hupflags & ISDN_INHUP) {
+							HERE;
 							isdn_net_hangup(&p->dev);
+						}
 				} else if (l->outgoing) {
 					if (l->hupflags & ISDN_CHARGEHUP) {
 						if (l->hupflags & ISDN_WAITCHARGE) {
@@ -378,8 +406,10 @@
 							isdn_net_hangup(&p->dev);
 						}
 					}
-				} else if (l->hupflags & ISDN_INHUP)
+				} else if (l->hupflags & ISDN_INHUP) {
+					HERE;
 					isdn_net_hangup(&p->dev);
+				}
 			}
 
 			if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*l) == ISDN_NET_DM_OFF)) {
@@ -387,7 +417,6 @@
 				break;
 			}
 		}
-		p = (isdn_net_dev *) p->next;
 	}
 	last_jiffies = jiffies;
 	isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, anymore);
@@ -398,6 +427,47 @@
 	isdn_net_rm_from_bundle(lp);
 }
 
+static void isdn_net_connected(isdn_net_local *lp)
+{
+#ifdef CONFIG_ISDN_X25
+	struct concap_proto *cprot = lp -> netdev -> cprot;
+	struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
+#endif
+	lp->dialstate = ST_ACTIVE;
+	isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);
+	if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
+		isdn_net_ciscohdlck_connected(lp);
+	if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {
+		if (lp->master) { /* is lp a slave? */
+			isdn_net_dev *nd = ((isdn_net_local *)lp->master->priv)->netdev;
+			isdn_net_add_to_bundle(nd, lp);
+		}
+	}
+	printk(KERN_INFO "isdn_net: %s connected\n", lp->name);
+	/* If first Chargeinfo comes before B-Channel connect,
+	 * we correct the timestamp here.
+	 */
+	lp->chargetime = jiffies;
+	
+	/* reset dial-timeout */
+	lp->dialstarted = 0;
+	lp->dialwait_timer = 0;
+	
+#ifdef CONFIG_ISDN_PPP
+	if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
+		isdn_ppp_wakeup_daemon(lp);
+#endif
+#ifdef CONFIG_ISDN_X25
+	/* try if there are generic concap receiver routines */
+	if( pops )
+		if( pops->connect_ind)
+			pops->connect_ind(cprot);
+#endif /* CONFIG_ISDN_X25 */
+	/* ppp needs to do negotiations first */
+	if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
+		isdn_net_device_wake_queue(lp);
+}
+
 /*
  * Handle status-messages from ISDN-interfacecard.
  * This function is called from within the main-status-dispatcher
@@ -407,443 +477,343 @@
 int
 isdn_net_stat_callback(int idx, isdn_ctrl *c)
 {
-	isdn_net_dev *p = dev->st_netdev[idx];
+	isdn_net_dev *p = isdn_slot_st_netdev(idx);
+	isdn_net_local *lp;
 	int cmd = c->command;
 
-	if (p) {
-		isdn_net_local *lp = p->local;
-#ifdef CONFIG_ISDN_X25
-		struct concap_proto *cprot = lp -> netdev -> cprot;
-		struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
-#endif
-		switch (cmd) {
-			case ISDN_STAT_BSENT:
-				/* A packet has successfully been sent out */
-				if ((lp->flags & ISDN_NET_CONNECTED) &&
-				    (!lp->dialstate)) {
-					isdn_net_dec_frame_cnt(lp);
-					lp->stats.tx_packets++;
-					lp->stats.tx_bytes += c->parm.length;
-				}
-				return 1;
-			case ISDN_STAT_DCONN:
-				/* D-Channel is up */
-				switch (lp->dialstate) {
-					case 4:
-					case 7:
-					case 8:
-						lp->dialstate++;
-						return 1;
-					case 12:
-						lp->dialstate = 5;
-						return 1;
-				}
-				break;
-			case ISDN_STAT_DHUP:
-				/* Either D-Channel-hangup or error during dialout */
-#ifdef CONFIG_ISDN_X25
-				/* If we are not connencted then dialing had
-				   failed. If there are generic encap protocol
-				   receiver routines signal the closure of
-				   the link*/
-
-				if( !(lp->flags & ISDN_NET_CONNECTED)
-				    && pops && pops -> disconn_ind )
-					pops -> disconn_ind(cprot);
-#endif /* CONFIG_ISDN_X25 */
-				if ((!lp->dialstate) && (lp->flags & ISDN_NET_CONNECTED)) {
-					if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
-						isdn_net_ciscohdlck_disconnected(lp);
-#ifdef CONFIG_ISDN_PPP
-					if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
-						isdn_ppp_free(lp);
-#endif
-					isdn_net_lp_disconnected(lp);
-					isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
-					printk(KERN_INFO "%s: remote hangup\n", lp->name);
-					printk(KERN_INFO "%s: Chargesum is %d\n", lp->name,
-					       lp->charge);
-					isdn_net_unbind_channel(lp);
-					return 1;
-				}
-				break;
-#ifdef CONFIG_ISDN_X25
-			case ISDN_STAT_BHUP:
-				/* B-Channel-hangup */
-				/* try if there are generic encap protocol
-				   receiver routines and signal the closure of
-				   the link */
-				if( pops  &&  pops -> disconn_ind ){
-						pops -> disconn_ind(cprot);
-						return 1;
-					}
-				break;
-#endif /* CONFIG_ISDN_X25 */
-			case ISDN_STAT_BCONN:
-				/* B-Channel is up */
-				isdn_net_zero_frame_cnt(lp);
-				switch (lp->dialstate) {
-					case 5:
-					case 6:
-					case 7:
-					case 8:
-					case 9:
-					case 10:
-					case 12:
-						if (lp->dialstate <= 6) {
-							dev->usage[idx] |= ISDN_USAGE_OUTGOING;
-							isdn_info_update();
-						} else
-							dev->rx_netdev[idx] = p;
-						lp->dialstate = 0;
-						isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);
-						if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
-							isdn_net_ciscohdlck_connected(lp);
-						if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {
-							if (lp->master) { /* is lp a slave? */
-								isdn_net_dev *nd = ((isdn_net_local *)lp->master->priv)->netdev;
-								isdn_net_add_to_bundle(nd, lp);
-							}
-						}
-						printk(KERN_INFO "isdn_net: %s connected\n", lp->name);
-						/* If first Chargeinfo comes before B-Channel connect,
-						 * we correct the timestamp here.
-						 */
-						lp->chargetime = jiffies;
+	if (!p) {
+		HERE;
+		return 0;
+	}
+	lp = &p->local;
 
-						/* reset dial-timeout */
-						lp->dialstarted = 0;
-						lp->dialwait_timer = 0;
+	return isdn_net_handle_event(lp, cmd, c);
+}
 
-#ifdef CONFIG_ISDN_PPP
-						if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
-							isdn_ppp_wakeup_daemon(lp);
-#endif
-#ifdef CONFIG_ISDN_X25
-						/* try if there are generic concap receiver routines */
-						if( pops )
-							if( pops->connect_ind)
-								pops->connect_ind(cprot);
-#endif /* CONFIG_ISDN_X25 */
-						/* ppp needs to do negotiations first */
-						if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
-							isdn_net_device_wake_queue(lp);
-						return 1;
-				}
-				break;
-			case ISDN_STAT_NODCH:
-				/* No D-Channel avail. */
-				if (lp->dialstate == 4) {
-					lp->dialstate--;
-					return 1;
-				}
-				break;
-			case ISDN_STAT_CINF:
-				/* Charge-info from TelCo. Calculate interval between
-				 * charge-infos and set timestamp for last info for
-				 * usage by isdn_net_autohup()
-				 */
-				lp->charge++;
-				if (lp->hupflags & ISDN_HAVECHARGE) {
-					lp->hupflags &= ~ISDN_WAITCHARGE;
-					lp->chargeint = jiffies - lp->chargetime - (2 * HZ);
-				}
-				if (lp->hupflags & ISDN_WAITCHARGE)
-					lp->hupflags |= ISDN_HAVECHARGE;
-				lp->chargetime = jiffies;
-				printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
-				       lp->name, lp->chargetime);
-				return 1;
-		}
+static void
+isdn_net_dial_timer(unsigned long data)
+{
+	isdn_net_local *lp = (isdn_net_local *) data;
+
+	if (!lp) {
+		isdn_BUG();
+		return;
 	}
-	return 0;
+	printk("%s: %s %#x\n", __FUNCTION__, lp->name, lp->dial_event);
+	isdn_net_handle_event(lp, lp->dial_event, NULL);
 }
 
-/*
- * Perform dialout for net-interfaces and timeout-handling for
- * D-Channel-up and B-Channel-up Messages.
- * This function is initially called from within isdn_net_start_xmit() or
- * or isdn_net_find_icall() after initializing the dialstate for an
- * interface. If further calls are needed, the function schedules itself
- * for a timer-callback via isdn_timer_function().
- * The dialstate is also affected by incoming status-messages from
- * the ISDN-Channel which are handled in isdn_net_stat_callback() above.
+/* Initiate dialout. Set phone-number-pointer to first number
+ * of interface.
  */
-void
-isdn_net_dial(void)
+static int
+init_dialout(isdn_net_local *lp)
 {
-	isdn_net_dev *p = dev->netdev;
-	int anymore = 0;
-	int i;
 	unsigned long flags;
-	isdn_ctrl cmd;
-        u_char *phone_number;
 
-	while (p) {
-		isdn_net_local *lp = p->local;
+	save_flags(flags);
+	cli();
+	lp->dial = lp->phone[1];
+	restore_flags(flags);
 
-#ifdef ISDN_DEBUG_NET_DIAL
-		if (lp->dialstate)
-			printk(KERN_DEBUG "%s: dialstate=%d\n", lp->name, lp->dialstate);
-#endif
-		switch (lp->dialstate) {
-			case 0:
-				/* Nothing to do for this interface */
-				break;
-			case 1:
-				/* Initiate dialout. Set phone-number-pointer to first number
-				 * of interface.
-				 */
-				save_flags(flags);
-				cli();
-				lp->dial = lp->phone[1];
-				restore_flags(flags);
-				if (!lp->dial) {
-					printk(KERN_WARNING "%s: phone number deleted?\n",
-					       lp->name);
-					isdn_net_hangup(&p->dev);
-					break;
-				}
-				anymore = 1;
+	if (!lp->dial) {
+		printk(KERN_WARNING "%s: phone number deleted?\n",
+		       lp->name);
+		isdn_net_hangup(&lp->netdev->dev);
+		return 0;
+	}
+	if (lp->dialtimeout > 0 &&
+	    (lp->dialstarted == 0 || 
+	     time_after(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait))) {
+		lp->dialstarted = jiffies;
+		lp->dialwait_timer = 0;
+	}
+	lp->dialretry = 0;
+	return do_dialout(lp);
+}
 
-				if(lp->dialtimeout > 0)
-					if(lp->dialstarted == 0 || time_after(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait)) {
-						lp->dialstarted = jiffies;
-						lp->dialwait_timer = 0;
-					}
+/* Setup interface, dial current phone-number, switch to next number.
+ * If list of phone-numbers is exhausted, increment
+ * retry-counter.
+ */
+static int
+do_dialout(isdn_net_local *lp)
+{
+	unsigned long flags;
 
-				lp->dialstate++;
-				/* Fall through */
-			case 2:
-				/* Prepare dialing. Clear EAZ, then set EAZ. */
-				cmd.driver = lp->isdn_device;
-				cmd.arg = lp->isdn_channel;
-				cmd.command = ISDN_CMD_CLREAZ;
-				isdn_command(&cmd);
-				sprintf(cmd.parm.num, "%s", isdn_map_eaz2msn(lp->msn, cmd.driver));
-				cmd.command = ISDN_CMD_SETEAZ;
-				isdn_command(&cmd);
-				lp->dialretry = 0;
-				anymore = 1;
-				lp->dialstate++;
-				/* Fall through */
-			case 3:
-				/* Setup interface, dial current phone-number, switch to next number.
-				 * If list of phone-numbers is exhausted, increment
-				 * retry-counter.
-				 */
-				if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF)) {
-					char *s;
-					if (dev->global_flags & ISDN_GLOBAL_STOPPED)
-						s = "dial suppressed: isdn system stopped";
-					else
-						s = "dial suppressed: dialmode `off'";
-					isdn_net_unreachable(&p->dev, 0, s);
-					isdn_net_hangup(&p->dev);
-					break;
-				}
-				cmd.driver = lp->isdn_device;
-				cmd.command = ISDN_CMD_SETL2;
-				cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);
-				isdn_command(&cmd);
-				cmd.driver = lp->isdn_device;
-				cmd.command = ISDN_CMD_SETL3;
-				cmd.arg = lp->isdn_channel + (lp->l3_proto << 8);
-				isdn_command(&cmd);
-				cmd.driver = lp->isdn_device;
-				cmd.arg = lp->isdn_channel;
-				save_flags(flags);
-				cli();
-				if (!lp->dial) {
-					restore_flags(flags);
-					printk(KERN_WARNING "%s: phone number deleted?\n",
-					       lp->name);
-					isdn_net_hangup(&p->dev);
-					break;
+	if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF)) {
+		char *s;
+		if (dev->global_flags & ISDN_GLOBAL_STOPPED)
+			s = "dial suppressed: isdn system stopped";
+		else
+			s = "dial suppressed: dialmode `off'";
+		isdn_net_unreachable(&lp->netdev->dev, 0, s);
+		isdn_net_hangup(&lp->netdev->dev);
+		return 0;
+	}
+
+	save_flags(flags);
+	cli();
+	if (!lp->dial) {
+		restore_flags(flags);
+		printk(KERN_WARNING "%s: phone number deleted?\n",
+		       lp->name);
+		isdn_net_hangup(&lp->netdev->dev);
+		return 0;
+	}
+	if (!strncmp(lp->dial->num, "LEASED", strlen("LEASED"))) {
+		restore_flags(flags);
+		lp->dialstate = ST_OUT_WAIT_DCONN;
+		printk(KERN_INFO "%s: Open leased line ...\n", lp->name);
+		return 1;
+	} else {
+		struct dial_info dial = {
+			.l2_proto = lp->l2_proto,
+			.l3_proto = lp->l3_proto,
+			.si1      = 7,
+			.si2      = 0,
+			.msn      = lp->msn,
+			.phone    = lp->dial->num,
+		};
+		if(lp->dialtimeout > 0) {
+			if (time_after(jiffies, lp->dialstarted + lp->dialtimeout)) {
+				restore_flags(flags);
+				lp->dialwait_timer = jiffies + lp->dialwait;
+				lp->dialstarted = 0;
+				isdn_net_unreachable(&lp->netdev->dev, 0, "dial: timed out");
+				isdn_net_hangup(&lp->netdev->dev);
+				return 0;
+			}
+		}
+		/*
+		 * Switch to next number or back to start if at end of list.
+		 */
+		if (!(lp->dial = (isdn_net_phone *) lp->dial->next)) {
+			lp->dial = lp->phone[1];
+			lp->dialretry++;
+			
+			if (lp->dialretry > lp->dialmax) {
+				restore_flags(flags);
+				if (lp->dialtimeout == 0) {
+					lp->dialwait_timer = jiffies + lp->dialwait;
+					lp->dialstarted = 0;
+					isdn_net_unreachable(&lp->netdev->dev, 0, "dial: tried all numbers dialmax times");
 				}
-				if (!strncmp(lp->dial->num, "LEASED", strlen("LEASED"))) {
-					restore_flags(flags);
-					lp->dialstate = 4;
-					printk(KERN_INFO "%s: Open leased line ...\n", lp->name);
-				} else {
-					if(lp->dialtimeout > 0)
-						if (time_after(jiffies, lp->dialstarted + lp->dialtimeout)) {
-							restore_flags(flags);
-							lp->dialwait_timer = jiffies + lp->dialwait;
-							lp->dialstarted = 0;
-							isdn_net_unreachable(&p->dev, 0, "dial: timed out");
-							isdn_net_hangup(&p->dev);
-							break;
-						}
+				isdn_net_hangup(&lp->netdev->dev);
+				return 0;
+			}
+		}
+		restore_flags(flags);
+		isdn_slot_dial(lp->isdn_slot, &dial);
+	}
+	lp->huptimer = 0;
+	lp->outgoing = 1;
+	if (lp->chargeint) {
+		lp->hupflags |= ISDN_HAVECHARGE;
+		lp->hupflags &= ~ISDN_WAITCHARGE;
+	} else {
+		lp->hupflags |= ISDN_WAITCHARGE;
+		lp->hupflags &= ~ISDN_HAVECHARGE;
+	}
+	if (lp->cbdelay && (lp->flags & ISDN_NET_CBOUT)) {
+		lp->dial_timer.expires = jiffies + lp->cbdelay;
+		lp->dial_event = EV_NET_TIMER_CB;
+	} else {
+		lp->dial_timer.expires = jiffies + 10 * HZ;
+		lp->dial_event = EV_NET_TIMER_OUT_DCONN;
+	}
+	lp->dialstate = ST_OUT_WAIT_DCONN;
+	add_timer(&lp->dial_timer);
+	return 1;
+}
 
-					cmd.driver = lp->isdn_device;
-					cmd.command = ISDN_CMD_DIAL;
-					cmd.parm.setup.si2 = 0;
-
-                                        /* check for DOV */
-                                        phone_number = lp->dial->num;
-                                        if ((*phone_number == 'v') ||
-					    (*phone_number == 'V')) { /* DOV call */
-                                                cmd.parm.setup.si1 = 1;
-                                        } else { /* DATA call */
-                                                cmd.parm.setup.si1 = 7;
-					}
+/* For EV_NET_DIAL, returns 1 if timer callback is needed 
+ * For ISDN_STAT_*, returns 1 if event was for us 
+ */
+static int
+isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg)
+{
+#ifdef CONFIG_ISDN_X25
+	struct concap_proto *cprot = lp -> netdev -> cprot;
+	struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
+#endif
+	isdn_net_dev *p = lp->netdev;
+	isdn_ctrl *c = arg;
+	isdn_ctrl cmd;
 
-					strcpy(cmd.parm.setup.phone, phone_number);
-					/*
-					 * Switch to next number or back to start if at end of list.
-					 */
-					if (!(lp->dial = (isdn_net_phone *) lp->dial->next)) {
-						lp->dial = lp->phone[1];
-						lp->dialretry++;
+	dbg_net_dial("%s: dialstate=%d pr=%#x\n", lp->name, lp->dialstate,pr);
 
-						if (lp->dialretry > lp->dialmax) {
-							restore_flags(flags);
-							if (lp->dialtimeout == 0) {
-								lp->dialwait_timer = jiffies + lp->dialwait;
-								lp->dialstarted = 0;
-								isdn_net_unreachable(&p->dev, 0, "dial: tried all numbers dialmax times");
-							}
-							isdn_net_hangup(&p->dev);
-							break;
-						}
-					}
-					restore_flags(flags);
-					sprintf(cmd.parm.setup.eazmsn, "%s",
-						isdn_map_eaz2msn(lp->msn, cmd.driver));
-					i = isdn_dc2minor(lp->isdn_device, lp->isdn_channel);
-					if (i >= 0) {
-						strcpy(dev->num[i], cmd.parm.setup.phone);
-						dev->usage[i] |= ISDN_USAGE_OUTGOING;
-						isdn_info_update();
-					}
-					printk(KERN_INFO "%s: dialing %d %s... %s\n", lp->name,
-					       lp->dialretry, cmd.parm.setup.phone,
-					       (cmd.parm.setup.si1 == 1) ? "DOV" : "");
-					lp->dtimer = 0;
-#ifdef ISDN_DEBUG_NET_DIAL
-					printk(KERN_DEBUG "dial: d=%d c=%d\n", lp->isdn_device,
-					       lp->isdn_channel);
-#endif
-					isdn_command(&cmd);
-				}
-				lp->huptimer = 0;
-				lp->outgoing = 1;
-				if (lp->chargeint) {
-					lp->hupflags |= ISDN_HAVECHARGE;
-					lp->hupflags &= ~ISDN_WAITCHARGE;
-				} else {
-					lp->hupflags |= ISDN_WAITCHARGE;
-					lp->hupflags &= ~ISDN_HAVECHARGE;
-				}
-				anymore = 1;
-				lp->dialstate =
-				    (lp->cbdelay &&
-				     (lp->flags & ISDN_NET_CBOUT)) ? 12 : 4;
-				break;
-			case 4:
-				/* Wait for D-Channel-connect.
-				 * If timeout, switch back to state 3.
-				 * Dialmax-handling moved to state 3.
-				 */
-				if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
-					lp->dialstate = 3;
-				anymore = 1;
-				break;
-			case 5:
-				/* Got D-Channel-Connect, send B-Channel-request */
-				cmd.driver = lp->isdn_device;
-				cmd.arg = lp->isdn_channel;
-				cmd.command = ISDN_CMD_ACCEPTB;
-				anymore = 1;
-				lp->dtimer = 0;
-				lp->dialstate++;
-				isdn_command(&cmd);
-				break;
-			case 6:
-				/* Wait for B- or D-Channel-connect. If timeout,
-				 * switch back to state 3.
-				 */
-#ifdef ISDN_DEBUG_NET_DIAL
-				printk(KERN_DEBUG "dialtimer2: %d\n", lp->dtimer);
-#endif
-				if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
-					lp->dialstate = 3;
-				anymore = 1;
-				break;
-			case 7:
-				/* Got incoming Call, setup L2 and L3 protocols,
-				 * then wait for D-Channel-connect
-				 */
-#ifdef ISDN_DEBUG_NET_DIAL
-				printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer);
-#endif
-				cmd.driver = lp->isdn_device;
-				cmd.command = ISDN_CMD_SETL2;
-				cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);
-				isdn_command(&cmd);
-				cmd.driver = lp->isdn_device;
-				cmd.command = ISDN_CMD_SETL3;
-				cmd.arg = lp->isdn_channel + (lp->l3_proto << 8);
-				isdn_command(&cmd);
-				if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT15)
-					isdn_net_hangup(&p->dev);
-				else {
-					anymore = 1;
-					lp->dialstate++;
-				}
-				break;
-			case 9:
-				/* Got incoming D-Channel-Connect, send B-Channel-request */
-				cmd.driver = lp->isdn_device;
-				cmd.arg = lp->isdn_channel;
-				cmd.command = ISDN_CMD_ACCEPTB;
-				isdn_command(&cmd);
-				anymore = 1;
-				lp->dtimer = 0;
-				lp->dialstate++;
-				break;
-			case 8:
-			case 10:
-				/*  Wait for B- or D-channel-connect */
-#ifdef ISDN_DEBUG_NET_DIAL
-				printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer);
+	switch (lp->dialstate) {
+	case ST_ACTIVE:
+		switch (pr) {
+		case ISDN_STAT_BSENT:
+			/* A packet has successfully been sent out */
+			if (lp->flags & ISDN_NET_CONNECTED) {
+				isdn_net_dec_frame_cnt(lp);
+				lp->stats.tx_packets++;
+				lp->stats.tx_bytes += c->parm.length;
+				return 1;
+			}
+			break;
+		case ISDN_STAT_DHUP:
+			/* Either D-Channel-hangup or error during dialout */
+#ifdef CONFIG_ISDN_X25 // FIXME handle != ST_0?
+			/* If we are not connencted then dialing had
+			   failed. If there are generic encap protocol
+			   receiver routines signal the closure of
+			   the link*/
+			
+			if (!(lp->flags & ISDN_NET_CONNECTED)
+			    && pops && pops->disconn_ind)
+				pops -> disconn_ind(cprot);
+#endif /* CONFIG_ISDN_X25 */
+			if (lp->flags & ISDN_NET_CONNECTED) {
+				if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
+					isdn_net_ciscohdlck_disconnected(lp);
+#ifdef CONFIG_ISDN_PPP
+				if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
+					isdn_ppp_free(lp);
 #endif
-				if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
-					isdn_net_hangup(&p->dev);
-				else
-					anymore = 1;
-				break;
-			case 11:
-				/* Callback Delay */
-				if (lp->dtimer++ > lp->cbdelay)
-					lp->dialstate = 1;
-				anymore = 1;
-				break;
-			case 12:
-				/* Remote does callback. Hangup after cbdelay, then wait for incoming
-				 * call (in state 4).
-				 */
-				if (lp->dtimer++ > lp->cbdelay)
-				{
-					printk(KERN_INFO "%s: hangup waiting for callback ...\n", lp->name);
-					lp->dtimer = 0;
-					lp->dialstate = 4;
-					cmd.driver = lp->isdn_device;
-					cmd.command = ISDN_CMD_HANGUP;
-					cmd.arg = lp->isdn_channel;
-					isdn_command(&cmd);
-					isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
-				}
-				anymore = 1;
-				break;
-			default:
-				printk(KERN_WARNING "isdn_net: Illegal dialstate %d for device %s\n",
-				       lp->dialstate, lp->name);
+				isdn_net_lp_disconnected(lp);
+				isdn_slot_all_eaz(lp->isdn_slot);
+				printk(KERN_INFO "%s: remote hangup\n", lp->name);
+				printk(KERN_INFO "%s: Chargesum is %d\n", lp->name,
+				       lp->charge);
+				isdn_net_unbind_channel(lp);
+				return 1;
+			}
+			break;
+#ifdef CONFIG_ISDN_X25 // FIXME handle != ST_0?
+		case ISDN_STAT_BHUP:
+			/* B-Channel-hangup */
+			/* try if there are generic encap protocol
+			   receiver routines and signal the closure of
+			   the link */
+			if( pops  &&  pops -> disconn_ind ){
+				pops -> disconn_ind(cprot);
+				return 1;
+			}
+			break;
+#endif /* CONFIG_ISDN_X25 */
+		case ISDN_STAT_CINF:
+			/* Charge-info from TelCo. Calculate interval between
+			 * charge-infos and set timestamp for last info for
+			 * usage by isdn_net_autohup()
+			 */
+			lp->charge++;
+			if (lp->hupflags & ISDN_HAVECHARGE) {
+				lp->hupflags &= ~ISDN_WAITCHARGE;
+				lp->chargeint = jiffies - lp->chargetime - (2 * HZ);
+			}
+			if (lp->hupflags & ISDN_WAITCHARGE)
+				lp->hupflags |= ISDN_HAVECHARGE;
+			lp->chargetime = jiffies;
+			printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
+			       lp->name, lp->chargetime);
+			return 1;
 		}
-		p = (isdn_net_dev *) p->next;
+		break;
+	case ST_OUT_WAIT_DCONN:
+		switch (pr) {
+		case EV_NET_TIMER_OUT_DCONN:
+			/* try again */
+			do_dialout(lp);
+			return 1;
+		case EV_NET_TIMER_CB:
+			/* Remote does callback. Hangup after cbdelay, 
+			 * then wait for incoming call */
+			printk(KERN_INFO "%s: hangup waiting for callback ...\n", lp->name);
+			isdn_net_hangup(&lp->netdev->dev);
+			return 1;
+		case ISDN_STAT_DCONN:
+			/* Got D-Channel-Connect, send B-Channel-request */
+			del_timer(&lp->dial_timer);
+			lp->dialstate = ST_OUT_WAIT_BCONN;
+			isdn_slot_command(lp->isdn_slot, ISDN_CMD_ACCEPTB, &cmd);
+			lp->dial_timer.expires = jiffies + 10 * HZ;
+			lp->dial_event = EV_NET_TIMER_OUT_BCONN;
+			add_timer(&lp->dial_timer);
+			return 1;
+		case ISDN_STAT_DHUP:
+			del_timer(&lp->dial_timer);
+			isdn_slot_all_eaz(lp->isdn_slot);
+			printk(KERN_INFO "%s: remote hangup\n", lp->name);
+			isdn_net_unbind_channel(lp);
+			return 1;
+		}
+		break;
+	case ST_OUT_WAIT_BCONN:
+		switch (pr) {
+		case EV_NET_TIMER_OUT_BCONN:
+			/* try again */
+			do_dialout(lp);
+			return 1;
+		case ISDN_STAT_BCONN:
+			del_timer(&lp->dial_timer);
+			isdn_slot_set_usage(lp->isdn_slot, isdn_slot_usage(lp->isdn_slot) | ISDN_USAGE_OUTGOING);
+			isdn_net_connected(lp);
+			return 1;
+		case ISDN_STAT_DHUP:
+			del_timer(&lp->dial_timer);
+			isdn_slot_all_eaz(lp->isdn_slot);
+			printk(KERN_INFO "%s: remote hangup\n", lp->name);
+			isdn_net_unbind_channel(lp);
+			return 1;
+		}
+		break;
+	case ST_IN_WAIT_DCONN:
+		switch (pr) {
+		case EV_NET_TIMER_IN_DCONN:
+			isdn_net_hangup(&p->dev);
+			return 1;
+		case ISDN_STAT_DCONN:
+			del_timer(&lp->dial_timer);
+			lp->dialstate = ST_IN_WAIT_BCONN;
+			isdn_slot_command(lp->isdn_slot, ISDN_CMD_ACCEPTB, &cmd);
+			lp->dial_timer.expires = jiffies + 10 * HZ;
+			lp->dial_event = EV_NET_TIMER_IN_BCONN;
+			add_timer(&lp->dial_timer);
+			return 1;
+		case ISDN_STAT_DHUP:
+			del_timer(&lp->dial_timer);
+			isdn_slot_all_eaz(lp->isdn_slot);
+			printk(KERN_INFO "%s: remote hangup\n", lp->name);
+			isdn_net_unbind_channel(lp);
+			return 1;
+		}
+		break;
+	case ST_IN_WAIT_BCONN:
+		switch (pr) {
+		case EV_NET_TIMER_IN_BCONN:
+			isdn_net_hangup(&p->dev);
+			break;
+		case ISDN_STAT_BCONN:
+			del_timer(&lp->dial_timer);
+			isdn_slot_set_rx_netdev(lp->isdn_slot, p);
+			isdn_net_connected(lp);
+			return 1;
+		case ISDN_STAT_DHUP:
+			del_timer(&lp->dial_timer);
+			isdn_slot_all_eaz(lp->isdn_slot);
+			printk(KERN_INFO "%s: remote hangup\n", lp->name);
+			isdn_net_unbind_channel(lp);
+			return 1;
+		}
+		break;
+	case ST_WAIT_BEFORE_CB:
+		switch (pr) {
+		case EV_NET_TIMER_CB:
+			/* Callback Delay */
+			init_dialout(lp);
+			return 1;
+		}
+		break;
+	default:
+		isdn_BUG();
+		break;
 	}
-	isdn_timer_ctrl(ISDN_TIMER_NETDIAL, anymore);
+	printk("NOT HANDLED?\n");
+	return 0;
 }
 
 /*
@@ -883,12 +853,9 @@
 		  pops -> disconn_ind(cprot);
 #endif /* CONFIG_ISDN_X25 */
 
-		cmd.driver = lp->isdn_device;
-		cmd.command = ISDN_CMD_HANGUP;
-		cmd.arg = lp->isdn_channel;
-		isdn_command(&cmd);
+		isdn_slot_command(lp->isdn_slot, ISDN_CMD_HANGUP, &cmd);
 		printk(KERN_INFO "%s: Chargesum is %d\n", lp->name, lp->charge);
-		isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
+		isdn_slot_all_eaz(lp->isdn_slot);
 	}
 	isdn_net_unbind_channel(lp);
 }
@@ -1041,15 +1008,15 @@
 	/* before obtaining the lock the caller should have checked that
 	   the lp isn't busy */
 	if (isdn_net_lp_busy(lp)) {
-		printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
+		isdn_BUG();
 		goto error;
 	}
 
 	if (!(lp->flags & ISDN_NET_CONNECTED)) {
-		printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
+		isdn_BUG();
 		goto error;
 	}
-	ret = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb);
+	ret = isdn_slot_write(lp->isdn_slot, skb);
 	if (ret != len) {
 		/* we should never get here */
 		printk(KERN_WARNING "%s: HL driver queue full\n", lp->name);
@@ -1137,7 +1104,7 @@
 			lp->sqfull = 0;
 		}
 		/* this is a hack to allow auto-hangup for slaves on moderate loads */
-		nd->queue = nd->local;
+		nd->queue = &nd->local;
 	}
 
 	return retv;
@@ -1165,7 +1132,7 @@
 	isdn_net_local *lp = (isdn_net_local *) ndev->priv;
 
 	printk(KERN_WARNING "isdn_tx_timeout dev %s dialstate %d\n", ndev->name, lp->dialstate);
-	if (!lp->dialstate){
+	if (lp->dialstate == ST_ACTIVE){
 		lp->stats.tx_errors++;
                 /*
 		 * There is a certain probability that this currently
@@ -1220,14 +1187,8 @@
 #endif
 	/* auto-dialing xmit function */
 	{
-#ifdef ISDN_DEBUG_NET_DUMP
-		u_char *buf;
-#endif
 		isdn_net_adjust_hdr(skb, ndev);
-#ifdef ISDN_DEBUG_NET_DUMP
-		buf = skb->data;
-		isdn_dumppkt("S:", buf, skb->len, 40);
-#endif
+		isdn_dumppkt("S:", skb->data, skb->len, 40);
 
 		if (!(lp->flags & ISDN_NET_CONNECTED)) {
 			int chi;
@@ -1257,7 +1218,7 @@
 				}
 				/* Grab a free ISDN-Channel */
 				if (((chi =
-				     isdn_get_free_channel(
+				     isdn_get_free_slot(
 					 		ISDN_USAGE_NET,
 							lp->l2_proto,
 							lp->l3_proto,
@@ -1266,7 +1227,7 @@
 							lp->msn)
 							) < 0) &&
 					((chi =
-				     isdn_get_free_channel(
+				     isdn_get_free_slot(
 					 		ISDN_USAGE_NET,
 							lp->l2_proto,
 							lp->l3_proto,
@@ -1283,7 +1244,6 @@
 				/* Log packet, which triggered dialing */
 				if (dev->net_verbose)
 					isdn_net_log_skb(skb, lp);
-				lp->dialstate = 1;
 				/* Connect interface with channel */
 				isdn_net_bind_channel(lp, chi);
 #ifdef CONFIG_ISDN_PPP
@@ -1296,14 +1256,14 @@
 						return 0;	/* STN (skb to nirvana) ;) */
 					}
 					restore_flags(flags);
-					isdn_net_dial();	/* Initiate dialing */
+					init_dialout(lp);
 					netif_stop_queue(ndev);
 					return 1;	/* let upper layer requeue skb packet */
 				}
 #endif
 				/* Initiate dialing */
 				restore_flags(flags);
-				isdn_net_dial();
+				init_dialout(lp);
 				isdn_net_device_stop_queue(lp);
 				return 1;
 			} else {
@@ -1315,7 +1275,7 @@
 		} else {
 			/* Device is connected to an ISDN channel */ 
 			ndev->trans_start = jiffies;
-			if (!lp->dialstate) {
+			if (lp->dialstate == ST_ACTIVE) {
 				/* ISDN connection is established, try sending */
 				int ret;
 				ret = (isdn_net_xmit(ndev, skb));
@@ -1433,7 +1393,7 @@
 static struct sk_buff*
 isdn_net_ciscohdlck_alloc_skb(isdn_net_local *lp, int len)
 {
-	unsigned short hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
+	unsigned short hl = isdn_slot_hdrlen(lp->isdn_slot);
 	struct sk_buff *skb;
 
 	skb = alloc_skb(hl + len, GFP_ATOMIC);
@@ -1523,8 +1483,8 @@
 	unsigned long last_cisco_myseq = lp->cisco_myseq;
 	int myseq_diff = 0;
 
-	if (!(lp->flags & ISDN_NET_CONNECTED) || lp->dialstate) {
-		printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
+	if (!(lp->flags & ISDN_NET_CONNECTED) || lp->dialstate != ST_ACTIVE) {
+		isdn_BUG();
 		return;
 	}
 	lp->cisco_myseq++;
@@ -1814,9 +1774,7 @@
 	skb->dev = ndev;
 	skb->pkt_type = PACKET_HOST;
 	skb->mac.raw = skb->data;
-#ifdef ISDN_DEBUG_NET_DUMP
 	isdn_dumppkt("R:", skb->data, skb->len, 40);
-#endif
 	switch (lp->p_encap) {
 		case ISDN_NET_ENCAP_ETHER:
 			/* Ethernet over ISDN */
@@ -1893,12 +1851,12 @@
 int
 isdn_net_rcv_skb(int idx, struct sk_buff *skb)
 {
-	isdn_net_dev *p = dev->rx_netdev[idx];
+	isdn_net_dev *p = isdn_slot_rx_netdev(idx);
 
 	if (p) {
-		isdn_net_local *lp = p->local;
+		isdn_net_local *lp = &p->local;
 		if ((lp->flags & ISDN_NET_CONNECTED) &&
-		    (!lp->dialstate)) {
+		    (lp->dialstate == ST_ACTIVE)) {
 			isdn_net_receive(&p->dev, skb);
 			return 1;
 		}
@@ -2093,40 +2051,34 @@
 static void
 isdn_net_swapbind(int drvidx)
 {
-	isdn_net_dev *p;
+	struct list_head *l;
 
-#ifdef ISDN_DEBUG_NET_ICALL
-	printk(KERN_DEBUG "n_fi: swapping ch of %d\n", drvidx);
-#endif
-	p = dev->netdev;
-	while (p) {
-		if (p->local->pre_device == drvidx)
-			switch (p->local->pre_channel) {
-				case 0:
-					p->local->pre_channel = 1;
-					break;
-				case 1:
-					p->local->pre_channel = 0;
-					break;
-			}
-		p = (isdn_net_dev *) p->next;
+	dbg_net_icall("n_fi: swapping ch of %d\n", drvidx);
+	list_for_each(l, &isdn_net_devs) {
+		isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
+		if (p->local.pre_device != drvidx)
+			continue;
+
+		switch (p->local.pre_channel) {
+		case 0:
+			p->local.pre_channel = 1;
+			break;
+		case 1:
+			p->local.pre_channel = 0;
+			break;
+		}
 	}
 }
 
 static void
 isdn_net_swap_usage(int i1, int i2)
 {
-	int u1 = dev->usage[i1] & ISDN_USAGE_EXCLUSIVE;
-	int u2 = dev->usage[i2] & ISDN_USAGE_EXCLUSIVE;
+	int u1 = isdn_slot_usage(i1);
+	int u2 = isdn_slot_usage(i2);
 
-#ifdef ISDN_DEBUG_NET_ICALL
-	printk(KERN_DEBUG "n_fi: usage of %d and %d\n", i1, i2);
-#endif
-	dev->usage[i1] &= ~ISDN_USAGE_EXCLUSIVE;
-	dev->usage[i1] |= u2;
-	dev->usage[i2] &= ~ISDN_USAGE_EXCLUSIVE;
-	dev->usage[i2] |= u1;
-	isdn_info_update();
+	dbg_net_icall("n_fi: usage of %d and %d\n", i1, i2);
+	isdn_slot_set_usage(i1, (u1 & ~ISDN_USAGE_EXCLUSIVE) | (u2 & ISDN_USAGE_EXCLUSIVE));
+	isdn_slot_set_usage(i2, (u2 & ~ISDN_USAGE_EXCLUSIVE) | (u1 & ISDN_USAGE_EXCLUSIVE));
 }
 
 /*
@@ -2155,12 +2107,14 @@
 	int wret;
 	int swapped;
 	int sidx = 0;
-	isdn_net_dev *p;
+	struct list_head *l;
 	isdn_net_phone *n;
 	ulong flags;
 	char nr[32];
 	char *my_eaz;
+	isdn_ctrl cmd;
 
+	int slot = isdn_dc2minor(di, ch);
 	/* Search name in netdev-chain */
 	save_flags(flags);
 	cli();
@@ -2188,16 +2142,15 @@
                 return 0;
         }
 
-n = (isdn_net_phone *) 0;
-p = dev->netdev;
+	n = (isdn_net_phone *) 0;
 	ematch = wret = swapped = 0;
-#ifdef ISDN_DEBUG_NET_ICALL
-	printk(KERN_DEBUG "n_fi: di=%d ch=%d idx=%d usg=%d\n", di, ch, idx,
-	       dev->usage[idx]);
-#endif
-	while (p) {
+	dbg_net_icall("n_fi: di=%d ch=%d idx=%d usg=%d\n", di, ch, idx,
+		      isdn_slot_usage(idx));
+
+	list_for_each(l, &isdn_net_devs) {
 		int matchret;
-		isdn_net_local *lp = p->local;
+		isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
+		isdn_net_local *lp = &p->local;
 
 		/* If last check has triggered as binding-swap, revert it */
 		switch (swapped) {
@@ -2210,7 +2163,7 @@
 		}
 		swapped = 0;
                 /* check acceptable call types for DOV */
-                my_eaz = isdn_map_eaz2msn(lp->msn, di);
+                my_eaz = isdn_slot_map_eaz2msn(slot, lp->msn);
                 if (si1 == 1) { /* it's a DOV call, check if we allow it */
                         if (*my_eaz == 'v' || *my_eaz == 'V' ||
 			    *my_eaz == 'b' || *my_eaz == 'B')
@@ -2231,22 +2184,18 @@
 		/* Remember if more numbers eventually can match */
 		if (matchret > wret)
 			wret = matchret;
-#ifdef ISDN_DEBUG_NET_ICALL
-		printk(KERN_DEBUG "n_fi: if='%s', l.msn=%s, l.flags=%d, l.dstate=%d\n",
+		dbg_net_icall("n_fi: if='%s', l.msn=%s, l.flags=%d, l.dstate=%d\n",
 		       lp->name, lp->msn, lp->flags, lp->dialstate);
-#endif
 		if ((!matchret) &&                                        /* EAZ is matching   */
 		    (((!(lp->flags & ISDN_NET_CONNECTED)) &&              /* but not connected */
-		      (USG_NONE(dev->usage[idx]))) ||                     /* and ch. unused or */
-		     ((((lp->dialstate == 4) || (lp->dialstate == 12)) && /* if dialing        */
+		      (USG_NONE(isdn_slot_usage(idx)))) ||                     /* and ch. unused or */
+		     ((((lp->dialstate == ST_OUT_WAIT_DCONN) || (lp->dialstate == ST_OUT_WAIT_DCONN)) && /* if dialing        */
 		       (!(lp->flags & ISDN_NET_CALLBACK)))                /* but no callback   */
 		     )))
 			 {
-#ifdef ISDN_DEBUG_NET_ICALL
-			printk(KERN_DEBUG "n_fi: match1, pdev=%d pch=%d\n",
+			dbg_net_icall("n_fi: match1, pdev=%d pch=%d\n",
 			       lp->pre_device, lp->pre_channel);
-#endif
-			if (dev->usage[idx] & ISDN_USAGE_EXCLUSIVE) {
+			if (isdn_slot_usage(idx) & ISDN_USAGE_EXCLUSIVE) {
 				if ((lp->pre_channel != ch) ||
 				    (lp->pre_device != di)) {
 					/* Here we got a problem:
@@ -2260,16 +2209,12 @@
 					 */
 					if (ch == 0) {
 						sidx = isdn_dc2minor(di, 1);
-#ifdef ISDN_DEBUG_NET_ICALL
-						printk(KERN_DEBUG "n_fi: ch is 0\n");
-#endif
-						if (USG_NONE(dev->usage[sidx])) {
+						dbg_net_icall("n_fi: ch is 0\n");
+						if (USG_NONE(isdn_slot_usage(sidx))) {
 							/* Second Channel is free, now see if it is bound
 							 * exclusive too. */
-							if (dev->usage[sidx] & ISDN_USAGE_EXCLUSIVE) {
-#ifdef ISDN_DEBUG_NET_ICALL
-								printk(KERN_DEBUG "n_fi: 2nd channel is down and bound\n");
-#endif
+							if (isdn_slot_usage(sidx) & ISDN_USAGE_EXCLUSIVE) {
+								dbg_net_icall("n_fi: 2nd channel is down and bound\n");
 								/* Yes, swap bindings only, if the original
 								 * binding is bound to channel 1 of this driver */
 								if ((lp->pre_device == di) &&
@@ -2278,43 +2223,31 @@
 									swapped = 1;
 								} else {
 									/* ... else iterate next device */
-									p = (isdn_net_dev *) p->next;
 									continue;
 								}
 							} else {
-#ifdef ISDN_DEBUG_NET_ICALL
-								printk(KERN_DEBUG "n_fi: 2nd channel is down and unbound\n");
-#endif
+								dbg_net_icall("n_fi: 2nd channel is down and unbound\n");
 								/* No, swap always and swap excl-usage also */
 								isdn_net_swap_usage(idx, sidx);
 								isdn_net_swapbind(di);
 								swapped = 2;
 							}
 							/* Now check for exclusive binding again */
-#ifdef ISDN_DEBUG_NET_ICALL
-							printk(KERN_DEBUG "n_fi: final check\n");
-#endif
-							if ((dev->usage[idx] & ISDN_USAGE_EXCLUSIVE) &&
+							dbg_net_icall("n_fi: final check\n");
+							if ((isdn_slot_usage(idx) & ISDN_USAGE_EXCLUSIVE) &&
 							    ((lp->pre_channel != ch) ||
 							     (lp->pre_device != di))) {
-#ifdef ISDN_DEBUG_NET_ICALL
-								printk(KERN_DEBUG "n_fi: final check failed\n");
-#endif
-								p = (isdn_net_dev *) p->next;
+								dbg_net_icall("n_fi: final check failed\n");
 								continue;
 							}
 						}
 					} else {
 						/* We are already on the second channel, so nothing to do */
-#ifdef ISDN_DEBUG_NET_ICALL
-						printk(KERN_DEBUG "n_fi: already on 2nd channel\n");
-#endif
+						dbg_net_icall("n_fi: already on 2nd channel\n");
 					}
 				}
 			}
-#ifdef ISDN_DEBUG_NET_ICALL
-			printk(KERN_DEBUG "n_fi: match2\n");
-#endif
+			dbg_net_icall("n_fi: match2\n");
 			n = lp->phone[0];
 			if (lp->flags & ISDN_NET_SECURE) {
 				while (n) {
@@ -2324,9 +2257,7 @@
 				}
 			}
 			if (n || (!(lp->flags & ISDN_NET_SECURE))) {
-#ifdef ISDN_DEBUG_NET_ICALL
-				printk(KERN_DEBUG "n_fi: match3\n");
-#endif
+				dbg_net_icall("n_fi: match3\n");
 				/* matching interface found */
 
 				/*
@@ -2370,7 +2301,6 @@
 					/* Found parent, if it's offline iterate next device */
 					printk(KERN_DEBUG "mlpf: %d\n", mlp->flags & ISDN_NET_CONNECTED);
 					if (!(mlp->flags & ISDN_NET_CONNECTED)) {
-						p = (isdn_net_dev *) p->next;
 						continue;
 					}
 				} 
@@ -2392,7 +2322,7 @@
 					if (lp->phone[1]) {
 						/* Grab a free ISDN-Channel */
 						if ((chi = 
-							isdn_get_free_channel(
+							isdn_get_free_slot(
 								ISDN_USAGE_NET,
 								lp->l2_proto,
 								lp->l3_proto,
@@ -2406,8 +2336,11 @@
 							return 0;
 						}
 						/* Setup dialstate. */
-						lp->dtimer = 0;
-						lp->dialstate = 11;
+						lp->dial_timer.expires = jiffies + lp->cbdelay;
+						lp->dial_event = EV_NET_TIMER_CB;
+						add_timer(&lp->dial_timer);
+
+						lp->dialstate = ST_WAIT_BEFORE_CB;
 						/* Connect interface with channel */
 						isdn_net_bind_channel(lp, chi);
 #ifdef CONFIG_ISDN_PPP
@@ -2430,30 +2363,39 @@
 					       eaz);
 					/* if this interface is dialing, it does it probably on a different
 					   device, so free this device */
-					if ((lp->dialstate == 4) || (lp->dialstate == 12)) {
+					if (lp->dialstate == ST_OUT_WAIT_DCONN) {
 #ifdef CONFIG_ISDN_PPP
 						if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
 							isdn_ppp_free(lp);
 #endif
 						isdn_net_lp_disconnected(lp);
-						isdn_free_channel(lp->isdn_device, lp->isdn_channel,
+						isdn_slot_free(lp->isdn_slot,
 							 ISDN_USAGE_NET);
 					}
-					dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE;
-					dev->usage[idx] |= ISDN_USAGE_NET;
-					strcpy(dev->num[idx], nr);
-					isdn_info_update();
-					dev->st_netdev[idx] = lp->netdev;
-					lp->isdn_device = di;
-					lp->isdn_channel = ch;
+					strcpy(isdn_slot_num(idx), nr);
+					isdn_slot_set_usage(idx, (isdn_slot_usage(idx) & ISDN_USAGE_EXCLUSIVE) | ISDN_USAGE_NET);
+					isdn_slot_set_st_netdev(idx, lp->netdev);
+					lp->isdn_slot = slot;
 					lp->ppp_slot = -1;
 					lp->flags |= ISDN_NET_CONNECTED;
-					lp->dialstate = 7;
-					lp->dtimer = 0;
+
 					lp->outgoing = 0;
 					lp->huptimer = 0;
 					lp->hupflags |= ISDN_WAITCHARGE;
 					lp->hupflags &= ~ISDN_HAVECHARGE;
+					/* Got incoming Call, setup L2 and L3 protocols,
+					 * then wait for D-Channel-connect
+					 */
+					cmd.arg = lp->l2_proto << 8;
+					isdn_slot_command(lp->isdn_slot, ISDN_CMD_SETL2, &cmd);
+					cmd.arg = lp->l3_proto << 8;
+					isdn_slot_command(lp->isdn_slot, ISDN_CMD_SETL3, &cmd);
+
+					lp->dial_timer.expires = jiffies + 15 * HZ;
+					lp->dial_event = EV_NET_TIMER_IN_DCONN;
+					add_timer(&lp->dial_timer);
+					lp->dialstate = ST_IN_WAIT_DCONN;
+
 #ifdef CONFIG_ISDN_PPP
 					if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
 						if (isdn_ppp_bind(lp) < 0) {
@@ -2467,11 +2409,10 @@
 				}
 			}
 		}
-		p = (isdn_net_dev *) p->next;
 	}
 	/* If none of configured EAZ/MSN matched and not verbose, be silent */
 	if (!ematch || dev->net_verbose)
-		printk(KERN_INFO "isdn_net: call from %s -> %d %s ignored\n", nr, di, eaz);
+		printk(KERN_INFO "isdn_net: call from %s -> %d %s ignored\n", nr, slot, eaz);
 	restore_flags(flags);
 	return (wret == 2)?5:0;
 }
@@ -2482,14 +2423,14 @@
 isdn_net_dev *
 isdn_net_findif(char *name)
 {
-	isdn_net_dev *p = dev->netdev;
+	struct list_head *l;
 
-	while (p) {
-		if (!strcmp(p->local->name, name))
+	list_for_each(l, &isdn_net_devs) {
+		isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
+		if (!strcmp(p->local.name, name))
 			return p;
-		p = (isdn_net_dev *) p->next;
 	}
-	return (isdn_net_dev *) NULL;
+	return NULL;
 }
 
 /*
@@ -2500,7 +2441,7 @@
 int
 isdn_net_force_dial_lp(isdn_net_local * lp)
 {
-	if ((!(lp->flags & ISDN_NET_CONNECTED)) && !lp->dialstate) {
+	if ((!(lp->flags & ISDN_NET_CONNECTED)) && lp->dialstate == ST_NULL) {
 		int chi;
 		if (lp->phone[1]) {
 			ulong flags;
@@ -2509,7 +2450,7 @@
 
 			/* Grab a free ISDN-Channel */
 			if ((chi = 
-						isdn_get_free_channel(
+						isdn_get_free_slot(
 							ISDN_USAGE_NET,
 							lp->l2_proto,
 							lp->l3_proto,
@@ -2521,7 +2462,6 @@
 				restore_flags(flags);
 				return -EAGAIN;
 			}
-			lp->dialstate = 1;
 			/* Connect interface with channel */
 			isdn_net_bind_channel(lp, chi);
 #ifdef CONFIG_ISDN_PPP
@@ -2534,7 +2474,7 @@
 #endif
 			/* Initiate dialing */
 			restore_flags(flags);
-			isdn_net_dial();
+			init_dialout(lp);
 			return 0;
 		} else
 			return -EINVAL;
@@ -2567,47 +2507,39 @@
 
 	if (!p)
 		return -ENODEV;
-	return (isdn_net_force_dial_lp(p->local));
+	return (isdn_net_force_dial_lp(&p->local));
 }
 
 /*
  * Allocate a new network-interface and initialize its data structures.
  */
-char *
+int
 isdn_net_new(char *name, struct net_device *master)
 {
+	int retval;
 	isdn_net_dev *netdev;
 
 	/* Avoid creating an existing interface */
 	if (isdn_net_findif(name)) {
 		printk(KERN_WARNING "isdn_net: interface %s already exists\n", name);
-		return NULL;
+		return -EEXIST;
 	}
-	if (!(netdev = (isdn_net_dev *) kmalloc(sizeof(isdn_net_dev), GFP_KERNEL))) {
+	if (!(netdev = kmalloc(sizeof(isdn_net_dev), GFP_KERNEL))) {
 		printk(KERN_WARNING "isdn_net: Could not allocate net-device\n");
-		return NULL;
+		return -ENOMEM;
 	}
 	memset(netdev, 0, sizeof(isdn_net_dev));
-	if (!(netdev->local = (isdn_net_local *) kmalloc(sizeof(isdn_net_local), GFP_KERNEL))) {
-		printk(KERN_WARNING "isdn_net: Could not allocate device locals\n");
-		kfree(netdev);
-		return NULL;
-	}
-	memset(netdev->local, 0, sizeof(isdn_net_local));
-	if (name == NULL)
-		strcpy(netdev->local->name, "         ");
-	else
-		strcpy(netdev->local->name, name);
-	strcpy(netdev->dev.name, netdev->local->name);
-	netdev->dev.priv = netdev->local;
+	strcpy(netdev->local.name, name);
+	strcpy(netdev->dev.name, name);
+	netdev->dev.priv = &netdev->local;
 	netdev->dev.init = isdn_net_init;
-	netdev->local->p_encap = ISDN_NET_ENCAP_RAWIP;
+	netdev->local.p_encap = ISDN_NET_ENCAP_RAWIP;
 	if (master) {
 		/* Device shall be a slave */
 		struct net_device *p = (((isdn_net_local *) master->priv)->slave);
 		struct net_device *q = master;
 
-		netdev->local->master = master;
+		netdev->local.master = master;
 		/* Put device at end of slave-chain */
 		while (p) {
 			q = p;
@@ -2621,81 +2553,80 @@
 		 */
 		netdev->dev.tx_timeout = isdn_net_tx_timeout;
 		netdev->dev.watchdog_timeo = ISDN_NET_TX_TIMEOUT;
-		if (register_netdev(&netdev->dev) != 0) {
+		retval = register_netdev(&netdev->dev);
+		if (retval) {
 			printk(KERN_WARNING "isdn_net: Could not register net-device\n");
-			kfree(netdev->local);
 			kfree(netdev);
-			return NULL;
+			return retval;
 		}
 	}
-	netdev->local->magic = ISDN_NET_MAGIC;
+	netdev->local.magic = ISDN_NET_MAGIC;
 
-	netdev->queue = netdev->local;
+	netdev->queue = &netdev->local;
 	spin_lock_init(&netdev->queue_lock);
 
-	netdev->local->last = netdev->local;
-	netdev->local->netdev = netdev;
-	netdev->local->next = netdev->local;
-
-	netdev->local->tqueue.sync = 0;
-	netdev->local->tqueue.routine = isdn_net_softint;
-	netdev->local->tqueue.data = netdev->local;
-	spin_lock_init(&netdev->local->xmit_lock);
-
-	netdev->local->isdn_device = -1;
-	netdev->local->isdn_channel = -1;
-	netdev->local->pre_device = -1;
-	netdev->local->pre_channel = -1;
-	netdev->local->exclusive = -1;
-	netdev->local->ppp_slot = -1;
-	netdev->local->pppbind = -1;
-	skb_queue_head_init(&netdev->local->super_tx_queue);
-	netdev->local->l2_proto = ISDN_PROTO_L2_X75I;
-	netdev->local->l3_proto = ISDN_PROTO_L3_TRANS;
-	netdev->local->triggercps = 6000;
-	netdev->local->slavedelay = 10 * HZ;
-	netdev->local->hupflags = ISDN_INHUP;	/* Do hangup even on incoming calls */
-	netdev->local->onhtime = 10;	/* Default hangup-time for saving costs
+	netdev->local.last = &netdev->local;
+	netdev->local.netdev = netdev;
+	netdev->local.next = &netdev->local;
+
+	netdev->local.tqueue.sync = 0;
+	netdev->local.tqueue.routine = isdn_net_softint;
+	netdev->local.tqueue.data = &netdev->local;
+	spin_lock_init(&netdev->local.xmit_lock);
+
+	netdev->local.isdn_slot = -1;
+	netdev->local.pre_device = -1;
+	netdev->local.pre_channel = -1;
+	netdev->local.exclusive = -1;
+	netdev->local.ppp_slot = -1;
+	netdev->local.pppbind = -1;
+	skb_queue_head_init(&netdev->local.super_tx_queue);
+	netdev->local.l2_proto = ISDN_PROTO_L2_X75I;
+	netdev->local.l3_proto = ISDN_PROTO_L3_TRANS;
+	netdev->local.triggercps = 6000;
+	netdev->local.slavedelay = 10 * HZ;
+	netdev->local.hupflags = ISDN_INHUP;	/* Do hangup even on incoming calls */
+	netdev->local.onhtime = 10;	/* Default hangup-time for saving costs
 	   of those who forget configuring this */
-	netdev->local->dialmax = 1;
-	netdev->local->flags = ISDN_NET_CBHUP | ISDN_NET_DM_MANUAL;	/* Hangup before Callback, manual dial */
-	netdev->local->cbdelay = 25;	/* Wait 5 secs before Callback */
-	netdev->local->dialtimeout = -1;  /* Infinite Dial-Timeout */
-	netdev->local->dialwait = 5 * HZ; /* Wait 5 sec. after failed dial */
-	netdev->local->dialstarted = 0;   /* Jiffies of last dial-start */
-	netdev->local->dialwait_timer = 0;  /* Jiffies of earliest next dial-start */
+	netdev->local.dialmax = 1;
+	netdev->local.flags = ISDN_NET_CBHUP | ISDN_NET_DM_MANUAL;	/* Hangup before Callback, manual dial */
+	netdev->local.cbdelay = 5 * HZ;	/* Wait 5 secs before Callback */
+	netdev->local.dialtimeout = -1;  /* Infinite Dial-Timeout */
+	netdev->local.dialwait = 5 * HZ; /* Wait 5 sec. after failed dial */
+	netdev->local.dialstarted = 0;   /* Jiffies of last dial-start */
+	netdev->local.dialwait_timer = 0;  /* Jiffies of earliest next dial-start */
+
+	init_timer(&netdev->local.dial_timer);
+	netdev->local.dial_timer.data = (unsigned long) &netdev->local;
+	netdev->local.dial_timer.function = isdn_net_dial_timer;
 
 	/* Put into to netdev-chain */
-	netdev->next = (void *) dev->netdev;
-	dev->netdev = netdev;
-	return netdev->dev.name;
+	list_add(&netdev->global_list, &isdn_net_devs);
+	return 0;
 }
 
-char *
+int
 isdn_net_newslave(char *parm)
 {
 	char *p = strchr(parm, ',');
-	isdn_net_dev *n;
-	char newname[10];
+	isdn_net_dev *m;
 
-	if (p) {
-		/* Slave-Name MUST not be empty */
-		if (!strlen(p + 1))
-			return NULL;
-		strcpy(newname, p + 1);
-		*p = 0;
-		/* Master must already exist */
-		if (!(n = isdn_net_findif(parm)))
-			return NULL;
-		/* Master must be a real interface, not a slave */
-		if (n->local->master)
-			return NULL;
-		/* Master must not be started yet */
-		if (isdn_net_device_started(n)) 
-			return NULL;
-		return (isdn_net_new(newname, &(n->dev)));
-	}
-	return NULL;
+	/* Slave-Name MUST not be empty */
+	if (!p || !p[1])
+		return -EINVAL;
+
+	*p = 0;
+	/* Master must already exist */
+	if (!(m = isdn_net_findif(parm)))
+		return -ESRCH;
+	/* Master must be a real interface, not a slave */
+	if (m->local.master)
+		return -ENXIO;
+	/* Master must not be started yet */
+	if (isdn_net_device_started(m)) 
+		return -EBUSY;
+
+	return isdn_net_new(p+1, &m->dev);
 }
 
 /*
@@ -2717,7 +2648,7 @@
 	ulong flags;
 #endif
 	if (p) {
-		isdn_net_local *lp = p->local;
+		isdn_net_local *lp = &p->local;
 
 		/* See if any registered driver supports the features we want */
 		features = ((1 << cfg->l2_proto) << ISDN_FEATURE_L2_SHIFT) |
@@ -2777,7 +2708,7 @@
 		case ISDN_NET_ENCAP_X25IFACE:
 #ifndef CONFIG_ISDN_X25
 			printk(KERN_WARNING "%s: isdn-x25 support not configured\n",
-			       p->local->name);
+			       p->local.name);
 			return -EINVAL;
 #else
 			p->dev.type = ARPHRD_X25;	/* change ARP type */
@@ -2793,7 +2724,7 @@
 				break;
 			printk(KERN_WARNING
 			       "%s: encapsulation protocol %d not supported\n",
-			       p->local->name, cfg->p_encap);
+			       p->local.name, cfg->p_encap);
 			return -EINVAL;
 		}
 		if (strlen(cfg->drvid)) {
@@ -2830,7 +2761,7 @@
 
 			/* If binding is exclusive, try to grab the channel */
 			save_flags(flags);
-			if ((i = isdn_get_free_channel(ISDN_USAGE_NET,
+			if ((i = isdn_get_free_slot(ISDN_USAGE_NET,
 				lp->l2_proto, lp->l3_proto, drvidx,
 				chidx, lp->msn)) < 0) {
 				/* Grab failed, because desired channel is in use */
@@ -2839,8 +2770,7 @@
 				return -EBUSY;
 			}
 			/* All went ok, so update isdninfo */
-			dev->usage[i] = ISDN_USAGE_EXCLUSIVE;
-			isdn_info_update();
+			isdn_slot_set_usage(i, ISDN_USAGE_EXCLUSIVE);
 			restore_flags(flags);
 			lp->exclusive = i;
 		} else {
@@ -2860,7 +2790,7 @@
 		lp->charge = cfg->charge;
 		lp->l2_proto = cfg->l2_proto;
 		lp->l3_proto = cfg->l3_proto;
-		lp->cbdelay = cfg->cbdelay;
+		lp->cbdelay = cfg->cbdelay * HZ / 5;
 		lp->dialmax = cfg->dialmax;
 		lp->triggercps = cfg->triggercps;
 		lp->slavedelay = cfg->slavedelay * HZ;
@@ -2944,7 +2874,7 @@
 	isdn_net_dev *p = isdn_net_findif(cfg->name);
 
 	if (p) {
-		isdn_net_local *lp = p->local;
+		isdn_net_local *lp = &p->local;
 
 		strcpy(cfg->eaz, lp->msn);
 		cfg->exclusive = lp->exclusive;
@@ -2968,7 +2898,7 @@
 		cfg->dialmode = lp->flags & ISDN_NET_DIALMODE_MASK;
 		cfg->chargehup = (lp->hupflags & 4) ? 1 : 0;
 		cfg->ihup = (lp->hupflags & 8) ? 1 : 0;
-		cfg->cbdelay = lp->cbdelay;
+		cfg->cbdelay = lp->cbdelay * 5 / HZ;
 		cfg->dialmax = lp->dialmax;
 		cfg->triggercps = lp->triggercps;
 		cfg->slavedelay = lp->slavedelay / HZ;
@@ -3003,8 +2933,8 @@
 		if (!(n = (isdn_net_phone *) kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
 			return -ENOMEM;
 		strcpy(n->num, phone->phone);
-		n->next = p->local->phone[phone->outgoing & 1];
-		p->local->phone[phone->outgoing & 1] = n;
+		n->next = p->local.phone[phone->outgoing & 1];
+		p->local.phone[phone->outgoing & 1] = n;
 		return 0;
 	}
 	return -ENODEV;
@@ -3026,7 +2956,7 @@
 	if (!p)
 		return -ENODEV;
 	inout &= 1;
-	for (n = p->local->phone[inout]; n; n = n->next) {
+	for (n = p->local.phone[inout]; n; n = n->next) {
 		if (more) {
 			put_user(' ', phones++);
 			count++;
@@ -3051,7 +2981,7 @@
 isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone *peer)
 {
 	isdn_net_dev *p = isdn_net_findif(phone->name);
-	int ch, dv, idx;
+	int idx;
 
 	if (!p) return -ENODEV;
 	/*
@@ -3060,15 +2990,12 @@
          * in (partially) wrong number copied to user. This race
 	 * currently ignored.
 	 */
-	ch = p->local->isdn_channel;
-	dv = p->local->isdn_device;
-	if(ch<0 && dv<0) return -ENOTCONN;
-	idx = isdn_dc2minor(dv, ch);
-	if (idx<0) return -ENODEV;
+	idx = p->local.isdn_slot;
+	if (idx<0) return -ENOTCONN;
 	/* for pre-bound channels, we need this extra check */
-	if ( strncmp(dev->num[idx],"???",3) == 0 ) return -ENOTCONN;
-	strncpy(phone->phone,dev->num[idx],ISDN_MSNLEN);
-	phone->outgoing=USG_OUTGOING(dev->usage[idx]);
+	if (strncmp(isdn_slot_num(idx),"???",3) == 0 ) return -ENOTCONN;
+	strncpy(phone->phone,isdn_slot_num(idx),ISDN_MSNLEN);
+	phone->outgoing=USG_OUTGOING(isdn_slot_usage(idx));
 	if ( copy_to_user(peer,phone,sizeof(*peer)) ) return -EFAULT;
 	return 0;
 }
@@ -3087,16 +3014,16 @@
 	if (p) {
 		save_flags(flags);
 		cli();
-		n = p->local->phone[inout];
+		n = p->local.phone[inout];
 		m = NULL;
 		while (n) {
 			if (!strcmp(n->num, phone->phone)) {
-				if (p->local->dial == n)
-					p->local->dial = n->next;
+				if (p->local.dial == n)
+					p->local.dial = n->next;
 				if (m)
 					m->next = n->next;
 				else
-					p->local->phone[inout] = n->next;
+					p->local.phone[inout] = n->next;
 				kfree(n);
 				restore_flags(flags);
 				return 0;
@@ -3124,15 +3051,15 @@
 	save_flags(flags);
 	cli();
 	for (i = 0; i < 2; i++) {
-		n = p->local->phone[i];
+		n = p->local.phone[i];
 		while (n) {
 			m = n->next;
 			kfree(n);
 			n = m;
 		}
-		p->local->phone[i] = NULL;
+		p->local.phone[i] = NULL;
 	}
-	p->local->dial = NULL;
+	p->local.dial = NULL;
 	restore_flags(flags);
 	return 0;
 }
@@ -3147,9 +3074,9 @@
 	struct net_device *q;
 
 	if (p) {
-		if (p->local->isdn_device < 0)
+		if (p->local.isdn_slot < 0)
 			return 1;
-		q = p->local->slave;
+		q = p->local.slave;
 		/* If this interface has slaves, do a hangup for them also. */
 		while (q) {
 			isdn_net_hangup(q);
@@ -3165,7 +3092,7 @@
  * Helper-function for isdn_net_rm: Do the real work.
  */
 static int
-isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
+isdn_net_realrm(isdn_net_dev *p)
 {
 	unsigned long flags;
 
@@ -3182,42 +3109,37 @@
 	/* Free all phone-entries */
 	isdn_net_rmallphone(p);
 	/* If interface is bound exclusive, free channel-usage */
-	if (p->local->exclusive != -1)
-		isdn_unexclusive_channel(p->local->pre_device, p->local->pre_channel);
-	if (p->local->master) {
+	if (p->local.exclusive != -1)
+		isdn_unexclusive_channel(p->local.pre_device, p->local.pre_channel);
+	if (p->local.master) {
 		/* It's a slave-device, so update master's slave-pointer if necessary */
-		if (((isdn_net_local *) (p->local->master->priv))->slave == &p->dev)
-			((isdn_net_local *) (p->local->master->priv))->slave = p->local->slave;
+		if (((isdn_net_local *) (p->local.master->priv))->slave == &p->dev)
+			((isdn_net_local *) (p->local.master->priv))->slave = p->local.slave;
 	} else {
 		/* Unregister only if it's a master-device */
-		p->dev.hard_header_cache = p->local->org_hhc;
-		p->dev.header_cache_update = p->local->org_hcu;
+		p->dev.hard_header_cache = p->local.org_hhc;
+		p->dev.header_cache_update = p->local.org_hcu;
 		unregister_netdev(&p->dev);
 	}
 	/* Unlink device from chain */
-	if (q)
-		q->next = p->next;
-	else
-		dev->netdev = p->next;
-	if (p->local->slave) {
+	list_del(&p->global_list);
+	if (p->local.slave) {
 		/* If this interface has a slave, remove it also */
-		char *slavename = ((isdn_net_local *) (p->local->slave->priv))->name;
-		isdn_net_dev *n = dev->netdev;
-		q = NULL;
-		while (n) {
-			if (!strcmp(n->local->name, slavename)) {
-				isdn_net_realrm(n, q);
+		char *slavename = ((isdn_net_local *) (p->local.slave->priv))->name;
+		struct list_head *l;
+
+		list_for_each(l, &isdn_net_devs) {
+			isdn_net_dev *n = list_entry(l, isdn_net_dev, global_list);
+			if (!strcmp(n->local.name, slavename)) {
+				isdn_net_realrm(n);
 				break;
 			}
-			q = n;
-			n = (isdn_net_dev *) n->next;
 		}
 	}
 	/* If no more net-devices remain, disable auto-hangup timer */
-	if (dev->netdev == NULL)
+	if (list_empty(&isdn_net_devs))
 		isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0);
 	restore_flags(flags);
-	kfree(p->local);
 	kfree(p);
 
 	return 0;
@@ -3229,21 +3151,14 @@
 int
 isdn_net_rm(char *name)
 {
-	isdn_net_dev *p;
-	isdn_net_dev *q;
+	struct list_head *l;
 
 	/* Search name in netdev-chain */
-	p = dev->netdev;
-	q = NULL;
-	while (p) {
-		if (!strcmp(p->local->name, name))
-			return (isdn_net_realrm(p, q));
-		q = p;
-		p = (isdn_net_dev *) p->next;
+	list_for_each(l, &isdn_net_devs) {
+		isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
+		if (!strcmp(p->local.name, name))
+			return isdn_net_realrm(p);
 	}
-	/* If no more net-devices remain, disable auto-hangup timer */
-	if (dev->netdev == NULL)
-		isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0);
 	return -ENODEV;
 }
 
@@ -3259,16 +3174,17 @@
 	/* Walk through netdev-chain */
 	save_flags(flags);
 	cli();
-	while (dev->netdev) {
-		if (!dev->netdev->local->master) {
-			/* Remove master-devices only, slaves get removed with their master */
-			if ((ret = isdn_net_realrm(dev->netdev, NULL))) {
+	while (!list_empty(&isdn_net_devs)) {
+		isdn_net_dev *p = list_entry(isdn_net_devs.next, isdn_net_dev, global_list);
+
+		/* Remove master-devices only, slaves get removed with their master */
+		if (!p->local.master) {
+			if ((ret = isdn_net_realrm(p))) {
 				restore_flags(flags);
 				return ret;
 			}
 		}
 	}
-	dev->netdev = NULL;
 	restore_flags(flags);
 	return 0;
 }
diff -Nru a/drivers/isdn/i4l/isdn_net.h b/drivers/isdn/i4l/isdn_net.h
--- a/drivers/isdn/i4l/isdn_net.h	Sat Aug 10 18:42:23 2002
+++ b/drivers/isdn/i4l/isdn_net.h	Sat Aug 10 18:42:23 2002
@@ -31,8 +31,8 @@
 #define CISCO_SLARP_REPLY     1
 #define CISCO_SLARP_KEEPALIVE 2
 
-extern char *isdn_net_new(char *, struct net_device *);
-extern char *isdn_net_newslave(char *);
+extern int isdn_net_new(char *, struct net_device *);
+extern int isdn_net_newslave(char *);
 extern int isdn_net_rm(char *);
 extern int isdn_net_rmall(void);
 extern int isdn_net_stat_callback(int, isdn_ctrl *);
@@ -44,7 +44,6 @@
 extern int isdn_net_delphone(isdn_net_ioctl_phone *);
 extern int isdn_net_find_icall(int, int, int, setup_parm *);
 extern void isdn_net_hangup(struct net_device *);
-extern void isdn_net_dial(void);
 extern void isdn_net_autohup(void);
 extern int isdn_net_force_hangup(char *);
 extern int isdn_net_force_dial(char *);
@@ -131,7 +130,7 @@
 	if (master_lp->netdev->queue == lp) {
 		master_lp->netdev->queue = lp->next;
 		if (lp->next == lp) { /* last in queue */
-			master_lp->netdev->queue = master_lp->netdev->local;
+			master_lp->netdev->queue = &master_lp->netdev->local;
 		}
 	}
 	lp->next = lp->last = lp;	/* (re)set own pointers */
diff -Nru a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
--- a/drivers/isdn/i4l/isdn_ppp.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/isdn/i4l/isdn_ppp.c	Sat Aug 10 18:42:23 2002
@@ -165,14 +165,15 @@
 	save_flags(flags);
 	cli();
 	if (lp->pppbind < 0) {  /* device bounded to ippp device ? */
-		isdn_net_dev *net_dev = dev->netdev;
+		struct list_head *l;
 		char exclusive[ISDN_MAX_CHANNELS];	/* exclusive flags */
 		memset(exclusive, 0, ISDN_MAX_CHANNELS);
-		while (net_dev) {	/* step through net devices to find exclusive minors */
-			isdn_net_local *lp = net_dev->local;
+		/* step through net devices to find exclusive minors */
+		list_for_each(l, &isdn_net_devs) {
+			isdn_net_dev *p = list_entry(l, isdn_net_dev, global_list);
+			isdn_net_local *lp = &p->local;
 			if (lp->pppbind >= 0)
 				exclusive[lp->pppbind] = 1;
-			net_dev = net_dev->next;
 		}
 		/*
 		 * search a free device / slot
@@ -804,11 +805,11 @@
 		if (proto != PPP_LCP)
 			lp->huptimer = 0;
 
-		if (lp->isdn_device < 0 || lp->isdn_channel < 0) {
+		if (lp->isdn_slot < 0) {
 			retval = 0;
 			goto out;
 		}
-		if ((dev->drv[lp->isdn_device]->flags & DRV_FLAG_RUNNING) &&
+		if ((dev->drv[isdn_slot_driver(lp->isdn_slot)]->flags & DRV_FLAG_RUNNING) &&
 			lp->dialstate == 0 &&
 		    (lp->flags & ISDN_NET_CONNECTED)) {
 			unsigned short hl;
@@ -818,7 +819,7 @@
 			 * sk_buff. old call to dev_alloc_skb only reserved
 			 * 16 bytes, now we are looking what the driver want
 			 */
-			hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
+			hl = isdn_slot_hdrlen(lp->isdn_slot);
 			skb = alloc_skb(hl+count, GFP_ATOMIC);
 			if (!skb) {
 				printk(KERN_WARNING "isdn_ppp_write: out of memory!\n");
@@ -974,7 +975,7 @@
 	int slot;
 	int proto;
 
-	if (net_dev->local->master)
+	if (net_dev->local.master)
 		BUG(); // we're called with the master device always
 
 	slot = lp->ppp_slot;
@@ -1077,12 +1078,12 @@
 		case PPP_VJC_UNCOMP:
 			if (is->debug & 0x20)
 				printk(KERN_DEBUG "isdn_ppp: VJC_UNCOMP\n");
-			if (net_dev->local->ppp_slot < 0) {
+			if (net_dev->local.ppp_slot < 0) {
 				printk(KERN_ERR __FUNCTION__": net_dev->local->ppp_slot(%d) out of range\n",
-					net_dev->local->ppp_slot);
+					net_dev->local.ppp_slot);
 				goto drop_packet;
 			}
-			if (slhc_remember(ippp_table[net_dev->local->ppp_slot]->slcomp, skb->data, skb->len) <= 0) {
+			if (slhc_remember(ippp_table[net_dev->local.ppp_slot]->slcomp, skb->data, skb->len) <= 0) {
 				printk(KERN_WARNING "isdn_ppp: received illegal VJC_UNCOMP frame!\n");
 				goto drop_packet;
 			}
@@ -1103,12 +1104,12 @@
 				}
 				skb_put(skb, skb_old->len + 128);
 				memcpy(skb->data, skb_old->data, skb_old->len);
-				if (net_dev->local->ppp_slot < 0) {
+				if (net_dev->local.ppp_slot < 0) {
 					printk(KERN_ERR __FUNCTION__": net_dev->local->ppp_slot(%d) out of range\n",
-						net_dev->local->ppp_slot);
+						net_dev->local.ppp_slot);
 					goto drop_packet;
 				}
-				pkt_len = slhc_uncompress(ippp_table[net_dev->local->ppp_slot]->slcomp,
+				pkt_len = slhc_uncompress(ippp_table[net_dev->local.ppp_slot]->slcomp,
 						skb->data, skb_old->len);
 				kfree_skb(skb_old);
 				if (pkt_len < 0)
@@ -1144,7 +1145,7 @@
 	return;
 
  drop_packet:
-	net_dev->local->stats.rx_dropped++;
+	net_dev->local.stats.rx_dropped++;
 	kfree_skb(skb);
 }
 
@@ -1263,7 +1264,7 @@
 		 * sk_buff. old call to dev_alloc_skb only reserved
 		 * 16 bytes, now we are looking what the driver want.
 		 */
-		hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen + IPPP_MAX_HEADER;
+		hl = isdn_slot_hdrlen(lp->isdn_slot) + IPPP_MAX_HEADER;;
 		/* 
 		 * Note: hl might still be insufficient because the method
 		 * above does not account for a possibible MPPP slave channel
@@ -1976,7 +1977,7 @@
 
 	if (!(ndev = isdn_net_findif(name)))
 		return 1;
-	lp = ndev->local;
+	lp = &ndev->local;
 	if (!(lp->flags & ISDN_NET_CONNECTED))
 		return 5;
 
@@ -2007,7 +2008,7 @@
 
 	if (!(ndev = isdn_net_findif(name)))
 		return 1;
-	lp = ndev->local;
+	lp = &ndev->local;
 	if (!(lp->flags & ISDN_NET_CONNECTED))
 		return 5;
 
@@ -2094,7 +2095,7 @@
 	isdn_net_local *lp = is->lp;
 
 	/* Alloc large enough skb */
-	hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
+	hl = isdn_slot_hdrlen(lp->isdn_slot);
 	skb = alloc_skb(len + hl + 16,GFP_ATOMIC);
 	if(!skb) {
 		printk(KERN_WARNING
diff -Nru a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
--- a/drivers/isdn/i4l/isdn_tty.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/isdn/i4l/isdn_tty.c	Sat Aug 10 18:42:21 2002
@@ -128,7 +128,7 @@
 	modem_info *info;
 
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
-		if ((midx = dev->m_idx[i]) >= 0) {
+		if ((midx = isdn_slot_m_idx(i)) >= 0) {
 			info = &dev->mdm.info[midx];
 			if (info->online) {
 				r = 0;
@@ -143,9 +143,9 @@
 						if (c > 0) {
 							save_flags(flags);
 							cli();
-							r = isdn_readbchan(info->isdn_driver, info->isdn_channel,
+							r = isdn_slot_readbchan(info->isdn_slot,
 									   tty->flip.char_buf_ptr,
-									   tty->flip.flag_buf_ptr, c, 0);
+									   tty->flip.flag_buf_ptr, c);
 							/* CISCO AsyncPPP Hack */
 							if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP))
 								memset(tty->flip.flag_buf_ptr, 0, r);
@@ -182,7 +182,7 @@
 #endif
 	modem_info *info;
 
-	if ((midx = dev->m_idx[i]) < 0) {
+	if ((midx = isdn_slot_m_idx(i)) < 0) {
 		/* if midx is invalid, packet is not for tty */
 		return 0;
 	}
@@ -315,8 +315,7 @@
 	if (!skb)
 		return;
 	len = skb->len;
-	if ((slen = isdn_writebuf_skb_stub(info->isdn_driver,
-					   info->isdn_channel, 1, skb)) == len) {
+	if ((slen = isdn_slot_write(info->isdn_slot, skb)) == len) {
 		struct tty_struct *tty = info->tty;
 		info->send_outstanding++;
 		info->msr &= ~UART_MSR_CTS;
@@ -479,11 +478,11 @@
 	atomic_inc(&info->xmit_lock);
 	if (!(atomic_dec_and_test(&info->xmit_lock)))
 		return;
-	if (info->isdn_driver < 0) {
+	if (info->isdn_slot < 0) {
 		info->xmit_count = 0;
 		return;
 	}
-	skb_res = dev->drv[info->isdn_driver]->interface->hl_hdrlen + 4;
+	skb_res = isdn_slot_hdrlen(info->isdn_slot);
 #ifdef CONFIG_ISDN_AUDIO
 	if (info->vonline & 2)
 		audio_len = buflen * voice_cf[info->emu.vpar[3]];
@@ -627,7 +626,6 @@
 	int usg = ISDN_USAGE_MODEM;
 	int si = 7;
 	int l2 = m->mdmreg[REG_L2PROT];
-	isdn_ctrl cmd;
 	ulong flags;
 	int i;
 	int j;
@@ -652,56 +650,34 @@
 	m->mdmreg[REG_SI1I] = si2bit[si];
 	save_flags(flags);
 	cli();
-	i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
+	i = isdn_get_free_slot(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
 	if (i < 0) {
 		restore_flags(flags);
 		isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
 	} else {
-		info->isdn_driver = dev->drvmap[i];
-		info->isdn_channel = dev->chanmap[i];
-		info->drv_index = i;
-		dev->m_idx[i] = info->line;
-		dev->usage[i] |= ISDN_USAGE_OUTGOING;
+		struct dial_info dial = {
+			.l2_proto = l2,
+			.l3_proto = m->mdmreg[REG_L3PROT],
+			.si1      = si,
+			.si2      = m->mdmreg[REG_SI2],
+			.msn      = m->msn,
+			.phone    = n,
+		};
+		info->isdn_slot = i;
+		isdn_slot_set_m_idx(i, info->line);
 		info->last_dir = 1;
+		info->last_l2 = l2;
 		strcpy(info->last_num, n);
-		isdn_info_update();
 		restore_flags(flags);
-		cmd.driver = info->isdn_driver;
-		cmd.arg = info->isdn_channel;
-		cmd.command = ISDN_CMD_CLREAZ;
-		isdn_command(&cmd);
-		strcpy(cmd.parm.num, isdn_map_eaz2msn(m->msn, info->isdn_driver));
-		cmd.driver = info->isdn_driver;
-		cmd.command = ISDN_CMD_SETEAZ;
-		isdn_command(&cmd);
-		cmd.driver = info->isdn_driver;
-		cmd.command = ISDN_CMD_SETL2;
-		info->last_l2 = l2;
-		cmd.arg = info->isdn_channel + (l2 << 8);
-		isdn_command(&cmd);
-		cmd.driver = info->isdn_driver;
-		cmd.command = ISDN_CMD_SETL3;
-		cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8);
 #ifdef CONFIG_ISDN_TTY_FAX
 		if (l2 == ISDN_PROTO_L2_FAX) {
-			cmd.parm.fax = info->fax;
+			dial.fax = info->fax;
 			info->fax->direction = ISDN_TTY_FAX_CONN_OUT;
 		}
 #endif
-		isdn_command(&cmd);
-		cmd.driver = info->isdn_driver;
-		cmd.arg = info->isdn_channel;
-		sprintf(cmd.parm.setup.phone, "%s", n);
-		sprintf(cmd.parm.setup.eazmsn, "%s",
-			isdn_map_eaz2msn(m->msn, info->isdn_driver));
-		cmd.parm.setup.si1 = si;
-		cmd.parm.setup.si2 = m->mdmreg[REG_SI2];
-		cmd.command = ISDN_CMD_DIAL;
 		info->dialing = 1;
 		info->emu.carrierwait = 0;
-		strcpy(dev->num[i], n);
-		isdn_info_update();
-		isdn_command(&cmd);
+		isdn_slot_dial(info->isdn_slot, &dial);
 		isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1);
 	}
 }
@@ -714,19 +690,15 @@
 isdn_tty_modem_hup(modem_info * info, int local)
 {
 	isdn_ctrl cmd;
-	int di, ch;
+	int slot;
 
 	if (!info)
 		return;
 
-	di = info->isdn_driver;
-	ch = info->isdn_channel;
-	if (di < 0 || ch < 0)
+	slot = info->isdn_slot;
+	if (slot < 0)
 		return;
 
-	info->isdn_driver = -1;
-	info->isdn_channel = -1;
-
 #ifdef ISDN_DEBUG_MODEM_HUP
 	printk(KERN_DEBUG "Mhup ttyI%d\n", info->line);
 #endif
@@ -768,21 +740,14 @@
 	info->msr &= ~(UART_MSR_DCD | UART_MSR_RI);
 	info->lsr |= UART_LSR_TEMT;
 
-	if (local) {
-		cmd.driver = di;
-		cmd.command = ISDN_CMD_HANGUP;
-		cmd.arg = ch;
-		isdn_command(&cmd);
-	}
+	if (local)
+		isdn_slot_command(slot, ISDN_CMD_HANGUP, &cmd);
 
-	isdn_all_eaz(di, ch);
+	isdn_slot_all_eaz(slot);
 	info->emu.mdmreg[REG_RINGCNT] = 0;
-	isdn_free_channel(di, ch, 0);
-
-	if (info->drv_index >= 0) {
-		dev->m_idx[info->drv_index] = -1;
-		info->drv_index = -1;
-	}
+	isdn_slot_free(slot, 0);
+	isdn_slot_set_m_idx(slot, -1);
+	info->isdn_slot = -1;
 }
 
 /*
@@ -812,11 +777,11 @@
 	printk(KERN_DEBUG "Msusp ttyI%d\n", info->line);
 #endif
 	l = strlen(id);
-	if ((info->isdn_driver >= 0)) {
+	if ((info->isdn_slot >= 0)) {
 		cmd.parm.cmsg.Length = l+18;
 		cmd.parm.cmsg.Command = CAPI_FACILITY;
 		cmd.parm.cmsg.Subcommand = CAPI_REQ;
-		cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1;
+		cmd.parm.cmsg.adr.Controller = isdn_slot_driver(info->isdn_slot) + 1;
 		cmd.parm.cmsg.para[0] = 3; /* 16 bit 0x0003 suplementary service */
 		cmd.parm.cmsg.para[1] = 0;
 		cmd.parm.cmsg.para[2] = l + 3;
@@ -824,10 +789,7 @@
 		cmd.parm.cmsg.para[4] = 0;
 		cmd.parm.cmsg.para[5] = l;
 		strncpy(&cmd.parm.cmsg.para[6], id, l);
-		cmd.command = CAPI_PUT_MESSAGE;
-		cmd.driver = info->isdn_driver;
-		cmd.arg = info->isdn_channel;
-		isdn_command(&cmd);
+		isdn_slot_command(info->isdn_slot, CAPI_PUT_MESSAGE, &cmd);
 	}
 }
 
@@ -871,43 +833,26 @@
 	m->mdmreg[REG_SI1I] = si2bit[si];
 	save_flags(flags);
 	cli();
-	i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
+	i = isdn_get_free_slot(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
 	if (i < 0) {
 		restore_flags(flags);
 		isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
 	} else {
-		info->isdn_driver = dev->drvmap[i];
-		info->isdn_channel = dev->chanmap[i];
-		info->drv_index = i;
-		dev->m_idx[i] = info->line;
-		dev->usage[i] |= ISDN_USAGE_OUTGOING;
+		info->isdn_slot = i;
+		isdn_slot_set_m_idx(i, info->line);
+		isdn_slot_set_usage(i, isdn_slot_usage(i) | ISDN_USAGE_OUTGOING);
 		info->last_dir = 1;
 //		strcpy(info->last_num, n);
-		isdn_info_update();
 		restore_flags(flags);
-		cmd.driver = info->isdn_driver;
-		cmd.arg = info->isdn_channel;
-		cmd.command = ISDN_CMD_CLREAZ;
-		isdn_command(&cmd);
-		strcpy(cmd.parm.num, isdn_map_eaz2msn(m->msn, info->isdn_driver));
-		cmd.driver = info->isdn_driver;
-		cmd.command = ISDN_CMD_SETEAZ;
-		isdn_command(&cmd);
-		cmd.driver = info->isdn_driver;
-		cmd.command = ISDN_CMD_SETL2;
 		info->last_l2 = l2;
-		cmd.arg = info->isdn_channel + (l2 << 8);
-		isdn_command(&cmd);
-		cmd.driver = info->isdn_driver;
-		cmd.command = ISDN_CMD_SETL3;
-		cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8);
-		isdn_command(&cmd);
-		cmd.driver = info->isdn_driver;
-		cmd.arg = info->isdn_channel;
+		cmd.arg = l2 << 8;
+		isdn_slot_command(info->isdn_slot, ISDN_CMD_SETL2, &cmd);
+		cmd.arg = m->mdmreg[REG_L3PROT] << 8;
+		isdn_slot_command(info->isdn_slot, ISDN_CMD_SETL3, &cmd);
 		cmd.parm.cmsg.Length = l+18;
 		cmd.parm.cmsg.Command = CAPI_FACILITY;
 		cmd.parm.cmsg.Subcommand = CAPI_REQ;
-		cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1;
+		cmd.parm.cmsg.adr.Controller = isdn_slot_driver(info->isdn_slot) + 1;
 		cmd.parm.cmsg.para[0] = 3; /* 16 bit 0x0003 suplementary service */
 		cmd.parm.cmsg.para[1] = 0;
 		cmd.parm.cmsg.para[2] = l+3;
@@ -915,11 +860,10 @@
 		cmd.parm.cmsg.para[4] = 0;
 		cmd.parm.cmsg.para[5] = l;
 		strncpy(&cmd.parm.cmsg.para[6], id, l);
-		cmd.command =CAPI_PUT_MESSAGE;
 		info->dialing = 1;
 //		strcpy(dev->num[i], n);
 		isdn_info_update();
-		isdn_command(&cmd);
+		isdn_slot_command(info->isdn_slot, CAPI_PUT_MESSAGE, &cmd);
 		isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1);
 	}
 }
@@ -965,51 +909,33 @@
 	m->mdmreg[REG_SI1I] = si2bit[si];
 	save_flags(flags);
 	cli();
-	i = isdn_get_free_channel(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
+	i = isdn_get_free_slot(usg, l2, m->mdmreg[REG_L3PROT], -1, -1, m->msn);
 	if (i < 0) {
 		restore_flags(flags);
 		isdn_tty_modem_result(RESULT_NO_DIALTONE, info);
 	} else {
-		info->isdn_driver = dev->drvmap[i];
-		info->isdn_channel = dev->chanmap[i];
-		info->drv_index = i;
-		dev->m_idx[i] = info->line;
-		dev->usage[i] |= ISDN_USAGE_OUTGOING;
+		info->isdn_slot = i;
+		isdn_slot_set_m_idx(i, info->line);
+		isdn_slot_set_usage(i, isdn_slot_usage(i) | ISDN_USAGE_OUTGOING);
 		info->last_dir = 1;
-		isdn_info_update();
 		restore_flags(flags);
-		cmd.driver = info->isdn_driver;
-		cmd.arg = info->isdn_channel;
-		cmd.command = ISDN_CMD_CLREAZ;
-		isdn_command(&cmd);
-		strcpy(cmd.parm.num, isdn_map_eaz2msn(m->msn, info->isdn_driver));
-		cmd.driver = info->isdn_driver;
-		cmd.command = ISDN_CMD_SETEAZ;
-		isdn_command(&cmd);
-		cmd.driver = info->isdn_driver;
-		cmd.command = ISDN_CMD_SETL2;
 		info->last_l2 = l2;
-		cmd.arg = info->isdn_channel + (l2 << 8);
-		isdn_command(&cmd);
-		cmd.driver = info->isdn_driver;
-		cmd.command = ISDN_CMD_SETL3;
-		cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8);
-		isdn_command(&cmd);
-		cmd.driver = info->isdn_driver;
-		cmd.arg = info->isdn_channel;
+		cmd.arg = l2 << 8;
+		isdn_slot_command(info->isdn_slot, ISDN_CMD_SETL2, &cmd);
+		cmd.arg = m->mdmreg[REG_L3PROT] << 8;
+		isdn_slot_command(info->isdn_slot, ISDN_CMD_SETL3, &cmd);
 		cmd.parm.cmsg.Length = l+14;
 		cmd.parm.cmsg.Command = CAPI_MANUFACTURER;
 		cmd.parm.cmsg.Subcommand = CAPI_REQ;
-		cmd.parm.cmsg.adr.Controller = info->isdn_driver + 1;
+		cmd.parm.cmsg.adr.Controller = isdn_slot_driver(info->isdn_slot) + 1;
 		cmd.parm.cmsg.para[0] = l+1;
 		strncpy(&cmd.parm.cmsg.para[1], msg, l);
 		cmd.parm.cmsg.para[l+1] = 0xd;
-		cmd.command =CAPI_PUT_MESSAGE;
 /*		info->dialing = 1;
 		strcpy(dev->num[i], n);
 		isdn_info_update();
 */
-		isdn_command(&cmd);
+		isdn_slot_command(info->isdn_slot, CAPI_PUT_MESSAGE, &cmd);
 	}
 }
 
@@ -1173,6 +1099,7 @@
 {
 	int c;
 	int total = 0;
+	int di;
 	modem_info *info = (modem_info *) tty->driver_data;
 	atemu *m = &info->emu;
 
@@ -1186,8 +1113,9 @@
 		c = count;
 		if (c > info->xmit_size - info->xmit_count)
 			c = info->xmit_size - info->xmit_count;
-		if (info->isdn_driver >= 0 && c > dev->drv[info->isdn_driver]->maxbufsize)
-			c = dev->drv[info->isdn_driver]->maxbufsize;
+		di = isdn_slot_driver(info->isdn_slot);
+		if (di >= 0 && c > dev->drv[di]->maxbufsize)
+			c = dev->drv[di]->maxbufsize;
 		if (c <= 0)
 			break;
 		if ((info->online > 1)
@@ -1247,12 +1175,9 @@
 				if (info->vonline & 4) { /* ETX seen */
 					isdn_ctrl c;
 
-					c.command = ISDN_CMD_FAXCMD;
-					c.driver = info->isdn_driver;
-					c.arg = info->isdn_channel;
 					c.parm.aux.cmd = ISDN_FAX_CLASS1_CTRL;
 					c.parm.aux.subcmd = ETX;
-					isdn_command(&c);
+					isdn_slot_command(info->isdn_slot, ISDN_CMD_FAXCMD, &c);
 				}
 				info->vonline = 0;
 #ifdef ISDN_DEBUG_MODEM_VOICE
@@ -2015,10 +1940,10 @@
 }
 
 int
-isdn_tty_modem_init(void)
+isdn_tty_init(void)
 {
 	modem *m;
-	int i;
+	int i, retval;
 	modem_info *info;
 
 	m = &dev->mdm;
@@ -2063,13 +1988,15 @@
 	m->tty_modem.minor_start = 0;
 	m->cua_modem.subtype = ISDN_SERIAL_TYPE_CALLOUT;
 
-	if (tty_register_driver(&m->tty_modem)) {
+	retval = tty_register_driver(&m->tty_modem);
+	if (retval) {
 		printk(KERN_WARNING "isdn_tty: Couldn't register modem-device\n");
-		return -1;
+		goto err;
 	}
-	if (tty_register_driver(&m->cua_modem)) {
+	retval = tty_register_driver(&m->cua_modem);
+	if (retval) {
 		printk(KERN_WARNING "isdn_tty: Couldn't register modem-callout-device\n");
-		return -2;
+		goto err_unregister_tty;
 	}
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
 		info = &m->info[i];
@@ -2098,24 +2025,58 @@
 		info->normal_termios = m->tty_modem.init_termios;
 		init_waitqueue_head(&info->open_wait);
 		init_waitqueue_head(&info->close_wait);
-		info->isdn_driver = -1;
-		info->isdn_channel = -1;
-		info->drv_index = -1;
+		info->isdn_slot = -1;
 		info->xmit_size = ISDN_SERIAL_XMIT_SIZE;
 		skb_queue_head_init(&info->xmit_queue);
 #ifdef CONFIG_ISDN_AUDIO
 		skb_queue_head_init(&info->dtmf_queue);
 #endif
-		if (!(info->xmit_buf = kmalloc(ISDN_SERIAL_XMIT_MAX + 5, GFP_KERNEL))) {
+		info->xmit_buf = kmalloc(ISDN_SERIAL_XMIT_MAX + 5, GFP_KERNEL);
+		if (!info->xmit_buf) {
 			printk(KERN_ERR "Could not allocate modem xmit-buffer\n");
-			return -3;
+#ifdef CONFIG_ISDN_TTY_FAX
+			kfree(info->fax);
+#endif
+			goto err_unregister_cua;
 		}
 		/* Make room for T.70 header */
 		info->xmit_buf += 4;
 	}
 	return 0;
+
+ err_unregister_cua:
+	for (i--; i >= 0; i--) {
+		info = &m->info[i];
+#ifdef CONFIG_ISDN_TTY_FAX
+		kfree(info->fax);
+#endif
+		kfree(info->xmit_buf - 4);
+	}
+	tty_unregister_driver(&dev->mdm.cua_modem);
+ err_unregister_tty:
+	tty_unregister_driver(&dev->mdm.tty_modem);
+ err:
+	return retval;
 }
 
+void
+isdn_tty_exit(void)
+{
+	modem *m = &dev->mdm;
+	modem_info *info;
+	int i;
+
+	for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
+		info = &m->info[i];
+		isdn_tty_cleanup_xmit(info);
+#ifdef CONFIG_ISDN_TTY_FAX
+		kfree(info->fax);
+#endif
+		kfree(info->xmit_buf - 4);
+	}
+	tty_unregister_driver(&dev->mdm.cua_modem);
+	tty_unregister_driver(&dev->mdm.tty_modem);
+}
 
 /*
  * isdn_tty_match_icall(char *MSN, atemu *tty_emulator, int dev_idx)
@@ -2227,26 +2188,21 @@
 #ifndef FIX_FILE_TRANSFER
 				(info->flags & ISDN_ASYNC_NORMAL_ACTIVE) &&
 #endif
-				(info->isdn_driver == -1) &&
-				(info->isdn_channel == -1) &&
-				(USG_NONE(dev->usage[idx]))) {
+				(info->isdn_slot == -1) &&
+				(USG_NONE(isdn_slot_usage(idx)))) {
 				int matchret;
 
 				if ((matchret = isdn_tty_match_icall(eaz, &info->emu, di)) > wret)
 					wret = matchret;
 				if (!matchret) {                  /* EAZ is matching */
-					info->isdn_driver = di;
-					info->isdn_channel = ch;
-					info->drv_index = idx;
-					dev->m_idx[idx] = info->line;
-					dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE;
-					dev->usage[idx] |= isdn_calc_usage(si1, info->emu.mdmreg[REG_L2PROT]); 
-					strcpy(dev->num[idx], nr);
+					info->isdn_slot = idx;
+					isdn_slot_set_m_idx(idx, info->line);
+					strcpy(isdn_slot_num(idx), nr);
 					strcpy(info->emu.cpn, eaz);
 					info->emu.mdmreg[REG_SI1I] = si2bit[si1];
 					info->emu.mdmreg[REG_PLAN] = setup->plan;
 					info->emu.mdmreg[REG_SCREEN] = setup->screen;
-					isdn_info_update();
+					isdn_slot_set_usage(idx, (isdn_slot_usage(idx) & ISDN_USAGE_EXCLUSIVE) | isdn_calc_usage(si1, info->emu.mdmreg[REG_L2PROT]));
 					restore_flags(flags);
 					printk(KERN_INFO "isdn_tty: call from %s, -> RING on ttyI%d\n", nr,
 					       info->line);
@@ -2276,7 +2232,7 @@
 
 	if (i < 0)
 		return 0;
-	if ((mi = dev->m_idx[i]) >= 0) {
+	if ((mi = isdn_slot_m_idx(i)) >= 0) {
 		info = &dev->mdm.info[mi];
 		switch (c->command) {
                         case ISDN_STAT_CINF:
@@ -2290,8 +2246,7 @@
 #ifdef ISDN_TTY_STAT_DEBUG
 				printk(KERN_DEBUG "tty_STAT_BSENT ttyI%d\n", info->line);
 #endif
-				if ((info->isdn_driver == c->driver) &&
-				    (info->isdn_channel == c->arg)) {
+				if ((info->isdn_slot == isdn_dc2minor(c->driver, c->arg))) {
 					info->msr |= UART_MSR_CTS;
 					if (info->send_outstanding)
 						if (!(--info->send_outstanding))
@@ -2375,14 +2330,14 @@
 						info->last_dir = 0;
 					info->dialing = 0;
 					info->rcvsched = 1;
-					if (USG_MODEM(dev->usage[i])) {
+					if (USG_MODEM(isdn_slot_usage(i))) {
 						if (info->emu.mdmreg[REG_L2PROT] == ISDN_PROTO_L2_MODEM) {
 							strcpy(info->emu.connmsg, c->parm.num);
 							isdn_tty_modem_result(RESULT_CONNECT, info);
 						} else
 							isdn_tty_modem_result(RESULT_CONNECT64000, info);
 					}
-					if (USG_VOICE(dev->usage[i]))
+					if (USG_VOICE(isdn_slot_usage(i)))
 						isdn_tty_modem_result(RESULT_VCON, info);
 					return 1;
 				}
@@ -2421,7 +2376,7 @@
 #endif
 				for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
 					info = &dev->mdm.info[i];
-					if (info->isdn_driver == c->driver) {
+					if (isdn_slot_driver(info->isdn_slot) == c->driver) {
 						if (info->online)
 							isdn_tty_modem_hup(info, 1);
 					}
@@ -2473,6 +2428,7 @@
 	ulong flags;
 	struct sk_buff *skb = 0;
 	char *sp = 0;
+	int di,ch;
 
 	if (!msg) {
 		printk(KERN_WARNING "isdn_tty: Null-Message in isdn_tty_at_cout\n");
@@ -2488,8 +2444,9 @@
 
 	/* use queue instead of direct flip, if online and */
 	/* data is in queue or flip buffer is full */
+	di = isdn_slot_driver(info->isdn_slot); ch = isdn_slot_channel(info->isdn_slot);
 	if ((info->online) && (((tty->flip.count + strlen(msg)) >= TTY_FLIPBUF_SIZE) ||
-	    (!skb_queue_empty(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel])))) {
+	    (!skb_queue_empty(&dev->drv[di]->rpqueue[ch])))) {
 		skb = alloc_skb(strlen(msg)
 #ifdef CONFIG_ISDN_AUDIO
 			+ sizeof(isdn_audio_skb)
@@ -2532,8 +2489,8 @@
 		}
 	}
 	if (skb) {
-		__skb_queue_tail(&dev->drv[info->isdn_driver]->rpqueue[info->isdn_channel], skb);
-		dev->drv[info->isdn_driver]->rcvcount[info->isdn_channel] += skb->len;
+		__skb_queue_tail(&dev->drv[di]->rpqueue[ch], skb);
+		dev->drv[di]->rcvcount[ch] += skb->len;
 		restore_flags(flags);
 		/* Schedule dequeuing */
 		if ((dev->modempoll) && (info->rcvsched))
@@ -2551,7 +2508,7 @@
 static void
 isdn_tty_on_hook(modem_info * info)
 {
-	if (info->isdn_channel >= 0) {
+	if (info->isdn_slot >= 0) {
 #ifdef ISDN_DEBUG_MODEM_HUP
 		printk(KERN_DEBUG "Mhup in isdn_tty_on_hook\n");
 #endif
@@ -2711,7 +2668,7 @@
 			    /* print CID, _before_ _every_ ring */
 			    if (!(m->mdmreg[REG_CIDONCE] & BIT_CIDONCE)) {
 				    isdn_tty_at_cout("\r\nCALLER NUMBER: ", info);
-				    isdn_tty_at_cout(dev->num[info->drv_index], info);
+				    isdn_tty_at_cout(isdn_slot_num(info->isdn_slot), info);
 				    if (m->mdmreg[REG_CDN] & BIT_CDN) {
 					    isdn_tty_at_cout("\r\nCALLED NUMBER: ", info);
 					    isdn_tty_at_cout(info->emu.cpn, info);
@@ -2740,7 +2697,7 @@
 					    (m->mdmreg[REG_RINGCNT] == 1)) {
 						isdn_tty_at_cout("\r\n", info);
 						isdn_tty_at_cout("CALLER NUMBER: ", info);
-						isdn_tty_at_cout(dev->num[info->drv_index], info);
+						isdn_tty_at_cout(isdn_slot_num(info->isdn_slot), info);
 						if (m->mdmreg[REG_CDN] & BIT_CDN) {
 							isdn_tty_at_cout("\r\nCALLED NUMBER: ", info);
 							isdn_tty_at_cout(info->emu.cpn, info);
@@ -3252,7 +3209,7 @@
 	if (info->msr & UART_MSR_RI) {
 		/* Accept incoming call */
 		info->last_dir = 0;
-		strcpy(info->last_num, dev->num[info->drv_index]);
+		strcpy(info->last_num, isdn_slot_num(info->isdn_slot));
 		m->mdmreg[REG_RINGCNT] = 0;
 		info->msr &= ~UART_MSR_RI;
 		l2 = m->mdmreg[REG_L2PROT];
@@ -3266,27 +3223,20 @@
 				l2 = ISDN_PROTO_L2_X75I;
 		}
 #endif
-		cmd.driver = info->isdn_driver;
-		cmd.command = ISDN_CMD_SETL2;
-		cmd.arg = info->isdn_channel + (l2 << 8);
+		cmd.arg = l2 << 8;
 		info->last_l2 = l2;
-		isdn_command(&cmd);
-		cmd.driver = info->isdn_driver;
-		cmd.command = ISDN_CMD_SETL3;
-		cmd.arg = info->isdn_channel + (m->mdmreg[REG_L3PROT] << 8);
+		isdn_slot_command(info->isdn_slot, ISDN_CMD_SETL2, &cmd);
+		cmd.arg = m->mdmreg[REG_L3PROT] << 8;
 #ifdef CONFIG_ISDN_TTY_FAX
 		if (l2 == ISDN_PROTO_L2_FAX) {
 			cmd.parm.fax = info->fax;
 			info->fax->direction = ISDN_TTY_FAX_CONN_IN;
 		}
 #endif
-		isdn_command(&cmd);
-		cmd.driver = info->isdn_driver;
-		cmd.arg = info->isdn_channel;
-		cmd.command = ISDN_CMD_ACCEPTD;
+		isdn_slot_command(info->isdn_slot, ISDN_CMD_SETL3, &cmd);
 		info->dialing = 16;
 		info->emu.carrierwait = 0;
-		isdn_command(&cmd);
+		isdn_slot_command(info->isdn_slot, ISDN_CMD_ACCEPTD, &cmd);
 		isdn_timer_ctrl(ISDN_TIMER_CARRIER, 1);
 	} else
 		isdn_tty_modem_result(RESULT_NO_ANSWER, info);
@@ -3642,12 +3592,10 @@
 							PARSE_ERROR1;
 						m->vpar[4] = par1;
 						m->vpar[5] = par2;
-						cmd.driver = info->isdn_driver;
-						cmd.command = ISDN_CMD_AUDIO;
-						cmd.arg = info->isdn_channel + (ISDN_AUDIO_SETDD << 8);
+						cmd.arg = ISDN_AUDIO_SETDD << 8;
 						cmd.parm.num[0] = par1;
 						cmd.parm.num[1] = par2;
-						isdn_command(&cmd);
+						isdn_slot_command(info->isdn_slot, ISDN_CMD_AUDIO, &cmd);
 						break;
 					} else
 					if (*p[0] == '?') {
@@ -3973,8 +3921,8 @@
 	int midx;
 
 	for (i = 0; i < ISDN_MAX_CHANNELS; i++)
-		if (USG_MODEM(dev->usage[i]))
-			if ((midx = dev->m_idx[i]) >= 0) {
+		if (USG_MODEM(isdn_slot_usage(i)))
+			if ((midx = isdn_slot_m_idx(i)) >= 0) {
 				modem_info *info = &dev->mdm.info[midx];
 				if (info->online) {
 					ton = 1;
diff -Nru a/drivers/isdn/i4l/isdn_tty.h b/drivers/isdn/i4l/isdn_tty.h
--- a/drivers/isdn/i4l/isdn_tty.h	Sat Aug 10 18:42:23 2002
+++ b/drivers/isdn/i4l/isdn_tty.h	Sat Aug 10 18:42:23 2002
@@ -105,7 +105,7 @@
 extern void isdn_tty_modem_ring(void);
 extern void isdn_tty_carrier_timeout(void);
 extern void isdn_tty_modem_xmit(void);
-extern int isdn_tty_modem_init(void);
+extern int isdn_tty_init(void);
 extern void isdn_tty_readmodem(void);
 extern int isdn_tty_find_icall(int, int, setup_parm *);
 extern void isdn_tty_cleanup_xmit(modem_info *);
@@ -119,3 +119,6 @@
 extern int isdn_tty_fax_command(modem_info *, isdn_ctrl *);
 extern void isdn_tty_fax_bitorder(modem_info *, struct sk_buff *);
 #endif
+
+extern int isdn_tty_init(void);
+extern void isdn_tty_exit(void);
diff -Nru a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c
--- a/drivers/isdn/i4l/isdn_ttyfax.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/isdn/i4l/isdn_ttyfax.c	Sat Aug 10 18:42:20 2002
@@ -74,7 +74,7 @@
 		case 2:	/* +FCON */
 			/* Append CPN, if enabled */
 			if ((m->mdmreg[REG_CPNFCON] & BIT_CPNFCON) &&
-				(!(dev->usage[info->isdn_channel] & ISDN_USAGE_OUTGOING))) {
+				(!(isdn_slot_usage(info->isdn_slot) & ISDN_USAGE_OUTGOING))) {
 				sprintf(rs, "/%s", m->cpn);
 				isdn_tty_at_cout(rs, info);
 			}
@@ -360,12 +360,11 @@
 		default:
 			PARSE_ERROR1;
 	}
-	c.command = ISDN_CMD_FAXCMD;
 #ifdef ISDN_TTY_FAX_CMD_DEBUG
 	printk(KERN_DEBUG "isdn_tty_cmd_FCLASS1 %d/%d/%d)\n",
 	       c.parm.aux.cmd, c.parm.aux.subcmd, c.parm.aux.para[0]);
 #endif
-	if (info->isdn_driver < 0) {
+	if (info->isdn_slot < 0) {
 		save_flags(flags);
 		cli();
 		if ((c.parm.aux.subcmd == AT_EQ_VALUE) ||
@@ -374,32 +373,21 @@
 			PARSE_ERROR1;
 		}
 		/* get a temporary connection to the first free fax driver */
-		i = isdn_get_free_channel(ISDN_USAGE_FAX, ISDN_PROTO_L2_FAX,
-					  ISDN_PROTO_L3_FCLASS1, -1, -1, "00");
+		i = isdn_get_free_slot(ISDN_USAGE_FAX, ISDN_PROTO_L2_FAX,
+				       ISDN_PROTO_L3_FCLASS1, -1, -1, "00");
 		if (i < 0) {
 			restore_flags(flags);
 			PARSE_ERROR1;
 		}
-		info->isdn_driver = dev->drvmap[i];
-		info->isdn_channel = dev->chanmap[i];
-		info->drv_index = i;
-		dev->m_idx[i] = info->line;
-		c.driver = info->isdn_driver;
-		c.arg = info->isdn_channel;
-		isdn_command(&c);
-		isdn_free_channel(info->isdn_driver, info->isdn_channel,
-				  ISDN_USAGE_FAX);
-		info->isdn_driver = -1;
-		info->isdn_channel = -1;
-		if (info->drv_index >= 0) {
-			dev->m_idx[info->drv_index] = -1;
-			info->drv_index = -1;
-		}
+		info->isdn_slot = i;
+		isdn_slot_set_m_idx(i, info->line);
+		isdn_slot_command(info->isdn_slot, ISDN_CMD_FAXCMD, &c);
+		isdn_slot_free(info->isdn_slot, ISDN_USAGE_FAX);
+		isdn_slot_set_m_idx(i, -1);
+		info->isdn_slot = -1;
 		restore_flags(flags);
 	} else {
-		c.driver = info->isdn_driver;
-		c.arg = info->isdn_channel;
-		isdn_command(&c);
+		isdn_slot_command(info->isdn_slot, ISDN_CMD_FAXCMD, &c);
 	}
 	return 1;
 }
@@ -800,10 +788,7 @@
 			printk(KERN_DEBUG "isdn_tty: Fax FDR\n");
 #endif
 			f->code = ISDN_TTY_FAX_DR;
-			cmd.driver = info->isdn_driver;
-			cmd.arg = info->isdn_channel;
-			cmd.command = ISDN_CMD_FAXCMD;
-			isdn_command(&cmd);
+			isdn_slot_command(info->isdn_slot, ISDN_CMD_FAXCMD, &cmd);
 			if (f->phase == ISDN_FAX_PHASE_B) {
 				f->phase = ISDN_FAX_PHASE_C;
 			} else if (f->phase == ISDN_FAX_PHASE_D) {
@@ -855,10 +840,7 @@
 #endif
 		if ((f->phase == ISDN_FAX_PHASE_B) || (f->phase == ISDN_FAX_PHASE_D)) {
 			f->code = ISDN_TTY_FAX_DT;
-			cmd.driver = info->isdn_driver;
-			cmd.arg = info->isdn_channel;
-			cmd.command = ISDN_CMD_FAXCMD;
-			isdn_command(&cmd);
+			isdn_slot_command(info->isdn_slot, ISDN_CMD_FAXCMD, &cmd);
 			if (f->phase == ISDN_FAX_PHASE_D) {
 				f->phase = ISDN_FAX_PHASE_C;
 				isdn_tty_fax_modem_result(7, info);	/* CONNECT */
@@ -913,10 +895,7 @@
 				PARSE_ERROR1;
 			f->fet = par;
 			f->code = ISDN_TTY_FAX_ET;
-			cmd.driver = info->isdn_driver;
-			cmd.arg = info->isdn_channel;
-			cmd.command = ISDN_CMD_FAXCMD;
-			isdn_command(&cmd);
+			isdn_slot_command(info->isdn_slot, ISDN_CMD_FAXCMD, &cmd);
 #ifdef ISDN_TTY_FAX_STAT_DEBUG
 			printk(KERN_DEBUG "isdn_tty: Fax FET=%d\n", par);
 #endif
diff -Nru a/drivers/isdn/i4l/isdn_v110.c b/drivers/isdn/i4l/isdn_v110.c
--- a/drivers/isdn/i4l/isdn_v110.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/isdn/i4l/isdn_v110.c	Sat Aug 10 18:42:23 2002
@@ -515,14 +515,12 @@
 }
 
 int
-isdn_v110_stat_callback(int idx, isdn_ctrl * c)
+isdn_v110_stat_callback(struct isdn_v110 *iv110, isdn_ctrl *c)
 {
 	isdn_v110_stream *v = NULL;
 	int i;
 	int ret;
 
-	if (idx < 0)
-		return 0;
 	switch (c->command) {
 		case ISDN_STAT_BSENT:
                         /* Keep the send-queue of the driver filled
@@ -531,9 +529,9 @@
 			 * send down an Idle-Frame (or an Sync-Frame, if
 			 * v->SyncInit != 0). 
 			 */
-			if (!(v = dev->v110[idx]))
+			if (!(v = iv110->v110))
 				return 0;
-			atomic_inc(&dev->v110use[idx]);
+			atomic_inc(&iv110->v110use);
 			if (v->skbidle > 0) {
 				v->skbidle--;
 				ret = 1;
@@ -560,38 +558,38 @@
 				} else
 					break;
 			}
-			atomic_dec(&dev->v110use[idx]);
+			atomic_dec(&iv110->v110use);
 			return ret;
 		case ISDN_STAT_DHUP:
 		case ISDN_STAT_BHUP:
 			while (1) {
-				atomic_inc(&dev->v110use[idx]);
-				if (atomic_dec_and_test(&dev->v110use[idx])) {
-					isdn_v110_close(dev->v110[idx]);
-					dev->v110[idx] = NULL;
+				atomic_inc(&iv110->v110use);
+				if (atomic_dec_and_test(&iv110->v110use)) {
+					isdn_v110_close(iv110->v110);
+					iv110->v110 = NULL;
 					break;
 				}
 				sti();
 			}
 			break;
 		case ISDN_STAT_BCONN:
-			if (dev->v110emu[idx] && (dev->v110[idx] == NULL)) {
+			if (iv110->v110emu && (iv110->v110 == NULL)) {
 				int hdrlen = dev->drv[c->driver]->interface->hl_hdrlen;
 				int maxsize = dev->drv[c->driver]->interface->maxbufsize;
-				atomic_inc(&dev->v110use[idx]);
-				switch (dev->v110emu[idx]) {
+				atomic_inc(&iv110->v110use);
+				switch (iv110->v110emu) {
 					case ISDN_PROTO_L2_V11096:
-						dev->v110[idx] = isdn_v110_open(V110_9600, hdrlen, maxsize);
+						iv110->v110 = isdn_v110_open(V110_9600, hdrlen, maxsize);
 						break;
 					case ISDN_PROTO_L2_V11019:
-						dev->v110[idx] = isdn_v110_open(V110_19200, hdrlen, maxsize);
+						iv110->v110 = isdn_v110_open(V110_19200, hdrlen, maxsize);
 						break;
 					case ISDN_PROTO_L2_V11038:
-						dev->v110[idx] = isdn_v110_open(V110_38400, hdrlen, maxsize);
+						iv110->v110 = isdn_v110_open(V110_38400, hdrlen, maxsize);
 						break;
 					default:;
 				}
-				if ((v = dev->v110[idx])) {
+				if ((v = iv110->v110)) {
 					while (v->SyncInit) {
 						struct sk_buff *skb = isdn_v110_sync(v);
 						if (dev->drv[c->driver]->interface->writebuf_skb(c->driver, c->arg, 1, skb) <= 0) {
@@ -603,8 +601,8 @@
 						v->skbidle++;
 					}
 				} else
-					printk(KERN_WARNING "isdn_v110: Couldn't open stream for chan %d\n", idx);
-				atomic_dec(&dev->v110use[idx]);
+					printk(KERN_WARNING "isdn_v110: Couldn't open stream\n");
+				atomic_dec(&iv110->v110use);
 			}
 			break;
 		default:
diff -Nru a/drivers/isdn/i4l/isdn_v110.h b/drivers/isdn/i4l/isdn_v110.h
--- a/drivers/isdn/i4l/isdn_v110.h	Sat Aug 10 18:42:21 2002
+++ b/drivers/isdn/i4l/isdn_v110.h	Sat Aug 10 18:42:21 2002
@@ -9,8 +9,14 @@
  *
  */
 
-#ifndef _isdn_v110_h_
-#define _isdn_v110_h_
+#ifndef ISDN_V110_H
+#define ISDN_V110_H
+
+struct isdn_v110 {
+  int               v110emu;             /* V.110 emulator-mode 0=none */
+  atomic_t          v110use;             /* Usage-Semaphore for stream */
+  isdn_v110_stream  *v110;               /* V.110 private data         */
+};
 
 /* 
  * isdn_v110_encode will take raw data and encode it using V.110 
@@ -23,7 +29,7 @@
  */
 extern struct sk_buff *isdn_v110_decode(isdn_v110_stream *, struct sk_buff *);
 
-extern int isdn_v110_stat_callback(int, isdn_ctrl *);
+extern int isdn_v110_stat_callback(struct isdn_v110 *v110, isdn_ctrl *);
 extern void isdn_v110_close(isdn_v110_stream * v);
 
 #endif
diff -Nru a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c
--- a/drivers/isdn/isdnloop/isdnloop.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/isdn/isdnloop/isdnloop.c	Sat Aug 10 18:42:20 2002
@@ -757,6 +757,10 @@
 	int i;
 	static char nphone[30];
 
+	if (!card) {
+		printk("BUG!!!\n");
+		return "";
+	}
 	switch (card->ptype) {
 		case ISDN_PTYPE_EURO:
 			if (caller) {
@@ -775,7 +779,7 @@
 				return (&phone[strlen(phone) - 1]);
 			break;
 	}
-	return ("\0");
+	return "";
 }
 
 /*
@@ -882,7 +886,7 @@
 						isdnloop_vstphone(card, cmd.parm.setup.eazmsn, 1),
 						cmd.parm.setup.si1,
 						cmd.parm.setup.si2,
-					isdnloop_vstphone(card->rcard[ch],
+					isdnloop_vstphone(card->rcard[ch - 1],
 					       cmd.parm.setup.phone, 0));
 					isdnloop_fake(card->rcard[ch - 1], buf, card->rch[ch - 1] + 1);
 					/* Fall through */
diff -Nru a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c
--- a/drivers/mtd/ftl.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/mtd/ftl.c	Sat Aug 10 18:42:22 2002
@@ -125,6 +125,7 @@
 /* Each memory region corresponds to a minor device */
 typedef struct partition_t {
     struct mtd_info	*mtd;
+    struct gndisk	*disk;
     u_int32_t		state;
     u_int32_t		*VirtualBlockMap;
     u_int32_t		*VirtualPageMap;
@@ -176,13 +177,6 @@
 
 static struct hd_struct ftl_hd[MINOR_NR(MAX_DEV, 0, 0)];
 
-static struct gendisk ftl_gendisk = {
-    major:		FTL_MAJOR,
-    major_name:		"ftl",
-    minor_shift:	PART_BITS,
-    part:		ftl_hd,
-};
-
 /*====================================================================*/
 
 static int ftl_ioctl(struct inode *inode, struct file *file,
@@ -190,6 +184,7 @@
 static int ftl_open(struct inode *inode, struct file *file);
 static release_t ftl_close(struct inode *inode, struct file *file);
 static int ftl_reread_partitions(kdev_t dev);
+static int ftl_revalidate(kdev_t dev);
 
 static void ftl_erase_callback(struct erase_info *done);
 
@@ -198,6 +193,7 @@
     open:	ftl_open,
     release:	ftl_close,
     ioctl:	ftl_ioctl,
+    revalidate:	ftl_revalidate,
 };
 
 /*======================================================================
@@ -850,7 +846,7 @@
     if (partition->state != FTL_FORMATTED)
 	return -ENXIO;
     
-    if (ftl_gendisk.part[minor].nr_sects == 0)
+    if (partition->disk->part[0].nr_sects == 0)
 	return -ENXIO;
 
     if (!get_mtd_device(partition->mtd, -1))
@@ -1112,25 +1108,17 @@
     if (!part)
 	return -ENODEV; /* How? */
 
-    switch (cmd) {
-    case HDIO_GETGEO:
-	ret = verify_area(VERIFY_WRITE, (long *)arg, sizeof(*geo));
-	if (ret) return ret;
-	/* Sort of arbitrary: round size down to 4K boundary */
-	sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE;
-	put_user(1, (char *)&geo->heads);
-	put_user(8, (char *)&geo->sectors);
-	put_user((sect>>3), (short *)&geo->cylinders);
-	put_user(get_start_sect(inode->i_bdev), (u_long *)&geo->start);
-	break;
-    case BLKRRPART:
-	ret = ftl_reread_partitions(inode->i_rdev);
-	break;
-    default:
-	ret = -EINVAL;
-    }
-
-    return ret;
+    if (cmd != HDIO_GETGEO)
+	return -EINVAL;
+    ret = verify_area(VERIFY_WRITE, (long *)arg, sizeof(*geo));
+    if (ret) return ret;
+    /* Sort of arbitrary: round size down to 4K boundary */
+    sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE;
+    put_user(1, (char *)&geo->heads);
+    put_user(8, (char *)&geo->sectors);
+    put_user((sect>>3), (short *)&geo->cylinders);
+    put_user(get_start_sect(inode->i_bdev), (u_long *)&geo->start);
+    return 0;
 } /* ftl_ioctl */
 
 /*======================================================================
@@ -1139,22 +1127,14 @@
 
 ======================================================================*/
 
-static int ftl_reread_partitions(kdev_t dev)
+static int ftl_revalidate(kdev_t dev)
 {
-	int minor = minor(dev);
-	partition_t *part = myparts[minor >> 4];
-	kdev_t device = mk_kdev(MAJOR_NR, minor & ~15);
-	int res = dev_lock_part(device);
-	if (rec < 0)
-		return res;
-	res = wipe_partitions(device);
-	if (!res) {
-		scan_header(part);
-		grok_partitions(device,
-			le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
-	}
-	dev_unlock_part(device);
-	return res;
+	int unit = minor(dev) >> 4;
+	partition_t *part = myparts[unit];
+	scan_header(part);
+	part->disk->part[0].nr_sects =
+		le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
+	return 0;
 }
 
 /*======================================================================
@@ -1181,15 +1161,13 @@
 	  
 	  switch (CURRENT->cmd) {
 	  case READ:
-	    ret = ftl_read(part, CURRENT->buffer,
-			   CURRENT->sector+ftl_hd[minor].start_sect,
+	    ret = ftl_read(part, CURRENT->buffer, CURRENT->sector,
 			   CURRENT->current_nr_sectors);
 	    if (ret) printk("ftl_read returned %d\n", ret);
 	    break;
 	    
 	  case WRITE:
-	    ret = ftl_write(part, CURRENT->buffer,
-			    CURRENT->sector+ftl_hd[minor].start_sect,
+	    ret = ftl_write(part, CURRENT->buffer, CURRENT->sector,
 			    CURRENT->current_nr_sectors);
 	    if (ret) printk("ftl_write returned %d\n", ret);
 	    break;
@@ -1241,6 +1219,8 @@
 static void ftl_notify_add(struct mtd_info *mtd)
 {
 	partition_t *partition;
+	struct gendisk *disk;
+	char *name;
 	int device;
 
 	for (device=0; device < MAX_MTD_DEVICES && myparts[device]; device++)
@@ -1253,30 +1233,48 @@
 	}
 
 	partition = kmalloc(sizeof(partition_t), GFP_KERNEL);
+	disk = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
+	name = kmalloc(4, GFP_KERNEL);
 		
-	if (!partition) {
+	if (!partition||!disk||!name) {
 		printk(KERN_WARNING "No memory to scan for FTL on %s\n",
-		       mtd->name);
+			mtd->name);
+		kfree(partition);
+		kfree(disk);
+		kfree(name);
 		return;
 	}    
 
 	memset(partition, 0, sizeof(partition_t));
-
+	memset(disk, 0, sizeof(struct gendisk));
+	sprintf(name, "ftl%c", 'a' + device);
+	disk->major = FTL_MAJOR;
+	disk->first_minor = device << 4;
+	disk->major_name = name;
+	disk->minor_shift = PART_BITS;
+	disk->part = ftl_hd + (device << 4);
+	disk->fops = &ftl_blk_fops;
+	disk->nr_real = 1;
 	partition->mtd = mtd;
+	partition->disk = disk;
 
 	if ((scan_header(partition) == 0) && (build_maps(partition) == 0)) {
 		partition->state = FTL_FORMATTED;
 		atomic_set(&partition->open, 0);
 		myparts[device] = partition;
-		register_disk(&ftl_gendisk, mk_kdev(MAJOR_NR, device << 4),
+		add_gendisk(disk);
+		register_disk(disk, mk_kdev(MAJOR_NR, device << 4),
 			      MAX_PART, &ftl_blk_fops,
 			      le32_to_cpu(partition->header.FormattedSize)/SECTOR_SIZE);
 #ifdef PCMCIA_DEBUG
 		printk(KERN_INFO "ftl_cs: opening %d kb FTL partition\n",
 		       le32_to_cpu(partition->header.FormattedSize) >> 10);
 #endif
-	} else
+	} else {
 		kfree(partition);
+		kfree(disk);
+		kfree(name);
+	}
 }
 
 static void ftl_notify_remove(struct mtd_info *mtd)
@@ -1300,10 +1298,10 @@
 				ftl_freepart(myparts[i]);
 			
 			myparts[i]->state = 0;
-			for (j=0; j<16; j++) {
-				ftl_gendisk.part[j].nr_sects=0;
-				ftl_gendisk.part[j].start_sect=0;
-			}
+			wipe_partitions(mk_kdev(MAJOR_NR, i<<4));
+			del_gendisk(myparts[i]->disk);
+			kfree(myparts[i]->disk->name);
+			kfree(myparts[i]->disk);
 			kfree(myparts[i]);
 			myparts[i] = NULL;
 		}
@@ -1312,9 +1310,6 @@
 int init_ftl(void)
 {
     int i;
-
-    memset(myparts, 0, sizeof(myparts));
-    
     DEBUG(0, "$Id: ftl.c,v 1.39 2001/10/02 15:05:11 dwmw2 Exp $\n");
     
     if (register_blkdev(FTL_MAJOR, "ftl", &ftl_blk_fops)) {
@@ -1322,15 +1317,7 @@
 	       "device number!\n");
 	return -EAGAIN;
     }
-    
-    for (i = 0; i < MAX_DEV*MAX_PART; i++) {
-	ftl_hd[i].nr_sects = 0;
-	ftl_hd[i].start_sect = 0;
-    }
-    ftl_gendisk.major = FTL_MAJOR;
     blk_init_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR), &do_ftl_request);
-    add_gendisk(&ftl_gendisk);
-    
     register_mtd_user(&ftl_notifier);
     
     return 0;
@@ -1339,12 +1326,9 @@
 static void __exit cleanup_ftl(void)
 {
     unregister_mtd_user(&ftl_notifier);
-
     unregister_blkdev(FTL_MAJOR, "ftl");
     blk_cleanup_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR));
     blk_clear(FTL_MAJOR);
-
-    del_gendisk(&ftl_gendisk);
 }
 
 module_init(init_ftl);
diff -Nru a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
--- a/drivers/mtd/nftlcore.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/mtd/nftlcore.c	Sat Aug 10 18:42:20 2002
@@ -58,12 +58,6 @@
 struct hd_struct part_table[256];
 
 static struct block_device_operations nftl_fops;
-static struct gendisk nftl_gendisk = {
-	major:		MAJOR_NR,
-	major_name:	"nftl",
-	minor_shift:	NFTL_PARTN_BITS,	/* # of partition bits */
-	part:		part_table,		/* hd struct */
-};
 
 struct NFTLrecord *NFTLs[MAX_NFTLS];
 
@@ -73,6 +67,8 @@
 	struct NFTLrecord *nftl;
 	unsigned long temp;
 	int firstfree = -1;
+	struct gendisk *gd;
+	char *name;
 
 	DEBUG(MTD_DEBUG_LEVEL1,"NFTL_setup\n");
 
@@ -91,7 +87,12 @@
         }
 
 	nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL);
-	if (!nftl) {
+	gd = kmalloc(sizeof(struct gendisk), GFP_KERNEL);
+	name = kmalloc(6, GFP_KERNEL);
+	if (!nftl || !gd || !name) {
+		kfree(nftl);
+		kfree(gd);
+		kfree(name);
 		printk(KERN_WARNING "Out of memory for NFTL data structures\n");
 		return;
 	}
@@ -106,6 +107,8 @@
         if (NFTL_mount(nftl) < 0) {
 		printk(KERN_WARNING "Could not mount NFTL device\n");
 		kfree(nftl);
+		kfree(gd);
+		kfree(name);
 		return;
         }
 
@@ -142,19 +145,18 @@
 		/* Oh no we don't have nftl->nr_sects = nftl->heads * nftl->cylinders * nftl->sectors; */
 	}
 	NFTLs[firstfree] = nftl;
-	/* Finally, set up the block device sizes */
-	part_table[firstfree * 16].nr_sects = nftl->nr_sects;
-
-	nftl_gendisk.nr_real++;
-
-	/* partition check ... */
-#if LINUX_VERSION_CODE < 0x20328
-	resetup_one_dev(&nftl_gendisk, firstfree);
-#else
-	register_disk(&nftl_gendisk,
-		      mk_kdev(MAJOR_NR,firstfree<<NFTL_PARTN_BITS),
+	memset(gd, 0, sizeof(struct gendisk));
+	sprintf(name, "nftl%c", 'a' + firstfree);
+	gd->major = MAJOR_NR;
+	gd->first_minor = firstfree << NFTL_PARTN_BITS;
+	gd->minor_shift = NFTL_PARTN_BITS;
+	gd->part = part_table + (firstfree << NFTL_PARTN_BITS);
+	gd->major_name = name;
+	gd->nr_real = 1;
+	nftl->disk = gd;
+	add_gendisk(gd);
+	register_disk(gd, mk_kdev(MAJOR_NR,firstfree<<NFTL_PARTN_BITS),
 		      1<<NFTL_PARTN_BITS, &nftl_fops, nftl->nr_sects);
-#endif
 }
 
 static void NFTL_unsetup(int i)
@@ -169,8 +171,9 @@
 		kfree(nftl->ReplUnitTable);
 	if (nftl->EUNtable)
 		kfree(nftl->EUNtable);
-		      
-	nftl_gendisk.nr_real--;
+	del_gendisk(nftl->disk);
+	kfree(nftl->disk->major_name);
+	kfree(nftl->disk);
 	kfree(nftl);
 }
 
@@ -796,21 +799,6 @@
 		if (nftl->mtd->sync)
 			nftl->mtd->sync(nftl->mtd);
 		return 0;
-
-	case BLKRRPART:
-		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-		{
-		kdev_t device = mk_kdev(MAJOR_NR,
-			minor(inode->i_rdev) & -(1<<NFTL_PARTN_BITS));
-		res = dev_lock_part(device);
-		if (res < 0)
-			return res;
-		res = wipe_partitions(device);
-		if (!res)
-			grok_partitions(device, nftl->nr_sects);
-		dev_unlock_part(device);
-		}
-		return res;
 	default:
 		return -EINVAL;
 	}
@@ -964,16 +952,6 @@
 
 	return 0;
 }
-#if LINUX_VERSION_CODE < 0x20326
-static struct file_operations nftl_fops = {
-	read:		block_read,
-	write:		block_write,
-	ioctl:		nftl_ioctl,
-	open:		nftl_open,
-	release:	nftl_release,
-	fsync:		block_fsync,
-};
-#else
 static struct block_device_operations nftl_fops = 
 {
 	owner:		THIS_MODULE,
@@ -981,9 +959,6 @@
 	release:	nftl_release,
 	ioctl: 		nftl_ioctl
 };
-#endif
-
-
 
 /****************************************************************************
  *
@@ -1009,10 +984,8 @@
 	if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)){
 		printk("unable to register NFTL block device on major %d\n", MAJOR_NR);
 		return -EBUSY;
-	} else {
-		blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request, &nftl_lock);
-		add_gendisk(&nftl_gendisk);
 	}
+	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request, &nftl_lock);
 	
 	register_mtd_user(&nftl_notifier);
 
@@ -1023,10 +996,7 @@
 {
   	unregister_mtd_user(&nftl_notifier);
   	unregister_blkdev(MAJOR_NR, "nftl");
-  	
   	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-
-	del_gendisk(&nftl_gendisk);
 }
 
 module_init(init_nftl);
diff -Nru a/drivers/net/3c501.c b/drivers/net/3c501.c
--- a/drivers/net/3c501.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/net/3c501.c	Sat Aug 10 18:42:20 2002
@@ -1011,9 +1011,9 @@
 #ifdef MODULE
 
 static struct net_device dev_3c501 = {
-	init:		el1_probe,
-	base_addr:	0x280,
-	irq:		5,
+	.init		= el1_probe,
+	.base_addr	= 0x280,
+	.irq		= 5,
 };
 
 static int io=0x280;
diff -Nru a/drivers/net/3c503.c b/drivers/net/3c503.c
--- a/drivers/net/3c503.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/3c503.c	Sat Aug 10 18:42:23 2002
@@ -512,6 +512,7 @@
 
     if (dev->mem_start) {       /* Use the shared memory. */
 	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+	hdr->count = le16_to_cpu(hdr->count);
 	return;
     }
 
diff -Nru a/drivers/net/3c59x.c b/drivers/net/3c59x.c
--- a/drivers/net/3c59x.c	Sat Aug 10 18:42:19 2002
+++ b/drivers/net/3c59x.c	Sat Aug 10 18:42:19 2002
@@ -418,7 +418,8 @@
 	EEPROM_8BIT=0x10,	/* AKPM: Uses 0x230 as the base bitmaps for EEPROM reads */
 	HAS_PWR_CTRL=0x20, HAS_MII=0x40, HAS_NWAY=0x80, HAS_CB_FNS=0x100,
 	INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400, MAX_COLLISION_RESET=0x800,
-	EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000, WNO_XCVR_PWR=0x4000 };
+	EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000, WNO_XCVR_PWR=0x4000,
+	EXTRA_PREAMBLE=0x8000, };
 
 enum vortex_chips {
 	CH_3C590 = 0,
@@ -504,7 +505,7 @@
 	{"3c905 Boomerang 100baseT4",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, },
 	{"3c905B Cyclone 100baseTx",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
+	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
 
 	{"3c905B Cyclone 10/100/BNC",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
@@ -1281,6 +1282,8 @@
 		int phy, phy_idx = 0;
 		EL3WINDOW(4);
 		mii_preamble_required++;
+		if (vp->drv_flags & EXTRA_PREAMBLE)
+			mii_preamble_required++;
 		mdio_sync(ioaddr, 32);
 		mdio_read(dev, 24, 1);
 		for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
@@ -1297,8 +1300,8 @@
 			else
 				phyx = phy;
 			mii_status = mdio_read(dev, phyx, 1);
-		printk("phy=%d, phyx=%d, mii_status=0x%04x\n",
-			phy, phyx, mii_status);
+			printk("phy=%d, phyx=%d, mii_status=0x%04x\n",
+				phy, phyx, mii_status);
 			if (mii_status  &&  mii_status != 0xffff) {
 				vp->phys[phy_idx++] = phyx;
 				if (print_info) {
@@ -2955,13 +2958,13 @@
 
 
 static struct pci_driver vortex_driver = {
-	name:		"3c59x",
-	probe:		vortex_init_one,
-	remove:		__devexit_p(vortex_remove_one),
-	id_table:	vortex_pci_tbl,
+	.name		= "3c59x",
+	.probe		= vortex_init_one,
+	.remove		= __devexit_p(vortex_remove_one),
+	.id_table	= vortex_pci_tbl,
 #ifdef CONFIG_PM
-	suspend:	vortex_suspend,
-	resume:		vortex_resume,
+	.suspend	= vortex_suspend,
+	.resume		= vortex_resume,
 #endif
 };
 
diff -Nru a/drivers/net/8139cp.c b/drivers/net/8139cp.c
--- a/drivers/net/8139cp.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/8139cp.c	Sat Aug 10 18:42:22 2002
@@ -21,13 +21,13 @@
 	Contributors:
 	
 		Wake-on-LAN support - Felipe Damasio <felipewd@terra.com.br>
+		PCI suspend/resume  - Felipe Damasio <felipewd@terra.com.br>
 			
 	TODO, in rough priority order:
 	* dev->tx_timeout
 	* LinkChg interrupt
 	* Support forcing media type with a module parameter,
 	  like dl2k.c/sundance.c
-	* Implement PCI suspend/resume
 	* Constants (module parms?) for Rx work limit
 	* support 64-bit PCI DMA
 	* Complete reset on PciErr
@@ -360,6 +360,7 @@
 	unsigned int		board_type;
 
 	unsigned int		wol_enabled : 1; /* Is Wake-on-LAN enabled? */
+	u32			power_state[16];
 
 	struct mii_if_info	mii_if;
 };
@@ -976,11 +977,11 @@
 
 static inline void cp_start_hw (struct cp_private *cp)
 {
-	cpw8(Cmd, RxOn | TxOn);
 	if (cp->board_type == RTL8169)
 		cpw16(CpCmd, PCIMulRW | RxChkSum);
 	else
 		cpw16(CpCmd, PCIMulRW | RxChkSum | CpRxOn | CpTxOn);
+	cpw8(Cmd, RxOn | TxOn);
 }
 
 static void cp_init_hw (struct cp_private *cp)
@@ -1896,11 +1897,68 @@
 	kfree(dev);
 }
 
+#ifdef CONFIG_PM
+static int cp_suspend (struct pci_dev *pdev, u32 state)
+{
+	struct net_device *dev;
+	struct cp_private *cp;
+	unsigned long flags;
+
+	dev = pci_get_drvdata (pdev);
+	cp  = dev->priv;
+
+	if (!dev || !netif_running (dev)) return 0;
+
+	netif_device_detach (dev);
+	netif_stop_queue (dev);
+
+	spin_lock_irqsave (&cp->lock, flags);
+
+	/* Disable Rx and Tx */
+	cpw16 (IntrMask, 0);
+	cpw8  (Cmd, cpr8 (Cmd) & (~RxOn | ~TxOn));
+
+	spin_unlock_irqrestore (&cp->lock, flags);
+
+	if (cp->pdev && cp->wol_enabled) {
+		pci_save_state (cp->pdev, cp->power_state);
+		cp_set_d3_state (cp);
+	}
+
+	return 0;
+}
+
+static int cp_resume (struct pci_dev *pdev)
+{
+	struct net_device *dev;
+	struct cp_private *cp;
+
+	dev = pci_get_drvdata (pdev);
+	cp  = dev->priv;
+
+	netif_device_attach (dev);
+	
+	if (cp->pdev && cp->wol_enabled) {
+		pci_set_power_state (cp->pdev, 0);
+		pci_restore_state (cp->pdev, cp->power_state);
+	}
+	
+	cp_init_hw (cp);
+	netif_start_queue (dev);
+	
+	return 0;
+}
+#endif /* CONFIG_PM */
+
 static struct pci_driver cp_driver = {
 	.name         = DRV_NAME,
 	.id_table     = cp_pci_tbl,
 	.probe        =	cp_init_one,
 	.remove       = __devexit_p(cp_remove_one),
+#ifdef CONFIG_PM
+	.resume       = cp_resume,
+	.suspend      = cp_suspend,
+#endif
 };
 
 static int __init cp_init (void)
diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c
--- a/drivers/net/8139too.c	Sat Aug 10 18:42:19 2002
+++ b/drivers/net/8139too.c	Sat Aug 10 18:42:19 2002
@@ -221,6 +221,8 @@
 	FE2000VX,
 	ALLIED8139,
 	RTL8129,
+	FNW3603TX,
+	FNW3800TX,
 } board_t;
 
 
@@ -240,6 +242,8 @@
 	{ "AboCom FE2000VX (RealTek RTL8139)", RTL8139_CAPS },
 	{ "Allied Telesyn 8139 CardBus", RTL8139_CAPS },
 	{ "RealTek RTL8129", RTL8129_CAPS },
+	{ "Planex FNW-3603-TX 10/100 CardBus", RTL8139_CAPS },
+	{ "Planex FNW-3800-TX 10/100 CardBus", RTL8139_CAPS },
 };
 
 
@@ -254,6 +258,8 @@
 	{0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DFE690TXD },
 	{0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FE2000VX },
 	{0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALLIED8139 },
+	{0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FNW3603TX },
+	{0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, FNW3800TX },
 
 #ifdef CONFIG_8139TOO_8129
 	{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 },
@@ -2611,13 +2617,13 @@
 
 
 static struct pci_driver rtl8139_pci_driver = {
-	name:		DRV_NAME,
-	id_table:	rtl8139_pci_tbl,
-	probe:		rtl8139_init_one,
-	remove:		__devexit_p(rtl8139_remove_one),
+	.name		= DRV_NAME,
+	.id_table	= rtl8139_pci_tbl,
+	.probe		= rtl8139_init_one,
+	.remove		= __devexit_p(rtl8139_remove_one),
 #ifdef CONFIG_PM
-	suspend:	rtl8139_suspend,
-	resume:		rtl8139_resume,
+	.suspend	= rtl8139_suspend,
+	.resume		= rtl8139_resume,
 #endif /* CONFIG_PM */
 };
 
diff -Nru a/drivers/net/8390.h b/drivers/net/8390.h
--- a/drivers/net/8390.h	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/8390.h	Sat Aug 10 18:42:23 2002
@@ -111,8 +111,7 @@
  
 #if defined(CONFIG_MAC) ||  \
     defined(CONFIG_ARIADNE2) || defined(CONFIG_ARIADNE2_MODULE) || \
-    defined(CONFIG_HYDRA) || defined(CONFIG_HYDRA_MODULE) || \
-    defined(CONFIG_ARM_ETHERH) || defined(CONFIG_ARM_ETHERH_MODULE)
+    defined(CONFIG_HYDRA) || defined(CONFIG_HYDRA_MODULE)
 #define EI_SHIFT(x)	(ei_local->reg_offset[x])
 #undef inb
 #undef inb_p
@@ -124,6 +123,8 @@
 #define inb_p(port)   in_8(port)
 #define outb_p(val,port)  out_8(port,val)
 
+#elif defined(CONFIG_ARM_ETHERH) || defined(CONFIG_ARM_ETHERH_MODULE)
+#define EI_SHIFT(x)	(ei_local->reg_offset[x])
 #else
 #define EI_SHIFT(x)	(x)
 #endif
diff -Nru a/drivers/net/Space.c b/drivers/net/Space.c
--- a/drivers/net/Space.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/Space.c	Sat Aug 10 18:42:21 2002
@@ -466,10 +466,10 @@
 
 #ifdef CONFIG_ETHERTAP
 static struct net_device tap0_dev = {
-	name:		"tap0",
-	base_addr:	NETLINK_TAPBASE,
-	next:		NEXT_DEV,
-	init:		ethertap_probe,
+	.name		= "tap0",
+	.base_addr	= NETLINK_TAPBASE,
+	.next		= NEXT_DEV,
+	.init		= ethertap_probe,
 };
 #undef NEXT_DEV
 #define NEXT_DEV	(&tap0_dev)
@@ -478,9 +478,9 @@
 #ifdef CONFIG_SDLA
 extern int sdla_init(struct net_device *);
 static struct net_device sdla0_dev = {
-	name:		 "sdla0",
-	next:		 NEXT_DEV,
-	init:		 sdla_init,
+	.name		=  "sdla0",
+	.next		=  NEXT_DEV,
+	.init		=  sdla_init,
 };
 #undef NEXT_DEV
 #define NEXT_DEV	(&sdla0_dev)
@@ -489,9 +489,9 @@
 #if defined(CONFIG_LTPC)
 extern int ltpc_probe(struct net_device *);
 static struct net_device dev_ltpc = {
-	name:		"lt0",
-	next:		NEXT_DEV,
-	init:		ltpc_probe
+	.name		= "lt0",
+	.next		= NEXT_DEV,
+	.init		= ltpc_probe
 };
 #undef NEXT_DEV
 #define NEXT_DEV	(&dev_ltpc)
@@ -500,63 +500,63 @@
 #if defined(CONFIG_COPS)
 extern int cops_probe(struct net_device *);
 static struct net_device cops2_dev = {
-	name:		"lt2",
-	next:		NEXT_DEV,
-	init:		cops_probe,
+	.name		= "lt2",
+	.next		= NEXT_DEV,
+	.init		= cops_probe,
 };
 static struct net_device cops1_dev = {
-	name:		"lt1",
-	next:		&cops2_dev,
-	init:		cops_probe,
+	.name		= "lt1",
+	.next		= &cops2_dev,
+	.init		= cops_probe,
 };
 static struct net_device cops0_dev = {
-	name:		"lt0",
-	next:		&cops1_dev,
-	init:		cops_probe,
+	.name		= "lt0",
+	.next		= &cops1_dev,
+	.init		= cops_probe,
 };
 #undef NEXT_DEV
 #define NEXT_DEV     (&cops0_dev)
 #endif  /* COPS */
 
 static struct net_device eth7_dev = {
-	name:		"eth%d",
-	next:		NEXT_DEV,
-	init:		ethif_probe,
+	.name		= "eth%d",
+	.next		= NEXT_DEV,
+	.init		= ethif_probe,
 };
 static struct net_device eth6_dev = {
-	name:		"eth%d",
-	next:		&eth7_dev,
-	init:		ethif_probe,
+	.name		= "eth%d",
+	.next		= &eth7_dev,
+	.init		= ethif_probe,
 };
 static struct net_device eth5_dev = {
-	name:		"eth%d",
-	next:		&eth6_dev,
-	init:		ethif_probe,
+	.name		= "eth%d",
+	.next		= &eth6_dev,
+	.init		= ethif_probe,
 };
 static struct net_device eth4_dev = {
-	name:		"eth%d",
-	next:		&eth5_dev,
-	init:		ethif_probe,
+	.name		= "eth%d",
+	.next		= &eth5_dev,
+	.init		= ethif_probe,
 };
 static struct net_device eth3_dev = {
-	name:		"eth%d",
-	next:		&eth4_dev,
-	init:		ethif_probe,
+	.name		= "eth%d",
+	.next		= &eth4_dev,
+	.init		= ethif_probe,
 };
 static struct net_device eth2_dev = {
-	name:		"eth%d",
-	next:		&eth3_dev,
-	init:		ethif_probe,
+	.name		= "eth%d",
+	.next		= &eth3_dev,
+	.init		= ethif_probe,
 };
 static struct net_device eth1_dev = {
-	name:		"eth%d",
-	next:		&eth2_dev,
-	init:		ethif_probe,
+	.name		= "eth%d",
+	.next		= &eth2_dev,
+	.init		= ethif_probe,
 };
 static struct net_device eth0_dev = {
-	name:		"eth%d",
-	next:		&eth1_dev,
-	init:		ethif_probe,
+	.name		= "eth%d",
+	.next		= &eth1_dev,
+	.init		= ethif_probe,
 };
 
 #undef NEXT_DEV
@@ -585,44 +585,44 @@
     return 0;
 }
 static struct net_device tr7_dev = {
-	name:		"tr%d",
-	next:		NEXT_DEV,
-	init:		trif_probe,
+	.name		= "tr%d",
+	.next		= NEXT_DEV,
+	.init		= trif_probe,
 };
 static struct net_device tr6_dev = {
-	name:		"tr%d",
-	next:		&tr7_dev,
-	init:		trif_probe,
+	.name		= "tr%d",
+	.next		= &tr7_dev,
+	.init		= trif_probe,
 };
 static struct net_device tr5_dev = {
-	name:		"tr%d",
-	next:		&tr6_dev,
-	init:		trif_probe,
+	.name		= "tr%d",
+	.next		= &tr6_dev,
+	.init		= trif_probe,
 };
 static struct net_device tr4_dev = {
-	name:		"tr%d",
-	next:		&tr5_dev,
-	init:		trif_probe,
+	.name		= "tr%d",
+	.next		= &tr5_dev,
+	.init		= trif_probe,
 };
 static struct net_device tr3_dev = {
-	name:		"tr%d",
-	next:		&tr4_dev,
-	init:		trif_probe,
+	.name		= "tr%d",
+	.next		= &tr4_dev,
+	.init		= trif_probe,
 };
 static struct net_device tr2_dev = {
-	name:		"tr%d",
-	next:		&tr3_dev,
-	init:		trif_probe,
+	.name		= "tr%d",
+	.next		= &tr3_dev,
+	.init		= trif_probe,
 };
 static struct net_device tr1_dev = {
-	name:		"tr%d",
-	next:		&tr2_dev,
-	init:		trif_probe,
+	.name		= "tr%d",
+	.next		= &tr2_dev,
+	.init		= trif_probe,
 };
 static struct net_device tr0_dev = {
-	name:		"tr%d",
-	next:		&tr1_dev,
-	init:		trif_probe,
+	.name		= "tr%d",
+	.next		= &tr1_dev,
+	.init		= trif_probe,
 };
 #undef       NEXT_DEV
 #define      NEXT_DEV        (&tr0_dev)
@@ -631,44 +631,44 @@
 
 #ifdef CONFIG_FDDI
 static struct net_device fddi7_dev = {
-	name:		"fddi7",
-	next:		 NEXT_DEV,
-	init:		fddiif_probe
+	.name		= "fddi7",
+	.next		=  NEXT_DEV,
+	.init		= fddiif_probe
 };
 static struct net_device fddi6_dev = {
-	name:		"fddi6",
-	next:		&fddi7_dev,
-	init:		fddiif_probe
+	.name		= "fddi6",
+	.next		= &fddi7_dev,
+	.init		= fddiif_probe
 };
 static struct net_device fddi5_dev = {
-	name:		"fddi5",
-	next:		&fddi6_dev,
-	init:		fddiif_probe
+	.name		= "fddi5",
+	.next		= &fddi6_dev,
+	.init		= fddiif_probe
 };
 static struct net_device fddi4_dev = {
-	name:		"fddi4",
-	next:		&fddi5_dev,
-	init:		fddiif_probe
+	.name		= "fddi4",
+	.next		= &fddi5_dev,
+	.init		= fddiif_probe
 };
 static struct net_device fddi3_dev = {
-	name:		"fddi3",
-	next:		&fddi4_dev,
-	init:		fddiif_probe
+	.name		= "fddi3",
+	.next		= &fddi4_dev,
+	.init		= fddiif_probe
 };
 static struct net_device fddi2_dev = {
-	name:		"fddi2",
-	next:		&fddi3_dev,
-	init:		fddiif_probe
+	.name		= "fddi2",
+	.next		= &fddi3_dev,
+	.init		= fddiif_probe
 };
 static struct net_device fddi1_dev = {
-	name:		"fddi1",
-	next:		&fddi2_dev,
-	init:		fddiif_probe
+	.name		= "fddi1",
+	.next		= &fddi2_dev,
+	.init		= fddiif_probe
 };
 static struct net_device fddi0_dev = {
-	name:		"fddi0",
-	next:		&fddi1_dev,
-	init:		fddiif_probe
+	.name		= "fddi0",
+	.next		= &fddi1_dev,
+	.init		= fddiif_probe
 };
 #undef	NEXT_DEV
 #define	NEXT_DEV	(&fddi0_dev)
@@ -677,14 +677,14 @@
 
 #ifdef CONFIG_NET_FC
 static struct net_device fc1_dev = {
-	name:		"fc1",
-	next:		NEXT_DEV,
-	init:		fcif_probe
+	.name		= "fc1",
+	.next		= NEXT_DEV,
+	.init		= fcif_probe
 };
 static struct net_device fc0_dev = {
-	name:		"fc0",
-	next:		 &fc1_dev,
-	init:		fcif_probe
+	.name		= "fc0",
+	.next		=  &fc1_dev,
+	.init		= fcif_probe
 };
 #undef       NEXT_DEV
 #define      NEXT_DEV        (&fc0_dev)
@@ -693,44 +693,44 @@
 
 #ifdef CONFIG_SBNI
 static struct net_device sbni7_dev = {
-	name:		"sbni7",
-	next:		NEXT_DEV,
-	init:		sbni_probe,
+	.name		= "sbni7",
+	.next		= NEXT_DEV,
+	.init		= sbni_probe,
 };
 static struct net_device sbni6_dev = {
-	name:		"sbni6",
-	next:		&sbni7_dev,
-	init:		sbni_probe,
+	.name		= "sbni6",
+	.next		= &sbni7_dev,
+	.init		= sbni_probe,
 };
 static struct net_device sbni5_dev = {
-	name:		"sbni5",
-	next:		&sbni6_dev,
-	init:		sbni_probe,
+	.name		= "sbni5",
+	.next		= &sbni6_dev,
+	.init		= sbni_probe,
 };
 static struct net_device sbni4_dev = {
-	name:		"sbni4",
-	next:		&sbni5_dev,
-	init:		sbni_probe,
+	.name		= "sbni4",
+	.next		= &sbni5_dev,
+	.init		= sbni_probe,
 };
 static struct net_device sbni3_dev = {
-	name:		"sbni3",
-	next:		&sbni4_dev,
-	init:		sbni_probe,
+	.name		= "sbni3",
+	.next		= &sbni4_dev,
+	.init		= sbni_probe,
 };
 static struct net_device sbni2_dev = {
-	name:		"sbni2",
-	next:		&sbni3_dev,
-	init:		sbni_probe,
+	.name		= "sbni2",
+	.next		= &sbni3_dev,
+	.init		= sbni_probe,
 };
 static struct net_device sbni1_dev = {
-	name:		"sbni1",
-	next:		&sbni2_dev,
-	init:		sbni_probe,
+	.name		= "sbni1",
+	.next		= &sbni2_dev,
+	.init		= sbni_probe,
 };
 static struct net_device sbni0_dev = {
-	name:		"sbni0",
-	next:		&sbni1_dev,
-	init:		sbni_probe,
+	.name		= "sbni0",
+	.next		= &sbni1_dev,
+	.init		= sbni_probe,
 };
 
 #undef	NEXT_DEV
@@ -744,9 +744,9 @@
 
 extern int loopback_init(struct net_device *dev);
 struct net_device loopback_dev = {
-	name:		"lo",
-	next:		NEXT_DEV,
-	init:		loopback_init
+	.name		= "lo",
+	.next		= NEXT_DEV,
+	.init		= loopback_init
 };
 
 /*
diff -Nru a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
--- a/drivers/net/arcnet/com20020-pci.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/arcnet/com20020-pci.c	Sat Aug 10 18:42:21 2002
@@ -158,10 +158,10 @@
 MODULE_DEVICE_TABLE(pci, com20020pci_id_table);
 
 static struct pci_driver com20020pci_driver = {
-	name:		"com20020",
-	id_table:	com20020pci_id_table,
-	probe:		com20020pci_probe,
-	remove:		__devexit_p(com20020pci_remove),
+	.name		= "com20020",
+	.id_table	= com20020pci_id_table,
+	.probe		= com20020pci_probe,
+	.remove		= __devexit_p(com20020pci_remove),
 };
 
 static int __init com20020pci_init(void)
diff -Nru a/drivers/net/bonding.c b/drivers/net/bonding.c
--- a/drivers/net/bonding.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/bonding.c	Sat Aug 10 18:42:22 2002
@@ -2202,7 +2202,7 @@
 }
 
 static struct notifier_block bond_netdev_notifier = {
-	notifier_call: bond_event,
+	.notifier_call = bond_event,
 };
 
 static int __init bond_init(struct net_device *dev)
diff -Nru a/drivers/net/defxx.c b/drivers/net/defxx.c
--- a/drivers/net/defxx.c	Sat Aug 10 18:42:19 2002
+++ b/drivers/net/defxx.c	Sat Aug 10 18:42:19 2002
@@ -3360,10 +3360,10 @@
 MODULE_DEVICE_TABLE(pci, dfx_pci_tbl);
 
 static struct pci_driver dfx_driver = {
-	name:		"defxx",
-	probe:		dfx_init_one,
-	remove:		__devexit_p(dfx_remove_one),
-	id_table:	dfx_pci_tbl,
+	.name		= "defxx",
+	.probe		= dfx_init_one,
+	.remove		= __devexit_p(dfx_remove_one),
+	.id_table	= dfx_pci_tbl,
 };
 
 static int dfx_have_pci;
diff -Nru a/drivers/net/dl2k.c b/drivers/net/dl2k.c
--- a/drivers/net/dl2k.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/dl2k.c	Sat Aug 10 18:42:22 2002
@@ -1108,7 +1108,6 @@
 	u16 rx_mode = 0;
 	int i;
 	int bit;
-	int index, crc;
 	struct dev_mc_list *mclist;
 	struct netdev_private *np = dev->priv;
 	
@@ -1130,13 +1129,14 @@
 		for (i=0, mclist = dev->mc_list; mclist && i < dev->mc_count; 
 			i++, mclist=mclist->next) {
 
-			crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
+			int index = 0;
+			int crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
 
 			/* The inverted high significant 6 bits of CRC are
 			   used as an index to hashtable */
-			for (index = 0, bit = 0; bit < 6; bit++)
-				if (test_bit(31 - bit, &crc))
-					set_bit(bit, &index);
+			for (bit = 0; bit < 6; bit++)
+				if (crc & (1 << (31 - bit)))
+					index |= (1 << bit);
 
 			hash_table[index / 32] |= (1 << (index % 32));
 		}
@@ -1635,7 +1635,7 @@
 
 	/* Stop Tx and Rx logics */
 	writel (TxDisable | RxDisable | StatsDisable, ioaddr + MACCtrl);
-	synchronize_irq ();
+	synchronize_irq (dev->irq);
 	free_irq (dev->irq, dev);
 	del_timer_sync (&np->timer);
 	
@@ -1688,10 +1688,10 @@
 }
 
 static struct pci_driver rio_driver = {
-	name:		"dl2k",
-	id_table:	rio_pci_tbl,
-	probe:		rio_probe1,
-	remove:		__devexit_p(rio_remove1),
+	.name		= "dl2k",
+	.id_table	= rio_pci_tbl,
+	.probe		= rio_probe1,
+	.remove		= __devexit_p(rio_remove1),
 };
 
 static int __init
diff -Nru a/drivers/net/e100/e100.h b/drivers/net/e100/e100.h
--- a/drivers/net/e100/e100.h	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/e100/e100.h	Sat Aug 10 18:42:22 2002
@@ -91,13 +91,12 @@
 #include <linux/version.h>
 #include <linux/string.h>
 #include <linux/wait.h>
+#include <linux/reboot.h>
 #include <asm/io.h>
 #include <asm/unaligned.h>
 #include <asm/processor.h>
-#ifdef SIOCETHTOOL
 #include <linux/ethtool.h>
 #include <linux/inetdevice.h>
-#endif
 
 #include <linux/if.h>
 #include <asm/uaccess.h>
@@ -147,6 +146,12 @@
 #define E100_MAX_SCB_WAIT	100	/* Max udelays in wait_scb */
 #define E100_MAX_CU_IDLE_WAIT	50	/* Max udelays in wait_cus_idle */
 
+/* HWI feature related constant */
+#define HWI_MAX_LOOP                    100
+#define MAX_SAME_RESULTS		3
+#define HWI_REGISTER_GRANULARITY        80	/* register granularity = 80 Cm */
+#define HWI_NEAR_END_BOUNDARY           1000	/* Near end is defined as < 10 meters */
+
 /* CPUSAVER_BUNDLE_MAX: Sets the maximum number of frames that will be bundled.
  * In some situations, such as the TCP windowing algorithm, it may be
  * better to limit the growth of the bundle size than let it go as
@@ -504,6 +509,7 @@
 #define IS_ICH             0x00000020
 #define DF_SPEED_FORCED    0x00000040	/* set if speed is forced */
 #define LED_IS_ON	   0x00000080	/* LED is turned ON by the driver */
+#define DF_LINK_FC_TX_ONLY 0x00000100	/* Received PAUSE frames are honored*/
 
 typedef struct net_device_stats net_dev_stats_t;
 
@@ -774,15 +780,7 @@
 	u16 total_tcp_payload;
 } tcb_ipcb_t __attribute__ ((__packed__));
 
-#ifdef MAX_SKB_FRAGS
-#define E100_ZEROCOPY
-#endif
-
-#ifdef E100_ZEROCOPY
 #define E100_TBD_ARRAY_SIZE (2+MAX_SKB_FRAGS)
-#else
-#define E100_TBD_ARRAY_SIZE 2
-#endif /*E100_ZEROCOPY */
 
 /* Transmit Command Block (TCB)*/
 struct _tcb_t {
@@ -803,19 +801,15 @@
 	 */
 	tbd_t *tbd_ptr;
 
-#ifdef E100_ZEROCOPY
 	u32 tcb_tbd_dflt_ptr;	/* TBD address for non-segmented packet */
 	u32 tcb_tbd_expand_ptr;	/* TBD address for segmented packet */
-#endif				/*E100_ZEROCOPY */
 
 	struct sk_buff *tcb_skb;	/* the associated socket buffer */
 	dma_addr_t tcb_phys;	/* phys addr of the TCB */
 } __attribute__ ((__packed__));
 
-#ifndef _TCB_T_
 #define _TCB_T_
 typedef struct _tcb_t tcb_t;
-#endif
 
 /* Receive Frame Descriptor (RFD) - will be using the simple model*/
 struct _rfd_t {
@@ -836,10 +830,8 @@
 
 } __attribute__ ((__packed__));
 
-#ifndef _RFD_T_
 #define _RFD_T_
 typedef struct _rfd_t rfd_t;
-#endif
 
 /* Receive Buffer Descriptor (RBD)*/
 typedef struct _rbd_t {
@@ -901,14 +893,12 @@
 	int PollingMaxWork;
 	u32 b_params;
 };
-#ifdef ETHTOOL_TEST 
 struct ethtool_lpbk_data{
         dma_addr_t dma_handle;
         tcb_t *tcb;
         rfd_t *rfd;
 
 };
-#endif
 
 struct e100_private {
 	u32 flags;		/* board management flags */
@@ -987,28 +977,33 @@
 
 	rwlock_t isolate_lock;
 	int driver_isolated;
+	char *id_string;
+	char *cable_status;
+	char *mdix_status;
+
+	/* Variables for HWI */
+	int saved_open_circut;
+	int saved_short_circut;
+	int saved_distance;
+	int saved_i;
+	int saved_same;
+	unsigned char hwi_started;
+	struct timer_list hwi_timer;	/* hwi timer id */
 
 	u32 speed_duplex_caps;	/* adapter's speed/duplex capabilities */
 
 	struct tasklet_struct polling_tasklet;
 
-#ifdef ETHTOOL_GWOL
 	/* WOL params for ethtool */
 	u32 wolsupported;
 	u32 wolopts;
 	u16 ip_lbytes;
-#endif
-#ifdef ETHTOOL_TEST 
 	struct ethtool_lpbk_data loopback;
-#endif
-#ifdef ETHTOOL_PHYS_ID
 	struct timer_list blink_timer;	/* led blink timer id */
-#endif
 
 #ifdef CONFIG_PM
 	u32 pci_state[16];
 #endif
-
 };
 
 #define E100_AUTONEG        0
@@ -1036,8 +1031,6 @@
 extern unsigned char e100_hw_reset_recover(struct e100_private *bdp,
 					   u32 reset_cmd);
 
-#ifdef ETHTOOL_TEST
-
 #define ROM_TEST_FAIL		0x01
 #define REGISTER_TEST_FAIL	0x02
 #define SELF_TEST_FAIL		0x04
@@ -1053,6 +1046,5 @@
 	E100_LPBK_PHY_FAIL,
 	E100_MAX_TEST_RES
 };
-#endif
 
 #endif
diff -Nru a/drivers/net/e100/e100_config.c b/drivers/net/e100/e100_config.c
--- a/drivers/net/e100/e100_config.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/e100/e100_config.c	Sat Aug 10 18:42:22 2002
@@ -86,10 +86,6 @@
 *               operating system.                                     *
 *                                                                     *
 **********************************************************************/
-#ifdef SIOCETHTOOL
-#include <linux/ethtool.h>
-#endif
-
 #include "e100_config.h"
 
 static void e100_config_long_rx(struct e100_private *bdp, unsigned char enable);
@@ -308,85 +304,58 @@
 
 /**
  * e100_config_fc - config flow-control state
- * @bdp: atapter's private data struct
+ * @bdp: adapter's private data struct
  *
  * This routine will enable or disable flow control support in the adapter's
  * config block. Flow control will be enable only if requested using the command
  * line option, and if the link is flow-contorl capable (both us and the link
- * partner).
- *
- * Returns:
- *      true: if then option was indeed changed
- *      false: if no change was needed
+ * partner). But, if link partner is capable of autoneg, but not capable of
+ * flow control, received PAUSE	frames are still honored.
  */
-unsigned char
+void
 e100_config_fc(struct e100_private *bdp)
 {
 	unsigned char enable = false;
-	unsigned char changed = false;
-
 	/* 82557 doesn't support fc. Don't touch this option */
 	if (!(bdp->flags & IS_BACHELOR))
-		return false;
+		return;
 
 	/* Enable fc if requested and if the link supports it */
-	if ((bdp->params.b_params & PRM_FC) && (bdp->flags & DF_LINK_FC_CAP)) {
+	if ((bdp->params.b_params & PRM_FC) && (bdp->flags & 
+		(DF_LINK_FC_CAP | DF_LINK_FC_TX_ONLY))) {
 		enable = true;
 	}
 
 	spin_lock_bh(&(bdp->config_lock));
 
 	if (enable) {
-
-		if (bdp->config[16] != DFLT_FC_DELAY_LSB) {
+		if (bdp->flags & DF_LINK_FC_TX_ONLY) {
+			/* If link partner is capable of autoneg, but  */
+			/* not capable of flow control, Received PAUSE */
+			/* frames are still honored, i.e.,             */
+			/* transmitted frames would be paused by       */
+			/* incoming PAUSE frames                       */
+			bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
+			bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
+			bdp->config[19] &= ~(CB_CFIG_FC_RESTOP | CB_CFIG_FC_RESTART);
+			bdp->config[19] |= CB_CFIG_FC_REJECT;
+			bdp->config[19] &= ~CB_CFIG_TX_FC_DIS;
+		} else {
 			bdp->config[16] = DFLT_FC_DELAY_LSB;
-			E100_CONFIG(bdp, 16);
-			changed = true;
-		}
-
-		if (bdp->config[17] != DFLT_FC_DELAY_LSB) {
 			bdp->config[17] = DFLT_FC_DELAY_MSB;
-			E100_CONFIG(bdp, 17);
-			changed = true;
-		}
-
-		/* check if *all* fc config options were already set */
-		if (((bdp->config[19] & CB_CFIG_FC_OPTS) != CB_CFIG_FC_OPTS) ||
-		    (bdp->config[19] & CB_CFIG_TX_FC_DIS)) {
-
 			bdp->config[19] |= CB_CFIG_FC_OPTS;
 			bdp->config[19] &= ~CB_CFIG_TX_FC_DIS;
-			E100_CONFIG(bdp, 19);
-			changed = true;
 		}
-
 	} else {
-		if (bdp->config[16] != DFLT_NO_FC_DELAY_LSB) {
-			bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
-			E100_CONFIG(bdp, 16);
-			changed = true;
-		}
-
-		if (bdp->config[17] != DFLT_NO_FC_DELAY_MSB) {
-			bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
-			E100_CONFIG(bdp, 17);
-			changed = true;
-		}
-
-		/* check if *any* fc config options was already set */
-		if ((bdp->config[19] & CB_CFIG_FC_OPTS) ||
-		    !(bdp->config[19] & CB_CFIG_TX_FC_DIS)) {
-
-			bdp->config[19] &= ~CB_CFIG_FC_OPTS;
-			bdp->config[19] |= CB_CFIG_TX_FC_DIS;
-			E100_CONFIG(bdp, 19);
-			changed = true;
-		}
+		bdp->config[16] = DFLT_NO_FC_DELAY_LSB;
+		bdp->config[17] = DFLT_NO_FC_DELAY_MSB;
+		bdp->config[19] &= ~CB_CFIG_FC_OPTS;
+		bdp->config[19] |= CB_CFIG_TX_FC_DIS;
 	}
-
+	E100_CONFIG(bdp, 19);
 	spin_unlock_bh(&(bdp->config_lock));
 
-	return changed;
+	return;
 }
 
 /**
@@ -566,7 +535,6 @@
 	}
 }
 
-#ifdef ETHTOOL_GWOL
 /**
  * e100_config_wol
  * @bdp: atapter's private data struct
@@ -591,7 +559,6 @@
 
 	spin_unlock_bh(&(bdp->config_lock));
 }
-#endif
 
 /**
  * e100_config_loopback_mode
@@ -618,7 +585,7 @@
 		config_byte = CB_CFIG_LOOPBACK_EXTERNAL;
 		break;
 	default:
-		printk(KERN_NOTICE "e100_config_loopback_mode: "
+		printk(KERN_NOTICE "e100: e100_config_loopback_mode: "
 		       "Invalid argument 'mode': %d\n", mode);
 		goto exit;
 	}
diff -Nru a/drivers/net/e100/e100_config.h b/drivers/net/e100/e100_config.h
--- a/drivers/net/e100/e100_config.h	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/e100/e100_config.h	Sat Aug 10 18:42:21 2002
@@ -198,7 +198,7 @@
 extern void e100_config_init(struct e100_private *bdp);
 extern unsigned char e100_force_config(struct e100_private *bdp);
 extern unsigned char e100_config(struct e100_private *bdp);
-extern unsigned char e100_config_fc(struct e100_private *bdp);
+extern void e100_config_fc(struct e100_private *bdp);
 extern void e100_config_promisc(struct e100_private *bdp, unsigned char enable);
 extern void e100_config_brdcast_dsbl(struct e100_private *bdp);
 extern void e100_config_mulcast_enbl(struct e100_private *bdp,
diff -Nru a/drivers/net/e100/e100_eeprom.c b/drivers/net/e100/e100_eeprom.c
--- a/drivers/net/e100/e100_eeprom.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/e100/e100_eeprom.c	Sat Aug 10 18:42:22 2002
@@ -145,8 +145,6 @@
 		data |= SCB_GCR2_EEPROM_ACCESS_SEMAPHORE;
 		writeb(data, &CSR_GENERAL_CONTROL2_FIELD(adapter));
 
-		barrier();
-
 		// Check to see if this bit set or not.
 		data = readb(&CSR_GENERAL_CONTROL2_FIELD(adapter));
 
@@ -224,6 +222,7 @@
 		x &= ~EEDI;	// address consists of all zeros
 
 		writew(x, &CSR_EEPROM_CONTROL_FIELD(adapter));
+		readw(&(adapter->scb->scb_status));
 		udelay(EEPROM_STALL_TIME);
 		raise_clock(adapter, &x);
 		lower_clock(adapter, &x);
diff -Nru a/drivers/net/e100/e100_main.c b/drivers/net/e100/e100_main.c
--- a/drivers/net/e100/e100_main.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/e100/e100_main.c	Sat Aug 10 18:42:22 2002
@@ -93,8 +93,30 @@
 *                                                                     *
 **********************************************************************/
 
-#undef __NO_VERSION__
-
+/* Change Log
+ *
+ * 2.1.6        7/5/02
+ *   o Added device ID support for Dell LOM.
+ *   o Added device ID support for 82511QM mobile nics.
+ *   o Bug fix: ethtool get/set EEPROM routines modified to use byte
+ *     addressing rather than word addressing.
+ *   o Feature: added MDIX mode support for 82550 and up.
+ *   o Bug fix: added reboot notifer to setup WOL settings when
+ *     shutting system down.
+ *   o Cleanup: removed yield() redefinition (Andrew Morton, 
+ *     akpm@zip.com.au).
+ *   o Bug fix: flow control now working when link partner is 
+ *     autoneg capable but not flow control capable.
+ *   o Bug fix: added check for corrupted EEPROM
+ *   o Bug fix: don't report checksum offloading for the older
+ *     controllers that don't support the feature.
+ *   o Bug fix: calculate cable diagnostics when link goes down
+ *     rather than when queuering /proc file.
+ *   o Cleanup: move mdi_access_lock to local get/set mdi routines.
+ *
+ * 2.0.30       5/30/02
+ */
+ 
 #include <linux/config.h>
 #include <net/checksum.h>
 #include <linux/tcp.h>
@@ -105,11 +127,7 @@
 #include "e100_phy.h"
 #include "e100_vendor.h"
 
-#ifndef CONFIG_PROC_FS
-#undef E100_CONFIG_PROC_FS
-#endif
-
-#ifdef E100_CONFIG_PROC_FS
+#ifdef CONFIG_PROC_FS
 extern int e100_create_proc_subdir(struct e100_private *);
 extern void e100_remove_proc_subdir(struct e100_private *);
 #else
@@ -117,41 +135,24 @@
 #define e100_remove_proc_subdir(X) do {} while(0)
 #endif
 
-#ifdef SIOCETHTOOL
-#define E100_ETHTOOL_IOCTL
-#endif
-#ifdef E100_ETHTOOL_IOCTL
 static int e100_do_ethtool_ioctl(struct net_device *, struct ifreq *);
 static void e100_get_speed_duplex_caps(struct e100_private *);
 static int e100_ethtool_get_settings(struct net_device *, struct ifreq *);
 static int e100_ethtool_set_settings(struct net_device *, struct ifreq *);
 
-#ifdef ETHTOOL_GDRVINFO
 static int e100_ethtool_get_drvinfo(struct net_device *, struct ifreq *);
-#endif
-#ifdef ETHTOOL_GEEPROM
 static int e100_ethtool_eeprom(struct net_device *, struct ifreq *);
 
 #define E100_EEPROM_MAGIC 0x1234
-#endif
-#ifdef ETHTOOL_GLINK
 static int e100_ethtool_glink(struct net_device *, struct ifreq *);
-#endif
-#ifdef ETHTOOL_NWAY_RST
 static int e100_ethtool_nway_rst(struct net_device *, struct ifreq *);
-#endif
-#ifdef ETHTOOL_GWOL
 static int e100_ethtool_wol(struct net_device *, struct ifreq *);
 static unsigned char e100_setup_filter(struct e100_private *bdp);
 static void e100_do_wol(struct pci_dev *pcid, struct e100_private *bdp);
 static u16 e100_get_ip_lbytes(struct net_device *dev);
 extern void e100_config_wol(struct e100_private *bdp);
-#endif
-#ifdef ETHTOOL_TEST
 extern u32 e100_run_diag(struct net_device *dev, u64 *test_info, u32 flags);
 static int e100_ethtool_test(struct net_device *, struct ifreq *);
-#endif
-#ifdef ETHTOOL_GSTRINGS
 static int e100_ethtool_gstrings(struct net_device *, struct ifreq *);
 static char *test_strings[] = {
 	"E100_EEPROM_TEST_FAIL",
@@ -163,19 +164,10 @@
 	"E100_LPBK_PHY_FAIL"
 };
 
-#endif
-#ifdef	ETHTOOL_PHYS_ID
 static int e100_ethtool_led_blink(struct net_device *, struct ifreq *);
-#endif
-#endif /*E100_ETHTOOL_IOCTL */
 
-#ifdef SIOCGMIIPHY
-#define E100_MII_IOCTL
-#endif
-#ifdef E100_MII_IOCTL
 #include <linux/mii.h>
 static int e100_mii_ioctl(struct net_device *, struct ifreq *, int);
-#endif /*E100_MII_IOCTL */
 
 static unsigned char e100_delayed_exec_non_cu_cmd(struct e100_private *,
 						  nxmit_cb_entry_t *);
@@ -184,23 +176,24 @@
 
 /* Global Data structures and variables */
 char e100_copyright[] __devinitdata = "Copyright (c) 2002 Intel Corporation";
-
-#define E100_VERSION  "2.0.30-k1"
-
-#define E100_FULL_DRIVER_NAME 	"Intel(R) PRO/100 Fast Ethernet Adapter - Loadable driver, ver "
-
-const char *e100_version = E100_VERSION;
-const char *e100_full_driver_name = E100_FULL_DRIVER_NAME E100_VERSION;
-char *e100_short_driver_name = "e100";
+char e100_driver_version[]="2.1.6-k1";
+const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver";
+char e100_short_driver_name[] = "e100";
 static int e100nics = 0;
 
 #ifdef CONFIG_PM
-static int e100_save_state(struct pci_dev *pcid, u32 state);
+static int e100_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
 static int e100_suspend(struct pci_dev *pcid, u32 state);
-static int e100_enable_wake(struct pci_dev *pcid, u32 state, int enable);
 static int e100_resume(struct pci_dev *pcid);
+struct notifier_block e100_notifier = {
+        notifier_call:  e100_notify_reboot,
+        next:           NULL,
+        priority:       0
+};
 #endif
 
+static void e100_get_mdix_status(struct e100_private *bdp);
+
 /*********************************************************************/
 /*! This is a GCC extension to ANSI C.
  *  See the item "Labeled Elements in Initializers" in the section
@@ -250,6 +243,7 @@
 extern u16 e100_eeprom_read(struct e100_private *, u16);
 extern void e100_eeprom_write_block(struct e100_private *, u16, u16 *, u16);
 extern u16 e100_eeprom_size(struct e100_private *);
+u16 e100_eeprom_calculate_chksum(struct e100_private *adapter);
 
 static unsigned char e100_clr_cntrs(struct e100_private *);
 static unsigned char e100_load_microcode(struct e100_private *);
@@ -391,6 +385,8 @@
 void e100_polling_tasklet(unsigned long);
 
 void e100_watchdog(struct net_device *);
+static void e100_do_hwi(struct net_device *);
+static void e100_hwi_restore(struct e100_private *);
 void e100_refresh_txthld(struct e100_private *);
 void e100_manage_adaptive_ifs(struct e100_private *);
 void e100_clear_pools(struct e100_private *);
@@ -400,7 +396,7 @@
 static void e100_set_multi_exec(struct net_device *dev);
 
 MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
-MODULE_DESCRIPTION(E100_FULL_DRIVER_NAME E100_VERSION);
+MODULE_DESCRIPTION("Intel(R) PRO/100 Network Driver");
 MODULE_LICENSE("Dual BSD/GPL");
 
 E100_PARAM(TxDescriptors, "Number of transmit descriptors");
@@ -429,7 +425,7 @@
 e100_exec_cmd(struct e100_private *bdp, u8 cmd_low)
 {
 	writeb(cmd_low, &(bdp->scb->scb_cmd_low));
-	readw(&(bdp->scb->scb_status));	/* flashes last write, read-safe */
+	readw(&(bdp->scb->scb_status));	/* flushes last write, read-safe */
 }
 
 /**
@@ -484,7 +480,7 @@
 e100_wait_exec_simple(struct e100_private *bdp, u8 scb_cmd_low)
 {
 	if (!e100_wait_scb(bdp)) {
-		printk(KERN_DEBUG "%s e100_wait_exec_simple: Wait failed\n",
+		printk(KERN_DEBUG "e100: %s: e100_wait_exec_simple: failed\n",
 		       bdp->device->name);
 		return false;
 	}
@@ -496,7 +492,7 @@
 e100_exec_cmplx(struct e100_private *bdp, u32 phys_addr, u8 cmd)
 {
 	writel(phys_addr, &(bdp->scb->scb_gen_ptr));
-	readw(&(bdp->scb->scb_status));	/* flashes last write, read-safe */
+	readw(&(bdp->scb->scb_status));	/* flushes last write, read-safe */
 	e100_exec_cmd(bdp, cmd);
 }
 
@@ -580,10 +576,11 @@
 	struct net_device *dev = NULL;
 	struct e100_private *bdp = NULL;
 	int rc = 0;
+	u16 cal_checksum, read_checksum;
 
 	dev = alloc_etherdev(sizeof (struct e100_private));
 	if (dev == NULL) {
-		printk(KERN_ERR "Not able to alloc etherdev struct\n");
+		printk(KERN_ERR "e100: Not able to alloc etherdev struct\n");
 		rc = -ENODEV;
 		goto out;
 	}
@@ -592,7 +589,8 @@
 
 	if (first_time) {
 		first_time = false;
-		printk(KERN_NOTICE "%s\n", e100_full_driver_name);
+        	printk(KERN_NOTICE "%s - version %s\n",
+	               e100_full_driver_name, e100_driver_version);
 		printk(KERN_NOTICE "%s\n", e100_copyright);
 		printk(KERN_NOTICE "\n");
 	}
@@ -622,6 +620,10 @@
 	bdp->watchdog_timer.data = (unsigned long) dev;
 	bdp->watchdog_timer.function = (void *) &e100_watchdog;
 
+	init_timer(&bdp->hwi_timer);
+	bdp->hwi_timer.data = (unsigned long) dev;
+	bdp->hwi_timer.function = (void *) &e100_do_hwi;
+
 	if ((rc = e100_pci_setup(pcid, bdp)) != 0) {
 		goto err_dealloc;
 	}
@@ -647,16 +649,25 @@
 	} else {
 		bdp->rfd_size = 16;
 	}
-
 	e100_check_options(e100nics, bdp);
 
 	if (!e100_init(bdp)) {
-		printk(KERN_ERR "Failed to initialize e100, instance #%d\n",
+		printk(KERN_ERR "e100: Failed to initialize, instance #%d\n",
 		       e100nics);
 		rc = -ENODEV;
 		goto err_pci;
 	}
 
+	/* Check if checksum is valid */
+	cal_checksum = e100_eeprom_calculate_chksum(bdp);
+	read_checksum = e100_eeprom_read(bdp, (bdp->eeprom_size - 1));
+	if (cal_checksum != read_checksum) {
+                printk(KERN_ERR "e100: Corrupted EERPROM on instance #%d\n",
+		       e100nics);
+                rc = -ENODEV;
+                goto err_pci;
+	}
+	
 	dev->irq = pcid->irq;
 	dev->open = &e100_open;
 	dev->hard_start_xmit = &e100_xmit_frame;
@@ -666,16 +677,12 @@
 	dev->set_multicast_list = &e100_set_multi;
 	dev->set_mac_address = &e100_set_mac;
 	dev->do_ioctl = &e100_ioctl;
-#ifdef E100_ZEROCOPY
 	if (bdp->flags & USE_IPCB) {
 		dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
 	}
-#endif
 	e100nics++;
 
-#ifdef E100_ETHTOOL_IOCTL
 	e100_get_speed_duplex_caps(bdp);
-#endif /*E100_ETHTOOL_IOCTL */
 
 	if ((rc = register_netdev(dev)) != 0) {
 		goto err_pci;
@@ -683,15 +690,26 @@
 
 	bdp->device_type = ent->driver_data;
 	printk(KERN_NOTICE
-	       "%s: %s\n", bdp->device->name, e100_get_brand_msg(bdp));
+	       "e100: %s: %s\n", 
+	       bdp->device->name, e100_get_brand_msg(bdp));
 	e100_print_brd_conf(bdp);
+	bdp->id_string = e100_get_brand_msg(bdp);
+	e100_get_mdix_status(bdp);
+
+	if (netif_carrier_ok(bdp->device)) 
+		bdp->cable_status = "Cable OK";
+	else {
+		if (bdp->rev_id < D102_REV_ID) 
+			bdp->cable_status = "Not supported";
+		else
+			bdp->cable_status = "Not available";
+	}
 
 	if (e100_create_proc_subdir(bdp) < 0) {
-		printk(KERN_ERR "Failed to create proc directory for %s\n",
+		printk(KERN_ERR "e100: Failed to create proc dir for %s\n",
 		       bdp->device->name);
 	}
 
-#ifdef ETHTOOL_GWOL
 	/* Disabling all WOLs as initialization */
 	bdp->wolsupported = bdp->wolopts = 0;
 	if (bdp->rev_id >= D101A4_REV_ID) {
@@ -700,7 +718,6 @@
 			bdp->wolsupported |= WAKE_UCAST | WAKE_ARP;
 		bdp->wolopts = WAKE_MAGIC;
 	}
-#endif
 
 	printk(KERN_NOTICE "\n");
 
@@ -762,7 +779,6 @@
 		bdp->non_tx_command_state = E100_NON_TX_IDLE;
 	}
 
-#ifdef ETHTOOL_GWOL
 	/* Set up wol options and enable PME if wol is enabled */
 	if (bdp->wolopts) {
 		e100_do_wol(pcid, bdp);
@@ -772,7 +788,6 @@
 		/* If system powers down, device is switched from D1 to D3 */
 		pci_set_power_state(pcid, 1);
 	}
-#endif
 
 	e100_clear_structs(dev);
 
@@ -782,31 +797,37 @@
 MODULE_DEVICE_TABLE(pci, e100_id_table);
 
 static struct pci_driver e100_driver = {
-	name:           "e100",
-	id_table:       e100_id_table,
-	probe:          e100_found1,
-	remove:         __devexit_p(e100_remove1),
+	.name         = "e100",
+	.id_table     = e100_id_table,
+	.probe        = e100_found1,
+	.remove       = __devexit_p(e100_remove1),
 #ifdef CONFIG_PM
-	suspend:        e100_suspend,
-	resume:         e100_resume,
-	save_state:     e100_save_state,
-	enable_wake:    e100_enable_wake,
-#else
-	suspend:        NULL,
-	resume:         NULL,
+	.suspend      = e100_suspend,
+	.resume       = e100_resume,
 #endif
 };
 
 static int __init
 e100_init_module(void)
 {
-	return pci_module_init(&e100_driver);
+	int ret;
+        ret = pci_module_init(&e100_driver);
+
+#ifdef CONFIG_PM	
+	if(ret >= 0)
+		register_reboot_notifier(&e100_notifier);
+#endif	
 
+	return ret;
 }
 
 static void __exit
 e100_cleanup_module(void)
 {
+#ifdef CONFIG_PM	
+	unregister_reboot_notifier(&e100_notifier);
+#endif	
+
 	pci_unregister_driver(&e100_driver);
 }
 
@@ -824,9 +845,10 @@
 e100_check_options(int board, struct e100_private *bdp)
 {
 	if (board >= E100_MAX_NIC) {
-		printk(KERN_NOTICE "No configuration available for board #%d\n",
+		printk(KERN_NOTICE 
+		       "e100: No configuration available for board #%d\n",
 		       board);
-		printk(KERN_NOTICE "Using defaults for all values\n");
+		printk(KERN_NOTICE "e100: Using defaults for all values\n");
 		board = E100_MAX_NIC;
 	}
 
@@ -907,13 +929,14 @@
 
 	} else if ((val < min) || (val > max)) {
 		printk(KERN_NOTICE
-		       "Invalid %s specified (%i). Valid range is %i-%i\n",
+		       "e100: Invalid %s specified (%i). "
+		       "Valid range is %i-%i\n",
 		       name, val, min, max);
-		printk(KERN_NOTICE "Using default %s of %i\n", name,
+		printk(KERN_NOTICE "e100: Using default %s of %i\n", name,
 		       default_val);
 		*option = default_val;
 	} else {
-		printk(KERN_INFO "Using specified %s of %i\n", name, val);
+		printk(KERN_INFO "e100: Using specified %s of %i\n", name, val);
 		*option = val;
 	}
 }
@@ -941,15 +964,16 @@
 
 	} else if ((val != true) && (val != false)) {
 		printk(KERN_NOTICE
-		       "Invalid %s specified (%i). Valid values are %i/%i\n",
+		       "e100: Invalid %s specified (%i). "
+		       "Valid values are %i/%i\n",
 		       name, val, false, true);
-		printk(KERN_NOTICE "Using default %s of %i\n", name,
+		printk(KERN_NOTICE "e100: Using default %s of %i\n", name,
 		       default_val);
 
 		if (default_val)
 			bdp->params.b_params |= mask;
 	} else {
-		printk(KERN_INFO "Using specified %s of %i\n", name, val);
+		printk(KERN_INFO "e100: Using specified %s of %i\n", name, val);
 		if (val)
 			bdp->params.b_params |= mask;
 	}
@@ -1035,9 +1059,7 @@
 	bdp->intr_mask = SCB_INT_MASK;
 	e100_isolate_driver(bdp);
 
-#ifdef ETHTOOL_GWOL
 	bdp->ip_lbytes = e100_get_ip_lbytes(dev);
-#endif
 	free_irq(dev->irq, dev);
 	e100_clear_pools(bdp);
 
@@ -1198,7 +1220,8 @@
 	}
 
 	if (!e100_exec_non_cu_cmd(bdp, cmd)) {
-		printk(KERN_WARNING "%s: Multicast setup failed\n", dev->name);
+		printk(KERN_WARNING "e100: %s: Multicast setup failed\n", 
+		       dev->name);
 	}
 }
 
@@ -1247,19 +1270,15 @@
 
 	switch (cmd) {
 
-#ifdef E100_ETHTOOL_IOCTL
 	case SIOCETHTOOL:
 		return e100_do_ethtool_ioctl(dev, ifr);
 		break;
-#endif /*E100_ETHTOOL_IOCTL */
 
-#ifdef E100_MII_IOCTL
 	case SIOCGMIIPHY:	/* Get address of MII PHY in use. */
 	case SIOCGMIIREG:	/* Read MII PHY register. */
 	case SIOCSMIIREG:	/* Write to MII PHY register. */
 		return e100_mii_ioctl(dev, ifr, cmd);
 		break;
-#endif /*E100_MII_IOCTL */
 
 	default:
 		return -EOPNOTSUPP;
@@ -1286,7 +1305,7 @@
 	e100_sw_init(bdp);
 
 	if (!e100_selftest(bdp, NULL, NULL)) {
-		printk(KERN_ERR "selftest failed\n");
+		printk(KERN_ERR "e100: selftest failed\n");
 		return false;
 	}
 
@@ -1296,7 +1315,7 @@
 	e100_rd_pwa_no(bdp);
 
 	if (!e100_hw_init(bdp, PORT_SOFTWARE_RESET)) {
-		printk(KERN_ERR "hw init failed\n");
+		printk(KERN_ERR "e100: hw init failed\n");
 		return false;
 	}
 	e100_dis_intr(bdp);
@@ -1462,7 +1481,6 @@
 				cpu_to_le32(pcurr_tcb->tcb_phys + 0x10);
 		}
 
-#ifdef E100_ZEROCOPY
 		if (bdp->flags & IS_BACHELOR) {
 			pcurr_tcb->tcb_tbd_expand_ptr =
 				cpu_to_le32(pcurr_tcb->tcb_phys + 0x20);
@@ -1471,7 +1489,6 @@
 				cpu_to_le32(pcurr_tcb->tcb_phys + 0x10);
 		}
 		pcurr_tcb->tcb_tbd_dflt_ptr = pcurr_tcb->tcb_tbd_ptr;
-#endif
 
 		if (bdp->flags & USE_IPCB) {
 			pcurr_tcb->tbd_ptr = &(pcurr_tcb->tcbu.tbd_array[1]);
@@ -1532,7 +1549,7 @@
 
 err:
 	printk(KERN_ERR
-	       "%s - Failed to allocate memory\n", e100_short_driver_name);
+	       "e100: Failed to allocate memory\n");
 	return -ENOMEM;
 }
 
@@ -1665,7 +1682,7 @@
 	if (!netif_running(dev)) {
 		goto exit;
 	}
-	spin_lock_bh(&(bdp->mdi_access_lock));
+	e100_get_mdix_status(bdp);
 
 	/* check if link state has changed */
 	if (e100_phy_check(bdp)) {
@@ -1677,11 +1694,38 @@
 			       "Half" : "Full");
 
 			e100_config_fc(bdp);
-			e100_config(bdp);	
+			e100_config(bdp);  
+			bdp->cable_status = "Cable OK";
 
 		} else {
 			printk(KERN_ERR "e100: %s NIC Link is Down\n",
 			       bdp->device->name);
+                	if (bdp->rev_id < D102_REV_ID)
+				bdp->cable_status = "Not supported";
+		        else {				
+				/* Initiate hwi, ie, cable diagnostic */
+				bdp->saved_open_circut = 0xffff;
+				bdp->saved_short_circut = 0xffff;
+				bdp->saved_distance = 0xffff;
+				bdp->saved_i = 0;
+				bdp->saved_same = 0;
+				bdp->hwi_started = 1;
+				
+				/* Disable MDI/MDI-X auto switching */
+                		e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
+		                	MDI_MDIX_RESET_ALL_MASK);
+
+				/* Set to 100 Full as required by hwi test */
+				e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr,
+				       BMCR_SPEED100 | BMCR_FULLDPLX);
+
+				/* Enable and execute HWI test */
+				e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,
+					(HWI_TEST_ENABLE | HWI_TEST_EXECUTE));
+
+				/* Launch hwi timer in 1 msec */
+				mod_timer(&(bdp->hwi_timer), jiffies + (HZ / 1000) );
+			}
 		}
 	}
 
@@ -1722,8 +1766,6 @@
 
 	wmb();
 
-	spin_unlock_bh(&(bdp->mdi_access_lock));
-
 	/* relaunch watchdog timer in 2 sec */
 	mod_timer(&(bdp->watchdog_timer), jiffies + (2 * HZ));
 
@@ -1869,6 +1911,7 @@
 	e100_dis_intr(bdp);
 
 	writew(intr_status, &bdp->scb->scb_status);	/* ack intrs */
+	readw(&bdp->scb->scb_status);
 
 	/* the device is closed, don't continue or else bad things may happen. */
 	if (!netif_running(dev)) {
@@ -1923,7 +1966,6 @@
 e100_tx_skb_free(struct e100_private *bdp, tcb_t *tcb)
 {
 	if (tcb->tcb_skb) {
-#ifdef E100_ZEROCOPY
 		int i;
 		tbd_t *tbd_arr = tcb->tbd_ptr;
 		int frags = skb_shinfo(tcb->tcb_skb)->nr_frags;
@@ -1934,11 +1976,6 @@
 					 le16_to_cpu(tbd_arr->tbd_buf_cnt),
 					 PCI_DMA_TODEVICE);
 		}
-#else
-		pci_unmap_single(bdp->pdev,
-				 le32_to_cpu((tcb->tbd_ptr)->tbd_buf_addr),
-				 tcb->tcb_skb->len, PCI_DMA_TODEVICE);
-#endif
 		dev_kfree_skb_irq(tcb->tcb_skb);
 		tcb->tcb_skb = NULL;
 	}
@@ -2181,7 +2218,6 @@
 	}			/* end underrun check */
 }
 
-#ifdef E100_ZEROCOPY
 /**
  * e100_pseudo_hdr_csum - compute IP pseudo-header checksum
  * @ip: points to the header of the IP packet
@@ -2207,7 +2243,6 @@
 
 	return FOLD_CSUM(pseudo);
 }
-#endif /* E100_ZEROCOPY */
 
 /**
  * e100_prepare_xmit_buff - prepare a buffer for transmission
@@ -2247,7 +2282,6 @@
 
 	tcb->tcb_skb = skb;
 
-#ifdef E100_ZEROCOPY
 	if (skb->ip_summed == CHECKSUM_HW) {
 		const struct iphdr *ip = skb->nh.iph;
 
@@ -2312,12 +2346,6 @@
 		tcb->tcb_tbd_num = skb_shinfo(skb)->nr_frags + 1;
 		tcb->tcb_tbd_ptr = tcb->tcb_tbd_expand_ptr;
 	}
-#else
-	(tcb->tbd_ptr)->tbd_buf_addr =
-		cpu_to_le32(pci_map_single(bdp->pdev, skb->data,
-					   skb->len, PCI_DMA_TODEVICE));
-	(tcb->tbd_ptr)->tbd_buf_cnt = cpu_to_le16(skb->len);
-#endif
 
 	/* clear the S-BIT on the previous tcb */
 	prev_tcb = bdp->tcb_pool.data;
@@ -2377,12 +2405,12 @@
 		// The last command was a non_tx CU command
 		if (!e100_wait_cus_idle(bdp))
 			printk(KERN_DEBUG
-			       "%s cu_start: timeout waiting for cu\n",
+			       "e100: %s: cu_start: timeout waiting for cu\n",
 			       bdp->device->name);
 		if (!e100_wait_exec_cmplx(bdp, (u32) (tcb->tcb_phys),
 					  SCB_CUC_START)) {
 			printk(KERN_DEBUG
-			       "%s cu_start: timeout waiting for scb\n",
+			       "e100: %s: cu_start: timeout waiting for scb\n",
 			       bdp->device->name);
 			e100_exec_cmplx(bdp, (u32) (tcb->tcb_phys),
 					SCB_CUC_START);
@@ -2498,7 +2526,8 @@
 
 	res = e100_exec_non_cu_cmd(bdp, cmd);
 	if (!res)
-		printk(KERN_WARNING "%s IA setup failed\n", bdp->device->name);
+		printk(KERN_WARNING "e100: %s: IA setup failed\n", 
+		       bdp->device->name);
 
 exit:
 	return res;
@@ -2544,7 +2573,8 @@
 
 	if (!e100_wait_exec_cmplx(bdp, rx_struct->dma_addr, SCB_RUC_START)) {
 		printk(KERN_DEBUG
-		       "%s start_ru: wait_scb failed\n", bdp->device->name);
+		       "e100: %s: start_ru: wait_scb failed\n", 
+		       bdp->device->name);
 		e100_exec_cmplx(bdp, rx_struct->dma_addr, SCB_RUC_START);
 	}
 	if (bdp->next_cu_cmd == RESUME_NO_WAIT) {
@@ -3051,8 +3081,10 @@
 	/* Print the string if checksum Offloading was enabled */
 	if (bdp->flags & DF_CSUM_OFFLOAD)
 		printk(KERN_NOTICE "  Hardware receive checksums enabled\n");
-	else
-		printk(KERN_NOTICE "  Hardware receive checksums disabled\n");
+	else {
+		if (bdp->rev_id >= D101MA_REV_ID) 
+			printk(KERN_NOTICE "  Hardware receive checksums disabled\n");
+	}
 
 	if ((bdp->flags & DF_UCODE_LOADED))
 		printk(KERN_NOTICE "  cpu cycle saver enabled\n");
@@ -3125,9 +3157,8 @@
 	bdp->scb = (scb_t *) ioremap_nocache(dev->mem_start, sizeof (scb_t));
 
 	if (!bdp->scb) {
-		printk(KERN_ERR "%s - %s: Failed to map PCI address 0x%lX\n",
-		       e100_short_driver_name, dev->name,
-		       pci_resource_start(pcid, 0));
+		printk(KERN_ERR "e100: %s: Failed to map PCI address 0x%lX\n",
+		       dev->name, pci_resource_start(pcid, 0));
 		rc = -ENOMEM;
 		goto err_region;
 	}
@@ -3151,6 +3182,13 @@
 
 	del_timer_sync(&bdp->watchdog_timer);
 
+	del_timer_sync(&bdp->hwi_timer);
+	/* If in middle of cable diag, */
+	if (bdp->hwi_started) {
+		bdp->hwi_started = 0;
+		e100_hwi_restore(bdp);
+	}
+
 	if (netif_running(bdp->device))
 		netif_stop_queue(bdp->device);
 
@@ -3218,7 +3256,8 @@
 
 		if (!e100_setup_iaaddr(bdp, bdp->device->dev_addr)) {
 			printk(KERN_ERR
-			       "e100_hw_reset_recover: setup iaaddr failed\n");
+			       "e100: e100_hw_reset_recover: "
+			       "setup iaaddr failed\n");
 			return false;
 		}
 
@@ -3248,7 +3287,7 @@
 	if (full_init) {
 		e100_sw_reset(bdp, PORT_SOFTWARE_RESET);
 		if (!e100_hw_reset_recover(bdp, PORT_SOFTWARE_RESET))
-			printk(KERN_ERR "e100_deisolate_driver:"
+			printk(KERN_ERR "e100: e100_deisolate_driver:"
 			       " HW SOFTWARE reset recover failed\n");
 	}
 
@@ -3262,7 +3301,7 @@
 			e100_sw_reset(bdp, PORT_SELECTIVE_RESET);
 
 			if (!e100_hw_reset_recover(bdp, PORT_SELECTIVE_RESET)) {
-				printk(KERN_ERR "e100_deisolate_driver:"
+				printk(KERN_ERR "e100: e100_deisolate_driver:"
 				       " HW reset recover failed\n");
 			}
 		}
@@ -3285,7 +3324,6 @@
 	bdp->driver_isolated = false;
 }
 
-#ifdef E100_ETHTOOL_IOCTL
 static int
 e100_do_ethtool_ioctl(struct net_device *dev, struct ifreq *ifr)
 {
@@ -3302,48 +3340,32 @@
 	case ETHTOOL_SSET:
 		rc = e100_ethtool_set_settings(dev, ifr);
 		break;
-#ifdef ETHTOOL_GDRVINFO
 	case ETHTOOL_GDRVINFO:
 		rc = e100_ethtool_get_drvinfo(dev, ifr);
 		break;
-#endif
-#ifdef ETHTOOL_NWAY_RST
 	case ETHTOOL_NWAY_RST:
 		rc = e100_ethtool_nway_rst(dev, ifr);
 		break;
-#endif
-#ifdef ETHTOOL_GLINK
 	case ETHTOOL_GLINK:
 		rc = e100_ethtool_glink(dev, ifr);
 		break;
-#endif
-#ifdef ETHTOOL_GEEPROM
 	case ETHTOOL_GEEPROM:
 	case ETHTOOL_SEEPROM:
 		rc = e100_ethtool_eeprom(dev, ifr);
 		break;
-#endif
-#ifdef ETHTOOL_GWOL
 	case ETHTOOL_GWOL:
 	case ETHTOOL_SWOL:
 		rc = e100_ethtool_wol(dev, ifr);
 		break;
-#endif
-#ifdef ETHTOOL_TEST
 	case ETHTOOL_TEST:
 		rc = e100_ethtool_test(dev, ifr);
 		break;
-#endif
-#ifdef ETHTOOL_GSTRINGS
 	case ETHTOOL_GSTRINGS:
 		rc = e100_ethtool_gstrings(dev,ifr);
 		break;
-#endif
-#ifdef	ETHTOOL_PHYS_ID
 	case ETHTOOL_PHYS_ID:
 		rc = e100_ethtool_led_blink(dev,ifr);
 		break;
-#endif
 	default:
 		break;
 	}			//switch
@@ -3382,9 +3404,7 @@
 	}
 
 	if (bdp->speed_duplex_caps & SUPPORTED_MII) {
-		spin_lock_bh(&(bdp->mdi_access_lock));
 		e100_mdi_read(bdp, MII_ADVERTISE, bdp->phy_addr, &advert);
-		spin_unlock_bh(&(bdp->mdi_access_lock));
 
 		if (advert & ADVERTISE_10HALF)
 			ecmd.advertising |= ADVERTISED_10baseT_Half;
@@ -3483,7 +3503,6 @@
 	return 0;
 }
 
-#ifdef ETHTOOL_GLINK
 static int
 e100_ethtool_glink(struct net_device *dev, struct ifreq *ifr)
 {
@@ -3495,18 +3514,14 @@
 	bdp = dev->priv;
 	info.cmd = ETHTOOL_GLINK;
 
-	spin_lock_bh(&(bdp->mdi_access_lock));
 	info.data = e100_get_link_state(bdp);
-	spin_unlock_bh(&(bdp->mdi_access_lock));
 
 	if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
 		return -EFAULT;
 
 	return 0;
 }
-#endif
 
-#ifdef ETHTOOL_TEST
 static int
 e100_ethtool_test(struct net_device *dev, struct ifreq *ifr)
 {
@@ -3534,9 +3549,7 @@
 	kfree(info);
 	return rc;
 }
-#endif
 
-#ifdef ETHTOOL_NWAY_RST
 static int
 e100_ethtool_nway_rst(struct net_device *dev, struct ifreq *ifr)
 {
@@ -3555,9 +3568,7 @@
 	}
 	return 0;
 }
-#endif
 
-#ifdef ETHTOOL_GDRVINFO
 static int
 e100_ethtool_get_drvinfo(struct net_device *dev, struct ifreq *ifr)
 {
@@ -3569,25 +3580,19 @@
 	bdp = dev->priv;
 
 	strncpy(info.driver, e100_short_driver_name, sizeof (info.driver) - 1);
-	strncpy(info.version, e100_version, sizeof (info.version) - 1);
+	strncpy(info.version, e100_driver_version, sizeof (info.version) - 1);
 	strncpy(info.fw_version, e100_get_brand_msg(bdp),
 		sizeof (info.fw_version) - 1);
 	strncpy(info.bus_info, bdp->pdev->slot_name,
 		sizeof (info.bus_info) - 1);
-#ifdef ETHTOOL_GEEPROM
 	info.eedump_len = (bdp->eeprom_size << 1);	
-#endif
-#ifdef ETHTOOL_TEST
 	info.testinfo_len = E100_MAX_TEST_RES;
-#endif
 	if (copy_to_user(ifr->ifr_data, &info, sizeof (info)))
 		return -EFAULT;
 
 	return 0;
 }
-#endif //ETHTOOL_GDRVINFO
 
-#ifdef ETHTOOL_GEEPROM
 static int
 e100_ethtool_eeprom(struct net_device *dev, struct ifreq *ifr)
 {
@@ -3595,8 +3600,9 @@
 	struct ethtool_eeprom ecmd;
 	u16 eeprom_data[256];
 	u16 *usr_eeprom_ptr;
-	u16 word_length, word_offset;
-	int i;
+	u16 first_word, last_word;
+	int i, max_len;
+	void *ptr;
 
 	if (!capable(CAP_NET_ADMIN))
 		return -EPERM;
@@ -3609,48 +3615,56 @@
 	usr_eeprom_ptr =
 		(u16 *) (ifr->ifr_data + offsetof(struct ethtool_eeprom, data));
 
-	word_offset = (ecmd.offset >> 1);
-	if (word_offset >= bdp->eeprom_size)
+        max_len = bdp->eeprom_size * 2;
+	if ((ecmd.offset + ecmd.len) > max_len)
+		ecmd.len = (max_len - ecmd.offset);
+
+	first_word = ecmd.offset >> 1;
+	last_word = (ecmd.offset + ecmd.len - 1) >> 1;
+		
+	if (first_word >= bdp->eeprom_size)
 		return -EFAULT;
 
-	word_length =
-		min_t(u32, (ecmd.len >> 1), (bdp->eeprom_size - word_offset));
-
 	if (ecmd.cmd == ETHTOOL_GEEPROM) {
-		for (i = word_offset; i < (word_length + word_offset); i++)
-			eeprom_data[i] = e100_eeprom_read(bdp, i);
+        	for(i = 0; i <= (last_word - first_word); i++)
+			eeprom_data[i] = e100_eeprom_read(bdp, first_word + i);
 
-		ecmd.len = (word_length << 1);
 		ecmd.magic = E100_EEPROM_MAGIC;
 
 		if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
 			return -EFAULT;
 
-		if (copy_to_user(usr_eeprom_ptr, &(eeprom_data[word_offset]),
-				 (ecmd.len << 1)))
+		if (copy_to_user(usr_eeprom_ptr, eeprom_data, ecmd.len))
 			return -EFAULT;
 	} else {
 		if (ecmd.magic != E100_EEPROM_MAGIC)
 			return -EFAULT;
 
-		if (copy_from_user(&(eeprom_data[word_offset]), usr_eeprom_ptr,
-				   (ecmd.len << 1)))
-			return -EFAULT;
-
-		e100_eeprom_write_block(bdp, word_offset,
-					&(eeprom_data[word_offset]),
-					word_length);
+		ptr = (void *)eeprom_data;
+        	if(ecmd.offset & 1) {
+                	/* need modification of first changed EEPROM word */
+                	/* only the second byte of the word is being modified */
+			eeprom_data[0] = e100_eeprom_read(bdp, first_word);
+                	ptr++;
+        	}
+        	if((ecmd.offset + ecmd.len) & 1) {
+	                /* need modification of last changed EEPROM word */
+	                /* only the first byte of the word is being modified */
+			eeprom_data[last_word - first_word] = 
+				e100_eeprom_read(bdp, last_word);
+		}
+        	if(copy_from_user(ptr, usr_eeprom_ptr, ecmd.len))
+	                return -EFAULT;
 
-		ecmd.len = (word_length << 1);
+		e100_eeprom_write_block(bdp, first_word, eeprom_data,
+					last_word - first_word + 1);
 
 		if (copy_to_user(ifr->ifr_data, &ecmd, sizeof (ecmd)))
 			return -EFAULT;
 	}
 	return 0;
 }
-#endif
 
-#ifdef ETHTOOL_PHYS_ID
 #define E100_BLINK_INTERVAL	(HZ/4)
 /**
  * e100_led_control
@@ -3663,12 +3677,9 @@
 static void
 e100_led_control(struct e100_private *bdp, u16 led_mdi_op)
 {
-	spin_lock_bh(&bdp->mdi_access_lock);
-
 	e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
 		       bdp->phy_addr, led_mdi_op);
 
-	spin_unlock_bh(&bdp->mdi_access_lock);
 }
 /**
  * e100_led_blink_callback
@@ -3736,7 +3747,6 @@
 
 	return 0;
 }
-#endif
 
 static inline int __devinit
 e100_10BaseT_adapter(struct e100_private *bdp)
@@ -3785,7 +3795,6 @@
 
 }
 
-#ifdef ETHTOOL_GWOL
 static unsigned char
 e100_setup_filter(struct e100_private *bdp)
 {
@@ -3818,7 +3827,7 @@
 
 	res = e100_exec_non_cu_cmd(bdp, cmd);
 	if (!res)
-		printk(KERN_WARNING "%s Filter setup failed\n",
+		printk(KERN_WARNING "e100: %s: Filter setup failed\n",
 		       bdp->device->name);
 
 exit:
@@ -3835,9 +3844,9 @@
 		if (bdp->wolopts & (WAKE_UCAST | WAKE_ARP))
 			if (!e100_setup_filter(bdp))
 				printk(KERN_ERR
-				       "e100_config WOL options failed\n");
+				       "e100: WOL options failed\n");
 	} else {
-		printk(KERN_ERR "e100_config WOL failed\n");
+		printk(KERN_ERR "e100: config WOL failed\n");
 	}
 }
 
@@ -3899,9 +3908,6 @@
 	return res;
 }
 
-#endif
-
-#ifdef ETHTOOL_GSTRINGS
 static int e100_ethtool_gstrings(struct net_device *dev, struct ifreq *ifr)
 {
 	struct ethtool_gstrings info;
@@ -3944,10 +3950,7 @@
 	kfree(strings);
 	return 0;
 }
-#endif
-#endif /*E100_ETHTOOL_IOCTL */
 
-#ifdef E100_MII_IOCTL
 static int
 e100_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
@@ -3965,10 +3968,8 @@
 	case SIOCGMIIREG:
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
-		spin_lock_bh(&(bdp->mdi_access_lock));
 		e100_mdi_read(bdp, data_ptr->reg_num & 0x1f, bdp->phy_addr,
 			      &(data_ptr->val_out));
-		spin_unlock_bh(&(bdp->mdi_access_lock));
 		break;
 
 	case SIOCSMIIREG:
@@ -3977,10 +3978,8 @@
 		if (netif_running(dev)) {
 			return -EBUSY;
 		}
-		spin_lock_bh(&(bdp->mdi_access_lock));
 		e100_mdi_write(bdp, data_ptr->reg_num & 0x1f, bdp->phy_addr,
 			       data_ptr->val_in);
-		spin_unlock_bh(&(bdp->mdi_access_lock));
 		break;
 
 	default:
@@ -3988,7 +3987,6 @@
 	}
 	return 0;
 }
-#endif //E100_MII_IOCTL
 
 nxmit_cb_entry_t *
 e100_alloc_non_tx_cmd(struct e100_private *bdp)
@@ -4149,17 +4147,22 @@
 
 #ifdef CONFIG_PM
 static int
-e100_save_state(struct pci_dev *pcid, u32 state)
+e100_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
 {
-	struct net_device *dev;
-	struct e100_private *bdp;
-
-	/* Actually, PCI PM does NOT call this entry */
-	if (!(dev = (struct net_device *) pci_get_drvdata(pcid)))
-		return -1;
-	bdp = dev->priv;
-	pci_save_state(pcid, bdp->pci_state);
-	return 0;
+        struct pci_dev *pdev = NULL;
+        switch(event) {
+        case SYS_DOWN:
+        case SYS_HALT:
+        case SYS_POWER_OFF:
+                pci_for_each_dev(pdev) {
+                        if(pci_dev_driver(pdev) == &e100_driver) {
+				/* If net_device struct is allocated? */
+                                if (pci_get_drvdata(pdev))
+					e100_suspend(pdev, 3);
+                	}
+		}
+        }
+        return NOTIFY_DONE;
 }
 
 static int
@@ -4169,10 +4172,9 @@
 	struct e100_private *bdp = netdev->priv;
 
 	e100_isolate_driver(bdp);
-	e100_save_state(pcid, state);
+	pci_save_state(pcid, bdp->pci_state);
 
 	/* If wol is enabled */
-#ifdef ETHTOOL_GWOL
 	if (bdp->wolopts) {
 		bdp->ip_lbytes = e100_get_ip_lbytes(netdev);
 		e100_do_wol(pcid, bdp);
@@ -4183,10 +4185,6 @@
 		pci_disable_device(pcid);
 		pci_set_power_state(pcid, state);
 	}
-#else
-	pci_disable_device(pcid);
-	pci_set_power_state(pcid, state);
-#endif
 
 	return 0;
 }
@@ -4207,23 +4205,135 @@
 		recover = true;
 	}
 
-#ifdef ETHTOOL_GWOL
 	if (bdp->wolopts & (WAKE_UCAST | WAKE_ARP)) {
 		full_init = true;
 	}
-#endif
 
 	e100_deisolate_driver(bdp, recover, full_init);
 
 	return 0;
 }
 
-static int
-e100_enable_wake(struct pci_dev *pcid, u32 state, int enable)
+#endif /* CONFIG_PM */
+
+static void
+e100_get_mdix_status(struct e100_private *bdp)
+{	
+	if (bdp->rev_id < D102_REV_ID) {
+		if (netif_carrier_ok(bdp->device))
+			bdp->mdix_status = "MDI";				
+		else			
+			bdp->mdix_status = "None";
+	} else {	
+		u16 ctrl_reg;
+		/* Read the MDIX control register */
+		e100_mdi_read(bdp, MII_NCONFIG, bdp->phy_addr, &ctrl_reg);
+		if (ctrl_reg & MDI_MDIX_CONFIG_IS_OK) {
+			if (ctrl_reg & MDI_MDIX_STATUS)
+				bdp->mdix_status = "MDI-X";
+			else
+				bdp->mdix_status = "MDI";
+		} else
+			bdp->mdix_status = "None";
+	}
+}
+
+static void
+e100_do_hwi(struct net_device *dev)
 {
-	/* Driver doesn't need to do anything because it will enable */
-	/* wol when suspended.                                       */
-	/* Actually, PCI PM does NOT call this entry.                */
-	return 0;
+	struct e100_private *bdp = dev->priv;
+	u16 ctrl_reg;
+	int distance, open_circut, short_circut;
+
+	e100_mdi_read(bdp, HWI_CONTROL_REG, bdp->phy_addr, &ctrl_reg);
+
+	distance = ctrl_reg & HWI_TEST_DISTANCE;
+	open_circut = ctrl_reg & HWI_TEST_HIGHZ_PROBLEM;
+	short_circut = ctrl_reg & HWI_TEST_LOWZ_PROBLEM;
+
+	if ((distance == bdp->saved_distance) &&
+	    (open_circut == bdp->saved_open_circut) &&
+	    (short_circut == bdp->saved_short_circut)) 
+		bdp->saved_same++;
+	else {
+		bdp->saved_same = 0;
+		bdp->saved_distance = distance;
+		bdp->saved_open_circut = open_circut;
+		bdp->saved_short_circut = short_circut;
+	}
+		
+	if (bdp->saved_same == MAX_SAME_RESULTS) {
+		if ((open_circut && !(short_circut)) ||
+		    (!(open_circut) && short_circut)) {
+
+			u8 near_end = ((distance * HWI_REGISTER_GRANULARITY) <
+				       HWI_NEAR_END_BOUNDARY);
+			if (open_circut) {
+				if (near_end) 
+					bdp->cable_status = "Open Circut Near End";
+				else 
+					bdp->cable_status = "Open Circut Far End";
+			} else {
+				if (near_end) 
+					bdp->cable_status = "Short Circut Near End";
+				else 
+					bdp->cable_status = "Short Circut Far End";
+			}
+			goto done;
+		}
+	}
+	else if (bdp->saved_i == HWI_MAX_LOOP) {
+		bdp->cable_status = "Test failed";
+		goto done;
+	}
+		
+	/* Do another hwi test */
+	e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,
+		       (HWI_TEST_ENABLE | HWI_TEST_EXECUTE));
+	bdp->saved_i++;
+	/* relaunch hwi timer in 1 msec */
+	mod_timer(&(bdp->hwi_timer), jiffies + (HZ / 1000) );
+	return;
+
+done:
+	e100_hwi_restore(bdp);
+	bdp->hwi_started = 0;
+	return;
+}
+
+static void e100_hwi_restore(struct e100_private *bdp)
+{
+	u16 control = 0;
+
+	/* Restore speed, duplex and autoneg before */
+	/* hwi test, i.e., cable diagnostic         */
+	
+	/* Reset hwi test */
+        e100_mdi_write(bdp, HWI_CONTROL_REG, bdp->phy_addr,					       HWI_RESET_ALL_MASK);
+				
+	if ((bdp->params.e100_speed_duplex == E100_AUTONEG) &&
+        	(bdp->rev_id >= D102_REV_ID)) 
+		/* Enable MDI/MDI-X auto switching */
+                e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
+			MDI_MDIX_AUTO_SWITCH_ENABLE);
+
+	switch (bdp->params.e100_speed_duplex) {
+	case E100_SPEED_10_HALF:
+		break;
+	case E100_SPEED_10_FULL:
+		control = BMCR_FULLDPLX;
+		break;
+	case E100_SPEED_100_HALF:
+		control = BMCR_SPEED100;
+		break;
+	case E100_SPEED_100_FULL:
+		control = BMCR_SPEED100 | BMCR_FULLDPLX;
+		break;
+	case E100_AUTONEG:
+		control = BMCR_ANENABLE | BMCR_ANRESTART;
+		break;
+	}
+	/* Restore original speed/duplex */
+	e100_mdi_write(bdp, MII_BMCR, bdp->phy_addr, control);
+	return;
 }
-#endif /* CONFIG_PM */
diff -Nru a/drivers/net/e100/e100_phy.c b/drivers/net/e100/e100_phy.c
--- a/drivers/net/e100/e100_phy.c	Sat Aug 10 18:42:19 2002
+++ b/drivers/net/e100/e100_phy.c	Sat Aug 10 18:42:20 2002
@@ -96,9 +96,11 @@
 	int e100_retry;
 	u32 temp_val;
 
+	spin_lock_bh(&bdp->mdi_access_lock);
 	temp_val = (((u32) data) | (reg_addr << 16) |
 		    (phy_addr << 21) | (MDI_WRITE << 26));
 	writel(temp_val, &bdp->scb->scb_mdi_cntrl);
+	readw(&bdp->scb->scb_status);
 
 	/* wait 20usec before checking status */
 	udelay(20);
@@ -111,6 +113,7 @@
 		udelay(20);
 		e100_retry--;
 	}
+	spin_unlock_bh(&bdp->mdi_access_lock);
 }
 
 /* 
@@ -138,9 +141,11 @@
 	int e100_retry;
 	u32 temp_val;
 
+	spin_lock_bh(&bdp->mdi_access_lock);
 	/* Issue the read command to the MDI control register. */
 	temp_val = ((reg_addr << 16) | (phy_addr << 21) | (MDI_READ << 26));
 	writel(temp_val, &bdp->scb->scb_mdi_cntrl);
+	readw(&bdp->scb->scb_status);
 
 	/* wait 20usec before checking status */
 	udelay(20);
@@ -156,6 +161,7 @@
 
 	// return the lower word
 	*data = (u16) readl(&bdp->scb->scb_mdi_cntrl);
+	spin_unlock_bh(&bdp->mdi_access_lock);
 }
 
 static unsigned char __devinit
@@ -263,21 +269,22 @@
 		case E100_AUTONEG:
 			/* The adapter can't autoneg. so set to 10/HALF */
 			printk(KERN_INFO
-			       "503 serial component detected which "
+			       "e100: 503 serial component detected which "
 			       "cannot autonegotiate\n");
 			printk(KERN_INFO
-			       "speed/duplex forced to 10Mbps / Half duplex\n");
+			       "e100: speed/duplex forced to "
+			       "10Mbps / Half duplex\n");
 			bdp->params.e100_speed_duplex = E100_SPEED_10_HALF;
 			break;
 
 		case E100_SPEED_100_HALF:
 		case E100_SPEED_100_FULL:
 			printk(KERN_ERR
-			       "503 serial component detected which does not "
-			       "support 100Mbps\n");
+			       "e100: 503 serial component detected "
+			       "which does not support 100Mbps\n");
 			printk(KERN_ERR
-			       "Change the forced speed/duplex to a supported "
-			       "setting\n");
+			       "e100: Change the forced speed/duplex "
+			       "to a supported setting\n");
 			return false;
 		}
 
@@ -294,7 +301,7 @@
 		if ((bdp->params.e100_speed_duplex != E100_AUTONEG) &&
 		    (bdp->params.e100_speed_duplex != E100_SPEED_100_FULL)) {
 			/* just inform user about 100 full */
-			printk(KERN_ERR "NC3133 NIC can only run "
+			printk(KERN_ERR "e100: NC3133 NIC can only run "
 			       "at 100Mbps full duplex\n");
 		}
 
@@ -657,8 +664,6 @@
 
 	bdp->flags |= DF_SPEED_FORCED;
 
-	spin_lock_bh(&(bdp->mdi_access_lock));
-
 	e100_mdi_read(bdp, MII_BMCR, bdp->phy_addr, &control);
 	control &= ~BMCR_ANENABLE;
 
@@ -702,14 +707,10 @@
 		    time_after(jiffies, expires)) {
 			break;
 		} else {
-			spin_unlock_bh(&(bdp->mdi_access_lock));
 			yield();
-			spin_lock_bh(&(bdp->mdi_access_lock));
 		}
 
 	} while (true);
-
-	spin_unlock_bh(&(bdp->mdi_access_lock));
 }
 
 /* 
@@ -753,7 +754,12 @@
 		if (ad_reg & NWAY_AD_FC_SUPPORTED)
 			bdp->flags |= DF_LINK_FC_CAP;
 		else
-			bdp->flags &= ~DF_LINK_FC_CAP;
+			/* If link partner is capable of autoneg, but  */
+			/* not capable of flow control, Received PAUSE */
+			/* frames are still honored, i.e.,             */
+		        /* transmitted frames would be paused */
+			/* by incoming PAUSE frames           */
+			bdp->flags |= DF_LINK_FC_TX_ONLY;
 
 	} else {
 		bdp->flags &= ~DF_LINK_FC_CAP;
@@ -821,8 +827,6 @@
 
 	bdp->flags &= ~DF_SPEED_FORCED;
 
-	spin_lock_bh(&(bdp->mdi_access_lock));
-
 	e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
 	e100_mdi_read(bdp, MII_BMSR, bdp->phy_addr, &stat_reg);
 
@@ -848,25 +852,30 @@
 			    time_after(jiffies, expires) ) {
 				goto exit;
 			} else {
-				spin_unlock_bh(&(bdp->mdi_access_lock));
 				yield();
-				spin_lock_bh(&(bdp->mdi_access_lock));
 			}
 		} while (true);
 	}
 
 exit:
 	e100_find_speed_duplex(bdp);
-	spin_unlock_bh(&(bdp->mdi_access_lock));
 }
 
 void
 e100_phy_set_speed_duplex(struct e100_private *bdp, unsigned char force_restart)
 {
 	if (bdp->params.e100_speed_duplex == E100_AUTONEG) {
+        	if (bdp->rev_id >= D102_REV_ID) 
+			/* Enable MDI/MDI-X auto switching */
+                	e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
+		                       MDI_MDIX_AUTO_SWITCH_ENABLE);
 		e100_auto_neg(bdp, force_restart);
 
 	} else {
+        	if (bdp->rev_id >= D102_REV_ID) 
+			/* Disable MDI/MDI-X auto switching */
+                	e100_mdi_write(bdp, MII_NCONFIG, bdp->phy_addr,
+		                       MDI_MDIX_RESET_ALL_MASK);
 		e100_force_speed_duplex(bdp);
 	}
 
diff -Nru a/drivers/net/e100/e100_phy.h b/drivers/net/e100/e100_phy.h
--- a/drivers/net/e100/e100_phy.h	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/e100/e100_phy.h	Sat Aug 10 18:42:21 2002
@@ -124,6 +124,27 @@
 #define NSC_CONG_CONTROL_REG	    0x17	/* National (TX) congestion control */
 #define NSC_SPEED_IND_REG	    0x19	/* National (TX) speed indication */
 
+#define HWI_CONTROL_REG             0x1D	/* HWI Control register */
+/* MDI/MDI-X Control Register bit definitions */
+#define MDI_MDIX_RES_TIMER          BIT_0_3	/* minimum slot time for resolution timer */
+#define MDI_MDIX_CONFIG_IS_OK       BIT_4	/* 1 = resolution algorithm completes OK */
+#define MDI_MDIX_STATUS             BIT_5	/* 1 = MDIX (croos over), 0 = MDI (straight through) */
+#define MDI_MDIX_SWITCH             BIT_6	/* 1 = Forces to MDIX, 0 = Forces to MDI */
+#define MDI_MDIX_AUTO_SWITCH_ENABLE BIT_7	/* 1 = MDI/MDI-X feature enabled */
+#define MDI_MDIX_CONCT_CONFIG       BIT_8	/* Sets the MDI/MDI-X connectivity configuration (test prupose only) */
+#define MDI_MDIX_CONCT_TEST_ENABLE  BIT_9	/* 1 = Enables connectivity testing */
+#define MDI_MDIX_RESET_ALL_MASK     0x0000
+
+/* HWI Control Register bit definitions */
+#define HWI_TEST_DISTANCE           BIT_0_8	/* distance to cable problem */
+#define HWI_TEST_HIGHZ_PROBLEM      BIT_9	/* 1 = Open Circuit */
+#define HWI_TEST_LOWZ_PROBLEM       BIT_10	/* 1 = Short Circuit */
+#define HWI_TEST_RESERVED           (BIT_11 | BIT_12)	/* reserved */
+#define HWI_TEST_EXECUTE            BIT_13	/* 1 = Execute the HWI test on the PHY */
+#define HWI_TEST_ABILITY            BIT_14	/* 1 = test passed */
+#define HWI_TEST_ENABLE             BIT_15	/* 1 = Enables the HWI feature */
+#define HWI_RESET_ALL_MASK          0x0000
+
 /* ############Start of 82555 specific defines################## */
 
 /* Intel 82555 specific registers */
diff -Nru a/drivers/net/e100/e100_proc.c b/drivers/net/e100/e100_proc.c
--- a/drivers/net/e100/e100_proc.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/e100/e100_proc.c	Sat Aug 10 18:42:22 2002
@@ -91,11 +91,7 @@
 
 #include <linux/config.h>
 
-#ifndef CONFIG_PROC_FS
-#undef E100_CONFIG_PROC_FS
-#endif
-
-#ifdef E100_CONFIG_PROC_FS
+#ifdef CONFIG_PROC_FS
 #include "e100.h"
 /* MDI sleep time is at least 50 ms, in jiffies */
 #define MDI_SLEEP_TIME ((HZ / 20) + 1)
@@ -106,8 +102,8 @@
 static struct proc_dir_entry *adapters_proc_dir = 0;
 
 /* externs from e100_main.c */
-extern const char *e100_short_driver_name;
-extern const char *e100_version;
+extern char e100_short_driver_name[];
+extern char e100_driver_version[];
 extern struct net_device_stats *e100_get_stats(struct net_device *dev);
 extern char *e100_get_brand_msg(struct e100_private *bdp);
 extern void e100_mdi_write(struct e100_private *, u32, u32, u16);
@@ -115,8 +111,6 @@
 static void e100_proc_cleanup(void);
 static unsigned char e100_init_proc_dir(void);
 
-#define E100_EOU
-
 #define ADAPTERS_PROC_DIR "PRO_LAN_Adapters"
 #define WRITE_BUF_MAX_LEN 20	
 #define READ_BUF_MAX_LEN  256
@@ -191,7 +185,7 @@
 	struct e100_private *bdp = data;
 	int len;
 
-	len = sprintf(page, "%s\n", e100_get_brand_msg(bdp));
+	len = sprintf(page, "%s\n", bdp->id_string);
 
 	return generic_read(page, start, off, count, eof, len);
 }
@@ -223,23 +217,15 @@
 static void
 set_led(struct e100_private *bdp, u16 led_mdi_op)
 {
-	spin_lock_bh(&bdp->mdi_access_lock);
-
 	e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
 		       bdp->phy_addr, led_mdi_op);
 
-	spin_unlock_bh(&bdp->mdi_access_lock);
-
 	set_current_state(TASK_UNINTERRUPTIBLE);
 	schedule_timeout(MDI_SLEEP_TIME);
 
-	spin_lock_bh(&bdp->mdi_access_lock);
-
 	/* turn led ownership to the chip */
 	e100_mdi_write(bdp, PHY_82555_LED_SWITCH_CONTROL,
 		       bdp->phy_addr, PHY_82555_LED_NORMAL_CONTROL);
-
-	spin_unlock_bh(&bdp->mdi_access_lock);
 }
 
 static int
@@ -350,335 +336,6 @@
 	return generic_read(page, start, off, count, eof, len);
 }
 
-#ifdef E100_EOU
-/**********************
- *  parameter entries
- **********************/
-static int
-read_int_param(char *page, char *name, char *desc, int def, int min, int max)
-{
-	int len;
-
-	len = sprintf(page, "Name: %s\n", name);
-	len += sprintf(page + len, "Description: %s\n", desc);
-	len += sprintf(page + len, "Default_Value: %d\n", def);
-	len += sprintf(page + len, "Type: Range\n");
-	len += sprintf(page + len, "Min: %d\n", min);
-	len += sprintf(page + len, "Max: %d\n", max);
-	len += sprintf(page + len, "Step:1\n");
-	len += sprintf(page + len, "Radix: dec\n");
-
-	return len;
-}
-
-static int
-read_bool_param(char *page, char *name, char *desc, int def)
-{
-	int len;
-
-	len = sprintf(page, "Name: %s\n", name);
-	len += sprintf(page + len, "Description: %s\n", desc);
-	len += sprintf(page + len, "Default_Value: %d\n", def);
-	len += sprintf(page + len, "Type: Enum\n");
-	len += sprintf(page + len, "0: Off\n");
-	len += sprintf(page + len, "1: On\n");
-
-	return len;
-}
-
-static int
-read_speed_duplex_def(char *page, char **start, off_t off,
-		      int count, int *eof, void *data)
-{
-	int len;
-
-	len = sprintf(page, "Name: Speed and Duplex\n");
-	len += sprintf(page + len, "Description: Sets the adapter's "
-		       "speed and duplex mode\n");
-	len += sprintf(page + len, "Default_Value: 0\n");
-	len += sprintf(page + len, "Type: Enum\n");
-	len += sprintf(page + len, "0: Auto-Negotiate\n");
-	len += sprintf(page + len, "1: 10 Mbps / Half Duplex\n");
-	len += sprintf(page + len, "2: 10 Mbps / Full Duplex\n");
-	len += sprintf(page + len, "3: 100 Mbps / Half Duplex\n");
-	len += sprintf(page + len, "4: 100 Mbps / Full Duplex\n");
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_tx_desc_def(char *page, char **start, off_t off,
-		 int count, int *eof, void *data)
-{
-	int len;
-
-	len = read_int_param(page, "Transmit Descriptors",
-			     "Sets the number of Tx descriptors "
-			     "available for the adapter",
-			     E100_DEFAULT_TCB, E100_MIN_TCB, E100_MAX_TCB);
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_rx_desc_def(char *page, char **start, off_t off,
-		 int count, int *eof, void *data)
-{
-	int len;
-
-	len = read_int_param(page, "Receive Descriptors",
-			     "Sets the number of Rx descriptors "
-			     "available for the adapter",
-			     E100_DEFAULT_RFD, E100_MIN_RFD, E100_MAX_RFD);
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_ber_def(char *page, char **start, off_t off,
-	     int count, int *eof, void *data)
-{
-	int len;
-
-	len = read_int_param(page, "Bit Error Rate",
-			     "Sets the value for the BER correction algorithm",
-			     E100_DEFAULT_BER, 0, ZLOCK_MAX_ERRORS);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_xsum_rx_def(char *page, char **start, off_t off,
-		 int count, int *eof, void *data)
-{
-	int len;
-
-	len = read_bool_param(page, "RX Checksum",
-			      "Setting this value to \"On\" enables "
-			      "receive checksum", E100_DEFAULT_XSUM);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_ucode_def(char *page, char **start, off_t off,
-	       int count, int *eof, void *data)
-{
-	int len;
-
-	len = read_bool_param(page, "Microcode",
-			      "Setting this value to \"On\" enables "
-			      "the adapter's microcode", E100_DEFAULT_UCODE);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_bundle_small_def(char *page, char **start, off_t off,
-		      int count, int *eof, void *data)
-{
-	int len;
-
-	len = read_bool_param(page, "Bundle Small Frames",
-			      "Setting this value to \"On\" enables "
-			      "interrupt bundling of small frames",
-			      E100_DEFAULT_BUNDLE_SMALL_FR);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_fc_def(char *page, char **start, off_t off,
-	    int count, int *eof, void *data)
-{
-	int len;
-
-	len = read_bool_param(page, "Flow Control",
-			      "Setting this value to \"On\" enables processing "
-			      "flow-control packets", E100_DEFAULT_FC);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_rcv_cong_def(char *page, char **start, off_t off,
-		  int count, int *eof, void *data)
-{
-	int len;
-
-	len = read_bool_param(page, "Receive Congestion Control",
-			      "Setting this value to \"On\" enables switching "
-			      "to polling mode on receive",
-			      E100_DEFAULT_RX_CONGESTION_CONTROL);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_poll_max_def(char *page, char **start, off_t off,
-		  int count, int *eof, void *data)
-{
-	struct e100_private *bdp = data;
-
-	int len;
-
-	len = read_int_param(page, "Maximum Polling Work",
-			     "Sets the max number of RX packets processed"
-			     " by single polling function call",
-			     bdp->params.RxDescriptors, 1, E100_MAX_RFD);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_int_delay_def(char *page, char **start, off_t off,
-		   int count, int *eof, void *data)
-{
-	int len;
-
-	len = read_int_param(page, "CPU Saver Interrupt Delay",
-			     "Sets the value for CPU saver's interrupt delay",
-			     E100_DEFAULT_CPUSAVER_INTERRUPT_DELAY, 0x0,
-			     0xFFFF);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_bundle_max_def(char *page, char **start, off_t off,
-		    int count, int *eof, void *data)
-{
-	int len;
-
-	len = read_int_param(page, "CPU Saver Maximum Bundle",
-			     "Sets CPU saver's maximum value",
-			     E100_DEFAULT_CPUSAVER_BUNDLE_MAX, 0x1, 0xFFFF);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_ifs_def(char *page, char **start, off_t off,
-	     int count, int *eof, void *data)
-{
-	int len;
-
-	len = read_bool_param(page, "IFS",
-			      "Setting this value to \"On\" enables "
-			      "the adaptive IFS algorithm", E100_DEFAULT_IFS);
-
-	return generic_read(page, start, off, count, eof, len);
-}
-
-static int
-read_xsum_rx_val(char *page, char **start, off_t off,
-		 int count, int *eof, void *data)
-{
-	struct e100_private *bdp = data;
-	unsigned long val;
-
-	val = (bdp->params.b_params & PRM_XSUMRX) ? 1 : 0;
-	return read_ulong(page, start, off, count, eof, val);
-}
-
-static int
-read_ucode_val(char *page, char **start, off_t off,
-	       int count, int *eof, void *data)
-{
-	struct e100_private *bdp = data;
-	unsigned long val;
-
-	val = (bdp->params.b_params & PRM_UCODE) ? 1 : 0;
-	return read_ulong(page, start, off, count, eof, val);
-}
-
-static int
-read_fc_val(char *page, char **start, off_t off,
-	    int count, int *eof, void *data)
-{
-	struct e100_private *bdp = data;
-	unsigned long val;
-
-	val = (bdp->params.b_params & PRM_FC) ? 1 : 0;
-	return read_ulong(page, start, off, count, eof, val);
-}
-
-static int
-read_ifs_val(char *page, char **start, off_t off,
-	     int count, int *eof, void *data)
-{
-	struct e100_private *bdp = data;
-	unsigned long val;
-
-	val = (bdp->params.b_params & PRM_IFS) ? 1 : 0;
-	return read_ulong(page, start, off, count, eof, val);
-}
-
-static int
-read_bundle_small_val(char *page, char **start, off_t off,
-		      int count, int *eof, void *data)
-{
-	struct e100_private *bdp = data;
-	unsigned long val;
-
-	val = (bdp->params.b_params & PRM_BUNDLE_SMALL) ? 1 : 0;
-	return read_ulong(page, start, off, count, eof, val);
-}
-
-static int
-read_rcv_cong_val(char *page, char **start, off_t off,
-		  int count, int *eof, void *data)
-{
-	struct e100_private *bdp = data;
-	unsigned long val;
-
-	val = (bdp->params.b_params & PRM_RX_CONG) ? 1 : 0;
-	return read_ulong(page, start, off, count, eof, val);
-}
-
-static int
-read_gen_prm(char *page, char **start, off_t off,
-	     int count, int *eof, void *data)
-{
-	int val = 0;
-
-	if (data)
-		val = *((int *) data);
-
-	return read_ulong(page, start, off, count, eof, (unsigned long) val);
-}
-
-static e100_proc_entry e100_proc_params[] = { 
-	/* definitions */
-	{"e100_speed_duplex.def", read_speed_duplex_def, 0, 0},
-	{"RxDescriptors.def",     read_rx_desc_def,      0, 0},
-	{"TxDescriptors.def",     read_tx_desc_def,      0, 0},
-	{"XsumRX.def",            read_xsum_rx_def,      0, 0},
-	{"ucode.def",             read_ucode_def,        0, 0},
-	{"BundleSmallFr.def",     read_bundle_small_def, 0, 0},
-	{"IntDelay.def",          read_int_delay_def,    0, 0},
-	{"BundleMax.def",         read_bundle_max_def,   0, 0},
-	{"ber.def",               read_ber_def,          0, 0},
-	{"flow_control.def",      read_fc_def,           0, 0},
-	{"IFS.def",               read_ifs_def,          0, 0},
-	{"RxCongestionControl.def", read_rcv_cong_def,   0, 0},
-	{"PollingMaxWork.def",      read_poll_max_def,   0, 0},
-	/* values */
-	{"e100_speed_duplex.val", read_gen_prm, 0, bdp_prm_off(e100_speed_duplex)},
-	{"RxDescriptors.val",     read_gen_prm, 0, bdp_prm_off(RxDescriptors)},
-	{"TxDescriptors.val",     read_gen_prm, 0, bdp_prm_off(TxDescriptors)},
-	{"XsumRX.val",            read_xsum_rx_val,      0, 0},
-	{"ucode.val",             read_ucode_val,        0, 0},
-	{"BundleSmallFr.val",     read_bundle_small_val, 0, 0},
-	{"IntDelay.val",          read_gen_prm, 0, bdp_prm_off(IntDelay)},
-	{"BundleMax.val",         read_gen_prm, 0, bdp_prm_off(BundleMax)},
-	{"ber.val",               read_gen_prm, 0, bdp_prm_off(ber)},
-	{"flow_control.val",      read_fc_val,           0, 0},
-	{"IFS.val",               read_ifs_val,          0, 0},
-	{"RxCongestionControl.val", read_rcv_cong_val,   0, 0},
-	{"PollingMaxWork.val",      read_gen_prm, 0, bdp_prm_off(PollingMaxWork)},
-	{"", 0, 0, 0}
-};
-#endif /* E100_EOU */
-
 static struct proc_dir_entry * __devinit
 create_proc_rw(char *name, void *data, struct proc_dir_entry *parent,
 	       read_proc_t * read_proc, write_proc_t * write_proc)
@@ -705,58 +362,6 @@
 	return pdep;
 }
 
-#ifdef E100_EOU
-static int __devinit
-create_proc_param_subdir(struct e100_private *bdp,
-			 struct proc_dir_entry *dev_dir)
-{
-	struct proc_dir_entry *param_dir;
-	e100_proc_entry *pe;
-	void *data;
-
-	param_dir = create_proc_entry("LoadParameters", S_IFDIR, dev_dir);
-	if (!param_dir)
-		return -ENOMEM;
-
-	for (pe = e100_proc_params; pe->name[0]; pe++) {
-
-		data = ((char *) bdp) + pe->offset;
-
-		if (!(create_proc_rw(pe->name, data, param_dir,
-				     pe->read_proc, pe->write_proc))) {
-			return -ENOMEM;
-		}
-	}
-
-	return 0;
-}
-
-static void
-remove_proc_param_subdir(struct proc_dir_entry *parent)
-{
-	struct proc_dir_entry *de;
-	e100_proc_entry *pe;
-	int len;
-
-	len = strlen("LoadParameters");
-
-	for (de = parent->subdir; de; de = de->next) {
-		if ((de->namelen == len) &&
-		    (!memcmp(de->name, "LoadParameters", len)))
-			break;
-	}
-
-	if (!de)
-		return;
-
-	for (pe = e100_proc_params; pe->name[0]; pe++) {
-		remove_proc_entry(pe->name, de);
-	}
-
-	remove_proc_entry("LoadParameters", parent);
-}
-#endif /* E100_EOU */
-
 void
 e100_remove_proc_subdir(struct e100_private *bdp)
 {
@@ -781,9 +386,6 @@
 			remove_proc_entry(pe->name, bdp->proc_parent);
 		}
 
-#ifdef E100_EOU
-		remove_proc_param_subdir(bdp->proc_parent);
-#endif
 		remove_proc_entry(bdp->device->name, adapters_proc_dir);
 		bdp->proc_parent = NULL;
 	}
@@ -843,13 +445,6 @@
 			return -ENOMEM;
 		}
 	}
-
-#ifdef E100_EOU
-	if (create_proc_param_subdir(bdp, dev_dir)) {
-		e100_remove_proc_subdir(bdp);
-		return -ENOMEM;
-	}
-#endif
 
 	return 0;
 }
diff -Nru a/drivers/net/e100/e100_test.c b/drivers/net/e100/e100_test.c
--- a/drivers/net/e100/e100_test.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/e100/e100_test.c	Sat Aug 10 18:42:22 2002
@@ -72,7 +72,6 @@
 
 #include "e100.h"
 #include "e100_config.h"
-#ifdef ETHTOOL_TEST
 
 extern u16 e100_eeprom_read(struct e100_private *, u16);
 extern int e100_wait_exec_cmplx(struct e100_private *, u32,u8);
@@ -380,11 +379,11 @@
 {
 	/*load CU & RU base */ 
 	if (!e100_wait_exec_cmplx(bdp, 0, SCB_CUC_LOAD_BASE))
-		printk("@@@ SCB_CUC_LOAD_BASE failed\n");
+		printk("e100: SCB_CUC_LOAD_BASE failed\n");
 	if(!e100_wait_exec_cmplx(bdp, 0, SCB_RUC_LOAD_BASE))
-		printk("@@@ SCB_RUC_LOAD_BASE failed!\n");
+		printk("e100: SCB_RUC_LOAD_BASE failed!\n");
 	if(!e100_wait_exec_cmplx(bdp, bdp->loopback.dma_handle, SCB_RUC_START))
-		printk("@@@ SCB_RUC_START failed!\n");
+		printk("e100: SCB_RUC_START failed!\n");
 
 	bdp->next_cu_cmd = START_WAIT;
 	e100_start_cu(bdp, bdp->loopback.tcb);
@@ -456,6 +455,4 @@
         pci_free_consistent(bdp->pdev, sizeof(rfd_t), bdp->loopback.rfd,
 			    bdp->loopback.dma_handle);
 }
-
-#endif
 
diff -Nru a/drivers/net/e100/e100_vendor.h b/drivers/net/e100/e100_vendor.h
--- a/drivers/net/e100/e100_vendor.h	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/e100/e100_vendor.h	Sat Aug 10 18:42:23 2002
@@ -125,6 +125,7 @@
 	E100_82559_LOM,
 	E100_82559_LOM_AOL,
 	E100_82559_LOM_AOL2,
+	E100_82559_LOM_DELL,
 	E100_IBM_MDS,
 	E100_CMPQ_S,
 	E100_PROVE_DA,
@@ -132,7 +133,8 @@
 	E100_PROVE_LOM,
 	E100_PROVE_NET,
 	E100_82562,
-	E100_ALL_BOARDS,
+	E100_82551QM,
+	E100_ALL_BOARDS
 };
 
 struct e100_vendor_info e100_vendor_info_array[] = {
@@ -147,6 +149,7 @@
 	{ E100_BRD_100, "Intel(R) PRO/100+ PCI Adapter"},
 	{ E100_BRD_100M, "Intel(R) PRO/100+ Management Adapter"},
 	{ E100_BRD_AOL2, "Intel(R) PRO/100+ Alert on LAN* 2 Management Adapter"},
+	{ E100_82559_LOM_DELL, "Intel(R) 8255x Based Network Connection"},
 	{ E100_BRD_AOL, "Intel(R) PRO/100+ Alert on LAN* Management Adapter"},
 	{ E100_PROS_M, "Intel(R) PRO/100 S Management Adapter"},
 	{ E100_PROS_AM, "Intel(R) PRO/100 S Advanced Management Adapter"},
@@ -186,6 +189,7 @@
 	{ E100_PROVE_LOM, "Intel(R) PRO/100 VE Network ConnectionPLC LOM" },
 	{ E100_PROVE_NET, "Intel(R) PRO/100 VE Network Connection"},
 	{ E100_82562, "Intel(R)82562 based Fast Ethernet Connection"},
+	{ E100_82551QM, "Intel(R) PRO/100 M Mobile Connection"},
 	{ E100_ALL_BOARDS, "Intel(R) 8255x-based Ethernet Adapter"},
 	{0,NULL}
 };
@@ -309,6 +313,7 @@
 	{0x8086, 0x1229, 0x0E11, 0xB144, 0, 0, E100_CMPQ_S},     
 	{0x8086, 0x1229, 0x0E11, 0xB163, 0, 0, E100_CMPQ_S},     
 	{0x8086, 0x1229, 0x0E11, 0xB164, 0, 0, E100_CMPQ_S},
+	{0x8086, 0x1229, 0x1028, PCI_ANY_ID, 0, 0, E100_82559_LOM_DELL},
 	{0x8086, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
 
 	{0x8086, 0x2449, 0x1014, 0x0265, 0, 0, E100_PROVE_D},
@@ -324,7 +329,11 @@
 	{0x8086, 0x2449, 0x0E11, PCI_ANY_ID, 0, 0, E100_PROVM_NET},
 	{0x8086, 0x2449, 0x1014, PCI_ANY_ID, 0, 0, E100_PROVE_D},	
 	{0x8086, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
-
+	
+	{0x8086, 0x1059, 0x1179, 0x0005, 0, 0, E100_82551QM},
+	{0x8086, 0x1059, 0x1033, 0x8191, 0, 0, E100_82551QM},
+	{0x8086, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_82551QM},
+	
 	{0x8086, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
   	{0x8086, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},
 	{0x8086, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, E100_ALL_BOARDS},	
diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
--- a/drivers/net/e1000/e1000.h	Sat Aug 10 18:42:20 2002
+++ b/drivers/net/e1000/e1000.h	Sat Aug 10 18:42:20 2002
@@ -109,11 +109,11 @@
 #include <linux/list.h>
 #include <linux/reboot.h>
 #include <linux/ethtool.h>
-#ifdef NETIF_F_HW_VLAN_TX
 #include <linux/if_vlan.h>
-#endif
 
 #define BAR_0		0
+#define BAR_1		1
+#define BAR_5		5
 #define PCI_DMA_64BIT	0xffffffffffffffffULL
 #define PCI_DMA_32BIT	0x00000000ffffffffULL
 
@@ -150,6 +150,8 @@
 #define E1000_JUMBO_PBA      0x00000028
 #define E1000_DEFAULT_PBA    0x00000030
 
+#define AUTO_ALL_MODES       0
+
 /* only works for sizes that are powers of 2 */
 #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
 
@@ -195,9 +197,7 @@
 #ifdef CONFIG_PROC_FS
 	struct list_head proc_list_head;
 #endif
-#ifdef NETIF_F_HW_VLAN_TX
 	struct vlan_group *vlgrp;
-#endif
 	char *id_string;
 	uint32_t bd_number;
 	uint32_t rx_buffer_len;
@@ -208,10 +208,8 @@
 	spinlock_t stats_lock;
 	atomic_t irq_sem;
 
-#ifdef ETHTOOL_PHYS_ID
 	struct timer_list blink_timer;
 	unsigned long led_status;
-#endif
 
 	/* TX */
 	struct e1000_desc_ring tx_ring;
diff -Nru a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
--- a/drivers/net/e1000/e1000_ethtool.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/e1000/e1000_ethtool.c	Sat Aug 10 18:42:22 2002
@@ -249,17 +249,70 @@
                       struct ethtool_eeprom *eeprom, uint16_t *eeprom_buff)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	int i, max_len;
+	int i, max_len, first_word, last_word;
+
+	if(eeprom->len == 0) return;
 
 	eeprom->magic = hw->vendor_id | (hw->device_id << 16);
 
 	max_len = e1000_eeprom_size(hw);
 
-	if ((eeprom->offset + eeprom->len) > max_len)
+	if((eeprom->offset + eeprom->len) > max_len)
 		eeprom->len = (max_len - eeprom->offset);
 
-	for(i = 0; i < (max_len >> 1); i++)
-		e1000_read_eeprom(&adapter->hw, i, &eeprom_buff[i]);
+	first_word = eeprom->offset >> 1;
+	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
+
+	for(i = 0; i <= (last_word - first_word); i++)
+		e1000_read_eeprom(hw, first_word + i, &eeprom_buff[i]);
+}
+
+static int 
+e1000_ethtool_seeprom(struct e1000_adapter *adapter,
+                      struct ethtool_eeprom *eeprom, void *user_data)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	uint16_t eeprom_buff[256];
+	int i, max_len, first_word, last_word;
+	void *ptr;
+
+	if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
+		return -EFAULT;
+
+	if(eeprom->len == 0) return 0;
+
+	max_len = e1000_eeprom_size(hw);
+
+	if((eeprom->offset + eeprom->len) > max_len)
+		eeprom->len = (max_len - eeprom->offset);
+
+	first_word = eeprom->offset >> 1;
+	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
+	ptr = (void *)eeprom_buff;
+
+	if(eeprom->offset & 1) {
+		/* need read/modify/write of first changed EEPROM word */
+		/* only the second byte of the word is being modified */
+		e1000_read_eeprom(hw, first_word, &eeprom_buff[0]);
+		ptr++;
+	}
+	if((eeprom->offset + eeprom->len) & 1) {
+		/* need read/modify/write of last changed EEPROM word */
+		/* only the first byte of the word is being modified */
+		e1000_read_eeprom(hw, last_word,
+		                  &eeprom_buff[last_word - first_word]);
+	}
+	if(copy_from_user(ptr, user_data, eeprom->len))
+		return -EFAULT;
+
+	for(i = 0; i <= (last_word - first_word); i++)
+		e1000_write_eeprom(hw, first_word + i, eeprom_buff[i]);
+
+	/* Update the checksum over the first part of the EEPROM if needed */
+	if(first_word <= EEPROM_CHECKSUM_REG)
+		e1000_update_eeprom_checksum(hw);
+
+	return 0;
 }
 
 static void
@@ -339,7 +392,7 @@
 	case E1000_DEV_ID_82545EM_COPPER:
 	case E1000_DEV_ID_82545EM_FIBER:
 	case E1000_DEV_ID_82546EB_COPPER:
-		if(wol->wolopts & WAKE_ARP)
+		if(wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))
 			return -EOPNOTSUPP;
 
 		adapter->wol = 0;
@@ -359,7 +412,6 @@
 	return 0;
 }
 
-#ifdef	ETHTOOL_PHYS_ID
 
 /* toggle LED 4 times per second = 2 "blinks" per second */
 #define E1000_ID_INTERVAL	(HZ/4)
@@ -405,7 +457,6 @@
 
 	return 0;
 }
-#endif	/* ETHTOOL_PHYS_ID */
 
 int
 e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr)
@@ -463,14 +514,12 @@
 		e1000_up(adapter);
 		return 0;
 	}
-#ifdef	ETHTOOL_PHYS_ID
 	case ETHTOOL_PHYS_ID: {
 		struct ethtool_value id;
 		if(copy_from_user(&id, addr, sizeof(id)))
 			return -EFAULT;
 		return e1000_ethtool_led_blink(adapter, &id);
 	}
-#endif	/* ETHTOOL_PHYS_ID */
 	case ETHTOOL_GLINK: {
 		struct ethtool_value link = {ETHTOOL_GLINK};
 		link.data = netif_carrier_ok(netdev);
@@ -496,6 +545,7 @@
 	case ETHTOOL_GEEPROM: {
 		struct ethtool_eeprom eeprom = {ETHTOOL_GEEPROM};
 		uint16_t eeprom_buff[256];
+		void *ptr;
 
 		if(copy_from_user(&eeprom, addr, sizeof(eeprom)))
 			return -EFAULT;
@@ -506,10 +556,23 @@
 			return -EFAULT;
 
 		addr += offsetof(struct ethtool_eeprom, data);
+		ptr = ((void *)eeprom_buff) + (eeprom.offset & 1);
 
-		if(copy_to_user(addr, eeprom_buff + eeprom.offset, eeprom.len))
+		if(copy_to_user(addr, ptr, eeprom.len))
 			return -EFAULT;
 		return 0;
+	}
+	case ETHTOOL_SEEPROM: {
+		struct ethtool_eeprom eeprom;
+
+		if(!capable(CAP_NET_ADMIN))
+			return -EPERM;
+
+		if(copy_from_user(&eeprom, addr, sizeof(eeprom)))
+			return -EFAULT;
+
+		addr += offsetof(struct ethtool_eeprom, data);
+		return e1000_ethtool_seeprom(adapter, &eeprom, addr);
 	}
 	default:
 		return -EOPNOTSUPP;
diff -Nru a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
--- a/drivers/net/e1000/e1000_hw.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/e1000/e1000_hw.c	Sat Aug 10 18:42:22 2002
@@ -107,17 +107,13 @@
     uint32_t ctrl_ext;
     uint32_t icr;
     uint32_t manc;
-    uint16_t pci_cmd_word;
 
     DEBUGFUNC("e1000_reset_hw");
     
     /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
     if(hw->mac_type == e1000_82542_rev2_0) {
-        if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
-            DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
-            pci_cmd_word = hw->pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE;
-            e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &pci_cmd_word);
-        }
+        DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
+        e1000_pci_clear_mwi(hw);
     }
 
     /* Clear interrupt mask to stop board from generating interrupts */
@@ -130,6 +126,7 @@
      */
     E1000_WRITE_REG(hw, RCTL, 0);
     E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
+    E1000_WRITE_FLUSH(hw);
 
     /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. */
     hw->tbi_compatibility_on = FALSE;
@@ -146,7 +143,11 @@
      */
     DEBUGOUT("Issuing a global reset to MAC\n");
     ctrl = E1000_READ_REG(hw, CTRL);
-    E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
+
+    if(hw->mac_type > e1000_82543)
+        E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
+    else
+        E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
 
     /* Force a reload from the EEPROM if necessary */
     if(hw->mac_type < e1000_82540) {
@@ -155,6 +156,7 @@
         ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
         ctrl_ext |= E1000_CTRL_EXT_EE_RST;
         E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+        E1000_WRITE_FLUSH(hw);
         /* Wait for EEPROM reload */
         msec_delay(2);
     } else {
@@ -176,7 +178,7 @@
     /* If MWI was previously enabled, reenable it. */
     if(hw->mac_type == e1000_82542_rev2_0) {
         if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
-            e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &hw->pci_cmd_word);
+            e1000_pci_set_mwi(hw);
     }
 }
 
@@ -197,7 +199,6 @@
     uint32_t ctrl, status;
     uint32_t i;
     int32_t ret_val;
-    uint16_t pci_cmd_word;
     uint16_t pcix_cmd_word;
     uint16_t pcix_stat_hi_word;
     uint16_t cmd_mmrbc;
@@ -240,12 +241,10 @@
 
     /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
     if(hw->mac_type == e1000_82542_rev2_0) {
-        if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE) {
-            DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
-            pci_cmd_word = hw->pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE;
-            e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &pci_cmd_word);
-        }
+        DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
+        e1000_pci_clear_mwi(hw);
         E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
+        E1000_WRITE_FLUSH(hw);
         msec_delay(5);
     }
 
@@ -257,9 +256,10 @@
     /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
     if(hw->mac_type == e1000_82542_rev2_0) {
         E1000_WRITE_REG(hw, RCTL, 0);
+        E1000_WRITE_FLUSH(hw);
         msec_delay(1);
         if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
-            e1000_write_pci_cfg(hw, PCI_COMMAND_REGISTER, &hw->pci_cmd_word);
+            e1000_pci_set_mwi(hw);
     }
 
     /* Zero out the Multicast HASH table */
@@ -505,6 +505,7 @@
 
     E1000_WRITE_REG(hw, TXCW, txcw);
     E1000_WRITE_REG(hw, CTRL, ctrl);
+    E1000_WRITE_FLUSH(hw);
 
     hw->txcw = txcw;
     msec_delay(1);
@@ -1118,6 +1119,7 @@
     tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
 
     E1000_WRITE_REG(hw, TCTL, tctl);
+    E1000_WRITE_FLUSH(hw);
 }
 
 /******************************************************************************
@@ -1715,6 +1717,7 @@
      * bit), and then delay 2 microseconds.
      */
     E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
+    E1000_WRITE_FLUSH(hw);
     usec_delay(2);
 }
 
@@ -1732,6 +1735,7 @@
      * bit), and then delay 2 microseconds.
      */
     E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
+    E1000_WRITE_FLUSH(hw);
     usec_delay(2);
 }
 
@@ -1774,6 +1778,7 @@
         else ctrl &= ~E1000_CTRL_MDIO;
 
         E1000_WRITE_REG(hw, CTRL, ctrl);
+        E1000_WRITE_FLUSH(hw);
 
         usec_delay(2);
 
@@ -1782,9 +1787,6 @@
 
         mask = mask >> 1;
     }
-
-    /* Clear the data bit just before leaving this routine. */
-    ctrl &= ~E1000_CTRL_MDIO;
 }
 
 /******************************************************************************
@@ -1815,6 +1817,7 @@
     ctrl &= ~E1000_CTRL_MDIO;
 
     E1000_WRITE_REG(hw, CTRL, ctrl);
+    E1000_WRITE_FLUSH(hw);
 
     /* Raise and Lower the clock before reading in the data. This accounts for
      * the turnaround bits. The first clock occurred when we clocked out the
@@ -1835,9 +1838,6 @@
     e1000_raise_mdi_clk(hw, &ctrl);
     e1000_lower_mdi_clk(hw, &ctrl);
 
-    /* Clear the MDIO bit just before leaving this routine. */
-    ctrl &= ~E1000_CTRL_MDIO;
-
     return data;
 }
 
@@ -2011,8 +2011,10 @@
          */
         ctrl = E1000_READ_REG(hw, CTRL);
         E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
+        E1000_WRITE_FLUSH(hw);
         msec_delay(10);
         E1000_WRITE_REG(hw, CTRL, ctrl);
+        E1000_WRITE_FLUSH(hw);
     } else {
         /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
          * bit to put the PHY into reset. Then, take it out of reset.
@@ -2021,9 +2023,11 @@
         ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
         ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
         E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+        E1000_WRITE_FLUSH(hw);
         msec_delay(10);
         ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
         E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+        E1000_WRITE_FLUSH(hw);
     }
     usec_delay(150);
 }
@@ -2226,6 +2230,7 @@
      */
     *eecd = *eecd | E1000_EECD_SK;
     E1000_WRITE_REG(hw, EECD, *eecd);
+    E1000_WRITE_FLUSH(hw);
     usec_delay(50);
 }
 
@@ -2244,6 +2249,7 @@
      */
     *eecd = *eecd & ~E1000_EECD_SK;
     E1000_WRITE_REG(hw, EECD, *eecd);
+    E1000_WRITE_FLUSH(hw);
     usec_delay(50);
 }
 
@@ -2281,6 +2287,7 @@
             eecd |= E1000_EECD_DI;
 
         E1000_WRITE_REG(hw, EECD, eecd);
+        E1000_WRITE_FLUSH(hw);
 
         usec_delay(50);
 
@@ -2375,24 +2382,71 @@
     /* Deselct EEPROM */
     eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
     E1000_WRITE_REG(hw, EECD, eecd);
+    E1000_WRITE_FLUSH(hw);
     usec_delay(50);
 
     /* Clock high */
     eecd |= E1000_EECD_SK;
     E1000_WRITE_REG(hw, EECD, eecd);
+    E1000_WRITE_FLUSH(hw);
     usec_delay(50);
 
     /* Select EEPROM */
     eecd |= E1000_EECD_CS;
     E1000_WRITE_REG(hw, EECD, eecd);
+    E1000_WRITE_FLUSH(hw);
     usec_delay(50);
 
     /* Clock low */
     eecd &= ~E1000_EECD_SK;
     E1000_WRITE_REG(hw, EECD, eecd);
+    E1000_WRITE_FLUSH(hw);
+    usec_delay(50);
+}
+
+/******************************************************************************
+ * Raises then lowers the EEPROM's clock pin
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_clock_eeprom(struct e1000_hw *hw)
+{
+    uint32_t eecd;
+
+    eecd = E1000_READ_REG(hw, EECD);
+
+    /* Rising edge of clock */
+    eecd |= E1000_EECD_SK;
+    E1000_WRITE_REG(hw, EECD, eecd);
+    E1000_WRITE_FLUSH(hw);
+    usec_delay(50);
+
+    /* Falling edge of clock */
+    eecd &= ~E1000_EECD_SK;
+    E1000_WRITE_REG(hw, EECD, eecd);
+    E1000_WRITE_FLUSH(hw);
     usec_delay(50);
 }
 
+/******************************************************************************
+ * Terminates a command by lowering the EEPROM's chip select pin
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_cleanup_eeprom(struct e1000_hw *hw)
+{
+    uint32_t eecd;
+
+    eecd = E1000_READ_REG(hw, EECD);
+
+    eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
+
+    E1000_WRITE_REG(hw, EECD, eecd);
+
+    e1000_clock_eeprom(hw);
+}
 
 /******************************************************************************
  * Reads a 16 bit word from the EEPROM.
@@ -2495,6 +2549,152 @@
 }
 
 /******************************************************************************
+ * Calculates the EEPROM checksum and writes it to the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA.
+ * Writes the difference to word offset 63 of the EEPROM.
+ *****************************************************************************/
+int32_t
+e1000_update_eeprom_checksum(struct e1000_hw *hw)
+{
+    uint16_t checksum = 0;
+    uint16_t i, eeprom_data;
+
+    DEBUGFUNC("e1000_update_eeprom_checksum");
+
+    for(i = 0; i < EEPROM_CHECKSUM_REG; i++) {
+        if(e1000_read_eeprom(hw, i, &eeprom_data) < 0) {
+            DEBUGOUT("EEPROM Read Error\n");
+            return -E1000_ERR_EEPROM;
+        }
+        checksum += eeprom_data;
+    }
+    checksum = (uint16_t) EEPROM_SUM - checksum;
+    if(e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, checksum) < 0) {
+        DEBUGOUT("EEPROM Write Error\n");
+        return -E1000_ERR_EEPROM;
+    }
+    return 0;
+}
+
+/******************************************************************************
+ * Writes a 16 bit word to a given offset in the EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * offset - offset within the EEPROM to be written to
+ * data - 16 bit word to be writen to the EEPROM
+ *
+ * If e1000_update_eeprom_checksum is not called after this function, the 
+ * EEPROM will most likely contain an invalid checksum.
+ *****************************************************************************/
+int32_t
+e1000_write_eeprom(struct e1000_hw *hw,
+                   uint16_t offset,
+                   uint16_t data)
+{
+    uint32_t eecd;
+    uint32_t i = 0;
+    int32_t status = 0;
+    boolean_t large_eeprom = FALSE;
+
+    DEBUGFUNC("e1000_write_eeprom");
+
+    /* Request EEPROM Access */
+    if(hw->mac_type > e1000_82544) {
+        eecd = E1000_READ_REG(hw, EECD);
+        if(eecd & E1000_EECD_SIZE) large_eeprom = TRUE;
+        eecd |= E1000_EECD_REQ;
+        E1000_WRITE_REG(hw, EECD, eecd);
+        eecd = E1000_READ_REG(hw, EECD);
+        while((!(eecd & E1000_EECD_GNT)) && (i < 100)) {
+            i++;
+            usec_delay(5);
+            eecd = E1000_READ_REG(hw, EECD);
+        }
+        if(!(eecd & E1000_EECD_GNT)) {
+            eecd &= ~E1000_EECD_REQ;
+            E1000_WRITE_REG(hw, EECD, eecd);
+            DEBUGOUT("Could not acquire EEPROM grant\n");
+            return -E1000_ERR_EEPROM;
+        }
+    }
+
+    /* Prepare the EEPROM for writing  */
+    e1000_setup_eeprom(hw);
+
+    /* Send the 9-bit (or 11-bit on large EEPROM) EWEN (write enable) command
+     * to the EEPROM (5-bit opcode plus 4/6-bit dummy). This puts the EEPROM
+     * into write/erase mode. 
+     */
+    e1000_shift_out_ee_bits(hw, EEPROM_EWEN_OPCODE, 5);
+    if(large_eeprom) 
+        e1000_shift_out_ee_bits(hw, 0, 6);
+    else
+        e1000_shift_out_ee_bits(hw, 0, 4);
+
+    /* Prepare the EEPROM */
+    e1000_standby_eeprom(hw);
+
+    /* Send the Write command (3-bit opcode + addr) */
+    e1000_shift_out_ee_bits(hw, EEPROM_WRITE_OPCODE, 3);
+    if(large_eeprom) 
+        /* If we have a 256 word EEPROM, there are 8 address bits */
+        e1000_shift_out_ee_bits(hw, offset, 8);
+    else
+        /* If we have a 64 word EEPROM, there are 6 address bits */
+        e1000_shift_out_ee_bits(hw, offset, 6);
+
+    /* Send the data */
+    e1000_shift_out_ee_bits(hw, data, 16);
+
+    /* Toggle the CS line.  This in effect tells to EEPROM to actually execute 
+     * the command in question.
+     */
+    e1000_standby_eeprom(hw);
+
+    /* Now read DO repeatedly until is high (equal to '1').  The EEEPROM will
+     * signal that the command has been completed by raising the DO signal.
+     * If DO does not go high in 10 milliseconds, then error out.
+     */
+    for(i = 0; i < 200; i++) {
+        eecd = E1000_READ_REG(hw, EECD);
+        if(eecd & E1000_EECD_DO) break;
+        usec_delay(50);
+    }
+    if(i == 200) {
+        DEBUGOUT("EEPROM Write did not complete\n");
+        status = -E1000_ERR_EEPROM;
+    }
+
+    /* Recover from write */
+    e1000_standby_eeprom(hw);
+
+    /* Send the 9-bit (or 11-bit on large EEPROM) EWDS (write disable) command
+     * to the EEPROM (5-bit opcode plus 4/6-bit dummy). This takes the EEPROM
+     * out of write/erase mode.
+     */
+    e1000_shift_out_ee_bits(hw, EEPROM_EWDS_OPCODE, 5);
+    if(large_eeprom) 
+        e1000_shift_out_ee_bits(hw, 0, 6);
+    else
+        e1000_shift_out_ee_bits(hw, 0, 4);
+
+    /* Done with writing */
+    e1000_cleanup_eeprom(hw);
+
+    /* Stop requesting EEPROM access */
+    if(hw->mac_type > e1000_82544) {
+        eecd = E1000_READ_REG(hw, EECD);
+        eecd &= ~E1000_EECD_REQ;
+        E1000_WRITE_REG(hw, EECD, eecd);
+    }
+
+    return status;
+}
+
+/******************************************************************************
  * Reads the adapter's part number from the EEPROM
  *
  * hw - Struct containing variables accessed by shared code
@@ -3333,5 +3533,42 @@
     }
     hw->bus_width = (status & E1000_STATUS_BUS64) ?
                     e1000_bus_width_64 : e1000_bus_width_32;
+}
+/******************************************************************************
+ * Reads a value from one of the devices registers using port I/O (as opposed
+ * memory mapped I/O). Only 82544 and newer devices support port I/O.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * offset - offset to read from
+ *****************************************************************************/
+uint32_t
+e1000_read_reg_io(struct e1000_hw *hw,
+                  uint32_t offset)
+{
+    uint32_t io_addr = hw->io_base;
+    uint32_t io_data = hw->io_base + 4;
+
+    e1000_io_write(hw, io_addr, offset);
+    return e1000_io_read(hw, io_data);
+}
+
+/******************************************************************************
+ * Writes a value to one of the devices registers using port I/O (as opposed to
+ * memory mapped I/O). Only 82544 and newer devices support port I/O.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * offset - offset to write to
+ * value - value to write
+ *****************************************************************************/
+void
+e1000_write_reg_io(struct e1000_hw *hw,
+                   uint32_t offset,
+                   uint32_t value)
+{
+    uint32_t io_addr = hw->io_base;
+    uint32_t io_data = hw->io_base + 4;
+
+    e1000_io_write(hw, io_addr, offset);
+    e1000_io_write(hw, io_data, value);
 }
 
diff -Nru a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
--- a/drivers/net/e1000/e1000_hw.h	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/e1000/e1000_hw.h	Sat Aug 10 18:42:23 2002
@@ -236,6 +236,8 @@
 /* EEPROM Functions */
 int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t *data);
 int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
+int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw);
+int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t data);
 int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num);
 int32_t e1000_read_mac_addr(struct e1000_hw * hw);
 
@@ -262,8 +264,19 @@
 void e1000_update_adaptive(struct e1000_hw *hw);
 void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats, uint32_t frame_len, uint8_t * mac_addr);
 void e1000_get_bus_info(struct e1000_hw *hw);
+void e1000_pci_set_mwi(struct e1000_hw *hw);
+void e1000_pci_clear_mwi(struct e1000_hw *hw);
 void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
 void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
+/* Port I/O is only supported on 82544 and newer */
+uint32_t e1000_io_read(struct e1000_hw *hw, uint32_t port);
+uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset);
+void e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value);
+void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
+#define E1000_READ_REG_IO(a, reg) \
+    e1000_read_reg_io((a), E1000_##reg)
+#define E1000_WRITE_REG_IO(a, reg, val) \
+    e1000_write_reg_io((a), E1000_##reg, val)
 
 /* PCI Device IDs */
 #define E1000_DEV_ID_82542          0x1000
@@ -878,6 +891,7 @@
     e1000_bus_speed bus_speed;
     e1000_bus_width bus_width;
     e1000_bus_type bus_type;
+    uint32_t io_base;
     uint32_t phy_id;
     uint32_t phy_addr;
     uint32_t original_fc;
@@ -1333,6 +1347,7 @@
 #define EEPROM_EWDS_OPCODE  0x10 /* EERPOM erast/write disable */
 
 /* EEPROM Word Offsets */
+#define EEPROM_COMPAT              0x0003
 #define EEPROM_ID_LED_SETTINGS     0x0004
 #define EEPROM_INIT_CONTROL1_REG   0x000A
 #define EEPROM_INIT_CONTROL2_REG   0x000F
@@ -1343,9 +1358,9 @@
 #define ID_LED_RESERVED_0000 0x0000
 #define ID_LED_RESERVED_FFFF 0xFFFF
 #define ID_LED_DEFAULT       ((ID_LED_OFF1_ON2 << 12) | \
-		              (ID_LED_OFF1_OFF2 << 8) | \
-		              (ID_LED_DEF1_DEF2 << 4) | \
-			      (ID_LED_DEF1_DEF2))
+                              (ID_LED_OFF1_OFF2 << 8) | \
+                              (ID_LED_DEF1_DEF2 << 4) | \
+                              (ID_LED_DEF1_DEF2))
 #define ID_LED_DEF1_DEF2     0x1
 #define ID_LED_DEF1_ON2      0x2
 #define ID_LED_DEF1_OFF2     0x3
@@ -1355,6 +1370,10 @@
 #define ID_LED_OFF1_DEF2     0x7
 #define ID_LED_OFF1_ON2      0x8
 #define ID_LED_OFF1_OFF2     0x9
+
+/* Mask bits for fields in Word 0x03 of the EEPROM */
+#define EEPROM_COMPAT_SERVER 0x0400
+#define EEPROM_COMPAT_CLIENT 0x0200
 
 /* Mask bits for fields in Word 0x0a of the EEPROM */
 #define EEPROM_WORD0A_ILOS   0x0010
diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/e1000/e1000_main.c	Sat Aug 10 18:42:22 2002
@@ -70,13 +70,35 @@
   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 *******************************************************************************/
-
 #define __E1000_MAIN__
 #include "e1000.h"
 
+/* Change Log
+ *
+ * 4.3.2       7/5/02
+ *   o Bug fix: perform controller reset using I/O rather than mmio because
+ *     some chipsets try to perform a 64-bit write, but the controller ignores
+ *     the upper 32-bit write once the reset is intiated by the lower 32-bit
+ *     write, causing a master abort.
+ *   o Bug fix: fixed jumbo frames sized from 1514 to 2048.
+ *   o ASF support: disable ARP when driver is loaded or resumed; enable when 
+ *     driver is removed or suspended.
+ *   o Bug fix: changed default setting for RxIntDelay to 0 for 82542/3/4
+ *     controllers to workaround h/w errata where controller will hang when
+ *     RxIntDelay <> 0 under certian network conditions.
+ *   o Clean up: removed unused and undocumented user-settable settings for
+ *     PHY.
+ *   o Bug fix: ethtool GEEPROM was using byte address rather than word
+ *     addressing.
+ *   o Feature: added support for ethtool SEEPROM.
+ *   o Feature: added support for entropy pool.
+ *
+ * 4.2.17      5/30/02
+ */
+
 char e1000_driver_name[] = "e1000";
 char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-char e1000_driver_version[] = "4.2.17-k1";
+char e1000_driver_version[] = "4.3.2-k1";
 char e1000_copyright[] = "Copyright (c) 1999-2002 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
@@ -156,7 +178,6 @@
 static void e1000_update_phy_info(unsigned long data);
 static void e1000_watchdog(unsigned long data);
 static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
-static void e1000_tx_timeout(struct net_device *dev);
 static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
 static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
 static int e1000_set_mac(struct net_device *netdev, void *p);
@@ -173,11 +194,11 @@
 static inline void e1000_rx_checksum(struct e1000_adapter *adapter,
                                      struct e1000_rx_desc *rx_desc,
                                      struct sk_buff *skb);
-#ifdef NETIF_F_HW_VLAN_TX
+static void e1000_tx_timeout(struct net_device *dev);
+
 static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
 static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
 static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
-#endif
 
 static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
 static int e1000_suspend(struct pci_dev *pdev, uint32_t state);
@@ -186,9 +207,9 @@
 #endif
 
 struct notifier_block e1000_notifier = {
-	notifier_call:	e1000_notify_reboot,
-	next:		NULL,
-	priority:	0
+	.notifier_call	= e1000_notify_reboot,
+	.next		= NULL,
+	.priority	= 0
 };
 
 /* Exported from other modules */
@@ -199,14 +220,14 @@
 extern int e1000_ethtool_ioctl(struct net_device *netdev, struct ifreq *ifr);
 
 static struct pci_driver e1000_driver = {
-	name:     e1000_driver_name,
-	id_table: e1000_pci_tbl,
-	probe:    e1000_probe,
-	remove:   __devexit_p(e1000_remove),
+	.name     = e1000_driver_name,
+	.id_table = e1000_pci_tbl,
+	.probe    = e1000_probe,
+	.remove   = __devexit_p(e1000_remove),
 	/* Power Managment Hooks */
 #ifdef CONFIG_PM
-	suspend:  e1000_suspend,
-	resume:   e1000_resume
+	.suspend  = e1000_suspend,
+	.resume   = e1000_resume
 #endif
 };
 
@@ -260,7 +281,7 @@
 {
 	struct net_device *netdev = adapter->netdev;
 
-	if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ,
+	if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ | SA_SAMPLE_RANDOM,
 	               netdev->name, netdev))
 		return -1;
 
@@ -380,6 +401,15 @@
 	if(!adapter->hw.hw_addr)
 		goto err_ioremap;
 
+	for(i = BAR_1; i <= BAR_5; i++) {
+		if(pci_resource_len(pdev, i) == 0)
+			continue;
+		if(pci_resource_flags(pdev, i) & IORESOURCE_IO) {
+			adapter->hw.io_base = pci_resource_start(pdev, i);
+			break;
+		}
+	}
+
 	netdev->open = &e1000_open;
 	netdev->stop = &e1000_close;
 	netdev->hard_start_xmit = &e1000_xmit_frame;
@@ -390,14 +420,13 @@
 	netdev->do_ioctl = &e1000_ioctl;
 	netdev->tx_timeout = &e1000_tx_timeout;
 	netdev->watchdog_timeo = HZ;
-#ifdef NETIF_F_HW_VLAN_TX
 	netdev->vlan_rx_register = e1000_vlan_rx_register;
 	netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
 	netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
-#endif
 
 	netdev->irq = pdev->irq;
-	netdev->base_addr = mmio_start;
+	netdev->mem_start = mmio_start;
+	netdev->base_addr = adapter->hw.io_base;
 
 	adapter->bd_number = cards_found;
 	adapter->id_string = e1000_strings[ent->driver_data];
@@ -407,15 +436,11 @@
 	e1000_sw_init(adapter);
 
 	if(adapter->hw.mac_type >= e1000_82543) {
-#ifdef NETIF_F_HW_VLAN_TX
 		netdev->features = NETIF_F_SG |
 			           NETIF_F_HW_CSUM |
 		       	           NETIF_F_HW_VLAN_TX |
 		                   NETIF_F_HW_VLAN_RX |
 				   NETIF_F_HW_VLAN_FILTER;
-#else
-		netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM;
-#endif
 	} else {
 		netdev->features = NETIF_F_SG;
 	}
@@ -509,7 +534,16 @@
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev->priv;
-
+	uint32_t manc;
+	
+	if(adapter->hw.mac_type >= e1000_82540) {
+		manc = E1000_READ_REG(&adapter->hw, MANC);
+		if(manc & E1000_MANC_SMBUS_EN) {
+			manc |= E1000_MANC_ARP_EN;
+			E1000_WRITE_REG(&adapter->hw, MANC, manc);
+		}
+	}
+		
 	unregister_netdev(netdev);
 
 	e1000_phy_hw_reset(&adapter->hw);
@@ -540,18 +574,12 @@
 
 	/* PCI config space info */
 
-	uint16_t *vendor = &hw->vendor_id;
-	uint16_t *device = &hw->device_id;
-	uint16_t *subvendor = &hw->subsystem_vendor_id;
-	uint16_t *subsystem = &hw->subsystem_id;
-	uint8_t  *revision  = &hw->revision_id;
-
-	pci_read_config_word(pdev, PCI_VENDOR_ID, vendor);
-	pci_read_config_word(pdev, PCI_DEVICE_ID, device);
-	pci_read_config_byte(pdev, PCI_REVISION_ID, revision);
-	pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, subvendor);
-	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, subsystem);
-
+	pci_read_config_word(pdev, PCI_VENDOR_ID, &hw->vendor_id);
+	pci_read_config_word(pdev, PCI_DEVICE_ID, &hw->device_id);
+	pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, 
+	                     &hw->subsystem_vendor_id);
+	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &hw->subsystem_id);
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id);
 	pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
 
 	adapter->rx_buffer_len = E1000_RXBUFFER_2048;
@@ -561,9 +589,9 @@
 
 	/* identify the MAC */
 
-	switch (*device) {
+	switch (hw->device_id) {
 	case E1000_DEV_ID_82542:
-		switch (*revision) {
+		switch (hw->revision_id) {
 		case E1000_82542_2_0_REV_ID:
 			hw->mac_type = e1000_82542_rev2_0;
 			break;
@@ -597,7 +625,7 @@
 		hw->mac_type = e1000_82546;
 		break;
 	default:
-		/* should never have loaded on this device */
+		E1000_ERR("Should never have loaded on this device\n");
 		BUG();
 	}
 
@@ -630,6 +658,13 @@
 	hw->tbi_compatibility_en = TRUE;
 	hw->adaptive_ifs = TRUE;
 
+	/* Copper options */
+	
+	if(hw->media_type == e1000_media_type_copper) {
+		hw->mdix = AUTO_ALL_MODES;
+		hw->disable_polarity_correction = FALSE;
+	}
+
 	atomic_set(&adapter->irq_sem, 1);
 	spin_lock_init(&adapter->stats_lock);
 }
@@ -1089,20 +1124,16 @@
 static void
 e1000_enter_82542_rst(struct e1000_adapter *adapter)
 {
-	struct pci_dev *pdev = adapter->pdev;
 	struct net_device *netdev = adapter->netdev;
-	uint16_t pci_command_word = adapter->hw.pci_cmd_word;
 	uint32_t rctl;
 
-	if(pci_command_word & PCI_COMMAND_INVALIDATE) {
-		pci_command_word &= ~PCI_COMMAND_INVALIDATE;
-		pci_write_config_word(pdev, PCI_COMMAND, pci_command_word);
-	}
+	e1000_pci_clear_mwi(&adapter->hw);
 
 	rctl = E1000_READ_REG(&adapter->hw, RCTL);
 	rctl |= E1000_RCTL_RST;
 	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
-	msec_delay(5);
+	E1000_WRITE_FLUSH(&adapter->hw);
+	mdelay(5);
 
 	if(netif_running(netdev))
 		e1000_clean_rx_ring(adapter);
@@ -1111,18 +1142,17 @@
 static void
 e1000_leave_82542_rst(struct e1000_adapter *adapter)
 {
-	struct pci_dev *pdev = adapter->pdev;
 	struct net_device *netdev = adapter->netdev;
-	uint16_t pci_command_word = adapter->hw.pci_cmd_word;
 	uint32_t rctl;
 
 	rctl = E1000_READ_REG(&adapter->hw, RCTL);
 	rctl &= ~E1000_RCTL_RST;
 	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
-	msec_delay(5);
+	E1000_WRITE_FLUSH(&adapter->hw);
+	mdelay(5);
 
-	if(pci_command_word & PCI_COMMAND_INVALIDATE)
-		pci_write_config_word(pdev, PCI_COMMAND, pci_command_word);
+	if(adapter->hw.pci_cmd_word & PCI_COMMAND_INVALIDATE)
+		e1000_pci_set_mwi(&adapter->hw);
 
 	if(netif_running(netdev)) {
 		e1000_configure_rx(adapter);
@@ -1429,6 +1459,7 @@
 
 	tx_ring->next_to_use = i;
 	E1000_WRITE_REG(&adapter->hw, TDT, i);
+	E1000_WRITE_FLUSH(&adapter->hw);
 }
 
 #define TXD_USE_COUNT(S, X) (((S) / (X)) + (((S) % (X)) ? 1 : 0))
@@ -1458,12 +1489,10 @@
 	if(e1000_tx_csum(adapter, skb))
 		tx_flags |= E1000_TX_FLAGS_CSUM;
 
-#ifdef NETIF_F_HW_VLAN_TX
 	if(adapter->vlgrp && vlan_tx_tag_present(skb)) {
 		tx_flags |= E1000_TX_FLAGS_VLAN;
 		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
 	}
-#endif
 
 	count = e1000_tx_map(adapter, skb);
 
@@ -1525,7 +1554,7 @@
 		return -EINVAL;
 	}
 
-	if(max_frame <= E1000_RXBUFFER_2048) {
+	if(max_frame <= MAXIMUM_ETHERNET_FRAME_SIZE) {
 		adapter->rx_buffer_len = E1000_RXBUFFER_2048;
 
 	} else if(adapter->hw.mac_type < e1000_82543) {
@@ -1699,6 +1728,7 @@
 {
 	atomic_inc(&adapter->irq_sem);
 	E1000_WRITE_REG(&adapter->hw, IMC, ~0);
+	E1000_WRITE_FLUSH(&adapter->hw);
 	synchronize_irq(adapter->netdev->irq);
 }
 
@@ -1710,8 +1740,10 @@
 static inline void
 e1000_irq_enable(struct e1000_adapter *adapter)
 {
-	if(atomic_dec_and_test(&adapter->irq_sem))
+	if(atomic_dec_and_test(&adapter->irq_sem)) {
 		E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK);
+		E1000_WRITE_FLUSH(&adapter->hw);
+	}
 }
 
 /**
@@ -1779,8 +1811,7 @@
 			tx_ring->buffer_info[i].skb = NULL;
 		}
 
-		memset(tx_desc, 0, sizeof(struct e1000_tx_desc));
-		mb();
+		tx_desc->upper.data = 0;
 
 		i = (i + 1) % tx_ring->count;
 		tx_desc = E1000_TX_DESC(*tx_ring, i);
@@ -1833,8 +1864,7 @@
 			E1000_DBG("Receive packet consumed multiple buffers\n");
 
 			dev_kfree_skb_irq(skb);
-			memset(rx_desc, 0, sizeof(struct e1000_rx_desc));
-			mb();
+			rx_desc->status = 0;
 			rx_ring->buffer_info[i].skb = NULL;
 
 			i = (i + 1) % rx_ring->count;
@@ -1862,8 +1892,7 @@
 			} else {
 
 				dev_kfree_skb_irq(skb);
-				memset(rx_desc, 0, sizeof(struct e1000_rx_desc));
-				mb();
+				rx_desc->status = 0;
 				rx_ring->buffer_info[i].skb = NULL;
 
 				i = (i + 1) % rx_ring->count;
@@ -1880,20 +1909,15 @@
 		e1000_rx_checksum(adapter, rx_desc, skb);
 
 		skb->protocol = eth_type_trans(skb, netdev);
-#ifdef NETIF_F_HW_VLAN_TX
 		if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) {
 			vlan_hwaccel_rx(skb, adapter->vlgrp,
 				(rx_desc->special & E1000_RXD_SPC_VLAN_MASK));
 		} else {
 			netif_rx(skb);
 		}
-#else
-		netif_rx(skb);
-#endif
 		netdev->last_rx = jiffies;
 
-		memset(rx_desc, 0, sizeof(struct e1000_rx_desc));
-		mb();
+		rx_desc->status = 0;
 		rx_ring->buffer_info[i].skb = NULL;
 
 		i = (i + 1) % rx_ring->count;
@@ -2018,6 +2042,22 @@
 }
 
 void
+e1000_pci_set_mwi(struct e1000_hw *hw)
+{
+	struct e1000_adapter *adapter = hw->back;
+
+	pci_set_mwi(adapter->pdev);
+}
+
+void
+e1000_pci_clear_mwi(struct e1000_hw *hw)
+{
+	struct e1000_adapter *adapter = hw->back;
+
+	pci_clear_mwi(adapter->pdev);
+}
+
+void
 e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
 {
 	struct e1000_adapter *adapter = hw->back;
@@ -2033,7 +2073,18 @@
 	pci_write_config_word(adapter->pdev, reg, *value);
 }
 
-#ifdef NETIF_F_HW_VLAN_TX
+uint32_t
+e1000_io_read(struct e1000_hw *hw, uint32_t port)
+{
+	return inl(port);
+}
+
+void
+e1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value)
+{
+	outl(value, port);
+}
+
 static void
 e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
 {
@@ -2109,7 +2160,6 @@
 	vfta &= ~(1 << (vid & 0x1F));
 	e1000_write_vfta(&adapter->hw, index, vfta);
 }
-#endif
 
 static int
 e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
@@ -2133,7 +2183,7 @@
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev->priv;
-	uint32_t ctrl, ctrl_ext, rctl;
+	uint32_t ctrl, ctrl_ext, rctl, manc;
 
 	netif_device_detach(netdev);
 
@@ -2171,7 +2221,15 @@
 	}
 
 	pci_save_state(pdev, adapter->pci_state);
-	pci_set_power_state(pdev, 3);
+
+	if(adapter->hw.mac_type >= e1000_82540) {
+		manc = E1000_READ_REG(&adapter->hw, MANC);
+		if(manc & E1000_MANC_SMBUS_EN) {
+			manc |= E1000_MANC_ARP_EN;
+			E1000_WRITE_REG(&adapter->hw, MANC, manc);
+		}
+	} else
+		pci_set_power_state(pdev, 3);
 
 	return 0;
 }
@@ -2182,6 +2240,7 @@
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev->priv;
+	uint32_t manc;
 
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev, adapter->pci_state);
@@ -2195,6 +2254,12 @@
 		e1000_up(adapter);
 
 	netif_device_attach(netdev);
+
+	if(adapter->hw.mac_type >= e1000_82540) {
+		manc = E1000_READ_REG(&adapter->hw, MANC);
+		manc &= ~(E1000_MANC_ARP_EN);
+		E1000_WRITE_REG(&adapter->hw, MANC, manc);
+	}
 
 	return 0;
 }
diff -Nru a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h
--- a/drivers/net/e1000/e1000_osdep.h	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/e1000/e1000_osdep.h	Sat Aug 10 18:42:21 2002
@@ -88,7 +88,8 @@
 #define usec_delay(x) udelay(x)
 #ifndef msec_delay
 #define msec_delay(x)	do { if(in_interrupt()) { \
-	                	mdelay(x); \
+				/* Don't mdelay in interrupt context! */ \
+	                	BUG(); \
 			} else { \
 				set_current_state(TASK_UNINTERRUPTIBLE); \
 				schedule_timeout((x * HZ)/1000); \
@@ -139,5 +140,7 @@
     ((a)->mac_type >= e1000_82543) ? \
         readl((a)->hw_addr + E1000_##reg + ((offset) << 2)) : \
         readl((a)->hw_addr + E1000_82542_##reg + ((offset) << 2)))
+
+#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS);
 
 #endif /* _E1000_OSDEP_H_ */
diff -Nru a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
--- a/drivers/net/e1000/e1000_param.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/e1000/e1000_param.c	Sat Aug 10 18:42:21 2002
@@ -196,38 +196,11 @@
  *
  * Valid Range: 0-65535
  *
- * Default Value: 64/128
+ * Default Value: 0/128
  */
 
 E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
 
-/* MDI-X Support Enable/Disable - Applies only to Copper PHY
- *
- * Valid Range: 0, 3
- *  - 0 - Auto in all modes
- *  - 1 - MDI
- *  - 2 - MDI-X
- *  - 3 - Auto in 1000 Base-T mode (MDI in 10 Base-T and 100 Base-T)
- *
- * Default Value: 0 (Auto)
- */
-
-E1000_PARAM(MdiX, "Set MDI/MDI-X Mode");
-
-/* Automatic Correction of Reversed Cable Polarity Enable/Disable
- * This setting applies only to Copper PHY
- *
- * Valid Range: 0, 1
- *  - 0 - Disabled
- *  - 1 - Enabled
- *
- * Default Value: 1 (Enabled)
- */
-
-E1000_PARAM(DisablePolarityCorrection,
-	"Disable or enable Automatic Correction for Reversed Cable Polarity");
-
-
 #define AUTONEG_ADV_DEFAULT  0x2F
 #define AUTONEG_ADV_MASK     0x2F
 #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
@@ -242,16 +215,11 @@
 #define MIN_RXD                       80
 #define MAX_82544_RXD               4096
 
-#define DEFAULT_RDTR                  64
+#define DEFAULT_RDTR                   0
 #define DEFAULT_RADV                 128
 #define MAX_RXDELAY               0xFFFF
 #define MIN_RXDELAY                    0
 
-#define DEFAULT_MDIX                   0
-#define MAX_MDIX                       3
-#define MIN_MDIX                       0
-
-
 struct e1000_option {
 	enum { enable_option, range_option, list_option } type;
 	char *name;
@@ -345,11 +313,11 @@
 
 	{ /* Transmit Descriptor Count */
 		struct e1000_option opt = {
-			type: range_option,
-			name: "Transmit Descriptors",
-			err:  "using default of " __MODULE_STRING(DEFAULT_TXD),
-			def:  DEFAULT_TXD,
-			arg: { r: { min: MIN_TXD }}
+			.type = range_option,
+			.name = "Transmit Descriptors",
+			.err  = "using default of " __MODULE_STRING(DEFAULT_TXD),
+			.def  = DEFAULT_TXD,
+			.arg  = { r: { min: MIN_TXD }}
 		};
 		struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
 		e1000_mac_type mac_type = adapter->hw.mac_type;
@@ -361,11 +329,11 @@
 	}
 	{ /* Receive Descriptor Count */
 		struct e1000_option opt = {
-			type: range_option,
-			name: "Receive Descriptors",
-			err:  "using default of " __MODULE_STRING(DEFAULT_RXD),
-			def:  DEFAULT_RXD,
-			arg: { r: { min: MIN_RXD }}
+			.type = range_option,
+			.name = "Receive Descriptors",
+			.err  = "using default of " __MODULE_STRING(DEFAULT_RXD),
+			.def  = DEFAULT_RXD,
+			.arg  = { r: { min: MIN_RXD }}
 		};
 		struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
 		e1000_mac_type mac_type = adapter->hw.mac_type;
@@ -377,10 +345,10 @@
 	}
 	{ /* Checksum Offload Enable/Disable */
 		struct e1000_option opt = {
-			type: enable_option,
-			name: "Checksum Offload",
-			err:  "defaulting to Enabled",
-			def:  OPTION_ENABLED
+			.type = enable_option,
+			.name = "Checksum Offload",
+			.err  = "defaulting to Enabled",
+			.def  = OPTION_ENABLED
 		};
 		
 		int rx_csum = XsumRX[bd];
@@ -397,11 +365,11 @@
 			 { e1000_fc_default, "Flow Control Hardware Default" }};
 
 		struct e1000_option opt = {
-			type: list_option,
-			name: "Flow Control",
-			err:  "reading default settings from EEPROM",
-			def:  e1000_fc_default,
-			arg: { l: { nr: ARRAY_SIZE(fc_list), p: fc_list }}
+			.type = list_option,
+			.name = "Flow Control",
+			.err  = "reading default settings from EEPROM",
+			.def  = e1000_fc_default,
+			.arg  = { l: { nr: ARRAY_SIZE(fc_list), p: fc_list }}
 		};
 
 		int fc = FlowControl[bd];
@@ -412,9 +380,9 @@
 		char *rdtr = "using default of " __MODULE_STRING(DEFAULT_RDTR);
 		char *radv = "using default of " __MODULE_STRING(DEFAULT_RADV);
 		struct e1000_option opt = {
-			type: range_option,
-			name: "Receive Interrupt Delay",
-			arg: { r: { min: MIN_RXDELAY, max: MAX_RXDELAY }}
+			.type = range_option,
+			.name = "Receive Interrupt Delay",
+			.arg  = { r: { min: MIN_RXDELAY, max: MAX_RXDELAY }}
 		};
 		e1000_mac_type mac_type = adapter->hw.mac_type;
 		opt.def = mac_type < e1000_82540 ? DEFAULT_RDTR : DEFAULT_RADV;
@@ -483,11 +451,11 @@
 		                                      {  SPEED_100, "" },
 		                                      { SPEED_1000, "" }};
 		struct e1000_option opt = {
-			type: list_option,
-			name: "Speed",
-			err:  "parameter ignored",
-			def:  0,
-			arg: { l: { nr: ARRAY_SIZE(speed_list), p: speed_list }}
+			.type = list_option,
+			.name = "Speed",
+			.err  = "parameter ignored",
+			.def  = 0,
+			.arg  = { l: { nr: ARRAY_SIZE(speed_list), p: speed_list }}
 		};
 
 		speed = Speed[bd];
@@ -498,11 +466,11 @@
 		                                     { HALF_DUPLEX, "" },
 		                                     { FULL_DUPLEX, "" }};
 		struct e1000_option opt = {
-			type: list_option,
-			name: "Duplex",
-			err:  "parameter ignored",
-			def:  0,
-			arg: { l: { nr: ARRAY_SIZE(dplx_list), p: dplx_list }}
+			.type = list_option,
+			.name = "Duplex",
+			.err  = "parameter ignored",
+			.def  = 0,
+			.arg  = { l: { nr: ARRAY_SIZE(dplx_list), p: dplx_list }}
 		};
 
 		dplx = Duplex[bd];
@@ -550,11 +518,11 @@
 			 { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" }};
 
 		struct e1000_option opt = {
-			type: list_option,
-			name: "AutoNeg",
-			err:  "parameter ignored",
-			def:  AUTONEG_ADV_DEFAULT,
-			arg: { l: { nr: ARRAY_SIZE(an_list), p: an_list }}
+			.type = list_option,
+			.name = "AutoNeg",
+			.err  = "parameter ignored",
+			.def  = AUTONEG_ADV_DEFAULT,
+			.arg  = { l: { nr: ARRAY_SIZE(an_list), p: an_list }}
 		};
 
 		int an = AutoNeg[bd];
@@ -646,36 +614,6 @@
 		BUG();
 	}
 
-	/* a few other copper only options */
-
-	{ /* MDI/MDI-X */
-		struct e1000_option opt = {
-			type: range_option,
-			name: "MDI/MDI-X",
-			err:  "using default of " __MODULE_STRING(DEFAULT_MDIX),
-			def:  DEFAULT_MDIX,
-			arg: { r: { min: MIN_MDIX, max: MAX_MDIX }}
-		};
-
-		int mdix = MdiX[bd];
-		e1000_validate_option(&mdix, &opt);
-		adapter->hw.mdix = mdix;
-	}
-	{ /* Automatic Correction for Reverse Cable Polarity */
-	  /* option is actually to disable polarity correction,
-	   * so setting to OPTION_ENABLED turns the hardware feature off */
-		struct e1000_option opt = {
-			type: enable_option,
-			name: "Disable Polarity Correction",
-			err:  "defaulting to Disabled",
-			def:  OPTION_DISABLED,
-		};
-
-		int dpc = DisablePolarityCorrection[bd];
-		e1000_validate_option(&dpc, &opt);
-		adapter->hw.disable_polarity_correction = dpc;
-	}
-	
 	/* Speed, AutoNeg and MDI/MDI-X must all play nice */
 	if (e1000_validate_mdi_setting(&(adapter->hw)) < 0) {
 		printk(KERN_INFO "Speed, AutoNeg and MDI-X specifications are "
diff -Nru a/drivers/net/eepro.c b/drivers/net/eepro.c
--- a/drivers/net/eepro.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/eepro.c	Sat Aug 10 18:42:23 2002
@@ -23,6 +23,8 @@
 	This is a compatibility hardware problem.
 
 	Versions:
+	0.13a   in memory shortage, drop packets also in board
+		(Michael Westermann <mw@microdata-pos.de>, 07/30/2002)
 	0.13    irq sharing, rewrote probe function, fixed a nasty bug in
 		hardware_send_packet and a major cleanup (aris, 11/08/2001)
 	0.12d	fixing a problem with single card detected as eight eth devices
@@ -665,37 +667,37 @@
 
 	i = inb(dev->base_addr + ID_REG);
 	printk(KERN_DEBUG " id: %#x ",i);
-	printk(KERN_DEBUG " io: %#x ", (unsigned)dev->base_addr);
+	printk(" io: %#x ", (unsigned)dev->base_addr);
 
 	switch (lp->eepro) {
 		case LAN595FX_10ISA:
-			printk(KERN_INFO "%s: Intel EtherExpress 10 ISA\n at %#x,",
+			printk("%s: Intel EtherExpress 10 ISA\n at %#x,",
 					dev->name, (unsigned)dev->base_addr);
 			break;
 		case LAN595FX:
-			printk(KERN_INFO "%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", 
+			printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", 
 					dev->name, (unsigned)dev->base_addr);
 			break;
 		case LAN595TX:
-			printk(KERN_INFO "%s: Intel EtherExpress Pro/10 ISA at %#x,",
+			printk("%s: Intel EtherExpress Pro/10 ISA at %#x,",
 					dev->name, (unsigned)dev->base_addr);
 			break;
 		case LAN595:
-			printk(KERN_INFO "%s: Intel 82595-based lan card at %#x,", 
+			printk("%s: Intel 82595-based lan card at %#x,", 
 					dev->name, (unsigned)dev->base_addr);
 	}
 
 	for (i=0; i < 6; i++)
-		printk(KERN_INFO "%c%02x", i ? ':' : ' ', dev->dev_addr[i]);
+		printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]);
 
 	if (net_debug > 3)
 		printk(KERN_DEBUG ", %dK RCV buffer",
 				(int)(lp->rcv_ram)/1024);
 
 	if (dev->irq > 2)
-		printk(KERN_INFO ", IRQ %d, %s.\n", dev->irq, ifmap[dev->if_port]);
+		printk(", IRQ %d, %s.\n", dev->irq, ifmap[dev->if_port]);
 	else 
-		printk(KERN_INFO ", %s.\n", ifmap[dev->if_port]);
+		printk(", %s.\n", ifmap[dev->if_port]);
 
 	if (net_debug > 3) {
 		i = read_eeprom(dev->base_addr, 5, dev);
@@ -1584,6 +1586,10 @@
 			if (skb == NULL) {
 				printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
 				lp->stats.rx_dropped++;
+				rcv_car = lp->rx_start + RCV_HEADER + rcv_size;
+				lp->rx_start = rcv_next_frame;
+				outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG);
+
 				break;
 			}
 			skb->dev = dev;
diff -Nru a/drivers/net/eepro100.c b/drivers/net/eepro100.c
--- a/drivers/net/eepro100.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/eepro100.c	Sat Aug 10 18:42:23 2002
@@ -1,7 +1,5 @@
 /* drivers/net/eepro100.c: An Intel i82557-559 Ethernet driver for Linux. */
 /*
-   NOTICE: For use with late 2.3 kernels only.
-   May not compile for kernels 2.3.43-47.
 	Written 1996-1999 by Donald Becker.
 
 	The driver also contains updates by different kernel developers
@@ -25,6 +23,8 @@
 		Disabled FC and ER, to avoid lockups when when we get FCP interrupts.
 	2000 Jul 17 Goutham Rao <goutham.rao@intel.com>
 		PCI DMA API fixes, adding pci_dma_sync_single calls where neccesary
+	2000 Aug 31 David Mosberger <davidm@hpl.hp.com>
+		rx_align support: enables rx DMA without causing unaligned accesses.
 */
 
 static const char *version =
@@ -41,14 +41,19 @@
 static int txdmacount = 128;
 static int rxdmacount /* = 0 */;
 
+#if defined(__ia64__) || defined(__alpha__) || defined(__sparc__) || defined(__mips__) || \
+	defined(__arm__)
+  /* align rx buffers to 2 bytes so that IP header is aligned */
+# define rx_align(skb)		skb_reserve((skb), 2)
+# define RxFD_ALIGNMENT		__attribute__ ((aligned (2), packed))
+#else
+# define rx_align(skb)
+# define RxFD_ALIGNMENT
+#endif
+
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx method.
    Lower values use more memory, but are faster. */
-#if defined(__alpha__) || defined(__sparc__) || defined(__mips__) || \
-    defined(__arm__)
-static int rx_copybreak = 1518;
-#else
 static int rx_copybreak = 200;
-#endif
 
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 20;
@@ -377,18 +382,18 @@
 
 /* The Speedo3 Rx and Tx frame/buffer descriptors. */
 struct descriptor {			    /* A generic descriptor. */
-	s32 cmd_status;				/* All command and status fields. */
+	volatile s32 cmd_status;	/* All command and status fields. */
 	u32 link;				    /* struct descriptor *  */
 	unsigned char params[0];
 };
 
 /* The Speedo3 Rx and Tx buffer descriptors. */
 struct RxFD {					/* Receive frame descriptor. */
-	s32 status;
+	volatile s32 status;
 	u32 link;					/* struct RxFD * */
 	u32 rx_buf_addr;			/* void * */
 	u32 count;
-};
+} RxFD_ALIGNMENT;
 
 /* Selected elements of the Tx/RxFD.status word. */
 enum RxFD_bits {
@@ -523,6 +528,7 @@
 
 static int eepro100_init_one(struct pci_dev *pdev,
 		const struct pci_device_id *ent);
+
 static void eepro100_remove_one (struct pci_dev *pdev);
 
 static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len);
@@ -1229,6 +1235,8 @@
 	for (i = 0; i < RX_RING_SIZE; i++) {
 		struct sk_buff *skb;
 		skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
+		/* XXX: do we really want to call this before the NULL check? --hch */
+		rx_align(skb);			/* Align IP on 16 byte boundary */
 		sp->rx_skbuff[i] = skb;
 		if (skb == NULL)
 			break;			/* OK.  Just initially short of Rx bufs. */
@@ -1620,6 +1628,8 @@
 	struct sk_buff *skb;
 	/* Get a fresh skbuff to replace the consumed one. */
 	skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
+	/* XXX: do we really want to call this before the NULL check? --hch */
+	rx_align(skb);				/* Align IP on 16 byte boundary */
 	sp->rx_skbuff[entry] = skb;
 	if (skb == NULL) {
 		sp->rx_ringp[entry] = NULL;
@@ -2300,13 +2310,13 @@
 MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
 	
 static struct pci_driver eepro100_driver = {
-	name:		"eepro100",
-	id_table:	eepro100_pci_tbl,
-	probe:		eepro100_init_one,
-	remove:		__devexit_p(eepro100_remove_one),
+	.name		= "eepro100",
+	.id_table	= eepro100_pci_tbl,
+	.probe		= eepro100_init_one,
+	.remove		= __devexit_p(eepro100_remove_one),
 #ifdef CONFIG_PM
-	suspend:	eepro100_suspend,
-	resume:		eepro100_resume,
+	.suspend	= eepro100_suspend,
+	.resume		= eepro100_resume,
 #endif /* CONFIG_PM */
 };
 
diff -Nru a/drivers/net/epic100.c b/drivers/net/epic100.c
--- a/drivers/net/epic100.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/epic100.c	Sat Aug 10 18:42:22 2002
@@ -63,12 +63,15 @@
 	LK1.1.13:
 	* revert version 1.1.12, power-up sequence "fix"
 
-*/
+	LK1.1.14 (Kryzsztof Halasa):
+	* fix spurious bad initializations
+	* pound phy a la SMSC's app note on the subject
 
-#define DRV_NAME	"epic100"
-#define DRV_VERSION	"1.11+LK1.1.13"
-#define DRV_RELDATE	"Mar 20, 2002"
+*/
 
+#define DRV_NAME        "epic100"
+#define DRV_VERSION     "1.11+LK1.1.14"
+#define DRV_RELDATE     "Aug 4, 2002"
 
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
@@ -457,7 +460,9 @@
 	/* Bring the chip out of low-power mode. */
 	outl(0x4200, ioaddr + GENCTL);
 	/* Magic?!  If we don't set this bit the MII interface won't work. */
-	outl(0x0008, ioaddr + TEST1);
+	/* This magic is documented in SMSC app note 7.15 */
+	for (i = 16; i > 0; i--)
+		outl(0x0008, ioaddr + TEST1);
 
 	/* Turn on the MII transceiver. */
 	outl(0x12, ioaddr + MIICfg);
@@ -674,7 +679,8 @@
 
 	outl(0x4000, ioaddr + GENCTL);
 	/* This magic is documented in SMSC app note 7.15 */
-	outl(0x0008, ioaddr + TEST1);
+	for (i = 16; i > 0; i--)
+		outl(0x0008, ioaddr + TEST1);
 
 	/* Pull the chip out of low-power mode, enable interrupts, and set for
 	   PCI read multiple.  The MIIcfg setting and strange write order are
@@ -697,6 +703,8 @@
 	outl(0x0412 | (RX_FIFO_THRESH<<8), ioaddr + GENCTL);
 #endif
 
+	udelay(20); /* Looks like EPII needs that if you want reliable RX init. FIXME: pci posting bug? */
+	
 	for (i = 0; i < 3; i++)
 		outl(cpu_to_le16(((u16*)dev->dev_addr)[i]), ioaddr + LAN0 + i*4);
 
@@ -1534,13 +1542,13 @@
 
 
 static struct pci_driver epic_driver = {
-	name:		DRV_NAME,
-	id_table:	epic_pci_tbl,
-	probe:		epic_init_one,
-	remove:		__devexit_p(epic_remove_one),
+	.name		= DRV_NAME,
+	.id_table	= epic_pci_tbl,
+	.probe		= epic_init_one,
+	.remove		= __devexit_p(epic_remove_one),
 #ifdef CONFIG_PM
-	suspend:	epic_suspend,
-	resume:		epic_resume,
+	.suspend	= epic_suspend,
+	.resume		= epic_resume,
 #endif /* CONFIG_PM */
 };
 
diff -Nru a/drivers/net/ewrk3.c b/drivers/net/ewrk3.c
--- a/drivers/net/ewrk3.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/ewrk3.c	Sat Aug 10 18:42:22 2002
@@ -133,6 +133,7 @@
    0.42    22-Apr-96      Fix alloc_device() bug <jari@markkus2.fimr.fi>
    0.43    16-Aug-96      Update alloc_device() to conform to de4x5.c
    0.44    08-Nov-01      use library crc32 functions <Matt_Domsch@dell.com>
+   0.45	   19-Jul-02	  fix unaligned access on alpha <martin@bruli.net>
 
    =========================================================================
  */
@@ -1008,12 +1009,13 @@
 						}
 						p = skb->data;	/* Look at the dest addr */
 						if (p[0] & 0x01) {	/* Multicast/Broadcast */
-							if ((*(s32 *) & p[0] == -1) && (*(s16 *) & p[4] == -1)) {
+							if ((*(s16 *) & p[0] == -1) && (*(s16 *) & p[2] == -1) && (*(s16 *) & p[4] == -1)) {
 								lp->pktStats.broadcast++;
 							} else {
 								lp->pktStats.multicast++;
 							}
-						} else if ((*(s32 *) & p[0] == *(s32 *) & dev->dev_addr[0]) &&
+						} else if ((*(s16 *) & p[0] == *(s16 *) & dev->dev_addr[0]) &&
+							   (*(s16 *) & p[2] == *(s16 *) & dev->dev_addr[2]) &&
 							   (*(s16 *) & p[4] == *(s16 *) & dev->dev_addr[4])) {
 							lp->pktStats.unicast++;
 						}
diff -Nru a/drivers/net/fealnx.c b/drivers/net/fealnx.c
--- a/drivers/net/fealnx.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/fealnx.c	Sat Aug 10 18:42:23 2002
@@ -1926,10 +1926,10 @@
 
 
 static struct pci_driver fealnx_driver = {
-	name:		"fealnx",
-	id_table:	fealnx_pci_tbl,
-	probe:		fealnx_init_one,
-	remove:		__devexit_p(fealnx_remove_one),
+	.name		= "fealnx",
+	.id_table	= fealnx_pci_tbl,
+	.probe		= fealnx_init_one,
+	.remove		= __devexit_p(fealnx_remove_one),
 };
 
 static int __init fealnx_init(void)
diff -Nru a/drivers/net/hamachi.c b/drivers/net/hamachi.c
--- a/drivers/net/hamachi.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/hamachi.c	Sat Aug 10 18:42:22 2002
@@ -2005,10 +2005,10 @@
 MODULE_DEVICE_TABLE(pci, hamachi_pci_tbl);
 
 static struct pci_driver hamachi_driver = {
-	name:		DRV_NAME,
-	id_table:	hamachi_pci_tbl,
-	probe:		hamachi_init_one,
-	remove:		__devexit_p(hamachi_remove_one),
+	.name		= DRV_NAME,
+	.id_table	= hamachi_pci_tbl,
+	.probe		= hamachi_init_one,
+	.remove		= __devexit_p(hamachi_remove_one),
 };
 
 static int __init hamachi_init (void)
diff -Nru a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
--- a/drivers/net/hamradio/6pack.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/hamradio/6pack.c	Sat Aug 10 18:42:21 2002
@@ -687,15 +687,15 @@
 
 /* Fill in our line protocol discipline */
 static struct tty_ldisc sp_ldisc = {
-	magic:		TTY_LDISC_MAGIC,
-	name:		"6pack",
-	open:		sixpack_open,
-	close:		sixpack_close,
-	ioctl:		(int (*)(struct tty_struct *, struct file *,
+	.magic	= TTY_LDISC_MAGIC,
+	.name		= "6pack",
+	.open		= sixpack_open,
+	.close	= sixpack_close,
+	.ioctl	= (int (*)(struct tty_struct *, struct file *,
 			unsigned int, unsigned long)) sixpack_ioctl,
-	receive_buf:	sixpack_receive_buf,
-	receive_room:	sixpack_receive_room,
-	write_wakeup:	sixpack_write_wakeup,
+	.receive_buf	= sixpack_receive_buf,
+	.receive_room	= sixpack_receive_room,
+	.write_wakeup	= sixpack_write_wakeup,
 };
 
 /* Initialize 6pack control device -- register 6pack line discipline */
diff -Nru a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
--- a/drivers/net/hamradio/baycom_epp.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/hamradio/baycom_epp.c	Sat Aug 10 18:42:23 2002
@@ -1020,8 +1020,8 @@
 	struct baycom_state *bc;
         struct parport *pp;
 	const struct tq_struct run_bh = {
-		routine: (void *)(void *)epp_bh,
-		data: dev
+		.routine = (void *)(void *)epp_bh,
+		.data = dev
 	};
 	unsigned int i, j;
 	unsigned char tmp[128];
diff -Nru a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
--- a/drivers/net/hamradio/bpqether.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/hamradio/bpqether.c	Sat Aug 10 18:42:22 2002
@@ -102,12 +102,12 @@
 static char *bpq_print_ethaddr(unsigned char *);
 
 static struct packet_type bpq_packet_type = {
-	type:	__constant_htons(ETH_P_BPQ),
-	func:	bpq_rcv,
+	.type	= __constant_htons(ETH_P_BPQ),
+	.func	= bpq_rcv,
 };
 
 static struct notifier_block bpq_dev_notifier = {
-	notifier_call:	bpq_device_event,
+	.notifier_call =bpq_device_event,
 };
 
 
diff -Nru a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c
--- a/drivers/net/hp-plus.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/hp-plus.c	Sat Aug 10 18:42:21 2002
@@ -351,7 +351,7 @@
 	outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
 	isa_memcpy_fromio(hdr, dev->mem_start, sizeof(struct e8390_pkt_hdr));
 	outw(option_reg, ioaddr + HPP_OPTION);
-	hdr->count = (hdr->count + 3) & ~3;	/* Round up allocation. */
+	hdr->count = (le16_to_cpu(hdr->count) + 3) & ~3;	/* Round up allocation. */
 }
 
 static void
diff -Nru a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
--- a/drivers/net/ioc3-eth.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/ioc3-eth.c	Sat Aug 10 18:42:21 2002
@@ -1621,10 +1621,10 @@
 MODULE_DEVICE_TABLE(pci, ioc3_pci_tbl);
 
 static struct pci_driver ioc3_driver = {
-	name:		"ioc3-eth",
-	id_table:	ioc3_pci_tbl,
-	probe:		ioc3_probe,
-	remove:		__devexit_p(ioc3_remove_one),
+	.name		= "ioc3-eth",
+	.id_table	= ioc3_pci_tbl,
+	.probe		= ioc3_probe,
+	.remove		= __devexit_p(ioc3_remove_one),
 };
 
 static int __init ioc3_init_module(void)
diff -Nru a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
--- a/drivers/net/irda/irda-usb.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/irda/irda-usb.c	Sat Aug 10 18:42:23 2002
@@ -1591,10 +1591,10 @@
  * USB device callbacks
  */
 static struct usb_driver irda_driver = {
-	name:		"irda-usb",
-	probe:		irda_usb_probe,
-	disconnect:	irda_usb_disconnect,
-	id_table:	dongles,
+	.name		= "irda-usb",
+	.probe		= irda_usb_probe,
+	.disconnect	= irda_usb_disconnect,
+	.id_table	= dongles,
 };
 
 /************************* MODULE CALLBACKS *************************/
diff -Nru a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
--- a/drivers/net/irda/vlsi_ir.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/net/irda/vlsi_ir.c	Sat Aug 10 18:42:20 2002
@@ -56,9 +56,9 @@
 
 static struct pci_device_id vlsi_irda_table [] __devinitdata = { {
 
-	class:          PCI_CLASS_WIRELESS_IRDA << 8,
-	vendor:         PCI_VENDOR_ID_VLSI,
-	device:         PCI_DEVICE_ID_VLSI_82C147,
+	.class =        PCI_CLASS_WIRELESS_IRDA << 8,
+	.vendor =       PCI_VENDOR_ID_VLSI,
+	.device =       PCI_DEVICE_ID_VLSI_82C147,
 	}, { /* all zeroes */ }
 };
 
@@ -1288,12 +1288,12 @@
 /*********************************************************/
 
 static struct pci_driver vlsi_irda_driver = {
-	name:           drivername,
-	id_table:       vlsi_irda_table,
-	probe:          vlsi_irda_probe,
-	remove:         __devexit_p(vlsi_irda_remove),
-	suspend:        vlsi_irda_suspend,
-	resume:         vlsi_irda_resume,
+	.name		= drivername,
+	.id_table	= vlsi_irda_table,
+	.probe		= vlsi_irda_probe,
+	.remove		= __devexit_p(vlsi_irda_remove),
+	.suspend	= vlsi_irda_suspend,
+	.resume		= vlsi_irda_resume,
 };
 
 static int __init vlsi_mod_init(void)
diff -Nru a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
--- a/drivers/net/lasi_82596.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/lasi_82596.c	Sat Aug 10 18:42:21 2002
@@ -1515,8 +1515,8 @@
 {0,};
 static struct net_device dev_82596 =
 {
-	name: devicename,	/* device name inserted by drivers/net/net_init.c */
-	init: lasi_i82596_probe,
+	.name = devicename,	/* device name inserted by drivers/net/net_init.c */
+	.init = lasi_i82596_probe,
 };
 
 
diff -Nru a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
--- a/drivers/net/myri_sbus.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/myri_sbus.c	Sat Aug 10 18:42:21 2002
@@ -546,8 +546,11 @@
 	struct myri_eth *mp		= (struct myri_eth *) dev->priv;
 	unsigned long lregs		= mp->lregs;
 	struct myri_channel *chan	= &mp->shmem->channel;
+	unsigned long flags;
 	u32 status;
 
+	spin_lock_irqsave(&mp->irq_lock, flags);
+
 	status = sbus_readl(lregs + LANAI_ISTAT);
 	DIRQ(("myri_interrupt: status[%08x] ", status));
 	if (status & ISTAT_HOST) {
@@ -569,6 +572,8 @@
 		myri_enable_irq(lregs, mp->cregs);
 	}
 	DIRQ(("\n"));
+
+	spin_unlock_irqrestore(&mp->irq_lock, flags);
 }
 
 static int myri_open(struct net_device *dev)
@@ -622,7 +627,7 @@
 		return 1;
 	}
 
-	save_and_cli(flags);
+	spin_lock_irqsave(&mp->irq_lock, flags);
 
 	DHDR(("xmit[skbdata(%p)]\n", skb->data));
 #ifdef DEBUG_HEADER
@@ -669,7 +674,7 @@
 
 	DTX(("tbusy=0, returning 0\n"));
 	netif_start_queue(dev);
-	restore_flags(flags);
+	spin_unlock_irqrestore(&mp->irq_lock, flags);
 	return 0;
 }
 
@@ -900,6 +905,7 @@
 	printk("%s: MyriCOM MyriNET Ethernet ", dev->name);
 
 	mp = (struct myri_eth *) dev->priv;
+	spin_lock_init(&mp->irq_lock);
 	mp->myri_sdev = sdev;
 
 	/* Clean out skb arrays. */
diff -Nru a/drivers/net/myri_sbus.h b/drivers/net/myri_sbus.h
--- a/drivers/net/myri_sbus.h	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/myri_sbus.h	Sat Aug 10 18:42:23 2002
@@ -269,6 +269,7 @@
 	/* These are frequently accessed, keep together
 	 * to obtain good cache hit rates.
 	 */
+	spinlock_t			irq_lock;
 	struct myri_shmem		*shmem;		/* Shared data structures.    */
 	unsigned long			cregs;		/* Control register space.    */
 	struct recvq			*rqack;		/* Where we ack rx's.         */
diff -Nru a/drivers/net/natsemi.c b/drivers/net/natsemi.c
--- a/drivers/net/natsemi.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/net/natsemi.c	Sat Aug 10 18:42:20 2002
@@ -2503,13 +2503,13 @@
 #endif /* CONFIG_PM */
 
 static struct pci_driver natsemi_driver = {
-	name:		DRV_NAME,
-	id_table:	natsemi_pci_tbl,
-	probe:		natsemi_probe1,
-	remove:		__devexit_p(natsemi_remove1),
+	.name		= DRV_NAME,
+	.id_table	= natsemi_pci_tbl,
+	.probe		= natsemi_probe1,
+	.remove		= __devexit_p(natsemi_remove1),
 #ifdef CONFIG_PM
-	suspend:	natsemi_suspend,
-	resume:		natsemi_resume,
+	.suspend	= natsemi_suspend,
+	.resume		= natsemi_resume,
 #endif
 };
 
diff -Nru a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
--- a/drivers/net/ne2k-pci.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/ne2k-pci.c	Sat Aug 10 18:42:21 2002
@@ -640,10 +640,10 @@
 
 
 static struct pci_driver ne2k_driver = {
-	name:		DRV_NAME,
-	probe:		ne2k_pci_init_one,
-	remove:		__devexit_p(ne2k_pci_remove_one),
-	id_table:	ne2k_pci_tbl,
+	.name		= DRV_NAME,
+	.probe		= ne2k_pci_init_one,
+	.remove		= __devexit_p(ne2k_pci_remove_one),
+	.id_table	= ne2k_pci_tbl,
 };
 
 
diff -Nru a/drivers/net/ns83820.c b/drivers/net/ns83820.c
--- a/drivers/net/ns83820.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/ns83820.c	Sat Aug 10 18:42:23 2002
@@ -755,7 +755,7 @@
 
 	/* synchronize with the interrupt handler and kill it */
 	dev->rx_info.up = 0;
-	synchronize_irq();
+	synchronize_irq(dev->pci_dev->irq);
 
 	/* touch the pci bus... */
 	readl(dev->base + IMR);
@@ -1296,11 +1296,11 @@
 	readl(dev->base + IER);
 
 	dev->rx_info.up = 0;
-	synchronize_irq();
+	synchronize_irq(dev->pci_dev->irq);
 
 	ns83820_do_reset(dev, CR_RST);
 
-	synchronize_irq();
+	synchronize_irq(dev->pci_dev->irq);
 
 	dev->IMR_cache &= ~(ISR_TXURN | ISR_TXIDLE | ISR_TXERR | ISR_TXDESC | ISR_TXOK);
 	ns83820_cleanup_rx(dev);
@@ -1675,13 +1675,13 @@
 };
 
 static struct pci_driver driver = {
-	name:		"ns83820",
-	id_table:	ns83820_pci_tbl,
-	probe:		ns83820_init_one,
-	remove:		__devexit_p(ns83820_remove_one),
+	.name		= "ns83820",
+	.id_table	= ns83820_pci_tbl,
+	.probe		= ns83820_init_one,
+	.remove		= __devexit_p(ns83820_remove_one),
 #if 0	/* FIXME: implement */
-	suspend:	,
-	resume:		,
+	.suspend	= ,
+	.resume		= ,
 #endif
 };
 
diff -Nru a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c
--- a/drivers/net/pci-skeleton.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/net/pci-skeleton.c	Sat Aug 10 18:42:20 2002
@@ -1953,13 +1953,13 @@
 
 
 static struct pci_driver netdrv_pci_driver = {
-	name:		MODNAME,
-	id_table:	netdrv_pci_tbl,
-	probe:		netdrv_init_one,
-	remove:		__devexit_p(netdrv_remove_one),
+	.name		= MODNAME,
+	.id_table	= netdrv_pci_tbl,
+	.probe		= netdrv_init_one,
+	.remove		= __devexit_p(netdrv_remove_one),
 #ifdef CONFIG_PM
-	suspend:	netdrv_suspend,
-	resume:		netdrv_resume,
+	.suspend	= netdrv_suspend,
+	.resume		= netdrv_resume,
 #endif /* CONFIG_PM */
 };
 
diff -Nru a/drivers/net/plip.c b/drivers/net/plip.c
--- a/drivers/net/plip.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/plip.c	Sat Aug 10 18:42:23 2002
@@ -1350,9 +1350,9 @@
 }
 
 static struct parport_driver plip_driver = {
-	name:	"plip",
-	attach:	plip_attach,
-	detach:	plip_detach
+	.name	= "plip",
+	.attach = plip_attach,
+	.detach = plip_detach
 };
 
 static void __exit plip_cleanup_module (void)
diff -Nru a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
--- a/drivers/net/ppp_async.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/ppp_async.c	Sat Aug 10 18:42:23 2002
@@ -351,17 +351,17 @@
 
 
 static struct tty_ldisc ppp_ldisc = {
-	magic:	TTY_LDISC_MAGIC,
-	name:	"ppp",
-	open:	ppp_asynctty_open,
-	close:	ppp_asynctty_close,
-	read:	ppp_asynctty_read,
-	write:	ppp_asynctty_write,
-	ioctl:	ppp_asynctty_ioctl,
-	poll:	ppp_asynctty_poll,
-	receive_room: ppp_asynctty_room,
-	receive_buf: ppp_asynctty_receive,
-	write_wakeup: ppp_asynctty_wakeup,
+	.magic	= TTY_LDISC_MAGIC,
+	.name	= "ppp",
+	.open	= ppp_asynctty_open,
+	.close	= ppp_asynctty_close,
+	.read	= ppp_asynctty_read,
+	.write	= ppp_asynctty_write,
+	.ioctl	= ppp_asynctty_ioctl,
+	.poll	= ppp_asynctty_poll,
+	.receive_room = ppp_asynctty_room,
+	.receive_buf = ppp_asynctty_receive,
+	.write_wakeup = ppp_asynctty_wakeup,
 };
 
 static int __init
diff -Nru a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
--- a/drivers/net/ppp_generic.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/ppp_generic.c	Sat Aug 10 18:42:23 2002
@@ -765,13 +765,13 @@
 }
 
 static struct file_operations ppp_device_fops = {
-	owner:		THIS_MODULE,
-	read:		ppp_read,
-	write:		ppp_write,
-	poll:		ppp_poll,
-	ioctl:		ppp_ioctl,
-	open:		ppp_open,
-	release:	ppp_release
+	.owner		= THIS_MODULE,
+	.read		= ppp_read,
+	.write		= ppp_write,
+	.poll		= ppp_poll,
+	.ioctl		= ppp_ioctl,
+	.open		= ppp_open,
+	.release	= ppp_release
 };
 
 #define PPP_MAJOR	108
diff -Nru a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
--- a/drivers/net/ppp_synctty.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/ppp_synctty.c	Sat Aug 10 18:42:22 2002
@@ -404,17 +404,17 @@
 
 
 static struct tty_ldisc ppp_sync_ldisc = {
-	magic:	TTY_LDISC_MAGIC,
-	name:	"pppsync",
-	open:	ppp_sync_open,
-	close:	ppp_sync_close,
-	read:	ppp_sync_read,
-	write:	ppp_sync_write,
-	ioctl:	ppp_synctty_ioctl,
-	poll:	ppp_sync_poll,
-	receive_room: ppp_sync_room,
-	receive_buf: ppp_sync_receive,
-	write_wakeup: ppp_sync_wakeup,
+	.magic	= TTY_LDISC_MAGIC,
+	.name	= "pppsync",
+	.open	= ppp_sync_open,
+	.close	= ppp_sync_close,
+	.read	= ppp_sync_read,
+	.write	= ppp_sync_write,
+	.ioctl	= ppp_synctty_ioctl,
+	.poll	= ppp_sync_poll,
+	.receive_room = ppp_sync_room,
+	.receive_buf = ppp_sync_receive,
+	.write_wakeup = ppp_sync_wakeup,
 };
 
 static int __init
diff -Nru a/drivers/net/pppoe.c b/drivers/net/pppoe.c
--- a/drivers/net/pppoe.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/pppoe.c	Sat Aug 10 18:42:21 2002
@@ -332,7 +332,7 @@
 
 
 static struct notifier_block pppoe_notifier = {
-	notifier_call: pppoe_device_event,
+	.notifier_call = pppoe_device_event,
 };
 
 
@@ -459,13 +459,13 @@
 }
 
 struct packet_type pppoes_ptype = {
-	type:	__constant_htons(ETH_P_PPP_SES),
-	func:	pppoe_rcv,
+	.type	= __constant_htons(ETH_P_PPP_SES),
+	.func	= pppoe_rcv,
 };
 
 struct packet_type pppoed_ptype = {
-	type:	__constant_htons(ETH_P_PPP_DISC),
-	func:	pppoe_disc_rcv,
+	.type	= __constant_htons(ETH_P_PPP_DISC),
+	.func	= pppoe_disc_rcv,
 };
 
 /***********************************************************************
@@ -1033,27 +1033,27 @@
 
 
 struct proto_ops pppoe_ops = {
-    family:		AF_PPPOX,
-    release:		pppoe_release,
-    bind:		sock_no_bind,
-    connect:		pppoe_connect,
-    socketpair:		sock_no_socketpair,
-    accept:		sock_no_accept,
-    getname:		pppoe_getname,
-    poll:		datagram_poll,
-    ioctl:		pppoe_ioctl,
-    listen:		sock_no_listen,
-    shutdown:		sock_no_shutdown,
-    setsockopt:		sock_no_setsockopt,
-    getsockopt:		sock_no_getsockopt,
-    sendmsg:		pppoe_sendmsg,
-    recvmsg:		pppoe_rcvmsg,
-    mmap:		sock_no_mmap
+    .family		= AF_PPPOX,
+    .release		= pppoe_release,
+    .bind		= sock_no_bind,
+    .connect		= pppoe_connect,
+    .socketpair		= sock_no_socketpair,
+    .accept		= sock_no_accept,
+    .getname		= pppoe_getname,
+    .poll		= datagram_poll,
+    .ioctl		= pppoe_ioctl,
+    .listen		= sock_no_listen,
+    .shutdown		= sock_no_shutdown,
+    .setsockopt		= sock_no_setsockopt,
+    .getsockopt		= sock_no_getsockopt,
+    .sendmsg		= pppoe_sendmsg,
+    .recvmsg		= pppoe_rcvmsg,
+    .mmap		= sock_no_mmap
 };
 
 struct pppox_proto pppoe_proto = {
-    create:	pppoe_create,
-    ioctl:	pppoe_ioctl
+    .create	= pppoe_create,
+    .ioctl	= pppoe_ioctl
 };
 
 
diff -Nru a/drivers/net/rcpci45.c b/drivers/net/rcpci45.c
--- a/drivers/net/rcpci45.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/rcpci45.c	Sat Aug 10 18:42:21 2002
@@ -264,10 +264,10 @@
 }
 
 static struct pci_driver rcpci45_driver = {
-	name:		"rcpci45",
-	id_table:	rcpci45_pci_table,
-	probe:		rcpci45_init_one,
-	remove:		__devexit_p(rcpci45_remove_one),
+	.name		= "rcpci45",
+	.id_table	= rcpci45_pci_table,
+	.probe		= rcpci45_init_one,
+	.remove		= __devexit_p(rcpci45_remove_one),
 };
 
 static int __init
diff -Nru a/drivers/net/setup.c b/drivers/net/setup.c
--- a/drivers/net/setup.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/setup.c	Sat Aug 10 18:42:23 2002
@@ -28,7 +28,6 @@
 extern int lmc_setup(void);
 
 extern int madgemc_probe(void);
-extern int uml_net_probe(void);
 
 /* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is string of 9 zeros. */
 #define __PAD6 "\0\0\0\0\0\0\0\0\0"
@@ -102,9 +101,6 @@
  */  
 #ifdef CONFIG_MADGEMC
 	{madgemc_probe, 0},
-#endif
-#ifdef CONFIG_UML_NET
-	{uml_net_probe, 0},
 #endif
  
 	{NULL, 0},
diff -Nru a/drivers/net/sis900.c b/drivers/net/sis900.c
--- a/drivers/net/sis900.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/sis900.c	Sat Aug 10 18:42:22 2002
@@ -2163,10 +2163,10 @@
 }
 
 static struct pci_driver sis900_pci_driver = {
-	name:		SIS900_MODULE_NAME,
-	id_table:	sis900_pci_tbl,
-	probe:		sis900_probe,
-	remove:		__devexit_p(sis900_remove),
+	.name		= SIS900_MODULE_NAME,
+	.id_table	= sis900_pci_tbl,
+	.probe		= sis900_probe,
+	.remove		= __devexit_p(sis900_remove),
 };
 
 static int __init sis900_init_module(void)
diff -Nru a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
--- a/drivers/net/sk98lin/skge.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/sk98lin/skge.c	Sat Aug 10 18:42:21 2002
@@ -404,6 +404,7 @@
  */
 static int __init skge_probe (void)
 {
+	int			proc_root_initialized = 0;
 	int 		boards_found = 0;
 	int			version_disp = 0;
 	SK_AC		*pAC;
@@ -429,11 +430,6 @@
 	if (!pci_present())		/* is PCI support present? */
 		return -ENODEV;
 
-        pSkRootDir = create_proc_entry("sk98lin",
-                S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net); 
-
-	pSkRootDir->owner = THIS_MODULE;
-
 	while((pdev = pci_find_device(PCI_VENDOR_ID_SYSKONNECT,
 				      PCI_DEVICE_ID_SYSKONNECT_GE, pdev)) != NULL) {
 
@@ -484,6 +480,14 @@
 		dev->set_mac_address =	&SkGeSetMacAddr;
 		dev->do_ioctl =		&SkGeIoctl;
 		dev->change_mtu =	&SkGeChangeMtu;
+
+		if(!proc_root_initialized) {
+			pSkRootDir = create_proc_entry("sk98lin",
+				S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO, proc_net);
+			pSkRootDir->owner = THIS_MODULE;
+
+			proc_root_initialized = 1;
+		}
 
 		pProcFile = create_proc_entry(dev->name, 
 			S_IFREG | 0444, pSkRootDir);
diff -Nru a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
--- a/drivers/net/smc-ultra.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/smc-ultra.c	Sat Aug 10 18:42:21 2002
@@ -383,9 +383,11 @@
 	unsigned long hdr_start = dev->mem_start + ((ring_page - START_PG)<<8);
 
 	outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET);	/* shmem on */
-#ifdef notdef
+#ifdef __BIG_ENDIAN
 	/* Officially this is what we are doing, but the readl() is faster */
+	/* unfortunately it isn't endian aware of the struct               */
 	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+	hdr->count = le16_to_cpu(hdr->count);
 #else
 	((unsigned int*)hdr)[0] = isa_readl(hdr_start);
 #endif
diff -Nru a/drivers/net/smc-ultra32.c b/drivers/net/smc-ultra32.c
--- a/drivers/net/smc-ultra32.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/smc-ultra32.c	Sat Aug 10 18:42:23 2002
@@ -320,9 +320,11 @@
 	/* Select correct 8KB Window. */
 	outb(ei_status.reg0 | ((ring_page & 0x60) >> 5), RamReg);
 
-#ifdef notdef
+#ifdef __BIG_ENDIAN
 	/* Officially this is what we are doing, but the readl() is faster */
+	/* unfortunately it isn't endian aware of the struct               */
 	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+	hdr->count = le16_to_cpu(hdr->count);
 #else
 	((unsigned int*)hdr)[0] = isa_readl(hdr_start);
 #endif
diff -Nru a/drivers/net/starfire.c b/drivers/net/starfire.c
--- a/drivers/net/starfire.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/starfire.c	Sat Aug 10 18:42:21 2002
@@ -2012,10 +2012,10 @@
 
 
 static struct pci_driver starfire_driver = {
-	name:		DRV_NAME,
-	probe:		starfire_init_one,
-	remove:		__devexit_p(starfire_remove_one),
-	id_table:	starfire_pci_tbl,
+	.name		= DRV_NAME,
+	.probe		= starfire_init_one,
+	.remove		= __devexit_p(starfire_remove_one),
+	.id_table	= starfire_pci_tbl,
 };
 
 
diff -Nru a/drivers/net/strip.c b/drivers/net/strip.c
--- a/drivers/net/strip.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/strip.c	Sat Aug 10 18:42:21 2002
@@ -2812,14 +2812,14 @@
 /* Initialization							*/
 
 static struct tty_ldisc strip_ldisc = {
-	magic:		TTY_LDISC_MAGIC,
-	name:		"strip",
-	open:		strip_open,
-	close:		strip_close,
-	ioctl:		strip_ioctl,
-	receive_buf:	strip_receive_buf,
-	receive_room:	strip_receive_room,
-	write_wakeup:	strip_write_some_more,
+	.magic		= TTY_LDISC_MAGIC,
+	.name		= "strip",
+	.open		= strip_open,
+	.close		= strip_close,
+	.ioctl		= strip_ioctl,
+	.receive_buf	= strip_receive_buf,
+	.receive_room	= strip_receive_room,
+	.write_wakeup	= strip_write_some_more,
 };
 
 /*
diff -Nru a/drivers/net/sundance.c b/drivers/net/sundance.c
--- a/drivers/net/sundance.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/sundance.c	Sat Aug 10 18:42:23 2002
@@ -1460,10 +1460,10 @@
 }
 
 static struct pci_driver sundance_driver = {
-	name:		DRV_NAME,
-	id_table:	sundance_pci_tbl,
-	probe:		sundance_probe1,
-	remove:		__devexit_p(sundance_remove1),
+	.name		= DRV_NAME,
+	.id_table	= sundance_pci_tbl,
+	.probe		= sundance_probe1,
+	.remove		= __devexit_p(sundance_remove1),
 };
 
 static int __init sundance_init(void)
diff -Nru a/drivers/net/sungem.c b/drivers/net/sungem.c
--- a/drivers/net/sungem.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/sungem.c	Sat Aug 10 18:42:23 2002
@@ -3109,13 +3109,13 @@
 }
 
 static struct pci_driver gem_driver = {
-	name:		GEM_MODULE_NAME,
-	id_table:	gem_pci_tbl,
-	probe:		gem_init_one,
-	remove:		__devexit_p(gem_remove_one),
+	.name		= GEM_MODULE_NAME,
+	.id_table	= gem_pci_tbl,
+	.probe		= gem_init_one,
+	.remove		= __devexit_p(gem_remove_one),
 #ifdef CONFIG_PM
-	suspend:	gem_suspend,
-	resume:		gem_resume,
+	.suspend	= gem_suspend,
+	.resume		= gem_resume,
 #endif /* CONFIG_PM */
 };
 
diff -Nru a/drivers/net/sunhme.c b/drivers/net/sunhme.c
--- a/drivers/net/sunhme.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/sunhme.c	Sat Aug 10 18:42:22 2002
@@ -76,6 +76,7 @@
 /* accept MAC address of the form macaddr=0x08,0x00,0x20,0x30,0x40,0x50 */
 MODULE_PARM(macaddr, "6i");
 MODULE_PARM_DESC(macaddr, "Happy Meal MAC address to set");
+MODULE_LICENSE("GPL");
 
 static struct happy_meal *root_happy_dev;
 
@@ -192,7 +193,6 @@
 };
 
 MODULE_DEVICE_TABLE(pci, happymeal_pci_ids);
-MODULE_LICENSE("GPL");
 
 #endif
 
diff -Nru a/drivers/net/tc35815.c b/drivers/net/tc35815.c
--- a/drivers/net/tc35815.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/net/tc35815.c	Sat Aug 10 18:42:20 2002
@@ -1744,10 +1744,10 @@
 }
 
 static struct pci_driver tc35815_driver = {
-	name:  TC35815_MODULE_NAME,
-	probe: tc35815_probe,
-	remove: NULL,
-	id_table: tc35815_pci_tbl,
+	.name =TC35815_MODULE_NAME,
+	.probe = tc35815_probe,
+	.remove = NULL,
+	.id_table = tc35815_pci_tbl,
 };
 
 static int __init tc35815_init_module(void)
diff -Nru a/drivers/net/tg3.c b/drivers/net/tg3.c
--- a/drivers/net/tg3.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/tg3.c	Sat Aug 10 18:42:23 2002
@@ -52,8 +52,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"0.99-NAPI"
-#define DRV_MODULE_RELDATE	"Jun 20, 2002"
+#define DRV_MODULE_VERSION	"1.0"
+#define DRV_MODULE_RELDATE	"Jul 19, 2002"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -1922,8 +1922,11 @@
 		}
 	}
 
-	if (sblk->idx[0].tx_consumer != tp->tx_cons)
+	if (sblk->idx[0].tx_consumer != tp->tx_cons) {
+		spin_lock(&tp->tx_lock);
 		tg3_tx(tp);
+		spin_unlock(&tp->tx_lock);
+	}
 
 	done = 1;
 	if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) {
@@ -2014,11 +2017,13 @@
 	       dev->name);
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 
 	tg3_halt(tp);
 	tg3_init_rings(tp);
 	tg3_init_hw(tp);
 
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
 	netif_wake_queue(dev);
@@ -2203,12 +2208,16 @@
 
 	len = (skb->len - skb->data_len);
 
-	spin_lock_irq(&tp->lock);
+	/* No BH disabling for tx_lock here.  We are running in BH disabled
+	 * context and TX reclaim runs via tp->poll inside of a software
+	 * interrupt.  Rejoice!
+	 */
+	spin_lock(&tp->tx_lock);
 
 	/* This is a hard error, log it. */
 	if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
 		netif_stop_queue(dev);
-		spin_unlock_irq(&tp->lock);
+		spin_unlock(&tp->tx_lock);
 		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
 		       dev->name);
 		return 1;
@@ -2327,7 +2336,7 @@
 		netif_stop_queue(dev);
 
 out_unlock:
-	spin_unlock_irq(&tp->lock);
+	spin_unlock(&tp->tx_lock);
 
 	dev->trans_start = jiffies;
 
@@ -2342,12 +2351,16 @@
 
 	len = (skb->len - skb->data_len);
 
-	spin_lock_irq(&tp->lock);
+	/* No BH disabling for tx_lock here.  We are running in BH disabled
+	 * context and TX reclaim runs via tp->poll inside of a software
+	 * interrupt.  Rejoice!
+	 */
+	spin_lock(&tp->tx_lock);
 
 	/* This is a hard error, log it. */
 	if (unlikely(TX_BUFFS_AVAIL(tp) <= (skb_shinfo(skb)->nr_frags + 1))) {
 		netif_stop_queue(dev);
-		spin_unlock_irq(&tp->lock);
+		spin_unlock(&tp->tx_lock);
 		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
 		       dev->name);
 		return 1;
@@ -2416,7 +2429,7 @@
 	if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1))
 		netif_stop_queue(dev);
 
-	spin_unlock_irq(&tp->lock);
+	spin_unlock(&tp->tx_lock);
 
 	dev->trans_start = jiffies;
 
@@ -2439,6 +2452,7 @@
 	}
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 
 	tg3_halt(tp);
 
@@ -2452,6 +2466,7 @@
 	tg3_init_rings(tp);
 	tg3_init_hw(tp);
 
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
 	return 0;
@@ -2461,7 +2476,7 @@
  *
  * The chip has been shut down and the driver detached from
  * the networking, so no interrupts or new tx packets will
- * end up in the driver.  tp->lock is not held and we are not
+ * end up in the driver.  tp->{tx,}lock is not held and we are not
  * in an interrupt context and thus may sleep.
  */
 static void tg3_free_rings(struct tg3 *tp)
@@ -2546,7 +2561,7 @@
  *
  * The chip has been shut down and the driver detached from
  * the networking, so no interrupts or new tx packets will
- * end up in the driver.  tp->lock is not held and we are not
+ * end up in the driver.  tp->{tx,}lock is not held and we are not
  * in an interrupt context and thus may sleep.
  */
 static void tg3_init_rings(struct tg3 *tp)
@@ -3711,6 +3726,7 @@
 	struct tg3 *tp = (struct tg3 *) __opaque;
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 
 	/* All of this garbage is because when using non-tagged
 	 * IRQ status the mailbox/status_block protocol the chip
@@ -3772,6 +3788,7 @@
 		tp->timer_counter = tp->timer_multiplier;
 	}
 
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
 	tp->timer.expires = jiffies + tp->timer_offset;
@@ -3784,10 +3801,12 @@
 	int err;
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 
 	tg3_disable_ints(tp);
 	tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
 
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
 	/* If you move this call, make sure TG3_FLAG_HOST_TXDS in
@@ -3806,6 +3825,7 @@
 	}
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 
 	tg3_init_rings(tp);
 
@@ -3823,13 +3843,10 @@
 		tp->timer.function = tg3_timer;
 		add_timer(&tp->timer);
 
-		tp->last_rate_sample = jiffies;
-		tp->last_rx_count = 0;
-		tp->last_tx_count = 0;
-
 		tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
 	}
 
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
 	if (err) {
@@ -3841,9 +3858,11 @@
 	netif_start_queue(dev);
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 
 	tg3_enable_ints(tp);
 
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
 	return 0;
@@ -4105,6 +4124,7 @@
 	del_timer_sync(&tp->timer);
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 #if 0
 	tg3_dump_state(tp);
 #endif
@@ -4118,6 +4138,7 @@
 		  TG3_FLAG_GOT_SERDES_FLOWCTL);
 	netif_carrier_off(tp->dev);
 
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
 	free_irq(dev->irq, dev);
@@ -4325,6 +4346,7 @@
 	memset(orig_p, 0, TG3_REGDUMP_LEN);
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 
 #define __GET_REG32(reg)	(*((u32 *)(p))++ = tr32(reg))
 #define GET_REG32_LOOP(base,len)		\
@@ -4373,6 +4395,7 @@
 #undef GET_REG32_LOOP
 #undef GET_REG32_1
 
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
 	return orig_p;
@@ -4471,6 +4494,7 @@
 		}
 
 		spin_lock_irq(&tp->lock);
+		spin_lock(&tp->tx_lock);
 
 		tp->link_config.autoneg = cmd.autoneg;
 		if (cmd.autoneg == AUTONEG_ENABLE) {
@@ -4483,6 +4507,7 @@
 		}
 
 		tg3_setup_phy(tp);
+		spin_unlock(&tp->tx_lock);
 		spin_unlock_irq(&tp->lock);
 
 		return 0;
@@ -4617,6 +4642,7 @@
 			return -EINVAL;
 
 		spin_lock_irq(&tp->lock);
+		spin_lock(&tp->tx_lock);
 
 		tp->rx_pending = ering.rx_pending;
 #if TG3_MINI_RING_WORKS
@@ -4629,6 +4655,7 @@
 		tg3_init_rings(tp);
 		tg3_init_hw(tp);
 		netif_wake_queue(tp->dev);
+		spin_unlock(&tp->tx_lock);
 		spin_unlock_irq(&tp->lock);
 
 		return 0;
@@ -4653,6 +4680,7 @@
 			return -EFAULT;
 
 		spin_lock_irq(&tp->lock);
+		spin_lock(&tp->tx_lock);
 		if (epause.autoneg)
 			tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
 		else
@@ -4668,6 +4696,7 @@
 		tg3_halt(tp);
 		tg3_init_rings(tp);
 		tg3_init_hw(tp);
+		spin_unlock(&tp->tx_lock);
 		spin_unlock_irq(&tp->lock);
 
 		return 0;
@@ -4805,7 +4834,9 @@
 	struct tg3 *tp = dev->priv;
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 	tp->vlgrp = grp;
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 }
 
@@ -4814,8 +4845,10 @@
 	struct tg3 *tp = dev->priv;
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 	if (tp->vlgrp)
 		tp->vlgrp->vlan_devices[vid] = NULL;
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 }
 #endif
@@ -5926,6 +5959,7 @@
 	tp->grc_mode |= GRC_MODE_BSWAP_NONFRM_DATA;
 #endif
 	spin_lock_init(&tp->lock);
+	spin_lock_init(&tp->tx_lock);
 	spin_lock_init(&tp->indirect_lock);
 
 	tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len);
@@ -6061,22 +6095,28 @@
 		return 0;
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 	tg3_disable_ints(tp);
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
 	netif_device_detach(dev);
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 	tg3_halt(tp);
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
 	err = tg3_set_power_state(tp, state);
 	if (err) {
 		spin_lock_irq(&tp->lock);
+		spin_lock(&tp->tx_lock);
 
 		tg3_init_rings(tp);
 		tg3_init_hw(tp);
 
+		spin_unlock(&tp->tx_lock);
 		spin_unlock_irq(&tp->lock);
 
 		netif_device_attach(dev);
@@ -6101,23 +6141,25 @@
 	netif_device_attach(dev);
 
 	spin_lock_irq(&tp->lock);
+	spin_lock(&tp->tx_lock);
 
 	tg3_init_rings(tp);
 	tg3_init_hw(tp);
 	tg3_enable_ints(tp);
 
+	spin_unlock(&tp->tx_lock);
 	spin_unlock_irq(&tp->lock);
 
 	return 0;
 }
 
 static struct pci_driver tg3_driver = {
-	name:		DRV_MODULE_NAME,
-	id_table:	tg3_pci_tbl,
-	probe:		tg3_init_one,
-	remove:		__devexit_p(tg3_remove_one),
-	suspend:	tg3_suspend,
-	resume:		tg3_resume
+	.name		= DRV_MODULE_NAME,
+	.id_table	= tg3_pci_tbl,
+	.probe		= tg3_init_one,
+	.remove		= __devexit_p(tg3_remove_one),
+	.suspend	= tg3_suspend,
+	.resume		= tg3_resume
 };
 
 static int __init tg3_init(void)
diff -Nru a/drivers/net/tg3.h b/drivers/net/tg3.h
--- a/drivers/net/tg3.h	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/tg3.h	Sat Aug 10 18:42:21 2002
@@ -1701,7 +1701,21 @@
 };
 
 struct tg3 {
+	/* SMP locking strategy:
+	 *
+	 * lock: Held during all operations except TX packet
+	 *       processing.
+	 *
+	 * tx_lock: Held during tg3_start_xmit{,_4gbug} and tg3_tx
+	 *
+	 * If you want to shut up all asynchronous processing you must
+	 * acquire both locks, 'lock' taken before 'tx_lock'.  IRQs must
+	 * be disabled to take 'lock' but only softirq disabling is
+	 * necessary for acquisition of 'tx_lock'.
+	 */
 	spinlock_t			lock;
+	spinlock_t			tx_lock;
+
 	u32				tx_prod;
 	u32				tx_cons;
 	u32				rx_rcb_ptr;
@@ -1716,11 +1730,6 @@
 	struct net_device_stats		net_stats_prev;
 	unsigned long			phy_crc_errors;
 
-	/* Adaptive coalescing engine. */
-	unsigned long			last_rate_sample;
-	u32				last_rx_count;
-	u32				last_tx_count;
-
 	u32				rx_offset;
 	u32				tg3_flags;
 #define TG3_FLAG_HOST_TXDS		0x00000001
@@ -1728,8 +1737,6 @@
 #define TG3_FLAG_RX_CHECKSUMS		0x00000004
 #define TG3_FLAG_USE_LINKCHG_REG	0x00000008
 #define TG3_FLAG_USE_MI_INTERRUPT	0x00000010
-#define TG3_FLAG_ADAPTIVE_RX		0x00000020
-#define TG3_FLAG_ADAPTIVE_TX		0x00000040
 #define TG3_FLAG_POLL_SERDES		0x00000080
 #define TG3_FLAG_PHY_RESET_ON_INIT	0x00000100
 #define TG3_FLAG_PCIX_TARGET_HWBUG	0x00000200
diff -Nru a/drivers/net/tlan.c b/drivers/net/tlan.c
--- a/drivers/net/tlan.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/tlan.c	Sat Aug 10 18:42:21 2002
@@ -432,10 +432,10 @@
 } 
 
 static struct pci_driver tlan_driver = {
-	name:		"tlan",
-	id_table:	tlan_pci_tbl,
-	probe:		tlan_init_one,
-	remove:		__devexit_p(tlan_remove_one),	
+	.name		= "tlan",
+	.id_table	= tlan_pci_tbl,
+	.probe		= tlan_init_one,
+	.remove		= __devexit_p(tlan_remove_one),	
 };
 
 static int __init tlan_probe(void)
diff -Nru a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
--- a/drivers/net/tokenring/3c359.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/tokenring/3c359.c	Sat Aug 10 18:42:23 2002
@@ -1793,10 +1793,10 @@
 }
 
 static struct pci_driver xl_3c359_driver = {
-	name:		"3c359",
-	id_table:	xl_pci_tbl,
-	probe:		xl_probe,
-	remove:		__devexit_p(xl_remove_one),
+	.name		= "3c359",
+	.id_table	= xl_pci_tbl,
+	.probe		= xl_probe,
+	.remove		= __devexit_p(xl_remove_one),
 };
 
 static int __init xl_pci_init (void)
diff -Nru a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c
--- a/drivers/net/tokenring/abyss.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/tokenring/abyss.c	Sat Aug 10 18:42:21 2002
@@ -448,10 +448,10 @@
 }
 
 static struct pci_driver abyss_driver = {
-	name:		"abyss",
-	id_table:	abyss_pci_tbl,
-	probe:		abyss_attach,
-	remove:		__devexit_p(abyss_detach),
+	.name		= "abyss",
+	.id_table	= abyss_pci_tbl,
+	.probe		= abyss_attach,
+	.remove		= __devexit_p(abyss_detach),
 };
 
 static int __init abyss_init (void)
diff -Nru a/drivers/net/tokenring/lanstreamer.c b/drivers/net/tokenring/lanstreamer.c
--- a/drivers/net/tokenring/lanstreamer.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/tokenring/lanstreamer.c	Sat Aug 10 18:42:22 2002
@@ -1937,10 +1937,10 @@
 #endif
 
 static struct pci_driver streamer_pci_driver = {
-  name:       "lanstreamer",
-  id_table:   streamer_pci_tbl,
-  probe:      streamer_init_one,
-  remove:     __devexit_p(streamer_remove_one),
+  .name     = "lanstreamer",
+  .id_table = streamer_pci_tbl,
+  .probe    = streamer_init_one,
+  .remove   = __devexit_p(streamer_remove_one),
 };
 
 static int __init streamer_init_module(void) {
diff -Nru a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
--- a/drivers/net/tokenring/olympic.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/tokenring/olympic.c	Sat Aug 10 18:42:23 2002
@@ -1753,10 +1753,10 @@
 }
 
 static struct pci_driver olympic_driver = { 
-	name:		"olympic",
-	id_table:	olympic_pci_tbl,
-	probe:		olympic_probe,
-	remove:		__devexit_p(olympic_remove_one),
+	.name		= "olympic",
+	.id_table	= olympic_pci_tbl,
+	.probe		= olympic_probe,
+	.remove		= __devexit_p(olympic_remove_one),
 };
 
 static int __init olympic_pci_init(void) 
diff -Nru a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c
--- a/drivers/net/tokenring/tmspci.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/tokenring/tmspci.c	Sat Aug 10 18:42:23 2002
@@ -235,10 +235,10 @@
 }
 
 static struct pci_driver tms_pci_driver = {
-	name:		"tmspci",
-	id_table:	tmspci_pci_tbl,
-	probe:		tms_pci_attach,
-	remove:		__devexit_p(tms_pci_detach),
+	.name		= "tmspci",
+	.id_table	= tmspci_pci_tbl,
+	.probe		= tms_pci_attach,
+	.remove		= __devexit_p(tms_pci_detach),
 };
 
 static int __init tms_pci_init (void)
diff -Nru a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
--- a/drivers/net/tulip/de2104x.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/tulip/de2104x.c	Sat Aug 10 18:42:21 2002
@@ -2213,13 +2213,13 @@
 #endif /* CONFIG_PM */
 
 static struct pci_driver de_driver = {
-	name:		DRV_NAME,
-	id_table:	de_pci_tbl,
-	probe:		de_init_one,
-	remove:		de_remove_one,
+	.name		= DRV_NAME,
+	.id_table	= de_pci_tbl,
+	.probe		= de_init_one,
+	.remove		= de_remove_one,
 #ifdef CONFIG_PM
-	suspend:	de_suspend,
-	resume:		de_resume,
+	.suspend	= de_suspend,
+	.resume		= de_resume,
 #endif
 };
 
diff -Nru a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
--- a/drivers/net/tulip/dmfe.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/tulip/dmfe.c	Sat Aug 10 18:42:23 2002
@@ -461,7 +461,7 @@
 }
 
 
-static void __exit dmfe_remove_one (struct pci_dev *pdev)
+static void __devexit dmfe_remove_one (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct dmfe_board_info *db = dev->priv;
@@ -1983,10 +1983,10 @@
 
 
 static struct pci_driver dmfe_driver = {
-	name:		"dmfe",
-	id_table:	dmfe_pci_tbl,
-	probe:		dmfe_init_one,
-	remove:		__devexit_p(dmfe_remove_one),
+	.name		= "dmfe",
+	.id_table	= dmfe_pci_tbl,
+	.probe		= dmfe_init_one,
+	.remove		= __devexit_p(dmfe_remove_one),
 };
 
 MODULE_AUTHOR("Sten Wang, sten_wang@davicom.com.tw");
diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
--- a/drivers/net/tulip/tulip_core.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/tulip/tulip_core.c	Sat Aug 10 18:42:23 2002
@@ -218,6 +218,9 @@
 	{ 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
 	{ 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT },
+	{ 0x1186, 0x1561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+	{ 0x1626, 0x8410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+	{ 0x1737, 0xAB09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
 	{ } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, tulip_pci_tbl);
@@ -1752,13 +1755,13 @@
 
 
 static struct pci_driver tulip_driver = {
-	name:		DRV_NAME,
-	id_table:	tulip_pci_tbl,
-	probe:		tulip_init_one,
-	remove:		__devexit_p(tulip_remove_one),
+	.name		= DRV_NAME,
+	.id_table	= tulip_pci_tbl,
+	.probe		= tulip_init_one,
+	.remove		= __devexit_p(tulip_remove_one),
 #ifdef CONFIG_PM
-	suspend:	tulip_suspend,
-	resume:		tulip_resume,
+	.suspend	= tulip_suspend,
+	.resume		= tulip_resume,
 #endif /* CONFIG_PM */
 };
 
diff -Nru a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
--- a/drivers/net/tulip/winbond-840.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/tulip/winbond-840.c	Sat Aug 10 18:42:21 2002
@@ -1729,13 +1729,13 @@
 #endif
 
 static struct pci_driver w840_driver = {
-	name:		DRV_NAME,
-	id_table:	w840_pci_tbl,
-	probe:		w840_probe1,
-	remove:		__devexit_p(w840_remove1),
+	.name		= DRV_NAME,
+	.id_table	= w840_pci_tbl,
+	.probe		= w840_probe1,
+	.remove		= __devexit_p(w840_remove1),
 #ifdef CONFIG_PM
-	suspend:	w840_suspend,
-	resume:		w840_resume,
+	.suspend	= w840_suspend,
+	.resume		= w840_resume,
 #endif
 };
 
diff -Nru a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
--- a/drivers/net/tulip/xircom_cb.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/tulip/xircom_cb.c	Sat Aug 10 18:42:23 2002
@@ -148,12 +148,12 @@
 MODULE_DEVICE_TABLE(pci, xircom_pci_table);
 
 static struct pci_driver xircom_ops = {
-	name:		"xircom_cb", 
-	id_table:	xircom_pci_table, 
-	probe:		xircom_probe, 
-	remove:		xircom_remove, 
-	suspend:NULL,
-	resume:NULL
+	.name		= "xircom_cb", 
+	.id_table	= xircom_pci_table, 
+	.probe		= xircom_probe, 
+	.remove		= xircom_remove, 
+	.suspend =NULL,
+	.resume =NULL
 };
 
 
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	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/tulip/xircom_tulip_cb.c	Sat Aug 10 18:42:21 2002
@@ -1706,13 +1706,13 @@
 
 
 static struct pci_driver xircom_driver = {
-	name:		DRV_NAME,
-	id_table:	xircom_pci_table,
-	probe:		xircom_init_one,
-	remove:		__devexit_p(xircom_remove_one),
+	.name		= DRV_NAME,
+	.id_table	= xircom_pci_table,
+	.probe		= xircom_init_one,
+	.remove		= __devexit_p(xircom_remove_one),
 #ifdef CONFIG_PM
-	suspend:	xircom_suspend,
-	resume:		xircom_resume
+	.suspend	= xircom_suspend,
+	.resume		= xircom_resume
 #endif /* CONFIG_PM */
 };
 
diff -Nru a/drivers/net/tun.c b/drivers/net/tun.c
--- a/drivers/net/tun.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/tun.c	Sat Aug 10 18:42:22 2002
@@ -564,17 +564,17 @@
 }
 
 static struct file_operations tun_fops = {
-	owner:	THIS_MODULE,	
-	llseek:	no_llseek,
-	read:	tun_chr_read,
-	readv:	tun_chr_readv,
-	write:	tun_chr_write,
-	writev:	tun_chr_writev,
-	poll:	tun_chr_poll,
-	ioctl:	tun_chr_ioctl,
-	open:	tun_chr_open,
-	release:tun_chr_close,
-	fasync:	tun_chr_fasync		
+	.owner	= THIS_MODULE,	
+	.llseek = no_llseek,
+	.read	= tun_chr_read,
+	.readv	= tun_chr_readv,
+	.write	= tun_chr_write,
+	.writev = tun_chr_writev,
+	.poll	= tun_chr_poll,
+	.ioctl	= tun_chr_ioctl,
+	.open	= tun_chr_open,
+	.release = tun_chr_close,
+	.fasync = tun_chr_fasync		
 };
 
 static struct miscdevice tun_miscdev=
diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
--- a/drivers/net/via-rhine.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/via-rhine.c	Sat Aug 10 18:42:22 2002
@@ -1760,10 +1760,10 @@
 
 
 static struct pci_driver via_rhine_driver = {
-	name:		"via-rhine",
-	id_table:	via_rhine_pci_tbl,
-	probe:		via_rhine_init_one,
-	remove:		__devexit_p(via_rhine_remove_one),
+	.name		= "via-rhine",
+	.id_table	= via_rhine_pci_tbl,
+	.probe		= via_rhine_init_one,
+	.remove		= __devexit_p(via_rhine_remove_one),
 };
 
 
diff -Nru a/drivers/net/wan/comx-proto-fr.c b/drivers/net/wan/comx-proto-fr.c
--- a/drivers/net/wan/comx-proto-fr.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/wan/comx-proto-fr.c	Sat Aug 10 18:42:22 2002
@@ -963,27 +963,27 @@
 }
 
 static struct comx_protocol fr_master_protocol = {
-	name:		"frad", 
-	version:	VERSION,
-	encap_type:	ARPHRD_FRAD, 
-	line_init:	fr_master_init, 
-	line_exit:	fr_exit, 
+	.name		= "frad", 
+	.version	= VERSION,
+	.encap_type	= ARPHRD_FRAD, 
+	.line_init	= fr_master_init, 
+	.line_exit	= fr_exit, 
 };
 
 static struct comx_protocol fr_slave_protocol = {
-	name:		"ietf-ip", 
-	version:	VERSION,
-	encap_type:	ARPHRD_DLCI, 
-	line_init:	fr_slave_init, 
-	line_exit:	fr_exit, 
+	.name		= "ietf-ip", 
+	.version	= VERSION,
+	.encap_type	= ARPHRD_DLCI, 
+	.line_init	= fr_slave_init, 
+	.line_exit	= fr_exit, 
 };
 
 static struct comx_hardware fr_dlci = { 
-	name:		"dlci", 
-	version:	VERSION,
-	hw_init:	dlci_init, 
-	hw_exit:	dlci_exit, 
-	hw_dump:	dlci_dump, 
+	.name		= "dlci", 
+	.version	= VERSION,
+	.hw_init	= dlci_init, 
+	.hw_exit	= dlci_exit, 
+	.hw_dump	= dlci_dump, 
 };
 
 #ifdef MODULE
diff -Nru a/drivers/net/wan/comx.c b/drivers/net/wan/comx.c
--- a/drivers/net/wan/comx.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/wan/comx.c	Sat Aug 10 18:42:22 2002
@@ -98,9 +98,9 @@
 static struct dentry *comx_lookup(struct inode *, struct dentry *);
 
 static struct inode_operations comx_root_inode_ops = {
-	lookup:	comx_lookup,
-	mkdir: comx_mkdir,
-	rmdir: comx_rmdir,
+	.lookup = comx_lookup,
+	.mkdir = comx_mkdir,
+	.rmdir = comx_rmdir,
 };
 
 static int comx_delete_dentry(struct dentry *dentry);
@@ -108,7 +108,7 @@
 	int size, struct proc_dir_entry *dir);
 
 static struct dentry_operations comx_dentry_operations = {
-	d_delete:	comx_delete_dentry,
+	.d_delete	= comx_delete_dentry,
 };
 
 
diff -Nru a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
--- a/drivers/net/wan/cosa.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/net/wan/cosa.c	Sat Aug 10 18:42:20 2002
@@ -311,16 +311,16 @@
 #endif
 
 static struct file_operations cosa_fops = {
-	owner:		THIS_MODULE,
-	llseek:		no_llseek,
-	read:		cosa_read,
-	write:		cosa_write,
-	poll:		cosa_poll,
-	ioctl:		cosa_chardev_ioctl,
-	open:		cosa_open,
-	release:	cosa_release,
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.read		= cosa_read,
+	.write		= cosa_write,
+	.poll		= cosa_poll,
+	.ioctl		= cosa_chardev_ioctl,
+	.open		= cosa_open,
+	.release	= cosa_release,
 #ifdef COSA_FASYNC_WORKING
-	fasync:		cosa_fasync,
+	.fasync		= cosa_fasync,
 #endif
 };
 
diff -Nru a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
--- a/drivers/net/wan/dscc4.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/wan/dscc4.c	Sat Aug 10 18:42:21 2002
@@ -1860,10 +1860,10 @@
 MODULE_DEVICE_TABLE(pci, dscc4_pci_tbl);
 
 static struct pci_driver dscc4_driver = {
-	name:           DRV_NAME,
-	id_table:       dscc4_pci_tbl,
-	probe:          dscc4_init_one,
-	remove:         dscc4_remove_one,
+	.name		= DRV_NAME,
+	.id_table	= dscc4_pci_tbl,
+	.probe		= dscc4_init_one,
+	.remove		= dscc4_remove_one,
 };
 
 static int __init dscc4_init_module(void)
diff -Nru a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
--- a/drivers/net/wan/farsync.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/wan/farsync.c	Sat Aug 10 18:42:21 2002
@@ -1660,12 +1660,12 @@
 }
 
 static struct pci_driver fst_driver = {
-        name:           FST_NAME,
-        id_table:       fst_pci_dev_id,
-        probe:          fst_add_one,
-        remove:         __devexit_p(fst_remove_one),
-        suspend:        NULL,
-        resume:         NULL,
+        .name		= FST_NAME,
+        .id_table	= fst_pci_dev_id,
+        .probe		= fst_add_one,
+        .remove	= __devexit_p(fst_remove_one),
+        .suspend	= NULL,
+        .resume	= NULL,
 };
 
 static int __init
diff -Nru a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c
--- a/drivers/net/wan/lapbether.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/wan/lapbether.c	Sat Aug 10 18:42:22 2002
@@ -458,12 +458,12 @@
 /* ------------------------------------------------------------------------ */
 
 static struct packet_type lapbeth_packet_type = {
-	type:		__constant_htons(ETH_P_DEC),
-	func:		lapbeth_rcv,
+	.type		= __constant_htons(ETH_P_DEC),
+	.func		= lapbeth_rcv,
 };
 
 static struct notifier_block lapbeth_dev_notifier = {
-	notifier_call: lapbeth_device_event,
+	.notifier_call = lapbeth_device_event,
 };
 
 static char banner[] __initdata = KERN_INFO "LAPB Ethernet driver version 0.01\n";
diff -Nru a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
--- a/drivers/net/wan/pc300_drv.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/wan/pc300_drv.c	Sat Aug 10 18:42:23 2002
@@ -3661,12 +3661,12 @@
 }
 
 static struct pci_driver cpc_driver = {
-	name:"pc300",
-	id_table:cpc_pci_dev_id,
-	probe:cpc_init_one,
-	remove:cpc_remove_one,
-	suspend:NULL,
-	resume:NULL,
+	.name = "pc300",
+	.id_table = cpc_pci_dev_id,
+	.probe = cpc_init_one,
+	.remove = cpc_remove_one,
+	.suspend = NULL,
+	.resume = NULL,
 };
 
 static int __init cpc_init(void)
diff -Nru a/drivers/net/wan/sdlamain.c b/drivers/net/wan/sdlamain.c
--- a/drivers/net/wan/sdlamain.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/wan/sdlamain.c	Sat Aug 10 18:42:23 2002
@@ -244,8 +244,8 @@
 DECLARE_TASK_QUEUE(wanpipe_tq_custom);
 static struct tq_struct wanpipe_tq_task = 
 {
-	routine: (void (*)(void *)) run_wanpipe_tq,
-	data: &wanpipe_tq_custom
+	.routine = (void (*)(void *)) run_wanpipe_tq,
+	.data = &wanpipe_tq_custom
 };
 #else
 static struct tq_struct *wanpipe_tq_custom = NULL;
diff -Nru a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
--- a/drivers/net/wan/syncppp.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/wan/syncppp.c	Sat Aug 10 18:42:22 2002
@@ -1393,8 +1393,8 @@
 }
 
 struct packet_type sppp_packet_type = {
-	type:	__constant_htons(ETH_P_WAN_PPP),
-	func:	sppp_rcv,
+	.type	= __constant_htons(ETH_P_WAN_PPP),
+	.func	= sppp_rcv,
 };
 
 static char banner[] __initdata = 
diff -Nru a/drivers/net/wd.c b/drivers/net/wd.c
--- a/drivers/net/wd.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/wd.c	Sat Aug 10 18:42:21 2002
@@ -370,9 +370,11 @@
 	if (ei_status.word16)
 		outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5);
 
-#ifdef notdef
+#ifdef __BIG_ENDIAN
 	/* Officially this is what we are doing, but the readl() is faster */
+	/* unfortunately it isn't endian aware of the struct               */
 	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+	hdr->count = le16_to_cpu(hdr->count);
 #else
 	((unsigned int*)hdr)[0] = isa_readl(hdr_start);
 #endif
diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/wireless/airo.c	Sat Aug 10 18:42:21 2002
@@ -61,10 +61,10 @@
 static void airo_pci_remove(struct pci_dev *);
 
 static struct pci_driver airo_driver = {
-	name:     "airo",
-	id_table: card_ids,
-	probe:    airo_pci_probe,
-	remove:   __devexit_p(airo_pci_remove),
+	.name     = "airo",
+	.id_table = card_ids,
+	.probe    = airo_pci_probe,
+	.remove   = __devexit_p(airo_pci_remove),
 };
 #endif /* CONFIG_PCI */
 
@@ -2562,56 +2562,56 @@
 static int proc_wepkey_open( struct inode *inode, struct file *file );
 
 static struct file_operations proc_statsdelta_ops = {
-	read:           proc_read,
-	open:           proc_statsdelta_open,
-	release:        proc_close
+	.read		= proc_read,
+	.open		= proc_statsdelta_open,
+	.release	= proc_close
 };
 
 static struct file_operations proc_stats_ops = {
-	read:           proc_read,
-	open:           proc_stats_open,
-	release:        proc_close
+	.read		= proc_read,
+	.open		= proc_stats_open,
+	.release	= proc_close
 };
 
 static struct file_operations proc_status_ops = {
-	read:            proc_read,
-	open:            proc_status_open,
-	release:         proc_close
+	.read		= proc_read,
+	.open		= proc_status_open,
+	.release	= proc_close
 };
 
 static struct file_operations proc_SSID_ops = {
-	read:          proc_read,
-	write:         proc_write,
-	open:          proc_SSID_open,
-	release:       proc_close
+	.read		= proc_read,
+	.write		= proc_write,
+	.open		= proc_SSID_open,
+	.release	= proc_close
 };
 
 static struct file_operations proc_BSSList_ops = {
-	read:          proc_read,
-	write:         proc_write,
-	open:          proc_BSSList_open,
-	release:       proc_close
+	.read		= proc_read,
+	.write		= proc_write,
+	.open		= proc_BSSList_open,
+	.release	= proc_close
 };
 
 static struct file_operations proc_APList_ops = {
-	read:          proc_read,
-	write:         proc_write,
-	open:          proc_APList_open,
-	release:       proc_close
+	.read		= proc_read,
+	.write		= proc_write,
+	.open		= proc_APList_open,
+	.release	= proc_close
 };
 
 static struct file_operations proc_config_ops = {
-	read:          proc_read,
-	write:         proc_write,
-	open:          proc_config_open,
-	release:       proc_close
+	.read		= proc_read,
+	.write		= proc_write,
+	.open		= proc_config_open,
+	.release	= proc_close
 };
 
 static struct file_operations proc_wepkey_ops = {
-	read:          proc_read,
-	write:         proc_write,
-	open:          proc_wepkey_open,
-	release:       proc_close
+	.read		= proc_read,
+	.write		= proc_write,
+	.open		= proc_wepkey_open,
+	.release	= proc_close
 };
 
 static struct proc_dir_entry *airo_entry = 0;
@@ -5208,12 +5208,12 @@
 
 static const struct iw_handler_def	airo_handler_def =
 {
-	num_standard:	sizeof(airo_handler)/sizeof(iw_handler),
-	num_private:	sizeof(airo_private_handler)/sizeof(iw_handler),
-	num_private_args: sizeof(airo_private_args)/sizeof(struct iw_priv_args),
-	standard:	(iw_handler *) airo_handler,
-	private:	(iw_handler *) airo_private_handler,
-	private_args:	(struct iw_priv_args *) airo_private_args,
+	.num_standard	= sizeof(airo_handler)/sizeof(iw_handler),
+	.num_private	= sizeof(airo_private_handler)/sizeof(iw_handler),
+	.num_private_args = sizeof(airo_private_args)/sizeof(struct iw_priv_args),
+	.standard	= (iw_handler *) airo_handler,
+	.private	= (iw_handler *) airo_private_handler,
+	.private_args	= (struct iw_priv_args *) airo_private_args,
 };
 
 #endif /* WIRELESS_EXT > 12 */
diff -Nru a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
--- a/drivers/net/wireless/netwave_cs.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/wireless/netwave_cs.c	Sat Aug 10 18:42:22 2002
@@ -902,12 +902,12 @@
 
 static const struct iw_handler_def	netwave_handler_def =
 {
-	num_standard:	sizeof(netwave_handler)/sizeof(iw_handler),
-	num_private:	sizeof(netwave_private_handler)/sizeof(iw_handler),
-	num_private_args: sizeof(netwave_private_args)/sizeof(struct iw_priv_args),
-	standard:	(iw_handler *) netwave_handler,
-	private:	(iw_handler *) netwave_private_handler,
-	private_args:	(struct iw_priv_args *) netwave_private_args,
+	.num_standard	= sizeof(netwave_handler)/sizeof(iw_handler),
+	.num_private	= sizeof(netwave_private_handler)/sizeof(iw_handler),
+	.num_private_args = sizeof(netwave_private_args)/sizeof(struct iw_priv_args),
+	.standard	= (iw_handler *) netwave_handler,
+	.private	= (iw_handler *) netwave_private_handler,
+	.private_args	= (struct iw_priv_args *) netwave_private_args,
 };
 #endif /* WIRELESS_EXT > 12 */
 
diff -Nru a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
--- a/drivers/net/wireless/orinoco_pci.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/net/wireless/orinoco_pci.c	Sat Aug 10 18:42:21 2002
@@ -361,12 +361,10 @@
 MODULE_DEVICE_TABLE(pci, orinoco_pci_pci_id_table);
 
 static struct pci_driver orinoco_pci_driver = {
-	name:"orinoco_pci",
-	id_table:orinoco_pci_pci_id_table,
-	probe:orinoco_pci_init_one,
-	remove:orinoco_pci_remove_one,
-	suspend:0,
-	resume:0
+	.name		= "orinoco_pci",
+	.id_table	= orinoco_pci_pci_id_table,
+	.probe		= orinoco_pci_init_one,
+	.remove		= __devexit_p(orinoco_pci_remove_one),
 };
 
 static int __init orinoco_pci_init(void)
diff -Nru a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
--- a/drivers/net/wireless/orinoco_plx.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/wireless/orinoco_plx.c	Sat Aug 10 18:42:23 2002
@@ -363,6 +363,7 @@
 
 
 static struct pci_device_id orinoco_plx_pci_id_table[] __devinitdata = {
+	{0x10b7, 0x7770, PCI_ANY_ID, PCI_ANY_ID,},	/* 3ComAirConnect */
 	{0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,},	/* Siemens SpeedStream SS1023 */
 	{0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,},	/* Netgear MA301 */
 	{0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,},	/* Correga  - does this work? */
@@ -382,12 +383,10 @@
 MODULE_DEVICE_TABLE(pci, orinoco_plx_pci_id_table);
 
 static struct pci_driver orinoco_plx_driver = {
-	name:"orinoco_plx",
-	id_table:orinoco_plx_pci_id_table,
-	probe:orinoco_plx_init_one,
-	remove:orinoco_plx_remove_one,
-	suspend:0,
-	resume:0
+	.name		= "orinoco_plx",
+	.id_table	= orinoco_plx_pci_id_table,
+	.probe		= orinoco_plx_init_one,
+	.remove		= __devexit_p(orinoco_plx_remove_one),
 };
 
 static int __init orinoco_plx_init(void)
diff -Nru a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
--- a/drivers/net/wireless/wavelan.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/wireless/wavelan.c	Sat Aug 10 18:42:22 2002
@@ -2488,12 +2488,12 @@
 
 static const struct iw_handler_def	wavelan_handler_def =
 {
-	num_standard:	sizeof(wavelan_handler)/sizeof(iw_handler),
-	num_private:	sizeof(wavelan_private_handler)/sizeof(iw_handler),
-	num_private_args: sizeof(wavelan_private_args)/sizeof(struct iw_priv_args),
-	standard:	(iw_handler *) wavelan_handler,
-	private:	(iw_handler *) wavelan_private_handler,
-	private_args:	(struct iw_priv_args *) wavelan_private_args,
+	.num_standard	= sizeof(wavelan_handler)/sizeof(iw_handler),
+	.num_private	= sizeof(wavelan_private_handler)/sizeof(iw_handler),
+	.num_private_args = sizeof(wavelan_private_args)/sizeof(struct iw_priv_args),
+	.standard	= (iw_handler *) wavelan_handler,
+	.private	= (iw_handler *) wavelan_private_handler,
+	.private_args	= (struct iw_priv_args *) wavelan_private_args,
 };
 
 /*------------------------------------------------------------------*/
diff -Nru a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
--- a/drivers/net/wireless/wavelan_cs.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/net/wireless/wavelan_cs.c	Sat Aug 10 18:42:23 2002
@@ -2856,12 +2856,12 @@
 
 static const struct iw_handler_def	wavelan_handler_def =
 {
-	num_standard:	sizeof(wavelan_handler)/sizeof(iw_handler),
-	num_private:	sizeof(wavelan_private_handler)/sizeof(iw_handler),
-	num_private_args: sizeof(wavelan_private_args)/sizeof(struct iw_priv_args),
-	standard:	(iw_handler *) wavelan_handler,
-	private:	(iw_handler *) wavelan_private_handler,
-	private_args:	(struct iw_priv_args *) wavelan_private_args,
+	.num_standard	= sizeof(wavelan_handler)/sizeof(iw_handler),
+	.num_private	= sizeof(wavelan_private_handler)/sizeof(iw_handler),
+	.num_private_args = sizeof(wavelan_private_args)/sizeof(struct iw_priv_args),
+	.standard	= (iw_handler *) wavelan_handler,
+	.private	= (iw_handler *) wavelan_private_handler,
+	.private_args	= (struct iw_priv_args *) wavelan_private_args,
 };
 
 #else /* WIRELESS_EXT > 12 */
diff -Nru a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
--- a/drivers/net/yellowfin.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/net/yellowfin.c	Sat Aug 10 18:42:22 2002
@@ -1484,10 +1484,10 @@
 
 
 static struct pci_driver yellowfin_driver = {
-	name:		DRV_NAME,
-	id_table:	yellowfin_pci_tbl,
-	probe:		yellowfin_init_one,
-	remove:		__devexit_p(yellowfin_remove_one),
+	.name		= DRV_NAME,
+	.id_table	= yellowfin_pci_tbl,
+	.probe		= yellowfin_init_one,
+	.remove		= __devexit_p(yellowfin_remove_one),
 };
 
 
diff -Nru a/drivers/pci/Makefile b/drivers/pci/Makefile
--- a/drivers/pci/Makefile	Sat Aug 10 18:42:23 2002
+++ b/drivers/pci/Makefile	Sat Aug 10 18:42:23 2002
@@ -2,7 +2,8 @@
 # Makefile for the PCI bus specific drivers.
 #
 
-export-objs := access.o hotplug.o pci-driver.o pci.o pool.o probe.o proc.o search.o
+export-objs	:= access.o hotplug.o pci-driver.o pci.o pool.o \
+			probe.o proc.o search.o compat.o
 
 obj-y		+= access.o probe.o pci.o pool.o quirks.o \
 			compat.o names.o pci-driver.o search.o
diff -Nru a/drivers/pci/compat.c b/drivers/pci/compat.c
--- a/drivers/pci/compat.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/pci/compat.c	Sat Aug 10 18:42:22 2002
@@ -8,8 +8,11 @@
 
 #include <linux/types.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/pci.h>
 
+/* Obsolete functions, these will be going away... */
+
 int
 pcibios_present(void)
 {
@@ -63,3 +66,14 @@
 PCI_OP(write, byte, char)
 PCI_OP(write, word, short)
 PCI_OP(write, dword, int)
+
+
+EXPORT_SYMBOL(pcibios_present);
+EXPORT_SYMBOL(pcibios_read_config_byte);
+EXPORT_SYMBOL(pcibios_read_config_word);
+EXPORT_SYMBOL(pcibios_read_config_dword);
+EXPORT_SYMBOL(pcibios_write_config_byte);
+EXPORT_SYMBOL(pcibios_write_config_word);
+EXPORT_SYMBOL(pcibios_write_config_dword);
+EXPORT_SYMBOL(pcibios_find_class);
+EXPORT_SYMBOL(pcibios_find_device);
diff -Nru a/drivers/pci/names.c b/drivers/pci/names.c
--- a/drivers/pci/names.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/pci/names.c	Sat Aug 10 18:42:21 2002
@@ -32,18 +32,18 @@
  * real memory.. Parse the same file multiple times
  * to get all the info.
  */
-#define VENDOR( vendor, name )		static char __vendorstr_##vendor[] __initdata = name;
+#define VENDOR( vendor, name )		static char __vendorstr_##vendor[] __devinitdata = name;
 #define ENDVENDOR()
-#define DEVICE( vendor, device, name ) 	static char __devicestr_##vendor##device[] __initdata = name;
+#define DEVICE( vendor, device, name ) 	static char __devicestr_##vendor##device[] __devinitdata = name;
 #include "devlist.h"
 
 
-#define VENDOR( vendor, name )		static struct pci_device_info __devices_##vendor[] __initdata = {
+#define VENDOR( vendor, name )		static struct pci_device_info __devices_##vendor[] __devinitdata = {
 #define ENDVENDOR()			};
 #define DEVICE( vendor, device, name )	{ 0x##device, 0, __devicestr_##vendor##device },
 #include "devlist.h"
 
-static struct pci_vendor_info __initdata pci_vendor_list[] = {
+static struct pci_vendor_info __devinitdata pci_vendor_list[] = {
 #define VENDOR( vendor, name )		{ 0x##vendor, sizeof(__devices_##vendor) / sizeof(struct pci_device_info), __vendorstr_##vendor, __devices_##vendor },
 #define ENDVENDOR()
 #define DEVICE( vendor, device, name )
@@ -121,7 +121,7 @@
 
 #else
 
-void __init pci_name_device(struct pci_dev *dev)
+void __devinit pci_name_device(struct pci_dev *dev)
 {
 }
 
diff -Nru a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
--- a/drivers/pci/pci-driver.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/pci/pci-driver.c	Sat Aug 10 18:42:23 2002
@@ -90,7 +90,11 @@
 	struct pci_dev * pci_dev = to_pci_dev(dev);
 
 	if (pci_dev->driver) {
-		if (level == RESUME_POWER_ON && pci_dev->driver->resume)
+		/* We may not call PCI drivers resume at
+		   RESUME_POWER_ON because interrupts are not yet
+		   working at that point. Calling resume at
+		   RESUME_RESTORE_STATE seems like solution. */
+		if (level == RESUME_RESTORE_STATE && pci_dev->driver->resume)
 			pci_dev->driver->resume(pci_dev);
 	}
 	return 0;
diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c
--- a/drivers/pci/pci.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/pci/pci.c	Sat Aug 10 18:42:22 2002
@@ -602,18 +602,6 @@
 EXPORT_SYMBOL(pci_restore_state);
 EXPORT_SYMBOL(pci_enable_wake);
 
-/* Obsolete functions */
-
-EXPORT_SYMBOL(pcibios_present);
-EXPORT_SYMBOL(pcibios_read_config_byte);
-EXPORT_SYMBOL(pcibios_read_config_word);
-EXPORT_SYMBOL(pcibios_read_config_dword);
-EXPORT_SYMBOL(pcibios_write_config_byte);
-EXPORT_SYMBOL(pcibios_write_config_word);
-EXPORT_SYMBOL(pcibios_write_config_dword);
-EXPORT_SYMBOL(pcibios_find_class);
-EXPORT_SYMBOL(pcibios_find_device);
-
 /* Quirk info */
 
 EXPORT_SYMBOL(isa_dma_bridge_buggy);
diff -Nru a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
--- a/drivers/pcmcia/Makefile	Sat Aug 10 18:42:21 2002
+++ b/drivers/pcmcia/Makefile	Sat Aug 10 18:42:21 2002
@@ -2,7 +2,7 @@
 # Makefile for the kernel pcmcia subsystem (c/o David Hinds)
 #
 
-export-objs := ds.o cs.o yenta.o
+export-objs := ds.o cs.o yenta.o sa1100_pcmcia.o
 
 obj-$(CONFIG_PCMCIA)			+= pcmcia_core.o ds.o
 ifeq ($(CONFIG_CARDBUS),y)
diff -Nru a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
--- a/drivers/pcmcia/sa1100_generic.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/pcmcia/sa1100_generic.c	Sat Aug 10 18:42:23 2002
@@ -137,7 +137,7 @@
 
 	local_irq_restore(flags);
 
-	DEBUG(4, "%s(): FAST%u %lx  BSM%u %lx  BSA%u %lx  BSIO%u %lx\n",
+	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));
@@ -1052,6 +1052,7 @@
 	pcmcia_low_level = NULL;
 	return ret;
 }
+EXPORT_SYMBOL(sa1100_register_pcmcia);
 
 /* sa1100_unregister_pcmcia()
  * ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1091,6 +1092,7 @@
 
 	pcmcia_low_level = NULL;
 }
+EXPORT_SYMBOL(sa1100_unregister_pcmcia);
 
 /* sa1100_pcmcia_init()
  * ^^^^^^^^^^^^^^^^^^^^
diff -Nru a/drivers/pnp/pnpbios_core.c b/drivers/pnp/pnpbios_core.c
--- a/drivers/pnp/pnpbios_core.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/pnp/pnpbios_core.c	Sat Aug 10 18:42:20 2002
@@ -126,11 +126,11 @@
 
 #define Q_SET_SEL(cpu, selname, address, size) \
 set_base(cpu_gdt_table[cpu][(selname) >> 3], __va((u32)(address))); \
-_set_limit(&cpu_gdt_table[cpu][(selname) >> 3], size)
+set_limit(&cpu_gdt_table[cpu][(selname) >> 3], size)
 
 #define Q2_SET_SEL(cpu, selname, address, size) \
 set_base(cpu_gdt_table[cpu][(selname) >> 3], (u32)(address)); \
-_set_limit((char *)&cpu_gdt_table[cpu][(selname) >> 3], size)
+set_limit(&cpu_gdt_table[cpu][(selname) >> 3], size)
 
 /*
  * At some point we want to use this stack frame pointer to unwind
diff -Nru a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
--- a/drivers/s390/block/dasd_ioctl.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/s390/block/dasd_ioctl.c	Sat Aug 10 18:42:20 2002
@@ -448,31 +448,6 @@
 }
 
 /*
- * Reread partition table.
- */
-static int dasd_ioctl_rr_partition(void *inp, int no, long args)
-{
-	dasd_devmap_t *devmap;
-	dasd_device_t *device;
-
-	if (!capable(CAP_SYS_ADMIN))
-		return -EACCES;
-
-	devmap = dasd_devmap_from_kdev(((struct inode *) inp)->i_rdev);
-	device = (devmap != NULL) ?
-		dasd_get_device(devmap) : ERR_PTR(-ENODEV);
-	if (IS_ERR(device))
-		return PTR_ERR(device);
-	if (atomic_read(&device->open_count) != 1)
-		DEV_MESSAGE(KERN_WARNING, device, "%s",
-			    "BLKRRPART: device is open! expect errors.");
-	dasd_destroy_partitions(device);
-	dasd_setup_partitions(device);
-	dasd_put_device(devmap);
-	return 0;
-}
-
-/*
  * Return disk geometry.
  */
 static int dasd_ioctl_getgeo(void *inp, int no, long args)
@@ -516,7 +491,6 @@
 	{ BIODASDPRRD, dasd_ioctl_read_profile },
 	{ BIODASDPRRST, dasd_ioctl_reset_profile },
 	{ BLKROSET, dasd_ioctl_set_ro },
-	{ BLKRRPART, dasd_ioctl_rr_partition },
 	{ DASDAPIVER, dasd_ioctl_api_version },
 	{ HDIO_GETGEO, dasd_ioctl_getgeo },
 	{ -1, NULL }
diff -Nru a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
--- a/drivers/s390/block/xpram.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/s390/block/xpram.c	Sat Aug 10 18:42:23 2002
@@ -334,35 +334,26 @@
 {
 	struct hd_geometry *geo;
 	unsigned long size;
-	int idx;
-
-	if ((!inode) || kdev_none(inode->i_rdev))
-		return -EINVAL;
-	idx = minor(inode->i_rdev);
+	int idx = minor(inode->i_rdev);
 	if (idx >= xpram_devs)
 		return -ENODEV;
-	switch (cmd) {
-	case BLKRRPART:
-		/* re-read partition table: can't do it */
+	if (cmd != HDIO_GETGEO)
 		return -EINVAL;
-	case HDIO_GETGEO:
-		/*
-		 * get geometry: we have to fake one...  trim the size to a
-		 * multiple of 64 (32k): tell we have 16 sectors, 4 heads,
-		 * whatever cylinders. Tell also that data starts at sector. 4.
-		 */
-		geo = (struct hd_geometry *) arg;
-		if (geo == NULL)
-			return -EINVAL;
-		size = (xpram_pages * 8) & ~0x3f;
-		put_user(size >> 6, &geo->cylinders);
-		put_user(4, &geo->heads);
-		put_user(16, &geo->sectors);
-		put_user(4, &geo->start);
-		return 0;
-	default:
+	/*
+	 * get geometry: we have to fake one...  trim the size to a
+	 * multiple of 64 (32k): tell we have 16 sectors, 4 heads,
+	 * whatever cylinders. Tell also that data starts at sector. 4.
+	 */
+	geo = (struct hd_geometry *) arg;
+	if (geo == NULL)
 		return -EINVAL;
-	}
+	size = (xpram_pages * 8) & ~0x3f;
+	put_user(size >> 6, &geo->cylinders);
+	put_user(4, &geo->heads);
+	put_user(16, &geo->sectors);
+	put_user(4, &geo->start);
+	return 0;
+}
 }
 
 static struct block_device_operations xpram_devops =
diff -Nru a/drivers/sbus/audio/audio.c b/drivers/sbus/audio/audio.c
--- a/drivers/sbus/audio/audio.c	Sat Aug 10 18:42:19 2002
+++ b/drivers/sbus/audio/audio.c	Sat Aug 10 18:42:19 2002
@@ -1694,9 +1694,9 @@
 }
 
 static struct file_operations sparcaudioctl_fops = {
-	owner:		THIS_MODULE,
-	poll:		sparcaudio_poll,
-	ioctl:		sparcaudio_ioctl,
+	.owner =	THIS_MODULE,
+	.poll =		sparcaudio_poll,
+	.ioctl =	sparcaudio_ioctl,
 };
 
 static int sparcaudio_open(struct inode * inode, struct file * file)
@@ -1886,14 +1886,14 @@
 }
 
 static struct file_operations sparcaudio_fops = {
-	owner:		THIS_MODULE,
-	llseek:		no_llseek,
-	read:		sparcaudio_read,
-	write:		sparcaudio_write,
-	poll:		sparcaudio_poll,
-	ioctl:		sparcaudio_ioctl,
-	open:		sparcaudio_open,
-	release:	sparcaudio_release,
+	.owner =	THIS_MODULE,
+	.llseek =	no_llseek,
+	.read =		sparcaudio_read,
+	.write =	sparcaudio_write,
+	.poll =		sparcaudio_poll,
+	.ioctl =	sparcaudio_ioctl,
+	.open =		sparcaudio_open,
+	.release =	sparcaudio_release,
 };
 
 static struct {
diff -Nru a/drivers/sbus/char/Config.help b/drivers/sbus/char/Config.help
--- a/drivers/sbus/char/Config.help	Sat Aug 10 18:42:23 2002
+++ b/drivers/sbus/char/Config.help	Sat Aug 10 18:42:23 2002
@@ -57,10 +57,6 @@
   If you say Y here, you will be able to boot from your JavaStation's
   Flash memory.
 
-CONFIG_SAB82532
-  This driver supports the serial ports on newer (PCI) Ultra systems.
-  Say Y if you want to be able to use your serial ports.
-
 CONFIG_SUN_VIDEOPIX
   Say Y here to support the Videopix Frame Grabber from Sun
   Microsystems, commonly found on SPARCstations.  This card, which is
diff -Nru a/drivers/sbus/char/Config.in b/drivers/sbus/char/Config.in
--- a/drivers/sbus/char/Config.in	Sat Aug 10 18:42:21 2002
+++ b/drivers/sbus/char/Config.in	Sat Aug 10 18:42:21 2002
@@ -3,9 +3,6 @@
 tristate '/dev/openprom device support' CONFIG_SUN_OPENPROMIO
 tristate 'Mostek real time clock support' CONFIG_SUN_MOSTEK_RTC
 if [ "$CONFIG_SPARC64" = "y" ]; then
-   if [ "$CONFIG_PCI" = "y" ]; then
-      tristate 'Siemens SAB82532 serial support' CONFIG_SAB82532
-   fi
    tristate 'OBP Flash Device support' CONFIG_OBP_FLASH
 fi
 
diff -Nru a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile
--- a/drivers/sbus/char/Makefile	Sat Aug 10 18:42:23 2002
+++ b/drivers/sbus/char/Makefile	Sat Aug 10 18:42:23 2002
@@ -7,15 +7,11 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-export-objs := su.o bbc_i2c.o
-obj-y := sunkbd.o sunkbdmap.o sunmouse.o sunserial.o zs.o
+export-objs := bbc_i2c.o
 
 vfc-objs := vfc_dev.o vfc_i2c.o
 bbc-objs := bbc_i2c.o bbc_envctrl.o
 
-obj-$(CONFIG_PCI) += su.o pcikbd.o
-
-obj-$(CONFIG_SAB82532)			+= sab82532.o
 obj-$(CONFIG_ENVCTRL)			+= envctrl.o
 obj-$(CONFIG_DISPLAY7SEG)		+= display7seg.o
 obj-$(CONFIG_WATCHDOG_CP1XXX)		+= cpwatchdog.o
diff -Nru a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
--- a/drivers/sbus/char/bpp.c	Sat Aug 10 18:42:20 2002
+++ b/drivers/sbus/char/bpp.c	Sat Aug 10 18:42:20 2002
@@ -859,12 +859,12 @@
 }
 
 static struct file_operations bpp_fops = {
-	owner:		THIS_MODULE,
-	read:		bpp_read,
-	write:		bpp_write,
-	ioctl:		bpp_ioctl,
-	open:		bpp_open,
-	release:	bpp_release,
+	.owner =	THIS_MODULE,
+	.read =		bpp_read,
+	.write =	bpp_write,
+	.ioctl =	bpp_ioctl,
+	.open =		bpp_open,
+	.release =	bpp_release,
 };
 
 #if defined(__i386__)
diff -Nru a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c
--- a/drivers/sbus/char/cpwatchdog.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/sbus/char/cpwatchdog.c	Sat Aug 10 18:42:23 2002
@@ -460,12 +460,12 @@
 }
 
 static struct file_operations wd_fops = {
-	owner:		THIS_MODULE,
-	ioctl:		wd_ioctl,
-	open:		wd_open,
-	write:		wd_write,
-	read:		wd_read,
-	release:	wd_release,
+	.owner =	THIS_MODULE,
+	.ioctl =	wd_ioctl,
+	.open =		wd_open,
+	.write =	wd_write,
+	.read =		wd_read,
+	.release =	wd_release,
 };
 
 static struct miscdevice wd0_miscdev = { WD0_MINOR, WD0_DEVNAME, &wd_fops };
diff -Nru a/drivers/sbus/char/display7seg.c b/drivers/sbus/char/display7seg.c
--- a/drivers/sbus/char/display7seg.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/sbus/char/display7seg.c	Sat Aug 10 18:42:23 2002
@@ -164,10 +164,10 @@
 }
 
 static struct file_operations d7s_fops = {
-	owner:		THIS_MODULE,
-	ioctl:		d7s_ioctl,
-	open:		d7s_open,
-	release:	d7s_release,
+	.owner =	THIS_MODULE,
+	.ioctl =	d7s_ioctl,
+	.open =		d7s_open,
+	.release =	d7s_release,
 };
 
 static struct miscdevice d7s_miscdev = { D7S_MINOR, D7S_DEVNAME, &d7s_fops };
diff -Nru a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
--- a/drivers/sbus/char/envctrl.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/sbus/char/envctrl.c	Sat Aug 10 18:42:21 2002
@@ -722,11 +722,11 @@
 }
 
 static struct file_operations envctrl_fops = {
-	owner:		THIS_MODULE,
-	read:		envctrl_read,
-	ioctl:		envctrl_ioctl,
-	open:		envctrl_open,
-	release:	envctrl_release,
+	.owner =	THIS_MODULE,
+	.read =		envctrl_read,
+	.ioctl =	envctrl_ioctl,
+	.open =		envctrl_open,
+	.release =	envctrl_release,
 };	
 
 static struct miscdevice envctrl_dev = {
diff -Nru a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c
--- a/drivers/sbus/char/flash.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/sbus/char/flash.c	Sat Aug 10 18:42:23 2002
@@ -148,12 +148,12 @@
 	/* no write to the Flash, use mmap
 	 * and play flash dependent tricks.
 	 */
-	owner:		THIS_MODULE,
-	llseek:		flash_llseek,
-	read:		flash_read,
-	mmap:		flash_mmap,
-	open:		flash_open,
-	release:	flash_release,
+	.owner =	THIS_MODULE,
+	.llseek =	flash_llseek,
+	.read =		flash_read,
+	.mmap =		flash_mmap,
+	.open =		flash_open,
+	.release =	flash_release,
 };
 
 static struct miscdevice flash_dev = { FLASH_MINOR, "flash", &flash_fops };
diff -Nru a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c
--- a/drivers/sbus/char/jsflash.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/sbus/char/jsflash.c	Sat Aug 10 18:42:22 2002
@@ -533,23 +533,23 @@
 }
 
 static struct file_operations jsf_fops = {
-	owner:		THIS_MODULE,
-	llseek:		jsf_lseek,
-	read:		jsf_read,
-	write:		jsf_write,
-	ioctl:		jsf_ioctl,
-	mmap:		jsf_mmap,
-	open:		jsf_open,
-	release:	jsf_release,
+	.owner =	THIS_MODULE,
+	.llseek =	jsf_lseek,
+	.read =		jsf_read,
+	.write =	jsf_write,
+	.ioctl =	jsf_ioctl,
+	.mmap =		jsf_mmap,
+	.open =		jsf_open,
+	.release =	jsf_release,
 };
 
 static struct miscdevice jsf_dev = { JSF_MINOR, "jsflash", &jsf_fops };
 
 static struct block_device_operations jsfd_fops = {
-	owner:		THIS_MODULE,
-	open:		jsfd_open,
-	release:	jsfd_release,
-	ioctl:		jsfd_ioctl,
+	.owner =	THIS_MODULE,
+	.open =		jsfd_open,
+	.release =	jsfd_release,
+	.ioctl =	jsfd_ioctl,
 };
 
 int jsflash_init(void)
diff -Nru a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
--- a/drivers/sbus/char/openprom.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/sbus/char/openprom.c	Sat Aug 10 18:42:23 2002
@@ -147,7 +147,6 @@
 	DATA *data = (DATA *) file->private_data;
 	char buffer[OPROMMAXPARAM+1], *buf;
 	struct openpromio *opp;
-	unsigned long flags;
 	int bufsize, len, error = 0;
 	extern char saved_command_line[];
 	static int cnt;
@@ -163,18 +162,14 @@
 	switch (cmd) {
 	case OPROMGETOPT:
 	case OPROMGETPROP:
-		save_and_cli(flags);
 		len = prom_getproplen(node, opp->oprom_array);
-		restore_flags(flags);
 
 		if (len <= 0 || len > bufsize) {
 			error = copyout((void *)arg, opp, sizeof(int));
 			break;
 		}
 
-		save_and_cli(flags);
 		len = prom_getproperty(node, opp->oprom_array, buffer, bufsize);
-		restore_flags(flags);
 
 		memcpy(opp->oprom_array, buffer, len);
 		opp->oprom_array[len] = '\0';
@@ -185,9 +180,7 @@
 
 	case OPROMNXTOPT:
 	case OPROMNXTPROP:
-		save_and_cli(flags);
 		buf = prom_nextprop(node, opp->oprom_array, buffer);
-		restore_flags(flags);
 
 		len = strlen(buf);
 		if (len == 0 || len + 1 > bufsize) {
@@ -207,10 +200,8 @@
 		buf = opp->oprom_array + strlen(opp->oprom_array) + 1;
 		len = opp->oprom_array + bufsize - buf;
 
-		save_and_cli(flags);
 		error = prom_setprop(options_node, opp->oprom_array,
 				     buf, len);
-		restore_flags(flags);
 
 		if (error < 0)
 			error = -EINVAL;
@@ -226,13 +217,11 @@
 
 		node = *((int *) opp->oprom_array);
 
-		save_and_cli(flags);
 		switch (cmd) {
 		case OPROMNEXT: node = __prom_getsibling(node); break;
 		case OPROMCHILD: node = __prom_getchild(node); break;
 		case OPROMSETCUR: break;
 		}
-		restore_flags(flags);
 
 		data->current_node = node;
 		*((int *)opp->oprom_array) = node;
@@ -264,9 +253,7 @@
 		break;
 
 	case OPROMPATH2NODE:
-		save_and_cli(flags);
 		node = prom_finddevice(opp->oprom_array);
-		restore_flags(flags);
 		data->current_node = node;
 		*((int *)opp->oprom_array) = node;
 		opp->oprom_size = sizeof(int);
@@ -334,6 +321,9 @@
 {
 	char *tmp;
 
+	if ((ssize_t)len < 0 || (ssize_t)(len + 1) < 0)
+		return -EINVAL;
+
 	tmp = kmalloc(len + 1, GFP_KERNEL);
 	if (!tmp)
 		return -ENOMEM;
@@ -358,7 +348,6 @@
 {
 	DATA *data = (DATA *) file->private_data;
 	struct opiocdesc op;
-	unsigned long flags;
 	int error, node, len;
 	char *str, *tmp;
 	char buffer[64];
@@ -376,9 +365,7 @@
 		if (error)
 			return error;
 
-		save_and_cli(flags);
 		len = prom_getproplen(op.op_nodeid,str);
-		restore_flags(flags);
 
 		if (len > op.op_buflen) {
 			kfree(str);
@@ -402,9 +389,7 @@
 			return -ENOMEM;
 		}
 
-		save_and_cli(flags);
 		prom_getproperty(op.op_nodeid, str, tmp, len);
-		restore_flags(flags);
 
 		tmp[len] = '\0';
 
@@ -428,9 +413,7 @@
 		if (error)
 			return error;
 
-		save_and_cli(flags);
 		tmp = prom_nextprop(op.op_nodeid,str,buffer);
-		restore_flags(flags);
 
 		if (tmp) {
 			len = strlen(tmp);
@@ -478,9 +461,7 @@
 			return error;
 		}
 
-		save_and_cli(flags);
 		len = prom_setprop(op.op_nodeid,str,tmp,op.op_buflen+1);
-		restore_flags(flags);
 
 		if (len != op.op_buflen)
 			return -EINVAL;
@@ -500,12 +481,10 @@
 		if (copy_from_user(&node, (void *)arg, sizeof(int)))
 			return -EFAULT;
 
-		save_and_cli(flags);
 		if (cmd == OPIOCGETNEXT)
 			node = __prom_getsibling(node);
 		else
 			node = __prom_getchild(node);
-		restore_flags(flags);
 
 		if (__copy_to_user((void *)arg, &node, sizeof(int)))
 			return -EFAULT;
@@ -608,11 +587,11 @@
 }
 
 static struct file_operations openprom_fops = {
-	owner:		THIS_MODULE,
-	llseek:		no_llseek,
-	ioctl:		openprom_ioctl,
-	open:		openprom_open,
-	release:	openprom_release,
+	.owner =	THIS_MODULE,
+	.llseek =	no_llseek,
+	.ioctl =	openprom_ioctl,
+	.open =		openprom_open,
+	.release =	openprom_release,
 };
 
 static struct miscdevice openprom_dev = {
@@ -621,7 +600,6 @@
 
 static int __init openprom_init(void)
 {
-	unsigned long flags;
 	int error;
 
 	error = misc_register(&openprom_dev);
@@ -630,10 +608,8 @@
 		return error;
 	}
 
-	save_and_cli(flags);
 	options_node = prom_getchild(prom_root_node);
 	options_node = prom_searchsiblings(options_node,"options");
-	restore_flags(flags);
 
 	if (options_node == 0 || options_node == -1) {
 		printk(KERN_ERR "openprom: unable to find options node\n");
diff -Nru a/drivers/sbus/char/pcikbd.c b/drivers/sbus/char/pcikbd.c
--- a/drivers/sbus/char/pcikbd.c	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1430 +0,0 @@
-/* $Id: pcikbd.c,v 1.61 2001/08/18 09:40:46 davem Exp $
- * pcikbd.c: Ultra/AX PC keyboard support.
- *
- * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
- * JavaStation support by Pete A. Zaitcev.
- *
- * This code is mainly put together from various places in
- * drivers/char, please refer to these sources for credits
- * to the original authors.
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/poll.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/random.h>
-#include <linux/miscdevice.h>
-#include <linux/kbd_ll.h>
-#include <linux/kbd_kern.h>
-#include <linux/vt_kern.h>
-#include <linux/delay.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-
-#include <asm/ebus.h>
-#if defined(CONFIG_USB) && defined(CONFIG_SPARC64)
-#include <asm/isa.h>
-#endif
-#include <asm/oplib.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-/*
- * Different platforms provide different permutations of names.
- * AXi - kb_ps2, kdmouse.
- * MrCoffee - keyboard, mouse.
- * Espresso - keyboard, kdmouse.
- */
-#define	PCI_KB_NAME1	"kb_ps2"
-#define PCI_KB_NAME2	"keyboard"
-#define PCI_MS_NAME1	"kdmouse"
-#define PCI_MS_NAME2	"mouse"
-
-#include "pcikbd.h"
-#include "sunserial.h"
-
-#ifndef __sparc_v9__
-static int pcikbd_mrcoffee = 0;
-#else
-#define pcikbd_mrcoffee 0
-extern void (*prom_keyboard)(void);
-#endif
-
-static unsigned long pcikbd_iobase = 0;
-static unsigned int pcikbd_irq = 0;
-
-/* used only by send_data - set by keyboard_interrupt */
-static volatile unsigned char reply_expected = 0;
-static volatile unsigned char acknowledge = 0;
-static volatile unsigned char resend = 0;
-
-static spinlock_t pcikbd_lock = SPIN_LOCK_UNLOCKED;
-
-static void pcikbd_write(int address, int data);
-static int pcikbd_wait_for_input(void);
-
-unsigned char pckbd_read_mask = KBD_STAT_OBF;
-
-extern int pcikbd_init(void);
-extern void pci_compute_shiftstate(void);
-extern int pci_setkeycode(unsigned int, unsigned int);
-extern int pci_getkeycode(unsigned int);
-extern void pci_setledstate(struct kbd_struct *, unsigned int);
-extern unsigned char pci_getledstate(void);
-
-#define pcikbd_inb(x)     inb(x)
-#define pcikbd_outb(v,x)  outb(v,x)
-
-/* Wait for keyboard controller input buffer to drain.
- * Must be invoked under the pcikbd_lock.
- */
-static void kb_wait(void)
-{
-	unsigned long timeout = 250;
-
-	do {
-		if(!(pcikbd_inb(pcikbd_iobase + KBD_STATUS_REG) & KBD_STAT_IBF))
-			return;
-		mdelay(1);
-	} while (--timeout);
-}
-
-/*
- * Translation of escaped scancodes to keycodes.
- * This is now user-settable.
- * The keycodes 1-88,96-111,119 are fairly standard, and
- * should probably not be changed - changing might confuse X.
- * X also interprets scancode 0x5d (KEY_Begin).
- *
- * For 1-88 keycode equals scancode.
- */
-
-#define E0_KPENTER 96
-#define E0_RCTRL   97
-#define E0_KPSLASH 98
-#define E0_PRSCR   99
-#define E0_RALT    100
-#define E0_BREAK   101  /* (control-pause) */
-#define E0_HOME    102
-#define E0_UP      103
-#define E0_PGUP    104
-#define E0_LEFT    105
-#define E0_RIGHT   106
-#define E0_END     107
-#define E0_DOWN    108
-#define E0_PGDN    109
-#define E0_INS     110
-#define E0_DEL     111
-
-#define E1_PAUSE   119
-
-/*
- * The keycodes below are randomly located in 89-95,112-118,120-127.
- * They could be thrown away (and all occurrences below replaced by 0),
- * but that would force many users to use the `setkeycodes' utility, where
- * they needed not before. It does not matter that there are duplicates, as
- * long as no duplication occurs for any single keyboard.
- */
-#define SC_LIM 89
-
-#define FOCUS_PF1 85           /* actual code! */
-#define FOCUS_PF2 89
-#define FOCUS_PF3 90
-#define FOCUS_PF4 91
-#define FOCUS_PF5 92
-#define FOCUS_PF6 93
-#define FOCUS_PF7 94
-#define FOCUS_PF8 95
-#define FOCUS_PF9 120
-#define FOCUS_PF10 121
-#define FOCUS_PF11 122
-#define FOCUS_PF12 123
-
-#define JAP_86     124
-/* tfj@olivia.ping.dk:
- * The four keys are located over the numeric keypad, and are
- * labelled A1-A4. It's an rc930 keyboard, from
- * Regnecentralen/RC International, Now ICL.
- * Scancodes: 59, 5a, 5b, 5c.
- */
-#define RGN1 124
-#define RGN2 125
-#define RGN3 126
-#define RGN4 127
-
-static unsigned char high_keys[128 - SC_LIM] = {
-  RGN1, RGN2, RGN3, RGN4, 0, 0, 0,                   /* 0x59-0x5f */
-  0, 0, 0, 0, 0, 0, 0, 0,                            /* 0x60-0x67 */
-  0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,          /* 0x68-0x6f */
-  0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,    /* 0x70-0x77 */
-  FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,        /* 0x78-0x7b */
-  FOCUS_PF8, JAP_86, FOCUS_PF10, 0                   /* 0x7c-0x7f */
-};
-
-/* BTC */
-#define E0_MACRO   112
-/* LK450 */
-#define E0_F13     113
-#define E0_F14     114
-#define E0_HELP    115
-#define E0_DO      116
-#define E0_F17     117
-#define E0_KPMINPLUS 118
-/*
- * My OmniKey generates e0 4c for  the "OMNI" key and the
- * right alt key does nada. [kkoller@nyx10.cs.du.edu]
- */
-#define E0_OK	124
-/*
- * New microsoft keyboard is rumoured to have
- * e0 5b (left window button), e0 5c (right window button),
- * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
- * [or: Windows_L, Windows_R, TaskMan]
- */
-#define E0_MSLW	125
-#define E0_MSRW	126
-#define E0_MSTM	127
-
-static unsigned char e0_keys[128] = {
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x00-0x07 */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x08-0x0f */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x10-0x17 */
-  0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,	      /* 0x18-0x1f */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x20-0x27 */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x28-0x2f */
-  0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,	      /* 0x30-0x37 */
-  E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,	      /* 0x38-0x3f */
-  E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,	      /* 0x40-0x47 */
-  E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
-  E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,	      /* 0x50-0x57 */
-  0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,	      /* 0x58-0x5f */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x60-0x67 */
-  0, 0, 0, 0, 0, 0, 0, E0_MACRO,		      /* 0x68-0x6f */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x70-0x77 */
-  0, 0, 0, 0, 0, 0, 0, 0			      /* 0x78-0x7f */
-};
-
-/* Simple translation table for the SysRq keys */
-
-#ifdef CONFIG_MAGIC_SYSRQ
-unsigned char pcikbd_sysrq_xlate[128] =
-	"\000\0331234567890-=\177\t"			/* 0x00 - 0x0f */
-	"qwertyuiop[]\r\000as"				/* 0x10 - 0x1f */
-	"dfghjkl;'`\000\\zxcv"				/* 0x20 - 0x2f */
-	"bnm,./\000*\000 \000\201\202\203\204\205"	/* 0x30 - 0x3f */
-	"\206\207\210\211\212\000\000789-456+1"		/* 0x40 - 0x4f */
-	"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
-	"\r\000/";					/* 0x60 - 0x6f */
-#endif
-
-#define DEFAULT_KEYB_REP_DELAY	250
-#define DEFAULT_KEYB_REP_RATE	30	/* cps */
-
-static struct kbd_repeat kbdrate = {
-	DEFAULT_KEYB_REP_DELAY,
-	DEFAULT_KEYB_REP_RATE
-};
-
-static unsigned char parse_kbd_rate(struct kbd_repeat *r);
-static int write_kbd_rate(unsigned char r);
-
-int pcikbd_setkeycode(unsigned int scancode, unsigned int keycode)
-{
-	if(scancode < SC_LIM || scancode > 255 || keycode > 127)
-		return -EINVAL;
-	if(scancode < 128)
-		high_keys[scancode - SC_LIM] = keycode;
-	else
-		e0_keys[scancode - 128] = keycode;
-	return 0;
-}
-
-int pcikbd_getkeycode(unsigned int scancode)
-{
-	return
-		(scancode < SC_LIM || scancode > 255) ? -EINVAL :
-		(scancode < 128) ? high_keys[scancode - SC_LIM] :
-		e0_keys[scancode - 128];
-}
-
-static int do_acknowledge(unsigned char scancode)
-{
-	if(reply_expected) {
-		if(scancode == KBD_REPLY_ACK) {
-			acknowledge = 1;
-			reply_expected = 0;
-			return 0;
-		} else if(scancode == KBD_REPLY_RESEND) {
-			resend = 1;
-			reply_expected = 0;
-			return 0;
-		}
-	}
-	return 1;
-}
-
-#ifdef __sparc_v9__
-static void pcikbd_enter_prom(void)
-{
-	pcikbd_write(KBD_DATA_REG, KBD_CMD_DISABLE);
-	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		printk("Prom Enter: Disable keyboard: no ACK\n");
-
-	/* Disable PC scancode translation */
-	pcikbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE);
-	pcikbd_write(KBD_DATA_REG, KBD_MODE_SYS);
-	pcikbd_write(KBD_DATA_REG, KBD_CMD_ENABLE);
-	if (pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		printk("Prom Enter: Enable Keyboard: no ACK\n");
-}
-#endif
-
-static void ctrl_break(void)
-{
-	extern int stop_a_enabled;
-	unsigned long timeout;
-	int status, data;
-	int mode;
-
-	if (!stop_a_enabled)
-		return;
-
-	pcikbd_write(KBD_DATA_REG, KBD_CMD_DISABLE);
-	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		printk("Prom Enter: Disable keyboard: no ACK\n");
-
-	/* Save current mode register settings */
-	pcikbd_write(KBD_CNTL_REG, KBD_CCMD_READ_MODE);
-	if ((mode = pcikbd_wait_for_input()) == -1)
-		printk("Prom Enter: Read Mode: no ACK\n");
-
-	/* Disable PC scancode translation */
-	pcikbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE);
-	pcikbd_write(KBD_DATA_REG, mode & ~(KBD_MODE_KCC));
-	pcikbd_write(KBD_DATA_REG, KBD_CMD_ENABLE);
-	if (pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		printk("Prom Enter: Enable Keyboard: no ACK\n");
-
-	/* Drop into OBP.
-	 * Note that we must flush the user windows
-	 * first before giving up control.
-	 */
-        flush_user_windows();
-	prom_cmdline();
-
-	/* Read prom's key up event (use short timeout) */
-	do {
-		timeout = 10;
-		do {
-			mdelay(1);
-			status = pcikbd_inb(pcikbd_iobase + KBD_STATUS_REG);
-			if (!(status & KBD_STAT_OBF))
-				continue;
-			data = pcikbd_inb(pcikbd_iobase + KBD_DATA_REG);
-			if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
-				continue;
-			break;
-		} while (--timeout > 0);
-	} while (timeout > 0);
-
-	/* Reenable PC scancode translation */
-	pcikbd_write(KBD_DATA_REG, KBD_CMD_DISABLE);
-	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		printk("Prom Leave: Disable keyboard: no ACK\n");
-
-	pcikbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE);
-	pcikbd_write(KBD_DATA_REG, mode);
-	pcikbd_write(KBD_DATA_REG, KBD_CMD_ENABLE);
-	if (pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		printk("Prom Leave: Enable Keyboard: no ACK\n");
-
-	/* Reset keyboard rate */
-	write_kbd_rate(parse_kbd_rate(&kbdrate));
-}
-
-int pcikbd_translate(unsigned char scancode, unsigned char *keycode,
-		     char raw_mode)
-{
-	static int prev_scancode = 0;
-	int down = scancode & 0x80 ? 0 : 1;
-
-	if (scancode == 0xe0 || scancode == 0xe1) {
-		prev_scancode = scancode;
-		return 0;
-	}
-	if (scancode == 0x00 || scancode == 0xff) {
-		prev_scancode = 0;
-		return 0;
-	}
-	scancode &= 0x7f;
-	if(prev_scancode) {
-		if(prev_scancode != 0xe0) {
-			if(prev_scancode == 0xe1 && scancode == 0x1d) {
-				prev_scancode = 0x100;
-				return 0;
-			} else if(prev_scancode == 0x100 && scancode == 0x45) {
-				*keycode = E1_PAUSE;
-				prev_scancode = 0;
-			} else {
-				prev_scancode = 0;
-				return 0;
-			}
-		} else {
-			prev_scancode = 0;
-			if(scancode == 0x2a || scancode == 0x36)
-				return 0;
-			if(e0_keys[scancode])
-				*keycode = e0_keys[scancode];
-			else
-				return 0;
-		}
-	} else if(scancode >= SC_LIM) {
-		*keycode = high_keys[scancode - SC_LIM];
-		if(!*keycode)
-			return 0;
-
-	} else
-		*keycode = scancode;
-
-	if (*keycode == E0_BREAK) {
-		if (down)
-			return 0;
-
-		/* Handle ctrl-break event */
-		ctrl_break();
-
-		/* Send ctrl up event to the keyboard driver */
-		*keycode = 0x1d;
-	}
-
-	return 1;
-}
-
-char pcikbd_unexpected_up(unsigned char keycode)
-{
-	if(keycode >= SC_LIM || keycode == 85)
-		return 0;
-	else
-		return 0200;
-}
-
-static void
-pcikbd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	unsigned long flags;
-	unsigned char status;
-
-	spin_lock_irqsave(&pcikbd_lock, flags);
-
-	kbd_pt_regs = regs;
-	status = pcikbd_inb(pcikbd_iobase + KBD_STATUS_REG);
-	do {
-		unsigned char scancode;
-
-		if(status & pckbd_read_mask & KBD_STAT_MOUSE_OBF)
-			break;
-		scancode = pcikbd_inb(pcikbd_iobase + KBD_DATA_REG);
-		if((status & KBD_STAT_OBF) && do_acknowledge(scancode))
-			handle_scancode(scancode, !(scancode & 0x80));
-		status = pcikbd_inb(pcikbd_iobase + KBD_STATUS_REG);
-	} while(status & KBD_STAT_OBF);
-	tasklet_schedule(&keyboard_tasklet);
-
-	spin_unlock_irqrestore(&pcikbd_lock, flags);
-}
-
-static int send_data(unsigned char data)
-{
-	int retries = 3;
-	unsigned long flags;
-
-	do {
-		unsigned long timeout = 1000;
-
-		spin_lock_irqsave(&pcikbd_lock, flags);
-
-		kb_wait();
-
-		acknowledge = 0;
-		resend = 0;
-		reply_expected = 1;
-
-		pcikbd_outb(data, pcikbd_iobase + KBD_DATA_REG);
-
-		spin_unlock_irqrestore(&pcikbd_lock, flags);
-
-		do {
-			if (acknowledge)
-				return 1;
-			if (resend)
-				break;
-			mdelay(1);
-		} while (--timeout);
-
-		if (timeout == 0)
-			break;
-
-	} while (retries-- > 0);
-
-	return 0;
-}
-
-void pcikbd_leds(unsigned char leds)
-{
-	if (!pcikbd_iobase)
-		return;
-	if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))
-		send_data(KBD_CMD_ENABLE);
-}
-
-static unsigned char parse_kbd_rate(struct kbd_repeat *r)
-{
-	static struct r2v {
-		int rate;
-		unsigned char val;
-	} kbd_rates[]={	{ 5,  0x14 },
-			{ 7,  0x10 },
-			{ 10, 0x0c },
-			{ 15, 0x08 },
-			{ 20, 0x04 },
-			{ 25, 0x02 },
-			{ 30, 0x00 } };
-	static struct d2v {
-		int delay;
-		unsigned char val;
-	} kbd_delays[]={ { 250,  0 },
-			 { 500,  1 },
-			 { 750,  2 },
-			 { 1000, 3 } };
-	int rate = 0, delay = 0;
-
-	if (r != NULL) {
-		int i, new_rate = 30, new_delay = 250;
-		if (r->rate <= 0)
-			r->rate = kbdrate.rate;
-		if (r->delay <= 0)
-			r->delay = kbdrate.delay;
-
-		for (i = 0; i < sizeof(kbd_rates) / sizeof(struct r2v); i++) {
-			if (kbd_rates[i].rate == r->rate) {
-				new_rate = kbd_rates[i].rate;
-				rate = kbd_rates[i].val;
-				break;
-			}
-		}
-		for (i=0; i < sizeof(kbd_delays) / sizeof(struct d2v); i++) {
-			if (kbd_delays[i].delay == r->delay) {
-				new_delay = kbd_delays[i].delay;
-				delay = kbd_delays[i].val;
-				break;
-			}
-		}
-		r->rate = new_rate;
-		r->delay = new_delay;
-	}
-	return (delay << 5) | rate;
-}
-
-static int write_kbd_rate(unsigned char r)
-{
-	if (!send_data(KBD_CMD_SET_RATE) || !send_data(r)) {
-		/* re-enable kbd if any errors */
-		send_data(KBD_CMD_ENABLE);
-		return 0;
-	}
-
-	return 1;
-}
-
-static int pcikbd_rate(struct kbd_repeat *rep)
-{
-	unsigned char r;
-	struct kbd_repeat old_rep;
-
-	if (rep == NULL)
-		return -EINVAL;
-
-	r = parse_kbd_rate(rep);
-	memcpy(&old_rep, &kbdrate, sizeof(struct kbd_repeat));
-	if (write_kbd_rate(r)) {
-		memcpy(&kbdrate,rep,sizeof(struct kbd_repeat));
-		memcpy(rep,&old_rep,sizeof(struct kbd_repeat));
-		return 0;
-	}
-
-	return -EIO;
-}
-
-static int pcikbd_wait_for_input(void)
-{
-	int status, data;
-	unsigned long timeout = 1000;
-
-	do {
-		mdelay(1);
-
-		status = pcikbd_inb(pcikbd_iobase + KBD_STATUS_REG);
-		if (!(status & KBD_STAT_OBF))
-			continue;
-
-		data = pcikbd_inb(pcikbd_iobase + KBD_DATA_REG);
-		if (status & (KBD_STAT_GTO | KBD_STAT_PERR))
-			continue;
-
-		return (data & 0xff);
-
-	} while (--timeout > 0);
-
-	return -1;
-}
-
-static void pcikbd_write(int address, int data)
-{
-	int status;
-
-	do {
-		status = pcikbd_inb(pcikbd_iobase + KBD_STATUS_REG);
-	} while (status & KBD_STAT_IBF);
-	pcikbd_outb(data, pcikbd_iobase + address);
-}
-
-#ifdef __sparc_v9__
-
-static unsigned long pcibeep_iobase = 0;
-
-/* Timer routine to turn off the beep after the interval expires. */
-static void pcikbd_kd_nosound(unsigned long __unused)
-{
-	if (pcibeep_iobase & 0x2UL)
-		outb(0, pcibeep_iobase);
-	else
-		outl(0, pcibeep_iobase);
-}
-
-/*
- * Initiate a keyboard beep. If the frequency is zero, then we stop
- * the beep. Any other frequency will start a monotone beep. The beep
- * will be stopped by a timer after "ticks" jiffies. If ticks is 0,
- * then we do not start a timer.
- */
-static void pcikbd_kd_mksound(unsigned int hz, unsigned int ticks)
-{
-	unsigned long flags;
-	static struct timer_list sound_timer = { function: pcikbd_kd_nosound };
-
-	save_flags(flags); cli();
-	del_timer(&sound_timer);
-	if (hz) {
-		if (pcibeep_iobase & 0x2UL)
-			outb(1, pcibeep_iobase);
-		else
-			outl(1, pcibeep_iobase);
-		if (ticks) {
-			sound_timer.expires = jiffies + ticks;
-			add_timer(&sound_timer);
-		}
-	} else {
-		if (pcibeep_iobase & 0x2UL)
-			outb(0, pcibeep_iobase);
-		else
-			outl(0, pcibeep_iobase);
-	}
-	restore_flags(flags);
-}
-
-#if defined(CONFIG_USB) && defined(CONFIG_SPARC64)
-static void isa_kd_nosound(unsigned long __unused)
-{
-	/* disable counter 2 */
-	outb(inb(pcibeep_iobase + 0x61)&0xFC, pcibeep_iobase + 0x61);
-	return;
-}
-
-static void isa_kd_mksound(unsigned int hz, unsigned int ticks)
-{
-	static struct timer_list sound_timer = { function: isa_kd_nosound };
-	unsigned int count = 0;
-	unsigned long flags;
-
-	if (hz > 20 && hz < 32767)
-		count = 1193180 / hz;
-	
-	save_flags(flags);
-	cli();
-	del_timer(&sound_timer);
-	if (count) {
-		/* enable counter 2 */
-		outb(inb(pcibeep_iobase + 0x61)|3, pcibeep_iobase + 0x61);
-		/* set command for counter 2, 2 byte write */
-		outb(0xB6, pcibeep_iobase + 0x43);
-		/* select desired HZ */
-		outb(count & 0xff, pcibeep_iobase + 0x42);
-		outb((count >> 8) & 0xff, pcibeep_iobase + 0x42);
-
-		if (ticks) {
-			sound_timer.expires = jiffies+ticks;
-			add_timer(&sound_timer);
-		}
-	} else
-		isa_kd_nosound(0);
-	restore_flags(flags);
-	return;
-}
-#endif
-
-#endif
-
-static void nop_kd_mksound(unsigned int hz, unsigned int ticks)
-{
-}
-
-extern void (*kd_mksound)(unsigned int hz, unsigned int ticks);
-
-static char * __init do_pcikbd_init_hw(void)
-{
-
-	while(pcikbd_wait_for_input() != -1)
-		;
-
-	pcikbd_write(KBD_CNTL_REG, KBD_CCMD_SELF_TEST);
-	if(pcikbd_wait_for_input() != 0x55)
-		return "Keyboard failed self test";
-
-	pcikbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_TEST);
-	if(pcikbd_wait_for_input() != 0x00)
-		return "Keyboard interface failed self test";
-
-	pcikbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_ENABLE);
-	pcikbd_write(KBD_DATA_REG, KBD_CMD_RESET);
-	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		return "Keyboard reset failed, no ACK";
-	if(pcikbd_wait_for_input() != KBD_REPLY_POR)
-		return "Keyboard reset failed, no ACK";
-
-	pcikbd_write(KBD_DATA_REG, KBD_CMD_DISABLE);
-	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		return "Disable keyboard: no ACK";
-
-	pcikbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE);
-	pcikbd_write(KBD_DATA_REG,
-		     (KBD_MODE_KBD_INT | KBD_MODE_SYS |
-		      KBD_MODE_DISABLE_MOUSE | KBD_MODE_KCC));
-	pcikbd_write(KBD_DATA_REG, KBD_CMD_ENABLE);
-	if(pcikbd_wait_for_input() != KBD_REPLY_ACK)
-		return "Enable keyboard: no ACK";
-
-	write_kbd_rate(parse_kbd_rate(&kbdrate));
-
-	return NULL; /* success */
-}
-
-void __init pcikbd_init_hw(void)
-{
-	struct linux_ebus *ebus;
-	struct linux_ebus_device *edev;
-	struct linux_ebus_child *child;
-	char *msg;
-
-	if (pcikbd_mrcoffee) {
-		if ((pcikbd_iobase = (unsigned long) ioremap(0x71300060, 8)) == 0) {
-			prom_printf("pcikbd_init_hw: cannot map\n");
-			return;
-		}
-		pcikbd_irq = 13 | 0x20;
-		if (request_irq(pcikbd_irq, &pcikbd_interrupt,
-				SA_SHIRQ, "keyboard", (void *)pcikbd_iobase)) {
-			printk("8042: cannot register IRQ %x\n", pcikbd_irq);
-			return;
-		}
-		printk("8042(kbd): iobase[%x] irq[%x]\n",
-		    (unsigned)pcikbd_iobase, pcikbd_irq);
-	} else {
-		for_each_ebus(ebus) {
-			for_each_ebusdev(edev, ebus) {
-				if(!strcmp(edev->prom_name, "8042")) {
-					for_each_edevchild(edev, child) {
-                                                if (strcmp(child->prom_name, PCI_KB_NAME1) == 0 ||
-						    strcmp(child->prom_name, PCI_KB_NAME2) == 0)
-							goto found;
-					}
-				}
-			}
-		}
-#ifdef CONFIG_USB
-		/* We are being called for the sake of USB keyboard
-		 * state initialization.  So we should check for beeper
-		 * device in this case.
-		 */
-		edev = 0;
-		for_each_ebus(ebus) {
-			for_each_ebusdev(edev, ebus) {
-				if (!strcmp(edev->prom_name, "beep")) {
-					pcibeep_iobase = edev->resource[0].start;
-					kd_mksound = pcikbd_kd_mksound;
-					printk("8042(speaker): iobase[%016lx]\n", pcibeep_iobase);
-					return;
-				}
-			}
-		}
-
-#ifdef CONFIG_SPARC64
-		/* Maybe we have one inside the ALI southbridge? */
-		{
-			struct isa_bridge *isa_br;
-			struct isa_device *isa_dev;
-			for_each_isa(isa_br) {
-				for_each_isadev(isa_dev, isa_br) {
-					/* This is a hack, the 'dma' device node has
-					 * the base of the I/O port space for that PBM
-					 * as it's resource, so we use that. -DaveM
-					 */
-					if (!strcmp(isa_dev->prom_name, "dma")) {
-						pcibeep_iobase = isa_dev->resource.start;
-						kd_mksound = isa_kd_mksound;
-						printk("isa(speaker): iobase[%016lx:%016lx]\n",
-						       pcibeep_iobase + 0x42,
-						       pcibeep_iobase + 0x61);
-						return;
-					}
-				}
-			}
-		}
-#endif
-
-		/* No beeper found, ok complain. */
-#endif
-		printk("pcikbd_init_hw: no 8042 found\n");
-		return;
-
-found:
-		pcikbd_iobase = child->resource[0].start;
-		pcikbd_irq = child->irqs[0];
-		if (request_irq(pcikbd_irq, &pcikbd_interrupt,
-				SA_SHIRQ, "keyboard", (void *)pcikbd_iobase)) {
-			printk("8042: cannot register IRQ %s\n",
-			       __irq_itoa(pcikbd_irq));
-			return;
-		}
-
-		printk("8042(kbd) at 0x%lx (irq %s)\n", pcikbd_iobase,
-		       __irq_itoa(pcikbd_irq));
-	}
-
-	kd_mksound = nop_kd_mksound;
-	kbd_rate = pcikbd_rate;
-
-#ifdef __sparc_v9__
-	edev = 0;
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			if(!strcmp(edev->prom_name, "beeper"))
-				goto ebus_done;
-		}
-	}
-ebus_done:
-
-	/*
-	 * XXX: my 3.1.3 PROM does not give me the beeper node for the audio
-	 *      auxio register, though I know it is there... (ecd)
-	 *
-	 * JavaStations appear not to have beeper. --zaitcev
-	 */
-	if (!edev)
-		pcibeep_iobase = (pcikbd_iobase & ~(0xffffff)) | 0x722000;
-	else
-		pcibeep_iobase = edev->resource[0].start;
-
-	kd_mksound = pcikbd_kd_mksound;
-	printk("8042(speaker): iobase[%016lx]%s\n", pcibeep_iobase,
-	       edev ? "" : " (forced)");
-
-	prom_keyboard = pcikbd_enter_prom;
-#endif
-
-	disable_irq(pcikbd_irq);
-	msg = do_pcikbd_init_hw();
-	enable_irq(pcikbd_irq);
-
-	if(msg)
-		printk("8042: keyboard init failure [%s]\n", msg);
-}
-
-
-/*
- * Here begins the Mouse Driver.
- */
-
-static unsigned long pcimouse_iobase = 0;
-static unsigned int pcimouse_irq;
-
-#define AUX_BUF_SIZE	2048
-
-struct aux_queue {
-	unsigned long head;
-	unsigned long tail;
-	wait_queue_head_t proc_list;
-	struct fasync_struct *fasync;
-	unsigned char buf[AUX_BUF_SIZE];
-};
-
-static struct aux_queue *queue;
-static int aux_count = 0;
-static int aux_present = 0;
-
-#define pcimouse_inb(x)     inb(x)
-#define pcimouse_outb(v,x)  outb(v,x)
-
-/*
- *	Shared subroutines
- */
-
-static unsigned int get_from_queue(void)
-{
-	unsigned int result;
-	unsigned long flags;
-
-	spin_lock_irqsave(&pcikbd_lock, flags);
-	result = queue->buf[queue->tail];
-	queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE-1);
-	spin_unlock_irqrestore(&pcikbd_lock, flags);
-
-	return result;
-}
-
-
-static inline int queue_empty(void)
-{
-	return queue->head == queue->tail;
-}
-
-static int aux_fasync(int fd, struct file *filp, int on)
-{
-	int retval;
-
-	retval = fasync_helper(fd, filp, on, &queue->fasync);
-	if (retval < 0)
-		return retval;
-	return 0;
-}
-
-/*
- *	PS/2 Aux Device
- */
-
-#define AUX_INTS_OFF	(KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | \
-			 KBD_MODE_SYS | KBD_MODE_KBD_INT)
-
-#define AUX_INTS_ON	(KBD_MODE_KCC | KBD_MODE_SYS | \
-			 KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
-
-#define MAX_RETRIES	60		/* some aux operations take long time*/
-
-/*
- *	Status polling
- */
-
-static int poll_aux_status(void)
-{
-	int retries = 0;
-
-	while ((pcimouse_inb(pcimouse_iobase + KBD_STATUS_REG) &
-		(KBD_STAT_IBF | KBD_STAT_OBF)) && retries < MAX_RETRIES) {
- 		if ((pcimouse_inb(pcimouse_iobase + KBD_STATUS_REG) & AUX_STAT_OBF)
-		    == AUX_STAT_OBF)
-			pcimouse_inb(pcimouse_iobase + KBD_DATA_REG);
-		mdelay(5);
-		retries++;
-	}
-
-	return (retries < MAX_RETRIES);
-}
-
-/*
- * Write to aux device
- */
-
-static void aux_write_dev(int val)
-{
-	poll_aux_status();
-	pcimouse_outb(KBD_CCMD_WRITE_MOUSE, pcimouse_iobase + KBD_CNTL_REG);/* Write magic cookie */
-	poll_aux_status();
-	pcimouse_outb(val, pcimouse_iobase + KBD_DATA_REG);		 /* Write data */
-	udelay(1);
-}
-
-/*
- * Write to device & handle returned ack
- */
-
-static int __init aux_write_ack(int val)
-{
-	aux_write_dev(val);
-	poll_aux_status();
-
-	if ((pcimouse_inb(pcimouse_iobase + KBD_STATUS_REG) & AUX_STAT_OBF) == AUX_STAT_OBF)
-		return (pcimouse_inb(pcimouse_iobase + KBD_DATA_REG));
-	return 0;
-}
-
-/*
- * Write aux device command
- */
-
-static void aux_write_cmd(int val)
-{
-	poll_aux_status();
-	pcimouse_outb(KBD_CCMD_WRITE_MODE, pcimouse_iobase + KBD_CNTL_REG);
-	poll_aux_status();
-	pcimouse_outb(val, pcimouse_iobase + KBD_DATA_REG);
-}
-
-/*
- * Interrupt from the auxiliary device: a character
- * is waiting in the keyboard/aux controller.
- */
-
-void pcimouse_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	unsigned long flags;
-	int head, maxhead;
-	unsigned char val;
-
-	spin_lock_irqsave(&pcikbd_lock, flags);
-
-	head = queue->head;
-	maxhead = (queue->tail - 1) & (AUX_BUF_SIZE - 1);
-
-	if ((pcimouse_inb(pcimouse_iobase + KBD_STATUS_REG) & AUX_STAT_OBF) !=
-	    AUX_STAT_OBF) {
-		spin_unlock_irqrestore(&pcikbd_lock, flags);
-		return;
-	}
-
-	val = pcimouse_inb(pcimouse_iobase + KBD_DATA_REG);
-	queue->buf[head] = val;
-	add_mouse_randomness(val);
-	if (head != maxhead) {
-		head++;
-		head &= AUX_BUF_SIZE - 1;
-	}
-	queue->head = head;
-
-	spin_unlock_irqrestore(&pcikbd_lock, flags);
-
-	kill_fasync(&queue->fasync, SIGIO, POLL_IN);
-	wake_up_interruptible(&queue->proc_list);
-}
-
-static int aux_release(struct inode * inode, struct file * file)
-{
-	unsigned long flags;
-
-	aux_fasync(-1, file, 0);
-
-	spin_lock_irqsave(&pcikbd_lock, flags);
-
-	if (--aux_count)
-		goto out;
-
-	/* Disable controller ints */
-	aux_write_cmd(AUX_INTS_OFF);
-	poll_aux_status();
-
-	/* Disable Aux device */
-	pcimouse_outb(KBD_CCMD_MOUSE_DISABLE, pcimouse_iobase + KBD_CNTL_REG);
-	poll_aux_status();
-
-out:
-	spin_unlock_irqrestore(&pcikbd_lock, flags);
-
-	return 0;
-}
-
-/*
- * Install interrupt handler.
- * Enable auxiliary device.
- */
-
-static int aux_open(struct inode * inode, struct file * file)
-{
-	unsigned long flags;
-
-	if (!aux_present)
-		return -ENODEV;
-
-	spin_lock_irqsave(&pcikbd_lock, flags);
-
-	if (aux_count++) {
-		spin_unlock_irqrestore(&pcikbd_lock, flags);
-		return 0;
-	}
-
-	if (!poll_aux_status()) {
-		aux_count--;
-		spin_unlock_irqrestore(&pcikbd_lock, flags);
-		return -EBUSY;
-	}
-	queue->head = queue->tail = 0;		/* Flush input queue */
-
-	poll_aux_status();
-	pcimouse_outb(KBD_CCMD_MOUSE_ENABLE, pcimouse_iobase+KBD_CNTL_REG);    /* Enable Aux */
-	aux_write_dev(AUX_ENABLE_DEV);			    /* Enable aux device */
-	aux_write_cmd(AUX_INTS_ON);			    /* Enable controller ints */
-	poll_aux_status();
-
-	spin_unlock_irqrestore(&pcikbd_lock, flags);
-
-
-	return 0;
-}
-
-/*
- * Write to the aux device.
- */
-
-static ssize_t aux_write(struct file * file, const char * buffer,
-			 size_t count, loff_t *ppos)
-{
-	ssize_t retval = 0;
-	unsigned long flags;
-
-	if (count) {
-		ssize_t written = 0;
-
-		spin_lock_irqsave(&pcikbd_lock, flags);
-
-		do {
-			char c;
-
-			spin_unlock_irqrestore(&pcikbd_lock, flags);
-
-			get_user(c, buffer++);
-
-			spin_lock_irqsave(&pcikbd_lock, flags);
-
-			if (!poll_aux_status())
-				break;
-			pcimouse_outb(KBD_CCMD_WRITE_MOUSE,
-				      pcimouse_iobase + KBD_CNTL_REG);
-			if (!poll_aux_status())
-				break;
-
-			pcimouse_outb(c, pcimouse_iobase + KBD_DATA_REG);
-			written++;
-		} while (--count);
-
-		spin_unlock_irqrestore(&pcikbd_lock, flags);
-
-		retval = -EIO;
-		if (written) {
-			retval = written;
-			file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
-		}
-	}
-
-	return retval;
-}
-
-/*
- *	Generic part continues...
- */
-
-/*
- * Put bytes from input queue to buffer.
- */
-
-static ssize_t aux_read(struct file * file, char * buffer,
-		        size_t count, loff_t *ppos)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	ssize_t i = count;
-	unsigned char c;
-
-	if (queue_empty()) {
-		if (file->f_flags & O_NONBLOCK)
-			return -EAGAIN;
-		add_wait_queue(&queue->proc_list, &wait);
-repeat:
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (queue_empty() && !signal_pending(current)) {
-			schedule();
-			goto repeat;
-		}
-		current->state = TASK_RUNNING;
-		remove_wait_queue(&queue->proc_list, &wait);
-	}
-	while (i > 0 && !queue_empty()) {
-		c = get_from_queue();
-		put_user(c, buffer++);
-		i--;
-	}
-	if (count-i) {
-		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
-		return count-i;
-	}
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-	return 0;
-}
-
-static unsigned int aux_poll(struct file *file, poll_table * wait)
-{
-	poll_wait(file, &queue->proc_list, wait);
-	if (!queue_empty())
-		return POLLIN | POLLRDNORM;
-	return 0;
-}
-
-struct file_operations psaux_fops = {
-	owner:		THIS_MODULE,
-	read:		aux_read,
-	write:		aux_write,
-	poll:		aux_poll,
-	open:		aux_open,
-	release:	aux_release,
-	fasync:		aux_fasync,
-};
-
-static int aux_no_open(struct inode *inode, struct file *file)
-{
-	return -ENODEV;
-}
-
-struct file_operations psaux_no_fops = {
-	owner:		THIS_MODULE,
-	open:		aux_no_open,
-};
-
-static struct miscdevice psaux_mouse = {
-	PSMOUSE_MINOR, "ps2aux", &psaux_fops
-};
-
-static struct miscdevice psaux_no_mouse = {
-	PSMOUSE_MINOR, "ps2aux", &psaux_no_fops
-};
-
-int __init pcimouse_init(void)
-{
-	struct linux_ebus *ebus;
-	struct linux_ebus_device *edev;
-	struct linux_ebus_child *child;
-
-	if (pcikbd_mrcoffee) {
-		if ((pcimouse_iobase = pcikbd_iobase) == 0) {
-			printk("pcimouse_init: no 8042 given\n");
-			goto do_enodev;
-		}
-		pcimouse_irq = pcikbd_irq;
-	} else {
-		for_each_ebus(ebus) {
-			for_each_ebusdev(edev, ebus) {
-				if(!strcmp(edev->prom_name, "8042")) {
-					for_each_edevchild(edev, child) {
-							if (strcmp(child->prom_name, PCI_MS_NAME1) == 0 ||
-							    strcmp(child->prom_name, PCI_MS_NAME2) == 0)
-							goto found;
-					}
-				}
-			}
-		}
-		printk("pcimouse_init: no 8042 found\n");
-		goto do_enodev;
-
-found:
-		pcimouse_iobase = child->resource[0].start;
-		pcimouse_irq = child->irqs[0];
-	}
-
-	queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
-	if (!queue) {
-		printk("pcimouse_init: kmalloc(aux_queue) failed.\n");
-		return -ENOMEM;
-	}
-	memset(queue, 0, sizeof(*queue));
-
-	init_waitqueue_head(&queue->proc_list);
-
-	if (request_irq(pcimouse_irq, &pcimouse_interrupt,
-		        SA_SHIRQ, "mouse", (void *)pcimouse_iobase)) {
-		printk("8042: Cannot register IRQ %s\n",
-		       __irq_itoa(pcimouse_irq));
-		goto do_enodev;
-	}
-
-	printk("8042(mouse) at %lx (irq %s)\n", pcimouse_iobase,
-	       __irq_itoa(pcimouse_irq));
-
-	printk("8042: PS/2 auxiliary pointing device detected.\n");
-	aux_present = 1;
-	pckbd_read_mask = AUX_STAT_OBF;
-
-	misc_register(&psaux_mouse);
-
-	spin_lock_irq(&pcikbd_lock);
-
-	pcimouse_outb(KBD_CCMD_MOUSE_ENABLE, pcimouse_iobase + KBD_CNTL_REG);
-	aux_write_ack(AUX_RESET);
-	aux_write_ack(AUX_SET_SAMPLE);
-	aux_write_ack(100);
-	aux_write_ack(AUX_SET_RES);
-	aux_write_ack(3);
-	aux_write_ack(AUX_SET_SCALE21);
-	poll_aux_status();
-	pcimouse_outb(KBD_CCMD_MOUSE_DISABLE, pcimouse_iobase + KBD_CNTL_REG);
-	poll_aux_status();
-	pcimouse_outb(KBD_CCMD_WRITE_MODE, pcimouse_iobase + KBD_CNTL_REG);
-	poll_aux_status();
-	pcimouse_outb(AUX_INTS_OFF, pcimouse_iobase + KBD_DATA_REG);
-	poll_aux_status();
-
-	spin_unlock_irq(&pcikbd_lock);
-
-	return 0;
-
-do_enodev:
-	misc_register(&psaux_no_mouse);
-	return -ENODEV;
-}
-
-int __init pcimouse_no_init(void)
-{
-	misc_register(&psaux_no_mouse);
-	return -ENODEV;
-}
-
-int __init ps2kbd_probe(void)
-{
-	int pnode, enode, node, dnode, xnode;
-	int kbnode = 0, msnode = 0, bnode = 0;
-	int devices = 0;
-	char prop[128];
-	int len;
-
-#ifndef __sparc_v9__
-	/*
-	 * MrCoffee has hardware but has no PROM nodes whatsoever.
-	 */
-	len = prom_getproperty(prom_root_node, "name", prop, sizeof(prop));
-	if (len < 0) {
-		printk("ps2kbd_probe: no name of root node\n");
-		goto do_enodev;
-	}
-	if (strncmp(prop, "SUNW,JavaStation-1", len) == 0) {
-		pcikbd_mrcoffee = 1;	/* Brain damage detected */
-		goto found;
-	}
-#endif
-	/*
-	 * Get the nodes for keyboard and mouse from aliases on normal systems.
-	 */
-        node = prom_getchild(prom_root_node);
-	node = prom_searchsiblings(node, "aliases");
-	if (!node)
-		goto do_enodev;
-
-	len = prom_getproperty(node, "keyboard", prop, sizeof(prop));
-	if (len > 0) {
-		prop[len] = 0;
-		kbnode = prom_finddevice(prop);
-	}
-	if (!kbnode)
-		goto do_enodev;
-
-	len = prom_getproperty(node, "mouse", prop, sizeof(prop));
-	if (len > 0) {
-		prop[len] = 0;
-		msnode = prom_finddevice(prop);
-	}
-	if (!msnode)
-		goto do_enodev;
-
-	/*
-	 * Find matching EBus nodes...
-	 */
-        node = prom_getchild(prom_root_node);
-	pnode = prom_searchsiblings(node, "pci");
-
-	/*
-	 * Check for SUNW,sabre on Ultra5/10/AXi.
-	 */
-	len = prom_getproperty(pnode, "model", prop, sizeof(prop));
-	if ((len > 0) && !strncmp(prop, "SUNW,sabre", len)) {
-		pnode = prom_getchild(pnode);
-		pnode = prom_searchsiblings(pnode, "pci");
-	}
-
-	/*
-	 * For each PCI bus...
-	 */
-	while (pnode) {
-		enode = prom_getchild(pnode);
-		enode = prom_searchsiblings(enode, "ebus");
-
-		/*
-		 * For each EBus on this PCI...
-		 */
-		while (enode) {
-			node = prom_getchild(enode);
-			bnode = prom_searchsiblings(node, "beeper");
-
-			node = prom_getchild(enode);
-			node = prom_searchsiblings(node, "8042");
-
-			/*
-			 * For each '8042' on this EBus...
-			 */
-			while (node) {
-				dnode = prom_getchild(node);
-
-				/*
-				 * Does it match?
-				 */
-				if ((xnode = prom_searchsiblings(dnode, PCI_KB_NAME1)) == kbnode) {
-					++devices;
-				} else if ((xnode = prom_searchsiblings(dnode, PCI_KB_NAME2)) == kbnode) {
-					++devices;
-				}
-
-				if ((xnode = prom_searchsiblings(dnode, PCI_MS_NAME1)) == msnode) {
-					++devices;
-				} else if ((xnode = prom_searchsiblings(dnode, PCI_MS_NAME2)) == msnode) {
-					++devices;
-				}
-
-				/*
-				 * Found everything we need?
-				 */
-				if (devices == 2)
-					goto found;
-
-				node = prom_getsibling(node);
-				node = prom_searchsiblings(node, "8042");
-			}
-			enode = prom_getsibling(enode);
-			enode = prom_searchsiblings(enode, "ebus");
-		}
-		pnode = prom_getsibling(pnode);
-		pnode = prom_searchsiblings(pnode, "pci");
-	}
-do_enodev:
-	sunkbd_setinitfunc(pcimouse_no_init);
-	return -ENODEV;
-
-found:
-        sunkbd_setinitfunc(pcimouse_init);
-        sunkbd_setinitfunc(pcikbd_init);
-	kbd_ops.compute_shiftstate = pci_compute_shiftstate;
-	kbd_ops.setledstate = pci_setledstate;
-	kbd_ops.getledstate = pci_getledstate;
-	kbd_ops.setkeycode = pci_setkeycode;
-	kbd_ops.getkeycode = pci_getkeycode;
-	return 0;
-}
diff -Nru a/drivers/sbus/char/pcikbd.h b/drivers/sbus/char/pcikbd.h
--- a/drivers/sbus/char/pcikbd.h	Sat Aug 10 18:42:20 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,123 +0,0 @@
-/* $Id: pcikbd.h,v 1.2 1997/12/25 21:13:14 geert Exp $
- * pcikbd.h: PCI/PC 8042 keyboard/mouse driver stuff.  Mostly snarfed
- *           from the existing driver by Martin Mares.
- *
- * Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
- *
- * Ultra/AX specific hacks are:
- *
- * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#ifndef __PCIKBD_H
-#define __PCIKBD_H
-
-/*
- *	Configuration Switches
- */
-
-#define KBD_REPORT_ERR			/* Report keyboard errors */
-#define KBD_REPORT_UNKN			/* Report unknown scan codes */
-#define KBD_REPORT_TIMEOUTS		/* Report keyboard timeouts */
-
-#define KBD_INIT_TIMEOUT HZ		/* Timeout for initializing the keyboard */
-#define KBC_TIMEOUT (HZ/4)		/* Timeout for sending to keyboard controller */
-#define KBD_TIMEOUT (HZ/4)		/* Timeout for keyboard command acknowledge */
-
-/*
- *	Internal variables of the driver
- */
-
-extern unsigned char pckbd_read_mask;
-extern unsigned char aux_device_present;
-
-extern unsigned long pcikbd_iobase;
-extern unsigned int pcikbd_irq;
-
-/*
- *	Keyboard Controller Registers
- *
- * NOTE: These are offsets from pcikbd_iobase, not absolute.
- */
-
-#define KBD_STATUS_REG		0x04
-#define KBD_CNTL_REG		KBD_STATUS_REG
-#define KBD_DATA_REG		0x00
-
-/*
- *	Keyboard Controller Commands
- */
-
-#define KBD_CCMD_READ_MODE	0x20	/* Read mode bits */
-#define KBD_CCMD_WRITE_MODE	0x60	/* Write mode bits */
-#define KBD_CCMD_GET_VERSION	0xA1	/* Get controller version */
-#define KBD_CCMD_MOUSE_DISABLE	0xA7	/* Disable mouse interface */
-#define KBD_CCMD_MOUSE_ENABLE	0xA8	/* Enable mouse interface */
-#define KBD_CCMD_TEST_MOUSE	0xA9	/* Mouse interface test */
-#define KBD_CCMD_SELF_TEST	0xAA	/* Controller self test */
-#define KBD_CCMD_KBD_TEST	0xAB	/* Keyboard interface test */
-#define KBD_CCMD_KBD_DISABLE	0xAD	/* Keyboard interface disable */
-#define KBD_CCMD_KBD_ENABLE	0xAE	/* Keyboard interface enable */
-#define KBD_CCMD_WRITE_MOUSE	0xD4	/* Write the following byte to the mouse */
-
-/*
- *	Keyboard Commands
- */
-
-#define KBD_CMD_SET_LEDS	0xED	/* Set keyboard leds */
-#define KBD_CMD_SET_RATE	0xF3	/* Set typematic rate */
-#define KBD_CMD_ENABLE		0xF4	/* Enable scanning */
-#define KBD_CMD_DISABLE		0xF5	/* Disable scanning */
-#define KBD_CMD_RESET		0xFF	/* Reset */
-
-/*
- *	Keyboard Replies
- */
-
-#define KBD_REPLY_POR		0xAA	/* Power on reset */
-#define KBD_REPLY_ACK		0xFA	/* Command ACK */
-#define KBD_REPLY_RESEND	0xFE	/* Command NACK, send the cmd again */
-
-/*
- *	Status Register Bits
- */
-
-#define KBD_STAT_OBF 		0x01	/* Keyboard output buffer full */
-#define KBD_STAT_IBF 		0x02	/* Keyboard input buffer full */
-#define KBD_STAT_SELFTEST	0x04	/* Self test successful */
-#define KBD_STAT_CMD		0x08	/* Last write was a command write (0=data) */
-#define KBD_STAT_UNLOCKED	0x10	/* Zero if keyboard locked */
-#define KBD_STAT_MOUSE_OBF	0x20	/* Mouse output buffer full */
-#define KBD_STAT_GTO 		0x40	/* General receive/xmit timeout */
-#define KBD_STAT_PERR 		0x80	/* Parity error */
-
-#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
-
-/*
- *	Controller Mode Register Bits
- */
-
-#define KBD_MODE_KBD_INT	0x01	/* Keyboard data generage IRQ1 */
-#define KBD_MODE_MOUSE_INT	0x02	/* Mouse data generate IRQ12 */
-#define KBD_MODE_SYS 		0x04	/* The system flag (?) */
-#define KBD_MODE_NO_KEYLOCK	0x08	/* The keylock doesn't affect the keyboard if set */
-#define KBD_MODE_DISABLE_KBD	0x10	/* Disable keyboard interface */
-#define KBD_MODE_DISABLE_MOUSE	0x20	/* Disable mouse interface */
-#define KBD_MODE_KCC 		0x40	/* Scan code conversion to PC format */
-#define KBD_MODE_RFU		0x80
-
-/*
- *	Mouse Commands
- */
-
-#define AUX_SET_RES		0xE8	/* Set resolution */
-#define AUX_SET_SCALE11		0xE6	/* Set 1:1 scaling */
-#define AUX_SET_SCALE21		0xE7	/* Set 2:1 scaling */
-#define AUX_GET_SCALE		0xE9	/* Get scaling factor */
-#define AUX_SET_STREAM		0xEA	/* Set stream mode */
-#define AUX_SET_SAMPLE		0xF3	/* Set sample rate */
-#define AUX_ENABLE_DEV		0xF4	/* Enable aux device */
-#define AUX_DISABLE_DEV		0xF5	/* Disable aux device */
-#define AUX_RESET		0xFF	/* Reset aux device */
-
-#endif /* __PCIKBD_H */
diff -Nru a/drivers/sbus/char/riowatchdog.c b/drivers/sbus/char/riowatchdog.c
--- a/drivers/sbus/char/riowatchdog.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/sbus/char/riowatchdog.c	Sat Aug 10 18:42:23 2002
@@ -185,12 +185,12 @@
 }
 
 static struct file_operations riowd_fops = {
-	owner:		THIS_MODULE,
-	ioctl:		riowd_ioctl,
-	open:		riowd_open,
-	write:		riowd_write,
-	read:		riowd_read,
-	release:	riowd_release,
+	.owner =	THIS_MODULE,
+	.ioctl =	riowd_ioctl,
+	.open =		riowd_open,
+	.write =	riowd_write,
+	.read =		riowd_read,
+	.release =	riowd_release,
 };
 
 static struct miscdevice riowd_miscdev = { RIOWD_MINOR, RIOWD_NAME, &riowd_fops };
diff -Nru a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c
--- a/drivers/sbus/char/rtc.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/sbus/char/rtc.c	Sat Aug 10 18:42:22 2002
@@ -137,11 +137,11 @@
 }
 
 static struct file_operations rtc_fops = {
-	owner:		THIS_MODULE,
-	llseek:		no_llseek,
-	ioctl:		rtc_ioctl,
-	open:		rtc_open,
-	release:	rtc_release,
+	.owner =	THIS_MODULE,
+	.llseek =	no_llseek,
+	.ioctl =	rtc_ioctl,
+	.open =		rtc_open,
+	.release =	rtc_release,
 };
 
 static struct miscdevice rtc_dev = { RTC_MINOR, "rtc", &rtc_fops };
diff -Nru a/drivers/sbus/char/sab82532.c b/drivers/sbus/char/sab82532.c
--- a/drivers/sbus/char/sab82532.c	Sat Aug 10 18:42:22 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,2668 +0,0 @@
-/* $Id: sab82532.c,v 1.66 2002/01/08 16:00:16 davem Exp $
- * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
- *
- * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
- *
- * Rewrote buffer handling to use CIRC(Circular Buffer) macros.
- *   Maxim Krasnyanskiy <maxk@qualcomm.com>
- *
- * Fixed to use tty_get_baud_rate, and to allow for arbitrary baud
- * rates to be programmed into the UART.  Also eliminated a lot of
- * duplicated code in the console setup.
- *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <linux/console.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include <asm/sab82532.h>
-#include <asm/uaccess.h>
-#include <asm/ebus.h>
-#include <asm/irq.h>
-
-#include "sunserial.h"
-
-static DECLARE_TASK_QUEUE(tq_serial);
-
-/* This is (one of many) a special gross hack to allow SU and
- * SAB serials to co-exist on the same machine. -DaveM
- */
-#undef SERIAL_BH
-#define SERIAL_BH	AURORA_BH
-
-static struct tty_driver serial_driver, callout_driver;
-static int sab82532_refcount;
-
-/* number of characters left in xmit buffer before we ask for more */
-#define WAKEUP_CHARS 256
-
-#undef SERIAL_PARANOIA_CHECK
-#define SERIAL_DO_RESTART
-
-/* Set of debugging defines */
-#undef SERIAL_DEBUG_OPEN
-#undef SERIAL_DEBUG_FLOW
-#undef SERIAL_DEBUG_MODEM
-#undef SERIAL_DEBUG_WAIT_UNTIL_SENT
-#undef SERIAL_DEBUG_SEND_BREAK
-#undef SERIAL_DEBUG_INTR
-#undef SERIAL_DEBUG_FIFO
-#define SERIAL_DEBUG_OVERFLOW 1
-
-/* Trace things on serial device, useful for console debugging: */
-#undef SERIAL_LOG_DEVICE
-
-#ifdef SERIAL_LOG_DEVICE
-static void dprint_init(int tty);
-#endif
-
-static void change_speed(struct sab82532 *info);
-static void sab82532_wait_until_sent(struct tty_struct *tty, int timeout);
-
-/*
- * This assumes you have a 29.4912 MHz clock for your UART.
- */
-#define BASE_BAUD ( 29491200 / 16 )
-
-static struct sab82532 *sab82532_chain = 0;
-static struct tty_struct *sab82532_table[NR_PORTS];
-static struct termios *sab82532_termios[NR_PORTS];
-static struct termios *sab82532_termios_locked[NR_PORTS];
-
-#ifdef MODULE
-#undef CONFIG_SERIAL_CONSOLE
-#endif
-
-#ifdef CONFIG_SERIAL_CONSOLE
-extern int serial_console;
-static struct console sab82532_console;
-static int sab82532_console_init(void);
-static void batten_down_hatches(struct sab82532 *info);
-#endif
-
-#ifndef MIN
-#define MIN(a,b)	((a) < (b) ? (a) : (b))
-#endif
-
-static char *sab82532_version[16] = {
-	"V1.0", "V2.0", "V3.2", "V(0x03)",
-	"V(0x04)", "V(0x05)", "V(0x06)", "V(0x07)",
-	"V(0x08)", "V(0x09)", "V(0x0a)", "V(0x0b)",
-	"V(0x0c)", "V(0x0d)", "V(0x0e)", "V(0x0f)"
-};
-static char serial_version[16];
-
-/*
- * tmp_buf is used as a temporary buffer by sab82532_write.  We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char *tmp_buf = 0;
-static DECLARE_MUTEX(tmp_buf_sem);
-
-static inline int serial_paranoia_check(struct sab82532 *info,
-					kdev_t device, const char *routine)
-{
-#ifdef SERIAL_PARANOIA_CHECK
-	static const char *badmagic =
-		"Warning: bad magic number for serial struct (%s) in %s\n";
-	static const char *badinfo =
-		"Warning: null sab82532 for (%s) in %s\n";
-
-	if (!info) {
-		printk(badinfo, kdevname(device), routine);
-		return 1;
-	}
-	if (info->magic != SERIAL_MAGIC) {
-		printk(badmagic, kdevname(device), routine);
-		return 1;
-	}
-#endif
-	return 0;
-}
-
-/*
- * This is used to figure out the divisor speeds.
- *
- * The formula is:    Baud = BASE_BAUD / ((N + 1) * (1 << M)),
- *
- * with               0 <= N < 64 and 0 <= M < 16
- * 
- * 12-Oct-2001 - Replaced table driven approach with code written by
- * Theodore Ts'o <tytso@alum.mit.edu> which exactly replicates the
- * table.  (Modulo bugs for the 307200 and 61440 baud rates, which
- * were clearly incorrectly calculated in the original table.  This is
- * why tables filled with magic constants are evil.)
- */
-
-static void calc_ebrg(int baud, int *n_ret, int *m_ret)
-{
-	int	n, m;
-
-	if (baud == 0) {
-		*n_ret = 0;
-		*m_ret = 0;
-		return;
-	}
-     
-	/*
-	 * We scale numbers by 10 so that we get better accuracy
-	 * without having to use floating point.  Here we increment m
-	 * until n is within the valid range.
-	 */
-	n = (BASE_BAUD*10) / baud;
-	m = 0;
-	while (n >= 640) {
-		n = n / 2;
-		m++;
-	}
-	n = (n+5) / 10;
-	/*
-	 * We try very hard to avoid speeds with M == 0 since they may
-	 * not work correctly for XTAL frequences above 10 MHz.
-	 */
-	if ((m == 0) && ((n & 1) == 0)) {
-		n = n / 2;
-		m++;
-	}
-	*n_ret = n - 1;
-	*m_ret = m;
-}
-
-#define SAB82532_MAX_TEC_TIMEOUT 200000	/* 1 character time (at 50 baud) */
-#define SAB82532_MAX_CEC_TIMEOUT  50000	/* 2.5 TX CLKs (at 50 baud) */
-
-static __inline__ void sab82532_tec_wait(struct sab82532 *info)
-{
-	int timeout = info->tec_timeout;
-
-	while ((readb(&info->regs->r.star) & SAB82532_STAR_TEC) && --timeout)
-		udelay(1);
-}
-
-static __inline__ void sab82532_cec_wait(struct sab82532 *info)
-{
-	int timeout = info->cec_timeout;
-
-	while ((readb(&info->regs->r.star) & SAB82532_STAR_CEC) && --timeout)
-		udelay(1);
-}
-
-static __inline__ void sab82532_start_tx(struct sab82532 *info)
-{
-	unsigned long flags;
-	int i;
-
-	save_flags(flags); cli();
-
-	if (info->xmit.head == info->xmit.tail)
-		goto out;
-
-	if (!test_bit(SAB82532_XPR, &info->irqflags))
-		goto out;
-
-	info->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS);
-	writeb(info->interrupt_mask1, &info->regs->w.imr1);
-	clear_bit(SAB82532_ALLS, &info->irqflags);
-
-	clear_bit(SAB82532_XPR, &info->irqflags);
-	for (i = 0; i < info->xmit_fifo_size; i++) {
-		writeb(info->xmit.buf[info->xmit.tail],
-		       &info->regs->w.xfifo[i]);
-		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
-		info->icount.tx++;
-		if (info->xmit.head == info->xmit.tail)
-			break;
-	}
-
-	/* Issue a Transmit Frame command. */
-	sab82532_cec_wait(info);
-	writeb(SAB82532_CMDR_XF, &info->regs->w.cmdr);
-
-out:
-	restore_flags(flags);
-}
-
-
-/*
- * ------------------------------------------------------------
- * sab82532_stop() and sab82532_start()
- *
- * This routines are called before setting or resetting tty->stopped.
- * They enable or disable transmitter interrupts, as necessary.
- * ------------------------------------------------------------
- */
-static void sab82532_stop(struct tty_struct *tty)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_stop"))
-		return;
-
-	save_flags(flags); cli();
-	info->interrupt_mask1 |= SAB82532_IMR1_XPR;
-	writeb(info->interrupt_mask1, &info->regs->w.imr1);
-	restore_flags(flags);
-}
-
-static void sab82532_start(struct tty_struct *tty)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-	unsigned long flags;
-	
-	if (serial_paranoia_check(info, tty->device, "sab82532_start"))
-		return;
-
-	save_flags(flags); cli();
-	info->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
-	writeb(info->interrupt_mask1, &info->regs->w.imr1);
-	sab82532_start_tx(info);
-	restore_flags(flags);
-}
-
-/*
- * ----------------------------------------------------------------------
- *
- * Here starts the interrupt handling routines.  All of the following
- * subroutines are declared as inline and are folded into
- * sab82532_interrupt().  They were separated out for readability's sake.
- *
- * Note: sab82532_interrupt() is a "fast" interrupt, which means that it
- * runs with interrupts turned off.  People who may want to modify
- * sab82532_interrupt() should try to keep the interrupt handler as fast as
- * possible.  After you are done making modifications, it is not a bad
- * idea to do:
- * 
- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
- *
- * and look at the resulting assemble code in serial.s.
- *
- * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
- */
-
-/*
- * This routine is used by the interrupt handler to schedule
- * processing in the software interrupt portion of the driver.
- */
-static void sab82532_sched_event(struct sab82532 *info, int event)
-{
-	info->event |= 1 << event;
-	queue_task(&info->tqueue, &tq_serial);
-	mark_bh(SERIAL_BH);
-}
-
-static void receive_chars(struct sab82532 *info,
-			  union sab82532_irq_status *stat)
-{
-	struct tty_struct *tty = info->tty;
-	unsigned char buf[32];
-	unsigned char status;
-	int free_fifo = 0;
-	int i, count = 0;
-
-	/* Read number of BYTES (Character + Status) available. */
-	if (stat->sreg.isr0 & SAB82532_ISR0_RPF) {
-		count = info->recv_fifo_size;
-		free_fifo++;
-	}
-
-	if (stat->sreg.isr0 & SAB82532_ISR0_TCD) {
-		count = readb(&info->regs->r.rbcl) & (info->recv_fifo_size - 1);
-		free_fifo++;
-	}
-
-	/* Issue a FIFO read command in case we where idle. */
-	if (stat->sreg.isr0 & SAB82532_ISR0_TIME) {
-		sab82532_cec_wait(info);
-		writeb(SAB82532_CMDR_RFRD, &info->regs->w.cmdr);
-		return;
-	}
-
-	if (stat->sreg.isr0 & SAB82532_ISR0_RFO) {
-#ifdef SERIAL_DEBUG_OVERFLOW
-		printk("sab82532: receive_chars: RFO");
-#endif
-		free_fifo++;
-	}
-
-	/* Read the FIFO. */
-	for (i = 0; i < count; i++)
-		buf[i] = readb(&info->regs->r.rfifo[i]);
-
-	/* Issue Receive Message Complete command. */
-	if (free_fifo) {
-		sab82532_cec_wait(info);
-		writeb(SAB82532_CMDR_RMC, &info->regs->w.cmdr);
-	}
-
-	if (!tty)
-		return;
-
-	for (i = 0; i < count; ) {
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-#ifdef SERIAL_DEBUG_OVERFLOW
-			printk("sab82532: receive_chars: tty overrun\n");
-#endif
-			info->icount.buf_overrun++;
-			break;
-		}
-
-		tty->flip.count++;
-		*tty->flip.char_buf_ptr++ = buf[i++];
-		status = buf[i++];
-		info->icount.rx++;
-
-#ifdef SERIAL_DEBUG_INTR
-                printk("DR%02x:%02x...", (unsigned char)*(tty->flip.char_buf_ptr - 1), status);
-#endif
-
-		if (status & SAB82532_RSTAT_PE) {
-			*tty->flip.flag_buf_ptr++ = TTY_PARITY;
-			info->icount.parity++;
-		} else if (status & SAB82532_RSTAT_FE) {
-			*tty->flip.flag_buf_ptr++ = TTY_FRAME;
-			info->icount.frame++;
-		}
-		else
-			*tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-	}
-
-	queue_task(&tty->flip.tqueue, &tq_timer);
-}
-
-static void transmit_chars(struct sab82532 *info,
-			   union sab82532_irq_status *stat)
-{
-	int i;
-
-	if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) {
-		info->interrupt_mask1 |= SAB82532_IMR1_ALLS;
-		writeb(info->interrupt_mask1, &info->regs->w.imr1);
-		set_bit(SAB82532_ALLS, &info->irqflags);
-	}
-
-	if (!(stat->sreg.isr1 & SAB82532_ISR1_XPR))
-		return;
-
-	if (!(readb(&info->regs->r.star) & SAB82532_STAR_XFW)) {
-#ifdef SERIAL_DEBUG_FIFO
-		printk("%s: XPR, but no XFW (?)\n", __FUNCTION__);
-#endif
-		return;
-	}
-
-	set_bit(SAB82532_XPR, &info->irqflags);
-
-	if (!info->tty) {
-		info->interrupt_mask1 |= SAB82532_IMR1_XPR;
-		writeb(info->interrupt_mask1, &info->regs->w.imr1);
-		return;
-	}
-
-	if ((info->xmit.head == info->xmit.tail) ||
-	    info->tty->stopped || info->tty->hw_stopped) {
-		info->interrupt_mask1 |= SAB82532_IMR1_XPR;
-		writeb(info->interrupt_mask1, &info->regs->w.imr1);
-		return;
-	}
-
-	info->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS);
-	writeb(info->interrupt_mask1, &info->regs->w.imr1);
-	clear_bit(SAB82532_ALLS, &info->irqflags);
-
-	/* Stuff 32 bytes into Transmit FIFO. */
-	clear_bit(SAB82532_XPR, &info->irqflags);
-	for (i = 0; i < info->xmit_fifo_size; i++) {
-		writeb(info->xmit.buf[info->xmit.tail],
-		       &info->regs->w.xfifo[i]);
-		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
-		info->icount.tx++;
-		if (info->xmit.head == info->xmit.tail)
-			break;
-	}
-
-	/* Issue a Transmit Frame command. */
-	sab82532_cec_wait(info);
-	writeb(SAB82532_CMDR_XF, &info->regs->w.cmdr);
-
-	if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
-		sab82532_sched_event(info, RS_EVENT_WRITE_WAKEUP);
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("THRE...");
-#endif
-}
-
-static void check_status(struct sab82532 *info,
-			 union sab82532_irq_status *stat)
-{
-	struct tty_struct *tty = info->tty;
-	int modem_change = 0;
-
-	if (stat->sreg.isr1 & SAB82532_ISR1_BRK) {
-#ifdef CONFIG_SERIAL_CONSOLE
-		if (info->is_console) {
-			batten_down_hatches(info);
-			return;
-		}
-#endif
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-			info->icount.buf_overrun++;
-			goto check_modem;
-		}
-		tty->flip.count++;
-		*tty->flip.flag_buf_ptr++ = TTY_PARITY;
-		*tty->flip.char_buf_ptr++ = 0;
-		info->icount.brk++;
-	}
-
-	if (!tty)
-		return;
-
-	if (stat->sreg.isr0 & SAB82532_ISR0_RFO) {
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-			info->icount.buf_overrun++;
-			goto check_modem;
-		}
-		tty->flip.count++;
-		*tty->flip.flag_buf_ptr++ = TTY_PARITY;
-		*tty->flip.char_buf_ptr++ = 0;
-		info->icount.overrun++;
-	}
-
-check_modem:
-	if (stat->sreg.isr0 & SAB82532_ISR0_CDSC) {
-		info->dcd = (readb(&info->regs->r.vstr) & SAB82532_VSTR_CD) ? 0 : 1;
-		info->icount.dcd++;
-		modem_change++;
-#ifdef SERIAL_DEBUG_MODEM
-		printk("DCD change: %d\n", info->icount.dcd);
-#endif
-	}
-	if (stat->sreg.isr1 & SAB82532_ISR1_CSC) {
-		info->cts = readb(&info->regs->r.star) & SAB82532_STAR_CTS;
-		info->icount.cts++;
-		modem_change++;
-#ifdef SERIAL_DEBUG_MODEM
-		printk("CTS change: %d, CTS %s\n", info->icount.cts, info->cts ? "on" : "off");
-#endif
-	}
-	if ((readb(&info->regs->r.pvr) & info->pvr_dsr_bit) ^ info->dsr) {
-		info->dsr = (readb(&info->regs->r.pvr) & info->pvr_dsr_bit) ? 0 : 1;
-		info->icount.dsr++;
-		modem_change++;
-#ifdef SERIAL_DEBUG_MODEM
-		printk("DSR change: %d\n", info->icount.dsr);
-#endif
-	}
-	if (modem_change)
-		wake_up_interruptible(&info->delta_msr_wait);
-
-	if ((info->flags & ASYNC_CHECK_CD) &&
-	    (stat->sreg.isr0 & SAB82532_ISR0_CDSC)) {
-
-#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
-		printk("ttys%d CD now %s...", info->line,
-		       (info->dcd) ? "on" : "off");
-#endif		
-
-		if (info->dcd)
-			wake_up_interruptible(&info->open_wait);
-		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
-
-#ifdef SERIAL_DEBUG_OPEN
-			printk("scheduling hangup...");
-#endif
-			MOD_INC_USE_COUNT;
-			if (schedule_task(&info->tqueue_hangup) == 0)
-				MOD_DEC_USE_COUNT;
-		}
-	}
-
-	if (info->flags & ASYNC_CTS_FLOW) {
-		if (info->tty->hw_stopped) {
-			if (info->cts) {
-
-#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
-				printk("CTS tx start...");
-#endif
-				info->tty->hw_stopped = 0;
-				sab82532_sched_event(info,
-						     RS_EVENT_WRITE_WAKEUP);
-				info->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
-				writeb(info->interrupt_mask1, &info->regs->w.imr1);
-				sab82532_start_tx(info);
-			}
-		} else {
-			if (!(info->cts)) {
-
-#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
-				printk("CTS tx stop...");
-#endif
-				info->tty->hw_stopped = 1;
-			}
-		}
-	}
-}
-
-/*
- * This is the serial driver's generic interrupt routine
- */
-static void sab82532_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	struct sab82532 *info = dev_id;
-	union sab82532_irq_status status;
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("sab82532_interrupt(%d)...", irq);
-#endif
-
-	status.stat = 0;
-	if (readb(&info->regs->r.gis) & SAB82532_GIS_ISA0)
-		status.sreg.isr0 = readb(&info->regs->r.isr0);
-	if (readb(&info->regs->r.gis) & SAB82532_GIS_ISA1)
-		status.sreg.isr1 = readb(&info->regs->r.isr1);
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("%d<%02x.%02x>", info->line,
-	       status.sreg.isr0, status.sreg.isr1);
-#endif
-
-	if (!status.stat)
-		goto next;
-
-	if (status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
-				SAB82532_ISR0_RFO | SAB82532_ISR0_RPF))
-		receive_chars(info, &status);
-	if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) ||
-	    (status.sreg.isr1 & (SAB82532_ISR1_BRK | SAB82532_ISR1_CSC)))
-		check_status(info, &status);
-	if (status.sreg.isr1 & (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR))
-		transmit_chars(info, &status);
-
-next:
-	info = info->next;
-	status.stat = 0;
-	if (readb(&info->regs->r.gis) & SAB82532_GIS_ISB0)
-		status.sreg.isr0 = readb(&info->regs->r.isr0);
-	if (readb(&info->regs->r.gis) & SAB82532_GIS_ISB1)
-		status.sreg.isr1 = readb(&info->regs->r.isr1);
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("%d<%02x.%02x>", info->line,
-	       status.sreg.isr0, status.sreg.isr1);
-#endif
-
-	if (!status.stat)
-		goto done;
-
-	if (status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
-				SAB82532_ISR0_RFO | SAB82532_ISR0_RPF))
-		receive_chars(info, &status);
-	if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) ||
-	    (status.sreg.isr1 & (SAB82532_ISR1_BRK | SAB82532_ISR1_CSC)))
-		check_status(info, &status);
-	if (status.sreg.isr1 & (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR))
-		transmit_chars(info, &status);
-
-done:
-	;
-#ifdef SERIAL_DEBUG_INTR
-	printk("end.\n");
-#endif
-}
-
-/*
- * -------------------------------------------------------------------
- * Here ends the serial interrupt routines.
- * -------------------------------------------------------------------
- */
-
-/*
- * This routine is used to handle the "bottom half" processing for the
- * serial driver, known also the "software interrupt" processing.
- * This processing is done at the kernel interrupt level, after the
- * sab82532_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
- * is where time-consuming activities which can not be done in the
- * interrupt driver proper are done; the interrupt driver schedules
- * them using sab82532_sched_event(), and they get done here.
- */
-static void do_serial_bh(void)
-{
-	run_task_queue(&tq_serial);
-}
-
-static void do_softint(void *private_)
-{
-	struct sab82532	*info = (struct sab82532 *)private_;
-	struct tty_struct *tty;
-
-	tty = info->tty;
-	if (!tty)
-		return;
-
-	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
-	}
-}
-
-/*
- * This routine is called from the scheduler tqueue when the interrupt
- * routine has signalled that a hangup has occurred.  The path of
- * hangup processing is:
- *
- * 	serial interrupt routine -> (scheduler tqueue) ->
- * 	do_serial_hangup() -> tty->hangup() -> sab82532_hangup()
- * 
- */
-static void do_serial_hangup(void *private_)
-{
-	struct sab82532	*info = (struct sab82532 *) private_;
-	struct tty_struct *tty;
-
-	tty = info->tty;
-	if (tty)
-		tty_hangup(tty);
-	MOD_DEC_USE_COUNT;
-}
-
-static void
-sab82532_init_line(struct sab82532 *info)
-{
-	unsigned char stat, tmp;
-
-	/*
-	 * Wait for any commands or immediate characters
-	 */
-	sab82532_cec_wait(info);
-	sab82532_tec_wait(info);
-
-	/*
-	 * Clear the FIFO buffers.
-	 */
-	writeb(SAB82532_CMDR_RRES, &info->regs->w.cmdr);
-	sab82532_cec_wait(info);
-	writeb(SAB82532_CMDR_XRES, &info->regs->w.cmdr);
-
-	/*
-	 * Clear the interrupt registers.
-	 */
-	stat = readb(&info->regs->r.isr0);
-	stat = readb(&info->regs->r.isr1);
-
-	/*
-	 * Now, initialize the UART 
-	 */
-	writeb(0, &info->regs->w.ccr0);				/* power-down */
-	writeb(SAB82532_CCR0_MCE | SAB82532_CCR0_SC_NRZ |
-	       SAB82532_CCR0_SM_ASYNC, &info->regs->w.ccr0);
-	writeb(SAB82532_CCR1_ODS | SAB82532_CCR1_BCR | 7, &info->regs->w.ccr1);
-	writeb(SAB82532_CCR2_BDF | SAB82532_CCR2_SSEL |
-	       SAB82532_CCR2_TOE, &info->regs->w.ccr2);
-	writeb(0, &info->regs->w.ccr3);
-	writeb(SAB82532_CCR4_MCK4 | SAB82532_CCR4_EBRG, &info->regs->w.ccr4);
-	writeb(SAB82532_MODE_RTS | SAB82532_MODE_FCTS |
-	       SAB82532_MODE_RAC, &info->regs->w.mode);
-	writeb(SAB82532_RFC_DPS | SAB82532_RFC_RFDF, &info->regs->w.rfc);
-	switch (info->recv_fifo_size) {
-		case 1:
-			tmp = readb(&info->regs->w.rfc);
-			tmp |= SAB82532_RFC_RFTH_1;
-			writeb(tmp, &info->regs->w.rfc);
-			break;
-		case 4:
-			tmp = readb(&info->regs->w.rfc);
-			tmp |= SAB82532_RFC_RFTH_4;
-			writeb(tmp, &info->regs->w.rfc);
-			break;
-		case 16:
-			tmp = readb(&info->regs->w.rfc);
-			tmp |= SAB82532_RFC_RFTH_16;
-			writeb(tmp, &info->regs->w.rfc);
-			break;
-		default:
-			info->recv_fifo_size = 32;
-			/* fall through */
-		case 32:
-			tmp = readb(&info->regs->w.rfc);
-			tmp |= SAB82532_RFC_RFTH_32;
-			writeb(tmp, &info->regs->w.rfc);
-			break;
-	}
-	tmp = readb(&info->regs->rw.ccr0);
-	tmp |= SAB82532_CCR0_PU;	/* power-up */
-	writeb(tmp, &info->regs->rw.ccr0);
-}
-
-static int startup(struct sab82532 *info)
-{
-	unsigned long flags;
-	unsigned long page;
-	int retval = 0;
-
-	page = get_free_page(GFP_KERNEL);
-	if (!page)
-		return -ENOMEM;
-
-	save_flags(flags); cli();
-
-	if (info->flags & ASYNC_INITIALIZED) {
-		free_page(page);
-		goto errout;
-	}
-
-	if (!info->regs) {
-		if (info->tty)
-			set_bit(TTY_IO_ERROR, &info->tty->flags);
-		free_page(page);
-		retval = -ENODEV;
-		goto errout;
-	}
-	if (info->xmit.buf)
-		free_page(page);
-	else
-		info->xmit.buf = (unsigned char *)page;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("starting up serial port %d...", info->line);
-#endif
-
-	/*
-	 * Initialize the Hardware
-	 */
-	sab82532_init_line(info);
-
-	if (info->tty->termios->c_cflag & CBAUD) {
-		u8 tmp;
-
-		tmp = readb(&info->regs->rw.mode);
-		tmp &= ~(SAB82532_MODE_FRTS);
-		tmp |= SAB82532_MODE_RTS;
-		writeb(tmp, &info->regs->rw.mode);
-
-		tmp = readb(&info->regs->rw.pvr);
-		tmp &= ~(info->pvr_dtr_bit);
-		writeb(tmp, &info->regs->rw.pvr);
-	}
-
-	/*
-	 * Finally, enable interrupts
-	 */
-	info->interrupt_mask0 = SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
-				SAB82532_IMR0_PLLA;
-	writeb(info->interrupt_mask0, &info->regs->w.imr0);
-	info->interrupt_mask1 = SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |
-				SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |
-				SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
-				SAB82532_IMR1_XPR;
-	writeb(info->interrupt_mask1, &info->regs->w.imr1);
-	set_bit(SAB82532_ALLS, &info->irqflags);
-
-	if (info->tty)
-		clear_bit(TTY_IO_ERROR, &info->tty->flags);
-	info->xmit.head = info->xmit.tail = 0;
-
-	set_bit(SAB82532_XPR, &info->irqflags);
-
-	/*
-	 * and set the speed of the serial port
-	 */
-	change_speed(info);
-
-	info->flags |= ASYNC_INITIALIZED;
-	restore_flags(flags);
-	return 0;
-	
-errout:
-	restore_flags(flags);
-	return retval;
-}
-
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void shutdown(struct sab82532 *info)
-{
-	unsigned long flags;
-	u8 tmp;
-
-	if (!(info->flags & ASYNC_INITIALIZED))
-		return;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("Shutting down serial port %d...", info->line);
-#endif
-
-	save_flags(flags); cli(); /* Disable interrupts */
-
-	/*
-	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
-	 * here so the queue might never be waken up
-	 */
-	wake_up_interruptible(&info->delta_msr_wait);
-
-	if (info->xmit.buf) {
-		free_page((unsigned long)info->xmit.buf);
-		info->xmit.buf = 0;
-	}
-
-#ifdef CONFIG_SERIAL_CONSOLE
-	if (info->is_console) {
-		info->interrupt_mask0 = SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
-					SAB82532_IMR0_PLLA | SAB82532_IMR0_CDSC;
-		writeb(info->interrupt_mask0, &info->regs->w.imr0);
-		info->interrupt_mask1 = SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |
-					SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |
-					SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
-					SAB82532_IMR1_XPR;
-		writeb(info->interrupt_mask1, &info->regs->w.imr1);
-		if (info->tty)
-			set_bit(TTY_IO_ERROR, &info->tty->flags);
-		info->flags &= ~ASYNC_INITIALIZED;
-		restore_flags(flags);
-		return;
-	}
-#endif
-
-	/* Disable Interrupts */
-	info->interrupt_mask0 = 0xff;
-	writeb(info->interrupt_mask0, &info->regs->w.imr0);
-	info->interrupt_mask1 = 0xff;
-	writeb(info->interrupt_mask1, &info->regs->w.imr1);
-
-	if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
-		tmp = readb(&info->regs->r.mode);
-		tmp |= (SAB82532_MODE_FRTS | SAB82532_MODE_RTS);
-		writeb(tmp, &info->regs->rw.mode);
-		writeb(readb(&info->regs->rw.pvr) | info->pvr_dtr_bit,
-		       &info->regs->rw.pvr);
-	}
-
-	/* Disable break condition */
-	tmp = readb(&info->regs->rw.dafo);
-	tmp &= ~(SAB82532_DAFO_XBRK);
-	writeb(tmp, &info->regs->rw.dafo);
-
-	/* Disable Receiver */	
-	tmp = readb(&info->regs->rw.mode);
-	tmp &= ~(SAB82532_MODE_RAC);
-	writeb(tmp, &info->regs->rw.mode);
-
-	/* Power Down */	
-	tmp = readb(&info->regs->rw.ccr0);
-	tmp &= ~(SAB82532_CCR0_PU);
-	writeb(tmp, &info->regs->rw.ccr0);
-
-	if (info->tty)
-		set_bit(TTY_IO_ERROR, &info->tty->flags);
-
-	info->flags &= ~ASYNC_INITIALIZED;
-	restore_flags(flags);
-}
-
-/*
- * This routine is called to set the UART divisor registers to match
- * the specified baud rate for a serial port.
- */
-static void change_speed(struct sab82532 *info)
-{
-	unsigned long	flags;
-	unsigned int	ebrg;
-	tcflag_t	cflag;
-	unsigned char	dafo;
-	int		bits, n, m;
-
-	if (!info->tty || !info->tty->termios)
-		return;
-	cflag = info->tty->termios->c_cflag;
-
-	/* Byte size and parity */
-	switch (cflag & CSIZE) {
-	      case CS5: dafo = SAB82532_DAFO_CHL5; bits = 7; break;
-	      case CS6: dafo = SAB82532_DAFO_CHL6; bits = 8; break;
-	      case CS7: dafo = SAB82532_DAFO_CHL7; bits = 9; break;
-	      case CS8: dafo = SAB82532_DAFO_CHL8; bits = 10; break;
-	      /* Never happens, but GCC is too dumb to figure it out */
-	      default:  dafo = SAB82532_DAFO_CHL5; bits = 7; break;
-	}
-
-	if (cflag & CSTOPB) {
-		dafo |= SAB82532_DAFO_STOP;
-		bits++;
-	}
-
-	if (cflag & PARENB) {
-		dafo |= SAB82532_DAFO_PARE;
-		bits++;
-	}
-
-	if (cflag & PARODD) {
-#ifdef CMSPAR
-		if (cflag & CMSPAR)
-			dafo |= SAB82532_DAFO_PAR_MARK;
-		else
-#endif
-			dafo |= SAB82532_DAFO_PAR_ODD;
-	} else {
-#ifdef CMSPAR
-		if (cflag & CMSPAR)
-			dafo |= SAB82532_DAFO_PAR_SPACE;
-		else
-#endif
-			dafo |= SAB82532_DAFO_PAR_EVEN;
-	}
-
-	/* Determine EBRG values based on baud rate */
-	info->baud = tty_get_baud_rate(info->tty);
-	calc_ebrg(info->baud, &n, &m);
-	
-	ebrg = n | (m << 6);
-
-	if (info->baud) {
-		info->timeout = (info->xmit_fifo_size * HZ * bits) / info->baud;
-		info->tec_timeout = (10 * 1000000) / info->baud;
-		info->cec_timeout = info->tec_timeout >> 2;
-	} else {
-		info->timeout = 0;
-		info->tec_timeout = SAB82532_MAX_TEC_TIMEOUT;
-		info->cec_timeout = SAB82532_MAX_CEC_TIMEOUT;
-	}
-	info->timeout += HZ / 50;		/* Add .02 seconds of slop */
-
-	/* CTS flow control flags */
-	if (cflag & CRTSCTS)
-		info->flags |= ASYNC_CTS_FLOW;
-	else
-		info->flags &= ~(ASYNC_CTS_FLOW);
-
-	if (cflag & CLOCAL)
-		info->flags &= ~(ASYNC_CHECK_CD);
-	else
-		info->flags |= ASYNC_CHECK_CD;
-	if (info->tty)
-		info->tty->hw_stopped = 0;
-
-	/*
-	 * Set up parity check flag
-	 * XXX: not implemented, yet.
-	 */
-#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
-	/*
-	 * Characters to ignore
-	 * XXX: not implemented, yet.
-	 */
-
-	/*
-	 * !!! ignore all characters if CREAD is not set
-	 * XXX: not implemented, yet.
-	 */
-	if ((cflag & CREAD) == 0)
-		info->ignore_status_mask |= SAB82532_ISR0_RPF |
-					    SAB82532_ISR0_TCD |
-					    SAB82532_ISR0_TIME;
-
-	save_flags(flags); cli();
-	sab82532_cec_wait(info);
-	sab82532_tec_wait(info);
-	writeb(dafo, &info->regs->w.dafo);
-	writeb(ebrg & 0xff, &info->regs->w.bgr);
-	writeb(readb(&info->regs->rw.ccr2) & ~(0xc0), &info->regs->rw.ccr2);
-	writeb(readb(&info->regs->rw.ccr2) | ((ebrg >> 2) & 0xc0), &info->regs->rw.ccr2);
-	if (info->flags & ASYNC_CTS_FLOW) {
-		writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_RTS), &info->regs->rw.mode);
-		writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_FRTS, &info->regs->rw.mode);
-		writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_FCTS), &info->regs->rw.mode);
-		info->interrupt_mask1 &= ~(SAB82532_IMR1_CSC);
-		writeb(info->interrupt_mask1, &info->regs->w.imr1);
-	} else {
-		writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RTS, &info->regs->rw.mode);
-		writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_FRTS), &info->regs->rw.mode);
-		writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_FCTS, &info->regs->rw.mode);
-		info->interrupt_mask1 |= SAB82532_IMR1_CSC;
-		writeb(info->interrupt_mask1, &info->regs->w.imr1);
-	}
-	writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RAC, &info->regs->rw.mode);
-	restore_flags(flags);
-}
-
-static void sab82532_put_char(struct tty_struct *tty, unsigned char ch)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_put_char"))
-		return;
-
-	if (!tty || !info->xmit.buf)
-		return;
-
-	save_flags(flags); cli();
-	if (!CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE)) {
-		restore_flags(flags);
-		return;
-	}
-
-	info->xmit.buf[info->xmit.head] = ch;
-	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
-	restore_flags(flags);
-}
-
-static void sab82532_flush_chars(struct tty_struct *tty)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_flush_chars"))
-		return;
-
-	if ((info->xmit.head == info->xmit.tail) ||
-	    tty->stopped || tty->hw_stopped || !info->xmit.buf)
-		return;
-
-	save_flags(flags); cli();
-	info->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
-	writeb(info->interrupt_mask1, &info->regs->w.imr1);
-	sab82532_start_tx(info);
-	restore_flags(flags);
-}
-
-static int sab82532_write(struct tty_struct * tty, int from_user,
-			  const unsigned char *buf, int count)
-{
-	int c, ret = 0;
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_write"))
-		return 0;
-
-	if (!tty || !info->xmit.buf || !tmp_buf)
-		return 0;
-	    
-	save_flags(flags);
-	if (from_user) {
-		down(&tmp_buf_sem);
-		while (1) {
-			int c1;
-			c = CIRC_SPACE_TO_END(info->xmit.head,
-					      info->xmit.tail,
-					      SERIAL_XMIT_SIZE);
-			if (count < c)
-				c = count;
-			if (c <= 0)
-				break;
-
-			c -= copy_from_user(tmp_buf, buf, c);
-			if (!c) {
-				if (!ret)
-					ret = -EFAULT;
-				break;
-			}
-			cli();
-			c1 = CIRC_SPACE_TO_END(info->xmit.head,
-					       info->xmit.tail,
-					       SERIAL_XMIT_SIZE);
-			if (c1 < c)
-				c = c1;
-			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
-			info->xmit.head = (info->xmit.head + c) & (SERIAL_XMIT_SIZE-1);
-			restore_flags(flags);
-			buf += c;
-			count -= c;
-			ret += c;
-		}
-		up(&tmp_buf_sem);
-	} else {
-		cli();
-		while (1) {
-			c = CIRC_SPACE_TO_END(info->xmit.head,
-					      info->xmit.tail,
-					      SERIAL_XMIT_SIZE);
-			if (count < c)
-				c = count;
-			if (c <= 0)
-				break;
-			memcpy(info->xmit.buf + info->xmit.head, buf, c);
-			info->xmit.head = (info->xmit.head + c) & (SERIAL_XMIT_SIZE-1);
-			buf += c;
-			count -= c;
-			ret += c;
-		}
-		restore_flags(flags);
-	}
-
-	if ((info->xmit.head != info->xmit.tail) &&
-	    !tty->stopped && !tty->hw_stopped) {
-		info->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
-		writeb(info->interrupt_mask1, &info->regs->w.imr1);
-		sab82532_start_tx(info);
-	}
-
-	restore_flags(flags);
-	return ret;
-}
-
-static int sab82532_write_room(struct tty_struct *tty)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_write_room"))
-		return 0;
-
-	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-}
-
-static int sab82532_chars_in_buffer(struct tty_struct *tty)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-				
-	if (serial_paranoia_check(info, tty->device, "sab82532_chars_in_buffer"))
-		return 0;
-
-	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-}
-
-static void sab82532_flush_buffer(struct tty_struct *tty)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_flush_buffer"))
-		return;
-
-	save_flags(flags); cli();
-	info->xmit.head = info->xmit.tail = 0;
-	restore_flags(flags);
-
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
-}
-
-/*
- * This function is used to send a high-priority XON/XOFF character to
- * the device
- */
-static void sab82532_send_xchar(struct tty_struct *tty, char ch)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_send_xchar"))
-		return;
-
-	save_flags(flags); cli();
-	sab82532_tec_wait(info);
-	writeb(ch, &info->regs->w.tic);
-	restore_flags(flags);
-}
-
-/*
- * ------------------------------------------------------------
- * sab82532_throttle()
- * 
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void sab82532_throttle(struct tty_struct * tty)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-#ifdef SERIAL_DEBUG_THROTTLE
-	char	buf[64];
-	
-	printk("throttle %s: %d....\n", _tty_name(tty, buf),
-	       tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_throttle"))
-		return;
-	
-	if (I_IXOFF(tty))
-		sab82532_send_xchar(tty, STOP_CHAR(tty));
-
-	if (tty->termios->c_cflag & CRTSCTS) {
-		u8 mode = readb(&info->regs->r.mode);
-		mode &= ~(SAB82532_MODE_FRTS | SAB82532_MODE_RTS);
-		writeb(mode, &info->regs->w.mode);
-	}
-}
-
-static void sab82532_unthrottle(struct tty_struct * tty)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-#ifdef SERIAL_DEBUG_THROTTLE
-	char	buf[64];
-	
-	printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
-	       tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_unthrottle"))
-		return;
-	
-	if (I_IXOFF(tty)) {
-		if (info->x_char)
-			info->x_char = 0;
-		else
-			sab82532_send_xchar(tty, START_CHAR(tty));
-	}
-
-	if (tty->termios->c_cflag & CRTSCTS) {
-		u8 mode = readb(&info->regs->r.mode);
-		mode &= ~(SAB82532_MODE_RTS);
-		mode |= SAB82532_MODE_FRTS;
-		writeb(mode, &info->regs->w.mode);
-	}
-}
-
-/*
- * ------------------------------------------------------------
- * sab82532_ioctl() and friends
- * ------------------------------------------------------------
- */
-
-static int get_serial_info(struct sab82532 *info,
-			   struct serial_struct *retinfo)
-{
-	struct serial_struct tmp;
-   
-	if (!retinfo)
-		return -EFAULT;
-	memset(&tmp, 0, sizeof(tmp));
-	tmp.type = info->type;
-	tmp.line = info->line;
-	tmp.port = (unsigned long)info->regs;
-	tmp.irq = info->irq;
-	tmp.flags = info->flags;
-	tmp.xmit_fifo_size = info->xmit_fifo_size;
-	tmp.baud_base = info->baud_base;
-	tmp.close_delay = info->close_delay;
-	tmp.closing_wait = info->closing_wait;
-	tmp.custom_divisor = info->custom_divisor;
-	tmp.hub6 = 0;
-	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
-		return -EFAULT;
-	return 0;
-}
-
-static int set_serial_info(struct sab82532 *info,
-			   struct serial_struct *new_info)
-{
-	return 0;
-}
-
-
-/*
- * get_lsr_info - get line status register info
- *
- * Purpose: Let user call ioctl() to get info when the UART physically
- * 	    is emptied.  On bus types like RS485, the transmitter must
- * 	    release the bus after transmitting. This must be done when
- * 	    the transmit shift register is empty, not be done when the
- * 	    transmit holding register is empty.  This functionality
- * 	    allows an RS485 driver to be written in user space. 
- */
-static int get_lsr_info(struct sab82532 * info, unsigned int *value)
-{
-	unsigned int result;
-
-	result = (!info->xmit.buf && test_bit(SAB82532_ALLS, &info->irqflags))
-							? TIOCSER_TEMT : 0;
-	return put_user(result, value);
-}
-
-
-static int get_modem_info(struct sab82532 * info, unsigned int *value)
-{
-	unsigned int result;
-
-	result =  ((readb(&info->regs->r.mode) & SAB82532_MODE_RTS) ? 
-		    ((readb(&info->regs->r.mode) & SAB82532_MODE_FRTS) ? 0 : TIOCM_RTS)
-							    : TIOCM_RTS)
-		| ((readb(&info->regs->r.pvr) & info->pvr_dtr_bit) ? 0 : TIOCM_DTR)
-		| ((readb(&info->regs->r.vstr) & SAB82532_VSTR_CD) ? 0 : TIOCM_CAR)
-		| ((readb(&info->regs->r.pvr) & info->pvr_dsr_bit) ? 0 : TIOCM_DSR)
-		| ((readb(&info->regs->r.star) & SAB82532_STAR_CTS) ? TIOCM_CTS : 0);
-	return put_user(result,value);
-}
-
-static int set_modem_info(struct sab82532 * info, unsigned int cmd,
-			  unsigned int *value)
-{
-	unsigned int arg;
-
-	if (get_user(arg, value))
-		return -EFAULT;
-	switch (cmd) {
-	case TIOCMBIS: 
-		if (arg & TIOCM_RTS) {
-			writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_FRTS), &info->regs->rw.mode);
-			writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RTS, &info->regs->rw.mode);
-		}
-		if (arg & TIOCM_DTR) {
-			writeb(readb(&info->regs->rw.pvr) & ~(info->pvr_dtr_bit), &info->regs->rw.pvr);
-		}
-		break;
-	case TIOCMBIC:
-		if (arg & TIOCM_RTS) {
-			writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_FRTS, &info->regs->rw.mode);
-			writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RTS, &info->regs->rw.mode);
-		}
-		if (arg & TIOCM_DTR) {
-			writeb(readb(&info->regs->rw.pvr) | info->pvr_dtr_bit, &info->regs->rw.pvr);
-		}
-		break;
-	case TIOCMSET:
-		if (arg & TIOCM_RTS) {
-			writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_FRTS), &info->regs->rw.mode);
-			writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RTS, &info->regs->rw.mode);
-		} else {
-			writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_FRTS, &info->regs->rw.mode);
-			writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RTS, &info->regs->rw.mode);
-		}
-		if (arg & TIOCM_DTR) {
-			writeb(readb(&info->regs->rw.pvr) & ~(info->pvr_dtr_bit), &info->regs->rw.pvr);
-		} else {
-			writeb(readb(&info->regs->rw.pvr) | info->pvr_dtr_bit, &info->regs->rw.pvr);
-		}
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/*
- * This routine sends a break character out the serial port.
- */
-static void sab82532_break(struct tty_struct *tty, int break_state)
-{
-	struct sab82532 * info = (struct sab82532 *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_break"))
-		return;
-
-	if (!info->regs)
-		return;
-
-#ifdef SERIAL_DEBUG_SEND_BREAK
-	printk("sab82532_break(%d) jiff=%lu...", break_state, jiffies);
-#endif
-	save_flags(flags); cli();
-	if (break_state == -1)
-		writeb(readb(&info->regs->rw.dafo) | SAB82532_DAFO_XBRK, &info->regs->rw.dafo);
-	else
-		writeb(readb(&info->regs->rw.dafo) & ~(SAB82532_DAFO_XBRK), &info->regs->rw.dafo);
-	restore_flags(flags);
-}
-
-
-static int sab82532_ioctl(struct tty_struct *tty, struct file * file,
-		    unsigned int cmd, unsigned long arg)
-{
-	struct sab82532 * info = (struct sab82532 *)tty->driver_data;
-	struct async_icount cprev, cnow;	/* kernel counter temps */
-	struct serial_icounter_struct *p_cuser;	/* user space */
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_ioctl"))
-		return -ENODEV;
-
-	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
-	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
-	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT) &&
-	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
-		if (tty->flags & (1 << TTY_IO_ERROR))
-		    return -EIO;
-	}
-	
-	switch (cmd) {
-		case TIOCGSOFTCAR:
-			return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg);
-		case TIOCSSOFTCAR:
-			if (get_user(arg, (unsigned int *) arg))
-				return -EFAULT;
-			tty->termios->c_cflag =
-				((tty->termios->c_cflag & ~CLOCAL) |
-				 (arg ? CLOCAL : 0));
-			return 0;
-		case TIOCMGET:
-			return get_modem_info(info, (unsigned int *) arg);
-		case TIOCMBIS:
-		case TIOCMBIC:
-		case TIOCMSET:
-			return set_modem_info(info, cmd, (unsigned int *) arg);
-		case TIOCGSERIAL:
-			return get_serial_info(info,
-					       (struct serial_struct *) arg);
-		case TIOCSSERIAL:
-			return set_serial_info(info,
-					       (struct serial_struct *) arg);
-
-		case TIOCSERGETLSR: /* Get line status register */
-			return get_lsr_info(info, (unsigned int *) arg);
-
-		case TIOCSERGSTRUCT:
-			if (copy_to_user((struct sab82532 *) arg,
-					 info, sizeof(struct sab82532)))
-				return -EFAULT;
-			return 0;
-				
-		/*
-		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
-		 * - mask passed in arg for lines of interest
- 		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
-		 * Caller should use TIOCGICOUNT to see which one it was
-		 */
-		 case TIOCMIWAIT:
-			cli();
-			/* note the counters on entry */
-			cprev = info->icount;
-			sti();
-			while (1) {
-				interruptible_sleep_on(&info->delta_msr_wait);
-				/* see if a signal did it */
-				if (signal_pending(current))
-					return -ERESTARTSYS;
-				cli();
-				cnow = info->icount; /* atomic copy */
-				sti();
-				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
-				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
-					return -EIO; /* no change => error */
-				if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
-				     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
-				     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
-				     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
-					return 0;
-				}
-				cprev = cnow;
-			}
-			/* NOTREACHED */
-
-		/* 
-		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
-		 * Return: write counters to the user passed counter struct
-		 * NB: both 1->0 and 0->1 transitions are counted except for
-		 *     RI where only 0->1 is counted.
-		 */
-		case TIOCGICOUNT:
-			cli();
-			cnow = info->icount;
-			sti();
-			p_cuser = (struct serial_icounter_struct *) arg;
-			if (put_user(cnow.cts, &p_cuser->cts) ||
-			    put_user(cnow.dsr, &p_cuser->dsr) ||
-			    put_user(cnow.rng, &p_cuser->rng) ||
-			    put_user(cnow.dcd, &p_cuser->dcd))
-				return -EFAULT;
-			return 0;
-
-		default:
-			return -ENOIOCTLCMD;
-		}
-	return 0;
-}
-
-static void sab82532_set_termios(struct tty_struct *tty,
-				 struct termios *old_termios)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-
-	if (   (tty->termios->c_cflag == old_termios->c_cflag)
-	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
-		== RELEVANT_IFLAG(old_termios->c_iflag)))
-	  return;
-
-	change_speed(info);
-
-	/* Handle transition to B0 status */
-	if ((old_termios->c_cflag & CBAUD) &&
-	    !(tty->termios->c_cflag & CBAUD)) {
-		writeb(readb(&info->regs->w.mode) | SAB82532_MODE_FRTS, &info->regs->w.mode);
-		writeb(readb(&info->regs->w.mode) | SAB82532_MODE_RTS, &info->regs->w.mode);
-		writeb(readb(&info->regs->w.pvr) | info->pvr_dtr_bit, &info->regs->w.pvr);
-	}
-	
-	/* Handle transition away from B0 status */
-	if (!(old_termios->c_cflag & CBAUD) &&
-	    (tty->termios->c_cflag & CBAUD)) {
-		writeb(readb(&info->regs->w.pvr) & ~(info->pvr_dtr_bit), &info->regs->w.pvr);
-		if (tty->termios->c_cflag & CRTSCTS) {
-			writeb(readb(&info->regs->w.mode) & ~(SAB82532_MODE_RTS), &info->regs->w.mode);
-			writeb(readb(&info->regs->w.mode) | SAB82532_MODE_FRTS, &info->regs->w.mode);
-		} else if (test_bit(TTY_THROTTLED, &tty->flags)) {
-			writeb(readb(&info->regs->w.mode) & ~(SAB82532_MODE_FRTS | SAB82532_MODE_RTS), &info->regs->w.mode);
-		} else {
-			writeb(readb(&info->regs->w.mode) & ~(SAB82532_MODE_FRTS), &info->regs->w.mode);
-			writeb(readb(&info->regs->w.mode) | SAB82532_MODE_RTS, &info->regs->w.mode);
-		}
-	}
-	
-	/* Handle turning off CRTSCTS */
-	if ((old_termios->c_cflag & CRTSCTS) &&
-	    !(tty->termios->c_cflag & CRTSCTS)) {
-		tty->hw_stopped = 0;
-		sab82532_start(tty);
-	}
-}
-
-/*
- * ------------------------------------------------------------
- * sab82532_close()
- * 
- * This routine is called when the serial port gets closed.  First, we
- * wait for the last remaining data to be sent.  Then, we unlink its
- * async structure from the interrupt chain if necessary, and we free
- * that IRQ if nothing is left in the chain.
- * ------------------------------------------------------------
- */
-static void sab82532_close(struct tty_struct *tty, struct file * filp)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-	unsigned long flags;
-
-	if (!info || serial_paranoia_check(info, tty->device, "sab82532_close"))
-		return;
-
-	save_flags(flags); cli();
-
-	if (tty_hung_up_p(filp)) {
-		MOD_DEC_USE_COUNT;
-		restore_flags(flags);
-		return;
-	}
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("sab82532_close ttys%d, count = %d\n", info->line, info->count);
-#endif
-	if ((tty->count == 1) && (info->count != 1)) {
-		/*
-		 * Uh, oh.  tty->count is 1, which means that the tty
-		 * structure will be freed.  info->count should always
-		 * be one in these conditions.  If it's greater than
-		 * one, we've got real problems, since it means the
-		 * serial port won't be shutdown.
-		 */
-		printk("sab82532_close: bad serial port count; tty->count is 1,"
-		       " info->count is %d\n", info->count);
-		info->count = 1;
-	}
-	if (--info->count < 0) {
-		printk("sab82532_close: bad serial port count for ttys%d: %d\n",
-		       info->line, info->count);
-		info->count = 0;
-	}
-	if (info->count) {
-		MOD_DEC_USE_COUNT;
-		restore_flags(flags);
-		return;
-	}
-	info->flags |= ASYNC_CLOSING;
-	/*
-	 * Save the termios structure, since this port may have
-	 * separate termios for callout and dialin.
-	 */
-	if (info->flags & ASYNC_NORMAL_ACTIVE)
-		info->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
-	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
-	 * the line discipline to only process XON/XOFF characters.
-	 */
-	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
-
-	/*
-	 * At this point we stop accepting input.  To do this, we
-	 * disable the receive line status interrupts, and turn off
-	 * the receiver.
-	 */
-	info->interrupt_mask0 |= SAB82532_IMR0_TCD;
-	writeb(info->interrupt_mask0, &info->regs->w.imr0);
-	if (info->flags & ASYNC_INITIALIZED) {
-		/*
-		 * Before we drop DTR, make sure the UART transmitter
-		 * has completely drained; this is especially
-		 * important if there is a transmit FIFO!
-		 */
-		sab82532_wait_until_sent(tty, info->timeout);
-	}
-	shutdown(info);
-	if (tty->driver.flush_buffer)
-		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
-	tty->closing = 0;
-	info->event = 0;
-	info->tty = 0;
-	if (info->blocked_open) {
-		if (info->close_delay) {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(info->close_delay);
-		}
-		wake_up_interruptible(&info->open_wait);
-	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
-	wake_up_interruptible(&info->close_wait);
-	MOD_DEC_USE_COUNT;
-	restore_flags(flags);
-}
-
-/*
- * sab82532_wait_until_sent() --- wait until the transmitter is empty
- */
-static void sab82532_wait_until_sent(struct tty_struct *tty, int timeout)
-{
-	struct sab82532 *info = (struct sab82532 *)tty->driver_data;
-	unsigned long orig_jiffies, char_time;
-
-	if (serial_paranoia_check(info,tty->device,"sab82532_wait_until_sent"))
-		return;
-
-	/*
-	 * Set the check interval to be 1/5 of the estimated time to
-	 * send a single character, and make it at least 1.  The check
-	 * interval should also be less than the timeout.
-	 * 
-	 * Note: we have to use pretty tight timings here to satisfy
-	 * the NIST-PCTS.
-	 */
-	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
-	char_time = char_time / 5;
-	if (char_time == 0)
-		char_time = 1;
-	if (timeout)
-	  char_time = MIN(char_time, timeout);
-#ifdef SERIAL_DEBUG_WAIT_UNTIL_SENT
-	printk("In sab82532_wait_until_sent(%d) check=%lu "
-	       "xmit_cnt = %ld, alls = %d (jiff=%lu)...\n",
-	       timeout, char_time,
-	       CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE),
-	       test_bit(SAB82532_ALLS, &info->irqflags), jiffies);
-#endif
-	orig_jiffies = jiffies;
-	while ((info->xmit.head != info->xmit.tail) ||
-	       !test_bit(SAB82532_ALLS, &info->irqflags)) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(char_time);
-		if (signal_pending(current))
-			break;
-		if (timeout && time_after(jiffies, orig_jiffies + timeout))
-			break;
-	}
-#ifdef SERIAL_DEBUG_WAIT_UNTIL_SENT
-	printk("xmit_cnt = %ld, alls = %d (jiff=%lu)...done\n",
-	       CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE),
-	       test_bit(SAB82532_ALLS, &info->irqflags), jiffies);
-#endif
-}
-
-/*
- * sab82532_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-static void sab82532_hangup(struct tty_struct *tty)
-{
-	struct sab82532 * info = (struct sab82532 *)tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_hangup"))
-		return;
-
-#ifdef CONFIG_SERIAL_CONSOLE
-	if (info->is_console)
-		return;
-#endif
-
-	sab82532_flush_buffer(tty);
-	shutdown(info);
-	info->event = 0;
-	info->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
-	info->tty = 0;
-	wake_up_interruptible(&info->open_wait);
-}
-
-/*
- * ------------------------------------------------------------
- * sab82532_open() and friends
- * ------------------------------------------------------------
- */
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
-			   struct sab82532 *info)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	int retval;
-	int do_clocal = 0;
-
-	/*
-	 * If the device is in the middle of being closed, then block
-	 * until it's done, and then try again.
-	 */
-	if (tty_hung_up_p(filp) ||
-	    (info->flags & ASYNC_CLOSING)) {
-		if (info->flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&info->close_wait);
-#ifdef SERIAL_DO_RESTART
-		if (info->flags & ASYNC_HUP_NOTIFY)
-			return -EAGAIN;
-		else
-			return -ERESTARTSYS;
-#else
-		return -EAGAIN;
-#endif
-	}
-
-	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
-	/*
-	 * If non-blocking mode is set, or the port is not enabled,
-	 * then make the check up front and then exit.
-	 */
-	if ((filp->f_flags & O_NONBLOCK) ||
-	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
-		info->flags |= ASYNC_NORMAL_ACTIVE;
-		return 0;
-	}
-
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
-	/*
-	 * Block waiting for the carrier detect and the line to become
-	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, info->count is dropped by one, so that
-	 * sab82532_close() knows when to free things.  We restore it upon
-	 * exit, either normal or abnormal.
-	 */
-	retval = 0;
-	add_wait_queue(&info->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready before block: ttyS%d, count = %d\n",
-	       info->line, info->count);
-#endif
-	cli();
-	if (!tty_hung_up_p(filp)) 
-		info->count--;
-	sti();
-	info->blocked_open++;
-	while (1) {
-		cli();
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD)) {
-			writeb(readb(&info->regs->rw.pvr) & ~(info->pvr_dtr_bit), &info->regs->rw.pvr);
-			writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_FRTS, &info->regs->rw.mode);
-			writeb(readb(&info->regs->rw.mode) & ~(SAB82532_MODE_RTS), &info->regs->rw.mode);
-		}
-		sti();
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p(filp) ||
-		    !(info->flags & ASYNC_INITIALIZED)) {
-#ifdef SERIAL_DO_RESTART
-			if (info->flags & ASYNC_HUP_NOTIFY)
-				retval = -EAGAIN;
-			else
-				retval = -ERESTARTSYS;	
-#else
-			retval = -EAGAIN;
-#endif
-			break;
-		}
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING) &&
-		    (do_clocal || !(readb(&info->regs->r.vstr) & SAB82532_VSTR_CD)))
-			break;
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			break;
-		}
-#ifdef SERIAL_DEBUG_OPEN
-		printk("block_til_ready blocking: ttyS%d, count = %d, flags = %x, clocal = %d, vstr = %02x\n",
-		       info->line, info->count, info->flags, do_clocal, readb(&info->regs->r.vstr));
-#endif
-		schedule();
-	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&info->open_wait, &wait);
-	if (!tty_hung_up_p(filp))
-		info->count++;
-	info->blocked_open--;
-#ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready after blocking: ttys%d, count = %d\n",
-	       info->line, info->count);
-#endif
-	if (retval)
-		return retval;
-	info->flags |= ASYNC_NORMAL_ACTIVE;
-	return 0;
-}
-
-/*
- * This routine is called whenever a serial port is opened.  It
- * enables interrupts for a serial port, linking in its async structure into
- * the IRQ chain.   It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int sab82532_open(struct tty_struct *tty, struct file * filp)
-{
-	struct sab82532	*info = sab82532_chain;
-	int retval, line;
-	unsigned long page;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("sab82532_open: count = %d\n", info->count);
-#endif
-
-	line = minor(tty->device) - tty->driver.minor_start;
-	if ((line < 0) || (line >= NR_PORTS))
-		return -ENODEV;
-
-	while (info) {
-		if (info->line == line)
-			break;
-		info = info->next;
-	}
-	if (!info) {
-		printk("sab82532_open: can't find info for line %d\n",
-		       line);
-		return -ENODEV;
-	}
-
-	if (serial_paranoia_check(info, tty->device, "sab82532_open"))
-		return -ENODEV;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("sab82532_open %s%d, count = %d\n", tty->driver.name, info->line,
-	       info->count);
-#endif
-
-	if (!tmp_buf) {
-		page = get_free_page(GFP_KERNEL);
-		if (!page)
-			return -ENOMEM;
-		if (tmp_buf)
-			free_page(page);
-		else
-			tmp_buf = (unsigned char *) page;
-	}
-
-	info->count++;
-	tty->driver_data = info;
-	info->tty = tty;
-
-	/*
-	 * If the port is in the middle of closing, bail out now.
-	 */
-	if (tty_hung_up_p(filp) ||
-	    (info->flags & ASYNC_CLOSING)) {
-		if (info->flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&info->close_wait);
-#ifdef SERIAL_DO_RESTART
-		return ((info->flags & ASYNC_HUP_NOTIFY) ?
-			-EAGAIN : -ERESTARTSYS);
-#else
-		return -EAGAIN;
-#endif
-	}
-
-	/*
-	 * Start up serial port
-	 */
-	retval = startup(info);
-	if (retval)
-		return retval;
-
-	MOD_INC_USE_COUNT;
-	retval = block_til_ready(tty, filp, info);
-	if (retval) {
-#ifdef SERIAL_DEBUG_OPEN
-		printk("sab82532_open returning after block_til_ready with %d\n",
-		       retval);
-#endif
-		return retval;
-	}
-
-	if ((info->count == 1) &&
-	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
-		change_speed(info);
-	}
-
-#ifdef CONFIG_SERIAL_CONSOLE
-	if (sab82532_console.cflag && sab82532_console.index == line) {
-		tty->termios->c_cflag = sab82532_console.cflag;
-		sab82532_console.cflag = 0;
-		change_speed(info);
-	}
-#endif
-
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("sab82532_open ttys%d successful... count %d", info->line, info->count);
-#endif
-	return 0;
-}
-
-/*
- * /proc fs routines....
- */
-
-static __inline__ int
-line_info(char *buf, struct sab82532 *info)
-{
-	unsigned long flags;
-	char stat_buf[30];
-	int ret;
-
-	ret = sprintf(buf, "%u: uart:SAB82532 ", info->line);
-	switch (info->type) {
-		case 0:
-			ret += sprintf(buf+ret, "V1.0 ");
-			break;
-		case 1:
-			ret += sprintf(buf+ret, "V2.0 ");
-			break;
-		case 2:
-			ret += sprintf(buf+ret, "V3.2 ");
-			break;
-		default:
-			ret += sprintf(buf+ret, "V?.? ");
-			break;
-	}
-	ret += sprintf(buf+ret, "port:%lX irq:%s",
-		       (unsigned long)info->regs, __irq_itoa(info->irq));
-
-	if (!info->regs) {
-		ret += sprintf(buf+ret, "\n");
-		return ret;
-	}
-
-	/*
-	 * Figure out the current RS-232 lines
-	 */
-	stat_buf[0] = 0;
-	stat_buf[1] = 0;
-	save_flags(flags); cli();
-	if (readb(&info->regs->r.mode) & SAB82532_MODE_RTS) {
-		if (!(readb(&info->regs->r.mode) & SAB82532_MODE_FRTS))
-			strcat(stat_buf, "|RTS");
-	} else {
-		strcat(stat_buf, "|RTS");
-	}
-	if (readb(&info->regs->r.star) & SAB82532_STAR_CTS)
-		strcat(stat_buf, "|CTS");
-	if (!(readb(&info->regs->r.pvr) & info->pvr_dtr_bit))
-		strcat(stat_buf, "|DTR");
-	if (!(readb(&info->regs->r.pvr) & info->pvr_dsr_bit))
-		strcat(stat_buf, "|DSR");
-	if (!(readb(&info->regs->r.vstr) & SAB82532_VSTR_CD))
-		strcat(stat_buf, "|CD");
-	restore_flags(flags);
-
-	if (info->baud)
-		ret += sprintf(buf+ret, " baud:%u", info->baud);
-
-	ret += sprintf(buf+ret, " tx:%u rx:%u",
-		       info->icount.tx, info->icount.rx);
-
-	if (info->icount.frame)
-		ret += sprintf(buf+ret, " fe:%u", info->icount.frame);
-
-	if (info->icount.parity)
-		ret += sprintf(buf+ret, " pe:%u", info->icount.parity);
-
-	if (info->icount.brk)
-		ret += sprintf(buf+ret, " brk:%u", info->icount.brk);
-
-	if (info->icount.overrun)
-		ret += sprintf(buf+ret, " oe:%u", info->icount.overrun);
-
-	/*
-	 * Last thing is the RS-232 status lines.
-	 */
-	ret += sprintf(buf+ret, " %s\n", stat_buf + 1);
-	return ret;
-}
-
-int sab82532_read_proc(char *page, char **start, off_t off, int count,
-		       int *eof, void *data)
-{
-	struct sab82532 *info = sab82532_chain;
-	off_t begin = 0;
-	int len = 0;
-
-	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
-	for (info = sab82532_chain; info && len < 4000; info = info->next) {
-		len += line_info(page + len, info);
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
-	}
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
-}
-
-/*
- * ---------------------------------------------------------------------
- * sab82532_init() and friends
- *
- * sab82532_init() is called at boot-time to initialize the serial driver.
- * ---------------------------------------------------------------------
- */
-static int __init get_sab82532(unsigned long *memory_start)
-{
-	struct linux_ebus *ebus;
-	struct linux_ebus_device *edev = 0;
-	struct sab82532 *sab;
-	unsigned long regs, offset;
-	int i;
-
-	for_each_ebus(ebus) {
-		for_each_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_name, "se"))
-				goto ebus_done;
-
-			if (!strcmp(edev->prom_name, "serial")) {
-				char compat[32];
-				int clen;
-
-				/* On RIO this can be an SE, check it.  We could
-				 * just check ebus->is_rio, but this is more portable.
-				 */
-				clen = prom_getproperty(edev->prom_node, "compatible",
-							compat, sizeof(compat));
-				if (clen > 0) {
-					if (strncmp(compat, "sab82532", 8) == 0) {
-						/* Yep. */
-						goto ebus_done;
-					}
-				}
-			}
-		}
-	}
-ebus_done:
-	if (!edev)
-		return -ENODEV;
-
-	regs = edev->resource[0].start;
-	offset = sizeof(union sab82532_async_regs);
-
-	for (i = 0; i < 2; i++) {
-		if (memory_start) {
-			*memory_start = (*memory_start + 7) & ~(7);
-			sab = (struct sab82532 *)*memory_start;
-			*memory_start += sizeof(struct sab82532);
-		} else {
-			sab = (struct sab82532 *)kmalloc(sizeof(struct sab82532),
-							 GFP_KERNEL);
-			if (!sab) {
-				printk("sab82532: can't alloc sab struct\n");
-				break;
-			}
-		}
-		memset(sab, 0, sizeof(struct sab82532));
-
-		sab->regs = ioremap(regs + offset, sizeof(union sab82532_async_regs));
-		sab->irq = edev->irqs[0];
-		sab->line = 1 - i;
-		sab->xmit_fifo_size = 32;
-		sab->recv_fifo_size = 32;
-
-		writeb(SAB82532_IPC_IC_ACT_LOW, &sab->regs->w.ipc);
-
-		sab->next = sab82532_chain;
-		sab82532_chain = sab;
-
-		offset -= sizeof(union sab82532_async_regs);
-	}
-	return 0;
-}
-
-#ifndef MODULE
-static void __init sab82532_kgdb_hook(int line)
-{
-	prom_printf("sab82532: kgdb support is not implemented, yet\n");
-	prom_halt();
-}
-#endif
-
-static inline void __init show_serial_version(void)
-{
-	char *revision = "$Revision: 1.66 $";
-	char *version, *p;
-
-	version = strchr(revision, ' ');
-	strcpy(serial_version, ++version);
-	p = strchr(serial_version, ' ');
-	*p = '\0';
-	printk("SAB82532 serial driver version %s\n", serial_version);
-}
-
-extern int su_num_ports;
-
-/*
- * The serial driver boot-time initialization code!
- */
-int __init sab82532_init(void)
-{
-	struct sab82532 *info;
-	int i;
-
-	if (!sab82532_chain)
-		get_sab82532(0);
-	if (!sab82532_chain)
-		return -ENODEV;
-
-	init_bh(SERIAL_BH, do_serial_bh);
-
-	show_serial_version();
-
-	/* Initialize the tty_driver structure */
-	memset(&serial_driver, 0, sizeof(struct tty_driver));
-	serial_driver.magic = TTY_DRIVER_MAGIC;
-	serial_driver.driver_name = "serial";
-#ifdef CONFIG_DEVFS_FS
-	serial_driver.name = "tts/%d";
-#else
-	serial_driver.name = "ttyS";
-#endif
-	serial_driver.major = TTY_MAJOR;
-	serial_driver.minor_start = 64 + su_num_ports;
-	serial_driver.num = NR_PORTS;
-	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
-	serial_driver.subtype = SERIAL_TYPE_NORMAL;
-	serial_driver.init_termios = tty_std_termios;
-	serial_driver.init_termios.c_cflag =
-		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	serial_driver.flags = TTY_DRIVER_REAL_RAW;
-	serial_driver.refcount = &sab82532_refcount;
-	serial_driver.table = sab82532_table;
-	serial_driver.termios = sab82532_termios;
-	serial_driver.termios_locked = sab82532_termios_locked;
-
-	serial_driver.open = sab82532_open;
-	serial_driver.close = sab82532_close;
-	serial_driver.write = sab82532_write;
-	serial_driver.put_char = sab82532_put_char;
-	serial_driver.flush_chars = sab82532_flush_chars;
-	serial_driver.write_room = sab82532_write_room;
-	serial_driver.chars_in_buffer = sab82532_chars_in_buffer;
-	serial_driver.flush_buffer = sab82532_flush_buffer;
-	serial_driver.ioctl = sab82532_ioctl;
-	serial_driver.throttle = sab82532_throttle;
-	serial_driver.unthrottle = sab82532_unthrottle;
-	serial_driver.send_xchar = sab82532_send_xchar;
-	serial_driver.set_termios = sab82532_set_termios;
-	serial_driver.stop = sab82532_stop;
-	serial_driver.start = sab82532_start;
-	serial_driver.hangup = sab82532_hangup;
-	serial_driver.break_ctl = sab82532_break;
-	serial_driver.wait_until_sent = sab82532_wait_until_sent;
-	serial_driver.read_proc = sab82532_read_proc;
-
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-#ifdef CONFIG_DEVFS_FS
-	callout_driver.name = "cua/%d";
-#else
-	callout_driver.name = "cua";
-#endif
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-
-	if (tty_register_driver(&serial_driver))
-		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
-
-	for (info = sab82532_chain, i = 0; info; info = info->next, i++) {
-		info->magic = SERIAL_MAGIC;
-
-		info->type = readb(&info->regs->r.vstr) & 0x0f;
-		writeb(~((1 << 1) | (1 << 2) | (1 << 4)), &info->regs->w.pcr);
-		writeb(0xff, &info->regs->w.pim);
-		if (info->line == 0) {
-			info->pvr_dsr_bit = (1 << 0);
-			info->pvr_dtr_bit = (1 << 1);
-		} else {
-			info->pvr_dsr_bit = (1 << 3);
-			info->pvr_dtr_bit = (1 << 2);
-		}
-		writeb((1 << 1) | (1 << 2) | (1 << 4), &info->regs->w.pvr);
-		writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_FRTS, &info->regs->rw.mode);
-		writeb(readb(&info->regs->rw.mode) | SAB82532_MODE_RTS, &info->regs->rw.mode);
-
-		info->custom_divisor = 16;
-		info->close_delay = 5*HZ/10;
-		info->closing_wait = 30*HZ;
-		info->tec_timeout = SAB82532_MAX_TEC_TIMEOUT;
-		info->cec_timeout = SAB82532_MAX_CEC_TIMEOUT;
-		info->x_char = 0;
-		info->event = 0;	
-		info->blocked_open = 0;
-		info->tqueue.routine = do_softint;
-		info->tqueue.data = info;
-		info->tqueue_hangup.routine = do_serial_hangup;
-		info->tqueue_hangup.data = info;
-		info->callout_termios = callout_driver.init_termios;
-		info->normal_termios = serial_driver.init_termios;
-		init_waitqueue_head(&info->open_wait);
-		init_waitqueue_head(&info->close_wait);
-		init_waitqueue_head(&info->delta_msr_wait);
-		info->icount.cts = info->icount.dsr = 
-			info->icount.rng = info->icount.dcd = 0;
-		info->icount.rx = info->icount.tx = 0;
-		info->icount.frame = info->icount.parity = 0;
-		info->icount.overrun = info->icount.brk = 0;
-
-		if (!(info->line & 0x01)) {
-			if (request_irq(info->irq, sab82532_interrupt, SA_SHIRQ,
-					"serial(sab82532)", info)) {
-				printk("sab82532: can't get IRQ %x\n",
-				       info->irq);
-				panic("sab82532 initialization failed");
-			}
-		}
-	
-		printk(KERN_INFO
-		       "ttyS%02d at 0x%lx (irq = %s) is a SAB82532 %s\n",
-		       info->line + su_num_ports, (unsigned long)info->regs,
-		       __irq_itoa(info->irq), sab82532_version[info->type]);
-	}
-
-#ifdef SERIAL_LOG_DEVICE
-	dprint_init(SERIAL_LOG_DEVICE);
-#endif
-	return 0;
-}
-
-int __init sab82532_probe(void)
-{
-	int node, enode, snode;
-	char model[32];
-	int len;
-
-        node = prom_getchild(prom_root_node);
-	node = prom_searchsiblings(node, "pci");
-
-	/*
-	 * Check for SUNW,sabre on Ultra 5/10/AXi.
-	 */
-	len = prom_getproperty(node, "model", model, sizeof(model));
-	if ((len > 0) && !strncmp(model, "SUNW,sabre", len)) {
-        	node = prom_getchild(node);
-		node = prom_searchsiblings(node, "pci");
-	}
-
-	/*
-	 * For each PCI bus...
-	 */
-	while (node) {
-		enode = prom_getchild(node);
-		enode = prom_searchsiblings(enode, "ebus");
-
-		/*
-		 * For each EBus on this PCI...
-		 */
-		while (enode) {
-			int child;
-
-			child = prom_getchild(enode);
-			snode = prom_searchsiblings(child, "se");
-			if (snode)
-				goto found;
-
-			snode = prom_searchsiblings(child, "serial");
-			if (snode) {
-				char compat[32];
-				int clen;
-
-				clen = prom_getproperty(snode, "compatible",
-							compat, sizeof(compat));
-				if (clen > 0) {
-					if (strncmp(compat, "sab82532", 8) == 0)
-						goto found;
-				}
-			}
-
-			enode = prom_getsibling(enode);
-			enode = prom_searchsiblings(enode, "ebus");
-		}
-		node = prom_getsibling(node);
-		node = prom_searchsiblings(node, "pci");
-	}
-	return -ENODEV;
-
-found:
-#ifdef CONFIG_SERIAL_CONSOLE
-	sunserial_setinitfunc(sab82532_console_init);
-#endif
-#ifndef MODULE
-	sunserial_setinitfunc(sab82532_init);
-	rs_ops.rs_kgdb_hook = sab82532_kgdb_hook;
-#endif
-	return 0;
-}
-
-#ifdef MODULE
-MODULE_LICENSE("GPL");
-
-int init_module(void)
-{
-	if (get_sab82532(0))
-		return -ENODEV;
-
-	return sab82532_init();
-}
-
-void cleanup_module(void) 
-{
-	struct sab82532 *sab;
-	unsigned long flags;
-	int e1, e2;
-
-	/* printk("Unloading %s: version %s\n", serial_name, serial_version); */
-	save_flags(flags);
-	cli();
-        remove_bh(SERIAL_BH);
-	if ((e1 = tty_unregister_driver(&serial_driver)))
-		printk("SERIAL: failed to unregister serial driver (%d)\n",
-		       e1);
-	if ((e2 = tty_unregister_driver(&callout_driver)))
-		printk("SERIAL: failed to unregister callout driver (%d)\n", 
-		       e2);
-	restore_flags(flags);
-
-	if (tmp_buf) {
-		free_page((unsigned long) tmp_buf);
-		tmp_buf = NULL;
-	}
-	for (sab = sab82532_chain; sab; sab = sab->next) {
-		if (!(sab->line & 0x01))
-			free_irq(sab->irq, sab);
-		iounmap(sab->regs);
-	}
-}
-#endif /* MODULE */
-
-#ifdef CONFIG_SERIAL_CONSOLE
-static void
-batten_down_hatches(struct sab82532 *info)
-{
-	unsigned char saved_rfc, tmp;
-
-	if (!stop_a_enabled)
-		return;
-
-	/* If we are doing kadb, we call the debugger
-	 * else we just drop into the boot monitor.
-	 * Note that we must flush the user windows
-	 * first before giving up control.
-	 */
-	printk("\n");
-	flush_user_windows();
-
-	/*
-	 * Set FIFO to single character mode.
-	 */
-	saved_rfc = readb(&info->regs->r.rfc);
-	tmp = readb(&info->regs->rw.rfc);
-	tmp &= ~(SAB82532_RFC_RFDF);
-	writeb(tmp, &info->regs->rw.rfc);
-	sab82532_cec_wait(info);
-	writeb(SAB82532_CMDR_RRES, &info->regs->w.cmdr);
-
-#ifndef __sparc_v9__
-	if ((((unsigned long)linux_dbvec) >= DEBUG_FIRSTVADDR) &&
-	    (((unsigned long)linux_dbvec) <= DEBUG_LASTVADDR))
-		sp_enter_debugger();
-	else
-#endif
-		prom_cmdline();
-
-	/*
-	 * Reset FIFO to character + status mode.
-	 */
-	writeb(saved_rfc, &info->regs->w.rfc);
-	sab82532_cec_wait(info);
-	writeb(SAB82532_CMDR_RRES, &info->regs->w.cmdr);
-}
-
-static __inline__ void
-sab82532_console_putchar(struct sab82532 *info, char c)
-{
-	unsigned long flags;
-
-	save_flags(flags); cli();
-	sab82532_tec_wait(info);
-	writeb(c, &info->regs->w.tic);
-	restore_flags(flags);
-}
-
-static void
-sab82532_console_write(struct console *con, const char *s, unsigned n)
-{
-	struct sab82532 *info;
-	int i;
-
-	info = sab82532_chain;
-	for (i = con->index; i; i--) {
-		info = info->next;
-		if (!info)
-			return;
-	}
-
-	for (i = 0; i < n; i++) {
-		if (*s == '\n')
-			sab82532_console_putchar(info, '\r');
-		sab82532_console_putchar(info, *s++);
-	}
-	sab82532_tec_wait(info);
-}
-
-static kdev_t
-sab82532_console_device(struct console *con)
-{
-	return mk_kdev(TTY_MAJOR, 64 + con->index);
-}
-
-static int
-sab82532_console_setup(struct console *con, char *options)
-{
-	static struct tty_struct c_tty;
-	static struct termios c_termios;
-	struct sab82532 *info;
-	tcflag_t	cflag;
-	int		i;
-
-	info = sab82532_chain;
-	for (i = con->index; i; i--) {
-		info = info->next;
-		if (!info)
-			return -ENODEV;
-	}
-	info->is_console = 1;
-
-	/*
-	 * Initialize the hardware
-	 */
-	sab82532_init_line(info);
-
-	/*
-	 * Finally, enable interrupts
-	 */
-	info->interrupt_mask0 = SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
-				SAB82532_IMR0_PLLA | SAB82532_IMR0_CDSC;
-	writeb(info->interrupt_mask0, &info->regs->w.imr0);
-	info->interrupt_mask1 = SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |
-				SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |
-				SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
-				SAB82532_IMR1_XPR;
-	writeb(info->interrupt_mask1, &info->regs->w.imr1);
-
-	printk("Console: ttyS%d (SAB82532)\n", info->line);
-
-	sunserial_console_termios(con);
-	cflag = con->cflag;
-
-	/*
-	 * Fake up the tty and tty->termios structures so we can use
-	 * change_speed (and eliminate a lot of duplicate code).
-	 */
-	if (!info->tty) {
-		memset(&c_tty, 0, sizeof(c_tty));
-		info->tty = &c_tty;
-	}
-	if (!info->tty->termios) {
-		memset(&c_termios, 0, sizeof(c_termios));
-		info->tty->termios = &c_termios;
-	}
-	info->tty->termios->c_cflag = con->cflag;
-
-	change_speed(info);
-
-	/* Now take out the pointers to static structures if necessary */
-	if (info->tty->termios == &c_termios)
-		info->tty->termios = 0;
-	if (info->tty == &c_tty)
-		info->tty = 0;
-	
-	return 0;
-}
-
-static struct console sab82532_console = {
-	name:		"ttyS",
-	write:		sab82532_console_write,
-	device:		sab82532_console_device,
-	setup:		sab82532_console_setup,
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
-};
-
-int __init sab82532_console_init(void)
-{
-	extern int con_is_present(void);
-	extern int su_console_registered;
-
-	if (con_is_present() || su_console_registered)
-		return 0;
-
-	if (!sab82532_chain) {
-		prom_printf("sab82532_console_setup: can't get SAB82532 chain");
-		prom_halt();
-	}
-
-	sab82532_console.index = serial_console - 1;
-	register_console(&sab82532_console);
-	return 0;
-}
-
-#ifdef SERIAL_LOG_DEVICE
-
-static int serial_log_device = 0;
-
-static void
-dprint_init(int tty)
-{
-	serial_console = tty + 1;
-	sab82532_console.index = tty;
-	sab82532_console_setup(&sab82532_console, "");
-	serial_console = 0;
-	serial_log_device = tty + 1;
-}
-
-int
-dprintf(const char *fmt, ...)
-{
-	static char buffer[4096];
-	va_list args;
-	int i;
-
-	if (!serial_log_device)
-		return 0;
-
-	va_start(args, fmt);
-	i = vsprintf(buffer, fmt, args);
-	va_end(args);
-	sab82532_console.write(&sab82532_console, buffer, i);
-	return i;
-}
-#endif /* SERIAL_LOG_DEVICE */
-#endif /* CONFIG_SERIAL_CONSOLE */
diff -Nru a/drivers/sbus/char/su.c b/drivers/sbus/char/su.c
--- a/drivers/sbus/char/su.c	Sat Aug 10 18:42:21 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,3010 +0,0 @@
-/* $Id: su.c,v 1.55 2002/01/08 16:00:16 davem Exp $
- * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
- *
- * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
- * Copyright (C) 1998-1999  Pete Zaitcev   (zaitcev@yahoo.com)
- *
- * This is mainly a variation of drivers/char/serial.c,
- * credits go to authors mentioned therein.
- *
- * Fixed to use tty_get_baud_rate().
- *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
- */
-
-/*
- * Configuration section.
- */
-#undef SERIAL_PARANOIA_CHECK
-#define CONFIG_SERIAL_NOPAUSE_IO	/* Unused on sparc */
-#define SERIAL_DO_RESTART
-
-/* Set of debugging defines */
-
-#undef SERIAL_DEBUG_INTR
-#undef SERIAL_DEBUG_OPEN
-#undef SERIAL_DEBUG_FLOW
-#undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-#undef SERIAL_DEBUG_THROTTLE
-
-#define RS_ISR_PASS_LIMIT 256
-
-/*
- * 0x20 is sun4m thing, Dave Redman heritage.
- * See arch/sparc/kernel/irq.c.
- */
-#define IRQ_4M(n)	((n)|0x20)
-
-#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
-#define DBG_CNT(s)							\
-do {									\
-	printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n",		\
-	       kdevname(tty->device), (info->flags), serial_refcount,	\
-	       info->count,tty->count,s);				\
-} while (0)
-#else
-#define DBG_CNT(s)
-#endif
-
-/*
- * End of serial driver configuration section.
- */
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/delay.h>
-#ifdef CONFIG_SERIAL_CONSOLE
-#include <linux/console.h>
-#include <linux/major.h>
-#endif
-#include <linux/sysrq.h>
-
-#include <asm/system.h>
-#include <asm/oplib.h>
-#include <asm/io.h>
-#include <asm/ebus.h>
-#ifdef CONFIG_SPARC64
-#include <asm/isa.h>
-#endif
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/bitops.h>
-
-#include "sunserial.h"
-#include "sunkbd.h"
-#include "sunmouse.h"
-
-/* We are on a NS PC87303 clocked with 24.0 MHz, which results
- * in a UART clock of 1.8462 MHz.
- */
-#define BAUD_BASE	(1846200 / 16)
-
-#ifdef CONFIG_SERIAL_CONSOLE
-extern int serial_console;
-static struct console sercons;
-int su_serial_console_init(void);
-#endif
-
-enum su_type { SU_PORT_NONE, SU_PORT_MS, SU_PORT_KBD, SU_PORT_PORT };
-static char *su_typev[] = { "???", "mouse", "kbd", "serial" };
-
-#define SU_PROPSIZE	128
-
-/*
- * serial.c saves memory when it allocates async_info upon first open.
- * We have parts of state structure together because we do call startup
- * for keyboard and mouse.
- */
-struct su_struct {
-	int		 magic;
-	unsigned long	 port;
-	int		 baud_base;
-	int		 type;		/* Hardware type: e.g. 16550 */
-	int		 irq;
-	int		 flags;
-	int		 line;
-	int		 cflag;
-
-	enum su_type	 port_type;	/* Hookup type: e.g. mouse */
-	int		 is_console;
-	int		 port_node;
-
-	char		 name[16];
-
-	int		 xmit_fifo_size;
-	int		 custom_divisor;
-	unsigned short	 close_delay;
-	unsigned short	 closing_wait;	/* time to wait before closing */
-
-	struct tty_struct 	*tty;
-	int			read_status_mask;
-	int			ignore_status_mask;
-	int			timeout;
-	int			quot;
-	int			x_char;	/* xon/xoff character */
-	int			IER; 	/* Interrupt Enable Register */
-	int			MCR; 	/* Modem control register */
-	unsigned long		event;
-	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
-	unsigned char 		*xmit_buf;
-	int			xmit_head;
-	int			xmit_tail;
-	int			xmit_cnt;
-	struct tq_struct	tqueue;
-	wait_queue_head_t	open_wait;
-	wait_queue_head_t	close_wait;
-	wait_queue_head_t	delta_msr_wait;
-
-	int			count;
-	struct async_icount	icount;
-	struct termios		normal_termios, callout_termios;
-	unsigned long		last_active;	/* For async_struct, to be */
-};
-
-/*
- * Scan status structure.
- * "prop" is a local variable but it eats stack to keep it in each
- * stack frame of a recursive procedure.
- */
-struct su_probe_scan {
-	int msnode, kbnode;	/* PROM nodes for mouse and keyboard */
-	int msx, kbx;		/* minors for mouse and keyboard */
-	int devices;		/* scan index */
-	char prop[SU_PROPSIZE];
-};
-
-static char *serial_name = "PCIO serial driver";
-static char serial_version[16];
-
-static DECLARE_TASK_QUEUE(tq_serial);
-
-static struct tty_driver serial_driver, callout_driver;
-static int serial_refcount;
-
-/* number of characters left in xmit buffer before we ask for more */
-#define WAKEUP_CHARS 256
-
-static void autoconfig(struct su_struct *info);
-static void change_speed(struct su_struct *info, struct termios *old);
-static void su_wait_until_sent(struct tty_struct *tty, int timeout);
-
-/*
- * Here we define the default xmit fifo size used for each type of
- * UART
- */
-static struct serial_uart_config uart_config[] = {
-	{ "unknown", 1, 0 }, 
-	{ "8250", 1, 0 }, 
-	{ "16450", 1, 0 }, 
-	{ "16550", 1, 0 }, 
-	{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO }, 
-	{ "cirrus", 1, 0 }, 
-	{ "ST16650", 1, UART_CLEAR_FIFO |UART_STARTECH }, 
-	{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
-		  UART_STARTECH }, 
-	{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
-	{ 0, 0}
-};
-
-
-#define NR_PORTS	4
-
-static struct su_struct su_table[NR_PORTS];
-static struct tty_struct *serial_table[NR_PORTS];
-static struct termios *serial_termios[NR_PORTS];
-static struct termios *serial_termios_locked[NR_PORTS];
-
-#ifndef MIN
-#define MIN(a,b)	((a) < (b) ? (a) : (b))
-#endif
-
-/*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the copy_from_user blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char *tmp_buf;
-static DECLARE_MUTEX(tmp_buf_sem);
-
-static inline int serial_paranoia_check(struct su_struct *info,
-					kdev_t device, const char *routine)
-{
-#ifdef SERIAL_PARANOIA_CHECK
-	static const char *badmagic = KERN_WARNING
-		"Warning: bad magic number for serial struct (%s) in %s\n";
-	static const char *badinfo = KERN_WARNING
-		"Warning: null su_struct for (%s) in %s\n";
-
-	if (!info) {
-		printk(badinfo, kdevname(device), routine);
-		return 1;
-	}
-	if (info->magic != SERIAL_MAGIC) {
-		printk(badmagic, kdevname(device), routine);
-		return 1;
-	}
-#endif
-	return 0;
-}
-
-static inline
-unsigned int su_inb(struct su_struct *info, unsigned long offset)
-{
-	return inb(info->port + offset);
-}
-
-static inline void
-su_outb(struct su_struct *info, unsigned long offset, int value)
-{
-#ifndef __sparc_v9__
-	/*
-	 * MrCoffee has weird schematics: IRQ4 & P10(?) pins of SuperIO are
-	 * connected with a gate then go to SlavIO. When IRQ4 goes tristated
-	 * gate outputs a logical one. Since we use level triggered interrupts
-	 * we have lockup and watchdog reset. We cannot mask IRQ because
-	 * keyboard shares IRQ with us (Word has it as Bob Smelik's design).
-	 * This problem is similar to what Alpha people suffer, see serial.c.
-	 */
-	if (offset == UART_MCR) value |= UART_MCR_OUT2;
-#endif
-	outb(value, info->port + offset);
-}
-
-#define serial_in(info, off)		su_inb(info, off)
-#define serial_inp(info, off)		su_inb(info, off)
-#define serial_out(info, off, val)	su_outb(info, off, val)
-#define serial_outp(info, off, val)	su_outb(info, off, val)
-
-/*
- * ------------------------------------------------------------
- * su_stop() and su_start()
- *
- * This routines are called before setting or resetting tty->stopped.
- * They enable or disable transmitter interrupts, as necessary.
- * ------------------------------------------------------------
- */
-static void su_stop(struct tty_struct *tty)
-{
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "su_stop"))
-		return;
-
-	save_flags(flags); cli();
-	if (info->IER & UART_IER_THRI) {
-		info->IER &= ~UART_IER_THRI;
-		serial_out(info, UART_IER, info->IER);
-	}
-	restore_flags(flags);
-}
-
-static void su_start(struct tty_struct *tty)
-{
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-	unsigned long flags;
-	
-	if (serial_paranoia_check(info, tty->device, "su_start"))
-		return;
-
-	save_flags(flags); cli();
-	if (info->xmit_cnt && info->xmit_buf && !(info->IER & UART_IER_THRI)) {
-		info->IER |= UART_IER_THRI;
-		serial_out(info, UART_IER, info->IER);
-	}
-	restore_flags(flags);
-}
-
-/*
- * ----------------------------------------------------------------------
- *
- * Here starts the interrupt handling routines.  All of the following
- * subroutines are declared as inline and are folded into
- * su_interrupt().  They were separated out for readability's sake.
- *
- * Note: rs_interrupt() is a "fast" interrupt, which means that it
- * runs with interrupts turned off.  People who may want to modify
- * rs_interrupt() should try to keep the interrupt handler as fast as
- * possible.  After you are done making modifications, it is not a bad
- * idea to do:
- * 
- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
- *
- * and look at the resulting assemble code in serial.s.
- *
- * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
- */
-
-/*
- * This routine is used by the interrupt handler to schedule
- * processing in the software interrupt portion of the driver.
- */
-static void
-su_sched_event(struct su_struct *info, int event)
-{
-	info->event |= 1 << event;
-	queue_task(&info->tqueue, &tq_serial);
-	mark_bh(SERIAL_BH);
-}
-
-static void
-receive_kbd_ms_chars(struct su_struct *info, struct pt_regs *regs, int is_brk)
-{
-	unsigned char status = 0;
-	unsigned char ch;
-
-	do {
-		ch = serial_inp(info, UART_RX);
-		if (info->port_type == SU_PORT_KBD) {
-			if (ch == SUNKBD_RESET) {
-                        	l1a_state.kbd_id = 1;
-                        	l1a_state.l1_down = 0;
-                	} else if (l1a_state.kbd_id) {
-                        	l1a_state.kbd_id = 0;
-                	} else if (ch == SUNKBD_L1) {
-                        	l1a_state.l1_down = 1;
-                	} else if (ch == (SUNKBD_L1|SUNKBD_UP)) {
-                        	l1a_state.l1_down = 0;
-                	} else if (ch == SUNKBD_A && l1a_state.l1_down) {
-                        	/* whee... */
-                        	batten_down_hatches();
-                        	/* Continue execution... */
-                        	l1a_state.l1_down = 0;
-                        	l1a_state.kbd_id = 0;
-                        	return;
-                	}
-                	sunkbd_inchar(ch, regs);
-		} else {
-			sun_mouse_inbyte(ch, is_brk);
-		}
-
-		status = su_inb(info, UART_LSR);
-	} while (status & UART_LSR_DR);
-}
-
-static void
-receive_serial_chars(struct su_struct *info, int *status, struct pt_regs *regs)
-{
-	struct tty_struct *tty = info->tty;
-	unsigned char ch;
-	int ignored = 0, saw_console_brk = 0;
-	struct	async_icount *icount;
-
-	icount = &info->icount;
-	do {
-		ch = serial_inp(info, UART_RX);
-		if (info->is_console &&
-		    (ch == 0 || (*status &UART_LSR_BI)))
-			saw_console_brk = 1;
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-			break;
-		*tty->flip.char_buf_ptr = ch;
-		icount->rx++;
-
-#ifdef SERIAL_DEBUG_INTR
-		printk("D%02x:%02x.", ch, *status);
-#endif
-		*tty->flip.flag_buf_ptr = 0;
-		if (*status & (UART_LSR_BI | UART_LSR_PE |
-			       UART_LSR_FE | UART_LSR_OE)) {
-			/*
-			 * For statistics only
-			 */
-			if (*status & UART_LSR_BI) {
-				*status &= ~(UART_LSR_FE | UART_LSR_PE);
-				icount->brk++;
-			} else if (*status & UART_LSR_PE)
-				icount->parity++;
-			else if (*status & UART_LSR_FE)
-				icount->frame++;
-			if (*status & UART_LSR_OE)
-				icount->overrun++;
-
-			/*
-			 * Now check to see if character should be
-			 * ignored, and mask off conditions which
-			 * should be ignored.
-			 */
-			if (*status & info->ignore_status_mask) {
-				if (++ignored > 100) {
-#ifdef SERIAL_DEBUG_INTR
-					printk("ign100..");
-#endif
-					break;
-				}
-				goto ignore_char;
-			}
-			*status &= info->read_status_mask;
-
-			if (*status & (UART_LSR_BI)) {
-#ifdef SERIAL_DEBUG_INTR
-				printk("handling break....");
-#endif
-				*tty->flip.flag_buf_ptr = TTY_BREAK;
-				if (info->flags & ASYNC_SAK)
-					do_SAK(tty);
-			} else if (*status & UART_LSR_PE)
-				*tty->flip.flag_buf_ptr = TTY_PARITY;
-			else if (*status & UART_LSR_FE)
-				*tty->flip.flag_buf_ptr = TTY_FRAME;
-			if (*status & UART_LSR_OE) {
-				/*
-				 * Overrun is special, since it's
-				 * reported immediately, and doesn't
-				 * affect the current character
-				 */
-				if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-					tty->flip.count++;
-					tty->flip.flag_buf_ptr++;
-					tty->flip.char_buf_ptr++;
-					*tty->flip.flag_buf_ptr = TTY_OVERRUN;
-				}
-			}
-		}
-		tty->flip.flag_buf_ptr++;
-		tty->flip.char_buf_ptr++;
-		tty->flip.count++;
-	ignore_char:
-		*status = serial_inp(info, UART_LSR);
-	} while (*status & UART_LSR_DR);
-#ifdef SERIAL_DEBUG_INTR
-	printk("E%02x.R%d", *status, tty->flip.count);
-#endif
-	tty_flip_buffer_push(tty);
-	if (saw_console_brk != 0)
-		batten_down_hatches();
-}
-
-static void
-transmit_chars(struct su_struct *info, int *intr_done)
-{
-	int count;
-
-	if (info->x_char) {
-		serial_outp(info, UART_TX, info->x_char);
-		info->icount.tx++;
-		info->x_char = 0;
-		if (intr_done)
-			*intr_done = 0;
-		return;
-	}
-	if ((info->xmit_cnt <= 0) || info->tty->stopped ||
-	    info->tty->hw_stopped) {
-		info->IER &= ~UART_IER_THRI;
-		serial_out(info, UART_IER, info->IER);
-		return;
-	}
-
-	count = info->xmit_fifo_size;
-	do {
-		serial_out(info, UART_TX, info->xmit_buf[info->xmit_tail++]);
-		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
-		info->icount.tx++;
-		if (--info->xmit_cnt <= 0)
-			break;
-	} while (--count > 0);
-	
-	if (info->xmit_cnt < WAKEUP_CHARS)
-		su_sched_event(info, RS_EVENT_WRITE_WAKEUP);
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("T%d...", info->xmit_cnt);
-#endif
-	if (intr_done)
-		*intr_done = 0;
-
-	if (info->xmit_cnt <= 0) {
-		info->IER &= ~UART_IER_THRI;
-		serial_out(info, UART_IER, info->IER);
-	}
-}
-
-static void
-check_modem_status(struct su_struct *info)
-{
-	int	status;
-	struct	async_icount *icount;
-
-	status = serial_in(info, UART_MSR);
-
-	if (status & UART_MSR_ANY_DELTA) {
-		icount = &info->icount;
-		/* update input line counters */
-		if (status & UART_MSR_TERI)
-			icount->rng++;
-		if (status & UART_MSR_DDSR)
-			icount->dsr++;
-		if (status & UART_MSR_DDCD) {
-			icount->dcd++;
-#ifdef CONFIG_HARD_PPS
-			if ((info->flags & ASYNC_HARDPPS_CD) &&
-			    (status & UART_MSR_DCD))
-				hardpps();
-#endif
-		}
-		if (status & UART_MSR_DCTS)
-			icount->cts++;
-		wake_up_interruptible(&info->delta_msr_wait);
-	}
-
-	if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
-#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
-		printk("ttys%d CD now %s...", info->line,
-		       (status & UART_MSR_DCD) ? "on" : "off");
-#endif		
-		if (status & UART_MSR_DCD)
-			wake_up_interruptible(&info->open_wait);
-		else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-			   (info->flags & ASYNC_CALLOUT_NOHUP))) {
-#ifdef SERIAL_DEBUG_OPEN
-			printk("doing serial hangup...");
-#endif
-			if (info->tty)
-				tty_hangup(info->tty);
-	}
-	}
-	if (info->flags & ASYNC_CTS_FLOW) {
-		if (info->tty->hw_stopped) {
-			if (status & UART_MSR_CTS) {
-#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
-				printk("CTS tx start...");
-#endif
-				info->tty->hw_stopped = 0;
-				info->IER |= UART_IER_THRI;
-				serial_out(info, UART_IER, info->IER);
-				su_sched_event(info, RS_EVENT_WRITE_WAKEUP);
-				return;
-			}
-		} else {
-			if (!(status & UART_MSR_CTS)) {
-#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
-				printk("CTS tx stop...");
-#endif
-				info->tty->hw_stopped = 1;
-				info->IER &= ~UART_IER_THRI;
-				serial_out(info, UART_IER, info->IER);
-			}
-		}
-	}
-}
-
-/*
- * This is the kbd/mouse serial driver's interrupt routine
- */
-static void
-su_kbd_ms_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-	struct su_struct *info = (struct su_struct *)dev_id;
-	unsigned char status;
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("su_kbd_ms_interrupt(%s)...", __irq_itoa(irq));
-#endif
-	if (!info)
-		return;
-
-	if (serial_in(info, UART_IIR) & UART_IIR_NO_INT)
-		return;
-
-	status = serial_inp(info, UART_LSR);
-#ifdef SERIAL_DEBUG_INTR
-	printk("status = %x...", status);
-#endif
-	if ((status & UART_LSR_DR) || (status & UART_LSR_BI))
-		receive_kbd_ms_chars(info, regs,
-				     (status & UART_LSR_BI) != 0);
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("end.\n");
-#endif
-}
-
-/*
- * This is the serial driver's generic interrupt routine
- */
-static void
-su_serial_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-	int status;
-	struct su_struct *info;
-	int pass_counter = 0;
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("su_serial_interrupt(%s)...", __irq_itoa(irq));
-#endif
-	info = (struct su_struct *)dev_id;
-	if (!info || !info->tty) {
-#ifdef SERIAL_DEBUG_INTR
-		printk("strain\n");
-#endif
-		return;
-	}
-
-	do {
-		status = serial_inp(info, UART_LSR);
-#ifdef SERIAL_DEBUG_INTR
-		printk("status = %x...", status);
-#endif
-		if (status & UART_LSR_DR)
-			receive_serial_chars(info, &status, regs);
-		check_modem_status(info);
-		if (status & UART_LSR_THRE)
-			transmit_chars(info, 0);
-
-		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
-#ifdef SERIAL_DEBUG_INTR
-			printk("rs loop break");
-#endif
-			break; 	/* Prevent infinite loops */
-		}
-	} while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT));
-
-	info->last_active = jiffies;
-
-#ifdef SERIAL_DEBUG_INTR
-	printk("end.\n");
-#endif
-}
-
-/*
- * -------------------------------------------------------------------
- * Here ends the serial interrupt routines.
- * -------------------------------------------------------------------
- */
-
-/*
- * This routine is used to handle the "bottom half" processing for the
- * serial driver, known also the "software interrupt" processing.
- * This processing is done at the kernel interrupt level, after the
- * su_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
- * is where time-consuming activities which can not be done in the
- * interrupt driver proper are done; the interrupt driver schedules
- * them using su_sched_event(), and they get done here.
- */
-static void do_serial_bh(void)
-{
-	run_task_queue(&tq_serial);
-}
-
-static void do_softint(void *private_)
-{
-	struct su_struct	*info = (struct su_struct *) private_;
-	struct tty_struct	*tty;
-
-	tty = info->tty;
-	if (!tty)
-		return;
-
-	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
-	}
-}
-
-/*
- * ---------------------------------------------------------------
- * Low level utility subroutines for the serial driver:  routines to
- * figure out the appropriate timeout for an interrupt chain, routines
- * to initialize and startup a serial port, and routines to shutdown a
- * serial port.  Useful stuff like that.
- * ---------------------------------------------------------------
- */
-
-static int
-startup(struct su_struct *info)
-{
-	unsigned long flags;
-	int	retval=0;
-	unsigned long page;
-
-	save_flags(flags);
-	if (info->tty) {
-		page = get_free_page(GFP_KERNEL);
-		if (!page)
-			return -ENOMEM;
-
-		cli();
-
-		if (info->flags & ASYNC_INITIALIZED) {
-			free_page(page);
-			goto errout;
-		}
-
-		if (info->port == 0 || info->type == PORT_UNKNOWN) {
-			set_bit(TTY_IO_ERROR, &info->tty->flags);
-			free_page(page);
-			goto errout;
-		}
-		if (info->xmit_buf)
-			free_page(page);
-		else
-			info->xmit_buf = (unsigned char *) page;
-	}
-	cli();
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("starting up ttys%d (irq %s)...", info->line,
-	       __irq_itoa(info->irq));
-#endif
-
-	if (uart_config[info->type].flags & UART_STARTECH) {
-		/* Wake up UART */
-		serial_outp(info, UART_LCR, 0xBF);
-		serial_outp(info, UART_EFR, UART_EFR_ECB);
-		serial_outp(info, UART_IER, 0);
-		serial_outp(info, UART_EFR, 0);
-		serial_outp(info, UART_LCR, 0);
-	}
-
-	if (info->type == PORT_16750) {
-		/* Wake up UART */
-		serial_outp(info, UART_IER, 0);
-	}
-
-	/*
-	 * Clear the FIFO buffers and disable them
-	 * (they will be reenabled in change_speed())
-	 */
-	if (uart_config[info->type].flags & UART_CLEAR_FIFO)
-		serial_outp(info, UART_FCR, (UART_FCR_CLEAR_RCVR |
-					     UART_FCR_CLEAR_XMIT));
-
-	/*
-	 * At this point there's no way the LSR could still be 0xFF;
-	 * if it is, then bail out, because there's likely no UART
-	 * here.
-	 */
-	if (serial_inp(info, UART_LSR) == 0xff) {
-		if (capable(CAP_SYS_ADMIN)) {
-			if (info->tty)
-				set_bit(TTY_IO_ERROR, &info->tty->flags);
-		} else
-			retval = -ENODEV;
-		goto errout;
-	}
-
-	/*
-	 * Allocate the IRQ if necessary
-	 */
-	if (info->port_type != SU_PORT_PORT) {
-		retval = request_irq(info->irq, su_kbd_ms_interrupt,
-				     SA_SHIRQ, info->name, info);
-	} else {
-		retval = request_irq(info->irq, su_serial_interrupt,
-				     SA_SHIRQ, info->name, info);
-	}
-	if (retval) {
-		if (capable(CAP_SYS_ADMIN)) {
-			if (info->tty)
-				set_bit(TTY_IO_ERROR, &info->tty->flags);
-			retval = 0;
-		}
-		goto errout;
-	}
-
-	/*
-	 * Clear the interrupt registers.
-	 */
-	(void) serial_inp(info, UART_RX);
-	(void) serial_inp(info, UART_IIR);
-	(void) serial_inp(info, UART_MSR);
-
-	/*
-	 * Now, initialize the UART 
-	 */
-	serial_outp(info, UART_LCR, UART_LCR_WLEN8);	/* reset DLAB */
-
-	info->MCR = 0;
-	if (info->tty && info->tty->termios->c_cflag & CBAUD)
-		info->MCR = UART_MCR_DTR | UART_MCR_RTS;
-	if (info->irq != 0)
-		info->MCR |= UART_MCR_OUT2;
-	serial_outp(info, UART_MCR, info->MCR);
-
-	/*
-	 * Finally, enable interrupts
-	 */
-	info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
-	serial_outp(info, UART_IER, info->IER);	/* enable interrupts */
-
-	/*
-	 * And clear the interrupt registers again for luck.
-	 */
-	(void)serial_inp(info, UART_LSR);
-	(void)serial_inp(info, UART_RX);
-	(void)serial_inp(info, UART_IIR);
-	(void)serial_inp(info, UART_MSR);
-
-	if (info->tty)
-		clear_bit(TTY_IO_ERROR, &info->tty->flags);
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-
-	/*
-	 * Set up the tty->alt_speed kludge
-	 */
-	if (info->tty) {
-		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-			info->tty->alt_speed = 57600;
-		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-			info->tty->alt_speed = 115200;
-		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-			info->tty->alt_speed = 230400;
-		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-			info->tty->alt_speed = 460800;
-	}
-
-	/*
-	 * and set the speed of the serial port
-	 */
-	change_speed(info, 0);
-
-	info->flags |= ASYNC_INITIALIZED;
-	restore_flags(flags);
-	return 0;
-
-errout:
-	restore_flags(flags);
-	return retval;
-}
-
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void
-shutdown(struct su_struct *info)
-{
-	unsigned long	flags;
-
-	if (!(info->flags & ASYNC_INITIALIZED))
-		return;
-
-	save_flags(flags); cli(); /* Disable interrupts */
-
-	/*
-	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
-	 * here so the queue might never be waken up
-	 */
-	wake_up_interruptible(&info->delta_msr_wait);
-	
-	/*
-	 * Free the IRQ, if necessary
-	 */
-	free_irq(info->irq, info);
-
-	if (info->xmit_buf) {
-		free_page((unsigned long) info->xmit_buf);
-		info->xmit_buf = 0;
-	}
-
-	info->IER = 0;
-	serial_outp(info, UART_IER, 0x00);	/* disable all intrs */
-	info->MCR &= ~UART_MCR_OUT2;
-
-	/* disable break condition */
-	serial_out(info, UART_LCR, serial_inp(info, UART_LCR) & ~UART_LCR_SBC);
-
-	if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
-		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
-	serial_outp(info, UART_MCR, info->MCR);
-
-	/* disable FIFO's */	
-	serial_outp(info, UART_FCR, (UART_FCR_CLEAR_RCVR |
-				     UART_FCR_CLEAR_XMIT));
-	(void)serial_in(info, UART_RX);    /* read data port to reset things */
-
-	if (info->tty)
-		set_bit(TTY_IO_ERROR, &info->tty->flags);
-
-	if (uart_config[info->type].flags & UART_STARTECH) {
-		/* Arrange to enter sleep mode */
-		serial_outp(info, UART_LCR, 0xBF);
-		serial_outp(info, UART_EFR, UART_EFR_ECB);
-		serial_outp(info, UART_IER, UART_IERX_SLEEP);
-		serial_outp(info, UART_LCR, 0);
-	}
-	if (info->type == PORT_16750) {
-		/* Arrange to enter sleep mode */
-		serial_outp(info, UART_IER, UART_IERX_SLEEP);
-	}
-	info->flags &= ~ASYNC_INITIALIZED;
-	restore_flags(flags);
-}
-
-static int
-su_get_baud_rate(struct su_struct *info)
-{
-	static struct tty_struct c_tty;
-	static struct termios c_termios;
-
-	if (info->tty)
-		return tty_get_baud_rate(info->tty);
-
-	memset(&c_tty, 0, sizeof(c_tty));
-	memset(&c_termios, 0, sizeof(c_termios));
-	c_tty.termios = &c_termios;
-	c_termios.c_cflag = info->cflag;
-
-	return tty_get_baud_rate(&c_tty);
-}
-
-/*
- * This routine is called to set the UART divisor registers to match
- * the specified baud rate for a serial port.
- */
-static void
-change_speed(struct su_struct *info,
-	     struct termios *old_termios)
-{
-	int		quot = 0, baud;
-	unsigned int	cval, fcr = 0;
-	int		bits;
-	unsigned long	flags;
-
-	if (info->port_type == SU_PORT_PORT) {
-		if (!info->tty || !info->tty->termios)
-			return;
-		if (!info->port)
-			return;
-		info->cflag = info->tty->termios->c_cflag;
-	}
-
-	/* byte size and parity */
-	switch (info->cflag & CSIZE) {
-	      case CS5: cval = 0x00; bits = 7; break;
-	      case CS6: cval = 0x01; bits = 8; break;
-	      case CS7: cval = 0x02; bits = 9; break;
-	      case CS8: cval = 0x03; bits = 10; break;
-		/* Never happens, but GCC is too dumb to figure it out */
-	      default:  cval = 0x00; bits = 7; break;
-	}
-	if (info->cflag & CSTOPB) {
-		cval |= 0x04;
-		bits++;
-	}
-	if (info->cflag & PARENB) {
-		cval |= UART_LCR_PARITY;
-		bits++;
-	}
-	if (!(info->cflag & PARODD))
-		cval |= UART_LCR_EPAR;
-#ifdef CMSPAR
-	if (info->cflag & CMSPAR)
-		cval |= UART_LCR_SPAR;
-#endif
-
-	/* Determine divisor based on baud rate */
-	baud = su_get_baud_rate(info);
-	if (baud == 38400 &&
-	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
-		quot = info->custom_divisor;
-	else {
-		if (baud == 134)
-			/* Special case since 134 is really 134.5 */
-			quot = (2 * info->baud_base / 269);
-		else if (baud)
-			quot = info->baud_base / baud;
-	}
-	/* If the quotient is zero refuse the change */
-	if (!quot && old_termios) {
-		info->tty->termios->c_cflag &= ~CBAUD;
-		info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
-		baud = tty_get_baud_rate(info->tty);
-		if (!baud)
-			baud = 9600;
-		if (baud == 38400 &&
-		    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
-			quot = info->custom_divisor;
-		else {
-			if (baud == 134)
-				/* Special case since 134 is really 134.5 */
-				quot = (2*info->baud_base / 269);
-			else if (baud)
-				quot = info->baud_base / baud;
-		}
-	}
-	/* As a last resort, if the quotient is zero, default to 9600 bps */
-	if (!quot)
-		quot = info->baud_base / 9600;
-	info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / info->baud_base);
-	info->timeout += HZ/50;		/* Add .02 seconds of slop */
-
-	/* Set up FIFO's */
-	if (uart_config[info->type].flags & UART_USE_FIFO) {
-		if ((info->baud_base / quot) < 9600)
-			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
-		else
-			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
-	}
-	if (info->type == PORT_16750)
-		fcr |= UART_FCR7_64BYTE;
-
-	/* CTS flow control flag and modem status interrupts */
-	info->IER &= ~UART_IER_MSI;
-	if (info->flags & ASYNC_HARDPPS_CD)
-		info->IER |= UART_IER_MSI;
-	if (info->cflag & CRTSCTS) {
-		info->flags |= ASYNC_CTS_FLOW;
-		info->IER |= UART_IER_MSI;
-	} else
-		info->flags &= ~ASYNC_CTS_FLOW;
-	if (info->cflag & CLOCAL)
-		info->flags &= ~ASYNC_CHECK_CD;
-	else {
-		info->flags |= ASYNC_CHECK_CD;
-		info->IER |= UART_IER_MSI;
-	}
-	serial_out(info, UART_IER, info->IER);
-
-	/*
-	 * Set up parity check flag
-	 */
-	if (info->tty) {
-#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-
-		info->read_status_mask = UART_LSR_OE | UART_LSR_THRE |
-					 UART_LSR_DR;
-		if (I_INPCK(info->tty))
-			info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-		if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
-			info->read_status_mask |= UART_LSR_BI;
-
-		/*
-		 * Characters to ignore
-		 */
-		info->ignore_status_mask = 0;
-		if (I_IGNPAR(info->tty))
-			info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
-		if (I_IGNBRK(info->tty)) {
-			info->ignore_status_mask |= UART_LSR_BI;
-			/*
-			 * If we're ignore parity and break indicators, ignore 
-			 * overruns too.  (For real raw support).
-			 */
-			if (I_IGNPAR(info->tty))
-				info->ignore_status_mask |= UART_LSR_OE;
-		}
-		/*
-		 * !!! ignore all characters if CREAD is not set
-		 */
-		if ((info->cflag & CREAD) == 0)
-			info->ignore_status_mask |= UART_LSR_DR;
-	}
-
-	save_flags(flags); cli();
-	if (uart_config[info->type].flags & UART_STARTECH) {
-		serial_outp(info, UART_LCR, 0xBF);
-		serial_outp(info, UART_EFR,
-			    (info->cflag & CRTSCTS) ? UART_EFR_CTS : 0);
-	}
-	serial_outp(info, UART_LCR, cval | UART_LCR_DLAB);	/* set DLAB */
-	serial_outp(info, UART_DLL, quot & 0xff);	/* LS of divisor */
-	serial_outp(info, UART_DLM, quot >> 8);		/* MS of divisor */
-	if (info->type == PORT_16750)
-		serial_outp(info, UART_FCR, fcr); 	/* set fcr */
-	serial_outp(info, UART_LCR, cval);		/* reset DLAB */
-	if (info->type != PORT_16750)
-		serial_outp(info, UART_FCR, fcr); 	/* set fcr */
-	restore_flags(flags);
-	info->quot = quot;
-}
-
-static void
-su_put_char(struct tty_struct *tty, unsigned char ch)
-{
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "su_put_char"))
-		return;
-
-	if (!tty || !info->xmit_buf)
-		return;
-
-	save_flags(flags); cli();
-	if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
-		restore_flags(flags);
-		return;
-	}
-
-	info->xmit_buf[info->xmit_head++] = ch;
-	info->xmit_head &= SERIAL_XMIT_SIZE-1;
-	info->xmit_cnt++;
-	restore_flags(flags);
-}
-
-static void su_put_char_kbd(unsigned char c)
-{
-	struct su_struct *info = su_table;
-	int lsr;
-
-	if (info->port_type != SU_PORT_KBD)
-		++info;
-	if (info->port_type != SU_PORT_KBD)
-		return;
-
-	do {
-		lsr = serial_in(info, UART_LSR);
-	} while (!(lsr & UART_LSR_THRE));
-
-	/* Send the character out. */
-	su_outb(info, UART_TX, c);
-}
-
-static void
-su_change_mouse_baud(int baud)
-{
-	struct su_struct *info = su_table;
-
-	if (info->port_type != SU_PORT_MS)
-		++info;
-	if (info->port_type != SU_PORT_MS)
-		return;
-
-	info->cflag &= ~CBAUD;
-	switch (baud) {
-		case 1200:
-			info->cflag |= B1200;
-			break;
-		case 2400:
-			info->cflag |= B2400;
-			break;
-		case 4800:
-			info->cflag |= B4800;
-			break;
-		case 9600:
-			info->cflag |= B9600;
-			break;
-		default:
-			printk("su_change_mouse_baud: unknown baud rate %d, "
-			       "defaulting to 1200\n", baud);
-			info->cflag |= 1200;
-			break;
-	}
-	change_speed(info, 0);
-}
-
-static void
-su_flush_chars(struct tty_struct *tty)
-{
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-	unsigned long flags;
-				
-	if (serial_paranoia_check(info, tty->device, "su_flush_chars"))
-		return;
-
-	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
-	    !info->xmit_buf)
-		return;
-
-	save_flags(flags); cli();
-	info->IER |= UART_IER_THRI;
-	serial_out(info, UART_IER, info->IER);
-	restore_flags(flags);
-}
-
-static int
-su_write(struct tty_struct * tty, int from_user,
-		    const unsigned char *buf, int count)
-{
-	int	c, ret = 0;
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "su_write"))
-		return 0;
-
-	if (!tty || !info->xmit_buf || !tmp_buf)
-		return 0;
-
-	save_flags(flags);
-	if (from_user) {
-		down(&tmp_buf_sem);
-		while (1) {
-			c = MIN(count,
-				MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-				    SERIAL_XMIT_SIZE - info->xmit_head));
-			if (c <= 0)
-				break;
-
-			c -= copy_from_user(tmp_buf, buf, c);
-			if (!c) {
-				if (!ret)
-					ret = -EFAULT;
-				break;
-			}
-			cli();
-			c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-				       SERIAL_XMIT_SIZE - info->xmit_head));
-			memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
-			info->xmit_head = ((info->xmit_head + c) &
-					   (SERIAL_XMIT_SIZE-1));
-			info->xmit_cnt += c;
-			restore_flags(flags);
-			buf += c;
-			count -= c;
-			ret += c;
-		}
-		up(&tmp_buf_sem);
-	} else {
-		while (1) {
-			cli();		
-			c = MIN(count,
-				MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-				    SERIAL_XMIT_SIZE - info->xmit_head));
-			if (c <= 0) {
-				restore_flags(flags);
-				break;
-			}
-			memcpy(info->xmit_buf + info->xmit_head, buf, c);
-			info->xmit_head = ((info->xmit_head + c) &
-					   (SERIAL_XMIT_SIZE-1));
-			info->xmit_cnt += c;
-			restore_flags(flags);
-			buf += c;
-			count -= c;
-			ret += c;
-		}
-	}
-	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
-	    !(info->IER & UART_IER_THRI)) {
-		info->IER |= UART_IER_THRI;
-		serial_out(info, UART_IER, info->IER);
-	}
-	return ret;
-}
-
-static int
-su_write_room(struct tty_struct *tty)
-{
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-	int	ret;
-
-	if (serial_paranoia_check(info, tty->device, "su_write_room"))
-		return 0;
-	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
-	if (ret < 0)
-		ret = 0;
-	return ret;
-}
-
-static int
-su_chars_in_buffer(struct tty_struct *tty)
-{
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-				
-	if (serial_paranoia_check(info, tty->device, "su_chars_in_buffer"))
-		return 0;
-	return info->xmit_cnt;
-}
-
-static void
-su_flush_buffer(struct tty_struct *tty)
-{
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "su_flush_buffer"))
-		return;
-	save_flags(flags); cli();
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	restore_flags(flags);
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
-}
-
-/*
- * This function is used to send a high-priority XON/XOFF character to
- * the device
- */
-static void
-su_send_xchar(struct tty_struct *tty, char ch)
-{
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->device, "su_send_char"))
-		return;
-
-	if (!(info->flags & ASYNC_INITIALIZED))
-		return;
-
-	info->x_char = ch;
-	if (ch) {
-		/* Make sure transmit interrupts are on */
-		info->IER |= UART_IER_THRI;
-		serial_out(info, UART_IER, info->IER);
-	}
-}
-
-/*
- * ------------------------------------------------------------
- * su_throttle()
- * 
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void
-su_throttle(struct tty_struct * tty)
-{
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-	unsigned long flags;
-#ifdef SERIAL_DEBUG_THROTTLE
-	char	buf[64];
-
-	printk("throttle %s: %d....\n", tty_name(tty, buf),
-	       tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->device, "su_throttle"))
-		return;
-
-	if (I_IXOFF(tty))
-		su_send_xchar(tty, STOP_CHAR(tty));
-
-	if (tty->termios->c_cflag & CRTSCTS)
-		info->MCR &= ~UART_MCR_RTS;
-
-	save_flags(flags); cli();
-	serial_out(info, UART_MCR, info->MCR);
-	restore_flags(flags);
-}
-
-static void
-su_unthrottle(struct tty_struct * tty)
-{
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-	unsigned long flags;
-#ifdef SERIAL_DEBUG_THROTTLE
-	char	buf[64];
-
-	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
-	       tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->device, "su_unthrottle"))
-		return;
-
-	if (I_IXOFF(tty)) {
-		if (info->x_char)
-			info->x_char = 0;
-		else
-			su_send_xchar(tty, START_CHAR(tty));
-	}
-	if (tty->termios->c_cflag & CRTSCTS)
-		info->MCR |= UART_MCR_RTS;
-	save_flags(flags); cli();
-	serial_out(info, UART_MCR, info->MCR);
-	restore_flags(flags);
-}
-
-/*
- * ------------------------------------------------------------
- * su_ioctl() and friends
- * ------------------------------------------------------------
- */
-
-/*
- * get_serial_info - handle TIOCGSERIAL ioctl()
- *
- * Purpose: Return standard serial struct information about
- *          a serial port handled by this driver.
- *
- * Added:   11-May-2001 Lars Kellogg-Stedman <lars@larsshack.org>
- */
-static int get_serial_info(struct su_struct * info,
-			   struct serial_struct * retinfo)
-{
-	struct serial_struct	tmp;
-
-	if (!retinfo)
-		return -EFAULT;
-	memset(&tmp, 0, sizeof(tmp));
-
-	tmp.type		= info->type;
-	tmp.line		= info->line;
-	tmp.port		= info->port;
-	tmp.irq			= info->irq;
-	tmp.flags		= info->flags;
-	tmp.xmit_fifo_size	= info->xmit_fifo_size;
-	tmp.baud_base		= info->baud_base;
-	tmp.close_delay		= info->close_delay;
-	tmp.closing_wait	= info->closing_wait;
-	tmp.custom_divisor	= info->custom_divisor;
-	tmp.hub6		= 0;
-
-	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
-		return -EFAULT;
-
-	return 0;
-}
-
-/*
- * get_lsr_info - get line status register info
- *
- * Purpose: Let user call ioctl() to get info when the UART physically
- * 	    is emptied.  On bus types like RS485, the transmitter must
- * 	    release the bus after transmitting. This must be done when
- * 	    the transmit shift register is empty, not be done when the
- * 	    transmit holding register is empty.  This functionality
- * 	    allows an RS485 driver to be written in user space. 
- */
-static int
-get_lsr_info(struct su_struct * info, unsigned int *value)
-{
-	unsigned char status;
-	unsigned int result;
-	unsigned long flags;
-
-	save_flags(flags); cli();
-	status = serial_in(info, UART_LSR);
-	restore_flags(flags);
-	result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0);
-	return put_user(result,value);
-}
-
-
-static int
-get_modem_info(struct su_struct * info, unsigned int *value)
-{
-	unsigned char control, status;
-	unsigned int result;
-	unsigned long flags;
-
-	control = info->MCR;
-	save_flags(flags); cli();
-	status = serial_in(info, UART_MSR);
-	restore_flags(flags);
-	result =  ((control & UART_MCR_RTS) ? TIOCM_RTS : 0)
-		| ((control & UART_MCR_DTR) ? TIOCM_DTR : 0)
-#ifdef TIOCM_OUT1
-		| ((control & UART_MCR_OUT1) ? TIOCM_OUT1 : 0)
-		| ((control & UART_MCR_OUT2) ? TIOCM_OUT2 : 0)
-#endif
-		| ((status  & UART_MSR_DCD) ? TIOCM_CAR : 0)
-		| ((status  & UART_MSR_RI) ? TIOCM_RNG : 0)
-		| ((status  & UART_MSR_DSR) ? TIOCM_DSR : 0)
-		| ((status  & UART_MSR_CTS) ? TIOCM_CTS : 0);
-	return put_user(result,value);
-}
-
-static int
-set_modem_info(struct su_struct * info, unsigned int cmd, unsigned int *value)
-{
-	unsigned int arg;
-	unsigned long flags;
-
-	if (get_user(arg, value))
-		return -EFAULT;
-	switch (cmd) {
-	case TIOCMBIS: 
-		if (arg & TIOCM_RTS)
-			info->MCR |= UART_MCR_RTS;
-		if (arg & TIOCM_DTR)
-			info->MCR |= UART_MCR_DTR;
-#ifdef TIOCM_OUT1
-		if (arg & TIOCM_OUT1)
-			info->MCR |= UART_MCR_OUT1;
-		if (arg & TIOCM_OUT2)
-			info->MCR |= UART_MCR_OUT2;
-#endif
-		break;
-	case TIOCMBIC:
-		if (arg & TIOCM_RTS)
-			info->MCR &= ~UART_MCR_RTS;
-		if (arg & TIOCM_DTR)
-			info->MCR &= ~UART_MCR_DTR;
-#ifdef TIOCM_OUT1
-		if (arg & TIOCM_OUT1)
-			info->MCR &= ~UART_MCR_OUT1;
-		if (arg & TIOCM_OUT2)
-			info->MCR &= ~UART_MCR_OUT2;
-#endif
-		break;
-	case TIOCMSET:
-		info->MCR = ((info->MCR & ~(UART_MCR_RTS |
-#ifdef TIOCM_OUT1
-					    UART_MCR_OUT1 |
-					    UART_MCR_OUT2 |
-#endif
-					    UART_MCR_DTR))
-			     | ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
-#ifdef TIOCM_OUT1
-			     | ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0)
-			     | ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0)
-#endif
-			     | ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
-		break;
-	default:
-		return -EINVAL;
-	}
-	save_flags(flags); cli();
-	serial_out(info, UART_MCR, info->MCR);
-	restore_flags(flags);
-	return 0;
-}
-
-/*
- * su_break() --- routine which turns the break handling on or off
- */
-static void
-su_break(struct tty_struct *tty, int break_state)
-{
-	struct su_struct * info = (struct su_struct *)tty->driver_data;
-	unsigned long flags;
-	
-	if (serial_paranoia_check(info, tty->device, "su_break"))
-		return;
-
-	if (!info->port)
-		return;
-	save_flags(flags); cli();
-	if (break_state == -1)
-		serial_out(info, UART_LCR,
-			   serial_inp(info, UART_LCR) | UART_LCR_SBC);
-	else
-		serial_out(info, UART_LCR,
-			   serial_inp(info, UART_LCR) & ~UART_LCR_SBC);
-	restore_flags(flags);
-}
-
-static int
-su_ioctl(struct tty_struct *tty, struct file * file,
-		    unsigned int cmd, unsigned long arg)
-{
-	struct su_struct * info = (struct su_struct *)tty->driver_data;
-	struct async_icount cprev, cnow;	/* kernel counter temps */
-	struct serial_icounter_struct *p_cuser;	/* user space */
-
-	if (serial_paranoia_check(info, tty->device, "su_ioctl"))
-		return -ENODEV;
-
-	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
-	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
-	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
-		if (tty->flags & (1 << TTY_IO_ERROR))
-		    return -EIO;
-	}
-
-	switch (cmd) {
-		case TIOCMGET:
-			return get_modem_info(info, (unsigned int *) arg);
-		case TIOCMBIS:
-		case TIOCMBIC:
-		case TIOCMSET:
-			return set_modem_info(info, cmd, (unsigned int *) arg);
-
-		case TIOCGSERIAL:
-			return get_serial_info(info, (struct serial_struct *)arg);
-
-		case TIOCSERGETLSR: /* Get line status register */
-			return get_lsr_info(info, (unsigned int *) arg);
-
-#if 0
-		case TIOCSERGSTRUCT:
-			if (copy_to_user((struct async_struct *) arg,
-					 info, sizeof(struct async_struct)))
-				return -EFAULT;
-			return 0;
-#endif
-				
-		/*
-		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
-		 * - mask passed in arg for lines of interest
- 		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
-		 * Caller should use TIOCGICOUNT to see which one it was
-		 */
-		case TIOCMIWAIT:
-			cli();
-			/* note the counters on entry */
-			cprev = info->icount;
-			sti();
-			while (1) {
-				interruptible_sleep_on(&info->delta_msr_wait);
-				/* see if a signal did it */
-				if (signal_pending(current))
-					return -ERESTARTSYS;
-				cli();
-				cnow = info->icount; /* atomic copy */
-				sti();
-				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
-				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
-					return -EIO; /* no change => error */
-				if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
-				     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
-				     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
-				     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
-					return 0;
-				}
-				cprev = cnow;
-			}
-			/* NOTREACHED */
-
-		/* 
-		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
-		 * Return: write counters to the user passed counter struct
-		 * NB: both 1->0 and 0->1 transitions are counted except for
-		 *     RI where only 0->1 is counted.
-		 */
-		case TIOCGICOUNT:
-			cli();
-			cnow = info->icount;
-			sti();
-			p_cuser = (struct serial_icounter_struct *) arg;
-			if (put_user(cnow.cts, &p_cuser->cts) ||
-			    put_user(cnow.dsr, &p_cuser->dsr) ||
-			    put_user(cnow.rng, &p_cuser->rng) ||
-			    put_user(cnow.dcd, &p_cuser->dcd))
-				return -EFAULT;
-			return 0;
-
-		default:
-			return -ENOIOCTLCMD;
-		}
-	/* return 0; */ /* Trigger warnings if fall through by a chance. */
-}
-
-static void
-su_set_termios(struct tty_struct *tty, struct termios *old_termios)
-{
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-	unsigned long flags;
-
-	if (   (tty->termios->c_cflag == old_termios->c_cflag)
-	    && (   RELEVANT_IFLAG(tty->termios->c_iflag) 
-		== RELEVANT_IFLAG(old_termios->c_iflag)))
-	  return;
-
-	change_speed(info, old_termios);
-
-	/* Handle transition to B0 status */
-	if ((old_termios->c_cflag & CBAUD) &&
-	    !(tty->termios->c_cflag & CBAUD)) {
-		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
-		save_flags(flags); cli();
-		serial_out(info, UART_MCR, info->MCR);
-		restore_flags(flags);
-	}
-
-	/* Handle transition away from B0 status */
-	if (!(old_termios->c_cflag & CBAUD) &&
-	    (tty->termios->c_cflag & CBAUD)) {
-		info->MCR |= UART_MCR_DTR;
-		if (!(tty->termios->c_cflag & CRTSCTS) || 
-		    !test_bit(TTY_THROTTLED, &tty->flags)) {
-			info->MCR |= UART_MCR_RTS;
-		}
-		save_flags(flags); cli();
-		serial_out(info, UART_MCR, info->MCR);
-		restore_flags(flags);
-	}
-	
-	/* Handle turning off CRTSCTS */
-	if ((old_termios->c_cflag & CRTSCTS) &&
-	    !(tty->termios->c_cflag & CRTSCTS)) {
-		tty->hw_stopped = 0;
-		su_start(tty);
-	}
-
-#if 0
-	/*
-	 * No need to wake up processes in open wait, since they
-	 * sample the CLOCAL flag once, and don't recheck it.
-	 * XXX  It's not clear whether the current behavior is correct
-	 * or not.  Hence, this may change.....
-	 */
-	if (!(old_termios->c_cflag & CLOCAL) &&
-	    (tty->termios->c_cflag & CLOCAL))
-		wake_up_interruptible(&info->open_wait);
-#endif
-}
-
-/*
- * ------------------------------------------------------------
- * su_close()
- * 
- * This routine is called when the serial port gets closed.  First, we
- * wait for the last remaining data to be sent.  Then, we unlink its
- * async structure from the interrupt chain if necessary, and we free
- * that IRQ if nothing is left in the chain.
- * ------------------------------------------------------------
- */
-static void
-su_close(struct tty_struct *tty, struct file * filp)
-{
-	struct su_struct *info = (struct su_struct *)tty->driver_data;
-	unsigned long flags;
-
-	if (!info || serial_paranoia_check(info, tty->device, "su_close"))
-		return;
-
-	save_flags(flags); cli();
-	
-	if (tty_hung_up_p(filp)) {
-		DBG_CNT("before DEC-hung");
-		MOD_DEC_USE_COUNT;
-		restore_flags(flags);
-		return;
-	}
-	
-#ifdef SERIAL_DEBUG_OPEN
-	printk("su_close ttys%d, count = %d\n", info->line, info->count);
-#endif
-	if ((tty->count == 1) && (info->count != 1)) {
-		/*
-		 * Uh, oh.  tty->count is 1, which means that the tty
-		 * structure will be freed.  info->count should always
-		 * be one in these conditions.  If it's greater than
-		 * one, we've got real problems, since it means the
-		 * serial port won't be shutdown.
-		 */
-		printk("su_close: bad serial port count; tty->count is 1, "
-		       "info->count is %d\n", info->count);
-		info->count = 1;
-	}
-	if (--info->count < 0) {
-		printk("su_close: bad serial port count for ttys%d: %d\n",
-		       info->line, info->count);
-		info->count = 0;
-	}
-	if (info->count) {
-		DBG_CNT("before DEC-2");
-		MOD_DEC_USE_COUNT;
-		restore_flags(flags);
-		return;
-	}
-	info->flags |= ASYNC_CLOSING;
-	/*
-	 * Save the termios structure, since this port may have
-	 * separate termios for callout and dialin.
-	 */
-	if (info->flags & ASYNC_NORMAL_ACTIVE)
-		info->normal_termios = *tty->termios;
-	if (info->flags & ASYNC_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
-	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
-	 * the line discipline to only process XON/XOFF characters.
-	 */
-	tty->closing = 1;
-	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
-	/*
-	 * At this point we stop accepting input.  To do this, we
-	 * disable the receive line status interrupts, and tell the
-	 * interrupt driver to stop checking the data ready bit in the
-	 * line status register.
-	 */
-	info->IER &= ~UART_IER_RLSI;
-	info->read_status_mask &= ~UART_LSR_DR;
-	if (info->flags & ASYNC_INITIALIZED) {
-		serial_out(info, UART_IER, info->IER);
-		/*
-		 * Before we drop DTR, make sure the UART transmitter
-		 * has completely drained; this is especially
-		 * important if there is a transmit FIFO!
-		 */
-		su_wait_until_sent(tty, info->timeout);
-	}
-	shutdown(info);
-	if (tty->driver.flush_buffer)
-		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
-	tty->closing = 0;
-	info->event = 0;
-	info->tty = 0;
-	if (info->blocked_open) {
-		if (info->close_delay) {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(info->close_delay);
-		}
-		wake_up_interruptible(&info->open_wait);
-	}
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-			 ASYNC_CLOSING);
-	wake_up_interruptible(&info->close_wait);
-	MOD_DEC_USE_COUNT;
-	restore_flags(flags);
-}
-
-/*
- * su_wait_until_sent() --- wait until the transmitter is empty
- */
-static void
-su_wait_until_sent(struct tty_struct *tty, int timeout)
-{
-	struct su_struct * info = (struct su_struct *)tty->driver_data;
-	unsigned long orig_jiffies, char_time;
-	int lsr;
-
-	if (serial_paranoia_check(info, tty->device, "su_wait_until_sent"))
-		return;
-
-	if (info->type == PORT_UNKNOWN)
-		return;
-
-	if (info->xmit_fifo_size == 0)
-		return; /* Just in case ... */
-
-	orig_jiffies = jiffies;
-	/*
-	 * Set the check interval to be 1/5 of the estimated time to
-	 * send a single character, and make it at least 1.  The check
-	 * interval should also be less than the timeout.
-	 * 
-	 * Note: we have to use pretty tight timings here to satisfy
-	 * the NIST-PCTS.
-	 */
-	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
-	char_time = char_time / 5;
-	if (char_time == 0)
-		char_time = 1;
-	if (timeout)
-	  char_time = MIN(char_time, timeout);
-#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-	printk("In su_wait_until_sent(%d) check=%lu...", timeout, char_time);
-	printk("jiff=%lu...", jiffies);
-#endif
-	while (!((lsr = serial_inp(info, UART_LSR)) & UART_LSR_TEMT)) {
-#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
-#endif
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(char_time);
-		if (signal_pending(current))
-			break;
-		if (timeout && time_after(jiffies, orig_jiffies + timeout))
-			break;
-	}
-#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
-#endif
-}
-
-/*
- * su_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-static void
-su_hangup(struct tty_struct *tty)
-{
-	struct su_struct * info = (struct su_struct *)tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->device, "su_hangup"))
-		return;
-
-	su_flush_buffer(tty);
-	shutdown(info);
-	info->event = 0;
-	info->count = 0;
-	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
-	info->tty = 0;
-	wake_up_interruptible(&info->open_wait);
-}
-
-/*
- * ------------------------------------------------------------
- * su_open() and friends
- * ------------------------------------------------------------
- */
-static int
-block_til_ready(struct tty_struct *tty, struct file * filp,
-		struct su_struct *info)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	int		  retval;
-	int		  do_clocal = 0, extra_count = 0;
-	unsigned long	  flags;
-
-	/*
-	 * If the device is in the middle of being closed, then block
-	 * until it's done, and then try again.
-	 */
-	if (tty_hung_up_p(filp) ||
-	    (info->flags & ASYNC_CLOSING)) {
-		if (info->flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&info->close_wait);
-#ifdef SERIAL_DO_RESTART
-		return ((info->flags & ASYNC_HUP_NOTIFY) ?
-			-EAGAIN : -ERESTARTSYS);
-#else
-		return -EAGAIN;
-#endif
-	}
-
-	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ASYNC_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (info->flags & ASYNC_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ASYNC_CALLOUT_ACTIVE;
-		return 0;
-	}
-
-	/*
-	 * If non-blocking mode is set, or the port is not enabled,
-	 * then make the check up front and then exit.
-	 */
-	if ((filp->f_flags & O_NONBLOCK) ||
-	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ASYNC_CALLOUT_ACTIVE)
-			return -EBUSY;
-		info->flags |= ASYNC_NORMAL_ACTIVE;
-		return 0;
-	}
-
-	if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
-	/*
-	 * Block waiting for the carrier detect and the line to become
-	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, info->count is dropped by one, so that
-	 * su_close() knows when to free things.  We restore it upon
-	 * exit, either normal or abnormal.
-	 */
-	retval = 0;
-	add_wait_queue(&info->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready before block: ttys%d, count = %d\n",
-	       info->line, info->count);
-#endif
-	save_flags(flags); cli();
-	if (!tty_hung_up_p(filp)) {
-		extra_count = 1;
-		info->count--;
-	}
-	restore_flags(flags);
-	info->blocked_open++;
-	while (1) {
-		save_flags(flags); cli();
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD))
-			serial_out(info, UART_MCR,
-				   serial_inp(info, UART_MCR) |
-				   (UART_MCR_DTR | UART_MCR_RTS));
-		restore_flags(flags);
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p(filp) ||
-		    !(info->flags & ASYNC_INITIALIZED)) {
-#ifdef SERIAL_DO_RESTART
-			if (info->flags & ASYNC_HUP_NOTIFY)
-				retval = -EAGAIN;
-			else
-				retval = -ERESTARTSYS;	
-#else
-			retval = -EAGAIN;
-#endif
-			break;
-		}
-		if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-		    !(info->flags & ASYNC_CLOSING) &&
-		    (do_clocal || (serial_in(info, UART_MSR) &
-				   UART_MSR_DCD)))
-			break;
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			break;
-		}
-#ifdef SERIAL_DEBUG_OPEN
-		printk("block_til_ready blocking: ttys%d, count = %d\n",
-		       info->line, info->count);
-#endif
-		schedule();
-	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&info->open_wait, &wait);
-	if (extra_count)
-		info->count++;
-	info->blocked_open--;
-#ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready after blocking: ttys%d, count = %d\n",
-	       info->line, info->count);
-#endif
-	if (retval)
-		return retval;
-	info->flags |= ASYNC_NORMAL_ACTIVE;
-	return 0;
-}
-
-/*
- * This routine is called whenever a serial port is opened.  It
- * enables interrupts for a serial port, linking in its async structure into
- * the IRQ chain.   It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int
-su_open(struct tty_struct *tty, struct file * filp)
-{
-	struct su_struct	*info;
-	int 			retval, line;
-	unsigned long		page;
-
-	line = minor(tty->device) - tty->driver.minor_start;
-	if ((line < 0) || (line >= NR_PORTS))
-		return -ENODEV;
-	info = su_table + line;
-	info->count++;
-	tty->driver_data = info;
-	info->tty = tty;
-
-	if (serial_paranoia_check(info, tty->device, "su_open")) {
-		info->count--;
-		return -ENODEV;
-	}
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("su_open %s%d, count = %d\n", tty->driver.name, info->line,
-	       info->count);
-#endif
-	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
-
-	if (!tmp_buf) {
-		page = get_free_page(GFP_KERNEL);
-		if (!page)
-			return -ENOMEM;
-		if (tmp_buf)
-			free_page(page);
-		else
-			tmp_buf = (unsigned char *) page;
-	}
-
-	/*
-	 * If the port is the middle of closing, bail out now
-	 */
-	if (tty_hung_up_p(filp) ||
-	    (info->flags & ASYNC_CLOSING)) {
-		if (info->flags & ASYNC_CLOSING)
-			interruptible_sleep_on(&info->close_wait);
-#ifdef SERIAL_DO_RESTART
-		return ((info->flags & ASYNC_HUP_NOTIFY) ?
-			-EAGAIN : -ERESTARTSYS);
-#else
-		return -EAGAIN;
-#endif
-	}
-	
-	/*
-	 * Start up serial port
-	 */
-	retval = startup(info);
-	if (retval)
-		return retval;
-
-	MOD_INC_USE_COUNT;
-	retval = block_til_ready(tty, filp, info);
-	if (retval) {
-#ifdef SERIAL_DEBUG_OPEN
-		printk("su_open returning after block_til_ready with %d\n",
-		       retval);
-#endif
-		return retval;
-	}
-
-	if ((info->count == 1) &&
-	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
-		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
-		change_speed(info, 0);
-	}
-#ifdef CONFIG_SERIAL_CONSOLE
-	if (sercons.cflag && sercons.index == line) {
-		tty->termios->c_cflag = sercons.cflag;
-		sercons.cflag = 0;
-		change_speed(info, 0);
-	}
-#endif
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("su_open ttys%d successful...", info->line);
-#endif
-	return 0;
-}
-
-/*
- * /proc fs routines....
- */
-static int
-line_info(char *buf, struct su_struct *info)
-{
-	char		stat_buf[30], control, status;
-	int		ret;
-	unsigned long	flags;
-
-	if (info->port == 0 || info->type == PORT_UNKNOWN)
-		return 0;
-
-	ret = sprintf(buf, "%u: uart:%s port:%lX irq:%s",
-		      info->line, uart_config[info->type].name, 
-		      (unsigned long)info->port, __irq_itoa(info->irq));
-
-	/*
-	 * Figure out the current RS-232 lines
-	 */
-	save_flags(flags); cli();
-	status = serial_in(info, UART_MSR);
-	control = info ? info->MCR : serial_in(info, UART_MCR);
-	restore_flags(flags);
-
-	stat_buf[0] = 0;
-	stat_buf[1] = 0;
-	if (control & UART_MCR_RTS)
-		strcat(stat_buf, "|RTS");
-	if (status & UART_MSR_CTS)
-		strcat(stat_buf, "|CTS");
-	if (control & UART_MCR_DTR)
-		strcat(stat_buf, "|DTR");
-	if (status & UART_MSR_DSR)
-		strcat(stat_buf, "|DSR");
-	if (status & UART_MSR_DCD)
-		strcat(stat_buf, "|CD");
-	if (status & UART_MSR_RI)
-		strcat(stat_buf, "|RI");
-
-	if (info->quot) {
-		ret += sprintf(buf+ret, " baud:%u",
-			       info->baud_base / info->quot);
-	}
-
-	ret += sprintf(buf+ret, " tx:%u rx:%u",
-		       info->icount.tx, info->icount.rx);
-
-	if (info->icount.frame)
-		ret += sprintf(buf+ret, " fe:%u", info->icount.frame);
-
-	if (info->icount.parity)
-		ret += sprintf(buf+ret, " pe:%u", info->icount.parity);
-
-	if (info->icount.brk)
-		ret += sprintf(buf+ret, " brk:%u", info->icount.brk);	
-
-	if (info->icount.overrun)
-		ret += sprintf(buf+ret, " oe:%u", info->icount.overrun);
-
-	/*
-	 * Last thing is the RS-232 status lines
-	 */
-	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
-	return ret;
-}
-
-int su_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
-{
-	int i, len = 0;
-	off_t	begin = 0;
-
-	len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
-	for (i = 0; i < NR_PORTS && len < 4000; i++) {
-		len += line_info(page + len, &su_table[i]);
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
-	}
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
-}
-
-/*
- * ---------------------------------------------------------------------
- * su_XXX_init() and friends
- *
- * su_XXX_init() is called at boot-time to initialize the serial driver.
- * ---------------------------------------------------------------------
- */
-
-/*
- * This routine prints out the appropriate serial driver version
- * number, and identifies which options were configured into this
- * driver.
- */
-static __inline__ void __init show_su_version(void)
-{
-	char *revision = "$Revision: 1.55 $";
-	char *version, *p;
-
-	version = strchr(revision, ' ');
-	strcpy(serial_version, ++version);
-	p = strchr(serial_version, ' ');
-	*p = '\0';
- 	printk(KERN_INFO "%s version %s\n", serial_name, serial_version);
-}
-
-/*
- * This routine is called by su_{serial|kbd_ms}_init() to initialize a specific
- * serial port.  It determines what type of UART chip this serial port is
- * using: 8250, 16450, 16550, 16550A.  The important question is
- * whether or not this UART is a 16550A, since this will determine
- * whether or not we can use its FIFO features.
- */
-static void
-autoconfig(struct su_struct *info)
-{
-	unsigned char status1, status2, scratch, scratch2;
-	struct linux_ebus_device *dev = 0;
-	struct linux_ebus *ebus;
-#ifdef CONFIG_SPARC64
-	struct isa_bridge *isa_br;
-	struct isa_device *isa_dev;
-#endif
-#ifndef __sparc_v9__
-	struct linux_prom_registers reg0;
-#endif
-	unsigned long flags;
-
-	if (!info->port_node || !info->port_type)
-		return;
-
-	/*
-	 * First we look for Ebus-bases su's
-	 */
-	for_each_ebus(ebus) {
-		for_each_ebusdev(dev, ebus) {
-			if (dev->prom_node == info->port_node) {
-				info->port = dev->resource[0].start;
-				info->irq = dev->irqs[0];
-				goto ebus_done;
-			}
-		}
-	}
-
-#ifdef CONFIG_SPARC64
-	for_each_isa(isa_br) {
-		for_each_isadev(isa_dev, isa_br) {
-			if (isa_dev->prom_node == info->port_node) {
-				info->port = isa_dev->resource.start;
-				info->irq = isa_dev->irq;
-				goto ebus_done;
-			}
-		}
-	}
-#endif
-
-#ifdef __sparc_v9__
-	/*
-	 * Not on Ebus, bailing.
-	 */
-	return;
-#else
-	/*
-	 * Not on Ebus, must be OBIO.
-	 */
-	if (prom_getproperty(info->port_node, "reg",
-	    (char *)&reg0, sizeof(reg0)) == -1) {
-		prom_printf("su: no \"reg\" property\n");
-		return;
-	}
-	prom_apply_obio_ranges(&reg0, 1);
-	if (reg0.which_io != 0) {	/* Just in case... */
-		prom_printf("su: bus number nonzero: 0x%x:%x\n",
-		    reg0.which_io, reg0.phys_addr);
-		return;
-	}
-	if ((info->port = (unsigned long) ioremap(reg0.phys_addr,
-	    reg0.reg_size)) == 0) {
-		prom_printf("su: cannot map\n");
-		return;
-	}
-
-	/*
-	 * There is no intr property on MrCoffee, so hardwire it.
-	 */
-	info->irq = IRQ_4M(13);
-#endif
-
-ebus_done:
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("Found 'su' at %016lx IRQ %s\n", info->port,
-		__irq_itoa(info->irq));
-#endif
-
-	info->magic = SERIAL_MAGIC;
-
-	save_flags(flags); cli();
-
-	/*
-	 * Do a simple existence test first; if we fail this, there's
-	 * no point trying anything else.
-	 *
-	 * 0x80 is used as a nonsense port to prevent against false
-	 * positives due to ISA bus float.  The assumption is that
-	 * 0x80 is a non-existent port; which should be safe since
-	 * include/asm/io.h also makes this assumption.
-	 */
-	scratch = serial_inp(info, UART_IER);
-	serial_outp(info, UART_IER, 0);
-	scratch2 = serial_inp(info, UART_IER);
-	serial_outp(info, UART_IER, scratch);
-	if (scratch2) {
-		restore_flags(flags);
-		return;		/* We failed; there's nothing here */
-	}
-
-	scratch = serial_inp(info, UART_MCR);
-	serial_outp(info, UART_MCR, UART_MCR_LOOP | scratch);
-	serial_outp(info, UART_MCR, UART_MCR_LOOP | 0x0A);
-	status1 = serial_inp(info, UART_MSR) & 0xF0;
-	serial_outp(info, UART_MCR, scratch);
-	if (status1 != 0x90) {
-		/*
-		 * This code fragment used to fail, now it fixed itself.
-		 * We keep the printout for a case.
-		 */
-		printk("su: loopback returned status 0x%02x\n", status1);
-		restore_flags(flags);
-		return;
-	} 
-
-	scratch2 = serial_in(info, UART_LCR);
-	serial_outp(info, UART_LCR, 0xBF);	/* set up for StarTech test */
-	serial_outp(info, UART_EFR, 0);		/* EFR is the same as FCR */
-	serial_outp(info, UART_LCR, 0);
-	serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
-	scratch = serial_in(info, UART_IIR) >> 6;
-	switch (scratch) {
-		case 0:
-			info->type = PORT_16450;
-			break;
-		case 1:
-			info->type = PORT_UNKNOWN;
-			break;
-		case 2:
-			info->type = PORT_16550;
-			break;
-		case 3:
-			info->type = PORT_16550A;
-			break;
-	}
-	if (info->type == PORT_16550A) {
-		/* Check for Startech UART's */
-		serial_outp(info, UART_LCR, scratch2 | UART_LCR_DLAB);
-		if (serial_in(info, UART_EFR) == 0) {
-			info->type = PORT_16650;
-		} else {
-			serial_outp(info, UART_LCR, 0xBF);
-			if (serial_in(info, UART_EFR) == 0)
-				info->type = PORT_16650V2;
-		}
-	}
-	if (info->type == PORT_16550A) {
-		/* Check for TI 16750 */
-		serial_outp(info, UART_LCR, scratch2 | UART_LCR_DLAB);
-		serial_outp(info, UART_FCR,
-			    UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-		scratch = serial_in(info, UART_IIR) >> 5;
-		if (scratch == 7) {
-			serial_outp(info, UART_LCR, 0);
-			serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
-			scratch = serial_in(info, UART_IIR) >> 5;
-			if (scratch == 6)
-				info->type = PORT_16750;
-		}
-		serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
-	}
-	serial_outp(info, UART_LCR, scratch2);
-	if (info->type == PORT_16450) {
-		scratch = serial_in(info, UART_SCR);
-		serial_outp(info, UART_SCR, 0xa5);
-		status1 = serial_in(info, UART_SCR);
-		serial_outp(info, UART_SCR, 0x5a);
-		status2 = serial_in(info, UART_SCR);
-		serial_outp(info, UART_SCR, scratch);
-
-		if ((status1 != 0xa5) || (status2 != 0x5a))
-			info->type = PORT_8250;
-	}
-	info->xmit_fifo_size = uart_config[info->type].dfl_xmit_fifo_size;
-
-	if (info->type == PORT_UNKNOWN) {
-		restore_flags(flags);
-		return;
-	}
-
-	sprintf(info->name, "su(%s)", su_typev[info->port_type]);
-
-	/*
-	 * Reset the UART.
-	 */
-	serial_outp(info, UART_MCR, 0x00);
-	serial_outp(info, UART_FCR, (UART_FCR_CLEAR_RCVR|UART_FCR_CLEAR_XMIT));
-	(void)serial_in(info, UART_RX);
-	serial_outp(info, UART_IER, 0x00);
-
-	restore_flags(flags);
-}
-
-/* This is used by the SAB driver to adjust where its minor
- * numbers start, we always are probed for first.
- */
-int su_num_ports = 0;
-EXPORT_SYMBOL(su_num_ports);
-
-/*
- * The serial driver boot-time initialization code!
- */
-int __init su_serial_init(void)
-{
-	int i;
-	struct su_struct *info;
-
-	init_bh(SERIAL_BH, do_serial_bh);
-	show_su_version();
-
-	/* Initialize the tty_driver structure */
-
-	memset(&serial_driver, 0, sizeof(struct tty_driver));
-	serial_driver.magic = TTY_DRIVER_MAGIC;
-	serial_driver.driver_name = "su";
-#ifdef CONFIG_DEVFS_FS
-	serial_driver.name = "tts/%d";
-#else
-	serial_driver.name = "ttyS";
-#endif
-	serial_driver.major = TTY_MAJOR;
-	serial_driver.minor_start = 64;
-	serial_driver.num = NR_PORTS;
-	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
-	serial_driver.subtype = SERIAL_TYPE_NORMAL;
-	serial_driver.init_termios = tty_std_termios;
-	serial_driver.init_termios.c_cflag =
-		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	serial_driver.flags = TTY_DRIVER_REAL_RAW;
-	serial_driver.refcount = &serial_refcount;
-	serial_driver.table = serial_table;
-	serial_driver.termios = serial_termios;
-	serial_driver.termios_locked = serial_termios_locked;
-
-	serial_driver.open = su_open;
-	serial_driver.close = su_close;
-	serial_driver.write = su_write;
-	serial_driver.put_char = su_put_char;
-	serial_driver.flush_chars = su_flush_chars;
-	serial_driver.write_room = su_write_room;
-	serial_driver.chars_in_buffer = su_chars_in_buffer;
-	serial_driver.flush_buffer = su_flush_buffer;
-	serial_driver.ioctl = su_ioctl;
-	serial_driver.throttle = su_throttle;
-	serial_driver.unthrottle = su_unthrottle;
-	serial_driver.send_xchar = su_send_xchar;
-	serial_driver.set_termios = su_set_termios;
-	serial_driver.stop = su_stop;
-	serial_driver.start = su_start;
-	serial_driver.hangup = su_hangup;
-	serial_driver.break_ctl = su_break;
-	serial_driver.wait_until_sent = su_wait_until_sent;
-	serial_driver.read_proc = su_read_proc;
-
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-#ifdef CONFIG_DEVFS_FS
-	callout_driver.name = "cua/%d";
-#else
-	callout_driver.name = "cua";
-#endif
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-
-	if (tty_register_driver(&serial_driver))
-		panic("Couldn't register regular su\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout su\n");
-
-	for (i = 0, info = su_table; i < NR_PORTS; i++, info++) {
-		info->line = i;
-		info->type = PORT_UNKNOWN;
-		info->baud_base = BAUD_BASE;
-		/* info->flags = 0; */
-		info->custom_divisor = 0;
-		info->close_delay = 5*HZ/10;
-		info->closing_wait = 30*HZ;
-		info->callout_termios = callout_driver.init_termios;
-		info->normal_termios = serial_driver.init_termios;
-		info->icount.cts = info->icount.dsr = 
-			info->icount.rng = info->icount.dcd = 0;
-		info->icount.rx = info->icount.tx = 0;
-		info->icount.frame = info->icount.parity = 0;
-		info->icount.overrun = info->icount.brk = 0;
-		info->tqueue.routine = do_softint;
-		info->tqueue.data = info;
-		info->cflag = serial_driver.init_termios.c_cflag;
-		init_waitqueue_head(&info->open_wait);
-		init_waitqueue_head(&info->close_wait);
-		init_waitqueue_head(&info->delta_msr_wait);
-
-		autoconfig(info);
-		if (info->type == PORT_UNKNOWN)
-			continue;
-
-		printk(KERN_INFO "%s at 0x%lx (tty %d irq %s) is a %s\n",
-		       info->name, (long)info->port, i, __irq_itoa(info->irq),
-		       uart_config[info->type].name);
-	}
-
-	for (i = 0, info = su_table; i < NR_PORTS; i++, info++)
-		if (info->type == PORT_UNKNOWN)
-			break;
-
-	su_num_ports = i;
-	serial_driver.num = callout_driver.num = i;
-
-	return 0;
-}
-
-int __init su_kbd_ms_init(void)
-{
-	int i;
-	struct su_struct *info;
-
-	show_su_version();
-
-	for (i = 0, info = su_table; i < 2; i++, info++) {
-		info->line = i;
-		info->type = PORT_UNKNOWN;
-		info->baud_base = BAUD_BASE;
-
-		if (info->port_type == SU_PORT_KBD)
-			info->cflag = B1200 | CS8 | CLOCAL | CREAD;
-		else
-			info->cflag = B4800 | CS8 | CLOCAL | CREAD;
-
-		init_waitqueue_head(&info->open_wait);
-		init_waitqueue_head(&info->close_wait);
-		init_waitqueue_head(&info->delta_msr_wait);
-
-		autoconfig(info);
-		if (info->type == PORT_UNKNOWN)
-			continue;
-
-		printk(KERN_INFO "%s at 0x%lx (irq = %s) is a %s\n",
-		       info->name, info->port, __irq_itoa(info->irq),
-		       uart_config[info->type].name);
-
-		startup(info);
-		if (info->port_type == SU_PORT_KBD)
-			keyboard_zsinit(su_put_char_kbd);
-		else
-			sun_mouse_zsinit();
-	}
-	return 0;
-}
-
-static int su_node_ok(int node, char *name, int namelen)
-{
-	if (strncmp(name, "su", namelen) == 0 ||
-	    strncmp(name, "su_pnp", namelen) == 0)
-		return 1;
-
-	if (strncmp(name, "serial", namelen) == 0) {
-		char compat[32];
-		int clen;
-
-		/* Is it _really_ a 'su' device? */
-		clen = prom_getproperty(node, "compatible", compat, sizeof(compat));
-		if (clen > 0) {
-			if (strncmp(compat, "sab82532", 8) == 0) {
-				/* Nope, Siemens serial, not for us. */
-				return 0;
-			}
-		}
-		return 1;
-	}
-
-	return 0;
-}
-
-/*
- * We got several platforms which present 'su' in different parts
- * of device tree. 'su' may be found under obio, ebus, isa and pci.
- * We walk over the tree and find them wherever PROM hides them.
- */
-void __init su_probe_any(struct su_probe_scan *t, int sunode)
-{
-	struct su_struct *info;
-	int len;
-
-	if (t->devices >= NR_PORTS) return;
-
-	for (; sunode != 0; sunode = prom_getsibling(sunode)) {
-		len = prom_getproperty(sunode, "name", t->prop, SU_PROPSIZE);
-		if (len <= 1) continue;		/* Broken PROM node */
-		if (su_node_ok(sunode, t->prop, len)) {
-			info = &su_table[t->devices];
-			if (t->kbnode != 0 && sunode == t->kbnode) {
-				t->kbx = t->devices;
-				info->port_type = SU_PORT_KBD;
-			} else if (t->msnode != 0 && sunode == t->msnode) {
-				t->msx = t->devices;
-				info->port_type = SU_PORT_MS;
-			} else {
-#ifdef __sparc_v9__
-				/*
-				 * Do not attempt to use the truncated
-				 * keyboard/mouse ports as serial ports
-				 * on Ultras with PC keyboard attached.
-				 */
-				if (prom_getbool(sunode, "mouse"))
-					continue;
-				if (prom_getbool(sunode, "keyboard"))
-					continue;
-#endif
-				info->port_type = SU_PORT_PORT;
-			}
-			info->is_console = 0;
-			info->port_node = sunode;
-			++t->devices;
-		} else {
-			su_probe_any(t, prom_getchild(sunode));
-		}
-	}
-}
-
-int __init su_probe(void)
-{
-	int node;
-	int len;
-	struct su_probe_scan scan;
-
-	/*
-	 * First, we scan the tree.
-	 */
-	scan.devices = 0;
-	scan.msx = -1;
-	scan.kbx = -1;
-	scan.kbnode = 0;
-	scan.msnode = 0;
-
-	/*
-	 * Get the nodes for keyboard and mouse from 'aliases'...
-	 */
-        node = prom_getchild(prom_root_node);
-	node = prom_searchsiblings(node, "aliases");
-	if (node != 0) {
-
-		len = prom_getproperty(node, "keyboard", scan.prop,SU_PROPSIZE);
-		if (len > 0) {
-			scan.prop[len] = 0;
-			scan.kbnode = prom_finddevice(scan.prop);
-		}
-
-		len = prom_getproperty(node, "mouse", scan.prop, SU_PROPSIZE);
-		if (len > 0) {
-			scan.prop[len] = 0;
-			scan.msnode = prom_finddevice(scan.prop);
-		}
-	}
-
-	su_probe_any(&scan, prom_getchild(prom_root_node));
-
-	/*
-	 * Second, we process the special case of keyboard and mouse.
-	 *
-	 * Currently if we got keyboard and mouse hooked to "su" ports
-	 * we do not use any possible remaining "su" as a serial port.
-	 * Thus, we ignore values of .msx and .kbx, then compact ports.
-	 * Those who want to address this issue need to merge
-	 * su_serial_init() and su_ms_kbd_init().
-	 */
-	if (scan.msx != -1 && scan.kbx != -1) {
-		su_table[0].port_type = SU_PORT_MS;
-		su_table[0].is_console = 0;
-		su_table[0].port_node = scan.msnode;
-		su_table[1].port_type = SU_PORT_KBD;
-		su_table[1].is_console = 0;
-		su_table[1].port_node = scan.kbnode;
-
-        	sunserial_setinitfunc(su_kbd_ms_init);
-        	rs_ops.rs_change_mouse_baud = su_change_mouse_baud;
-		sunkbd_setinitfunc(sun_kbd_init);
-		kbd_ops.compute_shiftstate = sun_compute_shiftstate;
-		kbd_ops.setledstate = sun_setledstate;
-		kbd_ops.getledstate = sun_getledstate;
-		kbd_ops.setkeycode = sun_setkeycode;
-		kbd_ops.getkeycode = sun_getkeycode;
-#ifdef CONFIG_PCI
-		sunkbd_install_keymaps(sun_key_maps,
-		    sun_keymap_count, sun_func_buf, sun_func_table,
-		    sun_funcbufsize, sun_funcbufleft,
-		    sun_accent_table, sun_accent_table_size);
-#endif
-		return 0;
-	}
-	if (scan.msx != -1 || scan.kbx != -1) {
-		printk("su_probe: cannot match keyboard and mouse, confused\n");
-		return -ENODEV;
-	}
-
-	if (scan.devices == 0)
-		return -ENODEV;
-
-#ifdef CONFIG_SERIAL_CONSOLE
-	/*
-	 * Console must be initiated after the generic initialization.
-	 * sunserial_setinitfunc inverts order, so call this before next one.
-	 */
-	sunserial_setinitfunc(su_serial_console_init);
-#endif
-       	sunserial_setinitfunc(su_serial_init);
-	return 0;
-}
-
-/*
- * ------------------------------------------------------------
- * Serial console driver
- * ------------------------------------------------------------
- */
-#ifdef CONFIG_SERIAL_CONSOLE
-
-#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
-
-/*
- *	Wait for transmitter & holding register to empty
- */
-static __inline__ void
-wait_for_xmitr(struct su_struct *info)
-{
-	int lsr;
-	unsigned int tmout = 1000000;
-
-	do {
-		lsr = su_inb(info, UART_LSR);
-		if (--tmout == 0)
-			break;
-	} while ((lsr & BOTH_EMPTY) != BOTH_EMPTY);
-}
-
-/*
- *	Print a string to the serial port trying not to disturb
- *	any possible real use of the port...
- */
-static void
-serial_console_write(struct console *co, const char *s,
-				unsigned count)
-{
-	struct su_struct *info;
-	int ier;
-	unsigned i;
-
-	info = su_table + co->index;
-	/*
-	 *	First save the IER then disable the interrupts
-	 */
-	ier = su_inb(info, UART_IER);
-	su_outb(info, UART_IER, 0x00);
-
-	/*
-	 *	Now, do each character
-	 */
-	for (i = 0; i < count; i++, s++) {
-		wait_for_xmitr(info);
-
-		/*
-		 *	Send the character out.
-		 *	If a LF, also do CR...
-		 */
-		su_outb(info, UART_TX, *s);
-		if (*s == 10) {
-			wait_for_xmitr(info);
-			su_outb(info, UART_TX, 13);
-		}
-	}
-
-	/*
-	 *	Finally, Wait for transmitter & holding register to empty
-	 * 	and restore the IER
-	 */
-	wait_for_xmitr(info);
-	su_outb(info, UART_IER, ier);
-}
-
-static kdev_t
-serial_console_device(struct console *c)
-{
-	return mk_kdev(TTY_MAJOR, 64 + c->index);
-}
-
-/*
- *	Setup initial baud/bits/parity. We do two things here:
- *	- construct a cflag setting for the first su_open()
- *	- initialize the serial port
- *	Return non-zero if we didn't find a serial port.
- */
-static int __init serial_console_setup(struct console *co, char *options)
-{
-	struct su_struct *info;
-	unsigned cval;
-	int	baud = 9600;
-	int	bits = 8;
-	int	parity = 'n';
-	int	cflag = CREAD | HUPCL | CLOCAL;
-	int	quot = 0;
-	char	*s;
-
-	if (options) {
-		baud = simple_strtoul(options, NULL, 10);
-		s = options;
-		while (*s >= '0' && *s <= '9')
-			s++;
-		if (*s) parity = *s++;
-		if (*s) bits   = *s - '0';
-	}
-
-	/*
-	 *	Now construct a cflag setting.
-	 */
-	switch (baud) {
-		case 1200:
-			cflag |= B1200;
-			break;
-		case 2400:
-			cflag |= B2400;
-			break;
-		case 4800:
-			cflag |= B4800;
-			break;
-		case 19200:
-			cflag |= B19200;
-			break;
-		case 38400:
-			cflag |= B38400;
-			break;
-		case 57600:
-			cflag |= B57600;
-			break;
-		case 115200:
-			cflag |= B115200;
-			break;
-		case 9600:
-		default:
-			cflag |= B9600;
-			baud = 9600;
-			break;
-	}
-	switch (bits) {
-		case 7:
-			cflag |= CS7;
-			break;
-		default:
-		case 8:
-			cflag |= CS8;
-			break;
-	}
-	switch (parity) {
-		case 'o': case 'O':
-			cflag |= PARODD;
-			break;
-		case 'e': case 'E':
-			cflag |= PARENB;
-			break;
-	}
-	co->cflag = cflag;
-
-	/*
-	 *	Divisor, bytesize and parity
-	 */
-	info = su_table + co->index;
-	quot = BAUD_BASE / baud;
-	cval = cflag & (CSIZE | CSTOPB);
-#if defined(__powerpc__) || defined(__alpha__)
-	cval >>= 8;
-#else /* !__powerpc__ && !__alpha__ */
-	cval >>= 4;
-#endif /* !__powerpc__ && !__alpha__ */
-	if (cflag & PARENB)
-		cval |= UART_LCR_PARITY;
-	if (!(cflag & PARODD))
-		cval |= UART_LCR_EPAR;
-
-	/*
-	 *	Disable UART interrupts, set DTR and RTS high
-	 *	and set speed.
-	 */
-	su_outb(info, UART_IER, 0);
-	su_outb(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
-	su_outb(info, UART_LCR, cval | UART_LCR_DLAB);	/* set DLAB */
-	su_outb(info, UART_DLL, quot & 0xff);		/* LS of divisor */
-	su_outb(info, UART_DLM, quot >> 8);		/* MS of divisor */
-	su_outb(info, UART_LCR, cval);			/* reset DLAB */
-	info->quot = quot;
-
-	/*
-	 *	If we read 0xff from the LSR, there is no UART here.
-	 */
-	if (su_inb(info, UART_LSR) == 0xff)
-		return -1;
-
-	info->is_console = 1;
-
-	return 0;
-}
-
-static struct console sercons = {
-	name:		"ttyS",
-	write:		serial_console_write,
-	device:		serial_console_device,
-	setup:		serial_console_setup,
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
-};
-
-int su_console_registered = 0;
-
-/*
- *	Register console.
- */
-int __init su_serial_console_init(void)
-{
-	extern int con_is_present(void);
-	int index;
-
-	if (con_is_present())
-		return 0;
-	if (serial_console == 0)
-		return 0;
-	index = serial_console - 1;
-	if (su_table[index].port == 0 || su_table[index].port_node == 0)
-		return 0;
-	sercons.index = index;
-	register_console(&sercons);
-	su_console_registered = 1;
-	return 0;
-}
-
-#endif /* CONFIG_SERIAL_CONSOLE */
diff -Nru a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c
--- a/drivers/sbus/char/sunkbd.c	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1623 +0,0 @@
-/* keyboard.c: Sun keyboard driver.
- *
- * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
- *
- * Added vuid event generation and /dev/kbd device for SunOS
- * compatibility - Miguel (miguel@nuclecu.unam.mx)
- *
- * Added PCI 8042 controller support -DaveM
- * Added Magic SysRq support -MJ
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/mm.h>
-#include <linux/ptrace.h>
-#include <linux/signal.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/poll.h>
-#include <linux/random.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/sysrq.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h>
-
-#include <asm/kbio.h>
-#include <asm/vuid_event.h>
-#include <asm/bitops.h>
-#include <asm/oplib.h>
-#include <asm/uaccess.h>
-
-#include <linux/kbd_kern.h>
-#include <linux/kbd_diacr.h>
-#include <linux/vt_kern.h>
-
-#ifdef CONFIG_PCI
-#include <linux/pci.h>
-#include <asm/pbm.h>
-#include <asm/ebus.h>
-#endif
-
-#include "sunkbd.h"
-
-#define SIZE(x) (sizeof(x)/sizeof((x)[0]))
-
-/* Define this one if you are making a new frame buffer driver */
-/* it will not block the keyboard */
-/* #define CODING_NEW_DRIVER */
-
-/* KBD device number, temporal */
-#define KBD_MAJOR 11
-
-#define KBD_REPORT_ERR
-#define KBD_REPORT_UNKN
-
-#ifndef KBD_DEFMODE
-#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
-#endif
-
-#ifndef KBD_DEFLEDS
-/*
- * Some laptops take the 789uiojklm,. keys as number pad when NumLock
- * is on. This seems a good reason to start with NumLock off.
- */
-#define KBD_DEFLEDS 0
-#endif
-
-#ifndef KBD_DEFLOCK
-#define KBD_DEFLOCK 0
-#endif
-
-extern void poke_blanked_console(void);
-extern void ctrl_alt_del(void);
-extern void reset_vc(unsigned int new_console);
-extern void scrollback(int);
-extern void scrollfront(int);
-
-struct l1a_kbd_state l1a_state;
-
-static spinlock_t sunkbd_lock = SPIN_LOCK_UNLOCKED;
-
-/*
- * global state includes the following, and various static variables
- * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
- * (last_console is now a global variable)
- */
-
-/* shift state counters.. */
-static unsigned char k_down[NR_SHIFT];
-/* keyboard key bitmap */
-static unsigned long key_down[256/BITS_PER_LONG];
-
-void push_kbd (int scan);
-int kbd_redirected;
-
-static int dead_key_next;
-/* 
- * In order to retrieve the shift_state (for the mouse server), either
- * the variable must be global, or a new procedure must be created to 
- * return the value. I chose the former way.
- */
-#ifndef CONFIG_PCI
-int shift_state;
-struct kbd_struct kbd_table[MAX_NR_CONSOLES];
-#endif
-static int npadch = -1;			/* -1 or number assembled on pad */
-static unsigned char diacr;
-static char rep;			/* flag telling character repeat */
-static struct tty_struct **ttytab;
-static struct kbd_struct * kbd = kbd_table;
-static struct tty_struct * tty;
-static int compose_led_on;
-static int kbd_delay_ticks = HZ / 5;
-static int kbd_rate_ticks = HZ / 20;
-
-void sun_compute_shiftstate(void);
-
-typedef void (*k_hand)(unsigned char value, char up_flag);
-typedef void (k_handfn)(unsigned char value, char up_flag);
-
-static k_handfn
-	do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
-	do_meta, do_ascii, do_lock, do_lowercase, do_ignore;
-
-static k_hand key_handler[16] = {
-	do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
-	do_meta, do_ascii, do_lock, do_lowercase,
-	do_ignore, do_ignore, do_ignore, do_ignore
-};
-
-typedef void (*void_fnp)(void);
-typedef void (void_fn)(void);
-
-static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle,
-	num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose,
-	SAK, decr_console, incr_console, spawn_console, bare_num;
-
-static void_fnp spec_fn_table[] = {
-	do_null,	enter,		show_ptregs,	show_mem,
-	show_state,	send_intr,	lastcons,	caps_toggle,
-	num,		hold,		scroll_forw,	scroll_back,
-	boot_it,	caps_on,	compose,	SAK,
-	decr_console,	incr_console,	spawn_console,	bare_num
-};
-
-/* maximum values each key_handler can handle */
-#ifndef CONFIG_PCI
-const int max_vals[] = {
-	255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
-	NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
-	255, NR_ASCII - 1, NR_LOCK - 1, 255,
-	NR_LOCK - 1
-};
-
-const int NR_TYPES = SIZE(max_vals);
-#endif
-
-static void put_queue(int);
-static unsigned char handle_diacr(unsigned char);
-
-/* pt_regs - set by keyboard_interrupt(), used by show_ptregs() */
-static struct pt_regs * pt_regs;
-
-#ifdef CONFIG_MAGIC_SYSRQ
-unsigned char sun_sysrq_xlate[128] =
-	"\0\0\0\0\0\201\202\212\203\213\204\214\205\0\206\0"	/* 0x00 - 0x0f */
-	"\207\210\211\0\0\0\0\0\0\0\0\0\0\03312"		/* 0x10 - 0x1f */
-	"34567890-=`\177\0=/*"					/* 0x20 - 0x2f */
-	"\0\0.\0\0\011qwertyuiop"				/* 0x30 - 0x3f */
-	"[]\177\000789-\0\0\0\0\0asd"				/* 0x40 - 0x4f */
-	"fghjkl;'\\\015\0154560\0"				/* 0x50 - 0x5f */
-	"\0\0\0\0zxcvbnm,./\0\012"				/* 0x60 - 0x6f */
-	"123\0\0\0\0\0\0 \0\0\0\0\0\0";				/* 0x70 - 0x7f */
-#endif
-
-volatile unsigned char sunkbd_layout;
-volatile unsigned char sunkbd_type;
-#define SUNKBD_TYPE2        0x02
-#define SUNKBD_TYPE3        0x03
-#define SUNKBD_TYPE4        0x04
-
-#define SUNKBD_LOUT_TYP4    	0x00
-#define SUNKBD_LOUT_TYP5_MASK   0x20
-
-volatile int kbd_reset_pending;
-volatile int kbd_layout_pending;
-
-/* commands */
-#define SKBDCMD_RESET       0x1
-#define SKBDCMD_GLAYOUT     0xf
-#define SKBDCMD_BELLON      0x2
-#define SKBDCMD_BELLOFF     0x3
-#define SKBDCMD_SETLED      0xe
-#define SKBDCMD_NOCLICK     0xb
-#define SKBDCMD_CLICK       0xa
-
-static unsigned char sunkbd_clickp;
-
-/* The led set commands require sending the SETLED byte then
- * a byte encoding which led's to have set.  Here are the bit
- * values, a bit set = led-on.
- */
-#define LED_NLOCK           0x1   /* Num-lock */
-#define LED_CMPOSE          0x2   /* Compose */
-#define LED_SCRLCK          0x4   /* Scroll-lock */
-#define LED_CLOCK           0x8   /* Caps-lock */
-
-/* Special state characters */
-#define SKBD_RESET          0xff
-#define SKBD_ALLUP          0x7f
-#define SKBD_LYOUT          0xfe
-
-/* On the Sparc the keyboard could be one of two things.
- * It could be a real keyboard speaking over one of the
- * channels of the second zs8530 chip (other channel is
- * used by the Sun mouse).  Else we have serial console
- * going, and thus the other zs8530 chip is who we speak
- * to.  Either way, we communicate through the zs8530
- * driver for all our I/O.
- */
-
-#define SUNKBD_UBIT     0x80      /* If set, key went up */
-#define SUNKBD_KMASK    0x7f      /* Other bits are the keycode */
-
-#define KEY_LSHIFT      0x81
-#define KEY_RSHIFT      0x82
-#define KEY_CONTROL     0x83
-#define KEY_NILL        0x84
-#define KEY_CAPSLOCK    0x85
-#define KEY_ALT         0x86
-#define KEY_L1          0x87
-
-/* Due to sun_kbd_init() being called before rs_init(), and sun_kbd_init() doing:
- *
- *	tasklet_enable(&keyboard_tasklet);
- *	tasklet_schedule(&keyboard_tasklet);
- *
- * this might well be called before some driver has claimed interest in
- * handling the keyboard input/output. So we need to assign an initial nop.
- */
-static void nop_kbd_put_char(unsigned char c) { }
-static void (*kbd_put_char)(unsigned char) = nop_kbd_put_char;
-
-/* Must be invoked under sunkbd_lock. */
-static inline void send_cmd(unsigned char c)
-{
-	kbd_put_char(c);
-}
-
-/* kbd_bh() calls this to send the SKBDCMD_SETLED to the sun keyboard
- * with the proper bit pattern for the leds to be set.  It basically
- * converts the kbd->ledflagstate values to corresponding sun kbd led
- * bit value.
- */
-static inline unsigned char vcleds_to_sunkbd(unsigned char vcleds)
-{
-	unsigned char retval = 0;
-
-	if(vcleds & (1<<VC_SCROLLOCK))
-		retval |= LED_SCRLCK;
-	if(vcleds & (1<<VC_NUMLOCK))
-		retval |= LED_NLOCK;
-	if(vcleds & (1<<VC_CAPSLOCK))
-		retval |= LED_CLOCK;
-	if(compose_led_on)
-		retval |= LED_CMPOSE;
-	return retval;
-}
-
-/*
- * Translation of escaped scancodes to keycodes.
- * This is now user-settable.
- * The keycodes 1-88,96-111,119 are fairly standard, and
- * should probably not be changed - changing might confuse X.
- * X also interprets scancode 0x5d (KEY_Begin).
- *
- * For 1-88 keycode equals scancode.
- */
-
-#define E0_KPENTER 96
-#define E0_RCTRL   97
-#define E0_KPSLASH 98
-#define E0_PRSCR   99
-#define E0_RALT    100
-#define E0_BREAK   101  /* (control-pause) */
-#define E0_HOME    102
-#define E0_UP      103
-#define E0_PGUP    104
-#define E0_LEFT    105
-#define E0_RIGHT   106
-#define E0_END     107
-#define E0_DOWN    108
-#define E0_PGDN    109
-#define E0_INS     110
-#define E0_DEL     111
-
-#define E1_PAUSE   119
-
-/*
- * The keycodes below are randomly located in 89-95,112-118,120-127.
- * They could be thrown away (and all occurrences below replaced by 0),
- * but that would force many users to use the `setkeycodes' utility, where
- * they needed not before. It does not matter that there are duplicates, as
- * long as no duplication occurs for any single keyboard.
- */
-#define SC_LIM 89
-
-#define FOCUS_PF1 85           /* actual code! */
-#define FOCUS_PF2 89
-#define FOCUS_PF3 90
-#define FOCUS_PF4 91
-#define FOCUS_PF5 92
-#define FOCUS_PF6 93
-#define FOCUS_PF7 94
-#define FOCUS_PF8 95
-#define FOCUS_PF9 120
-#define FOCUS_PF10 121
-#define FOCUS_PF11 122
-#define FOCUS_PF12 123
-
-#define JAP_86     124
-/* tfj@olivia.ping.dk:
- * The four keys are located over the numeric keypad, and are
- * labelled A1-A4. It's an rc930 keyboard, from
- * Regnecentralen/RC International, Now ICL.
- * Scancodes: 59, 5a, 5b, 5c.
- */
-#define RGN1 124
-#define RGN2 125
-#define RGN3 126
-#define RGN4 127
-
-static unsigned char high_keys[128 - SC_LIM] = {
-  RGN1, RGN2, RGN3, RGN4, 0, 0, 0,                   /* 0x59-0x5f */
-  0, 0, 0, 0, 0, 0, 0, 0,                            /* 0x60-0x67 */
-  0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,          /* 0x68-0x6f */
-  0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,    /* 0x70-0x77 */
-  FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,        /* 0x78-0x7b */
-  FOCUS_PF8, JAP_86, FOCUS_PF10, 0                   /* 0x7c-0x7f */
-};
-
-/* BTC */
-#define E0_MACRO   112
-/* LK450 */
-#define E0_F13     113
-#define E0_F14     114
-#define E0_HELP    115
-#define E0_DO      116
-#define E0_F17     117
-#define E0_KPMINPLUS 118
-/*
- * My OmniKey generates e0 4c for  the "OMNI" key and the
- * right alt key does nada. [kkoller@nyx10.cs.du.edu]
- */
-#define E0_OK	124
-/*
- * New microsoft keyboard is rumoured to have
- * e0 5b (left window button), e0 5c (right window button),
- * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
- * [or: Windows_L, Windows_R, TaskMan]
- */
-#define E0_MSLW	125
-#define E0_MSRW	126
-#define E0_MSTM	127
-
-static unsigned char e0_keys[128] = {
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x00-0x07 */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x08-0x0f */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x10-0x17 */
-  0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,	      /* 0x18-0x1f */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x20-0x27 */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x28-0x2f */
-  0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,	      /* 0x30-0x37 */
-  E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,	      /* 0x38-0x3f */
-  E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,	      /* 0x40-0x47 */
-  E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
-  E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,	      /* 0x50-0x57 */
-  0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,	      /* 0x58-0x5f */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x60-0x67 */
-  0, 0, 0, 0, 0, 0, 0, E0_MACRO,		      /* 0x68-0x6f */
-  0, 0, 0, 0, 0, 0, 0, 0,			      /* 0x70-0x77 */
-  0, 0, 0, 0, 0, 0, 0, 0			      /* 0x78-0x7f */
-};
-
-/* we use this map to determine if a particular key should not be
-   autorepeated. We don't autorepeat CONTROL, LSHIFT, CAPS,
-   ALT, LMETA, RSHIFT, RMETA, ALTG and COMPOSE */
-static unsigned char norepeat_keys[128] = {
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,  /* 0x00-0x0f */
-	0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 0x10-0x1f */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 0x20-0x2f */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 0x30-0x3f */
-	0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,  /* 0x40-0x4f */
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 0x50-0x5f */
-	0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,  /* 0x60-0x6f */
-	0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0,  /* 0x70-0x7f */
-};
-
-
-int sun_setkeycode(unsigned int scancode, unsigned int keycode)
-{
-	if (scancode < SC_LIM || scancode > 255 || keycode > 127)
-	  return -EINVAL;
-	if (scancode < 128)
-	  high_keys[scancode - SC_LIM] = keycode;
-	else
-	  e0_keys[scancode - 128] = keycode;
-	return 0;
-}
-
-int sun_getkeycode(unsigned int scancode)
-{
-	return
-	  (scancode < SC_LIM || scancode > 255) ? -EINVAL :
-	  (scancode < 128) ? high_keys[scancode - SC_LIM] :
-	    e0_keys[scancode - 128];
-}
-
-static void __sunkbd_inchar(unsigned char ch, struct pt_regs *regs);
-void sunkbd_inchar(unsigned char ch, struct pt_regs *regs);
-static void keyboard_timer (unsigned long ignored);
-
-static struct timer_list
-auto_repeat_timer = { function: keyboard_timer };
-
-/* Keeps track of the last pressed key */
-static unsigned char last_keycode;
-
-static void
-keyboard_timer (unsigned long ignored)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&sunkbd_lock, flags);
-
-	/* Auto repeat: send regs = 0 to indicate autorepeat */
-	__sunkbd_inchar (last_keycode, 0);
-	del_timer (&auto_repeat_timer);
-	if (kbd_rate_ticks) {
-		auto_repeat_timer.expires = jiffies + kbd_rate_ticks;
-		add_timer (&auto_repeat_timer);
-	}
-
-	spin_unlock_irqrestore(&sunkbd_lock, flags);
-}
-
-#ifndef CONFIG_PCI
-DECLARE_TASKLET_DISABLED(keyboard_tasklet, sun_kbd_bh, 0);
-#endif
-
-/* #define SKBD_DEBUG */
-/* This is our keyboard 'interrupt' routine.
- * Must run under sunkbd_lock.
- */
-static void __sunkbd_inchar(unsigned char ch, struct pt_regs *regs)
-{
-	unsigned char keycode;
-	char up_flag;                          /* 0 or SUNKBD_UBIT */
-	char raw_mode;
-
-	if(ch == SKBD_RESET) {
-		kbd_reset_pending = 1;
-		goto out;
-	}
-	if(ch == SKBD_LYOUT) {
-		kbd_layout_pending = 1;
-		goto out;
-	}
-	if(kbd_reset_pending) {
-		sunkbd_type = ch;
-		kbd_reset_pending = 0;
-		if(ch == SUNKBD_TYPE4)
-			send_cmd(SKBDCMD_GLAYOUT);
-		goto out;
-	} else if(kbd_layout_pending) {
-		sunkbd_layout = ch;
-		kbd_layout_pending = 0;
-		goto out;
-	} else if(ch == SKBD_ALLUP) {
-		del_timer (&auto_repeat_timer);
-		memset(key_down, 0, sizeof(key_down));
-		sun_compute_shiftstate();
-		goto out;
-	}
-#ifdef SKBD_DEBUG
-	if(ch == 0x7f)
-		printk("KBD<ALL KEYS UP>");
-	else
-		printk("KBD<%x %s>", ch,
-		       ((ch&0x80) ? "UP" : "DOWN"));
-#endif
-
-	/* Whee, a real character. */
-	if(regs) {
-		pt_regs = regs;
-		last_keycode = keycode = ch;
-	} else {
-		keycode = ch;
-	}
-	
-	do_poke_blanked_console = 1;
-	schedule_console_callback();
-	add_keyboard_randomness(keycode);
-
-	tty = ttytab? ttytab[fg_console]: NULL;
-	if (tty && (!tty->driver_data)) {
-		/* This is to workaround ugly bug in tty_io.c, which
-                   does not do locking when it should */
-		tty = NULL;
-	}
-	kbd = kbd_table + fg_console;
-	if((raw_mode = (kbd->kbdmode == VC_RAW))) {
-		if (kbd_redirected == fg_console+1)
-			push_kbd (keycode);
-		else
-			put_queue(keycode);
-		/* we do not return yet, because we want to maintain
-		 * the key_down array, so that we have the correct
-		 * values  when finishing RAW mode or when changing VT's.
-		 */
-	}
-	up_flag = (keycode & SUNKBD_UBIT);  /* The 'up' bit */
-	keycode &= SUNKBD_KMASK;            /* all the rest */
-	del_timer (&auto_repeat_timer);
-	if(up_flag) {
-		rep = 0;
-		clear_bit(keycode, key_down);
-	} else {
-		if (!norepeat_keys[keycode]) {
-			if (kbd_rate_ticks) {
-				auto_repeat_timer.expires =
-						jiffies + kbd_delay_ticks;
-				add_timer (&auto_repeat_timer);
-			}
-		}
-		rep = test_and_set_bit(keycode, key_down);
-	}
-
-#ifdef CONFIG_MAGIC_SYSRQ			/* Handle the SysRq hack */
-	if (l1a_state.l1_down) {
-		if (!up_flag)
-			handle_sysrq(sun_sysrq_xlate[keycode], pt_regs, kbd, tty);
-		goto out;
-	}
-#endif
-
-	if(raw_mode)
-		goto out;
-
-	if(kbd->kbdmode == VC_MEDIUMRAW) {
-		put_queue(keycode + up_flag);
-		goto out;
-	}
-
- 	/*
-	 * Small change in philosophy: earlier we defined repetition by
-	 *	 rep = keycode == prev_keycode;
-	 *	 prev_keycode = keycode;
-	 * but now by the fact that the depressed key was down already.
-	 * Does this ever make a difference? Yes.
-	 */
-
-	/*
- 	 *  Repeat a key only if the input buffers are empty or the
- 	 *  characters get echoed locally. This makes key repeat usable
- 	 *  with slow applications and under heavy loads.
-	 */
-	if (!rep ||
-	    (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
-	     (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
-		u_short keysym;
-		u_char type;
-
-		/* the XOR below used to be an OR */
-		int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate;
-		ushort *key_map = key_maps[shift_final];
-
-		if (key_map != NULL) {
-			keysym = key_map[keycode];
-			type = KTYP(keysym);
-
-			if (type >= 0xf0) {
-			    type -= 0xf0;
-			    if (type == KT_LETTER) {
-				type = KT_LATIN;
-				if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
-				    key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
-				    if (key_map)
-				      keysym = key_map[keycode];
-				}
-			    }
-			    (*key_handler[type])(keysym & 0xff, up_flag);
-			    if (type != KT_SLOCK)
-			      kbd->slockstate = 0;
-			}
-		} else {
-			/* maybe beep? */
-			/* we have at least to update shift_state */
-			sun_compute_shiftstate();
-		}
-	}
-out:
-	tasklet_schedule(&keyboard_tasklet);
-}
-
-void sunkbd_inchar(unsigned char ch, struct pt_regs *regs)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&sunkbd_lock, flags);
-	__sunkbd_inchar(ch, regs);
-	spin_unlock_irqrestore(&sunkbd_lock, flags);
-}
-
-static void put_queue(int ch)
-{
-	if (tty) {
-		tty_insert_flip_char(tty, ch, 0);
-		con_schedule_flip(tty);
-	}
-}
-
-static void puts_queue(char *cp)
-{
-	if (!tty)
-		return;
-
-	while (*cp) {
-		tty_insert_flip_char(tty, *cp, 0);
-		cp++;
-	}
-	con_schedule_flip(tty);
-}
-
-static void applkey(int key, char mode)
-{
-	static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
-
-	buf[1] = (mode ? 'O' : '[');
-	buf[2] = key;
-	puts_queue(buf);
-}
-
-static void enter(void)
-{
-	put_queue(13);
-	if (vc_kbd_mode(kbd,VC_CRLF))
-		put_queue(10);
-}
-
-static void caps_toggle(void)
-{
-	if (rep)
-		return;
-	chg_vc_kbd_led(kbd, VC_CAPSLOCK);
-}
-
-static void caps_on(void)
-{
-	if (rep)
-		return;
-	set_vc_kbd_led(kbd, VC_CAPSLOCK);
-}
-
-static void show_ptregs(void)
-{
-	if (pt_regs)
-		show_regs(pt_regs);
-}
-
-static void hold(void)
-{
-	if (rep || !tty)
-		return;
-
-	/*
-	 * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
-	 * these routines are also activated by ^S/^Q.
-	 * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
-	 */
-	if (tty->stopped)
-		start_tty(tty);
-	else
-		stop_tty(tty);
-}
-
-static void num(void)
-{
-	if (vc_kbd_mode(kbd,VC_APPLIC))
-		applkey('P', 1);
-	else
-		bare_num();
-}
-
-/*
- * Bind this to Shift-NumLock if you work in application keypad mode
- * but want to be able to change the NumLock flag.
- * Bind this to NumLock if you prefer that the NumLock key always
- * changes the NumLock flag.
- */
-static void bare_num(void)
-{
-	if (!rep)
-		chg_vc_kbd_led(kbd,VC_NUMLOCK);
-}
-
-static void lastcons(void)
-{
-	/* switch to the last used console, ChN */
-	set_console(last_console);
-}
-
-static void decr_console(void)
-{
-	int i;
- 
-	for (i = fg_console-1; i != fg_console; i--) {
-		if (i == -1)
-			i = MAX_NR_CONSOLES-1;
-		if (vc_cons_allocated(i))
-			break;
-	}
-	set_console(i);
-}
-
-static void incr_console(void)
-{
-	int i;
-
-	for (i = fg_console+1; i != fg_console; i++) {
-		if (i == MAX_NR_CONSOLES)
-			i = 0;
-		if (vc_cons_allocated(i))
-			break;
-	}
-	set_console(i);
-}
-
-static void send_intr(void)
-{
-	if (!tty)
-		return;
-	tty_insert_flip_char(tty, 0, TTY_BREAK);
-	con_schedule_flip(tty);
-}
-
-static void scroll_forw(void)
-{
-	scrollfront(0);
-}
-
-static void scroll_back(void)
-{
-	scrollback(0);
-}
-
-static void boot_it(void)
-{
-	extern int obp_system_intr(void);
-
-	if (!obp_system_intr())
-		ctrl_alt_del();
-	/* sigh.. attempt to prevent multiple entry */
-	last_keycode=1;
-	rep = 0;
-}
-
-static void compose(void)
-{
-	dead_key_next = 1;
-	compose_led_on = 1;
-	set_leds();
-}
-
-#ifdef CONFIG_PCI
-extern int spawnpid, spawnsig;
-#else
-int spawnpid, spawnsig;
-#endif
-
-
-static void spawn_console(void)
-{
-        if (spawnpid)
-	   if(kill_proc(spawnpid, spawnsig, 1))
-	     spawnpid = 0;
-}
-
-static void SAK(void)
-{
-	do_SAK(tty);
-#if 0
-	/*
-	 * Need to fix SAK handling to fix up RAW/MEDIUM_RAW and
-	 * vt_cons modes before we can enable RAW/MEDIUM_RAW SAK
-	 * handling.
-	 * 
-	 * We should do this some day --- the whole point of a secure
-	 * attention key is that it should be guaranteed to always
-	 * work.
-	 */
-	reset_vc(fg_console);
-	do_unblank_screen();	/* not in interrupt routine? */
-#endif
-}
-
-static void do_ignore(unsigned char value, char up_flag)
-{
-}
-
-static void do_null()
-{
-	sun_compute_shiftstate();
-}
-
-static void do_spec(unsigned char value, char up_flag)
-{
-	if (up_flag)
-		return;
-	if (value >= SIZE(spec_fn_table))
-		return;
-	spec_fn_table[value]();
-}
-
-static void do_lowercase(unsigned char value, char up_flag)
-{
-	printk("keyboard.c: do_lowercase was called - impossible\n");
-}
-
-static void do_self(unsigned char value, char up_flag)
-{
-	if (up_flag)
-		return;		/* no action, if this is a key release */
-
-	if (diacr) {
-		value = handle_diacr(value);
-		compose_led_on = 0;
-		set_leds();
-	}
-
-	if (dead_key_next) {
-		dead_key_next = 0;
-		diacr = value;
-		return;
-	}
-
-	put_queue(value);
-}
-
-#define A_GRAVE  '`'
-#define A_ACUTE  '\''
-#define A_CFLEX  '^'
-#define A_TILDE  '~'
-#define A_DIAER  '"'
-#define A_CEDIL  ','
-static unsigned char ret_diacr[NR_DEAD] =
-	{A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL };
-
-/* If a dead key pressed twice, output a character corresponding to it,	*/
-/* otherwise just remember the dead key.				*/
-
-static void do_dead(unsigned char value, char up_flag)
-{
-	if (up_flag)
-		return;
-
-	value = ret_diacr[value];
-	if (diacr == value) {   /* pressed twice */
-		diacr = 0;
-		put_queue(value);
-		return;
-	}
-	diacr = value;
-}
-
-
-/* If space is pressed, return the character corresponding the pending	*/
-/* dead key, otherwise try to combine the two.				*/
-
-unsigned char handle_diacr(unsigned char ch)
-{
-	int d = diacr;
-	int i;
-
-	diacr = 0;
-	if (ch == ' ')
-		return d;
-
-	for (i = 0; i < accent_table_size; i++) {
-		if (accent_table[i].diacr == d && accent_table[i].base == ch)
-			return accent_table[i].result;
-	}
-
-	put_queue(d);
-	return ch;
-}
-
-static void do_cons(unsigned char value, char up_flag)
-{
-	if (up_flag)
-		return;
-	set_console(value);
-}
-
-static void do_fn(unsigned char value, char up_flag)
-{
-	if (up_flag)
-		return;
-	if (value < SIZE(func_table)) {
-		if (func_table[value])
-			puts_queue(func_table[value]);
-	} else
-		printk("do_fn called with value=%d\n", value);
-}
-
-static void do_pad(unsigned char value, char up_flag)
-{
-	static const char *pad_chars = "0123456789+-*/\015,.?";
-	static const char *app_map = "pqrstuvwxylSRQMnn?";
-
-	if (up_flag)
-		return;		/* no action, if this is a key release */
-
-	/* kludge... shift forces cursor/number keys */
-	if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
-		applkey(app_map[value], 1);
-		return;
-	}
-
-	if (!vc_kbd_led(kbd,VC_NUMLOCK))
-		switch (value) {
-			case KVAL(K_PCOMMA):
-			case KVAL(K_PDOT):
-				do_fn(KVAL(K_REMOVE), 0);
-				return;
-			case KVAL(K_P0):
-				do_fn(KVAL(K_INSERT), 0);
-				return;
-			case KVAL(K_P1):
-				do_fn(KVAL(K_SELECT), 0);
-				return;
-			case KVAL(K_P2):
-				do_cur(KVAL(K_DOWN), 0);
-				return;
-			case KVAL(K_P3):
-				do_fn(KVAL(K_PGDN), 0);
-				return;
-			case KVAL(K_P4):
-				do_cur(KVAL(K_LEFT), 0);
-				return;
-			case KVAL(K_P6):
-				do_cur(KVAL(K_RIGHT), 0);
-				return;
-			case KVAL(K_P7):
-				do_fn(KVAL(K_FIND), 0);
-				return;
-			case KVAL(K_P8):
-				do_cur(KVAL(K_UP), 0);
-				return;
-			case KVAL(K_P9):
-				do_fn(KVAL(K_PGUP), 0);
-				return;
-			case KVAL(K_P5):
-				applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
-				return;
-		}
-
-	put_queue(pad_chars[value]);
-	if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
-		put_queue(10);
-}
-
-static void do_cur(unsigned char value, char up_flag)
-{
-	static const char *cur_chars = "BDCA";
-	if (up_flag)
-		return;
-
-	applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
-}
-
-static void do_shift(unsigned char value, char up_flag)
-{
-	int old_state = shift_state;
-
-	if (rep)
-		return;
-
-	/* Mimic typewriter:
-	   a CapsShift key acts like Shift but undoes CapsLock */
-	if (value == KVAL(K_CAPSSHIFT)) {
-		value = KVAL(K_SHIFT);
-		if (!up_flag)
-			clr_vc_kbd_led(kbd, VC_CAPSLOCK);
-	}
-
-	if (up_flag) {
-		/* handle the case that two shift or control
-		   keys are depressed simultaneously */
-		if (k_down[value])
-			k_down[value]--;
-	} else
-		k_down[value]++;
-
-	if (k_down[value])
-		shift_state |= (1 << value);
-	else
-		shift_state &= ~ (1 << value);
-
-	/* kludge, no joke... */
-	if (up_flag && shift_state != old_state && npadch != -1) {
-		put_queue(npadch & 0xff);
-		npadch = -1;
-	}
-}
-
-/* called after returning from RAW mode or when changing consoles -
-   recompute k_down[] and shift_state from key_down[] */
-/* maybe called when keymap is undefined, so that shiftkey release is seen */
-void sun_compute_shiftstate(void)
-{
-	int i, j, k, sym, val;
-
-	shift_state = 0;
-	for(i=0; i < SIZE(k_down); i++)
-	  k_down[i] = 0;
-
-	for(i=0; i < SIZE(key_down); i++)
-	  if(key_down[i]) {	/* skip this word if not a single bit on */
-	    k = i*BITS_PER_LONG;
-	    for(j=0; j<BITS_PER_LONG; j++,k++)
-	      if(test_bit(k, key_down)) {
-		sym = U(plain_map[k]);
-		if(KTYP(sym) == KT_SHIFT) {
-		  val = KVAL(sym);
-		  if (val == KVAL(K_CAPSSHIFT))
-		    val = KVAL(K_SHIFT);
-		  k_down[val]++;
-		  shift_state |= (1<<val);
-		}
-	      }
-	  }
-}
-
-static void do_meta(unsigned char value, char up_flag)
-{
-	if (up_flag)
-		return;
-
-	if (vc_kbd_mode(kbd, VC_META)) {
-		put_queue('\033');
-		put_queue(value);
-	} else
-		put_queue(value | 0x80);
-}
-
-static void do_ascii(unsigned char value, char up_flag)
-{
-	int base;
-
-	if (up_flag)
-		return;
-
-	if (value < 10)    /* decimal input of code, while Alt depressed */
-	    base = 10;
-	else {       /* hexadecimal input of code, while AltGr depressed */
-	    value -= 10;
-	    base = 16;
-	}
-
-	if (npadch == -1)
-	  npadch = value;
-	else
-	  npadch = npadch * base + value;
-}
-
-static void do_lock(unsigned char value, char up_flag)
-{
-	if (up_flag || rep)
-		return;
-	chg_vc_kbd_lock(kbd, value);
-}
-
-/*
- * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
- * or (ii) whatever pattern of lights people want to show using KDSETLED,
- * or (iii) specified bits of specified words in kernel memory.
- */
-
-static unsigned char ledstate = 0xff; /* undefined */
-static unsigned char ledioctl;
-
-unsigned char sun_getledstate(void) {
-    return ledstate;
-}
-
-void sun_setledstate(struct kbd_struct *kbd, unsigned int led) {
-    if (!(led & ~7)) {
-	ledioctl = led;
-	kbd->ledmode = LED_SHOW_IOCTL;
-    } else
-	kbd->ledmode = LED_SHOW_FLAGS;
-    set_leds();
-}
-
-static struct ledptr {
-    unsigned int *addr;
-    unsigned int mask;
-    unsigned char valid:1;
-} ledptrs[3];
-
-void register_leds(int console, unsigned int led,
-		   unsigned int *addr, unsigned int mask) {
-    struct kbd_struct *kbd = kbd_table + console;
-    if (led < 3) {
-	ledptrs[led].addr = addr;
-	ledptrs[led].mask = mask;
-	ledptrs[led].valid = 1;
-	kbd->ledmode = LED_SHOW_MEM;
-    } else
-	kbd->ledmode = LED_SHOW_FLAGS;
-}
-
-static inline unsigned char getleds(void){
-    struct kbd_struct *kbd = kbd_table + fg_console;
-    unsigned char leds;
-
-    if (kbd->ledmode == LED_SHOW_IOCTL)
-      return ledioctl;
-    leds = kbd->ledflagstate;
-    if (kbd->ledmode == LED_SHOW_MEM) {
-	if (ledptrs[0].valid) {
-	    if (*ledptrs[0].addr & ledptrs[0].mask)
-	      leds |= 1;
-	    else
-	      leds &= ~1;
-	}
-	if (ledptrs[1].valid) {
-	    if (*ledptrs[1].addr & ledptrs[1].mask)
-	      leds |= 2;
-	    else
-	      leds &= ~2;
-	}
-	if (ledptrs[2].valid) {
-	    if (*ledptrs[2].addr & ledptrs[2].mask)
-	      leds |= 4;
-	    else
-	      leds &= ~4;
-	}
-    }
-    return leds;
-}
-
-/*
- * This routine is the bottom half of the keyboard interrupt
- * routine, and runs with all interrupts enabled. It does
- * console changing, led setting and copy_to_cooked, which can
- * take a reasonably long time.
- *
- * Aside from timing (which isn't really that important for
- * keyboard interrupts as they happen often), using the software
- * interrupt routines for this thing allows us to easily mask
- * this when we don't want any of the above to happen. Not yet
- * used, but this allows for easy and efficient race-condition
- * prevention later on.
- */
-static unsigned char sunkbd_ledstate = 0xff; /* undefined */
-void sun_kbd_bh(unsigned long dummy)
-{
-	unsigned long flags;
-	unsigned char leds, kbd_leds;
-
-	spin_lock_irqsave(&sunkbd_lock, flags);
-
-	leds = getleds();
-	kbd_leds = vcleds_to_sunkbd(leds);
-	if (kbd_leds != sunkbd_ledstate) {
-		ledstate = leds;
-		sunkbd_ledstate = kbd_leds;
-		send_cmd(SKBDCMD_SETLED);
-		send_cmd(kbd_leds);
-	}
-
-	spin_unlock_irqrestore(&sunkbd_lock, flags);
-}
-
-/* Support for keyboard "beeps". */ 
-
-/* Timer routine to turn off the beep after the interval expires. */
-static void sunkbd_kd_nosound(unsigned long __unused)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&sunkbd_lock, flags);
-	send_cmd(SKBDCMD_BELLOFF);
-	spin_unlock_irqrestore(&sunkbd_lock, flags);
-}
-
-/*
- * Initiate a keyboard beep. If the frequency is zero, then we stop
- * the beep. Any other frequency will start a monotone beep. The beep
- * will be stopped by a timer after "ticks" jiffies. If ticks is 0,
- * then we do not start a timer.
- */
-static void sunkbd_kd_mksound(unsigned int hz, unsigned int ticks)
-{
-	unsigned long flags;
-	static struct timer_list sound_timer = { function: sunkbd_kd_nosound };
-
-	spin_lock_irqsave(&sunkbd_lock, flags);
-
-	del_timer(&sound_timer);
-
-	if (hz) {
-		send_cmd(SKBDCMD_BELLON);
-		if (ticks) {
-			sound_timer.expires = jiffies + ticks;
-			add_timer(&sound_timer);
-		}
-	} else
-		send_cmd(SKBDCMD_BELLOFF);
-
-	spin_unlock_irqrestore(&sunkbd_lock, flags);
-}
-
-extern void (*kd_mksound)(unsigned int hz, unsigned int ticks);
-
-int __init sun_kbd_init(void)
-{
-	int i, opt_node;
-	struct kbd_struct kbd0;
-	extern struct tty_driver console_driver;
-
-	kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
-	kbd0.ledmode = LED_SHOW_FLAGS;
-	kbd0.lockstate = KBD_DEFLOCK;
-	kbd0.slockstate = 0;
-	kbd0.modeflags = KBD_DEFMODE;
-	kbd0.kbdmode = VC_XLATE;
- 
-	for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
-		kbd_table[i] = kbd0;
-
-	ttytab = console_driver.table;
-
-	kd_mksound = sunkbd_kd_mksound;
-
-	/* XXX Check keyboard-click? property in 'options' PROM node XXX */
-	if(sparc_cpu_model != sun4) {
-		opt_node = prom_getchild(prom_root_node);
-		opt_node = prom_searchsiblings(opt_node, "options");
-		i = prom_getintdefault(opt_node, "keyboard-click?", -1);
-		if(i != -1)
-			sunkbd_clickp = 1;
-		else
-			sunkbd_clickp = 0;
-	} else {
-		sunkbd_clickp = 0;
-	}
-
-	keyboard_tasklet.func = sun_kbd_bh;
-
-	tasklet_enable(&keyboard_tasklet);
-	tasklet_schedule(&keyboard_tasklet);
-
-	return 0;
-}
-
-/* /dev/kbd support */
-
-#define KBD_QSIZE 32
-static Firm_event kbd_queue [KBD_QSIZE];
-static int kbd_head, kbd_tail;
-static spinlock_t kbd_queue_lock = SPIN_LOCK_UNLOCKED;
-char kbd_opened;
-static int kbd_active = 0;
-static DECLARE_WAIT_QUEUE_HEAD(kbd_wait);
-static struct fasync_struct *kb_fasync;
-
-void
-push_kbd (int scan)
-{
-	unsigned long flags;
-	int next;
-
-	if (scan == KBD_IDLE)
-		return;
-
-	spin_lock_irqsave(&kbd_queue_lock, flags);
-	next = (kbd_head + 1) % KBD_QSIZE;
-	if (next != kbd_tail){
-		kbd_queue [kbd_head].id = scan & KBD_KEYMASK;
-		kbd_queue [kbd_head].value=scan & KBD_UP ? VKEY_UP : VKEY_DOWN;
-		kbd_queue [kbd_head].time = xtime;
-		kbd_head = next;
-	}
-	spin_unlock_irqrestore(&kbd_queue_lock, flags);
-
-	kill_fasync (&kb_fasync, SIGIO, POLL_IN);
-	wake_up_interruptible (&kbd_wait);
-}
-
-static ssize_t
-kbd_read (struct file *f, char *buffer, size_t count, loff_t *ppos)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-	char *end, *p;
-
-	/* Return EWOULDBLOCK, because this is what the X server expects */
-	if (kbd_head == kbd_tail){
-		if (f->f_flags & O_NONBLOCK)
-			return -EWOULDBLOCK;
-		add_wait_queue (&kbd_wait, &wait);
-repeat:
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (kbd_head == kbd_tail && !signal_pending(current)) {
-			schedule();
-			goto repeat;
-		}
-		current->state = TASK_RUNNING;
-		remove_wait_queue (&kbd_wait, &wait);
-	}
-	/* There is data in the keyboard, fill the user buffer */
-	end = buffer+count;
-	p = buffer;
-	spin_lock_irqsave(&kbd_queue_lock, flags);
-	for (; p < end && kbd_head != kbd_tail;){
-		Firm_event this_event = kbd_queue[kbd_tail];
-
-		kbd_tail = (kbd_tail + 1) % KBD_QSIZE;
-
-		spin_unlock_irqrestore(&kbd_queue_lock, flags);
-
-#ifdef CONFIG_SPARC32_COMPAT
-		if (test_thread_flag(TIF_32BIT)) {
-			if (copy_to_user((Firm_event *)p, &this_event,
-					 sizeof(Firm_event)-sizeof(struct timeval)))
-				return -EFAULT;
-			p += sizeof(Firm_event)-sizeof(struct timeval);
-			if (__put_user(this_event.time.tv_sec, (u32 *)p))
-				return -EFAULT;
-			p += sizeof(u32);
-			if (__put_user(this_event.time.tv_usec, (u32 *)p))
-				return -EFAULT;
-			p += sizeof(u32);
-		} else
-#endif
-		{
-			if (copy_to_user((Firm_event *)p, &this_event, 
-					 sizeof(Firm_event)))
-				return -EFAULT;
-			p += sizeof (Firm_event);
-		}
-#ifdef KBD_DEBUG
-		printk ("[%s]", this_event.value == VKEY_UP ? "UP" : "DOWN");
-#endif
-
-		spin_lock_irqsave(&kbd_queue_lock, flags);
-	}
-
-	spin_unlock_irqrestore(&kbd_queue_lock, flags);
-
-	return p-buffer;
-}
-
-/* Needed by X */
-static int kbd_fasync (int fd, struct file *filp, int on)
-{
-	int retval;
-
-	retval = fasync_helper (fd, filp, on, &kb_fasync);
-	if (retval < 0)
-		return retval;
-	return 0;
-}
-
-static unsigned int kbd_poll (struct file *f, poll_table *wait)
-{
-	poll_wait(f, &kbd_wait, wait);
-	if (kbd_head != kbd_tail)
-		return POLLIN | POLLRDNORM;
-	return 0;
-}
-
-static int
-kbd_ioctl (struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
-{
-	unsigned char c;
-	unsigned char leds = 0;
-	int value;
-
-	switch (cmd){
-	case KIOCTYPE:		  /* return keyboard type */
-		if (put_user(sunkbd_type, (int *) arg))
-			return -EFAULT;
-		break;
-	case KIOCGTRANS:
-		if (put_user(TR_UNTRANS_EVENT, (int *) arg))
-			return -EFAULT;
-		break;
-	case KIOCTRANS:
-		if (get_user(value, (int *) arg))
-			return -EFAULT;
-		if (value != TR_UNTRANS_EVENT)
-			return -EINVAL;
-		break;
-	case KIOCLAYOUT:
-		if (put_user(sunkbd_layout, (int *) arg))
-			return -EFAULT;
-		break;
-	case KIOCSDIRECT:
-#ifndef CODING_NEW_DRIVER
-		if (get_user(value, (int *) arg))
-			return -EFAULT;
-		if(value)
-			kbd_redirected = fg_console + 1;
-		else
-			kbd_redirected = 0;
-		kbd_table [fg_console].kbdmode = kbd_redirected ? VC_RAW : VC_XLATE;
-#endif
-		break;
-	case KIOCCMD:
-		if (get_user(value, (int *) arg))
-			return -EFAULT;
-		c = (unsigned char) value;
-		switch (c) {
-			case SKBDCMD_CLICK:
-			case SKBDCMD_NOCLICK:
-				spin_lock_irq(&sunkbd_lock);
-				send_cmd(c);
-				spin_unlock_irq(&sunkbd_lock);
-				return 0;
-			case SKBDCMD_BELLON:
-				kd_mksound(1,0);
-				return 0;
-			case SKBDCMD_BELLOFF:
-				kd_mksound(0,0);
-				return 0;
-			default:
-				return -EINVAL;
-		}
-	case KIOCSLED:
-		if (get_user(c, (unsigned char *) arg))
-			return -EFAULT;
-
-		if (c & LED_SCRLCK) leds |= (1 << VC_SCROLLOCK);
-		if (c & LED_NLOCK) leds |= (1 << VC_NUMLOCK);
-		if (c & LED_CLOCK) leds |= (1 << VC_CAPSLOCK);
-		compose_led_on = !!(c & LED_CMPOSE);
-		sun_setledstate(kbd_table + fg_console, leds);
-		break;
-	case KIOCGLED:
-		if (put_user(vcleds_to_sunkbd(getleds()), (unsigned char *) arg))
-			return -EFAULT;
-		break;
-	case KIOCGRATE:
-	{
-		struct kbd_rate rate;
-
-		rate.delay = kbd_delay_ticks;
-		if (kbd_rate_ticks)
-			rate.rate = HZ / kbd_rate_ticks;
-		else
-			rate.rate = 0;
-
-		if (copy_to_user((struct kbd_rate *)arg, &rate,
-				 sizeof(struct kbd_rate)))
-			return -EFAULT;
-
-		return 0;
-	}
-	case KIOCSRATE:
-	{
-		struct kbd_rate rate;
-
-		if (verify_area(VERIFY_READ, (void *)arg,
-				sizeof(struct kbd_rate)))
-			return -EFAULT;
-		copy_from_user(&rate, (struct kbd_rate *)arg,
-			       sizeof(struct kbd_rate));
-
-		if (rate.rate > 50)
-			return -EINVAL;
-		if (rate.rate == 0)
-			kbd_rate_ticks = 0;
-		else
-			kbd_rate_ticks = HZ / rate.rate;
-		kbd_delay_ticks = rate.delay;
-
-		return 0;
-	}
-	case FIONREAD:		/* return number of bytes in kbd queue */
-	{
-		int count;
-		
-		count = kbd_head - kbd_tail;
-		if (put_user((count < 0) ? KBD_QSIZE - count : count, (int *) arg))
-			return -EFAULT;
-		return 0;
-	}
-	default:
-		printk ("Unknown Keyboard ioctl: %8.8x\n", cmd);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int
-kbd_open (struct inode *i, struct file *f)
-{
-	spin_lock_irq(&kbd_queue_lock);
-	kbd_active++;
-
-	if (kbd_opened)
-		goto out;
-
-	kbd_opened = fg_console + 1;
-
-	kbd_head = kbd_tail = 0;
-
- out:
-	spin_unlock_irq(&kbd_queue_lock);
-
-	return 0;
-}
-
-static int
-kbd_close (struct inode *i, struct file *f)
-{
-	spin_lock_irq(&kbd_queue_lock);
-	if (!--kbd_active) {
-		if (kbd_redirected)
-			kbd_table [kbd_redirected-1].kbdmode = VC_XLATE;
-		kbd_redirected = 0;
-		kbd_opened = 0;
-		kbd_fasync (-1, f, 0);
-	}
-	spin_unlock_irq(&kbd_queue_lock);
-
-	return 0;
-}
-
-static struct file_operations kbd_fops =
-{
-	read:		kbd_read,
-	poll:		kbd_poll,
-	ioctl:		kbd_ioctl,
-	open:		kbd_open,
-	release:	kbd_close,
-	fasync:		kbd_fasync,
-};
-
-void __init keyboard_zsinit(void (*put_char)(unsigned char))
-{
-	int timeout = 0;
-
-	kbd_put_char = put_char;
-	if (!kbd_put_char)
-		panic("keyboard_zsinit: no put_char parameter");
-
-	/* Test out the leds */
-	sunkbd_type = 255;
-	sunkbd_layout = 0;
-
-	send_cmd(SKBDCMD_RESET);
-	send_cmd(SKBDCMD_RESET);
-	while((sunkbd_type==255) && timeout++ < 25000) {
-		udelay(100);
-		barrier();
-	}
-
-	if(timeout>=25000) {
-		printk("keyboard: not present\n");
-		return;
-	}
-
-	if(sunkbd_type != SUNKBD_TYPE4) {
-		printk("Sun TYPE %d keyboard detected ", sunkbd_type);
-	} else {
-		timeout=0;
-		while((sunkbd_layout==0) && timeout++ < 10000) {
-			udelay(100);
-			barrier();
-		}
-		printk("Sun TYPE %d keyboard detected ",
-		       ((sunkbd_layout & SUNKBD_LOUT_TYP5_MASK) ? 5 : 4));
-	}
-	if(sunkbd_type == SUNKBD_TYPE2)
-		sunkbd_clickp = 0;
-
-	spin_lock_irq(&sunkbd_lock);
-
-	if(sunkbd_clickp) {
-		send_cmd(SKBDCMD_CLICK);
-		printk("with keyclick\n");
-	} else {
-		send_cmd(SKBDCMD_NOCLICK);
-		printk("without keyclick\n");
-	}
-
-	/* Dork with led lights, then turn them all off */
-	send_cmd(SKBDCMD_SETLED); send_cmd(0xf); /* All on */
-	send_cmd(SKBDCMD_SETLED); send_cmd(0x0); /* All off */
-
-	spin_unlock_irq(&sunkbd_lock);
-
-	/* Register the /dev/kbd interface */
-	devfs_register (NULL, "kbd", DEVFS_FL_DEFAULT,
-			KBD_MAJOR, 0,
-			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH,
-			&kbd_fops, NULL);
-	if (register_chrdev (KBD_MAJOR, "kbd", &kbd_fops)){
-		printk ("Could not register /dev/kbd device\n");
-		return;
-	}
-	return;
-}
diff -Nru a/drivers/sbus/char/sunkbd.h b/drivers/sbus/char/sunkbd.h
--- a/drivers/sbus/char/sunkbd.h	Sat Aug 10 18:42:22 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,52 +0,0 @@
-/* $Id: sunkbd.h,v 1.4 2000/02/09 11:15:54 davem Exp $
- * sunkbd.h: Defines needed by SUN Keyboard drivers
- *
- * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
- */
-
-#ifndef _SPARC_SUNKBD_H
-#define _SPARC_SUNKBD_H 1
-
-#include <linux/config.h>
-
-/* Keyboard defines for L1-A processing... */
-#define SUNKBD_RESET		0xff
-#define SUNKBD_L1		0x01
-#define SUNKBD_UP		0x80
-#define SUNKBD_A		0x4d
-
-struct l1a_kbd_state {
-	int kbd_id;
-	int l1_down;
-};
-
-extern struct l1a_kbd_state l1a_state;
-
-extern void keyboard_zsinit(void (*kbd_put_char)(unsigned char));
-extern void sunkbd_inchar(unsigned char, struct pt_regs *);
-extern void batten_down_hatches(void);
-
-extern void sun_kbd_bh(unsigned long);
-extern int sun_kbd_init(void);
-extern void sun_compute_shiftstate(void);
-extern void sun_setledstate(struct kbd_struct *, unsigned int);
-extern unsigned char sun_getledstate(void);
-extern int sun_setkeycode(unsigned int, unsigned int);
-extern int sun_getkeycode(unsigned int);
-
-#ifdef CONFIG_PCI
-
-extern ushort *sun_key_maps[MAX_NR_KEYMAPS];
-extern unsigned int sun_keymap_count;
-
-extern char sun_func_buf[];
-extern char *sun_func_table[MAX_NR_FUNC];
-extern int sun_funcbufsize;
-extern int sun_funcbufleft;
-
-extern struct kbdiacr sun_accent_table[MAX_DIACR];
-extern unsigned int sun_accent_table_size;
-
-#endif /* CONFIG_PCI */
-
-#endif /* !(_SPARC_SUNKBD_H) */
diff -Nru a/drivers/sbus/char/sunkbdmap.c b/drivers/sbus/char/sunkbdmap.c
--- a/drivers/sbus/char/sunkbdmap.c	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,33 +0,0 @@
-
-/* $Id: sunkbdmap.c,v 1.1 1997/09/07 15:40:27 ecd Exp $
- * sunkbdmap.c: Wrapper around sunkeymap.c to change table names.
- *
- * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
- */
-
-#include <linux/config.h>
-
-#ifdef CONFIG_PCI
-
-#define func_buf			sun_func_buf
-#define func_table			sun_func_table
-#define funcbufsize			sun_funcbufsize
-#define funcbufleft			sun_funcbufleft
-#define funcbufptr			sun_funcbufptr
-#define accent_table			sun_accent_table
-#define accent_table_size		sun_accent_table_size
-
-#define key_maps			sun_key_maps
-#define keymap_count			sun_keymap_count
-
-#define plain_map			sun_plain_map
-#define shift_map			sun_shift_map
-#define ctrl_map			sun_ctrl_map
-#define alt_map				sun_alt_map
-#define altgr_map			sun_altgr_map
-#define shift_ctrl_map			sun_shift_ctrl_map
-#define ctrl_alt_map			sun_ctrl_alt_map
-
-#endif /* CONFIG_PCI */
-
-#include "sunkeymap.c"
diff -Nru a/drivers/sbus/char/sunkeymap.c b/drivers/sbus/char/sunkeymap.c
--- a/drivers/sbus/char/sunkeymap.c	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,265 +0,0 @@
-
-/* Do not edit this file! It was automatically generated by   */
-/*    loadkeys --mktable defkeymap.map > defkeymap.c          */
-
-#include <linux/types.h>
-#include <linux/keyboard.h>
-#include <linux/kd.h>
-
-u_short plain_map[NR_KEYS] = {
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf100,	0xf101,	0xf109,
-	0xf102,	0xf10a,	0xf103,	0xf10b,	0xf104,	0xf701,	0xf105,	0xf200,
-	0xf106,	0xf107,	0xf108,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf209,
-	0xf601,	0xf200,	0xf200,	0xf600,	0xf602,	0xf01b,	0xf031,	0xf032,
-	0xf033,	0xf034,	0xf035,	0xf036,	0xf037,	0xf038,	0xf039,	0xf030,
-	0xf02d,	0xf03d,	0xf060,	0xf07f,	0xf115,	0xf03d,	0xf30d,	0xf30c,
-	0xf200,	0xf200,	0xf310,	0xf200,	0xf114,	0xf009,	0xfb71,	0xfb77,
-	0xfb65,	0xfb72,	0xfb74,	0xfb79,	0xfb75,	0xfb69,	0xfb6f,	0xfb70,
-	0xf05b,	0xf05d,	0xf07f,	0xf20e,	0xf307,	0xf308,	0xf309,	0xf30b,
-	0xf200,	0xf200,	0xf117,	0xf200,	0xf702,	0xfb61,	0xfb73,	0xfb64,
-	0xfb66,	0xfb67,	0xfb68,	0xfb6a,	0xfb6b,	0xfb6c,	0xf03b,	0xf027,
-	0xf05c,	0xf201,	0xf30e,	0xf304,	0xf305,	0xf306,	0xf300,	0xf200,
-	0xf118,	0xf200,	0xf208,	0xf700,	0xfb7a,	0xfb78,	0xfb63,	0xfb76,
-	0xfb62,	0xfb6e,	0xfb6d,	0xf02c,	0xf02e,	0xf02f,	0xf700,	0xf00a,
-	0xf301,	0xf302,	0xf303,	0xf200,	0xf200,	0xf200,	0xf11b,	0xf207,
-	0xf200,	0xf020,	0xf200,	0xf119,	0xf200,	0xf30a,	0xf200,	0xf200,
-};
-
-u_short shift_map[NR_KEYS] = {
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf10a,	0xf10b,	0xf113,
-	0xf10c,	0xf10a,	0xf10d,	0xf10b,	0xf10e,	0xf701,	0xf10f,	0xf200,
-	0xf110,	0xf111,	0xf112,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf203,
-	0xf601,	0xf200,	0xf200,	0xf600,	0xf602,	0xf01b,	0xf021,	0xf040,
-	0xf023,	0xf024,	0xf025,	0xf05e,	0xf026,	0xf02a,	0xf028,	0xf029,
-	0xf05f,	0xf02b,	0xf07e,	0xf07f,	0xf115,	0xf03d,	0xf30d,	0xf30c,
-	0xf200,	0xf200,	0xf310,	0xf200,	0xf114,	0xf009,	0xfb51,	0xfb57,
-	0xfb45,	0xfb52,	0xfb54,	0xfb59,	0xfb55,	0xfb49,	0xfb4f,	0xfb50,
-	0xf07b,	0xf07d,	0xf07f,	0xf20e,	0xf307,	0xf308,	0xf309,	0xf30b,
-	0xf200,	0xf200,	0xf117,	0xf200,	0xf702,	0xfb41,	0xfb53,	0xfb44,
-	0xfb46,	0xfb47,	0xfb48,	0xfb4a,	0xfb4b,	0xfb4c,	0xf03a,	0xf022,
-	0xf07c,	0xf201,	0xf30e,	0xf304,	0xf305,	0xf306,	0xf300,	0xf200,
-	0xf20b,	0xf200,	0xf208,	0xf700,	0xfb5a,	0xfb58,	0xfb43,	0xfb56,
-	0xfb42,	0xfb4e,	0xfb4d,	0xf03c,	0xf03e,	0xf03f,	0xf700,	0xf00a,
-	0xf301,	0xf302,	0xf303,	0xf200,	0xf200,	0xf200,	0xf11b,	0xf207,
-	0xf200,	0xf020,	0xf200,	0xf20a,	0xf200,	0xf30a,	0xf200,	0xf200,
-};
-
-u_short altgr_map[NR_KEYS] = {
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf50c,	0xf50d,	0xf515,
-	0xf50e,	0xf516,	0xf50f,	0xf517,	0xf510,	0xf701,	0xf511,	0xf200,
-	0xf512,	0xf513,	0xf514,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf202,
-	0xf601,	0xf200,	0xf200,	0xf600,	0xf602,	0xf200,	0xf200,	0xf040,
-	0xf200,	0xf024,	0xf200,	0xf200,	0xf07b,	0xf05b,	0xf05d,	0xf07d,
-	0xf05c,	0xf200,	0xf200,	0xf200,	0xf115,	0xf03d,	0xf30d,	0xf30c,
-	0xf200,	0xf200,	0xf310,	0xf200,	0xf114,	0xf200,	0xfb71,	0xfb77,
-	0xf918,	0xfb72,	0xfb74,	0xfb79,	0xfb75,	0xfb69,	0xfb6f,	0xfb70,
-	0xf200,	0xf07e,	0xf200,	0xf20e,	0xf911,	0xf912,	0xf913,	0xf30b,
-	0xf200,	0xf200,	0xf117,	0xf200,	0xf702,	0xf914,	0xfb73,	0xf917,
-	0xf919,	0xfb67,	0xfb68,	0xfb6a,	0xfb6b,	0xfb6c,	0xf200,	0xf200,
-	0xf200,	0xf201,	0xf30e,	0xf90e,	0xf90f,	0xf910,	0xf90a,	0xf200,
-	0xf118,	0xf200,	0xf208,	0xf700,	0xfb7a,	0xfb78,	0xf916,	0xfb76,
-	0xf915,	0xfb6e,	0xfb6d,	0xf200,	0xf200,	0xf200,	0xf700,	0xf00a,
-	0xf90b,	0xf90c,	0xf90d,	0xf200,	0xf200,	0xf200,	0xf11b,	0xf207,
-	0xf200,	0xf200,	0xf200,	0xf119,	0xf200,	0xf30a,	0xf200,	0xf200,
-};
-
-u_short ctrl_map[NR_KEYS] = {
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf100,	0xf101,	0xf109,
-	0xf102,	0xf10a,	0xf103,	0xf10b,	0xf104,	0xf701,	0xf105,	0xf200,
-	0xf106,	0xf107,	0xf108,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf204,
-	0xf601,	0xf200,	0xf200,	0xf600,	0xf602,	0xf200,	0xf200,	0xf000,
-	0xf01b,	0xf01c,	0xf01d,	0xf01e,	0xf01f,	0xf07f,	0xf200,	0xf200,
-	0xf01f,	0xf200,	0xf000,	0xf008,	0xf115,	0xf03d,	0xf30d,	0xf30c,
-	0xf200,	0xf200,	0xf310,	0xf200,	0xf114,	0xf200,	0xf011,	0xf017,
-	0xf005,	0xf012,	0xf014,	0xf019,	0xf015,	0xf009,	0xf00f,	0xf010,
-	0xf01b,	0xf01d,	0xf008,	0xf20e,	0xf307,	0xf308,	0xf309,	0xf30b,
-	0xf200,	0xf200,	0xf117,	0xf200,	0xf702,	0xf001,	0xf013,	0xf004,
-	0xf006,	0xf007,	0xf008,	0xf00a,	0xf00b,	0xf00c,	0xf200,	0xf007,
-	0xf01c,	0xf201,	0xf30e,	0xf304,	0xf305,	0xf306,	0xf300,	0xf200,
-	0xf118,	0xf200,	0xf208,	0xf700,	0xf01a,	0xf018,	0xf003,	0xf016,
-	0xf002,	0xf00e,	0xf00d,	0xf200,	0xf20e,	0xf07f,	0xf700,	0xf00a,
-	0xf301,	0xf302,	0xf303,	0xf200,	0xf200,	0xf200,	0xf11b,	0xf207,
-	0xf200,	0xf000,	0xf200,	0xf119,	0xf200,	0xf30a,	0xf200,	0xf200,
-};
-
-u_short shift_ctrl_map[NR_KEYS] = {
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf701,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf200,
-	0xf601,	0xf200,	0xf200,	0xf600,	0xf602,	0xf200,	0xf200,	0xf000,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf01f,	0xf200,	0xf200,	0xf200,	0xf115,	0xf03d,	0xf30d,	0xf30c,
-	0xf200,	0xf200,	0xf310,	0xf200,	0xf114,	0xf200,	0xf011,	0xf017,
-	0xf005,	0xf012,	0xf014,	0xf019,	0xf015,	0xf009,	0xf00f,	0xf010,
-	0xf200,	0xf200,	0xf200,	0xf20e,	0xf307,	0xf308,	0xf309,	0xf30b,
-	0xf200,	0xf200,	0xf117,	0xf200,	0xf702,	0xf001,	0xf013,	0xf004,
-	0xf006,	0xf007,	0xf008,	0xf00a,	0xf00b,	0xf00c,	0xf200,	0xf200,
-	0xf200,	0xf201,	0xf30e,	0xf304,	0xf305,	0xf306,	0xf300,	0xf200,
-	0xf118,	0xf200,	0xf208,	0xf700,	0xf01a,	0xf018,	0xf003,	0xf016,
-	0xf002,	0xf00e,	0xf00d,	0xf200,	0xf200,	0xf200,	0xf700,	0xf00a,
-	0xf301,	0xf302,	0xf303,	0xf200,	0xf200,	0xf200,	0xf11b,	0xf207,
-	0xf200,	0xf200,	0xf200,	0xf119,	0xf200,	0xf30a,	0xf200,	0xf200,
-};
-
-u_short alt_map[NR_KEYS] = {
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf500,	0xf501,	0xf509,
-	0xf502,	0xf50a,	0xf503,	0xf50b,	0xf504,	0xf701,	0xf505,	0xf200,
-	0xf506,	0xf507,	0xf508,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf209,
-	0xf210,	0xf200,	0xf200,	0xf600,	0xf211,	0xf81b,	0xf831,	0xf832,
-	0xf833,	0xf834,	0xf835,	0xf836,	0xf837,	0xf838,	0xf839,	0xf830,
-	0xf82d,	0xf83d,	0xf860,	0xf87f,	0xf115,	0xf03d,	0xf30d,	0xf30c,
-	0xf200,	0xf200,	0xf310,	0xf200,	0xf114,	0xf809,	0xf871,	0xf877,
-	0xf865,	0xf872,	0xf874,	0xf879,	0xf875,	0xf869,	0xf86f,	0xf870,
-	0xf85b,	0xf85d,	0xf87f,	0xf20e,	0xf907,	0xf908,	0xf909,	0xf30b,
-	0xf200,	0xf200,	0xf117,	0xf200,	0xf702,	0xf861,	0xf873,	0xf864,
-	0xf866,	0xf867,	0xf868,	0xf86a,	0xf86b,	0xf86c,	0xf83b,	0xf827,
-	0xf85c,	0xf80d,	0xf30e,	0xf904,	0xf905,	0xf906,	0xf900,	0xf200,
-	0xf118,	0xf200,	0xf208,	0xf700,	0xf87a,	0xf878,	0xf863,	0xf876,
-	0xf862,	0xf86e,	0xf86d,	0xf82c,	0xf82e,	0xf82f,	0xf700,	0xf00a,
-	0xf901,	0xf902,	0xf903,	0xf200,	0xf200,	0xf200,	0xf11b,	0xf207,
-	0xf200,	0xf820,	0xf200,	0xf119,	0xf200,	0xf30a,	0xf200,	0xf200,
-};
-
-u_short ctrl_alt_map[NR_KEYS] = {
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf500,	0xf501,	0xf509,
-	0xf502,	0xf50a,	0xf503,	0xf50b,	0xf504,	0xf701,	0xf505,	0xf200,
-	0xf506,	0xf507,	0xf508,	0xf703,	0xf603,	0xf11d,	0xf200,	0xf200,
-	0xf601,	0xf200,	0xf200,	0xf600,	0xf602,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,	0xf200,
-	0xf200,	0xf200,	0xf200,	0xf200,	0xf115,	0xf03d,	0xf30d,	0xf30c,
-	0xf200,	0xf200,	0xf20c,	0xf200,	0xf114,	0xf200,	0xf811,	0xf817,
-	0xf805,	0xf812,	0xf814,	0xf819,	0xf815,	0xf809,	0xf80f,	0xf810,
-	0xf200,	0xf200,	0xf20c,	0xf20e,	0xf307,	0xf308,	0xf309,	0xf30b,
-	0xf200,	0xf200,	0xf117,	0xf200,	0xf702,	0xf801,	0xf813,	0xf804,
-	0xf806,	0xf807,	0xf808,	0xf80a,	0xf80b,	0xf80c,	0xf200,	0xf200,
-	0xf200,	0xf201,	0xf30e,	0xf304,	0xf305,	0xf306,	0xf300,	0xf200,
-	0xf118,	0xf200,	0xf208,	0xf700,	0xf81a,	0xf818,	0xf803,	0xf816,
-	0xf802,	0xf80e,	0xf80d,	0xf200,	0xf200,	0xf200,	0xf700,	0xf00a,
-	0xf301,	0xf302,	0xf303,	0xf200,	0xf200,	0xf200,	0xf11b,	0xf207,
-	0xf200,	0xf200,	0xf200,	0xf119,	0xf200,	0xf30a,	0xf200,	0xf200,
-};
-
-ushort *key_maps[MAX_NR_KEYMAPS] = {
-	plain_map, shift_map, altgr_map, 0,
-	ctrl_map, shift_ctrl_map, 0, 0,
-	alt_map, 0, 0, 0,
-	ctrl_alt_map,	0
-};
-
-unsigned int keymap_count = 7;
-
-
-/*
- * Philosophy: most people do not define more strings, but they who do
- * often want quite a lot of string space. So, we statically allocate
- * the default and allocate dynamically in chunks of 512 bytes.
- */
-
-char func_buf[] = {
-	'\033', '[', '[', 'A', 0, 
-	'\033', '[', '[', 'B', 0, 
-	'\033', '[', '[', 'C', 0, 
-	'\033', '[', '[', 'D', 0, 
-	'\033', '[', '[', 'E', 0, 
-	'\033', '[', '1', '7', '~', 0, 
-	'\033', '[', '1', '8', '~', 0, 
-	'\033', '[', '1', '9', '~', 0, 
-	'\033', '[', '2', '0', '~', 0, 
-	'\033', '[', '2', '1', '~', 0, 
-	'\033', '[', '2', '3', '~', 0, 
-	'\033', '[', '2', '4', '~', 0, 
-	'\033', '[', '2', '5', '~', 0, 
-	'\033', '[', '2', '6', '~', 0, 
-	'\033', '[', '2', '8', '~', 0, 
-	'\033', '[', '2', '9', '~', 0, 
-	'\033', '[', '3', '1', '~', 0, 
-	'\033', '[', '3', '2', '~', 0, 
-	'\033', '[', '3', '3', '~', 0, 
-	'\033', '[', '3', '4', '~', 0, 
-	'\033', '[', '1', '~', 0, 
-	'\033', '[', '2', '~', 0, 
-	'\033', '[', '3', '~', 0, 
-	'\033', '[', '4', '~', 0, 
-	'\033', '[', '5', '~', 0, 
-	'\033', '[', '6', '~', 0, 
-	'\033', '[', 'M', 0, 
-	'\033', '[', 'P', 0, 
-};
-
-
-char *funcbufptr = func_buf;
-int funcbufsize = sizeof(func_buf);
-int funcbufleft = 0;          /* space left */
-
-char *func_table[MAX_NR_FUNC] = {
-	func_buf + 0,
-	func_buf + 5,
-	func_buf + 10,
-	func_buf + 15,
-	func_buf + 20,
-	func_buf + 25,
-	func_buf + 31,
-	func_buf + 37,
-	func_buf + 43,
-	func_buf + 49,
-	func_buf + 55,
-	func_buf + 61,
-	func_buf + 67,
-	func_buf + 73,
-	func_buf + 79,
-	func_buf + 85,
-	func_buf + 91,
-	func_buf + 97,
-	func_buf + 103,
-	func_buf + 109,
-	func_buf + 115,
-	func_buf + 120,
-	func_buf + 125,
-	func_buf + 130,
-	func_buf + 135,
-	func_buf + 140,
-	func_buf + 145,
-	0,
-	0,
-	func_buf + 149,
-	0,
-};
-
-struct kbdiacr accent_table[MAX_DIACR] = {
-	{'`', 'A', '\300'},	{'`', 'a', '\340'},
-	{'\'', 'A', '\301'},	{'\'', 'a', '\341'},
-	{'^', 'A', '\302'},	{'^', 'a', '\342'},
-	{'~', 'A', '\303'},	{'~', 'a', '\343'},
-	{'"', 'A', '\304'},	{'"', 'a', '\344'},
-	{'O', 'A', '\305'},	{'o', 'a', '\345'},
-	{'0', 'A', '\305'},	{'0', 'a', '\345'},
-	{'A', 'A', '\305'},	{'a', 'a', '\345'},
-	{'A', 'E', '\306'},	{'a', 'e', '\346'},
-	{',', 'C', '\307'},	{',', 'c', '\347'},
-	{'`', 'E', '\310'},	{'`', 'e', '\350'},
-	{'\'', 'E', '\311'},	{'\'', 'e', '\351'},
-	{'^', 'E', '\312'},	{'^', 'e', '\352'},
-	{'"', 'E', '\313'},	{'"', 'e', '\353'},
-	{'`', 'I', '\314'},	{'`', 'i', '\354'},
-	{'\'', 'I', '\315'},	{'\'', 'i', '\355'},
-	{'^', 'I', '\316'},	{'^', 'i', '\356'},
-	{'"', 'I', '\317'},	{'"', 'i', '\357'},
-	{'-', 'D', '\320'},	{'-', 'd', '\360'},
-	{'~', 'N', '\321'},	{'~', 'n', '\361'},
-	{'`', 'O', '\322'},	{'`', 'o', '\362'},
-	{'\'', 'O', '\323'},	{'\'', 'o', '\363'},
-	{'^', 'O', '\324'},	{'^', 'o', '\364'},
-	{'~', 'O', '\325'},	{'~', 'o', '\365'},
-	{'"', 'O', '\326'},	{'"', 'o', '\366'},
-	{'/', 'O', '\330'},	{'/', 'o', '\370'},
-	{'`', 'U', '\331'},	{'`', 'u', '\371'},
-	{'\'', 'U', '\332'},	{'\'', 'u', '\372'},
-	{'^', 'U', '\333'},	{'^', 'u', '\373'},
-	{'"', 'U', '\334'},	{'"', 'u', '\374'},
-	{'\'', 'Y', '\335'},	{'\'', 'y', '\375'},
-	{'T', 'H', '\336'},	{'t', 'h', '\376'},
-	{'s', 's', '\337'},	{'"', 'y', '\377'},
-	{'s', 'z', '\337'},	{'i', 'j', '\377'},
-};
-
-unsigned int accent_table_size = 68;
diff -Nru a/drivers/sbus/char/sunkeymap.map b/drivers/sbus/char/sunkeymap.map
--- a/drivers/sbus/char/sunkeymap.map	Sat Aug 10 18:42:22 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,375 +0,0 @@
-# Keyboard map for the Sun Type4/Type5 keyboards
-# found on SparcStations
-keymaps 0-2,4-5,8,12
-#
-#
-# Stop/L1
-keycode	0x01 =
-# SND_LOWER
-keycode	0x02 =
-# Again/L2
-keycode	0x03 =
-# SND_LOUDER
-keycode	0x04 =
-keycode	0x05 = F1			F11	Console_13
-	control	keycode			0x05 = F1
-	alt	keycode			0x05 = Console_1
-	control	alt	keycode		0x05 = Console_1
-keycode	0x06 = F2			F12	Console_14
-	control	keycode			0x06 = F2
-	alt	keycode			0x06 = Console_2
-	control	alt	keycode		0x06 = Console_2
-keycode	0x07 = F10			F20	Console_22
-	control	keycode			0x07 = F10
-	alt	keycode			0x07 = Console_10
-	control	alt	keycode		0x07 = Console_10
-keycode	0x08 = F3			F13	Console_15
-	control	keycode			0x08 = F3
-	alt	keycode			0x08 = Console_3
-	control	alt	keycode		0x08 = Console_3
-keycode	0x09 = F11			F11	Console_23
-	control	keycode			0x09 = F11
-	alt	keycode			0x09 = Console_11
-	control	alt	keycode		0x09 = Console_11
-keycode	0x0a = F4			F14	Console_16
-	control	keycode			0x0a = F4
-	alt	keycode			0x0a = Console_4
-	control	alt	keycode		0x0a = Console_4
-keycode	0x0b = F12			F12	Console_24
-	control	keycode			0x0b = F12
-	alt	keycode			0x0b = Console_12
-	control	alt	keycode		0x0b = Console_12
-keycode	0x0c = F5			F15	Console_17
-	control	Keycode			0x0c = F5
-	alt	keycode			0x0c = Console_5
-	control	alt	keycode		0x0c = Console_5
-keycode	0x0d = AltGr
-keycode 0x0e = F6			F16	Console_18
-	control	keycode			0x0e = F6
-	alt	keycode			0x0e = Console_6
-	control	alt	keycode		0x0e = Console_6
-# BLANK KEY on type 5 keyboards
-keycode 0x0f =
-keycode 0x10 = F7			F17	Console_19
-	control	keycode			0x10 = F7
-	alt	keycode			0x10 = Console_7
-	control	alt	keycode		0x10 = Console_7
-keycode 0x11 = F8			F18	Console_20
-	control	keycode			0x11 = F8
-	alt	keycode			0x11 = Console_8
-	control	alt	keycode		0x11 = Console_8
-keycode 0x12 = F9			F19	Console_21
-	control	keycode			0x12 = F9
-	alt	keycode			0x12 = Console_9
-	control	alt	keycode		0x12 = Console_9
-keycode 0x13 = Alt
-keycode 0x14 = Up
-keycode 0x15 = Pause
-# Print Screen
-keycode 0x16 = 
-keycode 0x17 = Scroll_Lock	Show_Memory	Show_Registers
-	control	keycode				0x17 = Show_State
-	alt	keycode				0x17 = Scroll_Lock
-keycode 0x18 = Left
-	alt	keycode				0x18 = Decr_Console
-# Props/L3
-keycode 0x19 =
-# UNDO/L4
-keycode 0x1a =
-keycode 0x1b = Down
-keycode 0x1c = Right
-	alt	keycode				0x1c = Incr_Console
-keycode 0x1d = Escape		Escape
-	alt	keycode				0x1d = Meta_Escape
-keycode 0x1e = one		exclam
-	alt	keycode				0x1e = Meta_one
-keycode 0x1f = two		at		at
-	control	keycode				0x1f = nul
-	shift	control	keycode			0x1f = nul
-	alt	keycode				0x1f = Meta_two
-keycode 0x20 = three		numbersign
-	control	keycode				0x20 = Escape
-	alt	keycode				0x20 = Meta_three
-keycode 0x21 = four		dollar		dollar
-	control	keycode				0x21 = Control_backslash
-	alt	keycode				0x21 = Meta_four
-keycode 0x22 = five		percent
-	control	keycode				0x22 = Control_bracketright
-	alt	keycode				0x22 = Meta_five
-keycode 0x23 = six		asciicircum
-	control	keycode				0x23 = Control_asciicircum
-	alt	keycode				0x23 = Meta_six
-keycode 0x24 = seven		ampersand	braceleft
-	control	keycode				0x24 = Control_underscore
-	alt	keycode				0x24 = Meta_seven
-keycode 0x25 = eight		asterisk	bracketleft
-	control	keycode				0x25 = Delete
-	alt	keycode				0x25 = Meta_eight
-keycode 0x26 = nine		parenleft	bracketright
-	alt	keycode				0x26 = Meta_nine
-keycode 0x27 = zero		parenright	braceright
-	alt	keycode				0x27 = Meta_zero
-keycode 0x28 = minus		underscore	backslash
-	control	keycode				0x28 = Control_underscore
-	shift	control	keycode			0x28 = Control_underscore
-	alt	keycode				0x28 = Meta_minus
-keycode 0x29 = equal		plus
-	alt	keycode				0x29 = Meta_equal
-keycode 0x2a = grave		asciitilde
-	control	keycode				0x2a = nul
-	alt	keycode				0x2a = Meta_grave
-# Is marked as BackSpace but we define it as delete just like the i386
-# keyboard maps does
-keycode 0x2b = Delete		Delete
-	control	keycode				0x2b = BackSpace
-	alt	keycode				0x2b = Meta_Delete
-keycode 0x2c = Insert
-# This is really keypad = on type 4 keyboards
-keycode 0x2d = equal
-keycode 0x2e = KP_Divide
-keycode 0x2f = KP_Multiply
-# Power ON/OFF key on type 5 keyboard
-keycode 0x30 =
-# FRONT/L5
-keycode 0x31 = 
-keycode 0x32 = KP_Period
-#	altgr	control	keycode			0x32 = Boot
-	control	alt	keycode			0x32 = Boot
-# COPY/L6
-keycode 0x33 =
-# Home key, same difference
-keycode 0x34 = Find
-keycode 0x35 = Tab		Tab
-	alt	keycode				0x35 = Meta_Tab
-keycode 0x36 = q
-keycode 0x37 = w
-keycode 0x38 = e
-	altgr	keycode				0x38 = Hex_E
-keycode 0x39 = r
-keycode 0x3a = t
-keycode 0x3b = y
-keycode 0x3c = u
-keycode 0x3d = i
-keycode 0x3e = o
-keycode 0x3f = p
-keycode 0x40 = bracketleft	braceleft
-	control	keycode				0x40 = Escape
-	alt	keycode				0x40 = Meta_bracketleft
-keycode 0x41 = bracketright	braceright	asciitilde
-	control	keycode				0x41 = Control_bracketright
-	alt	keycode				0x41 = Meta_bracketright
-keycode 0x42 = Delete		Delete
-	control	keycode				0x42 = BackSpace
-	alt	keycode				0x42 = Meta_Delete
-	control	alt	keycode			0x42 = Boot
-keycode 0x43 = Compose
-keycode 0x44 = KP_7
-	alt	keycode				0x44 = Ascii_7
-	altgr	keycode				0x44 = Hex_7
-keycode 0x45 = KP_8
-	alt	keycode				0x45 = Ascii_8
-	altgr	keycode				0x45 = Hex_8
-keycode 0x46 = KP_9
-	alt	keycode				0x46 = Ascii_9
-	altgr	keycode				0x46 = Hex_9
-keycode 0x47 = KP_Subtract
-# OPEN/L6
-keycode 0x48 = 
-# PASTE/L8
-keycode 0x49 =
-keycode 0x4a = Select
-# No key produces 0x4b to my knowledge
-keycode 0x4b =
-keycode 0x4c = Control
-keycode 0x4d = a
-	altgr	keycode				0x4d = Hex_A
-keycode 0x4e = s
-keycode 0x4f = d
-	altgr	keycode				0x4f = Hex_D
-keycode 0x50 = f
-	altgr	keycode				0x50 = Hex_F
-keycode 0x51 = g
-keycode 0x52 = h
-keycode 0x53 = j
-keycode 0x54 = k
-keycode 0x55 = l
-keycode 0x56 = semicolon	colon
-	alt	keycode				0x56 = Meta_semicolon
-keycode 0x57 = apostrophe	quotedbl
-	control	keycode				0x57 = Control_g
-	alt	keycode				0x57 = Meta_apostrophe
-keycode 0x58 = backslash	bar
-	control	keycode				0x58 = Control_backslash
-	alt	keycode				0x58 = Meta_backslash
-keycode 0x59 = Return
-	alt	keycode				0x59 = Meta_Control_m
-keycode 0x5a = KP_Enter
-keycode 0x5b = KP_4
-	alt	keycode				0x5b = Ascii_4
-	altgr	keycode				0x5b = Hex_4
-keycode 0x5c = KP_5
-	alt	keycode				0x5c = Ascii_5
-	altgr	keycode				0x5c = Hex_5
-keycode 0x5d = KP_6
-	alt	keycode				0x5d = Ascii_6
-	altgr	keycode				0x5d = Hex_6
-keycode 0x5e = KP_0
-	alt	keycode				0x5e = Ascii_0
-	altgr	keycode				0x5e = Hex_0
-# FIND/L9
-keycode 0x5f =
-keycode 0x60 = Prior
-	shift	keycode				0x60 = Scroll_Backward
-# CUT/L10
-keycode 0x61 =
-keycode 0x62 = Num_Lock
-# Linux/i386 console makes no distinction between right/left shift
-# so neither do we.
-keycode 0x63 = Shift
-keycode 0x64 = z
-keycode 0x65 = x
-keycode 0x66 = c
-	altgr	keycode				0x66 = Hex_C
-keycode 0x67 = v
-keycode 0x68 = b
-	altgr	keycode				0x68 = Hex_B
-keycode 0x69 = n
-keycode 0x6a = m
-keycode 0x6b = comma		less
-	alt	keycode				0x6b = Meta_comma
-keycode 0x6c = period		greater
-	control	keycode				0x6c = Compose
-	alt	keycode				0x6c = Meta_period
-keycode 0x6d = slash		question
-	control	keycode				0x6d = Delete
-	alt	keycode				0x6d = Meta_slash
-keycode 0x6e = Shift
-keycode 0x6f = Linefeed
-keycode 0x70 = KP_1
-	alt	keycode				0x70 = Ascii_1
-	altgr	keycode				0x70 = Hex_1
-keycode 0x71 = KP_2
-	alt	keycode				0x71 = Ascii_2
-	altgr	keycode				0x71 = Hex_2
-keycode 0x72 = KP_3
-	alt	keycode				0x72 = Ascii_3
-	altgr	keycode				0x72 = Hex_3
-# To my knowledge no key produces 0x73, 0x74, or 0x75
-keycode 0x73 =
-keycode 0x74 =
-keycode 0x75 =
-keycode 0x76 = Help
-keycode 0x77 = Caps_Lock
-# A True Meta-key, unused at this time
-keycode 0x78 =
-keycode 0x79 = space		space
-	control	keycode				0x79 = nul
-	alt	keycode				0x79 = Meta_space
-# Another real Meta-key, again unused
-keycode 0x7a =
-keycode 0x7b = Next
-	shift	keycode				0x7b = Scroll_Forward
-# No keys produce the following
-keycode 0x7c =
-keycode 0x7d = KP_Add
-keycode 0x7e =
-# keycode 0x7f is special and it means 'all keys released' and is
-# taken care of within the sun keyboard driver itself
-keycode 0x7f =
-# That's all folks...
-string F1 = "\033[[A"
-string F2 = "\033[[B"
-string F3 = "\033[[C"
-string F4 = "\033[[D"
-string F5 = "\033[[E"
-string F6 = "\033[17~"
-string F7 = "\033[18~"
-string F8 = "\033[19~"
-string F9 = "\033[20~"
-string F10 = "\033[21~"
-string F11 = "\033[23~"
-string F12 = "\033[24~"
-string F13 = "\033[25~"
-string F14 = "\033[26~"
-string F15 = "\033[28~"
-string F16 = "\033[29~"
-string F17 = "\033[31~"
-string F18 = "\033[32~"
-string F19 = "\033[33~"
-string F20 = "\033[34~"
-string Find = "\033[1~"
-string Insert = "\033[2~"
-string Remove = "\033[3~"
-string Select = "\033[4~"
-string Prior = "\033[5~"
-string Next = "\033[6~"
-string Macro = "\033[M"
-string Pause = "\033[P"
-compose '`' 'A' to 'À'
-compose '`' 'a' to 'à'
-compose '\'' 'A' to 'Á'
-compose '\'' 'a' to 'á'
-compose '^' 'A' to 'Â'
-compose '^' 'a' to 'â'
-compose '~' 'A' to 'Ã'
-compose '~' 'a' to 'ã'
-compose '"' 'A' to 'Ä'
-compose '"' 'a' to 'ä'
-compose 'O' 'A' to 'Å'
-compose 'o' 'a' to 'å'
-compose '0' 'A' to 'Å'
-compose '0' 'a' to 'å'
-compose 'A' 'A' to 'Å'
-compose 'a' 'a' to 'å'
-compose 'A' 'E' to 'Æ'
-compose 'a' 'e' to 'æ'
-compose ',' 'C' to 'Ç'
-compose ',' 'c' to 'ç'
-compose '`' 'E' to 'È'
-compose '`' 'e' to 'è'
-compose '\'' 'E' to 'É'
-compose '\'' 'e' to 'é'
-compose '^' 'E' to 'Ê'
-compose '^' 'e' to 'ê'
-compose '"' 'E' to 'Ë'
-compose '"' 'e' to 'ë'
-compose '`' 'I' to 'Ì'
-compose '`' 'i' to 'ì'
-compose '\'' 'I' to 'Í'
-compose '\'' 'i' to 'í'
-compose '^' 'I' to 'Î'
-compose '^' 'i' to 'î'
-compose '"' 'I' to 'Ï'
-compose '"' 'i' to 'ï'
-compose '-' 'D' to 'Ð'
-compose '-' 'd' to 'ð'
-compose '~' 'N' to 'Ñ'
-compose '~' 'n' to 'ñ'
-compose '`' 'O' to 'Ò'
-compose '`' 'o' to 'ò'
-compose '\'' 'O' to 'Ó'
-compose '\'' 'o' to 'ó'
-compose '^' 'O' to 'Ô'
-compose '^' 'o' to 'ô'
-compose '~' 'O' to 'Õ'
-compose '~' 'o' to 'õ'
-compose '"' 'O' to 'Ö'
-compose '"' 'o' to 'ö'
-compose '/' 'O' to 'Ø'
-compose '/' 'o' to 'ø'
-compose '`' 'U' to 'Ù'
-compose '`' 'u' to 'ù'
-compose '\'' 'U' to 'Ú'
-compose '\'' 'u' to 'ú'
-compose '^' 'U' to 'Û'
-compose '^' 'u' to 'û'
-compose '"' 'U' to 'Ü'
-compose '"' 'u' to 'ü'
-compose '\'' 'Y' to 'Ý'
-compose '\'' 'y' to 'ý'
-compose 'T' 'H' to 'Þ'
-compose 't' 'h' to 'þ'
-compose 's' 's' to 'ß'
-compose '"' 'y' to 'ÿ'
-compose 's' 'z' to 'ß'
-compose 'i' 'j' to 'ÿ'
diff -Nru a/drivers/sbus/char/sunmouse.c b/drivers/sbus/char/sunmouse.c
--- a/drivers/sbus/char/sunmouse.c	Sat Aug 10 18:42:22 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,614 +0,0 @@
-/* sunmouse.c: Sun mouse driver for the Sparc
- *
- * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
- *
- * Parts based on the psaux.c driver written by:
- * Johan Myreen.
- *
- * Dec/19/95 Added SunOS mouse ioctls - miguel.
- * Jan/5/96  Added VUID support, sigio support - miguel.
- * Mar/5/96  Added proper mouse stream support - miguel.
- * Sep/96    Allow more than one reader -miguel.
- * Aug/97    Added PCI 8042 controller support -DaveM
- */
-
-/* The mouse is run off of one of the Zilog serial ports.  On
- * that port is the mouse and the keyboard, each gets a zs channel.
- * The mouse itself is mouse-systems in nature.  So the protocol is:
- *
- * Byte 1) Button state which is bit-encoded as
- *            0x4 == left-button down, else up
- *            0x2 == middle-button down, else up
- *            0x1 == right-button down, else up
- *
- * Byte 2) Delta-x
- * Byte 3) Delta-y
- * Byte 4) Delta-x again
- * Byte 5) Delta-y again
- *
- * One day this driver will have to support more than one mouse in the system.
- *
- * This driver has two modes of operation: the default VUID_NATIVE is
- * set when the device is opened and allows the application to see the
- * mouse character stream as we get it from the serial (for gpm for
- * example).  The second method, VUID_FIRM_EVENT will provide cooked
- * events in Firm_event records as expected by SunOS/Solaris applications.
- *
- * FIXME: We need to support more than one mouse.
- * */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/fcntl.h>
-#include <linux/signal.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/miscdevice.h>
-#include <linux/mm.h>
-#include <linux/poll.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/vuid_event.h>
-#include <linux/random.h>
-/* The following keeps track of software state for the Sun
- * mouse.
- */
-#define STREAM_SIZE   2048
-#define EV_SIZE       (STREAM_SIZE/sizeof (Firm_event))
-#define BUTTON_LEFT   4
-#define BUTTON_MIDDLE 2
-#define BUTTON_RIGHT  1
-
-struct sun_mouse {
-	unsigned char transaction[5];  /* Each protocol transaction */
-	unsigned char byte;            /* Counter, starts at 0 */
-	unsigned char button_state;    /* Current button state */
-	unsigned char prev_state;      /* Previous button state */
-	int delta_x;                   /* Current delta-x */
-	int delta_y;                   /* Current delta-y */
-	int active;		       /* set if device is open */
-        int vuid_mode;	               /* VUID_NATIVE or VUID_FIRM_EVENT */
-	wait_queue_head_t proc_list;
-	struct fasync_struct *fasync;
-	
-	/* The event/stream queue */
-	spinlock_t lock;
-	unsigned int head;
-	unsigned int tail;
-	union {
-		char stream [STREAM_SIZE];
-		Firm_event ev [EV_SIZE];
-	} queue;
-};
-
-static struct sun_mouse sunmouse;
-#define gen_events (sunmouse.vuid_mode != VUID_NATIVE)
-#define bstate sunmouse.button_state
-#define pstate sunmouse.prev_state
-
-extern void mouse_put_char(char ch);
-
-#undef SMOUSE_DEBUG
-
-static int
-push_event (Firm_event *ev)
-{
-	unsigned long flags;
-	int next, ret;
-	
-	spin_lock_irqsave(&sunmouse.lock, flags);
-
-	next = (sunmouse.head + 1) % EV_SIZE;
-	ret = 0;
-	if (next != sunmouse.tail) {
-		sunmouse.queue.ev [sunmouse.head] = *ev;
-		sunmouse.head = next;
-		ret = 1;
-	}
-
-	spin_unlock_irqrestore(&sunmouse.lock, flags);
-
-	return ret;
-}
-
-static int
-queue_empty (void)
-{
-	return sunmouse.head == sunmouse.tail;
-}
-
-/* Must be invoked under the sunmouse.lock */
-static void get_from_queue (Firm_event *p)
-{
-	*p = sunmouse.queue.ev [sunmouse.tail];
-	sunmouse.tail = (sunmouse.tail + 1) % EV_SIZE;
-}
-
-static void
-push_char (char c)
-{
-	unsigned long flags;
-	int next;
-
-	spin_lock_irqsave(&sunmouse.lock, flags);
-
-	next = (sunmouse.head + 1) % STREAM_SIZE;
-	if (next != sunmouse.tail) {
-#ifdef SMOUSE_DEBUG
-		printk("P<%02x>\n", (unsigned char)c);
-#endif
-		sunmouse.queue.stream [sunmouse.head] = c;
-		sunmouse.head = next;
-	}
-
-	spin_unlock_irqrestore(&sunmouse.lock, flags);
-
-	kill_fasync (&sunmouse.fasync, SIGIO, POLL_IN);
-	wake_up_interruptible (&sunmouse.proc_list);
-}
-
-/* Auto baud rate "detection".  ;-) */
-static int mouse_baud = 4800;		/* Initial rate set by zilog driver. */
-
-/* Change the baud rate after receiving too many "bogon bytes". */
-void sun_mouse_change_baud(void)
-{
-	extern void rs_change_mouse_baud(int newbaud);
-
-	if(mouse_baud == 1200)
-		mouse_baud = 2400;
-	else if(mouse_baud == 2400)
-		mouse_baud = 4800;
-	else if(mouse_baud == 4800)
-		mouse_baud = 9600;
-	else
-		mouse_baud = 1200;
-
-	rs_change_mouse_baud(mouse_baud);
-}
-
-/* This tries to monitor the mouse state so that it
- * can automatically adjust to the correct baud rate.
- * The mouse spits out BRKs when the baud rate is
- * incorrect.
- *
- * It returns non-zero if we should ignore this byte.
- */
-int mouse_baud_detection(unsigned char c, int is_break)
-{
-	static int mouse_got_break = 0;
-	static int ctr = 0;
-
-	if (is_break) {
-		/* Let a few normal bytes go by before
-		 * we jump the gun and say we need to
-		 * try another baud rate.
-		 */
-		if (mouse_got_break && ctr < 8)
-			return 1;
-
-		/* OK, we need to try another baud rate. */
-		sun_mouse_change_baud();
-		ctr = 0;
-		mouse_got_break = 1;
-		return 1;
-	}
-	if (mouse_got_break) {
-		ctr++;
-		if (c == 0x87) {
-			printk(KERN_INFO "sunmouse: Successfully "
-			       "adjusted to %d baud.\n", mouse_baud);
-			mouse_got_break = 0;
-		}
-		return 1;
-	}
-
-	return 0;
-}
-
-/* You ask me, why does this cap the lower bound at -127 and not
- * -128?  Because the xf86 mouse code is crap and treats -128
- * as an illegal value and resets it's protocol state machine
- * when it sees this value.
- */
-#define CLIP(__X)	(((__X) > 127) ? 127 : (((__X) < -127) ? -127 : (__X)))
-
-/* The following is called from the serial driver when bytes/breaks
- * are received on the Mouse line.
- */
-void
-sun_mouse_inbyte(unsigned char byte, int is_break)
-{
-	signed char mvalue;
-	int d, pushed = 0;
-	Firm_event ev;
-
-	add_mouse_randomness (byte);
-#if 0
-	{
-		static int xxx = 0;
-		printk("mouse(%02x:%d) ",
-		       byte, is_break);
-		if (byte == 0x87) {
-			xxx = 0;
-			printk("\n");
-		}
-	}
-#endif
-	if (mouse_baud_detection(byte, is_break))
-		return;
-
-	if(!sunmouse.active)
-		return;
-
-	/* Ignore this if it is garbage. */
-	if (sunmouse.byte == 69) {
-		if (byte != 0x87)
-			return;
-
-		/* Ok, we've begun the state machine. */
-		sunmouse.byte = 0;
-	}
-#if 0
-	/* If the mouse sends us a byte from 0x80 to 0x87
-	 * we are starting at byte zero in the transaction
-	 * protocol.
-	 */
-	if((byte & ~0x0f) == 0x80) 
-		sunmouse.byte = 0;
-#endif
-
-	mvalue = (signed char) byte;
-	switch(sunmouse.byte) {
-	case 0:
-		/* If we get a bogus button byte, just skip it.
-		 * When we get here the baud detection code has
-		 * passed, so the only other things which can
-		 * cause this are dropped serial characters and
-		 * confused mouse.  We check this because otherwise
-		 * begin posting erroneous mouse events.
-		 */
-		if ((byte & 0xf0) != 0x80)
-			return;
-
-		/* Button state */
-		sunmouse.button_state = (~byte) & 0x7;
-#ifdef SMOUSE_DEBUG
-		printk("B<Left %s, Middle %s, Right %s>",
-		       ((sunmouse.button_state & 0x4) ? "DOWN" : "UP"),
-		       ((sunmouse.button_state & 0x2) ? "DOWN" : "UP"),
-		       ((sunmouse.button_state & 0x1) ? "DOWN" : "UP"));
-#endif
-		/* To deal with the Sparcbook 3 */
-		if (byte & 0x8) {
-			sunmouse.byte += 2;
-			sunmouse.delta_y = 0;
-			sunmouse.delta_x = 0;
-		}
-		sunmouse.byte++;
-		return;
-	case 1:
-		/* Delta-x 1 */
-#ifdef SMOUSE_DEBUG
-		printk("DX1<%d>", mvalue);
-#endif
-		sunmouse.delta_x = mvalue;
-		sunmouse.byte++;
-		return;
-	case 2:
-		/* Delta-y 1 */
-#ifdef SMOUSE_DEBUG
-		printk("DY1<%d>", mvalue);
-#endif
-		sunmouse.delta_y = mvalue;
-		sunmouse.byte++;
-		return;
-	case 3:
-		/* Delta-x 2 */
-#ifdef SMOUSE_DEBUG
-		printk("DX2<%d>", mvalue);
-#endif
-		sunmouse.delta_x += mvalue;
-		sunmouse.delta_x = CLIP(sunmouse.delta_x);
-		sunmouse.byte++;
-		return;
-	case 4:
-		/* Last byte, Delta-y 2 */
-#ifdef SMOUSE_DEBUG
-		printk("DY2<%d>", mvalue);
-#endif
-		sunmouse.delta_y += mvalue;
-		sunmouse.delta_y = CLIP(sunmouse.delta_y);
-		sunmouse.byte = 0;  /* Back to button state */
-		break;
-	case 69:
-		/* Until we get the (0x80 -> 0x87) value we aren't
-		 * in the middle of a real transaction, so just
-		 * return.
-		 */
-		return;
-	default:
-		printk("sunmouse: bogon transaction state\n");
-		sunmouse.byte = 69;  /* What could cause this? */
-		return;
-	};
-
-	if (!gen_events) {
-		push_char (~sunmouse.button_state & 0x87);
-		push_char (sunmouse.delta_x);
-		push_char (sunmouse.delta_y);
-		return;
-	}
-
-	d = bstate ^ pstate;
-	pstate = bstate;
-	if (d) {
-		if (d & BUTTON_LEFT) {
-			ev.id = MS_LEFT;
-			ev.value = bstate & BUTTON_LEFT;
-		}
-		if (d & BUTTON_RIGHT) {
-			ev.id = MS_RIGHT;
-			ev.value = bstate & BUTTON_RIGHT;
-		}
-		if (d & BUTTON_MIDDLE) {
-			ev.id = MS_MIDDLE;
-			ev.value = bstate & BUTTON_MIDDLE;
-		}
-		ev.time = xtime;
-		ev.value = ev.value ? VKEY_DOWN : VKEY_UP;
-		pushed += push_event (&ev);
-	}
-	if (sunmouse.delta_x) {
-		ev.id = LOC_X_DELTA;
-		ev.time = xtime;
-		ev.value = sunmouse.delta_x;
-		pushed += push_event (&ev);
-		sunmouse.delta_x = 0;
-	}
-	if (sunmouse.delta_y) {
-		ev.id = LOC_Y_DELTA;
-		ev.time = xtime;
-		ev.value = sunmouse.delta_y;
-		pushed += push_event (&ev);
-	}
-	
-	if (pushed != 0) {
-		/* We just completed a transaction, wake up whoever is awaiting
-		 * this event.
-		 */
-		kill_fasync (&sunmouse.fasync, SIGIO, POLL_IN);
-		wake_up_interruptible(&sunmouse.proc_list);
-	}
-	return;
-}
-
-static int
-sun_mouse_open(struct inode * inode, struct file * file)
-{
-	spin_lock_irq(&sunmouse.lock);
-	if (sunmouse.active++)
-		goto out;
-	sunmouse.delta_x = sunmouse.delta_y = 0;
-	sunmouse.button_state = 0x80;
-	sunmouse.vuid_mode = VUID_NATIVE;
-out:
-	spin_unlock_irq(&sunmouse.lock);
-	return 0;
-}
-
-static int sun_mouse_fasync (int fd, struct file *filp, int on)
-{
-	int retval;
-
-	retval = fasync_helper (fd, filp, on, &sunmouse.fasync);
-	if (retval < 0)
-		return retval;
-	return 0;
-}
-
-static int
-sun_mouse_close(struct inode *inode, struct file *file)
-{
-	sun_mouse_fasync (-1, file, 0);
-
-	spin_lock_irq(&sunmouse.lock);
-	sunmouse.active--;
-	spin_unlock_irq(&sunmouse.lock);
-
-	return 0;
-}
-
-static ssize_t
-sun_mouse_write(struct file *file, const char *buffer,
-		size_t count, loff_t *ppos)
-{
-	return -EINVAL;  /* foo on you */
-}
-
-static ssize_t
-sun_mouse_read(struct file *file, char *buffer,
-	       size_t count, loff_t *ppos)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long flags;
-
-	if (queue_empty ()) {
-		if (file->f_flags & O_NONBLOCK)
-			return -EWOULDBLOCK;
-		add_wait_queue (&sunmouse.proc_list, &wait);
-repeat:
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (queue_empty() && !signal_pending(current)) {
-			schedule();
-			goto repeat;
-		}
-		current->state = TASK_RUNNING;
-		remove_wait_queue (&sunmouse.proc_list, &wait);
-	}
-	if (gen_events) {
-		char *p = buffer, *end = buffer+count;
-		
-		spin_lock_irqsave(&sunmouse.lock, flags);
-		while (p < end && !queue_empty ()){
-			Firm_event this_event;
-
-			get_from_queue(&this_event);
-			spin_unlock_irqrestore(&sunmouse.lock, flags);
-
-#ifdef CONFIG_SPARC32_COMPAT
-			if (test_thread_flag(TIF_32BIT)) {
-				if ((end - p) <
-				    ((sizeof(Firm_event) - sizeof(struct timeval) +
-				      (sizeof(u32) * 2))))
-					break;
-				if (copy_to_user((Firm_event *)p, &this_event,
-						 sizeof(Firm_event)-sizeof(struct timeval)))
-					return -EFAULT;
-				p += sizeof(Firm_event)-sizeof(struct timeval);
-				if (__put_user(this_event.time.tv_sec, (u32 *)p))
-					return -EFAULT;
-				p += sizeof(u32);
-				if (__put_user(this_event.time.tv_usec, (u32 *)p))
-					return -EFAULT;
-				p += sizeof(u32);
-			} else
-#endif	
-			{	
-				if ((end - p) < sizeof(Firm_event))
-					break;
-				if (copy_to_user((Firm_event *)p, &this_event,
-				     		 sizeof(Firm_event)))
-					return -EFAULT;
-				p += sizeof (Firm_event);
-			}
-			spin_lock_irqsave(&sunmouse.lock, flags);
-		}
-		spin_unlock_irqrestore(&sunmouse.lock, flags);
-		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
-		return p-buffer;
-	} else {
-		int c, limit = 3;
-
-		if (count < limit)
-			limit = count;
-		for (c = 0; c < limit; c++) {
-			unsigned char val;
-			int empty = 0;
-
-			spin_lock_irqsave(&sunmouse.lock, flags);
-			if (queue_empty()) {
-				empty = 1;
-				val = 0;
-			} else {
-				val = sunmouse.queue.stream[sunmouse.tail];
-				sunmouse.tail = (sunmouse.tail + 1) % STREAM_SIZE;
-			}
-			spin_unlock_irqrestore(&sunmouse.lock, flags);
-
-			if (empty)
-				break;
-
-			put_user(val, buffer);
-			buffer++;
-		}
-		while (c < count) {
-			if (c >= 5)
-				break;
-			put_user(0, buffer);
-			buffer++;
-			c++;
-		}
-		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
-		return c;
-	}
-	/* Only called if nothing was sent */
-	if (signal_pending(current))
-		return -ERESTARTSYS;
-	return 0;
-}
-
-static unsigned int sun_mouse_poll(struct file *file, poll_table *wait)
-{
-	poll_wait(file, &sunmouse.proc_list, wait);
-	if(!queue_empty())
-		return POLLIN | POLLRDNORM;
-	return 0;
-}
-int
-sun_mouse_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
-	int i;
-	
-	switch (cmd){
-		/* VUIDGFORMAT - Get input device byte stream format */
-	case _IOR('v', 2, int):
-		if (put_user(sunmouse.vuid_mode, (int *) arg))
-			return -EFAULT;
-		break;
-
-		/* VUIDSFORMAT - Set input device byte stream format*/
-	case _IOW('v', 1, int):
-		if (get_user(i, (int *) arg))
-			return -EFAULT;
-		if (i == VUID_NATIVE || i == VUID_FIRM_EVENT){
-			int value;
-
-			if (get_user(value, (int *)arg))
-				return -EFAULT;
-
-			spin_lock_irq(&sunmouse.lock);
-			sunmouse.vuid_mode = value;
-			sunmouse.head = sunmouse.tail = 0;
-			spin_unlock_irq(&sunmouse.lock);
-		} else
-			return -EINVAL;
-		break;
-
-	case 0x8024540b:
-	case 0x40245408:
-		/* This is a buggy application doing termios on the mouse driver */
-		/* we ignore it.  I keep this check here so that we will notice   */
-		/* future mouse vuid ioctls */
-		return -ENOTTY;
-		
-	default:
-#ifdef DEBUG
-		printk ("[MOUSE-ioctl: %8.8x]\n", cmd);
-#endif
-		return -EINVAL;
-	}
-	return 0;
-}
-
-struct file_operations sun_mouse_fops = {
-	read:		sun_mouse_read,
-	write:		sun_mouse_write,
-	poll:		sun_mouse_poll,
-	ioctl:		sun_mouse_ioctl,
-	open:		sun_mouse_open,
-	release:	sun_mouse_close,
-	fasync:		sun_mouse_fasync,
-};
-
-static struct miscdevice sun_mouse_mouse = {
-	SUN_MOUSE_MINOR, "sunmouse", &sun_mouse_fops
-};
-
-void sun_mouse_zsinit(void)
-{
-	printk("Sun Mouse-Systems mouse driver version 1.00\n");
-
-	sunmouse.active = 0;
-	misc_register (&sun_mouse_mouse);
-	sunmouse.delta_x = sunmouse.delta_y = 0;
-	sunmouse.button_state = 0x80;
-	init_waitqueue_head(&sunmouse.proc_list);
-	spin_lock_init(&sunmouse.lock);
-	sunmouse.byte = 69;
-}
diff -Nru a/drivers/sbus/char/sunmouse.h b/drivers/sbus/char/sunmouse.h
--- a/drivers/sbus/char/sunmouse.h	Sat Aug 10 18:42:21 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,13 +0,0 @@
-/* $Id: sunmouse.h,v 1.2 1999/11/19 09:56:34 davem Exp $
- * sunmouse.h: Interface to the SUN mouse driver.
- *
- * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
- */
-
-#ifndef _SPARC_SUNMOUSE_H
-#define _SPARC_SUNMOUSE_H 1
-
-extern void sun_mouse_zsinit(void);
-extern void sun_mouse_inbyte(unsigned char, int);
-
-#endif /* !(_SPARC_SUNMOUSE_H) */
diff -Nru a/drivers/sbus/char/sunserial.c b/drivers/sbus/char/sunserial.c
--- a/drivers/sbus/char/sunserial.c	Sat Aug 10 18:42:20 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,457 +0,0 @@
-/* $Id: sunserial.c,v 1.81 2002/01/05 01:13:43 davem Exp $
- * serial.c: Serial port driver infrastructure for the Sparc.
- *
- * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/tty.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/string.h>
-#include <linux/kbd_diacr.h>
-#include <linux/version.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-
-#include <asm/oplib.h>
-
-#include "sunserial.h"
-
-int serial_console;
-int stop_a_enabled = 1;
-
-int __init con_is_present(void)
-{
-	return serial_console ? 0 : 1;
-}
-
-static void __init nop_rs_kgdb_hook(int channel)
-{
-	printk("Oops: %s called\n", __FUNCTION__);
-}
-
-static void nop_rs_change_mouse_baud(int baud)
-{
-	printk("Oops: %s called\n", __FUNCTION__);
-}
-
-static int nop_rs_read_proc(char *page, char **start, off_t off, int count,
-			    int *eof, void *data)
-{
-	printk("Oops: %s called\n", __FUNCTION__);
-	return 0;
-}
-
-struct sunserial_operations rs_ops = {
-	0,
-	nop_rs_kgdb_hook,
-	nop_rs_change_mouse_baud,
-	nop_rs_read_proc
-};
-
-void rs_init(void)
-{
-	static int invoked = 0;
-
-	if (!invoked) {
-		struct initfunc *init;
-
-		invoked = 1;
-
-		init = rs_ops.rs_init;
-		while (init) {
-			(void) init->init();
-			init = init->next;
-		}
-	}
-}
-
-void __init rs_kgdb_hook(int channel)
-{
-	rs_ops.rs_kgdb_hook(channel);
-}
-
-void __init serial_console_init(void)
-{
-	return;
-}
-
-void rs_change_mouse_baud(int baud)
-{
-	rs_ops.rs_change_mouse_baud(baud);
-}
-
-int rs_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
-{
-	return rs_ops.rs_read_proc(page, start, off, count, eof, data);
-}
-
-int register_serial(struct serial_struct *req)
-{
-	return -1;
-}
-
-void unregister_serial(int line)
-{
-}
-
-
-static void nop_compute_shiftstate (void)
-{
-	printk("Oops: %s called\n", __FUNCTION__);
-}
-
-static void nop_setledstate (struct kbd_struct *kbd, unsigned int ledstate)
-{
-	printk("Oops: %s called\n", __FUNCTION__);
-}
-
-static unsigned char nop_getledstate (void)
-{
-	printk("Oops: %s called\n", __FUNCTION__);
-	return 0;
-}
-
-static int nop_setkeycode (unsigned int scancode, unsigned int keycode)
-{
-	printk("Oops: %s called\n", __FUNCTION__);
-	return -EINVAL;
-}
-
-static int nop_getkeycode (unsigned int scancode)
-{
-	printk("Oops: %s called\n", __FUNCTION__);
-	return -EINVAL;
-}
-
-struct sunkbd_operations kbd_ops = {
-	0,
-	nop_compute_shiftstate,
-	nop_setledstate,
-	nop_getledstate,
-	nop_setkeycode,
-	nop_getkeycode
-};
-
-#ifdef CONFIG_USB
-extern void pci_compute_shiftstate(void);
-extern int pci_setkeycode(unsigned int, unsigned int);
-extern int pci_getkeycode(unsigned int);
-extern void pci_setledstate(struct kbd_struct *, unsigned int);
-extern unsigned char pci_getledstate(void);
-extern int pcikbd_init(void);
-#endif
-
-int kbd_init(void)
-{
-	struct initfunc *init;
-	int err = -ENODEV;
-
-	init = kbd_ops.kbd_init;
-	while (init) {
-		err = init->init();
-		init = init->next;
-	}
-#ifdef CONFIG_USB
-	if (!serial_console &&
-	    kbd_ops.compute_shiftstate == nop_compute_shiftstate) {
-		printk("kbd_init: Assuming USB keyboard.\n");
-		kbd_ops.compute_shiftstate = pci_compute_shiftstate;
-		kbd_ops.setledstate = pci_setledstate;
-		kbd_ops.getledstate = pci_getledstate;
-		kbd_ops.setkeycode = pci_setkeycode;
-		kbd_ops.getkeycode = pci_getkeycode;
-		pcikbd_init();
-	}
-#endif
-	return err;
-}
-
-void compute_shiftstate (void)
-{
-	kbd_ops.compute_shiftstate();
-}
-
-void setledstate (struct kbd_struct *kbd, unsigned int ledstate)
-{
-	kbd_ops.setledstate(kbd, ledstate);
-}
-
-unsigned char getledstate (void)
-{
-	return kbd_ops.getledstate();
-}
-
-int setkeycode (unsigned int scancode, unsigned int keycode)
-{
-	return kbd_ops.setkeycode(scancode, keycode);
-}
-
-int getkeycode (unsigned int scancode)
-{
-	return kbd_ops.getkeycode(scancode);
-}
-
-void * __init sunserial_alloc_bootmem(unsigned long size)
-{
-	void *ret;
-
-	ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
-	if (ret != NULL)
-		memset(ret, 0, size);
-
-	return ret;
-}
-
-void
-sunserial_setinitfunc(int (*init) (void))
-{
-	struct initfunc *rs_init;
-
-	rs_init = sunserial_alloc_bootmem(sizeof(struct initfunc));
-	if (rs_init == NULL) {
-		prom_printf("sunserial_setinitfunc: Cannot alloc initfunc.\n");
-		prom_halt();
-	}
-
-	rs_init->init = init;
-	rs_init->next = rs_ops.rs_init;
-	rs_ops.rs_init = rs_init;
-}
-
-void
-sunserial_console_termios(struct console *con)
-{
-	char mode[16], buf[16], *s;
-	char *mode_prop = "ttyX-mode";
-	char *cd_prop = "ttyX-ignore-cd";
-	char *dtr_prop = "ttyX-rts-dtr-off";
-	int baud, bits, stop, cflag;
-	char parity;
-	int carrier = 0;
-	int rtsdtr = 1;
-	int topnd, nd;
-
-	if (!serial_console)
-		return;
-
-	if (serial_console == 1) {
-		mode_prop[3] = 'a';
-		cd_prop[3] = 'a';
-		dtr_prop[3] = 'a';
-	} else {
-		mode_prop[3] = 'b';
-		cd_prop[3] = 'b';
-		dtr_prop[3] = 'b';
-	}
-
-	topnd = prom_getchild(prom_root_node);
-	nd = prom_searchsiblings(topnd, "options");
-	if (!nd) {
-		strcpy(mode, "9600,8,n,1,-");
-		goto no_options;
-	}
-
-	if (!prom_node_has_property(nd, mode_prop)) {
-		strcpy(mode, "9600,8,n,1,-");
-		goto no_options;
-	}
-
-	memset(mode, 0, sizeof(mode));
-	prom_getstring(nd, mode_prop, mode, sizeof(mode));
-
-	if (prom_node_has_property(nd, cd_prop)) {
-		memset(buf, 0, sizeof(buf));
-		prom_getstring(nd, cd_prop, buf, sizeof(buf));
-		if (!strcmp(buf, "false"))
-			carrier = 1;
-
-		/* XXX: this is unused below. */
-	}
-
-	if (prom_node_has_property(nd, cd_prop)) {
-		memset(buf, 0, sizeof(buf));
-		prom_getstring(nd, cd_prop, buf, sizeof(buf));
-		if (!strcmp(buf, "false"))
-			rtsdtr = 0;
-
-		/* XXX: this is unused below. */
-	}
-
-no_options:
-	cflag = CREAD | HUPCL | CLOCAL;
-
-	s = mode;
-	baud = simple_strtoul(s, 0, 0);
-	s = strchr(s, ',');
-	bits = simple_strtoul(++s, 0, 0);
-	s = strchr(s, ',');
-	parity = *(++s);
-	s = strchr(s, ',');
-	stop = simple_strtoul(++s, 0, 0);
-	s = strchr(s, ',');
-	/* XXX handshake is not handled here. */
-
-	switch (baud) {
-		case 150: cflag |= B150; break;
-		case 300: cflag |= B300; break;
-		case 600: cflag |= B600; break;
-		case 1200: cflag |= B1200; break;
-		case 2400: cflag |= B2400; break;
-		case 4800: cflag |= B4800; break;
-		case 9600: cflag |= B9600; break;
-		case 19200: cflag |= B19200; break;
-		case 38400: cflag |= B38400; break;
-		default: baud = 9600; cflag |= B9600; break;
-	}
-
-	switch (bits) {
-		case 5: cflag |= CS5; break;
-		case 6: cflag |= CS6; break;
-		case 7: cflag |= CS7; break;
-		case 8: cflag |= CS8; break;
-		default: cflag |= CS8; break;
-	}
-
-	switch (parity) {
-		case 'o': cflag |= (PARENB | PARODD); break;
-		case 'e': cflag |= PARENB; break;
-		case 'n': default: break;
-	}
-
-	switch (stop) {
-		case 2: cflag |= CSTOPB; break;
-		case 1: default: break;
-	}
-
-	con->cflag = cflag;
-}
-
-void
-sunkbd_setinitfunc(int (*init) (void))
-{
-	struct initfunc *kbd_init;
-
-	kbd_init = sunserial_alloc_bootmem(sizeof(struct initfunc));
-	if (kbd_init == NULL) {
-		prom_printf("sunkbd_setinitfunc: Cannot alloc initfunc.\n");
-		prom_halt();
-	}
-
-	kbd_init->init = init;
-	kbd_init->next = kbd_ops.kbd_init;
-	kbd_ops.kbd_init = kbd_init;
-}
-
-#ifdef CONFIG_PCI
-void
-sunkbd_install_keymaps(ushort **src_key_maps, unsigned int src_keymap_count,
-		       char *src_func_buf, char **src_func_table,
-		       int src_funcbufsize, int src_funcbufleft,
-		       struct kbdiacr *src_accent_table,
-		       unsigned int src_accent_table_size)
-{
-	extern unsigned int keymap_count;
-	int i, j;
-
-	for (i = 0; i < MAX_NR_KEYMAPS; i++) {
-		if (src_key_maps[i]) {
-			if (!key_maps[i]) {
-				key_maps[i] = (ushort *)
-					sunserial_alloc_bootmem(NR_KEYS * sizeof(ushort));
-				if (key_maps[i] == NULL) {
-					prom_printf("sunkbd_install_keymaps: "
-						    "Cannot alloc key_map(%d).\n", i);
-					prom_halt();
-				}
-			}
-			for (j = 0; j < NR_KEYS; j++)
-				key_maps[i][j] = src_key_maps[i][j];
-		}
-		key_maps[i] = src_key_maps[i];
-	}
-	keymap_count = src_keymap_count;
-
-	for (i = 0; i < MAX_NR_FUNC; i++)
-		func_table[i] = src_func_table[i];
-	funcbufptr = src_func_buf;
-	funcbufsize = src_funcbufsize;
-	funcbufleft = src_funcbufleft;
-
-	for (i = 0; i < MAX_DIACR; i++)
-		accent_table[i] = src_accent_table[i];
-	accent_table_size = src_accent_table_size;
-}
-#endif
-
-extern int su_probe(void);
-extern int zs_probe(void);
-#ifdef CONFIG_SAB82532
-extern int sab82532_probe(void);
-#endif
-#ifdef CONFIG_PCI
-extern int ps2kbd_probe(void);
-#endif
-
-void __init sun_serial_setup(void)
-{
-	int ret = 1;
-	
-#if defined(CONFIG_PCI) && !defined(__sparc_v9__)
-	/*
-	 * Probing sequence on sparc differs from sparc64.
-	 * Keyboard is probed ahead of su because we want su function
-	 * when keyboard is active. su is probed ahead of zs in order to
-	 * get console on MrCoffee with fine but disconnected zs.
-	 */
-	if (!serial_console)
-		ps2kbd_probe();
-	if (su_probe() == 0)
-		return;
-#endif
-
-	if (zs_probe() == 0)
-		return;
-		
-#ifdef CONFIG_SAB82532
-	ret = sab82532_probe();
-#endif
-
-#if defined(CONFIG_PCI) && defined(__sparc_v9__)
-	/*
-	 * Keyboard serial devices.
-	 *
-	 * Well done, Sun, prom_devopen("/pci@1f,4000/ebus@1/su@14,3083f8")
-	 * hangs the machine if no keyboard is connected to the device...
-	 * All PCI PROMs seem to do this, I have seen this on the Ultra 450
-	 * with version 3.5 PROM, and on the Ultra/AX with 3.1.5 PROM.
-	 *
-	 * So be very careful not to probe for keyboards if we are on a
-	 * serial console.
-	 */
-	if (!serial_console)
-		ps2kbd_probe();
-	if (su_probe() == 0)
-		return;
-#endif
-
-	if (!ret)
-		return;
-		
-#ifdef __sparc_v9__
-	{	extern int this_is_starfire;
-		/* Hello, Starfire. Pleased to meet you :) */
-		if(this_is_starfire != 0)
-			return;
-	}
-#endif
-
-	prom_printf("No serial devices found, bailing out.\n");
-	prom_halt();
-}
diff -Nru a/drivers/sbus/char/sunserial.h b/drivers/sbus/char/sunserial.h
--- a/drivers/sbus/char/sunserial.h	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,53 +0,0 @@
-/* $Id: sunserial.h,v 1.19 1999/12/01 10:45:59 davem Exp $
- * sunserial.h: SUN serial driver infrastructure (including keyboards).
- *
- * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
- */
-
-#ifndef _SPARC_SUNSERIAL_H
-#define _SPARC_SUNSERIAL_H 1
-
-#include <linux/config.h>
-#include <linux/tty.h>
-#include <linux/kd.h>
-#include <linux/kbd_kern.h>
-#include <linux/console.h>
-
-struct initfunc {
-	int		(*init) (void);
-	struct initfunc *next;
-};
-
-struct sunserial_operations {
-	struct initfunc	*rs_init;
-	void		(*rs_kgdb_hook) (int);
-	void		(*rs_change_mouse_baud) (int);
-	int		(*rs_read_proc) (char *, char **, off_t, int, int *, void *);
-};
-
-struct sunkbd_operations {
-	struct initfunc	*kbd_init;
-	void		(*compute_shiftstate) (void);
-	void		(*setledstate) (struct kbd_struct *, unsigned int);
-	unsigned char	(*getledstate) (void);
-	int		(*setkeycode) (unsigned int, unsigned int);
-	int		(*getkeycode) (unsigned int);
-};
-
-extern struct sunserial_operations rs_ops;
-extern struct sunkbd_operations kbd_ops;
-
-extern void sunserial_setinitfunc(int (*) (void));
-extern void sunkbd_setinitfunc(int (*) (void));
-
-extern int serial_console;
-extern int stop_a_enabled;
-extern void sunserial_console_termios(struct console *);
-
-#ifdef CONFIG_PCI
-extern void sunkbd_install_keymaps(ushort **, unsigned int, char *,
-				   char **, int, int, struct kbdiacr *,
-				   unsigned int);
-#endif
-
-#endif /* !(_SPARC_SUNSERIAL_H) */
diff -Nru a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c
--- a/drivers/sbus/char/uctrl.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/sbus/char/uctrl.c	Sat Aug 10 18:42:23 2002
@@ -224,10 +224,10 @@
 }
 
 static struct file_operations uctrl_fops = {
-	owner:		THIS_MODULE,
-	llseek:		no_llseek,
-	ioctl:		uctrl_ioctl,
-	open:		uctrl_open,
+	.owner =	THIS_MODULE,
+	.llseek =	no_llseek,
+	.ioctl =	uctrl_ioctl,
+	.open =		uctrl_open,
 };
 
 static struct miscdevice uctrl_dev = {
diff -Nru a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
--- a/drivers/sbus/char/vfc_dev.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/sbus/char/vfc_dev.c	Sat Aug 10 18:42:23 2002
@@ -643,12 +643,12 @@
 
 
 static struct file_operations vfc_fops = {
-	owner:		THIS_MODULE,
-	llseek:		no_llseek,
-	ioctl:		vfc_ioctl,
-	mmap:		vfc_mmap,
-	open:		vfc_open,
-	release:	vfc_release,
+	.owner =	THIS_MODULE,
+	.llseek =	no_llseek,
+	.ioctl =	vfc_ioctl,
+	.mmap =		vfc_mmap,
+	.open =		vfc_open,
+	.release =	vfc_release,
 };
 
 static int vfc_probe(void)
diff -Nru a/drivers/sbus/char/zs.c b/drivers/sbus/char/zs.c
--- a/drivers/sbus/char/zs.c	Sat Aug 10 18:42:24 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,2892 +0,0 @@
-/* $Id: zs.c,v 1.71 2002/01/12 07:04:54 davem Exp $
- * zs.c: Zilog serial port driver for the Sparc.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996 Eddie C. Dost   (ecd@skynet.be)
- * Fixes by Pete A. Zaitcev <zaitcev@yahoo.com>.
- *
- * Fixed to use tty_get_baud_rate().
- *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
- *
- * /proc/tty/driver/serial now exists and is readable.
- *   Alex Buell <alex.buell@tahallah.demon.co.uk>, 2001-12-23
- *
- */
-
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/config.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/keyboard.h>
-#include <linux/console.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/sysrq.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/oplib.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/bitops.h>
-#include <asm/kdebug.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-#include <asm/sbus.h>
-#ifdef __sparc_v9__
-#include <asm/fhc.h>
-#endif
-#ifdef CONFIG_PCI
-#include <linux/pci.h>
-#endif
-
-#include "sunserial.h"
-#include "zs.h"
-#include "sunkbd.h"
-#include "sunmouse.h"
-
-static int num_serial = 2; /* sun4/sun4c/sun4m - Two chips on board. */
-#define NUM_SERIAL num_serial
-#define NUM_CHANNELS (NUM_SERIAL * 2)
-
-#define KEYBOARD_LINE 0x2
-#define MOUSE_LINE    0x3
-
-/* On 32-bit sparcs we need to delay after register accesses
- * to accomodate sun4 systems, but we do not need to flush writes.
- * On 64-bit sparc we only need to flush single writes to ensure
- * completion.
- */
-#ifndef __sparc_v9__
-#define ZSDELAY()		udelay(5)
-#define ZSDELAY_LONG()		udelay(20)
-#define ZS_WSYNC(channel)	do { } while(0)
-#else
-#define ZSDELAY()
-#define ZSDELAY_LONG()
-#define ZS_WSYNC(__channel) \
-	sbus_readb(&((__channel)->control))
-#endif
-
-struct sun_zslayout **zs_chips;
-struct sun_zschannel **zs_channels;
-struct sun_zschannel *zs_mousechan;
-struct sun_zschannel *zs_kbdchan;
-struct sun_zschannel *zs_kgdbchan;
-int *zs_nodes;
-
-struct sun_serial *zs_soft;
-struct sun_serial *zs_chain;  /* IRQ servicing chain */
-int zilog_irq;
-
-struct tty_struct *zs_ttys;
-
-/* Console hooks... */
-#ifdef CONFIG_SERIAL_CONSOLE
-static struct console zs_console;
-static int zs_console_init(void);
-
-/*
- * Define this to get the zs_fair_output() functionality.
- */
-#undef SERIAL_CONSOLE_FAIR_OUTPUT
-#endif /* CONFIG_SERIAL_CONSOLE */
-
-static unsigned char kgdb_regs[16] = {
-	0, 0, 0,                     /* write 0, 1, 2 */
-	(Rx8 | RxENAB),              /* write 3 */
-	(X16CLK | SB1 | PAR_EVEN),   /* write 4 */
-	(DTR | Tx8 | TxENAB),        /* write 5 */
-	0, 0, 0,                     /* write 6, 7, 8 */
-	(NV),                        /* write 9 */
-	(NRZ),                       /* write 10 */
-	(TCBR | RCBR),               /* write 11 */
-	0, 0,                        /* BRG time constant, write 12 + 13 */
-	(BRSRC | BRENAB),            /* write 14 */
-	(DCDIE)                      /* write 15 */
-};
-
-static unsigned char zscons_regs[16] = {
-	0,                           /* write 0 */
-	(EXT_INT_ENAB | INT_ALL_Rx), /* write 1 */
-	0,                           /* write 2 */
-	(Rx8 | RxENAB),              /* write 3 */
-	(X16CLK),                    /* write 4 */
-	(DTR | Tx8 | TxENAB),        /* write 5 */
-	0, 0, 0,                     /* write 6, 7, 8 */
-	(NV | MIE),                  /* write 9 */
-	(NRZ),                       /* write 10 */
-	(TCBR | RCBR),               /* write 11 */
-	0, 0,                        /* BRG time constant, write 12 + 13 */
-	(BRSRC | BRENAB),            /* write 14 */
-	(DCDIE | CTSIE | TxUIE | BRKIE) /* write 15 */
-};
-
-#define ZS_CLOCK         4915200   /* Zilog input clock rate */
-
-DECLARE_TASK_QUEUE(tq_serial);
-
-static struct tty_driver serial_driver, callout_driver;
-static int serial_refcount;
-
-/* serial subtype definitions */
-#define SERIAL_TYPE_NORMAL	1
-#define SERIAL_TYPE_CALLOUT	2
-  
-/* number of characters left in xmit buffer before we ask for more */
-#define WAKEUP_CHARS 256
-
-#define SERIAL_DO_RESTART
-
-/* Debugging... DEBUG_INTR is bad to use when one of the zs
- * lines is your console ;(
- */
-#undef SERIAL_DEBUG_INTR
-#undef SERIAL_DEBUG_OPEN
-#undef SERIAL_DEBUG_FLOW
-
-#define RS_STROBE_TIME 10
-#define RS_ISR_PASS_LIMIT 256
-
-#define _INLINE_ inline
-
-int zs_init(void);
-static void zs_kgdb_hook(int);
-
-static void change_speed(struct sun_serial *info);
-
-static struct tty_struct **serial_table;
-static struct termios **serial_termios;
-static struct termios **serial_termios_locked;
-
-#ifndef MIN
-#define MIN(a,b)	((a) < (b) ? (a) : (b))
-#endif
-
-#undef ZS_LOG
-#ifdef ZS_LOG
-struct zs_logent {
-	u8 reg, val;
-	u8 write, __pad;
-#define REGIRQ	0xff
-#define REGDATA	0xfe
-#define REGCTRL	0xfd
-};
-struct zs_logent zslog[32];
-int zs_curlog;
-#define ZSLOG(__reg, __val, __write) \
-do{	int index = zs_curlog; \
-	zslog[index].reg = (__reg); \
-	zslog[index].val = (__val); \
-	zslog[index].write = (__write); \
-	zs_curlog = (index + 1) & (32 - 1); \
-}while(0)
-int zs_dumplog(char *buffer)
-{
-	int len = 0;
-	int i;
-
-	for (i = 0; i < 32; i++) {
-		u8 reg, val, write;
-
-		reg = zslog[i].reg;
-		val = zslog[i].val;
-		write = zslog[i].write;
-		len += sprintf(buffer + len,
-			       "ZSLOG[%2d]: reg %2x val %2x %s\n",
-			       i, reg, val, write ? "write" : "read");
-	}
-	len += sprintf(buffer + len, "ZS current log index %d\n",
-		       zs_curlog);
-	return len;
-}
-#else
-#define ZSLOG(x,y,z)	do { } while (0)
-#endif
-
-/*
- * tmp_buf is used as a temporary buffer by serial_write.  We need to
- * lock it in case the memcpy_fromfs blocks while swapping in a page,
- * and some other program tries to do a serial write at the same time.
- * Since the lock will only come under contention when the system is
- * swapping and available memory is low, it makes sense to share one
- * buffer across all the serial ports, since it significantly saves
- * memory if large numbers of serial ports are open.
- */
-static unsigned char *tmp_buf = 0;
-static DECLARE_MUTEX(tmp_buf_sem);
-
-static inline int serial_paranoia_check(struct sun_serial *info,
-					kdev_t device, const char *routine)
-{
-#ifdef SERIAL_PARANOIA_CHECK
-	static const char *badmagic =
-		"Warning: bad magic number for serial struct (%d, %d) in %s\n";
-	static const char *badinfo =
-		"Warning: null sun_serial for (%d, %d) in %s\n";
-
-	if (!info) {
-		printk(badinfo, major(device), minor(device), routine);
-		return 1;
-	}
-	if (info->magic != SERIAL_MAGIC) {
-		printk(badmagic, major(device), minor(device), routine);
-		return 1;
-	}
-#endif
-	return 0;
-}
-
-/* Reading and writing Zilog8530 registers.  The delays are to make this
- * driver work on the Sun4 which needs a settling delay after each chip
- * register access, other machines handle this in hardware via auxiliary
- * flip-flops which implement the settle time we do in software.
- */
-static unsigned char read_zsreg(struct sun_zschannel *channel,
-				unsigned char reg)
-{
-	unsigned char retval;
-
-	sbus_writeb(reg, &channel->control);
-	ZSDELAY();
-	retval = sbus_readb(&channel->control);
-	ZSDELAY();
-	ZSLOG(reg, retval, 0);
-	return retval;
-}
-
-static void write_zsreg(struct sun_zschannel *channel,
-			unsigned char reg, unsigned char value)
-{
-	ZSLOG(reg, value, 1);
-	sbus_writeb(reg, &channel->control);
-	ZSDELAY();
-	sbus_writeb(value, &channel->control);
-	ZSDELAY();
-}
-
-static void load_zsregs(struct sun_serial *info, unsigned char *regs)
-{
-	struct sun_zschannel *channel = info->zs_channel;
-	unsigned long flags;
-	unsigned char stat;
-	int i;
-
-	for (i = 0; i < 1000; i++) {
-		stat = read_zsreg(channel, R1);
-		if (stat & ALL_SNT)
-			break;
-		udelay(100);
-	}
-	write_zsreg(channel, R3, 0);
-	ZS_CLEARSTAT(channel);
-	ZS_CLEARERR(channel);
-	ZS_CLEARFIFO(channel);
-
-	/* Load 'em up */
-	save_flags(flags); cli();
-	if (info->channelA)
-		write_zsreg(channel, R9, CHRA);
-	else
-		write_zsreg(channel, R9, CHRB);
-	ZSDELAY_LONG();
-	write_zsreg(channel, R4, regs[R4]);
-	write_zsreg(channel, R3, regs[R3] & ~RxENAB);
-	write_zsreg(channel, R5, regs[R5] & ~TxENAB);
-	write_zsreg(channel, R9, regs[R9] & ~MIE);
-	write_zsreg(channel, R10, regs[R10]);
-	write_zsreg(channel, R11, regs[R11]);
-	write_zsreg(channel, R12, regs[R12]);
-	write_zsreg(channel, R13, regs[R13]);
-	write_zsreg(channel, R14, regs[R14] & ~BRENAB);
-	write_zsreg(channel, R14, regs[R14]);
-	write_zsreg(channel, R14, (regs[R14] & ~SNRZI) | BRENAB);
-	write_zsreg(channel, R3, regs[R3]);
-	write_zsreg(channel, R5, regs[R5]);
-	write_zsreg(channel, R15, regs[R15]);
-	write_zsreg(channel, R0, RES_EXT_INT);
-	write_zsreg(channel, R0, ERR_RES);
-	write_zsreg(channel, R1, regs[R1]);
-	write_zsreg(channel, R9, regs[R9]);
-	restore_flags(flags);
-}
-
-#define ZS_PUT_CHAR_MAX_DELAY	2000	/* 10 ms */
-
-static void zs_put_char(struct sun_zschannel *channel, char ch)
-{
-	int loops = ZS_PUT_CHAR_MAX_DELAY;
-
-	/* Do not change this to use ZSDELAY as this is
-	 * a timed polling loop and on sparc64 ZSDELAY
-	 * is a nop.  -DaveM
-	 */
-	do {
-		u8 val = sbus_readb(&channel->control);
-		ZSLOG(REGCTRL, val, 0);
-		if (val & Tx_BUF_EMP)
-			break;
-		udelay(5);
-	} while (--loops);
-
-	sbus_writeb(ch, &channel->data);
-	ZSDELAY();
-	ZS_WSYNC(channel);
-	ZSLOG(REGDATA, ch, 1);
-}
-
-/* Sets or clears DTR/RTS on the requested line */
-static void zs_rtsdtr(struct sun_serial *ss, int set)
-{
-	unsigned long flags;
-
-	save_flags(flags); cli();
-	if(set) {
-		ss->curregs[5] |= (RTS | DTR);
-		write_zsreg(ss->zs_channel, 5, ss->curregs[5]);
-	} else {
-		ss->curregs[5] &= ~(RTS | DTR);
-		write_zsreg(ss->zs_channel, 5, ss->curregs[5]);
-	}
-	restore_flags(flags);
-	return;
-}
-
-static void kgdb_chaninit(struct sun_serial *ss, int intson, int bps)
-{
-	int brg;
-
-	if(intson) {
-		kgdb_regs[R1] = INT_ALL_Rx;
-		kgdb_regs[R9] |= MIE;
-	} else {
-		kgdb_regs[R1] = 0;
-		kgdb_regs[R9] &= ~MIE;
-	}
-	brg = BPS_TO_BRG(bps, ZS_CLOCK/16);
-	kgdb_regs[R12] = (brg & 255);
-	kgdb_regs[R13] = ((brg >> 8) & 255);
-	load_zsregs(ss, kgdb_regs);
-}
-
-/*
- * ------------------------------------------------------------
- * zs_stop() and zs_start()
- *
- * This routines are called before setting or resetting tty->stopped.
- * They enable or disable transmitter interrupts, as necessary.
- * ------------------------------------------------------------
- */
-static void zs_stop(struct tty_struct *tty)
-{
-	struct sun_serial *info = (struct sun_serial *) tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "zs_stop"))
-		return;
-	
-	save_flags(flags); cli();
-	if (info->curregs[5] & TxENAB) {
-		info->curregs[5] &= ~TxENAB;
-		write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	}
-	restore_flags(flags);
-}
-
-static void zs_start(struct tty_struct *tty)
-{
-	struct sun_serial *info = (struct sun_serial *) tty->driver_data;
-	unsigned long flags;
-	
-	if (serial_paranoia_check(info, tty->device, "zs_start"))
-		return;
-	
-	save_flags(flags); cli();
-	if (info->xmit_cnt && info->xmit_buf && !(info->curregs[5] & TxENAB)) {
-		info->curregs[5] |= TxENAB;
-		write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	}
-	restore_flags(flags);
-}
-
-/* Drop into either the boot monitor or kadb upon receiving a break
- * from keyboard/console input.
- */
-void batten_down_hatches(void)
-{
-	if (!stop_a_enabled)
-		return;
-	/* If we are doing kadb, we call the debugger
-	 * else we just drop into the boot monitor.
-	 * Note that we must flush the user windows
-	 * first before giving up control.
-	 */
-	printk("\n");
-	flush_user_windows();
-#ifndef __sparc_v9__
-	if((((unsigned long)linux_dbvec)>=DEBUG_FIRSTVADDR) &&
-	   (((unsigned long)linux_dbvec)<=DEBUG_LASTVADDR))
-		sp_enter_debugger();
-	else
-#endif
-		prom_cmdline();
-
-	/* XXX We want to notify the keyboard driver that all
-	 * XXX keys are in the up state or else weird things
-	 * XXX happen...
-	 */
-
-	return;
-}
-
-
-/*
- * ----------------------------------------------------------------------
- *
- * Here starts the interrupt handling routines.  All of the following
- * subroutines are declared as inline and are folded into
- * zs_interrupt().  They were separated out for readability's sake.
- *
- * Note: zs_interrupt() is a "fast" interrupt, which means that it
- * runs with interrupts turned off.  People who may want to modify
- * zs_interrupt() should try to keep the interrupt handler as fast as
- * possible.  After you are done making modifications, it is not a bad
- * idea to do:
- * 
- * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
- *
- * and look at the resulting assemble code in serial.s.
- *
- * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
- * -----------------------------------------------------------------------
- */
-
-/*
- * This routine is used by the interrupt handler to schedule
- * processing in the software interrupt portion of the driver.
- */
-static void zs_sched_event(struct sun_serial *info, int event)
-{
-	info->event |= 1 << event;
-	queue_task(&info->tqueue, &tq_serial);
-	mark_bh(SERIAL_BH);
-}
-
-#ifndef __sparc_v9__
-extern void breakpoint(void);  /* For the KGDB frame character */
-#endif
-
-static void receive_chars(struct sun_serial *info, struct pt_regs *regs)
-{
-	struct tty_struct *tty = info->tty;
-	int do_queue_task = 0;
-
-	while (1) {
-		unsigned char ch, r1;
-
-		r1 = read_zsreg(info->zs_channel, R1);
-		if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
-			sbus_writeb(ERR_RES, &info->zs_channel->control);
-			ZSDELAY();
-			ZS_WSYNC(info->zs_channel);
-			ZSLOG(REGCTRL, ERR_RES, 1);
-		}
-
-		ch = sbus_readb(&info->zs_channel->data);
-		ZSLOG(REGDATA, ch, 0);
-		ch &= info->parity_mask;
-		ZSDELAY();
-
-		/* If this is the console keyboard, we need to handle
-		 * L1-A's here.
-		 */
-		if (info->cons_keyb) {
-			if (ch == SUNKBD_RESET) {
-				l1a_state.kbd_id = 1;
-				l1a_state.l1_down = 0;
-			} else if (l1a_state.kbd_id) {
-				l1a_state.kbd_id = 0;
-			} else if (ch == SUNKBD_L1) {
-				l1a_state.l1_down = 1;
-			} else if (ch == (SUNKBD_L1|SUNKBD_UP)) {
-				l1a_state.l1_down = 0;
-			} else if (ch == SUNKBD_A && l1a_state.l1_down) {
-				/* whee... */
-				batten_down_hatches();
-				/* Continue execution... */
-				l1a_state.l1_down = 0;
-				l1a_state.kbd_id = 0;
-				return;
-			}
-			sunkbd_inchar(ch, regs);
-			goto next_char;
-		}
-		if (info->cons_mouse) {
-			sun_mouse_inbyte(ch, 0);
-			goto next_char;
-		}
-		if (info->is_cons) {
-			if (ch == 0) {
-				/* whee, break received */
-				batten_down_hatches();
-				/* Continue execution... */
-				return;
-			}
-		}
-#ifndef __sparc_v9__
-		/* Look for kgdb 'stop' character, consult the gdb
-		 * documentation for remote target debugging and
-		 * arch/sparc/kernel/sparc-stub.c to see how all this works.
-		 */
-		if (info->kgdb_channel && (ch =='\003')) {
-			breakpoint();
-			return;
-		}
-#endif
-		if (!tty)
-			return;
-
-		do_queue_task++;
-
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-			break;
-
-		tty->flip.count++;
-		if (r1 & PAR_ERR)
-			*tty->flip.flag_buf_ptr++ = TTY_PARITY;
-		else if (r1 & Rx_OVR)
-			*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-		else if (r1 & CRC_ERR)
-			*tty->flip.flag_buf_ptr++ = TTY_FRAME;
-		else
-			*tty->flip.flag_buf_ptr++ = 0;
-		*tty->flip.char_buf_ptr++ = ch;
-
-	next_char:
-		{
-			unsigned char stat;
-
-			/* Check if we have another character... */
-			stat = sbus_readb(&info->zs_channel->control);
-			ZSDELAY();
-			ZSLOG(REGCTRL, stat, 0);
-			if (!(stat & Rx_CH_AV))
-				break;
-		}
-	}
-
-	if (do_queue_task != 0)
-		queue_task(&tty->flip.tqueue, &tq_timer);
-}
-
-static void transmit_chars(struct sun_serial *info)
-{
-	struct tty_struct *tty = info->tty;
-
-	if (info->x_char) {
-		/* Send next char */
-		zs_put_char(info->zs_channel, info->x_char);
-		info->x_char = 0;
-		return;
-	}
-
-	if ((info->xmit_cnt <= 0) || (tty != 0 && tty->stopped)) {
-		/* That's peculiar... */
-		sbus_writeb(RES_Tx_P, &info->zs_channel->control);
-		ZSDELAY();
-		ZS_WSYNC(info->zs_channel);
-		ZSLOG(REGCTRL, RES_Tx_P, 1);
-		return;
-	}
-
-	/* Send char */
-	zs_put_char(info->zs_channel, info->xmit_buf[info->xmit_tail++]);
-	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
-	info->xmit_cnt--;
-
-	if (info->xmit_cnt < WAKEUP_CHARS)
-		zs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
-
-	if (info->xmit_cnt <= 0) {
-		sbus_writeb(RES_Tx_P, &info->zs_channel->control);
-		ZSDELAY();
-		ZS_WSYNC(info->zs_channel);
-		ZSLOG(REGCTRL, RES_Tx_P, 1);
-	}
-}
-
-static void status_handle(struct sun_serial *info)
-{
-	unsigned char status;
-
-	/* Get status from Read Register 0 */
-	status = sbus_readb(&info->zs_channel->control);
-	ZSDELAY();
-	ZSLOG(REGCTRL, status, 0);
-	/* Clear status condition... */
-	sbus_writeb(RES_EXT_INT, &info->zs_channel->control);
-	ZSDELAY();
-	ZS_WSYNC(info->zs_channel);
-	ZSLOG(REGCTRL, RES_EXT_INT, 1);
-#if 0
-	if (status & DCD) {
-		if ((info->tty->termios->c_cflag & CRTSCTS) &&
-		    ((info->curregs[3] & AUTO_ENAB)==0)) {
-			info->curregs[3] |= AUTO_ENAB;
-			write_zsreg(info->zs_channel, 3, info->curregs[3]);
-		}
-	} else {
-		if ((info->curregs[3] & AUTO_ENAB)) {
-			info->curregs[3] &= ~AUTO_ENAB;
-			write_zsreg(info->zs_channel, 3, info->curregs[3]);
-		}
-	}
-#endif
-	/* Whee, if this is console input and this is a
-	 * 'break asserted' status change interrupt, call
-	 * the boot prom.
-	 */
-	if (status & BRK_ABRT) {
-		if (info->break_abort)
-			batten_down_hatches();
-		if (info->cons_mouse)
-			sun_mouse_inbyte(0, 1);
-	}
-
-	/* XXX Whee, put in a buffer somewhere, the status information
-	 * XXX whee whee whee... Where does the information go...
-	 */
-	return;
-}
-
-/*
- * This is the serial driver's generic interrupt routine
- */
-void zs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
-{
-	struct sun_serial *info;
-	int i;
-
-	info = (struct sun_serial *)dev_id;
-	ZSLOG(REGIRQ, 0, 0);
-	for (i = 0; i < NUM_SERIAL; i++) {
-		unsigned char r3 = read_zsreg(info->zs_channel, 3);
-
-		/* Channel A -- /dev/ttya or /dev/kbd, could be the console */
-		if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
-			sbus_writeb(RES_H_IUS, &info->zs_channel->control);
-			ZSDELAY();
-			ZS_WSYNC(info->zs_channel);
-			ZSLOG(REGCTRL, RES_H_IUS, 1);
-			if (r3 & CHARxIP)
-				receive_chars(info, regs);
-			if (r3 & CHAEXT)
-				status_handle(info);
-			if (r3 & CHATxIP)
-				transmit_chars(info);
-		}
-
-		/* Channel B -- /dev/ttyb or /dev/mouse, could be the console */
-		info = info->zs_next;
-		if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
-			sbus_writeb(RES_H_IUS, &info->zs_channel->control);
-			ZSDELAY();
-			ZS_WSYNC(info->zs_channel);
-			ZSLOG(REGCTRL, RES_H_IUS, 1);
-			if (r3 & CHBRxIP)
-				receive_chars(info, regs);
-			if (r3 & CHBEXT)
-				status_handle(info);
-			if (r3 & CHBTxIP)
-				transmit_chars(info);
-		}
-
-		info = info->zs_next;
-	}
-}
-
-/*
- * -------------------------------------------------------------------
- * Here ends the serial interrupt routines.
- * -------------------------------------------------------------------
- */
-
-/*
- * This routine is used to handle the "bottom half" processing for the
- * serial driver, known also the "software interrupt" processing.
- * This processing is done at the kernel interrupt level, after the
- * zs_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
- * is where time-consuming activities which can not be done in the
- * interrupt driver proper are done; the interrupt driver schedules
- * them using zs_sched_event(), and they get done here.
- */
-static void do_serial_bh(void)
-{
-	run_task_queue(&tq_serial);
-}
-
-static void do_softint(void *private_)
-{
-	struct sun_serial	*info = (struct sun_serial *) private_;
-	struct tty_struct	*tty;
-	
-	tty = info->tty;
-	if (!tty)
-		return;
-
-	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
-		wake_up_interruptible(&tty->write_wait);
-	}
-}
-
-/*
- * This routine is called from the scheduler tqueue when the interrupt
- * routine has signalled that a hangup has occurred.  The path of
- * hangup processing is:
- *
- * 	serial interrupt routine -> (scheduler tqueue) ->
- * 	do_serial_hangup() -> tty->hangup() -> zs_hangup()
- * 
- */
-static void do_serial_hangup(void *private_)
-{
-	struct sun_serial	*info = (struct sun_serial *) private_;
-	struct tty_struct	*tty;
-	
-	tty = info->tty;
-	if (!tty)
-		return;
-#ifdef SERIAL_DEBUG_OPEN
-	printk("do_serial_hangup<%p: tty-%d\n",
-		__builtin_return_address(0), info->line);
-#endif
-
-	tty_hangup(tty);
-}
-
-static int startup(struct sun_serial * info)
-{
-	unsigned long flags;
-
-	if (info->flags & ZILOG_INITIALIZED)
-		return 0;
-
-	if (!info->xmit_buf) {
-		info->xmit_buf = (unsigned char *) get_free_page(GFP_KERNEL);
-		if (!info->xmit_buf)
-			return -ENOMEM;
-	}
-
-	save_flags(flags); cli();
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("Starting up tty-%d (irq %d)...\n", info->line, info->irq);
-#endif
-
-	/*
-	 * Clear the FIFO buffers and disable them
-	 * (they will be reenabled in change_speed())
-	 */
-	ZS_CLEARFIFO(info->zs_channel);
-	info->xmit_fifo_size = 1;
-
-	/*
-	 * Clear the interrupt registers.
-	 */
-	sbus_writeb(ERR_RES, &info->zs_channel->control);
-	ZSDELAY();
-	ZS_WSYNC(info->zs_channel);
-	ZSLOG(REGCTRL, ERR_RES, 1);
-
-	sbus_writeb(RES_H_IUS, &info->zs_channel->control);
-	ZSDELAY();
-	ZS_WSYNC(info->zs_channel);
-	ZSLOG(REGCTRL, RES_H_IUS, 1);
-
-	/*
-	 * Now, initialize the Zilog
-	 */
-	zs_rtsdtr(info, 1);
-
-	/*
-	 * Finally, enable sequencing and interrupts
-	 */
-	info->curregs[1] |= (info->curregs[1] & ~(RxINT_MASK)) |
-				(EXT_INT_ENAB | INT_ALL_Rx);
-	info->curregs[3] |= (RxENAB | Rx8);
-	/* We enable Tx interrupts as needed. */
-	info->curregs[5] |= (TxENAB | Tx8);
-	info->curregs[9] |= (NV | MIE);
-	write_zsreg(info->zs_channel, 3, info->curregs[3]);
-	write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	write_zsreg(info->zs_channel, 9, info->curregs[9]);
-	
-	/*
-	 * And clear the interrupt registers again for luck.
-	 */
-	sbus_writeb(ERR_RES, &info->zs_channel->control);
-	ZSDELAY();
-	ZS_WSYNC(info->zs_channel);
-	ZSLOG(REGCTRL, ERR_RES, 1);
-
-	sbus_writeb(RES_H_IUS, &info->zs_channel->control);
-	ZSDELAY();
-	ZS_WSYNC(info->zs_channel);
-	ZSLOG(REGCTRL, RES_H_IUS, 1);
-
-	if (info->tty)
-		clear_bit(TTY_IO_ERROR, &info->tty->flags);
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-
-	/*
-	 * and set the speed of the serial port
-	 */
-	change_speed(info);
-
-	info->flags |= ZILOG_INITIALIZED;
-	restore_flags(flags);
-	return 0;
-}
-
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void shutdown(struct sun_serial * info)
-{
-	unsigned long	flags;
-
-	if (!(info->flags & ZILOG_INITIALIZED))
-		return;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("Shutting down serial port %d (irq %d)....", info->line,
-	       info->irq);
-#endif
-	
-	save_flags(flags); cli(); /* Disable interrupts */
-	
-	if (info->xmit_buf) {
-		free_page((unsigned long) info->xmit_buf);
-		info->xmit_buf = 0;
-	}
-
-	if (info->tty)
-		set_bit(TTY_IO_ERROR, &info->tty->flags);
-	
-	info->flags &= ~ZILOG_INITIALIZED;
-	restore_flags(flags);
-}
-
-/*
- * This routine is called to set the UART divisor registers to match
- * the specified baud rate for a serial port.
- */
-static void change_speed(struct sun_serial *info)
-{
-	unsigned cflag;
-	int	baud, quot = 0;
-	int	brg;
-
-	if (!info->tty || !info->tty->termios)
-		return;
-	cflag = info->tty->termios->c_cflag;
-	if (!info->port)
-		return;
-	baud = tty_get_baud_rate(info->tty);
-	
-	if ((baud == 38400) && 
-	    ((info->flags & ZILOG_SPD_MASK) == ZILOG_SPD_CUST))
-		quot = info->custom_divisor;
-
-	if (quot) {
-		info->zs_baud = info->baud_base / quot;
-		info->clk_divisor = 16;
-
-		info->curregs[4] = X16CLK;
-		info->curregs[11] = TCBR | RCBR;
-		brg = BPS_TO_BRG(info->zs_baud, ZS_CLOCK/info->clk_divisor);
-		info->curregs[12] = (brg & 255);
-		info->curregs[13] = ((brg >> 8) & 255);
-		info->curregs[14] = BRSRC | BRENAB;
-		zs_rtsdtr(info, 1);
-	} else if (baud) {
-		info->zs_baud = baud;
-		info->clk_divisor = 16;
-
-		info->curregs[4] = X16CLK;
-		info->curregs[11] = TCBR | RCBR;
-		brg = BPS_TO_BRG(info->zs_baud, ZS_CLOCK/info->clk_divisor);
-		info->curregs[12] = (brg & 255);
-		info->curregs[13] = ((brg >> 8) & 255);
-		info->curregs[14] = BRSRC | BRENAB;
-		zs_rtsdtr(info, 1);
-	} else {
-		zs_rtsdtr(info, 0);
-		return;
-	}
-
-	/* byte size and parity */
-	switch (cflag & CSIZE) {
-	case CS5:
-		info->curregs[3] &= ~(RxN_MASK);
-		info->curregs[3] |= Rx5;
-		info->curregs[5] &= ~(TxN_MASK);
-		info->curregs[5] |= Tx5;
-		info->parity_mask = 0x1f;
-		break;
-	case CS6:
-		info->curregs[3] &= ~(RxN_MASK);
-		info->curregs[3] |= Rx6;
-		info->curregs[5] &= ~(TxN_MASK);
-		info->curregs[5] |= Tx6;
-		info->parity_mask = 0x3f;
-		break;
-	case CS7:
-		info->curregs[3] &= ~(RxN_MASK);
-		info->curregs[3] |= Rx7;
-		info->curregs[5] &= ~(TxN_MASK);
-		info->curregs[5] |= Tx7;
-		info->parity_mask = 0x7f;
-		break;
-	case CS8:
-	default: /* defaults to 8 bits */
-		info->curregs[3] &= ~(RxN_MASK);
-		info->curregs[3] |= Rx8;
-		info->curregs[5] &= ~(TxN_MASK);
-		info->curregs[5] |= Tx8;
-		info->parity_mask = 0xff;
-		break;
-	}
-	info->curregs[4] &= ~(0x0c);
-	if (cflag & CSTOPB) {
-		info->curregs[4] |= SB2;
-	} else {
-		info->curregs[4] |= SB1;
-	}
-	if (cflag & PARENB) {
-		info->curregs[4] |= PAR_ENAB;
-	} else {
-		info->curregs[4] &= ~PAR_ENAB;
-	}
-	if (!(cflag & PARODD)) {
-		info->curregs[4] |= PAR_EVEN;
-	} else {
-		info->curregs[4] &= ~PAR_EVEN;
-	}
-
-	/* Load up the new values */
-	load_zsregs(info, info->curregs);
-
-	return;
-}
-
-/* This is for mouse/keyboard output.
- * XXX mouse output??? can we send it commands??? XXX
- */
-static void kbd_put_char(unsigned char ch)
-{
-	struct sun_zschannel *chan = zs_kbdchan;
-	unsigned long flags;
-
-	if(!chan)
-		return;
-
-	save_flags(flags); cli();
-	zs_put_char(chan, ch);
-	restore_flags(flags);
-}
-
-void mouse_put_char(char ch)
-{
-	struct sun_zschannel *chan = zs_mousechan;
-	unsigned long flags;
-
-	if(!chan)
-		return;
-
-	save_flags(flags); cli();
-	zs_put_char(chan, ch);
-	restore_flags(flags);
-}
-
-/* These are for receiving and sending characters under the kgdb
- * source level kernel debugger.
- */
-void putDebugChar(char kgdb_char)
-{
-	struct sun_zschannel *chan = zs_kgdbchan;
-
-	while((sbus_readb(&chan->control) & Tx_BUF_EMP)==0)
-		udelay(5);
-	sbus_writeb(kgdb_char, &chan->data);
-	ZS_WSYNC(chan);
-	ZSLOG(REGDATA, kgdb_char, 1);
-}
-
-char getDebugChar(void)
-{
-	struct sun_zschannel *chan = zs_kgdbchan;
-	u8 val;
-
-	do {
-		val = sbus_readb(&chan->control);
-		ZSLOG(REGCTRL, val, 0);
-		udelay(5);
-	} while ((val & Rx_CH_AV) == 0);
-
-	val = sbus_readb(&chan->data);
-	ZSLOG(REGDATA, val, 0);
-	return val;
-}
-
-static void zs_flush_chars(struct tty_struct *tty)
-{
-	struct sun_serial *info = (struct sun_serial *) tty->driver_data;
-	unsigned long flags;
-
-	if (serial_paranoia_check(info, tty->device, "zs_flush_chars"))
-		return;
-
-	save_flags(flags); cli();
-	if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
-	    !info->xmit_buf)
-		goto out;
-
-	/* Enable transmitter */
-	info->curregs[1] |= TxINT_ENAB|EXT_INT_ENAB;
-	write_zsreg(info->zs_channel, 1, info->curregs[1]);
-	info->curregs[5] |= TxENAB;
-	write_zsreg(info->zs_channel, 5, info->curregs[5]);
-
-	/*
-	 * Send a first (bootstrapping) character. A best solution is
-	 * to call transmit_chars() here which handles output in a
-	 * generic way. Current transmit_chars() not only transmits,
-	 * but resets interrupts also what we do not desire here.
-	 * XXX Discuss with David.
-	 */
-	zs_put_char(info->zs_channel, info->xmit_buf[info->xmit_tail++]);
-	info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
-	info->xmit_cnt--;
-
-out:
-	restore_flags(flags);
-}
-
-static int zs_write(struct tty_struct * tty, int from_user,
-		    const unsigned char *buf, int count)
-{
-	struct sun_serial *info = (struct sun_serial *) tty->driver_data;
-	unsigned long flags;
-	int c, total = 0;
-
-	if (serial_paranoia_check(info, tty->device, "zs_write"))
-		return 0;
-
-	if (!info || !info->xmit_buf || !tmp_buf)
-		return 0;
-
-	save_flags(flags);
-	if (from_user) {
-		down(&tmp_buf_sem);
-		while (1) {
-			c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-					   SERIAL_XMIT_SIZE - info->xmit_head));
-			if (c <= 0)
-				break;
-			c -= copy_from_user(tmp_buf, buf, c);
-			if (!c) {
-				if (!total)
-					total = -EFAULT;
-				break;
-			}
-			cli();
-			c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-				       SERIAL_XMIT_SIZE - info->xmit_head));
-			memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
-			info->xmit_head = ((info->xmit_head + c) &
-					   (SERIAL_XMIT_SIZE - 1));
-			info->xmit_cnt += c;
-			restore_flags(flags);
-
-			buf += c;
-			count -= c;
-			total += c;
-		}
-		up(&tmp_buf_sem);
-	} else {
-		while (1) {
-			cli();		
-			c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-					   SERIAL_XMIT_SIZE - info->xmit_head));
-			if (c <= 0) {
-				restore_flags(flags);
-				break;
-			}
-			memcpy(info->xmit_buf + info->xmit_head, buf, c);
-			info->xmit_head = ((info->xmit_head + c) &
-					   (SERIAL_XMIT_SIZE - 1));
-			info->xmit_cnt += c;
-			restore_flags(flags);
-			buf += c;
-			count -= c;
-			total += c;
-		}
-	}
-
-	cli();		
-	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
-		/* Enable transmitter */
-		info->curregs[1] |= TxINT_ENAB|EXT_INT_ENAB;
-		write_zsreg(info->zs_channel, 1, info->curregs[1]);
-		info->curregs[5] |= TxENAB;
-		write_zsreg(info->zs_channel, 5, info->curregs[5]);
-#if 1
-		zs_put_char(info->zs_channel,
-			    info->xmit_buf[info->xmit_tail++]);
-		info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
-		info->xmit_cnt--;
-#endif
-	}
-
-	restore_flags(flags);
-	return total;
-}
-
-static int zs_write_room(struct tty_struct *tty)
-{
-	struct sun_serial *info = (struct sun_serial *) tty->driver_data;
-	int ret;
-
-	if (serial_paranoia_check(info, tty->device, "zs_write_room"))
-		return 0;
-	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
-	if (ret < 0)
-		ret = 0;
-	return ret;
-}
-
-static int zs_chars_in_buffer(struct tty_struct *tty)
-{
-	struct sun_serial *info = (struct sun_serial *) tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->device, "zs_chars_in_buffer"))
-		return 0;
-	return info->xmit_cnt;
-}
-
-static void zs_flush_buffer(struct tty_struct *tty)
-{
-	struct sun_serial *info = (struct sun_serial *) tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->device, "zs_flush_buffer"))
-		return;
-	cli();
-	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	sti();
-	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
-}
-
-/*
- * ------------------------------------------------------------
- * zs_throttle()
- * 
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void zs_throttle(struct tty_struct * tty)
-{
-	struct sun_serial *info = (struct sun_serial *) tty->driver_data;
-#ifdef SERIAL_DEBUG_THROTTLE
-	char	buf[64];
-	
-	printk("throttle %s: %d....\n", _tty_name(tty, buf),
-	       tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->device, "zs_throttle"))
-		return;
-	
-	if (I_IXOFF(tty))
-		info->x_char = STOP_CHAR(tty);
-
-	/* Turn off RTS line */
-	cli();
-	info->curregs[5] &= ~RTS;
-	write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	sti();
-}
-
-static void zs_unthrottle(struct tty_struct * tty)
-{
-	struct sun_serial *info = (struct sun_serial *) tty->driver_data;
-#ifdef SERIAL_DEBUG_THROTTLE
-	char	buf[64];
-	
-	printk("unthrottle %s: %d....\n", _tty_name(tty, buf),
-	       tty->ldisc.chars_in_buffer(tty));
-#endif
-
-	if (serial_paranoia_check(info, tty->device, "zs_unthrottle"))
-		return;
-	
-	if (I_IXOFF(tty)) {
-		if (info->x_char)
-			info->x_char = 0;
-		else
-			info->x_char = START_CHAR(tty);
-	}
-
-	/* Assert RTS line */
-	cli();
-	info->curregs[5] |= RTS;
-	write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	sti();
-}
-
-/*
- * ------------------------------------------------------------
- * zs_ioctl() and friends
- * ------------------------------------------------------------
- */
-
-static int get_serial_info(struct sun_serial * info,
-			   struct serial_struct * retinfo)
-{
-	struct serial_struct tmp;
-  
-	if (!retinfo)
-		return -EFAULT;
-	memset(&tmp, 0, sizeof(tmp));
-	tmp.type = info->type;
-	tmp.line = info->line;
-	tmp.port = info->port;
-	tmp.irq = info->irq;
-	tmp.flags = info->flags;
-	tmp.baud_base = info->baud_base;
-	tmp.close_delay = info->close_delay;
-	tmp.closing_wait = info->closing_wait;
-	tmp.custom_divisor = info->custom_divisor;
-	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
-		return -EFAULT;
-	return 0;
-}
-
-static int set_serial_info(struct sun_serial * info,
-			   struct serial_struct * new_info)
-{
-	struct serial_struct new_serial;
-	struct sun_serial old_info;
-	int retval = 0;
-
-	if (!new_info || copy_from_user(&new_serial,new_info,sizeof(new_serial)))
-		return -EFAULT;
-	old_info = *info;
-
-	if (!capable(CAP_SYS_ADMIN)) {
-		if ((new_serial.baud_base != info->baud_base) ||
-		    (new_serial.type != info->type) ||
-		    (new_serial.close_delay != info->close_delay) ||
-		    ((new_serial.flags & ~ZILOG_USR_MASK) !=
-		     (info->flags & ~ZILOG_USR_MASK)))
-			return -EPERM;
-		info->flags = ((info->flags & ~ZILOG_USR_MASK) |
-			       (new_serial.flags & ZILOG_USR_MASK));
-		info->custom_divisor = new_serial.custom_divisor;
-		goto check_and_exit;
-	}
-
-	if(new_serial.baud_base < 9600)
-		return -EINVAL;
-
-	if (info->count > 1)
-		return -EBUSY;
-
-	/*
-	 * OK, past this point, all the error checking has been done.
-	 * At this point, we start making changes.....
-	 */
-
-	info->baud_base = new_serial.baud_base;
-	info->flags = ((info->flags & ~ZILOG_FLAGS) |
-			(new_serial.flags & ZILOG_FLAGS));
-	info->custom_divisor = new_serial.custom_divisor;
-	info->type = new_serial.type;
-	info->close_delay = new_serial.close_delay;
-	info->closing_wait = new_serial.closing_wait;
-
-check_and_exit:
-	retval = startup(info);
-	return retval;
-}
-
-/*
- * get_lsr_info - get line status register info
- *
- * Purpose: Let user call ioctl() to get info when the UART physically
- * 	    is emptied.  On bus types like RS485, the transmitter must
- * 	    release the bus after transmitting. This must be done when
- * 	    the transmit shift register is empty, not be done when the
- * 	    transmit holding register is empty.  This functionality
- * 	    allows an RS485 driver to be written in user space. 
- */
-static int get_lsr_info(struct sun_serial * info, unsigned int *value)
-{
-	unsigned char status;
-
-	cli();
-	status = sbus_readb(&info->zs_channel->control);
-	ZSDELAY();
-	ZSLOG(REGCTRL, status, 0);
-	sti();
-	if (put_user(status, value))
-		return -EFAULT;
-	return 0;
-}
-
-static int get_modem_info(struct sun_serial * info, unsigned int *value)
-{
-	unsigned char status;
-	unsigned int result;
-
-	cli();
-	status = sbus_readb(&info->zs_channel->control);
-	ZSDELAY();
-	ZSLOG(REGCTRL, status, 0);
-	sti();
-	result =  ((info->curregs[5] & RTS) ? TIOCM_RTS : 0)
-		| ((info->curregs[5] & DTR) ? TIOCM_DTR : 0)
-		| ((status  & DCD) ? TIOCM_CAR : 0)
-		| ((status  & SYNC) ? TIOCM_DSR : 0)
-		| ((status  & CTS) ? TIOCM_CTS : 0);
-	if (put_user(result, value))
-		return -EFAULT;
-	return 0;
-}
-
-static int set_modem_info(struct sun_serial * info, unsigned int cmd,
-			  unsigned int *value)
-{
-	unsigned int arg;
-
-	if (get_user(arg, value))
-		return -EFAULT;
-	switch (cmd) {
-	case TIOCMBIS: 
-		if (arg & TIOCM_RTS)
-			info->curregs[5] |= RTS;
-		if (arg & TIOCM_DTR)
-			info->curregs[5] |= DTR;
-		break;
-	case TIOCMBIC:
-		if (arg & TIOCM_RTS)
-			info->curregs[5] &= ~RTS;
-		if (arg & TIOCM_DTR)
-			info->curregs[5] &= ~DTR;
-		break;
-	case TIOCMSET:
-		info->curregs[5] = ((info->curregs[5] & ~(RTS | DTR))
-			     | ((arg & TIOCM_RTS) ? RTS : 0)
-			     | ((arg & TIOCM_DTR) ? DTR : 0));
-		break;
-	default:
-		return -EINVAL;
-	}
-	cli();
-	write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	sti();
-	return 0;
-}
-
-/*
- * This routine sends a break character out the serial port.
- */
-static void send_break(	struct sun_serial * info, int duration)
-{
-	if (!info->port)
-		return;
-	current->state = TASK_INTERRUPTIBLE;
-	cli();
-	write_zsreg(info->zs_channel, 5, (info->curregs[5] | SND_BRK));
-	schedule_timeout(duration);
-	write_zsreg(info->zs_channel, 5, info->curregs[5]);
-	sti();
-}
-
-static int zs_ioctl(struct tty_struct *tty, struct file * file,
-		    unsigned int cmd, unsigned long arg)
-{
-	struct sun_serial * info = (struct sun_serial *) tty->driver_data;
-	int retval;
-
-	if (serial_paranoia_check(info, tty->device, "zs_ioctl"))
-		return -ENODEV;
-
-	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
-	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
-	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) {
-		if (tty->flags & (1 << TTY_IO_ERROR))
-		    return -EIO;
-	}
-	
-	switch (cmd) {
-		case TCSBRK:	/* SVID version: non-zero arg --> no break */
-			retval = tty_check_change(tty);
-			if (retval)
-				return retval;
-			tty_wait_until_sent(tty, 0);
-			if (!arg)
-				send_break(info, HZ/4);	/* 1/4 second */
-			return 0;
-		case TCSBRKP:	/* support for POSIX tcsendbreak() */
-			retval = tty_check_change(tty);
-			if (retval)
-				return retval;
-			tty_wait_until_sent(tty, 0);
-			send_break(info, arg ? arg*(HZ/10) : HZ/4);
-			return 0;
-		case TIOCGSOFTCAR:
-			if (put_user(C_CLOCAL(tty) ? 1 : 0,
-				     (unsigned long *) arg))
-				return -EFAULT;
-			return 0;
-		case TIOCSSOFTCAR:
-			if (get_user(arg, (unsigned long *) arg))
-				return -EFAULT;
-			tty->termios->c_cflag =
-				((tty->termios->c_cflag & ~CLOCAL) |
-				 (arg ? CLOCAL : 0));
-			return 0;
-		case TIOCMGET:
-			return get_modem_info(info, (unsigned int *) arg);
-		case TIOCMBIS:
-		case TIOCMBIC:
-		case TIOCMSET:
-			return set_modem_info(info, cmd, (unsigned int *) arg);
-		case TIOCGSERIAL:
-			return get_serial_info(info,
-					       (struct serial_struct *) arg);
-		case TIOCSSERIAL:
-			return set_serial_info(info,
-					       (struct serial_struct *) arg);
-		case TIOCSERGETLSR: /* Get line status register */
-			return get_lsr_info(info, (unsigned int *) arg);
-
-		case TIOCSERGSTRUCT:
-			if (copy_to_user((struct sun_serial *) arg,
-				    info, sizeof(struct sun_serial)))
-				return -EFAULT;
-			return 0;
-			
-		default:
-			return -ENOIOCTLCMD;
-		}
-	return 0;
-}
-
-static void zs_set_termios(struct tty_struct *tty, struct termios *old_termios)
-{
-	struct sun_serial *info = (struct sun_serial *) tty->driver_data;
-
-	if (tty->termios->c_cflag == old_termios->c_cflag)
-		return;
-
-	change_speed(info);
-
-	if ((old_termios->c_cflag & CRTSCTS) &&
-	    !(tty->termios->c_cflag & CRTSCTS)) {
-		tty->hw_stopped = 0;
-		zs_start(tty);
-	}
-}
-
-/*
- * ------------------------------------------------------------
- * zs_close()
- * 
- * This routine is called when the serial port gets closed.  First, we
- * wait for the last remaining data to be sent.  Then, we unlink its
- * ZILOG structure from the interrupt chain if necessary, and we free
- * that IRQ if nothing is left in the chain.
- * ------------------------------------------------------------
- */
-static void zs_close(struct tty_struct *tty, struct file * filp)
-{
-	struct sun_serial * info = (struct sun_serial *) tty->driver_data;
-	unsigned long flags;
-
-	if (!info || serial_paranoia_check(info, tty->device, "zs_close"))
-		return;
-	
-	save_flags(flags); cli();
-	
-	if (tty_hung_up_p(filp)) {
-		restore_flags(flags);
-		return;
-	}
-	
-#ifdef SERIAL_DEBUG_OPEN
-	printk("zs_close tty-%d, count = %d\n", info->line, info->count);
-#endif
-	if ((tty->count == 1) && (info->count != 1)) {
-		/*
-		 * Uh, oh.  tty->count is 1, which means that the tty
-		 * structure will be freed.  Info->count should always
-		 * be one in these conditions.  If it's greater than
-		 * one, we've got real problems, since it means the
-		 * serial port won't be shutdown.
-		 */
-		printk("zs_close: bad serial port count; tty->count is 1, "
-		       "info->count is %d\n", info->count);
-		info->count = 1;
-	}
-	if (--info->count < 0) {
-		printk("zs_close: bad serial port count for ttys%d: %d\n",
-		       info->line, info->count);
-		info->count = 0;
-	}
-	if (info->count) {
-		restore_flags(flags);
-		return;
-	}
-	info->flags |= ZILOG_CLOSING;
-	/*
-	 * Save the termios structure, since this port may have
-	 * separate termios for callout and dialin.
-	 */
-	if (info->flags & ZILOG_NORMAL_ACTIVE)
-		info->normal_termios = *tty->termios;
-	if (info->flags & ZILOG_CALLOUT_ACTIVE)
-		info->callout_termios = *tty->termios;
-	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
-	 * the line discipline to only process XON/XOFF characters.
-	 */
-	tty->closing = 1;
-	if (info->closing_wait != ZILOG_CLOSING_WAIT_NONE)
-		tty_wait_until_sent(tty, info->closing_wait);
-	/*
-	 * At this point we stop accepting input.  To do this, we
-	 * disable the receive line status interrupts, and tell the
-	 * interrupt driver to stop checking the data ready bit in the
-	 * line status register.
-	 */
-	/** if (!info->iscons) ... **/
-	info->curregs[3] &= ~RxENAB;
-	write_zsreg(info->zs_channel, 3, info->curregs[3]);
-	info->curregs[1] &= ~(RxINT_MASK);
-	write_zsreg(info->zs_channel, 1, info->curregs[1]);
-	ZS_CLEARFIFO(info->zs_channel);
-
-	shutdown(info);
-	if (tty->driver.flush_buffer)
-		tty->driver.flush_buffer(tty);
-	if (tty->ldisc.flush_buffer)
-		tty->ldisc.flush_buffer(tty);
-	tty->closing = 0;
-	info->event = 0;
-	info->tty = 0;
-	if (tty->ldisc.num != ldiscs[N_TTY].num) {
-		if (tty->ldisc.close)
-			(tty->ldisc.close)(tty);
-		tty->ldisc = ldiscs[N_TTY];
-		tty->termios->c_line = N_TTY;
-		if (tty->ldisc.open)
-			(tty->ldisc.open)(tty);
-	}
-	if (info->blocked_open) {
-		if (info->close_delay) {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(info->close_delay);
-		}
-		wake_up_interruptible(&info->open_wait);
-	}
-	info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE|
-			 ZILOG_CLOSING);
-	wake_up_interruptible(&info->close_wait);
-#ifdef SERIAL_DEBUG_OPEN
-	printk("zs_close tty-%d exiting, count = %d\n", info->line, info->count);
-#endif
-	restore_flags(flags);
-}
-
-/*
- * zs_hangup() --- called by tty_hangup() when a hangup is signaled.
- */
-void zs_hangup(struct tty_struct *tty)
-{
-	struct sun_serial * info = (struct sun_serial *) tty->driver_data;
-
-	if (serial_paranoia_check(info, tty->device, "zs_hangup"))
-		return;
-
-	if (info->is_cons)
-		return;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("zs_hangup<%p: tty-%d, count = %d bye\n",
-		__builtin_return_address(0), info->line, info->count);
-#endif
-
-	zs_flush_buffer(tty);
-	shutdown(info);
-	info->event = 0;
-	info->count = 0;
-	info->flags &= ~(ZILOG_NORMAL_ACTIVE|ZILOG_CALLOUT_ACTIVE);
-	info->tty = 0;
-	wake_up_interruptible(&info->open_wait);
-}
-
-/*
- *
- * line_info - returns information about each channel
- *
- */
-static inline int line_info(char *buf, struct sun_serial *info)
-{
-	unsigned char status;
-	char stat_buf[30];
-	int ret;
-
-	ret = sprintf(buf, "%d: uart:Zilog8530 port:%x irq:%d",
-		info->line, info->port, info->irq);
-
-	cli();
-	status = sbus_readb(&info->zs_channel->control);
-	ZSDELAY();
-	ZSLOG(REGCTRL, status, 0);
-	sti();
-
-	stat_buf[0] = 0;
-	stat_buf[1] = 0;
-	if (info->curregs[5] & RTS)
-		strcat(stat_buf, "|RTS");
-	if (status & CTS)
-		strcat(stat_buf, "|CTS");
-	if (info->curregs[5] & DTR)
-		strcat(stat_buf, "|DTR");
-	if (status & SYNC)
-		strcat(stat_buf, "|DSR");
-	if (status & DCD)
-		strcat(stat_buf, "|CD");
-
-	ret += sprintf(buf + ret, " baud:%d %s\n", info->zs_baud, stat_buf + 1);
-	return ret;
-}
-
-/*
- *
- * zs_read_proc() - called when /proc/tty/driver/serial is read.
- *
- */
-int zs_read_proc(char *page, char **start, off_t off, int count,
-                 int *eof, void *data)
-{
-	char *revision = "$Revision: 1.71 $";
-	char *version, *p;
-	int i, len = 0, l;
-	off_t begin = 0;
-
-	version = strchr(revision, ' ');
-	p = strchr(++version, ' ');
-	*p = '\0';
-	len += sprintf(page, "serinfo:1.0 driver:%s\n", version);
-	*p = ' ';
-
-	for (i = 0; i < NUM_CHANNELS && len < 4000; i++) {
-		l = line_info(page + len, &zs_soft[i]);
-		len += l;
-		if (len+begin > off+count)
-			goto done;
-		if (len+begin < off) {
-			begin += len;
-			len = 0;
-		}
-	}
-
-	*eof = 1;
-done:
-	if (off >= len+begin)
-		return 0;
-	*start = page + (off-begin);
-	return ((count < begin+len-off) ? count : begin+len-off);
-}
-
-/*
- * ------------------------------------------------------------
- * zs_open() and friends
- * ------------------------------------------------------------
- */
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
-			   struct sun_serial *info)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	int retval, do_clocal = 0;
-	unsigned char r0;
-
-	/*
-	 * If the device is in the middle of being closed, then block
-	 * until it's done, and then try again.
-	 */
-	if (info->flags & ZILOG_CLOSING) {
-		interruptible_sleep_on(&info->close_wait);
-#ifdef SERIAL_DO_RESTART
-		if (info->flags & ZILOG_HUP_NOTIFY)
-			return -EAGAIN;
-		else
-			return -ERESTARTSYS;
-#else
-		return -EAGAIN;
-#endif
-	}
-
-	/*
-	 * If this is a callout device, then just make sure the normal
-	 * device isn't being used.
-	 */
-	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
-		if (info->flags & ZILOG_NORMAL_ACTIVE)
-			return -EBUSY;
-		if ((info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    (info->flags & ZILOG_SESSION_LOCKOUT) &&
-		    (info->session != current->session))
-		    return -EBUSY;
-		if ((info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    (info->flags & ZILOG_PGRP_LOCKOUT) &&
-		    (info->pgrp != current->pgrp))
-		    return -EBUSY;
-		info->flags |= ZILOG_CALLOUT_ACTIVE;
-		return 0;
-	}
-	
-	/*
-	 * If non-blocking mode is set, or the port is not enabled,
-	 * then make the check up front and then exit.
-	 */
-	if ((filp->f_flags & O_NONBLOCK) ||
-	    (tty->flags & (1 << TTY_IO_ERROR))) {
-		if (info->flags & ZILOG_CALLOUT_ACTIVE)
-			return -EBUSY;
-		info->flags |= ZILOG_NORMAL_ACTIVE;
-		return 0;
-	}
-
-	if (info->flags & ZILOG_CALLOUT_ACTIVE) {
-		if (info->normal_termios.c_cflag & CLOCAL)
-			do_clocal = 1;
-	} else {
-		if (tty->termios->c_cflag & CLOCAL)
-			do_clocal = 1;
-	}
-	
-	/*
-	 * Block waiting for the carrier detect and the line to become
-	 * free (i.e., not in use by the callout).  While we are in
-	 * this loop, info->count is dropped by one, so that
-	 * zs_close() knows when to free things.  We restore it upon
-	 * exit, either normal or abnormal.
-	 */
-	retval = 0;
-	add_wait_queue(&info->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready before block: ttys%d, count = %d\n",
-	       info->line, info->count);
-#endif
-	cli();
-	if(!tty_hung_up_p(filp))
-		info->count--;
-	sti();
-	info->blocked_open++;
-	while (1) {
-		cli();
-		if (!(info->flags & ZILOG_CALLOUT_ACTIVE))
-			zs_rtsdtr(info, 1);
-		sti();
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p(filp) ||
-		    !(info->flags & ZILOG_INITIALIZED)) {
-#ifdef SERIAL_DEBUG_OPEN
-			printk("block_til_ready hup-ed: ttys%d, count = %d\n",
-				info->line, info->count);
-#endif
-#ifdef SERIAL_DO_RESTART
-			if (info->flags & ZILOG_HUP_NOTIFY)
-				retval = -EAGAIN;
-			else
-				retval = -ERESTARTSYS;	
-#else
-			retval = -EAGAIN;
-#endif
-			break;
-		}
-
-		cli();
-		r0 = read_zsreg(info->zs_channel, R0);
-		sti();
-		if (!(info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    !(info->flags & ZILOG_CLOSING) &&
-		    (do_clocal || (DCD & r0)))
-			break;
-		if (signal_pending(current)) {
-			retval = -ERESTARTSYS;
-			break;
-		}
-#ifdef SERIAL_DEBUG_OPEN
-		printk("block_til_ready blocking: ttys%d, count = %d\n",
-		       info->line, info->count);
-#endif
-		schedule();
-	}
-	current->state = TASK_RUNNING;
-	remove_wait_queue(&info->open_wait, &wait);
-	if (!tty_hung_up_p(filp))
-		info->count++;
-	info->blocked_open--;
-#ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready after blocking: ttys%d, count = %d\n",
-	       info->line, info->count);
-#endif
-	if (retval)
-		return retval;
-	info->flags |= ZILOG_NORMAL_ACTIVE;
-	return 0;
-}	
-
-/*
- * This routine is called whenever a serial port is opened.  It
- * enables interrupts for a serial port, linking in its ZILOG structure into
- * the IRQ chain.   It also performs the serial-specific
- * initialization for the tty structure.
- */
-int zs_open(struct tty_struct *tty, struct file * filp)
-{
-	struct sun_serial *info;
-	int retval, line;
-
-	line = minor(tty->device) - tty->driver.minor_start;
-
-	/* The zilog lines for the mouse/keyboard must be
-	 * opened using their respective drivers.
-	 */
-	if ((line < 0) || (line >= NUM_CHANNELS))
-		return -ENODEV;
-	if((line == KEYBOARD_LINE) || (line == MOUSE_LINE))
-		return -ENODEV;
-	info = zs_soft + line;
-	/* Is the kgdb running over this line? */
-	if (info->kgdb_channel)
-		return -ENODEV;
-	if (serial_paranoia_check(info, tty->device, "zs_open"))
-		return -ENODEV;
-#ifdef SERIAL_DEBUG_OPEN
-	printk("zs_open %s%d, count = %d\n", tty->driver.name, info->line,
-	       info->count);
-#endif
-	if (info->tty != 0 && info->tty != tty) {
-		/* Never happen? */
-		printk("zs_open %s%d, tty overwrite.\n", tty->driver.name, info->line);
-		return -EBUSY;
-	}
-
-	if (!tmp_buf) {
-		unsigned long page = get_free_page(GFP_KERNEL);
-		if (!page)
-			return -ENOMEM;
-		if (tmp_buf)
-			free_page(page);
-		else
-			tmp_buf = (unsigned char *) page;
-	}
-
-	info->count++;
-	tty->driver_data = info;
-	info->tty = tty;
-
-	/*
-	 * Start up serial port
-	 */
-	retval = startup(info);
-	if (retval)
-		return retval;
-
-	retval = block_til_ready(tty, filp, info);
-	if (retval) {
-#ifdef SERIAL_DEBUG_OPEN
-		printk("zs_open returning after block_til_ready with %d\n",
-		       retval);
-#endif
-		return retval;
-	}
-
-	if ((info->count == 1) && (info->flags & ZILOG_SPLIT_TERMIOS)) {
-		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
-			*tty->termios = info->normal_termios;
-		else 
-			*tty->termios = info->callout_termios;
-		change_speed(info);
-	}
-
-#ifdef CONFIG_SERIAL_CONSOLE
-	if (zs_console.cflag && zs_console.index == line) {
-		tty->termios->c_cflag = zs_console.cflag;
-		zs_console.cflag = 0;
-		change_speed(info);
-	}
-#endif
-
-	info->session = current->session;
-	info->pgrp = current->pgrp;
-
-#ifdef SERIAL_DEBUG_OPEN
-	printk("zs_open ttys%d successful...", info->line);
-#endif
-	return 0;
-}
-
-/* Finally, routines used to initialize the serial driver. */
-
-static void show_serial_version(void)
-{
-	char *revision = "$Revision: 1.71 $";
-	char *version, *p;
-
-	version = strchr(revision, ' ');
-	p = strchr(++version, ' ');
-	*p = '\0';
-	printk("Sparc Zilog8530 serial driver version %s\n", version);
-	*p = ' ';
-}
-
-/* Probe the PROM for the request zs chip number.
- *
- * Note: The Sun Voyager shows two addresses and two intr for it's
- *       Zilogs, what the second does, I don't know. It does work
- *       with using only the first number of each property.  Also
- *       we have a special version for sun4u.
- */
-#ifdef __sparc_v9__
-static struct sun_zslayout * __init get_zs(int chip)
-{
-	unsigned int vaddr[2] = { 0, 0 };
-	unsigned long mapped_addr = 0;
-	int busnode, seen, zsnode, sun4u_ino;
-	static int irq = 0;
-
-	if(chip < 0 || chip >= NUM_SERIAL) {
-		prom_printf("get_zs bogon zs chip number");
-		prom_halt();
-	}
-
-	if(central_bus)
-		busnode = central_bus->child->prom_node;
-	else
-		busnode = prom_searchsiblings(prom_getchild(prom_root_node), "sbus");
-	if(busnode == 0 || busnode == -1) {
-		prom_printf("get_zs: no zs bus to search");
-		prom_halt();
-	}
-	zsnode = prom_getchild(busnode);
-	seen = 0;
-	while(zsnode) {
-		int slave;
-
-		zsnode = prom_searchsiblings(zsnode, "zs");
-		slave = prom_getintdefault(zsnode, "slave", -1);
-		if((slave == chip) || (seen == chip)) {
-			int len = prom_getproperty(zsnode, "address",
-						   (void *) vaddr, sizeof(vaddr));
-
-			if(len == -1 || central_bus != NULL) {
-				struct sbus_bus *sbus = NULL;
-				struct sbus_dev *sdev = NULL;
-
-				/* "address" property is not guarenteed,
-				 * everything in I/O is implicitly mapped
-				 * anyways by our clever TLB miss handling
-				 * scheme, so don't fail here.  -DaveM
-				 */
-				if (central_bus == NULL) {
-					for_each_sbus(sbus) {
-						for_each_sbusdev(sdev, sbus) {
-							if (sdev->prom_node == zsnode)
-								goto found;
-						}
-					}
-				}
-			found:
-				if (sdev == NULL && central_bus == NULL)
-					prom_halt();
-				if (central_bus == NULL) {
-					mapped_addr =
-					    sbus_ioremap(&sdev->resource[0], 0,
-							 PAGE_SIZE, "Zilog Registers");
-				} else {
-					struct linux_prom_registers zsregs[1];
-					int err;
-
-					err = prom_getproperty(zsnode, "reg",
-							       (char *)&zsregs[0],
-							       sizeof(zsregs));
-					if (err == -1) {
-						prom_printf("ZS: Cannot map Zilog regs.\n");
-						prom_halt();
-					}
-					apply_fhc_ranges(central_bus->child, &zsregs[0], 1);
-					apply_central_ranges(central_bus, &zsregs[0], 1);
-					mapped_addr =
-						((((u64)zsregs[0].which_io)<<32UL)|
-						 ((u64)zsregs[0].phys_addr));
-				}
-			} else if(len % sizeof(unsigned int)) {
-				prom_printf("WHOOPS:  proplen for %s "
-					    "was %d, need multiple of "
-					    "%d\n", "address", len,
-					    sizeof(unsigned int));
-				panic("zilog: address property");
-			}
-			zs_nodes[chip] = zsnode;
-			len = prom_getproperty(zsnode, "interrupts",
-					       (char *) &sun4u_ino,
-					       (sizeof(sun4u_ino)));
-			if(!irq) {
-				if (central_bus) {
-					unsigned long iclr, imap;
-
-					iclr = central_bus->child->fhc_regs.uregs + FHC_UREGS_ICLR;
-					imap = central_bus->child->fhc_regs.uregs + FHC_UREGS_IMAP;
-					irq = zilog_irq = build_irq(12, 0, iclr, imap);
-				} else {
-					irq = zilog_irq = 
-						sbus_build_irq(sbus_root, sun4u_ino);
-				}
-			}
-			break;
-		}
-		zsnode = prom_getsibling(zsnode);
-		seen++;
-	}
-	if(!zsnode)
-		panic("get_zs: whee chip not found");
-	if(!vaddr[0] && !mapped_addr)
-		panic("get_zs: whee no serial chip mappable");
-	if (mapped_addr != 0) {
-		return (struct sun_zslayout *) mapped_addr;
-	} else {
-		return (struct sun_zslayout *) prom_virt_to_phys((unsigned long)vaddr[0], 0);
-	}
-}
-#else /* !(__sparc_v9__) */
-static struct sun_zslayout * __init get_zs(int chip)
-{
-	struct linux_prom_irqs tmp_irq[2];
-	unsigned int paddr = 0;
-	unsigned int vaddr[2] = { 0, 0 };
-	int zsnode, tmpnode, iospace, slave, len;
-	int cpunode = 0, bbnode = 0;
-	static int irq = 0;
-	int chipid = chip;
-
-	iospace = 0;
-	if(chip < 0 || chip >= NUM_SERIAL)
-		panic("get_zs bogon zs chip number");
-
-	if(sparc_cpu_model == sun4) {
-		struct resource dummy_resource;
-
-		/* Grrr, these have to be hardcoded aieee */
-		switch(chip) {
-		case 0:
-			paddr = 0xf1000000;
-			break;
-		case 1:
-			paddr = 0xf0000000;
-			break;
-		};
-		iospace = 0;
-		zs_nodes[chip] = 0;
-		if(!irq)
-			zilog_irq = irq = 12;
-		dummy_resource.start = paddr;
-		dummy_resource.end = paddr + 8 - 1;
-		dummy_resource.flags = IORESOURCE_IO;
-		vaddr[0] = sbus_ioremap(&dummy_resource, 0,
-					8, "Zilog Serial");
-	} else {
-		/* Can use the prom for other machine types */
-		zsnode = prom_getchild(prom_root_node);
-		if (sparc_cpu_model == sun4d) {
-			int no = 0;
-
-			tmpnode = zsnode;
-			zsnode = 0;
-			bbnode = 0;
-			while (tmpnode && (tmpnode = prom_searchsiblings(tmpnode, "cpu-unit"))) {
-				bbnode = prom_getchild(tmpnode);
-				if (bbnode && (bbnode = prom_searchsiblings(bbnode, "bootbus"))) {
-					if (no == (chip >> 1)) {
-						cpunode = tmpnode;
-						zsnode = prom_getchild(bbnode);
-						chipid = (chip & 1);
-						break;
-					}
-					no++;
-				}
-				tmpnode = prom_getsibling(tmpnode);
-			}
-			if (!tmpnode)
-				panic ("get_zs: couldn't find %dth bootbus\n", chip >> 1);
-		} else {
-			tmpnode = prom_searchsiblings(zsnode, "obio");
-			if(tmpnode)
-				zsnode = prom_getchild(tmpnode);
-		}
-		if(!zsnode)
-			panic("get_zs no zs serial prom node");
-		while(zsnode) {
-			zsnode = prom_searchsiblings(zsnode, "zs");
-			slave = prom_getintdefault(zsnode, "slave", -1);
-			if(slave == chipid) {
-				/* The one we want */
-				if (sparc_cpu_model != sun4d) {
-					len = prom_getproperty(zsnode, "address",
-							       (void *) vaddr,
-							       sizeof(vaddr));
-        				if (len % sizeof(unsigned int)) {
-						prom_printf("WHOOPS:  proplen for %s "
-							"was %d, need multiple of "
-							"%d\n", "address", len,
-							sizeof(unsigned int));
-						panic("zilog: address property");
-					}
-				} else {
-					/* On sun4d don't have address property :( */
-					struct linux_prom_registers zsreg[4];
-					struct resource res;
-					
-					if (prom_getproperty(zsnode, "reg", (char *)zsreg, sizeof(zsreg)) == -1) {
-						prom_printf ("Cannot map zs regs\n");
-						prom_halt();
-					}
-					prom_apply_generic_ranges(bbnode, cpunode, zsreg, 1);
-					res.start = zsreg[0].phys_addr;
-					res.end = res.start + 8 - 1;
-					res.flags = zsreg[0].which_io | IORESOURCE_IO;
-					vaddr[0] = sbus_ioremap(&res, 0,
-								8, "Zilog Serial");
-				}
-				zs_nodes[chip] = zsnode;
-				len = prom_getproperty(zsnode, "intr",
-						       (char *) tmp_irq,
-						       sizeof(tmp_irq));
-				if (len % sizeof(struct linux_prom_irqs)) {
-					prom_printf(
-					      "WHOOPS:  proplen for %s "
-					      "was %d, need multiple of "
-					      "%d\n", "intr", len,
-					      sizeof(struct linux_prom_irqs));
-					panic("zilog: intr property");
-				}
-				if(!irq) {
-					irq = zilog_irq = tmp_irq[0].pri;
-				} else {
-					if(tmp_irq[0].pri != irq)
-						panic("zilog: bogon irqs");
-				}
-				break;
-			}
-			zsnode = prom_getsibling(zsnode);
-		}
-		if(!zsnode)
-			panic("get_zs whee chip not found");
-	}
-	if(!vaddr[0])
-		panic("get_zs whee no serial chip mappable");
-
-	return (struct sun_zslayout *)(unsigned long) vaddr[0];
-}
-#endif
-/* This is for the auto baud rate detection in the mouse driver. */
-void zs_change_mouse_baud(int newbaud)
-{
-	int channel = MOUSE_LINE;
-	int brg;
-
-	zs_soft[channel].zs_baud = newbaud;
-	brg = BPS_TO_BRG(zs_soft[channel].zs_baud,
-			 (ZS_CLOCK / zs_soft[channel].clk_divisor));
-	write_zsreg(zs_soft[channel].zs_channel, R12, (brg & 0xff));
-	write_zsreg(zs_soft[channel].zs_channel, R13, ((brg >> 8) & 0xff));
-}
-
-void __init zs_init_alloc_failure(const char *table_name)
-{
-	prom_printf("zs_probe: Cannot alloc %s.\n", table_name);
-	prom_halt();
-}
-
-void * __init zs_alloc_bootmem(unsigned long size)
-{
-	void *ret;
-
-	ret = __alloc_bootmem(size, SMP_CACHE_BYTES, 0UL);
-	if (ret != NULL)
-		memset(ret, 0, size);
-
-	return ret;
-}
-
-void __init zs_alloc_tables(void)
-{
-	zs_chips = (struct sun_zslayout **)
-		zs_alloc_bootmem(NUM_SERIAL * sizeof(struct sun_zslayout *));
-	if (zs_chips == NULL)
-		zs_init_alloc_failure("zs_chips");
-	zs_channels = (struct sun_zschannel **)
-		zs_alloc_bootmem(NUM_CHANNELS * sizeof(struct sun_zschannel *));
-	if (zs_channels == NULL)
-		zs_init_alloc_failure("zs_channels");
-	zs_nodes = (int *)
-		zs_alloc_bootmem(NUM_SERIAL * sizeof(int));
-	if (zs_nodes == NULL)
-		zs_init_alloc_failure("zs_nodes");
-	zs_soft = (struct sun_serial *)
-		zs_alloc_bootmem(NUM_CHANNELS * sizeof(struct sun_serial));
-	if (zs_soft == NULL)
-		zs_init_alloc_failure("zs_soft");
-	zs_ttys = (struct tty_struct *)
-		zs_alloc_bootmem(NUM_CHANNELS * sizeof(struct tty_struct));
-	if (zs_ttys == NULL)
-		zs_init_alloc_failure("zs_ttys");
-	serial_table = (struct tty_struct **)
-		zs_alloc_bootmem(NUM_CHANNELS * sizeof(struct tty_struct *));
-	if (serial_table == NULL)
-		zs_init_alloc_failure("serial_table");
-	serial_termios = (struct termios **)
-		zs_alloc_bootmem(NUM_CHANNELS * sizeof(struct termios *));
-	if (serial_termios == NULL)
-		zs_init_alloc_failure("serial_termios");
-	serial_termios_locked = (struct termios **)
-		zs_alloc_bootmem(NUM_CHANNELS * sizeof(struct termios *));
-	if (serial_termios_locked == NULL)
-		zs_init_alloc_failure("serial_termios_locked");
-}
-
-int __init zs_probe(void)
-{
-	int node;
-
-	if(sparc_cpu_model == sun4)
-		goto no_probe;
-
-	NUM_SERIAL = 0;
-	
-	node = prom_getchild(prom_root_node);
-	if (sparc_cpu_model == sun4d) {
-		int bbnode;
-		
-		while (node && (node = prom_searchsiblings(node, "cpu-unit"))) {
-			bbnode = prom_getchild(node);
-			if (bbnode && prom_searchsiblings(bbnode, "bootbus"))
-				NUM_SERIAL += 2;
-			node = prom_getsibling(node);
-		}
-		goto no_probe;
-	}
-#ifdef __sparc_v9__
-	else if (sparc_cpu_model == sun4u) {
-		int central_node;
-
-		/* Central bus zilogs must be checked for first,
-		 * since Enterprise boxes might have SBUSes as well.
-		 */
-		central_node = prom_finddevice("/central");
-		if(central_node != 0 && central_node != -1)
-			node = prom_searchsiblings(prom_getchild(central_node), "fhc");
-		else
-			node = prom_searchsiblings(node, "sbus");
-		if(node != 0 && node != -1)
-			node = prom_getchild(node);
-		if(node == 0 || node == -1)
-			return -ENODEV;
-	}
-#endif /* __sparc_v9__ */
-	else {
-		node = prom_searchsiblings(node, "obio");
-		if(node)
-			node = prom_getchild(node);
-		NUM_SERIAL = 2;
-		goto no_probe;
-	}
-
-	node = prom_searchsiblings(node, "zs");
-	if (!node)
-		return -ENODEV;
-		
-	NUM_SERIAL = 2;
-
-no_probe:
-	zs_alloc_tables();
-
-	/* Fill in rs_ops struct... */
-#ifdef CONFIG_SERIAL_CONSOLE
-	sunserial_setinitfunc(zs_console_init);
-#endif
-	sunserial_setinitfunc(zs_init);
-	rs_ops.rs_kgdb_hook = zs_kgdb_hook;
-	rs_ops.rs_change_mouse_baud = zs_change_mouse_baud;
-
-	sunkbd_setinitfunc(sun_kbd_init);
-	kbd_ops.compute_shiftstate = sun_compute_shiftstate;
-	kbd_ops.setledstate = sun_setledstate;
-	kbd_ops.getledstate = sun_getledstate;
-	kbd_ops.setkeycode = sun_setkeycode;
-	kbd_ops.getkeycode = sun_getkeycode;
-#if defined(__sparc_v9__) && defined(CONFIG_PCI)
-	sunkbd_install_keymaps(sun_key_maps, sun_keymap_count,
-			       sun_func_buf, sun_func_table,
-			       sun_funcbufsize, sun_funcbufleft,
-			       sun_accent_table, sun_accent_table_size);
-#endif
-	return 0;
-}
-
-static inline void zs_prepare(void)
-{
-	int channel, chip;
-	unsigned long flags;
-
-	if (!NUM_SERIAL)
-		return;
-	
-	save_and_cli(flags);
-	
-	/* Set up our interrupt linked list */
-	zs_chain = &zs_soft[0];
-	for(channel = 0; channel < NUM_CHANNELS - 1; channel++) {
-		zs_soft[channel].zs_next = &zs_soft[channel + 1];
-		zs_soft[channel].line = channel;
-	}
-	zs_soft[channel].zs_next = 0;
-
-	/* Initialize Softinfo */
-	for(chip = 0; chip < NUM_SERIAL; chip++) {
-		/* If we are doing kgdb over one of the channels on
-		 * chip zero, kgdb_channel will be set to 1 by the
-		 * zs_kgdb_hook() routine below.
-		 */
-		if(!zs_chips[chip]) {
-			zs_chips[chip] = get_zs(chip);
-			/* Two channels per chip */
-			zs_channels[(chip*2)] = &zs_chips[chip]->channelA;
-			zs_channels[(chip*2)+1] = &zs_chips[chip]->channelB;
-			zs_soft[(chip*2)].kgdb_channel = 0;
-			zs_soft[(chip*2)+1].kgdb_channel = 0;
-		}
-
-		/* First, set up channel A on this chip. */
-		channel = chip * 2;
-		zs_soft[channel].zs_channel = zs_channels[channel];
-		zs_soft[channel].change_needed = 0;
-		zs_soft[channel].clk_divisor = 16;
-		zs_soft[channel].cons_keyb = 0;
-		zs_soft[channel].cons_mouse = 0;
-		zs_soft[channel].channelA = 1;
-
-		/* Now, channel B */
-		channel++;
-		zs_soft[channel].zs_channel = zs_channels[channel];
-		zs_soft[channel].change_needed = 0;
-		zs_soft[channel].clk_divisor = 16;
-		zs_soft[channel].cons_keyb = 0;
-		zs_soft[channel].cons_mouse = 0;
-		zs_soft[channel].channelA = 0;
-	}
-	
-	restore_flags(flags);
-}
-
-int __init zs_init(void)
-{
-	int channel, brg, i;
-	unsigned long flags;
-	struct sun_serial *info;
-	char dummy;
-
-	/* Setup base handler, and timer table. */
-	init_bh(SERIAL_BH, do_serial_bh);
-
-	show_serial_version();
-
-	/* Initialize the tty_driver structure */
-	/* SPARC: Not all of this is exactly right for us. */
-	
-	memset(&serial_driver, 0, sizeof(struct tty_driver));
-	serial_driver.magic = TTY_DRIVER_MAGIC;
-	serial_driver.driver_name = "serial";
-#ifdef CONFIG_DEVFS_FS
-	serial_driver.name = "tts/%d";
-#else
-	serial_driver.name = "ttyS";
-#endif
-	serial_driver.major = TTY_MAJOR;
-	serial_driver.minor_start = 64;
-	serial_driver.num = NUM_CHANNELS;
-	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
-	serial_driver.subtype = SERIAL_TYPE_NORMAL;
-	serial_driver.init_termios = tty_std_termios;
-	serial_driver.init_termios.c_cflag =
-		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	serial_driver.flags = TTY_DRIVER_REAL_RAW;
-	serial_driver.refcount = &serial_refcount;
-	serial_driver.table = serial_table;
-	serial_driver.termios = serial_termios;
-	serial_driver.termios_locked = serial_termios_locked;
-
-	serial_driver.open = zs_open;
-	serial_driver.close = zs_close;
-	serial_driver.write = zs_write;
-	serial_driver.flush_chars = zs_flush_chars;
-	serial_driver.write_room = zs_write_room;
-	serial_driver.chars_in_buffer = zs_chars_in_buffer;
-	serial_driver.flush_buffer = zs_flush_buffer;
-	serial_driver.ioctl = zs_ioctl;
-	serial_driver.throttle = zs_throttle;
-	serial_driver.unthrottle = zs_unthrottle;
-	serial_driver.set_termios = zs_set_termios;
-	serial_driver.stop = zs_stop;
-	serial_driver.start = zs_start;
-	serial_driver.hangup = zs_hangup;
-
-	/* I'm too lazy, someone write versions of this for us. -DaveM */
-	/* I just did. :-) -AIB 2001-12-23 */
-	serial_driver.read_proc = zs_read_proc;
-
-	/*
-	 * The callout device is just like normal device except for
-	 * major number and the subtype code.
-	 */
-	callout_driver = serial_driver;
-	callout_driver.name = "cua/%d";
-	callout_driver.major = TTYAUX_MAJOR;
-	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-	callout_driver.read_proc = 0;
-	callout_driver.proc_entry = 0;
-
-	if (tty_register_driver(&serial_driver))
-		panic("Couldn't register serial driver\n");
-	if (tty_register_driver(&callout_driver))
-		panic("Couldn't register callout driver\n");
-
-	save_flags(flags); cli();
-
-	/* Initialize Softinfo */
-	zs_prepare();
-
-	/* Grab IRQ line before poking the chips so we do
-	 * not lose any interrupts.
-	 */
-	if (request_irq(zilog_irq, zs_interrupt, SA_SHIRQ,
-			"Zilog8530", zs_chain)) {
-		prom_printf("Unable to attach zs intr\n");
-		prom_halt();
-	}
-
-	/* Initialize Hardware */
-	for(channel = 0; channel < NUM_CHANNELS; channel++) {
-		/* Hardware reset each chip */
-		if (!(channel & 1)) {
-			write_zsreg(zs_soft[channel].zs_channel, R9, FHWRES);
-			ZSDELAY_LONG();
-			dummy = read_zsreg(zs_soft[channel].zs_channel, R0);
-		}
-
-		if(channel == KEYBOARD_LINE) {
-			zs_soft[channel].cons_keyb = 1;
-			zs_soft[channel].parity_mask = 0xff;
-			zs_kbdchan = zs_soft[channel].zs_channel;
-
-			write_zsreg(zs_soft[channel].zs_channel, R4,
-				    (PAR_EVEN | X16CLK | SB1));
-			write_zsreg(zs_soft[channel].zs_channel, R3, Rx8);
-			write_zsreg(zs_soft[channel].zs_channel, R5, Tx8);
-			write_zsreg(zs_soft[channel].zs_channel, R9, NV);
-			write_zsreg(zs_soft[channel].zs_channel, R10, NRZ);
-			write_zsreg(zs_soft[channel].zs_channel, R11,
-				    (TCBR | RCBR));
-			zs_soft[channel].zs_baud = 1200;
-			brg = BPS_TO_BRG(zs_soft[channel].zs_baud,
-					 ZS_CLOCK/zs_soft[channel].clk_divisor);
-			write_zsreg(zs_soft[channel].zs_channel, R12,
-				    (brg & 0xff));
-			write_zsreg(zs_soft[channel].zs_channel, R13,
-				    ((brg >> 8) & 0xff));
-			write_zsreg(zs_soft[channel].zs_channel, R14, BRSRC);
-
-			/* Enable Rx/Tx, IRQs, and inform kbd driver */
-			write_zsreg(zs_soft[channel].zs_channel, R14,
-				    (BRSRC | BRENAB));
-			write_zsreg(zs_soft[channel].zs_channel, R3,
-				    (Rx8 | RxENAB));
-			write_zsreg(zs_soft[channel].zs_channel, R5,
-				    (Tx8 | TxENAB | DTR | RTS));
-
-			write_zsreg(zs_soft[channel].zs_channel, R15,
-				    (DCDIE | CTSIE | TxUIE | BRKIE));
-			write_zsreg(zs_soft[channel].zs_channel, R0,
-				    RES_EXT_INT);
-			write_zsreg(zs_soft[channel].zs_channel, R0,
-				    RES_EXT_INT);
-
-			write_zsreg(zs_soft[channel].zs_channel, R1,
-				    (EXT_INT_ENAB | INT_ALL_Rx));
-			write_zsreg(zs_soft[channel].zs_channel, R9,
-				    (NV | MIE));
-			ZS_CLEARERR(zs_soft[channel].zs_channel);
-			ZS_CLEARFIFO(zs_soft[channel].zs_channel);
-		} else if(channel == MOUSE_LINE) {
-			zs_soft[channel].cons_mouse = 1;
-			zs_soft[channel].parity_mask = 0xff;
-			zs_mousechan = zs_soft[channel].zs_channel;
-
-			write_zsreg(zs_soft[channel].zs_channel, R4,
-				    (PAR_EVEN | X16CLK | SB1));
-			write_zsreg(zs_soft[channel].zs_channel, R3, Rx8);
-			write_zsreg(zs_soft[channel].zs_channel, R5, Tx8);
-			write_zsreg(zs_soft[channel].zs_channel, R9, NV);
-			write_zsreg(zs_soft[channel].zs_channel, R10, NRZ);
-			write_zsreg(zs_soft[channel].zs_channel, R11,
-				    (TCBR | RCBR));
-
-			zs_soft[channel].zs_baud = 4800;
-			brg = BPS_TO_BRG(zs_soft[channel].zs_baud,
-					 ZS_CLOCK/zs_soft[channel].clk_divisor);
-			write_zsreg(zs_soft[channel].zs_channel, R12,
-				    (brg & 0xff));
-			write_zsreg(zs_soft[channel].zs_channel, R13,
-				    ((brg >> 8) & 0xff));
-			write_zsreg(zs_soft[channel].zs_channel, R14, BRSRC);
-
-			/* Enable Rx, IRQs, and inform mouse driver */
-			write_zsreg(zs_soft[channel].zs_channel, R14,
-				    (BRSRC | BRENAB));
-			write_zsreg(zs_soft[channel].zs_channel, R3,
-				    (Rx8 | RxENAB));
-			write_zsreg(zs_soft[channel].zs_channel, R5, Tx8);
-
-			write_zsreg(zs_soft[channel].zs_channel, R15,
-				    (DCDIE | CTSIE | TxUIE | BRKIE));
-			write_zsreg(zs_soft[channel].zs_channel, R0,
-				    RES_EXT_INT);
-			write_zsreg(zs_soft[channel].zs_channel, R0,
-				    RES_EXT_INT);
-
-			write_zsreg(zs_soft[channel].zs_channel, R1,
-				    (EXT_INT_ENAB | INT_ALL_Rx));
-			write_zsreg(zs_soft[channel].zs_channel, R9,
-				    (NV | MIE));
-
-			sun_mouse_zsinit();
-		} else if (zs_soft[channel].is_cons) {
-			brg = BPS_TO_BRG(zs_soft[channel].zs_baud,
-					 ZS_CLOCK/zs_soft[channel].clk_divisor);
-			zscons_regs[12] = brg & 0xff;
-			zscons_regs[13] = (brg >> 8) & 0xff;
-
-			memcpy(zs_soft[channel].curregs, zscons_regs, sizeof(zscons_regs));
-			load_zsregs(&zs_soft[channel], zscons_regs);
-
-			ZS_CLEARERR(zs_soft[channel].zs_channel);
-			ZS_CLEARFIFO(zs_soft[channel].zs_channel);
-		} else if (zs_soft[channel].kgdb_channel) {
-			/* If this is the kgdb line, enable interrupts because
-			 * we now want to receive the 'control-c' character
-			 * from the client attached to us asynchronously.
-			 */
-			zs_soft[channel].parity_mask = 0xff;
-        		kgdb_chaninit(&zs_soft[channel], 1,
-				      zs_soft[channel].zs_baud);
-		} else {
-			zs_soft[channel].parity_mask = 0xff;
-			write_zsreg(zs_soft[channel].zs_channel, R4,
-				    (PAR_EVEN | X16CLK | SB1));
-			write_zsreg(zs_soft[channel].zs_channel, R3, Rx8);
-			write_zsreg(zs_soft[channel].zs_channel, R5, Tx8);
-			write_zsreg(zs_soft[channel].zs_channel, R9, NV);
-			write_zsreg(zs_soft[channel].zs_channel, R10, NRZ);
-			write_zsreg(zs_soft[channel].zs_channel, R11,
-				    (RCBR | TCBR));
-			zs_soft[channel].zs_baud = 9600;
-			brg = BPS_TO_BRG(zs_soft[channel].zs_baud,
-					 ZS_CLOCK/zs_soft[channel].clk_divisor);
-			write_zsreg(zs_soft[channel].zs_channel, R12,
-				    (brg & 0xff));
-			write_zsreg(zs_soft[channel].zs_channel, R13,
-				    ((brg >> 8) & 0xff));
-			write_zsreg(zs_soft[channel].zs_channel, R14, BRSRC);
-			write_zsreg(zs_soft[channel].zs_channel, R14,
-				    (BRSRC | BRENAB));
-			write_zsreg(zs_soft[channel].zs_channel, R3, Rx8);
-			write_zsreg(zs_soft[channel].zs_channel, R5, Tx8);
-			write_zsreg(zs_soft[channel].zs_channel, R15, DCDIE);
-			write_zsreg(zs_soft[channel].zs_channel, R9, NV | MIE);
-			write_zsreg(zs_soft[channel].zs_channel, R0,
-				    RES_EXT_INT);
-			write_zsreg(zs_soft[channel].zs_channel, R0,
-				    RES_EXT_INT);
-		}
-	}
-
-	for (info = zs_chain, i=0; info; info = info->zs_next, i++) {
-		info->magic = SERIAL_MAGIC;
-		info->port = (long) info->zs_channel;
-		info->line = i;
-		info->tty = 0;
-		info->irq = zilog_irq;
-		info->custom_divisor = 16;
-		info->close_delay = 50;
-		info->closing_wait = 3000;
-		info->x_char = 0;
-		info->event = 0;
-		info->count = 0;
-		info->blocked_open = 0;
-		info->tqueue.routine = do_softint;
-		info->tqueue.data = info;
-		info->tqueue_hangup.routine = do_serial_hangup;
-		info->tqueue_hangup.data = info;
-		info->callout_termios = callout_driver.init_termios;
-		info->normal_termios = serial_driver.init_termios;
-		init_waitqueue_head(&info->open_wait);
-		init_waitqueue_head(&info->close_wait);
-		printk("tty%02d at 0x%04x (irq = %s)", info->line, 
-		       info->port, __irq_itoa(info->irq));
-		printk(" is a Zilog8530\n");
-	}
-
-	restore_flags(flags);
-
-	keyboard_zsinit(kbd_put_char);
-	return 0;
-}
-
-/* This is called at boot time to prime the kgdb serial debugging
- * serial line.  The 'tty_num' argument is 0 for /dev/ttya and 1
- * for /dev/ttyb which is determined in setup_arch() from the
- * boot command line flags.
- */
-static void __init zs_kgdb_hook(int tty_num)
-{
-	int chip = 0;
-
-	if(!zs_chips[chip]) {
-		zs_chips[chip] = get_zs(chip);
-		/* Two channels per chip */
-		zs_channels[(chip*2)] = &zs_chips[chip]->channelA;
-		zs_channels[(chip*2)+1] = &zs_chips[chip]->channelB;
-	}
-	zs_soft[tty_num].zs_channel = zs_channels[tty_num];
-	zs_kgdbchan = zs_soft[tty_num].zs_channel;
-	zs_soft[tty_num].change_needed = 0;
-	zs_soft[tty_num].clk_divisor = 16;
-	zs_soft[tty_num].zs_baud = 9600;
-	zs_soft[tty_num].kgdb_channel = 1;     /* This runs kgdb */
-	zs_soft[tty_num ^ 1].kgdb_channel = 0; /* This does not */
-	/* Turn on transmitter/receiver at 8-bits/char */
-        kgdb_chaninit(&zs_soft[tty_num], 0, 9600);
-        ZS_CLEARERR(zs_kgdbchan);
-        ZS_CLEARFIFO(zs_kgdbchan);
-}
-
-#ifdef CONFIG_SERIAL_CONSOLE
-
-/* This is for console output over ttya/ttyb */
-static void
-zs_console_putchar(struct sun_serial *info, char ch)
-{
-	int loops = ZS_PUT_CHAR_MAX_DELAY;
-	unsigned long flags;
-
-	if(!info->zs_channel)
-		return;
-
-	save_flags(flags); cli();
-	zs_put_char(info->zs_channel, ch);
-	while (!(read_zsreg(info->zs_channel, R1) & ALL_SNT) && --loops)
-		udelay(5);
-	restore_flags(flags);
-}
-
-#ifdef SERIAL_CONSOLE_FAIR_OUTPUT
-/*
- * Fair output driver allows a process to speak.
- */
-static void zs_fair_output(struct sun_serial *info)
-{
-	unsigned long flags;
-	int left;		/* Output no more than that */
-	char c;
-
-	if (info == NULL)
-		return;
-	if (info->xmit_buf == NULL)
-		return;
-
-	save_flags(flags);  cli();
-	left = info->xmit_cnt;
-	while (left != 0) {
-		c = info->xmit_buf[info->xmit_tail];
-		info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1);
-		info->xmit_cnt--;
-		restore_flags(flags);
-
-		zs_console_putchar(info, c);
-
-		cli();
-		left = MIN(info->xmit_cnt, left-1);
-	}
-
-	/* Last character is being transmitted now (hopefully). */
-	sbus_writeb(RES_Tx_P, &info->zs_channel->control);
-	ZSDELAY();
-	ZSLOG(REGCTRL, RES_Tx_P, 1);
-
-	restore_flags(flags);
-	return;
-}
-#endif
-
-/*
- * zs_console_write is registered for printk.
- */
-static void
-zs_console_write(struct console *con, const char *s, unsigned count)
-{
-	struct sun_serial *info;
-	int i;
-
-	info = zs_soft + con->index;
-
-	for (i = 0; i < count; i++, s++) {
-		if(*s == '\n')
-			zs_console_putchar(info, '\r');
-		zs_console_putchar(info, *s);
-	}
-#ifdef SERIAL_CONSOLE_FAIR_OUTPUT
-	/* Comment this if you want to have a strict interrupt-driven output */
-	zs_fair_output(info);
-#endif
-}
-
-static kdev_t zs_console_device(struct console *con)
-{
-	return mk_kdev(TTY_MAJOR, 64 + con->index);
-}
-
-static int __init zs_console_setup(struct console *con, char *options)
-{
-	static struct tty_struct c_tty;
-	static struct termios c_termios;
-	struct sun_serial *info;
-	int brg, baud;
-
-	info = zs_soft + con->index;
-	info->is_cons = 1;
-
-	printk("Console: ttyS%d (Zilog8530)\n", info->line);
-	
-	sunserial_console_termios(con);
-	memset(&c_tty, 0, sizeof(c_tty));
-	memset(&c_termios, 0, sizeof(c_termios));
-	c_tty.termios = &c_termios;
-	c_termios.c_cflag = con->cflag;
-	baud = tty_get_baud_rate(&c_tty);
-
-	info->zs_baud = baud;
-
-	switch (con->cflag & CSIZE) {
-		case CS5:
-			zscons_regs[3] = Rx5 | RxENAB;
-			zscons_regs[5] = Tx5 | TxENAB;
-			info->parity_mask = 0x1f;
-			break;
-		case CS6:
-			zscons_regs[3] = Rx6 | RxENAB;
-			zscons_regs[5] = Tx6 | TxENAB;
-			info->parity_mask = 0x3f;
-			break;
-		case CS7:
-			zscons_regs[3] = Rx7 | RxENAB;
-			zscons_regs[5] = Tx7 | TxENAB;
-			info->parity_mask = 0x7f;
-			break;
-		default:
-		case CS8:
-			zscons_regs[3] = Rx8 | RxENAB;
-			zscons_regs[5] = Tx8 | TxENAB;
-			info->parity_mask = 0xff;
-			break;
-	}
-	zscons_regs[5] |= DTR;
-
-	if (con->cflag & PARENB)
-		zscons_regs[4] |= PAR_ENAB;
-	if (!(con->cflag & PARODD))
-		zscons_regs[4] |= PAR_EVEN;
-
-	if (con->cflag & CSTOPB)
-		zscons_regs[4] |= SB2;
-	else
-		zscons_regs[4] |= SB1;
-
-	brg = BPS_TO_BRG(baud, ZS_CLOCK / info->clk_divisor);
-	zscons_regs[12] = brg & 0xff;
-	zscons_regs[13] = (brg >> 8) & 0xff;
-
-	memcpy(info->curregs, zscons_regs, sizeof(zscons_regs));
-	load_zsregs(info, zscons_regs);
-
-	ZS_CLEARERR(info->zs_channel);
-	ZS_CLEARFIFO(info->zs_channel);
-	return 0;
-}
-
-static struct console zs_console = {
-	name:		"ttyS",
-	write:		zs_console_write,
-	device:		zs_console_device,
-	setup:		zs_console_setup,
-	flags:		CON_PRINTBUFFER,
-	index:		-1,
-};
-
-static int __init zs_console_init(void)
-{
-	extern int con_is_present(void);
-
-	if (con_is_present())
-		return 0;
-
-	zs_console.index = serial_console - 1;
-	register_console(&zs_console);
-	return 0;
-}
-
-#endif /* CONFIG_SERIAL_CONSOLE */
diff -Nru a/drivers/sbus/char/zs.h b/drivers/sbus/char/zs.h
--- a/drivers/sbus/char/zs.h	Sat Aug 10 18:42:22 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,427 +0,0 @@
-/* $Id: zs.h,v 1.3 1999/09/21 14:38:18 davem Exp $
- * zs.h: Definitions for the Sparc Zilog serial driver.
- *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
- * Copyright (C) 1996 Eddie C. Dost   (ecd@skynet.be)
- */
-#ifndef _ZS_H
-#define _ZS_H
-
-/* Just one channel */
-struct sun_zschannel {
-	volatile unsigned char control;
-	volatile unsigned char pad1;
-	volatile unsigned char data;
-	volatile unsigned char pad2;
-};
-
-/* The address space layout for each zs chip.  Yes they are
- * backwards.
- */
-struct sun_zslayout {
-	struct sun_zschannel channelB;
-	struct sun_zschannel channelA;
-};
-
-#define NUM_ZSREGS    16
-
-struct serial_struct {
-	int	type;
-	int	line;
-	int	port;
-	int	irq;
-	int	flags;
-	int	xmit_fifo_size;
-	int	custom_divisor;
-	int	baud_base;
-	unsigned short	close_delay;
-	char	reserved_char[2];
-	int	hub6;
-	unsigned short	closing_wait; /* time to wait before closing */
-	unsigned short	closing_wait2; /* no longer used... */
-	int	reserved[4];
-};
-
-/*
- * For the close wait times, 0 means wait forever for serial port to
- * flush its output.  65535 means don't wait at all.
- */
-#define ZILOG_CLOSING_WAIT_INF	0
-#define ZILOG_CLOSING_WAIT_NONE	65535
-
-/*
- * Definitions for ZILOG_struct (and serial_struct) flags field
- */
-#define ZILOG_HUP_NOTIFY 0x0001 /* Notify getty on hangups and closes 
-				   on the callout port */
-#define ZILOG_FOURPORT  0x0002	/* Set OU1, OUT2 per AST Fourport settings */
-#define ZILOG_SAK	0x0004	/* Secure Attention Key (Orange book) */
-#define ZILOG_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
-
-#define ZILOG_SPD_MASK	0x0030
-#define ZILOG_SPD_HI	0x0010	/* Use 76800 instead of 38400 bps */
-#define ZILOG_SPD_CUST	0x0030  /* Use user-specified divisor */
-
-#define ZILOG_SKIP_TEST	0x0040 /* Skip UART test during autoconfiguration */
-#define ZILOG_AUTO_IRQ  0x0080 /* Do automatic IRQ during autoconfiguration */
-#define ZILOG_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
-#define ZILOG_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
-#define ZILOG_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
-
-#define ZILOG_FLAGS	0x0FFF	/* Possible legal ZILOG flags */
-#define ZILOG_USR_MASK 0x0430	/* Legal flags that non-privileged
-				 * users can set or reset */
-
-/* Internal flags used only by kernel/chr_drv/serial.c */
-#define ZILOG_INITIALIZED	0x80000000 /* Serial port was initialized */
-#define ZILOG_CALLOUT_ACTIVE	0x40000000 /* Call out device is active */
-#define ZILOG_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
-#define ZILOG_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
-#define ZILOG_CLOSING		0x08000000 /* Serial port is closing */
-#define ZILOG_CTS_FLOW		0x04000000 /* Do CTS flow control */
-#define ZILOG_CHECK_CD		0x02000000 /* i.e., CLOCAL */
-
-/* Software state per channel */
-
-#ifdef __KERNEL__
-/*
- * This is our internal structure for each serial port's state.
- * 
- * Many fields are paralleled by the structure used by the serial_struct
- * structure.
- *
- * For definitions of the flags field, see tty.h
- */
-
-struct sun_serial {
-	struct sun_serial *zs_next;       /* For IRQ servicing chain */
-	struct sun_zschannel *zs_channel; /* Channel registers */
-	unsigned char read_reg_zero;
-
-	char soft_carrier;  /* Use soft carrier on this channel */
-	char cons_keyb;     /* Channel runs the keyboard */
-	char cons_mouse;    /* Channel runs the mouse */
-	char break_abort;   /* Is serial console in, so process brk/abrt */
-	char kgdb_channel;  /* Kgdb is running on this channel */
-	char is_cons;       /* Is this our console. */
-
-	char channelA;      /* This is channel A. */
-	char parity_mask;   /* Mask out parity bits in data register. */
-
-	/* We need to know the current clock divisor
-	 * to read the bps rate the chip has currently
-	 * loaded.
-	 */
-	unsigned char clk_divisor;  /* May be 1, 16, 32, or 64 */
-	int zs_baud;
-
-	/* Current write register values */
-	unsigned char curregs[NUM_ZSREGS];
-
-	char change_needed;
-
-	int			magic;
-	int			baud_base;
-	int			port;
-	int			irq;
-	int			flags; 		/* defined in tty.h */
-	int			type; 		/* UART type */
-	struct tty_struct 	*tty;
-	int			read_status_mask;
-	int			ignore_status_mask;
-	int			timeout;
-	int			xmit_fifo_size;
-	int			custom_divisor;
-	int			x_char;	/* xon/xoff character */
-	int			close_delay;
-	unsigned short		closing_wait;
-	unsigned short		closing_wait2;
-	unsigned long		event;
-	unsigned long		last_active;
-	int			line;
-	int			count;	    /* # of fd on device */
-	int			blocked_open; /* # of blocked opens */
-	long			session; /* Session of opening process */
-	long			pgrp; /* pgrp of opening process */
-	unsigned char 		*xmit_buf;
-	int			xmit_head;
-	int			xmit_tail;
-	int			xmit_cnt;
-	struct tq_struct	tqueue;
-	struct tq_struct	tqueue_hangup;
-	struct termios		normal_termios;
-	struct termios		callout_termios;
-	wait_queue_head_t	open_wait;
-	wait_queue_head_t	close_wait;
-};
-
-
-#define SERIAL_MAGIC 0x5301
-
-/*
- * The size of the serial xmit buffer is 1 page, or 4096 bytes
- */
-#define SERIAL_XMIT_SIZE 4096
-
-/*
- * Events are used to schedule things to happen at timer-interrupt
- * time, instead of at rs interrupt time.
- */
-#define RS_EVENT_WRITE_WAKEUP	0
-
-#endif /* __KERNEL__ */
-
-/* Conversion routines to/from brg time constants from/to bits
- * per second.
- */
-#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2))
-#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2)
-
-/* The Zilog register set */
-
-#define	FLAG	0x7e
-
-/* Write Register 0 */
-#define	R0	0		/* Register selects */
-#define	R1	1
-#define	R2	2
-#define	R3	3
-#define	R4	4
-#define	R5	5
-#define	R6	6
-#define	R7	7
-#define	R8	8
-#define	R9	9
-#define	R10	10
-#define	R11	11
-#define	R12	12
-#define	R13	13
-#define	R14	14
-#define	R15	15
-
-#define	NULLCODE	0	/* Null Code */
-#define	POINT_HIGH	0x8	/* Select upper half of registers */
-#define	RES_EXT_INT	0x10	/* Reset Ext. Status Interrupts */
-#define	SEND_ABORT	0x18	/* HDLC Abort */
-#define	RES_RxINT_FC	0x20	/* Reset RxINT on First Character */
-#define	RES_Tx_P	0x28	/* Reset TxINT Pending */
-#define	ERR_RES		0x30	/* Error Reset */
-#define	RES_H_IUS	0x38	/* Reset highest IUS */
-
-#define	RES_Rx_CRC	0x40	/* Reset Rx CRC Checker */
-#define	RES_Tx_CRC	0x80	/* Reset Tx CRC Checker */
-#define	RES_EOM_L	0xC0	/* Reset EOM latch */
-
-/* Write Register 1 */
-
-#define	EXT_INT_ENAB	0x1	/* Ext Int Enable */
-#define	TxINT_ENAB	0x2	/* Tx Int Enable */
-#define	PAR_SPEC	0x4	/* Parity is special condition */
-
-#define	RxINT_DISAB	0	/* Rx Int Disable */
-#define	RxINT_FCERR	0x8	/* Rx Int on First Character Only or Error */
-#define	INT_ALL_Rx	0x10	/* Int on all Rx Characters or error */
-#define	INT_ERR_Rx	0x18	/* Int on error only */
-#define RxINT_MASK	0x18
-
-#define	WT_RDY_RT	0x20	/* Wait/Ready on R/T */
-#define	WT_FN_RDYFN	0x40	/* Wait/FN/Ready FN */
-#define	WT_RDY_ENAB	0x80	/* Wait/Ready Enable */
-
-/* Write Register #2 (Interrupt Vector) */
-
-/* Write Register 3 */
-
-#define	RxENAB  	0x1	/* Rx Enable */
-#define	SYNC_L_INH	0x2	/* Sync Character Load Inhibit */
-#define	ADD_SM		0x4	/* Address Search Mode (SDLC) */
-#define	RxCRC_ENAB	0x8	/* Rx CRC Enable */
-#define	ENT_HM		0x10	/* Enter Hunt Mode */
-#define	AUTO_ENAB	0x20	/* Auto Enables */
-#define	Rx5		0x0	/* Rx 5 Bits/Character */
-#define	Rx7		0x40	/* Rx 7 Bits/Character */
-#define	Rx6		0x80	/* Rx 6 Bits/Character */
-#define	Rx8		0xc0	/* Rx 8 Bits/Character */
-#define RxN_MASK	0xc0
-
-/* Write Register 4 */
-
-#define	PAR_ENAB	0x1	/* Parity Enable */
-#define	PAR_EVEN	0x2	/* Parity Even/Odd* */
-
-#define	SYNC_ENAB	0	/* Sync Modes Enable */
-#define	SB1		0x4	/* 1 stop bit/char */
-#define	SB15		0x8	/* 1.5 stop bits/char */
-#define	SB2		0xc	/* 2 stop bits/char */
-
-#define	MONSYNC		0	/* 8 Bit Sync character */
-#define	BISYNC		0x10	/* 16 bit sync character */
-#define	SDLC		0x20	/* SDLC Mode (01111110 Sync Flag) */
-#define	EXTSYNC		0x30	/* External Sync Mode */
-
-#define	X1CLK		0x0	/* x1 clock mode */
-#define	X16CLK		0x40	/* x16 clock mode */
-#define	X32CLK		0x80	/* x32 clock mode */
-#define	X64CLK		0xC0	/* x64 clock mode */
-
-/* Write Register 5 */
-
-#define	TxCRC_ENAB	0x1	/* Tx CRC Enable */
-#define	RTS		0x2	/* RTS */
-#define	SDLC_CRC	0x4	/* SDLC/CRC-16 */
-#define	TxENAB		0x8	/* Tx Enable */
-#define	SND_BRK		0x10	/* Send Break */
-#define	Tx5		0x0	/* Tx 5 bits (or less)/character */
-#define	Tx7		0x20	/* Tx 7 bits/character */
-#define	Tx6		0x40	/* Tx 6 bits/character */
-#define	Tx8		0x60	/* Tx 8 bits/character */
-#define TxN_MASK	0x60
-#define	DTR		0x80	/* DTR */
-
-/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */
-
-/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */
-
-/* Write Register 8 (transmit buffer) */
-
-/* Write Register 9 (Master interrupt control) */
-#define	VIS	1	/* Vector Includes Status */
-#define	NV	2	/* No Vector */
-#define	DLC	4	/* Disable Lower Chain */
-#define	MIE	8	/* Master Interrupt Enable */
-#define	STATHI	0x10	/* Status high */
-#define	NORESET	0	/* No reset on write to R9 */
-#define	CHRB	0x40	/* Reset channel B */
-#define	CHRA	0x80	/* Reset channel A */
-#define	FHWRES	0xc0	/* Force hardware reset */
-
-/* Write Register 10 (misc control bits) */
-#define	BIT6	1	/* 6 bit/8bit sync */
-#define	LOOPMODE 2	/* SDLC Loop mode */
-#define	ABUNDER	4	/* Abort/flag on SDLC xmit underrun */
-#define	MARKIDLE 8	/* Mark/flag on idle */
-#define	GAOP	0x10	/* Go active on poll */
-#define	NRZ	0	/* NRZ mode */
-#define	NRZI	0x20	/* NRZI mode */
-#define	FM1	0x40	/* FM1 (transition = 1) */
-#define	FM0	0x60	/* FM0 (transition = 0) */
-#define	CRCPS	0x80	/* CRC Preset I/O */
-
-/* Write Register 11 (Clock Mode control) */
-#define	TRxCXT	0	/* TRxC = Xtal output */
-#define	TRxCTC	1	/* TRxC = Transmit clock */
-#define	TRxCBR	2	/* TRxC = BR Generator Output */
-#define	TRxCDP	3	/* TRxC = DPLL output */
-#define	TRxCOI	4	/* TRxC O/I */
-#define	TCRTxCP	0	/* Transmit clock = RTxC pin */
-#define	TCTRxCP	8	/* Transmit clock = TRxC pin */
-#define	TCBR	0x10	/* Transmit clock = BR Generator output */
-#define	TCDPLL	0x18	/* Transmit clock = DPLL output */
-#define	RCRTxCP	0	/* Receive clock = RTxC pin */
-#define	RCTRxCP	0x20	/* Receive clock = TRxC pin */
-#define	RCBR	0x40	/* Receive clock = BR Generator output */
-#define	RCDPLL	0x60	/* Receive clock = DPLL output */
-#define	RTxCX	0x80	/* RTxC Xtal/No Xtal */
-
-/* Write Register 12 (lower byte of baud rate generator time constant) */
-
-/* Write Register 13 (upper byte of baud rate generator time constant) */
-
-/* Write Register 14 (Misc control bits) */
-#define	BRENAB 	1	/* Baud rate generator enable */
-#define	BRSRC	2	/* Baud rate generator source */
-#define	DTRREQ	4	/* DTR/Request function */
-#define	AUTOECHO 8	/* Auto Echo */
-#define	LOOPBAK	0x10	/* Local loopback */
-#define	SEARCH	0x20	/* Enter search mode */
-#define	RMC	0x40	/* Reset missing clock */
-#define	DISDPLL	0x60	/* Disable DPLL */
-#define	SSBR	0x80	/* Set DPLL source = BR generator */
-#define	SSRTxC	0xa0	/* Set DPLL source = RTxC */
-#define	SFMM	0xc0	/* Set FM mode */
-#define	SNRZI	0xe0	/* Set NRZI mode */
-
-/* Write Register 15 (external/status interrupt control) */
-#define	ZCIE	2	/* Zero count IE */
-#define	DCDIE	8	/* DCD IE */
-#define	SYNCIE	0x10	/* Sync/hunt IE */
-#define	CTSIE	0x20	/* CTS IE */
-#define	TxUIE	0x40	/* Tx Underrun/EOM IE */
-#define	BRKIE	0x80	/* Break/Abort IE */
-
-
-/* Read Register 0 */
-#define	Rx_CH_AV	0x1	/* Rx Character Available */
-#define	ZCOUNT		0x2	/* Zero count */
-#define	Tx_BUF_EMP	0x4	/* Tx Buffer empty */
-#define	DCD		0x8	/* DCD */
-#define	SYNC		0x10	/* Sync/hunt */
-#define	CTS		0x20	/* CTS */
-#define	TxEOM		0x40	/* Tx underrun */
-#define	BRK_ABRT	0x80	/* Break/Abort */
-
-/* Read Register 1 */
-#define	ALL_SNT		0x1	/* All sent */
-/* Residue Data for 8 Rx bits/char programmed */
-#define	RES3		0x8	/* 0/3 */
-#define	RES4		0x4	/* 0/4 */
-#define	RES5		0xc	/* 0/5 */
-#define	RES6		0x2	/* 0/6 */
-#define	RES7		0xa	/* 0/7 */
-#define	RES8		0x6	/* 0/8 */
-#define	RES18		0xe	/* 1/8 */
-#define	RES28		0x0	/* 2/8 */
-/* Special Rx Condition Interrupts */
-#define	PAR_ERR		0x10	/* Parity error */
-#define	Rx_OVR		0x20	/* Rx Overrun Error */
-#define	CRC_ERR		0x40	/* CRC/Framing Error */
-#define	END_FR		0x80	/* End of Frame (SDLC) */
-
-/* Read Register 2 (channel b only) - Interrupt vector */
-#define CHB_Tx_EMPTY	0x00
-#define CHB_EXT_STAT	0x02
-#define CHB_Rx_AVAIL	0x04
-#define CHB_SPECIAL	0x06
-#define CHA_Tx_EMPTY	0x08
-#define CHA_EXT_STAT	0x0a
-#define CHA_Rx_AVAIL	0x0c
-#define CHA_SPECIAL	0x0e
-#define STATUS_MASK	0x0e
-
-/* Read Register 3 (interrupt pending register) ch a only */
-#define	CHBEXT	0x1		/* Channel B Ext/Stat IP */
-#define	CHBTxIP	0x2		/* Channel B Tx IP */
-#define	CHBRxIP	0x4		/* Channel B Rx IP */
-#define	CHAEXT	0x8		/* Channel A Ext/Stat IP */
-#define	CHATxIP	0x10		/* Channel A Tx IP */
-#define	CHARxIP	0x20		/* Channel A Rx IP */
-
-/* Read Register 8 (receive data register) */
-
-/* Read Register 10  (misc status bits) */
-#define	ONLOOP	2		/* On loop */
-#define	LOOPSEND 0x10		/* Loop sending */
-#define	CLK2MIS	0x40		/* Two clocks missing */
-#define	CLK1MIS	0x80		/* One clock missing */
-
-/* Read Register 12 (lower byte of baud rate generator constant) */
-
-/* Read Register 13 (upper byte of baud rate generator constant) */
-
-/* Read Register 15 (value of WR 15) */
-
-/* Misc macros */
-#define ZS_CLEARERR(channel)    do { sbus_writeb(ERR_RES, &channel->control); \
-				     udelay(5); } while(0)
-
-#define ZS_CLEARSTAT(channel)   do { sbus_writeb(RES_EXT_INT, &channel->control); \
-				     udelay(5); } while(0)
-
-#define ZS_CLEARFIFO(channel)   do { sbus_readb(&channel->data); \
-				     udelay(2); \
-				     sbus_readb(&channel->data); \
-				     udelay(2); \
-				     sbus_readb(&channel->data); \
-				     udelay(2); } while(0)
-
-#endif /* !(_ZS_H) */
diff -Nru a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c
--- a/drivers/sbus/sbus.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/sbus/sbus.c	Sat Aug 10 18:42:22 2002
@@ -16,6 +16,9 @@
 #include <asm/oplib.h>
 #include <asm/bpp.h>
 #include <asm/irq.h>
+#ifdef CONFIG_SPARC32
+#include <asm/pcic.h>		/* pcic_present */
+#endif
 
 struct sbus_bus *sbus_root = NULL;
 
@@ -282,7 +285,6 @@
 
 extern void register_proc_sparc_ioport(void);
 extern void firetruck_init(void);
-extern void rs_init(void);
 
 static int __init sbus_init(void)
 {
@@ -334,10 +336,17 @@
 		   (nd = prom_getchild(iommund)) == 0 ||
 		   (nd = prom_searchsiblings(nd, "sbus")) == 0) {
 #ifdef CONFIG_PCI
-                        if (!pcibios_present()) {       
+#ifdef CONFIG_SPARC32
+                        if (!pcic_present()) {
                                 prom_printf("Neither SBUS nor PCI found.\n");
                                 prom_halt();
                         }
+#else
+                        if (!pcibios_present()) {
+                                prom_printf("Neither SBUS nor PCI found.\n");
+                                prom_halt();
+                        }
+#endif
                         return 0;
 #else
 			/* No reason to run further - the data access trap will occur. */
@@ -495,8 +504,6 @@
 		sun4d_init_sbi_irq();
 	}
 	
-	rs_init();
-
 #ifdef __sparc_v9__
 	if (sparc_cpu_model == sun4u) {
 		firetruck_init();
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_linux.c b/drivers/scsi/aic7xxx/aic7xxx_linux.c
--- a/drivers/scsi/aic7xxx/aic7xxx_linux.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/scsi/aic7xxx/aic7xxx_linux.c	Sat Aug 10 18:42:22 2002
@@ -1768,6 +1768,10 @@
 	u_long flags;
 
 	ahc = (struct ahc_softc *) dev_id;
+	if (!ahc->platform_data->host) {
+		printk("aic7xxx: interrupt while setup incomplete\n");
+		return;
+	}
 	ahc_lock(ahc, &flags); 
 	ahc_intr(ahc);
 	/*
diff -Nru a/drivers/scsi/esp.c b/drivers/scsi/esp.c
--- a/drivers/scsi/esp.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/scsi/esp.c	Sat Aug 10 18:42:23 2002
@@ -491,8 +491,6 @@
 	case dvmahme:
 		/* This is the HME DVMA gate array. */
 
-		save_flags(flags); cli(); /* I really hate this chip. */
-
 		sbus_writel(DMA_RESET_FAS366, esp->dregs + DMA_CSR);
 		sbus_writel(DMA_RST_SCSI, esp->dregs + DMA_CSR);
 
@@ -521,7 +519,6 @@
 		 */
 		sbus_writel(0, esp->dregs + DMA_ADDR);
 
-		restore_flags(flags);
 		break;
 	case dvmarev2:
 		/* This is the gate array found in the sun4m
diff -Nru a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
--- a/drivers/scsi/qlogicpti.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/scsi/qlogicpti.c	Sat Aug 10 18:42:21 2002
@@ -318,7 +318,7 @@
 
 	risc_code_addr = 0x1000;	/* all load addresses are at 0x1000 */
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&qpti->lock, flags);
 
 	sbus_writew(HCCTRL_PAUSE, qpti->qregs + HCCTRL);
 
@@ -366,7 +366,7 @@
 	if (qlogicpti_mbox_command(qpti, param, 1)) {
 		printk(KERN_EMERG "qlogicpti%d: Cannot execute ISP firmware.\n",
 		       qpti->qpti_id);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&qpti->lock, flags);
 		return 1;
 	}
 
@@ -377,7 +377,7 @@
 	   (param[0] != MBOX_COMMAND_COMPLETE)) {
 		printk(KERN_EMERG "qlogicpti%d: Cannot set initiator SCSI ID.\n",
 		       qpti->qpti_id);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&qpti->lock, flags);
 		return 1;
 	}
 
@@ -392,7 +392,7 @@
 	if (qlogicpti_mbox_command(qpti, param, 1)) {
 		printk(KERN_EMERG "qlogicpti%d: Cannot init response queue.\n",
 		       qpti->qpti_id);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&qpti->lock, flags);
 		return 1;
 	}
 
@@ -404,7 +404,7 @@
 	if (qlogicpti_mbox_command(qpti, param, 1)) {
 		printk(KERN_EMERG "qlogicpti%d: Cannot init request queue.\n",
 		       qpti->qpti_id);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&qpti->lock, flags);
 		return 1;
 	}
 
@@ -450,7 +450,7 @@
 	qlogicpti_mbox_command(qpti, param, 0);
 	qpti->send_marker = 1;
 
-	restore_flags(flags);
+	spin_unlock_irqrestore(&qpti->lock, flags);
 	return 0;
 }
 
@@ -468,7 +468,7 @@
 	risc_code_addr = 0x1000;	/* all f/w modules load at 0x1000 */
 	risc_code_length = sbus_risc_code_length01;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&qpti->lock, flags);
 
 	/* Verify the checksum twice, one before loading it, and once
 	 * afterwards via the mailbox commands.
@@ -476,7 +476,7 @@
 	for (i = 0; i < risc_code_length; i++)
 		csum += risc_code[i];
 	if (csum) {
-		restore_flags(flags);
+		spin_unlock_irqrestore(&qpti->lock, flags);
 		printk(KERN_EMERG "qlogicpti%d: Aieee, firmware checksum failed!",
 		       qpti->qpti_id);
 		return 1;
@@ -488,7 +488,7 @@
 	while (--timeout && (sbus_readw(qpti->qregs + SBUS_CTRL) & SBUS_CTRL_RESET))
 		udelay(20);
 	if (!timeout) {
-		restore_flags(flags);
+		spin_unlock_irqrestore(&qpti->lock, flags);
 		printk(KERN_EMERG "qlogicpti%d: Cannot reset the ISP.", qpti->qpti_id);
 		return 1;
 	}
@@ -528,7 +528,7 @@
 	if (qlogicpti_mbox_command(qpti, param, 1)) {
 		printk(KERN_EMERG "qlogicpti%d: Cannot stop firmware for reload.\n",
 		       qpti->qpti_id);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&qpti->lock, flags);
 		return 1;
 	}		
 
@@ -541,7 +541,7 @@
 		    param[0] != MBOX_COMMAND_COMPLETE) {
 			printk("qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
 			       qpti->qpti_id);
-			restore_flags(flags);
+			spin_unlock_irqrestore(&qpti->lock, flags);
 			return 1;
 		}
 	}
@@ -561,7 +561,7 @@
 	    (param[0] != MBOX_COMMAND_COMPLETE)) {
 		printk(KERN_EMERG "qlogicpti%d: New firmware csum failure!\n",
 		       qpti->qpti_id);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&qpti->lock, flags);
 		return 1;
 	}
 
@@ -575,7 +575,7 @@
 	    (param[0] != MBOX_COMMAND_COMPLETE)) {
 		printk(KERN_EMERG "qlogicpti%d: AboutFirmware cmd fails.\n",
 		       qpti->qpti_id);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&qpti->lock, flags);
 		return 1;
 	}
 
@@ -591,7 +591,7 @@
 	    (param[0] != MBOX_COMMAND_COMPLETE)) {
 		printk(KERN_EMERG "qlogicpti%d: could not set clock rate.\n",
 		       qpti->qpti_id);
-		restore_flags(flags);
+		spin_unlock_irqrestore(&qpti->lock, flags);
 		return 1;
 	}
 
@@ -608,7 +608,7 @@
 		qlogicpti_mbox_command(qpti, param, 1);
 	}
 
-	restore_flags(flags);
+	spin_unlock_irqrestore(&qpti->lock, flags);
 	return 0;
 }
 
@@ -1166,8 +1166,8 @@
 
 int qlogicpti_queuecommand_slow(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *))
 {
-	unsigned long flags;
 	struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->host->hostdata;
+	unsigned long flags;
 
 	/*
 	 * done checking this host adapter?
@@ -1178,12 +1178,13 @@
 	if (qpti->sbits && qpti->sbits != 0xffff) {
 		/* See above about in ourdone this ugliness... */
 		Cmnd->SCp.Message = ((unsigned long)done) & 0xffffffff;
-#ifdef __sparc_v9__
+#ifdef CONFIG_SPARC64
 		Cmnd->SCp.Status = ((unsigned long)done >> 32UL) & 0xffffffff;
 #endif
 		return qlogicpti_queuecommand(Cmnd, ourdone);
 	}
-	save_flags(flags); cli();
+
+	spin_lock_irqsave(&qpti->lock, flags);
 
 	/*
 	 * We've peeked at all targets for this bus- time
@@ -1226,7 +1227,8 @@
 	if (qpti == NULL)
 		Cmnd->host->hostt->queuecommand = qlogicpti_queuecommand;
 
-	restore_flags(flags);
+	spin_unlock_irqrestore(&qpti->lock, flags);
+
 	return qlogicpti_queuecommand(Cmnd, done);
 }
 
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/scsi/sd.c	Sat Aug 10 18:42:21 2002
@@ -91,7 +91,7 @@
 static rwlock_t sd_dsk_arr_lock = RW_LOCK_UNLOCKED;
 
 static int check_scsidisk_media_change(kdev_t);
-static int fop_revalidate_scsidisk(kdev_t);
+static int sd_revalidate(kdev_t);
 
 static void sd_init_onedisk(Scsi_Disk * sdkp, int dsk_nr);
 
@@ -243,12 +243,6 @@
 				return -EFAULT;
 			return 0;
 		}
-
-		case BLKRRPART: /* Re-read partition tables */
-		        if (!capable(CAP_SYS_ADMIN))
-		                return -EACCES;
-			return revalidate_scsidisk(dev, 1);
-
 		default:
 			return scsi_ioctl(sdp, cmd, (void *) arg);
 	}
@@ -501,7 +495,7 @@
 	sdp->access_count++;
 
 	if (sdp->removable) {
-		check_disk_change(inode->i_rdev);
+		check_disk_change(inode->i_bdev);
 
 		/*
 		 * If the drive is empty, just let the open fail.
@@ -600,7 +594,7 @@
 	release:		sd_release,
 	ioctl:			sd_ioctl,
 	check_media_change:	check_scsidisk_media_change,
-	revalidate:		fop_revalidate_scsidisk
+	revalidate:		sd_revalidate
 };
 
 static struct gendisk **sd_disks;
@@ -1318,6 +1312,7 @@
 		devfs_handle_t de;
 		struct device *dev;
 		char flags;
+		char name[5];
 	} *p;
 	struct gendisk *gd;
 
@@ -1368,10 +1363,14 @@
         gd->driverfs_dev_arr[0] = &sdp->sdev_driverfs_dev;
 	gd->major = SD_MAJOR(dsk_nr>>4);
 	gd->first_minor = (dsk_nr & 15)<<4;
-	gd->major_name = "sd";
 	gd->minor_shift = 4;
 	gd->part = sd + (dsk_nr << 4);
 	gd->fops = &sd_fops;
+	if (dsk_nr > 26)
+		sprintf(p->name, "sd%c%c", 'a'+dsk_nr/26-1, 'a'+dsk_nr%26);
+	else
+		sprintf(p->name, "sd%c", 'a'+dsk_nr%26);
+	gd->major_name = p->name;
         if (sdp->removable)
 		gd->flags[0] |= GENHD_FL_REMOVABLE;
 	sd_disks[dsk_nr] = gd;
@@ -1382,50 +1381,17 @@
 	return 0;
 }
 
-/**
- *	revalidate_scsidisk - called to flush all partitions and partition 
- *	tables for a changed scsi disk. sd_init_onedisk() is then called
- *	followed by re-reading the new partition table.
- *      @dev: kernel device descriptor (kdev_t)
- *      @maxusage: 0 when called from block level, 1 when called from
- *      sd_ioctl().
- *
- *	Returns 0 if successful; negated errno value otherwise.
- */
-int revalidate_scsidisk(kdev_t dev, int maxusage)
+static int sd_revalidate(kdev_t dev)
 {
 	int dsk_nr = DEVICE_NR(dev);
-	Scsi_Disk * sdkp;
-	Scsi_Device * sdp;
-	kdev_t device = mk_kdev(major(dev), minor(dev) & ~15);
-	int res;
+	Scsi_Disk * sdkp = sd_get_sdisk(dsk_nr);
 
-	SCSI_LOG_HLQUEUE(3, printk("revalidate_scsidisk: dsk_nr=%d\n", 
-				   DEVICE_NR(dev)));
-	sdkp = sd_get_sdisk(dsk_nr);
-	if ((NULL == sdkp) || (NULL == (sdp = sdkp->device)))
+	if (!sdkp || !sdkp->device)
 		return -ENODEV;
 
-	res = dev_lock_part(device);
-	if (res < 0)
-		return res;
-
-	res = wipe_partitions(device);
-	if (res)
-		goto leave;
-
 	sd_init_onedisk(sdkp, dsk_nr);
-
-	grok_partitions(device, sdkp->capacity);
-
-leave:
-	dev_unlock_part(device);
-	return res;
-}
-
-static int fop_revalidate_scsidisk(kdev_t dev)
-{
-	return revalidate_scsidisk(dev, 0);
+	sd_disks[dsk_nr]->part[0].nr_sects = sdkp->capacity;
+	return 0;
 }
 
 /**
diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c
--- a/drivers/scsi/sr.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/scsi/sr.c	Sat Aug 10 18:42:21 2002
@@ -402,8 +402,6 @@
 {
 	Scsi_CD *SCp = cdi->handle;
 
-	check_disk_change(cdi->dev);
-
 	if (minor(cdi->dev) >= sr_template.dev_max || !SCp->device) {
 		return -ENXIO;	/* No such device */
 	}
diff -Nru a/drivers/serial/Config.help b/drivers/serial/Config.help
--- a/drivers/serial/Config.help	Sat Aug 10 18:42:21 2002
+++ b/drivers/serial/Config.help	Sat Aug 10 18:42:21 2002
@@ -223,3 +223,16 @@
 #  you can make the first serial port the console by answering Y to
 #  this option.
 
+CONFIG_SERIAL_SUNZILOG
+  This driver supports the Zilog8530 serial ports found on many Sparc
+  systems.  Say Y or M if you want to be able to these serial ports.
+
+CONFIG_SERIAL_SUNSU
+  This driver supports the 8250 serial ports that run the keyboard and
+  mouse on (PCI) UltraSPARC systems.  Say Y or M if you want to be able
+  to these serial ports.
+
+CONFIG_SERIAL_SUNSAB
+  This driver supports the Siemens SAB82532 DUSCC serial ports on newer
+  (PCI) UltraSPARC systems.  Say Y or M if you want to be able to these
+  serial ports.
diff -Nru a/drivers/serial/Config.in b/drivers/serial/Config.in
--- a/drivers/serial/Config.in	Sat Aug 10 18:42:21 2002
+++ b/drivers/serial/Config.in	Sat Aug 10 18:42:21 2002
@@ -51,16 +51,28 @@
    dep_bool '  Console on SA1100 serial port' CONFIG_SERIAL_SA1100_CONSOLE $CONFIG_SERIAL_SA1100
 fi
 
+if [ "$CONFIG_SPARC" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
+   define_bool CONFIG_SERIAL_SUNCORE y
+   define_bool CONFIG_SERIAL_CORE_CONSOLE y
+   tristate 'Sun Zilog8530 serial support' CONFIG_SERIAL_SUNZILOG
+   dep_tristate 'Sun SU serial support' CONFIG_SERIAL_SUNSU $CONFIG_PCI
+   dep_tristate 'Sun Siemens SAB82532 serial support' CONFIG_SERIAL_SUNSAB $CONFIG_PCI
+fi
+
 if [ "$CONFIG_SERIAL_AMBA" = "y"   -o "$CONFIG_SERIAL_CLPS711X" = "y" -o \
      "$CONFIG_SERIAL_21285" = "y"  -o "$CONFIG_SERIAL_SA1100" = "y" -o \
      "$CONFIG_SERIAL_ANAKIN" = "y" -o "$CONFIG_SERIAL_UART00" = "y" -o \
-     "$CONFIG_SERIAL_8250" = "y"   -o "$CONFIG_SERIAL_ROCKETPORT" = "y" ]; then
+     "$CONFIG_SERIAL_8250" = "y"   -o "$CONFIG_SERIAL_ROCKETPORT" = "y" -o \
+     "$CONFIG_SERIAL_SUNZILOG" = "y" -o "$CONFIG_SERIAL_SUNSU" = "y" -o \
+     "$CONFIG_SERIAL_SUNSAB" = "y" ]; then
    define_bool CONFIG_SERIAL_CORE y
 else
    if [ "$CONFIG_SERIAL_AMBA" = "m"   -o "$CONFIG_SERIAL_CLPS711X" = "m" -o \
         "$CONFIG_SERIAL_21285" = "m"  -o "$CONFIG_SERIAL_SA1100" = "m" -o \
         "$CONFIG_SERIAL_ANAKIN" = "m" -o "$CONFIG_SERIAL_UART00" = "m" -o \
-        "$CONFIG_SERIAL_8250" = "m"   -o "$CONFIG_SERIAL_ROCKETPORT" = "m" ]; then
+        "$CONFIG_SERIAL_8250" = "m"   -o "$CONFIG_SERIAL_ROCKETPORT" = "m" -o \
+        "$CONFIG_SERIAL_SUNZILOG" = "m" -o "$CONFIG_SERIAL_SUNSU" = "m" -o \
+        "$CONFIG_SERIAL_SUNSAB" = "m" ]; then
       define_bool CONFIG_SERIAL_CORE m
    fi
 fi
@@ -70,7 +82,8 @@
      "$CONFIG_SERIAL_SA1100_CONSOLE" = "y" -o \
      "$CONFIG_SERIAL_ANAKIN_CONSOLE" = "y" -o \
      "$CONFIG_SERIAL_UART00_CONSOLE" = "y" -o \
-     "$CONFIG_SERIAL_8250_CONSOLE" = "y" ]; then
+     "$CONFIG_SERIAL_8250_CONSOLE" = "y"  -o \
+     "$CONFIG_SERIAL_SUNCORE" = "y" ]; then
    define_bool CONFIG_SERIAL_CORE_CONSOLE y
 fi
 
diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile
--- a/drivers/serial/Makefile	Sat Aug 10 18:42:22 2002
+++ b/drivers/serial/Makefile	Sat Aug 10 18:42:22 2002
@@ -4,7 +4,7 @@
 #  $Id: Makefile,v 1.8 2002/07/21 21:32:30 rmk Exp $
 #
 
-export-objs	:= core.o 8250.o
+export-objs	:= core.o 8250.o suncore.o
 
 serial-8250-y :=
 serial-8250-$(CONFIG_PCI) += 8250_pci.o
@@ -18,5 +18,9 @@
 obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
 obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
 obj-$(CONFIG_SERIAL_UART00) += uart00.o
+obj-$(CONFIG_SERIAL_SUNCORE) += suncore.o
+obj-$(CONFIG_SERIAL_SUNZILOG) += sunzilog.o
+obj-$(CONFIG_SERIAL_SUNSU) += sunsu.o
+obj-$(CONFIG_SERIAL_SUNSAB) += sunsab.o
 
 include $(TOPDIR)/Rules.make
diff -Nru a/drivers/serial/suncore.c b/drivers/serial/suncore.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/suncore.c	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,218 @@
+/* suncore.c
+ *
+ * Common SUN serial routines.  Based entirely
+ * upon drivers/sbus/char/sunserial.c which is:
+ *
+ * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
+ *
+ * Adaptation to new UART layer is:
+ *
+ * Copyright (C) 2002 David S. Miller (davem@redhat.com)
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/init.h>
+
+#include <asm/oplib.h>
+
+#include "suncore.h"
+
+int sunserial_current_minor = 64;
+
+EXPORT_SYMBOL(sunserial_current_minor);
+
+void
+sunserial_console_termios(struct console *con)
+{
+	char mode[16], buf[16], *s;
+	char *mode_prop = "ttyX-mode";
+	char *cd_prop = "ttyX-ignore-cd";
+	char *dtr_prop = "ttyX-rts-dtr-off";
+	int baud, bits, stop, cflag;
+	char parity;
+	int carrier = 0;
+	int rtsdtr = 1;
+	int topnd, nd;
+
+	if (!serial_console)
+		return;
+
+	if (serial_console == 1) {
+		mode_prop[3] = 'a';
+		cd_prop[3] = 'a';
+		dtr_prop[3] = 'a';
+	} else {
+		mode_prop[3] = 'b';
+		cd_prop[3] = 'b';
+		dtr_prop[3] = 'b';
+	}
+
+	topnd = prom_getchild(prom_root_node);
+	nd = prom_searchsiblings(topnd, "options");
+	if (!nd) {
+		strcpy(mode, "9600,8,n,1,-");
+		goto no_options;
+	}
+
+	if (!prom_node_has_property(nd, mode_prop)) {
+		strcpy(mode, "9600,8,n,1,-");
+		goto no_options;
+	}
+
+	memset(mode, 0, sizeof(mode));
+	prom_getstring(nd, mode_prop, mode, sizeof(mode));
+
+	if (prom_node_has_property(nd, cd_prop)) {
+		memset(buf, 0, sizeof(buf));
+		prom_getstring(nd, cd_prop, buf, sizeof(buf));
+		if (!strcmp(buf, "false"))
+			carrier = 1;
+
+		/* XXX: this is unused below. */
+	}
+
+	if (prom_node_has_property(nd, dtr_prop)) {
+		memset(buf, 0, sizeof(buf));
+		prom_getstring(nd, dtr_prop, buf, sizeof(buf));
+		if (!strcmp(buf, "false"))
+			rtsdtr = 0;
+
+		/* XXX: this is unused below. */
+	}
+
+no_options:
+	cflag = CREAD | HUPCL | CLOCAL;
+
+	s = mode;
+	baud = simple_strtoul(s, 0, 0);
+	s = strchr(s, ',');
+	bits = simple_strtoul(++s, 0, 0);
+	s = strchr(s, ',');
+	parity = *(++s);
+	s = strchr(s, ',');
+	stop = simple_strtoul(++s, 0, 0);
+	s = strchr(s, ',');
+	/* XXX handshake is not handled here. */
+
+	switch (baud) {
+		case 150: cflag |= B150; break;
+		case 300: cflag |= B300; break;
+		case 600: cflag |= B600; break;
+		case 1200: cflag |= B1200; break;
+		case 2400: cflag |= B2400; break;
+		case 4800: cflag |= B4800; break;
+		case 9600: cflag |= B9600; break;
+		case 19200: cflag |= B19200; break;
+		case 38400: cflag |= B38400; break;
+		default: baud = 9600; cflag |= B9600; break;
+	}
+
+	switch (bits) {
+		case 5: cflag |= CS5; break;
+		case 6: cflag |= CS6; break;
+		case 7: cflag |= CS7; break;
+		case 8: cflag |= CS8; break;
+		default: cflag |= CS8; break;
+	}
+
+	switch (parity) {
+		case 'o': cflag |= (PARENB | PARODD); break;
+		case 'e': cflag |= PARENB; break;
+		case 'n': default: break;
+	}
+
+	switch (stop) {
+		case 2: cflag |= CSTOPB; break;
+		case 1: default: break;
+	}
+
+	con->cflag = cflag;
+}
+
+EXPORT_SYMBOL(sunserial_console_termios);
+
+/* Sun serial MOUSE auto baud rate detection.  */
+static struct mouse_baud_cflag {
+	int baud;
+	unsigned int cflag;
+} mouse_baud_table[] = {
+	{ 1200, B1200 },
+	{ 2400, B2400 },
+	{ 4800, B4800 },
+	{ 9600, B9600 },
+	{ -1, ~0 },
+	{ -1, ~0 },
+};
+
+unsigned int suncore_mouse_baud_cflag_next(unsigned int cflag, int *new_baud)
+{
+	int i;
+
+	for (i = 0; mouse_baud_table[i].baud != -1; i++)
+		if (mouse_baud_table[i].cflag == (cflag & CBAUD))
+			break;
+
+	i += 1;
+	if (mouse_baud_table[i].baud == -1)
+		i = 0;
+
+	*new_baud = mouse_baud_table[i].baud;
+	return mouse_baud_table[i].cflag;
+}
+
+EXPORT_SYMBOL(suncore_mouse_baud_cflag_next);
+
+/* Basically, when the baud rate is wrong the mouse spits out
+ * breaks to us.
+ */
+int suncore_mouse_baud_detection(unsigned char ch, int is_break)
+{
+	static int mouse_got_break = 0;
+	static int ctr = 0;
+
+	if (is_break) {
+		/* Let a few normal bytes go by before we jump the gun
+		 * and say we need to try another baud rate.
+		 */
+		if (mouse_got_break && ctr < 8)
+			return 1;
+
+		/* Ok, we need to try another baud. */
+		ctr = 0;
+		mouse_got_break = 1;
+		return 2;
+	}
+	if (mouse_got_break) {
+		ctr++;
+		if (ch == 0x87) {
+			/* Correct baud rate determined. */
+			mouse_got_break = 0;
+		}
+		return 1;
+	}
+	return 0;
+}
+
+EXPORT_SYMBOL(suncore_mouse_baud_detection);
+
+static int __init suncore_init(void)
+{
+	return 0;
+}
+
+static void __exit suncore_exit(void)
+{
+}
+
+module_init(suncore_init);
+module_exit(suncore_exit);
+
+MODULE_AUTHOR("Eddie C. Dost, David S. Miller");
+MODULE_DESCRIPTION("Sun serial common layer");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/serial/suncore.h b/drivers/serial/suncore.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/suncore.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,29 @@
+/* suncore.h
+ *
+ * Generic SUN serial/kbd/ms layer.  Based entirely
+ * upon drivers/sbus/char/sunserial.h which is:
+ *
+ * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
+ *
+ * Port to new UART layer is:
+ *
+ * Copyright (C) 2002 David S. Miller (davem@redhat.com)
+ */
+
+#ifndef _SERIAL_SUN_H
+#define _SERIAL_SUN_H
+
+/* Serial keyboard defines for L1-A processing... */
+#define SUNKBD_RESET		0xff
+#define SUNKBD_L1		0x01
+#define SUNKBD_UP		0x80
+#define SUNKBD_A		0x4d
+
+extern unsigned int suncore_mouse_baud_cflag_next(unsigned int, int *);
+extern int suncore_mouse_baud_detection(unsigned char, int);
+
+extern int sunserial_current_minor;
+
+extern void sunserial_console_termios(struct console *);
+
+#endif /* !(_SERIAL_SUN_H) */
diff -Nru a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/sunsab.c	Sat Aug 10 18:42:22 2002
@@ -0,0 +1,1170 @@
+/* sunsab.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
+ *
+ * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
+ * Copyright (C) 2002  David S. Miller (davem@redhat.com)
+ *
+ * Rewrote buffer handling to use CIRC(Circular Buffer) macros.
+ *   Maxim Krasnyanskiy <maxk@qualcomm.com>
+ *
+ * Fixed to use tty_get_baud_rate, and to allow for arbitrary baud
+ * rates to be programmed into the UART.  Also eliminated a lot of
+ * duplicated code in the console setup.
+ *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
+ *
+ * Ported to new 2.5.x UART layer.
+ *   David S. Miller <davem@redhat.com>
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/oplib.h>
+#include <asm/ebus.h>
+
+#include <linux/serial_core.h>
+
+#include "suncore.h"
+#include "sunsab.h"
+
+struct uart_sunsab_port {
+	struct uart_port		port;		/* Generic UART port	*/
+	union sab82532_async_regs	*regs;		/* Chip registers	*/
+	unsigned long			irqflags;	/* IRQ state flags	*/
+	int				xmit_fifo_size; /* TX fifo size		*/
+	int				recv_fifo_size; /* RX fifo size		*/
+	int				dsr;		/* Current DSR state	*/
+	unsigned int			cec_timeout;	/* Chip poll timeout... */
+	unsigned int			tec_timeout;	/* likewise		*/
+	unsigned char			interrupt_mask0;/* ISR0 masking		*/
+	unsigned char			interrupt_mask1;/* ISR1 masking		*/
+	unsigned char			pvr_dtr_bit;	/* Which PVR bit is DTR */
+	unsigned char			pvr_dsr_bit;	/* Which PVR bit is DSR */
+	int				type;		/* SAB82532 version	*/
+	int				sab_line;	/* Internal numbering	*/
+	unsigned int irq;				/* Device interrupt	*/
+};
+
+/*
+ * This assumes you have a 29.4912 MHz clock for your UART.
+ */
+#define SAB_BASE_BAUD ( 29491200 / 16 )
+
+static char *sab82532_version[16] = {
+	"V1.0", "V2.0", "V3.2", "V(0x03)",
+	"V(0x04)", "V(0x05)", "V(0x06)", "V(0x07)",
+	"V(0x08)", "V(0x09)", "V(0x0a)", "V(0x0b)",
+	"V(0x0c)", "V(0x0d)", "V(0x0e)", "V(0x0f)"
+};
+
+#define SAB82532_MAX_TEC_TIMEOUT 200000	/* 1 character time (at 50 baud) */
+#define SAB82532_MAX_CEC_TIMEOUT  50000	/* 2.5 TX CLKs (at 50 baud) */
+
+static __inline__ void sunsab_tec_wait(struct uart_sunsab_port *up)
+{
+	int timeout = up->tec_timeout;
+
+	while ((readb(&up->regs->r.star) & SAB82532_STAR_TEC) && --timeout)
+		udelay(1);
+}
+
+static __inline__ void sunsab_cec_wait(struct uart_sunsab_port *up)
+{
+	int timeout = up->cec_timeout;
+
+	while ((readb(&up->regs->r.star) & SAB82532_STAR_CEC) && --timeout)
+		udelay(1);
+}
+
+static void receive_chars(struct uart_sunsab_port *up,
+			  union sab82532_irq_status *stat,
+			  struct pt_regs *regs)
+{
+	struct tty_struct *tty = up->port.info->tty;
+	unsigned char buf[32];
+	int saw_console_brk = 0;
+	int free_fifo = 0;
+	int count = 0;
+	int i;
+
+	/* Read number of BYTES (Character + Status) available. */
+	if (stat->sreg.isr0 & SAB82532_ISR0_RPF) {
+		count = up->recv_fifo_size;
+		free_fifo++;
+	}
+
+	if (stat->sreg.isr0 & SAB82532_ISR0_TCD) {
+		count = readb(&up->regs->r.rbcl) & (up->recv_fifo_size - 1);
+		free_fifo++;
+	}
+
+	/* Issue a FIFO read command in case we where idle. */
+	if (stat->sreg.isr0 & SAB82532_ISR0_TIME) {
+		sunsab_cec_wait(up);
+		writeb(SAB82532_CMDR_RFRD, &up->regs->w.cmdr);
+		return;
+	}
+
+	if (stat->sreg.isr0 & SAB82532_ISR0_RFO)
+		free_fifo++;
+
+	/* Read the FIFO. */
+	for (i = 0; i < count; i++)
+		buf[i] = readb(&up->regs->r.rfifo[i]);
+
+	/* Issue Receive Message Complete command. */
+	if (free_fifo) {
+		sunsab_cec_wait(up);
+		writeb(SAB82532_CMDR_RMC, &up->regs->w.cmdr);
+	}
+
+	for (i = 0; i < count; i++) {
+		unsigned char ch = buf[i];
+
+		if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
+			tty->flip.tqueue.routine((void *)tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+				return; // if TTY_DONT_FLIP is set
+		}
+
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		up->port.icount.rx++;
+
+		if (unlikely(stat->sreg.isr0 & (SAB82532_ISR0_PERR |
+						SAB82532_ISR0_FERR |
+						SAB82532_ISR0_RFO)) ||
+		    unlikely(stat->sreg.isr1 & SAB82532_ISR1_BRK)) {
+			/*
+			 * For statistics only
+			 */
+			if (stat->sreg.isr1 & SAB82532_ISR1_BRK) {
+				stat->sreg.isr0 &= ~(SAB82532_ISR0_PERR |
+						     SAB82532_ISR0_FERR);
+				up->port.icount.brk++;
+				if (up->port.line == up->port.cons->index)
+					saw_console_brk = 1;
+				/*
+				 * We do the SysRQ and SAK checking
+				 * here because otherwise the break
+				 * may get masked by ignore_status_mask
+				 * or read_status_mask.
+				 */
+				if (uart_handle_break(&up->port))
+					continue;
+			} else if (stat->sreg.isr0 & SAB82532_ISR0_PERR)
+				up->port.icount.parity++;
+			else if (stat->sreg.isr0 & SAB82532_ISR0_FERR)
+				up->port.icount.frame++;
+			if (stat->sreg.isr0 & SAB82532_ISR0_RFO)
+				up->port.icount.overrun++;
+
+			/*
+			 * Mask off conditions which should be ingored.
+			 */
+			stat->sreg.isr0 &= (up->port.read_status_mask & 0xff);
+			stat->sreg.isr1 &= ((up->port.read_status_mask >> 8) & 0xff);
+
+			if (stat->sreg.isr1 & SAB82532_ISR1_BRK) {
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			} else if (stat->sreg.isr0 & SAB82532_ISR0_PERR)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (stat->sreg.isr0 & SAB82532_ISR0_FERR)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+
+		if (uart_handle_sysrq_char(&up->port, ch, regs))
+			continue;
+
+		if ((stat->sreg.isr0 & (up->port.ignore_status_mask & 0xff)) == 0 &&
+		    (stat->sreg.isr1 & ((up->port.ignore_status_mask >> 8) & 0xff)) == 0){
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((stat->sreg.isr0 & SAB82532_ISR0_RFO) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character.
+			 */
+			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+	}
+
+	tty_flip_buffer_push(tty);
+
+	if (saw_console_brk)
+		sun_do_break();
+}
+
+static void sunsab_stop_tx(struct uart_port *, unsigned int);
+
+static void transmit_chars(struct uart_sunsab_port *up,
+			   union sab82532_irq_status *stat)
+{
+	struct circ_buf *xmit = &up->port.info->xmit;
+	int i;
+
+	if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) {
+		up->interrupt_mask1 |= SAB82532_IMR1_ALLS;
+		writeb(up->interrupt_mask1, &up->regs->w.imr1);
+		set_bit(SAB82532_ALLS, &up->irqflags);
+	}
+
+	if (!(stat->sreg.isr1 & SAB82532_ISR1_XPR))
+		return;
+
+	if (!(readb(&up->regs->r.star) & SAB82532_STAR_XFW))
+		return;
+
+	set_bit(SAB82532_XPR, &up->irqflags);
+
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
+		up->interrupt_mask1 |= SAB82532_IMR1_XPR;
+		writeb(up->interrupt_mask1, &up->regs->w.imr1);
+		return;
+	}
+
+	up->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS);
+	writeb(up->interrupt_mask1, &up->regs->w.imr1);
+	clear_bit(SAB82532_ALLS, &up->irqflags);
+
+	/* Stuff 32 bytes into Transmit FIFO. */
+	clear_bit(SAB82532_XPR, &up->irqflags);
+	for (i = 0; i < up->xmit_fifo_size; i++) {
+		writeb(xmit->buf[xmit->tail],
+		       &up->regs->w.xfifo[i]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		up->port.icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	}
+
+	/* Issue a Transmit Frame command. */
+	sunsab_cec_wait(up);
+	writeb(SAB82532_CMDR_XF, &up->regs->w.cmdr);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_event(&up->port, EVT_WRITE_WAKEUP);
+
+	if (uart_circ_empty(xmit))
+		sunsab_stop_tx(&up->port, 0);
+}
+
+static void check_status(struct uart_sunsab_port *up,
+			 union sab82532_irq_status *stat)
+{
+	if (stat->sreg.isr0 & SAB82532_ISR0_CDSC)
+		uart_handle_dcd_change(&up->port,
+				       !(readb(&up->regs->r.vstr) & SAB82532_VSTR_CD));
+
+	if (stat->sreg.isr1 & SAB82532_ISR1_CSC)
+		uart_handle_cts_change(&up->port,
+				       (readb(&up->regs->r.star) & SAB82532_STAR_CTS));
+
+	if ((readb(&up->regs->r.pvr) & up->pvr_dsr_bit) ^ up->dsr) {
+		up->dsr = (readb(&up->regs->r.pvr) & up->pvr_dsr_bit) ? 0 : 1;
+		up->port.icount.dsr++;
+	}
+
+	wake_up_interruptible(&up->port.info->delta_msr_wait);
+}
+
+static void sunsab_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_sunsab_port *up = dev_id;
+	union sab82532_irq_status status;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	status.stat = 0;
+	if (readb(&up->regs->r.gis) & SAB82532_GIS_ISA0)
+		status.sreg.isr0 = readb(&up->regs->r.isr0);
+	if (readb(&up->regs->r.gis) & SAB82532_GIS_ISA1)
+		status.sreg.isr1 = readb(&up->regs->r.isr1);
+
+	if (status.stat) {
+		if (status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
+					SAB82532_ISR0_RFO | SAB82532_ISR0_RPF))
+			receive_chars(up, &status, regs);
+		if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) ||
+		    (status.sreg.isr1 & SAB82532_ISR1_CSC))
+			check_status(up, &status);
+		if (status.sreg.isr1 & (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR))
+			transmit_chars(up, &status);
+	}
+
+	spin_unlock(&up->port.lock);
+
+	up++;
+
+	spin_lock(&up->port.lock);
+
+	status.stat = 0;
+	if (readb(&up->regs->r.gis) & SAB82532_GIS_ISB0)
+		status.sreg.isr0 = readb(&up->regs->r.isr0);
+	if (readb(&up->regs->r.gis) & SAB82532_GIS_ISB1)
+		status.sreg.isr1 = readb(&up->regs->r.isr1);
+
+	if (status.stat) {
+		if (status.sreg.isr0 & (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
+					SAB82532_ISR0_RFO | SAB82532_ISR0_RPF))
+			receive_chars(up, &status, regs);
+		if ((status.sreg.isr0 & SAB82532_ISR0_CDSC) ||
+		    (status.sreg.isr1 & (SAB82532_ISR1_BRK | SAB82532_ISR1_CSC)))
+			check_status(up, &status);
+		if (status.sreg.isr1 & (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR))
+			transmit_chars(up, &status);
+	}
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+/* port->lock is not held.  */
+static unsigned int sunsab_tx_empty(struct uart_port *port)
+{
+	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
+	int ret;
+
+	/* Do not need a lock for a state test like this.  */
+	if (test_bit(SAB82532_ALLS, &up->irqflags))
+		ret = TIOCSER_TEMT;
+	else
+		ret = 0;
+
+	return ret;
+}
+
+/* port->lock held by caller.  */
+static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
+
+	if (mctrl & TIOCM_RTS) {
+		writeb(readb(&up->regs->rw.mode) & ~SAB82532_MODE_FRTS,
+		       &up->regs->rw.mode);
+		writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS,
+		       &up->regs->rw.mode);
+	} else {
+		writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_FRTS,
+		       &up->regs->rw.mode);
+		writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS,
+		       &up->regs->rw.mode);
+	}
+	if (mctrl & TIOCM_DTR) {
+		writeb(readb(&up->regs->rw.pvr) & ~(up->pvr_dtr_bit), &up->regs->rw.pvr);
+	} else {
+		writeb(readb(&up->regs->rw.pvr) | up->pvr_dtr_bit, &up->regs->rw.pvr);
+	}
+}
+
+/* port->lock is not held.  */
+static unsigned int sunsab_get_mctrl(struct uart_port *port)
+{
+	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
+	unsigned long flags;
+	unsigned char val;
+	unsigned int result;
+
+	result = 0;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	val = readb(&up->regs->r.pvr);
+	result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR;
+
+	val = readb(&up->regs->r.vstr);
+	result |= (val & SAB82532_VSTR_CD) ? 0 : TIOCM_CAR;
+
+	val = readb(&up->regs->r.star);
+	result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0;
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	return result;
+}
+
+/* port->lock held by caller.  */
+static void sunsab_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
+
+	up->interrupt_mask1 |= SAB82532_IMR1_XPR;
+	writeb(up->interrupt_mask1, &up->regs->w.imr1);
+}
+
+/* port->lock held by caller.  */
+static void sunsab_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
+	struct circ_buf *xmit = &up->port.info->xmit;
+	int i;
+
+	if (!test_bit(SAB82532_XPR, &up->irqflags))
+		return;
+
+	up->interrupt_mask1 &= ~SAB82532_IMR1_XPR;
+	writeb(up->interrupt_mask1, &up->regs->w.imr1);
+	clear_bit(SAB82532_ALLS, &up->irqflags);
+	clear_bit(SAB82532_XPR, &up->irqflags);
+
+	for (i = 0; i < up->xmit_fifo_size; i++) {
+		writeb(xmit->buf[xmit->tail],
+		       &up->regs->w.xfifo[i]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		up->port.icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	}
+
+	/* Issue a Transmit Frame command.  */
+	sunsab_cec_wait(up);
+	writeb(SAB82532_CMDR_XF, &up->regs->w.cmdr);
+}
+
+/* port->lock is not held.  */
+static void sunsab_send_xchar(struct uart_port *port, char ch)
+{
+	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	sunsab_tec_wait(up);
+	writeb(ch, &up->regs->w.tic);
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+/* port->lock held by caller.  */
+static void sunsab_stop_rx(struct uart_port *port)
+{
+	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
+
+	up->interrupt_mask0 |= SAB82532_ISR0_TCD;
+	writeb(up->interrupt_mask1, &up->regs->w.imr0);
+}
+
+/* port->lock held by caller.  */
+static void sunsab_enable_ms(struct uart_port *port)
+{
+	/* For now we always receive these interrupts.  */
+}
+
+/* port->lock is not held.  */
+static void sunsab_break_ctl(struct uart_port *port, int break_state)
+{
+	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
+	unsigned long flags;
+	unsigned char val;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	val = readb(&up->regs->rw.dafo);
+	if (break_state)
+		val |= SAB82532_DAFO_XBRK;
+	else
+		val &= ~SAB82532_DAFO_XBRK;
+	writeb(val, &up->regs->rw.dafo);
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+/* port->lock is not held.  */
+static int sunsab_startup(struct uart_port *port)
+{
+	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
+	unsigned long flags;
+	unsigned char tmp;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	/*
+	 * Wait for any commands or immediate characters
+	 */
+	sunsab_cec_wait(up);
+	sunsab_tec_wait(up);
+
+	/*
+	 * Clear the FIFO buffers.
+	 */
+	writeb(SAB82532_CMDR_RRES, &up->regs->w.cmdr);
+	sunsab_cec_wait(up);
+	writeb(SAB82532_CMDR_XRES, &up->regs->w.cmdr);
+
+	/*
+	 * Clear the interrupt registers.
+	 */
+	(void) readb(&up->regs->r.isr0);
+	(void) readb(&up->regs->r.isr1);
+
+	/*
+	 * Now, initialize the UART 
+	 */
+	writeb(0, &up->regs->w.ccr0);				/* power-down */
+	writeb(SAB82532_CCR0_MCE | SAB82532_CCR0_SC_NRZ |
+	       SAB82532_CCR0_SM_ASYNC, &up->regs->w.ccr0);
+	writeb(SAB82532_CCR1_ODS | SAB82532_CCR1_BCR | 7, &up->regs->w.ccr1);
+	writeb(SAB82532_CCR2_BDF | SAB82532_CCR2_SSEL |
+	       SAB82532_CCR2_TOE, &up->regs->w.ccr2);
+	writeb(0, &up->regs->w.ccr3);
+	writeb(SAB82532_CCR4_MCK4 | SAB82532_CCR4_EBRG, &up->regs->w.ccr4);
+	writeb(SAB82532_MODE_RTS | SAB82532_MODE_FCTS |
+	       SAB82532_MODE_RAC, &up->regs->w.mode);
+	writeb(SAB82532_RFC_DPS | SAB82532_RFC_RFDF, &up->regs->w.rfc);
+
+	switch (up->recv_fifo_size) {
+		case 1:
+			tmp = readb(&up->regs->w.rfc);
+			tmp |= SAB82532_RFC_RFTH_1;
+			writeb(tmp, &up->regs->w.rfc);
+			break;
+		case 4:
+			tmp = readb(&up->regs->w.rfc);
+			tmp |= SAB82532_RFC_RFTH_4;
+			writeb(tmp, &up->regs->w.rfc);
+			break;
+		case 16:
+			tmp = readb(&up->regs->w.rfc);
+			tmp |= SAB82532_RFC_RFTH_16;
+			writeb(tmp, &up->regs->w.rfc);
+			break;
+		default:
+			up->recv_fifo_size = 32;
+			/* fall through */
+		case 32:
+			tmp = readb(&up->regs->w.rfc);
+			tmp |= SAB82532_RFC_RFTH_32;
+			writeb(tmp, &up->regs->w.rfc);
+			break;
+	};
+
+	tmp = readb(&up->regs->rw.ccr0);
+	tmp |= SAB82532_CCR0_PU;	/* power-up */
+	writeb(tmp, &up->regs->rw.ccr0);
+
+	/*
+	 * Finally, enable interrupts
+	 */
+	up->interrupt_mask0 = (SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
+			       SAB82532_IMR0_PLLA);
+	writeb(up->interrupt_mask0, &up->regs->w.imr0);
+	up->interrupt_mask1 = (SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |
+			       SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |
+			       SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
+			       SAB82532_IMR1_XPR);
+	writeb(up->interrupt_mask1, &up->regs->w.imr1);
+	set_bit(SAB82532_ALLS, &up->irqflags);
+	set_bit(SAB82532_XPR, &up->irqflags);
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	return 0;
+}
+
+/* port->lock is not held.  */
+static void sunsab_shutdown(struct uart_port *port)
+{
+	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
+	unsigned long flags;
+	unsigned char tmp;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	/* Disable Interrupts */
+	up->interrupt_mask0 = 0xff;
+	writeb(up->interrupt_mask0, &up->regs->w.imr0);
+	up->interrupt_mask1 = 0xff;
+	writeb(up->interrupt_mask1, &up->regs->w.imr1);
+
+	/* Disable break condition */
+	tmp = readb(&up->regs->rw.dafo);
+	tmp &= ~SAB82532_DAFO_XBRK;
+	writeb(tmp, &up->regs->rw.dafo);
+
+	/* Disable Receiver */	
+	tmp = readb(&up->regs->rw.mode);
+	tmp &= ~SAB82532_MODE_RAC;
+	writeb(tmp, &up->regs->rw.mode);
+
+	/* Power Down */	
+	tmp = readb(&up->regs->rw.ccr0);
+	tmp &= ~SAB82532_CCR0_PU;
+	writeb(tmp, &up->regs->rw.ccr0);
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+/*
+ * This is used to figure out the divisor speeds.
+ *
+ * The formula is:    Baud = SAB_BASE_BAUD / ((N + 1) * (1 << M)),
+ *
+ * with               0 <= N < 64 and 0 <= M < 16
+ */
+
+static void calc_ebrg(int baud, int *n_ret, int *m_ret)
+{
+	int	n, m;
+
+	if (baud == 0) {
+		*n_ret = 0;
+		*m_ret = 0;
+		return;
+	}
+     
+	/*
+	 * We scale numbers by 10 so that we get better accuracy
+	 * without having to use floating point.  Here we increment m
+	 * until n is within the valid range.
+	 */
+	n = (SAB_BASE_BAUD * 10) / baud;
+	m = 0;
+	while (n >= 640) {
+		n = n / 2;
+		m++;
+	}
+	n = (n+5) / 10;
+	/*
+	 * We try very hard to avoid speeds with M == 0 since they may
+	 * not work correctly for XTAL frequences above 10 MHz.
+	 */
+	if ((m == 0) && ((n & 1) == 0)) {
+		n = n / 2;
+		m++;
+	}
+	*n_ret = n - 1;
+	*m_ret = m;
+}
+
+/* Internal routine, port->lock is held and local interrupts are disabled.  */
+static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cflag,
+				  unsigned int iflag, int baud)
+{
+	unsigned int ebrg;
+	unsigned char dafo;
+	int bits, n, m;
+
+	/* Byte size and parity */
+	switch (cflag & CSIZE) {
+	      case CS5: dafo = SAB82532_DAFO_CHL5; bits = 7; break;
+	      case CS6: dafo = SAB82532_DAFO_CHL6; bits = 8; break;
+	      case CS7: dafo = SAB82532_DAFO_CHL7; bits = 9; break;
+	      case CS8: dafo = SAB82532_DAFO_CHL8; bits = 10; break;
+	      /* Never happens, but GCC is too dumb to figure it out */
+	      default:  dafo = SAB82532_DAFO_CHL5; bits = 7; break;
+	}
+
+	if (cflag & CSTOPB) {
+		dafo |= SAB82532_DAFO_STOP;
+		bits++;
+	}
+
+	if (cflag & PARENB) {
+		dafo |= SAB82532_DAFO_PARE;
+		bits++;
+	}
+
+	if (cflag & PARODD) {
+		dafo |= SAB82532_DAFO_PAR_ODD;
+	} else {
+		dafo |= SAB82532_DAFO_PAR_EVEN;
+	}
+
+	calc_ebrg(baud, &n, &m);
+
+	ebrg = n | (m << 6);
+
+	up->tec_timeout = (10 * 1000000) / baud;
+	up->cec_timeout = up->tec_timeout >> 2;
+
+	/* CTS flow control flags */
+	/* We encode read_status_mask and ignore_status_mask like so:
+	 *
+	 * ---------------------
+	 * | ... | ISR1 | ISR0 |
+	 * ---------------------
+	 *  ..    15   8 7    0
+	 */
+
+	up->port.read_status_mask = (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
+				     SAB82532_ISR0_RFO | SAB82532_ISR0_RPF |
+				     SAB82532_ISR0_CDSC);
+	up->port.read_status_mask |= (SAB82532_ISR1_CSC |
+				      SAB82532_ISR1_ALLS |
+				      SAB82532_ISR1_XPR) << 8;
+	if (iflag & INPCK)
+		up->port.read_status_mask |= (SAB82532_ISR0_PERR |
+					      SAB82532_ISR0_FERR);
+	if (iflag & (BRKINT | PARMRK))
+		up->port.read_status_mask |= (SAB82532_ISR1_BRK << 8);
+
+	/*
+	 * Characteres to ignore
+	 */
+	up->port.ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		up->port.ignore_status_mask |= (SAB82532_ISR0_PERR |
+						SAB82532_ISR0_FERR);
+	if (iflag & IGNBRK) {
+		up->port.ignore_status_mask |= (SAB82532_ISR1_BRK << 8);
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			up->port.ignore_status_mask |= SAB82532_ISR0_RFO;
+	}
+
+	/*
+	 * ignore all characters if CREAD is not set
+	 */
+	if ((cflag & CREAD) == 0)
+		up->port.ignore_status_mask |= (SAB82532_ISR0_RPF |
+						SAB82532_ISR0_TCD);
+
+	/* Now bang the new settings into the chip.  */
+	sunsab_cec_wait(up);
+	sunsab_tec_wait(up);
+	writeb(dafo, &up->regs->w.dafo);
+	writeb(ebrg & 0xff, &up->regs->w.bgr);
+	writeb((readb(&up->regs->rw.ccr2) & ~0xc0) | ((ebrg >> 2) & 0xc0),
+	       &up->regs->rw.ccr2);
+
+	if (cflag & CRTSCTS) {
+		writeb(readb(&up->regs->rw.mode) & ~SAB82532_MODE_RTS,
+		       &up->regs->rw.mode);
+		writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_FRTS,
+		       &up->regs->rw.mode);
+		writeb(readb(&up->regs->rw.mode) & ~SAB82532_MODE_FCTS,
+		       &up->regs->rw.mode);
+		up->interrupt_mask1 &= ~SAB82532_IMR1_CSC;
+		writeb(up->interrupt_mask1, &up->regs->w.imr1);
+	} else {
+		writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS,
+		       &up->regs->rw.mode);
+		writeb(readb(&up->regs->rw.mode) & ~SAB82532_MODE_FRTS,
+		       &up->regs->rw.mode);
+		writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_FCTS,
+		       &up->regs->rw.mode);
+		up->interrupt_mask1 |= SAB82532_IMR1_CSC;
+		writeb(up->interrupt_mask1, &up->regs->w.imr1);
+	}
+	writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RAC, &up->regs->rw.mode);
+
+}
+
+/* port->lock is not held.  */
+static void sunsab_change_speed(struct uart_port *port, unsigned int cflag,
+				unsigned int iflag, unsigned int quot)
+{
+	struct uart_sunsab_port *up = (struct uart_sunsab_port *) port;
+	unsigned long flags;
+	int baud;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	/* Undo what generic UART core did.  */
+	baud = (SAB_BASE_BAUD / (quot * 16));
+
+	sunsab_convert_to_sab(up, cflag, iflag, baud);
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static const char *sunsab_type(struct uart_port *port)
+{
+	return "SunSAB";
+}
+
+static void sunsab_release_port(struct uart_port *port)
+{
+}
+
+static int sunsab_request_port(struct uart_port *port)
+{
+	return 0;
+}
+
+static void sunsab_config_port(struct uart_port *port, int flags)
+{
+}
+
+static int sunsab_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	return -EINVAL;
+}
+
+static struct uart_ops sunsab_pops = {
+	.tx_empty	= sunsab_tx_empty,
+	.set_mctrl	= sunsab_set_mctrl,
+	.get_mctrl	= sunsab_get_mctrl,
+	.stop_tx	= sunsab_stop_tx,
+	.start_tx	= sunsab_start_tx,
+	.send_xchar	= sunsab_send_xchar,
+	.stop_rx	= sunsab_stop_rx,
+	.enable_ms	= sunsab_enable_ms,
+	.break_ctl	= sunsab_break_ctl,
+	.startup	= sunsab_startup,
+	.shutdown	= sunsab_shutdown,
+	.change_speed	= sunsab_change_speed,
+	.type		= sunsab_type,
+	.release_port	= sunsab_release_port,
+	.request_port	= sunsab_request_port,
+	.config_port	= sunsab_config_port,
+	.verify_port	= sunsab_verify_port,
+};
+
+static struct uart_driver sunsab_reg = {
+	.owner			= THIS_MODULE,
+	.driver_name		= "serial",
+#ifdef CONFIG_DEVFS_FS
+	.dev_name		= "tts/%d",
+#else
+	.dev_name		= "ttyS",
+#endif
+	.major			= TTY_MAJOR,
+};
+
+static struct uart_sunsab_port *sunsab_ports;
+static int num_channels;
+
+static __inline__ void sunsab_console_putchar(struct uart_sunsab_port *up, char c)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	sunsab_tec_wait(up);
+	writeb(c, &up->regs->w.tic);
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static void sunsab_console_write(struct console *con, const char *s, unsigned n)
+{
+	struct uart_sunsab_port *up = &sunsab_ports[con->index];
+	int i;
+
+	for (i = 0; i < n; i++) {
+		if (*s == '\n')
+			sunsab_console_putchar(up, '\r');
+		sunsab_console_putchar(up, *s++);
+	}
+	sunsab_tec_wait(up);
+}
+
+static kdev_t sunsab_console_device(struct console *con)
+{
+	return mk_kdev(sunsab_reg.major, sunsab_reg.minor + con->index);
+}
+
+static int sunsab_console_setup(struct console *con, char *options)
+{
+	struct uart_sunsab_port *up = &sunsab_ports[con->index];
+	unsigned long flags;
+	int baud;
+
+	printk("Console: ttyS%d (SAB82532)\n",
+	       (sunsab_reg.minor - 64) + con->index);
+
+	sunserial_console_termios(con);
+
+	/* Firmware console speed is limited to 150-->38400 baud so
+	 * this hackish cflag thing is OK.
+	 */
+	switch (con->cflag & CBAUD) {
+	case B150: baud = 150; break;
+	case B300: baud = 300; break;
+	case B600: baud = 600; break;
+	case B1200: baud = 1200; break;
+	case B2400: baud = 2400; break;
+	case B4800: baud = 4800; break;
+	default: case B9600: baud = 9600; break;
+	case B19200: baud = 19200; break;
+	case B38400: baud = 38400; break;
+	};
+
+	/*
+	 * Temporary fix.
+	 */
+	spin_lock_init(&up->port.lock);
+
+	/*
+	 * Initialize the hardware
+	 */
+	sunsab_startup(&up->port);
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	/*
+	 * Finally, enable interrupts
+	 */
+	up->interrupt_mask0 = SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
+				SAB82532_IMR0_PLLA | SAB82532_IMR0_CDSC;
+	writeb(up->interrupt_mask0, &up->regs->w.imr0);
+	up->interrupt_mask1 = SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |
+				SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |
+				SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
+				SAB82532_IMR1_XPR;
+	writeb(up->interrupt_mask1, &up->regs->w.imr1);
+
+	sunsab_convert_to_sab(up, con->cflag, 0, baud);
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+	
+	return 0;
+}
+
+static struct console sunsab_console = {
+	.name	=	"ttyS",
+	.write	=	sunsab_console_write,
+	.device	=	sunsab_console_device,
+	.setup	=	sunsab_console_setup,
+	.flags	=	CON_PRINTBUFFER,
+	.index	=	-1,
+};
+
+static void __init sunsab_console_init(void)
+{
+	int i;
+
+	if (con_is_present())
+		return;
+
+	for (i = 0; i < num_channels; i++) {
+		int this_minor = sunsab_reg.minor + i;
+
+		if ((this_minor - 64) == (serial_console - 1))
+			break;
+	}
+	if (i == num_channels)
+		return;
+
+	sunsab_console.index = i;
+	register_console(&sunsab_console);
+}
+
+static void __init for_each_sab_edev(void (*callback)(struct linux_ebus_device *, void *), void *arg)
+{
+	struct linux_ebus *ebus;
+	struct linux_ebus_device *edev = NULL;
+
+	for_each_ebus(ebus) {
+		for_each_ebusdev(edev, ebus) {
+			if (!strcmp(edev->prom_name, "se")) {
+				callback(edev, arg);
+				continue;
+			} else if (!strcmp(edev->prom_name, "serial")) {
+				char compat[32];
+				int clen;
+
+				/* On RIO this can be an SE, check it.  We could
+				 * just check ebus->is_rio, but this is more portable.
+				 */
+				clen = prom_getproperty(edev->prom_node, "compatible",
+							compat, sizeof(compat));
+				if (clen > 0) {
+					if (strncmp(compat, "sab82532", 8) == 0) {
+						callback(edev, arg);
+						continue;
+					}
+				}
+			}
+		}
+	}
+}
+
+static void __init sab_count_callback(struct linux_ebus_device *edev, void *arg)
+{
+	int *count_p = arg;
+
+	(*count_p)++;
+}
+
+static void __init sab_attach_callback(struct linux_ebus_device *edev, void *arg)
+{
+	int *instance_p = arg;
+	struct uart_sunsab_port *up;
+	unsigned long regs, offset;
+	int i;
+
+	regs = edev->resource[0].start;
+	offset = sizeof(union sab82532_async_regs);
+	for (i = 0; i < 2; i++) {
+		up = &sunsab_ports[(*instance_p * 2) + i];
+
+		memset(up, 0, sizeof(*up));
+		up->regs = ioremap(regs + offset, sizeof(union sab82532_async_regs));
+		up->irq = edev->irqs[0];
+		up->sab_line = 1 - i;
+		up->xmit_fifo_size = 32;
+		up->recv_fifo_size = 32;
+
+		writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc);
+
+		offset -= sizeof(union sab82532_async_regs);
+	}
+}
+
+static int __init probe_for_sabs(void)
+{
+	int this_sab = 0;
+
+	/* Find device instances.  */
+	for_each_sab_edev(&sab_count_callback, &this_sab);
+	if (!this_sab)
+		return -ENODEV;
+
+	/* Allocate tables.  */
+	sunsab_ports = kmalloc(sizeof(struct uart_sunsab_port) * this_sab * 2,
+			       GFP_KERNEL);
+	if (!sunsab_ports)
+		return -ENOMEM;
+
+	num_channels = this_sab * 2;
+
+	this_sab = 0;
+	for_each_sab_edev(&sab_attach_callback, &this_sab);
+	return 0;
+}
+
+static void __init sunsab_init_hw(void)
+{
+	int i;
+
+	for (i = 0; i < num_channels; i++) {
+		struct uart_sunsab_port *up = &sunsab_ports[i];
+
+		up->port.line = i;
+		up->port.ops = &sunsab_pops;
+		up->port.type = PORT_SUNSAB;
+		up->port.uartclk = SAB_BASE_BAUD;
+
+		up->type = readb(&up->regs->r.vstr) & 0x0f;
+		writeb(~((1 << 1) | (1 << 2) | (1 << 4)), &up->regs->w.pcr);
+		writeb(0xff, &up->regs->w.pim);
+		if (up->sab_line == 0) {
+			up->pvr_dsr_bit = (1 << 0);
+			up->pvr_dtr_bit = (1 << 1);
+		} else {
+			up->pvr_dsr_bit = (1 << 3);
+			up->pvr_dtr_bit = (1 << 2);
+		}
+		writeb((1 << 1) | (1 << 2) | (1 << 4), &up->regs->w.pvr);
+		writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_FRTS,
+		       &up->regs->rw.mode);
+		writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS,
+		       &up->regs->rw.mode);
+
+		up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT;
+		up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT;
+
+		if (!(up->sab_line & 0x01)) {
+			if (request_irq(up->irq, sunsab_interrupt, SA_SHIRQ,
+					"serial(sab82532)", up)) {
+				printk("sunsab%d: can't get IRQ %x\n",
+				       i, up->irq);
+				continue;
+			}
+		}
+	
+		printk(KERN_INFO
+		       "sunsab%d at 0x%lx (irq = %s) is a SAB82532 %s\n",
+		       i, (unsigned long)up->regs,
+		       __irq_itoa(up->irq), sab82532_version[up->type]);
+	}
+}
+
+static int __init sunsab_init(void)
+{
+	int ret = probe_for_sabs();
+	int i;
+
+	if (ret < 0)
+		return ret;
+
+	sunsab_init_hw();
+
+	sunsab_reg.minor = sunserial_current_minor;
+	sunserial_current_minor += num_channels;
+
+	sunsab_reg.nr = num_channels;
+	sunsab_reg.cons = &sunsab_console;
+
+	ret = uart_register_driver(&sunsab_reg);
+	if (ret < 0) {
+		int i;
+
+		for (i = 0; i < num_channels; i++) {
+			struct uart_sunsab_port *up = &sunsab_ports[i];
+
+			if (!(up->sab_line & 0x01))
+				free_irq(up->irq, up);
+			iounmap(up->regs);
+		}
+		kfree(sunsab_ports);
+		sunsab_ports = NULL;
+
+		return ret;
+	}
+
+	for (i = 0; i < num_channels; i++) {
+		struct uart_sunsab_port *up = &sunsab_ports[i];
+
+		uart_add_one_port(&sunsab_reg, &up->port);
+	}
+
+	sunsab_console_init();
+
+	return 0;
+}
+
+static void __exit sunsab_exit(void)
+{
+	int i;
+
+	for (i = 0; i < num_channels; i++) {
+		struct uart_sunsab_port *up = &sunsab_ports[i];
+
+		uart_remove_one_port(&sunsab_reg, &up->port);
+
+		if (!(up->sab_line & 0x01))
+			free_irq(up->irq, up);
+		iounmap(up->regs);
+	}
+
+	uart_unregister_driver(&sunsab_reg);
+
+	kfree(sunsab_ports);
+	sunsab_ports = NULL;
+}
+
+module_init(sunsab_init);
+module_exit(sunsab_exit);
+
+MODULE_AUTHOR("Eddie C. Dost and David S. Miller");
+MODULE_DESCRIPTION("Sun SAB82532 serial port driver");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/serial/sunsab.h b/drivers/serial/sunsab.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/sunsab.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,321 @@
+/* sunsab.h: Register Definitions for the Siemens SAB82532 DUSCC
+ *
+ * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
+ */
+
+#ifndef _SUNSAB_H
+#define _SUNSAB_H
+
+struct sab82532_async_rd_regs {
+	u8	rfifo[0x20];	/* Receive FIFO				*/
+	u8	star;		/* Status Register			*/
+	u8	__pad1;
+	u8	mode;		/* Mode Register			*/
+	u8	timr;		/* Timer Register			*/
+	u8	xon;		/* XON Character			*/
+	u8	xoff;		/* XOFF Character			*/
+	u8	tcr;		/* Termination Character Register	*/
+	u8	dafo;		/* Data Format				*/
+	u8	rfc;		/* RFIFO Control Register		*/
+	u8	__pad2;
+	u8	rbcl;		/* Receive Byte Count Low		*/
+	u8	rbch;		/* Receive Byte Count High		*/
+	u8	ccr0;		/* Channel Configuration Register 0	*/
+	u8	ccr1;		/* Channel Configuration Register 1	*/
+	u8	ccr2;		/* Channel Configuration Register 2	*/
+	u8	ccr3;		/* Channel Configuration Register 3	*/
+	u8	__pad3[4];
+	u8	vstr;		/* Version Status Register		*/
+	u8	__pad4[3];
+	u8	gis;		/* Global Interrupt Status		*/
+	u8	ipc;		/* Interrupt Port Configuration		*/
+	u8	isr0;		/* Interrupt Status 0			*/
+	u8	isr1;		/* Interrupt Status 1			*/
+	u8	pvr;		/* Port Value Register			*/
+	u8	pis;		/* Port Interrupt Status		*/
+	u8	pcr;		/* Port Configuration Register		*/
+	u8	ccr4;		/* Channel Configuration Register 4	*/
+};
+
+struct sab82532_async_wr_regs {
+	u8	xfifo[0x20];	/* Transmit FIFO			*/
+	u8	cmdr;		/* Command Register			*/
+	u8	__pad1;
+	u8	mode;
+	u8	timr;
+	u8	xon;
+	u8	xoff;
+	u8	tcr;
+	u8	dafo;
+	u8	rfc;
+	u8	__pad2;
+	u8	xbcl;		/* Transmit Byte Count Low		*/
+	u8	xbch;		/* Transmit Byte Count High		*/
+	u8	ccr0;
+	u8	ccr1;
+	u8	ccr2;
+	u8	ccr3;
+	u8	tsax;		/* Time-Slot Assignment Reg. Transmit	*/
+	u8	tsar;		/* Time-Slot Assignment Reg. Receive	*/
+	u8	xccr;		/* Transmit Channel Capacity Register	*/
+	u8	rccr;		/* Receive Channel Capacity Register	*/
+	u8	bgr;		/* Baud Rate Generator Register		*/
+	u8	tic;		/* Transmit Immediate Character		*/
+	u8	mxn;		/* Mask XON Character			*/
+	u8	mxf;		/* Mask XOFF Character			*/
+	u8	iva;		/* Interrupt Vector Address		*/
+	u8	ipc;
+	u8	imr0;		/* Interrupt Mask Register 0		*/
+	u8	imr1;		/* Interrupt Mask Register 1		*/
+	u8	pvr;
+	u8	pim;		/* Port Interrupt Mask			*/
+	u8	pcr;
+	u8	ccr4;
+};
+
+struct sab82532_async_rw_regs {	/* Read/Write registers			*/
+	u8	__pad1[0x20];
+	u8	__pad2;
+	u8	__pad3;
+	u8	mode;
+	u8	timr;
+	u8	xon;
+	u8	xoff;
+	u8	tcr;
+	u8	dafo;
+	u8	rfc;
+	u8	__pad4;
+	u8	__pad5;
+	u8	__pad6;
+	u8	ccr0;
+	u8	ccr1;
+	u8	ccr2;
+	u8	ccr3;
+	u8	__pad7;
+	u8	__pad8;
+	u8	__pad9;
+	u8	__pad10;
+	u8	__pad11;
+	u8	__pad12;
+	u8	__pad13;
+	u8	__pad14;
+	u8	__pad15;
+	u8	ipc;
+	u8	__pad16;
+	u8	__pad17;
+	u8	pvr;
+	u8	__pad18;
+	u8	pcr;
+	u8	ccr4;
+};
+
+union sab82532_async_regs {
+	__volatile__ struct sab82532_async_rd_regs	r;
+	__volatile__ struct sab82532_async_wr_regs	w;
+	__volatile__ struct sab82532_async_rw_regs	rw;
+};
+
+union sab82532_irq_status {
+	unsigned short			 stat;
+	struct {
+		unsigned char		 isr0;
+		unsigned char		 isr1;
+	} sreg;
+};
+
+/* irqflags bits */
+#define SAB82532_ALLS			0x00000001
+#define SAB82532_XPR			0x00000002
+
+/* RFIFO Status Byte */
+#define SAB82532_RSTAT_PE		0x80
+#define SAB82532_RSTAT_FE		0x40
+#define SAB82532_RSTAT_PARITY		0x01
+
+/* Status Register (STAR) */
+#define SAB82532_STAR_XDOV		0x80
+#define SAB82532_STAR_XFW		0x40
+#define SAB82532_STAR_RFNE		0x20
+#define SAB82532_STAR_FCS		0x10
+#define SAB82532_STAR_TEC		0x08
+#define SAB82532_STAR_CEC		0x04
+#define SAB82532_STAR_CTS		0x02
+
+/* Command Register (CMDR) */
+#define SAB82532_CMDR_RMC		0x80
+#define SAB82532_CMDR_RRES		0x40
+#define SAB82532_CMDR_RFRD		0x20
+#define SAB82532_CMDR_STI		0x10
+#define SAB82532_CMDR_XF		0x08
+#define SAB82532_CMDR_XRES		0x01
+
+/* Mode Register (MODE) */
+#define SAB82532_MODE_FRTS		0x40
+#define SAB82532_MODE_FCTS		0x20
+#define SAB82532_MODE_FLON		0x10
+#define SAB82532_MODE_RAC		0x08
+#define SAB82532_MODE_RTS		0x04
+#define SAB82532_MODE_TRS		0x02
+#define SAB82532_MODE_TLP		0x01
+
+/* Timer Register (TIMR) */
+#define SAB82532_TIMR_CNT_MASK		0xe0
+#define SAB82532_TIMR_VALUE_MASK	0x1f
+
+/* Data Format (DAFO) */
+#define SAB82532_DAFO_XBRK		0x40
+#define SAB82532_DAFO_STOP		0x20
+#define SAB82532_DAFO_PAR_SPACE		0x00
+#define SAB82532_DAFO_PAR_ODD		0x08
+#define SAB82532_DAFO_PAR_EVEN		0x10
+#define SAB82532_DAFO_PAR_MARK		0x18
+#define SAB82532_DAFO_PARE		0x04
+#define SAB82532_DAFO_CHL8		0x00
+#define SAB82532_DAFO_CHL7		0x01
+#define SAB82532_DAFO_CHL6		0x02
+#define SAB82532_DAFO_CHL5		0x03
+
+/* RFIFO Control Register (RFC) */
+#define SAB82532_RFC_DPS		0x40
+#define SAB82532_RFC_DXS		0x20
+#define SAB82532_RFC_RFDF		0x10
+#define SAB82532_RFC_RFTH_1		0x00
+#define SAB82532_RFC_RFTH_4		0x04
+#define SAB82532_RFC_RFTH_16		0x08
+#define SAB82532_RFC_RFTH_32		0x0c
+#define SAB82532_RFC_TCDE		0x01
+
+/* Received Byte Count High (RBCH) */
+#define SAB82532_RBCH_DMA		0x80
+#define SAB82532_RBCH_CAS		0x20
+
+/* Transmit Byte Count High (XBCH) */
+#define SAB82532_XBCH_DMA		0x80
+#define SAB82532_XBCH_CAS		0x20
+#define SAB82532_XBCH_XC		0x10
+
+/* Channel Configuration Register 0 (CCR0) */
+#define SAB82532_CCR0_PU		0x80
+#define SAB82532_CCR0_MCE		0x40
+#define SAB82532_CCR0_SC_NRZ		0x00
+#define SAB82532_CCR0_SC_NRZI		0x08
+#define SAB82532_CCR0_SC_FM0		0x10
+#define SAB82532_CCR0_SC_FM1		0x14
+#define SAB82532_CCR0_SC_MANCH		0x18
+#define SAB82532_CCR0_SM_HDLC		0x00
+#define SAB82532_CCR0_SM_SDLC_LOOP	0x01
+#define SAB82532_CCR0_SM_BISYNC		0x02
+#define SAB82532_CCR0_SM_ASYNC		0x03
+
+/* Channel Configuration Register 1 (CCR1) */
+#define SAB82532_CCR1_ODS		0x10
+#define SAB82532_CCR1_BCR		0x08
+#define SAB82532_CCR1_CM_MASK		0x07
+
+/* Channel Configuration Register 2 (CCR2) */
+#define SAB82532_CCR2_SOC1		0x80
+#define SAB82532_CCR2_SOC0		0x40
+#define SAB82532_CCR2_BR9		0x80
+#define SAB82532_CCR2_BR8		0x40
+#define SAB82532_CCR2_BDF		0x20
+#define SAB82532_CCR2_SSEL		0x10
+#define SAB82532_CCR2_XCS0		0x20
+#define SAB82532_CCR2_RCS0		0x10
+#define SAB82532_CCR2_TOE		0x08
+#define SAB82532_CCR2_RWX		0x04
+#define SAB82532_CCR2_DIV		0x01
+
+/* Channel Configuration Register 3 (CCR3) */
+#define SAB82532_CCR3_PSD		0x01
+
+/* Time Slot Assignment Register Transmit (TSAX) */
+#define SAB82532_TSAX_TSNX_MASK		0xfc
+#define SAB82532_TSAX_XCS2		0x02	/* see also CCR2 */
+#define SAB82532_TSAX_XCS1		0x01
+
+/* Time Slot Assignment Register Receive (TSAR) */
+#define SAB82532_TSAR_TSNR_MASK		0xfc
+#define SAB82532_TSAR_RCS2		0x02	/* see also CCR2 */
+#define SAB82532_TSAR_RCS1		0x01
+
+/* Version Status Register (VSTR) */
+#define SAB82532_VSTR_CD		0x80
+#define SAB82532_VSTR_DPLA		0x40
+#define SAB82532_VSTR_VN_MASK		0x0f
+#define SAB82532_VSTR_VN_1		0x00
+#define SAB82532_VSTR_VN_2		0x01
+#define SAB82532_VSTR_VN_3_2		0x02
+
+/* Global Interrupt Status Register (GIS) */
+#define SAB82532_GIS_PI			0x80
+#define SAB82532_GIS_ISA1		0x08
+#define SAB82532_GIS_ISA0		0x04
+#define SAB82532_GIS_ISB1		0x02
+#define SAB82532_GIS_ISB0		0x01
+
+/* Interrupt Vector Address (IVA) */
+#define SAB82532_IVA_MASK		0xf1
+
+/* Interrupt Port Configuration (IPC) */
+#define SAB82532_IPC_VIS		0x80
+#define SAB82532_IPC_SLA1		0x10
+#define SAB82532_IPC_SLA0		0x08
+#define SAB82532_IPC_CASM		0x04
+#define SAB82532_IPC_IC_OPEN_DRAIN	0x00
+#define SAB82532_IPC_IC_ACT_LOW		0x01
+#define SAB82532_IPC_IC_ACT_HIGH	0x03
+
+/* Interrupt Status Register 0 (ISR0) */
+#define SAB82532_ISR0_TCD		0x80
+#define SAB82532_ISR0_TIME		0x40
+#define SAB82532_ISR0_PERR		0x20
+#define SAB82532_ISR0_FERR		0x10
+#define SAB82532_ISR0_PLLA		0x08
+#define SAB82532_ISR0_CDSC		0x04
+#define SAB82532_ISR0_RFO		0x02
+#define SAB82532_ISR0_RPF		0x01
+
+/* Interrupt Status Register 1 (ISR1) */
+#define SAB82532_ISR1_BRK		0x80
+#define SAB82532_ISR1_BRKT		0x40
+#define SAB82532_ISR1_ALLS		0x20
+#define SAB82532_ISR1_XOFF		0x10
+#define SAB82532_ISR1_TIN		0x08
+#define SAB82532_ISR1_CSC		0x04
+#define SAB82532_ISR1_XON		0x02
+#define SAB82532_ISR1_XPR		0x01
+
+/* Interrupt Mask Register 0 (IMR0) */
+#define SAB82532_IMR0_TCD		0x80
+#define SAB82532_IMR0_TIME		0x40
+#define SAB82532_IMR0_PERR		0x20
+#define SAB82532_IMR0_FERR		0x10
+#define SAB82532_IMR0_PLLA		0x08
+#define SAB82532_IMR0_CDSC		0x04
+#define SAB82532_IMR0_RFO		0x02
+#define SAB82532_IMR0_RPF		0x01
+
+/* Interrupt Mask Register 1 (IMR1) */
+#define SAB82532_IMR1_BRK		0x80
+#define SAB82532_IMR1_BRKT		0x40
+#define SAB82532_IMR1_ALLS		0x20
+#define SAB82532_IMR1_XOFF		0x10
+#define SAB82532_IMR1_TIN		0x08
+#define SAB82532_IMR1_CSC		0x04
+#define SAB82532_IMR1_XON		0x02
+#define SAB82532_IMR1_XPR		0x01
+
+/* Port Interrupt Status Register (PIS) */
+#define SAB82532_PIS_SYNC_B		0x08
+#define SAB82532_PIS_DTR_B		0x04
+#define SAB82532_PIS_DTR_A		0x02
+#define SAB82532_PIS_SYNC_A		0x01
+
+/* Channel Configuration Register 4 (CCR4) */
+#define SAB82532_CCR4_MCK4		0x80
+#define SAB82532_CCR4_EBRG		0x40
+#define SAB82532_CCR4_TST1		0x20
+#define SAB82532_CCR4_ICD		0x10
+
+
+#endif /* !(_SUNSAB_H) */
diff -Nru a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/sunsu.c	Sat Aug 10 18:42:21 2002
@@ -0,0 +1,1678 @@
+/* $Id: su.c,v 1.55 2002/01/08 16:00:16 davem Exp $
+ * su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
+ *
+ * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
+ * Copyright (C) 1998-1999  Pete Zaitcev   (zaitcev@yahoo.com)
+ *
+ * This is mainly a variation of 8250.c, credits go to authors mentioned
+ * therein.  In fact this driver should be merged into the generic 8250.c
+ * infrastructure perhaps using a 8250_sparc.c module.
+ *
+ * Fixed to use tty_get_baud_rate().
+ *   Theodore Ts'o <tytso@mit.edu>, 2001-Oct-12
+ *
+ * Converted to new 2.5.x UART layer.
+ *   David S. Miller (davem@redhat.com), 2002-Jul-29
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/spinlock.h>
+#ifdef CONFIG_SERIO
+#include <linux/serio.h>
+#endif
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/oplib.h>
+#include <asm/ebus.h>
+#ifdef CONFIG_SPARC64
+#include <asm/isa.h>
+#endif
+
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+
+#include "suncore.h"
+
+/* We are on a NS PC87303 clocked with 24.0 MHz, which results
+ * in a UART clock of 1.8462 MHz.
+ */
+#define SU_BASE_BAUD	(1846200 / 16)
+
+enum su_type { SU_PORT_NONE, SU_PORT_MS, SU_PORT_KBD, SU_PORT_PORT };
+static char *su_typev[] = { "su(???)", "su(mouse)", "su(kbd)", "su(serial)" };
+
+/*
+ * Here we define the default xmit fifo size used for each type of UART.
+ */
+static const struct serial_uart_config uart_config[PORT_MAX_8250+1] = {
+	{ "unknown",	1,	0 },
+	{ "8250",	1,	0 },
+	{ "16450",	1,	0 },
+	{ "16550",	1,	0 },
+	{ "16550A",	16,	UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "Cirrus",	1, 	0 },
+	{ "ST16650",	1,	UART_CLEAR_FIFO | UART_STARTECH },
+	{ "ST16650V2",	32,	UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
+	{ "TI16750",	64,	UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "Startech",	1,	0 },
+	{ "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 }
+};
+
+struct uart_sunsu_port {
+	struct uart_port	port;
+	unsigned char		acr;
+	unsigned char		ier;
+	unsigned char		rev;
+	unsigned char		lcr;
+	unsigned int		lsr_break_flag;
+	unsigned int		cflag;
+
+	/* Probing information.  */
+	enum su_type		su_type;
+	int			port_node;
+	unsigned int		irq;
+
+	/* L1-A keyboard break state.  */
+	int			kbd_id;
+	int			l1_down;
+#ifdef CONFIG_SERIO
+	struct serio		serio;
+#endif
+};
+
+#define _INLINE_
+
+static _INLINE_ unsigned int serial_in(struct uart_sunsu_port *up, int offset)
+{
+	offset <<= up->port.regshift;
+
+	switch (up->port.iotype) {
+	case SERIAL_IO_HUB6:
+		outb(up->port.hub6 - 1 + offset, up->port.iobase);
+		return inb(up->port.iobase + 1);
+
+	case SERIAL_IO_MEM:
+		return readb(up->port.membase + offset);
+
+	default:
+		return inb(up->port.iobase + offset);
+	}
+}
+
+static _INLINE_ void
+serial_out(struct uart_sunsu_port *up, int offset, int value)
+{
+#ifndef CONFIG_SPARC64
+	/*
+	 * MrCoffee has weird schematics: IRQ4 & P10(?) pins of SuperIO are
+	 * connected with a gate then go to SlavIO. When IRQ4 goes tristated
+	 * gate outputs a logical one. Since we use level triggered interrupts
+	 * we have lockup and watchdog reset. We cannot mask IRQ because
+	 * keyboard shares IRQ with us (Word has it as Bob Smelik's design).
+	 * This problem is similar to what Alpha people suffer, see serial.c.
+	 */
+	if (offset == UART_MCR)
+		value |= UART_MCR_OUT2;
+#endif
+	offset <<= up->port.regshift;
+
+	switch (up->port.iotype) {
+	case SERIAL_IO_HUB6:
+		outb(up->port.hub6 - 1 + offset, up->port.iobase);
+		outb(value, up->port.iobase + 1);
+		break;
+
+	case SERIAL_IO_MEM:
+		writeb(value, up->port.membase + offset);
+		break;
+
+	default:
+		outb(value, up->port.iobase + offset);
+	}
+}
+
+/*
+ * We used to support using pause I/O for certain machines.  We
+ * haven't supported this for a while, but just in case it's badly
+ * needed for certain old 386 machines, I've left these #define's
+ * in....
+ */
+#define serial_inp(up, offset)		serial_in(up, offset)
+#define serial_outp(up, offset, value)	serial_out(up, offset, value)
+
+
+/*
+ * For the 16C950
+ */
+static void serial_icr_write(struct uart_sunsu_port *up, int offset, int value)
+{
+	serial_out(up, UART_SCR, offset);
+	serial_out(up, UART_ICR, value);
+}
+
+#if 0 /* Unused currently */
+static unsigned int serial_icr_read(struct uart_sunsu_port *up, int offset)
+{
+	unsigned int value;
+
+	serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
+	serial_out(up, UART_SCR, offset);
+	value = serial_in(up, UART_ICR);
+	serial_icr_write(up, UART_ACR, up->acr);
+
+	return value;
+}
+#endif
+
+#ifdef CONFIG_SERIAL_8250_RSA
+/*
+ * Attempts to turn on the RSA FIFO.  Returns zero on failure.
+ * We set the port uart clock rate if we succeed.
+ */
+static int __enable_rsa(struct uart_sunsu_port *up)
+{
+	unsigned char mode;
+	int result;
+
+	mode = serial_inp(up, UART_RSA_MSR);
+	result = mode & UART_RSA_MSR_FIFO;
+
+	if (!result) {
+		serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
+		mode = serial_inp(up, UART_RSA_MSR);
+		result = mode & UART_RSA_MSR_FIFO;
+	}
+
+	if (result)
+		up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
+
+	return result;
+}
+
+static void enable_rsa(struct uart_sunsu_port *up)
+{
+	if (up->port.type == PORT_RSA) {
+		if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
+			spin_lock_irq(&up->port.lock);
+			__enable_rsa(up);
+			spin_unlock_irq(&up->port.lock);
+		}
+		if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
+			serial_outp(up, UART_RSA_FRR, 0);
+	}
+}
+
+/*
+ * Attempts to turn off the RSA FIFO.  Returns zero on failure.
+ * It is unknown why interrupts were disabled in here.  However,
+ * the caller is expected to preserve this behaviour by grabbing
+ * the spinlock before calling this function.
+ */
+static void disable_rsa(struct uart_sunsu_port *up)
+{
+	unsigned char mode;
+	int result;
+
+	if (up->port.type == PORT_RSA &&
+	    up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
+		spin_lock_irq(&up->port.lock);
+
+		mode = serial_inp(up, UART_RSA_MSR);
+		result = !(mode & UART_RSA_MSR_FIFO);
+
+		if (!result) {
+			serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
+			mode = serial_inp(up, UART_RSA_MSR);
+			result = !(mode & UART_RSA_MSR_FIFO);
+		}
+
+		if (result)
+			up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
+		spin_unlock_irq(&up->port.lock);
+	}
+}
+#endif /* CONFIG_SERIAL_8250_RSA */
+
+static void sunsu_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
+
+	if (up->ier & UART_IER_THRI) {
+		up->ier &= ~UART_IER_THRI;
+		serial_out(up, UART_IER, up->ier);
+	}
+	if (up->port.type == PORT_16C950 && tty_stop) {
+		up->acr |= UART_ACR_TXDIS;
+		serial_icr_write(up, UART_ACR, up->acr);
+	}
+}
+
+static void sunsu_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
+
+	if (!(up->ier & UART_IER_THRI)) {
+		up->ier |= UART_IER_THRI;
+		serial_out(up, UART_IER, up->ier);
+	}
+	/*
+	 * We only do this from uart_start
+	 */
+	if (tty_start && up->port.type == PORT_16C950) {
+		up->acr &= ~UART_ACR_TXDIS;
+		serial_icr_write(up, UART_ACR, up->acr);
+	}
+}
+
+static void sunsu_stop_rx(struct uart_port *port)
+{
+	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	up->ier &= ~UART_IER_RLSI;
+	up->port.read_status_mask &= ~UART_LSR_DR;
+	serial_out(up, UART_IER, up->ier);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static void sunsu_enable_ms(struct uart_port *port)
+{
+	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	up->ier |= UART_IER_MSI;
+	serial_out(up, UART_IER, up->ier);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static _INLINE_ void
+receive_chars(struct uart_sunsu_port *up, unsigned char *status, struct pt_regs *regs)
+{
+	struct tty_struct *tty = up->port.info->tty;
+	unsigned char ch;
+	int max_count = 256;
+	int saw_console_brk = 0;
+
+	do {
+		if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
+			tty->flip.tqueue.routine((void *)tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+				return; // if TTY_DONT_FLIP is set
+		}
+		ch = serial_inp(up, UART_RX);
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		up->port.icount.rx++;
+
+		if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
+				       UART_LSR_FE | UART_LSR_OE))) {
+			/*
+			 * For statistics only
+			 */
+			if (*status & UART_LSR_BI) {
+				*status &= ~(UART_LSR_FE | UART_LSR_PE);
+				up->port.icount.brk++;
+				if (up->port.line == up->port.cons->index)
+					saw_console_brk = 1;
+				/*
+				 * We do the SysRQ and SAK checking
+				 * here because otherwise the break
+				 * may get masked by ignore_status_mask
+				 * or read_status_mask.
+				 */
+				if (uart_handle_break(&up->port))
+					goto ignore_char;
+			} else if (*status & UART_LSR_PE)
+				up->port.icount.parity++;
+			else if (*status & UART_LSR_FE)
+				up->port.icount.frame++;
+			if (*status & UART_LSR_OE)
+				up->port.icount.overrun++;
+
+			/*
+			 * Mask off conditions which should be ingored.
+			 */
+			*status &= up->port.read_status_mask;
+
+			if (up->port.line == up->port.cons->index) {
+				/* Recover the break flag from console xmit */
+				*status |= up->lsr_break_flag;
+				up->lsr_break_flag = 0;
+			}
+
+			if (*status & UART_LSR_BI) {
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			} else if (*status & UART_LSR_PE)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (*status & UART_LSR_FE)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+		if (uart_handle_sysrq_char(&up->port, ch, regs))
+			goto ignore_char;
+		if ((*status & up->port.ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((*status & UART_LSR_OE) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character.
+			 */
+			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+	ignore_char:
+		*status = serial_inp(up, UART_LSR);
+	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
+	tty_flip_buffer_push(tty);
+
+	if (saw_console_brk)
+		sun_do_break();
+}
+
+static _INLINE_ void transmit_chars(struct uart_sunsu_port *up)
+{
+	struct circ_buf *xmit = &up->port.info->xmit;
+	int count;
+
+	if (up->port.x_char) {
+		serial_outp(up, UART_TX, up->port.x_char);
+		up->port.icount.tx++;
+		up->port.x_char = 0;
+		return;
+	}
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
+		sunsu_stop_tx(&up->port, 0);
+		return;
+	}
+
+	count = up->port.fifosize;
+	do {
+		serial_out(up, UART_TX, xmit->buf[xmit->tail]);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		up->port.icount.tx++;
+		if (uart_circ_empty(xmit))
+			break;
+	} while (--count > 0);
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_event(&up->port, EVT_WRITE_WAKEUP);
+
+	if (uart_circ_empty(xmit))
+		sunsu_stop_tx(&up->port, 0);
+}
+
+static _INLINE_ void check_modem_status(struct uart_sunsu_port *up)
+{
+	int status;
+
+	status = serial_in(up, UART_MSR);
+
+	if ((status & UART_MSR_ANY_DELTA) == 0)
+		return;
+
+	if (status & UART_MSR_TERI)
+		up->port.icount.rng++;
+	if (status & UART_MSR_DDSR)
+		up->port.icount.dsr++;
+	if (status & UART_MSR_DDCD)
+		uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
+	if (status & UART_MSR_DCTS)
+		uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
+
+	wake_up_interruptible(&up->port.info->delta_msr_wait);
+}
+
+static void sunsu_serial_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_sunsu_port *up = dev_id;
+	unsigned long flags;
+	unsigned char status;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	do {
+		status = serial_inp(up, UART_LSR);
+		if (status & UART_LSR_DR)
+			receive_chars(up, &status, regs);
+		check_modem_status(up);
+		if (status & UART_LSR_THRE)
+			transmit_chars(up);
+	} while (!(serial_in(up, UART_IIR) & UART_IIR_NO_INT));
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+/* Seperate interrupt handling path for keyboard/mouse ports.  */
+
+static void
+sunsu_change_speed(struct uart_port *port, unsigned int cflag,
+		   unsigned int iflag, unsigned int quot);
+
+static void sunsu_change_mouse_baud(struct uart_sunsu_port *up)
+{
+	unsigned int cur_cflag = up->cflag;
+	int quot, new_baud;
+
+	up->cflag &= ~CBAUD;
+	up->cflag |= suncore_mouse_baud_cflag_next(cur_cflag, &new_baud);
+
+	quot = up->port.uartclk / (16 * new_baud);
+
+	spin_unlock(&up->port.lock);
+
+	sunsu_change_speed(&up->port, up->cflag, 0, quot);
+
+	spin_lock(&up->port.lock);
+}
+
+static void receive_kbd_ms_chars(struct uart_sunsu_port *up, struct pt_regs *regs, int is_break)
+{
+	do {
+		unsigned char ch = serial_inp(up, UART_RX);
+
+		if (up->su_type == SU_PORT_KBD) {
+			if (ch == SUNKBD_RESET) {
+				up->kbd_id = 1;
+				up->l1_down = 0;
+			} else if (up->kbd_id) {
+				up->kbd_id = 0;
+			} else if (ch == SUNKBD_L1) {
+				up->l1_down = 1;
+			} else if (ch == (SUNKBD_L1|SUNKBD_UP)) {
+				up->l1_down = 0;
+			} else if (ch == SUNKBD_A && up->l1_down) {
+				/* whee... */
+				sun_do_break();
+
+				/* Continue execution... */
+				up->l1_down = 0;
+				up->kbd_id = 0;
+				return;
+			}
+			kbd_pt_regs = regs;
+#ifdef CONFIG_SERIO
+			serio_interrupt(&up->serio, ch, 0);
+#endif
+		} else if (up->su_type == SU_PORT_MS) {
+			int ret = suncore_mouse_baud_detection(ch, is_break);
+
+			switch (ret) {
+			case 2:
+				sunsu_change_mouse_baud(up);
+				/* fallthru */
+			case 1:
+				break;
+
+			case 0:
+#ifdef CONFIG_SERIO
+				serio_interrupt(&up->serio, ch, 0);
+#endif
+				break;
+			};
+		}
+	} while (serial_in(up, UART_LSR) & UART_LSR_DR);
+}
+
+static void sunsu_kbd_ms_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_sunsu_port *up = dev_id;
+
+	if (!(serial_in(up, UART_IIR) & UART_IIR_NO_INT)) {
+		unsigned char status = serial_inp(up, UART_LSR);
+
+		if ((status & UART_LSR_DR) || (status & UART_LSR_BI))
+			receive_kbd_ms_chars(up, regs,
+					     (status & UART_LSR_BI) != 0);
+	}
+}
+
+static unsigned int sunsu_tx_empty(struct uart_port *port)
+{
+	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
+	unsigned long flags;
+	unsigned int ret;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	return ret;
+}
+
+static unsigned int sunsu_get_mctrl(struct uart_port *port)
+{
+	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
+	unsigned long flags;
+	unsigned char status;
+	unsigned int ret;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	status = serial_in(up, UART_MSR);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	ret = 0;
+	if (status & UART_MSR_DCD)
+		ret |= TIOCM_CAR;
+	if (status & UART_MSR_RI)
+		ret |= TIOCM_RNG;
+	if (status & UART_MSR_DSR)
+		ret |= TIOCM_DSR;
+	if (status & UART_MSR_CTS)
+		ret |= TIOCM_CTS;
+	return ret;
+}
+
+static void sunsu_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
+	unsigned char mcr = 0;
+
+	if (mctrl & TIOCM_RTS)
+		mcr |= UART_MCR_RTS;
+	if (mctrl & TIOCM_DTR)
+		mcr |= UART_MCR_DTR;
+	if (mctrl & TIOCM_OUT1)
+		mcr |= UART_MCR_OUT1;
+	if (mctrl & TIOCM_OUT2)
+		mcr |= UART_MCR_OUT2;
+	if (mctrl & TIOCM_LOOP)
+		mcr |= UART_MCR_LOOP;
+
+	serial_out(up, UART_MCR, mcr);
+}
+
+static void sunsu_break_ctl(struct uart_port *port, int break_state)
+{
+	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
+	unsigned long flags;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	if (break_state == -1)
+		up->lcr |= UART_LCR_SBC;
+	else
+		up->lcr &= ~UART_LCR_SBC;
+	serial_out(up, UART_LCR, up->lcr);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static int sunsu_startup(struct uart_port *port)
+{
+	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
+	unsigned long flags;
+	int retval;
+
+	if (up->port.type == PORT_16C950) {
+		/* Wake up and initialize UART */
+		up->acr = 0;
+		serial_outp(up, UART_LCR, 0xBF);
+		serial_outp(up, UART_EFR, UART_EFR_ECB);
+		serial_outp(up, UART_IER, 0);
+		serial_outp(up, UART_LCR, 0);
+		serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
+		serial_outp(up, UART_LCR, 0xBF);
+		serial_outp(up, UART_EFR, UART_EFR_ECB);
+		serial_outp(up, UART_LCR, 0);
+	}
+
+#ifdef CONFIG_SERIAL_8250_RSA
+	/*
+	 * If this is an RSA port, see if we can kick it up to the
+	 * higher speed clock.
+	 */
+	enable_rsa(up);
+#endif
+
+	/*
+	 * Clear the FIFO buffers and disable them.
+	 * (they will be reeanbled in change_speed())
+	 */
+	if (uart_config[up->port.type].flags & UART_CLEAR_FIFO) {
+		serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+		serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+				UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+		serial_outp(up, UART_FCR, 0);
+	}
+
+	/*
+	 * Clear the interrupt registers.
+	 */
+	(void) serial_inp(up, UART_LSR);
+	(void) serial_inp(up, UART_RX);
+	(void) serial_inp(up, UART_IIR);
+	(void) serial_inp(up, UART_MSR);
+
+	/*
+	 * At this point, there's no way the LSR could still be 0xff;
+	 * if it is, then bail out, because there's likely no UART
+	 * here.
+	 */
+	if (!(up->port.flags & ASYNC_BUGGY_UART) &&
+	    (serial_inp(up, UART_LSR) == 0xff)) {
+		printk("ttyS%d: LSR safety check engaged!\n", up->port.line);
+		return -ENODEV;
+	}
+
+	if (up->su_type != SU_PORT_PORT) {
+		retval = request_irq(up->irq, sunsu_kbd_ms_interrupt,
+				     SA_SHIRQ, su_typev[up->su_type], up);
+	} else {
+		retval = request_irq(up->irq, sunsu_serial_interrupt,
+				     SA_SHIRQ, su_typev[up->su_type], up);
+	}
+	if (retval) {
+		printk("su: Cannot register IRQ\n");
+		return retval;
+	}
+
+	/*
+	 * Now, initialize the UART
+	 */
+	serial_outp(up, UART_LCR, UART_LCR_WLEN8);
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	up->port.mctrl |= TIOCM_OUT2;
+
+	sunsu_set_mctrl(&up->port, up->port.mctrl);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	/*
+	 * Finally, enable interrupts.  Note: Modem status interrupts
+	 * are set via change_speed(), which will be occuring imminently
+	 * anyway, so we don't enable them here.
+	 */
+	up->ier = UART_IER_RLSI | UART_IER_RDI;
+	serial_outp(up, UART_IER, up->ier);
+
+	if (up->port.flags & ASYNC_FOURPORT) {
+		unsigned int icp;
+		/*
+		 * Enable interrupts on the AST Fourport board
+		 */
+		icp = (up->port.iobase & 0xfe0) | 0x01f;
+		outb_p(0x80, icp);
+		(void) inb_p(icp);
+	}
+
+	/*
+	 * And clear the interrupt registers again for luck.
+	 */
+	(void) serial_inp(up, UART_LSR);
+	(void) serial_inp(up, UART_RX);
+	(void) serial_inp(up, UART_IIR);
+	(void) serial_inp(up, UART_MSR);
+
+	return 0;
+}
+
+static void sunsu_shutdown(struct uart_port *port)
+{
+	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
+	unsigned long flags;
+
+	/*
+	 * Disable interrupts from this port
+	 */
+	up->ier = 0;
+	serial_outp(up, UART_IER, 0);
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	if (up->port.flags & ASYNC_FOURPORT) {
+		/* reset interrupts on the AST Fourport board */
+		inb((up->port.iobase & 0xfe0) | 0x1f);
+		up->port.mctrl |= TIOCM_OUT1;
+	} else
+		up->port.mctrl &= ~TIOCM_OUT2;
+
+	sunsu_set_mctrl(&up->port, up->port.mctrl);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	/*
+	 * Disable break condition and FIFOs
+	 */
+	serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
+				  UART_FCR_CLEAR_RCVR |
+				  UART_FCR_CLEAR_XMIT);
+	serial_outp(up, UART_FCR, 0);
+
+#ifdef CONFIG_SERIAL_8250_RSA
+	/*
+	 * Reset the RSA board back to 115kbps compat mode.
+	 */
+	disable_rsa(up);
+#endif
+
+	/*
+	 * Read data port to reset things.
+	 */
+	(void) serial_in(up, UART_RX);
+}
+
+static void
+sunsu_change_speed(struct uart_port *port, unsigned int cflag,
+		   unsigned int iflag, unsigned int quot)
+{
+	struct uart_sunsu_port *up = (struct uart_sunsu_port *) port;
+	unsigned char cval, fcr = 0;
+	unsigned long flags;
+
+	switch (cflag & CSIZE) {
+	case CS5:
+		cval = 0x00;
+		break;
+	case CS6:
+		cval = 0x01;
+		break;
+	case CS7:
+		cval = 0x02;
+		break;
+	default:
+	case CS8:
+		cval = 0x03;
+		break;
+	}
+
+	if (cflag & CSTOPB)
+		cval |= 0x04;
+	if (cflag & PARENB)
+		cval |= UART_LCR_PARITY;
+	if (!(cflag & PARODD))
+		cval |= UART_LCR_EPAR;
+#ifdef CMSPAR
+	if (cflag & CMSPAR)
+		cval |= UART_LCR_SPAR;
+#endif
+
+	/*
+	 * Work around a bug in the Oxford Semiconductor 952 rev B
+	 * chip which causes it to seriously miscalculate baud rates
+	 * when DLL is 0.
+	 */
+	if ((quot & 0xff) == 0 && up->port.type == PORT_16C950 &&
+	    up->rev == 0x5201)
+		quot ++;
+
+	if (uart_config[up->port.type].flags & UART_USE_FIFO) {
+		if ((up->port.uartclk / quot) < (2400 * 16))
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
+#ifdef CONFIG_SERIAL_8250_RSA
+		else if (up->port.type == PORT_RSA)
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14;
+#endif
+		else
+			fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
+	}
+	if (up->port.type == PORT_16750)
+		fcr |= UART_FCR7_64BYTE;
+
+	up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
+	if (iflag & INPCK)
+		up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
+	if (iflag & (BRKINT | PARMRK))
+		up->port.read_status_mask |= UART_LSR_BI;
+
+	/*
+	 * Characteres to ignore
+	 */
+	up->port.ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
+	if (iflag & IGNBRK) {
+		up->port.ignore_status_mask |= UART_LSR_BI;
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			up->port.ignore_status_mask |= UART_LSR_OE;
+	}
+
+	/*
+	 * ignore all characters if CREAD is not set
+	 */
+	if ((cflag & CREAD) == 0)
+		up->port.ignore_status_mask |= UART_LSR_DR;
+
+	/*
+	 * CTS flow control flag and modem status interrupts
+	 */
+	up->ier &= ~UART_IER_MSI;
+	if (UART_ENABLE_MS(&up->port, cflag))
+		up->ier |= UART_IER_MSI;
+
+	/*
+	 * Ok, we're now changing the port state.  Do it with
+	 * interrupts disabled.
+	 */
+	spin_lock_irqsave(&up->port.lock, flags);
+	serial_out(up, UART_IER, up->ier);
+
+	if (uart_config[up->port.type].flags & UART_STARTECH) {
+		serial_outp(up, UART_LCR, 0xBF);
+		serial_outp(up, UART_EFR, cflag & CRTSCTS ? UART_EFR_CTS :0);
+	}
+	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)
+		serial_outp(up, UART_FCR, fcr);		/* set fcr */
+	serial_outp(up, UART_LCR, cval);		/* reset DLAB */
+	up->lcr = cval;					/* Save LCR */
+	if (up->port.type != PORT_16750) {
+		if (fcr & UART_FCR_ENABLE_FIFO) {
+			/* emulated UARTs (Lucent Venus 167x) need two steps */
+			serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+		}
+		serial_outp(up, UART_FCR, fcr);		/* set fcr */
+	}
+
+	up->cflag = cflag;
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static void sunsu_release_port(struct uart_port *port)
+{
+}
+
+static int sunsu_request_port(struct uart_port *port)
+{
+	return 0;
+}
+
+static void sunsu_config_port(struct uart_port *port, int flags)
+{
+}
+
+static int
+sunsu_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	return -EINVAL;
+}
+
+static const char *
+sunsu_type(struct uart_port *port)
+{
+	int type = port->type;
+
+	if (type >= ARRAY_SIZE(uart_config))
+		type = 0;
+	return uart_config[type].name;
+}
+
+static struct uart_ops sunsu_pops = {
+	.tx_empty	= sunsu_tx_empty,
+	.set_mctrl	= sunsu_set_mctrl,
+	.get_mctrl	= sunsu_get_mctrl,
+	.stop_tx	= sunsu_stop_tx,
+	.start_tx	= sunsu_start_tx,
+	.stop_rx	= sunsu_stop_rx,
+	.enable_ms	= sunsu_enable_ms,
+	.break_ctl	= sunsu_break_ctl,
+	.startup	= sunsu_startup,
+	.shutdown	= sunsu_shutdown,
+	.change_speed	= sunsu_change_speed,
+	.type		= sunsu_type,
+	.release_port	= sunsu_release_port,
+	.request_port	= sunsu_request_port,
+	.config_port	= sunsu_config_port,
+	.verify_port	= sunsu_verify_port,
+};
+
+#define UART_NR	4
+
+static struct uart_sunsu_port sunsu_ports[UART_NR];
+
+#ifdef CONFIG_SERIO
+
+static spinlock_t sunsu_serio_lock = SPIN_LOCK_UNLOCKED;
+
+static int sunsu_serio_write(struct serio *serio, unsigned char ch)
+{
+	struct uart_sunsu_port *up = serio->driver;
+	unsigned long flags;
+	int lsr;
+
+	spin_lock_irqsave(&sunsu_serio_lock, flags);
+
+	do {
+		lsr = serial_in(up, UART_LSR);
+	} while (!(lsr & UART_LSR_THRE));
+
+	/* Send the character out. */
+	serial_out(up, UART_TX, ch);
+
+	spin_unlock_irqrestore(&sunsu_serio_lock, flags);
+
+	return 0;
+}
+
+static int sunsu_serio_open(struct serio *serio)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&sunsu_serio_lock, flags);
+	if (serio->private == NULL) {
+		serio->private = (void *) -1L;
+		ret = 0;
+	} else
+		ret = -EBUSY;
+	spin_unlock_irqrestore(&sunsu_serio_lock, flags);
+
+	return ret;
+}
+
+static void sunsu_serio_close(struct serio *serio)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&sunsu_serio_lock, flags);
+	serio->private = NULL;
+	spin_unlock_irqrestore(&sunsu_serio_lock, flags);
+}
+
+#endif /* CONFIG_SERIO */
+
+static void sunsu_autoconfig(struct uart_sunsu_port *up)
+{
+	unsigned char status1, status2, scratch, scratch2, scratch3;
+	unsigned char save_lcr, save_mcr;
+	struct linux_ebus_device *dev = 0;
+	struct linux_ebus *ebus;
+#ifdef CONFIG_SPARC64
+	struct isa_bridge *isa_br;
+	struct isa_device *isa_dev;
+#endif
+#ifndef CONFIG_SPARC64
+	struct linux_prom_registers reg0;
+#endif
+	unsigned long flags;
+
+	if (!up->port_node || !up->su_type)
+		return;
+
+	/*
+	 * First we look for Ebus-bases su's
+	 */
+	for_each_ebus(ebus) {
+		for_each_ebusdev(dev, ebus) {
+			if (dev->prom_node == up->port_node) {
+				up->port.membase = (char *) dev->resource[0].start;
+				up->irq = dev->irqs[0];
+				goto ebus_done;
+			}
+		}
+	}
+
+#ifdef CONFIG_SPARC64
+	for_each_isa(isa_br) {
+		for_each_isadev(isa_dev, isa_br) {
+			if (isa_dev->prom_node == up->port_node) {
+				up->port.membase = (char *) isa_dev->resource.start;
+				up->irq = isa_dev->irq;
+				goto ebus_done;
+			}
+		}
+	}
+#endif
+
+#ifdef CONFIG_SPARC64
+	/*
+	 * Not on Ebus, bailing.
+	 */
+	return;
+#else
+	/*
+	 * Not on Ebus, must be OBIO.
+	 */
+	if (prom_getproperty(up->port_node, "reg",
+			     (char *)&reg0, sizeof(reg0)) == -1) {
+		prom_printf("sunsu: no \"reg\" property\n");
+		return;
+	}
+	prom_apply_obio_ranges(&reg0, 1);
+	if (reg0.which_io != 0) {	/* Just in case... */
+		prom_printf("sunsu: bus number nonzero: 0x%x:%x\n",
+		    reg0.which_io, reg0.phys_addr);
+		return;
+	}
+	if ((up->port.membase = ioremap(reg0.phys_addr, reg0.reg_size)) == 0) {
+		prom_printf("sunsu: Cannot map registers.\n");
+		return;
+	}
+
+	/*
+	 * 0x20 is sun4m thing, Dave Redman heritage.
+	 * See arch/sparc/kernel/irq.c.
+	 */
+#define IRQ_4M(n)	((n)|0x20)
+
+	/*
+	 * There is no intr property on MrCoffee, so hardwire it.
+	 */
+	up->irq = IRQ_4M(13);
+#endif
+
+ebus_done:
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	if (!(up->port.flags & ASYNC_BUGGY_UART)) {
+		/*
+		 * Do a simple existence test first; if we fail this, there's
+		 * no point trying anything else.
+		 *
+		 * 0x80 is used as a nonsense port to prevent against false
+		 * positives due to ISA bus float.  The assumption is that
+		 * 0x80 is a non-existent port; which should be safe since
+		 * include/asm/io.h also makes this assumption.
+		 */
+		scratch = serial_inp(up, UART_IER);
+		serial_outp(up, UART_IER, 0);
+#ifdef __i386__
+		outb(0xff, 0x080);
+#endif
+		scratch2 = serial_inp(up, UART_IER);
+		serial_outp(up, UART_IER, 0x0f);
+#ifdef __i386__
+		outb(0, 0x080);
+#endif
+		scratch3 = serial_inp(up, UART_IER);
+		serial_outp(up, UART_IER, scratch);
+		if (scratch2 != 0 || scratch3 != 0x0F)
+			goto out;	/* We failed; there's nothing here */
+	}
+
+	save_mcr = serial_in(up, UART_MCR);
+	save_lcr = serial_in(up, UART_LCR);
+
+	/* 
+	 * Check to see if a UART is really there.  Certain broken
+	 * internal modems based on the Rockwell chipset fail this
+	 * test, because they apparently don't implement the loopback
+	 * test mode.  So this test is skipped on the COM 1 through
+	 * COM 4 ports.  This *should* be safe, since no board
+	 * manufacturer would be stupid enough to design a board
+	 * that conflicts with COM 1-4 --- we hope!
+	 */
+	if (!(up->port.flags & ASYNC_SKIP_TEST)) {
+		serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
+		status1 = serial_inp(up, UART_MSR) & 0xF0;
+		serial_outp(up, UART_MCR, save_mcr);
+		if (status1 != 0x90)
+			goto out;	/* We failed loopback test */
+	}
+	serial_outp(up, UART_LCR, 0xBF);	/* set up for StarTech test */
+	serial_outp(up, UART_EFR, 0);		/* EFR is the same as FCR */
+	serial_outp(up, UART_LCR, 0);
+	serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+	scratch = serial_in(up, UART_IIR) >> 6;
+	switch (scratch) {
+		case 0:
+			up->port.type = PORT_16450;
+			break;
+		case 1:
+			up->port.type = PORT_UNKNOWN;
+			break;
+		case 2:
+			up->port.type = PORT_16550;
+			break;
+		case 3:
+			up->port.type = PORT_16550A;
+			break;
+	}
+	if (up->port.type == PORT_16550A) {
+		/* Check for Startech UART's */
+		serial_outp(up, UART_LCR, UART_LCR_DLAB);
+		if (serial_in(up, UART_EFR) == 0) {
+			up->port.type = PORT_16650;
+		} else {
+			serial_outp(up, UART_LCR, 0xBF);
+			if (serial_in(up, UART_EFR) == 0)
+				up->port.type = PORT_16650V2;
+		}
+	}
+	if (up->port.type == PORT_16550A) {
+		/* Check for TI 16750 */
+		serial_outp(up, UART_LCR, save_lcr | UART_LCR_DLAB);
+		serial_outp(up, UART_FCR,
+			    UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+		scratch = serial_in(up, UART_IIR) >> 5;
+		if (scratch == 7) {
+			/*
+			 * If this is a 16750, and not a cheap UART
+			 * clone, then it should only go into 64 byte
+			 * mode if the UART_FCR7_64BYTE bit was set
+			 * while UART_LCR_DLAB was latched.
+			 */
+ 			serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+			serial_outp(up, UART_LCR, 0);
+			serial_outp(up, UART_FCR,
+				    UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
+			scratch = serial_in(up, UART_IIR) >> 5;
+			if (scratch == 6)
+				up->port.type = PORT_16750;
+		}
+		serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
+	}
+	serial_outp(up, UART_LCR, save_lcr);
+	if (up->port.type == PORT_16450) {
+		scratch = serial_in(up, UART_SCR);
+		serial_outp(up, UART_SCR, 0xa5);
+		status1 = serial_in(up, UART_SCR);
+		serial_outp(up, UART_SCR, 0x5a);
+		status2 = serial_in(up, UART_SCR);
+		serial_outp(up, UART_SCR, scratch);
+
+		if ((status1 != 0xa5) || (status2 != 0x5a))
+			up->port.type = PORT_8250;
+	}
+
+	up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size;
+
+	if (up->port.type == PORT_UNKNOWN)
+		goto out;
+
+	/*
+	 * Reset the UART.
+	 */
+#ifdef CONFIG_SERIAL_8250_RSA
+	if (up->port.type == PORT_RSA)
+		serial_outp(up, UART_RSA_FRR, 0);
+#endif
+	serial_outp(up, UART_MCR, save_mcr);
+	serial_outp(up, UART_FCR, (UART_FCR_ENABLE_FIFO |
+				     UART_FCR_CLEAR_RCVR |
+				     UART_FCR_CLEAR_XMIT));
+	serial_outp(up, UART_FCR, 0);
+	(void)serial_in(up, UART_RX);
+	serial_outp(up, UART_IER, 0);
+
+out:
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static struct uart_driver sunsu_reg = {
+	.owner			= THIS_MODULE,
+	.driver_name		= "serial",
+#ifdef CONFIG_DEVFS_FS
+	.dev_name		= "tts/%d",
+#else
+	.dev_name		= "ttyS",
+#endif
+	.major			= TTY_MAJOR,
+};
+
+static int __init sunsu_kbd_ms_init(void)
+{
+	struct uart_sunsu_port *up;
+	int i;
+
+	for (i = 0, up = sunsu_ports; i < 2; i++, up++) {
+		up->port.line = i;
+		up->port.type = PORT_UNKNOWN;
+		up->port.uartclk = (SU_BASE_BAUD * 16);
+
+		if (up->su_type == SU_PORT_KBD)
+			up->cflag = B1200 | CS8 | CLOCAL | CREAD;
+		else
+			up->cflag = B4800 | CS8 | CLOCAL | CREAD;
+
+		sunsu_autoconfig(up);
+		if (up->port.type == PORT_UNKNOWN)
+			continue;
+
+		printk(KERN_INFO "su%d at 0x%p (irq = %s) is a %s\n",
+		       i,
+		       up->port.membase, __irq_itoa(up->irq),
+		       sunsu_type(&up->port));
+
+#ifdef CONFIG_SERIO
+		memset(&up->serio, 0, sizeof(up->serio));
+
+		up->serio.driver = up;
+
+		up->serio.type = SERIO_RS232;
+		if (up->su_type == SU_PORT_KBD) {
+			up->serio.type |= SERIO_SUNKBD;
+			up->serio.name = "sukbd";
+		} else {
+			up->serio.type |= SERIO_SUN;
+			up->serio.name = "sums";
+		}
+		up->serio.phys = (i == 0 ? "su/serio0" : "su/serio1");
+
+		up->serio.write = sunsu_serio_write;
+		up->serio.open = sunsu_serio_open;
+		up->serio.close = sunsu_serio_close;
+
+		serio_register_port(&up->serio);
+#endif
+
+		sunsu_startup(&up->port);
+	}
+	return 0;
+}
+
+/*
+ * ------------------------------------------------------------
+ * Serial console driver
+ * ------------------------------------------------------------
+ */
+
+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
+
+/*
+ *	Wait for transmitter & holding register to empty
+ */
+static __inline__ void wait_for_xmitr(struct uart_sunsu_port *up)
+{
+	unsigned int status, tmout = 10000;
+
+	/* Wait up to 10ms for the character(s) to be sent. */
+	do {
+		status = serial_in(up, UART_LSR);
+
+		if (status & UART_LSR_BI)
+			up->lsr_break_flag = UART_LSR_BI;
+
+		if (--tmout == 0)
+			break;
+		udelay(1);
+	} while ((status & BOTH_EMPTY) != BOTH_EMPTY);
+
+	/* Wait up to 1s for flow control if necessary */
+	if (up->port.flags & ASYNC_CONS_FLOW) {
+		tmout = 1000000;
+		while (--tmout &&
+		       ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
+			udelay(1);
+	}
+}
+
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ */
+static void sunsu_console_write(struct console *co, const char *s,
+				unsigned int count)
+{
+	struct uart_sunsu_port *up = &sunsu_ports[co->index];
+	unsigned int ier;
+	int i;
+
+	/*
+	 *	First save the UER then disable the interrupts
+	 */
+	ier = serial_in(up, UART_IER);
+	serial_out(up, UART_IER, 0);
+
+	/*
+	 *	Now, do each character
+	 */
+	for (i = 0; i < count; i++, s++) {
+		wait_for_xmitr(up);
+
+		/*
+		 *	Send the character out.
+		 *	If a LF, also do CR...
+		 */
+		serial_out(up, UART_TX, *s);
+		if (*s == 10) {
+			wait_for_xmitr(up);
+			serial_out(up, UART_TX, 13);
+		}
+	}
+
+	/*
+	 *	Finally, wait for transmitter to become empty
+	 *	and restore the IER
+	 */
+	wait_for_xmitr(up);
+	serial_out(up, UART_IER, ier);
+}
+
+static kdev_t sunsu_console_device(struct console *co)
+{
+	return mk_kdev(sunsu_reg.major, sunsu_reg.minor + co->index);
+}
+
+/*
+ *	Setup initial baud/bits/parity. We do two things here:
+ *	- construct a cflag setting for the first su_open()
+ *	- initialize the serial port
+ *	Return non-zero if we didn't find a serial port.
+ */
+static int __init sunsu_console_setup(struct console *co, char *options)
+{
+	struct uart_port *port;
+	int baud = 9600;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	printk("Console: ttyS%d (SU)\n",
+	       (sunsu_reg.minor - 64) + co->index);
+
+	/*
+	 * Check whether an invalid uart number has been specified, and
+	 * if so, search for the first available port that does have
+	 * console support.
+	 */
+	if (co->index >= UART_NR)
+		co->index = 0;
+	port = &sunsu_ports[co->index].port;
+
+	/*
+	 * Temporary fix.
+	 */
+	spin_lock_init(&port->lock);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console sunsu_cons = {
+	.name	=	"ttyS",
+	.write	=	sunsu_console_write,
+	.device	=	sunsu_console_device,
+	.setup	=	sunsu_console_setup,
+	.flags	=	CON_PRINTBUFFER,
+	.index	=	-1,
+};
+
+/*
+ *	Register console.
+ */
+
+static int __init sunsu_serial_console_init(void)
+{
+	int i;
+
+	if (con_is_present())
+		return 0;
+
+	for (i = 0; i < UART_NR; i++) {
+		int this_minor = sunsu_reg.minor + i;
+
+		if ((this_minor - 64) == (serial_console - 1))
+			break;
+	}
+	if (i == UART_NR)
+		return 0;
+	if (sunsu_ports[i].port_node == 0)
+		return 0;
+
+	sunsu_cons.index = i;
+	register_console(&sunsu_cons);
+	return 0;
+}
+
+static int __init sunsu_serial_init(void)
+{
+	int instance, ret, i;
+
+	/* How many instances do we need?  */
+	instance = 0;
+	for (i = 0; i < UART_NR; i++) {
+		struct uart_sunsu_port *up = &sunsu_ports[i];
+
+		if (up->su_type == SU_PORT_MS ||
+		    up->su_type == SU_PORT_KBD)
+			continue;
+
+		up->port.type = PORT_UNKNOWN;
+		up->port.uartclk = (SU_BASE_BAUD * 16);
+
+		sunsu_autoconfig(up);
+		if (up->port.type == PORT_UNKNOWN)
+			continue;
+
+		up->port.line = instance++;
+		up->port.ops = &sunsu_pops;
+	}
+
+	sunsu_reg.minor = sunserial_current_minor;
+	sunserial_current_minor += instance;
+
+	sunsu_reg.nr = instance;
+	sunsu_reg.cons = &sunsu_cons;
+
+	ret = uart_register_driver(&sunsu_reg);
+	if (ret < 0)
+		return ret;
+
+	instance = 0;
+	for (i = 0; i < UART_NR; i++) {
+		struct uart_sunsu_port *up = &sunsu_ports[i];
+
+		/* Do not register Keyboard/Mouse lines with UART
+		 * layer.
+		 */
+		if (up->su_type == SU_PORT_MS ||
+		    up->su_type == SU_PORT_KBD)
+			continue;
+
+		if (up->port.type == PORT_UNKNOWN)
+			continue;
+
+		uart_add_one_port(&sunsu_reg, &up->port);
+	}
+
+	return 0;
+}
+
+static int su_node_ok(int node, char *name, int namelen)
+{
+	if (strncmp(name, "su", namelen) == 0 ||
+	    strncmp(name, "su_pnp", namelen) == 0)
+		return 1;
+
+	if (strncmp(name, "serial", namelen) == 0) {
+		char compat[32];
+		int clen;
+
+		/* Is it _really_ a 'su' device? */
+		clen = prom_getproperty(node, "compatible", compat, sizeof(compat));
+		if (clen > 0) {
+			if (strncmp(compat, "sab82532", 8) == 0) {
+				/* Nope, Siemens serial, not for us. */
+				return 0;
+			}
+		}
+		return 1;
+	}
+
+	return 0;
+}
+
+#define SU_PROPSIZE	128
+
+/*
+ * Scan status structure.
+ * "prop" is a local variable but it eats stack to keep it in each
+ * stack frame of a recursive procedure.
+ */
+struct su_probe_scan {
+	int msnode, kbnode;	/* PROM nodes for mouse and keyboard */
+	int msx, kbx;		/* minors for mouse and keyboard */
+	int devices;		/* scan index */
+	char prop[SU_PROPSIZE];
+};
+
+/*
+ * We have several platforms which present 'su' in different parts
+ * of the device tree. 'su' may be found under obio, ebus, isa and pci.
+ * We walk over the tree and find them wherever PROM hides them.
+ */
+static void __init su_probe_any(struct su_probe_scan *t, int sunode)
+{
+	struct uart_sunsu_port *up;
+	int len;
+
+	if (t->devices >= UART_NR)
+		return;
+
+	for (; sunode != 0; sunode = prom_getsibling(sunode)) {
+		len = prom_getproperty(sunode, "name", t->prop, SU_PROPSIZE);
+		if (len <= 1)
+			continue;		/* Broken PROM node */
+
+		if (su_node_ok(sunode, t->prop, len)) {
+			up = &sunsu_ports[t->devices];
+			if (t->kbnode != 0 && sunode == t->kbnode) {
+				t->kbx = t->devices;
+				up->su_type = SU_PORT_KBD;
+			} else if (t->msnode != 0 && sunode == t->msnode) {
+				t->msx = t->devices;
+				up->su_type = SU_PORT_MS;
+			} else {
+#ifdef CONFIG_SPARC64
+				/*
+				 * Do not attempt to use the truncated
+				 * keyboard/mouse ports as serial ports
+				 * on Ultras with PC keyboard attached.
+				 */
+				if (prom_getbool(sunode, "mouse"))
+					continue;
+				if (prom_getbool(sunode, "keyboard"))
+					continue;
+#endif
+				up->su_type = SU_PORT_PORT;
+			}
+			up->port_node = sunode;
+			++t->devices;
+		} else {
+			su_probe_any(t, prom_getchild(sunode));
+		}
+	}
+}
+
+static int __init sunsu_probe(void)
+{
+	int node;
+	int len;
+	struct su_probe_scan scan;
+
+	/*
+	 * First, we scan the tree.
+	 */
+	scan.devices = 0;
+	scan.msx = -1;
+	scan.kbx = -1;
+	scan.kbnode = 0;
+	scan.msnode = 0;
+
+	/*
+	 * Get the nodes for keyboard and mouse from 'aliases'...
+	 */
+        node = prom_getchild(prom_root_node);
+	node = prom_searchsiblings(node, "aliases");
+	if (node != 0) {
+		len = prom_getproperty(node, "keyboard", scan.prop, SU_PROPSIZE);
+		if (len > 0) {
+			scan.prop[len] = 0;
+			scan.kbnode = prom_finddevice(scan.prop);
+		}
+
+		len = prom_getproperty(node, "mouse", scan.prop, SU_PROPSIZE);
+		if (len > 0) {
+			scan.prop[len] = 0;
+			scan.msnode = prom_finddevice(scan.prop);
+		}
+	}
+
+	su_probe_any(&scan, prom_getchild(prom_root_node));
+
+	/*
+	 * Second, we process the special case of keyboard and mouse.
+	 *
+	 * Currently if we got keyboard and mouse hooked to "su" ports
+	 * we do not use any possible remaining "su" as a serial port.
+	 * Thus, we ignore values of .msx and .kbx, then compact ports.
+	 */
+	if (scan.msx != -1 && scan.kbx != -1) {
+		sunsu_ports[0].su_type = SU_PORT_MS;
+		sunsu_ports[0].port_node = scan.msnode;
+		sunsu_ports[1].su_type = SU_PORT_KBD;
+		sunsu_ports[1].port_node = scan.kbnode;
+
+		sunsu_kbd_ms_init();
+		return 0;
+	}
+
+	if (scan.msx != -1 || scan.kbx != -1) {
+		printk("sunsu_probe: cannot match keyboard and mouse, confused\n");
+		return -ENODEV;
+	}
+
+	if (scan.devices == 0)
+		return -ENODEV;
+
+	/*
+	 * Console must be initiated after the generic initialization.
+	 */
+	sunsu_reg.cons = &sunsu_cons;
+	sunsu_reg.nr = scan.devices;
+
+       	sunsu_serial_init();
+	sunsu_serial_console_init();
+
+	return 0;
+}
+
+static void __exit sunsu_exit(void)
+{
+	int i, saw_uart;
+
+	saw_uart = 0;
+	for (i = 0; i < UART_NR; i++) {
+		struct uart_sunsu_port *up = &sunsu_ports[i];
+
+		if (up->su_type == SU_PORT_MS ||
+		    up->su_type == SU_PORT_KBD) {
+#ifdef CONFIG_SERIO
+			serio_unregister_port(&up->serio);
+#endif
+		} else if (up->port.type != PORT_UNKNOWN) {
+			uart_remove_one_port(&sunsu_reg, &up->port);
+			saw_uart++;
+		}
+	}
+
+	if (saw_uart)
+		uart_unregister_driver(&sunsu_reg);
+}
+
+module_init(sunsu_probe);
+module_exit(sunsu_exit);
diff -Nru a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/sunzilog.c	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,1730 @@
+/*
+ * sunzilog.c
+ *
+ * Driver for Zilog serial chips found on Sun workstations and
+ * servers.  This driver could actually be made more generic.
+ *
+ * This is based on the old drivers/sbus/char/zs.c code.  A lot
+ * of code has been simply moved over directly from there but
+ * much has been rewritten.  Credits therefore go out to Eddie
+ * C. Dost, Peter Zaitcev, Ted Ts'o and Alex Buell for their
+ * work there.
+ *
+ *  Copyright (C) 2002 David S. Miller (davem@redhat.com)
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/circ_buf.h>
+#include <linux/serial.h>
+#include <linux/console.h>
+#include <linux/spinlock.h>
+#ifdef CONFIG_SERIO
+#include <linux/serio.h>
+#endif
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#ifdef CONFIG_SPARC64
+#include <asm/fhc.h>
+#endif
+#include <asm/sbus.h>
+
+#include <linux/serial_core.h>
+
+#include "suncore.h"
+#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.
+ * On 64-bit sparc we only need to flush single writes to ensure
+ * completion.
+ */
+#ifndef CONFIG_SPARC64
+#define ZSDELAY()		udelay(5)
+#define ZSDELAY_LONG()		udelay(20)
+#define ZS_WSYNC(channel)	do { } while (0)
+#else
+#define ZSDELAY()
+#define ZSDELAY_LONG()
+#define ZS_WSYNC(__channel) \
+	sbus_readb(&((__channel)->control))
+#endif
+
+static int num_sunzilog;
+#define NUM_SUNZILOG	num_sunzilog
+#define NUM_CHANNELS	(NUM_SUNZILOG * 2)
+
+#define KEYBOARD_LINE 0x2
+#define MOUSE_LINE    0x3
+
+#define ZS_CLOCK		4915200 /* Zilog input clock rate. */
+#define ZS_CLOCK_DIVISOR	16      /* Divisor this driver uses. */
+
+/*
+ * We wrap our port structure around the generic uart_port.
+ */
+struct uart_sunzilog_port {
+	struct uart_port		port;
+
+	/* IRQ servicing chain.  */
+	struct uart_sunzilog_port	*next;
+
+	/* Current values of Zilog write registers.  */
+	unsigned char			curregs[NUM_ZSREGS];
+
+	unsigned int			flags;
+#define SUNZILOG_FLAG_CONS_KEYB		0x00000001
+#define SUNZILOG_FLAG_CONS_MOUSE	0x00000002
+#define SUNZILOG_FLAG_IS_CONS		0x00000004
+#define SUNZILOG_FLAG_IS_KGDB		0x00000008
+#define SUNZILOG_FLAG_MODEM_STATUS	0x00000010
+#define SUNZILOG_FLAG_IS_CHANNEL_A	0x00000020
+#define SUNZILOG_FLAG_REGS_HELD		0x00000040
+#define SUNZILOG_FLAG_TX_STOPPED	0x00000080
+#define SUNZILOG_FLAG_TX_ACTIVE		0x00000100
+
+	unsigned int cflag;
+
+	/* L1-A keyboard break state.  */
+	int				kbd_id;
+	int				l1_down;
+
+	unsigned char			parity_mask;
+	unsigned char			prev_status;
+
+#ifdef CONFIG_SERIO
+	struct serio			serio;
+#endif
+};
+
+#define ZILOG_CHANNEL_FROM_PORT(PORT)	((struct zilog_channel *)((PORT)->membase))
+#define UART_ZILOG(PORT)		((struct uart_sunzilog_port *)(PORT))
+#define SUNZILOG_GET_CURR_REG(PORT, REGNUM)		\
+	(UART_ZILOG(PORT)->curregs[REGNUM])
+#define SUNZILOG_SET_CURR_REG(PORT, REGNUM, REGVAL)	\
+	((UART_ZILOG(PORT)->curregs[REGNUM]) = (REGVAL))
+#define ZS_IS_KEYB(UP)	((UP)->flags & SUNZILOG_FLAG_CONS_KEYB)
+#define ZS_IS_MOUSE(UP)	((UP)->flags & SUNZILOG_FLAG_CONS_MOUSE)
+#define ZS_IS_CONS(UP)	((UP)->flags & SUNZILOG_FLAG_IS_CONS)
+#define ZS_IS_KGDB(UP)	((UP)->flags & SUNZILOG_FLAG_IS_KGDB)
+#define ZS_WANTS_MODEM_STATUS(UP)	((UP)->flags & SUNZILOG_FLAG_MODEM_STATUS)
+#define ZS_IS_CHANNEL_A(UP)	((UP)->flags & SUNZILOG_FLAG_IS_CHANNEL_A)
+#define ZS_REGS_HELD(UP)	((UP)->flags & SUNZILOG_FLAG_REGS_HELD)
+#define ZS_TX_STOPPED(UP)	((UP)->flags & SUNZILOG_FLAG_TX_STOPPED)
+#define ZS_TX_ACTIVE(UP)	((UP)->flags & SUNZILOG_FLAG_TX_ACTIVE)
+
+/* Reading and writing Zilog8530 registers.  The delays are to make this
+ * driver work on the Sun4 which needs a settling delay after each chip
+ * register access, other machines handle this in hardware via auxiliary
+ * flip-flops which implement the settle time we do in software.
+ *
+ * The port lock must be held and local IRQs must be disabled
+ * when {read,write}_zsreg is invoked.
+ */
+static unsigned char read_zsreg(struct zilog_channel *channel,
+				unsigned char reg)
+{
+	unsigned char retval;
+
+	sbus_writeb(reg, &channel->control);
+	ZSDELAY();
+	retval = sbus_readb(&channel->control);
+	ZSDELAY();
+
+	return retval;
+}
+
+static void write_zsreg(struct zilog_channel *channel,
+			unsigned char reg, unsigned char value)
+{
+	sbus_writeb(reg, &channel->control);
+	ZSDELAY();
+	sbus_writeb(value, &channel->control);
+	ZSDELAY();
+}
+
+static void sunzilog_clear_fifo(struct zilog_channel *channel)
+{
+	int i;
+
+	for (i = 0; i < 32; i++) {
+		unsigned char regval;
+
+		regval = sbus_readb(&channel->control);
+		ZSDELAY();
+		if (regval & Rx_CH_AV)
+			break;
+
+		regval = read_zsreg(channel, R1);
+		sbus_readb(&channel->data);
+		ZSDELAY();
+
+		if (regval & (PAR_ERR | Rx_OVR | CRC_ERR)) {
+			sbus_writeb(ERR_RES, &channel->control);
+			ZSDELAY();
+			ZS_WSYNC(channel);
+		}
+	}
+}
+
+/* This function must only be called when the TX is not busy.  The UART
+ * port lock must be held and local interrupts disabled.
+ */
+static void __load_zsregs(struct zilog_channel *channel, unsigned char *regs)
+{
+	int i;
+
+	/* Let pending transmits finish.  */
+	for (i = 0; i < 1000; i++) {
+		unsigned char stat = read_zsreg(channel, R1);
+		if (stat & ALL_SNT)
+			break;
+		udelay(100);
+	}
+
+	sbus_writeb(ERR_RES, &channel->control);
+	ZSDELAY();
+	ZS_WSYNC(channel);
+
+	sunzilog_clear_fifo(channel);
+
+	/* Disable all interrupts.  */
+	write_zsreg(channel, R1,
+		    regs[R1] & ~(RxINT_MASK | TxINT_ENAB | EXT_INT_ENAB));
+
+	/* Set parity, sync config, stop bits, and clock divisor.  */
+	write_zsreg(channel, R4, regs[R4]);
+
+	/* Set misc. TX/RX control bits.  */
+	write_zsreg(channel, R10, regs[R10]);
+
+	/* Set TX/RX controls sans the enable bits.  */
+	write_zsreg(channel, R3, regs[R3] & ~RxENAB);
+	write_zsreg(channel, R5, regs[R5] & ~TxENAB);
+
+	/* Synchronous mode config.  */
+	write_zsreg(channel, R6, regs[R6]);
+	write_zsreg(channel, R7, regs[R7]);
+
+	/* Don't mess with the interrupt vector (R2, unused by us) and
+	 * master interrupt control (R9).  We make sure this is setup
+	 * properly at probe time then never touch it again.
+	 */
+
+	/* Disable baud generator.  */
+	write_zsreg(channel, R14, regs[R14] & ~BRENAB);
+
+	/* Clock mode control.  */
+	write_zsreg(channel, R11, regs[R11]);
+
+	/* Lower and upper byte of baud rate generator divisor.  */
+	write_zsreg(channel, R12, regs[R12]);
+	write_zsreg(channel, R13, regs[R13]);
+	
+	/* Now rewrite R14, with BRENAB (if set).  */
+	write_zsreg(channel, R14, regs[R14]);
+
+	/* External status interrupt control.  */
+	write_zsreg(channel, R15, regs[R15]);
+
+	/* Reset external status interrupts.  */
+	write_zsreg(channel, R0, RES_EXT_INT);
+	write_zsreg(channel, R0, RES_EXT_INT);
+
+	/* Rewrite R3/R5, this time without enables masked.  */
+	write_zsreg(channel, R3, regs[R3]);
+	write_zsreg(channel, R5, regs[R5]);
+
+	/* Rewrite R1, this time without IRQ enabled masked.  */
+	write_zsreg(channel, R1, regs[R1]);
+}
+
+/* Reprogram the Zilog channel HW registers with the copies found in the
+ * software state struct.  If the transmitter is busy, we defer this update
+ * until the next TX complete interrupt.  Else, we do it right now.
+ *
+ * The UART port lock must be held and local interrupts disabled.
+ */
+static void sunzilog_maybe_update_regs(struct uart_sunzilog_port *up,
+				       struct zilog_channel *channel)
+{
+	if (!ZS_REGS_HELD(up)) {
+		if (ZS_TX_ACTIVE(up)) {
+			up->flags |= SUNZILOG_FLAG_REGS_HELD;
+		} else {
+			__load_zsregs(channel, up->curregs);
+		}
+	}
+}
+
+static void sunzilog_change_mouse_baud(struct uart_sunzilog_port *up)
+{
+	unsigned int cur_cflag = up->cflag;
+	int brg, new_baud;
+
+	up->cflag &= ~CBAUD;
+	up->cflag |= suncore_mouse_baud_cflag_next(cur_cflag, &new_baud);
+
+	brg = BPS_TO_BRG(new_baud,
+			 (ZS_CLOCK / ZS_CLOCK_DIVISOR));
+	up->curregs[R12] = (brg & 0xff);
+	up->curregs[R13] = (brg >> 8) & 0xff;
+	sunzilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(&up->port));
+}
+
+static void sunzilog_kbdms_receive_chars(struct uart_sunzilog_port *up,
+					 unsigned char ch, int is_break,
+					 struct pt_regs *regs)
+{
+	if (ZS_IS_KEYB(up)) {
+		if (ch == SUNKBD_RESET) {
+			up->kbd_id = 1;
+			up->l1_down = 0;
+		} else if (up->kbd_id) {
+			up->kbd_id = 0;
+		} else if (ch == SUNKBD_L1) {
+			up->l1_down = 1;
+		} else if (ch == (SUNKBD_L1 | SUNKBD_UP)) {
+			up->l1_down = 0;
+		} else if (ch == SUNKBD_A && up->l1_down) {
+			sun_do_break();
+			up->l1_down = 0;
+			up->kbd_id = 0;
+			return;
+		}
+		kbd_pt_regs = regs;
+#ifdef CONFIG_SERIO
+		serio_interrupt(&up->serio, ch, 0);
+#endif
+	} else if (ZS_IS_MOUSE(up)) {
+		int ret = suncore_mouse_baud_detection(ch, is_break);
+
+		switch (ret) {
+		case 2:
+			sunzilog_change_mouse_baud(up);
+			/* fallthru */
+		case 1:
+			break;
+
+		case 0:
+#ifdef CONFIG_SERIO
+			serio_interrupt(&up->serio, ch, 0);
+#endif
+			break;
+		};
+	}
+}
+
+static void sunzilog_receive_chars(struct uart_sunzilog_port *up,
+				   struct zilog_channel *channel,
+				   struct pt_regs *regs)
+{
+	struct tty_struct *tty = up->port.info->tty;
+
+	while (1) {
+		unsigned char ch, r1;
+
+		if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
+			tty->flip.tqueue.routine((void *)tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+				return;
+		}
+
+		r1 = read_zsreg(channel, R1);
+		if (r1 & (PAR_ERR | Rx_OVR | CRC_ERR)) {
+			sbus_writeb(ERR_RES, &channel->control);
+			ZSDELAY();
+			ZS_WSYNC(channel);
+		}
+
+		ch = sbus_readb(&channel->control);
+		ZSDELAY();
+
+		/* This funny hack depends upon BRK_ABRT not interfering
+		 * with the other bits we care about in R1.
+		 */
+		if (ch & BRK_ABRT)
+			r1 |= BRK_ABRT;
+
+		ch = sbus_readb(&channel->data);
+		ZSDELAY();
+
+		ch &= up->parity_mask;
+
+		if (unlikely(ZS_IS_KEYB(up)) || unlikely(ZS_IS_MOUSE(up))) {
+			sunzilog_kbdms_receive_chars(up, ch, 0, regs);
+			goto next_char;
+		}
+
+		if (ZS_IS_CONS(up) && (r1 & BRK_ABRT)) {
+			/* Wait for BREAK to deassert to avoid potentially
+			 * confusing the PROM.
+			 */
+			while (1) {
+				ch = sbus_readb(&channel->control);
+				ZSDELAY();
+				if (!(ch & BRK_ABRT))
+					break;
+			}
+			sun_do_break();
+			return;
+		}
+#ifndef CONFIG_SPARC64
+		/* Look for kgdb 'stop' character.  */
+		if (ZS_IS_KGDB(up) && (ch == '\003')) {
+			breakpoint();
+			return;
+		}
+#endif
+
+		/* A real serial line, record the character and status.  */
+		*tty->flip.char_buf_ptr = ch;
+		*tty->flip.flag_buf_ptr = TTY_NORMAL;
+		up->port.icount.rx++;
+		if (r1 & (BRK_ABRT | PAR_ERR | Rx_OVR | CRC_ERR)) {
+			if (r1 & BRK_ABRT) {
+				r1 &= ~(PAR_ERR | CRC_ERR);
+				up->port.icount.brk++;
+				if (uart_handle_break(&up->port))
+					goto next_char;
+			}
+			else if (r1 & PAR_ERR)
+				up->port.icount.parity++;
+			else if (r1 & CRC_ERR)
+				up->port.icount.frame++;
+			if (r1 & Rx_OVR)
+				up->port.icount.overrun++;
+			r1 &= up->port.read_status_mask;
+			if (r1 & BRK_ABRT)
+				*tty->flip.flag_buf_ptr = TTY_BREAK;
+			else if (r1 & PAR_ERR)
+				*tty->flip.flag_buf_ptr = TTY_PARITY;
+			else if (r1 & CRC_ERR)
+				*tty->flip.flag_buf_ptr = TTY_FRAME;
+		}
+		if (uart_handle_sysrq_char(&up->port, ch, regs))
+			goto next_char;
+
+		if (up->port.ignore_status_mask == 0xff ||
+		    (r1 & up->port.ignore_status_mask) == 0) {
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+		if ((r1 & Rx_OVR) &&
+		    tty->flip.count < TTY_FLIPBUF_SIZE) {
+			*tty->flip.flag_buf_ptr = TTY_OVERRUN;
+			tty->flip.flag_buf_ptr++;
+			tty->flip.char_buf_ptr++;
+			tty->flip.count++;
+		}
+	next_char:
+		ch = sbus_readb(&channel->control);
+		ZSDELAY();
+		if (!(ch & Rx_CH_AV))
+			break;
+	}
+
+	tty_flip_buffer_push(tty);
+}
+
+static void sunzilog_status_handle(struct uart_sunzilog_port *up,
+				   struct zilog_channel *channel,
+				   struct pt_regs *regs)
+{
+	unsigned char status;
+
+	status = sbus_readb(&channel->control);
+	ZSDELAY();
+
+	sbus_writeb(RES_EXT_INT, &channel->control);
+	ZSDELAY();
+	ZS_WSYNC(channel);
+
+	if ((status & BRK_ABRT) && ZS_IS_MOUSE(up))
+		sunzilog_kbdms_receive_chars(up, 0, 1, regs);
+
+	if (ZS_WANTS_MODEM_STATUS(up)) {
+		if (status & SYNC)
+			up->port.icount.dsr++;
+
+		/* The Zilog just gives us an interrupt when DCD/CTS/etc. change.
+		 * But it does not tell us which bit has changed, we have to keep
+		 * track of this ourselves.
+		 */
+		if ((status & DCD) ^ up->prev_status)
+			uart_handle_dcd_change(&up->port,
+					       (status & DCD));
+		if ((status & CTS) ^ up->prev_status)
+			uart_handle_cts_change(&up->port,
+					       (status & CTS));
+
+		wake_up_interruptible(&up->port.info->delta_msr_wait);
+	}
+
+	up->prev_status = status;
+}
+
+static void sunzilog_transmit_chars(struct uart_sunzilog_port *up,
+				    struct zilog_channel *channel)
+{
+	struct circ_buf *xmit = &up->port.info->xmit;
+
+	if (ZS_IS_CONS(up)) {
+		unsigned char status = sbus_readb(&channel->control);
+		ZSDELAY();
+
+		/* TX still busy?  Just wait for the next TX done interrupt.
+		 *
+		 * It can occur because of how we do serial console writes.  It would
+		 * be nice to transmit console writes just like we normally would for
+		 * a TTY line. (ie. buffered and TX interrupt driven).  That is not
+		 * easy because console writes cannot sleep.  One solution might be
+		 * to poll on enough port->xmit space becomming free.  -DaveM
+		 */
+		if (!(status & Tx_BUF_EMP))
+			return;
+	}
+
+	if (ZS_REGS_HELD(up)) {
+		__load_zsregs(channel, up->curregs);
+		up->flags &= ~SUNZILOG_FLAG_REGS_HELD;
+	}
+
+	if (ZS_TX_STOPPED(up)) {
+		up->flags &= ~SUNZILOG_FLAG_TX_STOPPED;
+		goto disable_tx_int;
+	}
+
+	if (up->port.x_char) {
+		sbus_writeb(up->port.x_char, &channel->data);
+		ZSDELAY();
+		ZS_WSYNC(channel);
+
+		up->port.icount.tx++;
+		up->port.x_char = 0;
+		return;
+	}
+
+	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port))
+		goto disable_tx_int;
+
+	sbus_writeb(xmit->buf[xmit->tail], &channel->data);
+	ZSDELAY();
+	ZS_WSYNC(channel);
+
+	xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+	up->port.icount.tx++;
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_event(&up->port, EVT_WRITE_WAKEUP);
+
+	if (!uart_circ_empty(xmit))
+		return;
+
+disable_tx_int:
+	up->curregs[R5] &= ~TxENAB;
+	write_zsreg(ZILOG_CHANNEL_FROM_PORT(&up->port), R5, up->curregs[R5]);
+}
+
+static void sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct uart_sunzilog_port *up = dev_id;
+
+	while (up) {
+		struct zilog_channel *channel
+			= ZILOG_CHANNEL_FROM_PORT(&up->port);
+		unsigned char r3;
+
+		spin_lock(&up->port.lock);
+		r3 = read_zsreg(channel, 3);
+
+		/* Channel A */
+		if (r3 & (CHAEXT | CHATxIP | CHARxIP)) {
+			sbus_writeb(RES_H_IUS, &channel->control);
+			ZSDELAY();
+			ZS_WSYNC(channel);
+
+			if (r3 & CHARxIP)
+				sunzilog_receive_chars(up, channel, regs);
+			if (r3 & CHAEXT)
+				sunzilog_status_handle(up, channel, regs);
+			if (r3 & CHATxIP)
+				sunzilog_transmit_chars(up, channel);
+		}
+		spin_unlock(&up->port.lock);
+
+		/* Channel B */
+		up = up->next;
+		channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
+
+		spin_lock(&up->port.lock);
+		if (r3 & (CHBEXT | CHBTxIP | CHBRxIP)) {
+			sbus_writeb(RES_H_IUS, &channel->control);
+			ZSDELAY();
+			ZS_WSYNC(channel);
+
+			if (r3 & CHBRxIP)
+				sunzilog_receive_chars(up, channel, regs);
+			if (r3 & CHBEXT)
+				sunzilog_status_handle(up, channel, regs);
+			if (r3 & CHBTxIP)
+				sunzilog_transmit_chars(up, channel);
+		}
+		spin_unlock(&up->port.lock);
+
+		up = up->next;
+	}
+}
+
+/* A convenient way to quickly get R0 status.  The caller must _not_ hold the
+ * port lock, it is acquired here.
+ */
+static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port)
+{
+	struct zilog_channel *channel;
+	unsigned long flags;
+	unsigned char status;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	channel = ZILOG_CHANNEL_FROM_PORT(port);
+	status = sbus_readb(&channel->control);
+	ZSDELAY();
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	return status;
+}
+
+/* The port lock is not held.  */
+static unsigned int sunzilog_tx_empty(struct uart_port *port)
+{
+	unsigned char status;
+	unsigned int ret;
+
+	status = sunzilog_read_channel_status(port);
+	if (status & Tx_BUF_EMP)
+		ret = TIOCSER_TEMT;
+	else
+		ret = 0;
+
+	return ret;
+}
+
+/* The port lock is not held.  */
+static unsigned int sunzilog_get_mctrl(struct uart_port *port)
+{
+	unsigned char status;
+	unsigned int ret;
+
+	status = sunzilog_read_channel_status(port);
+
+	ret = 0;
+	if (status & DCD)
+		ret |= TIOCM_CAR;
+	if (status & SYNC)
+		ret |= TIOCM_DSR;
+	if (status & CTS)
+		ret |= TIOCM_CTS;
+
+	return ret;
+}
+
+/* The port lock is held and interrupts are disabled.  */
+static void sunzilog_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+	struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port;
+	struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
+	unsigned char set_bits, clear_bits;
+
+	set_bits = clear_bits = 0;
+
+	if (mctrl & TIOCM_RTS)
+		set_bits |= RTS;
+	else
+		clear_bits |= RTS;
+	if (mctrl & TIOCM_DTR)
+		set_bits |= DTR;
+	else
+		clear_bits |= DTR;
+
+	/* NOTE: Not subject to 'transmitter active' rule.  */ 
+	up->curregs[R5] |= set_bits;
+	up->curregs[R5] &= ~clear_bits;
+	write_zsreg(channel, R5, up->curregs[R5]);
+}
+
+/* The port lock is held and interrupts are disabled.  */
+static void sunzilog_stop_tx(struct uart_port *port, unsigned int tty_stop)
+{
+	struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port;
+
+	up->flags |= SUNZILOG_FLAG_TX_STOPPED;
+}
+
+/* The port lock is held and interrupts are disabled.  */
+static void sunzilog_start_tx(struct uart_port *port, unsigned int tty_start)
+{
+	struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port;
+	struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
+	unsigned char status;
+
+	up->flags |= SUNZILOG_FLAG_TX_ACTIVE;
+	up->flags &= ~SUNZILOG_FLAG_TX_STOPPED;
+
+	/* Enable the transmitter.  */
+	if (!(up->curregs[R5] & TxENAB)) {
+		/* NOTE: Not subject to 'transmitter active' rule.  */ 
+		up->curregs[R5] |= TxENAB;
+		write_zsreg(channel, R5, up->curregs[R5]);
+	}
+
+	status = sbus_readb(&channel->control);
+	ZSDELAY();
+
+	/* TX busy?  Just wait for the TX done interrupt.  */
+	if (!(status & Tx_BUF_EMP))
+		return;
+
+	/* Send the first character to jump-start the TX done
+	 * IRQ sending engine.
+	 */
+	if (port->x_char) {
+		sbus_writeb(port->x_char, &channel->data);
+		ZSDELAY();
+		ZS_WSYNC(channel);
+
+		port->icount.tx++;
+		port->x_char = 0;
+	} else {
+		struct circ_buf *xmit = &port->info->xmit;
+
+		sbus_writeb(xmit->buf[xmit->tail], &channel->data);
+		ZSDELAY();
+		ZS_WSYNC(channel);
+
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+
+		if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+			uart_event(&up->port, EVT_WRITE_WAKEUP);
+	}
+}
+
+/* The port lock is not held.  */
+static void sunzilog_stop_rx(struct uart_port *port)
+{
+	struct uart_sunzilog_port *up = UART_ZILOG(port);
+	struct zilog_channel *channel;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	channel = ZILOG_CHANNEL_FROM_PORT(port);
+
+	/* Disable all RX interrupts.  */
+	up->curregs[R1] &= ~RxINT_MASK;
+	sunzilog_maybe_update_regs(up, channel);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/* The port lock is not held.  */
+static void sunzilog_enable_ms(struct uart_port *port)
+{
+	struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port;
+	struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
+	unsigned char new_reg;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	new_reg = up->curregs[R15] | (DCDIE | SYNCIE | CTSIE);
+	if (new_reg != up->curregs[R15]) {
+		up->curregs[R15] = new_reg;
+
+		/* NOTE: Not subject to 'transmitter active' rule.  */ 
+		write_zsreg(channel, R15, up->curregs[R15]);
+	}
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/* The port lock is not held.  */
+static void sunzilog_break_ctl(struct uart_port *port, int break_state)
+{
+	struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port;
+	struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port);
+	unsigned char set_bits, clear_bits, new_reg;
+	unsigned long flags;
+
+	set_bits = clear_bits = 0;
+
+	if (break_state)
+		set_bits |= SND_BRK;
+	else
+		clear_bits |= SND_BRK;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	new_reg = (up->curregs[R5] | set_bits) & ~clear_bits;
+	if (new_reg != up->curregs[R5]) {
+		up->curregs[R5] = new_reg;
+
+		/* NOTE: Not subject to 'transmitter active' rule.  */ 
+		write_zsreg(channel, R5, up->curregs[R5]);
+	}
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int sunzilog_startup(struct uart_port *port)
+{
+	struct uart_sunzilog_port *up = UART_ZILOG(port);
+	struct zilog_channel *channel;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	channel = ZILOG_CHANNEL_FROM_PORT(port);
+	up->prev_status = sbus_readb(&channel->control);
+
+	/* Enable receiver and transmitter.  */
+	up->curregs[R3] |= RxENAB;
+	up->curregs[R5] |= TxENAB;
+
+	/* Enable RX and status interrupts.  TX interrupts are enabled
+	 * as needed.
+	 */
+	up->curregs[R1] |= EXT_INT_ENAB | INT_ALL_Rx;
+	up->curregs[R9] |= MIE;
+	sunzilog_maybe_update_regs(up, channel);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+
+	return 0;
+}
+
+static void sunzilog_shutdown(struct uart_port *port)
+{
+	struct uart_sunzilog_port *up = UART_ZILOG(port);
+	struct zilog_channel *channel;
+	unsigned long flags;
+
+	spin_lock_irqsave(&port->lock, flags);
+
+	channel = ZILOG_CHANNEL_FROM_PORT(port);
+
+	/* Disable receiver and transmitter.  */
+	up->curregs[R3] &= ~RxENAB;
+	up->curregs[R5] &= ~TxENAB;
+
+	/* Disable all interrupts and BRK assertion.  */
+	up->curregs[R1] &= ~(EXT_INT_ENAB | TxINT_ENAB | RxINT_MASK);
+	up->curregs[R5] &= ~SND_BRK;
+	up->curregs[R9] &= ~MIE;
+	sunzilog_maybe_update_regs(up, channel);
+
+	spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/* Shared by TTY driver and serial console setup.  The port lock is held
+ * and local interrupts are disabled.
+ */
+static void
+sunzilog_convert_to_zs(struct uart_sunzilog_port *up, unsigned int cflag,
+		       unsigned int iflag, int brg)
+{
+
+	/* Don't modify MIE. */
+	up->curregs[R9] |= NV;
+
+	up->curregs[R10] = NRZ;
+	up->curregs[11] = TCBR | RCBR;
+
+	/* Program BAUD and clock source. */
+	up->curregs[4] &= ~XCLK_MASK;
+	up->curregs[4] |= X16CLK;
+	up->curregs[12] = brg & 0xff;
+	up->curregs[13] = (brg >> 8) & 0xff;
+	up->curregs[14] = BRSRC | BRENAB;
+
+	/* Character size, stop bits, and parity. */
+	up->curregs[3] &= ~RxN_MASK;
+	up->curregs[5] &= ~TxN_MASK;
+	switch (cflag & CSIZE) {
+	case CS5:
+		up->curregs[3] |= Rx5;
+		up->curregs[5] |= Tx5;
+		up->parity_mask = 0x1f;
+		break;
+	case CS6:
+		up->curregs[3] |= Rx6;
+		up->curregs[5] |= Tx6;
+		up->parity_mask = 0x3f;
+		break;
+	case CS7:
+		up->curregs[3] |= Rx7;
+		up->curregs[5] |= Tx7;
+		up->parity_mask = 0x7f;
+		break;
+	case CS8:
+	default:
+		up->curregs[3] |= Rx8;
+		up->curregs[5] |= Tx8;
+		up->parity_mask = 0xff;
+		break;
+	};
+	up->curregs[4] &= ~0x0c;
+	if (cflag & CSTOPB)
+		up->curregs[4] |= SB2;
+	else
+		up->curregs[4] |= SB1;
+	if (cflag & PARENB)
+		up->curregs[4] |= PAR_ENAB;
+	else
+		up->curregs[4] &= ~PAR_ENAB;
+	if (!(cflag & PARODD))
+		up->curregs[4] |= PAR_EVEN;
+	else
+		up->curregs[4] &= ~PAR_EVEN;
+
+	up->port.read_status_mask = Rx_OVR;
+	if (iflag & INPCK)
+		up->port.read_status_mask |= CRC_ERR | PAR_ERR;
+	if (iflag & (BRKINT | PARMRK))
+		up->port.read_status_mask |= BRK_ABRT;
+
+	up->port.ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		up->port.ignore_status_mask |= CRC_ERR | PAR_ERR;
+	if (iflag & IGNBRK) {
+		up->port.ignore_status_mask |= BRK_ABRT;
+		if (iflag & IGNPAR)
+			up->port.ignore_status_mask |= Rx_OVR;
+	}
+
+	if ((cflag & CREAD) == 0)
+		up->port.ignore_status_mask = 0xff;
+}
+
+/* The port lock is not held.  */
+static void
+sunzilog_change_speed(struct uart_port *port, unsigned int cflag,
+		      unsigned int iflag, unsigned int quot)
+{
+	struct uart_sunzilog_port *up = (struct uart_sunzilog_port *) port;
+	unsigned long flags;
+	int baud, brg;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	baud = (ZS_CLOCK / (quot * 16));
+	brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
+
+	sunzilog_convert_to_zs(up, cflag, iflag, brg);
+
+	if (UART_ENABLE_MS(&up->port, cflag))
+		up->flags |= SUNZILOG_FLAG_MODEM_STATUS;
+	else
+		up->flags &= ~SUNZILOG_FLAG_MODEM_STATUS;
+
+	up->cflag = cflag;
+
+	sunzilog_maybe_update_regs(up, ZILOG_CHANNEL_FROM_PORT(port));
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static const char *sunzilog_type(struct uart_port *port)
+{
+	return "SunZilog";
+}
+
+/* We do not request/release mappings of the registers here, this
+ * happens at early serial probe time.
+ */
+static void sunzilog_release_port(struct uart_port *port)
+{
+}
+
+static int sunzilog_request_port(struct uart_port *port)
+{
+	return 0;
+}
+
+/* These do not need to do anything interesting either.  */
+static void sunzilog_config_port(struct uart_port *port, int flags)
+{
+}
+
+/* We do not support letting the user mess with the divisor, IRQ, etc. */
+static int sunzilog_verify_port(struct uart_port *port, struct serial_struct *ser)
+{
+	return -EINVAL;
+}
+
+static struct uart_ops sunzilog_pops = {
+	.tx_empty	=	sunzilog_tx_empty,
+	.set_mctrl	=	sunzilog_set_mctrl,
+	.get_mctrl	=	sunzilog_get_mctrl,
+	.stop_tx	=	sunzilog_stop_tx,
+	.start_tx	=	sunzilog_start_tx,
+	.stop_rx	=	sunzilog_stop_rx,
+	.enable_ms	=	sunzilog_enable_ms,
+	.break_ctl	=	sunzilog_break_ctl,
+	.startup	=	sunzilog_startup,
+	.shutdown	=	sunzilog_shutdown,
+	.change_speed	=	sunzilog_change_speed,
+	.type		=	sunzilog_type,
+	.release_port	=	sunzilog_release_port,
+	.request_port	=	sunzilog_request_port,
+	.config_port	=	sunzilog_config_port,
+	.verify_port	=	sunzilog_verify_port,
+};
+
+static struct uart_sunzilog_port *sunzilog_port_table;
+static struct zilog_layout **sunzilog_chip_regs;
+static int *sunzilog_nodes;
+
+static struct uart_sunzilog_port *sunzilog_irq_chain;
+static int zilog_irq = -1;
+
+static struct uart_driver sunzilog_reg = {
+	.owner		=	THIS_MODULE,
+	.driver_name	=	"ttyS",
+#ifdef CONFIG_DEVFS_FS
+	.dev_name	=	"ttyS%d",
+#else
+	.dev_name	=	"ttyS",
+#endif
+	.major		=	TTY_MAJOR,
+};
+
+static void * __init alloc_one_table(unsigned long size)
+{
+	void *ret;
+
+	ret = kmalloc(size, GFP_KERNEL);
+	if (ret != NULL)
+		memset(ret, 0, size);
+
+	return ret;
+}
+
+static void __init sunzilog_alloc_tables(void)
+{
+	sunzilog_port_table = (struct uart_sunzilog_port *)
+		alloc_one_table(NUM_CHANNELS * sizeof(struct uart_sunzilog_port));
+	sunzilog_chip_regs = (struct zilog_layout **)
+		alloc_one_table(NUM_SUNZILOG * sizeof(struct zilog_layout *));
+	sunzilog_nodes = (int *)
+		alloc_one_table(NUM_SUNZILOG * sizeof(int));
+
+	if (sunzilog_port_table == NULL ||
+	    sunzilog_chip_regs == NULL ||
+	    sunzilog_nodes == NULL) {
+		prom_printf("sunzilog_init: Cannot alloc SunZilog tables.\n");
+		prom_halt();
+	}
+}
+
+#ifdef CONFIG_SPARC64
+
+/* We used to attempt to use the address property of the Zilog device node
+ * but that totally is not necessary on sparc64.
+ */
+static struct zilog_layout * __init get_zs_sun4u(int chip)
+{
+	unsigned long mapped_addr = 0xdeadbeefUL;
+	unsigned int sun4u_ino;
+	int busnode, zsnode, seen;
+
+	if (central_bus)
+		busnode = central_bus->child->prom_node;
+	else
+		busnode = prom_searchsiblings(prom_getchild(prom_root_node), "sbus");
+
+	if (busnode == 0 || busnode == -1) {
+		prom_printf("SunZilog: Cannot find bus of Zilog %d in get_zs_sun4u.\n",
+			    chip);
+		prom_halt();
+	}
+
+	zsnode = prom_getchild(busnode);
+	seen = 0;
+	while (zsnode) {
+		int slave;
+
+		zsnode = prom_searchsiblings(zsnode, "zs");
+		if (zsnode == 0 || zsnode == -1)
+			break;
+		slave = prom_getintdefault(zsnode, "slave", -1);
+		if ((slave == chip) || (seen == chip)) {
+			struct sbus_bus *sbus = NULL;
+			struct sbus_dev *sdev = NULL;
+			int err;
+
+			if (central_bus == NULL) {
+				for_each_sbus(sbus) {
+					for_each_sbusdev(sdev, sbus) {
+						if (sdev->prom_node == zsnode)
+							goto found;
+					}
+				}
+			}
+		found:
+			if (sdev == NULL && central_bus == NULL) {
+				prom_printf("SunZilog: sdev&&central == NULL for "
+					    "Zilog %d in get_zs_sun4u.\n", chip);
+				prom_halt();
+			}
+			if (central_bus == NULL) {
+				mapped_addr =
+					sbus_ioremap(&sdev->resource[0], 0,
+						     PAGE_SIZE,
+						     "Zilog Registers");
+			} else {
+				struct linux_prom_registers zsregs[1];
+
+				err = prom_getproperty(zsnode, "reg",
+						       (char *) &zsregs[0],
+						       sizeof(zsregs));
+				if (err == -1) {
+					prom_printf("SunZilog: Cannot map "
+						    "Zilog %d regs on "
+						    "central bus.\n", chip);
+					prom_halt();
+				}
+				apply_fhc_ranges(central_bus->child,
+						 &zsregs[0], 1);
+				apply_central_ranges(central_bus, &zsregs[0], 1);
+				mapped_addr =
+					(((u64)zsregs[0].which_io)<<32UL) |
+					((u64)zsregs[0].phys_addr);
+			}
+
+			sunzilog_nodes[chip] = zsnode;
+			if (zilog_irq == -1) {
+				if (central_bus) {
+					unsigned long iclr, imap;
+
+					iclr = central_bus->child->fhc_regs.uregs
+						+ FHC_UREGS_ICLR;
+					imap = central_bus->child->fhc_regs.uregs
+						+ FHC_UREGS_IMAP;
+					zilog_irq = build_irq(12, 0, iclr, imap);
+				} else {
+					err = prom_getproperty(zsnode, "interrupts",
+							       (char *) &sun4u_ino,
+							       sizeof(sun4u_ino));
+					zilog_irq = sbus_build_irq(sbus_root, sun4u_ino);
+				}
+			}
+			break;
+		}
+		zsnode = prom_getsibling(zsnode);
+		seen++;
+	}
+
+	if (zsnode == 0 || zsnode == -1) {
+		prom_printf("SunZilog: Cannot find Zilog %d in get_zs_sun4u.\n", chip);
+		prom_halt();
+	}
+
+	return (struct zilog_layout *) mapped_addr;
+}
+#else /* CONFIG_SPARC64 */
+static struct zilog_layout * __init get_zs_sun4cmd(int chip)
+{
+	struct linux_prom_irqs irq_info[2];
+	unsigned long mapped_addr;
+	int zsnode, chipid, cpunode;
+
+	if (sparc_cpu_model == sun4d) {
+		int bbnode, walk, no;
+
+		zsnode = 0;
+		bbnode = 0;
+		no = 0;
+		for (walk = prom_getchild(prom_root_node);
+		     (walk = prom_searchsiblings(walk, "cpu-unit")) != 0;
+		     walk = prom_getsibling(walk)) {
+			bbnode = prom_getchild(walk);
+			if (bbnode &&
+			    (bbnode = prom_searchsiblings(bbnode, "bootbus"))) {
+				if (no == (chip / 2)) {
+					cpunode = walk;
+					zsnode = prom_getchild(bbnode);
+					chipid = (chip & 1);
+					break;
+				}
+				no++;
+			}
+		}
+		if (!walk) {
+			prom_printf("SunZilog: Cannot find the %d'th bootbus on sun4d.\n",
+				    (chip / 2));
+			prom_halt();
+		}
+	} else {
+		int tmp;
+
+		zsnode = prom_getchild(prom_root_node);
+		if ((tmp = prom_searchsiblings(zsnode, "obio"))) {
+			zsnode = prom_getchild(tmp);
+			if (!zsnode) {
+				prom_printf("SunZilog: Child of obio node does "
+					    "not exist.\n");
+				prom_halt();
+			}
+		}
+		chipid = 0;
+	}
+
+	while (zsnode) {
+		struct linux_prom_registers zsreg[4];
+		struct resource res;
+
+		zsnode = prom_searchsiblings(zsnode, "zs");
+		if (zsnode == 0 || zsnode == -1)
+			break;
+
+		if (prom_getintdefault(zsnode, "slave", -1) != chipid) {
+			zsnode = prom_getsibling(zsnode);
+			continue;
+		}
+
+		if (sparc_cpu_model == sun4d) {
+			/* Sun4d Zilog nodes lack the address property, so just
+			 * map it like a normal device.
+			 */
+			if (prom_getproperty(zsnode, "reg",
+					     (char *) zsreg, sizeof(zsreg)) == -1) {
+				prom_printf("SunZilog: Cannot map Zilog %d "
+					    "regs on sun4c.\n", chip);
+				prom_halt();
+			}
+			prom_apply_generic_ranges(bbnode, cpunode, zsreg, 1);
+			res.start = zsreg[0].phys_addr;
+			res.end = res.start + (8 - 1);
+			res.flags = zsreg[0].which_io | IORESOURCE_IO;
+			mapped_addr = sbus_ioremap(&res, 0, 8, "Zilog Serial");
+		} else {
+			unsigned int vaddr[2];
+
+			if (prom_getproperty(zsnode, "address",
+					     (void *) vaddr, sizeof(vaddr))
+			    % sizeof(unsigned int)) {
+				prom_printf("SunZilog: Cannot get address property for "
+					    "Zilog %d.\n", chip);
+				prom_halt();
+			}
+			mapped_addr = (unsigned long) vaddr[0];
+		}
+		sunzilog_nodes[chip] = zsnode;
+		if (prom_getproperty(zsnode, "intr",
+				     (char *) irq_info, sizeof(irq_info))
+		    % sizeof(struct linux_prom_irqs)) {
+			prom_printf("SunZilog: Cannot get IRQ property for "
+				    "Zilog %d.\n", chip);
+			prom_halt();
+		}
+		if (zilog_irq == -1) {
+			zilog_irq = irq_info[0].pri;
+		} else if (zilog_irq != irq_info[0].pri) {
+			prom_printf("SunZilog: Inconsistent IRQ layout for Zilog %d.\n",
+				    chip);
+			promt_halt();
+		}
+		break;
+	}
+	if (!zsnode) {
+		prom_printf("SunZilog: OBP node for Zilog %d not found.\n", chip);
+		prom_halt();
+	}
+
+	return (struct zilog_layout *) mapped_addr;
+}
+#endif /* !(CONFIG_SPARC64) */
+
+/* Get the address of the registers for SunZilog instance CHIP.  */
+static struct zilog_layout * __init get_zs(int chip)
+{
+	if (chip < 0 || chip >= NUM_SUNZILOG) {
+		prom_printf("SunZilog: Illegal chip number %d in get_zs.\n", chip);
+		prom_halt();
+	}
+
+#ifdef CONFIG_SPARC64
+	return get_zs_sun4u(chip);
+#else
+
+	if (sparc_cpu_model == sun4) {
+		struct resource res;
+
+		/* Not probe-able, hard code it. */
+		switch (chip) {
+		case 0:
+			res.start = 0xf1000000;
+			break;
+		case 1:
+			res.start = 0xf0000000;
+			break;
+		};
+		sunzilog_nodes[chip] = 0;
+		zilog_irq = 12;
+		res.end = (res.start + (8 - 1));
+		res.flags = IORESOURCE_IO;
+		return sbus_ioremap(&res, 0, 8, "SunZilog");
+	}
+
+	return get_zs_sun4cmd(chip);
+#endif
+}
+
+#define ZS_PUT_CHAR_MAX_DELAY	2000	/* 10 ms */
+
+static void sunzilog_put_char(struct zilog_channel *channel, unsigned char ch)
+{
+	int loops = ZS_PUT_CHAR_MAX_DELAY;
+
+	/* This is a timed polling loop so do not switch the explicit
+	 * udelay with ZSDELAY as that is a NOP on some platforms.  -DaveM
+	 */
+	do {
+		unsigned char val = sbus_readb(&channel->control);
+		if (val & Tx_BUF_EMP) {
+			ZSDELAY();
+			break;
+		}
+		udelay(5);
+	} while (--loops);
+
+	sbus_writeb(ch, &channel->data);
+	ZSDELAY();
+	ZS_WSYNC(channel);
+}
+
+#ifdef CONFIG_SERIO
+
+static spinlock_t sunzilog_serio_lock = SPIN_LOCK_UNLOCKED;
+
+static int sunzilog_serio_write(struct serio *serio, unsigned char ch)
+{
+	struct uart_sunzilog_port *up = serio->driver;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sunzilog_serio_lock, flags);
+
+	sunzilog_put_char(ZILOG_CHANNEL_FROM_PORT(&up->port), ch);
+
+	spin_unlock_irqrestore(&sunzilog_serio_lock, flags);
+
+	return 0;
+}
+
+static int sunzilog_serio_open(struct serio *serio)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&sunzilog_serio_lock, flags);
+	if (serio->private == NULL) {
+		serio->private = (void *) -1L;
+		ret = 0;
+	} else
+		ret = -EBUSY;
+	spin_unlock_irqrestore(&sunzilog_serio_lock, flags);
+
+	return ret;
+}
+
+static void sunzilog_serio_close(struct serio *serio)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&sunzilog_serio_lock, flags);
+	serio->private = NULL;
+	spin_unlock_irqrestore(&sunzilog_serio_lock, flags);
+}
+
+#endif /* CONFIG_SERIO */
+
+static void
+sunzilog_console_write(struct console *con, const char *s, unsigned int count)
+{
+	struct uart_sunzilog_port *up = &sunzilog_port_table[con->index];
+	struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&up->port.lock, flags);
+	for (i = 0; i < count; i++, s++) {
+		sunzilog_put_char(channel, *s);
+		if (*s == 10)
+			sunzilog_put_char(channel, 13);
+	}
+	udelay(2);
+	spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static kdev_t sunzilog_console_device(struct console *con)
+{
+	return mk_kdev(sunzilog_reg.major, sunzilog_reg.minor + con->index);
+}
+
+static int __init sunzilog_console_setup(struct console *con, char *options)
+{
+	struct uart_sunzilog_port *up = &sunzilog_port_table[con->index];
+	unsigned long flags;
+	int baud, brg;
+
+	printk("Console: ttyS%d (Zilog8530)\n",
+	       (sunzilog_reg.minor - 64) + con->index);
+
+	/* Get firmware console settings.  */
+	sunserial_console_termios(con);
+
+	/* Firmware console speed is limited to 150-->38400 baud so
+	 * this hackish cflag thing is OK.
+	 */
+	switch (con->cflag & CBAUD) {
+	case B150: baud = 150; break;
+	case B300: baud = 300; break;
+	case B600: baud = 600; break;
+	case B1200: baud = 1200; break;
+	case B2400: baud = 2400; break;
+	case B4800: baud = 4800; break;
+	default: case B9600: baud = 9600; break;
+	case B19200: baud = 19200; break;
+	case B38400: baud = 38400; break;
+	};
+
+	brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
+
+	/*
+	 * Temporary fix.
+	 */
+	spin_lock_init(&up->port.lock);
+
+	spin_lock_irqsave(&up->port.lock, flags);
+
+	up->curregs[R15] = BRKIE;
+
+	sunzilog_convert_to_zs(up, con->cflag, 0, brg);
+
+	spin_unlock_irqrestore(&up->port.lock, flags);
+
+	sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
+	sunzilog_startup(&up->port);
+
+	return 0;
+}
+
+static struct console sunzilog_console = {
+	.name	=	"ttyS",
+	.write	=	sunzilog_console_write,
+	.device	=	sunzilog_console_device,
+	.setup	=	sunzilog_console_setup,
+	.flags	=	CON_PRINTBUFFER,
+	.index	=	-1,
+};
+
+static int __init sunzilog_console_init(void)
+{
+	int i;
+
+	if (con_is_present())
+		return 0;
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		int this_minor = sunzilog_reg.minor + i;
+
+		if ((this_minor - 64) == (serial_console - 1))
+			break;
+	}
+	if (i == NUM_CHANNELS)
+		return 0;
+
+	sunzilog_console.index = i;
+	register_console(&sunzilog_console);
+	return 0;
+}
+
+static void __init sunzilog_prepare(void)
+{
+	struct uart_sunzilog_port *up;
+	struct zilog_layout *rp;
+	int channel, chip;
+
+	sunzilog_irq_chain = up = &sunzilog_port_table[0];
+	for (channel = 0; channel < NUM_CHANNELS - 1; channel++)
+		up[channel].next = &up[channel + 1];
+	up[channel].next = NULL;
+
+	for (chip = 0; chip < NUM_SUNZILOG; chip++) {
+		if (!sunzilog_chip_regs[chip]) {
+			sunzilog_chip_regs[chip] = rp = get_zs(chip);
+
+			up[(chip * 2) + 0].port.membase = (char *) &rp->channelA;
+			up[(chip * 2) + 1].port.membase = (char *) &rp->channelB;
+		}
+
+		/* Channel A */
+		up[(chip * 2) + 0].port.iotype = SERIAL_IO_MEM;
+		up[(chip * 2) + 0].port.irq = zilog_irq;
+		up[(chip * 2) + 0].port.uartclk = ZS_CLOCK;
+		up[(chip * 2) + 0].port.fifosize = 1;
+		up[(chip * 2) + 0].port.ops = &sunzilog_pops;
+		up[(chip * 2) + 0].port.type = PORT_SUNZILOG;
+		up[(chip * 2) + 0].port.flags = 0;
+		up[(chip * 2) + 0].port.line = (chip * 2) + 0;
+		up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
+
+		/* Channel B */
+		up[(chip * 2) + 1].port.iotype = SERIAL_IO_MEM;
+		up[(chip * 2) + 1].port.irq = zilog_irq;
+		up[(chip * 2) + 1].port.uartclk = ZS_CLOCK;
+		up[(chip * 2) + 1].port.fifosize = 1;
+		up[(chip * 2) + 1].port.ops = &sunzilog_pops;
+		up[(chip * 2) + 1].port.type = PORT_SUNZILOG;
+		up[(chip * 2) + 1].port.flags = 0;
+		up[(chip * 2) + 1].port.line = (chip * 2) + 1;
+		up[(chip * 2) + 1].flags |= 0;
+	}
+}
+
+static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channel)
+{
+	int baud, brg;
+
+	if (channel == KEYBOARD_LINE) {
+		up->flags |= SUNZILOG_FLAG_CONS_KEYB;
+		up->cflag = B1200 | CS8 | CLOCAL | CREAD;
+		baud = 1200;
+	} else {
+		up->flags |= SUNZILOG_FLAG_CONS_MOUSE;
+		up->cflag = B4800 | CS8 | CLOCAL | CREAD;
+		baud = 4800;
+	}
+	printk(KERN_INFO "zs%d at 0x%p (irq = %s) is a Zilog8530\n",
+	       channel, up->port.membase, __irq_itoa(zilog_irq));
+
+	up->curregs[R15] = BRKIE;
+	brg = BPS_TO_BRG(baud, ZS_CLOCK / ZS_CLOCK_DIVISOR);
+	sunzilog_convert_to_zs(up, up->cflag, 0, brg);
+
+#ifdef CONFIG_SERIO
+	memset(&up->serio, 0, sizeof(up->serio));
+
+	up->serio.driver = up;
+
+	up->serio.type = SERIO_RS232;
+	if (channel == KEYBOARD_LINE) {
+		up->serio.type |= SERIO_SUNKBD;
+		up->serio.name = "zskbd";
+	} else {
+		up->serio.type |= SERIO_SUN;
+		up->serio.name = "zsms";
+	}
+	up->serio.phys = (channel == KEYBOARD_LINE ?
+			  "zs/serio0" : "zs/serio1");
+
+	up->serio.write = sunzilog_serio_write;
+	up->serio.open = sunzilog_serio_open;
+	up->serio.close = sunzilog_serio_close;
+
+	serio_register_port(&up->serio);
+#endif
+
+	spin_unlock(&up->port.lock);
+	sunzilog_set_mctrl(&up->port, TIOCM_DTR | TIOCM_RTS);
+	sunzilog_startup(&up->port);
+	spin_lock(&up->port.lock);
+}
+
+static void __init sunzilog_init_hw(void)
+{
+	int i;
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		struct uart_sunzilog_port *up = &sunzilog_port_table[i];
+		struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(&up->port);
+		unsigned long flags;
+		int baud, brg;
+
+		spin_lock_irqsave(&up->port.lock, flags);
+
+		if (ZS_IS_CHANNEL_A(up)) {
+			write_zsreg(channel, R9, FHWRES);
+			ZSDELAY_LONG();
+			(void) read_zsreg(channel, R0);
+		}
+
+		if (i == KEYBOARD_LINE || i == MOUSE_LINE) {
+			sunzilog_init_kbdms(up, i);
+		} else if (ZS_IS_CONS(up)) {
+			/* sunzilog_console_setup takes care of this */
+		} else {
+			/* Normal serial TTY. */
+			up->parity_mask = 0xff;
+			up->curregs[R3] = RxENAB;
+			up->curregs[R5] = TxENAB;
+			up->curregs[R9] = NV | MIE;
+			up->curregs[R10] = NRZ;
+			up->curregs[R11] = TCBR | RCBR;
+			baud = 9600;
+			brg = BPS_TO_BRG(baud, (ZS_CLOCK / ZS_CLOCK_DIVISOR));
+			up->curregs[R12] = (brg & 0xff);
+			up->curregs[R13] = (brg >> 8) & 0xff;
+			up->curregs[R14] = BRSRC | BRENAB;
+			sunzilog_maybe_update_regs(up, channel);
+		}
+
+		spin_unlock_irqrestore(&up->port.lock, flags);
+	}
+}
+
+static int __init sunzilog_ports_init(void)
+{
+	int ret;
+
+	printk(KERN_INFO "Serial: Sun Zilog driver.\n");
+
+	sunzilog_prepare();
+
+	if (request_irq(zilog_irq, sunzilog_interrupt, SA_SHIRQ,
+			"SunZilog", sunzilog_irq_chain)) {
+		prom_printf("SunZilog: Unable to register zs interrupt handler.\n");
+		prom_halt();
+	}
+
+	sunzilog_init_hw();
+
+	/* We can only init this once we have probed the Zilogs
+	 * in the system.
+	 */
+	sunzilog_reg.nr = NUM_CHANNELS;
+	sunzilog_reg.cons = &sunzilog_console;
+
+	sunzilog_reg.minor = sunserial_current_minor;
+	sunserial_current_minor += NUM_CHANNELS;
+
+	ret = uart_register_driver(&sunzilog_reg);
+	if (ret == 0) {
+		int i;
+
+		for (i = 0; i < NUM_CHANNELS; i++) {
+			struct uart_sunzilog_port *up = &sunzilog_port_table[i];
+
+			if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up))
+				continue;
+
+			uart_add_one_port(&sunzilog_reg, &up->port);
+		}
+	}
+
+	return ret;
+}
+
+static int __init sunzilog_init(void)
+{
+	int node;
+
+	/* Sun4 Zilog setup is hard coded, no probing to do.  */
+	if (sparc_cpu_model == sun4) {
+		NUM_SUNZILOG = 2;
+		goto no_probe;
+	}
+
+	node = prom_getchild(prom_root_node);
+	if (sparc_cpu_model == sun4d) {
+		int bbnode;
+
+		NUM_SUNZILOG = 0;
+		while (node &&
+		       (node = prom_searchsiblings(node, "cpu-unit"))) {
+			bbnode = prom_getchild(node);
+			if (bbnode && prom_searchsiblings(bbnode, "bootbus"))
+				NUM_SUNZILOG += 2;
+			node = prom_getsibling(node);
+		}
+		goto no_probe;
+	} else if (sparc_cpu_model == sun4u) {
+		int central_node;
+
+		/* Central bus zilogs must be checked for first,
+		 * since Enterprise boxes might have SBUSes as well.
+		 */
+		central_node = prom_finddevice("/central");
+		if (central_node != 0 && central_node != -1)
+			node = prom_searchsiblings(prom_getchild(central_node), "fhc");
+		else
+			node = prom_searchsiblings(node, "sbus");
+		if (node != 0 && node != -1)
+			node = prom_getchild(node);
+		if (node == 0 || node == -1)
+			return -ENODEV;
+	} else {
+		node = prom_searchsiblings(node, "obio");
+		if (node)
+			node = prom_getchild(node);
+		NUM_SUNZILOG = 2;
+		goto no_probe;
+	}
+
+	node = prom_searchsiblings(node, "zs");
+	if (!node)
+		return -ENODEV;
+		
+	NUM_SUNZILOG = 2;
+
+no_probe:
+
+	sunzilog_alloc_tables();
+
+	sunzilog_ports_init();
+	sunzilog_console_init();
+
+	return 0;
+}
+
+static void __exit sunzilog_exit(void)
+{
+	int i;
+
+	for (i = 0; i < NUM_CHANNELS; i++) {
+		struct uart_sunzilog_port *up = &sunzilog_port_table[i];
+
+		if (ZS_IS_KEYB(up) || ZS_IS_MOUSE(up))
+			continue;
+
+		uart_remove_one_port(&sunzilog_reg, &up->port);
+	}
+
+	uart_unregister_driver(&sunzilog_reg);
+}
+
+module_init(sunzilog_init);
+module_exit(sunzilog_exit);
+
+EXPORT_NO_SYMBOLS;
+
+MODULE_AUTHOR("David S. Miller");
+MODULE_DESCRIPTION("Sun Zilog serial port driver");
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/serial/sunzilog.h b/drivers/serial/sunzilog.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/serial/sunzilog.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,272 @@
+#ifndef _SUNZILOG_H
+#define _SUNZILOG_H
+
+struct zilog_channel {
+	volatile unsigned char control;
+	volatile unsigned char __pad1;
+	volatile unsigned char data;
+	volatile unsigned char __pad2;
+};
+
+struct zilog_layout {
+	struct zilog_channel channelB;
+	struct zilog_channel channelA;
+};
+
+#define NUM_ZSREGS    16
+
+/* Conversion routines to/from brg time constants from/to bits
+ * per second.
+ */
+#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2))
+#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2)
+
+/* The Zilog register set */
+
+#define	FLAG	0x7e
+
+/* Write Register 0 */
+#define	R0	0		/* Register selects */
+#define	R1	1
+#define	R2	2
+#define	R3	3
+#define	R4	4
+#define	R5	5
+#define	R6	6
+#define	R7	7
+#define	R8	8
+#define	R9	9
+#define	R10	10
+#define	R11	11
+#define	R12	12
+#define	R13	13
+#define	R14	14
+#define	R15	15
+
+#define	NULLCODE	0	/* Null Code */
+#define	POINT_HIGH	0x8	/* Select upper half of registers */
+#define	RES_EXT_INT	0x10	/* Reset Ext. Status Interrupts */
+#define	SEND_ABORT	0x18	/* HDLC Abort */
+#define	RES_RxINT_FC	0x20	/* Reset RxINT on First Character */
+#define	RES_Tx_P	0x28	/* Reset TxINT Pending */
+#define	ERR_RES		0x30	/* Error Reset */
+#define	RES_H_IUS	0x38	/* Reset highest IUS */
+
+#define	RES_Rx_CRC	0x40	/* Reset Rx CRC Checker */
+#define	RES_Tx_CRC	0x80	/* Reset Tx CRC Checker */
+#define	RES_EOM_L	0xC0	/* Reset EOM latch */
+
+/* Write Register 1 */
+
+#define	EXT_INT_ENAB	0x1	/* Ext Int Enable */
+#define	TxINT_ENAB	0x2	/* Tx Int Enable */
+#define	PAR_SPEC	0x4	/* Parity is special condition */
+
+#define	RxINT_DISAB	0	/* Rx Int Disable */
+#define	RxINT_FCERR	0x8	/* Rx Int on First Character Only or Error */
+#define	INT_ALL_Rx	0x10	/* Int on all Rx Characters or error */
+#define	INT_ERR_Rx	0x18	/* Int on error only */
+#define RxINT_MASK	0x18
+
+#define	WT_RDY_RT	0x20	/* Wait/Ready on R/T */
+#define	WT_FN_RDYFN	0x40	/* Wait/FN/Ready FN */
+#define	WT_RDY_ENAB	0x80	/* Wait/Ready Enable */
+
+/* Write Register #2 (Interrupt Vector) */
+
+/* Write Register 3 */
+
+#define	RxENAB  	0x1	/* Rx Enable */
+#define	SYNC_L_INH	0x2	/* Sync Character Load Inhibit */
+#define	ADD_SM		0x4	/* Address Search Mode (SDLC) */
+#define	RxCRC_ENAB	0x8	/* Rx CRC Enable */
+#define	ENT_HM		0x10	/* Enter Hunt Mode */
+#define	AUTO_ENAB	0x20	/* Auto Enables */
+#define	Rx5		0x0	/* Rx 5 Bits/Character */
+#define	Rx7		0x40	/* Rx 7 Bits/Character */
+#define	Rx6		0x80	/* Rx 6 Bits/Character */
+#define	Rx8		0xc0	/* Rx 8 Bits/Character */
+#define RxN_MASK	0xc0
+
+/* Write Register 4 */
+
+#define	PAR_ENAB	0x1	/* Parity Enable */
+#define	PAR_EVEN	0x2	/* Parity Even/Odd* */
+
+#define	SYNC_ENAB	0	/* Sync Modes Enable */
+#define	SB1		0x4	/* 1 stop bit/char */
+#define	SB15		0x8	/* 1.5 stop bits/char */
+#define	SB2		0xc	/* 2 stop bits/char */
+
+#define	MONSYNC		0	/* 8 Bit Sync character */
+#define	BISYNC		0x10	/* 16 bit sync character */
+#define	SDLC		0x20	/* SDLC Mode (01111110 Sync Flag) */
+#define	EXTSYNC		0x30	/* External Sync Mode */
+
+#define	X1CLK		0x0	/* x1 clock mode */
+#define	X16CLK		0x40	/* x16 clock mode */
+#define	X32CLK		0x80	/* x32 clock mode */
+#define	X64CLK		0xC0	/* x64 clock mode */
+#define XCLK_MASK	0xC0
+
+/* Write Register 5 */
+
+#define	TxCRC_ENAB	0x1	/* Tx CRC Enable */
+#define	RTS		0x2	/* RTS */
+#define	SDLC_CRC	0x4	/* SDLC/CRC-16 */
+#define	TxENAB		0x8	/* Tx Enable */
+#define	SND_BRK		0x10	/* Send Break */
+#define	Tx5		0x0	/* Tx 5 bits (or less)/character */
+#define	Tx7		0x20	/* Tx 7 bits/character */
+#define	Tx6		0x40	/* Tx 6 bits/character */
+#define	Tx8		0x60	/* Tx 8 bits/character */
+#define TxN_MASK	0x60
+#define	DTR		0x80	/* DTR */
+
+/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */
+
+/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */
+
+/* Write Register 8 (transmit buffer) */
+
+/* Write Register 9 (Master interrupt control) */
+#define	VIS	1	/* Vector Includes Status */
+#define	NV	2	/* No Vector */
+#define	DLC	4	/* Disable Lower Chain */
+#define	MIE	8	/* Master Interrupt Enable */
+#define	STATHI	0x10	/* Status high */
+#define	NORESET	0	/* No reset on write to R9 */
+#define	CHRB	0x40	/* Reset channel B */
+#define	CHRA	0x80	/* Reset channel A */
+#define	FHWRES	0xc0	/* Force hardware reset */
+
+/* Write Register 10 (misc control bits) */
+#define	BIT6	1	/* 6 bit/8bit sync */
+#define	LOOPMODE 2	/* SDLC Loop mode */
+#define	ABUNDER	4	/* Abort/flag on SDLC xmit underrun */
+#define	MARKIDLE 8	/* Mark/flag on idle */
+#define	GAOP	0x10	/* Go active on poll */
+#define	NRZ	0	/* NRZ mode */
+#define	NRZI	0x20	/* NRZI mode */
+#define	FM1	0x40	/* FM1 (transition = 1) */
+#define	FM0	0x60	/* FM0 (transition = 0) */
+#define	CRCPS	0x80	/* CRC Preset I/O */
+
+/* Write Register 11 (Clock Mode control) */
+#define	TRxCXT	0	/* TRxC = Xtal output */
+#define	TRxCTC	1	/* TRxC = Transmit clock */
+#define	TRxCBR	2	/* TRxC = BR Generator Output */
+#define	TRxCDP	3	/* TRxC = DPLL output */
+#define	TRxCOI	4	/* TRxC O/I */
+#define	TCRTxCP	0	/* Transmit clock = RTxC pin */
+#define	TCTRxCP	8	/* Transmit clock = TRxC pin */
+#define	TCBR	0x10	/* Transmit clock = BR Generator output */
+#define	TCDPLL	0x18	/* Transmit clock = DPLL output */
+#define	RCRTxCP	0	/* Receive clock = RTxC pin */
+#define	RCTRxCP	0x20	/* Receive clock = TRxC pin */
+#define	RCBR	0x40	/* Receive clock = BR Generator output */
+#define	RCDPLL	0x60	/* Receive clock = DPLL output */
+#define	RTxCX	0x80	/* RTxC Xtal/No Xtal */
+
+/* Write Register 12 (lower byte of baud rate generator time constant) */
+
+/* Write Register 13 (upper byte of baud rate generator time constant) */
+
+/* Write Register 14 (Misc control bits) */
+#define	BRENAB 	1	/* Baud rate generator enable */
+#define	BRSRC	2	/* Baud rate generator source */
+#define	DTRREQ	4	/* DTR/Request function */
+#define	AUTOECHO 8	/* Auto Echo */
+#define	LOOPBAK	0x10	/* Local loopback */
+#define	SEARCH	0x20	/* Enter search mode */
+#define	RMC	0x40	/* Reset missing clock */
+#define	DISDPLL	0x60	/* Disable DPLL */
+#define	SSBR	0x80	/* Set DPLL source = BR generator */
+#define	SSRTxC	0xa0	/* Set DPLL source = RTxC */
+#define	SFMM	0xc0	/* Set FM mode */
+#define	SNRZI	0xe0	/* Set NRZI mode */
+
+/* Write Register 15 (external/status interrupt control) */
+#define	ZCIE	2	/* Zero count IE */
+#define	DCDIE	8	/* DCD IE */
+#define	SYNCIE	0x10	/* Sync/hunt IE */
+#define	CTSIE	0x20	/* CTS IE */
+#define	TxUIE	0x40	/* Tx Underrun/EOM IE */
+#define	BRKIE	0x80	/* Break/Abort IE */
+
+
+/* Read Register 0 */
+#define	Rx_CH_AV	0x1	/* Rx Character Available */
+#define	ZCOUNT		0x2	/* Zero count */
+#define	Tx_BUF_EMP	0x4	/* Tx Buffer empty */
+#define	DCD		0x8	/* DCD */
+#define	SYNC		0x10	/* Sync/hunt */
+#define	CTS		0x20	/* CTS */
+#define	TxEOM		0x40	/* Tx underrun */
+#define	BRK_ABRT	0x80	/* Break/Abort */
+
+/* Read Register 1 */
+#define	ALL_SNT		0x1	/* All sent */
+/* Residue Data for 8 Rx bits/char programmed */
+#define	RES3		0x8	/* 0/3 */
+#define	RES4		0x4	/* 0/4 */
+#define	RES5		0xc	/* 0/5 */
+#define	RES6		0x2	/* 0/6 */
+#define	RES7		0xa	/* 0/7 */
+#define	RES8		0x6	/* 0/8 */
+#define	RES18		0xe	/* 1/8 */
+#define	RES28		0x0	/* 2/8 */
+/* Special Rx Condition Interrupts */
+#define	PAR_ERR		0x10	/* Parity error */
+#define	Rx_OVR		0x20	/* Rx Overrun Error */
+#define	CRC_ERR		0x40	/* CRC/Framing Error */
+#define	END_FR		0x80	/* End of Frame (SDLC) */
+
+/* Read Register 2 (channel b only) - Interrupt vector */
+#define CHB_Tx_EMPTY	0x00
+#define CHB_EXT_STAT	0x02
+#define CHB_Rx_AVAIL	0x04
+#define CHB_SPECIAL	0x06
+#define CHA_Tx_EMPTY	0x08
+#define CHA_EXT_STAT	0x0a
+#define CHA_Rx_AVAIL	0x0c
+#define CHA_SPECIAL	0x0e
+#define STATUS_MASK	0x0e
+
+/* Read Register 3 (interrupt pending register) ch a only */
+#define	CHBEXT	0x1		/* Channel B Ext/Stat IP */
+#define	CHBTxIP	0x2		/* Channel B Tx IP */
+#define	CHBRxIP	0x4		/* Channel B Rx IP */
+#define	CHAEXT	0x8		/* Channel A Ext/Stat IP */
+#define	CHATxIP	0x10		/* Channel A Tx IP */
+#define	CHARxIP	0x20		/* Channel A Rx IP */
+
+/* Read Register 8 (receive data register) */
+
+/* Read Register 10  (misc status bits) */
+#define	ONLOOP	2		/* On loop */
+#define	LOOPSEND 0x10		/* Loop sending */
+#define	CLK2MIS	0x40		/* Two clocks missing */
+#define	CLK1MIS	0x80		/* One clock missing */
+
+/* Read Register 12 (lower byte of baud rate generator constant) */
+
+/* Read Register 13 (upper byte of baud rate generator constant) */
+
+/* Read Register 15 (value of WR 15) */
+
+/* Misc macros */
+#define ZS_CLEARERR(channel)    do { sbus_writeb(ERR_RES, &channel->control); \
+				     udelay(5); } while(0)
+
+#define ZS_CLEARSTAT(channel)   do { sbus_writeb(RES_EXT_INT, &channel->control); \
+				     udelay(5); } while(0)
+
+#define ZS_CLEARFIFO(channel)   do { sbus_readb(&channel->data); \
+				     udelay(2); \
+				     sbus_readb(&channel->data); \
+				     udelay(2); \
+				     sbus_readb(&channel->data); \
+				     udelay(2); } while(0)
+
+#endif /* _SUNZILOG_H */
diff -Nru a/drivers/usb/core/drivers.c b/drivers/usb/core/drivers.c
--- a/drivers/usb/core/drivers.c	Sat Aug 10 18:42:20 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,127 +0,0 @@
-/*
- * drivers.c
- * (C) Copyright 1999 Randy Dunlap.
- * (C) Copyright 1999, 2000 Thomas Sailer <sailer@ife.ee.ethz.ch>. (proc file per device)
- * (C) Copyright 1999 Deti Fliegl (new USB architecture)
- *
- * $id$
- *
- * 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
- *
- *************************************************************
- *
- * 1999-12-16: Thomas Sailer <sailer@ife.ee.ethz.ch>
- *   Converted the whole proc stuff to real
- *   read methods. Now not the whole device list needs to fit
- *   into one page, only the device list for one bus.
- *   Added a poll method to /proc/bus/usb/devices, to wake
- *   up an eventual usbd
- * 2000-01-04: Thomas Sailer <sailer@ife.ee.ethz.ch>
- *   Turned into its own filesystem
- *
- * $Id: drivers.c,v 1.3 2000/01/11 13:58:24 tom Exp $
- */
-
-#include <linux/fs.h>
-#include <linux/gfp.h>
-#include <linux/usb.h>
-#include <linux/usbdevice_fs.h>
-#include <linux/smp_lock.h>
-#include <asm/uaccess.h>
-
-/*****************************************************************/
-
-/*
- * Dump usb_driver_list.
- *
- * We now walk the list of registered USB drivers.
- */
-static ssize_t usb_driver_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
-{
-	struct list_head *tmp = usb_driver_list.next;
-	char *page, *start, *end;
-	ssize_t ret = 0;
-	unsigned int pos, len;
-
-	if (*ppos < 0)
-		return -EINVAL;
-	if (nbytes <= 0)
-		return 0;
-	if (!access_ok(VERIFY_WRITE, buf, nbytes))
-		return -EFAULT;
-        if (!(page = (char*) __get_free_page(GFP_KERNEL)))
-                return -ENOMEM;
-	start = page;
-	end = page + (PAGE_SIZE - 100);
-	pos = *ppos;
-	lock_kernel(); /* else drivers might be unloaded */
-	for (; tmp != &usb_driver_list; tmp = tmp->next) {
-		struct usb_driver *driver = list_entry(tmp, struct usb_driver, driver_list);
-		int minor = driver->fops ? driver->minor : -1;
-		if (minor == -1)
-			start += sprintf (start, "         %s\n", driver->name);
-		else if (driver->num_minors == 1)
-			start += sprintf (start, "    %3d: %s\n", minor, driver->name);
-		else
-			start += sprintf (start, "%3d-%3d: %s\n", minor, minor + driver->num_minors - 1, driver->name);
-		if (start > end) {
-			start += sprintf(start, "(truncated)\n");
-			break;
-		}
-	}
-	unlock_kernel();
-	if (start == page)
-		start += sprintf(start, "(none)\n");
-	len = start - page;
-	if (len > pos) {
-		len -= pos;
-		if (len > nbytes)
-			len = nbytes;
-		ret = len;
-		if (copy_to_user(buf, page + pos, len))
-			ret = -EFAULT;
-		else
-			*ppos += len;
-	}
-	free_page((unsigned long)page);
-	return ret;
-}
-
-static loff_t usb_driver_lseek(struct file * file, loff_t offset, int orig)
-{
-	loff_t ret;
-
-	lock_kernel();
-	switch (orig) {
-	case 0:
-		file->f_pos = offset;
-		ret = file->f_pos;
-		break;
-	case 1:
-		file->f_pos += offset;
-		ret = file->f_pos;
-		break;
-	case 2:
-	default:
-		ret = -EINVAL;
-	}
-	unlock_kernel();
-	return ret;
-}
-
-struct file_operations usbdevfs_drivers_fops = {
-	.llseek =	usb_driver_lseek,
-	.read =		usb_driver_read,
-};
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/usb/core/hub.c	Sat Aug 10 18:42:22 2002
@@ -876,10 +876,11 @@
 		 * (quite rare, since most hubs have 4-6 ports).
 		 */
 		pdev = dev->parent;
-		if (pdev->devpath [0] != '/')	/* parent not root */
+		if (pdev->devpath [0] != '0')	/* parent not root? */
 			len = snprintf (dev->devpath, sizeof dev->devpath,
 				"%s.%d", pdev->devpath, port + 1);
-		else	/* root == "/", root port 2 == "2", port 3 that hub "/2.3" */
+		/* root == "0", root port 2 == "2", port 3 that hub "2.3" */
+		else
 			len = snprintf (dev->devpath, sizeof dev->devpath,
 				"%d", port + 1);
 		if (len == sizeof dev->devpath)
diff -Nru a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
--- a/drivers/usb/core/inode.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/usb/core/inode.c	Sat Aug 10 18:42:21 2002
@@ -4,7 +4,7 @@
  *	inode.c  --  Inode/Dentry functions for the USB device file system.
  *
  *	Copyright (C) 2000 Thomas Sailer (sailer@ife.ee.ethz.ch)
- *	Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
+ *	Copyright (c) 2001,2002 Greg Kroah-Hartman (greg@kroah.com)
  *
  *	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
@@ -43,11 +43,13 @@
 static struct super_operations usbfs_ops;
 static struct file_operations default_file_operations;
 static struct inode_operations usbfs_dir_inode_operations;
+static struct vfsmount *usbdevfs_mount;
 static struct vfsmount *usbfs_mount;
 static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED;
 static int mount_count;	/* = 0 */
 
-static struct dentry *devices_dentry;
+static struct dentry *devices_usbdevfs_dentry;
+static struct dentry *devices_usbfs_dentry;
 static int num_buses;	/* = 0 */
 
 static uid_t devuid;	/* = 0 */
@@ -176,7 +178,10 @@
 			int dev)
 {
 	struct inode *inode = usbfs_get_inode(dir->i_sb, mode, dev);
-	int error = -ENOSPC;
+	int error = -EPERM;
+
+	if (dentry->d_inode)
+		return -EEXIST;
 
 	if (inode) {
 		d_instantiate(dentry, inode);
@@ -188,12 +193,19 @@
 
 static int usbfs_mkdir (struct inode *dir, struct dentry *dentry, int mode)
 {
-	return usbfs_mknod (dir, dentry, mode | S_IFDIR, 0);
+	int res;
+
+	mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR;
+	res = usbfs_mknod (dir, dentry, mode, 0);
+	if (!res)
+		dir->i_nlink++;
+	return res;
 }
 
 static int usbfs_create (struct inode *dir, struct dentry *dentry, int mode)
 {
- 	return usbfs_mknod (dir, dentry, mode | S_IFREG, 0);
+	mode = (mode & S_IALLUGO) | S_IFREG;
+	return usbfs_mknod (dir, dentry, mode, 0);
 }
 
 static inline int usbfs_positive (struct dentry *dentry)
@@ -221,21 +233,53 @@
 
 static int usbfs_unlink (struct inode *dir, struct dentry *dentry)
 {
+	struct inode *inode = dentry->d_inode;
+	down(&inode->i_sem);
+	dentry->d_inode->i_nlink--;
+	dput(dentry);
+	up(&inode->i_sem);
+	d_delete(dentry);
+	return 0;
+}
+
+static void d_unhash(struct dentry *dentry)
+{
+	dget(dentry);
+	spin_lock(&dcache_lock);
+	switch (atomic_read(&dentry->d_count)) {
+	default:
+		spin_unlock(&dcache_lock);
+		shrink_dcache_parent(dentry);
+		spin_lock(&dcache_lock);
+		if (atomic_read(&dentry->d_count) != 2)
+			break;
+	case 2:
+		list_del_init(&dentry->d_hash);
+	}
+	spin_unlock(&dcache_lock);
+}
+
+static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
 	int error = -ENOTEMPTY;
+	struct inode * inode = dentry->d_inode;
 
+	down(&inode->i_sem);
+	d_unhash(dentry);
 	if (usbfs_empty(dentry)) {
-		struct inode *inode = dentry->d_inode;
-
-		lock_kernel();
-		inode->i_nlink--;
-		unlock_kernel();
+		dentry->d_inode->i_nlink -= 2;
 		dput(dentry);
+		inode->i_flags |= S_DEAD;
+		dir->i_nlink--;
 		error = 0;
 	}
+	up(&inode->i_sem);
+	if (!error)
+		d_delete(dentry);
+	dput(dentry);
 	return error;
 }
 
-#define usbfs_rmdir usbfs_unlink
 
 /* default file operations */
 static ssize_t default_read_file (struct file *file, char *buf,
@@ -254,7 +298,7 @@
 {
 	loff_t retval = -EINVAL;
 
-	lock_kernel();
+	down(&file->f_dentry->d_inode->i_sem);
 	switch(orig) {
 	case 0:
 		if (offset > 0) {
@@ -271,14 +315,14 @@
 	default:
 		break;
 	}
-	unlock_kernel();
+	up(&file->f_dentry->d_inode->i_sem);
 	return retval;
 }
 
-static int default_open (struct inode *inode, struct file *filp)
+static int default_open (struct inode *inode, struct file *file)
 {
 	if (inode->u.generic_ip)
-		filp->private_data = inode->u.generic_ip;
+		file->private_data = inode->u.generic_ip;
 
 	return 0;
 }
@@ -291,11 +335,7 @@
 };
 
 static struct inode_operations usbfs_dir_inode_operations = {
-	.create =	usbfs_create,
 	.lookup =	simple_lookup,
-	.unlink =	usbfs_unlink,
-	.mkdir =	usbfs_mkdir,
-	.rmdir =	usbfs_rmdir,
 };
 
 static struct super_operations usbfs_ops = {
@@ -334,26 +374,30 @@
 	return 0;
 }
 
-/**
+static struct dentry * get_dentry(struct dentry *parent, const char *name)
+{               
+	struct qstr qstr;
+
+	qstr.name = name;
+	qstr.len = strlen(name);
+	qstr.hash = full_name_hash(name,qstr.len);
+	return lookup_hash(&qstr,parent);
+}               
+
+
+/*
  * fs_create_by_name - create a file, given a name
  * @name:	name of file
  * @mode:	type of file
  * @parent:	dentry of directory to create it in
  * @dentry:	resulting dentry of file
  *
- * There is a bit of overhead in creating a file - basically, we 
- * have to hash the name of the file, then look it up. This will
- * prevent files of the same name. 
- * We then call the proper vfs_ function to take care of all the 
- * file creation details. 
  * This function handles both regular files and directories.
  */
 static int fs_create_by_name (const char *name, mode_t mode,
 			      struct dentry *parent, struct dentry **dentry)
 {
-	struct dentry *d = NULL;
-	struct qstr qstr;
-	int error;
+	int error = 0;
 
 	/* If the parent is not specified, we create it in the root.
 	 * We need the root dentry to do this, which is in the super 
@@ -372,34 +416,17 @@
 	}
 
 	*dentry = NULL;
-	qstr.name = name;
-	qstr.len = strlen(name);
- 	qstr.hash = full_name_hash(name,qstr.len);
-
-	parent = dget(parent);
-
 	down(&parent->d_inode->i_sem);
-
-	d = lookup_hash(&qstr,parent);
-
-	error = PTR_ERR(d);
-	if (!IS_ERR(d)) {
-		switch(mode & S_IFMT) {
-			case 0: 
-			case S_IFREG:
-				error = vfs_create(parent->d_inode,d,mode);
-				break;
-			case S_IFDIR:
-				error = vfs_mkdir(parent->d_inode,d,mode);
-				break;
-			default:
-				err("cannot create special files");
-		}
-		*dentry = d;
-	}
+	*dentry = get_dentry (parent, name);
+	if (!IS_ERR(dentry)) {
+		if ((mode & S_IFMT) == S_IFDIR)
+			error = usbfs_mkdir (parent->d_inode, *dentry, mode);
+		else 
+			error = usbfs_create (parent->d_inode, *dentry, mode);
+	} else
+		error = PTR_ERR(dentry);
 	up(&parent->d_inode->i_sem);
 
-	dput(parent);
 	return error;
 }
 
@@ -413,7 +440,7 @@
 
 	dbg("creating file '%s'",name);
 
-	error = fs_create_by_name(name,mode,parent,&dentry);
+	error = fs_create_by_name (name, mode, parent, &dentry);
 	if (error) {
 		dentry = NULL;
 	} else {
@@ -441,12 +468,11 @@
 	if (usbfs_positive(dentry)) {
 		if (dentry->d_inode) {
 			if (S_ISDIR(dentry->d_inode->i_mode))
-				vfs_rmdir(parent->d_inode,dentry);
+				usbfs_rmdir(parent->d_inode, dentry);
 			else
-				vfs_unlink(parent->d_inode,dentry);
-		}
-
+				usbfs_unlink(parent->d_inode, dentry);
 		dput(dentry);
+		}
 	}
 	up(&parent->d_inode->i_sem);
 }
@@ -471,43 +497,43 @@
 	.owner =	THIS_MODULE,
 	.name =		"usbdevfs",
 	.get_sb =	usb_get_sb,
-	.kill_sb =	kill_anon_super,
+	.kill_sb =	kill_litter_super,
 };
 
 static struct file_system_type usb_fs_type = {
 	.owner =	THIS_MODULE,
 	.name =		"usbfs",
 	.get_sb =	usb_get_sb,
-	.kill_sb =	kill_anon_super,
+	.kill_sb =	kill_litter_super,
 };
 
 /* --------------------------------------------------------------------- */
-static int get_mount (void)
+static int get_mount (struct file_system_type *fs_type, struct vfsmount **mount)
 {
 	struct vfsmount *mnt;
 
 	spin_lock (&mount_lock);
-	if (usbfs_mount) {
-		mntget(usbfs_mount);
+	if (*mount) {
+		mntget(*mount);
 		++mount_count;
 		spin_unlock (&mount_lock);
 		goto go_ahead;
 	}
 
 	spin_unlock (&mount_lock);
-	mnt = kern_mount (&usbdevice_fs_type);
+	mnt = kern_mount (fs_type);
 	if (IS_ERR(mnt)) {
 		err ("could not mount the fs...erroring out!\n");
 		return -ENODEV;
 	}
 	spin_lock (&mount_lock);
-	if (!usbfs_mount) {
-		usbfs_mount = mnt;
+	if (!*mount) {
+		*mount = mnt;
 		++mount_count;
 		spin_unlock (&mount_lock);
 		goto go_ahead;
 	}
-	mntget(usbfs_mount);
+	mntget(*mount);
 	++mount_count;
 	spin_unlock (&mount_lock);
 	mntput(mnt);
@@ -517,15 +543,15 @@
 	return 0;
 }
 
-static void remove_mount (void)
+static void put_mount (struct vfsmount **mount)
 {
 	struct vfsmount *mnt;
 
 	spin_lock (&mount_lock);
-	mnt = usbfs_mount;
+	mnt = *mount;
 	--mount_count;
 	if (!mount_count)
-		usbfs_mount = NULL;
+		*mount = NULL;
 
 	spin_unlock (&mount_lock);
 	mntput(mnt);
@@ -534,18 +560,31 @@
 
 static int create_special_files (void)
 {
+	struct dentry *parent;
 	int retval;
 
-	/* create the devices and drivers special files */
-	retval = get_mount ();
+	/* create the devices special file */
+	retval = get_mount (&usbdevice_fs_type, &usbdevfs_mount);
 	if (retval)
 		return retval;
-	devices_dentry = fs_create_file ("devices",
-					 listmode | S_IFREG,
-					 NULL, NULL,
-					 &usbdevfs_devices_fops,
-					 listuid, listgid);
-	if (devices_dentry == NULL) {
+	retval = get_mount (&usb_fs_type, &usbfs_mount);
+	if (retval) {
+		put_mount (&usbfs_mount);
+		return retval;
+	}
+	parent = usbfs_mount->mnt_sb->s_root;
+	devices_usbfs_dentry = fs_create_file ("devices", listmode | S_IFREG, parent,
+					       NULL, &usbdevfs_devices_fops,
+					       listuid, listgid);
+	if (devices_usbfs_dentry == NULL) {
+		err ("Unable to create devices usbfs file");
+		return -ENODEV;
+	}
+	parent = usbdevfs_mount->mnt_sb->s_root;
+	devices_usbdevfs_dentry = fs_create_file ("devices", listmode | S_IFREG, parent,
+						  NULL, &usbdevfs_devices_fops,
+						  listuid, listgid);
+	if (devices_usbdevfs_dentry == NULL) {
 		err ("Unable to create devices usbfs file");
 		return -ENODEV;
 	}
@@ -555,18 +594,27 @@
 
 static void remove_special_files (void)
 {
-	if (devices_dentry)
-		fs_remove_file (devices_dentry);
-	devices_dentry = NULL;
-	remove_mount();
+	if (devices_usbdevfs_dentry)
+		fs_remove_file (devices_usbdevfs_dentry);
+	if (devices_usbfs_dentry)
+		fs_remove_file (devices_usbfs_dentry);
+	devices_usbdevfs_dentry = NULL;
+	devices_usbfs_dentry = NULL;
+	put_mount (&usbdevfs_mount);
+	put_mount (&usbfs_mount);
 }
 
 void usbfs_update_special (void)
 {
 	struct inode *inode;
 
-	if (devices_dentry) {
-		inode = devices_dentry->d_inode;
+	if (devices_usbdevfs_dentry) {
+		inode = devices_usbdevfs_dentry->d_inode;
+		if (inode)
+			inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	}
+	if (devices_usbfs_dentry) {
+		inode = devices_usbfs_dentry->d_inode;
 		if (inode)
 			inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	}
@@ -574,6 +622,7 @@
 
 void usbfs_add_bus(struct usb_bus *bus)
 {
+	struct dentry *parent;
 	char name[8];
 	int retval;
 
@@ -586,12 +635,22 @@
 	++num_buses;
 
 	sprintf (name, "%03d", bus->busnum);
-	bus->dentry = fs_create_file (name,
-				      busmode | S_IFDIR,
-				      NULL, bus, NULL,
-				      busuid, busgid);
-	if (bus->dentry == NULL)
+
+	parent = usbfs_mount->mnt_sb->s_root;
+	bus->usbfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent,
+					    bus, NULL, busuid, busgid);
+	if (bus->usbfs_dentry == NULL) {
+		err ("error creating usbfs bus entry");
+		return;
+	}
+
+	parent = usbdevfs_mount->mnt_sb->s_root;
+	bus->usbdevfs_dentry = fs_create_file (name, busmode | S_IFDIR, parent,
+					       bus, NULL, busuid, busgid);
+	if (bus->usbdevfs_dentry == NULL) {
+		err ("error creating usbdevfs bus entry");
 		return;
+	}
 
 	usbfs_update_special();
 	usbdevfs_conn_disc_event();
@@ -600,9 +659,13 @@
 
 void usbfs_remove_bus(struct usb_bus *bus)
 {
-	if (bus->dentry) {
-		fs_remove_file (bus->dentry);
-		bus->dentry = NULL;
+	if (bus->usbfs_dentry) {
+		fs_remove_file (bus->usbfs_dentry);
+		bus->usbfs_dentry = NULL;
+	}
+	if (bus->usbdevfs_dentry) {
+		fs_remove_file (bus->usbdevfs_dentry);
+		bus->usbdevfs_dentry = NULL;
 	}
 
 	--num_buses;
@@ -622,13 +685,22 @@
 	int i_size;
 
 	sprintf (name, "%03d", dev->devnum);
-	dev->dentry = fs_create_file (name,
-				      devmode | S_IFREG,
-				      dev->bus->dentry, dev,
-				      &usbdevfs_device_file_operations,
-				      devuid, devgid);
-	if (dev->dentry == NULL)
+	dev->usbfs_dentry = fs_create_file (name, devmode | S_IFREG,
+					    dev->bus->usbfs_dentry, dev,
+					    &usbdevfs_device_file_operations,
+					    devuid, devgid);
+	if (dev->usbfs_dentry == NULL) {
+		err ("error creating usbfs device entry");
 		return;
+	}
+	dev->usbdevfs_dentry = fs_create_file (name, devmode | S_IFREG,
+					       dev->bus->usbdevfs_dentry, dev,
+					       &usbdevfs_device_file_operations,
+					       devuid, devgid);
+	if (dev->usbdevfs_dentry == NULL) {
+		err ("error creating usbdevfs device entry");
+		return;
+	}
 
 	/* Set the size of the device's file to be
 	 * equal to the size of the device descriptors. */
@@ -638,8 +710,10 @@
 			(struct usb_config_descriptor *)dev->rawdescriptors[i];
 		i_size += le16_to_cpu (config->wTotalLength);
 	}
-	if (dev->dentry->d_inode)
-		dev->dentry->d_inode->i_size = i_size;
+	if (dev->usbfs_dentry->d_inode)
+		dev->usbfs_dentry->d_inode->i_size = i_size;
+	if (dev->usbdevfs_dentry->d_inode)
+		dev->usbdevfs_dentry->d_inode->i_size = i_size;
 
 	usbfs_update_special();
 	usbdevfs_conn_disc_event();
@@ -650,9 +724,13 @@
 	struct dev_state *ds;
 	struct siginfo sinfo;
 
-	if (dev->dentry) {
-		fs_remove_file (dev->dentry);
-		dev->dentry = NULL;
+	if (dev->usbfs_dentry) {
+		fs_remove_file (dev->usbfs_dentry);
+		dev->usbfs_dentry = NULL;
+	}
+	if (dev->usbdevfs_dentry) {
+		fs_remove_file (dev->usbdevfs_dentry);
+		dev->usbdevfs_dentry = NULL;
 	}
 	while (!list_empty(&dev->filelist)) {
 		ds = list_entry(dev->filelist.next, struct dev_state, list);
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/usb/core/usb.c	Sat Aug 10 18:42:23 2002
@@ -995,7 +995,7 @@
 	usb_bus_get(bus);
 
 	if (!parent)
-		dev->devpath [0] = '/';
+		dev->devpath [0] = '0';
 	dev->bus = bus;
 	dev->parent = parent;
 	atomic_set(&dev->refcnt, 1);
diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
--- a/drivers/usb/input/aiptek.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/usb/input/aiptek.c	Sat Aug 10 18:42:21 2002
@@ -172,7 +172,7 @@
 };
 
 struct usb_device_id aiptek_ids[] = {
-	{USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x20), driver_info:0},
+	{USB_DEVICE(USB_VENDOR_ID_AIPTEK, 0x20), .driver_info = 0},
 	{}
 };
 
diff -Nru a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c
--- a/drivers/usb/media/dabusb.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/usb/media/dabusb.c	Sat Aug 10 18:42:23 2002
@@ -712,18 +712,6 @@
 	.release =	dabusb_release,
 };
 
-static int dabusb_find_struct (void)
-{
-	int u;
-
-	for (u = 0; u < NRDABUSB; u++) {
-		pdabusb_t s = &dabusb[u];
-		if (!s->usbdev)
-			return u;
-	}
-	return -1;
-}
-
 /* --------------------------------------------------------------------- */
 static void *dabusb_probe (struct usb_device *usbdev, unsigned int ifnum,
 			   const struct usb_device_id *id)
diff -Nru a/drivers/usb/media/se401.c b/drivers/usb/media/se401.c
--- a/drivers/usb/media/se401.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/usb/media/se401.c	Sat Aug 10 18:42:22 2002
@@ -1521,10 +1521,10 @@
 }
 
 static struct usb_driver se401_driver = {
-        name:		"se401",
-        id_table:	device_table,
+        .name		= "se401",
+        .id_table	= device_table,
 	.probe =	se401_probe,
-        disconnect:	se401_disconnect
+        .disconnect	= se401_disconnect
 };
 
 
diff -Nru a/drivers/usb/media/vicamurbs.h b/drivers/usb/media/vicamurbs.h
--- a/drivers/usb/media/vicamurbs.h	Sat Aug 10 18:42:22 2002
+++ b/drivers/usb/media/vicamurbs.h	Sat Aug 10 18:42:22 2002
@@ -17,11 +17,13 @@
 
 /* Request 0x51 Image Setup */
 
+#if 0
 /* 128x98 ? 0x3180 size */
 static unsigned char s128x98bw[] = {
   0,    0x34, 0xC4, 0x00, 0x00, 0x00, 0,    0,
   0x18, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00
 };
+#endif
 
 /* 128x122 3D80 size */
 static unsigned char s128x122bw[] = {
diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
--- a/drivers/usb/misc/auerswald.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/usb/misc/auerswald.c	Sat Aug 10 18:42:22 2002
@@ -2,7 +2,7 @@
 /*
  *      auerswald.c  --  Auerswald PBX/System Telephone usb driver.
  *
- *      Copyright (C) 2001  Wolfgang Mües (wmues@nexgo.de)
+ *      Copyright (C) 2001  Wolfgang Mües (wolfgang@iksw-muees.de)
  *
  *      Very much code of this driver is borrowed from dabusb.c (Deti Fliegl)
  *      and from the USB Skeleton driver (Greg Kroah-Hartman). Thank you.
@@ -51,7 +51,7 @@
 /*-------------------------------------------------------------------*/
 /* Version Information */
 #define DRIVER_VERSION "0.9.11"
-#define DRIVER_AUTHOR  "Wolfgang Mües <wmues@nexgo.de>"
+#define DRIVER_AUTHOR  "Wolfgang Mües <wolfgang@iksw-muees.de>"
 #define DRIVER_DESC    "Auerswald PBX/System Telephone usb driver"
 
 /*-------------------------------------------------------------------*/
diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
--- a/drivers/usb/net/kaweth.c	Sat Aug 10 18:42:23 2002
+++ b/drivers/usb/net/kaweth.c	Sat Aug 10 18:42:23 2002
@@ -152,6 +152,7 @@
 	{ USB_DEVICE(0x10bd, 0x1427) }, /* ASANTE USB To Ethernet Adapter */
 	{ USB_DEVICE(0x1342, 0x0204) }, /* Mobility USB-Ethernet Adapter */
 	{ USB_DEVICE(0x13d2, 0x0400) }, /* Shark Pocket Adapter */
+	{ USB_DEVICE(0x1485, 0x0001) },	/* Silicom U2E */
 	{ USB_DEVICE(0x1645, 0x0005) }, /* Entrega E45 */
 	{ USB_DEVICE(0x1645, 0x0008) }, /* Entrega USB Ethernet Adapter */
 	{ USB_DEVICE(0x1645, 0x8005) }, /* PortGear Ethernet Adapter */
diff -Nru a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
--- a/drivers/usb/serial/ipaq.c	Sat Aug 10 18:42:22 2002
+++ b/drivers/usb/serial/ipaq.c	Sat Aug 10 18:42:22 2002
@@ -9,6 +9,10 @@
  *	the Free Software Foundation; either version 2 of the License, or
  *	(at your option) any later version.
  *
+ * (26/7/2002) ganesh
+ * 	Fixed up broken error handling in ipaq_open. Retry the "kickstart"
+ * 	packet much harder - this drastically reduces connection failures.
+ *
  * (30/4/2002) ganesh
  * 	Added support for the Casio EM500. Completely untested. Thanks
  * 	to info from Nathan <wfilardo@fuse.net>
@@ -54,6 +58,8 @@
 #include "usb-serial.h"
 #include "ipaq.h"
 
+#define KP_RETRIES	100
+
 /*
  * Version Information
  */
@@ -118,6 +124,7 @@
 	struct ipaq_private	*priv;
 	struct ipaq_packet	*pkt;
 	int			i, result = 0;
+	int			retries = KP_RETRIES;
 
 	if (port_paranoia_check(port, __FUNCTION__)) {
 		return -ENODEV;
@@ -192,31 +199,35 @@
 	result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 	if (result) {
 		err(__FUNCTION__ " - failed submitting read urb, error %d", result);
+		goto error;
 	}
 
 	/*
-	 * Send out two control messages observed in win98 sniffs. Not sure what
-	 * they do.
+	 * Send out control message observed in win98 sniffs. Not sure what
+	 * it does, but from empirical observations, it seems that the device
+	 * will start the chat sequence once one of these messages gets
+	 * through. Since this has a reasonably high failure rate, we retry
+	 * several times.
 	 */
 
-	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
-			0x1, 0, NULL, 0, 5 * HZ);
-	if (result < 0) {
-		err(__FUNCTION__ " - failed doing control urb, error %d", result);
-	}
-	result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
-			0x1, 0, NULL, 0, 5 * HZ);
-	if (result < 0) {
-		err(__FUNCTION__ " - failed doing control urb, error %d", result);
+	while (retries--) {
+		result = usb_control_msg(serial->dev,
+				usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
+				0x1, 0, NULL, 0, HZ / 10 + 1);
+		if (result == 0) {
+			return 0;
+		}
 	}
-	
-	return result;
+	err(__FUNCTION__ " - failed doing control urb, error %d", result);
+	goto error;
 
 enomem:
+	result = -ENOMEM;
+	err(__FUNCTION__ " - Out of memory");
+error:
 	ipaq_destroy_lists(port);
 	kfree(priv);
-	err(__FUNCTION__ " - Out of memory");
-	return -ENOMEM;
+	return result;
 }
 
 
diff -Nru a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
--- a/drivers/usb/serial/keyspan.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/usb/serial/keyspan.c	Sat Aug 10 18:42:21 2002
@@ -86,7 +86,6 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <asm/uaccess.h>
-#include <linux/usb.h>
 
 #ifdef CONFIG_USB_SERIAL_DEBUG
 	static int debug = 1;
diff -Nru a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
--- a/drivers/video/sa1100fb.c	Sat Aug 10 18:42:21 2002
+++ b/drivers/video/sa1100fb.c	Sat Aug 10 18:42:21 2002
@@ -205,9 +205,6 @@
 extern void (*sa1100fb_backlight_power)(int on);
 extern void (*sa1100fb_lcd_power)(int on);
 
-void (*sa1100fb_blank_helper)(int blank);
-EXPORT_SYMBOL(sa1100fb_blank_helper);
-
 /*
  * IMHO this looks wrong.  In 8BPP, length should be 8.
  */
@@ -262,7 +259,7 @@
 #endif
 #endif
 
-#ifdef CONFIG_SA1100_H3XXX
+#ifdef CONFIG_SA1100_H3800
 static struct sa1100fb_mach_info h3800_info __initdata = {
 	pixclock:	174757, 	bpp:		16,
 	xres:		320,		yres:		240,
@@ -274,9 +271,12 @@
 	sync:		0,		cmap_static:	1,
 
 	lccr0:		LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-	lccr3:		LCCR3_ACBsCntOff | LCCR3_PixFlEdg | LCCR3_OutEnH,
+	lccr3:		LCCR3_ACBsDiv(2) | LCCR3_PixRsEdg | LCCR3_OutEnH |
+			LCCR3_ACBsCntOff,
 };
+#endif
 
+#ifdef CONFIG_SA1100_H3600
 static struct sa1100fb_mach_info h3600_info __initdata = {
 	pixclock:	174757, 	bpp:		16,
 	xres:		320,		yres:		240,
@@ -288,7 +288,8 @@
 	sync:		0,		cmap_static:	1,
 
 	lccr0:		LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-	lccr3:		LCCR3_ACBsCntOff | LCCR3_OutEnH | LCCR3_PixFlEdg,
+	lccr3:		LCCR3_ACBsDiv(2) | LCCR3_PixRsEdg | LCCR3_OutEnH |
+			LCCR3_ACBsCntOff,
 };
 
 static struct sa1100fb_rgb h3600_rgb_16 = {
@@ -297,7 +298,9 @@
 	blue:	{ offset: 1,  length: 4, },
 	transp: { offset: 0,  length: 0, },
 };
+#endif
 
+#ifdef CONFIG_SA1100_H3100
 static struct sa1100fb_mach_info h3100_info __initdata = {
 	pixclock:	406977, 	bpp:		4,
 	xres:		320,		yres:		240,
@@ -680,14 +683,18 @@
 #endif
 	}
 #endif
-#ifdef CONFIG_SA1100_H3XXX
+#ifdef CONFIG_SA1100_H3100
+	if (machine_is_h3100()) {
+		inf = &h3100_info;
+	}
+#endif
+#ifdef CONFIG_SA1100_H3600
 	if (machine_is_h3600()) {
 		inf = &h3600_info;
 		fbi->rgb[RGB_16] = &h3600_rgb_16;
 	}
-	if (machine_is_h3100()) {
-		inf = &h3100_info;
-	}
+#endif
+#ifdef CONFIG_SA1100_H3800
 	if (machine_is_h3800()) {
 		inf = &h3800_info;
 	}
@@ -1310,13 +1317,9 @@
 			for (i = 0; i < fbi->palette_size; i++)
 				sa1100fb_setpalettereg(i, 0, 0, 0, 0, info);
 		sa1100fb_schedule_task(fbi, C_DISABLE);
-		if (sa1100fb_blank_helper)
-			sa1100fb_blank_helper(blank);
 		break;
 
 	case VESA_NO_BLANKING:
-		if (sa1100fb_blank_helper)
-			sa1100fb_blank_helper(blank);
 		if (fbi->fb.disp->visual == FB_VISUAL_PSEUDOCOLOR ||
 		    fbi->fb.disp->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
 			fb_set_cmap(&fbi->fb.cmap, 1, info);
diff -Nru a/fs/adfs/dir.c b/fs/adfs/dir.c
--- a/fs/adfs/dir.c	Sat Aug 10 18:42:23 2002
+++ b/fs/adfs/dir.c	Sat Aug 10 18:42:23 2002
@@ -198,9 +198,9 @@
 }
 
 struct file_operations adfs_dir_operations = {
-	read:		generic_read_dir,
-	readdir:	adfs_readdir,
-	fsync:		file_fsync,
+	.read		= generic_read_dir,
+	.readdir	= adfs_readdir,
+	.fsync		= file_fsync,
 };
 
 static int
@@ -265,8 +265,8 @@
 }
 
 struct dentry_operations adfs_dentry_operations = {
-	d_hash:		adfs_hash,
-	d_compare:	adfs_compare,
+	.d_hash		= adfs_hash,
+	.d_compare	= adfs_compare,
 };
 
 struct dentry *adfs_lookup(struct inode *dir, struct dentry *dentry)
@@ -297,6 +297,6 @@
  * directories can handle most operations...
  */
 struct inode_operations adfs_dir_inode_operations = {
-	lookup:		adfs_lookup,
-	setattr:	adfs_notify_change,
+	.lookup		= adfs_lookup,
+	.setattr	= adfs_notify_change,
 };
diff -Nru a/fs/adfs/file.c b/fs/adfs/file.c
--- a/fs/adfs/file.c	Sat Aug 10 18:42:21 2002
+++ b/fs/adfs/file.c	Sat Aug 10 18:42:21 2002
@@ -31,14 +31,14 @@
 #include "adfs.h"
 
 struct file_operations adfs_file_operations = {
-	llseek:		generic_file_llseek,
-	read:		generic_file_read,
-	mmap:		generic_file_mmap,
-	fsync:		file_fsync,
-	write:		generic_file_write,
-	sendfile:	generic_file_sendfile,
+	.llseek		= generic_file_llseek,
+	.read		= generic_file_read,
+	.mmap		= generic_file_mmap,
+	.fsync		= file_fsync,
+	.write		= generic_file_write,
+	.sendfile	= generic_file_sendfile,
 };
 
 struct inode_operations adfs_file_inode_operations = {
-	setattr:	adfs_notify_change,
+	.setattr	= adfs_notify_change,
 };
diff -Nru a/fs/adfs/inode.c b/fs/adfs/inode.c
--- a/fs/adfs/inode.c	Sat Aug 10 18:42:22 2002
+++ b/fs/adfs/inode.c	Sat Aug 10 18:42:22 2002
@@ -73,12 +73,12 @@
 }
 
 static struct address_space_operations adfs_aops = {
-	readpage:	adfs_readpage,
-	writepage:	adfs_writepage,
-	sync_page:	block_sync_page,
-	prepare_write:	adfs_prepare_write,
-	commit_write:	generic_commit_write,
-	bmap:		_adfs_bmap
+	.readpage	= adfs_readpage,
+	.writepage	= adfs_writepage,
+	.sync_page	= block_sync_page,
+	.prepare_write	= adfs_prepare_write,
+	.commit_write	= generic_commit_write,
+	.bmap		= _adfs_bmap
 };
 
 static inline unsigned int
diff -Nru a/fs/adfs/super.c b/fs/adfs/super.c
--- a/fs/adfs/super.c	Sat Aug 10 18:42:20 2002
+++ b/fs/adfs/super.c	Sat Aug 10 18:42:20 2002
@@ -247,12 +247,12 @@
 }
 
 static struct super_operations adfs_sops = {
-	alloc_inode:	adfs_alloc_inode,
-	destroy_inode:	adfs_destroy_inode,
-	write_inode:	adfs_write_inode,
-	put_super:	adfs_put_super,
-	statfs:		adfs_statfs,
-	remount_fs:	adfs_remount,
+	.alloc_inode	= adfs_alloc_inode,
+	.destroy_inode	= adfs_destroy_inode,
+	.write_inode	= adfs_write_inode,
+	.put_super	= adfs_put_super,
+	.statfs		= adfs_statfs,
+	.remount_fs	= adfs_remount,
 };
 
 static struct adfs_discmap *adfs_read_map(struct super_block *sb, struct adfs_discrecord *dr)
@@ -464,11 +464,11 @@
 }
 
 static struct file_system_type adfs_fs_type = {
-	owner:		THIS_MODULE,
-	name:		"adfs",
-	get_sb:		adfs_get_sb,
-	kill_sb:	kill_block_super,
-	fs_flags:	FS_REQUIRES_DEV,
+	.owner		= THIS_MODULE,
+	.name		= "adfs",
+	.get_sb		= adfs_get_sb,
+	.kill_sb	= kill_block_super,
+	.fs_flags	= FS_REQUIRES_DEV,
 };
 
 static int __init init_adfs_fs(void)
diff -Nru a/fs/block_dev.c b/fs/block_dev.c
--- a/fs/block_dev.c	Sat Aug 10 18:42:24 2002
+++ b/fs/block_dev.c	Sat Aug 10 18:42:24 2002
@@ -105,7 +105,7 @@
 blkdev_get_blocks(struct inode *inode, sector_t iblock,
 		unsigned long max_blocks, struct buffer_head *bh, int create)
 {
-	if ((iblock + max_blocks) >= max_block(inode->i_bdev))
+	if ((iblock + max_blocks) > max_block(inode->i_bdev))
 		return -EIO;
 
 	bh->b_bdev = inode->i_bdev;
@@ -310,7 +310,7 @@
 			new_bdev->bd_contains = NULL;
 			new_bdev->bd_inode = inode;
 			new_bdev->bd_part_count = 0;
-			sema_init(&new_bdev->bd_part_sem, 1);
+			new_bdev->bd_invalidated = 0;
 			inode->i_mode = S_IFBLK;
 			inode->i_rdev = kdev;
 			inode->i_bdev = new_bdev;
@@ -498,49 +498,86 @@
  * People changing diskettes in the middle of an operation deserve
  * to lose :-)
  */
-int check_disk_change(kdev_t dev)
+int check_disk_change(struct block_device *bdev)
 {
-	int i;
-	struct block_device_operations * bdops = NULL;
+	struct block_device_operations * bdops = bdev->bd_op;
+	kdev_t dev = to_kdev_t(bdev->bd_dev);
+	struct gendisk *disk;
+	struct hd_struct *part;
 
-	i = major(dev);
-	if (i < MAX_BLKDEV)
-		bdops = blkdevs[i].bdops;
-	if (bdops == NULL) {
-		devfs_handle_t de;
-
-		de = devfs_get_handle(NULL, NULL, i, minor(dev),
-				      DEVFS_SPECIAL_BLK, 0);
-		if (de) {
-			bdops = devfs_get_ops(de);
-			devfs_put_ops(de); /* We're running in owner module */
-			devfs_put(de);
-		}
-	}
-	if (bdops == NULL)
-		return 0;
 	if (bdops->check_media_change == NULL)
 		return 0;
 	if (!bdops->check_media_change(dev))
 		return 0;
 
 	printk(KERN_DEBUG "VFS: Disk change detected on device %s\n",
-		__bdevname(dev));
+		bdevname(bdev));
 
 	if (invalidate_device(dev, 0))
 		printk("VFS: busy inodes on changed media.\n");
 
+	disk = get_gendisk(dev);
+	part = disk->part + minor(dev) - disk->first_minor;
 	if (bdops->revalidate)
 		bdops->revalidate(dev);
+	if (disk && disk->minor_shift)
+		bdev->bd_invalidated = 1;
 	return 1;
 }
 
+int full_check_disk_change(struct block_device *bdev)
+{
+	int res;
+	down(&bdev->bd_sem);
+	res = check_disk_change(bdev);
+	if (bdev->bd_invalidated && !bdev->bd_part_count) {
+		struct gendisk *g = get_gendisk(to_kdev_t(bdev->bd_dev));
+		struct hd_struct *part;
+		part = g->part + MINOR(bdev->bd_dev) - g->first_minor;
+		bdev->bd_invalidated = 0;
+		wipe_partitions(to_kdev_t(bdev->bd_dev));
+		if (part[0].nr_sects)
+			check_partition(g, bdev);
+	}
+	up(&bdev->bd_sem);
+	return res;
+}
+
+/*
+ * Will die as soon as two remaining callers get converted.
+ */
+int __check_disk_change(dev_t dev)
+{
+	struct block_device *bdev = bdget(dev);
+	int res;
+	if (!bdev)
+		return 0;
+	if (blkdev_get(bdev, FMODE_READ, 0, BDEV_RAW) < 0)
+		return 0;
+	res = full_check_disk_change(bdev);
+	blkdev_put(bdev, BDEV_RAW);
+	return res;
+}
+
+static void bd_set_size(struct block_device *bdev, loff_t size)
+{
+	unsigned bsize = bdev_hardsect_size(bdev);
+	bdev->bd_inode->i_size = size;
+	while (bsize < PAGE_CACHE_SIZE) {
+		if (size & bsize)
+			break;
+		bsize <<= 1;
+	}
+	bdev->bd_block_size = bsize;
+	bdev->bd_inode->i_blkbits = blksize_bits(bsize);
+}
+
 static int do_open(struct block_device *bdev, struct inode *inode, struct file *file)
 {
 	int ret = -ENXIO;
 	kdev_t dev = to_kdev_t(bdev->bd_dev);
 	struct module *owner = NULL;
-	struct block_device_operations *ops, *current_ops;
+	struct block_device_operations *ops, *old;
 
 	lock_kernel();
 	ops = get_blkfops(major(dev));
@@ -551,12 +588,15 @@
 	}
 
 	down(&bdev->bd_sem);
-	if (!bdev->bd_op)
-		current_ops = ops;
-	else
-		current_ops = bdev->bd_op;
-	if (!current_ops)
-		goto out;
+	old = bdev->bd_op;
+	if (!old) {
+		if (!ops)
+			goto out;
+		bdev->bd_op = ops;
+	} else {
+		if (owner)
+			__MOD_DEC_USE_COUNT(owner);
+	}
 	if (!bdev->bd_contains) {
 		unsigned minor = minor(dev);
 		struct gendisk *g = get_gendisk(dev);
@@ -578,57 +618,64 @@
 		}
 	}
 	if (bdev->bd_contains == bdev) {
-		if (current_ops->open) {
-			ret = current_ops->open(inode, file);
+		struct gendisk *g = get_gendisk(dev);
+		if (bdev->bd_op->open) {
+			ret = bdev->bd_op->open(inode, file);
 			if (ret)
 				goto out2;
 		}
-	} else {
-		down(&bdev->bd_contains->bd_part_sem);
-		bdev->bd_contains->bd_part_count++;
-		up(&bdev->bd_contains->bd_part_sem);
-	}
-	if (!bdev->bd_op)
-		bdev->bd_op = ops;
-	else if (owner)
-		__MOD_DEC_USE_COUNT(owner);
-	if (!bdev->bd_openers) {
-		struct blk_dev_struct *p = blk_dev + major(dev);
-		struct gendisk *g = get_gendisk(dev);
-		unsigned bsize = bdev_hardsect_size(bdev);
-
-		bdev->bd_offset = 0;
-		if (g) {
-			struct hd_struct *p;
-			p = g->part + minor(dev) - g->first_minor;
-			bdev->bd_inode->i_size = (loff_t) p->nr_sects << 9;
-			bdev->bd_offset = p->start_sect;
-		} else if (blk_size[major(dev)])
-			bdev->bd_inode->i_size =
-				(loff_t) blk_size[major(dev)][minor(dev)] << 10;
-		else
-			bdev->bd_inode->i_size = 0;
-		while (bsize < PAGE_CACHE_SIZE) {
-			if (bdev->bd_inode->i_size & bsize)
-				break;
-			bsize <<= 1;
-		}
-		bdev->bd_block_size = bsize;
-		bdev->bd_inode->i_blkbits = blksize_bits(bsize);
-		if (p->queue)
-			bdev->bd_queue =  p->queue(dev);
-		else
-			bdev->bd_queue = &p->request_queue;
-		if (bdev->bd_inode->i_data.backing_dev_info ==
-					&default_backing_dev_info) {
+		if (!bdev->bd_openers) {
+			struct blk_dev_struct *p = blk_dev + major(dev);
 			struct backing_dev_info *bdi;
+			sector_t sect = 0;
 
+			bdev->bd_offset = 0;
+			if (g) {
+				struct hd_struct *p;
+				p = g->part + minor(dev) - g->first_minor;
+				sect = p->nr_sects;
+			} else if (blk_size[major(dev)])
+				sect = blk_size[major(dev)][minor(dev)] << 1;
+			if (p->queue)
+				bdev->bd_queue =  p->queue(dev);
+			else
+				bdev->bd_queue = &p->request_queue;
+			bd_set_size(bdev, (loff_t)sect << 9);
 			bdi = blk_get_backing_dev_info(bdev);
 			if (bdi == NULL)
 				bdi = &default_backing_dev_info;
 			inode->i_data.backing_dev_info = bdi;
 			bdev->bd_inode->i_data.backing_dev_info = bdi;
 		}
+		if (bdev->bd_invalidated && !bdev->bd_part_count) {
+			struct hd_struct *part;
+			part = g->part + minor(dev) - g->first_minor;
+			bdev->bd_invalidated = 0;
+			wipe_partitions(dev);
+			if (part[0].nr_sects)
+				check_partition(g, bdev);
+		}
+	} else {
+		down(&bdev->bd_contains->bd_sem);
+		bdev->bd_contains->bd_part_count++;
+		if (!bdev->bd_openers) {
+			struct gendisk *g = get_gendisk(dev);
+			struct hd_struct *p;
+			p = g->part + minor(dev) - g->first_minor;
+			inode->i_data.backing_dev_info =
+			   bdev->bd_inode->i_data.backing_dev_info =
+			   bdev->bd_contains->bd_inode->i_data.backing_dev_info;
+			if (!p->nr_sects) {
+				bdev->bd_contains->bd_part_count--;
+				up(&bdev->bd_contains->bd_sem);
+				ret = -ENXIO;
+				goto out2;
+			}
+			bdev->bd_queue = bdev->bd_contains->bd_queue;
+			bdev->bd_offset = p->start_sect;
+			bd_set_size(bdev, (loff_t) p->nr_sects << 9);
+		}
+		up(&bdev->bd_contains->bd_sem);
 	}
 	bdev->bd_openers++;
 	up(&bdev->bd_sem);
@@ -644,8 +691,11 @@
 		}
 	}
 out1:
-	if (owner)
-		__MOD_DEC_USE_COUNT(owner);
+	if (!old) {
+		bdev->bd_op = NULL;
+		if (owner)
+			__MOD_DEC_USE_COUNT(owner);
+	}
 out:
 	up(&bdev->bd_sem);
 	unlock_kernel();
@@ -709,9 +759,9 @@
 		if (bdev->bd_op->release)
 			ret = bdev->bd_op->release(bd_inode, NULL);
 	} else {
-		down(&bdev->bd_contains->bd_part_sem);
+		down(&bdev->bd_contains->bd_sem);
 		bdev->bd_contains->bd_part_count--;
-		up(&bdev->bd_contains->bd_part_sem);
+		up(&bdev->bd_contains->bd_sem);
 	}
 	if (!bdev->bd_openers) {
 		if (bdev->bd_op->owner)
@@ -735,9 +785,39 @@
 	return blkdev_put(inode->i_bdev, BDEV_FILE);
 }
 
+static int blkdev_reread_part(struct block_device *bdev)
+{
+	kdev_t dev = to_kdev_t(bdev->bd_dev);
+	struct gendisk *disk = get_gendisk(dev);
+	struct hd_struct *part;
+	int res;
+
+	if (!disk || !disk->minor_shift)
+		return -EINVAL;
+	part = disk->part + minor(dev) - disk->first_minor;
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+	if (down_trylock(&bdev->bd_sem));
+		return -EBUSY;
+	if (bdev->bd_part_count) {
+		up(&bdev->bd_sem);
+		return -EBUSY;
+	}
+	res = wipe_partitions(dev);
+	if (!res) {
+		if (bdev->bd_op->revalidate)
+			bdev->bd_op->revalidate(dev);
+		if (part[0].nr_sects)
+			check_partition(disk, bdev);
+	}
+	up(&bdev->bd_sem);
+	return res;
+}
+
 static int blkdev_ioctl(struct inode *inode, struct file *file, unsigned cmd,
 			unsigned long arg)
 {
+	struct block_device *bdev = inode->i_bdev;
 	int ret = -EINVAL;
 	switch (cmd) {
 	/*
@@ -757,21 +837,23 @@
 	case BLKFRASET:
 	case BLKBSZSET:
 	case BLKPG:
-		ret = blk_ioctl(inode->i_bdev, cmd, arg);
+		ret = blk_ioctl(bdev, cmd, arg);
 		break;
 	default:
-		if (inode->i_bdev->bd_op->ioctl)
-			ret =inode->i_bdev->bd_op->ioctl(inode, file, cmd, arg);
+		if (bdev->bd_op->ioctl)
+			ret =bdev->bd_op->ioctl(inode, file, cmd, arg);
 		if (ret == -EINVAL) {
 			switch (cmd) {
 				case BLKGETSIZE:
 				case BLKGETSIZE64:
 				case BLKFLSBUF:
 				case BLKROSET:
-					ret = blk_ioctl(inode->i_bdev,cmd,arg);
+					ret = blk_ioctl(bdev,cmd,arg);
+					break;
+				case BLKRRPART:
+					ret = blkdev_reread_part(bdev);
 			}
 		}
-		break;
 	}
 	return ret;
 }
diff -Nru a/fs/devfs/base.c b/fs/devfs/base.c
--- a/fs/devfs/base.c	Sat Aug 10 18:42:21 2002
+++ b/fs/devfs/base.c	Sat Aug 10 18:42:21 2002
@@ -2377,23 +2377,20 @@
     int tmp;
     int retval = 0;
     kdev_t dev = mk_kdev (de->u.fcb.u.device.major, de->u.fcb.u.device.minor);
+    struct block_device *bdev;
     struct block_device_operations *bdops;
     extern int warn_no_part;
 
     if ( !S_ISBLK (de->mode) ) return 0;
+    bdev = bdget(kdev_t_to_nr(dev));
+    if (!bdev) return 0;
     bdops = devfs_get_ops (de);
     if (!bdops) return 0;
-    if (bdops->check_media_change == NULL) goto out;
-    if ( !bdops->check_media_change (dev) ) goto out;
-    retval = 1;
-    printk (KERN_DEBUG "VFS: Disk change detected on device %s\n",
-	     kdevname (dev) );
-    if ( invalidate_device (dev, 0) )
-	printk (KERN_WARNING "VFS: busy inodes on changed media..\n");
+    bdev->bd_op = bdops;
     /*  Ugly hack to disable messages about unable to read partition table  */
     tmp = warn_no_part;
     warn_no_part = 0;
-    if (bdops->revalidate) bdops->revalidate (dev);
+    retval = full_check_disk_change(bdev);
     warn_no_part = tmp;
 out:
     devfs_put_ops (de);
diff -Nru a/fs/direct-io.c b/fs/direct-io.c
--- a/fs/direct-io.c	Sat Aug 10 18:42:20 2002
+++ b/fs/direct-io.c	Sat Aug 10 18:42:20 2002
@@ -489,7 +489,7 @@
 
 			/* Work out how much disk we can add to this page */
 			this_chunk_blocks = dio->blocks_available;
-			u = (PAGE_SIZE - dio->bvec->bv_len) >> blkbits;
+			u = (PAGE_SIZE - (dio->bvec->bv_offset + dio->bvec->bv_len)) >> blkbits;
 			if (this_chunk_blocks > u)
 				this_chunk_blocks = u;
 			u = dio->final_block_in_request - dio->block_in_file;
@@ -567,10 +567,11 @@
 	dio.curr_page = 0;
 	bytes = count;
 	dio.total_pages = 0;
-	if (offset & PAGE_SIZE) {
+	if (user_addr & (PAGE_SIZE - 1)) {
 		dio.total_pages++;
-		bytes -= PAGE_SIZE - (offset & ~(PAGE_SIZE - 1));
+		bytes -= PAGE_SIZE - (user_addr & (PAGE_SIZE - 1));
 	}
+
 	dio.total_pages += (bytes + PAGE_SIZE - 1) / PAGE_SIZE;
 	dio.curr_user_address = user_addr;
 
diff -Nru a/fs/driverfs/inode.c b/fs/driverfs/inode.c
--- a/fs/driverfs/inode.c	Sat Aug 10 18:42:21 2002
+++ b/fs/driverfs/inode.c	Sat Aug 10 18:42:21 2002
@@ -56,7 +56,6 @@
 static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED;
 static int mount_count = 0;
 
-
 static int driverfs_readpage(struct file *file, struct page * page)
 {
 	if (!PageUptodate(page)) {
@@ -130,14 +129,15 @@
 
 static int driverfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev)
 {
-	struct inode *inode = driverfs_get_inode(dir->i_sb, mode, dev);
-	int error = -EPERM;
+	struct inode *inode;
+	int error = -ENOSPC;
 
 	if (dentry->d_inode)
 		return -EEXIST;
 
 	/* only allow create if ->d_fsdata is not NULL (so we can assume it 
 	 * comes from the driverfs API below. */
+	inode = driverfs_get_inode(dir->i_sb, mode, dev);
 	if (inode) {
 		d_instantiate(dentry, inode);
 		dget(dentry);
@@ -689,7 +689,7 @@
 		if (dentry->d_inode && 
 		    (dentry->d_parent->d_inode == dir->dentry->d_inode)) {
 			driverfs_unlink(dir->dentry->d_inode,dentry);
-			dput(dir->dentry);
+			dput(dentry);
 			put_mount();
 		}
 	}
@@ -721,7 +721,7 @@
 
 		node = node->next;
 		driverfs_unlink(dentry->d_inode,d);
-		dput(dentry);
+		dput(d);
 		put_mount();
 	}
 	up(&dentry->d_inode->i_sem);
diff -Nru a/fs/exec.c b/fs/exec.c
--- a/fs/exec.c	Sat Aug 10 18:42:22 2002
+++ b/fs/exec.c	Sat Aug 10 18:42:22 2002
@@ -185,25 +185,39 @@
  */
 int copy_strings(int argc,char ** argv, struct linux_binprm *bprm) 
 {
+	struct page *kmapped_page = NULL;
+	char *kaddr = NULL;
+	int ret;
+
 	while (argc-- > 0) {
 		char *str;
 		int len;
 		unsigned long pos;
 
-		if (get_user(str, argv+argc) || !(len = strnlen_user(str, bprm->p)))
-			return -EFAULT;
-		if (bprm->p < len) 
-			return -E2BIG; 
+		if (get_user(str, argv+argc) ||
+				!(len = strnlen_user(str, bprm->p))) {
+			ret = -EFAULT;
+			goto out;
+		}
+
+		if (bprm->p < len)  {
+			ret = -E2BIG;
+			goto out;
+		}
 
 		bprm->p -= len;
 		/* XXX: add architecture specific overflow check here. */ 
-
 		pos = bprm->p;
+
+		/*
+		 * The only sleeping function which we are allowed to call in
+		 * this loop is copy_from_user().  Otherwise, copy_user_state
+		 * could get trashed.
+		 */
 		while (len > 0) {
-			char *kaddr;
 			int i, new, err;
-			struct page *page;
 			int offset, bytes_to_copy;
+			struct page *page;
 
 			offset = pos % PAGE_SIZE;
 			i = pos/PAGE_SIZE;
@@ -212,32 +226,44 @@
 			if (!page) {
 				page = alloc_page(GFP_HIGHUSER);
 				bprm->page[i] = page;
-				if (!page)
-					return -ENOMEM;
+				if (!page) {
+					ret = -ENOMEM;
+					goto out;
+				}
 				new = 1;
 			}
-			kaddr = kmap(page);
 
+			if (page != kmapped_page) {
+				if (kmapped_page)
+					kunmap(kmapped_page);
+				kmapped_page = page;
+				kaddr = kmap(kmapped_page);
+			}
 			if (new && offset)
 				memset(kaddr, 0, offset);
 			bytes_to_copy = PAGE_SIZE - offset;
 			if (bytes_to_copy > len) {
 				bytes_to_copy = len;
 				if (new)
-					memset(kaddr+offset+len, 0, PAGE_SIZE-offset-len);
+					memset(kaddr+offset+len, 0,
+						PAGE_SIZE-offset-len);
+			}
+			err = copy_from_user(kaddr+offset, str, bytes_to_copy);
+			if (err) {
+				ret = -EFAULT;
+				goto out;
 			}
-			err = copy_from_user(kaddr + offset, str, bytes_to_copy);
-			kunmap(page);
-
-			if (err)
-				return -EFAULT; 
 
 			pos += bytes_to_copy;
 			str += bytes_to_copy;
 			len -= bytes_to_copy;
 		}
 	}
-	return 0;
+	ret = 0;
+out:
+	if (kmapped_page)
+		kunmap(kmapped_page);
+	return ret;
 }
 
 /*
diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c
--- a/fs/ext3/super.c	Sat Aug 10 18:42:23 2002
+++ b/fs/ext3/super.c	Sat Aug 10 18:42:23 2002
@@ -696,6 +696,11 @@
 				*mount_options &= ~EXT3_MOUNT_DATA_FLAGS;
 				*mount_options |= data_opt;
 			}
+		} else if (!strcmp (this_char, "commit")) {
+			unsigned long v;
+			if (want_numeric(value, "commit", &v))
+				return 0;
+			sbi->s_commit_interval = (HZ * v);
 		} else {
 			printk (KERN_ERR 
 				"EXT3-fs: Unrecognized mount option %s\n",
@@ -1260,6 +1265,22 @@
 	return -EINVAL;
 }
 
+/*
+ * Setup any per-fs journal parameters now.  We'll do this both on
+ * initial mount, once the journal has been initialised but before we've
+ * done any recovery; and again on any subsequent remount. 
+ */
+static void ext3_init_journal_params(struct ext3_sb_info *sbi, 
+				     journal_t *journal)
+{
+	if (sbi->s_commit_interval)
+		journal->j_commit_interval = sbi->s_commit_interval;
+	/* We could also set up an ext3-specific default for the commit
+	 * interval here, but for now we'll just fall back to the jbd
+	 * default. */
+}
+
+
 static journal_t *ext3_get_journal(struct super_block *sb, int journal_inum)
 {
 	struct inode *journal_inode;
@@ -1294,7 +1315,7 @@
 		printk(KERN_ERR "EXT3-fs: Could not load journal inode\n");
 		iput(journal_inode);
 	}
-	
+	ext3_init_journal_params(EXT3_SB(sb), journal);
 	return journal;
 }
 
@@ -1371,6 +1392,7 @@
 		goto out_journal;
 	}
 	EXT3_SB(sb)->journal_bdev = bdev;
+	ext3_init_journal_params(EXT3_SB(sb), journal);
 	return journal;
 out_journal:
 	journal_destroy(journal);
@@ -1667,6 +1689,8 @@
 
 	es = sbi->s_es;
 
+	ext3_init_journal_params(sbi, sbi->s_journal);
+	
 	if ((*flags & MS_RDONLY) != (sb->s_flags & MS_RDONLY)) {
 		if (sbi->s_mount_opt & EXT3_MOUNT_ABORT)
 			return -EROFS;
diff -Nru a/fs/jfs/Makefile b/fs/jfs/Makefile
--- a/fs/jfs/Makefile	Sat Aug 10 18:42:23 2002
+++ b/fs/jfs/Makefile	Sat Aug 10 18:42:23 2002
@@ -8,7 +8,7 @@
 	    jfs_xtree.o jfs_imap.o jfs_debug.o jfs_dmap.o \
 	    jfs_unicode.o jfs_dtree.o jfs_inode.o \
 	    jfs_extent.o symlink.o jfs_metapage.o \
-	    jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o
+	    jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o resize.o
 
 EXTRA_CFLAGS += -D_JFS_4K
 
diff -Nru a/fs/jfs/file.c b/fs/jfs/file.c
--- a/fs/jfs/file.c	Sat Aug 10 18:42:22 2002
+++ b/fs/jfs/file.c	Sat Aug 10 18:42:22 2002
@@ -38,9 +38,7 @@
 	if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
 		return rc;
 
-	IWRITE_LOCK(inode);
 	rc |= jfs_commit_inode(inode, 1);
-	IWRITE_UNLOCK(inode);
 
 	return rc ? -EIO : 0;
 }
@@ -64,10 +62,19 @@
 	do {
 		tid = txBegin(ip->i_sb, 0);
 
+		/*
+		 * The commit_sem cannot be taken before txBegin.
+		 * txBegin may block and there is a chance the inode
+		 * could be marked dirty and need to be committed
+		 * before txBegin unblocks
+		 */
+		down(&JFS_IP(ip)->commit_sem);
+
 		newsize = xtTruncate(tid, ip, length,
 				     COMMIT_TRUNCATE | COMMIT_PWMAP);
 		if (newsize < 0) {
 			txEnd(tid);
+			up(&JFS_IP(ip)->commit_sem);
 			break;
 		}
 
@@ -76,6 +83,7 @@
 
 		txCommit(tid, 1, &ip, 0);
 		txEnd(tid);
+		up(&JFS_IP(ip)->commit_sem);
 	} while (newsize > length);	/* Truncate isn't always atomic */
 }
 
diff -Nru a/fs/jfs/inode.c b/fs/jfs/inode.c
--- a/fs/jfs/inode.c	Sat Aug 10 18:42:19 2002
+++ b/fs/jfs/inode.c	Sat Aug 10 18:42:19 2002
@@ -107,8 +107,10 @@
 	}
 
 	tid = txBegin(inode->i_sb, COMMIT_INODE);
+	down(&JFS_IP(inode)->commit_sem);
 	rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
 	txEnd(tid);
+	up(&JFS_IP(inode)->commit_sem);
 	return -rc;
 }
 
@@ -123,25 +125,19 @@
 	    !test_cflag(COMMIT_Dirty, inode))
 		return;
 
-	IWRITE_LOCK(inode);
-
 	if (jfs_commit_inode(inode, wait)) {
 		jERROR(1, ("jfs_write_inode: jfs_commit_inode failed!\n"));
 	}
-
-	IWRITE_UNLOCK(inode);
 }
 
 void jfs_delete_inode(struct inode *inode)
 {
 	jFYI(1, ("In jfs_delete_inode, inode = 0x%p\n", inode));
 
-	IWRITE_LOCK(inode);
 	if (test_cflag(COMMIT_Freewmap, inode))
 		freeZeroLink(inode);
 
 	diFree(inode);
-	IWRITE_UNLOCK(inode);
 
 	clear_inode(inode);
 }
@@ -203,8 +199,7 @@
 
 	if ((no_size_check ||
 	     ((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size)) &&
-	    (xtLookup
-	     (ip, lblock64, 1, &xflag, &xaddr, &xlen, no_size_check)
+	    (xtLookup(ip, lblock64, 1, &xflag, &xaddr, &xlen, no_size_check)
 	     == 0) && xlen) {
 		if (xflag & XAD_NOTRECORDED) {
 			if (!create)
@@ -241,8 +236,7 @@
 	 * Allocate a new block
 	 */
 #ifdef _JFS_4K
-	if ((rc =
-	     extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad)))
+	if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad)))
 		goto unlock;
 	rc = extAlloc(ip, 1, lblock64, &xad, FALSE);
 	if (rc)
diff -Nru a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
--- a/fs/jfs/jfs_dmap.c	Sat Aug 10 18:42:23 2002
+++ b/fs/jfs/jfs_dmap.c	Sat Aug 10 18:42:23 2002
@@ -330,7 +330,7 @@
 	filemap_fdatawait(ipbmap->i_mapping);
 
 	ipbmap->i_state |= I_DIRTY;
-	diWriteSpecial(ipbmap);
+	diWriteSpecial(ipbmap, 0);
 
 	return (0);
 }
@@ -3175,7 +3175,7 @@
 			dp->wmap[word] |= cpu_to_le32(ONES << (DBWORD - nb)
 						      >> wbitno);
 
-			word += 1;
+			word++;
 		} else {
 			/* one or more dmap words are fully contained
 			 * within the block range.  determine how many
@@ -3187,6 +3187,7 @@
 
 			/* determine how many bits */
 			nb = nwords << L2DBWORD;
+			word += nwords;
 		}
 	}
 
diff -Nru a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c
--- a/fs/jfs/jfs_extent.c	Sat Aug 10 18:42:20 2002
+++ b/fs/jfs/jfs_extent.c	Sat Aug 10 18:42:20 2002
@@ -96,6 +96,9 @@
 	/* This blocks if we are low on resources */
 	txBeginAnon(ip->i_sb);
 
+	/* Avoid race with jfs_commit_inode() */
+	down(&JFS_IP(ip)->commit_sem);
+
 	/* validate extent length */
 	if (xlen > MAXXLEN)
 		xlen = MAXXLEN;
@@ -138,8 +141,8 @@
 	 * is smaller than the number of blocks per page.
 	 */
 	nxlen = xlen;
-	if ((rc =
-	     extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) {
+	if ((rc = extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) {
+		up(&JFS_IP(ip)->commit_sem);
 		return (rc);
 	}
 
@@ -160,6 +163,7 @@
 	 */
 	if (rc) {
 		dbFree(ip, nxaddr, nxlen);
+		up(&JFS_IP(ip)->commit_sem);
 		return (rc);
 	}
 
@@ -174,6 +178,7 @@
 
 	mark_inode_dirty(ip);
 
+	up(&JFS_IP(ip)->commit_sem);
 	/*
 	 * COMMIT_SyncList flags an anonymous tlock on page that is on
 	 * sync list.
@@ -217,6 +222,7 @@
 	/* This blocks if we are low on resources */
 	txBeginAnon(ip->i_sb);
 
+	down(&JFS_IP(ip)->commit_sem);
 	/* validate extent length */
 	if (nxlen > MAXXLEN)
 		nxlen = MAXXLEN;
@@ -235,7 +241,7 @@
 	if ((xp->flag & XAD_NOTRECORDED) && !abnr) {
 		xp->flag = 0;
 		if ((rc = xtUpdate(0, ip, xp)))
-			return (rc);
+			goto exit;
 	}
 
 	/* try to allocated the request number of blocks for the
@@ -247,7 +253,7 @@
 	 * space as to satisfy the extend page.
 	 */
 	if ((rc = extBrealloc(ip, xaddr, xlen, &nxlen, &nxaddr)))
-		return (rc);
+		goto exit;
 
 	delta = nxlen - xlen;
 
@@ -284,7 +290,7 @@
 		/* extend the extent */
 		if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
 			dbFree(ip, xaddr + xlen, delta);
-			return (rc);
+			goto exit;
 		}
 	} else {
 		/*
@@ -294,7 +300,7 @@
 		 */
 		if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
 			dbFree(ip, nxaddr, nxlen);
-			return (rc);
+			goto exit;
 		}
 	}
 
@@ -325,8 +331,9 @@
 	xp->flag = xflag;
 
 	mark_inode_dirty(ip);
-
-	return (0);
+exit:
+	up(&JFS_IP(ip)->commit_sem);
+	return (rc);
 }
 
 
@@ -423,19 +430,13 @@
 
 	txBeginAnon(ip->i_sb);
 
-	/* update the extent */
-	if ((rc = xtUpdate(0, ip, xp)))
-		return (rc);
+	down(&JFS_IP(ip)->commit_sem);
 
-#ifdef _STILL_TO_PORT
-	/* no longer abnr */
-	cp->cm_abnr = FALSE;
-
-	/* mark the cbuf as modified */
-	cp->cm_modified = TRUE;
-#endif				/*  _STILL_TO_PORT */
+	/* update the extent */
+	rc = xtUpdate(0, ip, xp);
 
-	return (0);
+	up(&JFS_IP(ip)->commit_sem);
+	return (rc);
 }
 
 
diff -Nru a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
--- a/fs/jfs/jfs_imap.c	Sat Aug 10 18:42:21 2002
+++ b/fs/jfs/jfs_imap.c	Sat Aug 10 18:42:21 2002
@@ -285,7 +285,7 @@
 	filemap_fdatawrite(ipimap->i_mapping);
 	filemap_fdatawait(ipimap->i_mapping);
 
-	diWriteSpecial(ipimap);
+	diWriteSpecial(ipimap, 0);
 
 	return (0);
 }
@@ -450,12 +450,13 @@
  * PARAMETERS:
  *      sb - filesystem superblock
  *	inum - aggregate inode number
+ *	secondary - 1 if secondary aggregate inode table
  *
  * RETURN VALUES:
  *      new inode	- success
  *      NULL		- i/o error.
  */
-struct inode *diReadSpecial(struct super_block *sb, ino_t inum)
+struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
 {
 	struct jfs_sb_info *sbi = JFS_SBI(sb);
 	uint address;
@@ -470,21 +471,16 @@
 		return ip;
 	}
 
-	/*
-	 * If ip->i_number >= 32 (INOSPEREXT), then read from secondary
-	 * aggregate inode table.
-	 */
-
-	if (inum >= INOSPEREXT) {
-		address =
-		    addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
-		inum -= INOSPEREXT;
-		ASSERT(inum < INOSPEREXT);
+	if (secondary) {
+		address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
 		JFS_IP(ip)->ipimap = sbi->ipaimap2;
 	} else {
 		address = AITBL_OFF >> L2PSIZE;
 		JFS_IP(ip)->ipimap = sbi->ipaimap;
 	}
+
+	ASSERT(inum < INOSPEREXT);
+
 	ip->i_ino = inum;
 
 	address += inum >> 3;	/* 8 inodes per 4K page */
@@ -538,11 +534,12 @@
  *
  * PARAMETERS:
  *      ip - special inode
+ *	secondary - 1 if secondary aggregate inode table
  *
  * RETURN VALUES: none
  */
 
-void diWriteSpecial(struct inode *ip)
+void diWriteSpecial(struct inode *ip, int secondary)
 {
 	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
 	uint address;
@@ -550,24 +547,14 @@
 	ino_t inum = ip->i_ino;
 	metapage_t *mp;
 
-	/*
-	 * If ip->i_number >= 32 (INOSPEREXT), then write to secondary
-	 * aggregate inode table.
-	 */
-
-	if (!(ip->i_state & I_DIRTY))
-		return;
-
 	ip->i_state &= ~I_DIRTY;
 
-	if (inum >= INOSPEREXT) {
-		address =
-		    addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
-		inum -= INOSPEREXT;
-		ASSERT(inum < INOSPEREXT);
-	} else {
+	if (secondary)
+		address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
+	else
 		address = AITBL_OFF >> L2PSIZE;
-	}
+
+	ASSERT(inum < INOSPEREXT);
 
 	address += inum >> 3;	/* 8 inodes per 4K page */
 
@@ -2996,7 +2983,7 @@
 	/* if AIT2 ipmap2 is bad, do not try to update it */
 	if (JFS_SBI(sb)->mntflag & JFS_BAD_SAIT)	/* s_flag */
 		return;
-	ip = diReadSpecial(sb, FILESYSTEM_I + INOSPEREXT);
+	ip = diReadSpecial(sb, FILESYSTEM_I, 1);
 	if (ip == 0) {
 		JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT;
 		if ((rc = readSuper(sb, &mpsuper)))
diff -Nru a/fs/jfs/jfs_imap.h b/fs/jfs/jfs_imap.h
--- a/fs/jfs/jfs_imap.h	Sat Aug 10 18:42:22 2002
+++ b/fs/jfs/jfs_imap.h	Sat Aug 10 18:42:22 2002
@@ -146,15 +146,12 @@
 /* external references */
 extern int diUpdatePMap(struct inode *ipimap, unsigned long inum,
 			boolean_t is_free, tblock_t * tblk);
-#ifdef _STILL_TO_PORT
-extern int diExtendFS(inode_t * ipimap, inode_t * ipbmap);
-#endif				/* _STILL_TO_PORT */
-
+extern int diExtendFS(struct inode *ipimap, struct inode *ipbmap);
 extern int diMount(struct inode *);
 extern int diUnmount(struct inode *, int);
 extern int diRead(struct inode *);
-extern struct inode *diReadSpecial(struct super_block *, ino_t);
-extern void diWriteSpecial(struct inode *);
+extern struct inode *diReadSpecial(struct super_block *, ino_t, int);
+extern void diWriteSpecial(struct inode *, int);
 extern void diFreeSpecial(struct inode *);
 extern int diWrite(tid_t tid, struct inode *);
 #endif				/* _H_JFS_IMAP */
diff -Nru a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h
--- a/fs/jfs/jfs_incore.h	Sat Aug 10 18:42:20 2002
+++ b/fs/jfs/jfs_incore.h	Sat Aug 10 18:42:20 2002
@@ -19,6 +19,7 @@
 #ifndef _H_JFS_INCORE
 #define _H_JFS_INCORE
 
+#include <linux/rwsem.h>
 #include <linux/slab.h>
 #include <asm/bitops.h>
 #include "jfs_types.h"
@@ -31,14 +32,6 @@
 #define JFS_SUPER_MAGIC 0x3153464a /* "JFS1" */
 
 /*
- * Due to header ordering problems this can't be in jfs_lock.h
- */
-typedef struct	jfs_rwlock {
-	struct rw_semaphore rw_sem;
-	atomic_t in_use;	/* for hacked implementation of trylock */
-} jfs_rwlock_t;
-
-/*
  * JFS-private inode information
  */
 struct jfs_inode_info {
@@ -62,7 +55,19 @@
 	lid_t	atltail;	/* anonymous tlock list tail	*/
 	struct list_head anon_inode_list; /* inodes having anonymous txns */
 	struct list_head mp_list; /* metapages in inode's address space */
-	jfs_rwlock_t rdwrlock;	/* read/write lock	*/
+	/*
+	 * rdwrlock serializes xtree between reads & writes and synchronizes
+	 * changes to special inodes.  It's use would be redundant on
+	 * directories since the i_sem taken in the VFS is sufficient.
+	 */
+	struct rw_semaphore rdwrlock;
+	/*
+	 * commit_sem serializes transaction processing on an inode.
+	 * It must be taken after beginning a transaction (txBegin), since
+	 * dirty inodes may be committed while a new transaction on the
+	 * inode is blocked in txBegin or TxBeginAnon
+	 */
+	struct semaphore commit_sem;
 	lid_t	xtlid;		/* lid of xtree lock on directory */
 	union {
 		struct {
@@ -87,6 +92,12 @@
 #define i_dtroot u.dir._dtroot
 #define i_inline u.link._inline
 
+
+#define IREAD_LOCK(ip)		down_read(&JFS_IP(ip)->rdwrlock)
+#define IREAD_UNLOCK(ip)	up_read(&JFS_IP(ip)->rdwrlock)
+#define IWRITE_LOCK(ip)		down_write(&JFS_IP(ip)->rdwrlock)
+#define IWRITE_UNLOCK(ip)	up_write(&JFS_IP(ip)->rdwrlock)
+
 /*
  * cflag
  */
@@ -125,6 +136,7 @@
 	u32		logdev;		/* 2: external log device	*/
 	uint		aggregate;	/* volume identifier in log record */
 	pxd_t		logpxd;		/* 8: pxd describing log	*/
+	pxd_t		fsckpxd;	/* 8: pxd describing fsck wkspc */
 	pxd_t		ait2;		/* 8: pxd describing AIT copy	*/
 	char		uuid[16];	/* 16: 128-bit uuid for volume	*/
 	char		loguuid[16];	/* 16: 128-bit uuid for log	*/
diff -Nru a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c
--- a/fs/jfs/jfs_inode.c	Sat Aug 10 18:42:21 2002
+++ b/fs/jfs/jfs_inode.c	Sat Aug 10 18:42:21 2002
@@ -91,40 +91,3 @@
 
 	return inode;
 }
-
-/*
- * NAME:	iwritelocklist()
- *
- * FUNCTION:	Lock multiple inodes in sorted order to avoid deadlock
- *
- */
-void iwritelocklist(int n, ...)
-{
-	va_list ilist;
-	struct inode *sort[4];
-	struct inode *ip;
-	int k, m;
-
-	va_start(ilist, n);
-	for (k = 0; k < n; k++)
-		sort[k] = va_arg(ilist, struct inode *);
-	va_end(ilist);
-
-	/* Bubble sort in descending order */
-	do {
-		m = 0;
-		for (k = 0; k < n; k++)
-			if ((k + 1) < n
-			    && sort[k + 1]->i_ino > sort[k]->i_ino) {
-				ip = sort[k];
-				sort[k] = sort[k + 1];
-				sort[k + 1] = ip;
-				m++;
-			}
-	} while (m);
-
-	/* Lock them */
-	for (k = 0; k < n; k++) {
-		IWRITE_LOCK(sort[k]);
-	}
-}
diff -Nru a/fs/jfs/jfs_lock.h b/fs/jfs/jfs_lock.h
--- a/fs/jfs/jfs_lock.h	Sat Aug 10 18:42:21 2002
+++ b/fs/jfs/jfs_lock.h	Sat Aug 10 18:42:21 2002
@@ -24,63 +24,7 @@
 
 /*
  *	jfs_lock.h
- *
- * JFS lock definition for globally referenced locks
  */
-
-/* readers/writer lock: thread-thread */
-
-/*
- * RW semaphores do not currently have a trylock function.  Since the
- * implementation varies by platform, I have implemented a platform-independent
- * wrapper around the rw_semaphore routines.  If this turns out to be the best
- * way of avoiding our locking problems, I will push to get a trylock
- * implemented in the kernel, but I'd rather find a way to avoid having to
- * use it.
- */
-#define RDWRLOCK_T jfs_rwlock_t
-static inline void RDWRLOCK_INIT(jfs_rwlock_t * Lock)
-{
-	init_rwsem(&Lock->rw_sem);
-	atomic_set(&Lock->in_use, 0);
-}
-static inline void READ_LOCK(jfs_rwlock_t * Lock)
-{
-	atomic_inc(&Lock->in_use);
-	down_read(&Lock->rw_sem);
-}
-static inline void READ_UNLOCK(jfs_rwlock_t * Lock)
-{
-	up_read(&Lock->rw_sem);
-	atomic_dec(&Lock->in_use);
-}
-static inline void WRITE_LOCK(jfs_rwlock_t * Lock)
-{
-	atomic_inc(&Lock->in_use);
-	down_write(&Lock->rw_sem);
-}
-
-static inline int WRITE_TRYLOCK(jfs_rwlock_t * Lock)
-{
-	if (atomic_read(&Lock->in_use))
-		return 0;
-	WRITE_LOCK(Lock);
-	return 1;
-}
-static inline void WRITE_UNLOCK(jfs_rwlock_t * Lock)
-{
-	up_write(&Lock->rw_sem);
-	atomic_dec(&Lock->in_use);
-}
-
-#define IREAD_LOCK(ip)		READ_LOCK(&JFS_IP(ip)->rdwrlock)
-#define IREAD_UNLOCK(ip)	READ_UNLOCK(&JFS_IP(ip)->rdwrlock)
-#define IWRITE_LOCK(ip)		WRITE_LOCK(&JFS_IP(ip)->rdwrlock)
-#define IWRITE_TRYLOCK(ip)	WRITE_TRYLOCK(&JFS_IP(ip)->rdwrlock)
-#define IWRITE_UNLOCK(ip)	WRITE_UNLOCK(&JFS_IP(ip)->rdwrlock)
-#define IWRITE_LOCK_LIST	iwritelocklist
-
-extern void iwritelocklist(int, ...);
 
 /*
  * Conditional sleep where condition is protected by spinlock
diff -Nru a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
--- a/fs/jfs/jfs_logmgr.c	Sat Aug 10 18:42:23 2002
+++ b/fs/jfs/jfs_logmgr.c	Sat Aug 10 18:42:23 2002
@@ -172,8 +172,6 @@
 
 static int lmNextPage(log_t * log);
 static int lmLogFileSystem(log_t * log, char *uuid, int activate);
-static int lmLogInit(log_t * log);
-static int lmLogShutdown(log_t * log);
 
 static int lbmLogInit(log_t * log);
 static void lbmLogShutdown(log_t * log);
@@ -1037,7 +1035,7 @@
 	 * by setting syncbarrier flag.
 	 */
 	if (written > LOGSYNC_BARRIER(logsize) && logsize > 32 * LOGPSIZE) {
-		log->syncbarrier = 1;
+		set_bit(log_SYNCBARRIER, &log->flag);
 		jFYI(1, ("log barrier on: lsn=0x%x syncpt=0x%x\n", lsn,
 			 log->syncpt));
 	}
@@ -1068,6 +1066,7 @@
 	if (!(log = kmalloc(sizeof(log_t), GFP_KERNEL)))
 		return ENOMEM;
 	memset(log, 0, sizeof(log_t));
+	init_waitqueue_head(&log->syncwait);
 
 	log->sb = sb;		/* This should be a list */
 
@@ -1080,7 +1079,7 @@
 	 * file system to log have 1-to-1 relationship;
 	 */
 
-	log->flag = JFS_INLINELOG;
+	set_bit(log_INLINELOG, &log->flag);
 	log->bdev = sb->s_bdev;
 	log->base = addressPXD(&JFS_SBI(sb)->logpxd);
 	log->size = lengthPXD(&JFS_SBI(sb)->logpxd) >>
@@ -1175,7 +1174,7 @@
  *			
  * serialization: single first open thread
  */
-static int lmLogInit(log_t * log)
+int lmLogInit(log_t * log)
 {
 	int rc = 0;
 	lrd_t lrd;
@@ -1203,7 +1202,7 @@
 	 */
 
 
-	if (!(log->flag & JFS_INLINELOG))
+	if (!test_bit(log_INLINELOG, &log->flag))
 		log->l2bsize = 12;	/* XXX kludge alert XXX */
 	if ((rc = lbmRead(log, 1, &bpsuper)))
 		goto errout10;
@@ -1224,7 +1223,7 @@
 	}
 
 	/* initialize log inode from log superblock */
-	if (log->flag & JFS_INLINELOG) {
+	if (test_bit(log_INLINELOG,&log->flag)) {
 		if (log->size != le32_to_cpu(logsuper->size)) {
 			rc = EINVAL;
 			goto errout20;
@@ -1244,10 +1243,6 @@
 		      log, (unsigned long long) log->base, log->size));
 	}
 
-	log->flag |= JFS_GROUPCOMMIT;
-/*
-	log->flag |= JFS_LAZYCOMMIT;
-*/
 	log->page = le32_to_cpu(logsuper->end) / LOGPSIZE;
 	log->eor = le32_to_cpu(logsuper->end) - (LOGPSIZE * log->page);
 
@@ -1309,7 +1304,6 @@
 	log->syncpt = lsn;
 	log->sync = log->syncpt;
 	log->nextsync = LOGSYNC_DELTA(log->logsize);
-	init_waitqueue_head(&log->syncwait);
 
 	jFYI(1, ("lmLogInit: lsn:0x%x syncpt:0x%x sync:0x%x\n",
 		 log->lsn, log->syncpt, log->sync));
@@ -1377,7 +1371,7 @@
 
 	jFYI(1, ("lmLogClose: log:0x%p\n", log));
 
-	if (!(log->flag & JFS_INLINELOG))
+	if (!test_bit(log_INLINELOG, &log->flag))
 		goto externalLog;
 	
 	/*
@@ -1445,7 +1439,7 @@
  *			
  * serialization: single last close thread
  */
-static int lmLogShutdown(log_t * log)
+int lmLogShutdown(log_t * log)
 {
 	int rc;
 	lrd_t lrd;
@@ -1524,8 +1518,6 @@
  *
  * RETURN:	0	- success
  *		errors returned by vms_iowait().
- *			
- * serialization: IWRITE_LOCK(log inode) held on entry/exit
  */
 static int lmLogFileSystem(log_t * log, char *uuid, int activate)
 {
@@ -1578,37 +1570,6 @@
 	return rc;
 }
 
-
-/*
- *	lmLogQuiesce()
- */
-int lmLogQuiesce(log_t * log)
-{
-	int rc;
-
-	rc = lmLogShutdown(log);
-
-	return rc;
-}
-
-
-/*
- *	lmLogResume()
- */
-int lmLogResume(log_t * log, struct super_block *sb)
-{
-	struct jfs_sb_info *sbi = JFS_SBI(sb);
-	int rc;
-
-	log->base = addressPXD(&sbi->logpxd);
-	log->size =
-	    (lengthPXD(&sbi->logpxd) << sb->s_blocksize_bits) >> L2LOGPSIZE;
-	rc = lmLogInit(log);
-
-	return rc;
-}
-
-
 /*
  *		log buffer manager (lbm)
  *		------------------------
@@ -2192,42 +2153,40 @@
 	return 0;
 }
 
-
-#ifdef _STILL_TO_PORT
 /*
  * NAME:	lmLogFormat()/jfs_logform()
  *
- * FUNCTION:	format file system log (ref. jfs_logform()).
+ * FUNCTION:	format file system log
  *
  * PARAMETERS:
- *	log	- log inode (with common mount inode base);
- *	logAddress - start address of log space in FS block;
+ *      log	- volume log
+ *	logAddress - start address of log space in FS block
  *	logSize	- length of log space in FS block;
  *
- * RETURN:	0 -	success
- *		-1 -	i/o error
+ * RETURN:	0	- success
+ *		-EIO	- i/o error
+ *
+ * XXX: We're synchronously writing one page at a time.  This needs to
+ *	be improved by writing multiple pages at once.
  */
-int lmLogFormat(inode_t * ipmnt, s64 logAddress, int logSize)
+int lmLogFormat(log_t *log, s64 logAddress, int logSize)
 {
-	int rc = 0;
-	cbuf_t *bp;
+	int rc = -EIO;
+	struct jfs_sb_info *sbi = JFS_SBI(log->sb);
 	logsuper_t *logsuper;
 	logpage_t *lp;
 	int lspn;		/* log sequence page number */
 	struct lrd *lrd_ptr;
-	int npbperpage, npages;
+	int npages = 0;
+	lbuf_t *bp;
 
 	jFYI(0, ("lmLogFormat: logAddress:%Ld logSize:%d\n",
-		 logAddress, logSize));
+		 (long long)logAddress, logSize));
 
-	/* allocate a JFS buffer */
-	bp = rawAllocate();
+	/* allocate a log buffer */
+	bp = lbmAllocate(log, 1);
 
-	/* map the logical block address to physical block address */
-	bp->cm_blkno = logAddress << ipmnt->i_l2bfactor;
-
-	npbperpage = LOGPSIZE >> ipmnt->i_l2pbsize;
-	npages = logSize / (LOGPSIZE >> ipmnt->i_l2bsize);
+	npages = logSize >> sbi->l2nbperpage;
 
 	/*
 	 *      log space:
@@ -2241,20 +2200,22 @@
 	/*
 	 *      init log superblock: log page 1
 	 */
-	logsuper = (logsuper_t *) bp->cm_cdata;
+	logsuper = (logsuper_t *) bp->l_ldata;
 
 	logsuper->magic = cpu_to_le32(LOGMAGIC);
 	logsuper->version = cpu_to_le32(LOGVERSION);
 	logsuper->state = cpu_to_le32(LOGREDONE);
-	logsuper->flag = cpu_to_le32(ipmnt->i_mntflag);	/* ? */
+	logsuper->flag = cpu_to_le32(sbi->mntflag);	/* ? */
 	logsuper->size = cpu_to_le32(npages);
-	logsuper->bsize = cpu_to_le32(ipmnt->i_bsize);
-	logsuper->l2bsize = cpu_to_le32(ipmnt->i_l2bsize);
-	logsuper->end =
-	    cpu_to_le32(2 * LOGPSIZE + LOGPHDRSIZE + LOGRDSIZE);
+	logsuper->bsize = cpu_to_le32(sbi->bsize);
+	logsuper->l2bsize = cpu_to_le32(sbi->l2bsize);
+	logsuper->end = cpu_to_le32(2 * LOGPSIZE + LOGPHDRSIZE + LOGRDSIZE);
 
-	bp->cm_blkno += npbperpage;
-	rawWrite(ipmnt, bp, 0);
+	bp->l_flag = lbmWRITE | lbmSYNC | lbmDIRECT;
+	bp->l_blkno = logAddress + sbi->nbperpage;
+	lbmStartIO(bp);
+	if ((rc = lbmIOWait(bp, 0)))
+		goto exit;
 
 	/*
 	 *      init pages 2 to npages-1 as log data pages:
@@ -2270,7 +2231,6 @@
 	 * a circular file for the log records;
 	 * lpsn grows by 1 monotonically as each log page is written
 	 * to the circular file of the log;
-	 * Since the AIX DUMMY log record is dropped for this XJFS,
 	 * and setLogpage() will not reset the page number even if
 	 * the eor is equal to LOGPHDRSIZE. In order for binary search
 	 * still work in find log end process, we have to simulate the
@@ -2279,8 +2239,7 @@
 	 * the succeeding log pages will have ascending order of
 	 * the lspn starting from 0, ... (N-2)
 	 */
-	lp = (logpage_t *) bp->cm_cdata;
-
+	lp = (logpage_t *) bp->l_ldata;
 	/*
 	 * initialize 1st log page to be written: lpsn = N - 1,
 	 * write a SYNCPT log record is written to this page
@@ -2295,8 +2254,11 @@
 	lrd_ptr->length = 0;
 	lrd_ptr->log.syncpt.sync = 0;
 
-	bp->cm_blkno += npbperpage;
-	rawWrite(ipmnt, bp, 0);
+	bp->l_blkno += sbi->nbperpage;
+	bp->l_flag = lbmWRITE | lbmSYNC | lbmDIRECT;
+	lbmStartIO(bp);
+	if ((rc = lbmIOWait(bp, 0)))
+		goto exit;
 
 	/*
 	 *      initialize succeeding log pages: lpsn = 0, 1, ..., (N-2)
@@ -2305,20 +2267,23 @@
 		lp->h.page = lp->t.page = cpu_to_le32(lspn);
 		lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE);
 
-		bp->cm_blkno += npbperpage;
-		rawWrite(ipmnt, bp, 0);
+		bp->l_blkno += sbi->nbperpage;
+		bp->l_flag = lbmWRITE | lbmSYNC | lbmDIRECT;
+		lbmStartIO(bp);
+		if ((rc = lbmIOWait(bp, 0)))
+			goto exit;
 	}
 
+	rc = 0;
+exit:
 	/*
 	 *      finalize log
 	 */
 	/* release the buffer */
-	rawRelease(bp);
+	lbmFree(bp);
 
 	return rc;
 }
-#endif				/* _STILL_TO_PORT */
-
 
 #ifdef CONFIG_JFS_STATISTICS
 int jfs_lmstats_read(char *buffer, char **start, off_t offset, int length,
diff -Nru a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h
--- a/fs/jfs/jfs_logmgr.h	Sat Aug 10 18:42:22 2002
+++ b/fs/jfs/jfs_logmgr.h	Sat Aug 10 18:42:22 2002
@@ -379,8 +379,7 @@
 	int size;		/* 4: log size in log page (in page) */
 	int l2bsize;		/* 4: log2 of bsize */
 
-	uint flag;		/* 4: flag */
-	uint state;		/* 4: state */
+	long flag;		/* 4: flag */
 
 	struct lbuf *lbuf_free;	/* 4: free lbufs */
 	wait_queue_head_t free_wait;	/* 4: */
@@ -396,7 +395,6 @@
 	/* syncpt */
 	int nextsync;		/* 4: bytes to write before next syncpt */
 	int active;		/* 4: */
-	int syncbarrier;	/* 4: */
 	wait_queue_head_t syncwait;	/* 4: */
 
 	/* commit */
@@ -421,6 +419,13 @@
 } log_t;
 
 /*
+ * Log flag
+ */
+#define log_INLINELOG	1
+#define log_SYNCBARRIER	2
+#define log_QUIESCE	3
+
+/*
  * group commit flag
  */
 /* log_t */
@@ -499,8 +504,8 @@
 extern void lmLogWait(log_t * log);
 extern int lmLogClose(struct super_block *sb, log_t * log);
 extern int lmLogSync(log_t * log, int nosyncwait);
-extern int lmLogQuiesce(log_t * log);
-extern int lmLogResume(log_t * log, struct super_block *sb);
-extern int lmLogFormat(struct super_block *sb, s64 logAddress, int logSize);
+extern int lmLogShutdown(log_t * log);
+extern int lmLogInit(log_t * log);
+extern int lmLogFormat(log_t *log, s64 logAddress, int logSize);
 
 #endif				/* _H_JFS_LOGMGR */
diff -Nru a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
--- a/fs/jfs/jfs_metapage.c	Sat Aug 10 18:42:21 2002
+++ b/fs/jfs/jfs_metapage.c	Sat Aug 10 18:42:21 2002
@@ -20,6 +20,7 @@
 #include <linux/fs.h>
 #include <linux/init.h>
 #include <linux/buffer_head.h>
+#include <linux/mempool.h>
 #include "jfs_incore.h"
 #include "jfs_filsys.h"
 #include "jfs_metapage.h"
@@ -27,11 +28,6 @@
 #include "jfs_debug.h"
 
 extern struct task_struct *jfsCommitTask;
-static unsigned int metapages = 1024;	/* ??? Need a better number */
-static unsigned int free_metapages;
-static metapage_t *metapage_buf;
-static unsigned long meta_order;
-static metapage_t *meta_free_list = NULL;
 static spinlock_t meta_lock = SPIN_LOCK_UNLOCKED;
 static wait_queue_head_t meta_wait;
 
@@ -93,12 +89,51 @@
 		__lock_metapage(mp);
 }
 
-int __init metapage_init(void)
+#define METAPOOL_MIN_PAGES 32
+static kmem_cache_t *metapage_cache;
+static mempool_t *metapage_mempool;
+
+static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
+{
+	metapage_t *mp = (metapage_t *)foo;
+
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR) {
+		mp->lid = 0;
+		mp->lsn = 0;
+		mp->flag = 0;
+		mp->data = NULL;
+		mp->clsn = 0;
+		mp->log = NULL;
+		set_bit(META_free, &mp->flag);
+		init_waitqueue_head(&mp->wait);
+	}
+}
+
+static inline metapage_t *alloc_metapage(int no_wait)
 {
-	int i;
-	metapage_t *last = NULL;
-	metapage_t *mp;
+	return mempool_alloc(metapage_mempool, no_wait ? GFP_ATOMIC : GFP_NOFS);
+}
+
+static inline void free_metapage(metapage_t *mp)
+{
+	mp->flag = 0;
+	set_bit(META_free, &mp->flag);
+
+	mempool_free(mp, metapage_mempool);
+}
+
+static void *mp_mempool_alloc(int gfp_mask, void *pool_data)
+{
+	return kmem_cache_alloc(metapage_cache, gfp_mask);
+}
+static void mp_mempool_free(void *element, void *pool_data)
+{
+	return kmem_cache_free(metapage_cache, element);
+}
 
+int __init metapage_init(void)
+{
 	/*
 	 * Initialize wait queue
 	 */
@@ -107,30 +142,18 @@
 	/*
 	 * Allocate the metapage structures
 	 */
-	for (meta_order = 0;
-	     ((PAGE_SIZE << meta_order) / sizeof(metapage_t)) < metapages;
-	     meta_order++);
-	metapages = (PAGE_SIZE << meta_order) / sizeof(metapage_t);
-
-	jFYI(1, ("metapage_init: metapage size = %Zd, metapages = %d\n",
-		 sizeof(metapage_t), metapages));
-
-	metapage_buf =
-	    (metapage_t *) __get_free_pages(GFP_KERNEL, meta_order);
-	assert(metapage_buf);
-	memset(metapage_buf, 0, PAGE_SIZE << meta_order);
-
-	mp = metapage_buf;
-	for (i = 0; i < metapages; i++, mp++) {
-		mp->flag = 0;
-		set_bit(META_free, &mp->flag);
-		init_waitqueue_head(&mp->wait);
-		mp->hash_next = last;
-		last = mp;
+	metapage_cache = kmem_cache_create("jfs_mp", sizeof(metapage_t), 0, 0,
+					   init_once, NULL);
+	if (metapage_cache == NULL)
+		return -ENOMEM;
+
+	metapage_mempool = mempool_create(METAPOOL_MIN_PAGES, mp_mempool_alloc,
+					  mp_mempool_free, NULL);
+
+	if (metapage_mempool == NULL) {
+		kmem_cache_destroy(metapage_cache);
+		return -ENOMEM;
 	}
-	meta_free_list = last;
-	free_metapages = metapages;
-
 	/*
 	 * Now the hash list
 	 */
@@ -147,64 +170,8 @@
 
 void metapage_exit(void)
 {
-	free_pages((unsigned long) metapage_buf, meta_order);
-	free_pages((unsigned long) hash_table, hash_order);
-	metapage_buf = 0;	/* This is a signal to the jfsIOwait thread */
-}
-
-/*
- * Get metapage structure from freelist
- * 
- * Caller holds meta_lock
- */
-static metapage_t *alloc_metapage(int *dropped_lock)
-{
-	metapage_t *new;
-
-	*dropped_lock = FALSE;
-
-	/*
-	 * Reserve two metapages for the lazy commit thread.  Otherwise
-	 * we may deadlock with holders of metapages waiting for tlocks
-	 * that lazy thread should be freeing.
-	 */
-	if ((free_metapages < 3) && (current != jfsCommitTask)) {
-		INCREMENT(mpStat.allocwait);
-		*dropped_lock = TRUE;
-		__SLEEP_COND(meta_wait, (free_metapages > 2),
-			     spin_lock(&meta_lock), spin_unlock(&meta_lock));
-	}
-
-	assert(meta_free_list);
-
-	new = meta_free_list;
-	meta_free_list = new->hash_next;
-	free_metapages--;
-
-	return new;
-}
-
-/*
- * Put metapage on freelist (holding meta_lock)
- */
-static inline void __free_metapage(metapage_t * mp)
-{
-	mp->flag = 0;
-	set_bit(META_free, &mp->flag);
-	mp->hash_next = meta_free_list;
-	meta_free_list = mp;
-	free_metapages++;
-	wake_up(&meta_wait);
-}
-
-/*
- * Put metapage on freelist (not holding meta_lock)
- */
-static inline void free_metapage(metapage_t * mp)
-{
-	spin_lock(&meta_lock);
-	__free_metapage(mp);
-	spin_unlock(&meta_lock);
+	mempool_destroy(metapage_mempool);
+	kmem_cache_destroy(metapage_cache);
 }
 
 /*
@@ -295,19 +262,18 @@
 }
 
 struct address_space_operations direct_aops = {
-	readpage:	direct_readpage,
-	writepage:	direct_writepage,
-	sync_page:	block_sync_page,
-	prepare_write:	direct_prepare_write,
-	commit_write:	generic_commit_write,
-	bmap:		direct_bmap,
+	.readpage	= direct_readpage,
+	.writepage	= direct_writepage,
+	.sync_page	= block_sync_page,
+	.prepare_write	= direct_prepare_write,
+	.commit_write	= generic_commit_write,
+	.bmap		= direct_bmap,
 };
 
 metapage_t *__get_metapage(struct inode *inode,
 			   unsigned long lblock, unsigned int size,
 			   int absolute, unsigned long new)
 {
-	int dropped_lock;
 	metapage_t **hash_ptr;
 	int l2BlocksPerPage;
 	int l2bsize;
@@ -353,17 +319,43 @@
 			jERROR(1, ("MetaData crosses page boundary!!\n"));
 			return NULL;
 		}
+		
+		/*
+		 * Locks held on aggregate inode pages are usually
+		 * not held long, and they are taken in critical code
+		 * paths (committing dirty inodes, txCommit thread) 
+		 * 
+		 * Attempt to get metapage without blocking, tapping into
+		 * reserves if necessary.
+		 */
+		mp = NULL;
+		if (JFS_IP(inode)->fileset == AGGREGATE_I) {
+			mp =  mempool_alloc(metapage_mempool, GFP_ATOMIC);
+			if (!mp) {
+				/*
+				 * mempool is supposed to protect us from
+				 * failing here.  We will try a blocking
+				 * call, but a deadlock is possible here
+				 */
+				printk(KERN_WARNING
+				       "__get_metapage: atomic call to mempool_alloc failed.\n");
+				printk(KERN_WARNING
+				       "Will attempt blocking call\n");
+			}
+		}
+		if (!mp) {
+			metapage_t *mp2;
 
-		mp = alloc_metapage(&dropped_lock);
-		if (dropped_lock) {
-			/* alloc_metapage blocked, we need to search the hash
-			 * again.  (The goto is ugly, maybe we'll clean this
-			 * up in the future.)
+			spin_unlock(&meta_lock);
+			mp =  mempool_alloc(metapage_mempool, GFP_NOFS);
+			spin_lock(&meta_lock);
+
+			/* we dropped the meta_lock, we need to search the
+			 * hash again.
 			 */
-			metapage_t *mp2;
 			mp2 = search_hash(hash_ptr, mapping, lblock);
 			if (mp2) {
-				__free_metapage(mp);
+				free_metapage(mp);
 				mp = mp2;
 				goto page_found;
 			}
@@ -416,7 +408,7 @@
 	remove_from_hash(mp, hash_ptr);
 	if (!absolute)
 		list_del(&mp->inode_list);
-	__free_metapage(mp);
+	free_metapage(mp);
 	spin_unlock(&meta_lock);
 	return NULL;
 }
@@ -631,12 +623,10 @@
 	len += sprintf(buffer,
 		       "JFS Metapage statistics\n"
 		       "=======================\n"
-		       "metapages in use = %d\n"
 		       "page allocations = %d\n"
 		       "page frees = %d\n"
 		       "lock waits = %d\n"
 		       "allocation waits = %d\n",
-		       metapages - free_metapages,
 		       mpStat.pagealloc,
 		       mpStat.pagefree,
 		       mpStat.lockwait,
diff -Nru a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c
--- a/fs/jfs/jfs_mount.c	Sat Aug 10 18:42:21 2002
+++ b/fs/jfs/jfs_mount.c	Sat Aug 10 18:42:21 2002
@@ -95,7 +95,7 @@
 		goto errout20;
 	}
 
-	ipaimap = diReadSpecial(sb, AGGREGATE_I);
+	ipaimap = diReadSpecial(sb, AGGREGATE_I, 0);
 	if (ipaimap == NULL) {
 		jERROR(1, ("jfs_mount: Faild to read AGGREGATE_I\n"));
 		rc = EIO;
@@ -118,7 +118,7 @@
 	/*
 	 * open aggregate block allocation map
 	 */
-	ipbmap = diReadSpecial(sb, BMAP_I);
+	ipbmap = diReadSpecial(sb, BMAP_I, 0);
 	if (ipbmap == NULL) {
 		rc = EIO;
 		goto errout22;
@@ -148,7 +148,7 @@
 	 * table.
 	 */
 	if ((sbi->mntflag & JFS_BAD_SAIT) == 0) {
-		ipaimap2 = diReadSpecial(sb, AGGREGATE_I + INOSPEREXT);
+		ipaimap2 = diReadSpecial(sb, AGGREGATE_I, 1);
 		if (ipaimap2 == 0) {
 			jERROR(1,
 			       ("jfs_mount: Faild to read AGGREGATE_I\n"));
@@ -178,7 +178,7 @@
 	/*
 	 * open fileset inode allocation map (aka fileset inode)
 	 */
-	ipimap = diReadSpecial(sb, FILESYSTEM_I);
+	ipimap = diReadSpecial(sb, FILESYSTEM_I, 0);
 	if (ipimap == NULL) {
 		jERROR(1, ("jfs_mount: Failed to read FILESYSTEM_I\n"));
 		/* open fileset secondary inode allocation map */
@@ -410,6 +410,7 @@
 		memcpy(sbi->uuid, j_sb->s_uuid, sizeof(sbi->uuid));
 		memcpy(sbi->loguuid, j_sb->s_loguuid, sizeof(sbi->uuid));
 	}
+	sbi->fsckpxd = j_sb->s_fsckpxd;
 	sbi->ait2 = j_sb->s_ait2;
 
       out:
diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
--- a/fs/jfs/jfs_txnmgr.c	Sat Aug 10 18:42:23 2002
+++ b/fs/jfs/jfs_txnmgr.c	Sat Aug 10 18:42:23 2002
@@ -318,11 +318,12 @@
 	TXN_LOCK();
 
       retry:
-	if (flag != COMMIT_FORCE) {
+	if (!(flag & COMMIT_FORCE)) {
 		/*
 		 * synchronize with logsync barrier
 		 */
-		if (log->syncbarrier) {
+		if (test_bit(log_SYNCBARRIER, &log->flag) ||
+		    test_bit(log_QUIESCE, &log->flag)) {
 			TXN_SLEEP(&log->syncwait);
 			goto retry;
 		}
@@ -330,8 +331,8 @@
 	if (flag == 0) {
 		/*
 		 * Don't begin transaction if we're getting starved for tlocks
-		 * unless COMMIT_FORCE (imap changes) or COMMIT_INODE (which
-		 * may ultimately free tlocks)
+		 * unless COMMIT_FORCE or COMMIT_INODE (which may ultimately
+		 * free tlocks)
 		 */
 		if (TlocksLow) {
 			TXN_SLEEP(&TxAnchor.lowlockwait);
@@ -411,7 +412,8 @@
 	/*
 	 * synchronize with logsync barrier
 	 */
-	if (log->syncbarrier) {
+	if (test_bit(log_SYNCBARRIER, &log->flag) ||
+	    test_bit(log_QUIESCE, &log->flag)) {
 		TXN_SLEEP(&log->syncwait);
 		goto retry;
 	}
@@ -490,14 +492,14 @@
 	/*
 	 * synchronize with logsync barrier
 	 */
-	if (log->syncbarrier && log->active == 0) {
+	if (test_bit(log_SYNCBARRIER, &log->flag) && log->active == 0) {
 		/* forward log syncpt */
 		/* lmSync(log); */
 
 		jFYI(1, ("     log barrier off: 0x%x\n", log->lsn));
 
 		/* enable new transactions start */
-		log->syncbarrier = 0;
+		clear_bit(log_SYNCBARRIER, &log->flag);
 
 		/* wakeup all waitors for logsync barrier */
 		TXN_WAKEUP(&log->syncwait);
@@ -823,36 +825,21 @@
  *
  * FUNCTION:    Initiates pageout of pages modified by tid in journalled
  *              objects and frees their lockwords.
- *
- * PARAMETER:
- *              flag    -
- *
- * RETURN:      Errors from subroutines.
  */
-static void txUnlock(tblock_t * tblk, int flag)
+static void txUnlock(tblock_t * tblk)
 {
 	tlock_t *tlck;
 	linelock_t *linelock;
 	lid_t lid, next, llid, k;
 	metapage_t *mp;
 	log_t *log;
-	int force;
 	int difft, diffp;
 
 	jFYI(1, ("txUnlock: tblk = 0x%p\n", tblk));
 	log = (log_t *) JFS_SBI(tblk->sb)->log;
-	force = flag & COMMIT_FLUSH;
-	if (log->syncbarrier)
-		force |= COMMIT_FORCE;
 
 	/*
 	 * mark page under tlock homeok (its log has been written):
-	 * if caller has specified FORCE (e.g., iRecycle()), or
-	 * if syncwait for the log is set (i.e., the log sync point
-	 * has fallen behind), or
-	 * if syncpt is set for the page, or
-	 * if the page is new, initiate pageout;
-	 * otherwise, leave the page in memory.
 	 */
 	for (lid = tblk->next; lid; lid = next) {
 		tlck = lid_to_tlock(lid);
@@ -1268,7 +1255,7 @@
 	txRelease(tblk);
 
 	if ((tblk->flag & tblkGC_LAZY) == 0)
-		txUnlock(tblk, flag);
+		txUnlock(tblk);
 
 
 	/*
@@ -2753,7 +2740,7 @@
 	spin_unlock_irq(&log->gclock);	// LOGGC_UNLOCK
 
 	if (tblk->flag & tblkGC_LAZY) {
-		txUnlock(tblk, 0);
+		txUnlock(tblk);
 		tblk->flag &= ~tblkGC_LAZY;
 		txEnd(tblk - TxBlock);	/* Convert back to tid */
 	}
@@ -2888,6 +2875,77 @@
 }
 
 /*
+ *	txQuiesce
+ *
+ *	Block all new transactions and push anonymous transactions to
+ *	completion
+ *
+ *	This does almost the same thing as jfs_sync below.  We don't
+ *	worry about deadlocking when TlocksLow is set, since we would
+ *	expect jfs_sync to get us out of that jam.
+ */
+void txQuiesce(struct super_block *sb)
+{
+	struct inode *ip;
+	struct jfs_inode_info *jfs_ip;
+	log_t *log = JFS_SBI(sb)->log;
+	int rc;
+	tid_t tid;
+
+	set_bit(log_QUIESCE, &log->flag);
+
+	TXN_LOCK();
+restart:
+	while (!list_empty(&TxAnchor.anon_list)) {
+		jfs_ip = list_entry(TxAnchor.anon_list.next,
+				    struct jfs_inode_info,
+				    anon_inode_list);
+		ip = &jfs_ip->vfs_inode;
+
+		/*
+		 * inode will be removed from anonymous list
+		 * when it is committed
+		 */
+		TXN_UNLOCK();
+		tid = txBegin(ip->i_sb, COMMIT_INODE | COMMIT_FORCE);
+		down(&jfs_ip->commit_sem);
+		rc = txCommit(tid, 1, &ip, 0);
+		txEnd(tid);
+		up(&jfs_ip->commit_sem);
+		/*
+		 * Just to be safe.  I don't know how
+		 * long we can run without blocking
+		 */
+		cond_resched();
+		TXN_LOCK();
+	}
+
+	/*
+	 * If jfs_sync is running in parallel, there could be some inodes
+	 * on anon_list2.  Let's check.
+	 */
+	if (!list_empty(&TxAnchor.anon_list2)) {
+		list_splice(&TxAnchor.anon_list2, &TxAnchor.anon_list);
+		INIT_LIST_HEAD(&TxAnchor.anon_list2);
+		goto restart;
+	}
+	TXN_UNLOCK();
+}
+
+/*
+ * txResume()
+ *
+ * Allows transactions to start again following txQuiesce
+ */
+void txResume(struct super_block *sb)
+{
+	log_t *log = JFS_SBI(sb)->log;
+
+	clear_bit(log_QUIESCE, &log->flag);
+	TXN_WAKEUP(&log->syncwait);
+}
+
+/*
  *      jfs_sync(void)
  *
  *	To be run as a kernel daemon.  This is awakened when tlocks run low.
@@ -2898,6 +2956,8 @@
 {
 	struct inode *ip;
 	struct jfs_inode_info *jfs_ip;
+	int rc;
+	tid_t tid;
 
 	lock_kernel();
 
@@ -2927,17 +2987,20 @@
 			ip = &jfs_ip->vfs_inode;
 
 			/*
-			 * We must release the TXN_LOCK since our
-			 * IWRITE_TRYLOCK implementation may still block
+			 * down_trylock returns 0 on success.  This is
+			 * inconsistent with spin_trylock.
 			 */
-			TXN_UNLOCK();
-			if (IWRITE_TRYLOCK(ip)) {
+			if (! down_trylock(&jfs_ip->commit_sem)) {
 				/*
 				 * inode will be removed from anonymous list
 				 * when it is committed
 				 */
-				jfs_commit_inode(ip, 0);
-				IWRITE_UNLOCK(ip);
+				TXN_UNLOCK();
+				tid = txBegin(ip->i_sb,
+					      COMMIT_INODE | COMMIT_FORCE);
+				rc = txCommit(tid, 1, &ip, 0);
+				txEnd(tid);
+				up(&jfs_ip->commit_sem);
 				/*
 				 * Just to be safe.  I don't know how
 				 * long we can run without blocking
@@ -2945,20 +3008,11 @@
 				cond_resched();
 				TXN_LOCK();
 			} else {
-				/* We can't get the write lock.  It may
+				/* We can't get the commit semaphore.  It may
 				 * be held by a thread waiting for tlock's
 				 * so let's not block here.  Save it to
 				 * put back on the anon_list.
 				 */
-
-				/*
-				 * We released TXN_LOCK, let's make sure
-				 * this inode is still there
-				 */
-				TXN_LOCK();
-				if (TxAnchor.anon_list.next !=
-				    &jfs_ip->anon_inode_list)
-					continue;
 
 				/* Take off anon_list */
 				list_del(&jfs_ip->anon_inode_list);
diff -Nru a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h
--- a/fs/jfs/jfs_txnmgr.h	Sat Aug 10 18:42:23 2002
+++ b/fs/jfs/jfs_txnmgr.h	Sat Aug 10 18:42:23 2002
@@ -310,4 +310,7 @@
 
 extern int lmLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
 
+extern void txQuiesce(struct super_block *sb);
+
+extern void txResume(struct super_block *sb);
 #endif				/* _H_JFS_TXNMGR */
diff -Nru a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
--- a/fs/jfs/jfs_xtree.c	Sat Aug 10 18:42:22 2002
+++ b/fs/jfs/jfs_xtree.c	Sat Aug 10 18:42:22 2002
@@ -2373,7 +2373,6 @@
 }
 
 
-#ifdef _STILL_TO_PORT
 /*
  *      xtAppend()
  *
@@ -2392,7 +2391,7 @@
  * return:
  */
 int xtAppend(tid_t tid,		/* transaction id */
-	     struct inode *ip, int xflag, s64 xoff, s32 maxblocks,	/* @GD1 */
+	     struct inode *ip, int xflag, s64 xoff, s32 maxblocks,	
 	     s32 * xlenp,	/* (in/out) */
 	     s64 * xaddrp,	/* (in/out) */
 	     int flag)
@@ -2460,7 +2459,7 @@
 	pxdlist.maxnpxd = pxdlist.npxd = 0;
 	pxd = &pxdlist.pxd[0];
 	nblocks = JFS_SBI(ip->i_sb)->nbperpage;
-	for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) {	/* @GD1 */
+	for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) {	
 		if ((rc = dbAllocBottomUp(ip, xaddr, (s64) nblocks)) == 0) {
 			PXDaddress(pxd, xaddr);
 			PXDlength(pxd, nblocks);
@@ -2475,7 +2474,7 @@
 		goto out;
 	}
 
-	xlen = min(xlen, maxblocks);	/* @GD1 */
+	xlen = min(xlen, maxblocks);	
 
 	/*
 	 * allocate data extent requested
@@ -2528,7 +2527,7 @@
 	    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);
 
 	xtlck->lwm.offset =
-	    (xtlck->lwm.offset) ? min(index, xtlck->lwm.offset) : index;
+	    (xtlck->lwm.offset) ? min(index,(int) xtlck->lwm.offset) : index;
 	xtlck->lwm.length = le16_to_cpu(p->header.nextindex) -
 	    xtlck->lwm.offset;
 
@@ -2541,7 +2540,7 @@
 
 	return rc;
 }
-
+#ifdef _STILL_TO_PORT
 
 /* - TBD for defragmentaion/reorganization -
  *
diff -Nru a/fs/jfs/namei.c b/fs/jfs/namei.c
--- a/fs/jfs/namei.c	Sat Aug 10 18:42:23 2002
+++ b/fs/jfs/namei.c	Sat Aug 10 18:42:23 2002
@@ -69,8 +69,6 @@
 
 	jFYI(1, ("jfs_create: dip:0x%p name:%s\n", dip, dentry->d_name.name));
 
-	IWRITE_LOCK(dip);
-
 	/*
 	 * search parent directory for entry/freespace
 	 * (dtSearch() returns parent directory page pinned)
@@ -91,12 +89,12 @@
 
 	tid = txBegin(dip->i_sb, 0);
 
+	down(&JFS_IP(dip)->commit_sem);
+	down(&JFS_IP(ip)->commit_sem);
+
 	if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
 		jERROR(1, ("jfs_create: dtSearch returned %d\n", rc));
-		ip->i_nlink = 0;
-		iput(ip);
-		txEnd(tid);
-		goto out2;
+		goto out3;
 	}
 
 	tblk = tid_to_tblock(tid);
@@ -118,16 +116,11 @@
 	ino = ip->i_ino;
 	if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
 		jERROR(1, ("jfs_create: dtInsert returned %d\n", rc));
-		/* discard new inode */
-		ip->i_nlink = 0;
-		iput(ip);
-
 		if (rc == EIO)
 			txAbort(tid, 1);	/* Marks Filesystem dirty */
 		else
 			txAbort(tid, 0);	/* Filesystem full */
-		txEnd(tid);
-		goto out2;
+		goto out3;
 	}
 
 	ip->i_op = &jfs_file_inode_operations;
@@ -143,14 +136,21 @@
 	mark_inode_dirty(dip);
 
 	rc = txCommit(tid, 2, &iplist[0], 0);
+
+      out3:
 	txEnd(tid);
+	up(&JFS_IP(dip)->commit_sem);
+	up(&JFS_IP(ip)->commit_sem);
+	if (rc) {
+		ip->i_nlink = 0;
+		iput(ip);
+	}
 
       out2:
 	free_UCSname(&dname);
 
       out1:
 
-	IWRITE_UNLOCK(dip);
 	jFYI(1, ("jfs_create: rc:%d\n", -rc));
 	return -rc;
 }
@@ -184,8 +184,6 @@
 
 	jFYI(1, ("jfs_mkdir: dip:0x%p name:%s\n", dip, dentry->d_name.name));
 
-	IWRITE_LOCK(dip);
-
 	/* link count overflow on parent directory ? */
 	if (dip->i_nlink == JFS_LINK_MAX) {
 		rc = EMLINK;
@@ -212,12 +210,12 @@
 
 	tid = txBegin(dip->i_sb, 0);
 
+	down(&JFS_IP(dip)->commit_sem);
+	down(&JFS_IP(ip)->commit_sem);
+
 	if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
 		jERROR(1, ("jfs_mkdir: dtSearch returned %d\n", rc));
-		ip->i_nlink = 0;
-		iput(ip);
-		txEnd(tid);
-		goto out2;
+		goto out3;
 	}
 
 	tblk = tid_to_tblock(tid);
@@ -239,16 +237,12 @@
 	ino = ip->i_ino;
 	if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
 		jERROR(1, ("jfs_mkdir: dtInsert returned %d\n", rc));
-		/* discard new directory inode */
-		ip->i_nlink = 0;
-		iput(ip);
 
 		if (rc == EIO)
 			txAbort(tid, 1);	/* Marks Filesystem dirty */
 		else
 			txAbort(tid, 0);	/* Filesystem full */
-		txEnd(tid);
-		goto out2;
+		goto out3;
 	}
 
 	ip->i_nlink = 2;	/* for '.' */
@@ -267,15 +261,21 @@
 	mark_inode_dirty(dip);
 
 	rc = txCommit(tid, 2, &iplist[0], 0);
+
+      out3:
 	txEnd(tid);
+	up(&JFS_IP(dip)->commit_sem);
+	up(&JFS_IP(ip)->commit_sem);
+	if (rc) {
+		ip->i_nlink = 0;
+		iput(ip);
+	}
 
       out2:
 	free_UCSname(&dname);
 
       out1:
 
-	IWRITE_UNLOCK(dip);
-
 	jFYI(1, ("jfs_mkdir: rc:%d\n", -rc));
 	return -rc;
 }
@@ -311,24 +311,21 @@
 
 	jFYI(1, ("jfs_rmdir: dip:0x%p name:%s\n", dip, dentry->d_name.name));
 
-	IWRITE_LOCK_LIST(2, dip, ip);
-
 	/* directory must be empty to be removed */
 	if (!dtEmpty(ip)) {
-		IWRITE_UNLOCK(ip);
-		IWRITE_UNLOCK(dip);
 		rc = ENOTEMPTY;
 		goto out;
 	}
 
 	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) {
-		IWRITE_UNLOCK(ip);
-		IWRITE_UNLOCK(dip);
 		goto out;
 	}
 
 	tid = txBegin(dip->i_sb, 0);
 
+	down(&JFS_IP(dip)->commit_sem);
+	down(&JFS_IP(ip)->commit_sem);
+
 	iplist[0] = dip;
 	iplist[1] = ip;
 
@@ -345,9 +342,8 @@
 		if (rc == EIO)
 			txAbort(tid, 1);
 		txEnd(tid);
-
-		IWRITE_UNLOCK(ip);
-		IWRITE_UNLOCK(dip);
+		up(&JFS_IP(dip)->commit_sem);
+		up(&JFS_IP(ip)->commit_sem);
 
 		goto out2;
 	}
@@ -384,7 +380,8 @@
 
 	txEnd(tid);
 
-	IWRITE_UNLOCK(ip);
+	up(&JFS_IP(dip)->commit_sem);
+	up(&JFS_IP(ip)->commit_sem);
 
 	/*
 	 * Truncating the directory index table is not guaranteed.  It
@@ -397,8 +394,6 @@
 		clear_cflag(COMMIT_Stale, dip);
 	}
 
-	IWRITE_UNLOCK(dip);
-
       out2:
 	free_UCSname(&dname);
 
@@ -444,10 +439,13 @@
 	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
 		goto out;
 
-	IWRITE_LOCK_LIST(2, ip, dip);
+	IWRITE_LOCK(ip);
 
 	tid = txBegin(dip->i_sb, 0);
 
+	down(&JFS_IP(dip)->commit_sem);
+	down(&JFS_IP(ip)->commit_sem);
+
 	iplist[0] = dip;
 	iplist[1] = ip;
 
@@ -460,8 +458,9 @@
 		if (rc == EIO)
 			txAbort(tid, 1);	/* Marks FS Dirty */
 		txEnd(tid);
+		up(&JFS_IP(dip)->commit_sem);
+		up(&JFS_IP(ip)->commit_sem);
 		IWRITE_UNLOCK(ip);
-		IWRITE_UNLOCK(dip);
 		goto out1;
 	}
 
@@ -483,8 +482,9 @@
 		if ((new_size = commitZeroLink(tid, ip)) < 0) {
 			txAbort(tid, 1);	/* Marks FS Dirty */
 			txEnd(tid);
+			up(&JFS_IP(dip)->commit_sem);
+			up(&JFS_IP(ip)->commit_sem);
 			IWRITE_UNLOCK(ip);
-			IWRITE_UNLOCK(dip);
 			rc = -new_size;		/* We return -rc */
 			goto out1;
 		}
@@ -511,8 +511,13 @@
 
 	txEnd(tid);
 
+	up(&JFS_IP(dip)->commit_sem);
+	up(&JFS_IP(ip)->commit_sem);
+
+
 	while (new_size && (rc == 0)) {
 		tid = txBegin(dip->i_sb, 0);
+		down(&JFS_IP(ip)->commit_sem);
 		new_size = xtTruncate_pmap(tid, ip, new_size);
 		if (new_size < 0) {
 			txAbort(tid, 1);	/* Marks FS Dirty */
@@ -520,6 +525,7 @@
 		} else
 			rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC);
 		txEnd(tid);
+		up(&JFS_IP(ip)->commit_sem);
 	}
 
 	if (ip->i_nlink == 0)
@@ -539,8 +545,6 @@
 		clear_cflag(COMMIT_Stale, dip);
 	}
 
-	IWRITE_UNLOCK(dip);
-
       out1:
 	free_UCSname(&dname);
       out:
@@ -764,10 +768,11 @@
 	     ("jfs_link: %s %s\n", old_dentry->d_name.name,
 	      dentry->d_name.name));
 
-	IWRITE_LOCK_LIST(2, dir, ip);
-
 	tid = txBegin(ip->i_sb, 0);
 
+	down(&JFS_IP(dir)->commit_sem);
+	down(&JFS_IP(ip)->commit_sem);
+
 	if (ip->i_nlink == JFS_LINK_MAX) {
 		rc = EMLINK;
 		goto out;
@@ -801,11 +806,11 @@
 	rc = txCommit(tid, 2, &iplist[0], 0);
 
       out:
-	IWRITE_UNLOCK(dir);
-	IWRITE_UNLOCK(ip);
-
 	txEnd(tid);
 
+	up(&JFS_IP(dir)->commit_sem);
+	up(&JFS_IP(ip)->commit_sem);
+
 	jFYI(1, ("jfs_link: rc:%d\n", rc));
 	return -rc;
 }
@@ -849,12 +854,8 @@
 
 	jFYI(1, ("jfs_symlink: dip:0x%p name:%s\n", dip, name));
 
-	IWRITE_LOCK(dip);
-
 	ssize = strlen(name) + 1;
 
-	tid = txBegin(dip->i_sb, 0);
-
 	/*
 	 * search parent directory for entry/freespace
 	 * (dtSearch() returns parent directory page pinned)
@@ -863,23 +864,24 @@
 	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
 		goto out1;
 
-	if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE)))
-		goto out2;
-
-
-
 	/*
 	 * allocate on-disk/in-memory inode for symbolic link:
 	 * (iAlloc() returns new, locked inode)
 	 */
-
 	ip = ialloc(dip, S_IFLNK | 0777);
 	if (ip == NULL) {
-		BT_PUTSEARCH(&btstack);
 		rc = ENOSPC;
 		goto out2;
 	}
 
+	tid = txBegin(dip->i_sb, 0);
+
+	down(&JFS_IP(dip)->commit_sem);
+	down(&JFS_IP(ip)->commit_sem);
+
+	if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE)))
+		goto out3;
+
 	tblk = tid_to_tblock(tid);
 	tblk->xflag |= COMMIT_CREATE;
 	tblk->ip = ip;
@@ -895,9 +897,7 @@
 	if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
 		jERROR(1, ("jfs_symlink: dtInsert returned %d\n", rc));
 		/* discard ne inode */
-		ip->i_nlink = 0;
-		iput(ip);
-		goto out2;
+		goto out3;
 
 	}
 
@@ -955,10 +955,8 @@
 				if (mp == NULL) {
 					dtDelete(tid, dip, &dname, &ino,
 						 JFS_REMOVE);
-					ip->i_nlink = 0;
-					iput(ip);
 					rc = EIO;
-					goto out2;
+					goto out3;
 				}
 				memcpy(mp->data, name, copy_size);
 				flush_metapage(mp);
@@ -977,10 +975,8 @@
 			ip->i_blocks = LBLK2PBLK(sb, xlen);
 		} else {
 			dtDelete(tid, dip, &dname, &ino, JFS_REMOVE);
-			ip->i_nlink = 0;
-			iput(ip);
 			rc = ENOSPC;
-			goto out2;
+			goto out3;
 		}
 	}
 
@@ -1008,14 +1004,19 @@
 	} else
 		rc = txCommit(tid, 1, &iplist[0], 0);
 
-      out2:
+      out3:
+	txEnd(tid);
+	up(&JFS_IP(dip)->commit_sem);
+	up(&JFS_IP(ip)->commit_sem);
+	if (rc) {
+		ip->i_nlink = 0;
+		iput(ip);
+	}
 
+      out2:
 	free_UCSname(&dname);
-      out1:
-	IWRITE_UNLOCK(dip);
-
-	txEnd(tid);
 
+      out1:
 	jFYI(1, ("jfs_symlink: rc:%d\n", -rc));
 	return -rc;
 }
@@ -1054,19 +1055,6 @@
 	old_ip = old_dentry->d_inode;
 	new_ip = new_dentry->d_inode;
 
-	if (old_dir == new_dir) {
-		if (new_ip)
-			IWRITE_LOCK_LIST(3, old_dir, old_ip, new_ip);
-		else
-			IWRITE_LOCK_LIST(2, old_dir, old_ip);
-	} else {
-		if (new_ip)
-			IWRITE_LOCK_LIST(4, old_dir, new_dir, old_ip,
-					 new_ip);
-		else
-			IWRITE_LOCK_LIST(3, old_dir, new_dir, old_ip);
-	}
-
 	if ((rc = get_UCSname(&old_dname, old_dentry,
 			      JFS_SBI(old_dir->i_sb)->nls_tab)))
 		goto out1;
@@ -1112,14 +1100,21 @@
 			rc = EMLINK;
 			goto out3;
 		}
-	}
+	} else if (new_ip)
+		IWRITE_LOCK(new_ip);
 
 	/*
 	 * The real work starts here
 	 */
 	tid = txBegin(new_dir->i_sb, 0);
 
+	down(&JFS_IP(new_dir)->commit_sem);
+	down(&JFS_IP(old_ip)->commit_sem);
+	if (old_dir != new_dir)
+		down(&JFS_IP(old_dir)->commit_sem);
+
 	if (new_ip) {
+		down(&JFS_IP(new_ip)->commit_sem);
 		/*
 		 * Change existing directory entry to new inode number
 		 */
@@ -1247,14 +1242,24 @@
 	/*
 	 * Don't unlock new_ip if COMMIT_HOLDLOCK is set
 	 */
-	if (new_ip && test_cflag(COMMIT_Holdlock, new_ip))
+	if (new_ip && test_cflag(COMMIT_Holdlock, new_ip)) {
+		up(&JFS_IP(new_ip)->commit_sem);
 		new_ip = 0;
+	}
 
       out4:
 	txEnd(tid);
 
+	up(&JFS_IP(new_dir)->commit_sem);
+	up(&JFS_IP(old_ip)->commit_sem);
+	if (old_dir != new_dir)
+		up(&JFS_IP(old_dir)->commit_sem);
+	if (new_ip)
+		up(&JFS_IP(new_ip)->commit_sem);
+
 	while (new_size && (rc == 0)) {
 		tid = txBegin(new_ip->i_sb, 0);
+		down(&JFS_IP(new_ip)->commit_sem);
 		new_size = xtTruncate_pmap(tid, new_ip, new_size);
 		if (new_size < 0) {
 			txAbort(tid, 1);
@@ -1262,6 +1267,7 @@
 		} else
 			rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
 		txEnd(tid);
+		up(&JFS_IP(new_ip)->commit_sem);
 	}
 	if (new_ip && (new_ip->i_nlink == 0))
 		set_cflag(COMMIT_Nolink, new_ip);
@@ -1270,12 +1276,8 @@
       out2:
 	free_UCSname(&old_dname);
       out1:
-	IWRITE_UNLOCK(old_ip);
-	if (old_dir != new_dir)
-		IWRITE_UNLOCK(new_dir);
-	if (new_ip)
+	if (new_ip && !S_ISDIR(new_ip->i_mode))
 		IWRITE_UNLOCK(new_ip);
-
 	/*
 	 * Truncating the directory index table is not guaranteed.  It
 	 * may need to be done iteratively
@@ -1287,8 +1289,6 @@
 		clear_cflag(COMMIT_Stale, old_dir);
 	}
 
-	IWRITE_UNLOCK(old_dir);
-
 	jFYI(1, ("jfs_rename: returning %d\n", rc));
 	return -rc;
 }
@@ -1315,8 +1315,6 @@
 	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab)))
 		goto out;
 
-	IWRITE_LOCK(dir);
-
 	ip = ialloc(dir, mode);
 	if (ip == NULL) {
 		rc = ENOSPC;
@@ -1325,24 +1323,19 @@
 
 	tid = txBegin(dir->i_sb, 0);
 
-	if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) {
-		ip->i_nlink = 0;
-		iput(ip);
-		txEnd(tid);
-		goto out1;
-	}
+	down(&JFS_IP(dir)->commit_sem);
+	down(&JFS_IP(ip)->commit_sem);
+
+	if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
+		goto out3;
 
 	tblk = tid_to_tblock(tid);
 	tblk->xflag |= COMMIT_CREATE;
 	tblk->ip = ip;
 
 	ino = ip->i_ino;
-	if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) {
-		ip->i_nlink = 0;
-		iput(ip);
-		txEnd(tid);
-		goto out1;
-	}
+	if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))
+		goto out3;
 
 	init_special_inode(ip, ip->i_mode, rdev);
 
@@ -1357,10 +1350,17 @@
 	iplist[0] = dir;
 	iplist[1] = ip;
 	rc = txCommit(tid, 2, iplist, 0);
+
+      out3:
 	txEnd(tid);
+	up(&JFS_IP(ip)->commit_sem);
+	up(&JFS_IP(dir)->commit_sem);
+	if (rc) {
+		ip->i_nlink = 0;
+		iput(ip);
+	}
 
       out1:
-	IWRITE_UNLOCK(dir);
 	free_UCSname(&dname);
 
       out:
@@ -1389,9 +1389,7 @@
 		if ((rc =
 		     get_UCSname(&key, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
 			return ERR_PTR(-rc);
-		IREAD_LOCK(dip);
 		rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP);
-		IREAD_UNLOCK(dip);
 		free_UCSname(&key);
 		if (rc == ENOENT) {
 			d_add(dentry, NULL);
diff -Nru a/fs/jfs/resize.c b/fs/jfs/resize.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/jfs/resize.c	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,532 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000-2002
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <linux/fs.h>
+#include <linux/buffer_head.h>
+#include "jfs_incore.h"
+#include "jfs_filsys.h"
+#include "jfs_metapage.h"
+#include "jfs_dinode.h"
+#include "jfs_imap.h"
+#include "jfs_dmap.h"
+#include "jfs_superblock.h"
+#include "jfs_txnmgr.h"
+#include "jfs_debug.h"
+
+#define BITSPERPAGE     (PSIZE << 3)
+#define L2MEGABYTE      20
+#define MEGABYTE        (1 << L2MEGABYTE)
+#define MEGABYTE32     (MEGABYTE << 5)
+
+/* convert block number to bmap file page number */
+#define BLKTODMAPN(b)\
+        (((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1)
+
+/*
+ *      jfs_extendfs()
+ *
+ * function: extend file system;
+ *
+ *   |-------------------------------|----------|----------|
+ *   file system space               fsck       inline log
+ *                                   workspace  space
+ *
+ * input:
+ *      new LVSize: in LV blocks (required)
+ *      new LogSize: in LV blocks (optional)
+ *      new FSSize: in LV blocks (optional)
+ *
+ * new configuration:
+ * 1. set new LogSize as specified or default from new LVSize;
+ * 2. compute new FSCKSize from new LVSize;
+ * 3. set new FSSize as MIN(FSSize, LVSize-(LogSize+FSCKSize)) where
+ *    assert(new FSSize >= old FSSize),
+ *    i.e., file system must not be shrinked;
+ */
+int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
+{
+	int rc = 0;
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+	struct inode *ipbmap = sbi->ipbmap;
+	struct inode *ipbmap2;
+	struct inode *ipimap = sbi->ipimap;
+	log_t *log = sbi->log;
+	bmap_t *bmp = sbi->bmap;
+	s64 newLogAddress, newFSCKAddress;
+	int newFSCKSize;
+	s64 newMapSize = 0, mapSize;
+	s64 XAddress, XSize, nblocks, xoff, xaddr, t64;
+	s64 oldLVSize;
+	s64 newFSSize;
+	s64 VolumeSize;
+	int newNpages = 0, nPages, newPage, xlen, t32;
+	int tid;
+	int log_formatted = 0;
+	struct inode *iplist[1];
+	struct jfs_superblock *j_sb, *j_sb2;
+	metapage_t *sbp, *sb2p;
+	uint old_agsize;
+	struct buffer_head *bh;
+
+	/* If the volume hasn't grown, get out now */
+
+	if (sbi->mntflag & JFS_INLINELOG)
+		oldLVSize = addressPXD(&sbi->logpxd) + lengthPXD(&sbi->logpxd);
+	else
+		oldLVSize = addressPXD(&sbi->fsckpxd) +
+		    lengthPXD(&sbi->fsckpxd);
+
+	if (oldLVSize >= newLVSize) {
+		printk(KERN_WARNING
+		       "jfs_extendfs: volume hasn't grown, returning\n");
+		goto out;
+	}
+
+	VolumeSize = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits;
+
+	if (VolumeSize) {
+		if (newLVSize > VolumeSize) {
+			printk(KERN_WARNING "jfs_extendfs: invalid size\n");
+			rc = -EINVAL;
+			goto out;
+		}
+	} else {
+		/* check the device */
+		bh = sb_bread(sb, newLVSize - 1);
+		if (!bh) {
+			printk(KERN_WARNING "jfs_extendfs: invalid size\n");
+			rc = -EINVAL;
+			goto out;
+		}
+		bforget(bh);
+	}
+
+	/* Can't extend write-protected drive */
+
+	if (isReadOnly(ipbmap)) {
+		printk(KERN_WARNING "jfs_extendfs: read-only file system\n");
+		rc = -EROFS;
+		goto out;
+	}
+
+	/*
+	 *      reconfigure LV spaces
+	 *      ---------------------
+	 *
+	 * validate new size, or, if not specified, determine new size
+	 */
+
+	/*
+	 * reconfigure inline log space:
+	 */
+	if ((sbi->mntflag & JFS_INLINELOG)) {
+		if (newLogSize == 0) {
+			/*
+			 * no size specified: default to 1/256 of aggregate
+			 * size; rounded up to a megabyte boundary;
+			 */
+			newLogSize = newLVSize >> 8;
+			t32 = (1 << (20 - sbi->l2bsize)) - 1;
+			newLogSize = (newLogSize + t32) & ~t32;
+			newLogSize =
+			    min(newLogSize, MEGABYTE32 >> sbi->l2bsize);
+		} else {
+			/*
+			 * convert the newLogSize to fs blocks.
+			 *
+			 * Since this is given in megabytes, it will always be
+			 * an even number of pages.
+			 */
+			newLogSize = (newLogSize * MEGABYTE) >> sbi->l2bsize;
+		}
+
+	} else
+		newLogSize = 0;
+
+	newLogAddress = newLVSize - newLogSize;
+
+	/*
+	 * reconfigure fsck work space:
+	 *
+	 * configure it to the end of the logical volume regardless of
+	 * whether file system extends to the end of the aggregate;
+	 * Need enough 4k pages to cover:
+	 *  - 1 bit per block in aggregate rounded up to BPERDMAP boundary
+	 *  - 1 extra page to handle control page and intermediate level pages
+	 *  - 50 extra pages for the chkdsk service log
+	 */
+	t64 = ((newLVSize - newLogSize + BPERDMAP - 1) >> L2BPERDMAP)
+	    << L2BPERDMAP;
+	t32 = ((t64 + (BITSPERPAGE - 1)) / BITSPERPAGE) + 1 + 50;
+	newFSCKSize = t32 << sbi->l2nbperpage;
+	newFSCKAddress = newLogAddress - newFSCKSize;
+
+	/*
+	 * compute new file system space;
+	 */
+	newFSSize = newLVSize - newLogSize - newFSCKSize;
+
+	/* file system cannot be shrinked */
+	if (newFSSize < bmp->db_mapsize) {
+		rc = EINVAL;
+		goto out;
+	}
+
+	/*
+	 * If we're expanding enough that the inline log does not overlap
+	 * the old one, we can format the new log before we quiesce the
+	 * filesystem.
+	 */
+	if ((sbi->mntflag & JFS_INLINELOG) && (newLogAddress > oldLVSize)) {
+		if ((rc = lmLogFormat(log, newLogAddress, newLogSize)))
+			goto out;
+		log_formatted = 1;
+	}
+	/*
+	 *      quiesce file system
+	 *
+	 * (prepare to move the inline log and to prevent map update)
+	 *
+	 * block any new transactions and wait for completion of
+	 * all wip transactions and flush modified pages s.t.
+	 * on-disk file system is in consistent state and
+	 * log is not required for recovery.
+	 */
+	txQuiesce(sb);
+
+	if (sbi->mntflag & JFS_INLINELOG) {
+		/*
+		 * deactivate old inline log
+		 */
+		lmLogShutdown(log);
+
+		/*
+		 * mark on-disk super block for fs in transition;
+		 *
+		 * update on-disk superblock for the new space configuration
+		 * of inline log space and fsck work space descriptors:
+		 * N.B. FS descriptor is NOT updated;
+		 *
+		 * crash recovery:
+		 * logredo(): if FM_EXTENDFS, return to fsck() for cleanup;
+		 * fsck(): if FM_EXTENDFS, reformat inline log and fsck
+		 * workspace from superblock inline log descriptor and fsck
+		 * workspace descriptor;
+		 */
+
+		/* read in superblock */
+		if ((rc = readSuper(sb, &sbp)))
+			goto error_out;
+		j_sb = (struct jfs_superblock *) (sbp->data);
+
+		/* mark extendfs() in progress */
+		j_sb->s_state |= cpu_to_le32(FM_EXTENDFS);
+		j_sb->s_xsize = cpu_to_le64(newFSSize);
+		PXDaddress(&j_sb->s_xfsckpxd, newFSCKAddress);
+		PXDlength(&j_sb->s_xfsckpxd, newFSCKSize);
+		PXDaddress(&j_sb->s_xlogpxd, newLogAddress);
+		PXDlength(&j_sb->s_xlogpxd, newLogSize);
+
+		/* synchronously update superblock */
+		flush_metapage(sbp);
+
+		/*
+		 * format new inline log synchronously;
+		 *
+		 * crash recovery: if log move in progress,
+		 * reformat log and exit success;
+		 */
+		if (!log_formatted)
+			if ((rc = lmLogFormat(log, newLogAddress, newLogSize)))
+				goto error_out;
+
+		/*
+		 * activate new log
+		 */
+		log->base = newLogAddress;
+		log->size = newLogSize >> (L2LOGPSIZE - sb->s_blocksize_bits);
+		if ((rc = lmLogInit(log)))
+			goto error_out;
+	}
+
+	/*
+	 *      extend block allocation map
+	 *      ---------------------------
+	 *
+	 * extendfs() for new extension, retry after crash recovery;
+	 *
+	 * note: both logredo() and fsck() rebuild map from
+	 * the bitmap and configuration parameter from superblock
+	 * (disregarding all other control information in the map);
+	 *
+	 * superblock:
+	 *  s_size: aggregate size in physical blocks;
+	 */
+	/*
+	 *      compute the new block allocation map configuration
+	 *
+	 * map dinode:
+	 *  di_size: map file size in byte;
+	 *  di_nblocks: number of blocks allocated for map file;
+	 *  di_mapsize: number of blocks in aggregate (covered by map);
+	 * map control page:
+	 *  db_mapsize: number of blocks in aggregate (covered by map);
+	 */
+	newMapSize = newFSSize;
+	/* number of data pages of new bmap file:
+	 * roundup new size to full dmap page boundary and
+	 * add 1 extra dmap page for next extendfs()
+	 */
+	t64 = (newMapSize - 1) + BPERDMAP;
+	newNpages = BLKTODMAPN(t64) + 1;
+
+	/*
+	 *      extend map from current map (WITHOUT growing mapfile)
+	 *
+	 * map new extension with unmapped part of the last partial
+	 * dmap page, if applicable, and extra page(s) allocated
+	 * at end of bmap by mkfs() or previous extendfs();
+	 */
+      extendBmap:
+	/* compute number of blocks requested to extend */
+	mapSize = bmp->db_mapsize;
+	XAddress = mapSize;	/* eXtension Address */
+	XSize = newMapSize - mapSize;	/* eXtension Size */
+	old_agsize = bmp->db_agsize;	/* We need to know if this changes */
+
+	/* compute number of blocks that can be extended by current mapfile */
+	t64 = dbMapFileSizeToMapSize(ipbmap);
+	if (mapSize > t64) {
+		printk(KERN_ERR
+		       "jfs_extendfs: mapSize (0x%llx) > t64 (0x%llx)\n",
+		       mapSize, t64);
+		rc = EIO;
+		goto error_out;
+	}
+	nblocks = min(t64 - mapSize, XSize);
+
+	/*
+	 * update map pages for new extension:
+	 *
+	 * update/init dmap and bubble up the control hierarchy
+	 * incrementally fold up dmaps into upper levels;
+	 * update bmap control page;
+	 */
+	if ((rc = dbExtendFS(ipbmap, XAddress, nblocks)))
+		goto error_out;
+	/*
+	 * the map now has extended to cover additional nblocks:
+	 * dn_mapsize = oldMapsize + nblocks;
+	 */
+	/* ipbmap->i_mapsize += nblocks; */
+	XSize -= nblocks;
+
+	/*
+	 *      grow map file to cover remaining extension
+	 *      and/or one extra dmap page for next extendfs();
+	 *
+	 * allocate new map pages and its backing blocks, and
+	 * update map file xtree
+	 */
+	/* compute number of data pages of current bmap file */
+	nPages = ipbmap->i_size >> L2PSIZE;
+
+	/* need to grow map file ? */
+	if (nPages == newNpages)
+		goto updateImap;
+
+	/*
+	 * grow bmap file for the new map pages required:
+	 *
+	 * allocate growth at the start of newly extended region;
+	 * bmap file only grows sequentially, i.e., both data pages
+	 * and possibly xtree index pages may grow in append mode,
+	 * s.t. logredo() can reconstruct pre-extension state
+	 * by washing away bmap file of pages outside s_size boundary;
+	 */
+	/*
+	 * journal map file growth as if a regular file growth:
+	 * (note: bmap is created with di_mode = IFJOURNAL|IFREG);
+	 *
+	 * journaling of bmap file growth is not required since
+	 * logredo() do/can not use log records of bmap file growth
+	 * but it provides careful write semantics, pmap update, etc.;
+	 */
+	/* synchronous write of data pages: bmap data pages are
+	 * cached in meta-data cache, and not written out
+	 * by txCommit();
+	 */
+	filemap_fdatawait(ipbmap->i_mapping);
+	filemap_fdatawrite(ipbmap->i_mapping);
+	filemap_fdatawait(ipbmap->i_mapping);
+	diWriteSpecial(ipbmap, 0);
+
+	newPage = nPages;	/* first new page number */
+	xoff = newPage << sbi->l2nbperpage;
+	xlen = (newNpages - nPages) << sbi->l2nbperpage;
+	xlen = min(xlen, (int) nblocks) & ~(sbi->nbperpage - 1);
+	xaddr = XAddress;
+
+	tid = txBegin(sb, COMMIT_FORCE);
+
+	if ((rc = xtAppend(tid, ipbmap, 0, xoff, nblocks, &xlen, &xaddr, 0))) {
+		txEnd(tid);
+		goto error_out;
+	}
+	/* update bmap file size */
+	ipbmap->i_size += xlen << sbi->l2bsize;
+	ipbmap->i_blocks += LBLK2PBLK(sb, xlen);
+
+	iplist[0] = ipbmap;
+	rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
+
+	txEnd(tid);
+
+	if (rc)
+		goto error_out;
+
+	/*
+	 * map file has been grown now to cover extension to further out;
+	 * di_size = new map file size;
+	 *
+	 * if huge extension, the previous extension based on previous
+	 * map file size may not have been sufficient to cover whole extension
+	 * (it could have been used up for new map pages),
+	 * but the newly grown map file now covers lot bigger new free space
+	 * available for further extension of map;
+	 */
+	/* any more blocks to extend ? */
+	if (XSize)
+		goto extendBmap;
+
+	/* finalize bmap */
+	dbFinalizeBmap(ipbmap);
+
+	/*
+	 *      update inode allocation map
+	 *      ---------------------------
+	 *
+	 * move iag lists from old to new iag;
+	 * agstart field is not updated for logredo() to reconstruct
+	 * iag lists if system crash occurs.
+	 * (computation of ag number from agstart based on agsize
+	 * will correctly identify the new ag);
+	 */
+      updateImap:
+	/* if new AG size the same as old AG size, done! */
+	if (bmp->db_agsize != old_agsize) {
+		if ((rc = diExtendFS(ipimap, ipbmap)))
+			goto error_out;
+
+		/* finalize imap */
+		if ((rc = diSync(ipimap)))
+			goto error_out;
+	}
+
+	/*
+	 *      finalize
+	 *      --------
+	 *
+	 * extension is committed when on-disk super block is
+	 * updated with new descriptors: logredo will recover
+	 * crash before it to pre-extension state;
+	 */
+
+	/* sync log to skip log replay of bmap file growth transaction; */
+	/* lmLogSync(log, 1); */
+
+	/*
+	 * synchronous write bmap global control page;
+	 * for crash before completion of write
+	 * logredo() will recover to pre-extendfs state;
+	 * for crash after completion of write,
+	 * logredo() will recover post-extendfs state;
+	 */
+	if ((rc = dbSync(ipbmap)))
+		goto error_out;
+
+	/*
+	 * copy primary bmap inode to secondary bmap inode
+	 */
+
+	ipbmap2 = diReadSpecial(sb, BMAP_I, 1);
+	if (ipbmap2 == NULL) {
+		printk(KERN_ERR "jfs_extendfs: diReadSpecial(bmap) failed\n");
+		goto error_out;
+	}
+	memcpy(&JFS_IP(ipbmap2)->i_xtroot, &JFS_IP(ipbmap)->i_xtroot, 288);
+	ipbmap2->i_size = ipbmap->i_size;
+	ipbmap2->i_blocks = ipbmap->i_blocks;
+
+	diWriteSpecial(ipbmap2, 1);
+	diFreeSpecial(ipbmap2);
+	/*
+	 *      update superblock
+	 */
+	if ((rc = readSuper(sb, &sbp)))
+		goto error_out;
+	j_sb = (struct jfs_superblock *) (sbp->data);
+
+	/* mark extendfs() completion */
+	j_sb->s_state &= cpu_to_le32(~FM_EXTENDFS);
+	j_sb->s_size = cpu_to_le64(bmp->db_mapsize) <<
+		       le16_to_cpu(j_sb->s_l2bfactor);
+	j_sb->s_agsize = cpu_to_le32(bmp->db_agsize);
+
+	/* update inline log space descriptor */
+	if (sbi->mntflag & JFS_INLINELOG) {
+		PXDaddress(&(j_sb->s_logpxd), newLogAddress);
+		PXDlength(&(j_sb->s_logpxd), newLogSize);
+	}
+
+	/* record log's mount serial number */
+	j_sb->s_logserial = cpu_to_le32(log->serial);
+
+	/* update fsck work space descriptor */
+	PXDaddress(&(j_sb->s_fsckpxd), newFSCKAddress);
+	PXDlength(&(j_sb->s_fsckpxd), newFSCKSize);
+	j_sb->s_fscklog = 1;
+	/* sb->s_fsckloglen remains the same */
+
+	/* Update secondary superblock */
+	sb2p = read_metapage(sbi->direct_inode,
+			     SUPER2_OFF >> sb->s_blocksize_bits, PSIZE, 1);
+
+	if (sb2p) {
+		j_sb2 = (struct jfs_superblock *) (sb2p->data);
+		memcpy(j_sb2, j_sb, sizeof (struct jfs_superblock));
+		flush_metapage(sb2p);
+	}
+
+	/* write primary superblock */
+	flush_metapage(sbp);
+
+	goto resume;
+
+      error_out:
+	updateSuper(sb, FM_DIRTY);
+
+      resume:
+	/*
+	 *      resume file system transactions
+	 */
+	txResume(sb);
+
+      out:
+	return rc;
+}
diff -Nru a/fs/jfs/super.c b/fs/jfs/super.c
--- a/fs/jfs/super.c	Sat Aug 10 18:42:22 2002
+++ b/fs/jfs/super.c	Sat Aug 10 18:42:22 2002
@@ -71,8 +71,9 @@
 extern void jfs_write_inode(struct inode *inode, int wait);
 
 extern struct dentry *jfs_get_parent(struct dentry *dentry);
+extern int jfs_extendfs(struct super_block *, s64, int);
 
-#ifdef PROC_FS_JFS /* see jfs_debug.h */
+#ifdef PROC_FS_JFS		/* see jfs_debug.h */
 extern void jfs_proc_init(void);
 extern void jfs_proc_clean(void);
 #endif
@@ -119,7 +120,7 @@
 	 */
 	maxinodes = min((s64) atomic_read(&imap->im_numinos) +
 			((sbi->bmap->db_nfree >> imap->im_l2nbperiext)
-			 << L2INOSPEREXT), (s64)0xffffffffLL);
+			 << L2INOSPEREXT), (s64) 0xffffffffLL);
 	buf->f_files = maxinodes;
 	buf->f_ffree = maxinodes - (atomic_read(&imap->im_numinos) -
 				    atomic_read(&imap->im_numfree));
@@ -156,20 +157,23 @@
 	kfree(sbi);
 }
 
-static int parse_options (char * options, struct jfs_sb_info *sbi)
+static int parse_options(char *options, struct super_block *sb, s64 *newLVSize)
 {
 	void *nls_map = NULL;
-	char * this_char;
-	char * value;
+	char *this_char;
+	char *value;
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+
+	*newLVSize = 0;
 
 	if (!options)
 		return 1;
-	while ((this_char = strsep (&options, ",")) != NULL) {
+	while ((this_char = strsep(&options, ",")) != NULL) {
 		if (!*this_char)
 			continue;
-		if ((value = strchr (this_char, '=')) != NULL)
+		if ((value = strchr(this_char, '=')) != NULL)
 			*value++ = 0;
-		if (!strcmp (this_char, "iocharset")) {
+		if (!strcmp(this_char, "iocharset")) {
 			if (!value || !*value)
 				goto needs_arg;
 			if (nls_map)	/* specified iocharset twice! */
@@ -179,14 +183,25 @@
 				printk(KERN_ERR "JFS: charset not found\n");
 				goto cleanup;
 			}
-		/* Silently ignore the quota options */
-		} else if (!strcmp (this_char, "grpquota")
-		         || !strcmp (this_char, "noquota")
-		         || !strcmp (this_char, "quota")
-		         || !strcmp (this_char, "usrquota"))
+		} else if (!strcmp(this_char, "resize")) {
+			if (!value || !*value) {
+				*newLVSize = sb->s_bdev->bd_inode->i_size >>
+					sb->s_blocksize_bits;
+				if (*newLVSize == 0)
+					printk(KERN_ERR
+					 "JFS: Cannot determine volume size\n");
+			} else
+				*newLVSize = simple_strtoull(value, &value, 0);
+
+			/* Silently ignore the quota options */
+		} else if (!strcmp(this_char, "grpquota")
+			   || !strcmp(this_char, "noquota")
+			   || !strcmp(this_char, "quota")
+			   || !strcmp(this_char, "usrquota"))
 			/* Don't do anything ;-) */ ;
 		else {
-			printk ("jfs: Unrecognized mount option %s\n", this_char);
+			printk("jfs: Unrecognized mount option %s\n",
+			       this_char);
 			goto cleanup;
 		}
 	}
@@ -208,10 +223,22 @@
 int jfs_remount(struct super_block *sb, int *flags, char *data)
 {
 	struct jfs_sb_info *sbi = JFS_SBI(sb);
+	s64 newLVSize = 0;
+	int rc = 0;
 
-	if (!parse_options(data, sbi)) {
+	if (!parse_options(data, sb, &newLVSize)) {
 		return -EINVAL;
 	}
+	if (newLVSize) {
+		if (sb->s_flags & MS_RDONLY) {
+			printk(KERN_ERR
+		  "JFS: resize requires volume to be mounted read-write\n");
+			return -EROFS;
+		}
+		rc = jfs_extendfs(sb, newLVSize, 0);
+		if (rc)
+			return rc;
+	}
 
 	if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
 		/*
@@ -232,20 +259,26 @@
 	struct jfs_sb_info *sbi;
 	struct inode *inode;
 	int rc;
+	s64 newLVSize = 0;
 
 	jFYI(1, ("In jfs_read_super: s_flags=0x%lx\n", sb->s_flags));
 
-	sbi = kmalloc(sizeof(struct jfs_sb_info), GFP_KERNEL);
+	sbi = kmalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
 	if (!sbi)
 		return -ENOSPC;
-	memset(sbi, 0, sizeof(struct jfs_sb_info));
+	memset(sbi, 0, sizeof (struct jfs_sb_info));
 	sb->u.generic_sbp = sbi;
 
-	if (!parse_options((char *)data, sbi)) {
+	if (!parse_options((char *) data, sb, &newLVSize)) {
 		kfree(sbi);
 		return -EINVAL;
 	}
 
+	if (newLVSize) {
+		printk(KERN_ERR "resize option for remount only\n");
+		return -EINVAL;
+	}
+
 	/*
 	 * Initialize blocksize to 4K.
 	 */
@@ -276,8 +309,7 @@
 	if (rc) {
 		if (!silent) {
 			jERROR(1,
-			       ("jfs_mount failed w/return code = %d\n",
-				rc));
+			       ("jfs_mount failed w/return code = %d\n", rc));
 		}
 		goto out_mount_failed;
 	}
@@ -314,7 +346,7 @@
 	 * Page cache is indexed by long.
 	 * I would use MAX_LFS_FILESIZE, but it's only half as big
 	 */
-	sb->s_maxbytes = min(((u64)PAGE_CACHE_SIZE << 32) - 1, sb->s_maxbytes);
+	sb->s_maxbytes = min(((u64) PAGE_CACHE_SIZE << 32) - 1, sb->s_maxbytes);
 #endif
 
 	return 0;
@@ -379,15 +411,17 @@
 extern void txExit(void);
 extern void metapage_exit(void);
 
-static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
 {
 	struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo;
 
-	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
 	    SLAB_CTOR_CONSTRUCTOR) {
 		INIT_LIST_HEAD(&jfs_ip->anon_inode_list);
 		INIT_LIST_HEAD(&jfs_ip->mp_list);
-		RDWRLOCK_INIT(&jfs_ip->rdwrlock);
+		init_rwsem(&jfs_ip->rdwrlock);
+		init_MUTEX(&jfs_ip->commit_sem);
+		jfs_ip->atlhead = 0;
 		inode_init_once(&jfs_ip->vfs_inode);
 	}
 }
@@ -397,9 +431,8 @@
 	int rc;
 
 	jfs_inode_cachep =
-	    kmem_cache_create("jfs_ip",
-			    sizeof(struct jfs_inode_info),
-			    0, 0, init_once, NULL);
+	    kmem_cache_create("jfs_ip", sizeof(struct jfs_inode_info), 0, 0,
+			      init_once, NULL);
 	if (jfs_inode_cachep == NULL)
 		return -ENOMEM;
 
@@ -425,37 +458,32 @@
 	 * I/O completion thread (endio)
 	 */
 	jfsIOthread = kernel_thread(jfsIOWait, 0,
-				    CLONE_FS | CLONE_FILES |
-				    CLONE_SIGHAND);
+				    CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 	if (jfsIOthread < 0) {
 		jERROR(1,
-		       ("init_jfs_fs: fork failed w/rc = %d\n",
-			jfsIOthread));
+		       ("init_jfs_fs: fork failed w/rc = %d\n", jfsIOthread));
 		goto end_txmngr;
 	}
-	wait_for_completion(&jfsIOwait);	/* Wait until IO thread starts */
+	wait_for_completion(&jfsIOwait);	/* Wait until thread starts */
 
 	jfsCommitThread = kernel_thread(jfs_lazycommit, 0,
-					CLONE_FS | CLONE_FILES |
-					CLONE_SIGHAND);
+					CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 	if (jfsCommitThread < 0) {
 		jERROR(1,
 		       ("init_jfs_fs: fork failed w/rc = %d\n",
 			jfsCommitThread));
 		goto kill_iotask;
 	}
-	wait_for_completion(&jfsIOwait);	/* Wait until IO thread starts */
+	wait_for_completion(&jfsIOwait);	/* Wait until thread starts */
 
 	jfsSyncThread = kernel_thread(jfs_sync, 0,
-				      CLONE_FS | CLONE_FILES |
-				      CLONE_SIGHAND);
+				      CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 	if (jfsSyncThread < 0) {
 		jERROR(1,
-		       ("init_jfs_fs: fork failed w/rc = %d\n",
-			jfsSyncThread));
+		       ("init_jfs_fs: fork failed w/rc = %d\n", jfsSyncThread));
 		goto kill_committask;
 	}
-	wait_for_completion(&jfsIOwait);	/* Wait until IO thread starts */
+	wait_for_completion(&jfsIOwait);	/* Wait until thread starts */
 
 #ifdef PROC_FS_JFS
 	jfs_proc_init();
@@ -463,15 +491,14 @@
 
 	return register_filesystem(&jfs_fs_type);
 
-
 kill_committask:
 	jfs_stop_threads = 1;
 	wake_up(&jfs_commit_thread_wait);
-	wait_for_completion(&jfsIOwait);	/* Wait until Commit thread exits */
+	wait_for_completion(&jfsIOwait);	/* Wait for thread exit */
 kill_iotask:
 	jfs_stop_threads = 1;
 	wake_up(&jfs_IO_thread_wait);
-	wait_for_completion(&jfsIOwait);	/* Wait until IO thread exits */
+	wait_for_completion(&jfsIOwait);	/* Wait for thread exit */
 end_txmngr:
 	txExit();
 free_metapage:
diff -Nru a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog
--- a/fs/ntfs/ChangeLog	Sat Aug 10 18:42:21 2002
+++ b/fs/ntfs/ChangeLog	Sat Aug 10 18:42:21 2002
@@ -2,6 +2,43 @@
 	- Find and fix bugs.
 	- Enable NFS exporting of NTFS.
 
+2.0.24 - Cleanups.
+
+	- Treat BUG_ON() as ASSERT() not VERIFY(), i.e. do not use side effects
+	  inside BUG_ON(). (Adam J. Richter)
+	- Split logical OR expressions inside BUG_ON() into individual BUG_ON()
+	  calls for improved debugging. (Adam J. Richter)
+	- Add errors flag to the ntfs volume state, accessed via
+	  NVol{,Set,Clear}Errors(vol).
+	- Do not allow read-write remounts of read-only volumes with errors.
+	- Clarify comment for ntfs file operation sendfile which was added by
+	  Christoph Hellwig a while ago (just using generic_file_sendfile())
+	  to say that ntfs ->sendfile is only used for the case where the
+	  source data is on the ntfs partition and the destination is
+	  somewhere else, i.e. nothing we need to concern ourselves with.
+	- Add generic_file_write() as our ntfs file write operation.
+
+2.0.23 - Major bug fixes (races, deadlocks, non-i386 architectures).
+
+	- Massive internal locking changes to mft record locking. Fixes lock
+	  recursion and replaces the mrec_lock read/write semaphore with a
+	  mutex. Also removes the now superfluous mft_count. This fixes several
+	  race conditions and deadlocks, especially in the future write code.
+	- Fix ntfs over loopback for compressed files by adding an
+	  optimization barrier. (gcc was screwing up otherwise ?)
+	- Miscellaneous cleanups all over the code and a fix or two in error
+	  handling code paths.
+	Thanks go to Christoph Hellwig for pointing out the following two:
+	- Remove now unused function fs/ntfs/malloc.h::vmalloc_nofs().
+	- Fix ntfs_free() for ia64 and parisc by checking for VMALLOC_END, too.
+
+2.0.22 - Cleanups, mainly to ntfs_readdir(), and use C99 initializers.
+
+	- Change fs/ntfs/dir.c::ntfs_reddir() to only read/write ->f_pos once
+	  at entry/exit respectively.
+	- Use C99 initializers for structures.
+	- Remove unused variable blocks from fs/ntfs/aops.c::ntfs_read_block().
+
 2.0.21 - Check for, and refuse to work with too large files/directories/volumes.
 
 	- Limit volume size at mount time to 2TiB on architectures where
diff -Nru a/fs/ntfs/Makefile b/fs/ntfs/Makefile
--- a/fs/ntfs/Makefile	Sat Aug 10 18:42:20 2002
+++ b/fs/ntfs/Makefile	Sat Aug 10 18:42:20 2002
@@ -5,7 +5,7 @@
 ntfs-objs := aops.o attrib.o compress.o debug.o dir.o file.o inode.o mft.o \
 	     mst.o namei.o super.o sysctl.o time.o unistr.o upcase.o
 
-EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.21\"
+EXTRA_CFLAGS = -DNTFS_VERSION=\"2.0.24\"
 
 ifeq ($(CONFIG_NTFS_DEBUG),y)
 EXTRA_CFLAGS += -DDEBUG
diff -Nru a/fs/ntfs/aops.c b/fs/ntfs/aops.c
--- a/fs/ntfs/aops.c	Sat Aug 10 18:42:23 2002
+++ b/fs/ntfs/aops.c	Sat Aug 10 18:42:23 2002
@@ -106,8 +106,6 @@
 	if (!NInoMstProtected(ni)) {
 		if (likely(page_uptodate && !PageError(page)))
 			SetPageUptodate(page);
-		unlock_page(page);
-		return;
 	} else {
 		char *addr;
 		unsigned int i, recs, nr_err;
@@ -171,7 +169,7 @@
 	run_list_element *rl;
 	struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
 	sector_t iblock, lblock, zblock;
-	unsigned int blocksize, blocks, vcn_ofs;
+	unsigned int blocksize, vcn_ofs;
 	int i, nr;
 	unsigned char blocksize_bits;
 
@@ -187,7 +185,6 @@
 	if (unlikely(!bh))
 		return -ENOMEM;
 
-	blocks = PAGE_CACHE_SIZE >> blocksize_bits;
 	iblock = page->index << (PAGE_CACHE_SHIFT - blocksize_bits);
 	lblock = (ni->allocated_size + blocksize - 1) >> blocksize_bits;
 	zblock = (ni->initialized_size + blocksize - 1) >> blocksize_bits;
@@ -333,6 +330,8 @@
  * for it to be read in before we can do the copy.
  *
  * Return 0 on success and -errno on error.
+ *
+ * WARNING: Do not make this function static! It is used by mft.c!
  */
 int ntfs_readpage(struct file *file, struct page *page)
 {
@@ -373,8 +372,8 @@
 	else
 		base_ni = ni->_INE(base_ntfs_ino);
 
-	/* Map, pin and lock the mft record for reading. */
-	mrec = map_mft_record(READ, base_ni);
+	/* Map, pin and lock the mft record. */
+	mrec = map_mft_record(base_ni);
 	if (unlikely(IS_ERR(mrec))) {
 		err = PTR_ERR(mrec);
 		goto err_out;
@@ -417,7 +416,7 @@
 put_unm_err_out:
 	put_attr_search_ctx(ctx);
 unm_err_out:
-	unmap_mft_record(READ, base_ni);
+	unmap_mft_record(base_ni);
 err_out:
 	unlock_page(page);
 	return err;
@@ -427,11 +426,8 @@
  * ntfs_aops - general address space operations for inodes and attributes
  */
 struct address_space_operations ntfs_aops = {
-	writepage:	NULL,			/* Write dirty page to disk. */
-	readpage:	ntfs_readpage,		/* Fill page with data. */
-	sync_page:	block_sync_page,	/* Currently, just unplugs the
+	.readpage	= ntfs_readpage,	/* Fill page with data. */
+	.sync_page	= block_sync_page,	/* Currently, just unplugs the
 						   disk request queue. */
-	prepare_write:	NULL,			/* . */
-	commit_write:	NULL,			/* . */
 };
 
diff -Nru a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
--- a/fs/ntfs/attrib.c	Sat Aug 10 18:42:22 2002
+++ b/fs/ntfs/attrib.c	Sat Aug 10 18:42:22 2002
@@ -110,7 +110,8 @@
 static inline BOOL ntfs_are_rl_mergeable(run_list_element *dst,
 		run_list_element *src)
 {
-	BUG_ON(!dst || !src);
+	BUG_ON(!dst);
+	BUG_ON(!src);
 
 	if ((dst->lcn < 0) || (src->lcn < 0))     /* Are we merging holes? */
 		return FALSE;
@@ -192,7 +193,8 @@
 	BOOL right;
 	int magic;
 
-	BUG_ON(!dst || !src);
+	BUG_ON(!dst);
+	BUG_ON(!src);
 
 	/* First, check if the right hand end needs merging. */
 	right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);
@@ -258,7 +260,8 @@
 	BOOL hole = FALSE;	/* Following a hole */
 	int magic;
 
-	BUG_ON(!dst || !src);
+	BUG_ON(!dst);
+	BUG_ON(!src);
 
 	/* disc => Discontinuity between the end of @dst and the start of @src.
 	 *         This means we might need to insert a hole.
@@ -362,7 +365,8 @@
 	BOOL right;
 	int magic;
 
-	BUG_ON(!dst || !src);
+	BUG_ON(!dst);
+	BUG_ON(!src);
 
 	/* First, merge the left and right ends, if necessary. */
 	right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);
@@ -423,7 +427,8 @@
 static inline run_list_element *ntfs_rl_split(run_list_element *dst, int dsize,
 		run_list_element *src, int ssize, int loc)
 {
-	BUG_ON(!dst || !src);
+	BUG_ON(!dst);
+	BUG_ON(!src);
 
 	/* Space required: @dst size + @src size + one new hole. */
 	dst = ntfs_rl_realloc(dst, dsize, dsize + ssize + 1);
@@ -948,7 +953,7 @@
 	else
 		base_ni = ni->_INE(base_ntfs_ino);
 
-	mrec = map_mft_record(READ, base_ni);
+	mrec = map_mft_record(base_ni);
 	if (IS_ERR(mrec))
 		return PTR_ERR(mrec);
 	ctx = get_attr_search_ctx(base_ni, mrec);
@@ -979,7 +984,7 @@
 	
 	put_attr_search_ctx(ctx);
 err_out:
-	unmap_mft_record(READ, base_ni);
+	unmap_mft_record(base_ni);
 	return err;
 }
 
@@ -1671,7 +1676,7 @@
 		return;
 	} /* Attribute list. */
 	if (ctx->ntfs_ino != ctx->base_ntfs_ino)
-		unmap_mft_record(READ, ctx->ntfs_ino);
+		unmap_mft_record(ctx->ntfs_ino);
 	init_attr_search_ctx(ctx, ctx->base_ntfs_ino, ctx->base_mrec);
 	return;
 }
@@ -1704,7 +1709,7 @@
 void put_attr_search_ctx(attr_search_context *ctx)
 {
 	if (ctx->base_ntfs_ino && ctx->ntfs_ino != ctx->base_ntfs_ino)
-		unmap_mft_record(READ, ctx->ntfs_ino);
+		unmap_mft_record(ctx->ntfs_ino);
 	kmem_cache_free(ntfs_attr_ctx_cache, ctx);
 	return;
 }
diff -Nru a/fs/ntfs/compress.c b/fs/ntfs/compress.c
--- a/fs/ntfs/compress.c	Sat Aug 10 18:42:23 2002
+++ b/fs/ntfs/compress.c	Sat Aug 10 18:42:23 2002
@@ -467,7 +467,8 @@
 	 * Bad things happen if we get here for anything that is not an
 	 * unnamed $DATA attribute.
 	 */
-	BUG_ON(ni->type != AT_DATA || ni->name_len);
+	BUG_ON(ni->type != AT_DATA);
+	BUG_ON(ni->name_len);
 
 	pages = kmalloc(nr_pages * sizeof(struct page *), GFP_NOFS);
 
@@ -608,8 +609,27 @@
 		if (buffer_uptodate(tbh))
 			continue;
 		wait_on_buffer(tbh);
-		if (unlikely(!buffer_uptodate(tbh)))
-			goto read_err;
+		/*      
+		 * We need an optimization barrier here, otherwise we start
+		 * hitting the below fixup code when accessing a loopback
+		 * mounted ntfs partition. This indicates either there is a
+		 * race condition in the loop driver or, more likely, gcc
+		 * overoptimises the code without the barrier and it doesn't 
+		 * do the Right Thing(TM).
+		 */      
+		barrier();
+		if (unlikely(!buffer_uptodate(tbh))) {
+			ntfs_warning(vol->sb, "Buffer is unlocked but not "
+					"uptodate! Unplugging the disk queue " 
+					"and rescheduling.");
+			get_bh(tbh);
+			blk_run_queues();
+			schedule();
+			put_bh(tbh);
+			if (unlikely(!buffer_uptodate(tbh)))
+				goto read_err;
+			ntfs_warning(vol->sb, "Buffer is now uptodate. Good.");
+		}
 	}
 
 	/*
diff -Nru a/fs/ntfs/dir.c b/fs/ntfs/dir.c
--- a/fs/ntfs/dir.c	Sat Aug 10 18:42:22 2002
+++ b/fs/ntfs/dir.c	Sat Aug 10 18:42:22 2002
@@ -76,7 +76,7 @@
 	u8 *index_end;
 	u64 mref;
 	attr_search_context *ctx;
-	int err = 0, rc;
+	int err, rc;
 	VCN vcn, old_vcn;
 	struct address_space *ia_mapping;
 	struct page *page;
@@ -84,23 +84,24 @@
 	ntfs_name *name = NULL;
 
 	/* Get hold of the mft record for the directory. */
-	m = map_mft_record(READ, dir_ni);
-	if (IS_ERR(m))
-		goto map_err_out;
-
+	m = map_mft_record(dir_ni);
+	if (unlikely(IS_ERR(m))) {
+		ntfs_error(sb, "map_mft_record() failed with error code %ld.",
+				-PTR_ERR(m));
+		return ERR_MREF(PTR_ERR(m));
+	}
 	ctx = get_attr_search_ctx(dir_ni, m);
-	if (!ctx) {
+	if (unlikely(!ctx)) {
 		err = -ENOMEM;
-		goto unm_err_out;
+		goto err_out;
 	}
-
 	/* Find the index root attribute in the mft record. */
 	if (!lookup_attr(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL, 0,
 			ctx)) {
 		ntfs_error(sb, "Index root attribute missing in directory "
 				"inode 0x%lx.", dir_ni->mft_no);
 		err = -EIO;
-		goto put_unm_err_out;
+		goto err_out;
 	}
 	/* Get to the index root value (it's been verified in read_inode). */
 	ir = (INDEX_ROOT*)((u8*)ctx->attr +
@@ -154,7 +155,7 @@
 							GFP_NOFS);
 					if (!name) {
 						err = -ENOMEM;
-						goto put_unm_err_out;
+						goto err_out;
 					}
 				}
 				name->mref = le64_to_cpu(
@@ -169,7 +170,7 @@
 			}
 			mref = le64_to_cpu(ie->_IIF(indexed_file));
 			put_attr_search_ctx(ctx);
-			unmap_mft_record(READ, dir_ni);
+			unmap_mft_record(dir_ni);
 			return mref;
 		}
 		/*
@@ -208,7 +209,7 @@
 			name = kmalloc(name_size, GFP_NOFS);
 			if (!name) {
 				err = -ENOMEM;
-				goto put_unm_err_out;
+				goto err_out;
 			}
 			name->mref = le64_to_cpu(ie->_IIF(indexed_file));
 			name->type = type;
@@ -267,12 +268,12 @@
 	if (!(ie->_IEH(flags) & INDEX_ENTRY_NODE)) {
 		if (name) {
 			put_attr_search_ctx(ctx);
-			unmap_mft_record(READ, dir_ni);
+			unmap_mft_record(dir_ni);
 			return name->mref;
 		}
 		ntfs_debug("Entry not found.");
 		err = -ENOENT;
-		goto put_unm_err_out;
+		goto err_out;
 	} /* Child node present, descend into it. */
 	/* Consistency check: Verify that an index allocation exists. */
 	if (!NInoIndexAllocPresent(dir_ni)) {
@@ -280,11 +281,19 @@
 				"requires one. Directory inode 0x%lx is "
 				"corrupt or driver bug.", dir_ni->mft_no);
 		err = -EIO;
-		goto put_unm_err_out;
+		goto err_out;
 	}
 	/* Get the starting vcn of the index_block holding the child node. */
 	vcn = sle64_to_cpup((u8*)ie + le16_to_cpu(ie->_IEH(length)) - 8);
 	ia_mapping = VFS_I(dir_ni)->i_mapping;
+	/*
+	 * We are done with the index root and the mft record. Release them,
+	 * otherwise we deadlock with ntfs_map_page().
+	 */
+	put_attr_search_ctx(ctx);
+	unmap_mft_record(dir_ni);
+	m = NULL;
+	ctx = NULL;
 descend_into_child_node:
 	/*
 	 * Convert vcn to index into the index allocation attribute in units
@@ -296,7 +305,8 @@
 	if (IS_ERR(page)) {
 		ntfs_error(sb, "Failed to map directory index page, error %ld.",
 				-PTR_ERR(page));
-		goto put_unm_err_out;
+		err = PTR_ERR(page);
+		goto err_out;
 	}
 	kaddr = (u8*)page_address(page);
 fast_descend_into_child_node:
@@ -308,7 +318,7 @@
 		ntfs_error(sb, "Out of bounds check failed. Corrupt directory "
 				"inode 0x%lx or driver bug.", dir_ni->mft_no);
 		err = -EIO;
-		goto unm_unm_err_out;
+		goto unm_err_out;
 	}
 	if (sle64_to_cpu(ia->index_block_vcn) != vcn) {
 		ntfs_error(sb, "Actual VCN (0x%Lx) of index buffer is "
@@ -318,7 +328,7 @@
 				(long long)sle64_to_cpu(ia->index_block_vcn),
 				(long long)vcn, dir_ni->mft_no);
 		err = -EIO;
-		goto unm_unm_err_out;
+		goto unm_err_out;
 	}
 	if (le32_to_cpu(ia->index.allocated_size) + 0x18 !=
 			dir_ni->_IDM(index_block_size)) {
@@ -330,7 +340,7 @@
 				le32_to_cpu(ia->index.allocated_size) + 0x18,
 				dir_ni->_IDM(index_block_size));
 		err = -EIO;
-		goto unm_unm_err_out;
+		goto unm_err_out;
 	}
 	index_end = (u8*)ia + dir_ni->_IDM(index_block_size);
 	if (index_end > kaddr + PAGE_CACHE_SIZE) {
@@ -339,7 +349,7 @@
 				"Cannot access! This is probably a bug in the "
 				"driver.", (long long)vcn, dir_ni->mft_no);
 		err = -EIO;
-		goto unm_unm_err_out;
+		goto unm_err_out;
 	}
 	index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
 	if (index_end > (u8*)ia + dir_ni->_IDM(index_block_size)) {
@@ -347,7 +357,7 @@
 				"inode 0x%lx exceeds maximum size.",
 				(long long)vcn, dir_ni->mft_no);
 		err = -EIO;
-		goto unm_unm_err_out;
+		goto unm_err_out;
 	}
 	/* The first index entry. */
 	ie = (INDEX_ENTRY*)((u8*)&ia->index +
@@ -367,7 +377,7 @@
 					"directory inode 0x%lx.",
 					dir_ni->mft_no);
 			err = -EIO;
-			goto unm_unm_err_out;
+			goto unm_err_out;
 		}
 		/*
 		 * The last entry cannot contain a name. It can however contain
@@ -403,7 +413,7 @@
 							GFP_NOFS);
 					if (!name) {
 						err = -ENOMEM;
-						goto unm_unm_err_out;
+						goto unm_err_out;
 					}
 				}
 				name->mref = le64_to_cpu(
@@ -418,8 +428,6 @@
 			}
 			mref = le64_to_cpu(ie->_IIF(indexed_file));
 			ntfs_unmap_page(page);
-			put_attr_search_ctx(ctx);
-			unmap_mft_record(READ, dir_ni);
 			return mref;
 		}
 		/*
@@ -459,7 +467,7 @@
 			name = kmalloc(name_size, GFP_NOFS);
 			if (!name) {
 				err = -ENOMEM;
-				goto put_unm_err_out;
+				goto unm_err_out;
 			}
 			name->mref = le64_to_cpu(ie->_IIF(indexed_file));
 			name->type = type;
@@ -519,7 +527,7 @@
 					"a leaf node in directory inode 0x%lx.",
 					dir_ni->mft_no);
 			err = -EIO;
-			goto unm_unm_err_out;
+			goto unm_err_out;
 		}
 		/* Child node present, descend into it. */
 		old_vcn = vcn;
@@ -539,7 +547,7 @@
 		ntfs_error(sb, "Negative child node vcn in directory inode "
 				"0x%lx.", dir_ni->mft_no);
 		err = -EIO;
-		goto unm_unm_err_out;
+		goto unm_err_out;
 	}
 	/*
 	 * No child node present, return -ENOENT, unless we have got a matching
@@ -548,31 +556,26 @@
 	 */
 	if (name) {
 		ntfs_unmap_page(page);
-		put_attr_search_ctx(ctx);
-		unmap_mft_record(READ, dir_ni);
 		return name->mref;
 	}
 	ntfs_debug("Entry not found.");
 	err = -ENOENT;
-unm_unm_err_out:
-	ntfs_unmap_page(page);
-put_unm_err_out:
-	put_attr_search_ctx(ctx);
 unm_err_out:
-	unmap_mft_record(READ, dir_ni);
+	ntfs_unmap_page(page);
+err_out:
+	if (ctx)
+		put_attr_search_ctx(ctx);
+	if (m)
+		unmap_mft_record(dir_ni);
 	if (name) {
 		kfree(name);
 		*res = NULL;
 	}
 	return ERR_MREF(err);
-map_err_out:
-	ntfs_error(sb, "map_mft_record(READ) failed with error code %ld.",
-			-PTR_ERR(m));
-	return ERR_MREF(PTR_ERR(m));
 dir_err_out:
 	ntfs_error(sb, "Corrupt directory. Aborting lookup.");
 	err = -EIO;
-	goto put_unm_err_out;
+	goto err_out;
 }
 
 #if 0
@@ -614,7 +617,7 @@
 	u8 *index_end;
 	u64 mref;
 	attr_search_context *ctx;
-	int err = 0, rc;
+	int err, rc;
 	IGNORE_CASE_BOOL ic;
 	VCN vcn, old_vcn;
 	struct address_space *ia_mapping;
@@ -622,23 +625,24 @@
 	u8 *kaddr;
 
 	/* Get hold of the mft record for the directory. */
-	m = map_mft_record(READ, dir_ni);
-	if (IS_ERR(m))
-		goto map_err_out;
-
+	m = map_mft_record(dir_ni);
+	if (IS_ERR(m)) {
+		ntfs_error(sb, "map_mft_record() failed with error code %ld.",
+				-PTR_ERR(m));
+		return ERR_MREF(PTR_ERR(m));
+	}
 	ctx = get_attr_search_ctx(dir_ni, m);
 	if (!ctx) {
 		err = -ENOMEM;
-		goto unm_err_out;
+		goto err_out;
 	}
-
 	/* Find the index root attribute in the mft record. */
 	if (!lookup_attr(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL, 0,
 			ctx)) {
 		ntfs_error(sb, "Index root attribute missing in directory "
 				"inode 0x%lx.", dir_ni->mft_no);
 		err = -EIO;
-		goto put_unm_err_out;
+		goto err_out;
 	}
 	/* Get to the index root value (it's been verified in read_inode). */
 	ir = (INDEX_ROOT*)((u8*)ctx->attr +
@@ -689,7 +693,7 @@
 found_it:
 			mref = le64_to_cpu(ie->_IIF(indexed_file));
 			put_attr_search_ctx(ctx);
-			unmap_mft_record(READ, dir_ni);
+			unmap_mft_record(dir_ni);
 			return mref;
 		}
 		/*
@@ -737,7 +741,7 @@
 	if (!(ie->_IEH(flags) & INDEX_ENTRY_NODE)) {
 		/* No child node, return -ENOENT. */
 		err = -ENOENT;
-		goto put_unm_err_out;
+		goto err_out;
 	} /* Child node present, descend into it. */
 	/* Consistency check: Verify that an index allocation exists. */
 	if (!NInoIndexAllocPresent(dir_ni)) {
@@ -745,11 +749,19 @@
 				"requires one. Directory inode 0x%lx is "
 				"corrupt or driver bug.", dir_ni->mft_no);
 		err = -EIO;
-		goto put_unm_err_out;
+		goto err_out;
 	}
 	/* Get the starting vcn of the index_block holding the child node. */
 	vcn = sle64_to_cpup((u8*)ie + le16_to_cpu(ie->_IEH(length)) - 8);
 	ia_mapping = VFS_I(dir_ni)->i_mapping;
+	/*
+	 * We are done with the index root and the mft record. Release them,
+	 * otherwise we deadlock with ntfs_map_page().
+	 */
+	put_attr_search_ctx(ctx);
+	unmap_mft_record(dir_ni);
+	m = NULL;
+	ctx = NULL;
 descend_into_child_node:
 	/*
 	 * Convert vcn to index into the index allocation attribute in units
@@ -761,7 +773,8 @@
 	if (IS_ERR(page)) {
 		ntfs_error(sb, "Failed to map directory index page, error %ld.",
 				-PTR_ERR(page));
-		goto put_unm_err_out;
+		err = PTR_ERR(page);
+		goto err_out;
 	}
 	kaddr = (u8*)page_address(page);
 fast_descend_into_child_node:
@@ -773,7 +786,7 @@
 		ntfs_error(sb, "Out of bounds check failed. Corrupt directory "
 				"inode 0x%lx or driver bug.", dir_ni->mft_no);
 		err = -EIO;
-		goto unm_unm_err_out;
+		goto unm_err_out;
 	}
 	if (sle64_to_cpu(ia->index_block_vcn) != vcn) {
 		ntfs_error(sb, "Actual VCN (0x%Lx) of index buffer is "
@@ -783,7 +796,7 @@
 				(long long)sle64_to_cpu(ia->index_block_vcn),
 				(long long)vcn, dir_ni->mft_no);
 		err = -EIO;
-		goto unm_unm_err_out;
+		goto unm_err_out;
 	}
 	if (le32_to_cpu(ia->index.allocated_size) + 0x18 !=
 			dir_ni->_IDM(index_block_size)) {
@@ -795,7 +808,7 @@
 				le32_to_cpu(ia->index.allocated_size) + 0x18,
 				dir_ni->_IDM(index_block_size));
 		err = -EIO;
-		goto unm_unm_err_out;
+		goto unm_err_out;
 	}
 	index_end = (u8*)ia + dir_ni->_IDM(index_block_size);
 	if (index_end > kaddr + PAGE_CACHE_SIZE) {
@@ -804,7 +817,7 @@
 				"Cannot access! This is probably a bug in the "
 				"driver.", (long long)vcn, dir_ni->mft_no);
 		err = -EIO;
-		goto unm_unm_err_out;
+		goto unm_err_out;
 	}
 	index_end = (u8*)&ia->index + le32_to_cpu(ia->index.index_length);
 	if (index_end > (u8*)ia + dir_ni->_IDM(index_block_size)) {
@@ -812,7 +825,7 @@
 				"inode 0x%lx exceeds maximum size.",
 				(long long)vcn, dir_ni->mft_no);
 		err = -EIO;
-		goto unm_unm_err_out;
+		goto unm_err_out;
 	}
 	/* The first index entry. */
 	ie = (INDEX_ENTRY*)((u8*)&ia->index +
@@ -832,7 +845,7 @@
 					"directory inode 0x%lx.",
 					dir_ni->mft_no);
 			err = -EIO;
-			goto unm_unm_err_out;
+			goto unm_err_out;
 		}
 		/*
 		 * The last entry cannot contain a name. It can however contain
@@ -865,8 +878,6 @@
 found_it2:
 			mref = le64_to_cpu(ie->_IIF(indexed_file));
 			ntfs_unmap_page(page);
-			put_attr_search_ctx(ctx);
-			unmap_mft_record(READ, dir_ni);
 			return mref;
 		}
 		/*
@@ -917,7 +928,7 @@
 					"a leaf node in directory inode 0x%lx.",
 					dir_ni->mft_no);
 			err = -EIO;
-			goto unm_unm_err_out;
+			goto unm_err_out;
 		}
 		/* Child node present, descend into it. */
 		old_vcn = vcn;
@@ -937,26 +948,23 @@
 		ntfs_error(sb, "Negative child node vcn in directory inode "
 				"0x%lx.", dir_ni->mft_no);
 		err = -EIO;
-		goto unm_unm_err_out;
+		goto unm_err_out;
 	}
 	/* No child node, return -ENOENT. */
 	ntfs_debug("Entry not found.");
 	err = -ENOENT;
-unm_unm_err_out:
-	ntfs_unmap_page(page);
-put_unm_err_out:
-	put_attr_search_ctx(ctx);
 unm_err_out:
-	unmap_mft_record(READ, dir_ni);
+	ntfs_unmap_page(page);
+err_out:
+	if (ctx)
+		put_attr_search_ctx(ctx);
+	if (m)
+		unmap_mft_record(dir_ni);
 	return ERR_MREF(err);
-map_err_out:
-	ntfs_error(sb, "map_mft_record(READ) failed with error code %ld.",
-			-PTR_ERR(m));
-	return ERR_MREF(PTR_ERR(m));
 dir_err_out:
 	ntfs_error(sb, "Corrupt directory. Aborting lookup.");
 	err = -EIO;
-	goto put_unm_err_out;
+	goto err_out;
 }
 
 #endif
@@ -974,7 +982,7 @@
 /**
  * ntfs_filldir - ntfs specific filldir method
  * @vol:	current ntfs volume
- * @filp:	open file descriptor for the current directory
+ * @fpos:	position in the directory
  * @ndir:	ntfs inode of current directory
  * @index_type:	specifies whether @iu is an index root or an index allocation
  * @iu:		index root or index allocation attribute to which @ie belongs
@@ -986,7 +994,7 @@
  * Convert the Unicode @name to the loaded NLS and pass it to the @filldir
  * callback.
  */
-static inline int ntfs_filldir(ntfs_volume *vol, struct file *filp,
+static inline int ntfs_filldir(ntfs_volume *vol, loff_t *fpos,
 		ntfs_inode *ndir, const INDEX_TYPE index_type,
 		index_union iu, INDEX_ENTRY *ie, u8 *name,
 		void *dirent, filldir_t filldir)
@@ -997,12 +1005,12 @@
 
 	/* Advance the position even if going to skip the entry. */
 	if (index_type == INDEX_TYPE_ALLOCATION)
-		filp->f_pos = (u8*)ie - (u8*)iu.ia +
+		*fpos = (u8*)ie - (u8*)iu.ia +
 				(sle64_to_cpu(iu.ia->index_block_vcn) <<
 				ndir->_IDM(index_vcn_size_bits)) +
 				vol->mft_record_size;
 	else /* if (index_type == INDEX_TYPE_ROOT) */
-		filp->f_pos = (u8*)ie - (u8*)iu.ir;
+		*fpos = (u8*)ie - (u8*)iu.ir;
 	name_type = ie->key.file_name.file_name_type;
 	if (name_type == FILE_NAME_DOS) {
 		ntfs_debug("Skipping DOS name space entry.");
@@ -1029,11 +1037,11 @@
 		dt_type = DT_DIR;
 	else
 		dt_type = DT_REG;
-	ntfs_debug("Calling filldir for %s with len %i, f_pos 0x%Lx, inode "
-			"0x%lx, DT_%s.", name, name_len, filp->f_pos,
+	ntfs_debug("Calling filldir for %s with len %i, fpos 0x%Lx, inode "
+			"0x%lx, DT_%s.", name, name_len, *fpos,
 			MREF_LE(ie->_IIF(indexed_file)),
 			dt_type == DT_DIR ? "DIR" : "REG");
-	return filldir(dirent, name, name_len, filp->f_pos,
+	return filldir(dirent, name, name_len, *fpos,
 			MREF_LE(ie->_IIF(indexed_file)), dt_type);
 }
 
@@ -1053,6 +1061,7 @@
 static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 {
 	s64 ia_pos, ia_start, prev_ia_pos, bmp_pos;
+	loff_t fpos;
 	struct inode *bmp_vi, *vdir = filp->f_dentry->d_inode;
 	struct super_block *sb = vdir->i_sb;
 	ntfs_inode *ndir = NTFS_I(vdir);
@@ -1068,47 +1077,34 @@
 	u8 *kaddr, *bmp, *index_end;
 	attr_search_context *ctx;
 
-	ntfs_debug("Entering for inode 0x%lx, f_pos 0x%Lx.",
-			vdir->i_ino, filp->f_pos);
+	fpos = filp->f_pos;
+	ntfs_debug("Entering for inode 0x%lx, fpos 0x%Lx.",
+			vdir->i_ino, fpos);
 	rc = err = 0;
 	/* Are we at end of dir yet? */
-	if (filp->f_pos >= vdir->i_size + vol->mft_record_size)
+	if (fpos >= vdir->i_size + vol->mft_record_size)
 		goto done;
 	/* Emulate . and .. for all directories. */
-	if (!filp->f_pos) {
-		ntfs_debug("Calling filldir for . with len 1, f_pos 0x0, "
+	if (!fpos) {
+		ntfs_debug("Calling filldir for . with len 1, fpos 0x0, "
 				"inode 0x%lx, DT_DIR.", vdir->i_ino);
-		rc = filldir(dirent, ".", 1, filp->f_pos, vdir->i_ino, DT_DIR);
+		rc = filldir(dirent, ".", 1, fpos, vdir->i_ino, DT_DIR);
 		if (rc)
 			goto done;
-		filp->f_pos++;
+		fpos++;
 	}
-	if (filp->f_pos == 1) {
-		ntfs_debug("Calling filldir for .. with len 2, f_pos 0x1, "
+	if (fpos == 1) {
+		ntfs_debug("Calling filldir for .. with len 2, fpos 0x1, "
 				"inode 0x%lx, DT_DIR.",
 				parent_ino(filp->f_dentry));
-		rc = filldir(dirent, "..", 2, filp->f_pos,
+		rc = filldir(dirent, "..", 2, fpos,
 				parent_ino(filp->f_dentry), DT_DIR);
 		if (rc)
 			goto done;
-		filp->f_pos++;
-	}
-
-	/* Get hold of the mft record for the directory. */
-	m = map_mft_record(READ, ndir);
-	if (unlikely(IS_ERR(m))) {
-		err = PTR_ERR(m);
-		m = NULL;
-		ctx = NULL;
-		goto err_out;
-	}
-
-	ctx = get_attr_search_ctx(ndir, m);
-	if (unlikely(!ctx)) {
-		err = -ENOMEM;
-		goto err_out;
+		fpos++;
 	}
-
+	m = NULL;
+	ctx = NULL;
 	/*
 	 * Allocate a buffer to store the current name being processed
 	 * converted to format determined by current NLS.
@@ -1120,10 +1116,22 @@
 		goto err_out;
 	}
 	/* Are we jumping straight into the index allocation attribute? */
-	if (filp->f_pos >= vol->mft_record_size)
+	if (fpos >= vol->mft_record_size)
 		goto skip_index_root;
+	/* Get hold of the mft record for the directory. */
+	m = map_mft_record(ndir);
+	if (unlikely(IS_ERR(m))) {
+		err = PTR_ERR(m);
+		m = NULL;
+		goto err_out;
+	}
+	ctx = get_attr_search_ctx(ndir, m);
+	if (unlikely(!ctx)) {
+		err = -ENOMEM;
+		goto err_out;
+	}
 	/* Get the offset into the index root attribute. */
-	ir_pos = (s64)filp->f_pos;
+	ir_pos = (s64)fpos;
 	/* Find the index root attribute in the mft record. */
 	if (unlikely(!lookup_attr(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0,
 			NULL, 0, ctx))) {
@@ -1158,21 +1166,33 @@
 		if (ir_pos > (u8*)ie - (u8*)ir)
 			continue;
 		/* Submit the name to the filldir callback. */
-		rc = ntfs_filldir(vol, filp, ndir, INDEX_TYPE_ROOT, ir, ie,
+		rc = ntfs_filldir(vol, &fpos, ndir, INDEX_TYPE_ROOT, ir, ie,
 				name, dirent, filldir);
-		if (rc)
+		if (rc) {
+			put_attr_search_ctx(ctx);
+			unmap_mft_record(ndir);
 			goto abort;
+		}
 	}
+	/*
+	 * We are done with the index root and the mft record for that matter.
+	 * We need to release it, otherwise we deadlock on ntfs_attr_iget()
+	 * and/or ntfs_read_page().
+	 */
+	put_attr_search_ctx(ctx);
+	unmap_mft_record(ndir);
+	m = NULL; 
+	ctx = NULL;
 	/* If there is no index allocation attribute we are finished. */
 	if (!NInoIndexAllocPresent(ndir))
 		goto EOD;
-	/* Advance f_pos to the beginning of the index allocation. */
-	filp->f_pos = vol->mft_record_size;
+	/* Advance fpos to the beginning of the index allocation. */
+	fpos = vol->mft_record_size;
 skip_index_root:
 	kaddr = NULL;
 	prev_ia_pos = -1LL;
 	/* Get the offset into the index allocation attribute. */
-	ia_pos = (s64)filp->f_pos - vol->mft_record_size;
+	ia_pos = (s64)fpos - vol->mft_record_size;
 	ia_mapping = vdir->i_mapping;
 	bmp_vi = ndir->_IDM(bmp_ino);
 	if (unlikely(!bmp_vi)) {
@@ -1195,7 +1215,7 @@
 	}
 	/* Get the starting bit position in the current bitmap page. */
 	cur_bmp_pos = bmp_pos & ((PAGE_CACHE_SIZE * 8) - 1);
-	bmp_pos &= ~((PAGE_CACHE_SIZE * 8) - 1);
+	bmp_pos &= ~(u64)((PAGE_CACHE_SIZE * 8) - 1);
 get_next_bmp_page:
 	ntfs_debug("Reading bitmap with page index 0x%Lx, bit ofs 0x%Lx",
 			(long long)bmp_pos >> (3 + PAGE_CACHE_SHIFT),
@@ -1324,7 +1344,7 @@
 		if (ia_pos - ia_start > (u8*)ie - (u8*)ia)
 			continue;
 		/* Submit the name to the filldir callback. */
-		rc = ntfs_filldir(vol, filp, ndir, INDEX_TYPE_ALLOCATION, ia,
+		rc = ntfs_filldir(vol, &fpos, ndir, INDEX_TYPE_ALLOCATION, ia,
 				ie, name, dirent, filldir);
 		if (rc) {
 			ntfs_unmap_page(ia_page);
@@ -1338,20 +1358,19 @@
 		ntfs_unmap_page(ia_page);
 	ntfs_unmap_page(bmp_page);
 EOD:
-	/* We are finished, set f_pos to EOD. */
-	filp->f_pos = vdir->i_size + vol->mft_record_size;
+	/* We are finished, set fpos to EOD. */
+	fpos = vdir->i_size + vol->mft_record_size;
 abort:
-	put_attr_search_ctx(ctx);
-	unmap_mft_record(READ, ndir);
 	kfree(name);
 done:
 #ifdef DEBUG
 	if (!rc)
-		ntfs_debug("EOD, f_pos 0x%Lx, returning 0.", filp->f_pos);
+		ntfs_debug("EOD, fpos 0x%Lx, returning 0.", fpos);
 	else
-		ntfs_debug("filldir returned %i, f_pos 0x%Lx, returning 0.",
-				rc, filp->f_pos);
+		ntfs_debug("filldir returned %i, fpos 0x%Lx, returning 0.",
+				rc, fpos);
 #endif
+	filp->f_pos = fpos;
 	return 0;
 err_out:
 	if (bmp_page)
@@ -1363,10 +1382,11 @@
 	if (ctx)
 		put_attr_search_ctx(ctx);
 	if (m)
-		unmap_mft_record(READ, ndir);
+		unmap_mft_record(ndir);
 	if (!err)
 		err = -EIO;
 	ntfs_debug("Failed. Returning error code %i.", -err);
+	filp->f_pos = fpos;
 	return err;
 }
 
@@ -1396,9 +1416,9 @@
 }
 
 struct file_operations ntfs_dir_ops = {
-	llseek:		generic_file_llseek,	/* Seek inside directory. */
-	read:		generic_read_dir,	/* Return -EISDIR. */
-	readdir:	ntfs_readdir,		/* Read directory contents. */
-	open:		ntfs_dir_open,		/* Open directory. */
+	.llseek		= generic_file_llseek,	/* Seek inside directory. */
+	.read		= generic_read_dir,	/* Return -EISDIR. */
+	.readdir	= ntfs_readdir,		/* Read directory contents. */
+	.open		= ntfs_dir_open,	/* Open directory. */
 };
 
diff -Nru a/fs/ntfs/file.c b/fs/ntfs/file.c
--- a/fs/ntfs/file.c	Sat Aug 10 18:42:23 2002
+++ b/fs/ntfs/file.c	Sat Aug 10 18:42:23 2002
@@ -49,11 +49,18 @@
 }
 
 struct file_operations ntfs_file_ops = {
-	llseek:		generic_file_llseek,	/* Seek inside file. */
-	read:		generic_file_read,	/* Read from file. */
-	mmap:		generic_file_mmap,	/* Mmap file. */
- 	sendfile:	generic_file_sendfile,	/* Zero-copy data send */
-	open:		ntfs_file_open,		/* Open file. */
+	.llseek		= generic_file_llseek,	/* Seek inside file. */
+	.read		= generic_file_read,	/* Read from file. */
+#ifdef NTFS_RW
+	.write		= generic_file_write,	/* Write to a file. */
+#endif
+	.mmap		= generic_file_mmap,	/* Mmap file. */
+	.sendfile	= generic_file_sendfile,/* Zero-copy data send with the
+						   data source being on the
+						   ntfs partition. We don't
+						   need to care about the data
+						   destination. */
+	.open		= ntfs_file_open,	/* Open file. */
 };
 
 struct inode_operations ntfs_file_inode_ops = {};
diff -Nru a/fs/ntfs/inode.c b/fs/ntfs/inode.c
--- a/fs/ntfs/inode.c	Sat Aug 10 18:42:22 2002
+++ b/fs/ntfs/inode.c	Sat Aug 10 18:42:22 2002
@@ -278,15 +278,18 @@
 	ntfs_inode *ni = NTFS_I(inode);
 
 	ntfs_debug("Entering.");
-	BUG_ON(atomic_read(&ni->mft_count) || !atomic_dec_and_test(&ni->count));
+	BUG_ON(ni->page);
+	if (!atomic_dec_and_test(&ni->count))
+		BUG();
 	kmem_cache_free(ntfs_big_inode_cache, NTFS_I(inode));
 }
 
-static ntfs_inode *ntfs_alloc_extent_inode(void)
+static inline ntfs_inode *ntfs_alloc_extent_inode(void)
 {
-	ntfs_inode *ni = (ntfs_inode *)kmem_cache_alloc(ntfs_inode_cache,
-			SLAB_NOFS);
+	ntfs_inode *ni;
+
 	ntfs_debug("Entering.");
+	ni = (ntfs_inode *)kmem_cache_alloc(ntfs_inode_cache, SLAB_NOFS);
 	if (likely(ni != NULL)) {
 		ni->state = 0;
 		return ni;
@@ -298,7 +301,9 @@
 void ntfs_destroy_extent_inode(ntfs_inode *ni)
 {
 	ntfs_debug("Entering.");
-	BUG_ON(atomic_read(&ni->mft_count) || !atomic_dec_and_test(&ni->count));
+	BUG_ON(ni->page);
+	if (!atomic_dec_and_test(&ni->count))
+		BUG();
 	kmem_cache_free(ntfs_inode_cache, ni);
 }
 
@@ -322,8 +327,7 @@
 	atomic_set(&ni->count, 1);
 	ni->vol = NTFS_SB(sb);
 	init_run_list(&ni->run_list);
-	init_rwsem(&ni->mrec_lock);
-	atomic_set(&ni->mft_count, 0);
+	init_MUTEX(&ni->mrec_lock);
 	ni->page = NULL;
 	ni->page_ofs = 0;
 	ni->attr_list_size = 0;
@@ -340,7 +344,7 @@
 	return;
 }
 
-static void ntfs_init_big_inode(struct inode *vi)
+static inline void ntfs_init_big_inode(struct inode *vi)
 {
 	ntfs_inode *ni = NTFS_I(vi);
 
@@ -350,7 +354,8 @@
 	return;
 }
 
-ntfs_inode *ntfs_new_extent_inode(struct super_block *sb, unsigned long mft_no)
+inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb,
+		unsigned long mft_no)
 {
 	ntfs_inode *ni = ntfs_alloc_extent_inode();
 
@@ -445,7 +450,7 @@
  * ntfs_read_locked_inode - read an inode from its device
  * @vi:		inode to read
  *
- * ntfs_read_locked_inode() is called from the ntfs_iget() to read the inode
+ * ntfs_read_locked_inode() is called from ntfs_iget() to read the inode
  * described by @vi into memory from the device.
  *
  * The only fields in @vi that we need to/can look at when the function is
@@ -502,7 +507,7 @@
 		ntfs_init_big_inode(vi);
 	ni = NTFS_I(vi);
 
-	m = map_mft_record(READ, ni);
+	m = map_mft_record(ni);
 	if (IS_ERR(m)) {
 		err = PTR_ERR(m);
 		goto err_out;
@@ -788,6 +793,11 @@
 			/* No index allocation. */
 			vi->i_size = ni->initialized_size =
 					ni->allocated_size = 0;
+			/* We are done with the mft record, so we release it. */
+			put_attr_search_ctx(ctx);
+			unmap_mft_record(ni);
+			m = NULL;
+			ctx = NULL;
 			goto skip_large_dir_stuff;
 		} /* LARGE_INDEX: Index allocation present. Setup state. */
 		NInoSetIndexAllocPresent(ni);
@@ -832,7 +842,14 @@
 				ctx->attr->_ANR(initialized_size));
 		ni->allocated_size = sle64_to_cpu(
 				ctx->attr->_ANR(allocated_size));
-
+		/*
+		 * We are done with the mft record, so we release it. Otherwise
+		 *
+		 */
+		put_attr_search_ctx(ctx);
+		unmap_mft_record(ni);
+		m = NULL;
+		ctx = NULL;
 		/* Get the index bitmap attribute inode. */
 		bvi = ntfs_attr_iget(vi, AT_BITMAP, I30, 4);
 		if (unlikely(IS_ERR(bvi))) {
@@ -856,7 +873,6 @@
 					bvi->i_size << 3, vi->i_size);
 			goto unm_err_out;
 		}
-
 skip_large_dir_stuff:
 		/* Everyone gets read and scan permissions. */
 		vi->i_mode |= S_IRUGO | S_IXUGO;
@@ -996,6 +1012,11 @@
 				le32_to_cpu(ctx->attr->_ARA(value_length));
 		}
 no_data_attr_special_case:
+		/* We are done with the mft record, so we release it. */
+		put_attr_search_ctx(ctx);
+		unmap_mft_record(ni);
+		m = NULL;
+		ctx = NULL;
 		/* Everyone gets all permissions. */
 		vi->i_mode |= S_IRWXUGO;
 		/* If read-only, noone gets write permissions. */
@@ -1024,9 +1045,6 @@
 	else
 		vi->i_blocks = ni->_ICF(compressed_size) >> 9;
 
-	put_attr_search_ctx(ctx);
-	unmap_mft_record(READ, ni);
-
 	ntfs_debug("Done.");
 	return 0;
 
@@ -1035,7 +1053,8 @@
 		err = -EIO;
 	if (ctx)
 		put_attr_search_ctx(ctx);
-	unmap_mft_record(READ, ni);
+	if (m)
+		unmap_mft_record(ni);
 err_out:
 	ntfs_error(vi->i_sb, "Failed with error code %i. Marking inode 0x%lx "
 			"as bad.", -err, vi->i_ino);
@@ -1089,7 +1108,7 @@
 	/* Set inode type to zero but preserve permissions. */
 	vi->i_mode	= base_vi->i_mode & ~S_IFMT;
 
-	m = map_mft_record(READ, base_ni);
+	m = map_mft_record(base_ni);
 	if (IS_ERR(m)) {
 		err = PTR_ERR(m);
 		goto err_out;
@@ -1263,7 +1282,7 @@
 	ni->nr_extents = -1;
 
 	put_attr_search_ctx(ctx);
-	unmap_mft_record(READ, base_ni);
+	unmap_mft_record(base_ni);
 
 	ntfs_debug("Done.");
 	return 0;
@@ -1273,7 +1292,7 @@
 		err = -EIO;
 	if (ctx)
 		put_attr_search_ctx(ctx);
-	unmap_mft_record(READ, base_ni);
+	unmap_mft_record(base_ni);
 err_out:
 	ntfs_error(vi->i_sb, "Failed with error code %i while reading "
 			"attribute inode (mft_no 0x%lx, type 0x%x, name_len "
@@ -1396,7 +1415,7 @@
 	/* Need this to sanity check attribute list references to $MFT. */
 	ni->seq_no = le16_to_cpu(m->sequence_number);
 
-	/* Provides readpage() and sync_page() for map_mft_record(READ). */
+	/* Provides readpage() and sync_page() for map_mft_record(). */
 	vi->i_mapping->a_ops = &ntfs_mft_aops;
 
 	ctx = get_attr_search_ctx(ni, m);
@@ -1793,8 +1812,8 @@
 		}
 	}
 	/* Synchronize with ntfs_commit_inode(). */
-	down_write(&ni->mrec_lock);
-	up_write(&ni->mrec_lock);
+	down(&ni->mrec_lock);
+	up(&ni->mrec_lock);
 	if (NInoDirty(ni)) {
 		ntfs_error(ni->vol->sb, "Failed to commit dirty inode "
 				"asynchronously.");
diff -Nru a/fs/ntfs/inode.h b/fs/ntfs/inode.h
--- a/fs/ntfs/inode.h	Sat Aug 10 18:42:23 2002
+++ b/fs/ntfs/inode.h	Sat Aug 10 18:42:23 2002
@@ -72,9 +72,8 @@
 	 * The following fields are only valid for real inodes and extent
 	 * inodes.
 	 */
-	struct rw_semaphore mrec_lock;	/* Lock for serializing access to the
+	struct semaphore mrec_lock; /* Lock for serializing access to the
 				   mft record belonging to this inode. */
-	atomic_t mft_count;	/* Mapping reference count for book keeping. */
 	struct page *page;	/* The page containing the mft record of the
 				   inode. This should only be touched by the
 				   (un)map_mft_record*() functions. */
@@ -223,7 +222,7 @@
 
 static inline struct inode *VFS_I(ntfs_inode *ni)
 {
-	return &((big_ntfs_inode*)ni)->vfs_inode;
+	return &((big_ntfs_inode *)ni)->vfs_inode;
 }
 
 extern struct inode *ntfs_iget(struct super_block *sb, unsigned long mft_no);
diff -Nru a/fs/ntfs/malloc.h b/fs/ntfs/malloc.h
--- a/fs/ntfs/malloc.h	Sat Aug 10 18:42:21 2002
+++ b/fs/ntfs/malloc.h	Sat Aug 10 18:42:21 2002
@@ -26,20 +26,6 @@
 #include <linux/slab.h>
 
 /**
- * vmalloc_nofs - allocate any pages but don't allow calls into fs layer
- * @size:	number of bytes to allocate
- *
- * Allocate any pages but don't allow calls into fs layer. Return allocated
- * memory or NULL if insufficient memory.
- */
-static inline void *vmalloc_nofs(unsigned long size)
-{
-	if (likely(size >> PAGE_SHIFT < num_physpages))
-		return __vmalloc(size, GFP_NOFS | __GFP_HIGHMEM, PAGE_KERNEL);
-	return NULL;
-}
-
-/**
  * ntfs_malloc_nofs - allocate memory in multiples of pages
  * @size	number of bytes to allocate
  *
@@ -66,7 +52,8 @@
 
 static inline void ntfs_free(void *addr)
 {
-	if (likely((unsigned long)addr < VMALLOC_START)) {
+	if (likely(((unsigned long)addr < VMALLOC_START) ||
+			((unsigned long)addr >= VMALLOC_END ))) {
 		return kfree(addr);
 		/* return free_page((unsigned long)addr); */
 	}
diff -Nru a/fs/ntfs/mft.c b/fs/ntfs/mft.c
--- a/fs/ntfs/mft.c	Sat Aug 10 18:42:21 2002
+++ b/fs/ntfs/mft.c	Sat Aug 10 18:42:21 2002
@@ -2,7 +2,7 @@
  * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
  *
  * Copyright (c) 2001,2002 Anton Altaparmakov.
- * Copyright (C) 2002 Richard Russon.
+ * Copyright (c) 2002 Richard Russon.
  *
  * This program/include file is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as published
@@ -85,13 +85,15 @@
 	if (mft_rec)
 		m = mft_rec;
 	else {
-		m = map_mft_record(WRITE, ni);
+		m = map_mft_record(ni);
 		if (IS_ERR(m))
 			return PTR_ERR(m);
 	}
 	__format_mft_record(m, ni->vol->mft_record_size, ni->mft_no);
-	if (!mft_rec)
-		unmap_mft_record(WRITE, ni);
+	if (!mft_rec) {
+		// FIXME: Need to set the mft record dirty!
+		unmap_mft_record(ni);
+	}
 	return 0;
 }
 
@@ -107,12 +109,12 @@
  * ntfs_map_page() in map_mft_record_page().
  */
 struct address_space_operations ntfs_mft_aops = {
-	writepage:	NULL,			/* Write dirty page to disk. */
-	readpage:	ntfs_readpage,		/* Fill page with data. */
-	sync_page:	block_sync_page,	/* Currently, just unplugs the
+	.writepage	= NULL,			/* Write dirty page to disk. */
+	.readpage	= ntfs_readpage,	/* Fill page with data. */
+	.sync_page	= block_sync_page,	/* Currently, just unplugs the
 						   disk request queue. */
-	prepare_write:	NULL,			/* . */
-	commit_write:	NULL,			/* . */
+	.prepare_write	= NULL,			/* . */
+	.commit_write	= NULL,			/* . */
 };
 
 /**
@@ -132,7 +134,7 @@
 	struct page *page;
 	unsigned long index, ofs, end_index;
 
-	BUG_ON(atomic_read(&ni->mft_count) || ni->page);
+	BUG_ON(ni->page);
 	/*
 	 * The index into the page cache and the offset within the page cache
 	 * page of the wanted mft record. FIXME: We need to check for
@@ -146,70 +148,36 @@
 	end_index = mft_vi->i_size >> PAGE_CACHE_SHIFT;
 
 	/* If the wanted index is out of bounds the mft record doesn't exist. */
-	if (index >= end_index) {
+	if (unlikely(index >= end_index)) {
 		if (index > end_index || (mft_vi->i_size & ~PAGE_CACHE_MASK) <
 				ofs + vol->mft_record_size) {
 			page = ERR_PTR(-ENOENT);
-			goto up_err_out;
+			goto err_out;
 		}
 	}
 	/* Read, map, and pin the page. */
 	page = ntfs_map_page(mft_vi->i_mapping, index);
-	if (!IS_ERR(page)) {
-		/* Pin the mft record mapping in the ntfs_inode. */
-		atomic_inc(&ni->mft_count);
-
-		/* Setup the references in the ntfs_inode. */
+	if (likely(!IS_ERR(page))) {
 		ni->page = page;
 		ni->page_ofs = ofs;
-
 		return page_address(page) + ofs;
 	}
-up_err_out:
-	/* Just in case... */
+err_out:
 	ni->page = NULL;
 	ni->page_ofs = 0;
-
 	ntfs_error(vol->sb, "Failed with error code %lu.", -PTR_ERR(page));
 	return (void*)page;
 }
 
 /**
- * unmap_mft_record_page - unmap the page in which a specific mft record resides
- * @ni:		ntfs inode whose mft record page to unmap
- *
- * This unmaps the page in which the mft record of the ntfs inode @ni is
- * situated and returns. This is a NOOP if highmem is not configured.
- *
- * The unmap happens via ntfs_unmap_page() which in turn decrements the use
- * count on the page thus releasing it from the pinned state.
- *
- * We do not actually unmap the page from memory of course, as that will be
- * done by the page cache code itself when memory pressure increases or
- * whatever.
- */
-static inline void unmap_mft_record_page(ntfs_inode *ni)
-{
-	BUG_ON(atomic_read(&ni->mft_count) || !ni->page);
-	// TODO: If dirty, blah...
-	ntfs_unmap_page(ni->page);
-	ni->page = NULL;
-	ni->page_ofs = 0;
-	return;
-}
-
-/**
  * map_mft_record - map, pin and lock an mft record
- * @rw:		map for read (rw = READ) or write (rw = WRITE)
  * @ni:		ntfs inode whose MFT record to map
  *
- * First, take the mrec_lock semaphore for reading or writing, depending on
- * the value or @rw. We might now be sleeping, while waiting for the semaphore
- * if it was already locked by someone else.
- *
- * Then increment the map reference count and return the mft. If this is the
- * first invocation, the page of the record is first mapped using
- * map_mft_record_page().
+ * First, take the mrec_lock semaphore. We might now be sleeping, while waiting
+ * for the semaphore if it was already locked by someone else.
+ *
+ * The page of the record is first mapped using map_mft_record_page() before
+ * being returned to the caller.
  *
  * This in turn uses ntfs_map_page() to get the page containing the wanted mft
  * record (it in turn calls read_cache_page() which reads it in from disk if
@@ -234,11 +202,11 @@
  * locking problem then is them locking the page while we are accessing it.
  *
  * So that code will end up having to own the mrec_lock of all mft
- * records/inodes present in the page before I/O can proceed. Grr. In that
- * case we wouldn't need 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 so much simpler this way that it is well worth it.
+ * 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
+ * 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
  * the returned pointer with IS_ERR() and if that is true, PTR_ERR() will return
@@ -251,89 +219,75 @@
  * A: No, the inode ones mean we want to change the mft record, not we want to
  * write it out.
  */
-MFT_RECORD *map_mft_record(const int rw, ntfs_inode *ni)
+MFT_RECORD *map_mft_record(ntfs_inode *ni)
 {
 	MFT_RECORD *m;
 
-	ntfs_debug("Entering for mft_no 0x%lx, mapping for %s.", ni->mft_no,
-			rw == READ ? "READ" : "WRITE");
+	ntfs_debug("Entering for mft_no 0x%lx.", ni->mft_no);
 
 	/* Make sure the ntfs inode doesn't go away. */
 	atomic_inc(&ni->count);
 
 	/* Serialize access to this mft record. */
-	if (rw == READ)
-		down_read(&ni->mrec_lock);
-	else
-		down_write(&ni->mrec_lock);
-
-	/* If already mapped, bump reference count and return the mft record. */
-	if (atomic_read(&ni->mft_count)) {
-		BUG_ON(!ni->page);
-		atomic_inc(&ni->mft_count);
-		return page_address(ni->page) + ni->page_ofs;
-	}
+	down(&ni->mrec_lock);
 
-	/* Wasn't mapped. Map it now and return it if all was ok. */
 	m = map_mft_record_page(ni);
-	if (!IS_ERR(m))
+	if (likely(!IS_ERR(m)))
 		return m;
 
-	/* Mapping failed. Release the mft record lock. */
-	if (rw == READ)
-		up_read(&ni->mrec_lock);
-	else
-		up_write(&ni->mrec_lock);
-
-	ntfs_error(ni->vol->sb, "Failed with error code %lu.", -PTR_ERR(m));
-
-	/* Release the ntfs inode and return the error code. */
+	up(&ni->mrec_lock);
 	atomic_dec(&ni->count);
+	ntfs_error(ni->vol->sb, "Failed with error code %lu.", -PTR_ERR(m));
 	return m;
 }
 
 /**
- * unmap_mft_record - release a mapped mft record
- * @rw:		unmap from read (@rw = READ) or write (@rw = WRITE)
- * @ni:		ntfs inode whose MFT record to unmap
- *
- * First, decrement the mapping count and when it reaches zero unmap the mft
- * record.
+ * unmap_mft_record_page - unmap the page in which a specific mft record resides
+ * @ni:		ntfs inode whose mft record page to unmap
  *
- * Second, release the mrec_lock semaphore.
+ * This unmaps the page in which the mft record of the ntfs inode @ni is
+ * situated and returns. This is a NOOP if highmem is not configured.
  *
- * The mft record is now released for others to get hold of.
+ * The unmap happens via ntfs_unmap_page() which in turn decrements the use
+ * count on the page thus releasing it from the pinned state.
  *
- * Finally, release the ntfs inode by decreasing the ntfs inode reference count.
+ * We do not actually unmap the page from memory of course, as that will be
+ * done by the page cache code itself when memory pressure increases or
+ * whatever.
+ */
+static inline void unmap_mft_record_page(ntfs_inode *ni)
+{
+	BUG_ON(!ni->page);
+
+	// TODO: If dirty, blah...
+	ntfs_unmap_page(ni->page);
+	ni->page = NULL;
+	ni->page_ofs = 0;
+	return;
+}
+
+/**
+ * unmap_mft_record - release a mapped mft record
+ * @ni:		ntfs inode whose MFT record to unmap
  *
- * NOTE: If caller had the mft record mapped for write and has modified it, it
- * is imperative to set the mft record dirty BEFORE calling unmap_mft_record().
+ * We release the page mapping and the mrec_lock mutex which unmaps the mft
+ * record and releases it for others to get hold of. We also release the ntfs
+ * inode by decrementing the ntfs inode reference count.
  *
- * NOTE: This has to be done both for 'normal' mft records, and for extent mft
- * records.
+ * NOTE: If caller has modified the mft record, it is imperative to set the mft
+ * record dirty BEFORE calling unmap_mft_record().
  */
-void unmap_mft_record(const int rw, ntfs_inode *ni)
+void unmap_mft_record(ntfs_inode *ni)
 {
 	struct page *page = ni->page;
 
-	BUG_ON(!atomic_read(&ni->mft_count) || !page);
+	BUG_ON(!page);
 
-	ntfs_debug("Entering for mft_no 0x%lx, unmapping from %s.", ni->mft_no,
-			rw == READ ? "READ" : "WRITE");
+	ntfs_debug("Entering for mft_no 0x%lx.", ni->mft_no);
 
-	/* Only release the actual page mapping if this is the last one. */
-	if (atomic_dec_and_test(&ni->mft_count))
-		unmap_mft_record_page(ni);
-
-	/* Release the semaphore. */
-	if (rw == READ)
-		up_read(&ni->mrec_lock);
-	else
-		up_write(&ni->mrec_lock);
-
-	/* Release the ntfs inode. */
+	unmap_mft_record_page(ni);
+	up(&ni->mrec_lock);
 	atomic_dec(&ni->count);
-
 	/*
 	 * If pure ntfs_inode, i.e. no vfs inode attached, we leave it to
 	 * ntfs_clear_extent_inode() in the extent inode case, and to the
@@ -355,11 +309,6 @@
  *
  * On successful return, @ntfs_ino contains a pointer to the ntfs_inode
  * structure of the mapped extent inode.
- *
- * Note, we always map for READ. We consider this lock as irrelevant because
- * the base inode will be write locked in all cases when we want to write to
- * an extent inode which already gurantees that there is no-one else accessing
- * the extent inode.
  */
 MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
 		ntfs_inode **ntfs_ino)
@@ -393,21 +342,21 @@
 			break;
 		}
 	}
-	if (ni) {
+	if (likely(ni != NULL)) {
 		up(&base_ni->extent_lock);
 		atomic_dec(&base_ni->count);
 		/* We found the record; just have to map and return it. */
-		m = map_mft_record(READ, ni);
-		/* Map mft record increments this on success. */
+		m = map_mft_record(ni);
+		/* map_mft_record() has incremented this on success. */
 		atomic_dec(&ni->count);
-		if (!IS_ERR(m)) {
+		if (likely(!IS_ERR(m))) {
 			/* Verify the sequence number. */
-			if (le16_to_cpu(m->sequence_number) == seq_no) {
+			if (likely(le16_to_cpu(m->sequence_number) == seq_no)) {
 				ntfs_debug("Done 1.");
 				*ntfs_ino = ni;
 				return m;
 			}
-			unmap_mft_record(READ, ni);
+			unmap_mft_record(ni);
 			ntfs_error(base_ni->vol->sb, "Found stale extent mft "
 					"reference! Corrupt file system. "
 					"Run chkdsk.");
@@ -420,7 +369,7 @@
 	}
 	/* Record wasn't there. Get a new ntfs inode and initialize it. */
 	ni = ntfs_new_extent_inode(base_ni->vol->sb, mft_no);
-	if (!ni) {
+	if (unlikely(!ni)) {
 		up(&base_ni->extent_lock);
 		atomic_dec(&base_ni->count);
 		return ERR_PTR(-ENOMEM);
@@ -430,15 +379,15 @@
 	ni->nr_extents = -1;
 	ni->_INE(base_ntfs_ino) = base_ni;
 	/* Now map the record. */
-	m = map_mft_record(READ, ni);
-	if (IS_ERR(m)) {
+	m = map_mft_record(ni);
+	if (unlikely(IS_ERR(m))) {
 		up(&base_ni->extent_lock);
 		atomic_dec(&base_ni->count);
 		ntfs_clear_extent_inode(ni);
 		goto map_err_out;
 	}
 	/* Verify the sequence number. */
-	if (le16_to_cpu(m->sequence_number) != seq_no) {
+	if (unlikely(le16_to_cpu(m->sequence_number) != seq_no)) {
 		ntfs_error(base_ni->vol->sb, "Found stale extent mft "
 				"reference! Corrupt file system. Run chkdsk.");
 		destroy_ni = TRUE;
@@ -451,7 +400,7 @@
 		int new_size = (base_ni->nr_extents + 4) * sizeof(ntfs_inode *);
 
 		tmp = (ntfs_inode **)kmalloc(new_size, GFP_NOFS);
-		if (!tmp) {
+		if (unlikely(!tmp)) {
 			ntfs_error(base_ni->vol->sb, "Failed to allocate "
 					"internal buffer.");
 			destroy_ni = TRUE;
@@ -472,7 +421,7 @@
 	*ntfs_ino = ni;
 	return m;
 unm_err_out:
-	unmap_mft_record(READ, ni);
+	unmap_mft_record(ni);
 	up(&base_ni->extent_lock);
 	atomic_dec(&base_ni->count);
 	/*
diff -Nru a/fs/ntfs/mft.h b/fs/ntfs/mft.h
--- a/fs/ntfs/mft.h	Sat Aug 10 18:42:21 2002
+++ b/fs/ntfs/mft.h	Sat Aug 10 18:42:21 2002
@@ -31,15 +31,15 @@
 //extern int format_mft_record2(struct super_block *vfs_sb,
 //		const unsigned long inum, MFT_RECORD *m);
 
-extern MFT_RECORD *map_mft_record(const int rw, ntfs_inode *ni);
-extern void unmap_mft_record(const int rw, ntfs_inode *ni);
+extern MFT_RECORD *map_mft_record(ntfs_inode *ni);
+extern void unmap_mft_record(ntfs_inode *ni);
 
 extern MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
 		ntfs_inode **ntfs_ino);
 
 static inline void unmap_extent_mft_record(ntfs_inode *ni)
 {
-	unmap_mft_record(READ, ni);
+	unmap_mft_record(ni);
 	return;
 }
 
diff -Nru a/fs/ntfs/namei.c b/fs/ntfs/namei.c
--- a/fs/ntfs/namei.c	Sat Aug 10 18:42:23 2002
+++ b/fs/ntfs/namei.c	Sat Aug 10 18:42:23 2002
@@ -162,6 +162,7 @@
 handle_name:
    {
 	struct dentry *real_dent;
+	MFT_RECORD *m;
 	attr_search_context *ctx;
 	ntfs_inode *ni = NTFS_I(dent_inode);
 	int err;
@@ -175,22 +176,23 @@
 				name->len * 3 + 1);
 		kfree(name);
 	} else /* if (name->type == FILE_NAME_DOS) */ {		/* Case 3. */
-		MFT_RECORD *m;
 		FILE_NAME_ATTR *fn;
 
 		kfree(name);
 
 		/* Find the WIN32 name corresponding to the matched DOS name. */
 		ni = NTFS_I(dent_inode);
-		m = map_mft_record(READ, ni);
+		m = map_mft_record(ni);
 		if (IS_ERR(m)) {
 			err = PTR_ERR(m);
-			goto name_err_out;
+			m = NULL;
+			ctx = NULL;
+			goto err_out;
 		}
 		ctx = get_attr_search_ctx(ni, m);
 		if (!ctx) {
 			err = -ENOMEM;
-			goto unm_err_out;
+			goto err_out;
 		}
 		do {
 			ATTR_RECORD *a;
@@ -202,21 +204,21 @@
 						"namespace counterpart to DOS "
 						"file name. Run chkdsk.");
 				err = -EIO;
-				goto put_unm_err_out;
+				goto err_out;
 			}
 			/* Consistency checks. */
 			a = ctx->attr;
 			if (a->non_resident || a->flags)
-				goto eio_put_unm_err_out;
+				goto eio_err_out;
 			val_len = le32_to_cpu(a->_ARA(value_length));
 			if (le16_to_cpu(a->_ARA(value_offset)) + val_len >
 					le32_to_cpu(a->length))
-				goto eio_put_unm_err_out;
+				goto eio_err_out;
 			fn = (FILE_NAME_ATTR*)((u8*)ctx->attr + le16_to_cpu(
 					ctx->attr->_ARA(value_offset)));
 			if ((u32)(fn->file_name_length * sizeof(uchar_t) +
 					sizeof(FILE_NAME_ATTR)) > val_len)
-				goto eio_put_unm_err_out;
+				goto eio_err_out;
 		} while (fn->file_name_type != FILE_NAME_WIN32);
 
 		/* Convert the found WIN32 name to current NLS code page. */
@@ -226,13 +228,15 @@
 				fn->file_name_length * 3 + 1);
 
 		put_attr_search_ctx(ctx);
-		unmap_mft_record(READ, ni);
+		unmap_mft_record(ni);
 	}
+	m = NULL;
+	ctx = NULL;
 
 	/* Check if a conversion error occured. */
 	if ((signed)nls_name.len < 0) {
 		err = (signed)nls_name.len;
-		goto name_err_out;
+		goto err_out;
 	}
 	nls_name.hash = full_name_hash(nls_name.name, nls_name.len);
 
@@ -248,7 +252,7 @@
 		kfree(nls_name.name);
 		if (!real_dent) {
 			err = -ENOMEM;
-			goto name_err_out;
+			goto err_out;
 		}
 		d_add(real_dent, dent_inode);
 		return real_dent;
@@ -269,14 +273,14 @@
 	d_instantiate(real_dent, dent_inode);
 	return real_dent;
 
-eio_put_unm_err_out:
+eio_err_out:
 	ntfs_error(vol->sb, "Illegal file name attribute. Run chkdsk.");
 	err = -EIO;
-put_unm_err_out:
-	put_attr_search_ctx(ctx);
-unm_err_out:
-	unmap_mft_record(READ, ni);
-name_err_out:
+err_out:
+	if (ctx)
+		put_attr_search_ctx(ctx);
+	if (m)
+		unmap_mft_record(ni);
 	iput(dent_inode);
 	return ERR_PTR(err);
    }
@@ -286,6 +290,6 @@
  * Inode operations for directories.
  */
 struct inode_operations ntfs_dir_inode_ops = {
-	lookup:		ntfs_lookup,	/* VFS: Lookup directory. */
+	.lookup	= ntfs_lookup,	/* VFS: Lookup directory. */
 };
 
diff -Nru a/fs/ntfs/super.c b/fs/ntfs/super.c
--- a/fs/ntfs/super.c	Sat Aug 10 18:42:21 2002
+++ b/fs/ntfs/super.c	Sat Aug 10 18:42:21 2002
@@ -307,6 +307,23 @@
 
 	ntfs_debug("Entering with remount options string: %s", opt);
 
+#ifndef NTFS_RW
+	/* For read-only compiled driver, enforce all read-only flags. */
+	*flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
+#else
+	/*
+	 * For the read-write compiled driver, if we are remounting read-write,
+	 * make sure there aren't any volume errors.
+	 */
+	if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
+		if (NVolErrors(vol)) {
+			ntfs_error(sb, "Volume has errors and is read-only."
+					"Cannot remount read-write.");
+			return -EROFS;
+		}
+	}
+#endif
+
 	// FIXME/TODO: If left like this we will have problems with rw->ro and
 	// ro->rw, as well as with sync->async and vice versa remounts.
 	// Note: The VFS already checks that there are no pending deletes and
@@ -324,10 +341,6 @@
 	if (!parse_options(vol, opt))
 		return -EINVAL;
 
-#ifndef NTFS_RW
-	*flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;
-#endif
-
 	return 0;
 }
 
@@ -852,7 +865,7 @@
 		ntfs_error(sb, "Failed to load $Volume.");
 		goto iput_lcnbmp_err_out;
 	}
-	m = map_mft_record(READ, NTFS_I(vol->vol_ino));
+	m = map_mft_record(NTFS_I(vol->vol_ino));
 	if (IS_ERR(m)) {
 iput_volume_failed:
 		iput(vol->vol_ino);
@@ -867,7 +880,7 @@
 err_put_vol:
 		put_attr_search_ctx(ctx);
 get_ctx_vol_failed:
-		unmap_mft_record(READ, NTFS_I(vol->vol_ino));
+		unmap_mft_record(NTFS_I(vol->vol_ino));
 		goto iput_volume_failed;
 	}
 	vi = (VOLUME_INFORMATION*)((char*)ctx->attr +
@@ -882,7 +895,7 @@
 	vol->major_ver = vi->major_ver;
 	vol->minor_ver = vi->minor_ver;
 	put_attr_search_ctx(ctx);
-	unmap_mft_record(READ, NTFS_I(vol->vol_ino));
+	unmap_mft_record(NTFS_I(vol->vol_ino));
 	printk(KERN_INFO "NTFS volume version %i.%i.\n", vol->major_ver,
 			vol->minor_ver);
 	/*
@@ -1260,38 +1273,38 @@
  * proper functions.
  */
 struct super_operations ntfs_mount_sops = {
-	alloc_inode:	ntfs_alloc_big_inode,	/* VFS: Allocate a new inode. */
-	destroy_inode:	ntfs_destroy_big_inode,	/* VFS: Deallocate an inode. */
-	read_inode:	ntfs_read_inode_mount,	/* VFS: Load inode from disk,
-						   called from iget(). */
-	clear_inode:	ntfs_clear_big_inode,	/* VFS: Called when an inode is
-						   removed from memory. */
+	.alloc_inode	= ntfs_alloc_big_inode,	  /* VFS: Allocate new inode. */
+	.destroy_inode	= ntfs_destroy_big_inode, /* VFS: Deallocate inode. */
+	.read_inode	= ntfs_read_inode_mount,  /* VFS: Load inode from disk,
+						     called from iget(). */
+	.clear_inode	= ntfs_clear_big_inode,	  /* VFS: Called when inode is
+						     removed from memory. */
 };
 
 /**
  * The complete super operations.
  */
 struct super_operations ntfs_sops = {
-	alloc_inode:	ntfs_alloc_big_inode,	/* VFS: Allocate a new inode. */
-	destroy_inode:	ntfs_destroy_big_inode,	/* VFS: Deallocate an inode. */
-	dirty_inode:	ntfs_dirty_inode,	/* VFS: Called from
-						   __mark_inode_dirty(). */
-	//write_inode:	NULL,		/* VFS: Write dirty inode to disk. */
-	put_inode:	ntfs_put_inode,	/* VFS: Called just before the inode
-					   reference count is decreased. */
-	//delete_inode:	NULL,		/* VFS: Delete inode from disk. Called
-	//				   when i_count becomes 0 and i_nlink is
-	//				   also 0. */
-	put_super:	ntfs_put_super,	/* Syscall: umount. */
-	//write_super:	NULL,		/* Flush dirty super block to disk. */
-	//write_super_lockfs:	NULL,	/* ? */
-	//unlockfs:	NULL,		/* ? */
-	statfs:		ntfs_statfs,	/* Syscall: statfs */
-	remount_fs:	ntfs_remount,	/* Syscall: mount -o remount. */
-	clear_inode:	ntfs_clear_big_inode,	/* VFS: Called when an inode is
+	.alloc_inode	= ntfs_alloc_big_inode,	  /* VFS: Allocate new inode. */
+	.destroy_inode	= ntfs_destroy_big_inode, /* VFS: Deallocate inode. */
+	//.dirty_inode	= ntfs_dirty_inode,	  /* VFS: Called from
+	//					     __mark_inode_dirty(). */
+	//.write_inode	= NULL,		  /* VFS: Write dirty inode to disk. */
+	.put_inode	= ntfs_put_inode, /* VFS: Called just before the inode
+					     reference count is decreased. */
+	//.delete_inode	= NULL,		  /* VFS: Delete inode from disk. Called
+	//				     when i_count becomes 0 and i_nlink
+	//				     is also 0. */
+	.put_super	= ntfs_put_super, /* Syscall: umount. */
+	//write_super	= NULL,		  /* Flush dirty super block to disk. */
+	//write_super_lockfs	= NULL,	  /* ? */
+	//unlockfs	= NULL,		  /* ? */
+	.statfs		= ntfs_statfs,	  /* Syscall: statfs */
+	.remount_fs	= ntfs_remount,	  /* Syscall: mount -o remount. */
+	.clear_inode	= ntfs_clear_big_inode,	/* VFS: Called when an inode is
 						   removed from memory. */
-	//umount_begin:	NULL,		/* Forced umount. */
-	show_options:	ntfs_show_options, /* Show mount options in proc. */
+	//.umount_begin	= NULL,		     /* Forced umount. */
+	.show_options	= ntfs_show_options, /* Show mount options in proc. */
 };
 
 /**
@@ -1562,7 +1575,7 @@
 		ntfs_error(sb, "Busy inodes left. This is most likely a NTFS "
 				"driver bug.");
 		/* Copied from fs/super.c. I just love this message. (-; */
-		printk("VFS: Busy inodes after umount. Self-destruct in 5 "
+		printk("NTFS: Busy inodes after umount. Self-destruct in 5 "
 				"seconds.  Have a nice day...\n");
 	}
 	/* Errors at this stage are irrelevant. */
@@ -1618,11 +1631,11 @@
 }
 
 static struct file_system_type ntfs_fs_type = {
-	owner:		THIS_MODULE,
-	name:		"ntfs",
-	get_sb:		ntfs_get_sb,
-	kill_sb:	kill_block_super,
-	fs_flags:	FS_REQUIRES_DEV,
+	.owner		= THIS_MODULE,
+	.name		= "ntfs",
+	.get_sb		= ntfs_get_sb,
+	.kill_sb	= kill_block_super,
+	.fs_flags	= FS_REQUIRES_DEV,
 };
 
 /* Stable names for the slab caches. */
diff -Nru a/fs/ntfs/volume.h b/fs/ntfs/volume.h
--- a/fs/ntfs/volume.h	Sat Aug 10 18:42:21 2002
+++ b/fs/ntfs/volume.h	Sat Aug 10 18:42:21 2002
@@ -101,6 +101,7 @@
  * Defined bits for the flags field in the ntfs_volume structure.
  */
 typedef enum {
+	NV_Errors,		/* 1: Volume has errors, prevent remount rw. */
 	NV_ShowSystemFiles,	/* 1: Return system files in ntfs_readdir(). */
 	NV_CaseSensitive,	/* 1: Treat file names as case sensitive and
 				      create filenames in the POSIX namespace.
@@ -127,6 +128,7 @@
 }
 
 /* Emit the ntfs volume bitops functions. */
+NVOL_FNS(Errors)
 NVOL_FNS(ShowSystemFiles)
 NVOL_FNS(CaseSensitive)
 
diff -Nru a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c
--- a/fs/openpromfs/inode.c	Sat Aug 10 18:42:22 2002
+++ b/fs/openpromfs/inode.c	Sat Aug 10 18:42:22 2002
@@ -501,7 +501,6 @@
 int property_release (struct inode *inode, struct file *filp)
 {
 	openprom_property *op = (openprom_property *)filp->private_data;
-	unsigned long flags;
 	int error;
 	u32 node;
 	
@@ -526,19 +525,15 @@
 	} else if (op->flag & OPP_DIRTY) {
 		if (op->flag & OPP_STRING) {
 			op->value [op->len] = 0;
-			save_and_cli (flags);
 			error = prom_setprop (node, op->name,
 					      op->value, op->len + 1);
-			restore_flags (flags);
 			if (error <= 0)
 				printk (KERN_WARNING "openpromfs: "
 					"Couldn't write property %s\n",
 					op->name);
 		} else if ((op->flag & OPP_BINARY) || !op->len) {
-			save_and_cli (flags);
 			error = prom_setprop (node, op->name,
 					      op->value, op->len);
-			restore_flags (flags);
 			if (error <= 0)
 				printk (KERN_WARNING "openpromfs: "
 					"Couldn't write property %s\n",
diff -Nru a/fs/partitions/check.c b/fs/partitions/check.c
--- a/fs/partitions/check.c	Sat Aug 10 18:42:22 2002
+++ b/fs/partitions/check.c	Sat Aug 10 18:42:22 2002
@@ -16,8 +16,8 @@
 #include <linux/init.h>
 #include <linux/fs.h>
 #include <linux/blk.h>
-#include <linux/buffer_head.h>	/* for invalidate_bdev() */
 #include <linux/kmod.h>
+#include <linux/ctype.h>
 
 #include "check.h"
 
@@ -104,10 +104,11 @@
 
 char *disk_name (struct gendisk *hd, int minor, char *buf)
 {
-	const char *maj = hd->major_name;
 	unsigned int unit = (minor >> hd->minor_shift);
 	unsigned int part = (minor & ((1 << hd->minor_shift) -1 ));
 	struct hd_struct *p = hd->part + minor - hd->first_minor;
+	char s[40];
+	const char *maj;
 
 	if ((((minor - hd->first_minor) >> hd->minor_shift) < hd->nr_real) &&
 	     p->de) {
@@ -124,83 +125,45 @@
 		return buf;
 #endif
 	/*
-	 * IDE devices use multiple major numbers, but the drives
-	 * are named as:  {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}..
-	 * This requires special handling here.
+	 * Yes, I know, ... in cases is gccism and not a pretty one.  
+	 * However, the first variant will eventually consume _all_ cases
+	 * and switch will disappear.
 	 */
 	switch (hd->major) {
-		case IDE9_MAJOR:
-			unit += 2;
-		case IDE8_MAJOR:
-			unit += 2;
-		case IDE7_MAJOR:
-			unit += 2;
-		case IDE6_MAJOR:
-			unit += 2;
-		case IDE5_MAJOR:
-			unit += 2;
-		case IDE4_MAJOR:
-			unit += 2;
-		case IDE3_MAJOR:
-			unit += 2;
-		case IDE2_MAJOR:
-			unit += 2;
-		case IDE1_MAJOR:
-			unit += 2;
-		case IDE0_MAJOR:
-			maj = "hd";
+		default:
+			maj = hd->major_name;
 			break;
 		case MD_MAJOR:
-			sprintf(buf, "%s%d", maj, unit);
-			return buf;
-	}
-	if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) {
-		unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16;
-		if (unit+'a' > 'z') {
-			unit -= 26;
-			sprintf(buf, "sd%c%c", 'a' + unit / 26, 'a' + unit % 26);
-			if (part)
-				sprintf(buf + 4, "%d", part);
-			return buf;
-		}
-	}
-	if (hd->major >= COMPAQ_SMART2_MAJOR && hd->major <= COMPAQ_SMART2_MAJOR+7) {
-		int ctlr = hd->major - COMPAQ_SMART2_MAJOR;
- 		if (part == 0)
- 			sprintf(buf, "%s/c%dd%d", maj, ctlr, unit);
- 		else
- 			sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
- 		return buf;
- 	}
-	if (hd->major >= COMPAQ_CISS_MAJOR && hd->major <= COMPAQ_CISS_MAJOR+7) {
-                int ctlr = hd->major - COMPAQ_CISS_MAJOR;
-                if (part == 0)
-                        sprintf(buf, "%s/c%dd%d", maj, ctlr, unit);
-                else
-                        sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
-                return buf;
-	}
-	if (hd->major >= DAC960_MAJOR && hd->major <= DAC960_MAJOR+7) {
-		int ctlr = hd->major - DAC960_MAJOR;
- 		if (part == 0)
- 			sprintf(buf, "%s/c%dd%d", maj, ctlr, unit);
- 		else
- 			sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
- 		return buf;
- 	}
-	if (hd->major == ATARAID_MAJOR) {
-		int disk = minor >> hd->minor_shift;
-		int part = minor & (( 1 << hd->minor_shift) - 1);
-		if (part == 0)
-			sprintf(buf, "%s/d%d", maj, disk);
-		else
-			sprintf(buf, "%s/d%dp%d", maj, disk, part);
-		return buf;
-	}
-	if (part)
-		sprintf(buf, "%s%c%d", maj, unit+'a', part);
+			sprintf(s, "%s%d", "md", unit);
+			maj = s;
+			break;
+		case COMPAQ_CISS_MAJOR ... COMPAQ_CISS_MAJOR+7:
+			sprintf(s, "cciss/c%dd%d",
+				hd->major - COMPAQ_CISS_MAJOR, unit);
+			maj = s;
+			break;
+		case DAC960_MAJOR ... DAC960_MAJOR+7:
+			sprintf(s, "rd/c%dd%d",
+				hd->major - DAC960_MAJOR, unit);
+			maj = s;
+			break;
+		case ATARAID_MAJOR:
+			sprintf(s, "ataraid/d%d", unit);
+			maj = s;
+			break;
+		case ACSI_MAJOR:
+		case XT_DISK_MAJOR:
+		case I2O_MAJOR:
+		case DASD_MAJOR:
+			sprintf(s, "%s%c", hd->major_name, unit + 'a');
+			maj = s;
+	}
+	if (!part)
+		sprintf(buf, "%s", maj);
+	else if (isdigit(maj[strlen(maj)-1]))
+		sprintf(buf, "%sp%d", maj, part);
 	else
-		sprintf(buf, "%s%c", maj, unit+'a');
+		sprintf(buf, "%s%d", maj, part);
 	return buf;
 }
 
@@ -326,10 +289,13 @@
 	return;
 }
 
-static void check_partition(struct gendisk *hd, kdev_t dev)
+/*
+ *	DON'T EXPORT
+ */
+void check_partition(struct gendisk *hd, struct block_device *bdev)
 {
 	devfs_handle_t de = NULL;
-	struct block_device *bdev;
+	kdev_t dev = to_kdev_t(bdev->bd_dev);
 	char buf[64];
 	struct parsed_partitions *state;
 	int i;
@@ -351,9 +317,6 @@
 		if (n - COMPAQ_SMART2_MAJOR <= 7 || n - COMPAQ_CISS_MAJOR <= 7)
 			sprintf(state->name, "p");
 	}
-	bdev = bdget(kdev_t_to_nr(dev));
-	if (blkdev_get(bdev, FMODE_READ, 0, BDEV_RAW))
-		goto out;
 	state->limit = 1<<hd->minor_shift;
 	for (i = 0; check_part[i]; i++) {
 		int res, j;
@@ -365,7 +328,7 @@
 		if (res < 0) {
 			if (warn_no_part)
 				printk(" unable to read partition table\n");
-			goto setup_devfs;
+			goto out;
 		} 
 		p = hd->part + minor(dev) - hd->first_minor;
 		for (j = 1; j < state->limit; j++) {
@@ -377,12 +340,10 @@
 			md_autodetect_dev(mk_kdev(major(dev),minor(dev)+j));
 #endif
 		}
-		goto setup_devfs;
+		goto out;
 	}
 
 	printk(" unknown partition table\n");
-setup_devfs:
-	blkdev_put(bdev, BDEV_RAW);
 out:
 	driverfs_create_partitions(hd, minor(dev));
 	devfs_register_partitions (hd, minor(dev), 0);
@@ -467,7 +428,7 @@
 	for (part = 1; part < max_p; part++) {
 		if ( unregister || (p[part].nr_sects < 1) ) {
 			devfs_unregister(p[part].de);
-			dev->part[p].de = NULL;
+			p[part].de = NULL;
 			continue;
 		}
 		devfs_register_partition (dev, minor, part);
@@ -500,34 +461,29 @@
 
 void grok_partitions(kdev_t dev, long size)
 {
-	int minors, first_minor, end_minor;
+	struct block_device *bdev;
 	struct gendisk *g = get_gendisk(dev);
 	struct hd_struct *p;
 
 	if (!g)
 		return;
 
-	minors = 1 << g->minor_shift;
-	first_minor = minor(dev);
-	if (first_minor & (minors-1)) {
-		printk("grok_partitions: bad device 0x%02x:%02x\n",
-		       major(dev), first_minor);
-		first_minor &= ~(minors-1);
-	}
-	end_minor = first_minor + minors;
- 
-	p = g->part + first_minor - g->first_minor;
+	p = g->part + minor(dev) - g->first_minor;
 	p[0].nr_sects = size;
 
 	/* No minors to use for partitions */
-	if (minors == 1)
+	if (!g->minor_shift)
 		return;
 
 	/* No such device (e.g., media were just removed) */
 	if (!size)
 		return;
 
-	check_partition(g, mk_kdev(g->major, first_minor));
+	bdev = bdget(kdev_t_to_nr(dev));
+	if (blkdev_get(bdev, FMODE_READ, 0, BDEV_RAW) < 0)
+		return;
+	check_partition(g, bdev);
+	blkdev_put(bdev, BDEV_RAW);
 }
 
 unsigned char *read_dev_sector(struct block_device *bdev, unsigned long n, Sector *p)
diff -Nru a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
--- a/fs/proc/proc_misc.c	Sat Aug 10 18:42:21 2002
+++ b/fs/proc/proc_misc.c	Sat Aug 10 18:42:21 2002
@@ -430,13 +430,6 @@
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
-static int dma_read_proc(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	int len = get_dma_list(page);
-	return proc_calc_metrics(page, start, off, count, eof, len);
-}
-
 static int ioports_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
@@ -589,7 +582,6 @@
 		{"stat",	kstat_read_proc},
 		{"devices",	devices_read_proc},
 		{"filesystems",	filesystems_read_proc},
-		{"dma",		dma_read_proc},
 		{"ioports",	ioports_read_proc},
 		{"cmdline",	cmdline_read_proc},
 #ifdef CONFIG_SGI_DS1286
diff -Nru a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
--- a/fs/reiserfs/bitmap.c	Sat Aug 10 18:42:23 2002
+++ b/fs/reiserfs/bitmap.c	Sat Aug 10 18:42:23 2002
@@ -689,7 +689,7 @@
   struct reiserfs_inode_info *ei = REISERFS_I(inode);
 #ifdef CONFIG_REISERFS_CHECK
   if (ei->i_prealloc_count < 0)
-     reiserfs_warning("zam-4001:" __FUNCTION__ ": inode has negative prealloc blocks count.\n");
+     reiserfs_warning("zam-4001:%s inode has negative prealloc blocks count.\n", __FUNCTION__);
 #endif  
     if (ei->i_prealloc_count > 0) {
     __discard_prealloc(th, ei);
@@ -705,7 +705,7 @@
 	ei = list_entry(plist->next, struct reiserfs_inode_info, i_prealloc_list);
 #ifdef CONFIG_REISERFS_CHECK
 	if (!ei->i_prealloc_count) {
-		reiserfs_warning("zam-4001:" __FUNCTION__ ": inode is in prealloc list but has no preallocated blocks.\n");
+		reiserfs_warning("zam-4001:%s: inode is in prealloc list but has no preallocated blocks.\n", __FUNCTION__);
 	}
 #endif
 	__discard_prealloc(th, ei);
diff -Nru a/fs/reiserfs/file.c b/fs/reiserfs/file.c
--- a/fs/reiserfs/file.c	Sat Aug 10 18:42:20 2002
+++ b/fs/reiserfs/file.c	Sat Aug 10 18:42:20 2002
@@ -141,19 +141,19 @@
 }
 
 struct file_operations reiserfs_file_operations = {
-    read:	generic_file_read,
-    write:	generic_file_write,
-    ioctl:	reiserfs_ioctl,
-    mmap:	generic_file_mmap,
-    release:	reiserfs_file_release,
-    fsync:	reiserfs_sync_file,
-    sendfile:	generic_file_sendfile,
+    .read	= generic_file_read,
+    .write	= generic_file_write,
+    .ioctl	= reiserfs_ioctl,
+    .mmap	= generic_file_mmap,
+    .release	= reiserfs_file_release,
+    .fsync	= reiserfs_sync_file,
+    .sendfile	= generic_file_sendfile,
 };
 
 
 struct  inode_operations reiserfs_file_inode_operations = {
-    truncate:	reiserfs_vfs_truncate_file,
-    setattr:    reiserfs_setattr,
+    .truncate	= reiserfs_vfs_truncate_file,
+    .setattr    = reiserfs_setattr,
 };
 
 
diff -Nru a/fs/reiserfs/item_ops.c b/fs/reiserfs/item_ops.c
--- a/fs/reiserfs/item_ops.c	Sat Aug 10 18:42:21 2002
+++ b/fs/reiserfs/item_ops.c	Sat Aug 10 18:42:21 2002
@@ -111,18 +111,18 @@
 }
 
 struct item_operations stat_data_ops = {
-	bytes_number:		sd_bytes_number,
-	decrement_key:		sd_decrement_key,
-	is_left_mergeable:	sd_is_left_mergeable,
-	print_item:		sd_print_item,
-	check_item:		sd_check_item,
-
-	create_vi:		sd_create_vi,
-	check_left:		sd_check_left,
-	check_right:		sd_check_right,
-	part_size:		sd_part_size,
-	unit_num:		sd_unit_num,
-	print_vi:		sd_print_vi
+	.bytes_number		= sd_bytes_number,
+	.decrement_key		= sd_decrement_key,
+	.is_left_mergeable	= sd_is_left_mergeable,
+	.print_item		= sd_print_item,
+	.check_item		= sd_check_item,
+
+	.create_vi		= sd_create_vi,
+	.check_left		= sd_check_left,
+	.check_right		= sd_check_right,
+	.part_size		= sd_part_size,
+	.unit_num		= sd_unit_num,
+	.print_vi		= sd_print_vi
 };
 
 
@@ -214,18 +214,18 @@
 }
 
 struct item_operations direct_ops = {
-	bytes_number:		direct_bytes_number,
-	decrement_key:		direct_decrement_key,
-	is_left_mergeable:	direct_is_left_mergeable,
-	print_item:		direct_print_item,
-	check_item:		direct_check_item,
-
-	create_vi:		direct_create_vi,
-	check_left:		direct_check_left,
-	check_right:		direct_check_right,
-	part_size:		direct_part_size,
-	unit_num:		direct_unit_num,
-	print_vi:		direct_print_vi
+	.bytes_number		= direct_bytes_number,
+	.decrement_key		= direct_decrement_key,
+	.is_left_mergeable	= direct_is_left_mergeable,
+	.print_item		= direct_print_item,
+	.check_item		= direct_check_item,
+
+	.create_vi		= direct_create_vi,
+	.check_left		= direct_check_left,
+	.check_right		= direct_check_right,
+	.part_size		= direct_part_size,
+	.unit_num		= direct_unit_num,
+	.print_vi		= direct_print_vi
 };
 
 
@@ -368,18 +368,18 @@
 }
 
 struct item_operations indirect_ops = {
-	bytes_number:		indirect_bytes_number,
-	decrement_key:		indirect_decrement_key,
-	is_left_mergeable:	indirect_is_left_mergeable,
-	print_item:		indirect_print_item,
-	check_item:		indirect_check_item,
-
-	create_vi:		indirect_create_vi,
-	check_left:		indirect_check_left,
-	check_right:		indirect_check_right,
-	part_size:		indirect_part_size,
-	unit_num:		indirect_unit_num,
-	print_vi:		indirect_print_vi
+	.bytes_number		= indirect_bytes_number,
+	.decrement_key		= indirect_decrement_key,
+	.is_left_mergeable	= indirect_is_left_mergeable,
+	.print_item		= indirect_print_item,
+	.check_item		= indirect_check_item,
+
+	.create_vi		= indirect_create_vi,
+	.check_left		= indirect_check_left,
+	.check_right		= indirect_check_right,
+	.part_size		= indirect_part_size,
+	.unit_num		= indirect_unit_num,
+	.print_vi		= indirect_print_vi
 };
 
 
@@ -662,18 +662,18 @@
 }
 
 struct item_operations direntry_ops = {
-	bytes_number:		direntry_bytes_number,
-	decrement_key:		direntry_decrement_key,
-	is_left_mergeable:	direntry_is_left_mergeable,
-	print_item:		direntry_print_item,
-	check_item:		direntry_check_item,
-
-	create_vi:		direntry_create_vi,
-	check_left:		direntry_check_left,
-	check_right:		direntry_check_right,
-	part_size:		direntry_part_size,
-	unit_num:		direntry_unit_num,
-	print_vi:		direntry_print_vi
+	.bytes_number		= direntry_bytes_number,
+	.decrement_key		= direntry_decrement_key,
+	.is_left_mergeable	= direntry_is_left_mergeable,
+	.print_item		= direntry_print_item,
+	.check_item		= direntry_check_item,
+
+	.create_vi		= direntry_create_vi,
+	.check_left		= direntry_check_left,
+	.check_right		= direntry_check_right,
+	.part_size		= direntry_part_size,
+	.unit_num		= direntry_unit_num,
+	.print_vi		= direntry_print_vi
 };
 
 
diff -Nru a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
--- a/fs/reiserfs/namei.c	Sat Aug 10 18:42:20 2002
+++ b/fs/reiserfs/namei.c	Sat Aug 10 18:42:20 2002
@@ -296,7 +296,7 @@
     while (1) {
 	retval = search_by_entry_key (dir->i_sb, &key_to_search, path_to_entry, de);
 	if (retval == IO_ERROR) {
-	    reiserfs_warning ("zam-7001: io error in " __FUNCTION__ "\n");
+	    reiserfs_warning ("zam-7001: io error in %s\n", __FUNCTION__);
 	    return IO_ERROR;
 	}
 
@@ -468,8 +468,8 @@
 	}
 
         if (retval != NAME_FOUND) {
-	    reiserfs_warning ("zam-7002:" __FUNCTION__ ": \"reiserfs_find_entry\" has returned"
-                              " unexpected value (%d)\n", retval);
+	    reiserfs_warning ("zam-7002:%s: \"reiserfs_find_entry\" has returned"
+                              " unexpected value (%d)\n", __FUNCTION__, retval);
        }
 
 	return -EEXIST;
diff -Nru a/fs/reiserfs/super.c b/fs/reiserfs/super.c
--- a/fs/reiserfs/super.c	Sat Aug 10 18:42:22 2002
+++ b/fs/reiserfs/super.c	Sat Aug 10 18:42:22 2002
@@ -1313,11 +1313,11 @@
 }
 
 static struct file_system_type reiserfs_fs_type = {
-	owner: THIS_MODULE,
-	name: "reiserfs",
-	get_sb: get_super_block,
-	kill_sb: kill_block_super,
-	fs_flags: FS_REQUIRES_DEV,
+	.owner		= THIS_MODULE,
+	.name		= "reiserfs",
+	.get_sb		= get_super_block,
+	.kill_sb	= kill_block_super,
+	.fs_flags	= FS_REQUIRES_DEV,
 };
 
 MODULE_DESCRIPTION ("ReiserFS journaled filesystem");
diff -Nru a/fs/seq_file.c b/fs/seq_file.c
--- a/fs/seq_file.c	Sat Aug 10 18:42:23 2002
+++ b/fs/seq_file.c	Sat Aug 10 18:42:23 2002
@@ -94,8 +94,10 @@
 		m->buf = kmalloc(m->size <<= 1, GFP_KERNEL);
 		if (!m->buf)
 			goto Enomem;
+		m->count = 0;
 	}
 	m->op->stop(m, p);
+	m->count = 0;
 	goto Done;
 Fill:
 	/* they want more? let's try to get some more */
diff -Nru a/fs/super.c b/fs/super.c
--- a/fs/super.c	Sat Aug 10 18:42:22 2002
+++ b/fs/super.c	Sat Aug 10 18:42:22 2002
@@ -502,7 +502,6 @@
 	devfs_put_ops (de);   /*  Decrement module use count now we're safe  */
 	if (error)
 		goto out;
-	check_disk_change(dev);
 	error = -EACCES;
 	if (!(flags & MS_RDONLY) && bdev_read_only(bdev))
 		goto out1;
diff -Nru a/include/asm-alpha/a.out.h b/include/asm-alpha/a.out.h
--- a/include/asm-alpha/a.out.h	Sat Aug 10 18:42:21 2002
+++ b/include/asm-alpha/a.out.h	Sat Aug 10 18:42:21 2002
@@ -95,8 +95,8 @@
    Worse, we have to notice the start address before swapping to use
    /sbin/loader, which of course is _not_ a TASO application.  */
 #define SET_AOUT_PERSONALITY(BFPM, EX) \
-	set_personality (BFPM->sh_bang || EX.ah.entry < 0x100000000 \
-			 ? PER_LINUX_32BIT : PER_LINUX)
+	set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000 \
+			   ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
 
 #define STACK_TOP \
   (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
diff -Nru a/include/asm-alpha/bitops.h b/include/asm-alpha/bitops.h
--- a/include/asm-alpha/bitops.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-alpha/bitops.h	Sat Aug 10 18:42:23 2002
@@ -315,6 +315,20 @@
 	return word ? result+1 : 0;
 }
 
+/*
+ * fls: find last bit set.
+ */
+#if defined(__alpha_cix__) && defined(__alpha_fix__)
+static inline int fls(int word)
+{
+	long result;
+	__asm__("ctlz %1,%0" : "=r"(result) : "r"(word & 0xffffffff));
+	return 64 - result;
+}
+#else
+#define fls	generic_fls
+#endif
+
 /* Compute powers of two for the given integer.  */
 static inline int floor_log2(unsigned long word)
 {
diff -Nru a/include/asm-alpha/hardirq.h b/include/asm-alpha/hardirq.h
--- a/include/asm-alpha/hardirq.h	Sat Aug 10 18:42:21 2002
+++ b/include/asm-alpha/hardirq.h	Sat Aug 10 18:42:21 2002
@@ -7,91 +7,91 @@
 /* entry.S is sensitive to the offsets of these fields */
 typedef struct {
 	unsigned long __softirq_pending;
-	unsigned int __local_irq_count;
-	unsigned int __local_bh_count;
 	unsigned int __syscall_count;
+	unsigned long idle_timestamp;
 	struct task_struct * __ksoftirqd_task;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
 
 /*
- * Are we in an interrupt context? Either doing bottom half
- * or hardware interrupt processing?
+ * We put the hardirq and softirq counter into the preemption
+ * counter. The bitmask has the following meaning:
+ *
+ * - bits 0-7 are the preemption count (max preemption depth: 256)
+ * - bits 8-15 are the softirq count (max # of softirqs: 256)
+ * - bits 16-27 are the hardirq count (max # of hardirqs: 4096)
+ *
+ * - ( bit 30 is the PREEMPT_ACTIVE flag. )
+ *
+ * PREEMPT_MASK: 0x000000ff
+ * SOFTIRQ_MASK: 0x0000ff00
+ * HARDIRQ_MASK: 0x0fff0000
  */
 
-#define in_interrupt()						\
-({								\
-	int __cpu = smp_processor_id();				\
-	(local_irq_count(__cpu) + local_bh_count(__cpu)) != 0;	\
-})
+#define PREEMPT_BITS	8
+#define SOFTIRQ_BITS	8
+#define HARDIRQ_BITS	12
+
+#define PREEMPT_SHIFT	0
+#define SOFTIRQ_SHIFT	(PREEMPT_SHIFT + PREEMPT_BITS)
+#define HARDIRQ_SHIFT	(SOFTIRQ_SHIFT + SOFTIRQ_BITS)
+
+#define __MASK(x)	((1UL << (x))-1)
+
+#define PREEMPT_MASK	(__MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
+#define HARDIRQ_MASK	(__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
+#define SOFTIRQ_MASK	(__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
+
+#define hardirq_count()	(preempt_count() & HARDIRQ_MASK)
+#define softirq_count()	(preempt_count() & SOFTIRQ_MASK)
+#define irq_count()	(preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
+
+#define PREEMPT_OFFSET	(1UL << PREEMPT_SHIFT)
+#define SOFTIRQ_OFFSET	(1UL << SOFTIRQ_SHIFT)
+#define HARDIRQ_OFFSET	(1UL << HARDIRQ_SHIFT)
 
-#define in_irq() (local_irq_count(smp_processor_id()) != 0)
-
-#ifndef CONFIG_SMP
+/*
+ * The hardirq mask has to be large enough to have
+ * space for potentially all IRQ sources in the system
+ * nesting on a single CPU:
+ */
+#if (1 << HARDIRQ_BITS) < NR_IRQS
+#error HARDIRQ_BITS is too low!
+#endif
 
-extern unsigned long __irq_attempt[];
-#define irq_attempt(cpu, irq)  ((void)(cpu), __irq_attempt[irq])
+/*
+ * Are we doing bottom half or hardware interrupt processing?
+ * Are we in a softirq context? Interrupt context?
+ */
+#define in_irq()		(hardirq_count())
+#define in_softirq()		(softirq_count())
+#define in_interrupt()		(irq_count())
 
-#define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
-#define hardirq_endlock(cpu)	((void) 0)
 
-#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
-#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
+#define hardirq_trylock()	(!in_interrupt())
+#define hardirq_endlock()	do { } while (0)
 
-#define synchronize_irq()	barrier()
+#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
 
+#if CONFIG_PREEMPT
+# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
 #else
+#define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
+# endif
+#define irq_exit()						\
+do {								\
+		preempt_count() -= IRQ_EXIT_OFFSET;		\
+		if (!in_interrupt() &&				\
+		    softirq_pending(smp_processor_id()))	\
+			do_softirq();				\
+		preempt_enable_no_resched();			\
+} while (0)
 
-#define irq_attempt(cpu, irq) (cpu_data[cpu].irq_attempt[irq])
-
-#include <asm/atomic.h>
-#include <linux/spinlock.h>
-#include <asm/smp.h>
-
-extern int global_irq_holder;
-extern spinlock_t global_irq_lock;
-
-static inline int irqs_running (void)
-{
-	int i;
-
-	for (i = 0; i < smp_num_cpus; i++)
-		if (local_irq_count(i))
-			return 1;
-	return 0;
-}
-
-static inline void release_irqlock(int cpu)
-{
-	/* if we didn't own the irq lock, just ignore.. */
-	if (global_irq_holder == cpu) {
-		global_irq_holder = NO_PROC_ID;
-		spin_unlock(&global_irq_lock);
-        }
-}
-
-static inline void irq_enter(int cpu, int irq)
-{
-	++local_irq_count(cpu);
-
-	while (spin_is_locked(&global_irq_lock))
-		barrier();
-}
-
-static inline void irq_exit(int cpu, int irq)
-{
-        --local_irq_count(cpu);
-}
-
-static inline int hardirq_trylock(int cpu)
-{
-	return !local_irq_count(cpu) && !spin_is_locked(&global_irq_lock);
-}
-
-#define hardirq_endlock(cpu)	do { } while (0)
-
-extern void synchronize_irq(void);
-
+#ifndef CONFIG_SMP
+# define synchronize_irq(irq)	barrier()
+#else
+  extern void synchronize_irq(unsigned int irq);
 #endif /* CONFIG_SMP */
+
 #endif /* _ALPHA_HARDIRQ_H */
diff -Nru a/include/asm-alpha/linkage.h b/include/asm-alpha/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-alpha/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/asm-alpha/mmu_context.h b/include/asm-alpha/mmu_context.h
--- a/include/asm-alpha/mmu_context.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-alpha/mmu_context.h	Sat Aug 10 18:42:23 2002
@@ -227,8 +227,9 @@
 {
 	int i;
 
-	for (i = 0; i < smp_num_cpus; i++)
-		mm->context[cpu_logical_map(i)] = 0;
+	for (i = 0; i < NR_CPUS; i++)
+		if (cpu_online(i))
+			mm->context[i] = 0;
         tsk->thread_info->pcb.ptbr
 	  = ((unsigned long)mm->pgd - IDENT_ADDR) >> PAGE_SHIFT;
 	return 0;
diff -Nru a/include/asm-alpha/page.h b/include/asm-alpha/page.h
--- a/include/asm-alpha/page.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-alpha/page.h	Sat Aug 10 18:42:23 2002
@@ -15,10 +15,10 @@
 #define STRICT_MM_TYPECHECKS
 
 extern void clear_page(void *page);
-#define clear_user_page(page, vaddr)	clear_page(page)
+#define clear_user_page(page, vaddr, pg)	clear_page(page)
 
 extern void copy_page(void * _to, void * _from);
-#define copy_user_page(to, from, vaddr)	copy_page(to, from)
+#define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)
 
 #ifdef STRICT_MM_TYPECHECKS
 /*
@@ -95,8 +95,12 @@
 #define __pa(x)			((unsigned long) (x) - PAGE_OFFSET)
 #define __va(x)			((void *)((unsigned long) (x) + PAGE_OFFSET))
 #ifndef CONFIG_DISCONTIGMEM
-#define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
-#define VALID_PAGE(page)	(((page) - mem_map) < max_mapnr)
+#define pfn_to_page(pfn)	(mem_map + (pfn))
+#define page_to_pfn(page)	((unsigned long)((page) - mem_map))
+#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
+
+#define pfn_valid(pfn)		((pfn) < max_mapnr)
+#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 #endif /* CONFIG_DISCONTIGMEM */
 
 #define VM_DATA_DEFAULT_FLAGS		(VM_READ | VM_WRITE | VM_EXEC | \
diff -Nru a/include/asm-alpha/param.h b/include/asm-alpha/param.h
--- a/include/asm-alpha/param.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-alpha/param.h	Sat Aug 10 18:42:22 2002
@@ -15,6 +15,8 @@
 # endif
 #endif
 
+#define USER_HZ		HZ
+
 #define EXEC_PAGESIZE	8192
 
 #ifndef NGROUPS
diff -Nru a/include/asm-alpha/percpu.h b/include/asm-alpha/percpu.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-alpha/percpu.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ALPHA_PERCPU_H
+#define __ALPHA_PERCPU_H
+
+#include <asm-generic/percpu.h>
+
+#endif /* __ALPHA_PERCPU_H */
diff -Nru a/include/asm-alpha/pgalloc.h b/include/asm-alpha/pgalloc.h
--- a/include/asm-alpha/pgalloc.h	Sat Aug 10 18:42:20 2002
+++ b/include/asm-alpha/pgalloc.h	Sat Aug 10 18:42:20 2002
@@ -2,6 +2,7 @@
 #define _ALPHA_PGALLOC_H
 
 #include <linux/config.h>
+#include <linux/mm.h>
 
 /*      
  * Allocate and free page tables. The xxx_kernel() versions are
diff -Nru a/include/asm-alpha/pgtable.h b/include/asm-alpha/pgtable.h
--- a/include/asm-alpha/pgtable.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-alpha/pgtable.h	Sat Aug 10 18:42:22 2002
@@ -179,11 +179,12 @@
 #endif
 #if defined(CONFIG_ALPHA_GENERIC) || \
     (defined(CONFIG_ALPHA_EV6) && !defined(USE_48_BIT_KSEG))
-#define PHYS_TWIDDLE(phys) \
-  ((((phys) & 0xc0000000000UL) == 0x40000000000UL) \
-  ? ((phys) ^= 0xc0000000000UL) : (phys))
+#define KSEG_PFN	(0xc0000000000UL >> PAGE_SHIFT)
+#define PHYS_TWIDDLE(pfn) \
+  ((((pfn) & KSEG_PFN) == (0x40000000000UL >> PAGE_SHIFT)) \
+  ? ((pfn) ^= KSEG_PFN) : (pfn))
 #else
-#define PHYS_TWIDDLE(phys) (phys)
+#define PHYS_TWIDDLE(pfn) (pfn)
 #endif
 
 /*
@@ -199,12 +200,13 @@
 #endif
 
 #ifndef CONFIG_DISCONTIGMEM
+#define pte_pfn(pte)	(pte_val(pte) >> 32)
+#define pte_page(pte)	pfn_to_page(pte_pfn(pte))
 #define mk_pte(page, pgprot)						\
 ({									\
 	pte_t pte;							\
 									\
-	pte_val(pte) = ((unsigned long)(page - mem_map) << 32) |	\
-		       pgprot_val(pgprot);				\
+	pte_val(pte) = (page_to_pfn(page) << 32) | pgprot_val(pgprot);	\
 	pte;								\
 })
 #else
@@ -219,10 +221,20 @@
 										\
 	pte;									\
 })
+#define pte_page(x)							\
+({									\
+	unsigned long kvirt;						\
+	struct page * __xx;						\
+									\
+	kvirt = (unsigned long)__va(pte_val(x) >> (32-PAGE_SHIFT));	\
+	__xx = virt_to_page(kvirt);					\
+									\
+	__xx;								\
+})
 #endif
 
-extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
-{ pte_t pte; pte_val(pte) = (PHYS_TWIDDLE(physpage) << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; }
+extern inline pte_t pfn_pte(unsigned long physpfn, pgprot_t pgprot)
+{ pte_t pte; pte_val(pte) = (PHYS_TWIDDLE(physpfn) << 32) | pgprot_val(pgprot); return pte; }
 
 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
 { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
@@ -233,20 +245,6 @@
 extern inline void pgd_set(pgd_t * pgdp, pmd_t * pmdp)
 { pgd_val(*pgdp) = _PAGE_TABLE | ((((unsigned long) pmdp) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
 
-#ifndef CONFIG_DISCONTIGMEM
-#define pte_page(x)	(mem_map+(unsigned long)((pte_val(x) >> 32)))
-#else
-#define pte_page(x)							\
-({									\
-	unsigned long kvirt;						\
-	struct page * __xx;						\
-									\
-	kvirt = (unsigned long)__va(pte_val(x) >> (32-PAGE_SHIFT));	\
-	__xx = virt_to_page(kvirt);					\
-									\
-	__xx;								\
-})
-#endif
 
 extern inline unsigned long
 pmd_page_kernel(pmd_t pmd)
diff -Nru a/include/asm-alpha/regdef.h b/include/asm-alpha/regdef.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-alpha/regdef.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,44 @@
+#ifndef __alpha_regdef_h__
+#define __alpha_regdef_h__
+
+#define v0	$0	/* function return value */
+
+#define t0	$1	/* temporary registers (caller-saved) */
+#define t1	$2
+#define t2	$3
+#define t3	$4
+#define t4	$5
+#define t5	$6
+#define t6	$7
+#define t7	$8
+
+#define	s0	$9	/* saved-registers (callee-saved registers) */
+#define	s1	$10
+#define	s2	$11
+#define	s3	$12
+#define	s4	$13
+#define	s5	$14
+#define	s6	$15
+#define	fp	s6	/* frame-pointer (s6 in frame-less procedures) */
+
+#define a0	$16	/* argument registers (caller-saved) */
+#define a1	$17
+#define a2	$18
+#define a3	$19
+#define a4	$20
+#define a5	$21
+
+#define t8	$22	/* more temps (caller-saved) */
+#define t9	$23
+#define t10	$24
+#define t11	$25
+#define ra	$26	/* return address register */
+#define t12	$27
+
+#define pv	t12	/* procedure-variable register */
+#define AT	$at	/* assembler temporary */
+#define gp	$29	/* global pointer */
+#define sp	$30	/* stack pointer */
+#define zero	$31	/* reads as zero, writes are noops */
+
+#endif /* __alpha_regdef_h__ */
diff -Nru a/include/asm-alpha/rwsem.h b/include/asm-alpha/rwsem.h
--- a/include/asm-alpha/rwsem.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-alpha/rwsem.h	Sat Aug 10 18:42:23 2002
@@ -21,6 +21,7 @@
 extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
 extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
 extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *);
+extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
 
 /*
  * the semaphore definition
@@ -83,10 +84,26 @@
 	:"=&r" (oldcount), "=m" (sem->count), "=&r" (temp)
 	:"Ir" (RWSEM_ACTIVE_READ_BIAS), "m" (sem->count) : "memory");
 #endif
-	if (__builtin_expect(oldcount < 0, 0))
+	if (unlikely(oldcount < 0))
 		rwsem_down_read_failed(sem);
 }
 
+/*
+ * trylock for reading -- returns 1 if successful, 0 if contention
+ */
+static inline int __down_read_trylock(struct rw_semaphore *sem)
+{
+	long res, tmp;
+
+	res = sem->count;
+	do {
+		tmp = res + RWSEM_ACTIVE_READ_BIAS;
+		if (tmp <= 0)
+			break;
+	} while (cmpxchg(&sem->count, res, tmp) != res);
+	return res >= 0 ? 1 : 0;
+}
+
 static inline void __down_write(struct rw_semaphore *sem)
 {
 	long oldcount;
@@ -107,10 +124,22 @@
 	:"=&r" (oldcount), "=m" (sem->count), "=&r" (temp)
 	:"Ir" (RWSEM_ACTIVE_WRITE_BIAS), "m" (sem->count) : "memory");
 #endif
-	if (__builtin_expect(oldcount, 0))
+	if (unlikely(oldcount))
 		rwsem_down_write_failed(sem);
 }
 
+/*
+ * trylock for writing -- returns 1 if successful, 0 if contention
+ */
+static inline int __down_write_trylock(struct rw_semaphore *sem)
+{
+	long ret = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
+			   RWSEM_ACTIVE_WRITE_BIAS);
+	if (ret == RWSEM_UNLOCKED_VALUE)
+		return 1;
+	return 0;
+}
+
 static inline void __up_read(struct rw_semaphore *sem)
 {
 	long oldcount;
@@ -131,7 +160,7 @@
 	:"=&r" (oldcount), "=m" (sem->count), "=&r" (temp)
 	:"Ir" (RWSEM_ACTIVE_READ_BIAS), "m" (sem->count) : "memory");
 #endif
-	if (__builtin_expect(oldcount < 0, 0)) 
+	if (unlikely(oldcount < 0))
 		if ((int)oldcount - RWSEM_ACTIVE_READ_BIAS == 0)
 			rwsem_wake(sem);
 }
@@ -157,9 +186,36 @@
 	:"=&r" (count), "=m" (sem->count), "=&r" (temp)
 	:"Ir" (RWSEM_ACTIVE_WRITE_BIAS), "m" (sem->count) : "memory");
 #endif
-	if (__builtin_expect(count, 0))
+	if (unlikely(count))
 		if ((int)count == 0)
 			rwsem_wake(sem);
+}
+
+/*
+ * downgrade write lock to read lock
+ */
+static inline void __downgrade_write(struct rw_semaphore *sem)
+{
+	long oldcount;
+#ifndef	CONFIG_SMP
+	oldcount = sem->count;
+	sem->count -= RWSEM_WAITING_BIAS;
+#else
+	long temp;
+	__asm__ __volatile__(
+	"1:	ldq_l	%0,%1\n"
+	"	addq	%0,%3,%2\n"
+	"	stq_c	%2,%1\n"
+	"	beq	%2,2f\n"
+	"	mb\n"
+	".subsection 2\n"
+	"2:	br	1b\n"
+	".previous"
+	:"=&r" (oldcount), "=m" (sem->count), "=&r" (temp)
+	:"Ir" (-RWSEM_WAITING_BIAS), "m" (sem->count) : "memory");
+#endif
+	if (unlikely(oldcount < 0))
+		rwsem_downgrade_wake(sem);
 }
 
 static inline void rwsem_atomic_add(long val, struct rw_semaphore *sem)
diff -Nru a/include/asm-alpha/smp.h b/include/asm-alpha/smp.h
--- a/include/asm-alpha/smp.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-alpha/smp.h	Sat Aug 10 18:42:22 2002
@@ -30,7 +30,6 @@
 	int need_new_asn;
 	int asn_lock;
 	unsigned long ipi_count;
-	unsigned long irq_attempt[NR_IRQS];
 	unsigned long prof_multiplier;
 	unsigned long prof_counter;
 	unsigned char mcheck_expected;
@@ -42,20 +41,16 @@
 
 #define PROC_CHANGE_PENALTY     20
 
-/* Map from cpu id to sequential logical cpu number.  This will only
-   not be idempotent when cpus failed to come on-line.  */
-extern int __cpu_number_map[NR_CPUS];
-#define cpu_number_map(cpu)  __cpu_number_map[cpu]
-
-/* The reverse map from sequential logical cpu number to cpu id.  */
-extern int __cpu_logical_map[NR_CPUS];
-#define cpu_logical_map(cpu)  __cpu_logical_map[cpu]
-
 #define hard_smp_processor_id()	__hard_smp_processor_id()
 #define smp_processor_id()	(current_thread_info()->cpu)
 
 extern unsigned long cpu_present_mask;
-#define cpu_online_map cpu_present_mask
+extern int smp_num_cpus;
+
+#define cpu_online_map		cpu_present_mask
+#define num_online_cpus()	(smp_num_cpus)
+#define cpu_online(cpu)		(cpu_present_mask & (1<<(cpu)))
+#define cpu_possible(cpu)	cpu_online(cpu)
 
 extern int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, unsigned long cpu);
 
diff -Nru a/include/asm-alpha/smplock.h b/include/asm-alpha/smplock.h
--- a/include/asm-alpha/smplock.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-alpha/smplock.h	Sat Aug 10 18:42:22 2002
@@ -15,12 +15,10 @@
 /*
  * Release global kernel lock and global interrupt lock
  */
-static __inline__ void release_kernel_lock(struct task_struct *task, int cpu)
+static __inline__ void release_kernel_lock(struct task_struct *task)
 {
-	if (task->lock_depth >= 0)
+	if (unlikely(task->lock_depth >= 0))
 		spin_unlock(&kernel_flag);
-	release_irqlock(cpu);
-	local_irq_enable();
 }
 
 /*
@@ -28,7 +26,7 @@
  */
 static __inline__ void reacquire_kernel_lock(struct task_struct *task)
 {
-	if (task->lock_depth >= 0)
+	if (unlikely(task->lock_depth >= 0))
 		spin_lock(&kernel_flag);
 }
 
@@ -41,8 +39,14 @@
  */
 static __inline__ void lock_kernel(void)
 {
+#ifdef CONFIG_PREEMPT
+	if (current->lock_depth == -1)
+		spin_lock(&kernel_flag);
+	++current->lock_depth;
+#else
 	if (!++current->lock_depth)
 		spin_lock(&kernel_flag);
+#endif
 }
 
 static __inline__ void unlock_kernel(void)
diff -Nru a/include/asm-alpha/softirq.h b/include/asm-alpha/softirq.h
--- a/include/asm-alpha/softirq.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-alpha/softirq.h	Sat Aug 10 18:42:22 2002
@@ -1,35 +1,21 @@
 #ifndef _ALPHA_SOFTIRQ_H
 #define _ALPHA_SOFTIRQ_H
 
-#include <linux/stddef.h>
-#include <asm/atomic.h>
+#include <linux/preempt.h>
 #include <asm/hardirq.h>
 
-extern inline void cpu_bh_disable(int cpu)
-{
-	local_bh_count(cpu)++;
-	barrier();
-}
-
-extern inline void __cpu_bh_enable(int cpu)
-{
-	barrier();
-	local_bh_count(cpu)--;
-}
-
-#define __local_bh_enable()	__cpu_bh_enable(smp_processor_id())
-#define local_bh_disable()	cpu_bh_disable(smp_processor_id())
+#define local_bh_disable() \
+		do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0)
+#define __local_bh_enable() \
+		do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0)
 
 #define local_bh_enable()					\
 do {								\
-	int cpu;						\
-								\
-	barrier();						\
-	cpu = smp_processor_id();				\
-	if (!--local_bh_count(cpu) && softirq_pending(cpu))	\
+	__local_bh_enable();					\
+	if (unlikely(!in_interrupt() &&				\
+		     softirq_pending(smp_processor_id())))	\
 		do_softirq();					\
+	preempt_check_resched();				\
 } while (0)
-
-#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
 #endif /* _ALPHA_SOFTIRQ_H */
diff -Nru a/include/asm-alpha/system.h b/include/asm-alpha/system.h
--- a/include/asm-alpha/system.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-alpha/system.h	Sat Aug 10 18:42:23 2002
@@ -130,8 +130,10 @@
 extern void halt(void) __attribute__((noreturn));
 #define __halt() __asm__ __volatile__ ("call_pal %0 #halt" : : "i" (PAL_halt))
 
-#define prepare_to_switch()	do { } while(0)
-#define switch_to(prev,next)						  \
+#define prepare_arch_schedule(prev)		do { } while(0)
+#define finish_arch_schedule(prev)		do { } while(0)
+
+#define switch_to(prev,next,last)						  \
 do {									  \
 	alpha_switch_to(virt_to_phys(&(next)->thread_info->pcb), (prev)); \
 	check_mmu_context();						  \
@@ -308,32 +310,6 @@
 #define local_save_flags(flags)	((flags) = rdps())
 #define local_irq_save(flags)	do { (flags) = swpipl(IPL_MAX); barrier(); } while(0)
 #define local_irq_restore(flags)	do { barrier(); setipl(flags); barrier(); } while(0)
-
-#ifdef CONFIG_SMP
-
-extern int global_irq_holder;
-
-#define save_and_cli(flags)     (save_flags(flags), cli())
-
-extern void __global_cli(void);
-extern void __global_sti(void);
-extern unsigned long __global_save_flags(void);
-extern void __global_restore_flags(unsigned long flags);
-
-#define cli()                   __global_cli()
-#define sti()                   __global_sti()
-#define save_flags(flags)	((flags) = __global_save_flags())
-#define restore_flags(flags)    __global_restore_flags(flags)
-
-#else /* CONFIG_SMP */
-
-#define cli()			local_irq_disable()
-#define sti()			local_irq_enable()
-#define save_flags(flags)	local_save_flags(flags)
-#define save_and_cli(flags)	local_irq_save(flags)
-#define restore_flags(flags)	local_irq_restore(flags)
-
-#endif /* CONFIG_SMP */
 
 /*
  * TB routines..
diff -Nru a/include/asm-alpha/thread_info.h b/include/asm-alpha/thread_info.h
--- a/include/asm-alpha/thread_info.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-alpha/thread_info.h	Sat Aug 10 18:42:23 2002
@@ -19,7 +19,7 @@
 
 	struct exec_domain	*exec_domain;	/* execution domain */
 	mm_segment_t		addr_limit;	/* thread address space */
-	int			cpu;		/* current CPU */
+	long			cpu;		/* current CPU */
 	int			preempt_count; /* 0 => preemptable, <0 => BUG */
 
 	int bpt_nsaved;
@@ -54,7 +54,7 @@
 
 #endif /* __ASSEMBLY__ */
 
-#define PREEMPT_ACTIVE		0x4000000
+#define PREEMPT_ACTIVE		0x40000000
 
 /*
  * Thread information flags:
diff -Nru a/include/asm-alpha/tlb.h b/include/asm-alpha/tlb.h
--- a/include/asm-alpha/tlb.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-alpha/tlb.h	Sat Aug 10 18:42:22 2002
@@ -1 +1,15 @@
+#ifndef _ALPHA_TLB_H
+#define _ALPHA_TLB_H
+
+#define tlb_start_vma(tlb, vma)			do { } while (0)
+#define tlb_end_vma(tlb, vma)			do { } while (0)
+#define tlb_remove_tlb_entry(tlb, pte, addr)	do { } while (0)
+
+#define tlb_flush(tlb)				flush_tlb_mm((tlb)->mm)
+
 #include <asm-generic/tlb.h>
+
+#define pte_free_tlb(tlb,pte)			pte_free(pte)
+#define pmd_free_tlb(tlb,pmd)			pmd_free(pmd)
+ 
+#endif
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	Sat Aug 10 18:42:20 2002
+++ b/include/asm-arm/arch-pxa/hardware.h	Sat Aug 10 18:42:20 2002
@@ -27,17 +27,27 @@
 
 
 /*
- * Intel PXA internal I/O mappings
+ * We requires absolute addresses.
  */
+#define PCIO_BASE		0
 
-#define io_p2v(x)	\
-	(((x) < 0x44000000) ? ((x) - 0x40000000 + 0xfc000000) :	\
-	 ((x) < 0x48000000) ? ((x) - 0x44000000 + 0xfe000000) :	\
-	 		      ((x) - 0x48000000 + 0xff000000))
-#define io_v2p( x )	\
-	(((x) < 0xfe000000) ? ((x) - 0xfc000000 + 0x40000000) :	\
-	 ((x) < 0xff000000) ? ((x) - 0xfe000000 + 0x44000000) :	\
-	 		      ((x) - 0xff000000 + 0x48000000))
+/*
+ * Workarounds for at least 2 errata so far require this.
+ * The mapping is set in mach-pxa/generic.c.
+ */
+#define UNCACHED_PHYS_0		0xff000000
+#define UNCACHED_ADDR		UNCACHED_PHYS_0
+
+/*
+ * Intel PXA internal I/O mappings:
+ *
+ * 0x40000000 - 0x41ffffff <--> 0xf8000000 - 0xf9ffffff
+ * 0x44000000 - 0x45ffffff <--> 0xfa000000 - 0xfbffffff
+ * 0x48000000 - 0x49ffffff <--> 0xfc000000 - 0xfdffffff
+ */
+
+#define io_p2v(x)	( ((x) | 0xbe000000) ^ (~((x) >> 1) & 0x06000000) )
+#define io_v2p( x )	( ((x) & 0x41ffffff) ^ ( ((x) & 0x06000000) << 1) )
 
 #ifndef __ASSEMBLY__
 
@@ -51,7 +61,7 @@
  * doesn't guess this by itself.
  */
 #include <asm/types.h>
-typedef struct { volatile u32 offset[1024]; } __regbase;
+typedef struct { volatile u32 offset[4096]; } __regbase;
 # define __REGP(x)	((__regbase *)((x)&~4095))->offset[((x)&4095)>>2]
 # define __REG(x)	__REGP(io_p2v(x))
 #endif
@@ -93,5 +103,6 @@
 
 #include "lubbock.h"
 #include "idp.h"
+#include "cerf.h"
 
 #endif  /* _ASM_ARCH_HARDWARE_H */
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	Sat Aug 10 18:42:23 2002
+++ b/include/asm-arm/arch-pxa/pxa-regs.h	Sat Aug 10 18:42:23 2002
@@ -262,6 +262,7 @@
 
 /* default combinations */
 #define DCMD_RXPCDR	(DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
+#define DCMD_RXMCDR	(DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
 #define DCMD_TXPCDR	(DCMD_INCSRCADDR|DCMD_FLOWTRG|DCMD_BURST32|DCMD_WIDTH4)
 
 
@@ -361,7 +362,7 @@
 #define LSR_OE		(1 << 1)	/* Overrun Error */
 #define LSR_DR		(1 << 0)	/* Data Ready */
 
-#define MCR_LOOP	(1 << 4)
+#define MCR_LOOP	(1 << 4)	*/
 #define MCR_OUT2	(1 << 3)	/* force MSR_DCD in loopback mode */
 #define MCR_OUT1	(1 << 2)	/* force MSR_RI in loopback mode */
 #define MCR_RTS		(1 << 1)	/* Request to Send */
@@ -376,6 +377,35 @@
 #define MSR_DDSR	(1 << 1)	/* Delta Data Set Ready */
 #define MSR_DCTS	(1 << 0)	/* Delta Clear To Send */
 
+/*
+ * IrSR (Infrared Selection Register)
+ */
+#define IrSR_OFFSET 0x20
+
+#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
@@ -387,6 +417,37 @@
 #define ISR		__REG(0x40301698)  /* I2C Status Register - ISR */
 #define ISAR		__REG(0x403016A0)  /* I2C Slave Address Register - ISAR */
 
+/* ----- Control register bits ---------------------------------------- */
+
+#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
@@ -486,24 +547,92 @@
 /*
  * USB Device Controller
  */
+#define UDC_RES1	__REG(0x40600004)  /* UDC Undocumented - Reserved1 */
+#define UDC_RES2	__REG(0x40600008)  /* UDC Undocumented - Reserved2 */
+#define UDC_RES3	__REG(0x4060000C)  /* UDC Undocumented - Reserved3 */
 
 #define UDCCR		__REG(0x40600000)  /* UDC Control Register */
+#define UDCCR_UDE	(1 << 0)	/* UDC enable */
+#define UDCCR_UDA	(1 << 1)	/* UDC active */
+#define UDCCR_RSM	(1 << 2)	/* Device resume */
+#define UDCCR_RESIR	(1 << 3)	/* Resume interrupt request */
+#define UDCCR_SUSIR	(1 << 4)	/* Suspend interrupt request */
+#define UDCCR_SRM	(1 << 5)	/* Suspend/resume interrupt mask */
+#define UDCCR_RSTIR	(1 << 6)	/* Reset interrupt request */
+#define UDCCR_REM	(1 << 7)	/* Reset interrupt mask */
+
 #define UDCCS0		__REG(0x40600010)  /* UDC Endpoint 0 Control/Status Register */
+#define UDCCS0_OPR	(1 << 0)	/* OUT packet ready */
+#define UDCCS0_IPR	(1 << 1)	/* IN packet ready */
+#define UDCCS0_FTF	(1 << 2)	/* Flush Tx FIFO */
+#define UDCCS0_DRWF	(1 << 3)	/* Device remote wakeup feature */
+#define UDCCS0_SST	(1 << 4)	/* Sent stall */
+#define UDCCS0_FST	(1 << 5)	/* Force stall */
+#define UDCCS0_RNE	(1 << 6)	/* Receive FIFO no empty */
+#define UDCCS0_SA	(1 << 7)	/* Setup active */
+
+/* Bulk IN - Endpoint 1,6,11 */
 #define UDCCS1		__REG(0x40600014)  /* UDC Endpoint 1 (IN) Control/Status Register */
-#define UDCCS2		__REG(0x40600018)  /* UDC Endpoint 2 (OUT) Control/Status Register */
-#define UDCCS3		__REG(0x4060001C)  /* UDC Endpoint 3 (IN) Control/Status Register */
-#define UDCCS4		__REG(0x40600020)  /* UDC Endpoint 4 (OUT) Control/Status Register */
-#define UDCCS5		__REG(0x40600024)  /* UDC Endpoint 5 (Interrupt) Control/Status Register */
 #define UDCCS6		__REG(0x40600028)  /* UDC Endpoint 6 (IN) Control/Status Register */
-#define UDCCS7		__REG(0x4060002C)  /* UDC Endpoint 7 (OUT) Control/Status Register */
-#define UDCCS8		__REG(0x40600030)  /* UDC Endpoint 8 (IN) Control/Status Register */
-#define UDCCS9		__REG(0x40600034)  /* UDC Endpoint 9 (OUT) Control/Status Register */
-#define UDCCS10		__REG(0x40600038)  /* UDC Endpoint 10 (Interrupt) Control/Status Register */
 #define UDCCS11		__REG(0x4060003C)  /* UDC Endpoint 11 (IN) Control/Status Register */
+
+#define UDCCS_BI_TFS	(1 << 0)	/* Transmit FIFO service */
+#define UDCCS_BI_TPC	(1 << 1)	/* Transmit packet complete */
+#define UDCCS_BI_FTF	(1 << 2)	/* Flush Tx FIFO */
+#define UDCCS_BI_TUR	(1 << 3)	/* Transmit FIFO underrun */
+#define UDCCS_BI_SST	(1 << 4)	/* Sent stall */
+#define UDCCS_BI_FST	(1 << 5)	/* Force stall */
+#define UDCCS_BI_TSP	(1 << 7)	/* Transmit short packet */
+
+/* Bulk OUT - Endpoint 2,7,12 */
+#define UDCCS2		__REG(0x40600018)  /* UDC Endpoint 2 (OUT) Control/Status Register */
+#define UDCCS7		__REG(0x4060002C)  /* UDC Endpoint 7 (OUT) Control/Status Register */
 #define UDCCS12		__REG(0x40600040)  /* UDC Endpoint 12 (OUT) Control/Status Register */
+
+#define UDCCS_BO_RFS	(1 << 0)	/* Receive FIFO service */
+#define UDCCS_BO_RPC	(1 << 1)	/* Receive packet complete */
+#define UDCCS_BO_DME	(1 << 3)	/* DMA enable */
+#define UDCCS_BO_SST	(1 << 4)	/* Sent stall */
+#define UDCCS_BO_FST	(1 << 5)	/* Force stall */
+#define UDCCS_BO_RNE	(1 << 6)	/* Receive FIFO not empty */
+#define UDCCS_BO_RSP	(1 << 7)	/* Receive short packet */
+
+/* Isochronous IN - Endpoint 3,8,13 */
+#define UDCCS3		__REG(0x4060001C)  /* UDC Endpoint 3 (IN) Control/Status Register */
+#define UDCCS8		__REG(0x40600030)  /* UDC Endpoint 8 (IN) Control/Status Register */
 #define UDCCS13		__REG(0x40600044)  /* UDC Endpoint 13 (IN) Control/Status Register */
+
+#define UDCCS_II_TFS	(1 << 0)	/* Transmit FIFO service */
+#define UDCCS_II_TPC	(1 << 1)	/* Transmit packet complete */
+#define UDCCS_II_FTF	(1 << 2)	/* Flush Tx FIFO */
+#define UDCCS_II_TUR	(1 << 3)	/* Transmit FIFO underrun */
+#define UDCCS_II_TSP	(1 << 7)	/* Transmit short packet */
+
+/* Isochronous OUT - Endpoint 4,9,14 */
+#define UDCCS4		__REG(0x40600020)  /* UDC Endpoint 4 (OUT) Control/Status Register */
+#define UDCCS9		__REG(0x40600034)  /* UDC Endpoint 9 (OUT) Control/Status Register */
 #define UDCCS14		__REG(0x40600048)  /* UDC Endpoint 14 (OUT) Control/Status Register */
+
+#define UDCCS_IO_RFS	(1 << 0)	/* Receive FIFO service */
+#define UDCCS_IO_RPC	(1 << 1)	/* Receive packet complete */
+#define UDCCS_IO_ROF	(1 << 3)	/* Receive overflow */
+#define UDCCS_IO_DME	(1 << 3)	/* DMA enable */
+#define UDCCS_IO_RNE	(1 << 6)	/* Receive FIFO not empty */
+#define UDCCS_IO_RSP	(1 << 7)	/* Receive short packet */
+
+/* Interrupt IN - Endpoint 5,10,15 */
+#define UDCCS5		__REG(0x40600024)  /* UDC Endpoint 5 (Interrupt) Control/Status Register */
+#define UDCCS10		__REG(0x40600038)  /* UDC Endpoint 10 (Interrupt) Control/Status Register */
 #define UDCCS15		__REG(0x4060004C)  /* UDC Endpoint 15 (Interrupt) Control/Status Register */
+
+#define UDCCS_INT_TFS	(1 << 0)	/* Transmit FIFO service */
+#define UDCCS_INT_TPC	(1 << 1)	/* Transmit packet complete */
+#define UDCCS_INT_FTF	(1 << 2)	/* Flush Tx FIFO */
+#define UDCCS_INT_TUR	(1 << 3)	/* Transmit FIFO underrun */
+#define UDCCS_INT_SST	(1 << 4)	/* Sent stall */
+#define UDCCS_INT_FST	(1 << 5)	/* Force stall */
+#define UDCCS_INT_TSP	(1 << 7)	/* Transmit short packet */
+
 #define UFNRH		__REG(0x40600060)  /* UDC Frame Number Register High */
 #define UFNRL		__REG(0x40600064)  /* UDC Frame Number Register Low */
 #define UBCR2		__REG(0x40600068)  /* UDC Byte Count Reg 2 */
@@ -528,11 +657,51 @@
 #define UDDR13		__REG(0x40600C00)  /* UDC Endpoint 13 Data Register */
 #define UDDR14		__REG(0x40600E00)  /* UDC Endpoint 14 Data Register */
 #define UDDR15		__REG(0x406000E0)  /* UDC Endpoint 15 Data Register */
+
 #define UICR0		__REG(0x40600050)  /* UDC Interrupt Control Register 0 */
+
+#define UICR0_IM0	(1 << 0)	/* Interrupt mask ep 0 */
+#define UICR0_IM1	(1 << 1)	/* Interrupt mask ep 1 */
+#define UICR0_IM2	(1 << 2)	/* Interrupt mask ep 2 */
+#define UICR0_IM3	(1 << 3)	/* Interrupt mask ep 3 */
+#define UICR0_IM4	(1 << 4)	/* Interrupt mask ep 4 */
+#define UICR0_IM5	(1 << 5)	/* Interrupt mask ep 5 */
+#define UICR0_IM6	(1 << 6)	/* Interrupt mask ep 6 */
+#define UICR0_IM7	(1 << 7)	/* Interrupt mask ep 7 */
+
 #define UICR1		__REG(0x40600054)  /* UDC Interrupt Control Register 1 */
+
+#define UICR1_IM8	(1 << 0)	/* Interrupt mask ep 8 */
+#define UICR1_IM9	(1 << 1)	/* Interrupt mask ep 9 */
+#define UICR1_IM10	(1 << 2)	/* Interrupt mask ep 10 */
+#define UICR1_IM11	(1 << 3)	/* Interrupt mask ep 11 */
+#define UICR1_IM12	(1 << 4)	/* Interrupt mask ep 12 */
+#define UICR1_IM13	(1 << 5)	/* Interrupt mask ep 13 */
+#define UICR1_IM14	(1 << 6)	/* Interrupt mask ep 14 */
+#define UICR1_IM15	(1 << 7)	/* Interrupt mask ep 15 */
+
 #define USIR0		__REG(0x40600058)  /* UDC Status Interrupt Register 0 */
+
+#define USIR0_IR0	(1 << 0)	/* Interrup request ep 0 */
+#define USIR0_IR1	(1 << 1)	/* Interrup request ep 1 */
+#define USIR0_IR2	(1 << 2)	/* Interrup request ep 2 */
+#define USIR0_IR3	(1 << 3)	/* Interrup request ep 3 */
+#define USIR0_IR4	(1 << 4)	/* Interrup request ep 4 */
+#define USIR0_IR5	(1 << 5)	/* Interrup request ep 5 */
+#define USIR0_IR6	(1 << 6)	/* Interrup request ep 6 */
+#define USIR0_IR7	(1 << 7)	/* Interrup request ep 7 */
+
 #define USIR1		__REG(0x4060005C)  /* UDC Status Interrupt Register 1 */
 
+#define USIR1_IR8	(1 << 0)	/* Interrup request ep 8 */
+#define USIR1_IR9	(1 << 1)	/* Interrup request ep 9 */
+#define USIR1_IR10	(1 << 2)	/* Interrup request ep 10 */
+#define USIR1_IR11	(1 << 3)	/* Interrup request ep 11 */
+#define USIR1_IR12	(1 << 4)	/* Interrup request ep 12 */
+#define USIR1_IR13	(1 << 5)	/* Interrup request ep 13 */
+#define USIR1_IR14	(1 << 6)	/* Interrup request ep 14 */
+#define USIR1_IR15	(1 << 7)	/* Interrup request ep 15 */
+
 
 /*
  * Fast Infrared Communication Port
@@ -879,6 +1048,22 @@
 #define PGSR2		__REG(0x40F00028)  /* Power Manager GPIO Sleep State Register for GP[84-64] */
 #define RCSR		__REG(0x40F00030)  /* Reset Controller Status Register */
 
+#define PSSR_RDH	(1 << 5)	/* Read Disable Hold */
+#define PSSR_PH		(1 << 4)	/* Peripheral Control Hold */
+#define PSSR_VFS	(1 << 2)	/* VDD Fault Status */
+#define PSSR_BFS	(1 << 1)	/* Battery Fault Status */
+#define PSSR_SSS	(1 << 0)	/* Software Sleep Status */
+
+#define PCFR_DS		(1 << 3)	/* Deep Sleep Mode */
+#define PCFR_FS		(1 << 2)	/* Float Static Chip Selects */
+#define PCFR_FP		(1 << 1)	/* Float PCMCIA controls */
+#define PCFR_OPDE	(1 << 0)	/* 3.6864 MHz oscillator power-down enable */
+
+#define RCSR_GPR	(1 << 3)	/* GPIO Reset */
+#define RCSR_SMR	(1 << 2)	/* Sleep Mode */
+#define RCSR_WDR	(1 << 1)	/* Watchdog Reset */
+#define RCSR_HWR	(1 << 0)	/* Hardware Reset */
+
 
 /*
  * SSP Serial Port Registers
@@ -1034,4 +1219,20 @@
 #define MCIO1		__REG(0x4800003C)  /* Card interface I/O Space Socket 1 Timing Configuration */
 #define MDMRS		__REG(0x48000040)  /* MRS value to be written to SDRAM */
 #define BOOT_DEF	__REG(0x48000044)  /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
+
+#define MDREFR_K2FREE	(1 << 25)	/* SDRAM Free-Running Control */
+#define MDREFR_K1FREE	(1 << 24)	/* SDRAM Free-Running Control */
+#define MDREFR_K0FREE	(1 << 23)	/* SDRAM Free-Running Control */
+#define MDREFR_SLFRSH	(1 << 22)	/* SDRAM Self-Refresh Control/Status */
+#define MDREFR_APD	(1 << 20)	/* SDRAM/SSRAM Auto-Power-Down Enable */
+#define MDREFR_K2DB2	(1 << 19)	/* SDCLK2 Divide by 2 Control/Status */
+#define MDREFR_K2RUN	(1 << 18)	/* SDCLK2 Run Control/Status */
+#define MDREFR_K1DB2	(1 << 17)	/* SDCLK1 Divide by 2 Control/Status */
+#define MDREFR_K1RUN	(1 << 16)	/* SDCLK1 Run Control/Status */
+#define MDREFR_E1PIN	(1 << 15)	/* SDCKE1 Level Control/Status */
+#define MDREFR_K0DB2	(1 << 14)	/* SDCLK0 Divide by 2 Control/Status */
+#define MDREFR_K0RUN	(1 << 13)	/* SDCLK0 Run Control/Status */
+#define MDREFR_E0PIN	(1 << 12)	/* SDCKE0 Level Control/Status */
+
+
 
diff -Nru a/include/asm-arm/arch-sa1100/irqs.h b/include/asm-arm/arch-sa1100/irqs.h
--- a/include/asm-arm/arch-sa1100/irqs.h	Sat Aug 10 18:42:19 2002
+++ b/include/asm-arm/arch-sa1100/irqs.h	Sat Aug 10 18:42:19 2002
@@ -131,7 +131,8 @@
 #ifdef CONFIG_SA1111
 #define NR_IRQS			(S1_BVD1_STSCHG + 1)
 #elif defined(CONFIG_SA1100_GRAPHICSCLIENT) || \
-      defined(CONFIG_SA1100_GRAPHICSMASTER)
+      defined(CONFIG_SA1100_GRAPHICSMASTER) || \
+      defined(CONFIG_SA1100_H3800)
 #define NR_IRQS			(IRQ_BOARD_END)
 #else
 #define NR_IRQS			(IRQ_BOARD_START)
@@ -148,3 +149,24 @@
 /* PT Digital Board Interrupts (CONFIG_SA1100_PT_SYSTEM3) */
 #define IRQ_SYSTEM3_SA1111	(IRQ_BOARD_START + 0)
 #define IRQ_SYSTEM3_SMC9196	(IRQ_BOARD_START + 1)
+
+/* H3800-specific IRQs (CONFIG_SA1100_H3800) */
+#define H3800_KPIO_IRQ_START    (IRQ_BOARD_START)
+#define IRQ_H3800_KEY           (IRQ_BOARD_START + 0)
+#define IRQ_H3800_SPI           (IRQ_BOARD_START + 1)
+#define IRQ_H3800_OWM           (IRQ_BOARD_START + 2)
+#define IRQ_H3800_ADC           (IRQ_BOARD_START + 3)
+#define IRQ_H3800_UART_0        (IRQ_BOARD_START + 4)
+#define IRQ_H3800_UART_1        (IRQ_BOARD_START + 5)
+#define IRQ_H3800_TIMER_0       (IRQ_BOARD_START + 6)
+#define IRQ_H3800_TIMER_1       (IRQ_BOARD_START + 7)
+#define IRQ_H3800_TIMER_2       (IRQ_BOARD_START + 8)
+#define H3800_KPIO_IRQ_COUNT    9
+
+#define H3800_GPIO_IRQ_START    (IRQ_BOARD_START + 9)
+#define IRQ_H3800_PEN           (IRQ_BOARD_START + 9)
+#define IRQ_H3800_SD_DETECT     (IRQ_BOARD_START + 10)
+#define IRQ_H3800_EAR_IN        (IRQ_BOARD_START + 11)
+#define IRQ_H3800_USB_DETECT    (IRQ_BOARD_START + 12)
+#define IRQ_H3800_SD_CON_SLT    (IRQ_BOARD_START + 13)
+#define H3800_GPIO_IRQ_COUNT    5
diff -Nru a/include/asm-arm/linkage.h b/include/asm-arm/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-arm/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,7 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define __ALIGN .align 0
+#define __ALIGN_STR ".align 0"
+
+#endif
diff -Nru a/include/asm-cris/linkage.h b/include/asm-cris/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-cris/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
--- a/include/asm-generic/tlb.h	Sat Aug 10 18:42:19 2002
+++ b/include/asm-generic/tlb.h	Sat Aug 10 18:42:19 2002
@@ -54,7 +54,7 @@
 	tlb->mm = mm;
 
 	/* Use fast mode if only one CPU is online */
-	tlb->nr = num_online_cpus() > 1 ? 0UL : ~0UL;
+	tlb->nr = num_online_cpus() > 1 ? 0U : ~0U;
 
 	tlb->fullmm = full_mm_flush;
 	tlb->freed = 0;
diff -Nru a/include/asm-i386/linkage.h b/include/asm-i386/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-i386/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,12 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
+#define FASTCALL(x)	x __attribute__((regparm(3)))
+
+#ifdef CONFIG_X86_ALIGNMENT_16
+#define __ALIGN .align 16,0x90
+#define __ALIGN_STR ".align 16,0x90"
+#endif
+
+#endif
diff -Nru a/include/asm-i386/rwsem.h b/include/asm-i386/rwsem.h
--- a/include/asm-i386/rwsem.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-i386/rwsem.h	Sat Aug 10 18:42:22 2002
@@ -46,7 +46,7 @@
 extern struct rw_semaphore *FASTCALL(rwsem_down_read_failed(struct rw_semaphore *sem));
 extern struct rw_semaphore *FASTCALL(rwsem_down_write_failed(struct rw_semaphore *sem));
 extern struct rw_semaphore *FASTCALL(rwsem_wake(struct rw_semaphore *));
-extern struct rw_semaphore *FASTCALL(rwsem_downgrade_write(struct rw_semaphore *sem));
+extern struct rw_semaphore *FASTCALL(rwsem_downgrade_wake(struct rw_semaphore *sem));
 
 /*
  * the semaphore definition
diff -Nru a/include/asm-ia64/linkage.h b/include/asm-ia64/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ia64/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define asmlinkage CPP_ASMLINKAGE __attribute__((syscall_linkage))
+
+#endif
diff -Nru a/include/asm-m68k/linkage.h b/include/asm-m68k/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-m68k/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,7 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define __ALIGN .align 4
+#define __ALIGN_STR ".align 4"
+
+#endif
diff -Nru a/include/asm-mips/linkage.h b/include/asm-mips/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-mips/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/asm-mips64/linkage.h b/include/asm-mips64/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-mips64/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/asm-parisc/linkage.h b/include/asm-parisc/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-parisc/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/asm-ppc/bitops.h b/include/asm-ppc/bitops.h
--- a/include/asm-ppc/bitops.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-ppc/bitops.h	Sat Aug 10 18:42:22 2002
@@ -26,10 +26,6 @@
 #define SMP_MB
 #endif /* CONFIG_SMP */
 
-/*
- * These used to be if'd out here because using : "cc" as a constraint
- * resulted in errors from egcs.  Things appear to be OK with gcc-2.95.
- */
 static __inline__ void set_bit(int nr, volatile unsigned long * addr)
 {
 	unsigned long old;
@@ -224,9 +220,7 @@
 
 static __inline__ int test_bit(int nr, __const__ volatile unsigned long *addr)
 {
-	__const__ unsigned int *p = (__const__ unsigned int *) addr;
-
-	return ((p[nr >> 5] >> (nr & 0x1f)) & 1) != 0;
+	return ((addr[nr >> 5] >> (nr & 0x1f)) & 1) != 0;
 }
 
 /* Return the bit position of the most significant 1 bit in a word */
diff -Nru a/include/asm-ppc/bootinfo.h b/include/asm-ppc/bootinfo.h
--- a/include/asm-ppc/bootinfo.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-ppc/bootinfo.h	Sat Aug 10 18:42:22 2002
@@ -35,6 +35,7 @@
 
 extern struct bi_record *find_bootinfo(void);
 extern void parse_bootinfo(struct bi_record *rec);
+extern unsigned long boot_mem_size;
 
 #endif /* CONFIG_APUS */
 
diff -Nru a/include/asm-ppc/linkage.h b/include/asm-ppc/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ppc/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h
--- a/include/asm-ppc/processor.h	Sat Aug 10 18:42:20 2002
+++ b/include/asm-ppc/processor.h	Sat Aug 10 18:42:20 2002
@@ -196,10 +196,11 @@
 #define	SPRN_DSISR	0x012	/* Data Storage Interrupt Status Register */
 #define	SPRN_EAR	0x11A	/* External Address Register */
 #define	SPRN_ESR	0x3D4	/* Exception Syndrome Register */
-#define	  ESR_IMCP	0x80000000	/* Instr. Machine Check - Protection */
-#define	  ESR_IMCN	0x40000000	/* Instr. Machine Check - Non-config */
-#define	  ESR_IMCB	0x20000000	/* Instr. Machine Check - Bus error */
-#define	  ESR_IMCT	0x10000000	/* Instr. Machine Check - Timeout */
+#define	  ESR_MCI	0x80000000	/* 405 Machine Check - Instruction */
+#define	  ESR_IMCP	0x80000000	/* 403 Inst. Mach. Check - Protection */
+#define	  ESR_IMCN	0x40000000	/* 403 Inst. Mach. Check - Non-config */
+#define	  ESR_IMCB	0x20000000	/* 403 Inst. Mach. Check - Bus error */
+#define	  ESR_IMCT	0x10000000	/* 403 Inst. Mach. Check - Timeout */
 #define	  ESR_PIL	0x08000000	/* Program Exception - Illegal */
 #define	  ESR_PPR	0x04000000	/* Program Exception - Priveleged */
 #define	  ESR_PTR	0x02000000	/* Program Exception - Trap */
@@ -747,9 +748,10 @@
 #define KSTK_ESP(tsk)  ((tsk)->thread.regs? (tsk)->thread.regs->gpr[1]: 0)
 
 /* Get/set floating-point exception mode */
-#define GET_FP_EXC_MODE(tsk)		__unpack_fe01((tsk)->thread.fpexc_mode)
-#define SET_FP_EXC_MODE(tsk, val)	set_fpexc_mode((tsk), (val))
+#define GET_FPEXC_CTL(tsk, adr)	get_fpexc_mode((tsk), (adr))
+#define SET_FPEXC_CTL(tsk, val)	set_fpexc_mode((tsk), (val))
 
+extern int get_fpexc_mode(struct task_struct *tsk, unsigned long adr);
 extern int set_fpexc_mode(struct task_struct *tsk, unsigned int val);
 
 static inline unsigned int __unpack_fe01(unsigned int msr_bits)
diff -Nru a/include/asm-ppc/rwsem.h b/include/asm-ppc/rwsem.h
--- a/include/asm-ppc/rwsem.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-ppc/rwsem.h	Sat Aug 10 18:42:23 2002
@@ -72,12 +72,26 @@
  */
 static inline void __down_read(struct rw_semaphore *sem)
 {
-	if (atomic_inc_return((atomic_t *)(&sem->count)) >= 0)
+	if (atomic_inc_return((atomic_t *)(&sem->count)) > 0)
 		smp_wmb();
 	else
 		rwsem_down_read_failed(sem);
 }
 
+static inline int __down_read_trylock(struct rw_semaphore *sem)
+{
+	int tmp;
+
+	while ((tmp = sem->count) >= 0) {
+		if (tmp == cmpxchg(&sem->count, tmp,
+				   tmp + RWSEM_ACTIVE_READ_BIAS)) {
+			smp_wmb();
+			return 1;
+		}
+	}
+	return 0;
+}
+
 /*
  * lock for writing
  */
@@ -91,6 +105,16 @@
 		smp_wmb();
 	else
 		rwsem_down_write_failed(sem);
+}
+
+static inline int __down_write_trylock(struct rw_semaphore *sem)
+{
+	int tmp;
+
+	tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
+		      RWSEM_ACTIVE_WRITE_BIAS);
+	smp_wmb();
+	return tmp == RWSEM_UNLOCKED_VALUE;
 }
 
 /*
diff -Nru a/include/asm-ppc/smplock.h b/include/asm-ppc/smplock.h
--- a/include/asm-ppc/smplock.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-ppc/smplock.h	Sat Aug 10 18:42:22 2002
@@ -24,7 +24,7 @@
 /*
  * Release global kernel lock and global interrupt lock
  */
-#define release_kernel_lock(task, cpu)		\
+#define release_kernel_lock(task)		\
 do {						\
 	if (unlikely(task->lock_depth >= 0))	\
 		spin_unlock(&kernel_flag);	\
diff -Nru a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h
--- a/include/asm-ppc/unistd.h	Sat Aug 10 18:42:21 2002
+++ b/include/asm-ppc/unistd.h	Sat Aug 10 18:42:21 2002
@@ -231,6 +231,8 @@
 #define __NR_futex		221
 #define __NR_sched_setaffinity	222
 #define __NR_sched_getaffinity	223
+#define __NR_security		224
+#define __NR_tuxcall		225
 
 #define __NR(n)	#n
 
diff -Nru a/include/asm-ppc64/linkage.h b/include/asm-ppc64/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ppc64/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/asm-s390/linkage.h b/include/asm-s390/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-s390/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/asm-s390x/linkage.h b/include/asm-s390x/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-s390x/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/asm-sh/linkage.h b/include/asm-sh/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-sh/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,7 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+#define __ALIGN .balign 4
+#define __ALIGN_STR ".balign 4"
+
+#endif
diff -Nru a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h
--- a/include/asm-sparc/bitops.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc/bitops.h	Sat Aug 10 18:42:23 2002
@@ -207,12 +207,74 @@
 	return result;
 }
 
+/**
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static __inline__ int __ffs(unsigned long word)
+{
+	int num = 0;
+
+	if ((word & 0xffff) == 0) {
+		num += 16;
+		word >>= 16;
+	}
+	if ((word & 0xff) == 0) {
+		num += 8;
+		word >>= 8;
+	}
+	if ((word & 0xf) == 0) {
+		num += 4;
+		word >>= 4;
+	}
+	if ((word & 0x3) == 0) {
+		num += 2;
+		word >>= 2;
+	}
+	if ((word & 0x1) == 0)
+		num += 1;
+	return num;
+}
+
+/*
+ * Every architecture must define this function. It's the fastest
+ * way of searching a 140-bit bitmap where the first 100 bits are
+ * unlikely to be set. It's guaranteed that at least one of the 140
+ * bits is cleared.
+ */
+static __inline__ int sched_find_first_bit(unsigned long *b)
+{
+
+	if (unlikely(b[0]))
+		return __ffs(b[0]);
+	if (unlikely(b[1]))
+		return __ffs(b[1]) + 32;
+	if (unlikely(b[2]))
+		return __ffs(b[2]) + 64;
+	if (b[3])
+		return __ffs(b[3]) + 96;
+	return __ffs(b[4]) + 128;
+}
+
 /*
  * ffs: find first bit set. This is defined the same way as
  * the libc and compiler builtin ffs routines, therefore
  * differs in spirit from the above ffz (man ffs).
  */
-#define ffs(x) generic_ffs(x)
+static __inline__ int ffs(int x)
+{
+	if (!x)
+		return 0;
+	return __ffs((unsigned long)x);
+}
+
+/*
+ * fls: find last (most-significant) bit set.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+#define fls(x) generic_fls(x)
 
 /*
  * hweightN: returns the hamming weight (i.e. the number
@@ -272,6 +334,34 @@
 #define find_first_zero_bit(addr, size) \
         find_next_zero_bit((addr), (size), 0)
 
+/**
+ * find_next_bit - find the first set bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ *
+ * Scheduler induced bitop, do not use.
+ */
+static __inline__ int find_next_bit(unsigned long *addr, int size, int offset)
+{
+	unsigned long *p = addr + (offset >> 5);
+	int num = offset & ~0x1f;
+	unsigned long word;
+
+	word = *p++;
+	word &= ~((1 << (offset & 0x1f)) - 1);
+	while (num < size) {
+		if (word != 0) {
+			return __ffs(word) + num;
+		}
+		word = *p++;
+		num += 0x20;
+	}
+	return num;
+}
+
+/*
+ */
 static __inline__ int test_le_bit(int nr, __const__ void * addr)
 {
 	__const__ unsigned char *ADDR = (__const__ unsigned char *) addr;
diff -Nru a/include/asm-sparc/cacheflush.h b/include/asm-sparc/cacheflush.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-sparc/cacheflush.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,69 @@
+#ifndef _SPARC_CACHEFLUSH_H
+#define _SPARC_CACHEFLUSH_H
+
+#include <linux/config.h>
+#include <linux/mm.h>		/* Common for other includes */
+// #include <linux/kernel.h> from pgalloc.h
+// #include <linux/sched.h>  from pgalloc.h
+
+// #include <asm/page.h>
+#include <asm/btfixup.h>
+
+/*
+ * Fine grained cache flushing.
+ */
+#ifdef CONFIG_SMP
+
+BTFIXUPDEF_CALL(void, local_flush_cache_all, void)
+BTFIXUPDEF_CALL(void, local_flush_cache_mm, struct mm_struct *)
+BTFIXUPDEF_CALL(void, local_flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
+BTFIXUPDEF_CALL(void, local_flush_cache_page, struct vm_area_struct *, unsigned long)
+
+#define local_flush_cache_all() BTFIXUP_CALL(local_flush_cache_all)()
+#define local_flush_cache_mm(mm) BTFIXUP_CALL(local_flush_cache_mm)(mm)
+#define local_flush_cache_range(vma,start,end) BTFIXUP_CALL(local_flush_cache_range)(vma,start,end)
+#define local_flush_cache_page(vma,addr) BTFIXUP_CALL(local_flush_cache_page)(vma,addr)
+
+BTFIXUPDEF_CALL(void, local_flush_page_to_ram, unsigned long)
+BTFIXUPDEF_CALL(void, local_flush_sig_insns, struct mm_struct *, unsigned long)
+
+#define local_flush_page_to_ram(addr) BTFIXUP_CALL(local_flush_page_to_ram)(addr)
+#define local_flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(local_flush_sig_insns)(mm,insn_addr)
+
+extern void smp_flush_cache_all(void);
+extern void smp_flush_cache_mm(struct mm_struct *mm);
+extern void smp_flush_cache_range(struct vm_area_struct *vma,
+				  unsigned long start,
+				  unsigned long end);
+extern void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
+
+extern void smp_flush_page_to_ram(unsigned long page);
+extern void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
+
+#endif /* CONFIG_SMP */
+
+BTFIXUPDEF_CALL(void, flush_cache_all, void)
+BTFIXUPDEF_CALL(void, flush_cache_mm, struct mm_struct *)
+BTFIXUPDEF_CALL(void, flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
+BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long)
+
+#define flush_cache_all() BTFIXUP_CALL(flush_cache_all)()
+#define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
+#define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end)
+#define flush_cache_page(vma,addr) BTFIXUP_CALL(flush_cache_page)(vma,addr)
+#define flush_icache_range(start, end)		do { } while (0)
+#define flush_icache_page(vma, pg)		do { } while (0)
+
+#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
+
+BTFIXUPDEF_CALL(void, __flush_page_to_ram, unsigned long)
+BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long)
+
+#define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr)
+#define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr)
+
+extern void flush_page_to_ram(struct page *page);
+
+#define flush_dcache_page(page)			do { } while (0)
+
+#endif /* _SPARC_CACHEFLUSH_H */
diff -Nru a/include/asm-sparc/current.h b/include/asm-sparc/current.h
--- a/include/asm-sparc/current.h	Sat Aug 10 18:42:21 2002
+++ b/include/asm-sparc/current.h	Sat Aug 10 18:42:21 2002
@@ -1,7 +1,38 @@
-#ifndef _SPARC_CURRENT_H
-#define _SPARC_CURRENT_H
+/*
+ *  include/asm-sparc/current.h
+ *
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Copyright (C) 2002 Pete Zaitcev (zaitcev@yahoo.com)
+ *
+ *  Derived from "include/asm-s390/current.h" by
+ *  Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *  Derived from "include/asm-i386/current.h"
+ */
+#ifndef _ASM_CURRENT_H
+#define _ASM_CURRENT_H
 
-/* Sparc rules... */
-register struct task_struct *current asm("g6");
+/*
+ * At the sparc64 DaveM keeps current_thread_info in %g4.
+ * We might want to consider doing the same to shave a few cycles.
+ */
 
-#endif /* !(_SPARC_CURRENT_H) */
+// Applications do not include kernel headers anymore, period.
+// #ifdef __KERNEL__
+
+#ifndef _ASM_THREAD_INFO_H
+#include <asm/thread_info.h>
+#endif
+
+struct task_struct;
+
+/* Two stage process (inline + #define) for type-checking. */
+/* We also obfuscate get_current() to check if anyone used that by mistake. */
+static inline struct task_struct *__get_current(void)
+{
+	return current_thread_info()->task;
+}
+#define current __get_current()
+
+// #endif /* __KERNEL__ */
+
+#endif /* !(_ASM_CURRENT_H) */
diff -Nru a/include/asm-sparc/elf.h b/include/asm-sparc/elf.h
--- a/include/asm-sparc/elf.h	Sat Aug 10 18:42:21 2002
+++ b/include/asm-sparc/elf.h	Sat Aug 10 18:42:21 2002
@@ -41,7 +41,7 @@
 	dest[34] = src->npc;				\
 	dest[35] = src->y;				\
 	dest[36] = dest[37] = 0; /* XXX */		\
-} while(0)
+} while(0); /* Janitors: Don't touch this colon. */
 
 typedef struct {
 	union {
diff -Nru a/include/asm-sparc/highmem.h b/include/asm-sparc/highmem.h
--- a/include/asm-sparc/highmem.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc/highmem.h	Sat Aug 10 18:42:23 2002
@@ -25,6 +25,8 @@
 #include <asm/vaddrs.h>
 #include <asm/kmap_types.h>
 #include <asm/pgtable.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
 
 /* undef for production */
 #define HIGHMEM_DEBUG 1
diff -Nru a/include/asm-sparc/kmap_types.h b/include/asm-sparc/kmap_types.h
--- a/include/asm-sparc/kmap_types.h	Sat Aug 10 18:42:21 2002
+++ b/include/asm-sparc/kmap_types.h	Sat Aug 10 18:42:21 2002
@@ -9,6 +9,8 @@
 	KM_USER1,
 	KM_BIO_SRC_IRQ,
 	KM_BIO_DST_IRQ,
+	KM_PTE0,
+	KM_PTE1,
 	KM_TYPE_NR
 };
 
diff -Nru a/include/asm-sparc/linkage.h b/include/asm-sparc/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-sparc/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/asm-sparc/mmu_context.h b/include/asm-sparc/mmu_context.h
--- a/include/asm-sparc/mmu_context.h	Sat Aug 10 18:42:20 2002
+++ b/include/asm-sparc/mmu_context.h	Sat Aug 10 18:42:21 2002
@@ -5,29 +5,6 @@
 
 #ifndef __ASSEMBLY__
 
-/*
- * Every architecture must define this function. It's the fastest
- * way of searching a 168-bit bitmap where the first 128 bits are
- * unlikely to be clear. It's guaranteed that at least one of the 168
- * bits is cleared.
- */
-#if MAX_RT_PRIO != 128 || MAX_PRIO != 168
-# error update this function.
-#endif
-
-static inline int sched_find_first_zero_bit(unsigned long *b)
-{
-	unsigned int rt;
-
-	rt = b[0] & b[1] & b[2] & b[3];
-	if (unlikely(rt != 0xffffffff))
-		return find_first_zero_bit(b, MAX_RT_PRIO);
-
-	if (b[4] != ~0)
-		return ffz(b[4]) + MAX_RT_PRIO;
-	return ffz(b[5]) + 32 + MAX_RT_PRIO;
-}
-
 static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu)
 {
 }
diff -Nru a/include/asm-sparc/page.h b/include/asm-sparc/page.h
--- a/include/asm-sparc/page.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-sparc/page.h	Sat Aug 10 18:42:22 2002
@@ -27,9 +27,6 @@
 #include <asm/head.h>       /* for KERNBASE */
 #include <asm/btfixup.h>
 
-/* This is always 2048*sizeof(long), doesn't change with PAGE_SIZE */
-#define TASK_UNION_SIZE		8192
-
 #ifndef __ASSEMBLY__
 
 /*
@@ -176,8 +173,12 @@
 #define PAGE_OFFSET	0xf0000000
 #define __pa(x)                 ((unsigned long)(x) - PAGE_OFFSET)
 #define __va(x)                 ((void *)((unsigned long) (x) + PAGE_OFFSET))
+
+#define pfn_to_page(pfn)        (mem_map + (pfn))
+#define page_to_pfn(page)       ((unsigned long)((page) - mem_map))
 #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
-#define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
+#define pfn_valid(pfn)		((pfn) < max_mapnr)
+#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
diff -Nru a/include/asm-sparc/pgalloc.h b/include/asm-sparc/pgalloc.h
--- a/include/asm-sparc/pgalloc.h	Sat Aug 10 18:42:21 2002
+++ b/include/asm-sparc/pgalloc.h	Sat Aug 10 18:42:21 2002
@@ -9,85 +9,7 @@
 #include <asm/page.h>
 #include <asm/btfixup.h>
 
-/* Fine grained cache/tlb flushing. */
-#ifdef CONFIG_SMP
-BTFIXUPDEF_CALL(void, local_flush_cache_all, void)
-BTFIXUPDEF_CALL(void, local_flush_cache_mm, struct mm_struct *)
-BTFIXUPDEF_CALL(void, local_flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(void, local_flush_cache_page, struct vm_area_struct *, unsigned long)
-
-#define local_flush_cache_all() BTFIXUP_CALL(local_flush_cache_all)()
-#define local_flush_cache_mm(mm) BTFIXUP_CALL(local_flush_cache_mm)(mm)
-#define local_flush_cache_range(vma,start,end) BTFIXUP_CALL(local_flush_cache_range)(vma,start,end)
-#define local_flush_cache_page(vma,addr) BTFIXUP_CALL(local_flush_cache_page)(vma,addr)
-
-BTFIXUPDEF_CALL(void, local_flush_tlb_all, void)
-BTFIXUPDEF_CALL(void, local_flush_tlb_mm, struct mm_struct *)
-BTFIXUPDEF_CALL(void, local_flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(void, local_flush_tlb_page, struct vm_area_struct *, unsigned long)
-
-#define local_flush_tlb_all() BTFIXUP_CALL(local_flush_tlb_all)()
-#define local_flush_tlb_mm(mm) BTFIXUP_CALL(local_flush_tlb_mm)(mm)
-#define local_flush_tlb_range(vma,start,end) BTFIXUP_CALL(local_flush_tlb_range)(vma,start,end)
-#define local_flush_tlb_page(vma,addr) BTFIXUP_CALL(local_flush_tlb_page)(vma,addr)
-
-BTFIXUPDEF_CALL(void, local_flush_page_to_ram, unsigned long)
-BTFIXUPDEF_CALL(void, local_flush_sig_insns, struct mm_struct *, unsigned long)
-
-#define local_flush_page_to_ram(addr) BTFIXUP_CALL(local_flush_page_to_ram)(addr)
-#define local_flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(local_flush_sig_insns)(mm,insn_addr)
-
-extern void smp_flush_cache_all(void);
-extern void smp_flush_cache_mm(struct mm_struct *mm);
-extern void smp_flush_cache_range(struct vm_area_struct *vma,
-				  unsigned long start,
-				  unsigned long end);
-extern void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page);
-
-extern void smp_flush_tlb_all(void);
-extern void smp_flush_tlb_mm(struct mm_struct *mm);
-extern void smp_flush_tlb_range(struct vm_area_struct *vma,
-				  unsigned long start,
-				  unsigned long end);
-extern void smp_flush_tlb_page(struct vm_area_struct *mm, unsigned long page);
-extern void smp_flush_page_to_ram(unsigned long page);
-extern void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr);
-#endif
-
-BTFIXUPDEF_CALL(void, flush_cache_all, void)
-BTFIXUPDEF_CALL(void, flush_cache_mm, struct mm_struct *)
-BTFIXUPDEF_CALL(void, flush_cache_range, struct vm_area_struct *, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(void, flush_cache_page, struct vm_area_struct *, unsigned long)
-
-#define flush_cache_all() BTFIXUP_CALL(flush_cache_all)()
-#define flush_cache_mm(mm) BTFIXUP_CALL(flush_cache_mm)(mm)
-#define flush_cache_range(vma,start,end) BTFIXUP_CALL(flush_cache_range)(vma,start,end)
-#define flush_cache_page(vma,addr) BTFIXUP_CALL(flush_cache_page)(vma,addr)
-#define flush_icache_range(start, end)		do { } while (0)
-
-BTFIXUPDEF_CALL(void, flush_tlb_all, void)
-BTFIXUPDEF_CALL(void, flush_tlb_mm, struct mm_struct *)
-BTFIXUPDEF_CALL(void, flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
-BTFIXUPDEF_CALL(void, flush_tlb_page, struct vm_area_struct *, unsigned long)
-
-extern __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end)
-{
-}
-
-#define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)()
-#define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm)
-#define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end)
-#define flush_tlb_page(vma,addr) BTFIXUP_CALL(flush_tlb_page)(vma,addr)
-
-BTFIXUPDEF_CALL(void, __flush_page_to_ram, unsigned long)
-BTFIXUPDEF_CALL(void, flush_sig_insns, struct mm_struct *, unsigned long)
-
-#define __flush_page_to_ram(addr) BTFIXUP_CALL(__flush_page_to_ram)(addr)
-#define flush_sig_insns(mm,insn_addr) BTFIXUP_CALL(flush_sig_insns)(mm,insn_addr)
-
-extern void flush_page_to_ram(struct page *page);
-
-#define flush_dcache_page(page)			do { } while (0)
+struct page;
 
 extern struct pgtable_cache_struct {
 	unsigned long *pgd_cache;
@@ -101,7 +23,8 @@
 #define pgtable_cache_size      (pgt_quicklists.pgtable_cache_sz)
 #define pgd_cache_size		(pgt_quicklists.pgd_cache_sz)
 
-BTFIXUPDEF_CALL(int,	 do_check_pgt_cache, int, int)
+extern void check_pgt_cache(void);
+BTFIXUPDEF_CALL(void,	 do_check_pgt_cache, int, int)
 #define do_check_pgt_cache(low,high) BTFIXUP_CALL(do_check_pgt_cache)(low,high)
 
 BTFIXUPDEF_CALL(pgd_t *, get_pgd_fast, void)
@@ -113,6 +36,8 @@
 #define pgd_free(pgd)	free_pgd_fast(pgd)
 #define pgd_alloc(mm)	get_pgd_fast()
 
+BTFIXUPDEF_CALL(void, pgd_set, pgd_t *, pmd_t *)
+#define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp)
 #define pgd_populate(MM, PGD, PMD)      pgd_set(PGD, PMD)
 
 static __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
@@ -127,18 +52,24 @@
 #define free_pmd_fast(pmd)	BTFIXUP_CALL(free_pmd_fast)(pmd)
 
 #define pmd_free(pmd)           free_pmd_fast(pmd)
+#define pmd_free_tlb(tlb, pmd)	pmd_free(pmd)
 
-#define pmd_populate(MM, PMD, PTE)      pmd_set(PMD, PTE)
+BTFIXUPDEF_CALL(void, pmd_populate, pmd_t *, struct page *)
+#define pmd_populate(MM, PMD, PTE)        BTFIXUP_CALL(pmd_populate)(PMD, PTE)
+BTFIXUPDEF_CALL(void, pmd_set, pmd_t *, pte_t *)
+#define pmd_populate_kernel(MM, PMD, PTE) BTFIXUP_CALL(pmd_set)(PMD, PTE)
 
-BTFIXUPDEF_CALL(pte_t *, pte_alloc_one, struct mm_struct *, unsigned long)
+BTFIXUPDEF_CALL(struct page *, pte_alloc_one, struct mm_struct *, unsigned long)
 #define pte_alloc_one(mm, address)	BTFIXUP_CALL(pte_alloc_one)(mm, address)
-
-BTFIXUPDEF_CALL(pte_t *, pte_alloc_one_fast, struct mm_struct *, unsigned long)
-#define pte_alloc_one_fast(mm, address)	BTFIXUP_CALL(pte_alloc_one_fast)(mm, address)
+BTFIXUPDEF_CALL(pte_t *, pte_alloc_one_kernel, struct mm_struct *, unsigned long)
+#define pte_alloc_one_kernel(mm, addr)	BTFIXUP_CALL(pte_alloc_one_kernel)(mm, addr)
 
 BTFIXUPDEF_CALL(void, free_pte_fast, pte_t *)
 #define free_pte_fast(pte)	BTFIXUP_CALL(free_pte_fast)(pte)
+#define pte_free_kernel(pte)	free_pte_fast(pte)
 
-#define pte_free(pte)		free_pte_fast(pte)
+BTFIXUPDEF_CALL(void, pte_free, struct page *)
+#define pte_free(pte)		BTFIXUP_CALL(pte_free)(pte)
+#define pte_free_tlb(tlb, pte)	pte_free(pte)
 
 #endif /* _SPARC_PGALLOC_H */
diff -Nru a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h
--- a/include/asm-sparc/pgtable.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc/pgtable.h	Sat Aug 10 18:42:23 2002
@@ -11,6 +11,8 @@
 
 #include <linux/config.h>
 #include <linux/spinlock.h>
+/* XXX This creates many nasty warnings. */
+/* #include <linux/highmem.h> */	/* kmap_atomic in pte_offset_map */
 #include <asm/asi.h>
 #ifdef CONFIG_SUN4
 #include <asm/pgtsun4.h>
@@ -26,6 +28,8 @@
 
 #ifndef __ASSEMBLY__
 
+struct vm_area_struct;
+
 extern void load_mmu(void);
 extern unsigned long calc_highpages(void);
 			       
@@ -183,7 +187,7 @@
 
 #define BAD_PAGETABLE __bad_pagetable()
 #define BAD_PAGE __bad_page()
-#define ZERO_PAGE(vaddr) (mem_map + (((unsigned long)&empty_zero_page - PAGE_OFFSET + phys_base) >> PAGE_SHIFT))
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
 
 /* number of bits that fit into a memory pointer */
 #define BITS_PER_PTR      (8*sizeof(unsigned long))
@@ -193,7 +197,7 @@
 
 #define SIZEOF_PTR_LOG2   2
 
-BTFIXUPDEF_CALL_CONST(unsigned long, pmd_page, pmd_t)
+BTFIXUPDEF_CALL_CONST(struct page *, pmd_page, pmd_t)
 BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page, pgd_t)
 
 #define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd)
@@ -291,13 +295,12 @@
 #define pte_mkyoung(pte) BTFIXUP_CALL(pte_mkyoung)(pte)
 
 #define page_pte_prot(page, prot)	mk_pte(page, prot)
-#define page_pte(page)			page_pte_prot(page, __pgprot(0))
-
-/* Permanent address of a page. */
-#define page_address(page)  ((page)->virtual)
+#define page_pte(page)			mk_pte(page, __pgprot(0))
+#define pfn_pte(pfn, prot)		mk_pte(pfn_to_page(pfn), prot)
 
-BTFIXUPDEF_CALL(struct page *, pte_page, pte_t)
-#define pte_page(pte) BTFIXUP_CALL(pte_page)(pte)
+BTFIXUPDEF_CALL(unsigned long,	 pte_pfn, pte_t)
+#define pte_pfn(pte) BTFIXUP_CALL(pte_pfn)(pte)
+#define pte_page(pte)	pfn_to_page(pte_pfn(pte))
 
 /*
  * Conversion functions: convert a page and protection to a page entry,
@@ -312,12 +315,6 @@
 #define mk_pte_phys(page,pgprot) BTFIXUP_CALL(mk_pte_phys)(page,pgprot)
 #define mk_pte_io(page,pgprot,space) BTFIXUP_CALL(mk_pte_io)(page,pgprot,space)
 
-BTFIXUPDEF_CALL(void, pgd_set, pgd_t *, pmd_t *)
-BTFIXUPDEF_CALL(void, pmd_set, pmd_t *, pte_t *)
-
-#define pgd_set(pgdp,pmdp) BTFIXUP_CALL(pgd_set)(pgdp,pmdp)
-#define pmd_set(pmdp,ptep) BTFIXUP_CALL(pmd_set)(pmdp,ptep)
-
 BTFIXUPDEF_INT(pte_modify_mask)
 
 extern pte_t pte_modify(pte_t pte, pgprot_t newprot) __attribute__((const));
@@ -335,20 +332,31 @@
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
-BTFIXUPDEF_CALL(pmd_t *, pmd_offset, pgd_t *, unsigned long)
-BTFIXUPDEF_CALL(pte_t *, pte_offset, pmd_t *, unsigned long)
-
 /* Find an entry in the second-level page table.. */
+BTFIXUPDEF_CALL(pmd_t *, pmd_offset, pgd_t *, unsigned long)
 #define pmd_offset(dir,addr) BTFIXUP_CALL(pmd_offset)(dir,addr)
 
 /* Find an entry in the third-level page table.. */ 
-#define pte_offset(dir,addr) BTFIXUP_CALL(pte_offset)(dir,addr)
+BTFIXUPDEF_CALL(pte_t *, pte_offset_kernel, pmd_t *, unsigned long)
+#define pte_offset_kernel(dir,addr) BTFIXUP_CALL(pte_offset_kernel)(dir,addr)
+
+/* __pte_offset is not BTFIXUP-ed, but PTRS_PER_PTE is, so it's ok. */
+#define __pte_offset(address) \
+	(((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#if 0 /* XXX Should we expose pmd_page_kernel? */
+#define pte_offset_kernel(dir, addr) \
+	((pte_t *) pmd_page_kernel(*(dir)) + __pte_offset(addr))
+#endif
+#define pte_offset_map(dir, addr) \
+	((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE0) + __pte_offset(addr))
+#define pte_offset_map_nested(dir, addr) \
+	((pte_t *) kmap_atomic(pmd_page(*(dir)), KM_PTE1) + __pte_offset(addr))
+
+#define pte_unmap(pte)		kunmap_atomic(pte, KM_PTE0)
+#define pte_unmap_nested(pte)	kunmap_atomic(pte, KM_PTE1)
 
 /* The permissions for pgprot_val to make a page mapped on the obio space */
 extern unsigned int pg_iobits;
-
-#define flush_icache_page(vma, pg)      do { } while(0)
-#define flush_icache_user_range(vma,pg,adr,len)	do { } while (0)
 
 /* Certain architectures need to do special things when pte's
  * within a page table are directly modified.  Thus, the following
diff -Nru a/include/asm-sparc/pgtsrmmu.h b/include/asm-sparc/pgtsrmmu.h
--- a/include/asm-sparc/pgtsrmmu.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-sparc/pgtsrmmu.h	Sat Aug 10 18:42:22 2002
@@ -8,6 +8,7 @@
 #define _SPARC_PGTSRMMU_H
 
 #include <asm/page.h>
+#include <asm/thread_info.h>	/* TI_UWINMASK for WINDOW_FLUSH */
 
 /* PMD_SHIFT determines the size of the area a second-level page table can map */
 #define SRMMU_PMD_SHIFT         18
@@ -87,7 +88,7 @@
 
 #define WINDOW_FLUSH(tmp1, tmp2)					\
 	mov	0, tmp1;						\
-98:	ld	[%g6 + AOFF_task_thread + AOFF_thread_uwinmask], tmp2;	\
+98:	ld	[%g6 + TI_UWINMASK], tmp2;				\
 	orcc	%g0, tmp2, %g0;						\
 	add	tmp1, 1, tmp1;						\
 	bne	98b;							\
diff -Nru a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h
--- a/include/asm-sparc/processor.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc/processor.h	Sat Aug 10 18:42:23 2002
@@ -44,6 +44,8 @@
  */
 #define TASK_SIZE	PAGE_OFFSET
 
+struct task_struct;
+
 struct fpq {
 	unsigned long *insn_addr;
 	unsigned long insn;
@@ -55,15 +57,8 @@
 
 /* The Sparc processor specific thread struct. */
 struct thread_struct {
-	unsigned long uwinmask __attribute__ ((aligned (8)));
 	struct pt_regs *kregs;
 
-	/* Context switch saved kernel state. */
-	unsigned long ksp __attribute__ ((aligned (8)));
-	unsigned long kpc;
-	unsigned long kpsr;
-	unsigned long kwim;
-
 	/* Special child fork kpsr/kwim values. */
 	unsigned long fork_kpsr __attribute__ ((aligned (8)));
 	unsigned long fork_kwim;
@@ -92,8 +87,8 @@
 #define SPARC_FLAG_UNALIGNED    0x2    /* is allowed to do unaligned accesses */
 
 #define INIT_THREAD  { \
-/* uwinmask, kregs, ksp, kpc, kpsr, kwim */ \
-   0,        0,     0,   0,   0,    0, \
+/* kregs, */ \
+   0,  \
 /* fork_kpsr, fork_kwim */ \
    0,         0, \
 /* reg_window */  \
@@ -115,10 +110,7 @@
 }
 
 /* Return saved PC of a blocked thread. */
-extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t)
-{
-	return t->kpc;
-}
+extern unsigned long thread_saved_pc(struct task_struct *t);
 
 /* Do necessary setup to start up a newly executed thread. */
 extern __inline__ void start_thread(struct pt_regs * regs, unsigned long pc,
@@ -163,7 +155,7 @@
 	if (!(__TSK) || (__TSK) == current || \
             (__TSK)->state == TASK_RUNNING) \
 		goto __out; \
-	fp = (__TSK)->thread.ksp + bias; \
+	fp = (__TSK)->thread_info->ksp + bias; \
 	do { \
 		/* Bogus frame pointer? */ \
 		if (fp < (task_base + sizeof(struct task_struct)) || \
@@ -185,21 +177,8 @@
 #define KSTK_ESP(tsk)  ((tsk)->thread.kregs->u_regs[UREG_FP])
 
 #ifdef __KERNEL__
-#define THREAD_SIZE (2*PAGE_SIZE)
 
 extern struct task_struct *last_task_used_math;
-
-/* Allocation and freeing of basic task resources. */
-BTFIXUPDEF_CALL(struct task_struct *, alloc_task_struct, void)
-BTFIXUPDEF_CALL(void, free_task_struct, struct task_struct *)
-BTFIXUPDEF_CALL(void, get_task_struct, struct task_struct *)
-
-#define alloc_task_struct() BTFIXUP_CALL(alloc_task_struct)()
-#define free_task_struct(tsk) BTFIXUP_CALL(free_task_struct)(tsk)
-#define get_task_struct(tsk) BTFIXUP_CALL(get_task_struct)(tsk)
-
-#define init_task	(init_task_union.task)
-#define init_stack	(init_task_union.stack)
 
 #define cpu_relax()	barrier()
 
diff -Nru a/include/asm-sparc/spinlock.h b/include/asm-sparc/spinlock.h
--- a/include/asm-sparc/spinlock.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc/spinlock.h	Sat Aug 10 18:42:23 2002
@@ -12,15 +12,7 @@
 
 #include <asm/psr.h>
 
-/*
- * Define this to use the verbose/debugging versions in
- * arch/sparc/lib/debuglocks.c
- *
- * Be sure to make dep whenever changing this option.
- */
-#define SPIN_LOCK_DEBUG
-
-#ifdef SPIN_LOCK_DEBUG
+#ifdef CONFIG_DEBUG_SPINLOCK
 struct _spinlock_debug {
 	unsigned char lock;
 	unsigned long owner_pc;
@@ -36,9 +28,9 @@
 extern int _spin_trylock(spinlock_t *lock);
 extern void _do_spin_unlock(spinlock_t *lock);
 
-#define spin_trylock(lp)	_spin_trylock(lp)
-#define spin_lock(lock)		_do_spin_lock(lock, "spin_lock")
-#define spin_unlock(lock)	_do_spin_unlock(lock)
+#define _raw_spin_trylock(lp)	_spin_trylock(lp)
+#define _raw_spin_lock(lock)	_do_spin_lock(lock, "spin_lock")
+#define _raw_spin_unlock(lock)	_do_spin_unlock(lock)
 
 struct _rwlock_debug {
 	volatile unsigned int lock;
@@ -56,35 +48,35 @@
 extern void _do_write_lock(rwlock_t *rw, char *str);
 extern void _do_write_unlock(rwlock_t *rw);
 
-#define read_lock(lock)	\
+#define _raw_read_lock(lock)	\
 do {	unsigned long flags; \
 	local_irq_save(flags); \
 	_do_read_lock(lock, "read_lock"); \
 	local_irq_restore(flags); \
 } while(0)
 
-#define read_unlock(lock) \
+#define _raw_read_unlock(lock) \
 do {	unsigned long flags; \
 	local_irq_save(flags); \
 	_do_read_unlock(lock, "read_unlock"); \
 	local_irq_restore(flags); \
 } while(0)
 
-#define write_lock(lock) \
+#define _raw_write_lock(lock) \
 do {	unsigned long flags; \
 	local_irq_save(flags); \
 	_do_write_lock(lock, "write_lock"); \
 	local_irq_restore(flags); \
 } while(0)
 
-#define write_unlock(lock) \
+#define _raw_write_unlock(lock) \
 do {	unsigned long flags; \
 	local_irq_save(flags); \
 	_do_write_unlock(lock); \
 	local_irq_restore(flags); \
 } while(0)
 
-#else /* !SPIN_LOCK_DEBUG */
+#else /* !CONFIG_DEBUG_SPINLOCK */
 
 typedef unsigned char spinlock_t;
 #define SPIN_LOCK_UNLOCKED	0
@@ -97,7 +89,7 @@
 	barrier(); \
 } while(*((volatile unsigned char *)lock))
 
-extern __inline__ void spin_lock(spinlock_t *lock)
+extern __inline__ void _raw_spin_lock(spinlock_t *lock)
 {
 	__asm__ __volatile__(
 	"\n1:\n\t"
@@ -117,7 +109,7 @@
 	: "g2", "memory", "cc");
 }
 
-extern __inline__ int spin_trylock(spinlock_t *lock)
+extern __inline__ int _raw_spin_trylock(spinlock_t *lock)
 {
 	unsigned int result;
 	__asm__ __volatile__("ldstub [%1], %0"
@@ -127,7 +119,7 @@
 	return (result == 0);
 }
 
-extern __inline__ void spin_unlock(spinlock_t *lock)
+extern __inline__ void _raw_spin_unlock(spinlock_t *lock)
 {
 	__asm__ __volatile__("stb %%g0, [%0]" : : "r" (lock) : "memory");
 }
@@ -178,7 +170,7 @@
 	: "g2", "g4", "memory", "cc");
 }
 
-#define read_lock(lock) \
+#define _raw_read_lock(lock) \
 do {	unsigned long flags; \
 	local_irq_save(flags); \
 	_read_lock(lock); \
@@ -198,14 +190,14 @@
 	: "g2", "g4", "memory", "cc");
 }
 
-#define read_unlock(lock) \
+#define _raw_read_unlock(lock) \
 do {	unsigned long flags; \
 	local_irq_save(flags); \
 	_read_unlock(lock); \
 	local_irq_restore(flags); \
 } while(0)
 
-extern __inline__ void write_lock(rwlock_t *rw)
+extern __inline__ void _raw_write_lock(rwlock_t *rw)
 {
 	register rwlock_t *lp asm("g1");
 	lp = rw;
@@ -218,9 +210,9 @@
 	: "g2", "g4", "memory", "cc");
 }
 
-#define write_unlock(rw)	do { (rw)->lock = 0; } while(0)
+#define _raw_write_unlock(rw)	do { (rw)->lock = 0; } while(0)
 
-#endif /* SPIN_LOCK_DEBUG */
+#endif /* CONFIG_DEBUG_SPINLOCK */
 
 #endif /* !(__ASSEMBLY__) */
 
diff -Nru a/include/asm-sparc/system.h b/include/asm-sparc/system.h
--- a/include/asm-sparc/system.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc/system.h	Sat Aug 10 18:42:23 2002
@@ -4,19 +4,18 @@
 #ifndef __SPARC_SYSTEM_H
 #define __SPARC_SYSTEM_H
 
+#include <linux/config.h>
 #include <linux/kernel.h>
+#include <linux/threads.h>	/* NR_CPUS */
 
 #include <asm/segment.h>
-
-#ifdef __KERNEL__
+#include <asm/thread_info.h>
 #include <asm/page.h>
-#include <asm/oplib.h>
+#include <asm/openprom.h>	/* romvec. XXX will be dealt later. Promise. */
 #include <asm/psr.h>
 #include <asm/ptrace.h>
 #include <asm/btfixup.h>
 
-#endif /* __KERNEL__ */
-
 #ifndef __ASSEMBLY__
 
 /*
@@ -48,6 +47,8 @@
 
 #define SUN4M_NCPUS            4              /* Architectural limit of sun4m. */
 
+extern struct thread_info *current_set[NR_CPUS];
+
 extern unsigned long empty_bad_page;
 extern unsigned long empty_bad_page_table;
 extern unsigned long empty_zero_page;
@@ -67,28 +68,43 @@
 		   void *fpqueue, unsigned long *fpqdepth);
 
 #ifdef CONFIG_SMP
-#define SWITCH_ENTER \
-	if(prev->flags & PF_USEDFPU) { \
+#define SWITCH_ENTER(prv) \
+	do {			\
+	if (test_tsk_thread_flag(prv, TIF_USEDFPU) { \
 		put_psr(get_psr() | PSR_EF); \
-		fpsave(&prev->thread.float_regs[0], &prev->thread.fsr, \
-		       &prev->thread.fpqueue[0], &prev->thread.fpqdepth); \
-		prev->flags &= ~PF_USEDFPU; \
-		prev->thread.kregs->psr &= ~PSR_EF; \
-	}
+		fpsave(&(prv)->thread.float_regs[0], &(prv)->thread.fsr, \
+		       &(prv)->thread.fpqueue[0], &(prv)->thread.fpqdepth); \
+		clear_tsk_thread_flag(prv, TIF_USEDFPU); \
+		(prv)->thread.kregs->psr &= ~PSR_EF; \
+	} \
+	} while(0)
 
-#define SWITCH_DO_LAZY_FPU
+#define SWITCH_DO_LAZY_FPU(next)	/* */
 #else
-#define SWITCH_ENTER
-#define SWITCH_DO_LAZY_FPU if(last_task_used_math != next) next->thread.kregs->psr&=~PSR_EF;
+#define SWITCH_ENTER(prv)		/* */
+#define SWITCH_DO_LAZY_FPU(nxt)	\
+	do {			\
+	if (last_task_used_math != (nxt))		\
+		(nxt)->thread.kregs->psr&=~PSR_EF;	\
+	} while(0)
 #endif
 
+// #define prepare_arch_schedule(prev)	task_lock(prev)
+// #define finish_arch_schedule(prev)	task_unlock(prev)
+#define prepare_arch_schedule(prev)	do{ }while(0)
+#define finish_arch_schedule(prev)	do{ }while(0)
+
 /*
  * Flush windows so that the VM switch which follows
  * would not pull the stack from under us.
  *
  * SWITCH_ENTER and SWITH_DO_LAZY_FPU do not work yet (e.g. SMP does not work)
+ * XXX WTF is the above comment? Found in late teen 2.4.x.
+ *
+ * XXX prepare_arch_switch() is much smarter than this in sparc64, are we sure?
+ * XXX Cosider if doing it the flush_user_windows way is faster (by uwinmask).
  */
-#define prepare_to_switch() do { \
+#define prepare_arch_switch(rq) do { \
 	__asm__ __volatile__( \
 	".globl\tflush_patch_switch\nflush_patch_switch:\n\t" \
 	"save %sp, -0x40, %sp; save %sp, -0x40, %sp; save %sp, -0x40, %sp\n\t" \
@@ -96,6 +112,7 @@
 	"save %sp, -0x40, %sp\n\t" \
 	"restore; restore; restore; restore; restore; restore; restore"); \
 } while(0)
+#define finish_arch_switch(rq)	do{ }while(0)
 
 	/* Much care has gone into this code, do not touch it.
 	 *
@@ -111,9 +128,8 @@
 #define switch_to(prev, next, last) do {						\
 	__label__ here;									\
 	register unsigned long task_pc asm("o7");					\
-	extern struct task_struct *current_set[NR_CPUS];				\
-	SWITCH_ENTER									\
-	SWITCH_DO_LAZY_FPU								\
+	SWITCH_ENTER(prev);								\
+	SWITCH_DO_LAZY_FPU(next);							\
 	next->active_mm->cpu_vm_mask |= (1 << smp_processor_id());			\
 	task_pc = ((unsigned long) &&here) - 0x8;					\
 	__asm__ __volatile__(								\
@@ -140,11 +156,13 @@
 	"nop\n\t"									\
 	"nop\n\t"									\
 	"jmpl	%%o7 + 0x8, %%g0\n\t"							\
-	" mov	%%g3, %0\n\t"								\
+	" ld	[%%g3 + %5], %0\n\t"								\
         : "=&r" (last)									\
-        : "r" (&(current_set[hard_smp_processor_id()])), "r" (next),			\
-	  "i" ((const unsigned long)(&((struct task_struct *)0)->thread.kpsr)),		\
-	  "i" ((const unsigned long)(&((struct task_struct *)0)->thread.ksp)),		\
+        : "r" (&(current_set[hard_smp_processor_id()])),	\
+	  "r" ((next)->thread_info),				\
+	  "i" (TI_KPSR),					\
+	  "i" (TI_KSP),						\
+	  "i" (TI_TASK),					\
 	  "r" (task_pc)									\
 	: "g1", "g2", "g3", "g4", "g5", "g7", "l0", "l1",				\
 	"l4", "l5", "l6", "l7", "i0", "i1", "i2", "i3", "i4", "i5", "o0", "o1", "o2",	\
diff -Nru a/include/asm-sparc/thread_info.h b/include/asm-sparc/thread_info.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-sparc/thread_info.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,138 @@
+/*
+ * thread_info.h: sparc low-level thread information
+ * adapted from the ppc version by Pete Zaitcev, which was
+ * adapted from the i386 version by Paul Mackerras
+ *
+ * Copyright (C) 2002  David Howells (dhowells@redhat.com)
+ * Copyright (c) 2002  Pete Zaitcev (zaitcev@yahoo.com)
+ * - Incorporating suggestions made by Linus Torvalds and Dave Miller
+ */
+
+#ifndef _ASM_THREAD_INFO_H
+#define _ASM_THREAD_INFO_H
+
+// XXX todo: comment thread_info components and see what breaks.
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#include <asm/btfixup.h>
+
+/*
+ * Low level task data.
+ *
+ * If you change this, change the TI_* offsets below to match. XXX check_asm.
+ *
+ * The uwinmask is a first class citizen among w_saved and friends.
+ * XXX Is this a good idea? wof.S/wuf.S have to use w_saved anyway,
+ *     so they waste a register on current, and an ld on fetching it.
+ */
+struct thread_info {
+	unsigned long		uwinmask;
+	struct task_struct	*task;		/* main task structure */
+	struct exec_domain	*exec_domain;	/* execution domain */
+	unsigned long		flags;		/* low level flags */
+
+	int			cpu;		/* cpu we're on */
+	int			preempt_count;
+	int			softirq_count;
+	int			hardirq_count;
+
+	/* Context switch saved kernel state. */
+	unsigned long ksp;	/* ... ksp __attribute__ ((aligned (8))); */
+	unsigned long kpc;
+	unsigned long kpsr;
+	unsigned long kwim;
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ */
+#define INIT_THREAD_INFO(tsk)			\
+{						\
+	uwinmask:	0,			\
+	task:		&tsk,			\
+	exec_domain:	&default_exec_domain,	\
+	flags:		0,			\
+	cpu:		0,			\
+}
+
+#define init_thread_info	(init_thread_union.thread_info)
+#define init_stack		(init_thread_union.stack)
+
+/* how to get the thread information struct from C */
+register struct thread_info *current_thread_info_reg asm("g6");
+#define current_thread_info()   (current_thread_info_reg)
+
+/*
+ * thread information allocation
+ */
+#ifdef CONFIG_SUN4
+#define THREAD_INFO_ORDER  0
+#else
+#define THREAD_INFO_ORDER  1
+#endif
+
+BTFIXUPDEF_CALL(struct thread_info *, alloc_thread_info, void)
+#define alloc_thread_info() BTFIXUP_CALL(alloc_thread_info)()
+
+BTFIXUPDEF_CALL(void, free_thread_info, struct thread_info *)
+#define free_thread_info(ti) BTFIXUP_CALL(free_thread_info)(ti)
+
+#define get_thread_info(ti)	get_task_struct((ti)->task)
+#define put_thread_info(ti)	put_task_struct((ti)->task)
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Size of kernel stack for each process.
+ * Observe the order of get_free_pages() in alloc_thread_info().
+ * The sun4 has 8K stack too, because it's short on memory, and 16K is a waste.
+ *
+ * XXX Watch how INIT_THREAD_SIZE evolves in linux/sched.h and elsewhere.
+ *     On 2.5.24 it happens to match 8192 magically.
+ */
+#define THREAD_SIZE		8192
+
+/*
+ * Offsets in thread_info structure, used in assembly code
+ */
+#define TI_UWINMASK	0x00	/* uwinmask */
+#define TI_TASK		0x04
+#define TI_EXECDOMAIN	0x08	/* exec_domain */
+#define TI_FLAGS	0x0c
+#define TI_CPU		0x10
+#define TI_PREEMPT	0x14	/* preempt_count */
+#define TI_SOFTIRQ	0x18	/* softirq_count */
+#define TI_HARDIRQ	0x1c	/* hardirq_count */
+#define TI_KSP		0x20	/* ksp */
+#define TI_KPC		0x24	/* kpc (ldd'ed with kpc) */
+#define TI_KPSR		0x28	/* kpsr */
+#define TI_KWIM		0x2c	/* kwim (ldd'ed with kpsr) */
+
+#define PREEMPT_ACTIVE		0x4000000
+
+/*
+ * thread information flag bit numbers
+ */
+#define TIF_SYSCALL_TRACE	0	/* syscall trace active */
+#define TIF_NOTIFY_RESUME	1	/* resumption notification requested */
+#define TIF_SIGPENDING		2	/* signal pending */
+#define TIF_NEED_RESCHED	3	/* rescheduling necessary */
+#define TIF_USEDFPU		8	/* FPU was used by this task
+					 * this quantum (SMP) */
+#define TIF_POLLING_NRFLAG	9	/* true if poll_idle() is polling
+					 * TIF_NEED_RESCHED */
+
+/* as above, but as bit values */
+#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
+#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
+#define _TIF_USEDFPU		(1<<TIF_USEDFPU)
+#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_THREAD_INFO_H */
diff -Nru a/include/asm-sparc/tlb.h b/include/asm-sparc/tlb.h
--- a/include/asm-sparc/tlb.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-sparc/tlb.h	Sat Aug 10 18:42:22 2002
@@ -1 +1,24 @@
+#ifndef _SPARC_TLB_H
+#define _SPARC_TLB_H
+
+#define tlb_start_vma(tlb, vma) \
+do {								\
+	flush_cache_range(vma, vma->vm_start, vma->vm_end);	\
+} while (0)
+
+#define tlb_end_vma(tlb, vma) \
+do {								\
+	flush_tlb_range(vma, vma->vm_start, vma->vm_end);	\
+} while (0)
+
+#define tlb_remove_tlb_entry(tlb, pte, address) \
+	do { } while (0)
+
+#define tlb_flush(tlb) \
+do {								\
+	flush_tlb_mm((tlb)->mm);				\
+} while (0)
+
 #include <asm-generic/tlb.h>
+
+#endif /* _SPARC_TLB_H */
diff -Nru a/include/asm-sparc/tlbflush.h b/include/asm-sparc/tlbflush.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-sparc/tlbflush.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,63 @@
+#ifndef _SPARC_TLBFLUSH_H
+#define _SPARC_TLBFLUSH_H
+
+#include <linux/config.h>
+#include <linux/mm.h>
+// #include <asm/processor.h>
+
+/*
+ * TLB flushing:
+ *
+ *  - flush_tlb() flushes the current mm struct TLBs	XXX Exists?
+ *  - flush_tlb_all() flushes all processes TLBs 
+ *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ *  - flush_tlb_page(vma, vmaddr) flushes one page
+ *  - flush_tlb_range(vma, start, end) flushes a range of pages
+ *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
+ *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
+ */
+
+#ifdef CONFIG_SMP
+
+BTFIXUPDEF_CALL(void, local_flush_tlb_all, void)
+BTFIXUPDEF_CALL(void, local_flush_tlb_mm, struct mm_struct *)
+BTFIXUPDEF_CALL(void, local_flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
+BTFIXUPDEF_CALL(void, local_flush_tlb_page, struct vm_area_struct *, unsigned long)
+
+#define local_flush_tlb_all() BTFIXUP_CALL(local_flush_tlb_all)()
+#define local_flush_tlb_mm(mm) BTFIXUP_CALL(local_flush_tlb_mm)(mm)
+#define local_flush_tlb_range(vma,start,end) BTFIXUP_CALL(local_flush_tlb_range)(vma,start,end)
+#define local_flush_tlb_page(vma,addr) BTFIXUP_CALL(local_flush_tlb_page)(vma,addr)
+
+extern void smp_flush_tlb_all(void);
+extern void smp_flush_tlb_mm(struct mm_struct *mm);
+extern void smp_flush_tlb_range(struct vm_area_struct *vma,
+				  unsigned long start,
+				  unsigned long end);
+extern void smp_flush_tlb_page(struct vm_area_struct *mm, unsigned long page);
+
+#endif /* CONFIG_SMP */
+
+BTFIXUPDEF_CALL(void, flush_tlb_all, void)
+BTFIXUPDEF_CALL(void, flush_tlb_mm, struct mm_struct *)
+BTFIXUPDEF_CALL(void, flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long)
+BTFIXUPDEF_CALL(void, flush_tlb_page, struct vm_area_struct *, unsigned long)
+
+// Thanks to Anton Blanchard, our pagetables became uncached in 2.4. Wee!
+// extern void flush_tlb_pgtables(struct mm_struct *mm,
+//     unsigned long start, unsigned long end);
+#define flush_tlb_pgtables(mm, start, end)	do{ }while(0)
+
+#define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)()
+#define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm)
+#define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end)
+#define flush_tlb_page(vma,addr) BTFIXUP_CALL(flush_tlb_page)(vma,addr)
+
+// #define flush_tlb() flush_tlb_mm(current->active_mm)	/* XXX Sure? */
+
+/*
+ * This is a kludge, until I know better. --zaitcev XXX
+ */
+#define flush_tlb_kernel_range(start, end) flush_tlb_all()
+
+#endif /* _SPARC_TLBFLUSH_H */
diff -Nru a/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h
--- a/include/asm-sparc/uaccess.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc/uaccess.h	Sat Aug 10 18:42:23 2002
@@ -10,6 +10,7 @@
 #ifdef __KERNEL__
 #include <linux/sched.h>
 #include <linux/string.h>
+#include <linux/errno.h>
 #include <asm/vac-ops.h>
 #include <asm/a.out.h>
 #endif
diff -Nru a/include/asm-sparc64/auxio.h b/include/asm-sparc64/auxio.h
--- a/include/asm-sparc64/auxio.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc64/auxio.h	Sat Aug 10 18:42:23 2002
@@ -80,14 +80,13 @@
 } while(0)
 
 #ifndef __ASSEMBLY__
-extern __inline__ void set_auxio(unsigned char bits_on, unsigned char bits_off)
+static __inline__ void set_auxio(unsigned char bits_on, unsigned char bits_off)
 {
 	unsigned char regval;
 	unsigned long flags;
 
-	save_flags(flags); cli();
-
-	if(AUXREG) {
+	local_irq_save(flags);
+	if (AUXREG) {
 		unsigned char newval;
 
 		regval = sbus_readb(AUXREG);
@@ -96,7 +95,7 @@
 		newval |= AUXIO_ORMEIN4M;
 		sbus_writeb(newval, AUXREG);
 	}
-	restore_flags(flags);
+	local_irq_restore(flags);
 }
 #endif /* !(__ASSEMBLY__) */
 
diff -Nru a/include/asm-sparc64/hardirq.h b/include/asm-sparc64/hardirq.h
--- a/include/asm-sparc64/hardirq.h	Sat Aug 10 18:42:21 2002
+++ b/include/asm-sparc64/hardirq.h	Sat Aug 10 18:42:21 2002
@@ -16,85 +16,91 @@
 typedef struct {
 	unsigned int __softirq_pending;
 	unsigned int __unused_1;
-#ifndef CONFIG_SMP
-	unsigned int __local_irq_count;
-#else
-	unsigned int __unused_on_SMP;	/* DaveM says use brlock for SMP irq. KAO */
-#endif
-	unsigned int __local_bh_count;
+	unsigned int __unused_2;
+	unsigned int __unused_3;
 	unsigned int __syscall_count;
         struct task_struct * __ksoftirqd_task;
 } ____cacheline_aligned irq_cpustat_t;
 
 #include <linux/irq_cpustat.h>	/* Standard mappings for irq_cpustat_t above */
-/* Note that local_irq_count() is replaced by sparc64 specific version for SMP */
-
-#ifndef CONFIG_SMP
-#define irq_enter(cpu, irq)	((void)(irq), local_irq_count(cpu)++)
-#define irq_exit(cpu, irq)	((void)(irq), local_irq_count(cpu)--)
-#else
-#undef local_irq_count
-#define local_irq_count(cpu)	(__brlock_array[cpu][BR_GLOBALIRQ_LOCK])
-#define irq_enter(cpu, irq)	br_read_lock(BR_GLOBALIRQ_LOCK)
-#define irq_exit(cpu, irq)	br_read_unlock(BR_GLOBALIRQ_LOCK)
-#endif
 
 /*
- * Are we in an interrupt context? Either doing bottom half
- * or hardware interrupt processing?
+ * We put the hardirq and softirq counter into the preemption
+ * counter. The bitmask has the following meaning:
+ *
+ * - bits 0-7 are the preemption count (max preemption depth: 256)
+ * - bits 8-15 are the softirq count (max # of softirqs: 256)
+ * - bits 16-23 are the hardirq count (max # of hardirqs: 256)
+ *
+ * - ( bit 26 is the PREEMPT_ACTIVE flag. )
+ *
+ * PREEMPT_MASK: 0x000000ff
+ * HARDIRQ_MASK: 0x0000ff00
+ * SOFTIRQ_MASK: 0x00ff0000
  */
-#define in_interrupt() ((local_irq_count(smp_processor_id()) + \
-		         local_bh_count(smp_processor_id())) != 0)
-
-/* This tests only the local processors hw IRQ context disposition.  */
-#define in_irq() (local_irq_count(smp_processor_id()) != 0)
-
-#ifndef CONFIG_SMP
-
-#define hardirq_trylock(cpu)	((void)(cpu), local_irq_count(smp_processor_id()) == 0)
-#define hardirq_endlock(cpu)	do { (void)(cpu); } while(0)
-
-#define synchronize_irq()	barrier()
 
-#define release_irqlock(cpu)	do { } while (0)
+#define PREEMPT_BITS	8
+#define SOFTIRQ_BITS	8
+#define HARDIRQ_BITS	8
+
+#define PREEMPT_SHIFT	0
+#define SOFTIRQ_SHIFT	(PREEMPT_SHIFT + PREEMPT_BITS)
+#define HARDIRQ_SHIFT	(SOFTIRQ_SHIFT + SOFTIRQ_BITS)
+
+#define __MASK(x)	((1UL << (x))-1)
+
+#define PREEMPT_MASK	(__MASK(PREEMPT_BITS) << PREEMPT_SHIFT)
+#define HARDIRQ_MASK	(__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)
+#define SOFTIRQ_MASK	(__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT)
+
+#define hardirq_count()	(preempt_count() & HARDIRQ_MASK)
+#define softirq_count()	(preempt_count() & SOFTIRQ_MASK)
+#define irq_count()	(preempt_count() & (HARDIRQ_MASK | SOFTIRQ_MASK))
+
+#define PREEMPT_OFFSET	(1UL << PREEMPT_SHIFT)
+#define SOFTIRQ_OFFSET	(1UL << SOFTIRQ_SHIFT)
+#define HARDIRQ_OFFSET	(1UL << HARDIRQ_SHIFT)
 
-#else /* (CONFIG_SMP) */
-
-static __inline__ int irqs_running(void)
-{
-	int i;
-
-	for (i = 0; i < NR_CPUS; i++) {
-		if (!cpu_online(i))
-			continue;
-		if (local_irq_count(i))
-			return 1;
-	}
-	return 0;
-}
-
-extern unsigned char global_irq_holder;
+/*
+ * The hardirq mask has to be large enough to have
+ * space for potentially all IRQ sources in the system
+ * nesting on a single CPU:
+ */
+#if (1 << HARDIRQ_BITS) < NR_IRQS
+# error HARDIRQ_BITS is too low!
+#endif
 
-static inline void release_irqlock(int cpu)
-{
-	/* if we didn't own the irq lock, just ignore... */
-	if(global_irq_holder == (unsigned char) cpu) {
-		global_irq_holder = NO_PROC_ID;
-		br_write_unlock(BR_GLOBALIRQ_LOCK);
-	}
-}
+/*
+ * Are we doing bottom half or hardware interrupt processing?
+ * Are we in a softirq context? Interrupt context?
+ */
+#define in_irq()		(hardirq_count())
+#define in_softirq()		(softirq_count())
+#define in_interrupt()		(irq_count())
 
-static inline int hardirq_trylock(int cpu)
-{
-	spinlock_t *lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock;
 
-	return (!local_irq_count(cpu) && !spin_is_locked(lock));
-}
+#define hardirq_trylock()	(!in_interrupt())
+#define hardirq_endlock()	do { } while (0)
 
-#define hardirq_endlock(cpu)	do { (void)(cpu); } while (0)
+#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
 
-extern void synchronize_irq(void);
+#if CONFIG_PREEMPT
+# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
+#else
+# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
+#endif
+#define irq_exit()							\
+do {									\
+		preempt_count() -= IRQ_EXIT_OFFSET;			\
+		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
+			do_softirq();					\
+		preempt_enable_no_resched();				\
+} while (0)
 
+#ifndef CONFIG_SMP
+# define synchronize_irq(irq)	barrier()
+#else
+  extern void synchronize_irq(unsigned int irq);
 #endif /* CONFIG_SMP */
 
 #endif /* !(__SPARC64_HARDIRQ_H) */
diff -Nru a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h
--- a/include/asm-sparc64/irq.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc64/irq.h	Sat Aug 10 18:42:23 2002
@@ -91,6 +91,7 @@
 #define IBF_PCI		0x02	/* Indicates PSYCHO/SABRE/SCHIZO PCI interrupt.	 */
 #define IBF_ACTIVE	0x04	/* This interrupt is active and has a handler.	 */
 #define IBF_MULTI	0x08	/* On PCI, indicates shared bucket.		 */
+#define IBF_INPROGRESS	0x10	/* IRQ is being serviced.			 */
 
 #define NUM_IVECS	8192
 extern struct ino_bucket ivector_table[NUM_IVECS];
@@ -111,6 +112,7 @@
 
 #define NR_IRQS    15
 
+#define irq_cannonicalize(irq)	(irq)
 extern void disable_irq(unsigned int);
 #define disable_irq_nosync disable_irq
 extern void enable_irq(unsigned int);
diff -Nru a/include/asm-sparc64/keyboard.h b/include/asm-sparc64/keyboard.h
--- a/include/asm-sparc64/keyboard.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc64/keyboard.h	Sat Aug 10 18:42:23 2002
@@ -13,38 +13,21 @@
 
 #ifdef __KERNEL__
 
-#include <linux/kernel.h>
-#include <linux/kd.h>
+/* We use the generic input layer for keyboard handling, thus
+ * some of this stuff should never be invoked.
+ */
+#define kbd_setkeycode(scancode, keycode)	(BUG(), 0)
+#define kbd_getkeycode(scancode)		(BUG(), 0)
 
-#define KEYBOARD_IRQ			1
-#define DISABLE_KBD_DURING_INTERRUPTS	0
+#define kbd_translate(keycode, keycodep, raw_mode) \
+	({ *(keycodep) = scancode; 1; })
+#define kbd_unexpected_up(keycode)		(0200)
 
-extern int pcikbd_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int pcikbd_getkeycode(unsigned int scancode);
-extern int pcikbd_translate(unsigned char scancode, unsigned char *keycode,
-			    char raw_mode);
-extern char pcikbd_unexpected_up(unsigned char keycode);
-extern void pcikbd_leds(unsigned char leds);
-extern void pcikbd_init_hw(void);
-extern unsigned char pcikbd_sysrq_xlate[128];
-
-#define kbd_setkeycode			pcikbd_setkeycode
-#define kbd_getkeycode			pcikbd_getkeycode
-#define kbd_translate			pcikbd_translate
-#define kbd_unexpected_up		pcikbd_unexpected_up
-#define kbd_leds			pcikbd_leds
-#define kbd_init_hw			pcikbd_init_hw
-#define kbd_sysrq_xlate			pcikbd_sysrq_xlate
-#define kbd_init			pcikbd_init
-
-#define compute_shiftstate		pci_compute_shiftstate
-#define getkeycode			pci_getkeycode
-#define setkeycode			pci_setkeycode
-#define getledstate			pci_getledstate
-#define setledstate			pci_setledstate
-#define register_leds			pci_register_leds
+#define kbd_leds(leds)				do { } while (0)
+#define kbd_init_hw()				do { } while (0)
 
 #define SYSRQ_KEY 0x54
+extern unsigned char kbd_sysrq_xlate[128];
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-sparc64/linkage.h b/include/asm-sparc64/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-sparc64/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/asm-sparc64/ns87303.h b/include/asm-sparc64/ns87303.h
--- a/include/asm-sparc64/ns87303.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc64/ns87303.h	Sat Aug 10 18:42:23 2002
@@ -78,9 +78,13 @@
 
 #ifdef __KERNEL__
 
+#include <linux/spinlock.h>
+
 #include <asm/system.h>
 #include <asm/io.h>
 
+extern spinlock_t ns87303_lock;
+
 static __inline__ int ns87303_modify(unsigned long port, unsigned int index,
 				     unsigned char clr, unsigned char set)
 {
@@ -96,14 +100,16 @@
 	if (index > 0x0d)
 		return -EINVAL;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&ns87303_lock, flags);
+
 	outb(index, port);
 	value = inb(port + 1);
 	value &= ~(reserved[index] | clr);
 	value |= set;
 	outb(value, port + 1);
 	outb(value, port + 1);
-	restore_flags(flags);
+
+	spin_unlock_irqrestore(&ns87303_lock, flags);
 
 	return 0;
 }
diff -Nru a/include/asm-sparc64/rwsem.h b/include/asm-sparc64/rwsem.h
--- a/include/asm-sparc64/rwsem.h	Sat Aug 10 18:42:21 2002
+++ b/include/asm-sparc64/rwsem.h	Sat Aug 10 18:42:21 2002
@@ -21,6 +21,7 @@
 extern struct rw_semaphore *FASTCALL(rwsem_down_read_failed(struct rw_semaphore *sem));
 extern struct rw_semaphore *FASTCALL(rwsem_down_write_failed(struct rw_semaphore *sem));
 extern struct rw_semaphore *FASTCALL(rwsem_wake(struct rw_semaphore *));
+extern struct rw_semaphore *FASTCALL(rwsem_downgrade_wake(struct rw_semaphore *));
 
 struct rw_semaphore {
 	signed int count;
@@ -40,14 +41,14 @@
 #define DECLARE_RWSEM(name) \
 	struct rw_semaphore name = __RWSEM_INITIALIZER(name)
 
-static inline void init_rwsem(struct rw_semaphore *sem)
+static __inline__ void init_rwsem(struct rw_semaphore *sem)
 {
 	sem->count = RWSEM_UNLOCKED_VALUE;
 	spin_lock_init(&sem->wait_lock);
 	INIT_LIST_HEAD(&sem->wait_list);
 }
 
-static inline void __down_read(struct rw_semaphore *sem)
+static __inline__ void __down_read(struct rw_semaphore *sem)
 {
 	__asm__ __volatile__(
 		"! beginning __down_read\n"
@@ -79,7 +80,32 @@
 		: "g5", "g7", "memory", "cc");
 }
 
-static inline void __down_write(struct rw_semaphore *sem)
+static __inline__ int __down_read_trylock(struct rw_semaphore *sem)
+{
+	int result;
+
+	__asm__ __volatile__(
+		"! beginning __down_read_trylock\n"
+		"1:\tlduw	[%1], %%g5\n\t"
+		"add		%%g5, 1, %%g7\n\t"
+		"cmp		%%g7, 0\n\t"
+		"bl,pn		%%icc, 2f\n\t"
+		" mov		0, %0\n\t"
+		"cas		[%1], %%g5, %%g7\n\t"
+		"cmp		%%g5, %%g7\n\t"
+		"bne,pn		%%icc, 1b\n\t"
+		" mov		1, %0\n\t"
+		"membar		#StoreLoad | #StoreStore\n"
+		"2:\n\t"
+		"! ending __down_read_trylock"
+		: "=&r" (result)
+                : "r" (sem)
+		: "g5", "g7", "memory", "cc");
+
+	return result;
+}
+
+static __inline__ void __down_write(struct rw_semaphore *sem)
 {
 	__asm__ __volatile__(
 		"! beginning __down_write\n\t"
@@ -111,7 +137,34 @@
 		: "g1", "g5", "g7", "memory", "cc");
 }
 
-static inline void __up_read(struct rw_semaphore *sem)
+static __inline__ int __down_write_trylock(struct rw_semaphore *sem)
+{
+	int result;
+
+	__asm__ __volatile__(
+		"! beginning __down_write_trylock\n\t"
+		"sethi		%%hi(%2), %%g1\n\t"
+		"or		%%g1, %%lo(%2), %%g1\n"
+		"1:\tlduw	[%1], %%g5\n\t"
+		"cmp		%%g5, 0\n\t"
+		"bne,pn		%%icc, 2f\n\t"
+		" mov		0, %0\n\t"
+		"add		%%g5, %%g1, %%g7\n\t"
+		"cas		[%1], %%g5, %%g7\n\t"
+		"cmp		%%g5, %%g7\n\t"
+		"bne,pn		%%icc, 1b\n\t"
+		" mov		1, %0\n\t"
+		"membar		#StoreLoad | #StoreStore\n"
+		"2:\n\t"
+		"! ending __down_write_trylock"
+		: "=&r" (result)
+		: "r" (sem), "i" (RWSEM_ACTIVE_WRITE_BIAS)
+		: "g1", "g5", "g7", "memory", "cc");
+
+	return result;
+}
+
+static __inline__ void __up_read(struct rw_semaphore *sem)
 {
 	__asm__ __volatile__(
 		"! beginning __up_read\n\t"
@@ -146,7 +199,7 @@
 		: "g1", "g5", "g7", "memory", "cc");
 }
 
-static inline void __up_write(struct rw_semaphore *sem)
+static __inline__ void __up_write(struct rw_semaphore *sem)
 {
 	__asm__ __volatile__(
 		"! beginning __up_write\n\t"
@@ -179,7 +232,40 @@
 		: "g1", "g5", "g7", "memory", "cc");
 }
 
-static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+static __inline__ void __downgrade_write(struct rw_semaphore *sem)
+{
+	__asm__ __volatile__(
+		"! beginning __up_write\n\t"
+		"sethi		%%hi(%2), %%g1\n\t"
+		"or		%%g1, %%lo(%2), %%g1\n"
+		"1:\tlduw	[%0], %%g5\n\t"
+		"sub		%%g5, %%g1, %%g7\n\t"
+		"cas		[%0], %%g5, %%g7\n\t"
+		"cmp		%%g5, %%g7\n\t"
+		"bne,pn		%%icc, 1b\n\t"
+		" sub		%%g7, %%g1, %%g7\n\t"
+		"cmp		%%g7, 0\n\t"
+		"bl,pn		%%icc, 3f\n\t"
+		" membar	#StoreLoad | #StoreStore\n"
+		"2:\n\t"
+		".subsection 2\n"
+		"3:\tmov	%0, %%g5\n\t"
+		"save		%%sp, -160, %%sp\n\t"
+		"mov		%%g2, %%l2\n\t"
+		"mov		%%g3, %%l3\n\t"
+		"call		%1\n\t"
+		" mov		%%g5, %%o0\n\t"
+		"mov		%%l2, %%g2\n\t"
+		"ba,pt		%%xcc, 2b\n\t"
+		" restore	%%l3, %%g0, %%g3\n\t"
+		".previous\n\t"
+		"! ending __up_write"
+		: : "r" (sem), "i" (rwsem_downgrade_wake),
+		    "i" (RWSEM_WAITING_BIAS)
+		: "g1", "g5", "g7", "memory", "cc");
+}
+
+static __inline__ int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
 {
 	int tmp = delta;
 
@@ -200,7 +286,7 @@
 
 #define rwsem_atomic_add rwsem_atomic_update
 
-static inline __u16 rwsem_cmpxchgw(struct rw_semaphore *sem, __u16 __old, __u16 __new)
+static __inline__ __u16 rwsem_cmpxchgw(struct rw_semaphore *sem, __u16 __old, __u16 __new)
 {
 	u32 old = (sem->count & 0xffff0000) | (u32) __old;
 	u32 new = (old & 0xffff0000) | (u32) __new;
@@ -223,7 +309,7 @@
 	return prev & 0xffff;
 }
 
-static inline signed long rwsem_cmpxchg(struct rw_semaphore *sem, signed long old, signed long new)
+static __inline__ signed long rwsem_cmpxchg(struct rw_semaphore *sem, signed long old, signed long new)
 {
 	return cmpxchg(&sem->count,old,new);
 }
diff -Nru a/include/asm-sparc64/sab82532.h b/include/asm-sparc64/sab82532.h
--- a/include/asm-sparc64/sab82532.h	Sat Aug 10 18:42:24 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,380 +0,0 @@
-/* $Id: sab82532.h,v 1.7 2001/05/23 23:09:10 ecd Exp $
- * sab82532.h: Register Definitions for the Siemens SAB82532 DUSCC
- *
- * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
- */
-
-#ifndef _SPARC64_SAB82532_H
-#define _SPARC64_SAB82532_H
-
-#include <linux/types.h>
-#include <linux/serial.h>
-#include <linux/circ_buf.h>
-
-struct sab82532_async_rd_regs {
-	u8	rfifo[0x20];	/* Receive FIFO				*/
-	u8	star;		/* Status Register			*/
-	u8	__pad1;
-	u8	mode;		/* Mode Register			*/
-	u8	timr;		/* Timer Register			*/
-	u8	xon;		/* XON Character			*/
-	u8	xoff;		/* XOFF Character			*/
-	u8	tcr;		/* Termination Character Register	*/
-	u8	dafo;		/* Data Format				*/
-	u8	rfc;		/* RFIFO Control Register		*/
-	u8	__pad2;
-	u8	rbcl;		/* Receive Byte Count Low		*/
-	u8	rbch;		/* Receive Byte Count High		*/
-	u8	ccr0;		/* Channel Configuration Register 0	*/
-	u8	ccr1;		/* Channel Configuration Register 1	*/
-	u8	ccr2;		/* Channel Configuration Register 2	*/
-	u8	ccr3;		/* Channel Configuration Register 3	*/
-	u8	__pad3[4];
-	u8	vstr;		/* Version Status Register		*/
-	u8	__pad4[3];
-	u8	gis;		/* Global Interrupt Status		*/
-	u8	ipc;		/* Interrupt Port Configuration		*/
-	u8	isr0;		/* Interrupt Status 0			*/
-	u8	isr1;		/* Interrupt Status 1			*/
-	u8	pvr;		/* Port Value Register			*/
-	u8	pis;		/* Port Interrupt Status		*/
-	u8	pcr;		/* Port Configuration Register		*/
-	u8	ccr4;		/* Channel Configuration Register 4	*/
-};
-
-struct sab82532_async_wr_regs {
-	u8	xfifo[0x20];	/* Transmit FIFO			*/
-	u8	cmdr;		/* Command Register			*/
-	u8	__pad1;
-	u8	mode;
-	u8	timr;
-	u8	xon;
-	u8	xoff;
-	u8	tcr;
-	u8	dafo;
-	u8	rfc;
-	u8	__pad2;
-	u8	xbcl;		/* Transmit Byte Count Low		*/
-	u8	xbch;		/* Transmit Byte Count High		*/
-	u8	ccr0;
-	u8	ccr1;
-	u8	ccr2;
-	u8	ccr3;
-	u8	tsax;		/* Time-Slot Assignment Reg. Transmit	*/
-	u8	tsar;		/* Time-Slot Assignment Reg. Receive	*/
-	u8	xccr;		/* Transmit Channel Capacity Register	*/
-	u8	rccr;		/* Receive Channel Capacity Register	*/
-	u8	bgr;		/* Baud Rate Generator Register		*/
-	u8	tic;		/* Transmit Immediate Character		*/
-	u8	mxn;		/* Mask XON Character			*/
-	u8	mxf;		/* Mask XOFF Character			*/
-	u8	iva;		/* Interrupt Vector Address		*/
-	u8	ipc;
-	u8	imr0;		/* Interrupt Mask Register 0		*/
-	u8	imr1;		/* Interrupt Mask Register 1		*/
-	u8	pvr;
-	u8	pim;		/* Port Interrupt Mask			*/
-	u8	pcr;
-	u8	ccr4;
-};
-
-struct sab82532_async_rw_regs {	/* Read/Write registers			*/
-	u8	__pad1[0x20];
-	u8	__pad2;
-	u8	__pad3;
-	u8	mode;
-	u8	timr;
-	u8	xon;
-	u8	xoff;
-	u8	tcr;
-	u8	dafo;
-	u8	rfc;
-	u8	__pad4;
-	u8	__pad5;
-	u8	__pad6;
-	u8	ccr0;
-	u8	ccr1;
-	u8	ccr2;
-	u8	ccr3;
-	u8	__pad7;
-	u8	__pad8;
-	u8	__pad9;
-	u8	__pad10;
-	u8	__pad11;
-	u8	__pad12;
-	u8	__pad13;
-	u8	__pad14;
-	u8	__pad15;
-	u8	ipc;
-	u8	__pad16;
-	u8	__pad17;
-	u8	pvr;
-	u8	__pad18;
-	u8	pcr;
-	u8	ccr4;
-};
-
-union sab82532_async_regs {
-	__volatile__ struct sab82532_async_rd_regs	r;
-	__volatile__ struct sab82532_async_wr_regs	w;
-	__volatile__ struct sab82532_async_rw_regs	rw;
-};
-
-#define NR_PORTS			 2
-
-union sab82532_irq_status {
-	unsigned short			 stat;
-	struct {
-		unsigned char		 isr0;
-		unsigned char		 isr1;
-	} sreg;
-};
-
-struct sab82532 {
-	int				 magic;
-	int				 baud_base;
-	union sab82532_async_regs	*regs;
-	int				 irq;
-	int				 flags;		/* defined in tty.h */
-	int				 type;		/* SAB82532 version */
-	struct tty_struct		*tty;
-	int				 read_status_mask;
-	int				 ignore_status_mask;
-	int				 timeout;
-	int				 xmit_fifo_size;
-	int				 recv_fifo_size;
-	int				 custom_divisor;
-	int				 baud;
-	unsigned int			 cec_timeout;
-	unsigned int			 tec_timeout;
-	int				 x_char;
-	int				 close_delay;
-	unsigned short			 closing_wait;
-	unsigned short			 closing_wait2;
-	unsigned long			 irqflags;
-	int				 is_console;
-	unsigned char			 interrupt_mask0;
-	unsigned char			 interrupt_mask1;
-	unsigned char			 pvr_dtr_bit;
-	unsigned char			 pvr_dsr_bit;
-	unsigned char			 dcd;
-	unsigned char			 cts;
-	unsigned char			 dsr;
-	unsigned long			 event;
-	unsigned long			 last_active;
-	int				 line;
-	int				 count;
-	int				 blocked_open;
-	long				 session;
-	long				 pgrp;
-	struct circ_buf			 xmit;
-	struct tq_struct		 tqueue;
-	struct tq_struct		 tqueue_hangup;
-	struct async_icount		 icount;
-	struct termios			 normal_termios;
-	struct termios			 callout_termios;
-	wait_queue_head_t		 open_wait;
-	wait_queue_head_t		 close_wait;
-	wait_queue_head_t		 delta_msr_wait;
-	struct sab82532			*next;
-	struct sab82532			*prev;
-};
-
-
-/* irqflags bits */
-#define SAB82532_ALLS			0x00000001
-#define SAB82532_XPR			0x00000002
-
-
-/* RFIFO Status Byte */
-#define SAB82532_RSTAT_PE		0x80
-#define SAB82532_RSTAT_FE		0x40
-#define SAB82532_RSTAT_PARITY		0x01
-
-/* Status Register (STAR) */
-#define SAB82532_STAR_XDOV		0x80
-#define SAB82532_STAR_XFW		0x40
-#define SAB82532_STAR_RFNE		0x20
-#define SAB82532_STAR_FCS		0x10
-#define SAB82532_STAR_TEC		0x08
-#define SAB82532_STAR_CEC		0x04
-#define SAB82532_STAR_CTS		0x02
-
-/* Command Register (CMDR) */
-#define SAB82532_CMDR_RMC		0x80
-#define SAB82532_CMDR_RRES		0x40
-#define SAB82532_CMDR_RFRD		0x20
-#define SAB82532_CMDR_STI		0x10
-#define SAB82532_CMDR_XF		0x08
-#define SAB82532_CMDR_XRES		0x01
-
-/* Mode Register (MODE) */
-#define SAB82532_MODE_FRTS		0x40
-#define SAB82532_MODE_FCTS		0x20
-#define SAB82532_MODE_FLON		0x10
-#define SAB82532_MODE_RAC		0x08
-#define SAB82532_MODE_RTS		0x04
-#define SAB82532_MODE_TRS		0x02
-#define SAB82532_MODE_TLP		0x01
-
-/* Timer Register (TIMR) */
-#define SAB82532_TIMR_CNT_MASK		0xe0
-#define SAB82532_TIMR_VALUE_MASK	0x1f
-
-/* Data Format (DAFO) */
-#define SAB82532_DAFO_XBRK		0x40
-#define SAB82532_DAFO_STOP		0x20
-#define SAB82532_DAFO_PAR_SPACE		0x00
-#define SAB82532_DAFO_PAR_ODD		0x08
-#define SAB82532_DAFO_PAR_EVEN		0x10
-#define SAB82532_DAFO_PAR_MARK		0x18
-#define SAB82532_DAFO_PARE		0x04
-#define SAB82532_DAFO_CHL8		0x00
-#define SAB82532_DAFO_CHL7		0x01
-#define SAB82532_DAFO_CHL6		0x02
-#define SAB82532_DAFO_CHL5		0x03
-
-/* RFIFO Control Register (RFC) */
-#define SAB82532_RFC_DPS		0x40
-#define SAB82532_RFC_DXS		0x20
-#define SAB82532_RFC_RFDF		0x10
-#define SAB82532_RFC_RFTH_1		0x00
-#define SAB82532_RFC_RFTH_4		0x04
-#define SAB82532_RFC_RFTH_16		0x08
-#define SAB82532_RFC_RFTH_32		0x0c
-#define SAB82532_RFC_TCDE		0x01
-
-/* Received Byte Count High (RBCH) */
-#define SAB82532_RBCH_DMA		0x80
-#define SAB82532_RBCH_CAS		0x20
-
-/* Transmit Byte Count High (XBCH) */
-#define SAB82532_XBCH_DMA		0x80
-#define SAB82532_XBCH_CAS		0x20
-#define SAB82532_XBCH_XC		0x10
-
-/* Channel Configuration Register 0 (CCR0) */
-#define SAB82532_CCR0_PU		0x80
-#define SAB82532_CCR0_MCE		0x40
-#define SAB82532_CCR0_SC_NRZ		0x00
-#define SAB82532_CCR0_SC_NRZI		0x08
-#define SAB82532_CCR0_SC_FM0		0x10
-#define SAB82532_CCR0_SC_FM1		0x14
-#define SAB82532_CCR0_SC_MANCH		0x18
-#define SAB82532_CCR0_SM_HDLC		0x00
-#define SAB82532_CCR0_SM_SDLC_LOOP	0x01
-#define SAB82532_CCR0_SM_BISYNC		0x02
-#define SAB82532_CCR0_SM_ASYNC		0x03
-
-/* Channel Configuration Register 1 (CCR1) */
-#define SAB82532_CCR1_ODS		0x10
-#define SAB82532_CCR1_BCR		0x08
-#define SAB82532_CCR1_CM_MASK		0x07
-
-/* Channel Configuration Register 2 (CCR2) */
-#define SAB82532_CCR2_SOC1		0x80
-#define SAB82532_CCR2_SOC0		0x40
-#define SAB82532_CCR2_BR9		0x80
-#define SAB82532_CCR2_BR8		0x40
-#define SAB82532_CCR2_BDF		0x20
-#define SAB82532_CCR2_SSEL		0x10
-#define SAB82532_CCR2_XCS0		0x20
-#define SAB82532_CCR2_RCS0		0x10
-#define SAB82532_CCR2_TOE		0x08
-#define SAB82532_CCR2_RWX		0x04
-#define SAB82532_CCR2_DIV		0x01
-
-/* Channel Configuration Register 3 (CCR3) */
-#define SAB82532_CCR3_PSD		0x01
-
-/* Time Slot Assignment Register Transmit (TSAX) */
-#define SAB82532_TSAX_TSNX_MASK		0xfc
-#define SAB82532_TSAX_XCS2		0x02	/* see also CCR2 */
-#define SAB82532_TSAX_XCS1		0x01
-
-/* Time Slot Assignment Register Receive (TSAR) */
-#define SAB82532_TSAR_TSNR_MASK		0xfc
-#define SAB82532_TSAR_RCS2		0x02	/* see also CCR2 */
-#define SAB82532_TSAR_RCS1		0x01
-
-/* Version Status Register (VSTR) */
-#define SAB82532_VSTR_CD		0x80
-#define SAB82532_VSTR_DPLA		0x40
-#define SAB82532_VSTR_VN_MASK		0x0f
-#define SAB82532_VSTR_VN_1		0x00
-#define SAB82532_VSTR_VN_2		0x01
-#define SAB82532_VSTR_VN_3_2		0x02
-
-/* Global Interrupt Status Register (GIS) */
-#define SAB82532_GIS_PI			0x80
-#define SAB82532_GIS_ISA1		0x08
-#define SAB82532_GIS_ISA0		0x04
-#define SAB82532_GIS_ISB1		0x02
-#define SAB82532_GIS_ISB0		0x01
-
-/* Interrupt Vector Address (IVA) */
-#define SAB82532_IVA_MASK		0xf1
-
-/* Interrupt Port Configuration (IPC) */
-#define SAB82532_IPC_VIS		0x80
-#define SAB82532_IPC_SLA1		0x10
-#define SAB82532_IPC_SLA0		0x08
-#define SAB82532_IPC_CASM		0x04
-#define SAB82532_IPC_IC_OPEN_DRAIN	0x00
-#define SAB82532_IPC_IC_ACT_LOW		0x01
-#define SAB82532_IPC_IC_ACT_HIGH	0x03
-
-/* Interrupt Status Register 0 (ISR0) */
-#define SAB82532_ISR0_TCD		0x80
-#define SAB82532_ISR0_TIME		0x40
-#define SAB82532_ISR0_PERR		0x20
-#define SAB82532_ISR0_FERR		0x10
-#define SAB82532_ISR0_PLLA		0x08
-#define SAB82532_ISR0_CDSC		0x04
-#define SAB82532_ISR0_RFO		0x02
-#define SAB82532_ISR0_RPF		0x01
-
-/* Interrupt Status Register 1 (ISR1) */
-#define SAB82532_ISR1_BRK		0x80
-#define SAB82532_ISR1_BRKT		0x40
-#define SAB82532_ISR1_ALLS		0x20
-#define SAB82532_ISR1_XOFF		0x10
-#define SAB82532_ISR1_TIN		0x08
-#define SAB82532_ISR1_CSC		0x04
-#define SAB82532_ISR1_XON		0x02
-#define SAB82532_ISR1_XPR		0x01
-
-/* Interrupt Mask Register 0 (IMR0) */
-#define SAB82532_IMR0_TCD		0x80
-#define SAB82532_IMR0_TIME		0x40
-#define SAB82532_IMR0_PERR		0x20
-#define SAB82532_IMR0_FERR		0x10
-#define SAB82532_IMR0_PLLA		0x08
-#define SAB82532_IMR0_CDSC		0x04
-#define SAB82532_IMR0_RFO		0x02
-#define SAB82532_IMR0_RPF		0x01
-
-/* Interrupt Mask Register 1 (IMR1) */
-#define SAB82532_IMR1_BRK		0x80
-#define SAB82532_IMR1_BRKT		0x40
-#define SAB82532_IMR1_ALLS		0x20
-#define SAB82532_IMR1_XOFF		0x10
-#define SAB82532_IMR1_TIN		0x08
-#define SAB82532_IMR1_CSC		0x04
-#define SAB82532_IMR1_XON		0x02
-#define SAB82532_IMR1_XPR		0x01
-
-/* Port Interrupt Status Register (PIS) */
-#define SAB82532_PIS_SYNC_B		0x08
-#define SAB82532_PIS_DTR_B		0x04
-#define SAB82532_PIS_DTR_A		0x02
-#define SAB82532_PIS_SYNC_A		0x01
-
-/* Channel Configuration Register 4 (CCR4) */
-#define SAB82532_CCR4_MCK4		0x80
-#define SAB82532_CCR4_EBRG		0x40
-#define SAB82532_CCR4_TST1		0x20
-#define SAB82532_CCR4_ICD		0x10
-
-
-#endif /* !(_SPARC64_SAB82532_H) */
diff -Nru a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
--- a/include/asm-sparc64/smp.h	Sat Aug 10 18:42:22 2002
+++ b/include/asm-sparc64/smp.h	Sat Aug 10 18:42:22 2002
@@ -65,11 +65,19 @@
 #include <asm/atomic.h>
 
 extern unsigned char boot_cpu_id;
+
+extern unsigned long phys_cpu_present_map;
+#define cpu_possible(cpu)	(phys_cpu_present_map & (1UL << (cpu)))
+
 extern unsigned long cpu_online_map;
 #define cpu_online(cpu)		(cpu_online_map & (1UL << (cpu)))
+
 extern atomic_t sparc64_num_cpus_online;
 #define num_online_cpus()	(atomic_read(&sparc64_num_cpus_online))
 
+extern atomic_t sparc64_num_cpus_possible;
+#define num_possible_cpus()	(atomic_read(&sparc64_num_cpus_possible))
+
 static inline int any_online_cpu(unsigned long mask)
 {
 	if ((mask &= cpu_online_map) != 0UL)
@@ -80,10 +88,6 @@
 /*
  *	General functions that each host system must provide.
  */
-
-extern void smp_callin(void);
-extern void smp_boot_cpus(void);
-extern void smp_store_cpu_info(int id);
 
 extern __inline__ int hard_smp_processor_id(void)
 {
diff -Nru a/include/asm-sparc64/smplock.h b/include/asm-sparc64/smplock.h
--- a/include/asm-sparc64/smplock.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc64/smplock.h	Sat Aug 10 18:42:23 2002
@@ -24,13 +24,10 @@
 /*
  * Release global kernel lock and global interrupt lock
  */
-#define release_kernel_lock(task, cpu)		\
+#define release_kernel_lock(task)		\
 do {						\
-	if (unlikely(task->lock_depth >= 0)) {	\
+	if (unlikely(task->lock_depth >= 0))	\
 		spin_unlock(&kernel_flag);	\
-		release_irqlock(cpu);		\
-		local_irq_enable();			\
-	}					\
 } while (0)
 
 /*
diff -Nru a/include/asm-sparc64/softirq.h b/include/asm-sparc64/softirq.h
--- a/include/asm-sparc64/softirq.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc64/softirq.h	Sat Aug 10 18:42:23 2002
@@ -6,21 +6,20 @@
 #ifndef __SPARC64_SOFTIRQ_H
 #define __SPARC64_SOFTIRQ_H
 
-#include <asm/atomic.h>
+#include <linux/preempt.h>
 #include <asm/hardirq.h>
 #include <asm/system.h>		/* for membar() */
 
-#define local_bh_disable()	do { barrier(); preempt_disable(); local_bh_count(smp_processor_id())++; } while (0)
-#define __local_bh_enable()	do { local_bh_count(smp_processor_id())--; preempt_enable(); barrier(); } while (0)
-#define local_bh_enable()			  \
-do { if (!--local_bh_count(smp_processor_id()) && \
-	 softirq_pending(smp_processor_id())) {   \
-		do_softirq();			  \
-		local_irq_enable();			  \
-     }						  \
-     preempt_enable();				  \
+#define local_bh_disable()	\
+	do { preempt_count() += SOFTIRQ_OFFSET; barrier(); } while (0)
+#define __local_bh_enable()	\
+	do { barrier(); preempt_count() -= SOFTIRQ_OFFSET; } while (0)
+#define local_bh_enable()				\
+do {	__local_bh_enable();				\
+	if (unlikely(!in_interrupt() &&			\
+	    softirq_pending(smp_processor_id())))	\
+		do_softirq();				\
+	preempt_check_resched();			\
 } while (0)
-
-#define in_softirq() (local_bh_count(smp_processor_id()) != 0)
 
 #endif /* !(__SPARC64_SOFTIRQ_H) */
diff -Nru a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h
--- a/include/asm-sparc64/system.h	Sat Aug 10 18:42:20 2002
+++ b/include/asm-sparc64/system.h	Sat Aug 10 18:42:20 2002
@@ -66,28 +66,16 @@
 #define local_irq_save(flags)		((flags) = read_pil_and_cli())
 #define local_irq_restore(flags)		setipl((flags))
 
-#ifndef CONFIG_SMP
-#define cli() local_irq_disable()
-#define sti() local_irq_enable()
-#define save_flags(x) local_save_flags(x)
-#define restore_flags(x) local_irq_restore(x)
-#define save_and_cli(x) local_irq_save(x)
-#else
-
-#ifndef __ASSEMBLY__
-extern void __global_cli(void);
-extern void __global_sti(void);
-extern unsigned long __global_save_flags(void);
-extern void __global_restore_flags(unsigned long flags);
-#endif
-
-#define cli()			__global_cli()
-#define sti()			__global_sti()
-#define save_flags(x)		((x) = __global_save_flags())
-#define restore_flags(flags)	__global_restore_flags(flags)
-#define save_and_cli(flags)	do { save_flags(flags); cli(); } while(0)
-
-#endif
+/* On sparc64 IRQ flags are the PIL register.  A value of zero
+ * means all interrupt levels are enabled, any other value means
+ * only IRQ levels greater than that value will be received.
+ * Consequently this means that the lowest IRQ level is one.
+ */
+#define irqs_disabled()		\
+({	unsigned long flags;	\
+	local_save_flags(flags);\
+	(flags > 0);		\
+})
 
 #define nop() 		__asm__ __volatile__ ("nop")
 
@@ -132,6 +120,17 @@
 
 #ifndef __ASSEMBLY__
 
+extern void sun_do_break(void);
+extern int serial_console;
+extern int stop_a_enabled;
+
+static __inline__ int con_is_present(void)
+{
+	return serial_console ? 0 : 1;
+}
+
+extern struct pt_regs *kbd_pt_regs;
+
 extern void synchronize_user_stack(void);
 
 extern void __flushw_user(void);
@@ -150,7 +149,8 @@
 do {	spin_unlock_irq(&(prev)->switch_lock);	\
 } while (0)
 
-
+#define task_running(rq, p) \
+	((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock))
 
 #ifndef CONFIG_DEBUG_SPINLOCK
 #define CHECK_LOCKS(PREV)	do { } while(0)
diff -Nru a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h
--- a/include/asm-sparc64/thread_info.h	Sat Aug 10 18:42:23 2002
+++ b/include/asm-sparc64/thread_info.h	Sat Aug 10 18:42:23 2002
@@ -114,6 +114,8 @@
 
 /*
  * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
  */
 #ifndef __ASSEMBLY__
 
@@ -122,6 +124,7 @@
 	task:		&tsk,				\
 	flags:		((unsigned long)ASI_P) << TI_FLAG_CURRENT_DS_SHIFT,	\
 	exec_domain:	&default_exec_domain,		\
+	preempt_count:	1,				\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
diff -Nru a/include/asm-x86_64/linkage.h b/include/asm-x86_64/linkage.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-x86_64/linkage.h	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,6 @@
+#ifndef __ASM_LINKAGE_H
+#define __ASM_LINKAGE_H
+
+/* Nothing to see here... */
+
+#endif
diff -Nru a/include/linux/atalk.h b/include/linux/atalk.h
--- a/include/linux/atalk.h	Sat Aug 10 18:42:21 2002
+++ b/include/linux/atalk.h	Sat Aug 10 18:42:21 2002
@@ -1,86 +1,89 @@
+#ifndef __LINUX_ATALK_H__
+#define __LINUX_ATALK_H__
 /*
- *	AppleTalk networking structures
+ * AppleTalk networking structures
  *
- *	The following are directly referenced from the University Of Michigan
- *	netatalk for compatibility reasons.
+ * The following are directly referenced from the University Of Michigan
+ * netatalk for compatibility reasons.
  */
-
-#ifndef __LINUX_ATALK_H__
-#define __LINUX_ATALK_H__
-
 #define ATPORT_FIRST	1
 #define ATPORT_RESERVED	128
-#define ATPORT_LAST	254 /* 254 is only legal on localtalk */ 
+#define ATPORT_LAST	254		/* 254 is only legal on localtalk */ 
 #define ATADDR_ANYNET	(__u16)0
 #define ATADDR_ANYNODE	(__u8)0
 #define ATADDR_ANYPORT  (__u8)0
 #define ATADDR_BCAST	(__u8)255
 #define DDP_MAXSZ	587
-#define DDP_MAXHOPS     15      /* 4 bits of hop counter */
+#define DDP_MAXHOPS     15		/* 4 bits of hop counter */
 
 #define SIOCATALKDIFADDR       (SIOCPROTOPRIVATE + 0)
 
-struct at_addr 
-{
+struct atalk_addr {
 	__u16	s_net;
 	__u8	s_node;
 };
 
-struct sockaddr_at 
-{
-	sa_family_t	sat_family;
-	__u8		sat_port;
-	struct at_addr	sat_addr;
-	char		sat_zero[ 8 ];
+struct sockaddr_at {
+	sa_family_t	  sat_family;
+	__u8		  sat_port;
+	struct atalk_addr sat_addr;
+	char		  sat_zero[8];
 };
 
-struct netrange 
-{
+struct atalk_netrange {
 	__u8	nr_phase;
 	__u16	nr_firstnet;
 	__u16	nr_lastnet;
 };
 
-struct atalk_route
-{
-	struct net_device *dev;
-	struct at_addr target;
-	struct at_addr gateway;
-	int flags;
+struct atalk_route {
+	struct net_device  *dev;
+	struct atalk_addr  target;
+	struct atalk_addr  gateway;
+	int		   flags;
 	struct atalk_route *next;
 };
 
-struct atalk_iface
-{
-	struct net_device *dev;
-	struct at_addr address;		/* Our address */
-	int status;			/* What are we doing? */
+/**
+ *	struct atalk_iface - AppleTalk Interface
+ *	@dev - Network device associated with this interface
+ *	@address - Our address
+ *	@status - What are we doing?
+ *	@nets - Associated direct netrange
+ *	@next - next element in the list of interfaces
+ */
+struct atalk_iface {
+	struct net_device	*dev;
+	struct atalk_addr	address;
+	int			status;
 #define ATIF_PROBE	1		/* Probing for an address */
 #define ATIF_PROBE_FAIL	2		/* Probe collided */
-	struct netrange nets;		/* Associated direct netrange */
-	struct atalk_iface *next;
+	struct atalk_netrange	nets;
+	struct atalk_iface	*next;
 };
 	
-struct atalk_sock
-{
-	unsigned short dest_net;
-	unsigned short src_net;
-	unsigned char dest_node;
-	unsigned char src_node;
-	unsigned char dest_port;
-	unsigned char src_port;
+struct atalk_sock {
+	unsigned short	dest_net;
+	unsigned short	src_net;
+	unsigned char	dest_node;
+	unsigned char	src_node;
+	unsigned char	dest_port;
+	unsigned char	src_port;
 };
 
 #ifdef __KERNEL__
 
 #include <asm/byteorder.h>
 
-struct ddpehdr
-{
+struct ddpehdr {
 #ifdef __LITTLE_ENDIAN_BITFIELD
-	__u16	deh_len:10, deh_hops:4, deh_pad:2;
+	__u16	deh_len:10,
+		deh_hops:4,
+		deh_pad:2;
 #else
-	__u16	deh_pad:2, deh_hops:4, deh_len:10;
+	__u16	deh_pad:2,
+		deh_hops:4,
+		deh_len:10;
 #endif
 	__u16	deh_sum;
 	__u16	deh_dnet;
@@ -92,30 +95,35 @@
 	/* And netatalk apps expect to stick the type in themselves */
 };
 
+static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb)
+{
+	return (struct ddpehdr *)skb->h.raw;
+}
+
 /*
  *	Don't drop the struct into the struct above.  You'll get some
  *	surprise padding.
  */
- 
-struct ddpebits
-{
+struct ddpebits {
 #ifdef __LITTLE_ENDIAN_BITFIELD
-	__u16	deh_len:10, deh_hops:4, deh_pad:2;
+	__u16	deh_len:10,
+		deh_hops:4,
+		deh_pad:2;
 #else
-	__u16	deh_pad:2, deh_hops:4, deh_len:10;
+	__u16	deh_pad:2,
+		deh_hops:4,
+		deh_len:10;
 #endif
 };
 
-/*
- *	Short form header
- */
- 
-struct ddpshdr
-{
+/* Short form header */
+struct ddpshdr {
 #ifdef __LITTLE_ENDIAN_BITFIELD
-	__u16	dsh_len:10, dsh_pad:6;
+	__u16	dsh_len:10,
+		dsh_pad:6;
 #else
-	__u16	dsh_pad:6, dsh_len:10;
+	__u16	dsh_pad:6,
+		dsh_len:10;
 #endif
 	__u8	dsh_dport;
 	__u8	dsh_sport;
@@ -123,9 +131,7 @@
 };
 
 /* AppleTalk AARP headers */
-
-struct elapaarp
-{
+struct elapaarp {
 	__u16	hw_type;
 #define AARP_HW_TYPE_ETHERNET		1
 #define AARP_HW_TYPE_TOKENRING		2
@@ -147,30 +153,44 @@
 	__u8	pa_dst_node		__attribute__ ((packed));	
 };
 
-#define AARP_EXPIRY_TIME	(5*60*HZ)	/* Not specified - how long till we drop a resolved entry */
-#define AARP_HASH_SIZE		16		/* Size of hash table */
-#define AARP_TICK_TIME		(HZ/5)		/* Fast retransmission timer when resolving */
-#define AARP_RETRANSMIT_LIMIT	10		/* Send 10 requests then give up (2 seconds) */
-#define AARP_RESOLVE_TIME	(10*HZ)		/* Some value bigger than total retransmit time + a bit for last reply to appear and to stop continual requests */
+static __inline__ struct elapaarp *aarp_hdr(struct sk_buff *skb)
+{
+	return (struct elapaarp *)skb->h.raw;
+}
+
+/* Not specified - how long till we drop a resolved entry */
+#define AARP_EXPIRY_TIME	(5 * 60 * HZ)
+/* Size of hash table */
+#define AARP_HASH_SIZE		16
+/* Fast retransmission timer when resolving */
+#define AARP_TICK_TIME		(HZ / 5)
+/* Send 10 requests then give up (2 seconds) */
+#define AARP_RETRANSMIT_LIMIT	10
+/*
+ * Some value bigger than total retransmit time + a bit for last reply to
+ * appear and to stop continual requests
+ */
+#define AARP_RESOLVE_TIME	(10 * HZ)
 
 extern struct datalink_proto *ddp_dl, *aarp_dl;
 extern void aarp_proto_init(void);
-/* Inter module exports */
 
-/*
- *	Give a device find its atif control structure
- */
+/* Inter module exports */
 
+/* Give a device find its atif control structure */
 static inline struct atalk_iface *atalk_find_dev(struct net_device *dev)
 {
 	return dev->atalk_ptr;
 }
 
-extern struct at_addr *atalk_find_dev_addr(struct net_device *dev);
-extern struct net_device *atrtr_get_dev(struct at_addr *sa);
-extern int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr);
-extern void aarp_send_probe(struct net_device *dev, struct at_addr *addr);
-extern void aarp_device_down(struct net_device *dev);
+extern struct atalk_addr *atalk_find_dev_addr(struct net_device *dev);
+extern struct net_device *atrtr_get_dev(struct atalk_addr *sa);
+extern int		 aarp_send_ddp(struct net_device *dev,
+				       struct sk_buff *skb,
+				       struct atalk_addr *sa, void *hwaddr);
+extern void		 aarp_send_probe(struct net_device *dev,
+					 struct atalk_addr *addr);
+extern void		 aarp_device_down(struct net_device *dev);
 
 #ifdef MODULE
 extern void aarp_cleanup_module(void);
diff -Nru a/include/linux/blkdev.h b/include/linux/blkdev.h
--- a/include/linux/blkdev.h	Sat Aug 10 18:42:21 2002
+++ b/include/linux/blkdev.h	Sat Aug 10 18:42:21 2002
@@ -279,6 +279,7 @@
 extern void grok_partitions(kdev_t dev, long size);
 extern int wipe_partitions(kdev_t dev);
 extern void register_disk(struct gendisk *dev, kdev_t first, unsigned minors, struct block_device_operations *ops, long size);
+extern void check_partition(struct gendisk *disk, struct block_device *bdev);
 extern void generic_make_request(struct bio *bio);
 extern inline request_queue_t *bdev_get_queue(struct block_device *bdev);
 extern void blk_put_request(struct request *);
diff -Nru a/include/linux/brlock.h b/include/linux/brlock.h
--- a/include/linux/brlock.h	Sat Aug 10 18:42:22 2002
+++ b/include/linux/brlock.h	Sat Aug 10 18:42:22 2002
@@ -34,7 +34,6 @@
 
 /* Register bigreader lock indices here. */
 enum brlock_indices {
-	BR_GLOBALIRQ_LOCK,
 	BR_NETPROTO_LOCK,
 	BR_LLC_LOCK,
 	__BR_END
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h	Sat Aug 10 18:42:22 2002
+++ b/include/linux/device.h	Sat Aug 10 18:42:22 2002
@@ -85,6 +85,24 @@
 			    int (*callback)(struct device_driver * drv, void * data));
 
 
+/* driverfs interface for exporting bus attributes */
+
+struct bus_attribute {
+	struct attribute	attr;
+	ssize_t (*show)(struct bus_type *, char * buf, size_t count, loff_t off);
+	ssize_t (*store)(struct bus_type *, const char * buf, size_t count, loff_t off);
+};
+
+#define BUS_ATTR(_name,_str,_mode,_show,_store)	\
+struct bus_attribute bus_attr_##_name = { 		\
+	.attr = {.name	= _str,	.mode	= _mode },	\
+	.show	= _show,				\
+	.store	= _store,				\
+};
+
+extern int bus_create_file(struct bus_type *, struct bus_attribute *);
+extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
+
 struct device_driver {
 	char			* name;
 	struct bus_type		* bus;
@@ -123,6 +141,24 @@
 extern int driver_for_each_dev(struct device_driver * drv, void * data, 
 			       int (*callback)(struct device * dev, void * data));
 
+
+/* driverfs interface for exporting driver attributes */
+
+struct driver_attribute {
+	struct attribute	attr;
+	ssize_t (*show)(struct device_driver *, char * buf, size_t count, loff_t off);
+	ssize_t (*store)(struct device_driver *, const char * buf, size_t count, loff_t off);
+};
+
+#define DRIVER_ATTR(_name,_str,_mode,_show,_store)	\
+struct driver_attribute driver_attr_##_name = { 		\
+	.attr = {.name	= _str,	.mode	= _mode },	\
+	.show	= _show,				\
+	.store	= _store,				\
+};
+
+extern int driver_create_file(struct device_driver *, struct driver_attribute *);
+extern void driver_remove_file(struct device_driver *, struct driver_attribute *);
 
 struct device {
 	struct list_head g_list;        /* node in depth-first order list */
diff -Nru a/include/linux/fs.h b/include/linux/fs.h
--- a/include/linux/fs.h	Sat Aug 10 18:42:21 2002
+++ b/include/linux/fs.h	Sat Aug 10 18:42:21 2002
@@ -356,8 +356,8 @@
 	struct block_device *	bd_contains;
 	unsigned		bd_block_size;
 	unsigned long		bd_offset;
-	struct semaphore	bd_part_sem;
 	unsigned		bd_part_count;
+	int			bd_invalidated;
 };
 
 struct inode {
@@ -1131,7 +1131,9 @@
  */
 #define bio_data_dir(bio)	((bio)->bi_rw & 1)
 
-extern int check_disk_change(kdev_t);
+extern int check_disk_change(struct block_device *);
+extern int full_check_disk_change(struct block_device *);
+extern int __check_disk_change(dev_t);
 extern int invalidate_inodes(struct super_block *);
 extern int invalidate_device(kdev_t, int);
 extern void invalidate_inode_pages(struct inode *);
@@ -1304,32 +1306,6 @@
 	res = dentry->d_parent->d_inode->i_ino;
 	read_unlock(&dparent_lock);
 	return res;
-}
-
-/* NOTE NOTE NOTE: this interface _will_ change in a couple of patches */
-
-static inline int dev_lock_part(kdev_t dev)
-{
-	struct block_device *bdev = bdget(kdev_t_to_nr(dev));
-	if (!bdev)
-		return -ENOMEM;
-	if (!down_trylock(&bdev->bd_part_sem)) {
-		if (!bdev->bd_part_count)
-			return 0;
-		up(&bdev->bd_part_sem);
-	}
-	bdput(bdev);
-	return -EBUSY;
-}
-
-static inline void dev_unlock_part(kdev_t dev)
-{
-	struct block_device *bdev = bdget(kdev_t_to_nr(dev));
-	if (!bdev)
-		BUG();
-	up(&bdev->bd_part_sem);
-	bdput(bdev);
-	bdput(bdev);
 }
 
 #endif /* __KERNEL__ */
diff -Nru a/include/linux/ide.h b/include/linux/ide.h
--- a/include/linux/ide.h	Sat Aug 10 18:42:21 2002
+++ b/include/linux/ide.h	Sat Aug 10 18:42:21 2002
@@ -1161,7 +1161,7 @@
 
 extern int ata_register_device(struct ata_device *, struct ata_operations *);
 extern int ata_unregister_device(struct ata_device *drive);
-extern int ata_revalidate(kdev_t i_rdev);
+extern int ide_revalidate(kdev_t i_rdev);
 extern void ide_driver_module(void);
 
 #ifdef CONFIG_PCI
diff -Nru a/include/linux/if_ether.h b/include/linux/if_ether.h
--- a/include/linux/if_ether.h	Sat Aug 10 18:42:23 2002
+++ b/include/linux/if_ether.h	Sat Aug 10 18:42:23 2002
@@ -96,6 +96,6 @@
 	unsigned char	h_dest[ETH_ALEN];	/* destination eth addr	*/
 	unsigned char	h_source[ETH_ALEN];	/* source ether addr	*/
 	unsigned short	h_proto;		/* packet type ID field	*/
-};
+} __attribute__((packed));
 
 #endif	/* _LINUX_IF_ETHER_H */
diff -Nru a/include/linux/init.h b/include/linux/init.h
--- a/include/linux/init.h	Sat Aug 10 18:42:20 2002
+++ b/include/linux/init.h	Sat Aug 10 18:42:20 2002
@@ -177,13 +177,23 @@
 #define __devinitdata
 #define __devexit
 #define __devexitdata
-#define __devexit_p(x)  &(x)
 #else
 #define __devinit __init
 #define __devinitdata __initdata
 #define __devexit __exit
 #define __devexitdata __exitdata
-#define __devexit_p(x)  0
+#endif
+
+/* Functions marked as __devexit may be discarded at kernel link time, depending
+   on config options.  Newer versions of binutils detect references from
+   retained sections to discarded sections and flag an error.  Pointers to
+   __devexit functions must use __devexit_p(function_name), the wrapper will
+   insert either the function_name or NULL, depending on the config options.
+ */
+#if defined(MODULE) || defined(CONFIG_HOTPLUG)
+#define __devexit_p(x) x
+#else
+#define __devexit_p(x) NULL
 #endif
 
 #endif /* _LINUX_INIT_H */
diff -Nru a/include/linux/ipx.h b/include/linux/ipx.h
--- a/include/linux/ipx.h	Sat Aug 10 18:42:23 2002
+++ b/include/linux/ipx.h	Sat Aug 10 18:42:23 2002
@@ -24,15 +24,13 @@
 #define IPX_DLTITF	0
 #define IPX_CRTITF	1
 
-typedef struct ipx_route_definition
-{
+struct ipx_route_definition {
 	__u32         ipx_network;
 	__u32         ipx_router_network;
 	unsigned char ipx_router_node[IPX_NODE_LEN];
-}	ipx_route_definition;
+};
 
-typedef struct ipx_interface_definition
-{
+struct ipx_interface_definition {
 	__u32         ipx_network;
 	unsigned char ipx_device[16];
 	unsigned char ipx_dlink_type;
@@ -47,13 +45,12 @@
 #define IPX_PRIMARY		1
 #define IPX_INTERNAL		2
 	unsigned char ipx_node[IPX_NODE_LEN];
-}	ipx_interface_definition;
+};
 	
-typedef struct ipx_config_data
-{
+struct ipx_config_data {
 	unsigned char	ipxcfg_auto_select_primary;
 	unsigned char	ipxcfg_auto_create_interfaces;
-}	ipx_config_data;
+};
 
 /*
  * OLD Route Definition for backward compatibility.
@@ -77,13 +74,4 @@
 #define SIOCAIPXPRISLT		(SIOCPROTOPRIVATE+1)
 #define SIOCIPXCFGDATA		(SIOCPROTOPRIVATE+2)
 #define SIOCIPXNCPCONN		(SIOCPROTOPRIVATE+3)
-
-#ifdef __KERNEL__
-#include <linux/skbuff.h>
-
-extern int ipxrtr_route_skb(struct sk_buff *);
-extern int ipx_if_offset(unsigned long ipx_net_number);
-extern void ipx_remove_socket(struct sock *sk);
-#endif /* def __KERNEL__ */
-
 #endif /* def _IPX_H_ */
diff -Nru a/include/linux/isdn.h b/include/linux/isdn.h
--- a/include/linux/isdn.h	Sat Aug 10 18:42:22 2002
+++ b/include/linux/isdn.h	Sat Aug 10 18:42:22 2002
@@ -245,18 +245,12 @@
 #define ISDN_TIMER_MODEMPLUS   2
 #define ISDN_TIMER_MODEMRING   4
 #define ISDN_TIMER_MODEMXMIT   8
-#define ISDN_TIMER_NETDIAL    16 
 #define ISDN_TIMER_NETHANGUP  32
 #define ISDN_TIMER_CARRIER   256 /* Wait for Carrier */
 #define ISDN_TIMER_FAST      (ISDN_TIMER_MODEMREAD | ISDN_TIMER_MODEMPLUS | \
                               ISDN_TIMER_MODEMXMIT)
 #define ISDN_TIMER_SLOW      (ISDN_TIMER_MODEMRING | ISDN_TIMER_NETHANGUP | \
-                              ISDN_TIMER_NETDIAL | ISDN_TIMER_CARRIER)
-
-/* Timeout-Values for isdn_net_dial() */
-#define ISDN_TIMER_DTIMEOUT10 (10*HZ/(ISDN_TIMER_02SEC*(ISDN_TIMER_RES+1)))
-#define ISDN_TIMER_DTIMEOUT15 (15*HZ/(ISDN_TIMER_02SEC*(ISDN_TIMER_RES+1)))
-#define ISDN_TIMER_DTIMEOUT60 (60*HZ/(ISDN_TIMER_02SEC*(ISDN_TIMER_RES+1)))
+                              ISDN_TIMER_CARRIER)
 
 /* GLOBAL_FLAGS */
 #define ISDN_GLOBAL_STOPPED 1
@@ -291,9 +285,10 @@
 typedef struct isdn_net_local_s {
   ulong                  magic;
   char                   name[10];     /* Name of device                   */
+  struct timer_list      dial_timer;   /* dial timeout                     */
+  int                    dial_event;   /* event in case of timer expiry    */
   struct net_device_stats stats;       /* Ethernet Statistics              */
-  int                    isdn_device;  /* Index to isdn-device             */
-  int                    isdn_channel; /* Index to isdn-channel            */
+  int                    isdn_slot;    /* Index to isdn device/channel     */
   int			 ppp_slot;     /* PPPD device slot number          */
   int                    pre_device;   /* Preselected isdn-device          */
   int                    pre_channel;  /* Preselected isdn-channel         */
@@ -302,7 +297,6 @@
   int                    dialretry;    /* Counter for Dialout-retries      */
   int                    dialmax;      /* Max. Number of Dial-retries      */
   int                    cbdelay;      /* Delay before Callback starts     */
-  int                    dtimer;       /* Timeout-counter for dialing      */
   char                   msn[ISDN_MSNLEN]; /* MSNs/EAZs for this interface */
   u_char                 cbhup;        /* Flag: Reject Call before Callback*/
   u_char                 dialstate;    /* State for dialing                */
@@ -387,12 +381,12 @@
 
 /* the interface itself */
 typedef struct isdn_net_dev_s {
-  isdn_net_local *local;
+  isdn_net_local local;
   isdn_net_local *queue;               /* circular list of all bundled
 					  channels, which are currently
 					  online                           */
   spinlock_t queue_lock;               /* lock to protect queue            */
-  void *next;                          /* Pointer to next isdn-interface   */
+  struct list_head global_list;        /* global list of all isdn_net_devs */
   struct net_device dev;               /* interface to upper levels        */
 #ifdef CONFIG_ISDN_PPP
   ippp_bundle * pb;		/* pointer to the common bundle structure
@@ -480,9 +474,7 @@
 					 /* 2 = B-Channel is up, deliver d.*/
   int                   dialing;         /* Dial in progress or ATA        */
   int                   rcvsched;        /* Receive needs schedule         */
-  int                   isdn_driver;	 /* Index to isdn-driver           */
-  int                   isdn_channel;    /* Index to isdn-channel          */
-  int                   drv_index;       /* Index to dev->usage            */
+  int                   isdn_slot;	 /* Index to isdn-driver/channel   */
   int                   ncarrier;        /* Flag: schedule NO CARRIER      */
   unsigned char         last_cause[8];   /* Last cause message             */
   unsigned char         last_num[ISDN_MSNLEN];
@@ -608,24 +600,10 @@
 	infostruct        *infochain;                /* List of open info-devs.    */
 	wait_queue_head_t info_waitq;               /* Wait-Queue for isdninfo    */
 	struct timer_list timer;		       /* Misc.-function Timer       */
-	int               chanmap[ISDN_MAX_CHANNELS];/* Map minor->device-channel  */
-	int               drvmap[ISDN_MAX_CHANNELS]; /* Map minor->driver-index    */
-	int               usage[ISDN_MAX_CHANNELS];  /* Used by tty/ip/voice       */
-	char              num[ISDN_MAX_CHANNELS][ISDN_MSNLEN];
-	/* Remote number of active ch.*/
-	int               m_idx[ISDN_MAX_CHANNELS];  /* Index for mdm....          */
 	driver            *drv[ISDN_MAX_DRIVERS];    /* Array of drivers           */
-	isdn_net_dev      *netdev;		       /* Linked list of net-if's    */
 	char              drvid[ISDN_MAX_DRIVERS][20];/* Driver-ID                 */
 	struct task_struct *profd;                   /* For iprofd                 */
 	modem             mdm;		       /* tty-driver-data            */
-	isdn_net_dev      *rx_netdev[ISDN_MAX_CHANNELS]; /* rx netdev-pointers     */
-	isdn_net_dev      *st_netdev[ISDN_MAX_CHANNELS]; /* stat netdev-pointers   */
-	ulong             ibytes[ISDN_MAX_CHANNELS]; /* Statistics incoming bytes  */
-	ulong             obytes[ISDN_MAX_CHANNELS]; /* Statistics outgoing bytes  */
-	int               v110emu[ISDN_MAX_CHANNELS];/* V.110 emulator-mode 0=none */
-	atomic_t          v110use[ISDN_MAX_CHANNELS];/* Usage-Semaphore for stream */
-	isdn_v110_stream  *v110[ISDN_MAX_CHANNELS];  /* V.110 private data         */
 	struct semaphore  sem;                       /* serialize list access*/
 	unsigned long     global_features;
 #ifdef CONFIG_DEVFS_FS
diff -Nru a/include/linux/isdnif.h b/include/linux/isdnif.h
--- a/include/linux/isdnif.h	Sat Aug 10 18:42:20 2002
+++ b/include/linux/isdnif.h	Sat Aug 10 18:42:20 2002
@@ -418,9 +418,7 @@
 		char display[85];/* display message data		*/ 
 		isdn_cmd_stat isdn_io; /* ISDN IO-parameter/result	*/
 		aux_s aux;	/* for modem commands/indications	*/
-#ifdef CONFIG_ISDN_TTY_FAX
 		T30_s	*fax;	/* Pointer to ttys fax struct		*/
-#endif
 		ulong userdata;	/* User Data */
 	} parm;
 } isdn_ctrl;
diff -Nru a/include/linux/linkage.h b/include/linux/linkage.h
--- a/include/linux/linkage.h	Sat Aug 10 18:42:20 2002
+++ b/include/linux/linkage.h	Sat Aug 10 18:42:20 2002
@@ -2,6 +2,7 @@
 #define _LINUX_LINKAGE_H
 
 #include <linux/config.h>
+#include <asm/linkage.h>
 
 #ifdef __cplusplus
 #define CPP_ASMLINKAGE extern "C"
@@ -9,36 +10,14 @@
 #define CPP_ASMLINKAGE
 #endif
 
-#if defined __i386__
-#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
-#elif defined __ia64__
-#define asmlinkage CPP_ASMLINKAGE __attribute__((syscall_linkage))
-#else
+#ifndef asmlinkage
 #define asmlinkage CPP_ASMLINKAGE
 #endif
 
-#ifdef __arm__
-#define __ALIGN .align 0
-#define __ALIGN_STR ".align 0"
-#else
-#ifdef __mc68000__
-#define __ALIGN .align 4
-#define __ALIGN_STR ".align 4"
-#else
-#ifdef __sh__
-#define __ALIGN .balign 4
-#define __ALIGN_STR ".balign 4"
-#else
-#if defined(__i386__) && defined(CONFIG_X86_ALIGNMENT_16)
-#define __ALIGN .align 16,0x90
-#define __ALIGN_STR ".align 16,0x90"
-#else
-#define __ALIGN .align 4,0x90
-#define __ALIGN_STR ".align 4,0x90"
+#ifndef __ALIGN
+#define __ALIGN		.align 4,0x90
+#define __ALIGN_STR	".align 4,0x90"
 #endif
-#endif /* __sh__ */
-#endif /* __mc68000__ */
-#endif /* __arm__ */
 
 #ifdef __ASSEMBLY__
 
@@ -52,13 +31,11 @@
 
 #endif
 
-# define NORET_TYPE    /**/
-# define ATTRIB_NORET  __attribute__((noreturn))
-# define NORET_AND     noreturn,
+#define NORET_TYPE    /**/
+#define ATTRIB_NORET  __attribute__((noreturn))
+#define NORET_AND     noreturn,
 
-#ifdef __i386__
-#define FASTCALL(x)	x __attribute__((regparm(3)))
-#else
+#ifndef FASTCALL
 #define FASTCALL(x)	x
 #endif
 
diff -Nru a/include/linux/mm.h b/include/linux/mm.h
--- a/include/linux/mm.h	Sat Aug 10 18:42:20 2002
+++ b/include/linux/mm.h	Sat Aug 10 18:42:20 2002
@@ -450,7 +450,6 @@
 
 struct zone_t;
 /* filemap.c */
-extern void remove_inode_page(struct page *);
 extern unsigned long page_unuse(struct page *);
 extern void truncate_inode_pages(struct address_space *, loff_t);
 
diff -Nru a/include/linux/mtd/nftl.h b/include/linux/mtd/nftl.h
--- a/include/linux/mtd/nftl.h	Sat Aug 10 18:42:22 2002
+++ b/include/linux/mtd/nftl.h	Sat Aug 10 18:42:22 2002
@@ -104,6 +104,7 @@
         unsigned int nb_blocks;		/* number of physical blocks */
         unsigned int nb_boot_blocks;	/* number of blocks used by the bios */
         struct erase_info instr;
+	struct gendisk *disk;
 };
 
 int NFTL_mount(struct NFTLrecord *s);
diff -Nru a/include/linux/pagemap.h b/include/linux/pagemap.h
--- a/include/linux/pagemap.h	Sat Aug 10 18:42:20 2002
+++ b/include/linux/pagemap.h	Sat Aug 10 18:42:20 2002
@@ -42,8 +42,14 @@
 extern struct page * find_or_create_page(struct address_space *mapping,
 				unsigned long index, unsigned int gfp_mask);
 
-extern struct page * grab_cache_page(struct address_space *mapping,
-				unsigned long index);
+/*
+ * Returns locked page at given index in given cache, creating it if needed.
+ */
+static inline struct page *grab_cache_page(struct address_space *mapping, unsigned long index)
+{
+	return find_or_create_page(mapping, index, mapping->gfp_mask);
+}
+
 extern struct page * grab_cache_page_nowait(struct address_space *mapping,
 				unsigned long index);
 extern struct page * read_cache_page(struct address_space *mapping,
@@ -52,6 +58,8 @@
 
 extern int add_to_page_cache(struct page *page,
 		struct address_space *mapping, unsigned long index);
+extern void remove_from_page_cache(struct page *page);
+extern void __remove_from_page_cache(struct page *page);
 
 static inline void ___add_to_page_cache(struct page *page,
 		struct address_space *mapping, unsigned long index)
diff -Nru a/include/linux/personality.h b/include/linux/personality.h
--- a/include/linux/personality.h	Sat Aug 10 18:42:23 2002
+++ b/include/linux/personality.h	Sat Aug 10 18:42:23 2002
@@ -62,6 +62,7 @@
 	PER_RISCOS =		0x000c,
 	PER_SOLARIS =		0x000d | STICKY_TIMEOUTS,
 	PER_UW7 =		0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO,
+	PER_OSF4 =		0x000f,			 /* OSF/1 v4 */
 	PER_MASK =		0x00ff,
 };
 
diff -Nru a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h
--- a/include/linux/pkt_sched.h	Sat Aug 10 18:42:23 2002
+++ b/include/linux/pkt_sched.h	Sat Aug 10 18:42:23 2002
@@ -248,6 +248,48 @@
        __u8            grio;
 };
 
+/* HTB section */
+#define TC_HTB_NUMPRIO		8
+#define TC_HTB_MAXDEPTH		8
+#define TC_HTB_PROTOVER		3 /* the same as HTB and TC's major */
+
+struct tc_htb_opt
+{
+	struct tc_ratespec 	rate;
+	struct tc_ratespec 	ceil;
+	__u32	buffer;
+	__u32	cbuffer;
+	__u32	quantum;
+	__u32	level;		/* out only */
+	__u32	prio;
+};
+struct tc_htb_glob
+{
+	__u32 version;		/* to match HTB/TC */
+    	__u32 rate2quantum;	/* bps->quantum divisor */
+    	__u32 defcls;		/* default class number */
+	__u32 debug;		/* debug flags */
+
+	/* stats */
+	__u32 direct_pkts; /* count of non shapped packets */
+};
+enum
+{
+	TCA_HTB_UNSPEC,
+	TCA_HTB_PARMS,
+	TCA_HTB_INIT,
+	TCA_HTB_CTAB,
+	TCA_HTB_RTAB,
+};
+struct tc_htb_xstats
+{
+	__u32 lends;
+	__u32 borrows;
+	__u32 giants;	/* too big packets (rate will not be accurate) */
+	__u32 tokens;
+	__u32 ctokens;
+};
+
 /* CBQ section */
 
 #define TC_CBQ_MAXPRIO		8
diff -Nru a/include/linux/preempt.h b/include/linux/preempt.h
--- a/include/linux/preempt.h	Sat Aug 10 18:42:21 2002
+++ b/include/linux/preempt.h	Sat Aug 10 18:42:21 2002
@@ -5,19 +5,29 @@
 
 #define preempt_count() (current_thread_info()->preempt_count)
 
+#define inc_preempt_count() \
+do { \
+	preempt_count()++; \
+} while (0)
+
+#define dec_preempt_count() \
+do { \
+	preempt_count()--; \
+} while (0)
+
 #ifdef CONFIG_PREEMPT
 
 extern void preempt_schedule(void);
 
 #define preempt_disable() \
 do { \
-	preempt_count()++; \
+	inc_preempt_count(); \
 	barrier(); \
 } while (0)
 
 #define preempt_enable_no_resched() \
 do { \
-	preempt_count()--; \
+	dec_preempt_count(); \
 	barrier(); \
 } while (0)
 
@@ -34,12 +44,22 @@
 		preempt_schedule(); \
 } while (0)
 
+#define inc_preempt_count_non_preempt()	do { } while (0)
+#define dec_preempt_count_non_preempt()	do { } while (0)
+
 #else
 
 #define preempt_disable()		do { } while (0)
 #define preempt_enable_no_resched()	do {} while(0)
 #define preempt_enable()		do { } while (0)
 #define preempt_check_resched()		do { } while (0)
+
+/*
+ * Sometimes we want to increment the preempt count, but we know that it's
+ * already incremented if the kernel is compiled for preemptibility.
+ */
+#define inc_preempt_count_non_preempt()	inc_preempt_count()
+#define dec_preempt_count_non_preempt()	dec_preempt_count()
 
 #endif
 
diff -Nru a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
--- a/include/linux/reiserfs_fs.h	Sat Aug 10 18:42:23 2002
+++ b/include/linux/reiserfs_fs.h	Sat Aug 10 18:42:23 2002
@@ -79,9 +79,9 @@
 /** always check a condition and panic if it's false. */
 #define RASSERT( cond, format, args... )					\
 if( !( cond ) ) 								\
-  reiserfs_panic( 0, "reiserfs[%i]: assertion " #cond " failed at "		\
-		  __FILE__ ":%i:" __FUNCTION__ ": " format "\n",		\
-		  in_interrupt() ? -1 : current -> pid, __LINE__ , ##args )
+  reiserfs_panic( 0, "reiserfs[%i]: assertion " #cond " failed at "	\
+		  __FILE__ ":%i:%s: " format "\n",		\
+		  in_interrupt() ? -1 : current -> pid, __LINE__ , __FUNCTION__ , ##args )
 
 #if defined( CONFIG_REISERFS_CHECK )
 #define RFALSE( cond, format, args... ) RASSERT( !( cond ), format, ##args )
diff -Nru a/include/linux/serial_core.h b/include/linux/serial_core.h
--- a/include/linux/serial_core.h	Sat Aug 10 18:42:21 2002
+++ b/include/linux/serial_core.h	Sat Aug 10 18:42:21 2002
@@ -51,6 +51,10 @@
 #define PORT_UART00	35
 #define PORT_21285	37
 
+/* Sparc type numbers.  */
+#define PORT_SUNZILOG	38
+#define PORT_SUNSAB	39
+
 #ifdef __KERNEL__
 
 #include <linux/config.h>
diff -Nru a/include/linux/skbuff.h b/include/linux/skbuff.h
--- a/include/linux/skbuff.h	Sat Aug 10 18:42:20 2002
+++ b/include/linux/skbuff.h	Sat Aug 10 18:42:20 2002
@@ -182,7 +182,6 @@
 		struct icmphdr	*icmph;
 		struct igmphdr	*igmph;
 		struct iphdr	*ipiph;
-		struct spxhdr	*spxh;
 		unsigned char	*raw;
 	} h;
 
@@ -190,7 +189,6 @@
 		struct iphdr	*iph;
 		struct ipv6hdr	*ipv6h;
 		struct arphdr	*arph;
-		struct ipxhdr	*ipxh;
 		unsigned char	*raw;
 	} nh;
 
diff -Nru a/include/linux/smp.h b/include/linux/smp.h
--- a/include/linux/smp.h	Sat Aug 10 18:42:23 2002
+++ b/include/linux/smp.h	Sat Aug 10 18:42:23 2002
@@ -100,6 +100,8 @@
 #define per_cpu(var, cpu)			var
 #define this_cpu(var)				var
 
+struct notifier_block;
+
 /* Need to know about CPUs going up/down? */
 static inline int register_cpu_notifier(struct notifier_block *nb)
 {
diff -Nru a/include/linux/stringify.h b/include/linux/stringify.h
--- a/include/linux/stringify.h	Sat Aug 10 18:42:21 2002
+++ b/include/linux/stringify.h	Sat Aug 10 18:42:21 2002
@@ -4,6 +4,10 @@
 /* Indirect stringification.  Doing two levels allows the parameter to be a
  * macro itself.  For example, compile with -DFOO=bar, __stringify(FOO)
  * converts to "bar".
+ *
+ * The "..." is gcc's cpp vararg macro syntax.  It is required because __ALIGN,
+ * in linkage.h, contains a comma, which when expanded, causes it to look 
+ * like two arguments, which breaks the standard non-vararg stringizer.
  */
 
 #define __stringify_1(x)	#x
diff -Nru a/include/linux/swap.h b/include/linux/swap.h
--- a/include/linux/swap.h	Sat Aug 10 18:42:20 2002
+++ b/include/linux/swap.h	Sat Aug 10 18:42:20 2002
@@ -133,7 +133,6 @@
 extern unsigned int nr_free_pages(void);
 extern unsigned int nr_free_buffer_pages(void);
 extern unsigned int nr_free_pagecache_pages(void);
-extern void __remove_inode_page(struct page *);
 
 /* Incomplete types for prototype declarations: */
 struct task_struct;
diff -Nru a/include/linux/threads.h b/include/linux/threads.h
--- a/include/linux/threads.h	Sat Aug 10 18:42:20 2002
+++ b/include/linux/threads.h	Sat Aug 10 18:42:20 2002
@@ -19,6 +19,7 @@
 /*
  * This controls the maximum pid allocated to a process
  */
-#define PID_MAX 0x8000
+#define PID_MASK 0x3fffffff
+#define PID_MAX (PID_MASK+1)
 
 #endif
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Sat Aug 10 18:42:22 2002
+++ b/include/linux/usb.h	Sat Aug 10 18:42:22 2002
@@ -351,7 +351,8 @@
 	int bandwidth_int_reqs;		/* number of Interrupt requests */
 	int bandwidth_isoc_reqs;	/* number of Isoc. requests */
 
-	struct dentry *dentry;		/* usbfs dentry entry for the bus */
+	struct dentry *usbfs_dentry;	/* usbfs dentry entry for the bus */
+	struct dentry *usbdevfs_dentry;	/* usbdevfs dentry entry for the bus */
 
 	atomic_t refcnt;
 };
@@ -410,7 +411,8 @@
 	void *hcpriv;			/* Host Controller private data */
 	
 	struct list_head filelist;
-	struct dentry *dentry;		/* usbfs dentry entry for the device */
+	struct dentry *usbfs_dentry;	/* usbfs dentry entry for the device */
+	struct dentry *usbdevfs_dentry;	/* usbdevfs dentry entry for the device */
 
 	/*
 	 * Child devices - these can be either new devices
diff -Nru a/include/net/ipx.h b/include/net/ipx.h
--- a/include/net/ipx.h	Sat Aug 10 18:42:21 2002
+++ b/include/net/ipx.h	Sat Aug 10 18:42:21 2002
@@ -14,12 +14,11 @@
 #include <net/datalink.h>
 #include <linux/ipx.h>
 
-typedef struct
-{
+struct ipx_address {
 	__u32   net;
 	__u8    node[IPX_NODE_LEN]; 
 	__u16   sock;
-} ipx_address;
+};
 
 #define ipx_broadcast_node	"\377\377\377\377\377\377"
 #define ipx_this_node           "\0\0\0\0\0\0"
@@ -39,11 +38,16 @@
 #define IPX_TYPE_SPX		0x05	/* SPX protocol */
 #define IPX_TYPE_NCP		0x11	/* $lots for docs on this (SPIT) */
 #define IPX_TYPE_PPROP		0x14	/* complicated flood fill brdcast */
-	ipx_address	ipx_dest __attribute__ ((packed));
-	ipx_address	ipx_source __attribute__ ((packed));
+	struct ipx_address	ipx_dest __attribute__ ((packed));
+	struct ipx_address	ipx_source __attribute__ ((packed));
 };
 
-typedef struct ipx_interface {
+static __inline__ struct ipxhdr *ipx_hdr(struct sk_buff *skb)
+{
+	return (struct ipxhdr *)skb->h.raw;
+}
+
+struct ipx_interface {
 	/* IPX address */
 	__u32           if_netnum;
 	unsigned char	if_node[IPX_NODE_LEN];
@@ -65,16 +69,16 @@
 	unsigned char	if_primary;
 	
 	struct ipx_interface	*if_next;
-}	ipx_interface;
+};
 
-typedef struct ipx_route {
+struct ipx_route {
 	__u32         ir_net;
-	ipx_interface *ir_intrfc;
+	struct ipx_interface	*ir_intrfc;
 	unsigned char ir_routed;
 	unsigned char ir_router_node[IPX_NODE_LEN];
-	struct ipx_route *ir_next;
+	struct ipx_route	*ir_next;
 	atomic_t      refcnt;
-}	ipx_route;
+};
 
 #ifdef __KERNEL__
 struct ipx_cb {
@@ -88,8 +92,8 @@
 };
 
 struct ipx_opt {
-	ipx_address	dest_addr;
-	ipx_interface	*intrfc;
+	struct ipx_address	dest_addr;
+	struct ipx_interface	*intrfc;
 	unsigned short	port;
 #ifdef CONFIG_IPX_INTERN
 	unsigned char	node[IPX_NODE_LEN];
@@ -105,8 +109,5 @@
 #endif
 #define IPX_MIN_EPHEMERAL_SOCKET	0x4000
 #define IPX_MAX_EPHEMERAL_SOCKET	0x7fff
-
-extern int ipx_register_spx(struct proto_ops **, struct net_proto_family *);
-extern int ipx_unregister_spx(void);
 
 #endif /* def _NET_INET_IPX_H_ */
diff -Nru a/include/net/llc.h b/include/net/llc.h
--- a/include/net/llc.h	Sat Aug 10 18:42:22 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,135 +0,0 @@
-#include <linux/skbuff.h>
-
-#define LLC_MODULE
-
-typedef struct llc_struct llc;
-typedef struct llc_struct *llcptr;
-
-/*
- *	LLC private data area structure.
- */
-
-struct llc_struct
-{ 
-	char eye[4];			/* To recognize llc area in dump */
-	int retry_count;		/* LLC link state variables */
-	unsigned char name[9];		/* name of this llc instance */
-	unsigned char s_flag;
-	unsigned char p_flag;
-	unsigned char f_flag;
-	unsigned char data_flag;
-	unsigned char cause_flag;
-	unsigned char vs;		/* Send state variable */
-	unsigned char vr;		/* Receive state variable */
-	unsigned char remote_busy;
-	unsigned char state;		/* Current state of type2 llc procedure */
-	int n1;				/* Maximum number of bytes in I pdu 7.8.2 */
-	int n2;				/* Naximum number of retransmissions 7.8.2 */
-	unsigned char k;		/* Transmit window size 7.8.4, tw in IBM doc*/ 
-	unsigned char rw;		/* Receive window size */
-	struct 
-	{     				
-		/*
-		 *	FRMR_RSP info field structure: 5.4.2.3.5 p55
-		 */
-
-		unsigned char cntl1;
-		unsigned char cntl2;
-		unsigned char vs;
-		unsigned char vr_cr;
-		unsigned char xxyz;
-	} frmr_info_fld;
-
-	/*
-	 *	Timers in 7.8.1 page 78 
-	 */
-
-#define P_TIMER         0
-#define REJ_TIMER       1
-#define ACK_TIMER       2 
-#define BUSY_TIMER      3
-	unsigned long timer_expire_time[4];	
-	unsigned char timer_state[4];	/* The state of each timer */
-#define TIMER_IDLE      0
-#define TIMER_RUNNING   1
-#define TIMER_EXPIRED   2
-	unsigned long timer_interval[4]; 
-	struct timer_list tl[4];
-
-	/* 
-	 *	Client entry point, called by the LLC.
-	 */
-	 
-	void	(*llc_event)(struct llc_struct *);
-	
-	/*
-	 *	Mux and Demux variables
-	 */
-	 
-	char * client_data;		/* Pointer to clients context */
-	unsigned char local_sap;
-	unsigned char remote_sap ;
-	char remote_mac[MAX_ADDR_LEN];  /* MAC address of remote session partner */ 
-	struct net_device *dev;		/* Device we are attached to */
-		     
-	unsigned char llc_mode;		/* See doc 7.1 on p70 */
-#define MODE_ADM 1
-#define MODE_ABM 2
-
-	int llc_callbacks;		/* Pending callbacks */
-#define LLC_CONN_INDICATION	1	/* We have to ensure the names don't */
-#define LLC_CONN_CONFIRM	2	/* mix up with the 802 state table */
-#define LLC_DATA_INDIC		4
-#define LLC_DISC_INDICATION	8
-#define LLC_RESET_INDIC_LOC	16
-#define LLC_RESET_INDIC_REM	32
-#define LLC_RST_CONFIRM		64
-#define LLC_FRMR_RECV		128
-#define LLC_FRMR_SENT		256
-#define LLC_REMOTE_BUSY		512
-#define LLC_REMOTE_NOTBUSY	1024
-#define LLC_TEST_INDICATION	2048
-#define LLC_XID_INDICATION	4096
-#define LLC_UI_DATA		8192
-
-	struct sk_buff *inc_skb;	/* Saved data buffer for indications */
-	
-	struct sk_buff_head rtq;	/* Retransmit queue */
-	struct sk_buff_head atq;	/* Await transit queue */
-      
-	unsigned char xid_count;
-
-	struct llc_struct *nextllc;	/* ptr to next llc struct in proto chain */
-};
-
-#define ADD_TO_RTQ(skb) skb_queue_tail(&lp->rtq,skb)
-#define ADD_TO_ATQ(skb) skb_queue_tail(&lp->atq,skb)
-
-void 		llc_cancel_timers(llcptr lp);
-int		llc_decode_frametype(frameptr fr);
-llcptr 		llc_find(void);
-int		llc_free_acknowledged_skbs(llcptr lp, unsigned char ack);
-void		llc_handle_xid_indication( char *chsp, short int ll, char *xid_data);
-void		llc_interpret_pseudo_code(llcptr lp, int pc_label, struct sk_buff *skb, char type);
-void		llc_add_to_queue(struct sk_buff *skb, struct sk_buff **f, struct sk_buff **b);
-void		llc_process_otype2_frame(llcptr lp, struct sk_buff *skb, char type);
-struct sk_buff *llc_pull_from_atq(llcptr lp); 
-int 		llc_resend_ipdu(llcptr lp, unsigned char ack_nr, unsigned char type, char p);
-void 		llc_sendpdu(llcptr lp, char type, char pf, int data_len, char *pdu_data);
-void 		llc_sendipdu(llcptr lp, char type, char pf, struct sk_buff *skb);
-void		llc_start_timer(llcptr lp, int t);
-void		llc_stop_timer(llcptr lp, int t);
-void		llc_timer_expired(llcptr lp, int t);
-int		llc_validate_seq_nos(llcptr lp, frameptr fr);
-
-int		llc_data_request(llcptr lp, struct sk_buff *skb);
-void		llc_unit_data_request(llcptr lp, int ll, char * data);
-void		llc_disconnect_request(llcptr lp);
-void		llc_connect_request(llcptr lp);
-void		llc_xid_request(llcptr lp, char opt, int data_len, char *pdu_data);
-void		llc_test_request(llcptr lp, int data_len, char *pdu_data);
-
-int		register_cl2llc_client(llcptr llc, const char *device, void (*ops)(llcptr), u8 *rmac, u8 ssap, u8 dsap);
-void		unregister_cl2llc_client(llcptr lp);
-int 		llc_mac_data_indicate(llcptr lp, struct sk_buff *skb );
-
diff -Nru a/include/net/llc_pdu.h b/include/net/llc_pdu.h
--- a/include/net/llc_pdu.h	Sat Aug 10 18:42:21 2002
+++ b/include/net/llc_pdu.h	Sat Aug 10 18:42:21 2002
@@ -191,34 +191,34 @@
        (info->ind_bits = ( (info->ind_bits & 0xEF) | (((u8) ind) & 0x10)))
 
 /* Sequence-numbered PDU format (4 bytes in length) */
-typedef struct llc_pdu_sn {
+struct llc_pdu_sn {
 	u8 dsap;
 	u8 ssap;
 	u8 ctrl_1;
 	u8 ctrl_2;
-} llc_pdu_sn_t;
+};
 
 /* Un-numbered PDU format (3 bytes in length) */
-typedef struct llc_pdu_un {
+struct llc_pdu_un {
 	u8 dsap;
 	u8 ssap;
 	u8 ctrl_1;
-} llc_pdu_un_t;
+};
 
 /* LLC Type 1 XID command/response information fields format */
-typedef struct llc_xid_info {
+struct llc_xid_info {
 	u8 fmt_id;	/* always 0x18 for LLC */
 	u8 type;	/* different if NULL/non-NULL LSAP */
 	u8 rw;		/* sender receive window */
-} llc_xid_info_t;
+};
 
 /* LLC Type 2 FRMR response information field format */
-typedef struct llc_frmr_info {
+struct llc_frmr_info {
 	u16 rej_pdu_ctrl;	/* bits 1-8 if U-PDU */
 	u8  curr_ssv;		/* current send state variable val */
 	u8  curr_rsv;		/* current receive state variable */
 	u8  ind_bits;		/* indicator bits set with macro */
-} llc_frmr_info_t;
+};
 
 extern void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 type);
 extern void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value);
@@ -246,7 +246,8 @@
 				   u8 rx_window);
 extern int llc_pdu_init_as_test_rsp(struct sk_buff *skb,
 				    struct sk_buff *ev_skb);
-extern int llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, llc_pdu_sn_t *prev_pdu,
+extern int llc_pdu_init_as_frmr_rsp(struct sk_buff *skb,
+				    struct llc_pdu_sn *prev_pdu,
 				    u8 f_bit, u8 vs, u8 vr, u8 vzyxw);
 extern int llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
 extern int llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
diff -Nru a/include/net/spx.h b/include/net/spx.h
--- a/include/net/spx.h	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,95 +0,0 @@
-#ifndef __NET_SPX_H
-#define __NET_SPX_H
-
-#include <net/ipx.h>
-
-struct spxhdr
-{	__u8	cctl;	
-	__u8	dtype;
-#define SPX_DTYPE_ECONN	0xFE	/* Finished */
-#define SPX_DTYPE_ECACK	0xFF	/* Ok */
-	__u16	sconn;	/* Connection ID */
-	__u16	dconn;	/* Connection ID */
-	__u16	sequence;
-	__u16	ackseq;
-	__u16	allocseq;
-};
-
-struct ipxspxhdr
-{	struct ipxhdr	ipx;
-	struct spxhdr	spx;
-};
-
-#define	SPX_SYS_PKT_LEN	(sizeof(struct ipxspxhdr))
-
-#ifdef __KERNEL__
-struct spx_opt
-{	int	state;
-	int	sndbuf;
-	int	retries;	/* Number of WD retries */
-	int	retransmits;	/* Number of retransmits */
-	int	max_retries;
-	int	wd_interval;
-	void	*owner;
-	__u16	dest_connid;	/* Net order */
-	__u16	source_connid;	/* Net order */
-	__u16	sequence;	/* Host order - our current pkt # */
-	__u16	alloc;		/* Host order - max seq we can rcv now */
-	__u16	rmt_ack;	/* Host order - last pkt ACKd by remote */
-	__u16	rmt_seq;
-	__u16	acknowledge;
-	__u16	rmt_alloc;	/* Host order - max seq remote can handle now */
-	ipx_address	dest_addr;
-	ipx_address	source_addr;
-	struct timer_list	watchdog;	/* Idle watch */
-	struct timer_list	retransmit;	/* Retransmit timer */
-	struct sk_buff_head     rcv_queue;
-	struct sk_buff_head	transmit_queue;
-	struct sk_buff_head     retransmit_queue;
-};
-
-#define spx_sk(__sk) ((struct spx_opt *)(((struct sock *)(__sk)) + 1))
-
-/* Packet connectino control defines */
-#define CCTL_SPXII_XHD  0x01    /* SPX2 extended header */
-#define CCTL_SPX_UNKNOWN 0x02   /* Unknown (unused ??) */
-#define CCTL_SPXII_NEG  0x04    /* Negotiate size */
-#define CCTL_SPXII      0x08    /* Set for SPX2 */
-#define CCTL_EOM        0x10    /* End of message marker */
-#define CCTL_URG        0x20    /* Urgent marker in SPP (not used in SPX?) */
-#define CCTL_ACK        0x40    /* Send me an ACK */
-#define CCTL_CTL        0x80    /* Control message */
-#define CCTL_SYS        CCTL_CTL        /* Spec uses CCTL_SYS */
-
-/* Connection state defines */
-#define SPX_CLOSED	7
-#define	SPX_CONNECTING	8
-#define SPX_CONNECTED	9
-
-/* Packet transmit types - Internal */
-#define DATA	0	/* Data */
-#define ACK	1	/* Data ACK */
-#define WDACK	2	/* WD ACK */
-#define CONACK	3	/* Connection Request ACK */
-#define	CONREQ	4	/* Connection Request */
-#define WDREQ	5	/* WD Request */
-#define	DISCON	6	/* Informed Disconnect */
-#define	DISACK	7	/* Informed Disconnect ACK */
-#define RETRAN	8	/* Int. Retransmit of packet */
-#define TQUEUE	9	/* Int. Transmit of a queued packet */
-
-/*
- * These are good canidates for IOcontrol calls
- */
-
-/* Watchdog defines */
-#define VERIFY_TIMEOUT  3 * HZ
-#define ABORT_TIMEOUT   30 * HZ
-
-/* Packet retransmit defines */
-#define RETRY_COUNT     10
-#define RETRY_TIME      1 * HZ
-#define MAX_RETRY_DELAY 5 * HZ
-
-#endif /* __KERNEL__ */
-#endif /* def __NET_SPX_H */
diff -Nru a/include/net/tcp.h b/include/net/tcp.h
--- a/include/net/tcp.h	Sat Aug 10 18:42:21 2002
+++ b/include/net/tcp.h	Sat Aug 10 18:42:21 2002
@@ -153,6 +153,9 @@
 	return (lport & (tcp_bhash_size - 1));
 }
 
+extern void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb,
+			  unsigned short snum);
+
 /* This is a TIME_WAIT bucket.  It works around the memory consumption
  * problems of sockets in such a state on heavily loaded servers, but
  * without violating the protocol specification.
diff -Nru a/kernel/Makefile b/kernel/Makefile
--- a/kernel/Makefile	Sat Aug 10 18:42:21 2002
+++ b/kernel/Makefile	Sat Aug 10 18:42:21 2002
@@ -10,13 +10,14 @@
 O_TARGET := kernel.o
 
 export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o \
-		printk.o platform.o suspend.o
+		printk.o platform.o suspend.o dma.o
 
-obj-y     = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
+obj-y     = sched.o fork.o exec_domain.o panic.o printk.o \
 	    module.o exit.o itimer.o time.o softirq.o resource.o \
 	    sysctl.o capability.o ptrace.o timer.o user.o \
 	    signal.o sys.o kmod.o context.o futex.o platform.o
 
+obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
 obj-$(CONFIG_SMP) += cpu.o
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += ksyms.o
diff -Nru a/kernel/dma.c b/kernel/dma.c
--- a/kernel/dma.c	Sat Aug 10 18:42:21 2002
+++ b/kernel/dma.c	Sat Aug 10 18:42:21 2002
@@ -9,11 +9,14 @@
  *   [It also happened to remove the sizeof(char *) == sizeof(int)
  *   assumption introduced because of those /proc/dma patches. -- Hennus]
  */
-
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/spinlock.h>
 #include <linux/string.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
 #include <asm/dma.h>
 #include <asm/system.h>
 
@@ -65,20 +68,6 @@
 	{ 0, 0 }
 };
 
-int get_dma_list(char *buf)
-{
-	int i, len = 0;
-
-	for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) {
-		if (dma_chan_busy[i].lock) {
-		    len += sprintf(buf+len, "%2d: %s\n",
-				   i,
-				   dma_chan_busy[i].device_id);
-		}
-	}
-	return len;
-} /* get_dma_list */
-
 
 int request_dma(unsigned int dmanr, const char * device_id)
 {
@@ -98,17 +87,30 @@
 void free_dma(unsigned int dmanr)
 {
 	if (dmanr >= MAX_DMA_CHANNELS) {
-		printk("Trying to free DMA%d\n", dmanr);
+		printk(KERN_WARNING "Trying to free DMA%d\n", dmanr);
 		return;
 	}
 
 	if (xchg(&dma_chan_busy[dmanr].lock, 0) == 0) {
-		printk("Trying to free free DMA%d\n", dmanr);
+		printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr);
 		return;
 	}	
 
 } /* free_dma */
 
+static int proc_dma_show(struct seq_file *m, void *v)
+{
+	int i;
+
+	for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) {
+		if (dma_chan_busy[i].lock) {
+		    seq_printf(m, "%2d: %s\n", i,
+			       dma_chan_busy[i].device_id);
+		}
+	}
+	return 0;
+}
+
 #else
 
 int request_dma(unsigned int dmanr, const char *device_id)
@@ -120,9 +122,54 @@
 {
 }
 
-int get_dma_list(char *buf)
-{	
-	strcpy(buf, "No DMA\n");
-	return 7;
+static int proc_dma_show(struct seq_file *m, void *v)
+{
+	seq_puts(m, "No DMA\n");
+	return 0;
 }
+
 #endif
+
+#ifdef CONFIG_PROC_FS
+static int proc_dma_open(struct inode *inode, struct file *file)
+{
+	char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	struct seq_file *m;
+	int res;
+
+	if (!buf)
+		return -ENOMEM;
+	res = single_open(file, proc_dma_show, NULL);
+	if (!res) {
+		m = file->private_data;
+		m->buf = buf;
+		m->size = PAGE_SIZE;
+	} else
+		kfree(buf);
+	return res;
+}
+
+static struct file_operations proc_dma_operations = {
+	open:		proc_dma_open,
+	read:		seq_read,
+	llseek:		seq_lseek,
+	release:	single_release,
+};
+
+static int __init proc_dma_init(void)
+{
+	struct proc_dir_entry *e;
+
+	e = create_proc_entry("dma", 0, NULL);
+	if (e)
+		e->proc_fops = &proc_dma_operations;
+
+	return 0;
+}
+
+__initcall(proc_dma_init);
+#endif
+
+EXPORT_SYMBOL(request_dma);
+EXPORT_SYMBOL(free_dma);
+EXPORT_SYMBOL(dma_spin_lock);
diff -Nru a/kernel/fork.c b/kernel/fork.c
--- a/kernel/fork.c	Sat Aug 10 18:42:21 2002
+++ b/kernel/fork.c	Sat Aug 10 18:42:21 2002
@@ -142,7 +142,7 @@
 		return 0;
 
 	spin_lock(&lastpid_lock);
-	if((++last_pid) & 0xffff8000) {
+	if((++last_pid) & ~PID_MASK) {
 		last_pid = 300;		/* Skip daemons etc. */
 		goto inside;
 	}
@@ -157,7 +157,7 @@
 			   p->tgid == last_pid	||
 			   p->session == last_pid) {
 				if(++last_pid >= next_safe) {
-					if(last_pid & 0xffff8000)
+					if(last_pid & ~PID_MASK)
 						last_pid = 300;
 					next_safe = PID_MAX;
 				}
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Sat Aug 10 18:42:20 2002
+++ b/kernel/ksyms.c	Sat Aug 10 18:42:20 2002
@@ -64,9 +64,6 @@
 extern void *sys_call_table;
 
 extern struct timezone sys_tz;
-extern int request_dma(unsigned int dmanr, const char * deviceID);
-extern void free_dma(unsigned int dmanr);
-extern spinlock_t dma_spin_lock;
 
 #ifdef CONFIG_MODVERSIONS
 const struct module_symbol __export_Using_Versions
@@ -180,6 +177,7 @@
 EXPORT_SYMBOL(put_filp);
 EXPORT_SYMBOL(files_lock);
 EXPORT_SYMBOL(check_disk_change);
+EXPORT_SYMBOL(__check_disk_change);
 EXPORT_SYMBOL(__invalidate_buffers);
 EXPORT_SYMBOL(invalidate_bdev);
 EXPORT_SYMBOL(invalidate_inodes);
@@ -271,7 +269,7 @@
 EXPORT_SYMBOL(ROOT_DEV);
 EXPORT_SYMBOL(find_get_page);
 EXPORT_SYMBOL(find_lock_page);
-EXPORT_SYMBOL(grab_cache_page);
+EXPORT_SYMBOL(find_or_create_page);
 EXPORT_SYMBOL(grab_cache_page_nowait);
 EXPORT_SYMBOL(read_cache_page);
 EXPORT_SYMBOL(vfs_readlink);
@@ -437,10 +435,6 @@
 EXPORT_SYMBOL(brw_kiovec);
 EXPORT_SYMBOL(kiobuf_wait_for_io);
 
-/* dma handling */
-EXPORT_SYMBOL(request_dma);
-EXPORT_SYMBOL(free_dma);
-EXPORT_SYMBOL(dma_spin_lock);
 #ifdef HAVE_DISABLE_HLT
 EXPORT_SYMBOL(disable_hlt);
 EXPORT_SYMBOL(enable_hlt);
@@ -508,6 +502,7 @@
 EXPORT_SYMBOL(__bdevname);
 EXPORT_SYMBOL(cdevname);
 EXPORT_SYMBOL(simple_strtoul);
+EXPORT_SYMBOL(simple_strtol);
 EXPORT_SYMBOL(system_utsname);	/* UTS data */
 EXPORT_SYMBOL(uts_sem);		/* UTS semaphore */
 #ifndef __mips__
diff -Nru a/kernel/panic.c b/kernel/panic.c
--- a/kernel/panic.c	Sat Aug 10 18:42:23 2002
+++ b/kernel/panic.c	Sat Aug 10 18:42:23 2002
@@ -88,7 +88,7 @@
 		extern int stop_a_enabled;
 		/* Make sure the user can actually press L1-A */
 		stop_a_enabled = 1;
-		printk("Press L1-A to return to the boot prom\n");
+		printk(KERN_EMERG "Press L1-A to return to the boot prom\n");
 	}
 #endif
 #if defined(CONFIG_ARCH_S390)
diff -Nru a/kernel/resource.c b/kernel/resource.c
--- a/kernel/resource.c	Sat Aug 10 18:42:23 2002
+++ b/kernel/resource.c	Sat Aug 10 18:42:23 2002
@@ -290,7 +290,7 @@
 		}
 		p = &res->sibling;
 	}
-	printk("Trying to free nonexistent resource <%08lx-%08lx>\n", start, end);
+	printk(KERN_WARNING "Trying to free nonexistent resource <%08lx-%08lx>\n", start, end);
 }
 
 /*
diff -Nru a/kernel/signal.c b/kernel/signal.c
--- a/kernel/signal.c	Sat Aug 10 18:42:22 2002
+++ b/kernel/signal.c	Sat Aug 10 18:42:22 2002
@@ -270,7 +270,7 @@
 	int sig = 0;
 
 #if DEBUG_SIG
-printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid,
+printk(KERN_DEBUG "SIG dequeue (%s:%d): %d ", current->comm, current->pid,
 	signal_pending(current));
 #endif
 
@@ -294,7 +294,7 @@
 	recalc_sigpending();
 
 #if DEBUG_SIG
-printk(" %d -> %d\n", signal_pending(current), sig);
+printk(KERN_DEBUG " %d -> %d\n", signal_pending(current), sig);
 #endif
 
 	return sig;
@@ -536,7 +536,7 @@
 
 
 #if DEBUG_SIG
-printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
+printk(KERN_DEBUG "SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
 #endif
 
 	ret = -EINVAL;
@@ -577,7 +577,7 @@
 	spin_unlock_irqrestore(&t->sigmask_lock, flags);
 out_nolock:
 #if DEBUG_SIG
-printk(" %d -> %d\n", signal_pending(t), ret);
+printk(KERN_DEBUG " %d -> %d\n", signal_pending(t), ret);
 #endif
 
 	return ret;
diff -Nru a/kernel/suspend.c b/kernel/suspend.c
--- a/kernel/suspend.c	Sat Aug 10 18:42:21 2002
+++ b/kernel/suspend.c	Sat Aug 10 18:42:21 2002
@@ -619,8 +619,8 @@
 /* Make disk drivers accept operations, again */
 static void drivers_unsuspend(void)
 {
-	device_resume(RESUME_ENABLE);
 	device_resume(RESUME_RESTORE_STATE);
+	device_resume(RESUME_ENABLE);
 }
 
 /* Called from process context */
@@ -647,8 +647,8 @@
 static void drivers_resume(int flags)
 {
 	if (flags & RESUME_PHASE1) {
-		device_resume(RESUME_ENABLE);
 		device_resume(RESUME_RESTORE_STATE);
+		device_resume(RESUME_ENABLE);
 	}
   	if (flags & RESUME_PHASE2) {
 		if(pm_suspend_state) {
diff -Nru a/kernel/timer.c b/kernel/timer.c
--- a/kernel/timer.c	Sat Aug 10 18:42:22 2002
+++ b/kernel/timer.c	Sat Aug 10 18:42:22 2002
@@ -194,7 +194,7 @@
 	return;
 bug:
 	spin_unlock_irqrestore(&timerlist_lock, flags);
-	printk("bug: kernel timer added twice at %p.\n",
+	printk(KERN_ERR "BUG: kernel timer added twice at %p.\n",
 			__builtin_return_address(0));
 }
 
diff -Nru a/mm/filemap.c b/mm/filemap.c
--- a/mm/filemap.c	Sat Aug 10 18:42:22 2002
+++ b/mm/filemap.c	Sat Aug 10 18:42:22 2002
@@ -68,7 +68,7 @@
  * sure the page is locked and that nobody else uses it - or that usage
  * is safe.  The caller must hold a write_lock on the mapping's page_lock.
  */
-void __remove_inode_page(struct page *page)
+void __remove_from_page_cache(struct page *page)
 {
 	struct address_space *mapping = page->mapping;
 
@@ -83,7 +83,7 @@
 	dec_page_state(nr_pagecache);
 }
 
-void remove_inode_page(struct page *page)
+void remove_from_page_cache(struct page *page)
 {
 	struct address_space *mapping = page->mapping;
 
@@ -91,7 +91,7 @@
 		PAGE_BUG(page);
 
 	write_lock(&mapping->page_lock);
-	__remove_inode_page(page);
+	__remove_from_page_cache(page);
 	write_unlock(&mapping->page_lock);
 }
 
@@ -143,7 +143,7 @@
 			goto unlock;
 
 		__lru_cache_del(page);
-		__remove_inode_page(page);
+		__remove_from_page_cache(page);
 		unlock_page(page);
 		page_cache_release(page);
 		continue;
@@ -186,7 +186,7 @@
 
 	ClearPageDirty(page);
 	ClearPageUptodate(page);
-	remove_inode_page(page);
+	remove_from_page_cache(page);
 	page_cache_release(page);
 }
 
@@ -807,15 +807,6 @@
 		page_cache_release(cached_page);
 	return page;
 }
-
-/*
- * Returns locked page at given index in given cache, creating it if needed.
- */
-struct page *grab_cache_page(struct address_space *mapping, unsigned long index)
-{
-	return find_or_create_page(mapping, index, mapping->gfp_mask);
-}
-
 
 /*
  * Same as grab_cache_page, but do not wait if the page is unavailable.
diff -Nru a/mm/memory.c b/mm/memory.c
--- a/mm/memory.c	Sat Aug 10 18:42:22 2002
+++ b/mm/memory.c	Sat Aug 10 18:42:22 2002
@@ -408,11 +408,8 @@
 {
 	struct mm_struct *mm = vma->vm_mm;
 	mmu_gather_t *tlb;
-	pgd_t * dir;
 	unsigned long start = address, end = address + size;
 
-	dir = pgd_offset(mm, address);
-
 	/*
 	 * This is a long-lived spinlock. That's fine.
 	 * There's no contention, because the page table
@@ -432,9 +429,11 @@
 }
 
 /*
- * Do a quick page-table lookup for a single page. 
+ * Do a quick page-table lookup for a single page.
+ * mm->page_table_lock must be held.
  */
-static struct page * follow_page(struct mm_struct *mm, unsigned long address, int write) 
+static inline struct page *
+follow_page(struct mm_struct *mm, unsigned long address, int write) 
 {
 	pgd_t *pgd;
 	pmd_t *pmd;
@@ -449,19 +448,14 @@
 	if (pmd_none(*pmd) || pmd_bad(*pmd))
 		goto out;
 
-	preempt_disable();
 	ptep = pte_offset_map(pmd, address);
-	if (!ptep) {
-		preempt_enable();
+	if (!ptep)
 		goto out;
-	}
 
 	pte = *ptep;
 	pte_unmap(ptep);
-	preempt_enable();
 	if (pte_present(pte)) {
-		if (!write ||
-		    (pte_write(pte) && pte_dirty(pte))) {
+		if (!write || (pte_write(pte) && pte_dirty(pte))) {
 			pfn = pte_pfn(pte);
 			if (pfn_valid(pfn))
 				return pfn_to_page(pfn);
@@ -478,13 +472,17 @@
  * with IO-aperture pages in kiobufs.
  */
 
-static inline struct page * get_page_map(struct page *page)
+static inline struct page *get_page_map(struct page *page)
 {
+	if (!pfn_valid(page_to_pfn(page)))
+		return 0;
 	return page;
 }
 
-int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
-		int len, int write, int force, struct page **pages, struct vm_area_struct **vmas)
+
+int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+		unsigned long start, int len, int write, int force,
+		struct page **pages, struct vm_area_struct **vmas)
 {
 	int i;
 	unsigned int flags;
@@ -496,14 +494,14 @@
 	flags = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD);
 	flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
 	i = 0;
-	
 
 	do {
 		struct vm_area_struct *	vma;
 
 		vma = find_extend_vma(mm, start);
 
-		if ( !vma || !(flags & vma->vm_flags) )
+		if (!vma || (pages && (vma->vm_flags & VM_IO))
+				|| !(flags & vma->vm_flags))
 			return i ? : -EFAULT;
 
 		spin_lock(&mm->page_table_lock);
@@ -511,7 +509,7 @@
 			struct page *map;
 			while (!(map = follow_page(mm, start, write))) {
 				spin_unlock(&mm->page_table_lock);
-				switch (handle_mm_fault(mm, vma, start, write)) {
+				switch (handle_mm_fault(mm,vma,start,write)) {
 				case VM_FAULT_MINOR:
 					tsk->min_flt++;
 					break;
@@ -529,11 +527,14 @@
 			}
 			if (pages) {
 				pages[i] = get_page_map(map);
-				/* FIXME: call the correct function,
-				 * depending on the type of the found page
-				 */
-				if (pages[i])
-					page_cache_get(pages[i]);
+				if (!pages[i]) {
+					spin_unlock(&mm->page_table_lock);
+					while (i--)
+						page_cache_release(pages[i]);
+					i = -EFAULT;
+					goto out;
+				}
+				page_cache_get(pages[i]);
 			}
 			if (vmas)
 				vmas[i] = vma;
@@ -543,6 +544,7 @@
 		} while(len && start < vma->vm_end);
 		spin_unlock(&mm->page_table_lock);
 	} while(len);
+out:
 	return i;
 }
 
diff -Nru a/mm/mmap.c b/mm/mmap.c
--- a/mm/mmap.c	Sat Aug 10 18:42:21 2002
+++ b/mm/mmap.c	Sat Aug 10 18:42:21 2002
@@ -422,6 +422,7 @@
 {
 	struct mm_struct * mm = current->mm;
 	struct vm_area_struct * vma, * prev;
+	struct inode *inode = NULL;
 	unsigned int vm_flags;
 	int correct_wcount = 0;
 	int error;
@@ -469,17 +470,18 @@
 	}
 
 	if (file) {
+		inode = file->f_dentry->d_inode;
 		switch (flags & MAP_TYPE) {
 		case MAP_SHARED:
 			if ((prot & PROT_WRITE) && !(file->f_mode & FMODE_WRITE))
 				return -EACCES;
 
 			/* Make sure we don't allow writing to an append-only file.. */
-			if (IS_APPEND(file->f_dentry->d_inode) && (file->f_mode & FMODE_WRITE))
+			if (IS_APPEND(inode) && (file->f_mode & FMODE_WRITE))
 				return -EACCES;
 
 			/* make sure there are no mandatory locks on the file. */
-			if (locks_verify_locked(file->f_dentry->d_inode))
+			if (locks_verify_locked(inode))
 				return -EAGAIN;
 
 			vm_flags |= VM_SHARED | VM_MAYSHARE;
@@ -603,7 +605,7 @@
 
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 	if (correct_wcount)
-		atomic_inc(&file->f_dentry->d_inode->i_writecount);
+		atomic_inc(&inode->i_writecount);
 
 out:	
 	mm->total_vm += len >> PAGE_SHIFT;
@@ -615,7 +617,7 @@
 
 unmap_and_free_vma:
 	if (correct_wcount)
-		atomic_inc(&file->f_dentry->d_inode->i_writecount);
+		atomic_inc(&inode->i_writecount);
 	vma->vm_file = NULL;
 	fput(file);
 
@@ -755,38 +757,41 @@
 	return prev ? prev->vm_next : vma;
 }
 
+#ifdef ARCH_STACK_GROWSUP
 /*
- * vma is the first one with  address < vma->vm_end,
- * and even address < vma->vm_start. Have to extend vma.
+ * vma is the first one with address > vma->vm_end.  Have to extend vma.
  */
 int expand_stack(struct vm_area_struct * vma, unsigned long address)
 {
 	unsigned long grow;
 
+	if (!(vma->vm_flags & VM_GROWSUP))
+		return -EFAULT;
+
 	/*
 	 * vma->vm_start/vm_end cannot change under us because the caller
-	 * is required to hold the mmap_sem in write mode. We need to get
+	 * is required to hold the mmap_sem in read mode. We need to get
 	 * the spinlock only before relocating the vma range ourself.
 	 */
+	address += 4 + PAGE_SIZE - 1;
 	address &= PAGE_MASK;
  	spin_lock(&vma->vm_mm->page_table_lock);
-	grow = (vma->vm_start - address) >> PAGE_SHIFT;
+	grow = (address - vma->vm_end) >> PAGE_SHIFT;
 
 	/* Overcommit.. */
-	if(!vm_enough_memory(grow)) {
+	if (!vm_enough_memory(grow)) {
 		spin_unlock(&vma->vm_mm->page_table_lock);
 		return -ENOMEM;
 	}
 	
-	if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
+	if (address - vma->vm_start > current->rlim[RLIMIT_STACK].rlim_cur ||
 			((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
 			current->rlim[RLIMIT_AS].rlim_cur) {
 		spin_unlock(&vma->vm_mm->page_table_lock);
 		vm_unacct_memory(grow);
 		return -ENOMEM;
 	}
-	vma->vm_start = address;
-	vma->vm_pgoff -= grow;
+	vma->vm_end = address;
 	vma->vm_mm->total_vm += grow;
 	if (vma->vm_flags & VM_LOCKED)
 		vma->vm_mm->locked_vm += grow;
@@ -794,7 +799,6 @@
 	return 0;
 }
 
-#ifdef ARCH_STACK_GROWSUP
 struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long addr)
 {
 	struct vm_area_struct *vma, *prev;
@@ -811,6 +815,44 @@
 	return prev;
 }
 #else
+/*
+ * vma is the first one with address < vma->vm_start.  Have to extend vma.
+ */
+int expand_stack(struct vm_area_struct * vma, unsigned long address)
+{
+	unsigned long grow;
+
+	/*
+	 * vma->vm_start/vm_end cannot change under us because the caller
+	 * is required to hold the mmap_sem in read mode. We need to get
+	 * the spinlock only before relocating the vma range ourself.
+	 */
+	address &= PAGE_MASK;
+ 	spin_lock(&vma->vm_mm->page_table_lock);
+	grow = (vma->vm_start - address) >> PAGE_SHIFT;
+
+	/* Overcommit.. */
+	if (!vm_enough_memory(grow)) {
+		spin_unlock(&vma->vm_mm->page_table_lock);
+		return -ENOMEM;
+	}
+	
+	if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
+			((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) >
+			current->rlim[RLIMIT_AS].rlim_cur) {
+		spin_unlock(&vma->vm_mm->page_table_lock);
+		vm_unacct_memory(grow);
+		return -ENOMEM;
+	}
+	vma->vm_start = address;
+	vma->vm_pgoff -= grow;
+	vma->vm_mm->total_vm += grow;
+	if (vma->vm_flags & VM_LOCKED)
+		vma->vm_mm->locked_vm += grow;
+	spin_unlock(&vma->vm_mm->page_table_lock);
+	return 0;
+}
+
 struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long addr)
 {
 	struct vm_area_struct * vma;
@@ -888,6 +930,8 @@
 	 * old method of shifting the VA >> by PGDIR_SHIFT doesn't work.
 	 */
 	start_index = pgd_index(first);
+	if (start_index < FIRST_USER_PGD_NR)
+		start_index = FIRST_USER_PGD_NR;
 	end_index = pgd_index(last);
 	if (end_index > start_index) {
 		clear_page_tables(tlb, start_index, end_index - start_index);
diff -Nru a/mm/page-writeback.c b/mm/page-writeback.c
--- a/mm/page-writeback.c	Sat Aug 10 18:42:21 2002
+++ b/mm/page-writeback.c	Sat Aug 10 18:42:21 2002
@@ -433,8 +433,10 @@
 
 	if (!TestSetPageDirty(page)) {
 		write_lock(&mapping->page_lock);
-		list_del(&page->list);
-		list_add(&page->list, &mapping->dirty_pages);
+		if (page->mapping) {	/* Race with truncate? */
+			list_del(&page->list);
+			list_add(&page->list, &mapping->dirty_pages);
+		}
 		write_unlock(&mapping->page_lock);
 		__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
 	}
@@ -467,8 +469,10 @@
 
 		if (mapping) {
 			write_lock(&mapping->page_lock);
-			list_del(&page->list);
-			list_add(&page->list, &mapping->dirty_pages);
+			if (page->mapping) {	/* Race with truncate? */
+				list_del(&page->list);
+				list_add(&page->list, &mapping->dirty_pages);
+			}
 			write_unlock(&mapping->page_lock);
 			__mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
 		}
diff -Nru a/mm/swap_state.c b/mm/swap_state.c
--- a/mm/swap_state.c	Sat Aug 10 18:42:22 2002
+++ b/mm/swap_state.c	Sat Aug 10 18:42:22 2002
@@ -95,7 +95,7 @@
 	BUG_ON(!PageSwapCache(page));
 	BUG_ON(PageWriteback(page));
 	ClearPageDirty(page);
-	__remove_inode_page(page);
+	__remove_from_page_cache(page);
 	INC_CACHE_INFO(del_total);
 }
 
@@ -206,7 +206,7 @@
 	err = radix_tree_reserve(&swapper_space.page_tree, entry.val, &pslot);
 	if (!err) {
 		/* Remove it from the page cache */
-		__remove_inode_page (page);
+		__remove_from_page_cache(page);
 
 		/* Add it to the swap cache */
 		*pslot = page;
diff -Nru a/mm/vmscan.c b/mm/vmscan.c
--- a/mm/vmscan.c	Sat Aug 10 18:42:21 2002
+++ b/mm/vmscan.c	Sat Aug 10 18:42:21 2002
@@ -288,7 +288,7 @@
 
 		/* point of no return */
 		if (likely(!PageSwapCache(page))) {
-			__remove_inode_page(page);
+			__remove_from_page_cache(page);
 			write_unlock(&mapping->page_lock);
 		} else {
 			swp_entry_t swap;
diff -Nru a/net/802/Makefile b/net/802/Makefile
--- a/net/802/Makefile	Sat Aug 10 18:42:22 2002
+++ b/net/802/Makefile	Sat Aug 10 18:42:22 2002
@@ -2,15 +2,14 @@
 # Makefile for the Linux 802.x protocol layers.
 #
 
-export-objs		:= llc_macinit.o p8022.o psnap.o
+export-objs		:= p8022.o psnap.o tr.o
 
 obj-y			:= p8023.o
 
 # Check the p8022 selections against net/core/Makefile.
 obj-$(CONFIG_SYSCTL)	+= sysctl_net_802.o
-obj-$(CONFIG_LLC)	+= p8022.o psnap.o llc_sendpdu.o llc_utility.o \
-			   		   cl2llc.o llc_macinit.o	
-obj-$(CONFIG_TR)	+= p8022.o psnap.o tr.o
+obj-$(CONFIG_LLC)	+= p8022.o psnap.o
+obj-$(CONFIG_TR)	+= p8022.o psnap.o tr.o sysctl_net_802.o
 obj-$(CONFIG_NET_FC)	+=                 fc.o
 obj-$(CONFIG_FDDI)	+=                 fddi.o
 obj-$(CONFIG_HIPPI)	+=                 hippi.o
@@ -18,25 +17,3 @@
 obj-$(CONFIG_ATALK)	+= p8022.o psnap.o
 
 include $(TOPDIR)/Rules.make
-
-# Dependencies on generated files need to be listed explicitly
-
-$(obj)/cl2llc.o: $(obj)/transit/pdutr.h $(obj)/transit/timertr.h \
-		 $(obj)/pseudo/pseudocode.h
-
-# Generated files
-
-$(obj)/transit/pdutr.h: $(src)/transit/pdutr.pre $(src)/transit/compile.awk
-	awk -f $(src)/transit/compile.awk $< >$@
-
-$(obj)/transit/timertr.h: $(src)/transit/timertr.pre $(src)/transit/compile.awk
-	awk -f $(src)/transit/compile.awk $< >$@
-
-$(obj)/pseudo/pseudocode.h: $(src)/pseudo/pseudocode \
-			    $(src)/pseudo/opcd2num.sed \
-			    $(src)/pseudo/compile.awk
-	sed -f $(src)/pseudo/opcd2num.sed $< | \
-	awk -f $(src)/pseudo/compile.awk >$@
-
-$(obj)/cl2llc.c: $(src)/cl2llc.pre $(src)/pseudo/opcd2num.sed
-	sed -f $(src)/pseudo/opcd2num.sed $< >$@
diff -Nru a/net/802/TODO b/net/802/TODO
--- a/net/802/TODO	Sat Aug 10 18:42:22 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,29 +0,0 @@
-Remaining Problems:
-
-1. Serialization of access to variables in the llc structure
-by mac_data_indicate(), timer expired functions, and data_request() .
-There is not serialization of any kind right now.
-While testing, I have not seen any problems that stem from this lack of
-serialization, but it wories me...
-
-2. The code is currently able to handle one connection only,
-there is more work in register_cl2llc_client() to make a chain
-of llc structures and in mac_data_indicate() to find back
-the llc structure addressed by an incoming frame.
-According to IEEE, connections are identified by (remote mac + local mac
-+ dsap + ssap). dsap and ssap do not seem important: existing applications
-always use the same dsap/ssap. Its probably sufficient to index on 
-the remote mac only. 
- 
-3. There is no test to see if the transmit window is full in data_request()
-as described in the doc p73, "7.5.1 Sending I PDUs" 3th alinea.
-The pdus presented to data_request() could probably go on the 
-awaiting-transmit-queue (atq). The real difficulty is coding a test
-to see if the transmit window is used up and to send the queue
-when space in the window becomes available.
-As I have no network layer that can generate a continous flow of pdus it is
-difficult to simulate a remote busy condition and hence to test the code
-to handle it.
- 
-4. A simple flow control algorithm, steering the size of the transmit
-window would be nice to have.
diff -Nru a/net/802/cl2llc.pre b/net/802/cl2llc.pre
--- a/net/802/cl2llc.pre	Sat Aug 10 18:42:22 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,615 +0,0 @@
-/*
- * NET		An implementation of the IEEE 802.2 LLC protocol for the
- *		LINUX operating system.  LLC is implemented as a set of 
- *		state machines and callbacks for higher networking layers.
- *
- *		Class 2 llc algorithm.
- *		Pseudocode interpreter, transition table lookup,
- *			data_request & indicate primitives...
- *
- *		Code for initialization, termination, registration and 
- *		MAC layer glue.
- *
- *		Copyright Tim Alpaerts, 
- *			<Tim_Alpaerts@toyota-motor-europe.com>
- *
- *		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.
- *
- *	Changes
- *		Alan Cox	:	Chainsawed into Linux format
- *					Modified to use llc_ names
- *					Changed callbacks
- *
- *	This file must be processed by sed before it can be compiled.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/p8022.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <asm/byteorder.h>
-
-#include "pseudo/pseudocode.h"
-#include "transit/pdutr.h"
-#include "transit/timertr.h"
-#include <net/llc_frame.h>
-#include <net/llc.h>
-
-/*
- *	Data_request() is called by the client to present a data unit
- *	to the llc for transmission.
- *	In the future this function should also check if the transmit window
- *	allows the sending of another pdu, and if not put the skb on the atq
- *	for deferred sending.
- */
-
-int llc_data_request(llcptr lp, struct sk_buff *skb)
-{
-	if (skb_headroom(skb) < (lp->dev->hard_header_len +4)){
-		printk("cl2llc: data_request() not enough headroom in skb\n");
-		return -1;
-	};
-
-	skb_push(skb, 4);
-
-	if ((lp->state != NORMAL) && (lp->state != BUSY) && (lp->state != REJECT))
-	{
-		printk("cl2llc: data_request() while no llc connection\n"); 
-		return -1;  
-	}
-
-	if (lp->remote_busy)
-	{     /* if the remote llc is BUSY, */
-		ADD_TO_ATQ(skb);      /* save skb in the await transmit queue */
-		return 0;
-	}                           
-	else
-	{
-		/*
-		 *	Else proceed with xmit 
-		 */
-
-		switch(lp->state)
-		{
-			case NORMAL:
-				if(lp->p_flag)
-					llc_interpret_pseudo_code(lp, NORMAL2, skb, NO_FRAME);
-				else
-					llc_interpret_pseudo_code(lp, NORMAL1, skb, NO_FRAME);
-				break;
-			case BUSY:
-				if (lp->p_flag)
-					llc_interpret_pseudo_code(lp, BUSY2, skb, NO_FRAME);
-				else
-					llc_interpret_pseudo_code(lp, BUSY1, skb, NO_FRAME);
-				break;
-			case REJECT:
-				if (lp->p_flag)
-					llc_interpret_pseudo_code(lp, REJECT2, skb, NO_FRAME);
-				else
-					llc_interpret_pseudo_code(lp, REJECT1, skb, NO_FRAME);
-				break;
-			default:;
-		}
-		if(lp->llc_callbacks)
-		{
-			lp->llc_event(lp);
-			lp->llc_callbacks=0;
-		}
-		return 0;  
-	}              
-}
-
-
-
-/* 
- *	Disconnect_request() requests that the llc to terminate a connection
- */
-
-void disconnect_request(llcptr lp)
-{
-	if ((lp->state == NORMAL) ||
-    		(lp->state == BUSY) ||
-		(lp->state == REJECT) ||
-		(lp->state == AWAIT) ||
-		(lp->state == AWAIT_BUSY) ||
-		(lp->state == AWAIT_REJECT))
-	{
-		lp->state = D_CONN;
-		llc_interpret_pseudo_code(lp, SH1, NULL, NO_FRAME);
-		if(lp->llc_callbacks)
-		{
-			lp->llc_event(lp);
-			lp->llc_callbacks=0;
-		}
-		/*
- 		 *	lp may be invalid after the callback
-		 */
-	}
-}
-
-
-/*
- *	Connect_request() requests that the llc to start a connection
- */
-
-void connect_request(llcptr lp)
-{
-	if (lp->state == ADM)
-	{
-		lp->state = SETUP;
-		llc_interpret_pseudo_code(lp, ADM1, NULL, NO_FRAME);
-		if(lp->llc_callbacks)
-		{
-			lp->llc_event(lp);
-			lp->llc_callbacks=0;
-		}
-		/*
- 		 *	lp may be invalid after the callback
-		 */
-	}
-}
-
-
-/*
- *	Interpret_pseudo_code() executes the actions in the connection component
- *	state transition table. Table 4 in document on p88.
- *
- *	If this function is called to handle an incoming pdu, skb will point
- *	to the buffer with the pdu and type will contain the decoded pdu type.
- *
- *	If called by data_request skb points to an skb that was skb_alloc-ed by 
- *	the llc client to hold the information unit to be transmitted, there is
- *	no valid type in this case.  
- *
- *	If called because a timer expired no skb is passed, and there is no 
- *	type.
- */
-
-void llc_interpret_pseudo_code(llcptr lp, int pc_label, struct sk_buff *skb, 
-		char type)
-{    
-	short int pc;	/* program counter in pseudo code array */ 
-	char p_flag_received;
-	frameptr fr;
-	int resend_count;   /* number of pdus resend by llc_resend_ipdu() */
-	int ack_count;      /* number of pdus acknowledged */
-	struct sk_buff *skb2;
-
-	if (skb != NULL) 
-	{
-		fr = (frameptr) skb->data;
-	}
-	else
-		fr = NULL;
-
-	pc = pseudo_code_idx[pc_label];
-	while(pseudo_code[pc])
-	{
-		switch(pseudo_code[pc])
-		{
-			case IF_F=1_CLEAR_REMOTE_BUSY:
-				if ((type != I_CMD) || (fr->i_hdr.i_pflag == 0))
-					break;
-			case CLEAR_REMOTE_BUSY:
-				lp->remote_busy = 0;
-				llc_stop_timer(lp, BUSY_TIMER);
-				if ((lp->state == NORMAL) ||
-					(lp->state == REJECT) ||
-					(lp->state == BUSY))
-				{
-					skb2 = llc_pull_from_atq(lp);
-					if (skb2 != NULL) 
-						llc_start_timer(lp, ACK_TIMER);
-					while (skb2 != NULL)
-					{
-						llc_sendipdu( lp, I_CMD, 0, skb2);
-						skb2 = llc_pull_from_atq(lp);
-					}
-				}	   
-				break;
-			case CONNECT_INDICATION:
-				lp->state = NORMAL;  /* needed to eliminate connect_response() */
-				lp->llc_mode = MODE_ABM;
-				lp->llc_callbacks|=LLC_CONN_INDICATION;
-				break;
-			case CONNECT_CONFIRM:
-				lp->llc_mode = MODE_ABM;
-				lp->llc_callbacks|=LLC_CONN_CONFIRM;
-				break;
-			case DATA_INDICATION:
-				skb_pull(skb, 4);
-				lp->inc_skb=skb;
-				lp->llc_callbacks|=LLC_DATA_INDIC;
-				break;
-			case DISCONNECT_INDICATION:
-				lp->llc_mode = MODE_ADM;
-				lp->llc_callbacks|=LLC_DISC_INDICATION;
-				break;
-			case RESET_INDICATION(LOCAL):
-				lp->llc_callbacks|=LLC_RESET_INDIC_LOC;
-				break;
-			case RESET_INDICATION(REMOTE):
-				lp->llc_callbacks|=LLC_RESET_INDIC_REM;
-				break;
-			case RESET_CONFIRM:
-				lp->llc_callbacks|=LLC_RST_CONFIRM;
-				break;
-			case REPORT_STATUS(FRMR_RECEIVED):
-				lp->llc_callbacks|=LLC_FRMR_RECV;
-				break;
-			case REPORT_STATUS(FRMR_SENT):
-				lp->llc_callbacks|=LLC_FRMR_SENT;
-				break;
-			case REPORT_STATUS(REMOTE_BUSY):
-				lp->llc_callbacks|=LLC_REMOTE_BUSY;
-				break;
-			case REPORT_STATUS(REMOTE_NOT_BUSY):
-				lp->llc_callbacks|=LLC_REMOTE_NOTBUSY;
-				break;
-			case SEND_DISC_CMD(P=X):
-				llc_sendpdu(lp, DISC_CMD, lp->f_flag, 0, NULL);
-				break;
-			case SEND_DM_RSP(F=X):
-				llc_sendpdu(lp, DM_RSP, 0, 0, NULL);
-				break;
-			case SEND_FRMR_RSP(F=X):                        
-				lp->frmr_info_fld.cntl1 = fr->pdu_cntl.byte1;
-				lp->frmr_info_fld.cntl2 = fr->pdu_cntl.byte2;
-				lp->frmr_info_fld.vs = lp->vs;
-				lp->frmr_info_fld.vr_cr = lp->vr;
-				llc_sendpdu(lp, FRMR_RSP, 0, 5, (char *) &lp->frmr_info_fld);
-				break;
-			case RE-SEND_FRMR_RSP(F=0):
-				llc_sendpdu(lp, FRMR_RSP, 0, 5, (char *) &lp->frmr_info_fld);
-				break;
-			case RE-SEND_FRMR_RSP(F=P):
-				llc_sendpdu(lp, FRMR_RSP, lp->p_flag,
-					5, (char *) &lp->frmr_info_fld);
-				break;
-			case SEND_I_CMD(P=1):
-				llc_sendipdu(lp, I_CMD, 1, skb);   
-				break;
-			case RE-SEND_I_CMD(P=1):
-				resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_CMD, 1);
-				break;
-			case RE-SEND_I_CMD(P=1)_OR_SEND_RR:
-				resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_CMD, 1);
-				if (resend_count == 0) 
-				{
-					llc_sendpdu(lp, RR_CMD, 1, 0, NULL);
-				}    
-				break;
-			case SEND_I_XXX(X=0):
-				llc_sendipdu(lp, I_CMD, 0, skb);   
-				break;
-			case RE-SEND_I_XXX(X=0):
-				resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_CMD, 0);
-				break;
-			case RE-SEND_I_XXX(X=0)_OR_SEND_RR:
-				resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_CMD, 0);
-				if (resend_count == 0) 
-				{
-					llc_sendpdu(lp, RR_CMD, 0, 0, NULL);
-				}    
-				break;
-			case RE-SEND_I_RSP(F=1):
-				resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_RSP, 1);
-				break;
-			case SEND_REJ_CMD(P=1):
-				llc_sendpdu(lp, REJ_CMD, 1, 0, NULL);
-				break;
-			case SEND_REJ_RSP(F=1):
-				llc_sendpdu(lp, REJ_RSP, 1, 0, NULL);
-				break;
-			case SEND_REJ_XXX(X=0):
-				if (IS_RSP(fr))
-					llc_sendpdu(lp, REJ_CMD, 0, 0, NULL);
-				else
-					llc_sendpdu(lp, REJ_RSP, 0, 0, NULL);
-				break;
-			case SEND_RNR_CMD(F=1):
-				llc_sendpdu(lp, RNR_CMD, 1, 0, NULL);
-				break;
-			case SEND_RNR_RSP(F=1):
-				llc_sendpdu(lp, RNR_RSP, 1, 0, NULL);
-				break;
-			case SEND_RNR_XXX(X=0):
-				if (IS_RSP(fr))
-					llc_sendpdu(lp, RNR_CMD, 0, 0, NULL);
-				else
-					llc_sendpdu(lp, RNR_RSP, 0, 0, NULL);
-				break;
-			case SET_REMOTE_BUSY:
-				if (lp->remote_busy == 0)
-				{
-					lp->remote_busy = 1;
-					llc_start_timer(lp, BUSY_TIMER);
-					lp->llc_callbacks|=LLC_REMOTE_BUSY;
-				}
-				else if (lp->timer_state[BUSY_TIMER] == TIMER_IDLE)
-				{
-					llc_start_timer(lp, BUSY_TIMER);
-				}
-				break;
-			case OPTIONAL_SEND_RNR_XXX(X=0):
-				if (IS_RSP(fr)) 
-					llc_sendpdu(lp, RNR_CMD, 0, 0, NULL);
-				else
-					llc_sendpdu(lp, RNR_RSP, 0, 0, NULL);
-				break;
-			case SEND_RR_CMD(P=1):
-				llc_sendpdu(lp, RR_CMD, 1, 0, NULL);
-				break;
-			case SEND_ACKNOWLEDGE_CMD(P=1):
-				llc_sendpdu(lp, RR_CMD, 1, 0, NULL);
-				break;
-			case SEND_RR_RSP(F=1):
-				llc_sendpdu(lp, RR_RSP, 1, 0, NULL);
-				break;
-			case SEND_ACKNOWLEDGE_RSP(F=1):
-				llc_sendpdu(lp, RR_RSP, 1, 0, NULL);
-				break;
-			case SEND_RR_XXX(X=0):
-				llc_sendpdu(lp, RR_RSP, 0, 0, NULL);
-				break;
-			case SEND_ACKNOWLEDGE_XXX(X=0):
-				if (IS_RSP(fr)) 
-					llc_sendpdu(lp, RR_CMD, 0, 0, NULL);
-				else
-					llc_sendpdu(lp, RR_RSP, 0, 0, NULL);
-				break;
-			case SEND_SABME_CMD(P=X):
-				llc_sendpdu(lp, SABME_CMD, 0, 0, NULL);
-				lp->f_flag = 0;
-				break;
-			case SEND_UA_RSP(F=X):
-				llc_sendpdu(lp, UA_RSP, lp->f_flag, 0, NULL);
-				break;
-			case S_FLAG:=0:
-				lp->s_flag = 0;
-				break;
-			case S_FLAG:=1:
-				lp->s_flag = 1;
-				break;
-			case START_P_TIMER:
-				if(lp->timer_state[P_TIMER] == TIMER_RUNNING)
-					llc_stop_timer(lp, P_TIMER);
-				llc_start_timer(lp, P_TIMER);
-				if (lp->p_flag == 0)
-				{
-					lp->retry_count = 0;
-					lp->p_flag = 1;
-				}
-				break;
-			case START_ACK_TIMER_IF_NOT_RUNNING:
-				if (lp->timer_state[ACK_TIMER] == TIMER_IDLE)
-					llc_start_timer(lp, ACK_TIMER);
-				break;
-			case START_ACK_TIMER:
-				llc_start_timer(lp, ACK_TIMER);
-				break;
-			case START_REJ_TIMER:
-				llc_start_timer(lp, REJ_TIMER);
-				break;
-			case STOP_ACK_TIMER:
-				llc_stop_timer(lp, ACK_TIMER);
-				break;
-			case STOP_P_TIMER:
-				llc_stop_timer(lp, ACK_TIMER);
-				lp->p_flag = 0;
-				break;
-			case IF_DATA_FLAG=2_STOP_REJ_TIMER:
-				if (lp->data_flag == 2)
-					llc_stop_timer(lp, REJ_TIMER);
-				break;
-			case STOP_REJ_TIMER:
-				llc_stop_timer(lp, REJ_TIMER);
-				break;
-			case STOP_ALL_TIMERS:
-				llc_stop_timer(lp, ACK_TIMER);
-				llc_stop_timer(lp, P_TIMER);
-				llc_stop_timer(lp, REJ_TIMER);
-				llc_stop_timer(lp, BUSY_TIMER);
-				break;
-			case STOP_OTHER_TIMERS:
-				llc_stop_timer(lp, P_TIMER);
-				llc_stop_timer(lp, REJ_TIMER);
-				llc_stop_timer(lp, BUSY_TIMER);
-				break;
-			case UPDATE_N(R)_RECEIVED:             
-				ack_count = llc_free_acknowledged_skbs(lp,
-					(unsigned char) fr->s_hdr.nr);
-				if (ack_count > 0)
-				{
-					lp->retry_count = 0;
-					llc_stop_timer(lp, ACK_TIMER);  
-					if (skb_peek(&lp->rtq) != NULL)
-					{
-						/*
- 						 *	Re-transmit queue not empty 
-						 */
-						llc_start_timer(lp, ACK_TIMER);  
-					}
-				}        
-				break;
-			case UPDATE_P_FLAG:
-				if (IS_UFRAME(fr)) 
-					p_flag_received = fr->u_hdr.u_pflag;
-				else
-					p_flag_received = fr->i_hdr.i_pflag;
-				if ((fr->pdu_hdr.ssap & 0x01) && (p_flag_received))
-				{
-					lp->p_flag = 0;
-					llc_stop_timer(lp, P_TIMER);  
-				}
-				break;
-			case DATA_FLAG:=2:
-				lp->data_flag = 2;
-				break;
-			case DATA_FLAG:=0:
-				lp->data_flag = 0;
-				break;
-			case DATA_FLAG:=1:
-				lp->data_flag = 1;
-				break;
-			case IF_DATA_FLAG_=0_THEN_DATA_FLAG:=1:
-				if (lp->data_flag == 0)
-					lp->data_flag = 1;
-				break;
-			case P_FLAG:=0:
-				lp->p_flag = 0;
-				break;
-			case P_FLAG:=P:
-				lp->p_flag = lp->f_flag;
-				break;
-			case REMOTE_BUSY:=0:
-				lp->remote_busy = 0;
-				break;
-			case RETRY_COUNT:=0:
-				lp->retry_count = 0;
-				break;
-			case RETRY_COUNT:=RETRY_COUNT+1:
-				lp->retry_count++;
-				break;
-			case V(R):=0:
-				lp->vr = 0;
-				break;
-			case V(R):=V(R)+1:
-				lp->vr++;
-				break;
-			case V(S):=0:
-				lp->vs = 0;
-				break;
-			case V(S):=N(R):
-				lp->vs = fr->i_hdr.nr;
-				break;
-			case F_FLAG:=P:
-				if (IS_UFRAME(fr)) 
-					lp->f_flag = fr->u_hdr.u_pflag;
-				else
-					lp->f_flag = fr->i_hdr.i_pflag;
-				break;
-			default:;
-		}
-		pc++;	
-	}
-}
-
-
-/*
- *	Process_otype2_frame will handle incoming frames
- *	for 802.2 Type 2 Procedure.
- */
-
-void llc_process_otype2_frame(llcptr lp, struct sk_buff *skb, char type)
-{
-	int idx;		/*	index in transition table */
-	int pc_label;		/*	action to perform, from tr tbl */
-	int validation;		/*	result of validate_seq_nos */
-	int p_flag_received;	/*	p_flag in received frame */
-	frameptr fr;
-
-	fr = (frameptr) skb->data;
-
-	if (IS_UFRAME(fr))
-		p_flag_received = fr->u_hdr.u_pflag;
-	else
-		p_flag_received = fr->i_hdr.i_pflag;
-
-	switch(lp->state)
-	{
-		/*	Compute index in transition table: */
-		case ADM:
-			idx = type;
-			idx = (idx << 1) + p_flag_received;
-			break;
-		case CONN:
-		case RESET_WAIT:
-		case RESET_CHECK:
-		case ERROR:
-			idx = type;
-			break;
-		case SETUP:
-		case RESET:
-		case D_CONN:
-			idx = type;
-			idx = (idx << 1) + lp->p_flag;
-			break;
-		case NORMAL:
-		case BUSY:
-		case REJECT:
-		case AWAIT:
-		case AWAIT_BUSY:
-		case AWAIT_REJECT:
-			validation = llc_validate_seq_nos(lp, fr);
-			if (validation > 3) 
-				type = BAD_FRAME;
-			idx = type;
-			idx = (idx << 1);
-			if (validation & 1) 
-				idx = idx +1;
-			idx = (idx << 1) + p_flag_received;
-			idx = (idx << 1) + lp->p_flag;
-		default:
-			printk("llc_proc: bad state\n");
-			return;
-	}
-	idx = (idx << 1) + pdutr_offset[lp->state];
-	lp->state = pdutr_entry[idx +1]; 
-	pc_label = pdutr_entry[idx];
-	if (pc_label != NOP)
-	{ 
-		llc_interpret_pseudo_code(lp, pc_label, skb, type);
-		if(lp->llc_callbacks)
-		{
-			lp->llc_event(lp);
-			lp->llc_callbacks=0;
-		}
-		/*
- 		 *	lp may no longer be valid after this point. Be
-		 *	careful what is added!
-		 */
-	}
-}
-
-
-void llc_timer_expired(llcptr lp, int t)
-{
-	int idx;		/* index in transition table	*/
-	int pc_label;       	/* action to perform, from tr tbl */
-
-	lp->timer_state[t] = TIMER_EXPIRED;
-	idx = lp->state;            /* Compute index in transition table: */
-	idx = (idx << 2) + t;
-	idx = idx << 1;
-	if (lp->retry_count >= lp->n2) 
-		idx = idx + 1;
-	idx = (idx << 1) + lp->s_flag;
-	idx = (idx << 1) + lp->p_flag;
-	idx = idx << 1;             /* 2 bytes per entry: action & newstate */
-
-	pc_label = timertr_entry[idx];
-	if (pc_label != NOP)
-	{
-		llc_interpret_pseudo_code(lp, pc_label, NULL, NO_FRAME);
-		lp->state = timertr_entry[idx +1];
-	}
-	lp->timer_state[t] = TIMER_IDLE;
-	if(lp->llc_callbacks)
-	{
-		lp->llc_event(lp);
-		lp->llc_callbacks=0;
-	}
-	/*
- 	 *	And lp may have vanished in the event callback
- 	 */
-}
-
diff -Nru a/net/802/llc_macinit.c b/net/802/llc_macinit.c
--- a/net/802/llc_macinit.c	Sat Aug 10 18:42:21 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,214 +0,0 @@
-/*
- * NET		An implementation of the IEEE 802.2 LLC protocol for the
- *		LINUX operating system.  LLC is implemented as a set of
- *		state machines and callbacks for higher networking layers.
- *
- *		Code for initialization, termination, registration and
- *		MAC layer glue.
- *
- *		Written by Tim Alpaerts, Tim_Alpaerts@toyota-motor-europe.com
- *
- *		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.
- *
- *	Changes
- *		Alan Cox	:	Chainsawed to Linux format
- *					Added llc_ to names
- *					Started restructuring handlers
- *
- *              Horst von Brand :      Add #include <linux/string.h>
- */
-
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/unistd.h>
-#include <linux/string.h>
-#include <linux/netdevice.h>
-#include <linux/init.h>
-#include <net/p8022.h>
-
-#include <asm/byteorder.h>
-
-#include <net/llc_frame.h>
-#include <net/llc.h>
-
-/*
- *	All incoming frames pass thru mac_data_indicate().
- *	On entry the llc structure related to the frame is passed as parameter. 
- *	The received sk_buffs with pdus other than I_CMD and I_RSP
- *	are freed by mac_data_indicate() after processing,
- *	the I pdu buffers are freed by the cl2llc client when it no longer needs
- *	the skb.
-*/
-
-int llc_mac_data_indicate(llcptr lp, struct sk_buff *skb)
-{
-	int ll;      		/* logical length == 802.3 length field */
-	unsigned char p_flag;
-	unsigned char type;
-	frameptr fr;
-	int free=1;
-
-	lp->inc_skb=NULL;
-	
-	/*
-	 *	Truncate buffer to true 802.3 length
-	 *	[FIXME: move to 802.2 demux]
-	 */
-
-	ll = *(skb->data -2) * 256 + *(skb->data -1);
-	skb_trim( skb, ll );
-
-	fr = (frameptr) skb->data;
-	type = llc_decode_frametype( fr );
-
-
-	if (type <= FRMR_RSP)
-	{
-		/*
-		 *	PDU is of the type 2 set
-		 */
-		if ((lp->llc_mode == MODE_ABM)||(type == SABME_CMD))
-			llc_process_otype2_frame(lp, skb, type);
-
-	}
-	else
-	{
-		/*
-		 *	PDU belongs to type 1 set
-		 */
-	        p_flag = fr->u_hdr.u_pflag;
-        	switch(type)
-        	{
-		        case TEST_CMD:
-				llc_sendpdu(lp, TEST_RSP, 0,ll -3,
-					fr->u_hdr.u_info);
-				break;
-			case TEST_RSP:
-				lp->llc_callbacks|=LLC_TEST_INDICATION;
-				lp->inc_skb=skb;
-				free=0;
-				break;
-			case XID_CMD:
-				/*
-				 *	Basic format XID is handled by LLC itself
-				 *	Doc 5.4.1.1.2 p 48/49
-				 */
-
-				if ((ll == 6)&&(fr->u_hdr.u_info[0] == 0x81))
-				{
-					lp->k = fr->u_hdr.u_info[2];
-					llc_sendpdu(lp, XID_RSP,
-						fr->u_hdr.u_pflag, ll -3,
-						fr->u_hdr.u_info);
-				}
-				break;
-
-			case XID_RSP:
-				if( ll == 6 && fr->u_hdr.u_info[0] == 0x81 )
-				{
-					lp->k = fr->u_hdr.u_info[2];
-				}
-				lp->llc_callbacks|=LLC_XID_INDICATION;
-				lp->inc_skb=skb;
-				free=0;
-				break;
-
-			case UI_CMD:
-				lp->llc_callbacks|=LLC_UI_DATA;
-				skb_pull(skb,3);
-				lp->inc_skb=skb;
-				free=0;
-				break;
-
-			default:;
-				/*
-				 *	All other type 1 pdus ignored for now
-				 */
-		}
-	}
-
-	if (free&&(!(IS_IFRAME(fr))))
-	{
-		/*
-		 *	No auto free for I pdus
-		 */
-		skb->sk = NULL;
-		kfree_skb(skb);
-	}
-
-	if(lp->llc_callbacks)
-	{
-		if ( lp->llc_event != NULL ) lp->llc_event(lp);
-		lp->llc_callbacks=0;
-	}
-	return 0;
-}
-
-
-/*
- *	Create an LLC client. As it is the job of the caller to clean up
- *	LLC's on device down, the device list must be locked before this call.
- */
-
-int register_cl2llc_client(llcptr lp, const char *device, void (*event)(llcptr), u8 *rmac, u8 ssap, u8 dsap)
-{
-	char eye_init[] = "LLC\0";
-
-	memset(lp, 0, sizeof(*lp));
-	lp->dev = __dev_get_by_name(device);
-	if(lp->dev == NULL)
-		return -ENODEV;
-	memcpy(lp->eye, eye_init, sizeof(lp->eye));
-	lp->rw = 1;
-	lp->k = 127;
-	lp->n1 = 1490;
-	lp->n2 = 10;
-	lp->timer_interval[P_TIMER] = HZ;    /* 1 sec */
-	lp->timer_interval[REJ_TIMER] = HZ/8;
-	lp->timer_interval[ACK_TIMER] = HZ/8;
-	lp->timer_interval[BUSY_TIMER] = HZ*2;
-	lp->local_sap = ssap;
-	lp->llc_event = event;
-	memcpy(lp->remote_mac, rmac, sizeof(lp->remote_mac));
-	lp->state = 0;
-	lp->llc_mode = MODE_ADM;
-	lp->remote_sap = dsap;
-	skb_queue_head_init(&lp->atq);
-	skb_queue_head_init(&lp->rtq);
-	MOD_INC_USE_COUNT;
-	return 0;
-}
-
-
-void unregister_cl2llc_client(llcptr lp)
-{
-	llc_cancel_timers(lp);
-	MOD_DEC_USE_COUNT;
-	kfree(lp);
-}
-
-
-EXPORT_SYMBOL(register_cl2llc_client);
-EXPORT_SYMBOL(unregister_cl2llc_client);
-EXPORT_SYMBOL(llc_data_request);
-EXPORT_SYMBOL(llc_unit_data_request);
-EXPORT_SYMBOL(llc_test_request);
-EXPORT_SYMBOL(llc_xid_request);
-EXPORT_SYMBOL(llc_mac_data_indicate);
-EXPORT_SYMBOL(llc_cancel_timers);
-
-#define ALL_TYPES_8022 0
-
-static int __init llc_init(void)
-{
-	printk(KERN_NOTICE "IEEE 802.2 LLC for Linux 2.1 (c) 1996 Tim Alpaerts\n");
-	return 0;
-}
-
-
-module_init(llc_init);
diff -Nru a/net/802/llc_sendpdu.c b/net/802/llc_sendpdu.c
--- a/net/802/llc_sendpdu.c	Sat Aug 10 18:42:20 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,357 +0,0 @@
-/*
- * NET		An implementation of the IEEE 802.2 LLC protocol for the
- *		LINUX operating system.  LLC is implemented as a set of 
- *		state machines and callbacks for higher networking layers.
- *
- *		llc_sendpdu(), llc_sendipdu(), resend() + queue handling code
- *
- *		Written by Tim Alpaerts, Tim_Alpaerts@toyota-motor-europe.com
- *
- *		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.
- *
- *	Changes
- *		Alan Cox	:	Chainsawed into Linux format, style
- *					Added llc_ to function names
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <net/p8022.h>
-#include <linux/stat.h>
-#include <asm/byteorder.h>
-#include <net/llc_frame.h>
-#include <net/llc.h>
-
-static unsigned char cntl_byte_encode[] = 
-{
-	0x00,   /* I_CMD */
-	0x01,   /* RR_CMD */
-	0x05,   /* RNR_CMD */
-	0x09,   /* REJ_CMD */
-	0x43,   /* DISC_CMD */
-	0x7F,   /* SABME_CMD */
-	0x00,   /* I_RSP */
-	0x01,   /* RR_RSP */
-	0x05,   /* RNR_RSP */
-	0x09,   /* REJ_RSP */
-	0x63,   /* UA_RSP */
-	0x0F,   /* DM_RSP */
-	0x87,   /* FRMR_RSP */
-	0xFF,   /* BAD_FRAME */
-	0x03,   /* UI_CMD */
-	0xBF,   /* XID_CMD */
-	0xE3,   /* TEST_CMD */
-	0xBF,   /* XID_RSP */
-	0xE3    /* TEST_RSP */
-};
-
-static unsigned char fr_length_encode[] = 
-{
-	0x04,   /* I_CMD */
-	0x04,   /* RR_CMD */
-	0x04,   /* RNR_CMD */
-	0x04,   /* REJ_CMD */
-	0x03,   /* DISC_CMD */
-	0x03,   /* SABME_CMD */
-	0x04,   /* I_RSP */
-	0x04,   /* RR_RSP */
-	0x04,   /* RNR_RSP */
-	0x04,   /* REJ_RSP */
-	0x03,   /* UA_RSP */
-	0x03,   /* DM_RSP */
-	0x03,   /* FRMR_RSP */
-	0x00,   /* BAD_FRAME */
-	0x03,   /* UI_CMD */
-	0x03,   /* XID_CMD */
-	0x03,   /* TEST_CMD */
-	0x03,   /* XID_RSP */
-	0x03    /* TEST_RSP */
-};
-
-static unsigned char cr_bit_encode[] = {
-	0x00,   /* I_CMD */
-	0x00,   /* RR_CMD */
-	0x00,   /* RNR_CMD */
-	0x00,   /* REJ_CMD */
-	0x00,   /* DISC_CMD */
-	0x00,   /* SABME_CMD */
-	0x01,   /* I_RSP */
-	0x01,   /* RR_RSP */
-	0x01,   /* RNR_RSP */
-	0x01,   /* REJ_RSP */
-	0x01,   /* UA_RSP */
-	0x01,   /* DM_RSP */
-	0x01,   /* FRMR_RSP */
-	0x00,   /* BAD_FRAME */
-	0x00,   /* UI_CMD */
-	0x00,   /* XID_CMD */
-	0x00,   /* TEST_CMD */
-	0x01,   /* XID_RSP */
-	0x01    /* TEST_RSP */
-};
-
-/*
- *	Sendpdu() constructs an output frame in a new skb and
- *	gives it to the MAC layer for transmission.
- *	This function is not used to send I pdus.
- *	No queues are updated here, nothing is saved for retransmission.
- *
- *	Parameter pf controls both the poll/final bit and dsap
- *	fields in the output pdu. 
- *	The dsap trick was needed to implement XID_CMD send with
- *	zero dsap field as described in doc 6.6 item 1 of enum.  
- */
-
-void llc_sendpdu(llcptr lp, char type, char pf, int data_len, char *pdu_data)
-{
-	frameptr fr;                /* ptr to output pdu buffer */
-	unsigned short int fl;      /* frame length == 802.3 "length" value */
-	struct sk_buff *skb;
-
-	fl = data_len + fr_length_encode[(int)type];
-	skb = alloc_skb(16 + fl, GFP_ATOMIC); 
-	if (skb != NULL)
-	{
-		skb->dev = lp->dev;	
-	        skb_reserve(skb, 16);
-		fr = (frameptr) skb_put(skb, fl);
-		memset(fr, 0, fl);
-                /*
-                 *	Construct 802.2 header 
-                 */
-		if (pf & 0x02) 
-			fr->pdu_hdr.dsap = 0;
-		else
-			fr->pdu_hdr.dsap = lp->remote_sap;
-		fr->pdu_hdr.ssap = lp->local_sap + cr_bit_encode[(int)type];
-		fr->pdu_cntl.byte1 = cntl_byte_encode[(int)type];
-		/* 
-		 *	Fill in pflag and seq nbrs: 
-		 */
-		if (IS_SFRAME(fr)) 
-		{
-		  	/* case S-frames */
-			if (pf & 0x01) 
-				fr->i_hdr.i_pflag = 1;
-			fr->i_hdr.nr = lp->vr;
-		}
-		else
-		{
-			/* case U frames */ 
-			if (pf & 0x01) 
-				fr->u_hdr.u_pflag = 1;
-		}
-                       
-		if (data_len > 0) 
-		{ 			/* append data if any  */ 
-			if (IS_UFRAME(fr)) 
-			{
-				memcpy(fr->u_hdr.u_info, pdu_data, data_len);
-			}
-			else 
-			{
-				memcpy(fr->i_hdr.is_info, pdu_data, data_len);
-			}
-		}
-		lp->dev->hard_header(skb, lp->dev, ETH_P_802_3,
-			 lp->remote_mac, NULL, fl);
-		skb->dev=lp->dev;
-		dev_queue_xmit(skb);
-	}
-	else
-		printk(KERN_DEBUG "cl2llc: skb_alloc() in llc_sendpdu() failed\n");     
-}
-
-void llc_xid_request(llcptr lp, char opt, int ll, char * data)
-{
-	llc_sendpdu(lp, XID_CMD, opt, ll, data); 
-}
-
-void llc_test_request(llcptr lp, int ll, char * data)
-{
-	llc_sendpdu(lp, TEST_CMD, 0, ll, data); 
-}
-
-void llc_unit_data_request(llcptr lp, int ll, char * data)
-{
-	llc_sendpdu(lp, UI_CMD, 0, ll, data); 
-}
-
-
-/*
- *	llc_sendipdu() Completes an I pdu in an existing skb and gives it
- *	to the MAC layer for transmission.
- *	Parameter "type" must be either I_CMD or I_RSP.
- *	The skb is not freed after xmit, it is kept in case a retransmission
- *	is requested. If needed it can be picked up again from the rtq.
- */
-
-void llc_sendipdu(llcptr lp, char type, char pf, struct sk_buff *skb)
-{
-	frameptr fr;                /* ptr to output pdu buffer */
-	struct sk_buff *tmp;
-	
-	fr = (frameptr) skb->data;
-
-	fr->pdu_hdr.dsap = lp->remote_sap;
-	fr->pdu_hdr.ssap = lp->local_sap + cr_bit_encode[(int)type];
-	fr->pdu_cntl.byte1 = cntl_byte_encode[(int)type];
-			
-	if (pf)
-		fr->i_hdr.i_pflag = 1; /* p/f and seq numbers */  
-	fr->i_hdr.nr = lp->vr;
-	fr->i_hdr.ns = lp->vs;
-	lp->vs++;
-	if (lp->vs > 127) 
-		lp->vs = 0;
-	lp->dev->hard_header(skb, lp->dev, ETH_P_802_3,
-		lp->remote_mac, NULL, skb->len);
-	ADD_TO_RTQ(skb);		/* add skb to the retransmit queue */
-	tmp=skb_clone(skb, GFP_ATOMIC);
-	if(tmp!=NULL)
-	{
-		tmp->dev=lp->dev;
-		dev_queue_xmit(tmp);
-	}
-}
-
-
-/*
- *	Resend_ipdu() will resend the pdus in the retransmit queue (rtq)
- *	the return value is the number of pdus resend.
- *	ack_nr is N(R) of 1st pdu to resent.
- *	Type is I_CMD or I_RSP for 1st pdu resent.
- *	p is p/f flag 0 or 1 for 1st pdu resent.
- *	All subsequent pdus will be sent as I_CMDs with p/f set to 0
- */ 
-
-int llc_resend_ipdu(llcptr lp, unsigned char ack_nr, unsigned char type, char p)
-{
-	struct sk_buff *skb,*tmp;
-	int resend_count;
-	frameptr fr;
-	unsigned long flags;
-	
-
-	resend_count = 0;
-	
-	save_flags(flags);
-	cli();
-	
-	skb = skb_peek(&lp->rtq);
-
-	while(skb && skb != (struct sk_buff *)&lp->rtq)
-	{
-		fr = (frameptr) (skb->data + lp->dev->hard_header_len);
-		if (resend_count == 0) 
-		{
-			/* 
-			 *	Resending 1st pdu: 
-			 */
-
-			if (p) 
-				fr->i_hdr.i_pflag = 1;
-			else
-				fr->i_hdr.i_pflag = 0;
-            
-			if (type == I_CMD)           
-				fr->pdu_hdr.ssap = fr->pdu_hdr.ssap & 0xfe;
-			else
-				fr->pdu_hdr.ssap = fr->pdu_hdr.ssap | 0x01;
-		}
-	        else
-	        {
-	        	/*
-	        	 *	Resending pdu 2...n 
-	        	 */
-
-			fr->pdu_hdr.ssap = fr->pdu_hdr.ssap & 0xfe;
-			fr->i_hdr.i_pflag = 0;
-		}
-		fr->i_hdr.nr = lp->vr;
-		fr->i_hdr.ns = lp->vs;
-		lp->vs++;
-		if (lp->vs > 127) 
-			lp->vs = 0;
-		tmp=skb_clone(skb, GFP_ATOMIC);
-		if(tmp!=NULL)
-		{
-			tmp->dev = lp->dev;
-			dev_queue_xmit(skb);
-		}
-		resend_count++;
-		skb = skb->next;
-	}
-	restore_flags(flags);
-	return resend_count;
-}
-
-/* ************** internal queue management code ****************** */
-
-
-/*
- *	Remove one skb from the front of the awaiting transmit queue
- *	(this is the skb longest on the queue) and return a pointer to 
- *	that skb. 
- */ 
-
-struct sk_buff *llc_pull_from_atq(llcptr lp) 
-{
-	return skb_dequeue(&lp->atq);
-}
- 
-/*
- *	Free_acknowledged_skbs(), remove from retransmit queue (rtq)
- *	and free all skbs with an N(S) chronologicaly before 'pdu_ack'.
- *	The return value is the number of pdus acknowledged.
- */
- 
-int llc_free_acknowledged_skbs(llcptr lp, unsigned char pdu_ack)
-{
-	struct sk_buff *pp;
-	frameptr fr; 
-	int ack_count;
-	unsigned char ack; 	/* N(S) of most recently ack'ed pdu */
-	unsigned char ns_save; 
-	unsigned long flags;
-
-	if (pdu_ack > 0) 
-		ack = pdu_ack -1;
-	else 
-		ack = 127;
-
-	ack_count = 0;
-
-	save_flags(flags);
-	cli();
-
-	pp = skb_dequeue(&lp->rtq); 
-	while (pp != NULL)
-	{
-		/* 
-		 *	Locate skb with N(S) == ack 
-		 */
-
-		/*
-		 *	BUG: FIXME - use skb->h.*
-		 */
-		fr = (frameptr) (pp->data + lp->dev->hard_header_len);
-		ns_save = fr->i_hdr.ns;
-
-		kfree_skb(pp);
-		ack_count++;
-
-		if (ns_save == ack) 
-			break;  
-		pp = skb_dequeue(&lp->rtq);
-	}
-	restore_flags(flags);
-	return ack_count; 
-}
-
diff -Nru a/net/802/llc_utility.c b/net/802/llc_utility.c
--- a/net/802/llc_utility.c	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,253 +0,0 @@
-/*
- * NET		An implementation of the IEEE 802.2 LLC protocol for the
- *		LINUX operating system.  LLC is implemented as a set of 
- *		state machines and callbacks for higher networking layers.
- *
- *		Small utilities, Linux timer handling.
- *
- *		Written by Tim Alpaerts, Tim_Alpaerts@toyota-motor-europe.com
- *
- *		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.
- *
- *	Changes
- *		Alan Cox	:	Chainsawed into Linux form.
- *					Added llc_ function name prefixes.
- *					Fixed bug in stop/start timer.
- *					Added llc_cancel_timers for closing
- *						down an llc
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/skbuff.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <net/llc_frame.h>
-#include <net/llc.h>
-
-int llc_decode_frametype(frameptr fr)
-{
-	if (IS_UFRAME(fr)) 
-	{      /* unnumbered cmd/rsp */
-		switch(fr->u_mm.mm & 0x3B)
-		{
-			case 0x1B:
-			    return(SABME_CMD);
-			    break;
-			case 0x10:
-			    return(DISC_CMD);
-			    break;
-			case 0x18:
-			    return(UA_RSP);
-			    break;
-			case 0x03:
-			    return(DM_RSP);
-			    break;
-			case 0x21:
-			    return(FRMR_RSP);
-			    break;
-			case 0x00:
-			    return(UI_CMD);
-			    break;
-			case 0x2B:
-		 	    if (IS_RSP(fr)) 
-		 	    	return(XID_RSP);
-			    else
-			    	return(XID_CMD);
-			    break;
-			case 0x38:
-		    	    if (IS_RSP(fr))
-		    	    	return(TEST_RSP);
-			    else
-				return(TEST_CMD);
-			    break;
-			default:
-			    return(BAD_FRAME);
-		}
-	}
-	else if (IS_SFRAME(fr))
-	{  /* supervisory cmd/rsp */
-		switch(fr->s_hdr.ss)
-		{
-			case 0x00:
-			    if (IS_RSP(fr)) 
-			    	return(RR_RSP);
-			    else
-			    	return(RR_CMD);
-			    break;
-			case 0x02:
-			    if (IS_RSP(fr))
-			    	return(REJ_RSP);
-			    else
-			    	return(REJ_CMD);
-			    break;
-			case 0x01:
-			    if (IS_RSP(fr))
-			    	return(RNR_RSP);
-			    else
-			    	return(RNR_CMD);
-			    break;
-			default:
-			    return(BAD_FRAME);
-		}
-	}
-	else
-	{			  /* information xfer */
-		if (IS_RSP(fr)) 
-			return(I_RSP);
-		else	
-			return(I_CMD);
-	}
-}
-
-
-/*
- *	Validate_seq_nos will check N(S) and N(R) to see if they are
- *	invalid or unexpected.
- *	"unexpected" is explained on p44 Send State Variable.
- *	The return value is:
- *		4 * invalid N(R) +
- *		2 * invalid N(S) +
- *		1 * unexpected N(S)
- */
-
-int llc_validate_seq_nos(llcptr lp, frameptr fr)
-{
-	int res;
-     
-	/*
-	 *	A U-frame is always good 
-	 */
-
-	if (IS_UFRAME(fr)) 
-		return(0);	
-
-	/*
-	 *	For S- and I-frames check N(R): 
-	 */
-
-	if (fr->i_hdr.nr == lp->vs) 
-	{    	/* if N(R) = V(S)  */
-        	res = 0;                        /* N(R) is good */
-	}
-	else
-	{				/* lp->k = transmit window size */
-    		if (lp->vs >= lp->k) 
-    		{	/* if window not wrapped around 127 */
-			if ((fr->i_hdr.nr < lp->vs) &&
-				(fr->i_hdr.nr > (lp->vs - lp->k)))
-				res = 0;
-			else 
-				res = 4;		/* N(R) invalid */
-		}
-		else
-		{	/* window wraps around 127 */
-			if ((fr->i_hdr.nr < lp->vs) ||
-				(fr->i_hdr.nr > (128 + lp->vs - lp->k))) 
-				res = 0;
-			else
-				res = 4;		/* N(R) invalid */
-		}
-	}
-
-	/*
-	 *	For an I-frame, must check N(S) also:  
-	 */
-
-	if (IS_IFRAME(fr)) 
-	{
-    		if (fr->i_hdr.ns == lp->vr) 
-    			return res;   /* N(S) good */
-		if (lp->vr >= lp->rw) 
-		{
-			/* if receive window not wrapped */
-
-			if ((fr->i_hdr.ns < lp->vr) &&
-				(fr->i_hdr.ns > (lp->vr - lp->k)))
-				res = res +1;   	/* N(S) unexpected */
-			else  
-				res = res +2;         /* N(S) invalid */            
-		}
-		else
-		{
-			/* Window wraps around 127 */
-
-			if ((fr->i_hdr.ns < lp->vr) ||
-				(fr->i_hdr.ns > (128 + lp->vr - lp->k)))
-				res = res +1;   	/* N(S) unexpected */
-			else
-				res = res +2;         /* N(S) invalid */            
-		}
-	}					
-	return(res);
-}
-
-/* **************** timer management routines ********************* */
-
-static void llc_p_timer_expired(unsigned long ulp)
-{
-	llc_timer_expired((llcptr) ulp, P_TIMER);
-}
-
-static void llc_rej_timer_expired(unsigned long ulp)
-{
-	llc_timer_expired((llcptr) ulp, REJ_TIMER);
-}
-
-static void llc_ack_timer_expired(unsigned long ulp)
-{
-	llc_timer_expired((llcptr) ulp, ACK_TIMER);
-} 
-
-static void llc_busy_timer_expired(unsigned long ulp)
-{
-	llc_timer_expired((llcptr) ulp, BUSY_TIMER);
-}
-
-/* exp_fcn is an array holding the 4 entry points of the
-   timer expiry routines above.
-   It is required to keep start_timer() generic.
-   Thank you cdecl.
- */
-
-static void (* exp_fcn[])(unsigned long) = 
-{
-	llc_p_timer_expired,
-	llc_rej_timer_expired,
-	llc_ack_timer_expired,
-	llc_busy_timer_expired
-};   
-
-void llc_start_timer(llcptr lp, int t)
-{
-	if (lp->timer_state[t] == TIMER_IDLE)
-	{
-    		lp->tl[t].expires = jiffies + lp->timer_interval[t];
-    		lp->tl[t].data = (unsigned long) lp;
-    		lp->tl[t].function = exp_fcn[t];
-    		add_timer(&lp->tl[t]);
-    		lp->timer_state[t] = TIMER_RUNNING;
-	}
-}
-
-void llc_stop_timer(llcptr lp, int t)
-{
-	if (lp->timer_state[t] == TIMER_RUNNING)
-	{
-        	del_timer(&lp->tl[t]);
-        	lp->timer_state[t] = TIMER_IDLE;
-	}
-}
-
-void llc_cancel_timers(llcptr lp)
-{
-	llc_stop_timer(lp, P_TIMER);
-	llc_stop_timer(lp, REJ_TIMER);
-	llc_stop_timer(lp, ACK_TIMER);
-	llc_stop_timer(lp, BUSY_TIMER);
-}
-
diff -Nru a/net/802/p8022.c b/net/802/p8022.c
--- a/net/802/p8022.c	Sat Aug 10 18:42:21 2002
+++ b/net/802/p8022.c	Sat Aug 10 18:42:21 2002
@@ -25,9 +25,9 @@
 #include <net/p8022.h>
 
 extern void llc_register_sap(unsigned char sap,
-			       int (*rcvfunc)(struct sk_buff *,
-					      struct net_device *,
-					       struct packet_type *));
+			     int (*rcvfunc)(struct sk_buff *,
+					    struct net_device *,
+					    struct packet_type *));
 extern void llc_unregister_sap(unsigned char sap);
 
 static struct datalink_proto *p8022_list;
@@ -124,3 +124,5 @@
 
 EXPORT_SYMBOL(register_8022_client);
 EXPORT_SYMBOL(unregister_8022_client);
+
+MODULE_LICENSE("GPL");
diff -Nru a/net/802/pseudo/actionnm.awk b/net/802/pseudo/actionnm.awk
--- a/net/802/pseudo/actionnm.awk	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,27 +0,0 @@
-# usage: awk -f actionnm.awk pseudocode.h
-#
-BEGIN { "date" | getline
-	today = $0
-	printf("\n/* this file generated on %s  */\n", today )
-	printf("\nstatic char *action_names[] = { \n    " )
-	opl = 0
-}
-
-/^#define/ {			
-	if ( opl > 3 ) {
-	    printf("\n    ")
-	    opl = 0
-	}
-	opl = opl +1
-	t = sprintf("\"%s\"", $2 )
-	printf("%-15s ,", t )
-#	printf("%-10s", $2 )
-}
-
-END {		
-	if ( opl > 3 ) {
-	    printf("\n    ")
-	}
-	printf("\t  0\n};\n\n")
-}
-
diff -Nru a/net/802/pseudo/compile.awk b/net/802/pseudo/compile.awk
--- a/net/802/pseudo/compile.awk	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,57 +0,0 @@
-# usage: cat pseudocode | sed -f act2num | awk -f compile.awk
-#
-#
-BEGIN { "date" | getline
-	today = $0
-	printf("\n/* this file generated on %s  */\n", today )
-	printf("\nstatic char pseudo_code [ ] = { \n" )
-	opl = 0			# op codes on the current line
-
-	opc = 0			# opcode counter
-	fpi = 0			# fill pointer for idx array
-}
-
-/^;/ { } 			# line starting with semicolon is comment 
-
-/^[A-Z]/ {			# start of a new action 
-	emit( 0 )
-	idx[ ++fpi ] = opc
-	name[ fpi ] = $1 
-	emit( $2 )
-}
-
-/^[\t ]/ { 
-        emit( $1 )
-}
-
-END {		
-	if ( opl > 8 ) {
-	    printf("\n")
-	}
-	printf("\t  0\n};\n\n")
-	printf("static short int pseudo_code_idx [ ] ={\n")
-	opl = 0
-	emit( 0 )
-	for( ii = 1; ii <= fpi; ii++ )
-	   emit( idx[ ii ] )
-	if ( opl > 8 ) {
-	    printf("\n")
-	}
-	printf("\t  0\n};\n\n")
-
-	printf("#define %-10s \t %3d \n", "NOP", 0 )
-	for( ii = 1; ii <= fpi; ii++ )
-	    printf("#define %-10s \t %3d \n", name[ ii ], ii )
-	printf("\n")
-}
-
-function emit( opcode ){	# Niclaus Wirth
-	if ( opl > 8 ) {
-	    printf("\n")
-	    opl = 0
-	}
-	opl = opl +1
-	printf("\t%4d,", opcode )
-	opc++
-}
-
diff -Nru a/net/802/pseudo/opcd2num.sed b/net/802/pseudo/opcd2num.sed
--- a/net/802/pseudo/opcd2num.sed	Sat Aug 10 18:42:22 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,72 +0,0 @@
-s/NOP/0/
-s/DUMMY_6/6/
-s/DUMMY_8/8/
-s/IF_F=1_CLEAR_REMOTE_BUSY/9/
-s/CLEAR_REMOTE_BUSY/1/
-s/CONNECT_CONFIRM/3/
-s/DISCONNECT_INDICATION/5/
-s/CONNECT_INDICATION/2/
-s/IF_DATA_FLAG_=0_THEN_DATA_FLAG:=1/55/
-s/DATA_FLAG:=0/53/
-s/DATA_FLAG:=1/54/
-s/DATA_FLAG:=2/52/
-s/DATA_INDICATION/4/
-s/F_FLAG:=P/65/
-s/IF_DATA_FLAG=2_STOP_REJ_TIMER/10/
-s/OPTIONAL_SEND_RNR_XXX(X=0)/30/
-s/P_FLAG:=0/56/
-s/P_FLAG:=P/57/
-s/RE-SEND_FRMR_RSP(F=0)/14/
-s/RE-SEND_FRMR_RSP(F=P)/15/
-s/RE-SEND_I_CMD(P=1)_OR_SEND_RR/18/
-s/RE-SEND_I_CMD(P=1)/17/
-s/RE-SEND_I_RSP(F=1)/22/
-s/RE-SEND_I_XXX(X=0)_OR_SEND_RR/21/
-s/RE-SEND_I_XXX(X=0)/20/
-s/REMOTE_BUSY:=0/58/
-s/REPORT_STATUS(FRMR_RECEIVED)/66/
-s/REPORT_STATUS(FRMR_SENT)/67/
-s/REPORT_STATUS(REMOTE_BUSY)/68/
-s/REPORT_STATUS(REMOTE_NOT_BUSY)/69/
-s/RESET_CONFIRM/7/
-s/RESET_INDICATION(LOCAL)/70/
-s/RESET_INDICATION(REMOTE)/71/
-s/RETRY_COUNT:=RETRY_COUNT+1/60/
-s/RETRY_COUNT:=0/59/
-s/SEND_ACKNOWLEDGE_CMD(P=1)/32/
-s/SEND_ACKNOWLEDGE_RSP(F=1)/34/
-s/SEND_ACKNOWLEDGE_XXX(X=0)/36/
-s/SEND_DISC_CMD(P=X)/11/
-s/SEND_DM_RSP(F=X)/12/
-s/SEND_FRMR_RSP(F=X)/13/
-s/SEND_I_CMD(P=1)/16/
-s/SEND_I_XXX(X=0)/19/
-s/SEND_REJ_CMD(P=1)/23/
-s/SEND_REJ_RSP(F=1)/24/
-s/SEND_REJ_XXX(X=0)/25/
-s/SEND_RNR_CMD(F=1)/26/
-s/SEND_RNR_RSP(F=1)/27/
-s/SEND_RNR_XXX(X=0)/28/
-s/SEND_RR_CMD(P=1)/31/
-s/SEND_RR_RSP(F=1)/33/
-s/SEND_RR_XXX(X=0)/35/
-s/SEND_SABME_CMD(P=X)/37/
-s/SEND_UA_RSP(F=X)/38/
-s/SET_REMOTE_BUSY/29/
-s/START_ACK_TIMER_IF_NOT_RUNNING/44/
-s/START_ACK_TIMER/42/
-s/START_P_TIMER/41/
-s/START_REJ_TIMER/43/
-s/STOP_ACK_TIMER/45/
-s/STOP_ALL_TIMERS/48/
-s/STOP_OTHER_TIMERS/49/
-s/STOP_P_TIMER/46/
-s/STOP_REJ_TIMER/47/
-s/S_FLAG:=0/39/
-s/S_FLAG:=1/40/
-s/UPDATE_N(R)_RECEIVED/50/
-s/UPDATE_P_FLAG/51/
-s/V(R):=0/61/
-s/V(R):=V(R)+1/62/
-s/V(S):=0/63/
-s/V(S):=N(R)/64/
diff -Nru a/net/802/pseudo/opcodes b/net/802/pseudo/opcodes
--- a/net/802/pseudo/opcodes	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,72 +0,0 @@
-   0	NOP
-   1	CLEAR_REMOTE_BUSY
-   2	CONNECT_INDICATION
-   3	CONNECT_CONFIRM
-   4	DATA_INDICATION
-   5	DISCONNECT_INDICATION
-   6	DUMMY_6
-   7	RESET_CONFIRM
-   8	DUMMY_8
-   9	IF_F=1_CLEAR_REMOTE_BUSY
-  10	IF_DATA_FLAG=2_STOP_REJ_TIMER
-  11	SEND_DISC_CMD(P=X)
-  12	SEND_DM_RSP(F=X)
-  13	SEND_FRMR_RSP(F=X)
-  14	RE-SEND_FRMR_RSP(F=0)
-  15	RE-SEND_FRMR_RSP(F=P)
-  16	SEND_I_CMD(P=1)
-  17	RE-SEND_I_CMD(P=1)
-  18	RE-SEND_I_CMD(P=1)_OR_SEND_RR
-  19	SEND_I_XXX(X=0)
-  20	RE-SEND_I_XXX(X=0)
-  21	RE-SEND_I_XXX(X=0)_OR_SEND_RR
-  22	RE-SEND_I_RSP(F=1)
-  23	SEND_REJ_CMD(P=1)
-  24	SEND_REJ_RSP(F=1)
-  25	SEND_REJ_XXX(X=0)
-  26	SEND_RNR_CMD(F=1)
-  27	SEND_RNR_RSP(F=1)
-  28	SEND_RNR_XXX(X=0)
-  29	SET_REMOTE_BUSY
-  30	OPTIONAL_SEND_RNR_XXX(X=0)
-  31	SEND_RR_CMD(P=1)
-  32	SEND_ACKNOWLEDGE_CMD(P=1)
-  33	SEND_RR_RSP(F=1)
-  34	SEND_ACKNOWLEDGE_RSP(F=1)
-  35	SEND_RR_XXX(X=0)
-  36	SEND_ACKNOWLEDGE_XXX(X=0)
-  37	SEND_SABME_CMD(P=X)
-  38	SEND_UA_RSP(F=X)
-  39	S_FLAG:=0
-  40	S_FLAG:=1
-  41	START_P_TIMER
-  42	START_ACK_TIMER
-  43	START_REJ_TIMER
-  44	START_ACK_TIMER_IF_NOT_RUNNING
-  45	STOP_ACK_TIMER
-  46	STOP_P_TIMER
-  47	STOP_REJ_TIMER
-  48	STOP_ALL_TIMERS
-  49	STOP_OTHER_TIMERS
-  50	UPDATE_N(R)_RECEIVED
-  51	UPDATE_P_FLAG
-  52	DATA_FLAG:=2
-  53	DATA_FLAG:=0
-  54	DATA_FLAG:=1
-  55	IF_DATA_FLAG_=0_THEN_DATA_FLAG:=1
-  56	P_FLAG:=0
-  57	P_FLAG:=P
-  58	REMOTE_BUSY:=0
-  59	RETRY_COUNT:=0
-  60	RETRY_COUNT:=RETRY_COUNT+1
-  61	V(R):=0
-  62	V(R):=V(R)+1
-  63	V(S):=0
-  64	V(S):=N(R)
-  65	F_FLAG:=P
-  66	REPORT_STATUS(FRMR_RECEIVED)
-  67	REPORT_STATUS(FRMR_SENT)
-  68	REPORT_STATUS(REMOTE_BUSY)
-  69	REPORT_STATUS(REMOTE_NOT_BUSY)
-  70	RESET_INDICATION(LOCAL)
-  71	RESET_INDICATION(REMOTE)
diff -Nru a/net/802/pseudo/opcodesnm.h b/net/802/pseudo/opcodesnm.h
--- a/net/802/pseudo/opcodesnm.h	Sat Aug 10 18:42:21 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,23 +0,0 @@
-static char *opcode_names[] = {
-"NOP", "CLEAR_REMOTE_BUSY", "CONNECT_INDICATION", "CONNECT_CONFIRM", "DATA_INDICATION",
-"DISCONNECT_INDICATION", "DUMMY_6", "RESET_CONFIRM", "DUMMY_8",
-"IF_F=1_CLEAR_REMOTE_BUSY", "IF_DATA_FLAG=2_STOP_REJ_TIMER", "SEND_DISC_CMD(P=X)",
-"SEND_DM_RSP(F=X)", "SEND_FRMR_RSP(F=X)", "RE-SEND_FRMR_RSP(F=0)",
-"RE-SEND_FRMR_RSP(F=P)", "SEND_I_CMD(P=1)", "RE-SEND_I_CMD(P=1)",
-"RE-SEND_I_CMD(P=1)_OR_SEND_RR", "SEND_I_XXX(X=0)", "RE-SEND_I_XXX(X=0)",
-"RE-SEND_I_XXX(X=0)_OR_SEND_RR", "RE-SEND_I_RSP(F=1)", "SEND_REJ_CMD(P=1)",
-"SEND_REJ_RSP(F=1)", "SEND_REJ_XXX(X=0)", "SEND_RNR_CMD(F=1)", "SEND_RNR_RSP(F=1)",
-"SEND_RNR_XXX(X=0)", "SET_REMOTE_BUSY", "OPTIONAL_SEND_RNR_XXX(X=0)",
-"SEND_RR_CMD(P=1)", "SEND_ACKNOWLEDGE_CMD(P=1)", "SEND_RR_RSP(F=1)",
-"SEND_ACKNOWLEDGE_RSP(F=1)", "SEND_RR_XXX(X=0)", "SEND_ACKNOWLEDGE_XXX(X=0)",
-"SEND_SABME_CMD(P=X)", "SEND_UA_RSP(F=X)", "S_FLAG:=0", "S_FLAG:=1", "START_P_TIMER",
-"START_ACK_TIMER", "START_REJ_TIMER", "START_ACK_TIMER_IF_NOT_RUNNING",
-"STOP_ACK_TIMER", "STOP_P_TIMER", "STOP_REJ_TIMER", "STOP_ALL_TIMERS",
-"STOP_OTHER_TIMERS", "UPDATE_N(R)_RECEIVED", "UPDATE_P_FLAG", "DATA_FLAG:=2",
-"DATA_FLAG:=0", "DATA_FLAG:=1", "IF_DATA_FLAG_=0_THEN_DATA_FLAG:=1", "P_FLAG:=0",
-"P_FLAG:=P", "REMOTE_BUSY:=0", "RETRY_COUNT:=0", "RETRY_COUNT:=RETRY_COUNT+1",
-"V(R):=0", "V(R):=V(R)+1", "V(S):=0", "V(S):=N(R)", "F_FLAG:=P",
-"REPORT_STATUS(FRMR_RECEIVED)", "REPORT_STATUS(FRMR_SENT)",
-"REPORT_STATUS(REMOTE_BUSY)", "REPORT_STATUS(REMOTE_NOT_BUSY)",
-"RESET_INDICATION(LOCAL)", "RESET_INDICATION(REMOTE)"
-};
diff -Nru a/net/802/pseudo/pseudocode b/net/802/pseudo/pseudocode
--- a/net/802/pseudo/pseudocode	Sat Aug 10 18:42:22 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,780 +0,0 @@
-;============================================================================
-;
-; translate this with 
-; 	cat pseudocode | sed -f act2num |  awk -f compile.awk >pseudocode.h
-;
-; actionname	pseudocode
-;
-;============================================================================
-ADM1		SEND_SABME_CMD(P=X)
-		P_FLAG:=P
-		START_ACK_TIMER
-		RETRY_COUNT:=0
-		S_FLAG:=0
-;
-; instructions in ADM2 have been changed:
-; 1. 	P_FLAG:=P is probably wrong in doc...
-; 	I think it should be F_FLAG:=P the way it is in CONN3
-; 2.	CONNECT_RESPONSE has been wired in here,
-;	CONN1 is no longer referenced
-;
-ADM2		F_FLAG:=P
-		SEND_UA_RSP(F=X)
-		V(S):=0
-		V(R):=0
-		RETRY_COUNT:=0
-		P_FLAG:=0
-		REMOTE_BUSY:=0
-		CONNECT_INDICATION
-ADM3		SEND_DM_RSP(F=X)
-ADM4		SEND_DM_RSP(F=X)
-ADM5		NOP
-;============================================================================
-;CONN1		SEND_UA_RSP(F=X)
-;		V(S):=0
-;		V(R):=0
-;		RETRY_COUNT:=0
-;		P_FLAG:=0
-;		REMOTE_BUSY:=0
-CONN2		SEND_DM_RSP(F=X)
-CONN3		F_FLAG:=P
-CONN4		DISCONNECT_INDICATION
-CONN5		NOP
-;============================================================================
-RESWAIT1	SEND_SABME_CMD(P=X)
-		P_FLAG:=P
-		START_ACK_TIMER
-		RETRY_COUNT:=0
-RESWAIT2	SEND_UA_RSP(F=X)
-		V(S):=0
-		V(R):=0
-		RETRY_COUNT:=0
-		P_FLAG:=0
-		REMOTE_BUSY:=0
-		RESET_CONFIRM
-RESWAIT3	SEND_DISC_CMD(P=X)
-		P_FLAG:=P
-		START_ACK_TIMER
-		RETRY_COUNT:=0
-RESWAIT4	SEND_DM_RSP(F=X)		
-RESWAIT5	DISCONNECT_INDICATION
-RESWAIT6	S_FLAG:=1
-		F_FLAG:=P
-RESWAIT7	SEND_DM_RSP(F=X)
-		DISCONNECT_INDICATION
-RESWAIT8	NOP
-;============================================================================
-RESCHK1		SEND_UA_RSP(F=X)
-		V(S):=0
-		V(R):=0
-		RETRY_COUNT:=0
-		P_FLAG:=0
-		REMOTE_BUSY:=0
-RESCHK2		SEND_DM_RSP(F=X)
-RESCHK3		DISCONNECT_INDICATION
-RESCHK4		F_FLAG:=P
-RESCHK5		SEND_DM_RSP(F=X)
-		DISCONNECT_INDICATION
-RESCHK6		NOP
-;============================================================================
-SETUP1		SEND_UA_RSP(F=X)
-		V(S):=0
-		V(R):=0
-		RETRY_COUNT:=0
-		S_FLAG:=1
-SETUP2		STOP_ACK_TIMER
-		V(S):=0
-		V(R):=0
-		RETRY_COUNT:=0
-		UPDATE_P_FLAG
-		CONNECT_CONFIRM
-		REMOTE_BUSY:=0
-SETUP3		P_FLAG:=0
-		CONNECT_CONFIRM
-		REMOTE_BUSY:=0
-SETUP4		SEND_DM_RSP(F=X)
-		DISCONNECT_INDICATION
-		STOP_ACK_TIMER
-SETUP5		DISCONNECT_INDICATION
-		STOP_ACK_TIMER
-SETUP6		NOP
-SETUP7		SEND_SABME_CMD(P=X)
-		P_FLAG:=P
-		START_ACK_TIMER
-		RETRY_COUNT:=RETRY_COUNT+1
-SETUP8		DISCONNECT_INDICATION
-;============================================================================
-RESET1		SEND_UA_RSP(F=X)
-		V(S):=0
-		V(R):=0
-		RETRY_COUNT:=0
-		S_FLAG:=1
-RESET2		STOP_ACK_TIMER
-		V(S):=0
-		V(R):=0
-		RETRY_COUNT:=0
-		UPDATE_P_FLAG
-		RESET_CONFIRM
-		REMOTE_BUSY:=0
-RESET3		P_FLAG:=0
-		RESET_CONFIRM
-		REMOTE_BUSY:=0
-RESET4		SEND_DM_RSP(F=X)
-		DISCONNECT_INDICATION
-		STOP_ACK_TIMER
-RESET5		DISCONNECT_INDICATION
-		STOP_ACK_TIMER
-RESET6		NOP
-RESET7		SEND_SABME_CMD(P=X)
-		P_FLAG:=P
-		START_ACK_TIMER
-		RETRY_COUNT:=RETRY_COUNT+1
-RESET8		DISCONNECT_INDICATION
-;============================================================================
-D_CONN1		SEND_DM_RSP(F=X)
-		STOP_ACK_TIMER
-D_CONN2		STOP_ACK_TIMER
-D_CONN3		SEND_UA_RSP(F=X)
-D_CONN4		STOP_ACK_TIMER
-D_CONN5		NOP
-D_CONN6		SEND_DISC_CMD(P=X)
-		P_FLAG:=P
-		START_ACK_TIMER
-		RETRY_COUNT:=RETRY_COUNT+1
-D_CONN7		NOP
-;============================================================================
-ERR1		RESET_INDICATION(REMOTE)
-		STOP_ACK_TIMER
-		F_FLAG:=P
-ERR2		SEND_UA_RSP(F=X)
-		DISCONNECT_INDICATION
-		STOP_ACK_TIMER
-ERR3		DISCONNECT_INDICATION
-		STOP_ACK_TIMER
-ERR4		RESET_INDICATION(LOCAL)
-		STOP_ACK_TIMER
-		REPORT_STATUS(FRMR_RECEIVED)
-		S_FLAG:=0
-ERR5		RE-SEND_FRMR_RSP(F=P)
-		START_ACK_TIMER
-ERR6		NOP
-ERR7		RE-SEND_FRMR_RSP(F=0)
-		START_ACK_TIMER
-		RETRY_COUNT:=RETRY_COUNT+1
-ERR8		S_FLAG:=0
-		RESET_INDICATION(LOCAL)
-;============================================================================
-; the shared actions are common to states NORMAL, BUSY, REJECT,
-; AWAIT, AWAIT_BUSY and AWAIT_REJECT.
-;============================================================================
-SH1		SEND_DISC_CMD(P=X)
-		P_FLAG:=P
-		START_ACK_TIMER
-		STOP_OTHER_TIMERS
-		RETRY_COUNT:=0
-SH2		SEND_SABME_CMD(P=X)
-		P_FLAG:=P
-		START_ACK_TIMER
-		STOP_OTHER_TIMERS
-		RETRY_COUNT:=0
-		S_FLAG:=0
-SH3		RESET_INDICATION(REMOTE)
-		F_FLAG:=P
-		STOP_ALL_TIMERS
-SH4		SEND_UA_RSP(F=X)
-		DISCONNECT_INDICATION
-		STOP_ALL_TIMERS
-SH5		STOP_ALL_TIMERS
-		RESET_INDICATION(LOCAL)
-		REPORT_STATUS(FRMR_RECEIVED)
-		S_FLAG:=0
-SH6		DISCONNECT_INDICATION
-		STOP_ALL_TIMERS
-SH7		SEND_FRMR_RSP(F=X)
-		REPORT_STATUS(FRMR_SENT)
-		START_ACK_TIMER
-		STOP_OTHER_TIMERS
-		RETRY_COUNT:=0
-SH8		SEND_FRMR_RSP(F=0)
-		REPORT_STATUS(FRMR_SENT)
-		START_ACK_TIMER
-		STOP_OTHER_TIMERS
-		RETRY_COUNT:=0
-SH9		SEND_FRMR_RSP(F=0)
-		REPORT_STATUS(FRMR_SENT)
-		START_ACK_TIMER
-		STOP_OTHER_TIMERS
-		RETRY_COUNT:=0
-SH10		SEND_FRMR_RSP(F=X)
-		REPORT_STATUS(FRMR_SENT)
-		START_ACK_TIMER
-		STOP_OTHER_TIMERS
-		RETRY_COUNT:=0
-SH11		STOP_ALL_TIMERS
-		RESET_INDICATION(LOCAL)
-		S_FLAG:=0
-;============================================================================
-NORMAL1		SEND_I_CMD(P=1)
-		START_P_TIMER
-		START_ACK_TIMER_IF_NOT_RUNNING
-;		SEND_I_XXX(X=0)
-;		START_ACK_TIMER_IF_NOT_RUNNING
-NORMAL2		SEND_I_XXX(X=0)
-		START_ACK_TIMER_IF_NOT_RUNNING
-NORMAL3		SEND_RNR_CMD(F=1)
-		START_P_TIMER
-		DATA_FLAG:=0
-;		SEND_RNR_XXX(X=0)
-;		DATA_FLAG:=0
-NORMAL4		SEND_RNR_XXX(X=0)
-		DATA_FLAG:=0
-NORMAL5		SEND_REJ_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		UPDATE_P_FLAG
-		START_REJ_TIMER
-		IF_F=1_CLEAR_REMOTE_BUSY
-;		SEND_REJ_CMD(P=1)
-;		UPDATE_N(R)_RECEIVED
-;		START_P_TIMER
-;		START_REJ_TIMER
-;		IF_F=1_CLEAR_REMOTE_BUSY
-NORMAL6		SEND_REJ_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		START_REJ_TIMER
-NORMAL7		SEND_REJ_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		START_REJ_TIMER
-;
-; the order of opcodes in NORMAL8 is changed.
-; the transition table will execute NORMAL8A for incoming pdus
-; with p/f 1, pdus with pf 0 are treated in NORMAL8B.
-;   
-NORMAL8A	V(R):=V(R)+1
-		SEND_ACKNOWLEDGE_CMD(P=1)
-		START_P_TIMER
-		UPDATE_N(R)_RECEIVED
-		IF_F=1_CLEAR_REMOTE_BUSY
-		DATA_INDICATION
-;
-NORMAL8B	V(R):=V(R)+1
-		UPDATE_P_FLAG
-		SEND_ACKNOWLEDGE_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		IF_F=1_CLEAR_REMOTE_BUSY
-		DATA_INDICATION
-;
-; the order of opcodes in NORMAL9 is changed 
-NORMAL9		V(R):=V(R)+1
-		SEND_ACKNOWLEDGE_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		DATA_INDICATION
-;
-; the order of opcodes in NORMAL10 is changed 
-NORMAL10	V(R):=V(R)+1
-		SEND_ACKNOWLEDGE_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		DATA_INDICATION
-NORMAL11	UPDATE_P_FLAG
-		UPDATE_N(R)_RECEIVED
-		CLEAR_REMOTE_BUSY
-NORMAL12	SEND_ACKNOWLEDGE_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		CLEAR_REMOTE_BUSY
-NORMAL13	UPDATE_P_FLAG
-		UPDATE_N(R)_RECEIVED
-		SET_REMOTE_BUSY
-NORMAL14	SEND_RR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		SET_REMOTE_BUSY
-NORMAL15	V(S):=N(R)
-		UPDATE_N(R)_RECEIVED
-		UPDATE_P_FLAG
-		RE-SEND_I_XXX(X=0)
-		CLEAR_REMOTE_BUSY
-;		V(S):=N(R)
-;		UPDATE_N(R)_RECEIVED
-;		START_P_TIMER
-;		RE-SEND_I_CMD(P=1)
-;		CLEAR_REMOTE_BUSY
-NORMAL16	V(S):=N(R)
-		UPDATE_N(R)_RECEIVED
-		RE-SEND_I_XXX(X=0)
-		CLEAR_REMOTE_BUSY
-NORMAL17	V(S):=N(R)
-		UPDATE_N(R)_RECEIVED
-		RE-SEND_I_RSP(F=1)
-		CLEAR_REMOTE_BUSY
-NORMAL18	SEND_RR_CMD(P=1)
-		START_P_TIMER
-NORMAL19	P_FLAG:=0
-;		SEND_RR_CMD(P=1)
-;		START_P_TIMER
-;		RETRY_COUNT:=RETRY_COUNT+1
-NORMAL20	SEND_RR_CMD(P=1)
-		START_P_TIMER
-		RETRY_COUNT:=RETRY_COUNT+1
-;============================================================================
-BUSY1		SEND_I_CMD(P=1)
-		START_P_TIMER
-		START_ACK_TIMER_IF_NOT_RUNNING
-;		SEND_I_XXX(X=0)
-;		START_ACK_TIMER_IF_NOT_RUNNING
-BUSY2		SEND_I_XXX(X=0)
-		START_ACK_TIMER_IF_NOT_RUNNING
-BUSY3		SEND_REJ_CMD(P=1)
-		START_REJ_TIMER
-		START_P_TIMER
-;		SEND_REJ_XXX(X=0)
-;		START_REJ_TIMER
-BUSY4		SEND_REJ_XXX(X=0)
-		START_REJ_TIMER
-BUSY5		SEND_RR_CMD(P=1)
-		START_P_TIMER
-		SEND_RR_XXX(X=0)
-BUSY6		SEND_RR_XXX(X=0)
-BUSY7		SEND_RR_CMD(P=1)
-		START_P_TIMER
-		SEND_RR_XXX(X=0)
-BUSY8		SEND_RR_XXX(X=0)
-BUSY9		OPTIONAL_SEND_RNR_XXX(X=0)
-		UPDATE_P_FLAG
-		UPDATE_N(R)_RECEIVED
-		IF_DATA_FLAG_=0_THEN_DATA_FLAG:=1
-		IF_F=1_CLEAR_REMOTE_BUSY
-;		SEND_RNR_CMD(P=1)
-;		START_P_TIMER
-;		UPDATE_N(R)_RECEIVED
-;		IF_DATA_FLAG_=0_THEN_DATA_FLAG:=1
-;		IF_F=1_CLEAR_REMOTE_BUSY
-BUSY10		OPTIONAL_SEND_RNR_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		IF_DATA_FLAG_=0_THEN_DATA_FLAG:=1
-BUSY11		SEND_RNR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		IF_DATA_FLAG_=0_THEN_DATA_FLAG:=1
-BUSY12		SEND_RNR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		IF_DATA_FLAG=2_STOP_REJ_TIMER
-		DATA_FLAG:=1
-;		V(R):=V(R)+1
-;		DATA_INDICATION
-;		SEND_RNR_RSP(F=1)
-;		UPDATE_N(R)_RECEIVED
-;		IF_DATA_FLAG=2_STOP_REJ_TIMER
-;		DATA_FLAG:=0
-BUSY13		OPTIONAL_SEND_RNR_XXX(X=0)
-		UPDATE_P_FLAG
-		UPDATE_N(R)_RECEIVED
-		IF_DATA_FLAG=2_STOP_REJ_TIMER
-		DATA_FLAG:=1
-		IF_F=1_CLEAR_REMOTE_BUSY
-;		SEND_RNR_CMD(F=1)
-;		START_P_TIMER
-;		UPDATE_N(R)_RECEIVED
-;		IF_DATA_FLAG=2_STOP_REJ_TIMER
-;		DATA_FLAG:=1
-;		IF_F=1_CLEAR_REMOTE_BUSY
-;		V(R):=V(R)+1
-;		DATA_INDICATION
-;		SEND_RNR_CMD(F=1)
-;		START_P_TIMER
-;		UPDATE_N(R)_RECEIVED
-;		IF_DATA_FLAG=2_STOP_REJ_TIMER
-;		DATA_FLAG:=0
-;		IF_F=1_CLEAR_REMOTE_BUSY
-;		V(R):=V(R)+1
-;		DATA_INDICATION
-;		UPDATE_P_FLAG
-;		OPTIONAL_SEND_RNR_XXX(X=0)
-;		UPDATE_N(R)_RECEIVED
-;		IF_DATA_FLAG=2_STOP_REJ_TIMER
-;		DATA_FLAG:=0
-;		IF_F=1_CLEAR_REMOTE_BUSY
-BUSY14		OPTIONAL_SEND_RNR_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		IF_DATA_FLAG=2_STOP_REJ_TIMER
-		DATA_FLAG:=1
-;		V(R):=V(R)+1
-;		DATA_INDICATION
-;		OPTIONAL_SEND_RNR_XXX(X=0)
-;		UPDATE_N(R)_RECEIVED
-;		IF_DATA_FLAG=2_STOP_REJ_TIMER
-;		DATA_FLAG:=0
-BUSY15		UPDATE_P_FLAG
-		UPDATE_N(R)_RECEIVED
-		CLEAR_REMOTE_BUSY
-BUSY16		SEND_RNR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		CLEAR_REMOTE_BUSY
-BUSY17		UPDATE_P_FLAG
-		UPDATE_N(R)_RECEIVED
-		SET_REMOTE_BUSY
-BUSY18		SEND_RNR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		SET_REMOTE_BUSY
-BUSY19		V(S):=N(R)
-		UPDATE_N(R)_RECEIVED
-		UPDATE_P_FLAG
-		RE-SEND_I_XXX(X=0)
-		CLEAR_REMOTE_BUSY
-;		V(S):=N(R)
-;		UPDATE_N(R)_RECEIVED
-;		RE-SEND_I_CMD(P=1)
-;		CLEAR_REMOTE_BUSY
-BUSY20		V(S):=N(R)
-		UPDATE_N(R)_RECEIVED
-		RE-SEND_I_XXX(X=0)
-		CLEAR_REMOTE_BUSY
-BUSY21		V(S):=N(R)
-		UPDATE_N(R)_RECEIVED
-		SEND_RNR_RSP(F=1)
-		RE-SEND_I_XXX(X=0)
-		CLEAR_REMOTE_BUSY
-BUSY22		SEND_RNR_CMD(F=1)
-		START_P_TIMER
-BUSY23		P_FLAG:=0
-;		SEND_RNR_CMD(F=1)
-;		START_P_TIMER
-;		RETRY_COUNT:=RETRY_COUNT+1
-BUSY24		SEND_RNR_CMD(F=1)
-		START_P_TIMER
-		RETRY_COUNT:=RETRY_COUNT+1
-BUSY25		DATA_FLAG:=1
-;		SEND_RNR_CMD(F=1)
-;		START_P_TIMER
-;		RETRY_COUNT:=RETRY_COUNT+1
-;		DATA_FLAG:=1
-BUSY26		DATA_FLAG:=1
-;============================================================================
-REJECT1		SEND_I_CMD(P=1)
-		START_P_TIMER
-		START_ACK_TIMER_IF_NOT_RUNNING
-;		SEND_I_XXX(X=0)
-;		START_ACK_TIMER_IF_NOT_RUNNING
-REJECT2		SEND_I_XXX(X=0)
-		START_ACK_TIMER_IF_NOT_RUNNING
-REJECT3		SEND_RNR_CMD(F=1)
-		START_P_TIMER
-		DATA_FLAG:=2
-;		SEND_RNR_XXX(X=0)
-;		DATA_FLAG:=2
-REJECT4		SEND_RNR_XXX(X=0)
-		DATA_FLAG:=2
-REJECT5		UPDATE_N(R)_RECEIVED
-		UPDATE_P_FLAG
-		IF_F=1_CLEAR_REMOTE_BUSY
-REJECT6		SEND_RR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-;
-; order of opcodes in REJECT7 is changed 
-REJECT7		V(R):=V(R)+1
-		SEND_ACKNOWLEDGE_CMD(P=1)
-		START_P_TIMER
-		UPDATE_N(R)_RECEIVED
-		IF_F=1_CLEAR_REMOTE_BUSY
-		STOP_REJ_TIMER
-		DATA_INDICATION
-;		V(R):=V(R)+1
-;		DATA_INDICATION
-;		UPDATE_P_FLAG
-;		SEND_ACKNOWLEDGE_XXX(X=0)
-;		UPDATE_N(R)_RECEIVED
-;		IF_F=1_CLEAR_REMOTE_BUSY
-;		STOP_REJ_TIMER
-;
-; order of opcodes in REJECT8 is changed 
-REJECT8		V(R):=V(R)+1
-		SEND_ACKNOWLEDGE_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		STOP_REJ_TIMER
-		DATA_INDICATION
-;
-; order of opcodes in REJECT9 is changed 
-REJECT9		V(R):=V(R)+1
-		SEND_ACKNOWLEDGE_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		STOP_REJ_TIMER
-		DATA_INDICATION
-REJECT10	UPDATE_P_FLAG
-		UPDATE_N(R)_RECEIVED
-		CLEAR_REMOTE_BUSY
-REJECT11	SEND_ACKNOWLEDGE_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		CLEAR_REMOTE_BUSY
-REJECT12	UPDATE_P_FLAG
-		UPDATE_N(R)_RECEIVED
-		SET_REMOTE_BUSY
-REJECT13	SEND_RR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		SET_REMOTE_BUSY
-REJECT14	V(S):=N(R)
-		UPDATE_N(R)_RECEIVED
-		UPDATE_P_FLAG
-		RE-SEND_I_XXX(X=0)
-		CLEAR_REMOTE_BUSY
-;		V(S):=N(R)
-;		UPDATE_N(R)_RECEIVED
-;		RE-SEND_I_CMD(P=1)
-;		START_P_TIMER
-;		CLEAR_REMOTE_BUSY
-REJECT15	V(S):=N(R)
-		UPDATE_N(R)_RECEIVED
-		RE-SEND_I_XXX(X=0)
-		CLEAR_REMOTE_BUSY
-REJECT16	V(S):=N(R)
-		UPDATE_N(R)_RECEIVED
-		RE-SEND_I_RSP(F=1)
-		CLEAR_REMOTE_BUSY
-REJECT17	SEND_RR_CMD(P=1)
-		START_P_TIMER
-REJECT18	SEND_REJ_CMD(P=1)
-		START_P_TIMER
-		START_REJ_TIMER
-		RETRY_COUNT:=RETRY_COUNT+1
-REJECT19	P_FLAG:=0
-;		SEND_RR_CMD(P=1)
-;		START_P_TIMER
-;		START_REJ_TIMER
-;		RETRY_COUNT:=RETRY_COUNT+1
-REJECT20	SEND_RR_CMD(P=1)
-		START_P_TIMER
-		START_REJ_TIMER
-		RETRY_COUNT:=RETRY_COUNT+1
-;============================================================================
-AWAIT1		SEND_RNR_XXX(X=0)
-		DATA_FLAG:=0
-AWAIT2		SEND_REJ_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		V(S):=N(R)
-		STOP_P_TIMER
-		RE-SEND_I_XXX(X=0)
-		START_REJ_TIMER
-		CLEAR_REMOTE_BUSY
-;		SEND_REJ_CMD(P=1)
-;		UPDATE_N(R)_RECEIVED
-;		V(S):=N(R)
-;		RE-SEND_I_XXX(X=0)
-;		START_P_TIMER
-;		START_REJ_TIMER
-;		CLEAR_REMOTE_BUSY
-AWAIT3		SEND_REJ_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		START_REJ_TIMER
-AWAIT4		SEND_REJ_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		START_REJ_TIMER
-;
-; order of opcode in AWAIT5 changed
-AWAIT5		V(R):=V(R)+1
-		UPDATE_N(R)_RECEIVED
-		V(S):=N(R)
-		RE-SEND_I_CMD(P=1)_OR_SEND_RR
-		START_P_TIMER
-		CLEAR_REMOTE_BUSY
-		DATA_INDICATION
-;		V(R):=V(R)+1
-;		DATA_INDICATION
-;		STOP_P_TIMER
-;		UPDATE_N(R)_RECEIVED
-;		V(S):=N(R)
-;		RE-SEND_I_XXX(X=0)_OR_SEND_RR
-;		CLEAR_REMOTE_BUSY
-;
-; order of opcode in AWAIT6 changed
-AWAIT6		V(R):=V(R)+1
-		SEND_RR_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		DATA_INDICATION
-;
-; order of opcode in AWAIT7 changed
-AWAIT7		V(R):=V(R)+1
-		SEND_RR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		DATA_INDICATION
-AWAIT8		UPDATE_N(R)_RECEIVED
-		V(S):=N(R)
-		STOP_P_TIMER
-		RE-SEND_I_XXX(X=0)
-		CLEAR_REMOTE_BUSY
-;		UPDATE_N(R)_RECEIVED
-;		V(S):=N(R)
-;		RE-SEND_I_CMD(P=1)
-;		START_P_TIMER
-;		CLEAR_REMOTE_BUSY
-AWAIT9		UPDATE_N(R)_RECEIVED
-		CLEAR_REMOTE_BUSY
-AWAIT10		SEND_RR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		CLEAR_REMOTE_BUSY
-AWAIT11		UPDATE_N(R)_RECEIVED
-		V(S):=N(R)
-		STOP_P_TIMER
-		SET_REMOTE_BUSY
-AWAIT12		UPDATE_N(R)_RECEIVED
-		SET_REMOTE_BUSY
-AWAIT13		SEND_RR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		SET_REMOTE_BUSY
-AWAIT14		SEND_RR_CMD(P=1)
-		START_P_TIMER
-		RETRY_COUNT:=RETRY_COUNT+1
-;============================================================================
-AWAIT_BUSY1	SEND_REJ_XXX(X=0)
-		START_REJ_TIMER		
-AWAIT_BUSY2	SEND_RR_XXX(X=0)
-AWAIT_BUSY3	SEND_RR_XXX(X=0)
-AWAIT_BUSY4	OPTIONAL_SEND_RNR_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		V(S):=N(R)
-		STOP_P_TIMER
-		DATA_FLAG:=1
-		CLEAR_REMOTE_BUSY
-		RE-SEND_I_XXX(X=0)
-;		SEND_RNR_CMD(F=1)
-;		UPDATE_N(R)_RECEIVED
-;		V(S):=N(R)
-;		START_P_TIMER
-;		DATA_FLAG:=1
-;		CLEAR_REMOTE_BUSY
-;		RE-SEND_I_XXX(X=0)
-AWAIT_BUSY5	OPTIONAL_SEND_RNR_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		DATA_FLAG:=1
-AWAIT_BUSY6	SEND_RNR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		DATA_FLAG:=1
-AWAIT_BUSY7	OPTIONAL_SEND_RNR_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		V(S):=N(R)
-		DATA_FLAG:=1
-		STOP_P_TIMER
-		CLEAR_REMOTE_BUSY
-		RE-SEND_I_XXX(X=0)
-;		SEND_RNR_CMD(F=1)
-;		V(R):=V(R)+1
-;		DATA_INDICATION
-;		START_P_TIMER
-;		UPDATE_N(R)_RECEIVED
-;		V(S):=N(R)
-;		DATA_FLAG:=0
-;		CLEAR_REMOTE_BUSY
-;		RE-SEND_I_XXX(X=0)
-;		OPTIONAL_SEND_RNR_XXX(X=0)
-;		V(R):=V(R)+1
-;		DATA_INDICATION
-;		STOP_P_TIMER
-;		UPDATE_N(R)_RECEIVED
-;		V(S):=N(R)
-;		DATA_FLAG:=0
-;		CLEAR_REMOTE_BUSY
-;		RE-SEND_I_XXX(X=0)
-AWAIT_BUSY8	OPTIONAL_SEND_RNR_XXX(X=0)
-		UPDATE_N(R)_RECEIVED
-		DATA_FLAG:=1
-;		OPTIONAL_SEND_RNR_XXX(X=0)
-;		V(R):=V(R)+1
-;		DATA_INDICATION
-;		UPDATE_N(R)_RECEIVED
-;		DATA_FLAG:=0
-AWAIT_BUSY9	SEND_RNR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		DATA_FLAG:=1
-;		SEND_RNR_RSP(F=1)
-;		V(R):=V(R)+1
-;		DATA_INDICATION
-;		UPDATE_N(R)_RECEIVED
-;		DATA_FLAG:=0
-AWAIT_BUSY10	UPDATE_N(R)_RECEIVED
-		V(S):=N(R)
-		STOP_P_TIMER
-		RE-SEND_I_XXX(X=0)
-		CLEAR_REMOTE_BUSY
-;		UPDATE_N(R)_RECEIVED
-;		V(S):=N(R)
-;		RE-SEND_I_CMD(P=1)
-;		START_P_TIMER
-;		CLEAR_REMOTE_BUSY
-AWAIT_BUSY11	UPDATE_N(R)_RECEIVED
-		CLEAR_REMOTE_BUSY
-AWAIT_BUSY12	SEND_RNR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		CLEAR_REMOTE_BUSY
-AWAIT_BUSY13	UPDATE_N(R)_RECEIVED
-		V(S):=N(R)
-		STOP_P_TIMER
-		SET_REMOTE_BUSY
-AWAIT_BUSY14	UPDATE_N(R)_RECEIVED
-		SET_REMOTE_BUSY
-AWAIT_BUSY15	SEND_RNR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		SET_REMOTE_BUSY
-AWAIT_BUSY16	SEND_RNR_CMD(F=1)
-		START_P_TIMER
-		RETRY_COUNT:=RETRY_COUNT+1
-;============================================================================
-AWAIT_REJECT1	SEND_RNR_XXX(X=0)
-		DATA_FLAG:=2
-AWAIT_REJECT2	UPDATE_N(R)_RECEIVED
-AWAIT_REJECT3	SEND_RR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-;
-; order of opcodes in AWAIT_REJECT4 changed
-AWAIT_REJECT4	V(R):=V(R)+1
-		UPDATE_N(R)_RECEIVED
-		V(S):=N(R)
-		RE-SEND_I_CMD(P=1)_OR_SEND_RR
-		START_P_TIMER
-		STOP_REJ_TIMER
-		CLEAR_REMOTE_BUSY
-		DATA_INDICATION
-;		V(R):=V(R)+1
-;		DATA_INDICATION
-;		STOP_P_TIMER
-;		STOP_REJ_TIMER
-;		UPDATE_N(R)_RECEIVED
-;		V(S):=N(R)
-;		RE-SEND_I_CMD(P=1)_OR_SEND_RR
-;		CLEAR_REMOTE_BUSY
-;
-; order of opcodes in AWAIT_REJECT5 changed
-AWAIT_REJECT5	V(R):=V(R)+1
-		SEND_RR_XXX(X=0)
-		STOP_REJ_TIMER
-		UPDATE_N(R)_RECEIVED
-		DATA_INDICATION
-;
-; order of opcodes in AWAIT_REJECT6 changed
-AWAIT_REJECT6	V(R):=V(R)+1
-		SEND_RR_RSP(F=1)
-		STOP_REJ_TIMER
-		UPDATE_N(R)_RECEIVED
-		DATA_INDICATION
-AWAIT_REJECT7	UPDATE_N(R)_RECEIVED
-		V(S):=N(R)
-		STOP_P_TIMER
-		RE-SEND_I_XXX(X=0)
-		CLEAR_REMOTE_BUSY
-;		UPDATE_N(R)_RECEIVED
-;		V(S):=N(R)
-;		RE-SEND_I_CMD(P=1)
-;		START_P_TIMER
-;		CLEAR_REMOTE_BUSY
-AWAIT_REJECT8	UPDATE_N(R)_RECEIVED
-		CLEAR_REMOTE_BUSY
-AWAIT_REJECT9	SEND_RR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		CLEAR_REMOTE_BUSY
-AWAIT_REJECT10	UPDATE_N(R)_RECEIVED
-		V(S):=N(R)
-		STOP_P_TIMER
-		SET_REMOTE_BUSY
-AWAIT_REJECT11	UPDATE_N(R)_RECEIVED
-		SET_REMOTE_BUSY
-AWAIT_REJECT12	SEND_RR_RSP(F=1)
-		UPDATE_N(R)_RECEIVED
-		SET_REMOTE_BUSY
-AWAIT_REJECT13	SEND_REJ_CMD(P=1)
-		START_P_TIMER
-		RETRY_COUNT:=RETRY_COUNT+1
-;============================================================================
-
diff -Nru a/net/802/psnap.c b/net/802/psnap.c
--- a/net/802/psnap.c	Sat Aug 10 18:42:22 2002
+++ b/net/802/psnap.c	Sat Aug 10 18:42:22 2002
@@ -1,7 +1,8 @@
 /*
  *	SNAP data link layer. Derived from 802.2
  *
- *		Alan Cox <Alan.Cox@linux.org>, from the 802.2 layer by Greg Page.
+ *		Alan Cox <Alan.Cox@linux.org>,
+ *		from the 802.2 layer by Greg Page.
  *		Merged in additions from Greg Page's psnap.c.
  *
  *		This program is free software; you can redistribute it and/or
@@ -20,50 +21,39 @@
 #include <linux/in.h>
 #include <linux/init.h>
 
-static struct datalink_proto *snap_list = NULL;
-static struct datalink_proto *snap_dl = NULL;		/* 802.2 DL for SNAP */
+static struct datalink_proto *snap_list;
+static struct datalink_proto *snap_dl;		/* 802.2 DL for SNAP */
 
 /*
  *	Find a snap client by matching the 5 bytes.
  */
-
 static struct datalink_proto *find_snap_client(unsigned char *desc)
 {
-	struct datalink_proto	*proto;
+	struct datalink_proto *proto = snap_list;
+
+	for (; proto && memcmp(proto->type, desc, 5); proto = proto->next);
 
-	for (proto = snap_list; proto != NULL && memcmp(proto->type, desc, 5) ; proto = proto->next);
 	return proto;
 }
 
 /*
  *	A SNAP packet has arrived
  */
-
-int snap_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
+int snap_rcv(struct sk_buff *skb, struct net_device *dev,
+	     struct packet_type *pt)
 {
-	static struct packet_type psnap_packet_type =
-	{
-		0,
-		NULL,		/* All Devices */
-		snap_rcv,
-		NULL,
-		NULL,
+	static struct packet_type psnap_packet_type = {
+		.type = __constant_htons(ETH_P_SNAP),
+		.func = snap_rcv,
 	};
 
-	struct datalink_proto	*proto;
-
-	proto = find_snap_client(skb->h.raw);
-	if (proto != NULL)
-	{
-		/*
-		 *	Pass the frame on.
-		 */
+	struct datalink_proto *proto = find_snap_client(skb->h.raw);
 
-		skb->h.raw += 5;
+	if (proto) {
+		/* Pass the frame on. */
+		skb->h.raw  += 5;
 		skb->nh.raw += 5;
-		skb_pull(skb,5);
-		if (psnap_packet_type.type == 0)
-			psnap_packet_type.type=htons(ETH_P_SNAP);
+		skb_pull(skb, 5);
 
 		return proto->rcvfunc(skb, dev, &psnap_packet_type);
 	}
@@ -75,60 +65,62 @@
 /*
  *	Put a SNAP header on a frame and pass to 802.2
  */
-
-static void snap_datalink_header(struct datalink_proto *dl, struct sk_buff *skb, unsigned char *dest_node)
+static void snap_datalink_header(struct datalink_proto *dl,
+				 struct sk_buff *skb, unsigned char *dest_node)
 {
-	memcpy(skb_push(skb,5),dl->type,5);
+	memcpy(skb_push(skb, 5), dl->type, 5);
 	snap_dl->datalink_header(snap_dl, skb, dest_node);
 }
 
 /*
  *	Set up the SNAP layer
  */
-
 EXPORT_SYMBOL(register_snap_client);
 EXPORT_SYMBOL(unregister_snap_client);
 
 static int __init snap_init(void)
 {
-	snap_dl=register_8022_client(0xAA, snap_rcv);
-	if(snap_dl==NULL)
-		printk("SNAP - unable to register with 802.2\n");
+	snap_dl = register_8022_client(0xAA, snap_rcv);
+
+	if (!snap_dl)
+		printk(KERN_CRIT "SNAP - unable to register with 802.2\n");
+
 	return 0;
 }
+
 module_init(snap_init);
 
 /*
  *	Register SNAP clients. We don't yet use this for IP.
  */
-
-struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *))
+struct datalink_proto *register_snap_client(unsigned char *desc,
+					    int (*rcvfunc)(struct sk_buff *,
+						    	   struct net_device *,
+							   struct packet_type *))
 {
-	struct datalink_proto	*proto;
+	struct datalink_proto *proto = NULL;
 
-	if (find_snap_client(desc) != NULL)
-		return NULL;
+	if (find_snap_client(desc))
+		goto out;
 
-	proto = (struct datalink_proto *) kmalloc(sizeof(*proto), GFP_ATOMIC);
-	if (proto != NULL)
-	{
+	proto = kmalloc(sizeof(*proto), GFP_ATOMIC);
+	if (proto) {
 		memcpy(proto->type, desc,5);
-		proto->type_len = 5;
-		proto->rcvfunc = rcvfunc;
-		proto->header_length = 5+snap_dl->header_length;
-		proto->datalink_header = snap_datalink_header;
-		proto->string_name = "SNAP";
-		proto->next = snap_list;
-		snap_list = proto;
+		proto->type_len		= 5;
+		proto->rcvfunc		= rcvfunc;
+		proto->header_length	= 5 + snap_dl->header_length;
+		proto->datalink_header	= snap_datalink_header;
+		proto->string_name	= "SNAP";
+		proto->next		= snap_list;
+		snap_list		= proto;
 	}
-
+out:
 	return proto;
 }
 
 /*
  *	Unregister SNAP clients. Protocols no longer want to play with us ...
  */
-
 void unregister_snap_client(unsigned char *desc)
 {
 	struct datalink_proto **clients = &snap_list;
@@ -138,17 +130,16 @@
 	save_flags(flags);
 	cli();
 
-	while ((tmp = *clients) != NULL)
-	{
-		if (memcmp(tmp->type,desc,5) == 0)
-		{
+	while ((tmp = *clients) != NULL) {
+		if (!memcmp(tmp->type, desc, 5)) {
 			*clients = tmp->next;
 			kfree(tmp);
 			break;
-		}
-		else
+		} else
 			clients = &tmp->next;
 	}
 
 	restore_flags(flags);
 }
+
+MODULE_LICENSE("GPL");
diff -Nru a/net/802/sysctl_net_802.c b/net/802/sysctl_net_802.c
--- a/net/802/sysctl_net_802.c	Sat Aug 10 18:42:21 2002
+++ b/net/802/sysctl_net_802.c	Sat Aug 10 18:42:21 2002
@@ -14,15 +14,20 @@
 #include <linux/sysctl.h>
 #include <linux/config.h>
 
-ctl_table e802_table[] = {
-	{0}
-};
-
 #ifdef CONFIG_TR
 extern int sysctl_tr_rif_timeout;
-ctl_table tr_table[] = {
-	{NET_TR_RIF_TIMEOUT, "rif_timeout", &sysctl_tr_rif_timeout, sizeof(int),
-	 0644, NULL, &proc_dointvec},
-	{0}
-};
 #endif
+
+struct ctl_table tr_table[] = {
+#ifdef CONFIG_TR
+	{
+		.ctl_name	= NET_TR_RIF_TIMEOUT,
+		.procname	= "rif_timeout",
+		.data		= &sysctl_tr_rif_timeout,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+#endif /* CONFIG_TR */
+	{ 0 },
+};
diff -Nru a/net/802/transit/compile.awk b/net/802/transit/compile.awk
--- a/net/802/transit/compile.awk	Sat Aug 10 18:42:21 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,81 +0,0 @@
-# to run: awk -f transit.awk transit.p0
-#
-BEGIN { "date" | getline
-	enable_index = 1
-	today = $0
-	printf("\n/* this file was generated on %s  */\n", today )
-	not_firstone = 0	# flag to avoid empty entry in 1st table
-	fpe = 0			# entry tbl array fill pointer
-	fpeo = 0		# entry tbl offset list fill pointer
-	fpdef = 0 		# define list fill pointer
-}
-
-### /^;/ { }			# line starting with a semicolon is comment 
-
-/^[A-Z]/ {			# table name
-	if ( $1 == "TABLE" ) {
-	   tbl = $2		# get table name
-	   newtbl( tbl )
-	}
-	else if ( $1 == "COMPILE" ) {
-	   array_name = $2
-	   if ( $3 == "NOINDEX" ) { enable_index = 0 }
-	}
-	else {			# table entry
-	   ec = ec +1
-	   n = split( $0, fld, " " )
-	   action = fld[ n-1 ]
-	   newstate = fld[ n ]
-	   store( action, newstate )
-	   ecct = ecct +1
-	}
-}
-
-END {	store( action, newstate )
-
-	if ( enable_index ) {
-	    printf( "\n/* index name #defines: */\n\n",
-		 ec, ecct )
-
-	    for( ii = 1; ii <= fpeo; ii++ ){
-	       printf( "#define %-12s %3d\n", define[ ii ], ii -1 )
-	    }
-	}
-
-	printf( "\n\n/* size of transition table is %d bytes */\n",
-		 fpe )
-
-	if ( enable_index ) {
-	    printf( "\nstatic short int %s_offset [ ] ={", array_name )
-	    for( ii = 1; ii <= fpeo; ii++ ){
-	        if ( (ii % 10) == 1 ) printf("\n  ")
-	        printf( " %4d", entry_offset[ ii ] )
-	        if ( ii < fpeo ) printf( "," )
-	    }
-	    printf(" };\n")
-	}
-
-	printf( "\nstatic char %s_entry [ ] = {", array_name )
-	for( ii = 1; ii <= fpe; ii++ ){
-	    if ( (ii % 6) == 1 ) printf("\n  ")
-	    printf( " %-14s", entry[ ii ] )
-	    if ( ii < fpe ) printf( "," )
-	}
-	printf(" };\n")
-
-}
-
-function store(  act, ns ){
-#	printf( "%s %s\n",  act, ns )
-	entry[ ++fpe ] = act
-	entry[ ++fpe ] = ns 
-}
-
-function newtbl( tbl ){
-	   if ( not_firstone ) {
-		store( action, newstate )
-	   }
-	   not_firstone = 1
-	   entry_offset[ ++fpeo ] = fpe		# entry tbl offset list
-	   define[ ++fpdef ] = tbl	# state name to define
-}
diff -Nru a/net/802/transit/pdutr.pre b/net/802/transit/pdutr.pre
--- a/net/802/transit/pdutr.pre	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1121 +0,0 @@
-COMPILE pdutr INDEX
-;
-; Transition tables for incoming pdu events.
-; translate this thing into C with
-;  	awk -f ./compile.awk pdu.trans > pdutr.h
-;
-TABLE ADM
-;Transition table for the ADM state:
-;
-;frame type   p bit     action    newstate
-;received     in frame
-;
-I_CMD         0         ADM5      ADM
-I_CMD         1         ADM4      ADM
-RR_CMD        0         ADM5      ADM
-RR_CMD        1         ADM4      ADM
-RNR_CMD       0         ADM5      ADM
-RNR_CMD       1         ADM4      ADM
-REJ_CMD       0         ADM5      ADM
-REJ_CMD       1         ADM4      ADM
-DISC_CMD      0         ADM3      ADM
-DISC_CMD      1         ADM3      ADM
-SABME_CMD     0         ADM2      CONN  
-SABME_CMD     1         ADM2      CONN  
-I_RSP         0         ADM5      ADM
-I_RSP         1         ADM5      ADM
-RR_RSP        0         ADM5      ADM
-RR_RSP        1         ADM5      ADM
-RNR_RSP       0         ADM5      ADM
-RNR_RSP       1         ADM5      ADM
-REJ_RSP       0         ADM5      ADM
-REJ_RSP       1         ADM5      ADM
-UA_RSP        0         ADM5      ADM
-UA_RSP        1         ADM5      ADM
-DM_RSP        0         ADM5      ADM
-DM_RSP        1         ADM5      ADM
-FRMR_RSP      0         ADM5      ADM
-FRMR_RSP      1         ADM5      ADM
-;
-TABLE CONN
-;
-;Transition table for the CONN state:
-;
-;frame type   action    newstate
-;received     
-;
-I_CMD         CONN5     CONN
-RR_CMD        CONN5     CONN
-RNR_CMD       CONN5     CONN
-REJ_CMD       CONN5     CONN
-DISC_CMD      CONN5     CONN
-SABME_CMD     CONN3     CONN  
-I_RSP         CONN5     CONN
-RR_RSP        CONN5     CONN
-RNR_RSP       CONN5     CONN
-REJ_RSP       CONN5     CONN
-UA_RSP        CONN5     CONN
-DM_RSP        CONN4     ADM
-FRMR_RSP      CONN5     CONN
-;
-TABLE RESET_WAIT
-;Transition table for the RESET_WAIT
-;
-;frame type   action    newstate
-;received     
-;
-I_CMD         RESWAIT8  RESET_WAIT
-RR_CMD        RESWAIT8  RESET_WAIT
-RNR_CMD       RESWAIT8  RESET_WAIT
-REJ_CMD       RESWAIT8  RESET_WAIT
-DISC_CMD      RESWAIT7  RESET_WAIT
-SABME_CMD     RESWAIT6  RESET_WAIT
-I_RSP         RESWAIT8  RESET_WAIT
-RR_RSP        RESWAIT8  RESET_WAIT
-RNR_RSP       RESWAIT8  RESET_WAIT
-REJ_RSP       RESWAIT8  RESET_WAIT
-UA_RSP        RESWAIT8  RESET_WAIT
-DM_RSP        RESWAIT5  ADM
-FRMR_RSP      RESWAIT8  RESET_WAIT
-;
-;
-TABLE RESET_CHECK
-;Transition table for the RESET_CHECK state
-;
-;frame type   action    newstate
-;received     
-;
-I_CMD         RESCHK6  RESET_CHECK
-RR_CMD        RESCHK6  RESET_CHECK
-RNR_CMD       RESCHK6  RESET_CHECK
-REJ_CMD       RESCHK6  RESET_CHECK
-DISC_CMD      RESCHK5  ADM
-SABME_CMD     RESCHK4  RESET_CHECK
-I_RSP         RESCHK6  RESET_CHECK
-RR_RSP        RESCHK6  RESET_CHECK
-RNR_RSP       RESCHK6  RESET_CHECK
-REJ_RSP       RESCHK6  RESET_CHECK
-UA_RSP        RESCHK6  RESET_CHECK
-DM_RSP        RESCHK3  ADM
-FRMR_RSP      RESCHK6  RESET_CHECK
-;
-;
-TABLE SETUP
-;Transition table for the SETUP state
-;
-;frame type   p flag    action    newstate
-;received     = f
-;
-I_CMD         0         SETUP6      SETUP
-I_CMD         1         SETUP6      SETUP
-RR_CMD        0         SETUP6      SETUP
-RR_CMD        1         SETUP6      SETUP
-RNR_CMD       0         SETUP6      SETUP
-RNR_CMD       1         SETUP6      SETUP
-REJ_CMD       0         SETUP6      SETUP
-REJ_CMD       1         SETUP6      SETUP
-DISC_CMD      0         SETUP4      ADM
-DISC_CMD      1         SETUP4      ADM  
-SABME_CMD     0         SETUP1      SETUP 
-SABME_CMD     1         SETUP1      SETUP 
-I_RSP         0         SETUP6      SETUP
-I_RSP         1         SETUP6      SETUP
-RR_RSP        0         SETUP6      SETUP
-RR_RSP        1         SETUP6      SETUP
-RNR_RSP       0         SETUP6      SETUP
-RNR_RSP       1         SETUP6      SETUP
-REJ_RSP       0         SETUP6      SETUP
-REJ_RSP       1         SETUP6      SETUP
-UA_RSP        0         SETUP6      SETUP
-UA_RSP        1         SETUP2      NORMAL
-DM_RSP        0         SETUP5      ADM  
-DM_RSP        1         SETUP5      ADM  
-FRMR_RSP      0         SETUP6      SETUP
-FRMR_RSP      1         SETUP6      SETUP
-;
-;
-TABLE RESET
-;Transition table for the RESET state:
-;
-;frame type   p flag    action    newstate
-;received     = f
-;
-I_CMD         0         RESET6      RESET
-I_CMD         1         RESET6      RESET
-RR_CMD        0         RESET6      RESET
-RR_CMD        1         RESET6      RESET
-RNR_CMD       0         RESET6      RESET
-RNR_CMD       1         RESET6      RESET
-REJ_CMD       0         RESET6      RESET
-REJ_CMD       1         RESET6      RESET
-DISC_CMD      0         RESET4      ADM
-DISC_CMD      1         RESET4      ADM  
-SABME_CMD     0         RESET1      RESET 
-SABME_CMD     1         RESET1      RESET 
-I_RSP         0         RESET6      RESET
-I_RSP         1         RESET6      RESET
-RR_RSP        0         RESET6      RESET
-RR_RSP        1         RESET6      RESET
-RNR_RSP       0         RESET6      RESET
-RNR_RSP       1         RESET6      RESET
-REJ_RSP       0         RESET6      RESET
-REJ_RSP       1         RESET6      RESET
-UA_RSP        0         RESET6      RESET
-UA_RSP        1         RESET2      NORMAL
-DM_RSP        0         RESET5      ADM  
-DM_RSP        1         RESET5      ADM  
-FRMR_RSP      0         RESET6      RESET
-FRMR_RSP      1         RESET6      RESET
-;
-;
-TABLE D_CONN
-;Transition table for the D_CONN state:
-;
-;frame type   p bit     action    newstate
-;received     in frame  
-I_CMD         0         D_CONN5      D_CONN
-I_CMD         1         D_CONN5      D_CONN
-RR_CMD        0         D_CONN5      D_CONN
-RR_CMD        1         D_CONN5      D_CONN
-RNR_CMD       0         D_CONN5      D_CONN
-RNR_CMD       1         D_CONN5      D_CONN
-REJ_CMD       0         D_CONN5      D_CONN
-REJ_CMD       1         D_CONN5      D_CONN
-DISC_CMD      0         D_CONN3      D_CONN
-DISC_CMD      1         D_CONN3      D_CONN
-SABME_CMD     0         D_CONN1      ADM  
-SABME_CMD     1         D_CONN1      ADM    
-I_RSP         0         D_CONN5      D_CONN
-I_RSP         1         D_CONN5      D_CONN
-RR_RSP        0         D_CONN5      D_CONN
-RR_RSP        1         D_CONN5      D_CONN
-RNR_RSP       0         D_CONN5      D_CONN
-RNR_RSP       1         D_CONN5      D_CONN
-REJ_RSP       0         D_CONN5      D_CONN
-REJ_RSP       1         D_CONN5      D_CONN
-UA_RSP        0         D_CONN5      D_CONN
-UA_RSP        1         D_CONN4      ADM   
-DM_RSP        0         D_CONN4      ADM  
-DM_RSP        1         D_CONN5      ADM  
-FRMR_RSP      0         D_CONN5      D_CONN
-FRMR_RSP      1         D_CONN5      D_CONN
-;
-;
-TABLE ERROR
-;Transition table for the ERROR state:
-;
-;frame type   action    newstate
-;received     
-;
-I_CMD         ERR5      ERROR
-RR_CMD        ERR5      ERROR
-RNR_CMD       ERR5      ERROR
-REJ_CMD       ERR5      ERROR
-DISC_CMD      ERR2      ADM
-SABME_CMD     ERR1      RESET_CHECK
-I_RSP         ERR6      ERROR
-RR_RSP        ERR6      ERROR
-RNR_RSP       ERR6      ERROR
-REJ_RSP       ERR6      ERROR
-UA_RSP        ERR6      ERROR
-DM_RSP        ERR3      ADM
-FRMR_RSP      ERR4      RESET_WAIT
-;
-TABLE NORMAL
-;Transition table for the NORMAL state:
-;
-;frame type   uexpect   p bit     p_flag    
-;received     N(S)      in frame            
-;
-I_CMD          	0	0	0	NORMAL8B	NORMAL
-I_CMD          	0	0	1	NORMAL9		NORMAL
-I_CMD          	0	1	0	NORMAL10	NORMAL
-I_CMD          	0	1	1	NORMAL10	NORMAL
-I_CMD          	1	0	0	NORMAL5		REJECT
-I_CMD          	1	0	1	NORMAL6		REJECT
-I_CMD          	1	1	0	NORMAL7		REJECT
-I_CMD          	1	1	1	NORMAL7		REJECT
-RR_CMD         	0	0	0	NORMAL11	NORMAL
-RR_CMD         	0	0	1	NORMAL11	NORMAL
-RR_CMD         	0	1	0	NORMAL12	NORMAL
-RR_CMD         	0	1	1	NORMAL12	NORMAL
-RR_CMD         	1	0	0	NORMAL11	NORMAL
-RR_CMD         	1	0	1	NORMAL11	NORMAL
-RR_CMD         	1	1	0	NORMAL12	NORMAL
-RR_CMD         	1	1	1	NORMAL12	NORMAL
-RNR_CMD        	0	0	0	NORMAL13	NORMAL
-RNR_CMD        	0	0	1	NORMAL13	NORMAL
-RNR_CMD        	0	1	0	NORMAL14	NORMAL
-RNR_CMD        	0	1	1	NORMAL14	NORMAL
-RNR_CMD        	1	0	0	NORMAL13	NORMAL
-RNR_CMD        	1	0	1	NORMAL13	NORMAL
-RNR_CMD        	1	1	0	NORMAL14	NORMAL
-RNR_CMD        	1	1	1	NORMAL14	NORMAL
-REJ_CMD        	0	0	0	NORMAL15	NORMAL
-REJ_CMD        	0	0	1	NORMAL16	NORMAL
-REJ_CMD        	0	1	0	NORMAL17	NORMAL 
-REJ_CMD        	0	1	1	NORMAL17	NORMAL 
-REJ_CMD        	1	0	0	NORMAL15	NORMAL
-REJ_CMD        	1	0	1	NORMAL16	NORMAL
-REJ_CMD        	1	1	0	NORMAL17	NORMAL 
-REJ_CMD        	1	1	1	NORMAL17	NORMAL 
-DISC_CMD       	0	0	0	SH4		ADM
-DISC_CMD       	0	0	1	SH4		ADM
-DISC_CMD       	0	1	0	SH4		ADM
-DISC_CMD       	0	1	1	SH4		ADM
-DISC_CMD       	1	0	0	SH4		ADM
-DISC_CMD       	1	0	1	SH4		ADM
-DISC_CMD       	1	1	0	SH4		ADM
-DISC_CMD       	1	1	1	SH4		ADM
-SABME_CMD      	0	0	0	SH3		RESET_CHECK
-SABME_CMD      	0	0	1	SH3		RESET_CHECK
-SABME_CMD      	0	1	0	SH3		RESET_CHECK
-SABME_CMD      	0	1	1	SH3		RESET_CHECK
-SABME_CMD      	1	0	0	SH3		RESET_CHECK
-SABME_CMD      	1	0	1	SH3		RESET_CHECK
-SABME_CMD      	1	1	0	SH3		RESET_CHECK
-SABME_CMD      	1	1	1	SH3		RESET_CHECK
-I_RSP          	0	0	0	NORMAL8B	NORMAL
-I_RSP          	0	0	1	NORMAL9		NORMAL
-I_RSP          	0	1	0	SH10		ERROR
-I_RSP          	0	1	1	NORMAL8A	NORMAL
-I_RSP          	1	0	0	NORMAL5		REJECT
-I_RSP          	1	0	1	NORMAL6		REJECT
-I_RSP          	1	1	0	SH10		ERROR
-I_RSP          	1	1	1	NORMAL5		REJECT
-RR_RSP         	0	0	0	NORMAL11	NORMAL
-RR_RSP         	0	0	1	NORMAL11	NORMAL
-RR_RSP         	0	1	0	SH10		ERROR
-RR_RSP         	0	1	1	NORMAL11	NORMAL
-RR_RSP         	1	0	0	NORMAL11	NORMAL
-RR_RSP         	1	0	1	NORMAL11	NORMAL
-RR_RSP         	1	1	0	SH10		ERROR
-RR_RSP         	1	1	1	NORMAL11	NORMAL
-RNR_RSP        	0	0	0	NORMAL13	NORMAL
-RNR_RSP        	0	0	1	NORMAL13	NORMAL
-RNR_RSP        	0	1	0	SH10		ERROR
-RNR_RSP        	0	1	1	NORMAL13	NORMAL
-RNR_RSP        	1	0	0	NORMAL13	NORMAL
-RNR_RSP        	1	0	1	NORMAL13	NORMAL
-RNR_RSP        	1	1	0	SH10		ERROR
-RNR_RSP        	1	1	1	NORMAL13	NORMAL
-REJ_RSP        	0	0	0	NORMAL15	NORMAL
-REJ_RSP        	0	0	1	NORMAL16	NORMAL
-REJ_RSP        	0	1	0	SH10		ERROR
-REJ_RSP        	0	1	1	NORMAL15	NORMAL
-REJ_RSP        	1	0	0	NORMAL15	NORMAL
-REJ_RSP        	1	0	1	NORMAL16	NORMAL
-REJ_RSP        	1	1	0	SH10		ERROR
-REJ_RSP        	1	1	1	NORMAL15	NORMAL
-UA_RSP         	0	0	0	SH9		ERROR
-UA_RSP         	0	0	1	SH9		ERROR
-UA_RSP         	0	1	0	SH9		ERROR
-UA_RSP         	0	1	1	SH9		ERROR
-UA_RSP         	1	0	0	SH9		ERROR
-UA_RSP         	1	0	1	SH9		ERROR
-UA_RSP         	1	1	0	SH9		ERROR
-UA_RSP         	1	1	1	SH9		ERROR
-DM_RSP         	0	0	0	SH6		ADM
-DM_RSP         	0	0	1	SH6		ADM
-DM_RSP         	0	1	0	SH6		ADM
-DM_RSP         	0	1	1	SH6		ADM
-DM_RSP         	1	0	0	SH6		ADM
-DM_RSP         	1	0	1	SH6		ADM
-DM_RSP         	1	1	0	SH6		ADM
-DM_RSP         	1	1	1	SH6		ADM
-FRMR_RSP       	0	0	0	SH5		RESET_WAIT
-FRMR_RSP       	0	0	1	SH5		RESET_WAIT
-FRMR_RSP       	0	1	0	SH5		RESET_WAIT
-FRMR_RSP       	0	1	1	SH5		RESET_WAIT
-FRMR_RSP       	1	0	0	SH5		RESET_WAIT
-FRMR_RSP       	1	0	1	SH5		RESET_WAIT
-FRMR_RSP       	1	1	0	SH5		RESET_WAIT
-FRMR_RSP       	1	1	1	SH5		RESET_WAIT
-BAD_FRAME      	0	0	0	SH7		ERROR
-BAD_FRAME      	0	0	1	SH7		ERROR
-BAD_FRAME      	0	1	0	SH7		ERROR
-BAD_FRAME      	0	1	1	SH7		ERROR
-BAD_FRAME      	1	0	0	SH7		ERROR
-BAD_FRAME      	1	0	1	SH7		ERROR
-BAD_FRAME      	1	1	0	SH7		ERROR
-BAD_FRAME      	1	1	1	SH7		ERROR
-;
-;112 entries in table, 8 modified by tredit4 SABME_CMD x x x SH3 RESET_CHECK
-;112 entries in table, 8 modified by tredit4 DISC_CMD x x x SH4 ADM
-;112 entries in table, 8 modified by tredit4 FRMR_RSP x x x SH5 RESET_WAIT
-;112 entries in table, 8 modified by tredit4 DM_RSP x x x SH6 ADM
-;112 entries in table, 8 modified by tredit4 BAD_FRAME x x x SH7 ERROR
-;112 entries in table, 8 modified by tredit4 UA_RSP x x x SH9 ERROR
-;112 entries in table, 8 modified by tredit4 anyrsp x 1 0 SH10 ERROR
-;112 entries in table, 1 modified by tredit4 I_CMD 1 0 0 NORMAL5 REJECT
-;112 entries in table, 1 modified by tredit4 I_RSP 1 0 0 NORMAL5 REJECT
-;112 entries in table, 1 modified by tredit4 I_RSP 1 1 1 NORMAL5 REJECT
-;112 entries in table, 1 modified by tredit4 I_CMD 1 0 1 NORMAL6 REJECT
-;112 entries in table, 1 modified by tredit4 I_RSP 1 0 1 NORMAL6 REJECT
-;112 entries in table, 2 modified by tredit4 I_CMD 1 1 x NORMAL7 REJECT
-;112 entries in table, 1 modified by tredit4 I_RSP x 1 1 NORMAL8A NORMAL
-;112 entries in table, 1 modified by tredit4 I_RSP x 0 0 NORMAL8B NORMAL
-;112 entries in table, 1 modified by tredit4 I_CMD x 0 0 NORMAL8B NORMAL
-;112 entries in table, 1 modified by tredit4 I_RSP x 0 1 NORMAL9 NORMAL
-;112 entries in table, 1 modified by tredit4 I_CMD x 0 1 NORMAL9 NORMAL
-;112 entries in table, 2 modified by tredit4 I_CMD x 1 x NORMAL10 NORMAL
-;112 entries in table, 4 modified by tredit4 RR_CMD x 0 x NORMAL11 NORMAL
-;112 entries in table, 4 modified by tredit4 RR_RSP x 0 x NORMAL11 NORMAL
-;112 entries in table, 2 modified by tredit4 RR_RSP x 1 1 NORMAL11 NORMAL
-;112 entries in table, 4 modified by tredit4 RR_CMD x 1 x NORMAL12 NORMAL
-;112 entries in table, 4 modified by tredit4 RNR_CMD x 0 x NORMAL13 NORMAL
-;112 entries in table, 4 modified by tredit4 RNR_RSP x 0 x NORMAL13 NORMAL
-;112 entries in table, 2 modified by tredit4 RNR_RSP x 1 1 NORMAL13 NORMAL
-;112 entries in table, 4 modified by tredit4 RNR_CMD x 1 x NORMAL14 NORMAL
-;112 entries in table, 2 modified by tredit4 REJ_CMD x 0 0 NORMAL15 NORMAL
-;112 entries in table, 2 modified by tredit4 REJ_RSP x 1 1 NORMAL15 NORMAL
-;112 entries in table, 2 modified by tredit4 REJ_RSP x 0 0 NORMAL15 NORMAL
-;112 entries in table, 2 modified by tredit4 REJ_CMD x 0 1 NORMAL16 NORMAL
-;112 entries in table, 2 modified by tredit4 REJ_RSP x 0 1 NORMAL16 NORMAL
-;112 entries in table, 4 modified by tredit4 REJ_CMD x 1 x NORMAL17 NORMAL
-;
-TABLE BUSY
-;Transition table for the BUSY state:
-;
-;frame type   uexpect   p bit     p_flag    
-;received     N(S)      in frame            
-;
-I_CMD          	0	0	0	BUSY13	BUSY
-I_CMD          	0	0	1	BUSY14	BUSY
-I_CMD          	0	1	0	BUSY12	BUSY
-I_CMD          	0	1	1	BUSY12	BUSY
-I_CMD          	1	0	0	BUSY9	BUSY
-I_CMD          	1	0	1	BUSY10	BUSY
-I_CMD          	1	1	0	BUSY11	BUSY
-I_CMD          	1	1	1	BUSY11	BUSY
-RR_CMD         	0	0	0	BUSY15	BUSY
-RR_CMD         	0	0	1	BUSY15	BUSY
-RR_CMD         	0	1	0	BUSY16	BUSY
-RR_CMD         	0	1	1	BUSY16	BUSY
-RR_CMD         	1	0	0	BUSY15	BUSY
-RR_CMD         	1	0	1	BUSY15	BUSY
-RR_CMD         	1	1	0	BUSY16	BUSY
-RR_CMD         	1	1	1	BUSY16	BUSY
-RNR_CMD        	0	0	0	BUSY17	BUSY
-RNR_CMD        	0	0	1	BUSY17	BUSY
-RNR_CMD        	0	1	0	BUSY18	BUSY
-RNR_CMD        	0	1	1	BUSY18	BUSY
-RNR_CMD        	1	0	0	BUSY17	BUSY
-RNR_CMD        	1	0	1	BUSY17	BUSY
-RNR_CMD        	1	1	0	BUSY18	BUSY
-RNR_CMD        	1	1	1	BUSY18	BUSY
-REJ_CMD        	0	0	0	BUSY19	BUSY
-REJ_CMD        	0	0	1	BUSY20	BUSY
-REJ_CMD        	0	1	0	BUSY21	BUSY 
-REJ_CMD        	0	1	1	BUSY21	BUSY 
-REJ_CMD        	1	0	0	BUSY19	BUSY
-REJ_CMD        	1	0	1	BUSY20	BUSY
-REJ_CMD        	1	1	0	BUSY21	BUSY 
-REJ_CMD        	1	1	1	BUSY21	BUSY 
-DISC_CMD       	0	0	0	SH4	ADM
-DISC_CMD       	0	0	1	SH4	ADM
-DISC_CMD       	0	1	0	SH4	ADM
-DISC_CMD       	0	1	1	SH4	ADM
-DISC_CMD       	1	0	0	SH4	ADM
-DISC_CMD       	1	0	1	SH4	ADM
-DISC_CMD       	1	1	0	SH4	ADM
-DISC_CMD       	1	1	1	SH4	ADM
-SABME_CMD      	0	0	0	SH3	RESET_CHECK
-SABME_CMD      	0	0	1	SH3	RESET_CHECK
-SABME_CMD      	0	1	0	SH3	RESET_CHECK
-SABME_CMD      	0	1	1	SH3	RESET_CHECK
-SABME_CMD      	1	0	0	SH3	RESET_CHECK
-SABME_CMD      	1	0	1	SH3	RESET_CHECK
-SABME_CMD      	1	1	0	SH3	RESET_CHECK
-SABME_CMD      	1	1	1	SH3	RESET_CHECK
-I_RSP          	0	0	0	BUSY13	BUSY
-I_RSP          	0	0	1	BUSY14	BUSY
-I_RSP          	0	1	0	SH10	ERROR
-I_RSP          	0	1	1	BUSY13	BUSY
-I_RSP          	1	0	0	BUSY9	BUSY
-I_RSP          	1	0	1	BUSY10	BUSY
-I_RSP          	1	1	0	SH10	ERROR
-I_RSP          	1	1	1	BUSY9	BUSY
-RR_RSP         	0	0	0	BUSY15	BUSY
-RR_RSP         	0	0	1	BUSY15	BUSY
-RR_RSP         	0	1	0	SH10	ERROR
-RR_RSP         	0	1	1	BUSY15	BUSY
-RR_RSP         	1	0	0	BUSY15	BUSY
-RR_RSP         	1	0	1	BUSY15	BUSY
-RR_RSP         	1	1	0	SH10	ERROR
-RR_RSP         	1	1	1	BUSY15	BUSY
-RNR_RSP        	0	0	0	BUSY17	BUSY
-RNR_RSP        	0	0	1	BUSY17	BUSY
-RNR_RSP        	0	1	0	SH10	ERROR
-RNR_RSP        	0	1	1	BUSY17	BUSY
-RNR_RSP        	1	0	0	BUSY17	BUSY
-RNR_RSP        	1	0	1	BUSY17	BUSY
-RNR_RSP        	1	1	0	SH10	ERROR
-RNR_RSP        	1	1	1	BUSY17	BUSY
-REJ_RSP        	0	0	0	BUSY19	BUSY
-REJ_RSP        	0	0	1	BUSY20	BUSY
-REJ_RSP        	0	1	0	SH10	ERROR
-REJ_RSP        	0	1	1	BUSY19	BUSY
-REJ_RSP        	1	0	0	BUSY19	BUSY
-REJ_RSP        	1	0	1	BUSY20	BUSY
-REJ_RSP        	1	1	0	SH10	ERROR
-REJ_RSP        	1	1	1	BUSY19	BUSY
-UA_RSP         	0	0	0	SH9	ERROR
-UA_RSP         	0	0	1	SH9	ERROR
-UA_RSP         	0	1	0	SH9	ERROR
-UA_RSP         	0	1	1	SH9	ERROR
-UA_RSP         	1	0	0	SH9	ERROR
-UA_RSP         	1	0	1	SH9	ERROR
-UA_RSP         	1	1	0	SH9	ERROR
-UA_RSP         	1	1	1	SH9	ERROR
-DM_RSP         	0	0	0	SH6	ADM
-DM_RSP         	0	0	1	SH6	ADM
-DM_RSP         	0	1	0	SH6	ADM
-DM_RSP         	0	1	1	SH6	ADM
-DM_RSP         	1	0	0	SH6	ADM
-DM_RSP         	1	0	1	SH6	ADM
-DM_RSP         	1	1	0	SH6	ADM
-DM_RSP         	1	1	1	SH6	ADM
-FRMR_RSP       	0	0	0	SH5	RESET_WAIT
-FRMR_RSP       	0	0	1	SH5	RESET_WAIT
-FRMR_RSP       	0	1	0	SH5	RESET_WAIT
-FRMR_RSP       	0	1	1	SH5	RESET_WAIT
-FRMR_RSP       	1	0	0	SH5	RESET_WAIT
-FRMR_RSP       	1	0	1	SH5	RESET_WAIT
-FRMR_RSP       	1	1	0	SH5	RESET_WAIT
-FRMR_RSP       	1	1	1	SH5	RESET_WAIT
-BAD_FRAME      	0	0	0	SH7	ERROR
-BAD_FRAME      	0	0	1	SH7	ERROR
-BAD_FRAME      	0	1	0	SH7	ERROR
-BAD_FRAME      	0	1	1	SH7	ERROR
-BAD_FRAME      	1	0	0	SH7	ERROR
-BAD_FRAME      	1	0	1	SH7	ERROR
-BAD_FRAME      	1	1	0	SH7	ERROR
-BAD_FRAME      	1	1	1	SH7	ERROR
-;
-;112 entries in table, 8 modified by tredit4 SABME_CMD x x x SH3 RESET_CHECK
-;112 entries in table, 8 modified by tredit4 DISC_CMD x x x SH4 ADM
-;112 entries in table, 8 modified by tredit4 FRMR_RSP x x x SH5 RESET_WAIT
-;112 entries in table, 8 modified by tredit4 DM_RSP x x x SH6 ADM
-;112 entries in table, 8 modified by tredit4 BAD_FRAME x x x SH7 ERROR
-;112 entries in table, 8 modified by tredit4 UA_RSP x x x SH9 ERROR
-;112 entries in table, 8 modified by tredit4 anyrsp x 1 0 SH10 ERROR
-;112 entries in table, 1 modified by tredit4 I_RSP 1 0 0 BUSY9 BUSY
-;112 entries in table, 1 modified by tredit4 I_RSP 1 1 1 BUSY9 BUSY
-;112 entries in table, 1 modified by tredit4 I_CMD 1 0 0 BUSY9 BUSY
-;112 entries in table, 1 modified by tredit4 I_RSP 1 0 1 BUSY10 BUSY
-;112 entries in table, 1 modified by tredit4 I_CMD 1 0 1 BUSY10 BUSY
-;112 entries in table, 2 modified by tredit4 I_CMD 1 1 x BUSY11 BUSY
-;112 entries in table, 2 modified by tredit4 I_CMD x 1 x BUSY12 BUSY
-;112 entries in table, 1 modified by tredit4 I_RSP x 0 0 BUSY13 BUSY
-;112 entries in table, 1 modified by tredit4 I_RSP x 1 1 BUSY13 BUSY
-;112 entries in table, 1 modified by tredit4 I_CMD x 0 0 BUSY13 BUSY
-;112 entries in table, 1 modified by tredit4 I_RSP x 0 1 BUSY14 BUSY
-;112 entries in table, 1 modified by tredit4 I_CMD x 0 1 BUSY14 BUSY
-;112 entries in table, 4 modified by tredit4 RR_CMD x 0 x BUSY15 BUSY
-;112 entries in table, 4 modified by tredit4 RR_RSP x 0 x BUSY15 BUSY
-;112 entries in table, 2 modified by tredit4 RR_RSP x 1 1 BUSY15 BUSY
-;112 entries in table, 4 modified by tredit4 RR_CMD x 1 x BUSY16 BUSY
-;112 entries in table, 4 modified by tredit4 RNR_CMD x 0 x BUSY17 BUSY
-;112 entries in table, 4 modified by tredit4 RNR_RSP x 0 x BUSY17 BUSY
-;112 entries in table, 2 modified by tredit4 RNR_RSP x 1 1 BUSY17 BUSY
-;112 entries in table, 4 modified by tredit4 RNR_CMD x 1 x BUSY18 BUSY
-;112 entries in table, 2 modified by tredit4 REJ_CMD x 0 0 BUSY19 BUSY
-;112 entries in table, 2 modified by tredit4 REJ_RSP x 0 0 BUSY19 BUSY
-;112 entries in table, 2 modified by tredit4 REJ_RSP x 1 1 BUSY19 BUSY
-;112 entries in table, 2 modified by tredit4 REJ_CMD x 0 1 BUSY20 BUSY
-;112 entries in table, 2 modified by tredit4 REJ_RSP x 0 1 BUSY20 BUSY
-;112 entries in table, 4 modified by tredit4 REJ_CMD x 1 x BUSY21 BUSY
-;
-TABLE REJECT
-;Transition table for the REJECT state:
-;
-;frame type   uexpect   p bit     p_flag    
-;received     N(S)      in frame            
-;
-I_CMD          	0	0	0	REJECT7		REJECT
-I_CMD          	0	0	1	REJECT8		REJECT
-I_CMD          	0	1	0	REJECT9		REJECT
-I_CMD          	0	1	1	REJECT9		REJECT
-I_CMD          	1	0	0	REJECT5		REJECT
-I_CMD          	1	0	1	REJECT5		REJECT
-I_CMD          	1	1	0	REJECT6		REJECT
-I_CMD          	1	1	1	REJECT6		REJECT
-RR_CMD         	0	0	0	REJECT10	REJECT
-RR_CMD         	0	0	1	REJECT10	REJECT
-RR_CMD         	0	1	0	REJECT11	REJECT
-RR_CMD         	0	1	1	REJECT11	REJECT
-RR_CMD         	1	0	0	REJECT10	REJECT
-RR_CMD         	1	0	1	REJECT10	REJECT
-RR_CMD         	1	1	0	REJECT11	REJECT
-RR_CMD         	1	1	1	REJECT11	REJECT
-RNR_CMD        	0	0	0	REJECT12	REJECT
-RNR_CMD        	0	0	1	REJECT12	REJECT
-RNR_CMD        	0	1	0	REJECT13	REJECT
-RNR_CMD        	0	1	1	REJECT13	REJECT
-RNR_CMD        	1	0	0	REJECT12	REJECT
-RNR_CMD        	1	0	1	REJECT12	REJECT
-RNR_CMD        	1	1	0	REJECT13	REJECT
-RNR_CMD        	1	1	1	REJECT13	REJECT
-REJ_CMD        	0	0	0	REJECT14	REJECT
-REJ_CMD        	0	0	1	REJECT15	REJECT
-REJ_CMD        	0	1	0	REJECT16	REJECT 
-REJ_CMD        	0	1	1	REJECT16	REJECT 
-REJ_CMD        	1	0	0	REJECT14	REJECT
-REJ_CMD        	1	0	1	REJECT15	REJECT
-REJ_CMD        	1	1	0	REJECT16	REJECT 
-REJ_CMD        	1	1	1	REJECT16	REJECT 
-DISC_CMD       	0	0	0	SH4		ADM
-DISC_CMD       	0	0	1	SH4		ADM
-DISC_CMD       	0	1	0	SH4		ADM
-DISC_CMD       	0	1	1	SH4		ADM
-DISC_CMD       	1	0	0	SH4		ADM
-DISC_CMD       	1	0	1	SH4		ADM
-DISC_CMD       	1	1	0	SH4		ADM
-DISC_CMD       	1	1	1	SH4		ADM
-SABME_CMD      	0	0	0	SH3		RESET_CHECK
-SABME_CMD      	0	0	1	SH3		RESET_CHECK
-SABME_CMD      	0	1	0	SH3		RESET_CHECK
-SABME_CMD      	0	1	1	SH3		RESET_CHECK
-SABME_CMD      	1	0	0	SH3		RESET_CHECK
-SABME_CMD      	1	0	1	SH3		RESET_CHECK
-SABME_CMD      	1	1	0	SH3		RESET_CHECK
-SABME_CMD      	1	1	1	SH3		RESET_CHECK
-I_RSP          	0	0	0	REJECT7		REJECT
-I_RSP          	0	0	1	REJECT8		REJECT
-I_RSP          	0	1	0	SH10		ERROR
-I_RSP          	0	1	1	REJECT7		REJECT
-I_RSP          	1	0	0	REJECT5		REJECT
-I_RSP          	1	0	1	REJECT5		REJECT
-I_RSP          	1	1	0	SH10		ERROR
-I_RSP          	1	1	1	REJECT5		REJECT
-RR_RSP         	0	0	0	REJECT10	REJECT
-RR_RSP         	0	0	1	REJECT10	REJECT
-RR_RSP         	0	1	0	SH10		ERROR
-RR_RSP         	0	1	1	REJECT10	REJECT
-RR_RSP         	1	0	0	REJECT10	REJECT
-RR_RSP         	1	0	1	REJECT10	REJECT
-RR_RSP         	1	1	0	SH10		ERROR
-RR_RSP         	1	1	1	REJECT10	REJECT
-RNR_RSP        	0	0	0	REJECT12	REJECT
-RNR_RSP        	0	0	1	REJECT12	REJECT
-RNR_RSP        	0	1	0	SH10		ERROR
-RNR_RSP        	0	1	1	REJECT12	REJECT
-RNR_RSP        	1	0	0	REJECT12	REJECT
-RNR_RSP        	1	0	1	REJECT12	REJECT
-RNR_RSP        	1	1	0	SH10		ERROR
-RNR_RSP        	1	1	1	REJECT12	REJECT
-REJ_RSP        	0	0	0	REJECT14	REJECT
-REJ_RSP        	0	0	1	REJECT15	REJECT
-REJ_RSP        	0	1	0	SH10		ERROR
-REJ_RSP        	0	1	1	REJECT14	REJECT
-REJ_RSP        	1	0	0	REJECT14	REJECT
-REJ_RSP        	1	0	1	REJECT15	REJECT
-REJ_RSP        	1	1	0	SH10		ERROR
-REJ_RSP        	1	1	1	REJECT14	REJECT
-UA_RSP         	0	0	0	SH9		ERROR
-UA_RSP         	0	0	1	SH9		ERROR
-UA_RSP         	0	1	0	SH9		ERROR
-UA_RSP         	0	1	1	SH9		ERROR
-UA_RSP         	1	0	0	SH9		ERROR
-UA_RSP         	1	0	1	SH9		ERROR
-UA_RSP         	1	1	0	SH9		ERROR
-UA_RSP         	1	1	1	SH9		ERROR
-DM_RSP         	0	0	0	SH6		ADM
-DM_RSP         	0	0	1	SH6		ADM
-DM_RSP         	0	1	0	SH6		ADM
-DM_RSP         	0	1	1	SH6		ADM
-DM_RSP         	1	0	0	SH6		ADM
-DM_RSP         	1	0	1	SH6		ADM
-DM_RSP         	1	1	0	SH6		ADM
-DM_RSP         	1	1	1	SH6		ADM
-FRMR_RSP       	0	0	0	SH5		RESET_WAIT
-FRMR_RSP       	0	0	1	SH5		RESET_WAIT
-FRMR_RSP       	0	1	0	SH5		RESET_WAIT
-FRMR_RSP       	0	1	1	SH5		RESET_WAIT
-FRMR_RSP       	1	0	0	SH5		RESET_WAIT
-FRMR_RSP       	1	0	1	SH5		RESET_WAIT
-FRMR_RSP       	1	1	0	SH5		RESET_WAIT
-FRMR_RSP       	1	1	1	SH5		RESET_WAIT
-BAD_FRAME      	0	0	0	SH7		ERROR
-BAD_FRAME      	0	0	1	SH7		ERROR
-BAD_FRAME      	0	1	0	SH7		ERROR
-BAD_FRAME      	0	1	1	SH7		ERROR
-BAD_FRAME      	1	0	0	SH7		ERROR
-BAD_FRAME      	1	0	1	SH7		ERROR
-BAD_FRAME      	1	1	0	SH7		ERROR
-BAD_FRAME      	1	1	1	SH7		ERROR
-;
-;112 entries in table, 8 modified by tredit4 SABME_CMD x x x SH3 RESET_CHECK
-;112 entries in table, 8 modified by tredit4 DISC_CMD x x x SH4 ADM
-;112 entries in table, 8 modified by tredit4 FRMR_RSP x x x SH5 RESET_WAIT
-;112 entries in table, 8 modified by tredit4 DM_RSP x x x SH6 ADM
-;112 entries in table, 8 modified by tredit4 BAD_FRAME x x x SH7 ERROR
-;112 entries in table, 8 modified by tredit4 UA_RSP x x x SH9 ERROR
-;112 entries in table, 8 modified by tredit4 anyrsp x 1 0 SH10 ERROR
-;112 entries in table, 2 modified by tredit4 I_CMD 1 0 x REJECT5 REJECT
-;112 entries in table, 2 modified by tredit4 I_RSP 1 0 x REJECT5 REJECT
-;112 entries in table, 1 modified by tredit4 I_RSP 1 1 1 REJECT5 REJECT
-;112 entries in table, 2 modified by tredit4 I_CMD 1 1 x REJECT6 REJECT
-;112 entries in table, 1 modified by tredit4 I_RSP x 1 1 REJECT7 REJECT
-;112 entries in table, 1 modified by tredit4 I_RSP x 0 0 REJECT7 REJECT
-;112 entries in table, 1 modified by tredit4 I_CMD x 0 0 REJECT7 REJECT
-;112 entries in table, 1 modified by tredit4 I_RSP x 0 1 REJECT8 REJECT
-;112 entries in table, 1 modified by tredit4 I_CMD x 0 1 REJECT8 REJECT
-;112 entries in table, 2 modified by tredit4 I_CMD x 1 x REJECT9 REJECT
-;112 entries in table, 4 modified by tredit4 RR_CMD x 0 x REJECT10 REJECT
-;112 entries in table, 4 modified by tredit4 RR_RSP x 0 x REJECT10 REJECT
-;112 entries in table, 2 modified by tredit4 RR_RSP x 1 1 REJECT10 REJECT
-;112 entries in table, 4 modified by tredit4 RR_CMD x 1 x REJECT11 REJECT
-;112 entries in table, 4 modified by tredit4 RNR_CMD x 0 x REJECT12 REJECT
-;112 entries in table, 4 modified by tredit4 RNR_RSP x 0 x REJECT12 REJECT
-;112 entries in table, 2 modified by tredit4 RNR_RSP x 1 1 REJECT12 REJECT
-;112 entries in table, 4 modified by tredit4 RNR_CMD x 1 x REJECT13 REJECT
-;112 entries in table, 2 modified by tredit4 REJ_CMD x 0 0 REJECT14 REJECT
-;112 entries in table, 2 modified by tredit4 REJ_RSP x 0 0 REJECT14 REJECT
-;112 entries in table, 2 modified by tredit4 REJ_RSP x 1 1 REJECT14 REJECT
-;112 entries in table, 2 modified by tredit4 REJ_CMD x 0 1 REJECT15 REJECT
-;112 entries in table, 2 modified by tredit4 REJ_RSP x 0 1 REJECT15 REJECT
-;112 entries in table, 4 modified by tredit4 REJ_CMD x 1 x REJECT16 REJECT
-;
-TABLE AWAIT
-;Transition table for the AWAIT state:
-;
-;frame type   uexpect   p bit     p_flag    
-;received     N(S)      in frame            
-;
-I_CMD          	0	0	0	AWAIT6	AWAIT
-I_CMD          	0	0	1	AWAIT6	AWAIT
-I_CMD          	0	1	0	AWAIT7	AWAIT
-I_CMD          	0	1	1	AWAIT7	AWAIT
-I_CMD          	1	0	0	AWAIT3	AWAIT_REJECT
-I_CMD          	1	0	1	AWAIT3	AWAIT_REJECT
-I_CMD          	1	1	0	AWAIT4	AWAIT_REJECT
-I_CMD          	1	1	1	AWAIT4	AWAIT_REJECT
-RR_CMD         	0	0	0	AWAIT9	AWAIT
-RR_CMD         	0	0	1	AWAIT9	AWAIT
-RR_CMD         	0	1	0	AWAIT10	AWAIT
-RR_CMD         	0	1	1	AWAIT10	AWAIT
-RR_CMD         	1	0	0	AWAIT9	AWAIT
-RR_CMD         	1	0	1	AWAIT9	AWAIT
-RR_CMD         	1	1	0	AWAIT10	AWAIT
-RR_CMD         	1	1	1	AWAIT10	AWAIT
-RNR_CMD        	0	0	0	AWAIT12	AWAIT
-RNR_CMD        	0	0	1	AWAIT12	AWAIT
-RNR_CMD        	0	1	0	AWAIT13	AWAIT 
-RNR_CMD        	0	1	1	AWAIT13	AWAIT 
-RNR_CMD        	1	0	0	AWAIT12	AWAIT
-RNR_CMD        	1	0	1	AWAIT12	AWAIT
-RNR_CMD        	1	1	0	AWAIT13	AWAIT 
-RNR_CMD        	1	1	1	AWAIT13	AWAIT 
-REJ_CMD        	0	0	0	AWAIT9	AWAIT
-REJ_CMD        	0	0	1	AWAIT9	AWAIT
-REJ_CMD        	0	1	0	AWAIT10	AWAIT
-REJ_CMD        	0	1	1	AWAIT10	AWAIT
-REJ_CMD        	1	0	0	AWAIT9	AWAIT
-REJ_CMD        	1	0	1	AWAIT9	AWAIT
-REJ_CMD        	1	1	0	AWAIT10	AWAIT
-REJ_CMD        	1	1	1	AWAIT10	AWAIT
-DISC_CMD       	0	0	0	SH4	ADM
-DISC_CMD       	0	0	1	SH4	ADM
-DISC_CMD       	0	1	0	SH4	ADM
-DISC_CMD       	0	1	1	SH4	ADM
-DISC_CMD       	1	0	0	SH4	ADM
-DISC_CMD       	1	0	1	SH4	ADM
-DISC_CMD       	1	1	0	SH4	ADM
-DISC_CMD       	1	1	1	SH4	ADM
-SABME_CMD      	0	0	0	SH3	RESET_CHECK
-SABME_CMD      	0	0	1	SH3	RESET_CHECK
-SABME_CMD      	0	1	0	SH3	RESET_CHECK
-SABME_CMD      	0	1	1	SH3	RESET_CHECK
-SABME_CMD      	1	0	0	SH3	RESET_CHECK
-SABME_CMD      	1	0	1	SH3	RESET_CHECK
-SABME_CMD      	1	1	0	SH3	RESET_CHECK
-SABME_CMD      	1	1	1	SH3	RESET_CHECK
-I_RSP          	0	0	0	AWAIT6	AWAIT
-I_RSP          	0	0	1	AWAIT6	AWAIT
-I_RSP          	0	1	0	SH10	ERROR
-I_RSP          	0	1	1	AWAIT5	NORMAL
-I_RSP          	1	0	0	AWAIT3	AWAIT_REJECT
-I_RSP          	1	0	1	AWAIT3	AWAIT_REJECT
-I_RSP          	1	1	0	SH10	ERROR
-I_RSP          	1	1	1	AWAIT2	REJECT
-RR_RSP         	0	0	0	AWAIT9	AWAIT
-RR_RSP         	0	0	1	AWAIT9	AWAIT
-RR_RSP         	0	1	0	SH10	ERROR
-RR_RSP         	0	1	1	AWAIT8	AWAIT
-RR_RSP         	1	0	0	AWAIT9	AWAIT
-RR_RSP         	1	0	1	AWAIT9	AWAIT
-RR_RSP         	1	1	0	SH10	ERROR
-RR_RSP         	1	1	1	AWAIT8	AWAIT
-RNR_RSP        	0	0	0	AWAIT12	AWAIT
-RNR_RSP        	0	0	1	AWAIT12	AWAIT
-RNR_RSP        	0	1	0	SH10	ERROR
-RNR_RSP        	0	1	1	AWAIT11	AWAIT
-RNR_RSP        	1	0	0	AWAIT12	AWAIT
-RNR_RSP        	1	0	1	AWAIT12	AWAIT
-RNR_RSP        	1	1	0	SH10	ERROR
-RNR_RSP        	1	1	1	AWAIT11	AWAIT
-REJ_RSP        	0	0	0	AWAIT9	AWAIT
-REJ_RSP        	0	0	1	AWAIT9	AWAIT
-REJ_RSP        	0	1	0	SH10	ERROR
-REJ_RSP        	0	1	1	AWAIT8	AWAIT
-REJ_RSP        	1	0	0	AWAIT9	AWAIT
-REJ_RSP        	1	0	1	AWAIT9	AWAIT
-REJ_RSP        	1	1	0	SH10	ERROR
-REJ_RSP        	1	1	1	AWAIT8	AWAIT
-UA_RSP         	0	0	0	SH9	ERROR
-UA_RSP         	0	0	1	SH9	ERROR
-UA_RSP         	0	1	0	SH9	ERROR
-UA_RSP         	0	1	1	SH9	ERROR
-UA_RSP         	1	0	0	SH9	ERROR
-UA_RSP         	1	0	1	SH9	ERROR
-UA_RSP         	1	1	0	SH9	ERROR
-UA_RSP         	1	1	1	SH9	ERROR
-DM_RSP         	0	0	0	SH6	ADM
-DM_RSP         	0	0	1	SH6	ADM
-DM_RSP         	0	1	0	SH6	ADM
-DM_RSP         	0	1	1	SH6	ADM
-DM_RSP         	1	0	0	SH6	ADM
-DM_RSP         	1	0	1	SH6	ADM
-DM_RSP         	1	1	0	SH6	ADM
-DM_RSP         	1	1	1	SH6	ADM
-FRMR_RSP       	0	0	0	SH5	RESET_WAIT
-FRMR_RSP       	0	0	1	SH5	RESET_WAIT
-FRMR_RSP       	0	1	0	SH5	RESET_WAIT
-FRMR_RSP       	0	1	1	SH5	RESET_WAIT
-FRMR_RSP       	1	0	0	SH5	RESET_WAIT
-FRMR_RSP       	1	0	1	SH5	RESET_WAIT
-FRMR_RSP       	1	1	0	SH5	RESET_WAIT
-FRMR_RSP       	1	1	1	SH5	RESET_WAIT
-BAD_FRAME      	0	0	0	SH7	ERROR
-BAD_FRAME      	0	0	1	SH7	ERROR
-BAD_FRAME      	0	1	0	SH7	ERROR
-BAD_FRAME      	0	1	1	SH7	ERROR
-BAD_FRAME      	1	0	0	SH7	ERROR
-BAD_FRAME      	1	0	1	SH7	ERROR
-BAD_FRAME      	1	1	0	SH7	ERROR
-BAD_FRAME      	1	1	1	SH7	ERROR
-;
-;112 entries in table, 8 modified by tredit4 SABME_CMD x x x SH3 RESET_CHECK
-;112 entries in table, 8 modified by tredit4 DISC_CMD x x x SH4 ADM
-;112 entries in table, 8 modified by tredit4 FRMR_RSP x x x SH5 RESET_WAIT
-;112 entries in table, 8 modified by tredit4 DM_RSP x x x SH6 ADM
-;112 entries in table, 8 modified by tredit4 BAD_FRAME x x x SH7 ERROR
-;112 entries in table, 8 modified by tredit4 UA_RSP x x x SH9 ERROR
-;112 entries in table, 8 modified by tredit4 anyrsp x 1 0 SH10 ERROR
-;112 entries in table, 1 modified by tredit4 I_RSP 1 1 x AWAIT2 REJECT
-;112 entries in table, 2 modified by tredit4 I_CMD 1 0 x AWAIT3 AWAIT_REJECT
-;112 entries in table, 2 modified by tredit4 I_RSP 1 0 x AWAIT3 AWAIT_REJECT
-;112 entries in table, 2 modified by tredit4 I_CMD 1 1 x AWAIT4 AWAIT_REJECT
-;112 entries in table, 1 modified by tredit4 I_RSP x 1 x AWAIT5 NORMAL
-;112 entries in table, 2 modified by tredit4 I_RSP x 0 x AWAIT6 AWAIT
-;112 entries in table, 2 modified by tredit4 I_CMD x 0 x AWAIT6 AWAIT
-;112 entries in table, 2 modified by tredit4 I_CMD x 1 x AWAIT7 AWAIT
-;112 entries in table, 2 modified by tredit4 RR_RSP x 1 x AWAIT8 AWAIT
-;112 entries in table, 2 modified by tredit4 REJ_RSP x 1 x AWAIT8 AWAIT
-;112 entries in table, 4 modified by tredit4 RR_CMD x 0 x AWAIT9 AWAIT
-;112 entries in table, 4 modified by tredit4 RR_RSP x 0 x AWAIT9 AWAIT
-;112 entries in table, 4 modified by tredit4 REJ_CMD x 0 x AWAIT9 AWAIT
-;112 entries in table, 4 modified by tredit4 REJ_RSP x 0 x AWAIT9 AWAIT
-;112 entries in table, 4 modified by tredit4 RR_CMD x 1 x AWAIT10 AWAIT
-;112 entries in table, 4 modified by tredit4 REJ_CMD x 1 x AWAIT10 AWAIT
-;112 entries in table, 2 modified by tredit4 RNR_RSP x 1 x AWAIT11 AWAIT
-;112 entries in table, 4 modified by tredit4 RNR_CMD x 0 x AWAIT12 AWAIT
-;112 entries in table, 4 modified by tredit4 RNR_RSP x 0 x AWAIT12 AWAIT
-;112 entries in table, 4 modified by tredit4 RNR_CMD x 1 x AWAIT13 AWAIT
-;
-TABLE AWAIT_BUSY
-;Transition table for the AWAIT_BUSY state:
-;
-;frame type   uexpect   p bit     p_flag    
-;received     N(S)      in frame            
-;
-I_CMD          	0	0	0	AWAIT_BUSY8	AWAIT_BUSY
-I_CMD          	0	0	1	AWAIT_BUSY8	AWAIT_BUSY
-I_CMD          	0	1	0	AWAIT_BUSY9	AWAIT_BUSY
-I_CMD          	0	1	1	AWAIT_BUSY9	AWAIT_BUSY
-I_CMD          	1	0	0	AWAIT_BUSY5	AWAIT_BUSY
-I_CMD          	1	0	1	AWAIT_BUSY5	AWAIT_BUSY
-I_CMD          	1	1	0	AWAIT_BUSY6	AWAIT_BUSY
-I_CMD          	1	1	1	AWAIT_BUSY6	AWAIT_BUSY
-RR_CMD         	0	0	0	AWAIT_BUSY11	AWAIT_BUSY
-RR_CMD         	0	0	1	AWAIT_BUSY11	AWAIT_BUSY
-RR_CMD         	0	1	0	AWAIT_BUSY12	AWAIT_BUSY
-RR_CMD         	0	1	1	AWAIT_BUSY12	AWAIT_BUSY
-RR_CMD         	1	0	0	AWAIT_BUSY11	AWAIT_BUSY
-RR_CMD         	1	0	1	AWAIT_BUSY11	AWAIT_BUSY
-RR_CMD         	1	1	0	AWAIT_BUSY12	AWAIT_BUSY
-RR_CMD         	1	1	1	AWAIT_BUSY12	AWAIT_BUSY
-RNR_CMD        	0	0	0	AWAIT_BUSY14	AWAIT_BUSY
-RNR_CMD        	0	0	1	AWAIT_BUSY14	AWAIT_BUSY
-RNR_CMD        	0	1	0	AWAIT_BUSY15	AWAIT_BUSY 
-RNR_CMD        	0	1	1	AWAIT_BUSY15	AWAIT_BUSY 
-RNR_CMD        	1	0	0	AWAIT_BUSY14	AWAIT_BUSY
-RNR_CMD        	1	0	1	AWAIT_BUSY14	AWAIT_BUSY
-RNR_CMD        	1	1	0	AWAIT_BUSY15	AWAIT_BUSY 
-RNR_CMD        	1	1	1	AWAIT_BUSY15	AWAIT_BUSY 
-REJ_CMD        	0	0	0	AWAIT_BUSY11	AWAIT_BUSY
-REJ_CMD        	0	0	1	AWAIT_BUSY11	AWAIT_BUSY
-REJ_CMD        	0	1	0	AWAIT_BUSY12	AWAIT_BUSY
-REJ_CMD        	0	1	1	AWAIT_BUSY12	AWAIT_BUSY
-REJ_CMD        	1	0	0	AWAIT_BUSY11	AWAIT_BUSY
-REJ_CMD        	1	0	1	AWAIT_BUSY11	AWAIT_BUSY
-REJ_CMD        	1	1	0	AWAIT_BUSY12	AWAIT_BUSY
-REJ_CMD        	1	1	1	AWAIT_BUSY12	AWAIT_BUSY
-DISC_CMD       	0	0	0	SH4		ADM
-DISC_CMD       	0	0	1	SH4		ADM
-DISC_CMD       	0	1	0	SH4		ADM
-DISC_CMD       	0	1	1	SH4		ADM
-DISC_CMD       	1	0	0	SH4		ADM
-DISC_CMD       	1	0	1	SH4		ADM
-DISC_CMD       	1	1	0	SH4		ADM
-DISC_CMD       	1	1	1	SH4		ADM
-SABME_CMD      	0	0	0	SH3		RESET_CHECK
-SABME_CMD      	0	0	1	SH3		RESET_CHECK
-SABME_CMD      	0	1	0	SH3		RESET_CHECK
-SABME_CMD      	0	1	1	SH3		RESET_CHECK
-SABME_CMD      	1	0	0	SH3		RESET_CHECK
-SABME_CMD      	1	0	1	SH3		RESET_CHECK
-SABME_CMD      	1	1	0	SH3		RESET_CHECK
-SABME_CMD      	1	1	1	SH3		RESET_CHECK
-I_RSP          	0	0	0	AWAIT_BUSY8	AWAIT_BUSY
-I_RSP          	0	0	1	AWAIT_BUSY8	AWAIT_BUSY
-I_RSP          	0	1	0	SH10		ERROR
-I_RSP          	0	1	1	AWAIT_BUSY7	BUSY
-I_RSP          	1	0	0	AWAIT_BUSY5	AWAIT_BUSY
-I_RSP          	1	0	1	AWAIT_BUSY5	AWAIT_BUSY
-I_RSP          	1	1	0	SH10		ERROR
-I_RSP          	1	1	1	AWAIT_BUSY4	BUSY
-RR_RSP         	0	0	0	AWAIT_BUSY11	AWAIT_BUSY
-RR_RSP         	0	0	1	AWAIT_BUSY11	AWAIT_BUSY
-RR_RSP         	0	1	0	SH10		ERROR
-RR_RSP         	0	1	1	AWAIT_BUSY10	BUSY
-RR_RSP         	1	0	0	AWAIT_BUSY11	AWAIT_BUSY
-RR_RSP         	1	0	1	AWAIT_BUSY11	AWAIT_BUSY
-RR_RSP         	1	1	0	SH10		ERROR
-RR_RSP         	1	1	1	AWAIT_BUSY10	BUSY
-RNR_RSP        	0	0	0	AWAIT_BUSY14	AWAIT_BUSY
-RNR_RSP        	0	0	1	AWAIT_BUSY14	AWAIT_BUSY
-RNR_RSP        	0	1	0	SH10		ERROR
-RNR_RSP        	0	1	1	AWAIT_BUSY13	BUSY
-RNR_RSP        	1	0	0	AWAIT_BUSY14	AWAIT_BUSY
-RNR_RSP        	1	0	1	AWAIT_BUSY14	AWAIT_BUSY
-RNR_RSP        	1	1	0	SH10		ERROR
-RNR_RSP        	1	1	1	AWAIT_BUSY13	BUSY
-REJ_RSP        	0	0	0	AWAIT_BUSY11	AWAIT_BUSY
-REJ_RSP        	0	0	1	AWAIT_BUSY11	AWAIT_BUSY
-REJ_RSP        	0	1	0	SH10		ERROR
-REJ_RSP        	0	1	1	AWAIT_BUSY10	BUSY
-REJ_RSP        	1	0	0	AWAIT_BUSY11	AWAIT_BUSY
-REJ_RSP        	1	0	1	AWAIT_BUSY11	AWAIT_BUSY
-REJ_RSP        	1	1	0	SH10		ERROR
-REJ_RSP        	1	1	1	AWAIT_BUSY10	BUSY
-UA_RSP         	0	0	0	SH9		ERROR
-UA_RSP         	0	0	1	SH9		ERROR
-UA_RSP         	0	1	0	SH9		ERROR
-UA_RSP         	0	1	1	SH9		ERROR
-UA_RSP         	1	0	0	SH9		ERROR
-UA_RSP         	1	0	1	SH9		ERROR
-UA_RSP         	1	1	0	SH9		ERROR
-UA_RSP         	1	1	1	SH9		ERROR
-DM_RSP         	0	0	0	SH6		ADM
-DM_RSP         	0	0	1	SH6		ADM
-DM_RSP         	0	1	0	SH6		ADM
-DM_RSP         	0	1	1	SH6		ADM
-DM_RSP         	1	0	0	SH6		ADM
-DM_RSP         	1	0	1	SH6		ADM
-DM_RSP         	1	1	0	SH6		ADM
-DM_RSP         	1	1	1	SH6		ADM
-FRMR_RSP       	0	0	0	SH5		RESET_WAIT
-FRMR_RSP       	0	0	1	SH5		RESET_WAIT
-FRMR_RSP       	0	1	0	SH5		RESET_WAIT
-FRMR_RSP       	0	1	1	SH5		RESET_WAIT
-FRMR_RSP       	1	0	0	SH5		RESET_WAIT
-FRMR_RSP       	1	0	1	SH5		RESET_WAIT
-FRMR_RSP       	1	1	0	SH5		RESET_WAIT
-FRMR_RSP       	1	1	1	SH5		RESET_WAIT
-BAD_FRAME      	0	0	0	SH7		ERROR
-BAD_FRAME      	0	0	1	SH7		ERROR
-BAD_FRAME      	0	1	0	SH7		ERROR
-BAD_FRAME      	0	1	1	SH7		ERROR
-BAD_FRAME      	1	0	0	SH7		ERROR
-BAD_FRAME      	1	0	1	SH7		ERROR
-BAD_FRAME      	1	1	0	SH7		ERROR
-BAD_FRAME      	1	1	1	SH7		ERROR
-;
-;112 entries in table, 8 modified by tredit4 SABME_CMD x x x SH3 RESET_CHECK
-;112 entries in table, 8 modified by tredit4 DISC_CMD x x x SH4 ADM
-;112 entries in table, 8 modified by tredit4 FRMR_RSP x x x SH5 RESET_WAIT
-;112 entries in table, 8 modified by tredit4 DM_RSP x x x SH6 ADM
-;112 entries in table, 8 modified by tredit4 BAD_FRAME x x x SH7 ERROR
-;112 entries in table, 8 modified by tredit4 UA_RSP x x x SH9 ERROR
-;112 entries in table, 8 modified by tredit4 anyrsp x 1 0 SH10 ERROR
-;112 entries in table, 1 modified by tredit4 I_RSP 1 1 x AWAIT_BUSY4 BUSY
-;112 entries in table, 2 modified by tredit4 I_CMD 1 0 x AWAIT_BUSY5 AWAIT_BUSY
-;112 entries in table, 2 modified by tredit4 I_RSP 1 0 x AWAIT_BUSY5 AWAIT_BUSY
-;112 entries in table, 2 modified by tredit4 I_CMD 1 1 x AWAIT_BUSY6 AWAIT_BUSY
-;112 entries in table, 1 modified by tredit4 I_RSP x 1 x AWAIT_BUSY7 BUSY
-;112 entries in table, 2 modified by tredit4 I_RSP x 0 x AWAIT_BUSY8 AWAIT_BUSY
-;112 entries in table, 2 modified by tredit4 I_CMD x 0 x AWAIT_BUSY8 AWAIT_BUSY
-;112 entries in table, 2 modified by tredit4 I_CMD x 1 x AWAIT_BUSY9 AWAIT_BUSY
-;112 entries in table, 2 modified by tredit4 RR_RSP x 1 x AWAIT_BUSY10 BUSY
-;112 entries in table, 2 modified by tredit4 REJ_RSP x 1 x AWAIT_BUSY10 BUSY
-;112 entries in table, 4 modified by tredit4 RR_CMD x 0 x AWAIT_BUSY11 AWAIT_BUSY
-;112 entries in table, 4 modified by tredit4 RR_RSP x 0 x AWAIT_BUSY11 AWAIT_BUSY
-;112 entries in table, 4 modified by tredit4 REJ_CMD x 0 x AWAIT_BUSY11 AWAIT_BUSY
-;112 entries in table, 4 modified by tredit4 REJ_RSP x 0 x AWAIT_BUSY11 AWAIT_BUSY
-;112 entries in table, 4 modified by tredit4 RR_CMD x 1 x AWAIT_BUSY12 AWAIT_BUSY
-;112 entries in table, 4 modified by tredit4 REJ_CMD x 1 x AWAIT_BUSY12 AWAIT_BUSY
-;112 entries in table, 2 modified by tredit4 RNR_RSP x 1 x AWAIT_BUSY13 BUSY
-;112 entries in table, 4 modified by tredit4 RNR_CMD x 0 x AWAIT_BUSY14 AWAIT_BUSY
-;112 entries in table, 4 modified by tredit4 RNR_RSP x 0 x AWAIT_BUSY14 AWAIT_BUSY
-;112 entries in table, 4 modified by tredit4 RNR_CMD x 1 x AWAIT_BUSY15 AWAIT_BUSY
-;
-TABLE AWAIT_REJECT
-;Transition table for the AWAIT_REJECT state:
-;
-;frame type   uexpect   p bit     p_flag    
-;received     N(S)      in frame            
-;
-I_CMD          	0	0	0	AWAIT_REJECT5	AWAIT
-I_CMD          	0	0	1	AWAIT_REJECT5	AWAIT
-I_CMD          	0	1	0	AWAIT_REJECT6	AWAIT
-I_CMD          	0	1	1	AWAIT_REJECT6	AWAIT
-I_CMD          	1	0	0	AWAIT_REJECT2	AWAIT_REJECT
-I_CMD          	1	0	1	AWAIT_REJECT2	AWAIT_REJECT
-I_CMD          	1	1	0	AWAIT_REJECT3	AWAIT_REJECT
-I_CMD          	1	1	1	AWAIT_REJECT3	AWAIT_REJECT
-RR_CMD         	0	0	0	AWAIT_REJECT8	AWAIT_REJECT
-RR_CMD         	0	0	1	AWAIT_REJECT8	AWAIT_REJECT
-RR_CMD         	0	1	0	AWAIT_REJECT9	AWAIT_REJECT
-RR_CMD         	0	1	1	AWAIT_REJECT9	AWAIT_REJECT
-RR_CMD         	1	0	0	AWAIT_REJECT8	AWAIT_REJECT
-RR_CMD         	1	0	1	AWAIT_REJECT8	AWAIT_REJECT
-RR_CMD         	1	1	0	AWAIT_REJECT9	AWAIT_REJECT
-RR_CMD         	1	1	1	AWAIT_REJECT9	AWAIT_REJECT
-RNR_CMD        	0	0	0	AWAIT_REJECT11	AWAIT_REJECT
-RNR_CMD        	0	0	1	AWAIT_REJECT11	AWAIT_REJECT
-RNR_CMD        	0	1	0	AWAIT_REJECT12	AWAIT_REJECT
-RNR_CMD        	0	1	1	AWAIT_REJECT12	AWAIT_REJECT
-RNR_CMD        	1	0	0	AWAIT_REJECT11	AWAIT_REJECT
-RNR_CMD        	1	0	1	AWAIT_REJECT11	AWAIT_REJECT
-RNR_CMD        	1	1	0	AWAIT_REJECT12	AWAIT_REJECT
-RNR_CMD        	1	1	1	AWAIT_REJECT12	AWAIT_REJECT
-REJ_CMD        	0	0	0	AWAIT_REJECT8	AWAIT_REJECT
-REJ_CMD        	0	0	1	AWAIT_REJECT8	AWAIT_REJECT
-REJ_CMD        	0	1	0	AWAIT_REJECT9	AWAIT_REJECT
-REJ_CMD        	0	1	1	AWAIT_REJECT9	AWAIT_REJECT
-REJ_CMD        	1	0	0	AWAIT_REJECT8	AWAIT_REJECT
-REJ_CMD        	1	0	1	AWAIT_REJECT8	AWAIT_REJECT
-REJ_CMD        	1	1	0	AWAIT_REJECT9	AWAIT_REJECT
-REJ_CMD        	1	1	1	AWAIT_REJECT9	AWAIT_REJECT
-DISC_CMD       	0	0	0	SH4	ADM
-DISC_CMD       	0	0	1	SH4	ADM
-DISC_CMD       	0	1	0	SH4	ADM
-DISC_CMD       	0	1	1	SH4	ADM
-DISC_CMD       	1	0	0	SH4	ADM
-DISC_CMD       	1	0	1	SH4	ADM
-DISC_CMD       	1	1	0	SH4	ADM
-DISC_CMD       	1	1	1	SH4	ADM
-SABME_CMD      	0	0	0	SH3	RESET_CHECK
-SABME_CMD      	0	0	1	SH3	RESET_CHECK
-SABME_CMD      	0	1	0	SH3	RESET_CHECK
-SABME_CMD      	0	1	1	SH3	RESET_CHECK
-SABME_CMD      	1	0	0	SH3	RESET_CHECK
-SABME_CMD      	1	0	1	SH3	RESET_CHECK
-SABME_CMD      	1	1	0	SH3	RESET_CHECK
-SABME_CMD      	1	1	1	SH3	RESET_CHECK
-I_RSP          	0	0	0	AWAIT_REJECT5	AWAIT
-I_RSP          	0	0	1	AWAIT_REJECT5	AWAIT
-I_RSP          	0	1	0	SH10	ERROR
-I_RSP          	0	1	1	AWAIT_REJECT4	NORMAL
-I_RSP          	1	0	0	AWAIT_REJECT2	AWAIT_REJECT
-I_RSP          	1	0	1	AWAIT_REJECT2	AWAIT_REJECT
-I_RSP          	1	1	0	SH10	ERROR
-I_RSP          	1	1	1	AWAIT_REJECT4	NORMAL
-RR_RSP         	0	0	0	AWAIT_REJECT8	AWAIT_REJECT
-RR_RSP         	0	0	1	AWAIT_REJECT8	AWAIT_REJECT
-RR_RSP         	0	1	0	SH10	ERROR
-RR_RSP         	0	1	1	AWAIT_REJECT7	REJECT
-RR_RSP         	1	0	0	AWAIT_REJECT8	AWAIT_REJECT
-RR_RSP         	1	0	1	AWAIT_REJECT8	AWAIT_REJECT
-RR_RSP         	1	1	0	SH10	ERROR
-RR_RSP         	1	1	1	AWAIT_REJECT7	REJECT
-RNR_RSP        	0	0	0	AWAIT_REJECT11	AWAIT_REJECT
-RNR_RSP        	0	0	1	AWAIT_REJECT11	AWAIT_REJECT
-RNR_RSP        	0	1	0	SH10	ERROR
-RNR_RSP        	0	1	1	AWAIT_REJECT10	REJECT
-RNR_RSP        	1	0	0	AWAIT_REJECT11	AWAIT_REJECT
-RNR_RSP        	1	0	1	AWAIT_REJECT11	AWAIT_REJECT
-RNR_RSP        	1	1	0	SH10	ERROR
-RNR_RSP        	1	1	1	AWAIT_REJECT10	REJECT
-REJ_RSP        	0	0	0	AWAIT_REJECT8	AWAIT_REJECT
-REJ_RSP        	0	0	1	AWAIT_REJECT8	AWAIT_REJECT
-REJ_RSP        	0	1	0	SH10	ERROR
-REJ_RSP        	0	1	1	AWAIT_REJECT7	REJECT
-REJ_RSP        	1	0	0	AWAIT_REJECT8	AWAIT_REJECT
-REJ_RSP        	1	0	1	AWAIT_REJECT8	AWAIT_REJECT
-REJ_RSP        	1	1	0	SH10	ERROR
-REJ_RSP        	1	1	1	AWAIT_REJECT7	REJECT
-UA_RSP         	0	0	0	SH9	ERROR
-UA_RSP         	0	0	1	SH9	ERROR
-UA_RSP         	0	1	0	SH9	ERROR
-UA_RSP         	0	1	1	SH9	ERROR
-UA_RSP         	1	0	0	SH9	ERROR
-UA_RSP         	1	0	1	SH9	ERROR
-UA_RSP         	1	1	0	SH9	ERROR
-UA_RSP         	1	1	1	SH9	ERROR
-DM_RSP         	0	0	0	SH6	ADM
-DM_RSP         	0	0	1	SH6	ADM
-DM_RSP         	0	1	0	SH6	ADM
-DM_RSP         	0	1	1	SH6	ADM
-DM_RSP         	1	0	0	SH6	ADM
-DM_RSP         	1	0	1	SH6	ADM
-DM_RSP         	1	1	0	SH6	ADM
-DM_RSP         	1	1	1	SH6	ADM
-FRMR_RSP       	0	0	0	SH5	RESET_WAIT
-FRMR_RSP       	0	0	1	SH5	RESET_WAIT
-FRMR_RSP       	0	1	0	SH5	RESET_WAIT
-FRMR_RSP       	0	1	1	SH5	RESET_WAIT
-FRMR_RSP       	1	0	0	SH5	RESET_WAIT
-FRMR_RSP       	1	0	1	SH5	RESET_WAIT
-FRMR_RSP       	1	1	0	SH5	RESET_WAIT
-FRMR_RSP       	1	1	1	SH5	RESET_WAIT
-BAD_FRAME      	0	0	0	SH7	ERROR
-BAD_FRAME      	0	0	1	SH7	ERROR
-BAD_FRAME      	0	1	0	SH7	ERROR
-BAD_FRAME      	0	1	1	SH7	ERROR
-BAD_FRAME      	1	0	0	SH7	ERROR
-BAD_FRAME      	1	0	1	SH7	ERROR
-BAD_FRAME      	1	1	0	SH7	ERROR
-BAD_FRAME      	1	1	1	SH7	ERROR
-;
-;112 entries in table, 8 modified by tredit4 SABME_CMD x x x SH3 RESET_CHECK
-;112 entries in table, 8 modified by tredit4 DISC_CMD x x x SH4 ADM
-;112 entries in table, 8 modified by tredit4 FRMR_RSP x x x SH5 RESET_WAIT
-;112 entries in table, 8 modified by tredit4 DM_RSP x x x SH6 ADM
-;112 entries in table, 8 modified by tredit4 BAD_FRAME x x x SH7 ERROR
-;112 entries in table, 8 modified by tredit4 UA_RSP x x x SH9 ERROR
-;112 entries in table, 8 modified by tredit4 anyrsp x 1 0 SH10 ERROR
-;112 entries in table, 2 modified by tredit4 I_CMD 1 0 x AWAIT_REJECT2 AWAIT_REJECT
-;112 entries in table, 2 modified by tredit4 I_RSP 1 0 x AWAIT_REJECT2 AWAIT_REJECT
-;112 entries in table, 2 modified by tredit4 I_CMD 1 1 x AWAIT_REJECT3 AWAIT_REJECT
-;112 entries in table, 2 modified by tredit4 I_RSP x 1 x AWAIT_REJECT4 NORMAL
-;112 entries in table, 2 modified by tredit4 I_RSP x 0 x AWAIT_REJECT5 AWAIT
-;112 entries in table, 2 modified by tredit4 I_CMD x 0 x AWAIT_REJECT5 AWAIT
-;112 entries in table, 2 modified by tredit4 I_CMD x 1 x AWAIT_REJECT6 AWAIT
-;112 entries in table, 2 modified by tredit4 RR_RSP x 1 x AWAIT_REJECT7 REJECT
-;112 entries in table, 2 modified by tredit4 REJ_RSP x 1 x AWAIT_REJECT7 REJECT
-;112 entries in table, 0 modified by tredit4 I_RSP 1 1 x AWAIT_REJECT7 REJECT
-;112 entries in table, 4 modified by tredit4 RR_CMD x 0 x AWAIT_REJECT8 AWAIT_REJECT
-;112 entries in table, 4 modified by tredit4 RR_RSP x 0 x AWAIT_REJECT8 AWAIT_REJECT
-;112 entries in table, 4 modified by tredit4 REJ_CMD x 0 x AWAIT_REJECT8 AWAIT_REJECT
-;112 entries in table, 4 modified by tredit4 REJ_RSP x 0 x AWAIT_REJECT8 AWAIT_REJECT
-;112 entries in table, 4 modified by tredit4 RR_CMD x 1 x AWAIT_REJECT9 AWAIT_REJECT
-;112 entries in table, 4 modified by tredit4 REJ_CMD x 1 x AWAIT_REJECT9 AWAIT_REJECT
-;112 entries in table, 2 modified by tredit4 RNR_RSP x 1 x AWAIT_REJECT10 REJECT
-;112 entries in table, 4 modified by tredit4 RNR_CMD x 0 x AWAIT_REJECT11 AWAIT_REJECT
-;112 entries in table, 4 modified by tredit4 RNR_RSP x 0 x AWAIT_REJECT11 AWAIT_REJECT
-;112 entries in table, 4 modified by tredit4 RNR_CMD x 1 x AWAIT_REJECT12 AWAIT_REJECT
-;112 entries in table, 0 modified by tredit4 RNR_CMD x 1 x AWAIT_REJECT15 AWAIT_BUSY
diff -Nru a/net/802/transit/timertr.pre b/net/802/transit/timertr.pre
--- a/net/802/transit/timertr.pre	Sat Aug 10 18:42:22 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,527 +0,0 @@
-COMPILE timertr NOINDEX 
-TABLE XXX
-;
-;Transition table for expiring timers:
-;
-;llc state 	timer   	retry_c	s_flag 	p_flag	action	newstate
-;		expired    	>= N2  
-;				
-ADM		ACK_TIMER	0	0      	0	NOP	ADM	
-ADM		ACK_TIMER	0	0      	1	NOP	ADM
-ADM		ACK_TIMER	0	1      	0	NOP	ADM
-ADM		ACK_TIMER	0	1      	1	NOP	ADM
-ADM		ACK_TIMER	1	0      	0	NOP	ADM
-ADM		ACK_TIMER	1	0      	1	NOP	ADM
-ADM		ACK_TIMER	1	1       0	NOP	ADM
-ADM		ACK_TIMER	1	1	1	NOP	ADM
-;;
-ADM		P_TIMER		0	0	0	NOP	ADM
-ADM		P_TIMER		0	0	1	NOP	ADM
-ADM		P_TIMER		0	1	0	NOP	ADM
-ADM		P_TIMER		0	1	1	NOP	ADM
-ADM		P_TIMER		1	0	0	NOP	ADM
-ADM		P_TIMER		1	0	1	NOP	ADM
-ADM		P_TIMER		1	1	0	NOP	ADM
-ADM		P_TIMER		1	1	1	NOP	ADM
-;;			
-ADM		REJ_TIMER 	0	0	0	NOP	ADM
-ADM		REJ_TIMER 	0	0	1	NOP	ADM
-ADM		REJ_TIMER 	0	1	0	NOP	ADM
-ADM		REJ_TIMER 	0	1	1	NOP	ADM
-ADM		REJ_TIMER 	1	0	0	NOP	ADM
-ADM		REJ_TIMER 	1	0	1	NOP	ADM
-ADM		REJ_TIMER 	1	1	0	NOP	ADM
-ADM		REJ_TIMER 	1	1	1	NOP	ADM
-;;			
-ADM		BUSY_TIMER 	0	0	0	NOP	ADM
-ADM		BUSY_TIMER 	0	0	1	NOP	ADM
-ADM		BUSY_TIMER 	0	1	0	NOP	ADM
-ADM		BUSY_TIMER 	0	1	1	NOP	ADM
-ADM		BUSY_TIMER 	1	0	0	NOP	ADM
-ADM		BUSY_TIMER 	1	0	1	NOP	ADM
-ADM		BUSY_TIMER 	1	1	0	NOP	ADM
-ADM		BUSY_TIMER 	1	1	1	NOP	ADM
-;;
-;;
-CONN		ACK_TIMER	0	0      	0	NOP	CONN	
-CONN		ACK_TIMER	0	0      	1	NOP	CONN
-CONN		ACK_TIMER	0	1      	0	NOP	CONN
-CONN		ACK_TIMER	0	1      	1	NOP	CONN
-CONN		ACK_TIMER	1	0      	0	NOP	CONN
-CONN		ACK_TIMER	1	0      	1	NOP	CONN
-CONN		ACK_TIMER	1	1       0	NOP	CONN
-CONN		ACK_TIMER	1	1	1	NOP	CONN
-;;
-CONN		P_TIMER		0	0	0	NOP	CONN
-CONN		P_TIMER		0	0	1	NOP	CONN
-CONN		P_TIMER		0	1	0	NOP	CONN
-CONN		P_TIMER		0	1	1	NOP	CONN
-CONN		P_TIMER		1	0	0	NOP	CONN
-CONN		P_TIMER		1	0	1	NOP	CONN
-CONN		P_TIMER		1	1	0	NOP	CONN
-CONN		P_TIMER		1	1	1	NOP	CONN
-;;			
-CONN		REJ_TIMER 	0	0	0	NOP	CONN
-CONN		REJ_TIMER 	0	0	1	NOP	CONN
-CONN		REJ_TIMER 	0	1	0	NOP	CONN
-CONN		REJ_TIMER 	0	1	1	NOP	CONN
-CONN		REJ_TIMER 	1	0	0	NOP	CONN
-CONN		REJ_TIMER 	1	0	1	NOP	CONN
-CONN		REJ_TIMER 	1	1	0	NOP	CONN
-CONN		REJ_TIMER 	1	1	1	NOP	CONN
-;;			
-CONN		BUSY_TIMER 	0	0	0	NOP	CONN
-CONN		BUSY_TIMER 	0	0	1	NOP	CONN
-CONN		BUSY_TIMER 	0	1	0	NOP	CONN
-CONN		BUSY_TIMER 	0	1	1	NOP	CONN
-CONN		BUSY_TIMER 	1	0	0	NOP	CONN
-CONN		BUSY_TIMER 	1	0	1	NOP	CONN
-CONN		BUSY_TIMER 	1	1	0	NOP	CONN
-CONN		BUSY_TIMER 	1	1	1	NOP	CONN
-;;
-;;
-RESET_WAIT	ACK_TIMER	0	0      	0	NOP	RESET_WAIT	
-RESET_WAIT	ACK_TIMER	0	0      	1	NOP	RESET_WAIT
-RESET_WAIT	ACK_TIMER	0	1      	0	NOP	RESET_WAIT
-RESET_WAIT	ACK_TIMER	0	1      	1	NOP	RESET_WAIT
-RESET_WAIT	ACK_TIMER	1	0      	0	NOP	RESET_WAIT
-RESET_WAIT	ACK_TIMER	1	0      	1	NOP	RESET_WAIT
-RESET_WAIT	ACK_TIMER	1	1       0	NOP	RESET_WAIT
-RESET_WAIT	ACK_TIMER	1	1	1	NOP	RESET_WAIT
-;;
-RESET_WAIT	P_TIMER		0	0	0	NOP	RESET_WAIT
-RESET_WAIT	P_TIMER		0	0	1	NOP	RESET_WAIT
-RESET_WAIT	P_TIMER		0	1	0	NOP	RESET_WAIT
-RESET_WAIT	P_TIMER		0	1	1	NOP	RESET_WAIT
-RESET_WAIT	P_TIMER		1	0	0	NOP	RESET_WAIT
-RESET_WAIT	P_TIMER		1	0	1	NOP	RESET_WAIT
-RESET_WAIT	P_TIMER		1	1	0	NOP	RESET_WAIT
-RESET_WAIT	P_TIMER		1	1	1	NOP	RESET_WAIT
-;;			
-RESET_WAIT	REJ_TIMER 	0	0	0	NOP	RESET_WAIT
-RESET_WAIT	REJ_TIMER 	0	0	1	NOP	RESET_WAIT
-RESET_WAIT	REJ_TIMER 	0	1	0	NOP	RESET_WAIT
-RESET_WAIT	REJ_TIMER 	0	1	1	NOP	RESET_WAIT
-RESET_WAIT	REJ_TIMER 	1	0	0	NOP	RESET_WAIT
-RESET_WAIT	REJ_TIMER 	1	0	1	NOP	RESET_WAIT
-RESET_WAIT	REJ_TIMER 	1	1	0	NOP	RESET_WAIT
-RESET_WAIT	REJ_TIMER 	1	1	1	NOP	RESET_WAIT
-;;			
-RESET_WAIT	BUSY_TIMER 	0	0	0	NOP	RESET_WAIT
-RESET_WAIT	BUSY_TIMER 	0	0	1	NOP	RESET_WAIT
-RESET_WAIT	BUSY_TIMER 	0	1	0	NOP	RESET_WAIT
-RESET_WAIT	BUSY_TIMER 	0	1	1	NOP	RESET_WAIT
-RESET_WAIT	BUSY_TIMER 	1	0	0	NOP	RESET_WAIT
-RESET_WAIT	BUSY_TIMER 	1	0	1	NOP	RESET_WAIT
-RESET_WAIT	BUSY_TIMER 	1	1	0	NOP	RESET_WAIT
-RESET_WAIT	BUSY_TIMER 	1	1	1	NOP	RESET_WAIT
-;;
-;;
-RESET_CHECK	ACK_TIMER	0	0      	0	NOP	RESET_CHECK	
-RESET_CHECK	ACK_TIMER	0	0      	1	NOP	RESET_CHECK
-RESET_CHECK	ACK_TIMER	0	1      	0	NOP	RESET_CHECK
-RESET_CHECK	ACK_TIMER	0	1      	1	NOP	RESET_CHECK
-RESET_CHECK	ACK_TIMER	1	0      	0	NOP	RESET_CHECK
-RESET_CHECK	ACK_TIMER	1	0      	1	NOP	RESET_CHECK
-RESET_CHECK	ACK_TIMER	1	1       0	NOP	RESET_CHECK
-RESET_CHECK	ACK_TIMER	1	1	1	NOP	RESET_CHECK
-;;
-RESET_CHECK	P_TIMER		0	0	0	NOP	RESET_CHECK
-RESET_CHECK	P_TIMER		0	0	1	NOP	RESET_CHECK
-RESET_CHECK	P_TIMER		0	1	0	NOP	RESET_CHECK
-RESET_CHECK	P_TIMER		0	1	1	NOP	RESET_CHECK
-RESET_CHECK	P_TIMER		1	0	0	NOP	RESET_CHECK
-RESET_CHECK	P_TIMER		1	0	1	NOP	RESET_CHECK
-RESET_CHECK	P_TIMER		1	1	0	NOP	RESET_CHECK
-RESET_CHECK	P_TIMER		1	1	1	NOP	RESET_CHECK
-;;			
-RESET_CHECK	REJ_TIMER 	0	0	0	NOP	RESET_CHECK
-RESET_CHECK	REJ_TIMER 	0	0	1	NOP	RESET_CHECK
-RESET_CHECK	REJ_TIMER 	0	1	0	NOP	RESET_CHECK
-RESET_CHECK	REJ_TIMER 	0	1	1	NOP	RESET_CHECK
-RESET_CHECK	REJ_TIMER 	1	0	0	NOP	RESET_CHECK
-RESET_CHECK	REJ_TIMER 	1	0	1	NOP	RESET_CHECK
-RESET_CHECK	REJ_TIMER 	1	1	0	NOP	RESET_CHECK
-RESET_CHECK	REJ_TIMER 	1	1	1	NOP	RESET_CHECK
-;;			
-RESET_CHECK	BUSY_TIMER 	0	0	0	NOP	RESET_CHECK
-RESET_CHECK	BUSY_TIMER 	0	0	1	NOP	RESET_CHECK
-RESET_CHECK	BUSY_TIMER 	0	1	0	NOP	RESET_CHECK
-RESET_CHECK	BUSY_TIMER 	0	1	1	NOP	RESET_CHECK
-RESET_CHECK	BUSY_TIMER 	1	0	0	NOP	RESET_CHECK
-RESET_CHECK	BUSY_TIMER 	1	0	1	NOP	RESET_CHECK
-RESET_CHECK	BUSY_TIMER 	1	1	0	NOP	RESET_CHECK
-RESET_CHECK	BUSY_TIMER 	1	1	1	NOP	RESET_CHECK
-;;
-;;
-;;
-SETUP		ACK_TIMER	0	0      	0	SETUP7  SETUP	
-SETUP		ACK_TIMER	0	0      	1	SETUP7  SETUP
-SETUP		ACK_TIMER	0	1      	0	SETUP3  NORMAL
-SETUP		ACK_TIMER	0	1      	1	SETUP3  NORMAL
-SETUP		ACK_TIMER	1	0      	0	SETUP8  ADM
-SETUP		ACK_TIMER	1	0      	1	SETUP8  ADM
-SETUP		ACK_TIMER	1	1       0	SETUP3  NORMAL
-SETUP		ACK_TIMER	1	1	1	SETUP3  NORMAL
-;;
-SETUP		P_TIMER		0	0	0	NOP	SETUP
-SETUP		P_TIMER		0	0	1	NOP	SETUP
-SETUP		P_TIMER		0	1	0	NOP	SETUP
-SETUP		P_TIMER		0	1	1	NOP	SETUP
-SETUP		P_TIMER		1	0	0	NOP	SETUP
-SETUP		P_TIMER		1	0	1	NOP	SETUP
-SETUP		P_TIMER		1	1	0	NOP	SETUP
-SETUP		P_TIMER		1	1	1	NOP	SETUP
-;;			
-SETUP		REJ_TIMER 	0	0	0	NOP	SETUP
-SETUP		REJ_TIMER 	0	0	1	NOP	SETUP
-SETUP		REJ_TIMER 	0	1	0	NOP	SETUP
-SETUP		REJ_TIMER 	0	1	1	NOP	SETUP
-SETUP		REJ_TIMER 	1	0	0	NOP	SETUP
-SETUP		REJ_TIMER 	1	0	1	NOP	SETUP
-SETUP		REJ_TIMER 	1	1	0	NOP	SETUP
-SETUP		REJ_TIMER 	1	1	1	NOP	SETUP
-;;			
-SETUP		BUSY_TIMER 	0	0	0	NOP	SETUP
-SETUP		BUSY_TIMER 	0	0	1	NOP	SETUP
-SETUP		BUSY_TIMER 	0	1	0	NOP	SETUP
-SETUP		BUSY_TIMER 	0	1	1	NOP	SETUP
-SETUP		BUSY_TIMER 	1	0	0	NOP	SETUP
-SETUP		BUSY_TIMER 	1	0	1	NOP	SETUP
-SETUP		BUSY_TIMER 	1	1	0	NOP	SETUP
-SETUP		BUSY_TIMER 	1	1	1	NOP	SETUP
-;;
-;;
-;;
-RESET		ACK_TIMER	0	0      	0	RESET7  RESET	
-RESET		ACK_TIMER	0	0      	1	RESET7  RESET
-RESET		ACK_TIMER	0	1      	0	RESET3  NORMAL
-RESET		ACK_TIMER	0	1      	1	RESET3  NORMAL
-RESET		ACK_TIMER	1	0      	0	RESET8  ADM
-RESET		ACK_TIMER	1	0      	1	RESET8  ADM
-RESET		ACK_TIMER	1	1       0	RESET3  NORMAL
-RESET		ACK_TIMER	1	1	1	RESET3  NORMAL
-;;
-RESET		P_TIMER		0	0	0	NOP	RESET
-RESET		P_TIMER		0	0	1	NOP	RESET
-RESET		P_TIMER		0	1	0	NOP	RESET
-RESET		P_TIMER		0	1	1	NOP	RESET
-RESET		P_TIMER		1	0	0	NOP	RESET
-RESET		P_TIMER		1	0	1	NOP	RESET
-RESET		P_TIMER		1	1	0	NOP	RESET
-RESET		P_TIMER		1	1	1	NOP	RESET
-;;			
-RESET		REJ_TIMER 	0	0	0	NOP	RESET
-RESET		REJ_TIMER 	0	0	1	NOP	RESET
-RESET		REJ_TIMER 	0	1	0	NOP	RESET
-RESET		REJ_TIMER 	0	1	1	NOP	RESET
-RESET		REJ_TIMER 	1	0	0	NOP	RESET
-RESET		REJ_TIMER 	1	0	1	NOP	RESET
-RESET		REJ_TIMER 	1	1	0	NOP	RESET
-RESET		REJ_TIMER 	1	1	1	NOP	RESET
-;;			
-RESET		BUSY_TIMER 	0	0	0	NOP	RESET
-RESET		BUSY_TIMER 	0	0	1	NOP	RESET
-RESET		BUSY_TIMER 	0	1	0	NOP	RESET
-RESET		BUSY_TIMER 	0	1	1	NOP	RESET
-RESET		BUSY_TIMER 	1	0	0	NOP	RESET
-RESET		BUSY_TIMER 	1	0	1	NOP	RESET
-RESET		BUSY_TIMER 	1	1	0	NOP	RESET
-RESET		BUSY_TIMER 	1	1	1	NOP	RESET
-;;
-;;
-D_CONN		ACK_TIMER	0	0      	0	D_CONN6 D_CONN	
-D_CONN		ACK_TIMER	0	0      	1	D_CONN6 D_CONN
-D_CONN		ACK_TIMER	0	1      	0	D_CONN6 D_CONN
-D_CONN		ACK_TIMER	0	1      	1	D_CONN6 D_CONN
-D_CONN		ACK_TIMER	1	0      	0	D_CONN7 ADM
-D_CONN		ACK_TIMER	1	0      	1	D_CONN7 ADM
-D_CONN		ACK_TIMER	1	1       0	D_CONN7 ADM
-D_CONN		ACK_TIMER	1	1	1	D_CONN7 ADM
-;;
-D_CONN		P_TIMER		0	0	0	NOP	D_CONN
-D_CONN		P_TIMER		0	0	1	NOP	D_CONN
-D_CONN		P_TIMER		0	1	0	NOP	D_CONN
-D_CONN		P_TIMER		0	1	1	NOP	D_CONN
-D_CONN		P_TIMER		1	0	0	NOP	D_CONN
-D_CONN		P_TIMER		1	0	1	NOP	D_CONN
-D_CONN		P_TIMER		1	1	0	NOP	D_CONN
-D_CONN		P_TIMER		1	1	1	NOP	D_CONN
-;;			
-D_CONN		REJ_TIMER 	0	0	0	NOP	D_CONN
-D_CONN		REJ_TIMER 	0	0	1	NOP	D_CONN
-D_CONN		REJ_TIMER 	0	1	0	NOP	D_CONN
-D_CONN		REJ_TIMER 	0	1	1	NOP	D_CONN
-D_CONN		REJ_TIMER 	1	0	0	NOP	D_CONN
-D_CONN		REJ_TIMER 	1	0	1	NOP	D_CONN
-D_CONN		REJ_TIMER 	1	1	0	NOP	D_CONN
-D_CONN		REJ_TIMER 	1	1	1	NOP	D_CONN
-;;			
-D_CONN		BUSY_TIMER 	0	0	0	NOP	D_CONN
-D_CONN		BUSY_TIMER 	0	0	1	NOP	D_CONN
-D_CONN		BUSY_TIMER 	0	1	0	NOP	D_CONN
-D_CONN		BUSY_TIMER 	0	1	1	NOP	D_CONN
-D_CONN		BUSY_TIMER 	1	0	0	NOP	D_CONN
-D_CONN		BUSY_TIMER 	1	0	1	NOP	D_CONN
-D_CONN		BUSY_TIMER 	1	1	0	NOP	D_CONN
-D_CONN		BUSY_TIMER 	1	1	1	NOP	D_CONN
-;;
-;;
-ERROR		ACK_TIMER	0	0      	0	ERR7    ERROR	
-ERROR		ACK_TIMER	0	0      	1	ERR7    ERROR
-ERROR		ACK_TIMER	0	1      	0	ERR7    ERROR
-ERROR		ACK_TIMER	0	1      	1	ERR7    ERROR
-ERROR		ACK_TIMER	1	0      	0	ERR8    RESET_WAIT
-ERROR		ACK_TIMER	1	0      	1	ERR8    RESET_WAIT
-ERROR		ACK_TIMER	1	1       0       ERR8    RESET_WAIT
-ERROR		ACK_TIMER	1	1	1	ERR8    RESET_WAIT
-;;
-ERROR		P_TIMER		0	0	0	NOP	ERROR
-ERROR		P_TIMER		0	0	1	NOP	ERROR
-ERROR		P_TIMER		0	1	0	NOP	ERROR
-ERROR		P_TIMER		0	1	1	NOP	ERROR
-ERROR		P_TIMER		1	0	0	NOP	ERROR
-ERROR		P_TIMER		1	0	1	NOP	ERROR
-ERROR		P_TIMER		1	1	0	NOP	ERROR
-ERROR		P_TIMER		1	1	1	NOP	ERROR
-;;			
-ERROR		REJ_TIMER 	0	0	0	NOP	ERROR
-ERROR		REJ_TIMER 	0	0	1	NOP	ERROR
-ERROR		REJ_TIMER 	0	1	0	NOP	ERROR
-ERROR		REJ_TIMER 	0	1	1	NOP	ERROR
-ERROR		REJ_TIMER 	1	0	0	NOP	ERROR
-ERROR		REJ_TIMER 	1	0	1	NOP	ERROR
-ERROR		REJ_TIMER 	1	1	0	NOP	ERROR
-ERROR		REJ_TIMER 	1	1	1	NOP	ERROR
-;;			
-ERROR		BUSY_TIMER 	0	0	0	NOP	ERROR
-ERROR		BUSY_TIMER 	0	0	1	NOP	ERROR
-ERROR		BUSY_TIMER 	0	1	0	NOP	ERROR
-ERROR		BUSY_TIMER 	0	1	1	NOP	ERROR
-ERROR		BUSY_TIMER 	1	0	0	NOP	ERROR
-ERROR		BUSY_TIMER 	1	0	1	NOP	ERROR
-ERROR		BUSY_TIMER 	1	1	0	NOP	ERROR
-ERROR		BUSY_TIMER 	1	1	1	NOP	ERROR
-;;
-;;
-NORMAL		ACK_TIMER	0	0      	0	NORMAL20 AWAIT	
-NORMAL		ACK_TIMER	0	0      	1	NOP	NORMAL
-NORMAL		ACK_TIMER	0	1      	0	NORMAL20 AWAIT
-NORMAL		ACK_TIMER	0	1      	1	NOP	NORMAL
-NORMAL		ACK_TIMER	1	0      	0	SH11    RESET_WAIT
-NORMAL		ACK_TIMER	1	0      	1	SH11    RESET_WAIT
-NORMAL		ACK_TIMER	1	1       0	SH11    RESET_WAIT
-NORMAL		ACK_TIMER	1	1	1	SH11    RESET_WAIT
-;;
-NORMAL		P_TIMER		0	0	0	NORMAL19 NORMAL
-NORMAL		P_TIMER		0	0	1	NORMAL19 NORMAL
-NORMAL		P_TIMER		0	1	0	NORMAL19 NORMAL
-NORMAL		P_TIMER		0	1	1	NORMAL19 NORMAL
-NORMAL		P_TIMER		1	0	0	SH11    RESET_WAIT
-NORMAL		P_TIMER		1	0	1	SH11    RESET_WAIT
-NORMAL		P_TIMER		1	1	0	SH11    RESET_WAIT
-NORMAL		P_TIMER		1	1	1	SH11    RESET_WAIT
-;;			
-NORMAL		REJ_TIMER 	0	0	0	NOP	NORMAL
-NORMAL		REJ_TIMER 	0	0	1	NOP	NORMAL
-NORMAL		REJ_TIMER 	0	1	0	NOP	NORMAL
-NORMAL		REJ_TIMER 	0	1	1	NOP	NORMAL
-NORMAL		REJ_TIMER 	1	0	0	SH11    RESET_WAIT
-NORMAL		REJ_TIMER 	1	0	1	SH11    RESET_WAIT
-NORMAL		REJ_TIMER 	1	1	0	SH11    RESET_WAIT
-NORMAL		REJ_TIMER 	1	1	1	SH11    RESET_WAIT
-;;			
-NORMAL		BUSY_TIMER 	0	0	0	NORMAL20 AWAIT
-NORMAL		BUSY_TIMER 	0	0	1	NOP	NORMAL
-NORMAL		BUSY_TIMER 	0	1	0	NORMAL20 AWAIT
-NORMAL		BUSY_TIMER 	0	1	1	NOP	NORMAL
-NORMAL		BUSY_TIMER 	1	0	0	SH11    RESET_WAIT
-NORMAL		BUSY_TIMER 	1	0	1	SH11    RESET_WAIT
-NORMAL		BUSY_TIMER 	1	1	0	SH11    RESET_WAIT
-NORMAL		BUSY_TIMER 	1	1	1	SH11    RESET_WAIT
-;;
-;;
-BUSY		ACK_TIMER	0	0      	0	BUSY24  AWAIT_BUSY
-BUSY		ACK_TIMER	0	0      	1	NOP	BUSY
-BUSY		ACK_TIMER	0	1      	0	BUSY24  AWAIT_BUSY
-BUSY		ACK_TIMER	0	1      	1	NOP	BUSY
-BUSY		ACK_TIMER	1	0      	0	SH11    RESET_WAIT	
-BUSY		ACK_TIMER	1	0      	1	SH11    RESET_WAIT
-BUSY		ACK_TIMER	1	1       0	SH11    RESET_WAIT
-BUSY		ACK_TIMER	1	1	1	SH11    RESET_WAIT
-;;
-BUSY		P_TIMER		0	0	0	BUSY23  BUSY
-BUSY		P_TIMER		0	0	1	BUSY23  BUSY
-BUSY		P_TIMER		0	1	0	BUSY23  BUSY
-BUSY		P_TIMER		0	1	1	BUSY23  BUSY
-BUSY		P_TIMER		1	0	0	SH11    RESET_WAIT
-BUSY		P_TIMER		1	0	1	SH11    RESET_WAIT
-BUSY		P_TIMER		1	1	0	SH11    RESET_WAIT
-BUSY		P_TIMER		1	1	1	SH11    RESET_WAIT
-;;			
-BUSY		REJ_TIMER 	0	0	0	BUSY25  BUSY
-BUSY		REJ_TIMER 	0	0	1	BUSY26  BUSY
-BUSY		REJ_TIMER 	0	1	0	BUSY25  BUSY
-BUSY		REJ_TIMER 	0	1	1	BUSY26  BUSY
-BUSY		REJ_TIMER 	1	0	0	SH11    RESET_WAIT
-BUSY		REJ_TIMER 	1	0	1	SH11    RESET_WAIT
-BUSY		REJ_TIMER 	1	1	0	SH11    RESET_WAIT
-BUSY		REJ_TIMER 	1	1	1	SH11    RESET_WAIT
-;;			
-BUSY		BUSY_TIMER 	0	0	0	NOP	BUSY
-BUSY		BUSY_TIMER 	0	0	1	NOP	BUSY
-BUSY		BUSY_TIMER 	0	1	0	NOP	BUSY
-BUSY		BUSY_TIMER 	0	1	1	NOP	BUSY
-BUSY		BUSY_TIMER 	1	0	0	SH11    RESET_WAIT
-BUSY		BUSY_TIMER 	1	0	1	SH11    RESET_WAIT
-BUSY		BUSY_TIMER 	1	1	0	SH11    RESET_WAIT
-BUSY		BUSY_TIMER 	1	1	1	SH11    RESET_WAIT
-;;
-;;
-REJECT		ACK_TIMER	0	0      	0	NOP	REJECT	
-REJECT		ACK_TIMER	0	0      	1	NOP	REJECT
-REJECT		ACK_TIMER	0	1      	0	NOP	REJECT
-REJECT		ACK_TIMER	0	1      	1	NOP	REJECT
-REJECT		ACK_TIMER	1	0      	0	SH11    RESET_WAIT
-REJECT		ACK_TIMER	1	0      	1	SH11    RESET_WAIT
-REJECT		ACK_TIMER	1	1       0	SH11    RESET_WAIT
-REJECT		ACK_TIMER	1	1	1	SH11    RESET_WAIT
-;;
-REJECT		P_TIMER		0	0	0	NOP	REJECT
-REJECT		P_TIMER		0	0	1	NOP	REJECT
-REJECT		P_TIMER		0	1	0	NOP	REJECT
-REJECT		P_TIMER		0	1	1	NOP	REJECT
-REJECT		P_TIMER		1	0	0	SH11    RESET_WAIT
-REJECT		P_TIMER		1	0	1	SH11    RESET_WAIT
-REJECT		P_TIMER		1	1	0	SH11    RESET_WAIT
-REJECT		P_TIMER		1	1	1	SH11    RESET_WAIT
-;;			
-REJECT		REJ_TIMER 	0	0	0	NOP	REJECT
-REJECT		REJ_TIMER 	0	0	1	NOP	REJECT
-REJECT		REJ_TIMER 	0	1	0	NOP	REJECT
-REJECT		REJ_TIMER 	0	1	1	NOP	REJECT
-REJECT		REJ_TIMER 	1	0	0	SH11    RESET_WAIT
-REJECT		REJ_TIMER 	1	0	1	SH11    RESET_WAIT
-REJECT		REJ_TIMER 	1	1	0	SH11    RESET_WAIT
-REJECT		REJ_TIMER 	1	1	1	SH11    RESET_WAIT
-;;			
-REJECT		BUSY_TIMER 	0	0	0	NOP	REJECT
-REJECT		BUSY_TIMER 	0	0	1	NOP	REJECT
-REJECT		BUSY_TIMER 	0	1	0	NOP	REJECT
-REJECT		BUSY_TIMER 	0	1	1	NOP	REJECT
-REJECT		BUSY_TIMER 	1	0	0	SH11    RESET_WAIT
-REJECT		BUSY_TIMER 	1	0	1	SH11    RESET_WAIT
-REJECT		BUSY_TIMER 	1	1	0	SH11    RESET_WAIT
-REJECT		BUSY_TIMER 	1	1	1	SH11    RESET_WAIT
-;;
-;;
-AWAIT		ACK_TIMER	0	0      	0	NOP	AWAIT	
-AWAIT		ACK_TIMER	0	0      	1	NOP	AWAIT
-AWAIT		ACK_TIMER	0	1      	0	NOP	AWAIT
-AWAIT		ACK_TIMER	0	1      	1	NOP	AWAIT
-AWAIT		ACK_TIMER	1	0      	0	SH11    RESET_WAIT
-AWAIT		ACK_TIMER	1	0      	1	SH11    RESET_WAIT
-AWAIT		ACK_TIMER	1	1       0	SH11    RESET_WAIT
-AWAIT		ACK_TIMER	1	1	1	SH11    RESET_WAIT
-;;
-AWAIT		P_TIMER		0	0	0	NOP	AWAIT
-AWAIT		P_TIMER		0	0	1	NOP	AWAIT
-AWAIT		P_TIMER		0	1	0	NOP	AWAIT
-AWAIT		P_TIMER		0	1	1	NOP	AWAIT
-AWAIT		P_TIMER		1	0	0	SH11    RESET_WAIT
-AWAIT		P_TIMER		1	0	1	SH11    RESET_WAIT
-AWAIT		P_TIMER		1	1	0	SH11    RESET_WAIT
-AWAIT		P_TIMER		1	1	1	SH11    RESET_WAIT
-;;			
-AWAIT		REJ_TIMER 	0	0	0	NOP	AWAIT
-AWAIT		REJ_TIMER 	0	0	1	NOP	AWAIT
-AWAIT		REJ_TIMER 	0	1	0	NOP	AWAIT
-AWAIT		REJ_TIMER 	0	1	1	NOP	AWAIT
-AWAIT		REJ_TIMER 	1	0	0	SH11    RESET_WAIT
-AWAIT		REJ_TIMER 	1	0	1	SH11    RESET_WAIT
-AWAIT		REJ_TIMER 	1	1	0	SH11    RESET_WAIT
-AWAIT		REJ_TIMER 	1	1	1	SH11    RESET_WAIT
-;;			
-AWAIT		BUSY_TIMER 	0	0	0	NOP	AWAIT
-AWAIT		BUSY_TIMER 	0	0	1	NOP	AWAIT
-AWAIT		BUSY_TIMER 	0	1	0	NOP	AWAIT
-AWAIT		BUSY_TIMER 	0	1	1	NOP	AWAIT
-AWAIT		BUSY_TIMER 	1	0	0	SH11    RESET_WAIT
-AWAIT		BUSY_TIMER 	1	0	1	SH11    RESET_WAIT
-AWAIT		BUSY_TIMER 	1	1	0	SH11    RESET_WAIT
-AWAIT		BUSY_TIMER 	1	1	1	SH11    RESET_WAIT
-;;
-;;
-AWAIT_BUSY	ACK_TIMER	0	0      	0	NOP	AWAIT_BUSY	
-AWAIT_BUSY	ACK_TIMER	0	0      	1	NOP	AWAIT_BUSY
-AWAIT_BUSY	ACK_TIMER	0	1      	0	NOP	AWAIT_BUSY
-AWAIT_BUSY	ACK_TIMER	0	1      	1	NOP	AWAIT_BUSY
-AWAIT_BUSY	ACK_TIMER	1	0      	0	SH11    RESET_WAIT
-AWAIT_BUSY	ACK_TIMER	1	0      	1	SH11    RESET_WAIT
-AWAIT_BUSY	ACK_TIMER	1	1       0	SH11    RESET_WAIT
-AWAIT_BUSY	ACK_TIMER	1	1	1	SH11    RESET_WAIT
-;;
-AWAIT_BUSY	P_TIMER		0	0	0	NOP	AWAIT_BUSY
-AWAIT_BUSY	P_TIMER		0	0	1	NOP	AWAIT_BUSY
-AWAIT_BUSY	P_TIMER		0	1	0	NOP	AWAIT_BUSY
-AWAIT_BUSY	P_TIMER		0	1	1	NOP	AWAIT_BUSY
-AWAIT_BUSY	P_TIMER		1	0	0	SH11    RESET_WAIT
-AWAIT_BUSY	P_TIMER		1	0	1	SH11    RESET_WAIT
-AWAIT_BUSY	P_TIMER		1	1	0	SH11    RESET_WAIT
-AWAIT_BUSY	P_TIMER		1	1	1	SH11    RESET_WAIT
-;;			
-AWAIT_BUSY	REJ_TIMER 	0	0	0	NOP	AWAIT_BUSY
-AWAIT_BUSY	REJ_TIMER 	0	0	1	NOP	AWAIT_BUSY
-AWAIT_BUSY	REJ_TIMER 	0	1	0	NOP	AWAIT_BUSY
-AWAIT_BUSY	REJ_TIMER 	0	1	1	NOP	AWAIT_BUSY
-AWAIT_BUSY	REJ_TIMER 	1	0	0	SH11    RESET_WAIT
-AWAIT_BUSY	REJ_TIMER 	1	0	1	SH11    RESET_WAIT
-AWAIT_BUSY	REJ_TIMER 	1	1	0	SH11    RESET_WAIT
-AWAIT_BUSY	REJ_TIMER 	1	1	1	SH11    RESET_WAIT
-;;			
-AWAIT_BUSY	BUSY_TIMER 	0	0	0	NOP	AWAIT_BUSY
-AWAIT_BUSY	BUSY_TIMER 	0	0	1	NOP	AWAIT_BUSY
-AWAIT_BUSY	BUSY_TIMER 	0	1	0	NOP	AWAIT_BUSY
-AWAIT_BUSY	BUSY_TIMER 	0	1	1	NOP	AWAIT_BUSY
-AWAIT_BUSY	BUSY_TIMER 	1	0	0	SH11    RESET_WAIT
-AWAIT_BUSY	BUSY_TIMER 	1	0	1	SH11    RESET_WAIT
-AWAIT_BUSY	BUSY_TIMER 	1	1	0	SH11    RESET_WAIT
-AWAIT_BUSY	BUSY_TIMER 	1	1	1	SH11    RESET_WAIT
-;;
-;;
-AWAIT_REJECT	ACK_TIMER	0	0      	0	NOP	AWAIT_REJECT	
-AWAIT_REJECT	ACK_TIMER	0	0      	1	NOP	AWAIT_REJECT
-AWAIT_REJECT	ACK_TIMER	0	1      	0	NOP	AWAIT_REJECT
-AWAIT_REJECT	ACK_TIMER	0	1      	1	NOP	AWAIT_REJECT
-AWAIT_REJECT	ACK_TIMER	1	0      	0	SH11    RESET_WAIT
-AWAIT_REJECT	ACK_TIMER	1	0      	1	SH11    RESET_WAIT
-AWAIT_REJECT	ACK_TIMER	1	1       0	SH11    RESET_WAIT
-AWAIT_REJECT	ACK_TIMER	1	1	1	SH11    RESET_WAIT
-;;							
-AWAIT_REJECT	P_TIMER		0	0	0	NOP	AWAIT_REJECT
-AWAIT_REJECT	P_TIMER		0	0	1	NOP	AWAIT_REJECT
-AWAIT_REJECT	P_TIMER		0	1	0	NOP	AWAIT_REJECT
-AWAIT_REJECT	P_TIMER		0	1	1	NOP	AWAIT_REJECT
-AWAIT_REJECT	P_TIMER		1	0	0	SH11    RESET_WAIT
-AWAIT_REJECT	P_TIMER		1	0	1	SH11    RESET_WAIT
-AWAIT_REJECT	P_TIMER		1	1	0	SH11    RESET_WAIT
-AWAIT_REJECT	P_TIMER		1	1	1	SH11    RESET_WAIT
-;;			
-AWAIT_REJECT	REJ_TIMER 	0	0	0	NOP	AWAIT_REJECT
-AWAIT_REJECT	REJ_TIMER 	0	0	1	NOP	AWAIT_REJECT
-AWAIT_REJECT	REJ_TIMER 	0	1	0	NOP	AWAIT_REJECT
-AWAIT_REJECT	REJ_TIMER 	0	1	1	NOP	AWAIT_REJECT
-AWAIT_REJECT	REJ_TIMER 	1	0	0	SH11    RESET_WAIT
-AWAIT_REJECT	REJ_TIMER 	1	0	1	SH11    RESET_WAIT
-AWAIT_REJECT	REJ_TIMER 	1	1	0	SH11    RESET_WAIT
-AWAIT_REJECT	REJ_TIMER 	1	1	1	SH11    RESET_WAIT
-;;			
-AWAIT_REJECT	BUSY_TIMER 	0	0	0	NOP	AWAIT_REJECT
-AWAIT_REJECT	BUSY_TIMER 	0	0	1	NOP	AWAIT_REJECT
-AWAIT_REJECT	BUSY_TIMER 	0	1	0	NOP	AWAIT_REJECT
-AWAIT_REJECT	BUSY_TIMER 	0	1	1	NOP	AWAIT_REJECT
-AWAIT_REJECT	BUSY_TIMER 	1	0	0	SH11    RESET_WAIT
-AWAIT_REJECT	BUSY_TIMER 	1	0	1	SH11    RESET_WAIT
-AWAIT_REJECT	BUSY_TIMER 	1	1	0	SH11    RESET_WAIT
-AWAIT_REJECT	BUSY_TIMER 	1	1	1	SH11    RESET_WAIT
-;;
diff -Nru a/net/8021q/vlan.c b/net/8021q/vlan.c
--- a/net/8021q/vlan.c	Sat Aug 10 18:42:23 2002
+++ b/net/8021q/vlan.c	Sat Aug 10 18:42:23 2002
@@ -52,7 +52,7 @@
 static int vlan_device_event(struct notifier_block *, unsigned long, void *);
 
 struct notifier_block vlan_notifier_block = {
-	notifier_call: vlan_device_event,
+	.notifier_call = vlan_device_event,
 };
 
 /* These may be changed at run-time through IOCTLs */
@@ -64,11 +64,11 @@
 unsigned short vlan_default_dev_flags = 1;
 
 static struct packet_type vlan_packet_type = {
-	type: __constant_htons(ETH_P_8021Q),
-	dev:  NULL,
-	func: vlan_skb_recv, /* VLAN receive method */
-	data: (void *)(-1),  /* Set here '(void *)1' when this code can SHARE SKBs */
-	next: NULL
+	.type = __constant_htons(ETH_P_8021Q),
+	.dev =NULL,
+	.func = vlan_skb_recv, /* VLAN receive method */
+	.data = (void *)(-1),  /* Set here '(void *)1' when this code can SHARE SKBs */
+	.next = NULL
 };
 
 /* End of global variables definitions. */
@@ -91,9 +91,9 @@
 	/* proc file system initialization */
 	err = vlan_proc_init();
 	if (err < 0) {
-		printk(KERN_ERR __FUNCTION__
-		       "%s: can't create entry in proc filesystem!\n",
-		       VLAN_NAME);
+		printk(KERN_ERR 
+		       "%s %s: can't create entry in proc filesystem!\n",
+		       __FUNCTION__, VLAN_NAME);
 		return 1;
 	}
 
@@ -203,7 +203,7 @@
 	int i, ret;
 
 #ifdef VLAN_DEBUG
-	printk(VLAN_DBG __FUNCTION__ ": VID: %i\n", vlan_id);
+	printk(VLAN_DBG "%s: VID: %i\n", __FUNCTION__, vlan_id);
 #endif
 
 	/* sanity check */
@@ -289,16 +289,16 @@
 			if (ret == 1)
 				ret = 0;
 		} else {
-			printk(VLAN_ERR __FUNCTION__
-			       ": ERROR:	Tried to remove a non-vlan device "
+			printk(VLAN_ERR 
+			       "%s: ERROR:	Tried to remove a non-vlan device "
 			       "with VLAN code, name: %s  priv_flags: %hX\n",
-			       dev->name, dev->priv_flags);
+			       __FUNCTION__, dev->name, dev->priv_flags);
 			dev_put(dev);
 			ret = -EPERM;
 		}
 	} else {
 #ifdef VLAN_DEBUG
-		printk(VLAN_DBG __FUNCTION__ ": WARNING: Could not find dev.\n");
+		printk(VLAN_DBG "%s: WARNING: Could not find dev.\n", __FUNCTION__);
 #endif
 		ret = -EINVAL;
 	}
@@ -320,8 +320,8 @@
 	int r;
 
 #ifdef VLAN_DEBUG
-	printk(VLAN_DBG __FUNCTION__ ": if_name -:%s:-	vid: %i\n",
-	       eth_IF_name, VLAN_ID);
+	printk(VLAN_DBG "%s: if_name -:%s:-	vid: %i\n",
+		__FUNCTION__, eth_IF_name, VLAN_ID);
 #endif
 
 	if (VLAN_ID >= VLAN_VID_MASK)
@@ -333,24 +333,24 @@
 		goto out_ret_null;
 
 	if (real_dev->features & NETIF_F_VLAN_CHALLENGED) {
-		printk(VLAN_DBG __FUNCTION__ ": VLANs not supported on %s.\n",
-		       real_dev->name);
+		printk(VLAN_DBG "%s: VLANs not supported on %s.\n",
+			__FUNCTION__, real_dev->name);
 		goto out_put_dev;
 	}
 
 	if ((real_dev->features & NETIF_F_HW_VLAN_RX) &&
 	    (real_dev->vlan_rx_register == NULL ||
 	     real_dev->vlan_rx_kill_vid == NULL)) {
-		printk(VLAN_DBG __FUNCTION__ ": Device %s has buggy VLAN hw accel.\n",
-		       real_dev->name);
+		printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
+			__FUNCTION__, real_dev->name);
 		goto out_put_dev;
 	}
 
 	if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) &&
 	    (real_dev->vlan_rx_add_vid == NULL ||
 	     real_dev->vlan_rx_kill_vid == NULL)) {
-		printk(VLAN_DBG __FUNCTION__ ": Device %s has buggy VLAN hw accel.\n",
-		       real_dev->name);
+		printk(VLAN_DBG "%s: Device %s has buggy VLAN hw accel.\n",
+			__FUNCTION__, real_dev->name);
 		goto out_put_dev;
 	}
 
@@ -371,7 +371,7 @@
 
 	if (r) {
 		/* was already registered. */
-		printk(VLAN_DBG __FUNCTION__ ": ALREADY had VLAN registered\n");
+		printk(VLAN_DBG "%s: ALREADY had VLAN registered\n", __FUNCTION__);
 		goto out_unlock;
 	}
 
@@ -665,7 +665,7 @@
 	args.u.device2[23] = 0;
 
 #ifdef VLAN_DEBUG
-	printk(VLAN_DBG __FUNCTION__ ": args.cmd: %x\n", args.cmd);
+	printk(VLAN_DBG "%s: args.cmd: %x\n", __FUNCTION__, args.cmd);
 #endif
 
 	switch (args.cmd) {
@@ -728,8 +728,8 @@
 
 	default:
 		/* pass on to underlying device instead?? */
-		printk(VLAN_DBG __FUNCTION__ ": Unknown VLAN CMD: %x \n",
-		       args.cmd);
+		printk(VLAN_DBG "%s: Unknown VLAN CMD: %x \n",
+			__FUNCTION__, args.cmd);
 		return -EINVAL;
 	};
 
diff -Nru a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
--- a/net/8021q/vlan_dev.c	Sat Aug 10 18:42:23 2002
+++ b/net/8021q/vlan_dev.c	Sat Aug 10 18:42:23 2002
@@ -125,8 +125,8 @@
 	vid = (vlan_TCI & VLAN_VID_MASK);
 
 #ifdef VLAN_DEBUG
-	printk(VLAN_DBG __FUNCTION__ ": skb: %p vlan_id: %hx\n",
-	       skb, vid);
+	printk(VLAN_DBG "%s: skb: %p vlan_id: %hx\n",
+		__FUNCTION__, skb, vid);
 #endif
 
 	/* Ok, we will find the correct VLAN device, strip the header,
@@ -146,8 +146,8 @@
 		spin_unlock_bh(&vlan_group_lock);
 
 #ifdef VLAN_DEBUG
-		printk(VLAN_DBG __FUNCTION__ ": ERROR:	No net_device for VID: %i on dev: %s [%i]\n",
-		       (unsigned int)(vid), dev->name, dev->ifindex);
+		printk(VLAN_DBG "%s: ERROR: No net_device for VID: %i on dev: %s [%i]\n",
+			__FUNCTION__, (unsigned int)(vid), dev->name, dev->ifindex);
 #endif
 		kfree_skb(skb);
 		return -1;
@@ -170,8 +170,10 @@
 		spin_unlock_bh(&vlan_group_lock);
 
 #ifdef VLAN_DEBUG
-		printk(VLAN_DBG __FUNCTION__ ": dropping skb: %p because came in on wrong device, dev: %s  real_dev: %s, skb_dev: %s\n",
-		       skb, dev->name, VLAN_DEV_INFO(skb->dev)->real_dev->name, skb->dev->name);
+		printk(VLAN_DBG "%s: dropping skb: %p because came in on wrong device, dev: %s  real_dev: %s, skb_dev: %s\n",
+			__FUNCTION__ skb, dev->name, 
+			VLAN_DEV_INFO(skb->dev)->real_dev->name, 
+			skb->dev->name);
 #endif
 		kfree_skb(skb);
 		stats->rx_errors++;
@@ -184,8 +186,9 @@
 	skb->priority = vlan_get_ingress_priority(skb->dev, ntohs(vhdr->h_vlan_TCI));
 
 #ifdef VLAN_DEBUG
-	printk(VLAN_DBG __FUNCTION__ ": priority: %lu  for TCI: %hu (hbo)\n",
-	       (unsigned long)(skb->priority), ntohs(vhdr->h_vlan_TCI));
+	printk(VLAN_DBG "%s: priority: %lu  for TCI: %hu (hbo)\n",
+		__FUNCTION__, (unsigned long)(skb->priority), 
+		ntohs(vhdr->h_vlan_TCI));
 #endif
 
 	/* The ethernet driver already did the pkt_type calculations
@@ -331,8 +334,8 @@
 	struct net_device *vdev = dev; /* save this for the bottom of the method */
 
 #ifdef VLAN_DEBUG
-	printk(VLAN_DBG __FUNCTION__ ": skb: %p type: %hx len: %x vlan_id: %hx, daddr: %p\n",
-	       skb, type, len, VLAN_DEV_INFO(dev)->vlan_id, daddr);
+	printk(VLAN_DBG "%s: skb: %p type: %hx len: %x vlan_id: %hx, daddr: %p\n",
+		__FUNCTION__, skb, type, len, VLAN_DEV_INFO(dev)->vlan_id, daddr);
 #endif
 
 	/* build vlan header only if re_order_header flag is NOT set.  This
@@ -402,7 +405,7 @@
 		}
 		VLAN_DEV_INFO(vdev)->cnt_inc_headroom_on_tx++;
 #ifdef VLAN_DEBUG
-		printk(VLAN_DBG __FUNCTION__ ": %s: had to grow skb.\n", vdev->name);
+		printk(VLAN_DBG "%s: %s: had to grow skb.\n", __FUNCTION__, vdev->name);
 #endif
 	}
 
@@ -445,8 +448,8 @@
 		VLAN_DEV_INFO(dev)->cnt_encap_on_xmit++;
 
 #ifdef VLAN_DEBUG
-		printk(VLAN_DBG __FUNCTION__ ": proto to encap: 0x%hx (hbo)\n",
-		       htons(veth->h_vlan_proto));
+		printk(VLAN_DBG "%s: proto to encap: 0x%hx (hbo)\n",
+			__FUNCTION__, htons(veth->h_vlan_proto));
 #endif
 
 		if (skb_headroom(skb) < VLAN_HLEN) {
@@ -455,14 +458,14 @@
 			kfree_skb(sk_tmp);
 			if (skb == NULL) {
 				stats->tx_dropped++;
-				return -ENOMEM;
+				return 0;
 			}
 			VLAN_DEV_INFO(dev)->cnt_inc_headroom_on_tx++;
 		} else {
 			if (!(skb = skb_unshare(skb, GFP_ATOMIC))) {
 				printk(KERN_ERR "vlan: failed to unshare skbuff\n");
 				stats->tx_dropped++;
-				return -ENOMEM;
+				return 0;
 			}
 		}
 		veth = (struct vlan_ethhdr *)skb_push(skb, VLAN_HLEN);
@@ -489,8 +492,8 @@
 	skb->dev = VLAN_DEV_INFO(dev)->real_dev;
 
 #ifdef VLAN_DEBUG
-	printk(VLAN_DBG __FUNCTION__ ": about to send skb: %p to dev: %s\n",
-	       skb, skb->dev->name);
+	printk(VLAN_DBG "%s: about to send skb: %p to dev: %s\n",
+		__FUNCTION__, skb, skb->dev->name);
 	printk(VLAN_DBG "  %2hx.%2hx.%2hx.%2xh.%2hx.%2hx %2hx.%2hx.%2hx.%2hx.%2hx.%2hx %4hx %4hx %4hx\n",
 	       veth->h_dest[0], veth->h_dest[1], veth->h_dest[2], veth->h_dest[3], veth->h_dest[4], veth->h_dest[5],
 	       veth->h_source[0], veth->h_source[1], veth->h_source[2], veth->h_source[3], veth->h_source[4], veth->h_source[5],
@@ -609,19 +612,20 @@
 				dev_put(dev);
 				return 0;
 			} else {
-				printk(KERN_ERR __FUNCTION__ ": flag %i is not valid.\n",
-				       (int)(flag));
+				printk(KERN_ERR  "%s: flag %i is not valid.\n",
+					__FUNCTION__, (int)(flag));
 				dev_put(dev);
 				return -EINVAL;
 			}
 		} else {
-			printk(KERN_ERR __FUNCTION__
-			       ": %s is not a vlan device, priv_flags: %hX.\n",
-			       dev->name, dev->priv_flags);
+			printk(KERN_ERR 
+			       "%s: %s is not a vlan device, priv_flags: %hX.\n",
+			       __FUNCTION__, dev->name, dev->priv_flags);
 			dev_put(dev);
 		}
 	} else {
-		printk(KERN_ERR __FUNCTION__ ": Could not find device: %s\n", dev_name);
+		printk(KERN_ERR  "%s: Could not find device: %s\n", 
+			__FUNCTION__, dev_name);
 	}
 
 	return -EINVAL;
diff -Nru a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
--- a/net/8021q/vlanproc.c	Sat Aug 10 18:42:22 2002
+++ b/net/8021q/vlanproc.c	Sat Aug 10 18:42:22 2002
@@ -75,8 +75,8 @@
  */
 
 static struct file_operations vlan_fops = {
-	read:	vlan_proc_read,
-	ioctl: NULL, /* vlan_proc_ioctl */
+	.read =	vlan_proc_read,
+	.ioctl = NULL, /* vlan_proc_ioctl */
 };
 
 /*
@@ -84,8 +84,8 @@
  */
 
 static struct file_operations vlandev_fops = {
-	read:	vlan_proc_read,
-	ioctl:	NULL, /* vlan_proc_ioctl */
+	.read =	vlan_proc_read,
+	.ioctl =NULL, /* vlan_proc_ioctl */
 };
 
 /*
@@ -187,14 +187,14 @@
 int vlan_proc_rem_dev(struct net_device *vlandev)
 {
 	if (!vlandev) {
-		printk(VLAN_ERR __FUNCTION__ ": invalid argument: %p\n",
-		       vlandev);
+		printk(VLAN_ERR "%s: invalid argument: %p\n",
+			__FUNCTION__, vlandev);
 		return -EINVAL;
 	}
 
 	if (!(vlandev->priv_flags & IFF_802_1Q_VLAN)) {
-		printk(VLAN_DBG __FUNCTION__ ": invalid argument, device: %s is not a VLAN device, priv_flags: 0x%4hX.\n",
-		       vlandev->name, vlandev->priv_flags);
+		printk(VLAN_DBG "%s: invalid argument, device: %s is not a VLAN device, priv_flags: 0x%4hX.\n",
+			__FUNCTION__, vlandev->name, vlandev->priv_flags);
 		return -EINVAL;
 	}
 
diff -Nru a/net/Config.help b/net/Config.help
--- a/net/Config.help	Sat Aug 10 18:42:21 2002
+++ b/net/Config.help	Sat Aug 10 18:42:21 2002
@@ -266,8 +266,13 @@
   module will be called lapb.o.  If unsure, say N.
 
 CONFIG_LLC
-  This is a Logical Link Layer protocol used for X.25 connections over
-  Ethernet, using ordinary Ethernet cards.
+  This is a Logical Link Layer protocol used for Appletalk, IPX and in
+  the future by NetBEUI and by the linux-sna project. It originally
+  came from Procom Inc. that released the code for 2.0.36 and was
+  ported to 2.{4,5}. Select this if you want to have support for
+  those protocols or if you want to have the sockets interface for
+  LLC.
+  
 
 CONFIG_NET_DIVERT
   The Frame Diverter allows you to divert packets from the
diff -Nru a/net/appletalk/aarp.c b/net/appletalk/aarp.c
--- a/net/appletalk/aarp.c	Sat Aug 10 18:42:22 2002
+++ b/net/appletalk/aarp.c	Sat Aug 10 18:42:22 2002
@@ -30,7 +30,6 @@
  */
 
 #include <linux/config.h>
-#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) 
 #include <asm/uaccess.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -66,17 +65,29 @@
 int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME;
 
 /* Lists of aarp entries */
+/**
+ *	struct aarp_entry - AARP entry
+ *	@last_sent - Last time we xmitted the aarp request 
+ *	@packet_queue - Queue of frames wait for resolution
+ *	@status - Used for proxy AARP
+ *	expires_at - Entry expiry time
+ *	target_addr - DDP Address
+ *	dev - Device to use
+ *	hwaddr - Physical i/f address of target/router
+ *	xmit_count - When this hits 10 we give up
+ *	next - Next entry in chain
+ */
 struct aarp_entry {
 	/* These first two are only used for unresolved entries */
-	unsigned long last_sent;		/* Last time we xmitted the aarp request */
-	struct sk_buff_head packet_queue;	/* Queue of frames wait for resolution */
-	int status;				/* Used for proxy AARP */
-	unsigned long expires_at;		/* Entry expiry time */
-	struct at_addr target_addr;		/* DDP Address */
-	struct net_device *dev;			/* Device to use */
-	char hwaddr[6];				/* Physical i/f address of target/router */
-	unsigned short xmit_count;		/* When this hits 10 we give up */
-	struct aarp_entry *next;		/* Next entry in chain */
+	unsigned long		last_sent;
+	struct sk_buff_head	packet_queue;
+	int			status;
+	unsigned long		expires_at;
+	struct atalk_addr	target_addr;
+	struct net_device	*dev;
+	char			hwaddr[6];
+	unsigned short		xmit_count;
+	struct aarp_entry	*next;
 };
 
 /* Hashed list of resolved, unresolved and proxy entries */
@@ -110,14 +121,13 @@
  
 static void __aarp_send_query(struct aarp_entry *a)
 {
-	static char aarp_eth_multicast[ETH_ALEN] =
-		{ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
+	static unsigned char aarp_eth_multicast[ETH_ALEN] =
+					{ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
 	struct net_device *dev = a->dev;
-	int len = dev->hard_header_len + sizeof(struct elapaarp) +
-		aarp_dl->header_length;
-	struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
-	struct at_addr *sat = atalk_find_dev_addr(dev);
 	struct elapaarp *eah;
+	int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length;
+	struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
+	struct atalk_addr *sat = atalk_find_dev_addr(dev);
 	
 	if (!skb)
 		return;
@@ -129,30 +139,29 @@
 	
 	/* Set up the buffer */		
 	skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length);
-	eah		=	(struct elapaarp *)skb_put(skb,
-						sizeof(struct elapaarp));
-	skb->protocol   =       htons(ETH_P_ATALK);
-	skb->nh.raw     =       skb->h.raw = (void *) eah;
-	skb->dev	=	dev;
+	skb->nh.raw      = skb->h.raw = skb_put(skb, sizeof(*eah));
+	skb->protocol    = htons(ETH_P_ATALK);
+	skb->dev	 = dev;
+	eah		 = aarp_hdr(skb);
 	
 	/* Set up the ARP */
-	eah->hw_type	=	htons(AARP_HW_TYPE_ETHERNET);
-	eah->pa_type	=	htons(ETH_P_ATALK);
-	eah->hw_len	=	ETH_ALEN;	
-	eah->pa_len	=	AARP_PA_ALEN;
-	eah->function	=	htons(AARP_REQUEST);
+	eah->hw_type	 = htons(AARP_HW_TYPE_ETHERNET);
+	eah->pa_type	 = htons(ETH_P_ATALK);
+	eah->hw_len	 = ETH_ALEN;	
+	eah->pa_len	 = AARP_PA_ALEN;
+	eah->function	 = htons(AARP_REQUEST);
 	
 	memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN);
 	
-	eah->pa_src_zero=	0;
-	eah->pa_src_net	=	sat->s_net;
-	eah->pa_src_node=	sat->s_node;
+	eah->pa_src_zero = 0;
+	eah->pa_src_net	 = sat->s_net;
+	eah->pa_src_node = sat->s_node;
 	
 	memset(eah->hw_dst, '\0', ETH_ALEN);
 	
-	eah->pa_dst_zero=	0;
-	eah->pa_dst_net	=	a->target_addr.s_net;
-	eah->pa_dst_node=	a->target_addr.s_node;
+	eah->pa_dst_zero = 0;
+	eah->pa_dst_net	 = a->target_addr.s_net;
+	eah->pa_dst_node = a->target_addr.s_node;
 	
 	/* Add ELAP headers and set target to the AARP multicast */
 	aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast);	
@@ -165,46 +174,44 @@
 
 /* This runs under aarp_lock and in softint context, so only atomic memory
  * allocations can be used. */
-static void aarp_send_reply(struct net_device *dev, struct at_addr *us,
-			    struct at_addr *them, unsigned char *sha)
+static void aarp_send_reply(struct net_device *dev, struct atalk_addr *us,
+			    struct atalk_addr *them, unsigned char *sha)
 {
-	int len = dev->hard_header_len + sizeof(struct elapaarp) +
-			aarp_dl->header_length;
-	struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
 	struct elapaarp *eah;
+	int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length;
+	struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
 	
 	if (!skb)
 		return;
 	
 	/* Set up the buffer */
 	skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length);
-	eah		=	(struct elapaarp *)skb_put(skb,
-					sizeof(struct elapaarp));	 
-	skb->protocol   =       htons(ETH_P_ATALK);
-	skb->nh.raw     =       skb->h.raw = (void *) eah;
-	skb->dev	=	dev;
+	skb->nh.raw      = skb->h.raw = skb_put(skb, sizeof(*eah));	 
+	skb->protocol    = htons(ETH_P_ATALK);
+	skb->dev	 = dev;
+	eah		 = aarp_hdr(skb);
 	
 	/* Set up the ARP */
-	eah->hw_type	=	htons(AARP_HW_TYPE_ETHERNET);
-	eah->pa_type	=	htons(ETH_P_ATALK);
-	eah->hw_len	=	ETH_ALEN;	
-	eah->pa_len	=	AARP_PA_ALEN;
-	eah->function	=	htons(AARP_REPLY);
+	eah->hw_type	 = htons(AARP_HW_TYPE_ETHERNET);
+	eah->pa_type	 = htons(ETH_P_ATALK);
+	eah->hw_len	 = ETH_ALEN;	
+	eah->pa_len	 = AARP_PA_ALEN;
+	eah->function	 = htons(AARP_REPLY);
 	
 	memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN);
 	
-	eah->pa_src_zero=	0;
-	eah->pa_src_net	=	us->s_net;
-	eah->pa_src_node=	us->s_node;
+	eah->pa_src_zero = 0;
+	eah->pa_src_net	 = us->s_net;
+	eah->pa_src_node = us->s_node;
 	
 	if (!sha)
 		memset(eah->hw_dst, '\0', ETH_ALEN);
 	else
 		memcpy(eah->hw_dst, sha, ETH_ALEN);
 	
-	eah->pa_dst_zero=	0;
-	eah->pa_dst_net	=	them->s_net;
-	eah->pa_dst_node=	them->s_node;
+	eah->pa_dst_zero = 0;
+	eah->pa_dst_net	 = them->s_net;
+	eah->pa_dst_node = them->s_node;
 	
 	/* Add ELAP headers and set target to the AARP multicast */
 	aarp_dl->datalink_header(aarp_dl, skb, sha);	
@@ -217,44 +224,42 @@
  *	aarp_proxy_probe_network.
  */
 
-void aarp_send_probe(struct net_device *dev, struct at_addr *us)
+void aarp_send_probe(struct net_device *dev, struct atalk_addr *us)
 {
-	int len = dev->hard_header_len + sizeof(struct elapaarp) +
-			aarp_dl->header_length;
-	struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
-	static char aarp_eth_multicast[ETH_ALEN] =
-		{ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
 	struct elapaarp *eah;
+	int len = dev->hard_header_len + sizeof(*eah) + aarp_dl->header_length;
+	struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);
+	static unsigned char aarp_eth_multicast[ETH_ALEN] =
+					{ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
 
 	if (!skb)
 		return;
 
 	/* Set up the buffer */
 	skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length);
-	eah		=	(struct elapaarp *)skb_put(skb,
-					sizeof(struct elapaarp));
-	skb->protocol   =       htons(ETH_P_ATALK);
-	skb->nh.raw     =       skb->h.raw = (void *) eah;
-	skb->dev	=	dev;
+	skb->nh.raw      = skb->h.raw = skb_put(skb, sizeof(*eah));
+	skb->protocol    = htons(ETH_P_ATALK);
+	skb->dev	 = dev;
+	eah		 = aarp_hdr(skb);
 
 	/* Set up the ARP */
-	eah->hw_type	=	htons(AARP_HW_TYPE_ETHERNET);
-	eah->pa_type	=	htons(ETH_P_ATALK);
-	eah->hw_len	=	ETH_ALEN;
-	eah->pa_len	=	AARP_PA_ALEN;
-	eah->function	=	htons(AARP_PROBE);
+	eah->hw_type	 = htons(AARP_HW_TYPE_ETHERNET);
+	eah->pa_type	 = htons(ETH_P_ATALK);
+	eah->hw_len	 = ETH_ALEN;
+	eah->pa_len	 = AARP_PA_ALEN;
+	eah->function	 = htons(AARP_PROBE);
 
 	memcpy(eah->hw_src, dev->dev_addr, ETH_ALEN);
 
-	eah->pa_src_zero=	0;
-	eah->pa_src_net	=	us->s_net;
-	eah->pa_src_node=	us->s_node;
+	eah->pa_src_zero = 0;
+	eah->pa_src_net	 = us->s_net;
+	eah->pa_src_node = us->s_node;
 
 	memset(eah->hw_dst, '\0', ETH_ALEN);
 
-	eah->pa_dst_zero=	0;
-	eah->pa_dst_net	=	us->s_net;
-	eah->pa_dst_node=	us->s_node;
+	eah->pa_dst_zero = 0;
+	eah->pa_dst_net	 = us->s_net;
+	eah->pa_dst_node = us->s_node;
 
 	/* Add ELAP headers and set target to the AARP multicast */
 	aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast);
@@ -371,7 +376,7 @@
  
 static struct aarp_entry *aarp_alloc(void)
 {
-	struct aarp_entry *a = kmalloc(sizeof(struct aarp_entry), GFP_ATOMIC);
+	struct aarp_entry *a = kmalloc(sizeof(*a), GFP_ATOMIC);
 
 	if (a)
 		skb_queue_head_init(&a->packet_queue);
@@ -386,7 +391,7 @@
  */
 static struct aarp_entry *__aarp_find_entry(struct aarp_entry *list,
 					    struct net_device *dev,
-					    struct at_addr *sat)
+					    struct atalk_addr *sat)
 {
 	while (list) {
 		if (list->target_addr.s_net == sat->s_net &&
@@ -400,7 +405,7 @@
 }
 
 /* Called from the DDP code, and thus must be exported. */
-void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa)
+void aarp_proxy_remove(struct net_device *dev, struct atalk_addr *sa)
 {
 	int hash = sa->s_node % (AARP_HASH_SIZE - 1);
 	struct aarp_entry *a;
@@ -415,8 +420,8 @@
 }
 
 /* This must run under aarp_lock. */
-static struct at_addr *__aarp_proxy_find(struct net_device *dev,
-					 struct at_addr *sa)
+static struct atalk_addr *__aarp_proxy_find(struct net_device *dev,
+					    struct atalk_addr *sa)
 {
 	int hash = sa->s_node % (AARP_HASH_SIZE - 1);
 	struct aarp_entry *a = __aarp_find_entry(proxies[hash], dev, sa);
@@ -430,22 +435,22 @@
  */
 void aarp_send_probe_phase1(struct atalk_iface *iface)
 {
-    struct ifreq atreq;
-    struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr;
+	struct ifreq atreq;
+	struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr;
+
+	sa->sat_addr.s_node = iface->address.s_node;
+	sa->sat_addr.s_net = ntohs(iface->address.s_net);
 
-    sa->sat_addr.s_node = iface->address.s_node;
-    sa->sat_addr.s_net = ntohs(iface->address.s_net);
+	/* We pass the Net:Node to the drivers/cards by a Device ioctl. */
+	if (!(iface->dev->do_ioctl(iface->dev, &atreq, SIOCSIFADDR))) {
+		(void)iface->dev->do_ioctl(iface->dev, &atreq, SIOCGIFADDR);
+		if (iface->address.s_net != htons(sa->sat_addr.s_net) ||
+		    iface->address.s_node != sa->sat_addr.s_node)
+			iface->status |= ATIF_PROBE_FAIL;
 
-    /* We pass the Net:Node to the drivers/cards by a Device ioctl. */
-    if (!(iface->dev->do_ioctl(iface->dev, &atreq, SIOCSIFADDR))) {
-	    (void)iface->dev->do_ioctl(iface->dev, &atreq, SIOCGIFADDR);
-	    if (iface->address.s_net != htons(sa->sat_addr.s_net) ||
-		iface->address.s_node != sa->sat_addr.s_node)
-		    iface->status |= ATIF_PROBE_FAIL;
-
-	    iface->address.s_net  = htons(sa->sat_addr.s_net);
-	    iface->address.s_node = sa->sat_addr.s_node;
-    }
+		iface->address.s_net  = htons(sa->sat_addr.s_net);
+		iface->address.s_node = sa->sat_addr.s_node;
+	}
 }
 
 
@@ -462,7 +467,7 @@
 
 			/* Defer 1/10th */
 			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(HZ/10);
+			schedule_timeout(HZ / 10);
 							
 			if (atif->status & ATIF_PROBE_FAIL)
 				break;
@@ -470,9 +475,9 @@
 	}
 }
 
-int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa)
+int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa)
 {
-	int hash, retval = 1;
+	int hash, retval = -EPROTONOSUPPORT;
 	struct aarp_entry *entry;
 	unsigned int count;
 	
@@ -480,19 +485,18 @@
 	 * we don't currently support LocalTalk or PPP for proxy AARP;
 	 * if someone wants to try and add it, have fun
 	 */
-	if (atif->dev->type == ARPHRD_LOCALTLK)
-		return -EPROTONOSUPPORT;
-		
-	if (atif->dev->type == ARPHRD_PPP)
-		return -EPROTONOSUPPORT;
+	if (atif->dev->type == ARPHRD_LOCALTLK ||
+	    atif->dev->type == ARPHRD_PPP)
+		goto out;
 		
 	/* 
 	 * create a new AARP entry with the flags set to be published -- 
 	 * we need this one to hang around even if it's in use
 	 */
 	entry = aarp_alloc();
+	retval = -ENOMEM;
 	if (!entry)
-		return -ENOMEM;
+		goto out;
 	
 	entry->expires_at = -1;
 	entry->status = ATIF_PROBE;
@@ -512,7 +516,7 @@
 		/* Defer 1/10th */
 		current->state = TASK_INTERRUPTIBLE;
 		spin_unlock_bh(&aarp_lock);
-		schedule_timeout(HZ/10);
+		schedule_timeout(HZ / 10);
 		spin_lock_bh(&aarp_lock);
 
 		if (entry->status & ATIF_PROBE_FAIL)
@@ -522,16 +526,19 @@
 	if (entry->status & ATIF_PROBE_FAIL) {
 		entry->expires_at = jiffies - 1; /* free the entry */
 		retval = -EADDRINUSE; /* return network full */
-	} else /* clear the probing flag */
+	} else { /* clear the probing flag */
 		entry->status &= ~ATIF_PROBE;
+		retval = 1;
+	}
 
 	spin_unlock_bh(&aarp_lock);
+out:
 	return retval;
 }
 
 /* Send a DDP frame */
 int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb,
-			struct at_addr *sa, void *hwaddr)
+		  struct atalk_addr *sa, void *hwaddr)
 {
 	static char ddp_eth_multicast[ETH_ALEN] =
 		{ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
@@ -542,15 +549,15 @@
 	
 	/* Check for LocalTalk first */
 	if (dev->type == ARPHRD_LOCALTLK) {
-		struct at_addr *at = atalk_find_dev_addr(dev);
+		struct atalk_addr *at = atalk_find_dev_addr(dev);
 		struct ddpehdr *ddp = (struct ddpehdr *)skb->data;
 		int ft = 2;
 		
 		/*
-		 *	Compressible ?
+		 * Compressible ?
 		 * 
-		 *	IFF: src_net==dest_net==device_net
-		 *	(zero matches anything)
+		 * IFF: src_net == dest_net == device_net
+		 * (zero matches anything)
 		 */
 		 
 		if ((!ddp->deh_snet || at->s_net == ddp->deh_snet) &&
@@ -566,15 +573,15 @@
 			ft = 1;
 		}
 		/*
-		 *	Nice and easy. No AARP type protocols occur here
-		 *	so we can just shovel it out with a 3 byte LLAP header
+		 * Nice and easy. No AARP type protocols occur here so we can
+		 * just shovel it out with a 3 byte LLAP header
 		 */
 		 
 		skb_push(skb, 3);
 		skb->data[0] = sa->s_node;
 		skb->data[1] = at->s_node;
 		skb->data[2] = ft;
-		skb->dev = dev;
+		skb->dev     = dev;
 		goto sendit;
 	}	
 
@@ -613,8 +620,7 @@
 	a = __aarp_find_entry(unresolved[hash], dev, sa);
 	if (a) { /* Queue onto the unresolved queue */
 		skb_queue_tail(&a->packet_queue, skb);
-		spin_unlock_bh(&aarp_lock);
-		return 0;
+		goto out_unlock;
 	}
 
 	/* Allocate a new entry */
@@ -627,11 +633,11 @@
 
 	/* Set up the queue */
 	skb_queue_tail(&a->packet_queue, skb);
-	a->expires_at = jiffies + sysctl_aarp_resolve_time;
-	a->dev = dev;
-	a->next = unresolved[hash];
-	a->target_addr = *sa;
-	a->xmit_count = 0;
+	a->expires_at	 = jiffies + sysctl_aarp_resolve_time;
+	a->dev		 = dev;
+	a->next		 = unresolved[hash];
+	a->target_addr	 = *sa;
+	a->xmit_count	 = 0;
 	unresolved[hash] = a;
 	unresolved_count++;
 
@@ -639,20 +645,22 @@
 	__aarp_send_query(a);
 
 	/*
-	 *	Switch to fast timer if needed (That is if this is the
-	 *	first unresolved entry to get added)
+	 * Switch to fast timer if needed (That is if this is the first
+	 * unresolved entry to get added)
 	 */
 
 	if (unresolved_count == 1)
 		mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time);
 
 	/* Now finally, it is safe to drop the lock. */
+out_unlock:
 	spin_unlock_bh(&aarp_lock);
 
 	/* Tell the ddp layer we have taken over for this frame. */
 	return 0;
 
-sendit: if (skb->sk)
+sendit:
+	if (skb->sk)
 		skb->priority = skb->sk->priority;
 	dev_queue_xmit(skb);
 	return 1;
@@ -696,13 +704,13 @@
  *	frame. We currently only support Ethernet.
  */
 static int aarp_rcv(struct sk_buff *skb, struct net_device *dev,
-			struct packet_type *pt)
+		    struct packet_type *pt)
 {
-	struct elapaarp *ea = (struct elapaarp *)skb->h.raw;
+	struct elapaarp *ea = aarp_hdr(skb);
 	int hash, ret = 0;
 	__u16 function;
 	struct aarp_entry *a;
-	struct at_addr sa, *ma, da;
+	struct atalk_addr sa, *ma, da;
 	struct atalk_iface *ifa;
 
 	/* We only do Ethernet SNAP AARP. */
@@ -742,7 +750,7 @@
 
 	/* Check for replies of proxy AARP entries */
 	da.s_node = ea->pa_dst_node;
-	da.s_net = ea->pa_dst_net;
+	da.s_net  = ea->pa_dst_net;
 
 	spin_lock_bh(&aarp_lock);
 	a = __aarp_find_entry(proxies[hash], dev, &da);
@@ -776,20 +784,21 @@
 			
 		case AARP_REQUEST:
 		case AARP_PROBE:
+
 			/*
-			 *	If it is my address set ma to my address and
-			 *	reply. We can treat probe and request the
-			 *	same. Probe simply means we shouldn't cache
-			 *	the querying host, as in a probe they are
-			 *	proposing an address not using one.
+			 * If it is my address set ma to my address and reply.
+			 * We can treat probe and request the same.  Probe
+			 * simply means we shouldn't cache the querying host,
+			 * as in a probe they are proposing an address not
+			 * using one.
 			 *	
-			 *	Support for proxy-AARP added. We check if the
-			 *	address is one of our proxies before we toss
-			 *	the packet out.
+			 * Support for proxy-AARP added. We check if the
+			 * address is one of our proxies before we toss the
+			 * packet out.
 			 */
 			 
 			sa.s_node = ea->pa_dst_node;
-			sa.s_net = ea->pa_dst_net;
+			sa.s_net  = ea->pa_dst_net;
 
 			/* See if we have a matching proxy. */
 			ma = __aarp_proxy_find(dev, &sa);
@@ -802,16 +811,22 @@
 			}
 
 			if (function == AARP_PROBE) {
-				/* A probe implies someone trying to get an
+				/*
+				 * A probe implies someone trying to get an
 				 * address. So as a precaution flush any
-				 * entries we have for this address. */
+				 * entries we have for this address.
+				 */
 				struct aarp_entry *a = __aarp_find_entry(
-					resolved[sa.s_node%(AARP_HASH_SIZE-1)],
-					skb->dev, &sa);
-				/* Make it expire next tick - that avoids us
+						resolved[sa.s_node %
+							 (AARP_HASH_SIZE - 1)],
+								skb->dev, &sa);
+
+				/*
+				 * Make it expire next tick - that avoids us
 				 * getting into a probe/flush/learn/probe/
 				 * flush/learn cycle during probing of a slow
-				 * to respond host addr. */
+				 * to respond host addr.
+				 */
 				if (a) {
 					a->expires_at = jiffies - 1;
 					mod_timer(&aarp_timer, jiffies +
@@ -834,17 +849,20 @@
 			break;
 	}
 
-unlock:	spin_unlock_bh(&aarp_lock);
-out1:	ret = 1;
-out0:	kfree_skb(skb);
+unlock:
+	spin_unlock_bh(&aarp_lock);
+out1:
+	ret = 1;
+out0:
+	kfree_skb(skb);
 	return ret;
 }
 
 static struct notifier_block aarp_notifier = {
-	notifier_call:	aarp_device_event,
+	.notifier_call =aarp_device_event,
 };
 
-static char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 };
+static unsigned char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 };
 
 void __init aarp_proto_init(void)
 {
@@ -853,8 +871,8 @@
 		printk(KERN_CRIT "Unable to register AARP with SNAP.\n");
 	init_timer(&aarp_timer);
 	aarp_timer.function = aarp_expire_timeout;
-	aarp_timer.data = 0;
-	aarp_timer.expires = jiffies + sysctl_aarp_expiry_time;
+	aarp_timer.data	    = 0;
+	aarp_timer.expires  = jiffies + sysctl_aarp_expiry_time;
 	add_timer(&aarp_timer);
 	register_netdevice_notifier(&aarp_notifier);
 }
@@ -880,81 +898,84 @@
 {
 	/* we should dump all our AARP entries */
 	struct aarp_entry *entry;
-	int len, ct;
-
-	len = sprintf(buffer,
-		"%-10.10s  %-10.10s%-18.18s%12.12s%12.12s xmit_count  status\n",
-		"address", "device", "hw addr", "last_sent", "expires");
+	int ct, len = sprintf(buffer,
+			      "%-10.10s  %-10.10s%-18.18s%12.12s%12.12s "
+			      "xmit_count  status\n",
+			      "address", "device", "hw addr", "last_sent",
+			      "expires");
 
 	spin_lock_bh(&aarp_lock);
 
 	for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
 		for (entry = resolved[ct]; entry; entry = entry->next) {
-			len+= sprintf(buffer+len,"%6u:%-3u  ",
+			len += sprintf(buffer + len, "%6u:%-3u  ",
 				(unsigned int)ntohs(entry->target_addr.s_net),
 				(unsigned int)(entry->target_addr.s_node));
-			len+= sprintf(buffer+len,"%-10.10s",
-				entry->dev->name);
-			len+= sprintf(buffer+len,"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
-				(int)(entry->hwaddr[0] & 0x000000FF),
-				(int)(entry->hwaddr[1] & 0x000000FF),
-				(int)(entry->hwaddr[2] & 0x000000FF),
-				(int)(entry->hwaddr[3] & 0x000000FF),
-				(int)(entry->hwaddr[4] & 0x000000FF),
-				(int)(entry->hwaddr[5] & 0x000000FF));
-			len+= sprintf(buffer+len,"%12lu ""%12lu ",
-				(unsigned long)entry->last_sent,
-				(unsigned long)entry->expires_at);
-			len+=sprintf(buffer+len,"%10u",
-				(unsigned int)entry->xmit_count);
+			len += sprintf(buffer + len, "%-10.10s",
+				       entry->dev->name);
+			len += sprintf(buffer + len,
+				       "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+				       (int)(entry->hwaddr[0] & 0x000000FF),
+				       (int)(entry->hwaddr[1] & 0x000000FF),
+				       (int)(entry->hwaddr[2] & 0x000000FF),
+				       (int)(entry->hwaddr[3] & 0x000000FF),
+				       (int)(entry->hwaddr[4] & 0x000000FF),
+				       (int)(entry->hwaddr[5] & 0x000000FF));
+			len += sprintf(buffer + len, "%12lu ""%12lu ",
+				       (unsigned long)entry->last_sent,
+				       (unsigned long)entry->expires_at);
+			len += sprintf(buffer + len, "%10u",
+				       (unsigned int)entry->xmit_count);
 
-			len+=sprintf(buffer+len,"   resolved\n");
+			len += sprintf(buffer + len, "   resolved\n");
 		}
 	}
 
 	for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
 		for (entry = unresolved[ct]; entry; entry = entry->next) {
-			len+= sprintf(buffer+len,"%6u:%-3u  ",
+			len += sprintf(buffer + len, "%6u:%-3u  ",
 				(unsigned int)ntohs(entry->target_addr.s_net),
 				(unsigned int)(entry->target_addr.s_node));
-			len+= sprintf(buffer+len,"%-10.10s",
-				entry->dev->name);
-			len+= sprintf(buffer+len,"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
-				(int)(entry->hwaddr[0] & 0x000000FF),
-				(int)(entry->hwaddr[1] & 0x000000FF),
-				(int)(entry->hwaddr[2] & 0x000000FF),
-				(int)(entry->hwaddr[3] & 0x000000FF),
-				(int)(entry->hwaddr[4] & 0x000000FF),
-				(int)(entry->hwaddr[5] & 0x000000FF));
-			len+= sprintf(buffer+len,"%12lu ""%12lu ",
-				(unsigned long)entry->last_sent,
-				(unsigned long)entry->expires_at);
-			len+=sprintf(buffer+len,"%10u",
-				(unsigned int)entry->xmit_count);
-			len+=sprintf(buffer+len," unresolved\n");
+			len += sprintf(buffer + len, "%-10.10s",
+				       entry->dev->name);
+			len += sprintf(buffer + len,
+				       "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+				       (int)(entry->hwaddr[0] & 0x000000FF),
+				       (int)(entry->hwaddr[1] & 0x000000FF),
+				       (int)(entry->hwaddr[2] & 0x000000FF),
+				       (int)(entry->hwaddr[3] & 0x000000FF),
+				       (int)(entry->hwaddr[4] & 0x000000FF),
+				       (int)(entry->hwaddr[5] & 0x000000FF));
+			len += sprintf(buffer + len, "%12lu ""%12lu ",
+				       (unsigned long)entry->last_sent,
+				       (unsigned long)entry->expires_at);
+			len += sprintf(buffer + len, "%10u",
+				       (unsigned int)entry->xmit_count);
+			len += sprintf(buffer + len, " unresolved\n");
 		}
 	}
 
 	for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
 		for (entry = proxies[ct]; entry; entry = entry->next) {
-			len+= sprintf(buffer+len,"%6u:%-3u  ",
+			len += sprintf(buffer + len, "%6u:%-3u  ",
 				(unsigned int)ntohs(entry->target_addr.s_net),
 				(unsigned int)(entry->target_addr.s_node));
-			len+= sprintf(buffer+len,"%-10.10s",
-				entry->dev->name);
-			len+= sprintf(buffer+len,"%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
-				(int)(entry->hwaddr[0] & 0x000000FF),
-				(int)(entry->hwaddr[1] & 0x000000FF),
-				(int)(entry->hwaddr[2] & 0x000000FF),
-				(int)(entry->hwaddr[3] & 0x000000FF),
-				(int)(entry->hwaddr[4] & 0x000000FF),
-				(int)(entry->hwaddr[5] & 0x000000FF));
-			len+= sprintf(buffer+len,"%12lu ""%12lu ",
-				(unsigned long)entry->last_sent,
-				(unsigned long)entry->expires_at);
-			len+=sprintf(buffer+len,"%10u",
-				(unsigned int)entry->xmit_count);
-			len+=sprintf(buffer+len,"      proxy\n");
+			len += sprintf(buffer + len, "%-10.10s",
+				       entry->dev->name);
+			len += sprintf(buffer + len,
+				       "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+				       (int)(entry->hwaddr[0] & 0x000000FF),
+				       (int)(entry->hwaddr[1] & 0x000000FF),
+				       (int)(entry->hwaddr[2] & 0x000000FF),
+				       (int)(entry->hwaddr[3] & 0x000000FF),
+				       (int)(entry->hwaddr[4] & 0x000000FF),
+				       (int)(entry->hwaddr[5] & 0x000000FF));
+			len += sprintf(buffer + len, "%12lu ""%12lu ",
+				       (unsigned long)entry->last_sent,
+				       (unsigned long)entry->expires_at);
+			len += sprintf(buffer + len, "%10u",
+				       (unsigned int)entry->xmit_count);
+			len += sprintf(buffer + len, "      proxy\n");
 		}
 	}
 
@@ -982,5 +1003,4 @@
 	proc_net_remove("aarp");
 }
 #endif
-#endif  /* CONFIG_ATALK || CONFIG_ATALK_MODULE */
 MODULE_LICENSE("GPL");
diff -Nru a/net/appletalk/ddp.c b/net/appletalk/ddp.c
--- a/net/appletalk/ddp.c	Sat Aug 10 18:42:23 2002
+++ b/net/appletalk/ddp.c	Sat Aug 10 18:42:23 2002
@@ -49,7 +49,6 @@
  */
 
 #include <linux/config.h>
-#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
 #include <linux/module.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -96,15 +95,8 @@
 
 extern void aarp_probe_network(struct atalk_iface *atif);
 extern int  aarp_proxy_probe_network(struct atalk_iface *atif,
-					struct at_addr *sa);
-extern void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa);
-
-#undef APPLETALK_DEBUG
-#ifdef APPLETALK_DEBUG
-#define DPRINT(x)		print(x)
-#else
-#define DPRINT(x)
-#endif /* APPLETALK_DEBUG */
+				     struct atalk_addr *sa);
+extern void aarp_proxy_remove(struct net_device *dev, struct atalk_addr *sa);
 
 #ifdef CONFIG_SYSCTL
 extern inline void atalk_register_sysctl(void);
@@ -182,10 +174,13 @@
 	return s;
 }
 
-/*
- * Try to find a socket matching ADDR in the socket list,
- * if found then return it.  If not, insert SK into the
- * socket list.
+/**
+ * atalk_find_or_insert_socket - Try to find a socket matching ADDR
+ * @sk - socket to insert in the list if it is not there already
+ * @sat - address to search for
+ *
+ * Try to find a socket matching ADDR in the socket list, if found then return
+ * it. If not, insert SK into the socket list.
  *
  * This entire operation must execute atomically.
  */
@@ -219,7 +214,7 @@
 
 static void atalk_destroy_timer(unsigned long data)
 {
-	struct sock *sk = (struct sock *) data;
+	struct sock *sk = (struct sock *)data;
 
 	if (!atomic_read(&sk->wmem_alloc) &&
 	    !atomic_read(&sk->rmem_alloc) && sk->dead) {
@@ -263,16 +258,16 @@
 	for (s = atalk_sockets; s; s = s->next) {
 		struct atalk_sock *at = at_sk(s);
 
-		len += sprintf(buffer + len,"%02X   ", s->type);
-		len += sprintf(buffer + len,"%04X:%02X:%02X  ",
+		len += sprintf(buffer + len, "%02X   ", s->type);
+		len += sprintf(buffer + len, "%04X:%02X:%02X  ",
 			       ntohs(at->src_net), at->src_node, at->src_port);
-		len += sprintf(buffer + len,"%04X:%02X:%02X  ",
+		len += sprintf(buffer + len, "%04X:%02X:%02X  ",
 			       ntohs(at->dest_net), at->dest_node,
 			       at->dest_port);
-		len += sprintf(buffer + len,"%08X:%08X ",
+		len += sprintf(buffer + len, "%08X:%08X ",
 			       atomic_read(&s->wmem_alloc),
 			       atomic_read(&s->rmem_alloc));
-		len += sprintf(buffer + len,"%02X %d\n", s->state, 
+		len += sprintf(buffer + len, "%02X %d\n", s->state, 
 			       SOCK_INODE(s->socket)->i_uid);
 
 		/* Are we still dumping unwanted data then discard the record */
@@ -287,7 +282,7 @@
 	}
 	spin_unlock_bh(&atalk_sockets_lock);
 
-	/* The data in question runs from begin to begin+len */
+	/* The data in question runs from begin to begin + len */
 	*start = buffer + offset - begin;	/* Start of wanted data */
 	len -= offset - begin;   /* Remove unwanted header data from length */
 	if (len > length)
@@ -336,12 +331,15 @@
 }
 
 static struct atalk_iface *atif_add_device(struct net_device *dev,
-					   struct at_addr *sa)
+					   struct atalk_addr *sa)
 {
-	struct atalk_iface *iface = kmalloc(sizeof(*iface), GFP_KERNEL);
+	struct atalk_iface *iface;
 
+	MOD_INC_USE_COUNT;
+
+	iface = kmalloc(sizeof(*iface), GFP_KERNEL);
 	if (!iface)
-		return NULL;
+		goto out_mem;
 
 	iface->dev = dev;
 	dev->atalk_ptr = iface;
@@ -352,9 +350,11 @@
 	iface->next = atalk_iface_list;
 	atalk_iface_list = iface;
 	spin_unlock_bh(&atalk_iface_lock);
-
-	MOD_INC_USE_COUNT;
+out:
 	return iface;
+out_mem:
+	MOD_DEC_USE_COUNT;
+	goto out;
 }
 
 /* Perform phase 2 AARP probing on our tentative address */
@@ -381,7 +381,7 @@
 		/* Sweep the available nodes from a given start */
 		atif->address.s_net = htons(probe_net);
 		for (nodect = 0; nodect < 256; nodect++) {
-			atif->address.s_node = ((nodect+probe_node) & 0xFF);
+			atif->address.s_node = (nodect + probe_node) & 0xFF;
 			if (atif->address.s_node > 0 &&
 			    atif->address.s_node < 254) {
 				/* Probe a proposed address */
@@ -406,7 +406,7 @@
 
 /* Perform AARP probing for a proxy address */
 static int atif_proxy_probe_device(struct atalk_iface *atif,
-				   struct at_addr* proxy_addr)
+				   struct atalk_addr* proxy_addr)
 {
 	int netrange = ntohs(atif->nets.nr_lastnet) -
 			ntohs(atif->nets.nr_firstnet) + 1;
@@ -430,7 +430,7 @@
 		/* Sweep the available nodes from a given start */
 		proxy_addr->s_net = htons(probe_net);
 		for (nodect = 0; nodect < 256; nodect++) {
-			proxy_addr->s_node = ((nodect + probe_node) & 0xFF);
+			proxy_addr->s_node = (nodect + probe_node) & 0xFF;
 			if (proxy_addr->s_node > 0 &&
 			    proxy_addr->s_node < 254) {
 				/* Tell AARP to probe a proposed address */
@@ -450,16 +450,16 @@
 }
 
 
-struct at_addr *atalk_find_dev_addr(struct net_device *dev)
+struct atalk_addr *atalk_find_dev_addr(struct net_device *dev)
 {
 	struct atalk_iface *iface = dev->atalk_ptr;
 	return iface ? &iface->address : NULL;
 }
 
-static struct at_addr *atalk_find_primary(void)
+static struct atalk_addr *atalk_find_primary(void)
 {
 	struct atalk_iface *fiface = NULL;
-	struct at_addr *retval;
+	struct atalk_addr *retval;
 	struct atalk_iface *iface;
 
 	/*
@@ -482,7 +482,8 @@
 		retval = &atalk_iface_list->address;
 	else
 		retval = NULL;
-out:	spin_unlock_bh(&atalk_iface_lock);
+out:
+	spin_unlock_bh(&atalk_iface_lock);
 	return retval;
 }
 
@@ -495,14 +496,17 @@
 	struct atalk_iface *iface = dev->atalk_ptr;
 
 	if (!iface || iface->status & ATIF_PROBE)
-		return NULL;
-
-	if (node == ATADDR_BCAST ||
-	    iface->address.s_node == node ||
-	    node == ATADDR_ANYNODE)
-		return iface;
+		goto out_err;
 
-	return NULL;
+	if (node != ATADDR_BCAST &&
+	    iface->address.s_node != node &&
+	    node != ATADDR_ANYNODE)
+		goto out_err;
+out:
+	return iface;
+out_err:
+	iface = NULL;
+	goto out;
 }
 
 /* Find a match for a specific network:node pair */
@@ -535,7 +539,7 @@
  * the socket (later on...). We know about host routes and the fact
  * that a route must be direct to broadcast.
  */
-static struct atalk_route *atrtr_find(struct at_addr *target)
+static struct atalk_route *atrtr_find(struct atalk_addr *target)
 {
 	/*
 	 * we must search through all routes unless we find a 
@@ -577,7 +581,8 @@
 		r = &atrtr_default;
 	else /* No route can be found */
 		r = NULL;
-out:	read_unlock_bh(&atalk_router_lock);
+out:
+	read_unlock_bh(&atalk_router_lock);
 	return r;
 }
 
@@ -586,7 +591,7 @@
  * Given an AppleTalk network, find the device to use. This can be
  * a simple lookup.
  */
-struct net_device *atrtr_get_dev(struct at_addr *sa)
+struct net_device *atrtr_get_dev(struct atalk_addr *sa)
 {
 	struct atalk_route *atr = atrtr_find(sa);
 	return atr ? atr->dev : NULL;
@@ -595,9 +600,9 @@
 /* Set up a default router */
 static void atrtr_set_default(struct net_device *dev)
 {
-	atrtr_default.dev = dev;
-	atrtr_default.flags = RTF_UP;
-	atrtr_default.gateway.s_net = htons(0);
+	atrtr_default.dev	     = dev;
+	atrtr_default.flags	     = RTF_UP;
+	atrtr_default.gateway.s_net  = htons(0);
 	atrtr_default.gateway.s_node = 0;
 }
 
@@ -612,7 +617,7 @@
 	struct sockaddr_at *ga = (struct sockaddr_at *)&r->rt_gateway;
 	struct atalk_route *rt;
 	struct atalk_iface *iface, *riface;
-	int retval;
+	int retval = -EINVAL;
 
 	/*
 	 * Fixme: Raise/Lower a routing change semaphore for these
@@ -620,11 +625,9 @@
 	 */
 
 	/* Validate the request */
-	if (ta->sat_family != AF_APPLETALK)
-		return -EINVAL;
-
-	if (!devhint && ga->sat_family != AF_APPLETALK)
-		return -EINVAL;
+	if (ta->sat_family != AF_APPLETALK ||
+	    (!devhint && ga->sat_family != AF_APPLETALK))
+		goto out;
 
 	/* Now walk the routing table and make our decisions */
 	write_lock_bh(&atalk_router_lock);
@@ -660,13 +663,13 @@
 
 		retval = -ENETUNREACH;
 		if (!riface)
-			goto out;
+			goto out_unlock;
 
 		devhint = riface->dev;
 	}
 
 	if (!rt) {
-		rt = kmalloc(sizeof(struct atalk_route), GFP_ATOMIC);
+		rt = kmalloc(sizeof(*rt), GFP_ATOMIC);
 
 		retval = -ENOBUFS;
 		if (!rt)
@@ -683,12 +686,14 @@
 	rt->gateway = ga->sat_addr;
 
 	retval = 0;
-out:	write_unlock_bh(&atalk_router_lock);
+out_unlock:
+	write_unlock_bh(&atalk_router_lock);
+out:
 	return retval;
 }
 
 /* Delete a route. Find it and discard it */
-static int atrtr_delete(struct at_addr * addr)
+static int atrtr_delete(struct atalk_addr * addr)
 {
 	struct atalk_route **r = &atalk_router_list;
 	int retval = 0;
@@ -706,7 +711,8 @@
 		r = &tmp->next;
 	}
 	retval = -ENOENT;
-out:	write_unlock_bh(&atalk_router_lock);
+out:
+	write_unlock_bh(&atalk_router_lock);
 	return retval;
 }
 
@@ -746,11 +752,11 @@
  * delete our use of them (iface and route).
  */
 static int ddp_device_event(struct notifier_block *this, unsigned long event,
-				void *ptr)
+			    void *ptr)
 {
 	if (event == NETDEV_DOWN)
 		/* Discard any use of this */
-	        atalk_dev_down((struct net_device *) ptr);
+	        atalk_dev_down(ptr);
 
 	return NOTIFY_DONE;
 }
@@ -759,9 +765,9 @@
 /* Device configuration ioctl calls */
 static int atif_ioctl(int cmd, void *arg)
 {
-	static char aarp_mcast[6] = {0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF};
+	static char aarp_mcast[6] = { 0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF };
 	struct ifreq atreq;
-	struct netrange *nr;
+	struct atalk_netrange *nr;
 	struct sockaddr_at *sa;
 	struct net_device *dev;
 	struct atalk_iface *atif;
@@ -777,7 +783,7 @@
 	if (!dev)
 		return -ENODEV;
 
-	sa = (struct sockaddr_at*) &atreq.ifr_addr;
+	sa = (struct sockaddr_at *)&atreq.ifr_addr;
 	atif = atalk_find_dev(dev);
 
 	switch (cmd) {
@@ -792,7 +798,7 @@
 			    dev->type != ARPHRD_PPP)
 				return -EPROTONOSUPPORT;
 
-			nr = (struct netrange *) &sa->sat_zero[0];
+			nr = (struct atalk_netrange *)&sa->sat_zero[0];
 			add_route = 1;
 
 			/*
@@ -846,11 +852,11 @@
 			}
 
 			/* Hey it worked - add the direct routes */
-			sa = (struct sockaddr_at *) &rtdef.rt_gateway;
+			sa = (struct sockaddr_at *)&rtdef.rt_gateway;
 			sa->sat_family = AF_APPLETALK;
 			sa->sat_addr.s_net  = atif->address.s_net;
 			sa->sat_addr.s_node = atif->address.s_node;
-			sa = (struct sockaddr_at *) &rtdef.rt_dst;
+			sa = (struct sockaddr_at *)&rtdef.rt_dst;
 			rtdef.rt_flags = RTF_UP;
 			sa->sat_family = AF_APPLETALK;
 			sa->sat_addr.s_node = ATADDR_ANYNODE;
@@ -932,7 +938,7 @@
                         if (!atif)
                                 return -EADDRNOTAVAIL;
 
-                        nr = (struct netrange *) &(atif->nets);
+                        nr = (struct atalk_netrange *)&(atif->nets);
                         /*
                          * Phase 1 is fine on Localtalk but we don't do
                          * Ethertalk phase 1. Anyone wanting to add it go ahead.
@@ -978,7 +984,6 @@
 /* Routing ioctl() calls */
 static int atrtr_ioctl(unsigned int cmd, void *arg)
 {
-	struct net_device *dev = NULL;
 	struct rtentry rt;
 
 	if (copy_from_user(&rt, arg, sizeof(rt)))
@@ -991,15 +996,19 @@
 			return atrtr_delete(&((struct sockaddr_at *)
 						&rt.rt_dst)->sat_addr);
 
-		case SIOCADDRT:
-			/* FIXME: the name of the device is still in user
-			 * space, isn't it? */
+		case SIOCADDRT: {
+			struct net_device *dev = NULL;
+			/*
+			 * FIXME: the name of the device is still in user
+			 * space, isn't it?
+			 */
 			if (rt.rt_dev) {
 				dev = __dev_get_by_name(rt.rt_dev);
 				if (!dev)
 					return -ENODEV;
 			}			
 			return atrtr_create(&rt, dev);
+		}
 	}
 	return -EINVAL;
 }
@@ -1016,7 +1025,7 @@
 
 	spin_lock_bh(&atalk_iface_lock);
 	for (iface = atalk_iface_list; iface; iface = iface->next) {
-		len += sprintf(buffer+len,"%-16s %04X:%02X  %04X-%04X  %d\n",
+		len += sprintf(buffer + len, "%-16s %04X:%02X  %04X-%04X  %d\n",
 			       iface->dev->name, ntohs(iface->address.s_net),
 			       iface->address.s_node,
 			       ntohs(iface->nets.nr_firstnet),
@@ -1049,7 +1058,8 @@
 
 	if (atrtr_default.dev) {
 		rt = &atrtr_default;
-		len += sprintf(buffer + len,"Default     %04X:%02X  %-4d  %s\n",
+		len += sprintf(buffer + len,
+			       "Default     %04X:%02X  %-4d  %s\n",
 			       ntohs(rt->gateway.s_net), rt->gateway.s_node,
 			       rt->flags, rt->dev->name);
 	}
@@ -1092,7 +1102,7 @@
 unsigned short atalk_checksum(struct ddpehdr *ddp, int len)
 {
 	unsigned long sum = 0;	/* Assume unsigned long is >16 bits */
-	unsigned char *data = (unsigned char *) ddp;
+	unsigned char *data = (unsigned char *)ddp;
 
 	len  -= 4;		/* skip header 4 bytes */
 	data += 4;
@@ -1108,7 +1118,7 @@
 		data++;
 	}
 	/* Use 0xFFFF for 0. 0 itself means none */
-	return sum ? htons((unsigned short) sum) : 0xFFFF;
+	return sum ? htons((unsigned short)sum) : 0xFFFF;
 }
 
 /*
@@ -1140,9 +1150,12 @@
 	sock_init_data(sock, sk);
 	/* Checksums on by default */
 	sk->zapped = 1;
-out:	return rc;
-outsk:	sk_free(sk);
-decmod:	MOD_DEC_USE_COUNT;
+out:
+	return rc;
+outsk:
+	sk_free(sk);
+decmod:
+	MOD_DEC_USE_COUNT;
 	goto out;
 }
 
@@ -1151,20 +1164,23 @@
 {
 	struct sock *sk = sock->sk;
 
-	if (!sk)
-		goto out;
-	if (!sk->dead)
-		sk->state_change(sk);
-	sk->dead = 1;
-	sock->sk = NULL;
-	atalk_destroy_socket(sk);
-out:	return 0;
+	if (sk) {
+		if (!sk->dead)
+			sk->state_change(sk);
+		sk->dead = 1;
+		sock->sk = NULL;
+		atalk_destroy_socket(sk);
+	}
+	return 0;
 }
 
-/*
- * Pick a source port when one is not given. If we can
- * find a suitable free one, we insert the socket into
- * the tables using it.
+/**
+ * atalk_pick_and_bind_port - Pick a source port when one is not given
+ * @sk - socket to insert into the tables
+ * @sat - address to search for
+ *
+ * Pick a source port when one is not given. If we can find a suitable free
+ * one, we insert the socket into the tables using it.
  *
  * This whole operation must be atomic.
  */
@@ -1197,12 +1213,12 @@
 		retval = 0;
 		goto out;
 
-	try_next_port:
-		;
+try_next_port:;
 	}
 
 	retval = -EBUSY;
-out:	spin_unlock_bh(&atalk_sockets_lock);
+out:
+	spin_unlock_bh(&atalk_sockets_lock);
 	return retval;
 }
 
@@ -1210,21 +1226,20 @@
 {
 	struct atalk_sock *at = at_sk(sk);
 	struct sockaddr_at sat;
-	int n;
-	struct at_addr *ap = atalk_find_primary();
+	struct atalk_addr *ap = atalk_find_primary();
+	int n = -EADDRNOTAVAIL;
 
 	if (!ap || ap->s_net == htons(ATADDR_ANYNET))
-		return -EADDRNOTAVAIL;
+		goto out;
 
 	at->src_net  = sat.sat_addr.s_net  = ap->s_net;
 	at->src_node = sat.sat_addr.s_node = ap->s_node;
 
 	n = atalk_pick_and_bind_port(sk, &sat);
-	if (n < 0)
-		return n;
-
-	sk->zapped = 0;
-	return 0;
+	if (!n)
+		sk->zapped = 0;
+out:
+	return n;
 }
 
 /* Set the address 'our end' of the connection */
@@ -1241,7 +1256,7 @@
 		return -EAFNOSUPPORT;
 
 	if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) {
-		struct at_addr *ap = atalk_find_primary();
+		struct atalk_addr *ap = atalk_find_primary();
 
 		if (!ap)
 			return -EADDRNOTAVAIL;
@@ -1319,7 +1334,6 @@
 	return 0;
 }
 
-
 /*
  * Find the name of an AppleTalk socket. Just copy the right
  * fields into the sockaddr.
@@ -1355,17 +1369,140 @@
 	return 0;
 }
 
-/*
- * Receive a packet (in skb) from device dev. This has come from the SNAP
- * decoder, and on entry skb->h.raw is the DDP header, skb->len is the DDP
- * header, skb->len is the DDP length. The physical headers have been
- * extracted. PPP should probably pass frames marked as for this layer.
- * [ie ARPHRD_ETHERTALK]
+#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE)
+static __inline__ int is_ip_over_ddp(struct sk_buff *skb)
+{
+        return skb->data[12] == 22;
+}
+
+static int handle_ip_over_ddp(struct sk_buff *skb)
+{
+        struct net_device *dev = __dev_get_by_name("ipddp0");
+	struct net_device_stats *stats;
+
+	/* This needs to be able to handle ipddp"N" devices */
+        if (!dev)
+                return -ENODEV;
+
+        skb->protocol = htons(ETH_P_IP);
+        skb_pull(skb, 13);
+        skb->dev   = dev;
+        skb->h.raw = skb->data;
+
+	stats = dev->priv;
+        stats->rx_packets++;
+        stats->rx_bytes += skb->len + 13;
+        netif_rx(skb);  /* Send the SKB up to a higher place. */
+	return 0;
+}
+#else
+/* make it easy for gcc to optimize this test out, i.e. kill the code */
+#define is_ip_over_ddp(skb) 0
+#define handle_ip_over_ddp(skb) 0
+#endif
+
+static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
+			       struct ddpehdr *ddp, struct ddpebits *ddphv,
+			       int origlen)
+{
+	struct atalk_route *rt;
+	struct atalk_addr ta;
+
+	/*
+	 * Don't route multicast, etc., packets, or packets sent to "this
+	 * network" 
+	 */
+	if (skb->pkt_type != PACKET_HOST || !ddp->deh_dnet) {
+		/*
+		 * FIXME:
+		 *
+		 * Can it ever happen that a packet is from a PPP iface and
+		 * needs to be broadcast onto the default network?
+		 */
+		if (dev->type == ARPHRD_PPP)
+			printk(KERN_DEBUG "AppleTalk: didn't forward broadcast "
+					  "packet received from PPP iface\n");
+		goto free_it;
+	}
+
+	ta.s_net  = ddp->deh_dnet;
+	ta.s_node = ddp->deh_dnode;
+
+	/* Route the packet */
+	rt = atrtr_find(&ta);
+	if (!rt || ddphv->deh_hops == DDP_MAXHOPS)
+		goto free_it;
+	/* FIXME: use skb->cb to be able to use shared skbs */
+	ddphv->deh_hops++;
+
+	/*
+	 * Route goes through another gateway, so set the target to the
+	 * gateway instead.
+	 */
+
+	if (rt->flags & RTF_GATEWAY) {
+		ta.s_net  = rt->gateway.s_net;
+		ta.s_node = rt->gateway.s_node;
+	}
+
+        /* Fix up skb->len field */
+        skb_trim(skb, min_t(unsigned int, origlen,
+			    (rt->dev->hard_header_len +
+			     ddp_dl->header_length + ddphv->deh_len)));
+
+	/* Mend the byte order */
+	/* FIXME: use skb->cb to be able to use shared skbs */
+	*((__u16 *)ddp) = ntohs(*((__u16 *)ddphv));
+
+	/*
+	 * Send the buffer onwards
+	 *
+	 * Now we must always be careful. If it's come from LocalTalk to
+	 * EtherTalk it might not fit
+	 *
+	 * Order matters here: If a packet has to be copied to make a new
+	 * headroom (rare hopefully) then it won't need unsharing.
+	 *
+	 * Note. ddp-> becomes invalid at the realloc.
+	 */
+	if (skb_headroom(skb) < 22) {
+		/* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */
+		struct sk_buff *nskb = skb_realloc_headroom(skb, 32);
+		kfree_skb(skb);
+		if (!nskb) 
+			goto out;
+		skb = nskb;
+	} else
+		skb = skb_unshare(skb, GFP_ATOMIC);
+	
+	/*
+	 * If the buffer didn't vanish into the lack of space bitbucket we can
+	 * send it.
+	 */
+	if (skb && aarp_send_ddp(rt->dev, skb, &ta, NULL) == -1)
+		goto free_it;
+out:
+	return;
+free_it:
+	kfree_skb(skb);
+}
+
+/**
+ *	atalk_rcv - Receive a packet (in skb) from device dev
+ *	@skb - packet received
+ *	@dev - network device where the packet comes from
+ *	@pt - packet type
+ *
+ *	Receive a packet (in skb) from device dev. This has come from the SNAP
+ *	decoder, and on entry skb->h.raw is the DDP header, skb->len is the DDP
+ *	header, skb->len is the DDP length. The physical headers have been
+ *	extracted. PPP should probably pass frames marked as for this layer.
+ *	[ie ARPHRD_ETHERTALK]
  */
 static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
-			struct packet_type *pt)
+		     struct packet_type *pt)
 {
-	struct ddpehdr *ddp = (void *) skb->h.raw;
+	struct ddpehdr *ddp = ddp_hdr(skb);
 	struct sock *sock;
 	struct atalk_iface *atif;
 	struct sockaddr_at tosat;
@@ -1416,110 +1553,20 @@
 
 	/* Not ours, so we route the packet via the correct AppleTalk iface */
 	if (!atif) {
-		struct atalk_route *rt;
-		struct at_addr ta;
-
-		/*
-		 * Don't route multicast, etc., packets, or packets
-		 * sent to "this network" 
-		 */
-		if (skb->pkt_type != PACKET_HOST || !ddp->deh_dnet) {
-			/* FIXME:
-			 * Can it ever happen that a packet is from a PPP
-			 * iface and needs to be broadcast onto the default
-			 * network? */
-			if (dev->type == ARPHRD_PPP)
-				printk(KERN_DEBUG "AppleTalk: didn't forward "
-						  "broadcast packet received "
-						  "from PPP iface\n");
-			goto freeit;
-		}
-
-		ta.s_net  = ddp->deh_dnet;
-		ta.s_node = ddp->deh_dnode;
-
-		/* Route the packet */
-		rt = atrtr_find(&ta);
-		if (!rt || ddphv.deh_hops == DDP_MAXHOPS)
-			goto freeit;
-		ddphv.deh_hops++;
-
-		/*
-		 * Route goes through another gateway, so
-		 * set the target to the gateway instead.
-		 */
-		if (rt->flags & RTF_GATEWAY) {
-			ta.s_net  = rt->gateway.s_net;
-			ta.s_node = rt->gateway.s_node;
-		}
-
-                /* Fix up skb->len field */
-                skb_trim(skb, min_t(unsigned int, origlen, rt->dev->hard_header_len +
-			ddp_dl->header_length + ddphv.deh_len));
-
-		/* Mend the byte order */
-		*((__u16 *)ddp) = ntohs(*((__u16 *)&ddphv));
-
-		/*
-		 * Send the buffer onwards
-		 *
-		 * Now we must always be careful. If it's come from 
-		 * LocalTalk to EtherTalk it might not fit
-		 *
-		 * Order matters here: If a packet has to be copied
-		 * to make a new headroom (rare hopefully) then it
-		 * won't need unsharing.
-		 *
-		 * Note. ddp-> becomes invalid at the realloc.
-		 */
-		if (skb_headroom(skb) < 22) {
-			/* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */
-			struct sk_buff *nskb = skb_realloc_headroom(skb, 32);
-			kfree_skb(skb);
-			if (!nskb) 
-				goto out;
-			skb = nskb;
-		} else
-			skb = skb_unshare(skb, GFP_ATOMIC);
-		
-		/*
-		 * If the buffer didn't vanish into the lack of
-		 * space bitbucket we can send it.
-		 */
-		if (skb && aarp_send_ddp(rt->dev, skb, &ta, NULL) == -1)
-			goto freeit;
+		atalk_route_packet(skb, dev, ddp, &ddphv, origlen);
 		goto out;
 	}
 
-#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE)
-        /* Check if IP-over-DDP */
-        if (skb->data[12] == 22) {
-                struct net_device *dev = __dev_get_by_name("ipddp0");
-		struct net_device_stats *stats;
-
-		/* This needs to be able to handle ipddp"N" devices */
-                if (!dev)
-                        return -ENODEV;
-
-                skb->protocol = htons(ETH_P_IP);
-                skb_pull(skb, 13);
-                skb->dev = dev;
-                skb->h.raw = skb->data;
-
-		stats = dev->priv;
-                stats->rx_packets++;
-                stats->rx_bytes += skb->len + 13;
-                netif_rx(skb);  /* Send the SKB up to a higher place. */
-		goto out;
-        }
-#endif
+	/* if IP over DDP is not selected this code will be optimized out */
+	if (is_ip_over_ddp(skb))
+		return handle_ip_over_ddp(skb);
 	/*
 	 * Which socket - atalk_search_socket() looks for a *full match*
-	 * of the <net,node,port> tuple.
+	 * of the <net, node, port> tuple.
 	 */
 	tosat.sat_addr.s_net  = ddp->deh_dnet;
 	tosat.sat_addr.s_node = ddp->deh_dnode;
-	tosat.sat_port = ddp->deh_dport;
+	tosat.sat_port	      = ddp->deh_dport;
 
 	sock = atalk_search_socket(&tosat, atif);
 	if (!sock) /* But not one of our sockets */
@@ -1530,9 +1577,11 @@
 
 	if (sock_queue_rcv_skb(sock, skb) < 0)
 		goto freeit;
+out:
+	return 0;
+freeit:
+	kfree_skb(skb);
 	goto out;
-freeit:	kfree_skb(skb);
-out:	return 0;
 }
 
 /*
@@ -1543,25 +1592,21 @@
 static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
 			struct packet_type *pt)
 {
-	struct ddpehdr *ddp;
-	struct at_addr *ap;
-
 	/* Expand any short form frames */
 	if (skb->mac.raw[2] == 1) {
+		struct ddpehdr *ddp;
 		/* Find our address */
+		struct atalk_addr *ap = atalk_find_dev_addr(dev);
 
-		ap = atalk_find_dev_addr(dev);
-		if (!ap || skb->len < sizeof(struct ddpshdr)) {
-			kfree_skb(skb);
-			return 0;
-		}
-
+		if (!ap || skb->len < sizeof(struct ddpshdr))
+			goto freeit;
 		/*
 		 * The push leaves us with a ddephdr not an shdr, and
 		 * handily the port bytes in the right place preset.
 		 */
 
 		skb_push(skb, sizeof(*ddp) - 4);
+		/* FIXME: use skb->cb to be able to use shared skbs */
 		ddp = (struct ddpehdr *)skb->data;
 
 		/* Now fill in the long header */
@@ -1590,10 +1635,13 @@
 	skb->h.raw = skb->data;
 
 	return atalk_rcv(skb, dev, pt);
+freeit:
+	kfree_skb(skb);
+	return 0;
 }
 
 static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-				struct scm_cookie *scm)
+			 struct scm_cookie *scm)
 {
 	struct sock *sk = sock->sk;
 	struct atalk_sock *at = at_sk(sk);
@@ -1654,7 +1702,7 @@
 
 		dev = rt->dev;
 	} else {
-		struct at_addr at_hint;
+		struct atalk_addr at_hint;
 
 		at_hint.s_node = 0;
 		at_hint.s_net  = at->src_net;
@@ -1762,18 +1810,17 @@
 {
 	struct sock *sk = sock->sk;
 	struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;
-	struct ddpehdr *ddp = NULL;
+	struct ddpehdr *ddp;
 	int copied = 0;
 	int err = 0;
         struct ddpebits ddphv;
-	struct sk_buff *skb;
-
-	skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
-				flags & MSG_DONTWAIT, &err);
+	struct sk_buff *skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
+						flags & MSG_DONTWAIT, &err);
 	if (!skb)
 		return err;
 
-	ddp = (struct ddpehdr *)(skb->h.raw);
+	/* FIXME: use skb->cb to be able to use shared skbs */
+	ddp = ddp_hdr(skb);
 	*((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp));
 
 	if (sk->type == SOCK_RAW) {
@@ -1791,7 +1838,7 @@
 			msg->msg_flags |= MSG_TRUNC;
 		}
 		err = skb_copy_datagram_iovec(skb, sizeof(*ddp),
-						msg->msg_iov, copied);
+					      msg->msg_iov, copied);
 	}
 
 	if (!err) {
@@ -1805,65 +1852,69 @@
 	}
 
 	skb_free_datagram(sk, skb);	/* Free the datagram. */
-	return err ? err : copied;
+	return err ? : copied;
 }
 
 
 /*
  * AppleTalk ioctl calls.
  */
-static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
+static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
-	long amount = 0;
+	int rc = -EINVAL;
 	struct sock *sk = sock->sk;
 
 	switch (cmd) {
 		/* Protocol layer */
-		case TIOCOUTQ:
-			amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
+		case TIOCOUTQ: {
+			long amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
+
 			if (amount < 0)
 				amount = 0;
+			rc = put_user(amount, (int *)arg);
 			break;
-		case TIOCINQ:
-		{
-			/* These two are safe on a single CPU system as only
-			 * user tasks fiddle here */
+		}
+		case TIOCINQ: {
+			/*
+			 * These two are safe on a single CPU system as only
+			 * user tasks fiddle here
+			 */
 			struct sk_buff *skb = skb_peek(&sk->receive_queue);
+			long amount = 0;
 
 			if (skb)
-				amount = skb->len-sizeof(struct ddpehdr);
+				amount = skb->len - sizeof(struct ddpehdr);
+			rc = put_user(amount, (int *)arg);
 			break;
 		}
 		case SIOCGSTAMP:
 			if (!sk)
-				return -EINVAL;
+				break;
+			rc = -ENOENT;
 			if (!sk->stamp.tv_sec)
-				return -ENOENT;
-			return copy_to_user((void *)arg, &sk->stamp,
-					sizeof(struct timeval)) ? -EFAULT : 0;
+				break;
+			rc = copy_to_user((void *)arg, &sk->stamp,
+					  sizeof(struct timeval)) ? -EFAULT : 0;
+			break;
 		/* Routing */
 		case SIOCADDRT:
 		case SIOCDELRT:
-			if (!capable(CAP_NET_ADMIN))
-				return -EPERM;
-			return atrtr_ioctl(cmd, (void *)arg);
+			rc = -EPERM;
+			if (capable(CAP_NET_ADMIN))
+				rc = atrtr_ioctl(cmd, (void *)arg);
+			break;
 		/* Interface */
 		case SIOCGIFADDR:
 		case SIOCSIFADDR:
 		case SIOCGIFBRDADDR:
 		case SIOCATALKDIFADDR:
 		case SIOCDIFADDR:
-		case SIOCSARP:	/* proxy AARP */
-		case SIOCDARP:	/* proxy AARP */
-		{
-			int ret;
-
+		case SIOCSARP:		/* proxy AARP */
+		case SIOCDARP:		/* proxy AARP */
 			rtnl_lock();
-			ret = atif_ioctl(cmd, (void *)arg);
+			rc = atif_ioctl(cmd, (void *)arg);
 			rtnl_unlock();
-
-			return ret;
-		}
+			break;
 		/* Physical layer ioctl calls */
 		case SIOCSIFLINK:
 		case SIOCGIFHWADDR:
@@ -1877,79 +1928,56 @@
 		case SIOCGIFCOUNT:
 		case SIOCGIFINDEX:
 		case SIOCGIFNAME:
-			return dev_ioctl(cmd,(void *) arg);
-		case SIOCSIFMETRIC:
-		case SIOCSIFBRDADDR:
-		case SIOCGIFNETMASK:
-		case SIOCSIFNETMASK:
-		case SIOCGIFMEM:
-		case SIOCSIFMEM:
-		case SIOCGIFDSTADDR:
-		case SIOCSIFDSTADDR:
-			return -EINVAL;
-		default:
-			return -EINVAL;
+			rc = dev_ioctl(cmd, (void *)arg);
+			break;
 	}
 
-	return put_user(amount, (int *)arg);
+	return rc;
 }
 
 static struct net_proto_family atalk_family_ops = {
-	family:	PF_APPLETALK,
-	create:	atalk_create,
+	.family		= PF_APPLETALK,
+	.create		= atalk_create,
 };
 
-static struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops)=
-{
-	family:		PF_APPLETALK,
-
-	release:	atalk_release,
-	bind:		atalk_bind,
-	connect:	atalk_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		sock_no_accept,
-	getname:	atalk_getname,
-	poll:		datagram_poll,
-	ioctl:		atalk_ioctl,
-	listen:		sock_no_listen,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	sock_no_setsockopt,
-	getsockopt:	sock_no_getsockopt,
-	sendmsg:	atalk_sendmsg,
-	recvmsg:	atalk_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+static struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
+	.family		= PF_APPLETALK,
+	.release	= atalk_release,
+	.bind		= atalk_bind,
+	.connect	= atalk_connect,
+	.socketpair	= sock_no_socketpair,
+	.accept		= sock_no_accept,
+	.getname	= atalk_getname,
+	.poll		= datagram_poll,
+	.ioctl		= atalk_ioctl,
+	.listen		= sock_no_listen,
+	.shutdown	= sock_no_shutdown,
+	.setsockopt	= sock_no_setsockopt,
+	.getsockopt	= sock_no_getsockopt,
+	.sendmsg	= atalk_sendmsg,
+	.recvmsg	= atalk_recvmsg,
+	.mmap		= sock_no_mmap,
+	.sendpage	= sock_no_sendpage,
 };
 
 #include <linux/smp_lock.h>
 SOCKOPS_WRAP(atalk_dgram, PF_APPLETALK);
 
-static struct notifier_block ddp_notifier=
-{
-	ddp_device_event,
-	NULL,
-	0
+static struct notifier_block ddp_notifier = {
+	.notifier_call	= ddp_device_event,
 };
 
-struct packet_type ltalk_packet_type=
-{
-	0,
-	NULL,
-	ltalk_rcv,
-	NULL,
-	NULL
+struct packet_type ltalk_packet_type = {
+	.type		= __constant_htons(ETH_P_LOCALTALK),
+	.func		= ltalk_rcv,
 };
 
-struct packet_type ppptalk_packet_type=
-{
-	0,
-	NULL,
-	atalk_rcv,
-	NULL,
-	NULL
+struct packet_type ppptalk_packet_type = {
+	.type		= __constant_htons(ETH_P_PPPTALK),
+	.func		= atalk_rcv,
 };
 
-static char ddp_snap_id[] = {0x08, 0x00, 0x07, 0x80, 0x9B};
+static unsigned char ddp_snap_id[] = { 0x08, 0x00, 0x07, 0x80, 0x9B };
 
 /* Export symbols for use by drivers when AppleTalk is a module */
 EXPORT_SYMBOL(aarp_send_ddp);
@@ -1959,15 +1987,12 @@
 /* Called by proto.c on kernel start up */
 static int __init atalk_init(void)
 {
-	(void) sock_register(&atalk_family_ops);
+	(void)sock_register(&atalk_family_ops);
 	ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv);
 	if (!ddp_dl)
 		printk(KERN_CRIT "Unable to register DDP with SNAP.\n");
 
-	ltalk_packet_type.type = htons(ETH_P_LOCALTALK);
 	dev_add_pack(&ltalk_packet_type);
-
-	ppptalk_packet_type.type = htons(ETH_P_PPPTALK);
 	dev_add_pack(&ppptalk_packet_type);
 
 	register_netdevice_notifier(&ddp_notifier);
@@ -2020,4 +2045,3 @@
 }
 module_exit(atalk_exit);
 #endif  /* MODULE */
-#endif  /* CONFIG_ATALK || CONFIG_ATALK_MODULE */
diff -Nru a/net/appletalk/sysctl_net_atalk.c b/net/appletalk/sysctl_net_atalk.c
--- a/net/appletalk/sysctl_net_atalk.c	Sat Aug 10 18:42:21 2002
+++ b/net/appletalk/sysctl_net_atalk.c	Sat Aug 10 18:42:21 2002
@@ -1,4 +1,4 @@
-/* -*- linux-c -*-
+/*
  * sysctl_net_atalk.c: sysctl interface to net AppleTalk subsystem.
  *
  * Begun April 1, 1996, Mike Shaver.
@@ -17,25 +17,59 @@
 
 #ifdef CONFIG_SYSCTL
 static ctl_table atalk_table[] = {
-	{NET_ATALK_AARP_EXPIRY_TIME, "aarp-expiry-time",
-	 &sysctl_aarp_expiry_time, sizeof(int), 0644, NULL, &proc_dointvec_jiffies},
-	{NET_ATALK_AARP_TICK_TIME, "aarp-tick-time",
-	 &sysctl_aarp_tick_time, sizeof(int), 0644, NULL, &proc_dointvec_jiffies},
-	{NET_ATALK_AARP_RETRANSMIT_LIMIT, "aarp-retransmit-limit",
-	 &sysctl_aarp_retransmit_limit, sizeof(int), 0644, NULL, &proc_dointvec},
-	{NET_ATALK_AARP_RESOLVE_TIME, "aarp-resolve-time",
-	 &sysctl_aarp_resolve_time, sizeof(int), 0644, NULL, &proc_dointvec_jiffies},
-	{0}
+	{
+		.ctl_name	= NET_ATALK_AARP_EXPIRY_TIME,
+		.procname	= "aarp-expiry-time",
+		.data		= &sysctl_aarp_expiry_time,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+	},
+	{
+		.ctl_name	= NET_ATALK_AARP_TICK_TIME,
+		.procname	= "aarp-tick-time",
+		.data		= &sysctl_aarp_tick_time,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+	},
+	{
+		.ctl_name	= NET_ATALK_AARP_RETRANSMIT_LIMIT,
+		.procname	= "aarp-retransmit-limit",
+		.data		= &sysctl_aarp_retransmit_limit,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{
+		.ctl_name	= NET_ATALK_AARP_RESOLVE_TIME,
+		.procname	= "aarp-resolve-time",
+		.data		= &sysctl_aarp_resolve_time,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec_jiffies,
+	},
+	{ 0 },
 };
 
 static ctl_table atalk_dir_table[] = {
-	{NET_ATALK, "appletalk", NULL, 0, 0555, atalk_table},
-	{0}
+	{
+		.ctl_name	= NET_ATALK,
+		.procname	= "appletalk",
+		.mode		= 0555,
+		.child		= atalk_table,
+	},
+	{ 0 },
 };
 
 static ctl_table atalk_root_table[] = {
-	{CTL_NET, "net", NULL, 0, 0555, atalk_dir_table},
-	{0}
+	{
+		.ctl_name	= CTL_NET,
+		.procname	= "net",
+		.mode		= 0555,
+		.child		= atalk_dir_table,
+	},
+	{ 0 },
 };
 
 static struct ctl_table_header *atalk_table_header;
diff -Nru a/net/atm/clip.c b/net/atm/clip.c
--- a/net/atm/clip.c	Sat Aug 10 18:42:22 2002
+++ b/net/atm/clip.c	Sat Aug 10 18:42:22 2002
@@ -274,14 +274,14 @@
 
 
 static struct neigh_ops clip_neigh_ops = {
-	family:			AF_INET,
-	destructor:		clip_neigh_destroy,
-	solicit:		clip_neigh_solicit,
-	error_report:		clip_neigh_error,
-	output:			dev_queue_xmit,
-	connected_output:	dev_queue_xmit,
-	hh_output:		dev_queue_xmit,
-	queue_xmit:		dev_queue_xmit,
+	.family =		AF_INET,
+	.destructor =		clip_neigh_destroy,
+	.solicit =		clip_neigh_solicit,
+	.error_report =		clip_neigh_error,
+	.output =		dev_queue_xmit,
+	.connected_output =	dev_queue_xmit,
+	.hh_output =		dev_queue_xmit,
+	.queue_xmit =		dev_queue_xmit,
 };
 
 
@@ -699,7 +699,7 @@
 
 
 static struct atmdev_ops atmarpd_dev_ops = {
-	close:	atmarpd_close,
+	.close =atmarpd_close,
 };
 
 
diff -Nru a/net/atm/mpc.c b/net/atm/mpc.c
--- a/net/atm/mpc.c	Sat Aug 10 18:42:22 2002
+++ b/net/atm/mpc.c	Sat Aug 10 18:42:22 2002
@@ -736,8 +736,8 @@
 }
 
 static struct atmdev_ops mpc_ops = { /* only send is required */
-	close:	mpoad_close,
-	send:	msg_from_mpoad
+	.close =mpoad_close,
+	.send =	msg_from_mpoad
 };
 
 static struct atm_dev mpc_dev = {
diff -Nru a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c
--- a/net/atm/mpoa_proc.c	Sat Aug 10 18:42:23 2002
+++ b/net/atm/mpoa_proc.c	Sat Aug 10 18:42:23 2002
@@ -42,8 +42,8 @@
  *   Define allowed FILE OPERATIONS
  */
 static struct file_operations mpc_file_operations = {
-	read:		proc_mpc_read,
-	write:		proc_mpc_write,
+	.read =		proc_mpc_read,
+	.write =	proc_mpc_write,
 };
 
 static int print_header(char *buff,struct mpoa_client *mpc){
diff -Nru a/net/atm/pppoatm.c b/net/atm/pppoatm.c
--- a/net/atm/pppoatm.c	Sat Aug 10 18:42:23 2002
+++ b/net/atm/pppoatm.c	Sat Aug 10 18:42:23 2002
@@ -266,8 +266,8 @@
 }
 
 static /*const*/ struct ppp_channel_ops pppoatm_ops = {
-	start_xmit: pppoatm_send,
-	ioctl: pppoatm_devppp_ioctl,
+	.start_xmit = pppoatm_send,
+	.ioctl = pppoatm_devppp_ioctl,
 };
 
 static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, unsigned long arg)
diff -Nru a/net/atm/proc.c b/net/atm/proc.c
--- a/net/atm/proc.c	Sat Aug 10 18:42:22 2002
+++ b/net/atm/proc.c	Sat Aug 10 18:42:22 2002
@@ -57,11 +57,11 @@
     loff_t *pos);
 
 static struct file_operations proc_dev_atm_operations = {
-	read:		proc_dev_atm_read,
+	.read =		proc_dev_atm_read,
 };
 
 static struct file_operations proc_spec_atm_operations = {
-	read:		proc_spec_atm_read,
+	.read =		proc_spec_atm_read,
 };
 
 static void add_stats(char *buf,const char *aal,
diff -Nru a/net/atm/pvc.c b/net/atm/pvc.c
--- a/net/atm/pvc.c	Sat Aug 10 18:42:22 2002
+++ b/net/atm/pvc.c	Sat Aug 10 18:42:22 2002
@@ -78,24 +78,24 @@
 
 
 static struct proto_ops SOCKOPS_WRAPPED(pvc_proto_ops) = {
-	family:		PF_ATMPVC,
+	.family =	PF_ATMPVC,
 
-	release:	atm_release,
-	bind:		pvc_bind,
-	connect:	pvc_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		sock_no_accept,
-	getname:	pvc_getname,
-	poll:		atm_poll,
-	ioctl:		atm_ioctl,
-	listen:		sock_no_listen,
-	shutdown:	pvc_shutdown,
-	setsockopt:	atm_setsockopt,
-	getsockopt:	atm_getsockopt,
-	sendmsg:	atm_sendmsg,
-	recvmsg:	atm_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	atm_release,
+	.bind =		pvc_bind,
+	.connect =	pvc_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	sock_no_accept,
+	.getname =	pvc_getname,
+	.poll =		atm_poll,
+	.ioctl =	atm_ioctl,
+	.listen =	sock_no_listen,
+	.shutdown =	pvc_shutdown,
+	.setsockopt =	atm_setsockopt,
+	.getsockopt =	atm_getsockopt,
+	.sendmsg =	atm_sendmsg,
+	.recvmsg =	atm_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 
@@ -111,8 +111,8 @@
 
 
 static struct net_proto_family pvc_family_ops = {
-	family:	PF_ATMPVC,
-	create:	pvc_create,
+	.family =PF_ATMPVC,
+	.create =pvc_create,
 };
 
 
diff -Nru a/net/atm/signaling.c b/net/atm/signaling.c
--- a/net/atm/signaling.c	Sat Aug 10 18:42:23 2002
+++ b/net/atm/signaling.c	Sat Aug 10 18:42:23 2002
@@ -227,8 +227,8 @@
 
 
 static struct atmdev_ops sigd_dev_ops = {
-	close:	sigd_close,
-	send:	sigd_send
+	.close =sigd_close,
+	.send =	sigd_send
 };
 
 
diff -Nru a/net/atm/svc.c b/net/atm/svc.c
--- a/net/atm/svc.c	Sat Aug 10 18:42:23 2002
+++ b/net/atm/svc.c	Sat Aug 10 18:42:23 2002
@@ -391,24 +391,24 @@
 
 
 static struct proto_ops SOCKOPS_WRAPPED(svc_proto_ops) = {
-	family:		PF_ATMSVC,
+	.family =	PF_ATMSVC,
 
-	release:	svc_release,
-	bind:		svc_bind,
-	connect:	svc_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		svc_accept,
-	getname:	svc_getname,
-	poll:		atm_poll,
-	ioctl:		atm_ioctl,
-	listen:		svc_listen,
-	shutdown:	svc_shutdown,
-	setsockopt:	svc_setsockopt,
-	getsockopt:	svc_getsockopt,
-	sendmsg:	atm_sendmsg,
-	recvmsg:	atm_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	svc_release,
+	.bind =		svc_bind,
+	.connect =	svc_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	svc_accept,
+	.getname =	svc_getname,
+	.poll =		atm_poll,
+	.ioctl =	atm_ioctl,
+	.listen =	svc_listen,
+	.shutdown =	svc_shutdown,
+	.setsockopt =	svc_setsockopt,
+	.getsockopt =	svc_getsockopt,
+	.sendmsg =	atm_sendmsg,
+	.recvmsg =	atm_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 
@@ -430,8 +430,8 @@
 
 
 static struct net_proto_family svc_family_ops = {
-	family:	PF_ATMSVC,
-	create:	svc_create,
+	.family =PF_ATMSVC,
+	.create =svc_create,
 };
 
 
diff -Nru a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
--- a/net/ax25/af_ax25.c	Sat Aug 10 18:42:23 2002
+++ b/net/ax25/af_ax25.c	Sat Aug 10 18:42:23 2002
@@ -1810,29 +1810,29 @@
 }
 
 static struct net_proto_family ax25_family_ops = {
-	family:		PF_AX25,
-	create:		ax25_create,
+	.family =	PF_AX25,
+	.create =	ax25_create,
 };
 
 static struct proto_ops SOCKOPS_WRAPPED(ax25_proto_ops) = {
-	family:		PF_AX25,
+	.family =	PF_AX25,
 
-	release:	ax25_release,
-	bind:		ax25_bind,
-	connect:	ax25_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		ax25_accept,
-	getname:	ax25_getname,
-	poll:		datagram_poll,
-	ioctl:		ax25_ioctl,
-	listen:		ax25_listen,
-	shutdown:	ax25_shutdown,
-	setsockopt:	ax25_setsockopt,
-	getsockopt:	ax25_getsockopt,
-	sendmsg:	ax25_sendmsg,
-	recvmsg:	ax25_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	ax25_release,
+	.bind =		ax25_bind,
+	.connect =	ax25_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	ax25_accept,
+	.getname =	ax25_getname,
+	.poll =		datagram_poll,
+	.ioctl =	ax25_ioctl,
+	.listen =	ax25_listen,
+	.shutdown =	ax25_shutdown,
+	.setsockopt =	ax25_setsockopt,
+	.getsockopt =	ax25_getsockopt,
+	.sendmsg =	ax25_sendmsg,
+	.recvmsg =	ax25_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 #include <linux/smp_lock.h>
@@ -1842,12 +1842,12 @@
  *	Called by socket.c on kernel start up
  */
 static struct packet_type ax25_packet_type = {
-	type:		__constant_htons(ETH_P_AX25),
-	func:		ax25_kiss_rcv,
+	.type =		__constant_htons(ETH_P_AX25),
+	.func =		ax25_kiss_rcv,
 };
 
 static struct notifier_block ax25_dev_notifier = {
-	notifier_call:	ax25_device_event,
+	.notifier_call =ax25_device_event,
 };
 
 EXPORT_SYMBOL(ax25_encapsulate);
diff -Nru a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
--- a/net/bluetooth/hci_sock.c	Sat Aug 10 18:42:23 2002
+++ b/net/bluetooth/hci_sock.c	Sat Aug 10 18:42:23 2002
@@ -80,7 +80,7 @@
 };
 
 static struct bluez_sock_list hci_sk_list = {
-	lock: RW_LOCK_UNLOCKED
+	.lock = RW_LOCK_UNLOCKED
 };
 
 /* Send frame to RAW socket */
@@ -522,22 +522,22 @@
 }
 
 struct proto_ops hci_sock_ops = {
-	family:		PF_BLUETOOTH,
-	release:	hci_sock_release,
-	bind:		hci_sock_bind,
-	getname:	hci_sock_getname,
-	sendmsg:	hci_sock_sendmsg,
-	recvmsg:	hci_sock_recvmsg,
-	ioctl:		hci_sock_ioctl,
-	poll:		datagram_poll,
-	listen:		sock_no_listen,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	hci_sock_setsockopt,
-	getsockopt:	hci_sock_getsockopt,
-	connect:	sock_no_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		sock_no_accept,
-	mmap:		sock_no_mmap
+	.family =	PF_BLUETOOTH,
+	.release =	hci_sock_release,
+	.bind =		hci_sock_bind,
+	.getname =	hci_sock_getname,
+	.sendmsg =	hci_sock_sendmsg,
+	.recvmsg =	hci_sock_recvmsg,
+	.ioctl =	hci_sock_ioctl,
+	.poll =		datagram_poll,
+	.listen =	sock_no_listen,
+	.shutdown =	sock_no_shutdown,
+	.setsockopt =	hci_sock_setsockopt,
+	.getsockopt =	hci_sock_getsockopt,
+	.connect =	sock_no_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	sock_no_accept,
+	.mmap =		sock_no_mmap
 };
 
 static int hci_sock_create(struct socket *sock, int protocol)
@@ -600,12 +600,12 @@
 }
 
 struct net_proto_family hci_sock_family_ops = {
-	family: PF_BLUETOOTH,
-	create: hci_sock_create
+	.family = PF_BLUETOOTH,
+	.create = hci_sock_create
 };
 
 struct notifier_block hci_sock_nblock = {
-	notifier_call: hci_sock_dev_event
+	.notifier_call = hci_sock_dev_event
 };
 
 int hci_sock_init(void)
diff -Nru a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
--- a/net/bluetooth/l2cap.c	Sat Aug 10 18:42:23 2002
+++ b/net/bluetooth/l2cap.c	Sat Aug 10 18:42:23 2002
@@ -64,7 +64,7 @@
 static struct proto_ops l2cap_sock_ops;
 
 struct bluez_sock_list l2cap_sk_list = {
-	lock: RW_LOCK_UNLOCKED
+	.lock = RW_LOCK_UNLOCKED
 };
 
 static int l2cap_conn_del(struct hci_conn *conn, int err);
@@ -1973,38 +1973,38 @@
 }
 
 static struct proto_ops l2cap_sock_ops = {
-	family:		PF_BLUETOOTH,
-	release:	l2cap_sock_release,
-	bind:		l2cap_sock_bind,
-	connect:	l2cap_sock_connect,
-	listen:		l2cap_sock_listen,
-	accept:		l2cap_sock_accept,
-	getname:	l2cap_sock_getname,
-	sendmsg:	l2cap_sock_sendmsg,
-	recvmsg:	bluez_sock_recvmsg,
-	poll:		bluez_sock_poll,
-	socketpair:	sock_no_socketpair,
-	ioctl:		sock_no_ioctl,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	l2cap_sock_setsockopt,
-	getsockopt:	l2cap_sock_getsockopt,
-	mmap:		sock_no_mmap
+	.family =	PF_BLUETOOTH,
+	.release =	l2cap_sock_release,
+	.bind =		l2cap_sock_bind,
+	.connect =	l2cap_sock_connect,
+	.listen =	l2cap_sock_listen,
+	.accept =	l2cap_sock_accept,
+	.getname =	l2cap_sock_getname,
+	.sendmsg =	l2cap_sock_sendmsg,
+	.recvmsg =	bluez_sock_recvmsg,
+	.poll =		bluez_sock_poll,
+	.socketpair =	sock_no_socketpair,
+	.ioctl =	sock_no_ioctl,
+	.shutdown =	sock_no_shutdown,
+	.setsockopt =	l2cap_sock_setsockopt,
+	.getsockopt =	l2cap_sock_getsockopt,
+	.mmap =		sock_no_mmap
 };
 
 static struct net_proto_family l2cap_sock_family_ops = {
-	family:		PF_BLUETOOTH,
-	create:		l2cap_sock_create
+	.family =	PF_BLUETOOTH,
+	.create =	l2cap_sock_create
 };
 
 static struct hci_proto l2cap_hci_proto = {
-	name:		"L2CAP",
-	id:		HCI_PROTO_L2CAP,
-	connect_ind:	l2cap_connect_ind,
-	connect_cfm:	l2cap_connect_cfm,
-	disconn_ind:	l2cap_disconn_ind,
-	recv_acldata:	l2cap_recv_acldata,
-	auth_cfm:	l2cap_auth_cfm,
-	encrypt_cfm:	l2cap_encrypt_cfm
+	.name =		"L2CAP",
+	.id =		HCI_PROTO_L2CAP,
+	.connect_ind =	l2cap_connect_ind,
+	.connect_cfm =	l2cap_connect_cfm,
+	.disconn_ind =	l2cap_disconn_ind,
+	.recv_acldata =	l2cap_recv_acldata,
+	.auth_cfm =	l2cap_auth_cfm,
+	.encrypt_cfm =	l2cap_encrypt_cfm
 };
 
 int __init l2cap_init(void)
diff -Nru a/net/bluetooth/sco.c b/net/bluetooth/sco.c
--- a/net/bluetooth/sco.c	Sat Aug 10 18:42:21 2002
+++ b/net/bluetooth/sco.c	Sat Aug 10 18:42:21 2002
@@ -64,7 +64,7 @@
 static struct proto_ops sco_sock_ops;
 
 static struct bluez_sock_list sco_sk_list = {
-	lock: RW_LOCK_UNLOCKED
+	.lock = RW_LOCK_UNLOCKED
 };
 
 static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
@@ -936,36 +936,36 @@
 }
 
 static struct proto_ops sco_sock_ops = {
-	family:		PF_BLUETOOTH,
-	release:	sco_sock_release,
-	bind:		sco_sock_bind,
-	connect:	sco_sock_connect,
-	listen:		sco_sock_listen,
-	accept:		sco_sock_accept,
-	getname:	sco_sock_getname,
-	sendmsg:	sco_sock_sendmsg,
-	recvmsg:	bluez_sock_recvmsg,
-	poll:		bluez_sock_poll,
-	socketpair:	sock_no_socketpair,
-	ioctl:		sock_no_ioctl,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	sco_sock_setsockopt,
-	getsockopt:	sco_sock_getsockopt,
-	mmap:		sock_no_mmap
+	.family =	PF_BLUETOOTH,
+	.release =	sco_sock_release,
+	.bind =		sco_sock_bind,
+	.connect =	sco_sock_connect,
+	.listen =	sco_sock_listen,
+	.accept =	sco_sock_accept,
+	.getname =	sco_sock_getname,
+	.sendmsg =	sco_sock_sendmsg,
+	.recvmsg =	bluez_sock_recvmsg,
+	.poll =		bluez_sock_poll,
+	.socketpair =	sock_no_socketpair,
+	.ioctl =	sock_no_ioctl,
+	.shutdown =	sock_no_shutdown,
+	.setsockopt =	sco_sock_setsockopt,
+	.getsockopt =	sco_sock_getsockopt,
+	.mmap =		sock_no_mmap
 };
 
 static struct net_proto_family sco_sock_family_ops = {
-	family:		PF_BLUETOOTH,
-	create:		sco_sock_create
+	.family =	PF_BLUETOOTH,
+	.create =	sco_sock_create
 };
 
 static struct hci_proto sco_hci_proto = {
-	name:		"SCO",
-	id:		HCI_PROTO_SCO,
-	connect_ind:	sco_connect_ind,
-	connect_cfm:	sco_connect_cfm,
-	disconn_ind:	sco_disconn_ind,
-	recv_scodata:	sco_recv_scodata,
+	.name =		"SCO",
+	.id =		HCI_PROTO_SCO,
+	.connect_ind =	sco_connect_ind,
+	.connect_cfm =	sco_connect_cfm,
+	.disconn_ind =	sco_disconn_ind,
+	.recv_scodata =	sco_recv_scodata,
 };
 
 int __init sco_init(void)
diff -Nru a/net/core/datagram.c b/net/core/datagram.c
--- a/net/core/datagram.c	Sat Aug 10 18:42:23 2002
+++ b/net/core/datagram.c	Sat Aug 10 18:42:23 2002
@@ -204,8 +204,8 @@
 int skb_copy_datagram(const struct sk_buff *skb, int offset, char *to, int size)
 {
 	struct iovec iov = {
-		iov_base: to,
-		iov_len:  size,
+		.iov_base = to,
+		.iov_len =size,
 	};
 
 	return skb_copy_datagram_iovec(skb, offset, &iov, size);
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	Sat Aug 10 18:42:23 2002
+++ b/net/core/dev.c	Sat Aug 10 18:42:23 2002
@@ -2427,13 +2427,13 @@
  *	will not get the same name.
  */
 
-static int net_dev_init(void);
-
 int register_netdevice(struct net_device *dev)
 {
 	struct net_device *d, **dp;
 	int ret;
 
+	BUG_ON(dev_boot_phase);
+
 	spin_lock_init(&dev->queue_lock);
 	spin_lock_init(&dev->xmit_lock);
 	dev->xmit_lock_owner = -1;
@@ -2441,9 +2441,6 @@
 	dev->fastpath_lock = RW_LOCK_UNLOCKED;
 #endif
 
-	if (dev_boot_phase)
-		net_dev_init();
-
 #ifdef CONFIG_NET_DIVERT
 	ret = alloc_divert_blk(dev);
 	if (ret)
@@ -2552,6 +2549,8 @@
 	unsigned long now, warning_time;
 	struct net_device *d, **dp;
 
+	BUG_ON(dev_boot_phase);
+
 	/* If device is running, close it first. */
 	if (dev->flags & IFF_UP)
 		dev_close(dev);
@@ -2578,26 +2577,25 @@
 	br_write_lock_bh(BR_NETPROTO_LOCK);
 	br_write_unlock_bh(BR_NETPROTO_LOCK);
 
-	if (!dev_boot_phase) {
+
 #ifdef CONFIG_NET_FASTROUTE
-		dev_clear_fastroute(dev);
+	dev_clear_fastroute(dev);
 #endif
 
-		/* Shutdown queueing discipline. */
-		dev_shutdown(dev);
-
-		net_run_sbin_hotplug(dev, "unregister");
-
-		/* Notify protocols, that we are about to destroy
-		   this device. They should clean all the things.
-		 */
-		notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
-
-		/*
-		 *	Flush the multicast chain
-		 */
-		dev_mc_discard(dev);
-	}
+	/* Shutdown queueing discipline. */
+	dev_shutdown(dev);
+	
+	net_run_sbin_hotplug(dev, "unregister");
+	
+	/* Notify protocols, that we are about to destroy
+	   this device. They should clean all the things.
+	*/
+	notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
+	
+	/*
+	 *	Flush the multicast chain
+	 */
+	dev_mc_discard(dev);
 
 	if (dev->uninit)
 		dev->uninit(dev);
@@ -2690,17 +2688,15 @@
 
 
 /*
- *       Callers must hold the rtnl semaphore.  See the comment at the
- *       end of Space.c for details about the locking.
+ *       This is called single threaded during boot, so no need
+ *       to take the rtnl semaphore.
  */
 static int __init net_dev_init(void)
 {
 	struct net_device *dev, **dp;
 	int i;
 
-	if (!dev_boot_phase)
-		return 0;
-
+	BUG_ON(!dev_boot_phase);
 
 #ifdef CONFIG_NET_DIVERT
 	dv_init();
@@ -2834,7 +2830,7 @@
 	return 0;
 }
 
-__initcall(net_dev_init);
+subsys_initcall(net_dev_init);
 
 #ifdef CONFIG_HOTPLUG
 
diff -Nru a/net/core/ext8022.c b/net/core/ext8022.c
--- a/net/core/ext8022.c	Sat Aug 10 18:42:23 2002
+++ b/net/core/ext8022.c	Sat Aug 10 18:42:23 2002
@@ -25,12 +25,12 @@
 static int llc_users;
 
 static struct packet_type llc_packet_type = {
-	type:	__constant_htons(ETH_P_802_2),
-	func:	llc_rcv,
+	.type =	__constant_htons(ETH_P_802_2),
+	.func =	llc_rcv,
 };
 static struct packet_type llc_tr_packet_type = {
-	type:	__constant_htons(ETH_P_TR_802_2),
-	func:	llc_rcv,
+	.type =	__constant_htons(ETH_P_TR_802_2),
+	.func =	llc_rcv,
 };
 
 static int llc_rcv(struct sk_buff *skb, struct net_device *dev,
diff -Nru a/net/core/neighbour.c b/net/core/neighbour.c
--- a/net/core/neighbour.c	Sat Aug 10 18:42:20 2002
+++ b/net/core/neighbour.c	Sat Aug 10 18:42:20 2002
@@ -1471,143 +1471,143 @@
 	ctl_table		neigh_proto_dir[2];
 	ctl_table		neigh_root_dir[2];
 } neigh_sysctl_template = {
-	neigh_vars: {
+	.neigh_vars = {
 		{
-			ctl_name:	NET_NEIGH_MCAST_SOLICIT,
-			procname:	"mcast_solicit",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_NEIGH_MCAST_SOLICIT,
+			.procname =	"mcast_solicit",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_NEIGH_UCAST_SOLICIT,
-			procname:	"ucast_solicit",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_NEIGH_UCAST_SOLICIT,
+			.procname =	"ucast_solicit",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_NEIGH_APP_SOLICIT,
-			procname:	"app_solicit",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_NEIGH_APP_SOLICIT,
+			.procname =	"app_solicit",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_NEIGH_RETRANS_TIME,
-			procname:	"retrans_time",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_NEIGH_RETRANS_TIME,
+			.procname =	"retrans_time",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_NEIGH_REACHABLE_TIME,
-			procname:	"base_reachable_time",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec_jiffies,
+			.ctl_name =	NET_NEIGH_REACHABLE_TIME,
+			.procname =	"base_reachable_time",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec_jiffies,
 		},
 		{
-			ctl_name:	NET_NEIGH_DELAY_PROBE_TIME,
-			procname:	"delay_first_probe_time",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec_jiffies,
+			.ctl_name =	NET_NEIGH_DELAY_PROBE_TIME,
+			.procname =	"delay_first_probe_time",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec_jiffies,
 		},
 		{
-			ctl_name:	NET_NEIGH_GC_STALE_TIME,
-			procname:	"gc_stale_time",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec_jiffies,
+			.ctl_name =	NET_NEIGH_GC_STALE_TIME,
+			.procname =	"gc_stale_time",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec_jiffies,
 		},
 		{
-			ctl_name:	NET_NEIGH_UNRES_QLEN,
-			procname:	"unres_qlen",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_NEIGH_UNRES_QLEN,
+			.procname =	"unres_qlen",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_NEIGH_PROXY_QLEN,
-			procname:	"proxy_qlen",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_NEIGH_PROXY_QLEN,
+			.procname =	"proxy_qlen",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_NEIGH_ANYCAST_DELAY,
-			procname:	"anycast_delay",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_NEIGH_ANYCAST_DELAY,
+			.procname =	"anycast_delay",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_NEIGH_PROXY_DELAY,
-			procname:	"proxy_delay",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_NEIGH_PROXY_DELAY,
+			.procname =	"proxy_delay",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_NEIGH_LOCKTIME,
-			procname:	"locktime",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_NEIGH_LOCKTIME,
+			.procname =	"locktime",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_NEIGH_GC_INTERVAL,
-			procname:	"gc_interval",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec_jiffies,
+			.ctl_name =	NET_NEIGH_GC_INTERVAL,
+			.procname =	"gc_interval",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec_jiffies,
 		},
 		{
-			ctl_name:	NET_NEIGH_GC_THRESH1,
-			procname:	"gc_thresh1",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_NEIGH_GC_THRESH1,
+			.procname =	"gc_thresh1",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_NEIGH_GC_THRESH2,
-			procname:	"gc_thresh2",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_NEIGH_GC_THRESH2,
+			.procname =	"gc_thresh2",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_NEIGH_GC_THRESH3,
-			procname:	"gc_thresh3",
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_NEIGH_GC_THRESH3,
+			.procname =	"gc_thresh3",
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 	},
-	neigh_dev: {
+	.neigh_dev = {
 		{
-			ctl_name:	NET_PROTO_CONF_DEFAULT,
-			procname:	"default",
-			mode:		0555,
+			.ctl_name =	NET_PROTO_CONF_DEFAULT,
+			.procname =	"default",
+			.mode =	0555,
 		},
 	},
-	neigh_neigh_dir: {
+	.neigh_neigh_dir = {
 		{
-			procname:	"neigh",
-			mode:		0555,
+			.procname =	"neigh",
+			.mode =	0555,
 		},
 	},
-	neigh_proto_dir: {
+	.neigh_proto_dir = {
 		{
-			mode:		0555,
+			.mode =	0555,
 		},
 	},
-	neigh_root_dir: {
+	.neigh_root_dir = {
 		{
-			ctl_name:	CTL_NET,
-			procname:	"net",
-			mode:		0555,
+			.ctl_name =	CTL_NET,
+			.procname =	"net",
+			.mode =	0555,
 		},
 	},
 };
diff -Nru a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
--- a/net/decnet/af_decnet.c	Sat Aug 10 18:42:23 2002
+++ b/net/decnet/af_decnet.c	Sat Aug 10 18:42:23 2002
@@ -2098,16 +2098,16 @@
 }
 
 static struct notifier_block dn_dev_notifier = {
-	notifier_call:	dn_device_event,
+	.notifier_call =dn_device_event,
 };
 
 extern int dn_route_rcv(struct sk_buff *, struct net_device *, struct packet_type *);
 
 static struct packet_type dn_dix_packet_type = {
-	type:		__constant_htons(ETH_P_DNA_RT),
-	dev:		NULL,		/* All devices */
-	func:		dn_route_rcv,
-	data:		(void*)1,
+	.type =		__constant_htons(ETH_P_DNA_RT),
+	.dev =		NULL,		/* All devices */
+	.func =		dn_route_rcv,
+	.data =		(void*)1,
 };
 
 #define IS_NOT_PRINTABLE(x) ((x) < 32 || (x) > 126)
@@ -2196,29 +2196,29 @@
 
 
 static struct net_proto_family	dn_family_ops = {
-	family:		AF_DECnet,
-	create:		dn_create,
+	.family =	AF_DECnet,
+	.create =	dn_create,
 };
 
 static struct proto_ops dn_proto_ops = {
-	family:		AF_DECnet,
+	.family =	AF_DECnet,
 
-	release:	dn_release,
-	bind:		dn_bind,
-	connect:	dn_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		dn_accept,
-	getname:	dn_getname,
-	poll:		dn_poll,
-	ioctl:		dn_ioctl,
-	listen:		dn_listen,
-	shutdown:	dn_shutdown,
-	setsockopt:	dn_setsockopt,
-	getsockopt:	dn_getsockopt,
-	sendmsg:	dn_sendmsg,
-	recvmsg:	dn_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	dn_release,
+	.bind =		dn_bind,
+	.connect =	dn_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	dn_accept,
+	.getname =	dn_getname,
+	.poll =		dn_poll,
+	.ioctl =	dn_ioctl,
+	.listen =	dn_listen,
+	.shutdown =	dn_shutdown,
+	.setsockopt =	dn_setsockopt,
+	.getsockopt =	dn_getsockopt,
+	.sendmsg =	dn_sendmsg,
+	.recvmsg =	dn_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 #ifdef CONFIG_SYSCTL
diff -Nru a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
--- a/net/decnet/dn_dev.c	Sat Aug 10 18:42:22 2002
+++ b/net/decnet/dn_dev.c	Sat Aug 10 18:42:22 2002
@@ -66,77 +66,77 @@
 
 static struct dn_dev_parms dn_dev_list[] =  {
 {
-	type:		ARPHRD_ETHER, /* Ethernet */
-	mode:		DN_DEV_BCAST,
-	state:		DN_DEV_S_RU,
-	blksize:	1498,
-	t2:		1,
-	t3:		10,
-	name:		"ethernet",
-	ctl_name:	NET_DECNET_CONF_ETHER,
-	up:		dn_eth_up,
-	timer3:		dn_send_brd_hello,
+	.type =		ARPHRD_ETHER, /* Ethernet */
+	.mode =		DN_DEV_BCAST,
+	.state =	DN_DEV_S_RU,
+	.blksize =	1498,
+	.t2 =		1,
+	.t3 =		10,
+	.name =		"ethernet",
+	.ctl_name =	NET_DECNET_CONF_ETHER,
+	.up =		dn_eth_up,
+	.timer3 =	dn_send_brd_hello,
 },
 {
-	type:		ARPHRD_IPGRE, /* DECnet tunneled over GRE in IP */
-	mode:		DN_DEV_BCAST,
-	state:		DN_DEV_S_RU,
-	blksize:	1400,
-	t2:		1,
-	t3:		10,
-	name:		"ipgre",
-	ctl_name:	NET_DECNET_CONF_GRE,
-	timer3:		dn_send_brd_hello,
+	.type =		ARPHRD_IPGRE, /* DECnet tunneled over GRE in IP */
+	.mode =		DN_DEV_BCAST,
+	.state =	DN_DEV_S_RU,
+	.blksize =	1400,
+	.t2 =		1,
+	.t3 =		10,
+	.name =		"ipgre",
+	.ctl_name =	NET_DECNET_CONF_GRE,
+	.timer3 =	dn_send_brd_hello,
 },
 #if 0
 {
-	type:		ARPHRD_X25, /* Bog standard X.25 */
-	mode:		DN_DEV_UCAST,
-	state:		DN_DEV_S_DS,
-	blksize:	230,
-	t2:		1,
-	t3:		120,
-	name:		"x25",
-	ctl_name:	NET_DECNET_CONF_X25,
-	timer3:		dn_send_ptp_hello,
+	.type =		ARPHRD_X25, /* Bog standard X.25 */
+	.mode =		DN_DEV_UCAST,
+	.state =	DN_DEV_S_DS,
+	.blksize =	230,
+	.t2 =		1,
+	.t3 =		120,
+	.name =		"x25",
+	.ctl_name =	NET_DECNET_CONF_X25,
+	.timer3 =	dn_send_ptp_hello,
 },
 #endif
 #if 0
 {
-	type:		ARPHRD_PPP, /* DECnet over PPP */
-	mode:		DN_DEV_BCAST,
-	state:		DN_DEV_S_RU,
-	blksize:	230,
-	t2:		1,
-	t3:		10,
-	name:		"ppp",
-	ctl_name:	NET_DECNET_CONF_PPP,
-	timer3:		dn_send_brd_hello,
+	.type =		ARPHRD_PPP, /* DECnet over PPP */
+	.mode =		DN_DEV_BCAST,
+	.state =	DN_DEV_S_RU,
+	.blksize =	230,
+	.t2 =		1,
+	.t3 =		10,
+	.name =		"ppp",
+	.ctl_name =	NET_DECNET_CONF_PPP,
+	.timer3 =	dn_send_brd_hello,
 },
 #endif
 #if 0
 {
-	type:		ARPHRD_DDCMP, /* DECnet over DDCMP */
-	mode:		DN_DEV_UCAST,
-	state:		DN_DEV_S_DS,
-	blksize:	230,
-	t2:		1,
-	t3:		120,
-	name:		"ddcmp",
-	ctl_name:	NET_DECNET_CONF_DDCMP,
-	timer3:		dn_send_ptp_hello,
+	.type =		ARPHRD_DDCMP, /* DECnet over DDCMP */
+	.mode =		DN_DEV_UCAST,
+	.state =	DN_DEV_S_DS,
+	.blksize =	230,
+	.t2 =		1,
+	.t3 =		120,
+	.name =		"ddcmp",
+	.ctl_name =	NET_DECNET_CONF_DDCMP,
+	.timer3 =	dn_send_ptp_hello,
 },
 #endif
 {
-	type:		ARPHRD_LOOPBACK, /* Loopback interface - always last */
-	mode:		DN_DEV_BCAST,
-	state:		DN_DEV_S_RU,
-	blksize:	1498,
-	t2:		1,
-	t3:		10,
-	name:		"loopback",
-	ctl_name:	NET_DECNET_CONF_LOOPBACK,
-	timer3:		dn_send_brd_hello,
+	.type =		ARPHRD_LOOPBACK, /* Loopback interface - always last */
+	.mode =		DN_DEV_BCAST,
+	.state =	DN_DEV_S_RU,
+	.blksize =	1498,
+	.t2 =		1,
+	.t3 =		10,
+	.name =		"loopback",
+	.ctl_name =	NET_DECNET_CONF_LOOPBACK,
+	.timer3 =	dn_send_brd_hello,
 }
 };
 
diff -Nru a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
--- a/net/decnet/dn_neigh.c	Sat Aug 10 18:42:23 2002
+++ b/net/decnet/dn_neigh.c	Sat Aug 10 18:42:23 2002
@@ -54,66 +54,66 @@
  * For talking to broadcast devices: Ethernet & PPP
  */
 static struct neigh_ops dn_long_ops = {
-	family:			AF_DECnet,
-	error_report:		dn_long_error_report,
-	output:			dn_long_output,
-	connected_output:	dn_long_output,
-	hh_output:		dev_queue_xmit,
-	queue_xmit:		dev_queue_xmit,
+	.family =		AF_DECnet,
+	.error_report =		dn_long_error_report,
+	.output =		dn_long_output,
+	.connected_output =	dn_long_output,
+	.hh_output =		dev_queue_xmit,
+	.queue_xmit =		dev_queue_xmit,
 };
 
 /*
  * For talking to pointopoint and multidrop devices: DDCMP and X.25
  */
 static struct neigh_ops dn_short_ops = {
-	family:			AF_DECnet,
-	error_report:		dn_short_error_report,
-	output:			dn_short_output,
-	connected_output:	dn_short_output,
-	hh_output:		dev_queue_xmit,
-	queue_xmit:		dev_queue_xmit,
+	.family =		AF_DECnet,
+	.error_report =		dn_short_error_report,
+	.output =		dn_short_output,
+	.connected_output =	dn_short_output,
+	.hh_output =		dev_queue_xmit,
+	.queue_xmit =		dev_queue_xmit,
 };
 
 /*
  * For talking to DECnet phase III nodes
  */
 static struct neigh_ops dn_phase3_ops = {
-	family:			AF_DECnet,
-	error_report:		dn_short_error_report, /* Can use short version here */
-	output:			dn_phase3_output,
-	connected_output:	dn_phase3_output,
-	hh_output:		dev_queue_xmit,
-	queue_xmit:		dev_queue_xmit
+	.family =		AF_DECnet,
+	.error_report =		dn_short_error_report, /* Can use short version here */
+	.output =		dn_phase3_output,
+	.connected_output =	dn_phase3_output,
+	.hh_output =		dev_queue_xmit,
+	.queue_xmit =		dev_queue_xmit
 };
 
 struct neigh_table dn_neigh_table = {
-	family:				PF_DECnet,
-	entry_size:			sizeof(struct dn_neigh),
-	key_len:			sizeof(dn_address),
-	hash:				dn_neigh_hash,
-	constructor:			dn_neigh_construct,
-	id:				"dn_neigh_cache",
-	parms:	{
-		tbl:			&dn_neigh_table,
-		entries:		0,
-		base_reachable_time:	30 * HZ,
-		retrans_time:		1 * HZ,
-		gc_staletime:		60 * HZ,
-		reachable_time:		30 * HZ,
-		delay_probe_time:	5 * HZ,
-		queue_len:		3,
-		ucast_probes:		0,
-		app_probes:		0,
-		mcast_probes:		0,
-		anycast_delay:		0,
-		proxy_delay:		0,
-		proxy_qlen:		0,
-		locktime:		1 * HZ,
+	.family =			PF_DECnet,
+	.entry_size =			sizeof(struct dn_neigh),
+	.key_len =			sizeof(dn_address),
+	.hash =				dn_neigh_hash,
+	.constructor =			dn_neigh_construct,
+	.id =				"dn_neigh_cache",
+	.parms ={
+		.tbl =			&dn_neigh_table,
+		.entries =		0,
+		.base_reachable_time =	30 * HZ,
+		.retrans_time =	1 * HZ,
+		.gc_staletime =	60 * HZ,
+		.reachable_time =		30 * HZ,
+		.delay_probe_time =	5 * HZ,
+		.queue_len =		3,
+		.ucast_probes =	0,
+		.app_probes =		0,
+		.mcast_probes =	0,
+		.anycast_delay =	0,
+		.proxy_delay =		0,
+		.proxy_qlen =		0,
+		.locktime =		1 * HZ,
 	},
-	gc_interval:			30 * HZ,
-	gc_thresh1:			128,
-	gc_thresh2:			512,
-	gc_thresh3:			1024,
+	.gc_interval =			30 * HZ,
+	.gc_thresh1 =			128,
+	.gc_thresh2 =			512,
+	.gc_thresh3 =			1024,
 };
 
 static u32 dn_neigh_hash(const void *pkey, const struct net_device *dev)
diff -Nru a/net/decnet/dn_route.c b/net/decnet/dn_route.c
--- a/net/decnet/dn_route.c	Sat Aug 10 18:42:23 2002
+++ b/net/decnet/dn_route.c	Sat Aug 10 18:42:23 2002
@@ -112,16 +112,16 @@
 int decnet_dst_gc_interval = 2;
 
 static struct dst_ops dn_dst_ops = {
-	family:			PF_DECnet,
-	protocol:		__constant_htons(ETH_P_DNA_RT),
-	gc_thresh:		128,
-	gc:			dn_dst_gc,
-	check:			dn_dst_check,
-	reroute:		dn_dst_reroute,
-	negative_advice:	dn_dst_negative_advice,
-	link_failure:		dn_dst_link_failure,
-	entry_size:		sizeof(struct dn_route),
-	entries:		ATOMIC_INIT(0),
+	.family =		PF_DECnet,
+	.protocol =		__constant_htons(ETH_P_DNA_RT),
+	.gc_thresh =		128,
+	.gc =			dn_dst_gc,
+	.check =		dn_dst_check,
+	.reroute =		dn_dst_reroute,
+	.negative_advice =	dn_dst_negative_advice,
+	.link_failure =		dn_dst_link_failure,
+	.entry_size =		sizeof(struct dn_route),
+	.entries =		ATOMIC_INIT(0),
 };
 
 static __inline__ unsigned dn_hash(unsigned short src, unsigned short dst)
diff -Nru a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
--- a/net/decnet/dn_rules.c	Sat Aug 10 18:42:21 2002
+++ b/net/decnet/dn_rules.c	Sat Aug 10 18:42:21 2002
@@ -58,10 +58,10 @@
 };
 
 static struct dn_fib_rule default_rule = {
-	r_clntref:		ATOMIC_INIT(2),
-	r_preference:		0x7fff,
-	r_table:		DN_DEFAULT_TABLE,
-	r_action:		RTN_UNICAST
+	.r_clntref =		ATOMIC_INIT(2),
+	.r_preference =		0x7fff,
+	.r_table =		DN_DEFAULT_TABLE,
+	.r_action =		RTN_UNICAST
 };
 
 static struct dn_fib_rule *dn_fib_rules = &default_rule;
@@ -296,7 +296,7 @@
 
 
 static struct notifier_block dn_fib_rules_notifier = {
-	notifier_call:		dn_fib_rules_event,
+	.notifier_call =	dn_fib_rules_event,
 };
 
 static int dn_fib_fill_rule(struct sk_buff *skb, struct dn_fib_rule *r, struct netlink_callback *cb)
diff -Nru a/net/econet/af_econet.c b/net/econet/af_econet.c
--- a/net/econet/af_econet.c	Sat Aug 10 18:42:22 2002
+++ b/net/econet/af_econet.c	Sat Aug 10 18:42:23 2002
@@ -697,29 +697,29 @@
 }
 
 static struct net_proto_family econet_family_ops = {
-	family:		PF_ECONET,
-	create:		econet_create,
+	.family =	PF_ECONET,
+	.create =	econet_create,
 };
 
 static struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
-	family:		PF_ECONET,
+	.family =	PF_ECONET,
 
-	release:	econet_release,
-	bind:		econet_bind,
-	connect:	sock_no_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		sock_no_accept,
-	getname:	econet_getname, 
-	poll:		datagram_poll,
-	ioctl:		econet_ioctl,
-	listen:		sock_no_listen,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	sock_no_setsockopt,
-	getsockopt:	sock_no_getsockopt,
-	sendmsg:	econet_sendmsg,
-	recvmsg:	econet_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	econet_release,
+	.bind =		econet_bind,
+	.connect =	sock_no_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	sock_no_accept,
+	.getname =	econet_getname, 
+	.poll =		datagram_poll,
+	.ioctl =	econet_ioctl,
+	.listen =	sock_no_listen,
+	.shutdown =	sock_no_shutdown,
+	.setsockopt =	sock_no_setsockopt,
+	.getsockopt =	sock_no_getsockopt,
+	.sendmsg =	econet_sendmsg,
+	.recvmsg =	econet_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 #include <linux/smp_lock.h>
@@ -1068,8 +1068,8 @@
 }
 
 static struct packet_type econet_packet_type = {
-	type:		__constant_htons(ETH_P_ECONET),
-	func:		econet_rcv,
+	.type =		__constant_htons(ETH_P_ECONET),
+	.func =		econet_rcv,
 };
 
 static void econet_hw_initialise(void)
@@ -1103,7 +1103,7 @@
 }
 
 static struct notifier_block econet_netdev_notifier = {
-	notifier_call:	econet_notifier,
+	.notifier_call =econet_notifier,
 };
 
 static void __exit econet_proto_exit(void)
diff -Nru a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
--- a/net/ipv4/af_inet.c	Sat Aug 10 18:42:21 2002
+++ b/net/ipv4/af_inet.c	Sat Aug 10 18:42:21 2002
@@ -972,50 +972,50 @@
 }
 
 struct proto_ops inet_stream_ops = {
-	family:		PF_INET,
+	.family =	PF_INET,
 
-	release:	inet_release,
-	bind:		inet_bind,
-	connect:	inet_stream_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		inet_accept,
-	getname:	inet_getname,
-	poll:		tcp_poll,
-	ioctl:		inet_ioctl,
-	listen:		inet_listen,
-	shutdown:	inet_shutdown,
-	setsockopt:	inet_setsockopt,
-	getsockopt:	inet_getsockopt,
-	sendmsg:	inet_sendmsg,
-	recvmsg:	inet_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	tcp_sendpage
+	.release =	inet_release,
+	.bind =		inet_bind,
+	.connect =	inet_stream_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	inet_accept,
+	.getname =	inet_getname,
+	.poll =		tcp_poll,
+	.ioctl =	inet_ioctl,
+	.listen =	inet_listen,
+	.shutdown =	inet_shutdown,
+	.setsockopt =	inet_setsockopt,
+	.getsockopt =	inet_getsockopt,
+	.sendmsg =	inet_sendmsg,
+	.recvmsg =	inet_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	tcp_sendpage
 };
 
 struct proto_ops inet_dgram_ops = {
-	family:		PF_INET,
+	.family =	PF_INET,
 
-	release:	inet_release,
-	bind:		inet_bind,
-	connect:	inet_dgram_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		sock_no_accept,
-	getname:	inet_getname,
-	poll:		datagram_poll,
-	ioctl:		inet_ioctl,
-	listen:		sock_no_listen,
-	shutdown:	inet_shutdown,
-	setsockopt:	inet_setsockopt,
-	getsockopt:	inet_getsockopt,
-	sendmsg:	inet_sendmsg,
-	recvmsg:	inet_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	inet_release,
+	.bind =		inet_bind,
+	.connect =	inet_dgram_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	sock_no_accept,
+	.getname =	inet_getname,
+	.poll =		datagram_poll,
+	.ioctl =	inet_ioctl,
+	.listen =	sock_no_listen,
+	.shutdown =	inet_shutdown,
+	.setsockopt =	inet_setsockopt,
+	.getsockopt =	inet_getsockopt,
+	.sendmsg =	inet_sendmsg,
+	.recvmsg =	inet_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 struct net_proto_family inet_family_ops = {
-	family:	 PF_INET,
-	create:	 inet_create,
+	.family = PF_INET,
+	.create = inet_create,
 };
 
 
@@ -1028,34 +1028,34 @@
 static struct inet_protosw inetsw_array[] =
 {
         {
-                type:        SOCK_STREAM,
-                protocol:    IPPROTO_TCP,
-                prot:        &tcp_prot,
-                ops:         &inet_stream_ops,
-                capability:  -1,
-                no_check:    0,
-                flags:       INET_PROTOSW_PERMANENT,
+                .type =       SOCK_STREAM,
+                .protocol =   IPPROTO_TCP,
+                .prot =       &tcp_prot,
+                .ops =        &inet_stream_ops,
+                .capability = -1,
+                .no_check =   0,
+                .flags =      INET_PROTOSW_PERMANENT,
         },
 
         {
-                type:        SOCK_DGRAM,
-                protocol:    IPPROTO_UDP,
-                prot:        &udp_prot,
-                ops:         &inet_dgram_ops,
-                capability:  -1,
-                no_check:    UDP_CSUM_DEFAULT,
-                flags:       INET_PROTOSW_PERMANENT,
+                .type =       SOCK_DGRAM,
+                .protocol =   IPPROTO_UDP,
+                .prot =       &udp_prot,
+                .ops =        &inet_dgram_ops,
+                .capability = -1,
+                .no_check =   UDP_CSUM_DEFAULT,
+                .flags =      INET_PROTOSW_PERMANENT,
        },
         
 
        {
-               type:        SOCK_RAW,
-               protocol:    IPPROTO_IP,	/* wild card */
-               prot:        &raw_prot,
-               ops:         &inet_dgram_ops,
-               capability:  CAP_NET_RAW,
-               no_check:    UDP_CSUM_DEFAULT,
-               flags:       INET_PROTOSW_REUSE,
+               .type =       SOCK_RAW,
+               .protocol =   IPPROTO_IP,	/* wild card */
+               .prot =       &raw_prot,
+               .ops =        &inet_dgram_ops,
+               .capability = CAP_NET_RAW,
+               .no_check =   UDP_CSUM_DEFAULT,
+               .flags =      INET_PROTOSW_REUSE,
        }
 };
 
diff -Nru a/net/ipv4/arp.c b/net/ipv4/arp.c
--- a/net/ipv4/arp.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipv4/arp.c	Sat Aug 10 18:42:23 2002
@@ -124,70 +124,70 @@
 static void parp_redo(struct sk_buff *skb);
 
 static struct neigh_ops arp_generic_ops = {
-	family:			AF_INET,
-	solicit:		arp_solicit,
-	error_report:		arp_error_report,
-	output:			neigh_resolve_output,
-	connected_output:	neigh_connected_output,
-	hh_output:		dev_queue_xmit,
-	queue_xmit:		dev_queue_xmit,
+	.family =		AF_INET,
+	.solicit =		arp_solicit,
+	.error_report =		arp_error_report,
+	.output =		neigh_resolve_output,
+	.connected_output =	neigh_connected_output,
+	.hh_output =		dev_queue_xmit,
+	.queue_xmit =		dev_queue_xmit,
 };
 
 static struct neigh_ops arp_hh_ops = {
-	family:			AF_INET,
-	solicit:		arp_solicit,
-	error_report:		arp_error_report,
-	output:			neigh_resolve_output,
-	connected_output:	neigh_resolve_output,
-	hh_output:		dev_queue_xmit,
-	queue_xmit:		dev_queue_xmit,
+	.family =		AF_INET,
+	.solicit =		arp_solicit,
+	.error_report =		arp_error_report,
+	.output =		neigh_resolve_output,
+	.connected_output =	neigh_resolve_output,
+	.hh_output =		dev_queue_xmit,
+	.queue_xmit =		dev_queue_xmit,
 };
 
 static struct neigh_ops arp_direct_ops = {
-	family:			AF_INET,
-	output:			dev_queue_xmit,
-	connected_output:	dev_queue_xmit,
-	hh_output:		dev_queue_xmit,
-	queue_xmit:		dev_queue_xmit,
+	.family =		AF_INET,
+	.output =		dev_queue_xmit,
+	.connected_output =	dev_queue_xmit,
+	.hh_output =		dev_queue_xmit,
+	.queue_xmit =		dev_queue_xmit,
 };
 
 struct neigh_ops arp_broken_ops = {
-	family:			AF_INET,
-	solicit:		arp_solicit,
-	error_report:		arp_error_report,
-	output:			neigh_compat_output,
-	connected_output:	neigh_compat_output,
-	hh_output:		dev_queue_xmit,
-	queue_xmit:		dev_queue_xmit,
+	.family =		AF_INET,
+	.solicit =		arp_solicit,
+	.error_report =		arp_error_report,
+	.output =		neigh_compat_output,
+	.connected_output =	neigh_compat_output,
+	.hh_output =		dev_queue_xmit,
+	.queue_xmit =		dev_queue_xmit,
 };
 
 struct neigh_table arp_tbl = {
-	family:		AF_INET,
-	entry_size:	sizeof(struct neighbour) + 4,
-	key_len:	4,
-	hash:		arp_hash,
-	constructor:	arp_constructor,
-	proxy_redo:	parp_redo,
-	id:		"arp_cache",
-	parms: {
-		tbl:			&arp_tbl,
-		base_reachable_time:	30 * HZ,
-		retrans_time:		1 * HZ,
-		gc_staletime:		60 * HZ,
-		reachable_time:		30 * HZ,
-		delay_probe_time:	5 * HZ,
-		queue_len:		3,
-		ucast_probes:		3,
-		mcast_probes:		3,
-		anycast_delay:		1 * HZ,
-		proxy_delay:		(8 * HZ) / 10,
-		proxy_qlen:		64,
-		locktime:		1 * HZ,
+	.family =	AF_INET,
+	.entry_size =	sizeof(struct neighbour) + 4,
+	.key_len =	4,
+	.hash =		arp_hash,
+	.constructor =	arp_constructor,
+	.proxy_redo =	parp_redo,
+	.id =		"arp_cache",
+	.parms = {
+		.tbl =			&arp_tbl,
+		.base_reachable_time =	30 * HZ,
+		.retrans_time =	1 * HZ,
+		.gc_staletime =	60 * HZ,
+		.reachable_time =		30 * HZ,
+		.delay_probe_time =	5 * HZ,
+		.queue_len =		3,
+		.ucast_probes =	3,
+		.mcast_probes =	3,
+		.anycast_delay =	1 * HZ,
+		.proxy_delay =		(8 * HZ) / 10,
+		.proxy_qlen =		64,
+		.locktime =		1 * HZ,
 	},
-	gc_interval:	30 * HZ,
-	gc_thresh1:	128,
-	gc_thresh2:	512,
-	gc_thresh3:	1024,
+	.gc_interval =	30 * HZ,
+	.gc_thresh1 =	128,
+	.gc_thresh2 =	512,
+	.gc_thresh3 =	1024,
 };
 
 int arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir)
@@ -1180,9 +1180,9 @@
  */
 
 static struct packet_type arp_packet_type = {
-	type:	__constant_htons(ETH_P_ARP),
-	func:	arp_rcv,
-	data:	(void*) 1, /* understand shared skbs */
+	.type =	__constant_htons(ETH_P_ARP),
+	.func =	arp_rcv,
+	.data =	(void*) 1, /* understand shared skbs */
 };
 
 void __init arp_init (void)
diff -Nru a/net/ipv4/devinet.c b/net/ipv4/devinet.c
--- a/net/ipv4/devinet.c	Sat Aug 10 18:42:21 2002
+++ b/net/ipv4/devinet.c	Sat Aug 10 18:42:21 2002
@@ -62,18 +62,18 @@
 #include <net/ip_fib.h>
 
 struct ipv4_devconf ipv4_devconf = {
-	accept_redirects: 1,
-	send_redirects:	  1,
-	secure_redirects: 1,
-	shared_media:	  1,
+	.accept_redirects = 1,
+	.send_redirects =  1,
+	.secure_redirects = 1,
+	.shared_media =	  1,
 };
 
 static struct ipv4_devconf ipv4_devconf_dflt = {
-	accept_redirects:    1,
-	send_redirects:      1,
-	secure_redirects:    1,
-	shared_media:	     1,
-	accept_source_route: 1,
+	.accept_redirects =  1,
+	.send_redirects =    1,
+	.secure_redirects =  1,
+	.shared_media =	     1,
+	.accept_source_route = 1,
 };
 
 static void rtmsg_ifa(int event, struct in_ifaddr *);
@@ -886,7 +886,7 @@
 }
 
 struct notifier_block ip_netdev_notifier = {
-	notifier_call:	inetdev_event,
+	.notifier_call =inetdev_event,
 };
 
 static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
@@ -1047,150 +1047,150 @@
 	ctl_table		devinet_proto_dir[2];
 	ctl_table		devinet_root_dir[2];
 } devinet_sysctl = {
-	devinet_vars: {
+	.devinet_vars = {
 		{
-			ctl_name:	NET_IPV4_CONF_FORWARDING,
-			procname:	"forwarding",
-			data:		&ipv4_devconf.forwarding,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&devinet_sysctl_forward,
+			.ctl_name =	NET_IPV4_CONF_FORWARDING,
+			.procname =	"forwarding",
+			.data =	&ipv4_devconf.forwarding,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&devinet_sysctl_forward,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_MC_FORWARDING,
-			procname:	"mc_forwarding",
-			data:		&ipv4_devconf.mc_forwarding,
-			maxlen:		sizeof(int),
-			mode:		0444,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_MC_FORWARDING,
+			.procname =	"mc_forwarding",
+			.data =	&ipv4_devconf.mc_forwarding,
+			.maxlen =		sizeof(int),
+			.mode =	0444,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_ACCEPT_REDIRECTS,
-			procname:	"accept_redirects",
-			data:		&ipv4_devconf.accept_redirects,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_ACCEPT_REDIRECTS,
+			.procname =	"accept_redirects",
+			.data =	&ipv4_devconf.accept_redirects,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_SECURE_REDIRECTS,
-			procname:	"secure_redirects",
-			data:		&ipv4_devconf.secure_redirects,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_SECURE_REDIRECTS,
+			.procname =	"secure_redirects",
+			.data =	&ipv4_devconf.secure_redirects,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_SHARED_MEDIA,
-			procname:	"shared_media",
-			data:		&ipv4_devconf.shared_media,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_SHARED_MEDIA,
+			.procname =	"shared_media",
+			.data =	&ipv4_devconf.shared_media,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_RP_FILTER,
-			procname:	"rp_filter",
-			data:		&ipv4_devconf.rp_filter,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_RP_FILTER,
+			.procname =	"rp_filter",
+			.data =	&ipv4_devconf.rp_filter,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_SEND_REDIRECTS,
-			procname:	"send_redirects",
-			data:		&ipv4_devconf.send_redirects,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_SEND_REDIRECTS,
+			.procname =	"send_redirects",
+			.data =	&ipv4_devconf.send_redirects,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE,
-			procname:	"accept_source_route",
-			data:		&ipv4_devconf.accept_source_route,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE,
+			.procname =	"accept_source_route",
+			.data =	&ipv4_devconf.accept_source_route,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_PROXY_ARP,
-			procname:	"proxy_arp",
-			data:		&ipv4_devconf.proxy_arp,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_PROXY_ARP,
+			.procname =	"proxy_arp",
+			.data =	&ipv4_devconf.proxy_arp,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_MEDIUM_ID,
-			procname:	"medium_id",
-			data:		&ipv4_devconf.medium_id,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_MEDIUM_ID,
+			.procname =	"medium_id",
+			.data =	&ipv4_devconf.medium_id,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_BOOTP_RELAY,
-			procname:	"bootp_relay",
-			data:		&ipv4_devconf.bootp_relay,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_BOOTP_RELAY,
+			.procname =	"bootp_relay",
+			.data =	&ipv4_devconf.bootp_relay,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_LOG_MARTIANS,
-			procname:	"log_martians",
-			data:		&ipv4_devconf.log_martians,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_LOG_MARTIANS,
+			.procname =	"log_martians",
+			.data =	&ipv4_devconf.log_martians,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_TAG,
-			procname:	"tag",
-			data:		&ipv4_devconf.tag,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_TAG,
+			.procname =	"tag",
+			.data =	&ipv4_devconf.tag,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 		{
-			ctl_name:	NET_IPV4_CONF_ARPFILTER,
-			procname:	"arp_filter",
-			data:		&ipv4_devconf.arp_filter,
-			maxlen:		sizeof(int),
-			mode:		0644,
-			proc_handler:	&proc_dointvec,
+			.ctl_name =	NET_IPV4_CONF_ARPFILTER,
+			.procname =	"arp_filter",
+			.data =	&ipv4_devconf.arp_filter,
+			.maxlen =		sizeof(int),
+			.mode =	0644,
+			.proc_handler =&proc_dointvec,
 		},
 	},
-	devinet_dev: {
+	.devinet_dev = {
 		{
-			ctl_name:	NET_PROTO_CONF_ALL,
-			procname:	"all",
-			mode:		0555,
-			child:		devinet_sysctl.devinet_vars,
+			.ctl_name =	NET_PROTO_CONF_ALL,
+			.procname =	"all",
+			.mode =	0555,
+			.child =		devinet_sysctl.devinet_vars,
 		},
 	},
-	devinet_conf_dir: {
+	.devinet_conf_dir = {
 	        {
-			ctl_name:	NET_IPV4_CONF,
-			procname:	"conf",
-			mode:		0555,
-			child:		devinet_sysctl.devinet_dev,
+			.ctl_name =	NET_IPV4_CONF,
+			.procname =	"conf",
+			.mode =	0555,
+			.child =		devinet_sysctl.devinet_dev,
 		},
 	},
-	devinet_proto_dir: {
+	.devinet_proto_dir = {
 		{
-			ctl_name:	NET_IPV4,
-			procname:	"ipv4",
-			mode:		0555,
-			child:		devinet_sysctl.devinet_conf_dir,
+			.ctl_name =	NET_IPV4,
+			.procname =	"ipv4",
+			.mode =	0555,
+			.child =		devinet_sysctl.devinet_conf_dir,
 		},
 	},
-	devinet_root_dir: {
+	.devinet_root_dir = {
 		{
-			ctl_name:	CTL_NET,
-			procname:	"net",
-			mode:		0555,
-			child:		devinet_sysctl.devinet_proto_dir,
+			.ctl_name =	CTL_NET,
+			.procname =	"net",
+			.mode =	0555,
+			.child =		devinet_sysctl.devinet_proto_dir,
 		},
 	},
 };
diff -Nru a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
--- a/net/ipv4/fib_frontend.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipv4/fib_frontend.c	Sat Aug 10 18:42:23 2002
@@ -634,11 +634,11 @@
 }
 
 struct notifier_block fib_inetaddr_notifier = {
-	notifier_call:	fib_inetaddr_event,
+	.notifier_call =fib_inetaddr_event,
 };
 
 struct notifier_block fib_netdev_notifier = {
-	notifier_call:	fib_netdev_event,
+	.notifier_call =fib_netdev_event,
 };
 
 void __init ip_fib_init(void)
diff -Nru a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
--- a/net/ipv4/fib_rules.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipv4/fib_rules.c	Sat Aug 10 18:42:23 2002
@@ -77,25 +77,25 @@
 };
 
 static struct fib_rule default_rule = {
-	r_clntref:	ATOMIC_INIT(2),
-	r_preference:	0x7FFF,
-	r_table:	RT_TABLE_DEFAULT,
-	r_action:	RTN_UNICAST,
+	.r_clntref =	ATOMIC_INIT(2),
+	.r_preference =	0x7FFF,
+	.r_table =	RT_TABLE_DEFAULT,
+	.r_action =	RTN_UNICAST,
 };
 
 static struct fib_rule main_rule = {
-	r_next:		&default_rule,
-	r_clntref:	ATOMIC_INIT(2),
-	r_preference:	0x7FFE,
-	r_table:	RT_TABLE_MAIN,
-	r_action:	RTN_UNICAST,
+	.r_next =	&default_rule,
+	.r_clntref =	ATOMIC_INIT(2),
+	.r_preference =	0x7FFE,
+	.r_table =	RT_TABLE_MAIN,
+	.r_action =	RTN_UNICAST,
 };
 
 static struct fib_rule local_rule = {
-	r_next:		&main_rule,
-	r_clntref:	ATOMIC_INIT(2),
-	r_table:	RT_TABLE_LOCAL,
-	r_action:	RTN_UNICAST,
+	.r_next =	&main_rule,
+	.r_clntref =	ATOMIC_INIT(2),
+	.r_table =	RT_TABLE_LOCAL,
+	.r_action =	RTN_UNICAST,
 };
 
 static struct fib_rule *fib_rules = &local_rule;
@@ -392,7 +392,7 @@
 
 
 struct notifier_block fib_rules_notifier = {
-	notifier_call:	fib_rules_event,
+	.notifier_call =fib_rules_event,
 };
 
 static __inline__ int inet_fill_rule(struct sk_buff *skb,
diff -Nru a/net/ipv4/icmp.c b/net/ipv4/icmp.c
--- a/net/ipv4/icmp.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipv4/icmp.c	Sat Aug 10 18:42:23 2002
@@ -121,68 +121,68 @@
 
 struct icmp_err icmp_err_convert[] = {
 	{
-		errno:	ENETUNREACH,	/* ICMP_NET_UNREACH */
-		fatal:	0,
+		.errno =ENETUNREACH,	/* ICMP_NET_UNREACH */
+		.fatal =0,
 	},
 	{
-		errno:	EHOSTUNREACH,	/* ICMP_HOST_UNREACH */
-		fatal:	0,
+		.errno =EHOSTUNREACH,	/* ICMP_HOST_UNREACH */
+		.fatal =0,
 	},
 	{
-		errno:	ENOPROTOOPT	/* ICMP_PROT_UNREACH */,
-		fatal:	1,
+		.errno =ENOPROTOOPT	/* ICMP_PROT_UNREACH */,
+		.fatal =1,
 	},
 	{
-		errno:	ECONNREFUSED,	/* ICMP_PORT_UNREACH */
-		fatal:	1,
+		.errno =ECONNREFUSED,	/* ICMP_PORT_UNREACH */
+		.fatal =1,
 	},
 	{
-		errno:	EMSGSIZE,	/* ICMP_FRAG_NEEDED */
-		fatal:	0,
+		.errno =EMSGSIZE,	/* ICMP_FRAG_NEEDED */
+		.fatal =0,
 	},
 	{
-		errno:	EOPNOTSUPP,	/* ICMP_SR_FAILED */
-		fatal:	0,
+		.errno =EOPNOTSUPP,	/* ICMP_SR_FAILED */
+		.fatal =0,
 	},
 	{
-		errno:	ENETUNREACH,	/* ICMP_NET_UNKNOWN */
-		fatal:	1,
+		.errno =ENETUNREACH,	/* ICMP_NET_UNKNOWN */
+		.fatal =1,
 	},
 	{
-		errno:	EHOSTDOWN,	/* ICMP_HOST_UNKNOWN */
-		fatal:	1,
+		.errno =EHOSTDOWN,	/* ICMP_HOST_UNKNOWN */
+		.fatal =1,
 	},
 	{
-		errno:	ENONET,		/* ICMP_HOST_ISOLATED */
-		fatal:	1,
+		.errno =ENONET,		/* ICMP_HOST_ISOLATED */
+		.fatal =1,
 	},
 	{
-		errno:	ENETUNREACH,	/* ICMP_NET_ANO	*/
-		fatal:	1,
+		.errno =ENETUNREACH,	/* ICMP_NET_ANO	*/
+		.fatal =1,
 	},
 	{
-		errno:	EHOSTUNREACH,	/* ICMP_HOST_ANO */
-		fatal:	1,
+		.errno =EHOSTUNREACH,	/* ICMP_HOST_ANO */
+		.fatal =1,
 	},
 	{
-		errno:	ENETUNREACH,	/* ICMP_NET_UNR_TOS */
-		fatal:	0,
+		.errno =ENETUNREACH,	/* ICMP_NET_UNR_TOS */
+		.fatal =0,
 	},
 	{
-		errno:	EHOSTUNREACH,	/* ICMP_HOST_UNR_TOS */
-		fatal:	0,
+		.errno =EHOSTUNREACH,	/* ICMP_HOST_UNR_TOS */
+		.fatal =0,
 	},
 	{
-		errno:	EHOSTUNREACH,	/* ICMP_PKT_FILTERED */
-		fatal:	1,
+		.errno =EHOSTUNREACH,	/* ICMP_PKT_FILTERED */
+		.fatal =1,
 	},
 	{
-		errno:	EHOSTUNREACH,	/* ICMP_PREC_VIOLATION */
-		fatal:	1,
+		.errno =EHOSTUNREACH,	/* ICMP_PREC_VIOLATION */
+		.fatal =1,
 	},
 	{
-		errno:	EHOSTUNREACH,	/* ICMP_PREC_CUTOFF */
-		fatal:	1,
+		.errno =EHOSTUNREACH,	/* ICMP_PREC_CUTOFF */
+		.fatal =1,
 	},
 };
 
@@ -1022,123 +1022,123 @@
 static struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = {
 	/* ECHO REPLY (0) */
 	[0] = {
-		output:	 &icmp_statistics[0].IcmpOutEchoReps,
-		input:	 &icmp_statistics[0].IcmpInEchoReps,
-		handler: icmp_discard,
+		.output =	 &icmp_statistics[0].IcmpOutEchoReps,
+		.input = &icmp_statistics[0].IcmpInEchoReps,
+		.handler = icmp_discard,
 	},
 	[1] = {
-		output:	 &icmp_statistics[0].dummy,
-		input:	 &icmp_statistics[0].IcmpInErrors,
-		handler: icmp_discard,
-		error:	 1,
+		.output =	 &icmp_statistics[0].dummy,
+		.input = &icmp_statistics[0].IcmpInErrors,
+		.handler = icmp_discard,
+		.error = 1,
 	},
 	[2] = {
-		output:	 &icmp_statistics[0].dummy,
-		input:	 &icmp_statistics[0].IcmpInErrors,
-		handler: icmp_discard,
-		error:	 1,
+		.output =	 &icmp_statistics[0].dummy,
+		.input = &icmp_statistics[0].IcmpInErrors,
+		.handler = icmp_discard,
+		.error = 1,
 	},
 	/* DEST UNREACH (3) */
 	[3] = {
-		output:	 &icmp_statistics[0].IcmpOutDestUnreachs,
-		input:	 &icmp_statistics[0].IcmpInDestUnreachs,
-		handler: icmp_unreach,
-		error:	 1,
+		.output =	 &icmp_statistics[0].IcmpOutDestUnreachs,
+		.input = &icmp_statistics[0].IcmpInDestUnreachs,
+		.handler = icmp_unreach,
+		.error = 1,
 	},
 	/* SOURCE QUENCH (4) */
 	[4] = {
-		output:	 &icmp_statistics[0].IcmpOutSrcQuenchs,
-		input:	 &icmp_statistics[0].IcmpInSrcQuenchs,
+		.output =	 &icmp_statistics[0].IcmpOutSrcQuenchs,
+		.input = &icmp_statistics[0].IcmpInSrcQuenchs,
 		icmp_unreach,
-		error:	 1,
+		.error = 1,
 	},
 	/* REDIRECT (5) */
 	[5] = {
-		output:	 &icmp_statistics[0].IcmpOutRedirects,
-		input:	 &icmp_statistics[0].IcmpInRedirects,
-		handler: icmp_redirect,
-		error:	 1,
+		.output =	 &icmp_statistics[0].IcmpOutRedirects,
+		.input = &icmp_statistics[0].IcmpInRedirects,
+		.handler = icmp_redirect,
+		.error = 1,
 	},
 	[6] = {
-		output:	 &icmp_statistics[0].dummy,
-		input:	 &icmp_statistics[0].IcmpInErrors,
-		handler: icmp_discard,
-		error:	 1,
+		.output =	 &icmp_statistics[0].dummy,
+		.input = &icmp_statistics[0].IcmpInErrors,
+		.handler = icmp_discard,
+		.error = 1,
 	},
 	[7] = {
-		output:	 &icmp_statistics[0].dummy,
-		input:	 &icmp_statistics[0].IcmpInErrors,
-		handler: icmp_discard,
-		error:	 1,
+		.output =	 &icmp_statistics[0].dummy,
+		.input = &icmp_statistics[0].IcmpInErrors,
+		.handler = icmp_discard,
+		.error = 1,
 	},
 	/* ECHO (8) */
 	[8] = {
-		output:	 &icmp_statistics[0].IcmpOutEchos,
-		input:	 &icmp_statistics[0].IcmpInEchos,
-		handler: icmp_echo,
-		error:	 0,
+		.output =	 &icmp_statistics[0].IcmpOutEchos,
+		.input = &icmp_statistics[0].IcmpInEchos,
+		.handler = icmp_echo,
+		.error = 0,
 	},
 	[9] = {
-		output:	 &icmp_statistics[0].dummy,
-		input:	 &icmp_statistics[0].IcmpInErrors,
-		handler: icmp_discard,
-		error:	 1,
+		.output =	 &icmp_statistics[0].dummy,
+		.input = &icmp_statistics[0].IcmpInErrors,
+		.handler = icmp_discard,
+		.error = 1,
 	},
 	[10] = {
-		output:	 &icmp_statistics[0].dummy,
-		input:	 &icmp_statistics[0].IcmpInErrors,
-		handler: icmp_discard,
-		error:	 1,
+		.output =	 &icmp_statistics[0].dummy,
+		.input = &icmp_statistics[0].IcmpInErrors,
+		.handler = icmp_discard,
+		.error = 1,
 	},
 	/* TIME EXCEEDED (11) */
 	[11] = {
-		output:	 &icmp_statistics[0].IcmpOutTimeExcds,
-		input:	 &icmp_statistics[0].IcmpInTimeExcds,
-		handler: icmp_unreach,
-		error:	 1,
+		.output =	 &icmp_statistics[0].IcmpOutTimeExcds,
+		.input = &icmp_statistics[0].IcmpInTimeExcds,
+		.handler = icmp_unreach,
+		.error = 1,
 	},
 	/* PARAMETER PROBLEM (12) */
 	[12] = {
-		output:	 &icmp_statistics[0].IcmpOutParmProbs,
-		input:	 &icmp_statistics[0].IcmpInParmProbs,
-		handler: icmp_unreach,
-		error:	 1,
+		.output =	 &icmp_statistics[0].IcmpOutParmProbs,
+		.input = &icmp_statistics[0].IcmpInParmProbs,
+		.handler = icmp_unreach,
+		.error = 1,
 	},
 	/* TIMESTAMP (13) */
 	[13] = {
-		output:	 &icmp_statistics[0].IcmpOutTimestamps,
-		input:	 &icmp_statistics[0].IcmpInTimestamps,
-		handler: icmp_timestamp,
+		.output =	 &icmp_statistics[0].IcmpOutTimestamps,
+		.input = &icmp_statistics[0].IcmpInTimestamps,
+		.handler = icmp_timestamp,
 	},
 	/* TIMESTAMP REPLY (14) */
 	[14] = {
-		output:	 &icmp_statistics[0].IcmpOutTimestampReps,
-		input:	 &icmp_statistics[0].IcmpInTimestampReps,
-		handler: icmp_discard,
+		.output =	 &icmp_statistics[0].IcmpOutTimestampReps,
+		.input = &icmp_statistics[0].IcmpInTimestampReps,
+		.handler = icmp_discard,
 	},
 	/* INFO (15) */
 	[15] = {
-		output:	 &icmp_statistics[0].dummy,
-		input:	 &icmp_statistics[0].dummy,
-		handler: icmp_discard,
+		.output =	 &icmp_statistics[0].dummy,
+		.input = &icmp_statistics[0].dummy,
+		.handler = icmp_discard,
 	},
 	/* INFO REPLY (16) */
  	[16] = {
-		output:	 &icmp_statistics[0].dummy,
-		input:	 &icmp_statistics[0].dummy,
-		handler: icmp_discard,
+		.output =	 &icmp_statistics[0].dummy,
+		.input = &icmp_statistics[0].dummy,
+		.handler = icmp_discard,
 	},
 	/* ADDR MASK (17) */
 	[17] = {
-		output:	 &icmp_statistics[0].IcmpOutAddrMasks,
-		input:	 &icmp_statistics[0].IcmpInAddrMasks,
-		handler: icmp_address,
+		.output =	 &icmp_statistics[0].IcmpOutAddrMasks,
+		.input = &icmp_statistics[0].IcmpInAddrMasks,
+		.handler = icmp_address,
 	},
 	/* ADDR MASK REPLY (18) */
 	[18] = {
-		output:	 &icmp_statistics[0].IcmpOutAddrMaskReps,
-		input:	 &icmp_statistics[0].IcmpInAddrMaskReps,
-		handler: icmp_address_reply,
+		.output =	 &icmp_statistics[0].IcmpOutAddrMaskReps,
+		.input = &icmp_statistics[0].IcmpInAddrMaskReps,
+		.handler = icmp_address_reply,
 	}
 };
 
diff -Nru a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
--- a/net/ipv4/ip_gre.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipv4/ip_gre.c	Sat Aug 10 18:42:23 2002
@@ -120,13 +120,13 @@
 static int ipgre_fb_tunnel_init(struct net_device *dev);
 
 static struct net_device ipgre_fb_tunnel_dev = {
-	name:	"gre0",
-	init:	ipgre_fb_tunnel_init
+	.name =	"gre0",
+	.init =	ipgre_fb_tunnel_init
 };
 
 static struct ip_tunnel ipgre_fb_tunnel = {
-	dev:	&ipgre_fb_tunnel_dev,
-	parms:	{ name: "gre0" }
+	.dev =	&ipgre_fb_tunnel_dev,
+	.parms ={ name: "gre0" }
 };
 
 /* Tunnel hash table */
diff -Nru a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
--- a/net/ipv4/ip_output.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipv4/ip_output.c	Sat Aug 10 18:42:23 2002
@@ -523,8 +523,18 @@
 		/*
 		 *	Get the memory we require with some space left for alignment.
 		 */
-
-		skb = sock_alloc_send_skb(sk, fraglen+hh_len+15, flags&MSG_DONTWAIT, &err);
+		if (!(flags & MSG_DONTWAIT) || nfrags == 0) {
+			skb = sock_alloc_send_skb(sk, fraglen + hh_len + 15,
+						  (flags & MSG_DONTWAIT), &err);
+		} else {
+			/* On a non-blocking write, we check for send buffer
+			 * usage on the first fragment only.
+			 */
+			skb = sock_wmalloc(sk, fraglen + hh_len + 15, 1,
+					   sk->allocation);
+			if (!skb)
+				err = -ENOBUFS;
+		}
 		if (skb == NULL)
 			goto error;
 
diff -Nru a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
--- a/net/ipv4/ipconfig.c	Sat Aug 10 18:42:20 2002
+++ b/net/ipv4/ipconfig.c	Sat Aug 10 18:42:20 2002
@@ -382,8 +382,8 @@
 static int ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt);
 
 static struct packet_type rarp_packet_type __initdata = {
-	type:	__constant_htons(ETH_P_RARP),
-	func:	ic_rarp_recv,
+	.type =	__constant_htons(ETH_P_RARP),
+	.func =	ic_rarp_recv,
 };
 
 static inline void ic_rarp_init(void)
@@ -522,8 +522,8 @@
 static int ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt);
 
 static struct packet_type bootp_packet_type __initdata = {
-	type:	__constant_htons(ETH_P_IP),
-	func:	ic_bootp_recv,
+	.type =	__constant_htons(ETH_P_IP),
+	.func =	ic_bootp_recv,
 };
 
 
diff -Nru a/net/ipv4/ipip.c b/net/ipv4/ipip.c
--- a/net/ipv4/ipip.c	Sat Aug 10 18:42:24 2002
+++ b/net/ipv4/ipip.c	Sat Aug 10 18:42:24 2002
@@ -123,13 +123,13 @@
 static int ipip_tunnel_init(struct net_device *dev);
 
 static struct net_device ipip_fb_tunnel_dev = {
-	name:	"tunl0",
-	init:	ipip_fb_tunnel_init,
+	.name =	"tunl0",
+	.init =	ipip_fb_tunnel_init,
 };
 
 static struct ip_tunnel ipip_fb_tunnel = {
-	dev:	&ipip_fb_tunnel_dev,
-	parms:	{ name:	"tunl0", }
+	.dev =	&ipip_fb_tunnel_dev,
+	.parms ={ name:	"tunl0", }
 };
 
 static struct ip_tunnel *tunnels_r_l[HASH_SIZE];
@@ -877,10 +877,10 @@
 }
 
 static struct inet_protocol ipip_protocol = {
-	handler:	ipip_rcv,
-	err_handler:	ipip_err,
-	protocol:	IPPROTO_IPIP,
-	name:		"IPIP"
+	.handler =	ipip_rcv,
+	.err_handler =	ipip_err,
+	.protocol =	IPPROTO_IPIP,
+	.name =		"IPIP"
 };
 
 static char banner[] __initdata =
diff -Nru a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
--- a/net/ipv4/netfilter/ip_queue.c	Sat Aug 10 18:42:24 2002
+++ b/net/ipv4/netfilter/ip_queue.c	Sat Aug 10 18:42:24 2002
@@ -2,13 +2,14 @@
  * This is a module which is used for queueing IPv4 packets and
  * communicating with userspace via netlink.
  *
- * (C) 2000 James Morris, this code is GPL.
+ * (C) 2000-2002 James Morris, this code is GPL.
  *
  * 2000-03-27: Simplified code (thanks to Andi Kleen for clues).
  * 2000-05-20: Fixed notifier problems (following Miguel Freitas' report).
  * 2000-06-19: Fixed so nfmark is copied to metadata (reported by Sebastian 
  *             Zander).
  * 2000-08-01: Added Nick Williams' MAC support.
+ * 2002-06-25: Code cleanup.
  *
  */
 #include <linux/module.h>
@@ -18,205 +19,310 @@
 #include <linux/notifier.h>
 #include <linux/netdevice.h>
 #include <linux/netfilter.h>
+#include <linux/netfilter_ipv4/ip_queue.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netlink.h>
 #include <linux/spinlock.h>
-#include <linux/rtnetlink.h>
+#include <linux/brlock.h>
 #include <linux/sysctl.h>
 #include <linux/proc_fs.h>
 #include <net/sock.h>
 #include <net/route.h>
 
-#include <linux/netfilter_ipv4/ip_queue.h>
-#include <linux/netfilter_ipv4/ip_tables.h>
-
 #define IPQ_QMAX_DEFAULT 1024
 #define IPQ_PROC_FS_NAME "ip_queue"
 #define NET_IPQ_QMAX 2088
 #define NET_IPQ_QMAX_NAME "ip_queue_maxlen"
 
-typedef struct ipq_rt_info {
+struct ipq_rt_info {
 	__u8 tos;
 	__u32 daddr;
 	__u32 saddr;
-} ipq_rt_info_t;
+};
 
-typedef struct ipq_queue_element {
-	struct list_head list;		/* Links element into queue */
-	int verdict;			/* Current verdict */
-	struct nf_info *info;		/* Extra info from netfilter */
-	struct sk_buff *skb;		/* Packet inside */
-	ipq_rt_info_t rt_info;		/* May need post-mangle routing */
-} ipq_queue_element_t;
-
-typedef int (*ipq_send_cb_t)(ipq_queue_element_t *e);
-
-typedef struct ipq_peer {
-	pid_t pid;			/* PID of userland peer */
-	unsigned char died;		/* We think the peer died */
-	unsigned char copy_mode;	/* Copy packet as well as metadata? */
-	size_t copy_range;		/* Range past metadata to copy */
-	ipq_send_cb_t send;		/* Callback for sending data to peer */
-} ipq_peer_t;
-
-typedef struct ipq_queue {
- 	int len;			/* Current queue len */
- 	int *maxlen;			/* Maximum queue len, via sysctl */
- 	unsigned char flushing;		/* If queue is being flushed */
- 	unsigned char terminate;	/* If the queue is being terminated */
- 	struct list_head list;		/* Head of packet queue */
- 	spinlock_t lock;		/* Queue spinlock */
- 	ipq_peer_t peer;		/* Userland peer */
-} ipq_queue_t;
+struct ipq_queue_entry {
+	struct list_head list;
+	struct nf_info *info;
+	struct sk_buff *skb;
+	struct ipq_rt_info rt_info;
+};
 
-/****************************************************************************
- *
- * Packet queue
- *
- ****************************************************************************/
-/* Dequeue a packet if matched by cmp, or the next available if cmp is NULL */
-static ipq_queue_element_t *
-ipq_dequeue(ipq_queue_t *q,
-            int (*cmp)(ipq_queue_element_t *, unsigned long),
-            unsigned long data)
-{
-	struct list_head *i;
-
-	spin_lock_bh(&q->lock);
-	for (i = q->list.prev; i != &q->list; i = i->prev) {
-		ipq_queue_element_t *e = (ipq_queue_element_t *)i;
-		
-		if (!cmp || cmp(e, data)) {
-			list_del(&e->list);
-			q->len--;
-			spin_unlock_bh(&q->lock);
-			return e;
-		}
+typedef int (*ipq_cmpfn)(struct ipq_queue_entry *, unsigned long);
+
+static unsigned char copy_mode = IPQ_COPY_NONE;
+static unsigned int queue_maxlen = IPQ_QMAX_DEFAULT;
+static rwlock_t queue_lock = RW_LOCK_UNLOCKED;
+static int peer_pid;
+static unsigned int copy_range;
+static unsigned int queue_total;
+static struct sock *ipqnl;
+static LIST_HEAD(queue_list);
+static DECLARE_MUTEX(ipqnl_sem);
+
+static void
+ipq_issue_verdict(struct ipq_queue_entry *entry, int verdict)
+{
+	nf_reinject(entry->skb, entry->info, verdict);
+	kfree(entry);
+}
+
+static inline int
+__ipq_enqueue_entry(struct ipq_queue_entry *entry)
+{
+       if (queue_total >= queue_maxlen) {
+               if (net_ratelimit()) 
+                       printk(KERN_WARNING "ip_queue: full at %d entries, "
+                              "dropping packet(s).\n", queue_total);
+               return -ENOSPC;
+       }
+       list_add(&entry->list, &queue_list);
+       queue_total++;
+       return 0;
+}
+
+/*
+ * Find and return a queued entry matched by cmpfn, or return the last
+ * entry if cmpfn is NULL.
+ */
+static inline struct ipq_queue_entry *
+__ipq_find_entry(ipq_cmpfn cmpfn, unsigned long data)
+{
+	struct list_head *p;
+
+	list_for_each_prev(p, &queue_list) {
+		struct ipq_queue_entry *entry = (struct ipq_queue_entry *)p;
+		
+		if (!cmpfn || cmpfn(entry, data))
+			return entry;
 	}
-	spin_unlock_bh(&q->lock);
 	return NULL;
 }
 
-/* Flush all packets */
-static void ipq_flush(ipq_queue_t *q)
+static inline void
+__ipq_dequeue_entry(struct ipq_queue_entry *entry)
 {
-	ipq_queue_element_t *e;
-	
-	spin_lock_bh(&q->lock);
-	q->flushing = 1;
-	spin_unlock_bh(&q->lock);
-	while ((e = ipq_dequeue(q, NULL, 0))) {
-		e->verdict = NF_DROP;
-		nf_reinject(e->skb, e->info, e->verdict);
-		kfree(e);
-	}
-	spin_lock_bh(&q->lock);
-	q->flushing = 0;
-	spin_unlock_bh(&q->lock);
-}
-
-static ipq_queue_t *ipq_create_queue(nf_queue_outfn_t outfn,
-                                     ipq_send_cb_t send_cb,
-                                     int *errp, int *sysctl_qmax)
+	list_del(&entry->list);
+	queue_total--;
+}
+
+static inline struct ipq_queue_entry *
+__ipq_find_dequeue_entry(ipq_cmpfn cmpfn, unsigned long data)
 {
-	int status;
-	ipq_queue_t *q;
+	struct ipq_queue_entry *entry;
 
-	*errp = 0;
-	q = kmalloc(sizeof(ipq_queue_t), GFP_KERNEL);
-	if (q == NULL) {
-		*errp = -ENOMEM;
+	entry = __ipq_find_entry(cmpfn, data);
+	if (entry == NULL)
 		return NULL;
+
+	__ipq_dequeue_entry(entry);
+	return entry;
+}
+
+
+static inline void
+__ipq_flush(int verdict)
+{
+	struct ipq_queue_entry *entry;
+	
+	while ((entry = __ipq_find_dequeue_entry(NULL, 0)))
+		ipq_issue_verdict(entry, verdict);
+}
+
+static inline int
+__ipq_set_mode(unsigned char mode, unsigned int range)
+{
+	int status = 0;
+	
+	switch(mode) {
+	case IPQ_COPY_NONE:
+	case IPQ_COPY_META:
+		copy_mode = mode;
+		copy_range = 0;
+		break;
+		
+	case IPQ_COPY_PACKET:
+		copy_mode = mode;
+		copy_range = range;
+		if (copy_range > 0xFFFF)
+			copy_range = 0xFFFF;
+		break;
+		
+	default:
+		status = -EINVAL;
+
 	}
-	q->peer.pid = 0;
-	q->peer.died = 0;
-	q->peer.copy_mode = IPQ_COPY_NONE;
-	q->peer.copy_range = 0;
-	q->peer.send = send_cb;
-	q->len = 0;
-	q->maxlen = sysctl_qmax;
-	q->flushing = 0;
-	q->terminate = 0;
-	INIT_LIST_HEAD(&q->list);
-	spin_lock_init(&q->lock);
-	status = nf_register_queue_handler(PF_INET, outfn, q);
-	if (status < 0) {
-		*errp = -EBUSY;
-		kfree(q);
+	return status;
+}
+
+static inline void
+__ipq_reset(void)
+{
+	peer_pid = 0;
+	__ipq_set_mode(IPQ_COPY_NONE, 0);
+	__ipq_flush(NF_DROP);
+}
+
+static struct ipq_queue_entry *
+ipq_find_dequeue_entry(ipq_cmpfn cmpfn, unsigned long data)
+{
+	struct ipq_queue_entry *entry;
+	
+	write_lock_bh(&queue_lock);
+	entry = __ipq_find_dequeue_entry(cmpfn, data);
+	write_unlock_bh(&queue_lock);
+	return entry;
+}
+
+static void
+ipq_flush(int verdict)
+{
+	write_lock_bh(&queue_lock);
+	__ipq_flush(verdict);
+	write_unlock_bh(&queue_lock);
+}
+
+static struct sk_buff *
+ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
+{
+	unsigned char *old_tail;
+	size_t size = 0;
+	size_t data_len = 0;
+	struct sk_buff *skb;
+	struct ipq_packet_msg *pmsg;
+	struct nlmsghdr *nlh;
+
+	read_lock_bh(&queue_lock);
+	
+	switch (copy_mode) {
+	case IPQ_COPY_META:
+	case IPQ_COPY_NONE:
+		size = NLMSG_SPACE(sizeof(*pmsg));
+		data_len = 0;
+		break;
+	
+	case IPQ_COPY_PACKET:
+		if (copy_range == 0 || copy_range > entry->skb->len)
+			data_len = entry->skb->len;
+		else
+			data_len = copy_range;
+		
+		size = NLMSG_SPACE(sizeof(*pmsg) + data_len);
+		break;
+	
+	default:
+		*errp = -EINVAL;
+		read_unlock_bh(&queue_lock);
 		return NULL;
 	}
-	return q;
+
+	read_unlock_bh(&queue_lock);
+
+	skb = alloc_skb(size, GFP_ATOMIC);
+	if (!skb)
+		goto nlmsg_failure;
+		
+	old_tail= skb->tail;
+	nlh = NLMSG_PUT(skb, 0, 0, IPQM_PACKET, size - sizeof(*nlh));
+	pmsg = NLMSG_DATA(nlh);
+	memset(pmsg, 0, sizeof(*pmsg));
+
+	pmsg->packet_id       = (unsigned long )entry;
+	pmsg->data_len        = data_len;
+	pmsg->timestamp_sec   = entry->skb->stamp.tv_sec;
+	pmsg->timestamp_usec  = entry->skb->stamp.tv_usec;
+	pmsg->mark            = entry->skb->nfmark;
+	pmsg->hook            = entry->info->hook;
+	pmsg->hw_protocol     = entry->skb->protocol;
+	
+	if (entry->info->indev)
+		strcpy(pmsg->indev_name, entry->info->indev->name);
+	else
+		pmsg->indev_name[0] = '\0';
+	
+	if (entry->info->outdev)
+		strcpy(pmsg->outdev_name, entry->info->outdev->name);
+	else
+		pmsg->outdev_name[0] = '\0';
+	
+	if (entry->info->indev && entry->skb->dev) {
+		pmsg->hw_type = entry->skb->dev->type;
+		if (entry->skb->dev->hard_header_parse)
+			pmsg->hw_addrlen =
+				entry->skb->dev->hard_header_parse(entry->skb,
+				                                   pmsg->hw_addr);
+	}
+	
+	if (data_len)
+		memcpy(pmsg->payload, entry->skb->data, data_len);
+		
+	nlh->nlmsg_len = skb->tail - old_tail;
+	return skb;
+
+nlmsg_failure:
+	if (skb)
+		kfree_skb(skb);
+	*errp = -EINVAL;
+	printk(KERN_ERR "ip_queue: error creating packet message\n");
+	return NULL;
 }
 
-static int ipq_enqueue(ipq_queue_t *q,
-                       struct sk_buff *skb, struct nf_info *info)
+static int
+ipq_enqueue_packet(struct sk_buff *skb, struct nf_info *info, void *data)
 {
-	ipq_queue_element_t *e;
-	int status;
-	
-	e = kmalloc(sizeof(*e), GFP_ATOMIC);
-	if (e == NULL) {
-		printk(KERN_ERR "ip_queue: OOM in enqueue\n");
+	int status = -EINVAL;
+	struct sk_buff *nskb;
+	struct ipq_queue_entry *entry;
+
+	if (copy_mode == IPQ_COPY_NONE)
+		return -EAGAIN;
+
+	entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+	if (entry == NULL) {
+		printk(KERN_ERR "ip_queue: OOM in ipq_enqueue_packet()\n");
 		return -ENOMEM;
 	}
 
-	e->verdict = NF_DROP;
-	e->info = info;
-	e->skb = skb;
+	entry->info = info;
+	entry->skb = skb;
 
-	if (e->info->hook == NF_IP_LOCAL_OUT) {
+	if (entry->info->hook == NF_IP_LOCAL_OUT) {
 		struct iphdr *iph = skb->nh.iph;
 
-		e->rt_info.tos = iph->tos;
-		e->rt_info.daddr = iph->daddr;
-		e->rt_info.saddr = iph->saddr;
-	}
-
-	spin_lock_bh(&q->lock);
-	if (q->len >= *q->maxlen) {
-		spin_unlock_bh(&q->lock);
-		if (net_ratelimit()) 
-			printk(KERN_WARNING "ip_queue: full at %d entries, "
-			       "dropping packet(s).\n", q->len);
-		goto free_drop;
-	}
-	if (q->flushing || q->peer.copy_mode == IPQ_COPY_NONE
-	    || q->peer.pid == 0 || q->peer.died || q->terminate) {
-		spin_unlock_bh(&q->lock);
-		goto free_drop;
-	}
-	status = q->peer.send(e);
-	if (status > 0) {
-		list_add(&e->list, &q->list);
-		q->len++;
-		spin_unlock_bh(&q->lock);
-		return status;
-	}
-	spin_unlock_bh(&q->lock);
-	if (status == -ECONNREFUSED) {
-		printk(KERN_INFO "ip_queue: peer %d died, "
-		       "resetting state and flushing queue\n", q->peer.pid);
-			q->peer.died = 1;
-			q->peer.pid = 0;
-			q->peer.copy_mode = IPQ_COPY_NONE;
-			q->peer.copy_range = 0;
-			ipq_flush(q);
-	}
-free_drop:
-	kfree(e);
-	return -EBUSY;
-}
+		entry->rt_info.tos = iph->tos;
+		entry->rt_info.daddr = iph->daddr;
+		entry->rt_info.saddr = iph->saddr;
+	}
 
-static void ipq_destroy_queue(ipq_queue_t *q)
-{
-	nf_unregister_queue_handler(PF_INET);
-	spin_lock_bh(&q->lock);
-	q->terminate = 1;
-	spin_unlock_bh(&q->lock);
-	ipq_flush(q);
-	kfree(q);
+	nskb = ipq_build_packet_message(entry, &status);
+	if (nskb == NULL)
+		goto err_out_free;
+		
+	write_lock_bh(&queue_lock);
+	
+	if (!peer_pid)
+		goto err_out_unlock;
+
+	status = netlink_unicast(ipqnl, nskb, peer_pid, MSG_DONTWAIT);
+	if (status < 0)
+		goto err_out_unlock;
+	
+	status = __ipq_enqueue_entry(entry);
+	if (status < 0)
+		goto err_out_unlock;
+
+	write_unlock_bh(&queue_lock);
+	return status;
+	
+err_out_unlock:
+	write_unlock_bh(&queue_lock);
+
+err_out_free:
+	kfree(entry);
+	return status;
 }
 
-static int ipq_mangle_ipv4(ipq_verdict_msg_t *v, ipq_queue_element_t *e)
+static int
+ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
 {
 	int diff;
 	struct iphdr *user_iph = (struct iphdr *)v->payload;
@@ -266,296 +372,216 @@
 	return 0;
 }
 
-static inline int id_cmp(ipq_queue_element_t *e, unsigned long id)
+static inline int
+id_cmp(struct ipq_queue_entry *e, unsigned long id)
 {
 	return (id == (unsigned long )e);
 }
 
-static int ipq_set_verdict(ipq_queue_t *q,
-                           ipq_verdict_msg_t *v, unsigned int len)
+static int
+ipq_set_verdict(struct ipq_verdict_msg *vmsg, unsigned int len)
 {
-	ipq_queue_element_t *e;
+	struct ipq_queue_entry *entry;
 
-	if (v->value > NF_MAX_VERDICT)
+	if (vmsg->value > NF_MAX_VERDICT)
 		return -EINVAL;
-	e = ipq_dequeue(q, id_cmp, v->id);
-	if (e == NULL)
+
+	entry = ipq_find_dequeue_entry(id_cmp, vmsg->id);
+	if (entry == NULL)
 		return -ENOENT;
 	else {
-		e->verdict = v->value;
-		if (v->data_len && v->data_len == len)
-			if (ipq_mangle_ipv4(v, e) < 0)
-				e->verdict = NF_DROP;
-		nf_reinject(e->skb, e->info, e->verdict);
-		kfree(e);
+		int verdict = vmsg->value;
+		
+		if (vmsg->data_len && vmsg->data_len == len)
+			if (ipq_mangle_ipv4(vmsg, entry) < 0)
+				verdict = NF_DROP;
+		
+		ipq_issue_verdict(entry, verdict);
 		return 0;
 	}
 }
 
-static int ipq_receive_peer(ipq_queue_t *q, ipq_peer_msg_t *m,
-                            unsigned char type, unsigned int len)
+static int
+ipq_set_mode(unsigned char mode, unsigned int range)
 {
+	int status;
+
+	write_lock_bh(&queue_lock);
+	status = __ipq_set_mode(mode, range);
+	write_unlock_bh(&queue_lock);
+	return status;
+}
 
+static int
+ipq_receive_peer(struct ipq_peer_msg *pmsg,
+                 unsigned char type, unsigned int len)
+{
 	int status = 0;
-	int busy;
-		
-	spin_lock_bh(&q->lock);
-	busy = (q->terminate || q->flushing);
-	spin_unlock_bh(&q->lock);
-	if (busy)
-		return -EBUSY;
-	if (len < sizeof(ipq_peer_msg_t))
+
+	if (len < sizeof(*pmsg))
 		return -EINVAL;
+
 	switch (type) {
-		case IPQM_MODE:
-			switch (m->msg.mode.value) {
-				case IPQ_COPY_META:
-					q->peer.copy_mode = IPQ_COPY_META;
-					q->peer.copy_range = 0;
-					break;
-				case IPQ_COPY_PACKET:
-					q->peer.copy_mode = IPQ_COPY_PACKET;
-					q->peer.copy_range = m->msg.mode.range;
-					if (q->peer.copy_range > 0xFFFF)
-						q->peer.copy_range = 0xFFFF;
-					break;
-				default:
-					status = -EINVAL;
-			}
-			break;
-		case IPQM_VERDICT:
-			if (m->msg.verdict.value > NF_MAX_VERDICT)
-				status = -EINVAL;
-			else
-				status = ipq_set_verdict(q,
-				                         &m->msg.verdict,
-				                         len - sizeof(*m));
+	case IPQM_MODE:
+		status = ipq_set_mode(pmsg->msg.mode.value,
+		                      pmsg->msg.mode.range);
+		break;
+		
+	case IPQM_VERDICT:
+		if (pmsg->msg.verdict.value > NF_MAX_VERDICT)
+			status = -EINVAL;
+		else
+			status = ipq_set_verdict(&pmsg->msg.verdict,
+			                         len - sizeof(*pmsg));
 			break;
-		default:
-			 status = -EINVAL;
+	default:
+		status = -EINVAL;
 	}
 	return status;
 }
 
-static inline int dev_cmp(ipq_queue_element_t *e, unsigned long ifindex)
+static int
+dev_cmp(struct ipq_queue_entry *entry, unsigned long ifindex)
 {
-	if (e->info->indev)
-		if (e->info->indev->ifindex == ifindex)
+	if (entry->info->indev)
+		if (entry->info->indev->ifindex == ifindex)
 			return 1;
-	if (e->info->outdev)
-		if (e->info->outdev->ifindex == ifindex)
+			
+	if (entry->info->outdev)
+		if (entry->info->outdev->ifindex == ifindex)
 			return 1;
+
 	return 0;
 }
 
-/* Drop any queued packets associated with device ifindex */
-static void ipq_dev_drop(ipq_queue_t *q, int ifindex)
+static void
+ipq_dev_drop(int ifindex)
 {
-	ipq_queue_element_t *e;
+	struct ipq_queue_entry *entry;
 	
-	while ((e = ipq_dequeue(q, dev_cmp, ifindex))) {
-		e->verdict = NF_DROP;
-		nf_reinject(e->skb, e->info, e->verdict);
-		kfree(e);
-	}
-}
-
-/****************************************************************************
- *
- * Netfilter interface
- *
- ****************************************************************************/
-
-/*
- * Packets arrive here from netfilter for queuing to userspace.
- * All of them must be fed back via nf_reinject() or Alexey will kill Rusty.
- */
-static int netfilter_receive(struct sk_buff *skb,
-                             struct nf_info *info, void *data)
-{
-	return ipq_enqueue((ipq_queue_t *)data, skb, info);
-}
-
-/****************************************************************************
- *
- * Netlink interface.
- *
- ****************************************************************************/
-
-static struct sock *nfnl = NULL;
-ipq_queue_t *nlq = NULL;
-
-static struct sk_buff *netlink_build_message(ipq_queue_element_t *e, int *errp)
-{
-	unsigned char *old_tail;
-	size_t size = 0;
-	size_t data_len = 0;
-	struct sk_buff *skb;
-	ipq_packet_msg_t *pm;
-	struct nlmsghdr *nlh;
-
-	switch (nlq->peer.copy_mode) {
-		size_t copy_range;
-
-		case IPQ_COPY_META:
-			size = NLMSG_SPACE(sizeof(*pm));
-			data_len = 0;
-			break;
-		case IPQ_COPY_PACKET:
-			copy_range = nlq->peer.copy_range;
-			if (copy_range == 0 || copy_range > e->skb->len)
-				data_len = e->skb->len;
-			else
-				data_len = copy_range;
-			size = NLMSG_SPACE(sizeof(*pm) + data_len);
-			
-			break;
-		case IPQ_COPY_NONE:
-		default:
-			*errp = -EINVAL;
-			return NULL;
-	}
-	skb = alloc_skb(size, GFP_ATOMIC);
-	if (!skb)
-		goto nlmsg_failure;
-	old_tail = skb->tail;
-	nlh = NLMSG_PUT(skb, 0, 0, IPQM_PACKET, size - sizeof(*nlh));
-	pm = NLMSG_DATA(nlh);
-	memset(pm, 0, sizeof(*pm));
-	pm->packet_id = (unsigned long )e;
-	pm->data_len = data_len;
-	pm->timestamp_sec = e->skb->stamp.tv_sec;
-	pm->timestamp_usec = e->skb->stamp.tv_usec;
-	pm->mark = e->skb->nfmark;
-	pm->hook = e->info->hook;
-	if (e->info->indev) strcpy(pm->indev_name, e->info->indev->name);
-	else pm->indev_name[0] = '\0';
-	if (e->info->outdev) strcpy(pm->outdev_name, e->info->outdev->name);
-	else pm->outdev_name[0] = '\0';
-	pm->hw_protocol = e->skb->protocol;
-	if (e->info->indev && e->skb->dev) {
-		pm->hw_type = e->skb->dev->type;
-		if (e->skb->dev->hard_header_parse)
-			pm->hw_addrlen =
-				e->skb->dev->hard_header_parse(e->skb,
-				                               pm->hw_addr);
-	}
-	if (data_len)
-		memcpy(pm->payload, e->skb->data, data_len);
-	nlh->nlmsg_len = skb->tail - old_tail;
-	NETLINK_CB(skb).dst_groups = 0;
-	return skb;
-nlmsg_failure:
-	if (skb)
-		kfree_skb(skb);
-	*errp = 0;
-	printk(KERN_ERR "ip_queue: error creating netlink message\n");
-	return NULL;
-}
-
-static int netlink_send_peer(ipq_queue_element_t *e)
-{
-	int status = 0;
-	struct sk_buff *skb;
-
-	skb = netlink_build_message(e, &status);
-	if (skb == NULL)
-		return status;
-	return netlink_unicast(nfnl, skb, nlq->peer.pid, MSG_DONTWAIT);
+	while ((entry = ipq_find_dequeue_entry(dev_cmp, ifindex)) != NULL)
+		ipq_issue_verdict(entry, NF_DROP);
 }
 
 #define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0)
 
-static __inline__ void netlink_receive_user_skb(struct sk_buff *skb)
+static inline void
+ipq_rcv_skb(struct sk_buff *skb)
 {
-	int status, type;
+	int status, type, pid, flags, nlmsglen, skblen;
 	struct nlmsghdr *nlh;
 
-	if (skb->len < sizeof(struct nlmsghdr))
+	skblen = skb->len;
+	if (skblen < sizeof(*nlh))
 		return;
 
 	nlh = (struct nlmsghdr *)skb->data;
-	if (nlh->nlmsg_len < sizeof(struct nlmsghdr)
-	    || skb->len < nlh->nlmsg_len)
-	    	return;
-
-	if(nlh->nlmsg_pid <= 0
-	    || !(nlh->nlmsg_flags & NLM_F_REQUEST)
-	    || nlh->nlmsg_flags & NLM_F_MULTI)
+	nlmsglen = nlh->nlmsg_len;
+	if (nlmsglen < sizeof(*nlh) || skblen < nlmsglen)
+		return;
+
+	pid = nlh->nlmsg_pid;
+	flags = nlh->nlmsg_flags;
+	
+	if(pid <= 0 || !(flags & NLM_F_REQUEST) || flags & NLM_F_MULTI)
 		RCV_SKB_FAIL(-EINVAL);
-	if (nlh->nlmsg_flags & MSG_TRUNC)
+		
+	if (flags & MSG_TRUNC)
 		RCV_SKB_FAIL(-ECOMM);
+		
 	type = nlh->nlmsg_type;
 	if (type < NLMSG_NOOP || type >= IPQM_MAX)
 		RCV_SKB_FAIL(-EINVAL);
+		
 	if (type <= IPQM_BASE)
 		return;
+		
 	if(!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN))
 		RCV_SKB_FAIL(-EPERM);
-	if (nlq->peer.pid && !nlq->peer.died
-	    && (nlq->peer.pid != nlh->nlmsg_pid)) {
-	    	printk(KERN_WARNING "ip_queue: peer pid changed from %d to "
-	    	      "%d, flushing queue\n", nlq->peer.pid, nlh->nlmsg_pid);
-		ipq_flush(nlq);
-	}	
-	nlq->peer.pid = nlh->nlmsg_pid;
-	nlq->peer.died = 0;
-	status = ipq_receive_peer(nlq, NLMSG_DATA(nlh),
-	                          type, skb->len - NLMSG_LENGTH(0));
+	
+	write_lock_bh(&queue_lock);
+	
+	if (peer_pid) {
+		if (peer_pid != pid) {
+			write_unlock_bh(&queue_lock);
+			RCV_SKB_FAIL(-EBUSY);
+		}
+	}
+	else
+		peer_pid = pid;
+		
+	write_unlock_bh(&queue_lock);
+	
+	status = ipq_receive_peer(NLMSG_DATA(nlh), type,
+	                          skblen - NLMSG_LENGTH(0));
 	if (status < 0)
 		RCV_SKB_FAIL(status);
-	if (nlh->nlmsg_flags & NLM_F_ACK)
+		
+	if (flags & NLM_F_ACK)
 		netlink_ack(skb, nlh, 0);
         return;
 }
 
-/* Note: we are only dealing with single part messages at the moment. */
-static void netlink_receive_user_sk(struct sock *sk, int len)
+static void
+ipq_rcv_sk(struct sock *sk, int len)
 {
 	do {
 		struct sk_buff *skb;
 
-		if (rtnl_shlock_nowait())
+		if (down_trylock(&ipqnl_sem))
 			return;
+			
 		while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) {
-			netlink_receive_user_skb(skb);
+			ipq_rcv_skb(skb);
 			kfree_skb(skb);
 		}
-		up(&rtnl_sem);
-	} while (nfnl && nfnl->receive_queue.qlen);
-}
+		
+		up(&ipqnl_sem);
 
-/****************************************************************************
- *
- * System events
- *
- ****************************************************************************/
+	} while (ipqnl && ipqnl->receive_queue.qlen);
+}
 
-static int receive_event(struct notifier_block *this,
-                         unsigned long event, void *ptr)
+static int
+ipq_rcv_dev_event(struct notifier_block *this,
+                  unsigned long event, void *ptr)
 {
 	struct net_device *dev = ptr;
 
 	/* Drop any packets associated with the downed device */
 	if (event == NETDEV_DOWN)
-		ipq_dev_drop(nlq, dev->ifindex);
+		ipq_dev_drop(dev->ifindex);
 	return NOTIFY_DONE;
 }
 
-struct notifier_block ipq_dev_notifier = {
-	receive_event,
+static struct notifier_block ipq_dev_notifier = {
+	ipq_rcv_dev_event,
 	NULL,
 	0
 };
 
-/****************************************************************************
- *
- * Sysctl - queue tuning.
- *
- ****************************************************************************/
+static int
+ipq_rcv_nl_event(struct notifier_block *this,
+                 unsigned long event, void *ptr)
+{
+	struct netlink_notify *n = ptr;
+
+	if (event == NETLINK_URELEASE &&
+	    n->protocol == NETLINK_FIREWALL && n->pid) {
+		write_lock_bh(&queue_lock);
+		if (n->pid == peer_pid)
+			__ipq_reset();
+		write_unlock_bh(&queue_lock);
+	}
+	return NOTIFY_DONE;
+}
 
-static int sysctl_maxlen = IPQ_QMAX_DEFAULT;
+static struct notifier_block ipq_nl_notifier = {
+	ipq_rcv_nl_event,
+	NULL,
+	0
+};
 
+static int sysctl_maxlen = IPQ_QMAX_DEFAULT;
 static struct ctl_table_header *ipq_sysctl_header;
 
 static ctl_table ipq_table[] = {
@@ -574,35 +600,27 @@
 	{ 0 }
 };
 
-/****************************************************************************
- *
- * Procfs - debugging info.
- *
- ****************************************************************************/
-
-static int ipq_get_info(char *buffer, char **start, off_t offset, int length)
+static int
+ipq_get_info(char *buffer, char **start, off_t offset, int length)
 {
 	int len;
 
-	spin_lock_bh(&nlq->lock);
+	read_lock_bh(&queue_lock);
+	
 	len = sprintf(buffer,
-	              "Peer pid            : %d\n"
-	              "Peer died           : %d\n"
-	              "Peer copy mode      : %d\n"
-	              "Peer copy range     : %Zu\n"
-	              "Queue length        : %d\n"
-	              "Queue max. length   : %d\n"
-	              "Queue flushing      : %d\n"
-	              "Queue terminate     : %d\n",
-	              nlq->peer.pid,
-	              nlq->peer.died,
-	              nlq->peer.copy_mode,
-	              nlq->peer.copy_range,
-	              nlq->len,
-	              *nlq->maxlen,
-	              nlq->flushing,
-	              nlq->terminate);
-	spin_unlock_bh(&nlq->lock);
+	              "Peer PID          : %d\n"
+	              "Copy mode         : %hu\n"
+	              "Copy range        : %u\n"
+	              "Queue length      : %u\n"
+	              "Queue max. length : %u\n",
+	              peer_pid,
+	              copy_mode,
+	              copy_range,
+	              queue_total,
+	              queue_maxlen);
+
+	read_unlock_bh(&queue_lock);
+	
 	*start = buffer + offset;
 	len -= offset;
 	if (len > length)
@@ -612,53 +630,74 @@
 	return len;
 }
 
-/****************************************************************************
- *
- * Module stuff.
- *
- ****************************************************************************/
-
-static int __init init(void)
+static int
+init_or_cleanup(int init)
 {
-	int status = 0;
+	int status = -ENOMEM;
 	struct proc_dir_entry *proc;
 	
-	nfnl = netlink_kernel_create(NETLINK_FIREWALL, netlink_receive_user_sk);
-	if (nfnl == NULL) {
-		printk(KERN_ERR "ip_queue: initialisation failed: unable to "
-		       "create kernel netlink socket\n");
-		return -ENOMEM;
-	}
-	nlq = ipq_create_queue(netfilter_receive,
-	                       netlink_send_peer, &status, &sysctl_maxlen);
-	if (nlq == NULL) {
-		printk(KERN_ERR "ip_queue: initialisation failed: unable to "
-		       "create queue\n");
-		sock_release(nfnl->socket);
-		return status;
+	if (!init)
+		goto cleanup;
+
+	netlink_register_notifier(&ipq_nl_notifier);
+	ipqnl = netlink_kernel_create(NETLINK_FIREWALL, ipq_rcv_sk);
+	if (ipqnl == NULL) {
+		printk(KERN_ERR "ip_queue: failed to create netlink socket\n");
+		goto cleanup_netlink_notifier;
 	}
+
 	proc = proc_net_create(IPQ_PROC_FS_NAME, 0, ipq_get_info);
-	if (proc) proc->owner = THIS_MODULE;
+	if (proc)
+		proc->owner = THIS_MODULE;
 	else {
-		ipq_destroy_queue(nlq);
-		sock_release(nfnl->socket);
-		return -ENOMEM;
+		printk(KERN_ERR "ip_queue: failed to create proc entry\n");
+		goto cleanup_ipqnl;
 	}
+	
 	register_netdevice_notifier(&ipq_dev_notifier);
 	ipq_sysctl_header = register_sysctl_table(ipq_root_table, 0);
+	
+	status = nf_register_queue_handler(PF_INET, ipq_enqueue_packet, NULL);
+	if (status < 0) {
+		printk(KERN_ERR "ip_queue: failed to register queue handler\n");
+		goto cleanup_sysctl;
+	}
+	return status;
+
+cleanup:
+	nf_unregister_queue_handler(PF_INET);
+	br_write_lock_bh(BR_NETPROTO_LOCK);
+	br_write_unlock_bh(BR_NETPROTO_LOCK);
+	ipq_flush(NF_DROP);
+	
+cleanup_sysctl:
+	unregister_sysctl_table(ipq_sysctl_header);
+	unregister_netdevice_notifier(&ipq_dev_notifier);
+	proc_net_remove(IPQ_PROC_FS_NAME);
+	
+cleanup_ipqnl:
+	sock_release(ipqnl->socket);
+	down(&ipqnl_sem);
+	up(&ipqnl_sem);
+	
+cleanup_netlink_notifier:
+	netlink_unregister_notifier(&ipq_nl_notifier);
 	return status;
 }
 
+static int __init init(void)
+{
+	
+	return init_or_cleanup(1);
+}
+
 static void __exit fini(void)
 {
-	unregister_sysctl_table(ipq_sysctl_header);
-	proc_net_remove(IPQ_PROC_FS_NAME);
-	unregister_netdevice_notifier(&ipq_dev_notifier);
-	ipq_destroy_queue(nlq);
-	sock_release(nfnl->socket);
+	init_or_cleanup(0);
 }
 
 MODULE_DESCRIPTION("IPv4 packet queue handler");
+MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
 MODULE_LICENSE("GPL");
 
 module_init(init);
diff -Nru a/net/ipv4/protocol.c b/net/ipv4/protocol.c
--- a/net/ipv4/protocol.c	Sat Aug 10 18:42:21 2002
+++ b/net/ipv4/protocol.c	Sat Aug 10 18:42:21 2002
@@ -53,10 +53,10 @@
 #ifdef CONFIG_IP_MULTICAST
 
 static struct inet_protocol igmp_protocol = {
-	handler:	igmp_rcv,
-	next:		IPPROTO_PREVIOUS,
-	protocol:	IPPROTO_IGMP,
-	name:		"IGMP"
+	.handler =	igmp_rcv,
+	.next =		IPPROTO_PREVIOUS,
+	.protocol =	IPPROTO_IGMP,
+	.name =		"IGMP"
 };
 
 #undef  IPPROTO_PREVIOUS
@@ -65,32 +65,32 @@
 #endif
 
 static struct inet_protocol tcp_protocol = {
-	handler:	tcp_v4_rcv,
-	err_handler:	tcp_v4_err,
-	next:		IPPROTO_PREVIOUS,
-	protocol:	IPPROTO_TCP,
-	name:		"TCP"
+	.handler =	tcp_v4_rcv,
+	.err_handler =	tcp_v4_err,
+	.next =		IPPROTO_PREVIOUS,
+	.protocol =	IPPROTO_TCP,
+	.name =		"TCP"
 };
 
 #undef  IPPROTO_PREVIOUS
 #define IPPROTO_PREVIOUS &tcp_protocol
 
 static struct inet_protocol udp_protocol = {
-	handler:	udp_rcv,
-	err_handler:	udp_err,
-	next:		IPPROTO_PREVIOUS,
-	protocol:	IPPROTO_UDP,
-	name:		"UDP"
+	.handler =	udp_rcv,
+	.err_handler =	udp_err,
+	.next =		IPPROTO_PREVIOUS,
+	.protocol =	IPPROTO_UDP,
+	.name =		"UDP"
 };
 
 #undef  IPPROTO_PREVIOUS
 #define IPPROTO_PREVIOUS &udp_protocol
 
 static struct inet_protocol icmp_protocol = {
-	handler:	icmp_rcv,
-	next:		IPPROTO_PREVIOUS,
-	protocol:	IPPROTO_ICMP,
-	name:		"ICMP"
+	.handler =	icmp_rcv,
+	.next =		IPPROTO_PREVIOUS,
+	.protocol =	IPPROTO_ICMP,
+	.name =		"ICMP"
 };
 
 #undef  IPPROTO_PREVIOUS
diff -Nru a/net/ipv4/raw.c b/net/ipv4/raw.c
--- a/net/ipv4/raw.c	Sat Aug 10 18:42:20 2002
+++ b/net/ipv4/raw.c	Sat Aug 10 18:42:20 2002
@@ -688,18 +688,18 @@
 }
 
 struct proto raw_prot = {
-	name:		"RAW",
-	close:		raw_close,
-	connect:	udp_connect,
-	disconnect:	udp_disconnect,
-	ioctl:		raw_ioctl,
-	init:		raw_init,
-	setsockopt:	raw_setsockopt,
-	getsockopt:	raw_getsockopt,
-	sendmsg:	raw_sendmsg,
-	recvmsg:	raw_recvmsg,
-	bind:		raw_bind,
-	backlog_rcv:	raw_rcv_skb,
-	hash:		raw_v4_hash,
-	unhash:		raw_v4_unhash,
+	.name =		"RAW",
+	.close =	raw_close,
+	.connect =	udp_connect,
+	.disconnect =	udp_disconnect,
+	.ioctl =	raw_ioctl,
+	.init =		raw_init,
+	.setsockopt =	raw_setsockopt,
+	.getsockopt =	raw_getsockopt,
+	.sendmsg =	raw_sendmsg,
+	.recvmsg =	raw_recvmsg,
+	.bind =		raw_bind,
+	.backlog_rcv =	raw_rcv_skb,
+	.hash =		raw_v4_hash,
+	.unhash =	raw_v4_unhash,
 };
diff -Nru a/net/ipv4/route.c b/net/ipv4/route.c
--- a/net/ipv4/route.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipv4/route.c	Sat Aug 10 18:42:23 2002
@@ -139,15 +139,15 @@
 
 
 struct dst_ops ipv4_dst_ops = {
-	family:			AF_INET,
-	protocol:		__constant_htons(ETH_P_IP),
-	gc:			rt_garbage_collect,
-	check:			ipv4_dst_check,
-	reroute:		ipv4_dst_reroute,
-	destroy:		ipv4_dst_destroy,
-	negative_advice:	ipv4_negative_advice,
-	link_failure:		ipv4_link_failure,
-	entry_size:		sizeof(struct rtable),
+	.family =		AF_INET,
+	.protocol =		__constant_htons(ETH_P_IP),
+	.gc =			rt_garbage_collect,
+	.check =		ipv4_dst_check,
+	.reroute =		ipv4_dst_reroute,
+	.destroy =		ipv4_dst_destroy,
+	.negative_advice =	ipv4_negative_advice,
+	.link_failure =		ipv4_link_failure,
+	.entry_size =		sizeof(struct rtable),
 };
 
 #define ECN_OR_COST(class)	TC_PRIO_##class
@@ -2267,147 +2267,147 @@
 
 ctl_table ipv4_route_table[] = {
         {
-		ctl_name:	NET_IPV4_ROUTE_FLUSH,
-		procname:	"flush",
-		data:		&flush_delay,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&ipv4_sysctl_rtcache_flush,
-		strategy:	&ipv4_sysctl_rtcache_flush_strategy,
+		.ctl_name =	NET_IPV4_ROUTE_FLUSH,
+		.procname =	"flush",
+		.data =	&flush_delay,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&ipv4_sysctl_rtcache_flush,
+		.strategy =	&ipv4_sysctl_rtcache_flush_strategy,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_MIN_DELAY,
-		procname:	"min_delay",
-		data:		&ip_rt_min_delay,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec_jiffies,
-		strategy:	&sysctl_jiffies,
+		.ctl_name =	NET_IPV4_ROUTE_MIN_DELAY,
+		.procname =	"min_delay",
+		.data =	&ip_rt_min_delay,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec_jiffies,
+		.strategy =	&sysctl_jiffies,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_MAX_DELAY,
-		procname:	"max_delay",
-		data:		&ip_rt_max_delay,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec_jiffies,
-		strategy:	&sysctl_jiffies,
+		.ctl_name =	NET_IPV4_ROUTE_MAX_DELAY,
+		.procname =	"max_delay",
+		.data =	&ip_rt_max_delay,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec_jiffies,
+		.strategy =	&sysctl_jiffies,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_GC_THRESH,
-		procname:	"gc_thresh",
-		data:		&ipv4_dst_ops.gc_thresh,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec,
+		.ctl_name =	NET_IPV4_ROUTE_GC_THRESH,
+		.procname =	"gc_thresh",
+		.data =	&ipv4_dst_ops.gc_thresh,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_MAX_SIZE,
-		procname:	"max_size",
-		data:		&ip_rt_max_size,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec,
+		.ctl_name =	NET_IPV4_ROUTE_MAX_SIZE,
+		.procname =	"max_size",
+		.data =	&ip_rt_max_size,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_GC_MIN_INTERVAL,
-		procname:	"gc_min_interval",
-		data:		&ip_rt_gc_min_interval,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec_jiffies,
-		strategy:	&sysctl_jiffies,
+		.ctl_name =	NET_IPV4_ROUTE_GC_MIN_INTERVAL,
+		.procname =	"gc_min_interval",
+		.data =	&ip_rt_gc_min_interval,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec_jiffies,
+		.strategy =	&sysctl_jiffies,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_GC_TIMEOUT,
-		procname:	"gc_timeout",
-		data:		&ip_rt_gc_timeout,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec_jiffies,
-		strategy:	&sysctl_jiffies,
+		.ctl_name =	NET_IPV4_ROUTE_GC_TIMEOUT,
+		.procname =	"gc_timeout",
+		.data =	&ip_rt_gc_timeout,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec_jiffies,
+		.strategy =	&sysctl_jiffies,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_GC_INTERVAL,
-		procname:	"gc_interval",
-		data:		&ip_rt_gc_interval,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec_jiffies,
-		strategy:	&sysctl_jiffies,
+		.ctl_name =	NET_IPV4_ROUTE_GC_INTERVAL,
+		.procname =	"gc_interval",
+		.data =	&ip_rt_gc_interval,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec_jiffies,
+		.strategy =	&sysctl_jiffies,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_REDIRECT_LOAD,
-		procname:	"redirect_load",
-		data:		&ip_rt_redirect_load,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec,
+		.ctl_name =	NET_IPV4_ROUTE_REDIRECT_LOAD,
+		.procname =	"redirect_load",
+		.data =	&ip_rt_redirect_load,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_REDIRECT_NUMBER,
-		procname:	"redirect_number",
-		data:		&ip_rt_redirect_number,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec,
+		.ctl_name =	NET_IPV4_ROUTE_REDIRECT_NUMBER,
+		.procname =	"redirect_number",
+		.data =	&ip_rt_redirect_number,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_REDIRECT_SILENCE,
-		procname:	"redirect_silence",
-		data:		&ip_rt_redirect_silence,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec,
+		.ctl_name =	NET_IPV4_ROUTE_REDIRECT_SILENCE,
+		.procname =	"redirect_silence",
+		.data =	&ip_rt_redirect_silence,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_ERROR_COST,
-		procname:	"error_cost",
-		data:		&ip_rt_error_cost,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec,
+		.ctl_name =	NET_IPV4_ROUTE_ERROR_COST,
+		.procname =	"error_cost",
+		.data =	&ip_rt_error_cost,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_ERROR_BURST,
-		procname:	"error_burst",
-		data:		&ip_rt_error_burst,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec,
+		.ctl_name =	NET_IPV4_ROUTE_ERROR_BURST,
+		.procname =	"error_burst",
+		.data =	&ip_rt_error_burst,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_GC_ELASTICITY,
-		procname:	"gc_elasticity",
-		data:		&ip_rt_gc_elasticity,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec,
+		.ctl_name =	NET_IPV4_ROUTE_GC_ELASTICITY,
+		.procname =	"gc_elasticity",
+		.data =	&ip_rt_gc_elasticity,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_MTU_EXPIRES,
-		procname:	"mtu_expires",
-		data:		&ip_rt_mtu_expires,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec_jiffies,
-		strategy:	&sysctl_jiffies,
+		.ctl_name =	NET_IPV4_ROUTE_MTU_EXPIRES,
+		.procname =	"mtu_expires",
+		.data =	&ip_rt_mtu_expires,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec_jiffies,
+		.strategy =	&sysctl_jiffies,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_MIN_PMTU,
-		procname:	"min_pmtu",
-		data:		&ip_rt_min_pmtu,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec,
+		.ctl_name =	NET_IPV4_ROUTE_MIN_PMTU,
+		.procname =	"min_pmtu",
+		.data =	&ip_rt_min_pmtu,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec,
 	},
 	{
-		ctl_name:	NET_IPV4_ROUTE_MIN_ADVMSS,
-		procname:	"min_adv_mss",
-		data:		&ip_rt_min_advmss,
-		maxlen:		sizeof(int),
-		mode:		0644,
-		proc_handler:	&proc_dointvec,
+		.ctl_name =	NET_IPV4_ROUTE_MIN_ADVMSS,
+		.procname =	"min_adv_mss",
+		.data =	&ip_rt_min_advmss,
+		.maxlen =		sizeof(int),
+		.mode =	0644,
+		.proc_handler =&proc_dointvec,
 	},
 	 { 0 }
 };
@@ -2428,6 +2428,11 @@
 
 	if ((offset & 3) || (length & 3))
 		return -EIO;
+
+	if (offset >= sizeof(struct ip_rt_acct) * 256) {
+		*eof = 1;
+		return 0;
+	}
 
 	if (offset + length >= sizeof(struct ip_rt_acct) * 256) {
 		length = sizeof(struct ip_rt_acct) * 256 - offset;
diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c	Sat Aug 10 18:42:22 2002
+++ b/net/ipv4/tcp_ipv4.c	Sat Aug 10 18:42:22 2002
@@ -79,11 +79,11 @@
 		       struct sk_buff *skb);
 
 struct tcp_hashinfo __cacheline_aligned tcp_hashinfo = {
-	__tcp_lhash_lock:     RW_LOCK_UNLOCKED,
-	__tcp_lhash_users:    ATOMIC_INIT(0),
+	.__tcp_lhash_lock =   RW_LOCK_UNLOCKED,
+	.__tcp_lhash_users =  ATOMIC_INIT(0),
 	__tcp_lhash_wait:
 	  __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.__tcp_lhash_wait),
-	__tcp_portalloc_lock: SPIN_LOCK_UNLOCKED
+	.__tcp_portalloc_lock = SPIN_LOCK_UNLOCKED
 };
 
 /*
@@ -158,8 +158,8 @@
 	local_bh_enable();
 }
 
-static inline void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb,
-				 unsigned short snum)
+void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb,
+		   unsigned short snum)
 {
 	inet_sk(sk)->num = snum;
 	if ((sk->bind_next = tb->owners) != NULL)
@@ -1379,11 +1379,11 @@
 int sysctl_max_syn_backlog = 256;
 
 struct or_calltable or_ipv4 = {
-	family:		PF_INET,
-	rtx_syn_ack:	tcp_v4_send_synack,
-	send_ack:	tcp_v4_or_send_ack,
-	destructor:	tcp_v4_or_free,
-	send_reset:	tcp_v4_send_reset,
+	.family =	PF_INET,
+	.rtx_syn_ack =	tcp_v4_send_synack,
+	.send_ack =	tcp_v4_or_send_ack,
+	.destructor =	tcp_v4_or_free,
+	.send_reset =	tcp_v4_send_reset,
 };
 
 int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
@@ -1998,17 +1998,17 @@
 }
 
 struct tcp_func ipv4_specific = {
-	queue_xmit:	ip_queue_xmit,
-	send_check:	tcp_v4_send_check,
-	rebuild_header:	tcp_v4_rebuild_header,
-	conn_request:	tcp_v4_conn_request,
-	syn_recv_sock:	tcp_v4_syn_recv_sock,
-	remember_stamp:	tcp_v4_remember_stamp,
-	net_header_len:	sizeof(struct iphdr),
-	setsockopt:	ip_setsockopt,
-	getsockopt:	ip_getsockopt,
-	addr2sockaddr:	v4_addr2sockaddr,
-	sockaddr_len:	sizeof(struct sockaddr_in),
+	.queue_xmit =	ip_queue_xmit,
+	.send_check =	tcp_v4_send_check,
+	.rebuild_header =tcp_v4_rebuild_header,
+	.conn_request =	tcp_v4_conn_request,
+	.syn_recv_sock =tcp_v4_syn_recv_sock,
+	.remember_stamp =tcp_v4_remember_stamp,
+	.net_header_len =sizeof(struct iphdr),
+	.setsockopt =	ip_setsockopt,
+	.getsockopt =	ip_getsockopt,
+	.addr2sockaddr =v4_addr2sockaddr,
+	.sockaddr_len =	sizeof(struct sockaddr_in),
 };
 
 /* NOTE: A lot of things set to zero explicitly by call to
@@ -2305,23 +2305,23 @@
 }
 
 struct proto tcp_prot = {
-	name:		"TCP",
-	close:		tcp_close,
-	connect:	tcp_v4_connect,
-	disconnect:	tcp_disconnect,
-	accept:		tcp_accept,
-	ioctl:		tcp_ioctl,
-	init:		tcp_v4_init_sock,
-	destroy:	tcp_v4_destroy_sock,
-	shutdown:	tcp_shutdown,
-	setsockopt:	tcp_setsockopt,
-	getsockopt:	tcp_getsockopt,
-	sendmsg:	tcp_sendmsg,
-	recvmsg:	tcp_recvmsg,
-	backlog_rcv:	tcp_v4_do_rcv,
-	hash:		tcp_v4_hash,
-	unhash:		tcp_unhash,
-	get_port:	tcp_v4_get_port,
+	.name =		"TCP",
+	.close =	tcp_close,
+	.connect =	tcp_v4_connect,
+	.disconnect =	tcp_disconnect,
+	.accept =	tcp_accept,
+	.ioctl =	tcp_ioctl,
+	.init =		tcp_v4_init_sock,
+	.destroy =	tcp_v4_destroy_sock,
+	.shutdown =	tcp_shutdown,
+	.setsockopt =	tcp_setsockopt,
+	.getsockopt =	tcp_getsockopt,
+	.sendmsg =	tcp_sendmsg,
+	.recvmsg =	tcp_recvmsg,
+	.backlog_rcv =	tcp_v4_do_rcv,
+	.hash =		tcp_v4_hash,
+	.unhash =	tcp_unhash,
+	.get_port =	tcp_v4_get_port,
 };
 
 
diff -Nru a/net/ipv4/udp.c b/net/ipv4/udp.c
--- a/net/ipv4/udp.c	Sat Aug 10 18:42:21 2002
+++ b/net/ipv4/udp.c	Sat Aug 10 18:42:21 2002
@@ -1039,17 +1039,17 @@
 }
 
 struct proto udp_prot = {
- 	name:		"UDP",
-	close:		udp_close,
-	connect:	udp_connect,
-	disconnect:	udp_disconnect,
-	ioctl:		udp_ioctl,
-	setsockopt:	ip_setsockopt,
-	getsockopt:	ip_getsockopt,
-	sendmsg:	udp_sendmsg,
-	recvmsg:	udp_recvmsg,
-	backlog_rcv:	udp_queue_rcv_skb,
-	hash:		udp_v4_hash,
-	unhash:		udp_v4_unhash,
-	get_port:	udp_v4_get_port,
+ 	.name =		"UDP",
+	.close =	udp_close,
+	.connect =	udp_connect,
+	.disconnect =	udp_disconnect,
+	.ioctl =	udp_ioctl,
+	.setsockopt =	ip_setsockopt,
+	.getsockopt =	ip_getsockopt,
+	.sendmsg =	udp_sendmsg,
+	.recvmsg =	udp_recvmsg,
+	.backlog_rcv =	udp_queue_rcv_skb,
+	.hash =		udp_v4_hash,
+	.unhash =	udp_v4_unhash,
+	.get_port =	udp_v4_get_port,
 };
diff -Nru a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
--- a/net/ipv6/af_inet6.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipv6/af_inet6.c	Sat Aug 10 18:42:23 2002
@@ -506,50 +506,50 @@
 }
 
 struct proto_ops inet6_stream_ops = {
-	family:		PF_INET6,
+	.family =	PF_INET6,
 
-	release:	inet6_release,
-	bind:		inet6_bind,
-	connect:	inet_stream_connect,		/* ok		*/
-	socketpair:	sock_no_socketpair,		/* a do nothing	*/
-	accept:		inet_accept,			/* ok		*/
-	getname:	inet6_getname, 
-	poll:		tcp_poll,			/* ok		*/
-	ioctl:		inet6_ioctl,			/* must change  */
-	listen:		inet_listen,			/* ok		*/
-	shutdown:	inet_shutdown,			/* ok		*/
-	setsockopt:	inet_setsockopt,		/* ok		*/
-	getsockopt:	inet_getsockopt,		/* ok		*/
-	sendmsg:	inet_sendmsg,			/* ok		*/
-	recvmsg:	inet_recvmsg,			/* ok		*/
-	mmap:		sock_no_mmap,
-	sendpage:	tcp_sendpage
+	.release =	inet6_release,
+	.bind =		inet6_bind,
+	.connect =	inet_stream_connect,		/* ok		*/
+	.socketpair =	sock_no_socketpair,		/* a do nothing	*/
+	.accept =	inet_accept,			/* ok		*/
+	.getname =	inet6_getname, 
+	.poll =		tcp_poll,			/* ok		*/
+	.ioctl =	inet6_ioctl,			/* must change  */
+	.listen =	inet_listen,			/* ok		*/
+	.shutdown =	inet_shutdown,			/* ok		*/
+	.setsockopt =	inet_setsockopt,		/* ok		*/
+	.getsockopt =	inet_getsockopt,		/* ok		*/
+	.sendmsg =	inet_sendmsg,			/* ok		*/
+	.recvmsg =	inet_recvmsg,			/* ok		*/
+	.mmap =		sock_no_mmap,
+	.sendpage =	tcp_sendpage
 };
 
 struct proto_ops inet6_dgram_ops = {
-	family:		PF_INET6,
+	.family =	PF_INET6,
 
-	release:	inet6_release,
-	bind:		inet6_bind,
-	connect:	inet_dgram_connect,		/* ok		*/
-	socketpair:	sock_no_socketpair,		/* a do nothing	*/
-	accept:		sock_no_accept,			/* a do nothing	*/
-	getname:	inet6_getname, 
-	poll:		datagram_poll,			/* ok		*/
-	ioctl:		inet6_ioctl,			/* must change  */
-	listen:		sock_no_listen,			/* ok		*/
-	shutdown:	inet_shutdown,			/* ok		*/
-	setsockopt:	inet_setsockopt,		/* ok		*/
-	getsockopt:	inet_getsockopt,		/* ok		*/
-	sendmsg:	inet_sendmsg,			/* ok		*/
-	recvmsg:	inet_recvmsg,			/* ok		*/
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	inet6_release,
+	.bind =		inet6_bind,
+	.connect =	inet_dgram_connect,		/* ok		*/
+	.socketpair =	sock_no_socketpair,		/* a do nothing	*/
+	.accept =	sock_no_accept,			/* a do nothing	*/
+	.getname =	inet6_getname, 
+	.poll =		datagram_poll,			/* ok		*/
+	.ioctl =	inet6_ioctl,			/* must change  */
+	.listen =	sock_no_listen,			/* ok		*/
+	.shutdown =	inet_shutdown,			/* ok		*/
+	.setsockopt =	inet_setsockopt,		/* ok		*/
+	.getsockopt =	inet_getsockopt,		/* ok		*/
+	.sendmsg =	inet_sendmsg,			/* ok		*/
+	.recvmsg =	inet_recvmsg,			/* ok		*/
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 static struct net_proto_family inet6_family_ops = {
-	family:	PF_INET6,
-	create:	inet6_create,
+	.family =PF_INET6,
+	.create =inet6_create,
 };
 
 #ifdef MODULE
@@ -567,13 +567,13 @@
 #endif
 
 static struct inet_protosw rawv6_protosw = {
-	type:        SOCK_RAW,
-	protocol:    IPPROTO_IP,	/* wild card */
-	prot:        &rawv6_prot,
-	ops:         &inet6_dgram_ops,
-	capability:  CAP_NET_RAW,
-	no_check:    UDP_CSUM_DEFAULT,
-	flags:       INET_PROTOSW_REUSE,
+	.type =      SOCK_RAW,
+	.protocol =  IPPROTO_IP,	/* wild card */
+	.prot =      &rawv6_prot,
+	.ops =       &inet6_dgram_ops,
+	.capability =CAP_NET_RAW,
+	.no_check =  UDP_CSUM_DEFAULT,
+	.flags =     INET_PROTOSW_REUSE,
 };
 
 #define INETSW6_ARRAY_LEN (sizeof(inetsw6_array) / sizeof(struct inet_protosw))
diff -Nru a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
--- a/net/ipv6/ndisc.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipv6/ndisc.c	Sat Aug 10 18:42:23 2002
@@ -85,62 +85,62 @@
 static void pndisc_redo(struct sk_buff *skb);
 
 static struct neigh_ops ndisc_generic_ops = {
-	family:			AF_INET6,
-	solicit:		ndisc_solicit,
-	error_report:		ndisc_error_report,
-	output:			neigh_resolve_output,
-	connected_output:	neigh_connected_output,
-	hh_output:		dev_queue_xmit,
-	queue_xmit:		dev_queue_xmit,
+	.family =		AF_INET6,
+	.solicit =		ndisc_solicit,
+	.error_report =		ndisc_error_report,
+	.output =		neigh_resolve_output,
+	.connected_output =	neigh_connected_output,
+	.hh_output =		dev_queue_xmit,
+	.queue_xmit =		dev_queue_xmit,
 };
 
 static struct neigh_ops ndisc_hh_ops = {
-	family:			AF_INET6,
-	solicit:		ndisc_solicit,
-	error_report:		ndisc_error_report,
-	output:			neigh_resolve_output,
-	connected_output:	neigh_resolve_output,
-	hh_output:		dev_queue_xmit,
-	queue_xmit:		dev_queue_xmit,
+	.family =		AF_INET6,
+	.solicit =		ndisc_solicit,
+	.error_report =		ndisc_error_report,
+	.output =		neigh_resolve_output,
+	.connected_output =	neigh_resolve_output,
+	.hh_output =		dev_queue_xmit,
+	.queue_xmit =		dev_queue_xmit,
 };
 
 
 static struct neigh_ops ndisc_direct_ops = {
-	family:			AF_INET6,
-	output:			dev_queue_xmit,
-	connected_output:	dev_queue_xmit,
-	hh_output:		dev_queue_xmit,
-	queue_xmit:		dev_queue_xmit,
+	.family =		AF_INET6,
+	.output =		dev_queue_xmit,
+	.connected_output =	dev_queue_xmit,
+	.hh_output =		dev_queue_xmit,
+	.queue_xmit =		dev_queue_xmit,
 };
 
 struct neigh_table nd_tbl = {
-	family:		AF_INET6,
-	entry_size:	sizeof(struct neighbour) + sizeof(struct in6_addr),
-	key_len:	sizeof(struct in6_addr),
-	hash:		ndisc_hash,
-	constructor:	ndisc_constructor,
-	pconstructor:	pndisc_constructor,
-	pdestructor:	pndisc_destructor,
-	proxy_redo:	pndisc_redo,
-	id:		"ndisc_cache",
-	parms: {
-		tbl:			&nd_tbl,
-		base_reachable_time:	30 * HZ,
-		retrans_time:		 1 * HZ,
-		gc_staletime:		60 * HZ,
-		reachable_time:		30 * HZ,
-		delay_probe_time:	 5 * HZ,
-		queue_len:		 3,
-		ucast_probes:		 3,
-		mcast_probes:		 3,
-		anycast_delay:		 1 * HZ,
-		proxy_delay:		(8 * HZ) / 10,
-		proxy_qlen:		64,
+	.family =	AF_INET6,
+	.entry_size =	sizeof(struct neighbour) + sizeof(struct in6_addr),
+	.key_len =	sizeof(struct in6_addr),
+	.hash =		ndisc_hash,
+	.constructor =	ndisc_constructor,
+	.pconstructor =	pndisc_constructor,
+	.pdestructor =	pndisc_destructor,
+	.proxy_redo =	pndisc_redo,
+	.id =		"ndisc_cache",
+	.parms = {
+		.tbl =			&nd_tbl,
+		.base_reachable_time =	30 * HZ,
+		.retrans_time =	 1 * HZ,
+		.gc_staletime =	60 * HZ,
+		.reachable_time =		30 * HZ,
+		.delay_probe_time =	 5 * HZ,
+		.queue_len =		 3,
+		.ucast_probes =	 3,
+		.mcast_probes =	 3,
+		.anycast_delay =	 1 * HZ,
+		.proxy_delay =		(8 * HZ) / 10,
+		.proxy_qlen =		64,
 	},
-	gc_interval:	  30 * HZ,
-	gc_thresh1:	 128,
-	gc_thresh2:	 512,
-	gc_thresh3:	1024,
+	.gc_interval =	  30 * HZ,
+	.gc_thresh1 =	 128,
+	.gc_thresh2 =	 512,
+	.gc_thresh3 =	1024,
 };
 
 #define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
diff -Nru a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
--- a/net/ipv6/netfilter/ip6_tables.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipv6/netfilter/ip6_tables.c	Sat Aug 10 18:42:23 2002
@@ -742,7 +742,7 @@
 	t = ip6t_get_target(e);
 	target = find_target_lock(t->u.user.name, &ret, &ip6t_mutex);
 	if (!target) {
-	  //		duprintf("check_entry: `%s' not found\n", t->u.name);
+		duprintf("check_entry: `%s' not found\n", t->u.user.name);
 		goto cleanup_matches;
 	}
 	if (target->me)
diff -Nru a/net/ipv6/raw.c b/net/ipv6/raw.c
--- a/net/ipv6/raw.c	Sat Aug 10 18:42:22 2002
+++ b/net/ipv6/raw.c	Sat Aug 10 18:42:22 2002
@@ -912,19 +912,19 @@
 }
 
 struct proto rawv6_prot = {
-	name:		"RAW",
-	close:		rawv6_close,
-	connect:	udpv6_connect,
-	disconnect:	udp_disconnect,
-	ioctl:		rawv6_ioctl,
-	init:		rawv6_init_sk,
-	destroy:	inet6_destroy_sock,
-	setsockopt:	rawv6_setsockopt,
-	getsockopt:	rawv6_getsockopt,
-	sendmsg:	rawv6_sendmsg,
-	recvmsg:	rawv6_recvmsg,
-	bind:		rawv6_bind,
-	backlog_rcv:	rawv6_rcv_skb,
-	hash:		raw_v6_hash,
-	unhash:		raw_v6_unhash,
+	.name =		"RAW",
+	.close =	rawv6_close,
+	.connect =	udpv6_connect,
+	.disconnect =	udp_disconnect,
+	.ioctl =	rawv6_ioctl,
+	.init =		rawv6_init_sk,
+	.destroy =	inet6_destroy_sock,
+	.setsockopt =	rawv6_setsockopt,
+	.getsockopt =	rawv6_getsockopt,
+	.sendmsg =	rawv6_sendmsg,
+	.recvmsg =	rawv6_recvmsg,
+	.bind =		rawv6_bind,
+	.backlog_rcv =	rawv6_rcv_skb,
+	.hash =		raw_v6_hash,
+	.unhash =	raw_v6_unhash,
 };
diff -Nru a/net/ipv6/sit.c b/net/ipv6/sit.c
--- a/net/ipv6/sit.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipv6/sit.c	Sat Aug 10 18:42:23 2002
@@ -64,8 +64,8 @@
 static int ipip6_tunnel_init(struct net_device *dev);
 
 static struct net_device ipip6_fb_tunnel_dev = {
-	name: "sit0",
-	init: ipip6_fb_tunnel_init
+	.name = "sit0",
+	.init = ipip6_fb_tunnel_init
 };
 
 static struct ip_tunnel ipip6_fb_tunnel = {
diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipv6/tcp_ipv6.c	Sat Aug 10 18:42:23 2002
@@ -85,6 +85,37 @@
 	return tcp_v6_hashfn(laddr, lport, faddr, fport);
 }
 
+static inline int ipv6_rcv_saddr_equal(struct sock *sk, struct sock *sk2)
+{
+	struct ipv6_pinfo *np = inet6_sk(sk);
+	int addr_type = ipv6_addr_type(&np->rcv_saddr);
+
+	return !inet_sk(sk2)->rcv_saddr || addr_type == IPV6_ADDR_ANY ||
+	       (sk2->family == AF_INET6 &&
+	        !ipv6_addr_cmp(&np->rcv_saddr,
+			       sk2->state != TCP_TIME_WAIT ?
+			       &inet6_sk(sk2)->rcv_saddr :
+			       &((struct tcp_tw_bucket *)sk)->v6_rcv_saddr)) ||
+	       (addr_type == IPV6_ADDR_MAPPED && sk2->family == AF_INET &&
+		inet_sk(sk)->rcv_saddr == inet_sk(sk2)->rcv_saddr);
+}
+
+static inline int tcp_v6_bind_conflict(struct sock *sk,
+				       struct tcp_bind_bucket *tb)
+{
+	struct sock *sk2 = tb->owners;
+
+	/* We must walk the whole port owner list in this case. -DaveM */
+	for (; sk2; sk2 = sk2->bind_next)
+		if (sk != sk2 && sk->bound_dev_if == sk2->bound_dev_if &&
+		    (!sk->reuse || !sk2->reuse ||
+		     sk2->state == TCP_LISTEN) &&
+		     ipv6_rcv_saddr_equal(sk, sk2))
+			break;
+
+	return sk2 != NULL;
+}
+
 /* Grrr, addr_type already calculated by caller, but I don't want
  * to add some silly "cookie" argument to this method just for that.
  * But it doesn't matter, the recalculation is in the rarest path
@@ -139,44 +170,15 @@
 		if (tb->fastreuse > 0 && sk->reuse != 0 && sk->state != TCP_LISTEN) {
 			goto success;
 		} else {
-			struct ipv6_pinfo *np = inet6_sk(sk);
-			struct sock *sk2 = tb->owners;
-			int sk_reuse = sk->reuse;
-			int addr_type = ipv6_addr_type(&np->rcv_saddr);
-
-			/* We must walk the whole port owner list in this case. -DaveM */
-			for( ; sk2 != NULL; sk2 = sk2->bind_next) {
-				struct ipv6_pinfo *np2 = inet6_sk(sk2);
-
-				if (sk != sk2 &&
-				    sk->bound_dev_if == sk2->bound_dev_if) {
-					if (!sk_reuse	||
-					    !sk2->reuse	||
-					    sk2->state == TCP_LISTEN) {
-						/* NOTE: IPv6 tw bucket have different format */
-						if (!inet_sk(sk2)->rcv_saddr ||
-						    addr_type == IPV6_ADDR_ANY ||
-						    !ipv6_addr_cmp(&np->rcv_saddr,
-								   sk2->state != TCP_TIME_WAIT ?
-								   &np2->rcv_saddr :
-								   &((struct tcp_tw_bucket*)sk)->v6_rcv_saddr) ||
-						    (addr_type==IPV6_ADDR_MAPPED && sk2->family==AF_INET &&
-						     inet_sk(sk)->rcv_saddr ==
-						     inet_sk(sk2)->rcv_saddr))
-							break;
-					}
-				}
-			}
-			/* If we found a conflict, fail. */
 			ret = 1;
-			if (sk2 != NULL)
+			if (tcp_v6_bind_conflict(sk, tb))
 				goto fail_unlock;
 		}
 	}
 	ret = 1;
 	if (tb == NULL &&
 	    (tb = tcp_bucket_create(head, snum)) == NULL)
-			goto fail_unlock;
+		goto fail_unlock;
 	if (tb->owners == NULL) {
 		if (sk->reuse && sk->state != TCP_LISTEN)
 			tb->fastreuse = 1;
@@ -187,16 +189,9 @@
 		tb->fastreuse = 0;
 
 success:
-	inet_sk(sk)->num = snum;
-	if (sk->prev == NULL) {
-		if ((sk->bind_next = tb->owners) != NULL)
-			tb->owners->bind_pprev = &sk->bind_next;
-		tb->owners = sk;
-		sk->bind_pprev = &tb->owners;
-		sk->prev = (struct sock *) tb;
-	} else {
-		BUG_TRAP(sk->prev == (struct sock *) tb);
-	}
+	if (!sk->prev)
+		tcp_bind_hash(sk, tb, snum);
+	BUG_TRAP(sk->prev == (struct sock *)tb);
 	ret = 0;
 
 fail_unlock:
@@ -413,7 +408,7 @@
 
 static __u32 tcp_v6_init_sequence(struct sock *sk, struct sk_buff *skb)
 {
-	if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
+	if (skb->protocol == htons(ETH_P_IPV6)) {
 		return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
 						    skb->nh.ipv6h->saddr.s6_addr32,
 						    skb->h.th->dest,
@@ -1051,10 +1046,8 @@
 	
 	if (ts) {
 		u32 *ptr = (u32*)(t1 + 1);
-		*ptr++ = __constant_htonl((TCPOPT_NOP << 24) |
-					  (TCPOPT_NOP << 16) |
-					  (TCPOPT_TIMESTAMP << 8) |
-					  TCPOLEN_TIMESTAMP);
+		*ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+			       (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
 		*ptr++ = htonl(tcp_time_stamp);
 		*ptr = htonl(ts);
 	}
@@ -1166,7 +1159,7 @@
 	struct open_request *req = NULL;
 	__u32 isn = TCP_SKB_CB(skb)->when;
 
-	if (skb->protocol == __constant_htons(ETH_P_IP))
+	if (skb->protocol == htons(ETH_P_IP))
 		return tcp_v4_conn_request(sk, skb);
 
 	/* FIXME: do the same check for anycast */
@@ -1247,7 +1240,7 @@
 	struct sock *newsk;
 	struct ipv6_txoptions *opt;
 
-	if (skb->protocol == __constant_htons(ETH_P_IP)) {
+	if (skb->protocol == htons(ETH_P_IP)) {
 		/*
 		 *	v6 mapped
 		 */
@@ -1463,7 +1456,7 @@
 	   tcp_v6_hnd_req and tcp_v6_send_reset().   --ANK
 	 */
 
-	if (skb->protocol == __constant_htons(ETH_P_IP))
+	if (skb->protocol == htons(ETH_P_IP))
 		return tcp_v4_do_rcv(sk, skb);
 
 #ifdef CONFIG_FILTER
@@ -1784,7 +1777,7 @@
 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
 
 	sin6->sin6_family = AF_INET6;
-	memcpy(&sin6->sin6_addr, &np->daddr, sizeof(struct in6_addr));
+	ipv6_addr_copy(&sin6->sin6_addr, &np->daddr);
 	sin6->sin6_port	= inet_sk(sk)->dport;
 	/* We do not store received flowlabel for TCP */
 	sin6->sin6_flowinfo = 0;
@@ -2144,43 +2137,43 @@
 }
 
 struct proto tcpv6_prot = {
-	name:		"TCPv6",
-	close:		tcp_close,
-	connect:	tcp_v6_connect,
-	disconnect:	tcp_disconnect,
-	accept:		tcp_accept,
-	ioctl:		tcp_ioctl,
-	init:		tcp_v6_init_sock,
-	destroy:	tcp_v6_destroy_sock,
-	shutdown:	tcp_shutdown,
-	setsockopt:	tcp_setsockopt,
-	getsockopt:	tcp_getsockopt,
-	sendmsg:	tcp_sendmsg,
-	recvmsg:	tcp_recvmsg,
-	backlog_rcv:	tcp_v6_do_rcv,
-	hash:		tcp_v6_hash,
-	unhash:		tcp_unhash,
-	get_port:	tcp_v6_get_port,
+	.name =		"TCPv6",
+	.close =	tcp_close,
+	.connect =	tcp_v6_connect,
+	.disconnect =	tcp_disconnect,
+	.accept =	tcp_accept,
+	.ioctl =	tcp_ioctl,
+	.init =		tcp_v6_init_sock,
+	.destroy =	tcp_v6_destroy_sock,
+	.shutdown =	tcp_shutdown,
+	.setsockopt =	tcp_setsockopt,
+	.getsockopt =	tcp_getsockopt,
+	.sendmsg =	tcp_sendmsg,
+	.recvmsg =	tcp_recvmsg,
+	.backlog_rcv =	tcp_v6_do_rcv,
+	.hash =		tcp_v6_hash,
+	.unhash =	tcp_unhash,
+	.get_port =	tcp_v6_get_port,
 };
 
 static struct inet6_protocol tcpv6_protocol =
 {
-	handler:	tcp_v6_rcv,
-	err_handler:	tcp_v6_err,
-	protocol:	IPPROTO_TCP,
-	name:		"TCPv6",
+	.handler =	tcp_v6_rcv,
+	.err_handler =	tcp_v6_err,
+	.protocol =	IPPROTO_TCP,
+	.name =		"TCPv6",
 };
 
 extern struct proto_ops inet6_stream_ops;
 
 static struct inet_protosw tcpv6_protosw = {
-	type:        SOCK_STREAM,
-	protocol:    IPPROTO_TCP,
-	prot:        &tcpv6_prot,
-	ops:         &inet6_stream_ops,
-	capability:  -1,
-	no_check:    0,
-	flags:       INET_PROTOSW_PERMANENT,
+	.type =      SOCK_STREAM,
+	.protocol =  IPPROTO_TCP,
+	.prot =      &tcpv6_prot,
+	.ops =       &inet6_stream_ops,
+	.capability =-1,
+	.no_check =  0,
+	.flags =     INET_PROTOSW_PERMANENT,
 };
 
 void __init tcpv6_init(void)
diff -Nru a/net/ipv6/udp.c b/net/ipv6/udp.c
--- a/net/ipv6/udp.c	Sat Aug 10 18:42:22 2002
+++ b/net/ipv6/udp.c	Sat Aug 10 18:42:22 2002
@@ -905,10 +905,10 @@
 }
 
 static struct inet6_protocol udpv6_protocol = {
-	handler:	udpv6_rcv,
-	err_handler:	udpv6_err,
-	protocol:	IPPROTO_UDP,
-	name:		"UDPv6",
+	.handler =	udpv6_rcv,
+	.err_handler =	udpv6_err,
+	.protocol =	IPPROTO_UDP,
+	.name =		"UDPv6",
 };
 
 #define LINE_LEN 190
@@ -987,32 +987,32 @@
 }
 
 struct proto udpv6_prot = {
-	name:		"UDP",
-	close:		udpv6_close,
-	connect:	udpv6_connect,
-	disconnect:	udp_disconnect,
-	ioctl:		udp_ioctl,
-	destroy:	inet6_destroy_sock,
-	setsockopt:	ipv6_setsockopt,
-	getsockopt:	ipv6_getsockopt,
-	sendmsg:	udpv6_sendmsg,
-	recvmsg:	udpv6_recvmsg,
-	backlog_rcv:	udpv6_queue_rcv_skb,
-	hash:		udp_v6_hash,
-	unhash:		udp_v6_unhash,
-	get_port:	udp_v6_get_port,
+	.name =		"UDP",
+	.close =	udpv6_close,
+	.connect =	udpv6_connect,
+	.disconnect =	udp_disconnect,
+	.ioctl =	udp_ioctl,
+	.destroy =	inet6_destroy_sock,
+	.setsockopt =	ipv6_setsockopt,
+	.getsockopt =	ipv6_getsockopt,
+	.sendmsg =	udpv6_sendmsg,
+	.recvmsg =	udpv6_recvmsg,
+	.backlog_rcv =	udpv6_queue_rcv_skb,
+	.hash =		udp_v6_hash,
+	.unhash =	udp_v6_unhash,
+	.get_port =	udp_v6_get_port,
 };
 
 extern struct proto_ops inet6_dgram_ops;
 
 static struct inet_protosw udpv6_protosw = {
-	type:        SOCK_DGRAM,
-	protocol:    IPPROTO_UDP,
-	prot:        &udpv6_prot,
-	ops:         &inet6_dgram_ops,
-	capability:  -1,
-	no_check:    UDP_CSUM_DEFAULT,
-	flags:       INET_PROTOSW_PERMANENT,
+	.type =      SOCK_DGRAM,
+	.protocol =  IPPROTO_UDP,
+	.prot =      &udpv6_prot,
+	.ops =       &inet6_dgram_ops,
+	.capability =-1,
+	.no_check =  UDP_CSUM_DEFAULT,
+	.flags =     INET_PROTOSW_PERMANENT,
 };
 
 
diff -Nru a/net/ipx/Config.help b/net/ipx/Config.help
--- a/net/ipx/Config.help	Sat Aug 10 18:42:23 2002
+++ b/net/ipx/Config.help	Sat Aug 10 18:42:23 2002
@@ -23,25 +23,3 @@
 
   If you don't know what you are doing, say N.
 
-CONFIG_SPX
-  * Orphaned entry retained 20 April 2001 by Petr Vandrovec     *
-  * If you read this note from the configurator, please contact *
-  * the Configure.help maintainers.                             *
-  The Sequenced Packet eXchange protocol is a transport layer protocol
-  built on top of IPX. It is used in Novell NetWare systems for
-  client-server applications and is similar to TCP (which runs on top
-  of IP).
-
-  Note that Novell NetWare file sharing does not use SPX; it uses a
-  protocol called NCP, for which separate Linux support is available
-  ("NCP file system support" below for the client side, and the user
-  space programs lwared or mars_nwe for the server side).
-
-  Say Y here if you have use for SPX; read the IPX-HOWTO at
-  <http://www.linuxdoc.org/docs.html#howto> 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 af_spx.o. If you want to compile it as a
-  module, say M here and read <file:Documentation/modules.txt>.
-
diff -Nru a/net/ipx/Config.in b/net/ipx/Config.in
--- a/net/ipx/Config.in	Sat Aug 10 18:42:22 2002
+++ b/net/ipx/Config.in	Sat Aug 10 18:42:22 2002
@@ -3,6 +3,3 @@
 #
 
 bool '  IPX: Full internal IPX network' CONFIG_IPX_INTERN
-#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-#  dep_tristate '  IPX: SPX networking (EXPERIMENTAL)' CONFIG_SPX $CONFIG_IPX
-#fi
diff -Nru a/net/ipx/Makefile b/net/ipx/Makefile
--- a/net/ipx/Makefile	Sat Aug 10 18:42:21 2002
+++ b/net/ipx/Makefile	Sat Aug 10 18:42:21 2002
@@ -8,7 +8,6 @@
 
 ipx-y			:= af_ipx.o
 ipx-$(CONFIG_SYSCTL)	+= sysctl_net_ipx.o
-ipx-$(CONFIG_SPX)	+= af_spx.o
 ipx-objs		:= $(ipx-y)
 
 include $(TOPDIR)/Rules.make
diff -Nru a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
--- a/net/ipx/af_ipx.c	Sat Aug 10 18:42:21 2002
+++ b/net/ipx/af_ipx.c	Sat Aug 10 18:42:21 2002
@@ -76,6 +76,7 @@
  *	Revision 048:	Use sk->protinfo to store the pointer to IPX private
  *			area, remove af_ipx from sk->protinfo and move ipx_opt
  *			to include/net/ipx.h, use IPX_SK like DecNET, etc
+ *	Revision 049:	SPX support dropped, see comment in ipx_create
  *
  *	Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT
  *	pair. Also, now usage count is managed this way
@@ -144,17 +145,14 @@
 
 static struct proto_ops ipx_dgram_ops;
 
-static struct net_proto_family *spx_family_ops;
-static DECLARE_RWSEM(spx_family_ops_lock);
-
-static ipx_route *ipx_routes;
+static struct ipx_route *ipx_routes;
 static rwlock_t ipx_routes_lock = RW_LOCK_UNLOCKED;
 
-static ipx_interface *ipx_interfaces;
+static struct ipx_interface *ipx_interfaces;
 static spinlock_t ipx_interfaces_lock = SPIN_LOCK_UNLOCKED;
 
-static ipx_interface *ipx_primary_net;
-static ipx_interface *ipx_internal_net;
+static struct ipx_interface *ipx_primary_net;
+static struct ipx_interface *ipx_internal_net;
 
 #undef IPX_REFCNT_DEBUG
 #ifdef IPX_REFCNT_DEBUG
@@ -180,9 +178,9 @@
 		ipx_primary_net = ipx_interfaces;
 }
 
-static int ipxcfg_get_config_data(ipx_config_data *arg)
+static int ipxcfg_get_config_data(struct ipx_config_data *arg)
 {
-	ipx_config_data	vals;
+	struct ipx_config_data vals;
 
 	vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces;
 	vals.ipxcfg_auto_select_primary	   = ipxcfg_auto_select_primary;
@@ -192,22 +190,22 @@
 
 /* Handlers for the socket list. */
 
-static inline void ipxitf_hold(ipx_interface *intrfc)
+static __inline__ void ipxitf_hold(struct ipx_interface *intrfc)
 {
 	atomic_inc(&intrfc->refcnt);
 }
 
-static void ipxitf_down(ipx_interface *intrfc);
+static void ipxitf_down(struct ipx_interface *intrfc);
 
-static inline void ipxitf_put(ipx_interface *intrfc)
+static __inline__ void ipxitf_put(struct ipx_interface *intrfc)
 {
 	if (atomic_dec_and_test(&intrfc->refcnt))
 		ipxitf_down(intrfc);
 }
 
-static void __ipxitf_down(ipx_interface *intrfc);
+static void __ipxitf_down(struct ipx_interface *intrfc);
 
-static inline void __ipxitf_put(ipx_interface *intrfc)
+static __inline__ void __ipxitf_put(struct ipx_interface *intrfc)
 {
 	if (atomic_dec_and_test(&intrfc->refcnt))
 		__ipxitf_down(intrfc);
@@ -218,11 +216,11 @@
  * use this facility.
  */
 
-void ipx_remove_socket(struct sock *sk)
+static void ipx_remove_socket(struct sock *sk)
 {
 	struct sock *s;
 	/* Determine interface with which socket is associated */
-	ipx_interface *intrfc = ipx_sk(sk)->intrfc;
+	struct ipx_interface *intrfc = ipx_sk(sk)->intrfc;
 
 	if (!intrfc)
 		goto out;
@@ -268,7 +266,7 @@
  * The following code is used to support IPX Interfaces (IPXITF).  An
  * IPX interface is defined by a physical device and a frame type.
  */
-static ipx_route * ipxrtr_lookup(__u32);
+static struct ipx_route *ipxrtr_lookup(__u32 net);
 
 /* ipxitf_clear_primary_net has to be called with ipx_interfaces_lock held */
 
@@ -277,10 +275,10 @@
 	ipx_primary_net = ipxcfg_auto_select_primary ? ipx_interfaces : NULL;
 }
 
-static ipx_interface *__ipxitf_find_using_phys(struct net_device *dev,
-						unsigned short datalink)
+static struct ipx_interface *__ipxitf_find_using_phys(struct net_device *dev,
+						      unsigned short datalink)
 {
-	ipx_interface *i = ipx_interfaces;
+	struct ipx_interface *i = ipx_interfaces;
 
 	while (i && (i->if_dev != dev || i->if_dlink_type != datalink))
 		i = i->if_next;
@@ -288,10 +286,10 @@
 	return i;
 }
 
-static ipx_interface *ipxitf_find_using_phys(struct net_device *dev,
-						unsigned short datalink)
+static struct ipx_interface *ipxitf_find_using_phys(struct net_device *dev,
+						    unsigned short datalink)
 {
-	ipx_interface *i;
+	struct ipx_interface *i;
 
 	spin_lock_bh(&ipx_interfaces_lock);
 	i = __ipxitf_find_using_phys(dev, datalink);
@@ -301,9 +299,9 @@
 	return i;
 }
 
-static ipx_interface *ipxitf_find_using_net(__u32 net)
+static struct ipx_interface *ipxitf_find_using_net(__u32 net)
 {
-	ipx_interface *i;
+	struct ipx_interface *i;
 
 	spin_lock_bh(&ipx_interfaces_lock);
 	if (net)
@@ -320,7 +318,7 @@
 }
 
 /* Sockets are bound to a particular IPX interface. */
-static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk)
+static void ipxitf_insert_socket(struct ipx_interface *intrfc, struct sock *sk)
 {
 	ipxitf_hold(intrfc);
 	sock_hold(sk);
@@ -340,7 +338,7 @@
 }
 
 /* caller must hold intrfc->if_sklist_lock */
-static struct sock *__ipxitf_find_socket(ipx_interface *intrfc,
+static struct sock *__ipxitf_find_socket(struct ipx_interface *intrfc,
 					 unsigned short port)
 {
 	struct sock *s = intrfc->if_sklist;
@@ -352,7 +350,7 @@
 }
 
 /* caller must hold a reference to intrfc */
-static struct sock *ipxitf_find_socket(ipx_interface *intrfc,
+static struct sock *ipxitf_find_socket(struct ipx_interface *intrfc,
 					unsigned short port)
 {
 	struct sock *s;
@@ -367,8 +365,9 @@
 }
 
 #ifdef CONFIG_IPX_INTERN
-static struct sock *ipxitf_find_internal_socket(ipx_interface *intrfc,
-			    unsigned char *node, unsigned short port)
+static struct sock *ipxitf_find_internal_socket(struct ipx_interface *intrfc,
+						unsigned char *node,
+						unsigned short port)
 {
 	struct sock *s;
 
@@ -391,9 +390,9 @@
 }
 #endif
 
-static void ipxrtr_del_routes(ipx_interface *);
+static void ipxrtr_del_routes(struct ipx_interface *intrfc);
 
-static void __ipxitf_down(ipx_interface *intrfc)
+static void __ipxitf_down(struct ipx_interface *intrfc)
 {
 	struct sock *s, *t;
 
@@ -421,7 +420,7 @@
 	if (intrfc == ipx_interfaces)
 		ipx_interfaces = intrfc->if_next;
 	else {
-		ipx_interface *i = ipx_interfaces;
+		struct ipx_interface *i = ipx_interfaces;
 		while (i && i->if_next != intrfc)
 		     i = i->if_next;
 		if (i && i->if_next == intrfc)
@@ -440,7 +439,7 @@
 	MOD_DEC_USE_COUNT;
 }
 
-static void ipxitf_down(ipx_interface *intrfc)
+static void ipxitf_down(struct ipx_interface *intrfc)
 {
 	spin_lock_bh(&ipx_interfaces_lock);
 	__ipxitf_down(intrfc);
@@ -451,7 +450,7 @@
 				unsigned long event, void *ptr)
 {
 	struct net_device *dev = ptr;
-	ipx_interface *i, *tmp;
+	struct ipx_interface *i, *tmp;
 
 	if (event != NETDEV_DOWN && event != NETDEV_UP)
 		goto out;
@@ -484,10 +483,10 @@
 /* caller must hold a reference to intrfc */
 
 #ifdef CONFIG_IPX_INTERN
-static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb,
-				int copy)
+static int ipxitf_demux_socket(struct ipx_interface *intrfc,
+			       struct sk_buff *skb, int copy)
 {
-	struct ipxhdr *ipx = skb->nh.ipxh;
+	struct ipxhdr *ipx = ipx_hdr(skb);
 	int is_broadcast = !memcmp(ipx->ipx_dest.node, ipx_broadcast_node,
 				   IPX_NODE_LEN);
 	struct sock *s;
@@ -532,7 +531,7 @@
 	return ret;
 }
 #else
-static struct sock *ncp_connection_hack(ipx_interface *intrfc,
+static struct sock *ncp_connection_hack(struct ipx_interface *intrfc,
 					struct ipxhdr *ipx)
 {
 	/* The packet's target is a NCP connection handler. We want to hand it
@@ -566,10 +565,10 @@
 	return sk;
 }
 
-static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb,
-				int copy)
+static int ipxitf_demux_socket(struct ipx_interface *intrfc,
+			       struct sk_buff *skb, int copy)
 {
-	struct ipxhdr *ipx = skb->nh.ipxh;
+	struct ipxhdr *ipx = ipx_hdr(skb);
 	struct sock *sock1 = NULL, *sock2 = NULL;
 	struct sk_buff *skb1 = NULL, *skb2 = NULL;
 	int ret;
@@ -651,11 +650,11 @@
 }
 #endif	/* CONFIG_IPX_INTERN */
 
-static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc,
+static struct sk_buff *ipxitf_adjust_skbuff(struct ipx_interface *intrfc,
 					    struct sk_buff *skb)
 {
 	struct sk_buff *skb2;
-	int in_offset = skb->h.raw - skb->head;
+	int in_offset = (unsigned char *)ipx_hdr(skb) - skb->head;
 	int out_offset = intrfc->if_ipx_offset;
 	int len;
 
@@ -669,7 +668,7 @@
 	if (skb2) {
 		skb_reserve(skb2, out_offset);
 		skb2->nh.raw = skb2->h.raw = skb_put(skb2, skb->len);
-		memcpy(skb2->h.raw, skb->h.raw, skb->len);
+		memcpy(ipx_hdr(skb2), ipx_hdr(skb), skb->len);
 		memcpy(skb2->cb, skb->cb, sizeof(skb->cb));
 	}
 	kfree_skb(skb);
@@ -678,9 +677,10 @@
 
 /* caller must hold a reference to intrfc and the skb has to be unshared */
 
-static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node)
+static int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb,
+		       char *node)
 {
-	struct ipxhdr *ipx = skb->nh.ipxh;
+	struct ipxhdr *ipx = ipx_hdr(skb);
 	struct net_device *dev = intrfc->if_dev;
 	struct datalink_proto *dl = intrfc->if_dlink;
 	char dest_node[IPX_NODE_LEN];
@@ -784,21 +784,24 @@
 out:	return 0;
 }
 
-static int ipxrtr_add_route(__u32, ipx_interface *, unsigned char *);
+static int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc,
+			    unsigned char *);
 
-static int ipxitf_add_local_route(ipx_interface *intrfc)
+static int ipxitf_add_local_route(struct ipx_interface *intrfc)
 {
 	return ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL);
 }
 
-static const char * ipx_frame_name(unsigned short);
-static const char * ipx_device_name(ipx_interface *);
-static void ipxitf_discover_netnum(ipx_interface *intrfc, struct sk_buff *skb);
-static int ipxitf_pprop(ipx_interface *intrfc, struct sk_buff *skb);
+static const char *ipx_frame_name(unsigned short);
+static const char *ipx_device_name(struct ipx_interface *);
+static void ipxitf_discover_netnum(struct ipx_interface *intrfc,
+				   struct sk_buff *skb);
+static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb);
+static int ipxrtr_route_skb(struct sk_buff *skb);
 
-static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb)
+static int ipxitf_rcv(struct ipx_interface *intrfc, struct sk_buff *skb)
 {
-	struct ipxhdr	*ipx = skb->nh.ipxh;
+	struct ipxhdr *ipx = ipx_hdr(skb);
 	int ret = 0;
 
 	ipxitf_hold(intrfc);
@@ -850,13 +853,15 @@
 	return ret;
 }
 
-static void ipxitf_discover_netnum(ipx_interface *intrfc, struct sk_buff *skb)
+static void ipxitf_discover_netnum(struct ipx_interface *intrfc,
+				   struct sk_buff *skb)
 { 
 	const struct ipx_cb *cb = IPX_SKB_CB(skb);
 
 	/* see if this is an intra packet: source_net == dest_net */
 	if (cb->ipx_source_net == cb->ipx_dest_net && cb->ipx_source_net) {
-		ipx_interface *i = ipxitf_find_using_net(cb->ipx_source_net);
+		struct ipx_interface *i =
+				ipxitf_find_using_net(cb->ipx_source_net);
 		/* NB: NetWare servers lie about their hop count so we
 		 * dropped the test based on it. This is the best way
 		 * to determine this is a 0 hop count packet. */
@@ -900,11 +905,11 @@
  * Returns -EINVAL for invalid packets, so that the calling function drops
  * the packet without local processing. 0 if packet is to be locally processed.
  */
-static int ipxitf_pprop(ipx_interface *intrfc, struct sk_buff *skb)
+static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb)
 {
-	struct ipxhdr *ipx = skb->nh.ipxh;
+	struct ipxhdr *ipx = ipx_hdr(skb);
 	int i, ret = -EINVAL;
-	ipx_interface *ifcs;
+	struct ipx_interface *ifcs;
 	char *c;
 	u32 *l;
 
@@ -968,14 +973,14 @@
 out:	return ret;
 }
 
-static void ipxitf_insert(ipx_interface *intrfc)
+static void ipxitf_insert(struct ipx_interface *intrfc)
 {
 	intrfc->if_next = NULL;
 	spin_lock_bh(&ipx_interfaces_lock);
 	if (!ipx_interfaces)
 		ipx_interfaces = intrfc;
 	else {
-		ipx_interface *i = ipx_interfaces;
+		struct ipx_interface *i = ipx_interfaces;
 		while (i->if_next)
 			i = i->if_next;
 		i->if_next = intrfc;
@@ -986,12 +991,13 @@
 		ipx_primary_net = intrfc;
 }
 
-static ipx_interface *ipxitf_alloc(struct net_device *dev, __u32 netnum,
-				   unsigned short dlink_type,
-				   struct datalink_proto *dlink,
-				   unsigned char internal, int ipx_offset)
+static struct ipx_interface *ipxitf_alloc(struct net_device *dev, __u32 netnum,
+					  unsigned short dlink_type,
+					  struct datalink_proto *dlink,
+					  unsigned char internal,
+					  int ipx_offset)
 {
-	ipx_interface *intrfc = kmalloc(sizeof(*intrfc), GFP_ATOMIC);
+	struct ipx_interface *intrfc = kmalloc(sizeof(*intrfc), GFP_ATOMIC);
 
 	if (intrfc) {
 		intrfc->if_dev		= dev;
@@ -1010,9 +1016,9 @@
 	return intrfc;
 }
 
-static int ipxitf_create_internal(ipx_interface_definition *idef)
+static int ipxitf_create_internal(struct ipx_interface_definition *idef)
 {
-	ipx_interface *intrfc;
+	struct ipx_interface *intrfc;
 	int ret = -EEXIST;
 
 	/* Only one primary network allowed */
@@ -1061,12 +1067,12 @@
 	return ret;
 }
 
-static int ipxitf_create(ipx_interface_definition *idef)
+static int ipxitf_create(struct ipx_interface_definition *idef)
 {
 	struct net_device *dev;
 	unsigned short dlink_type = 0;
 	struct datalink_proto *datalink = NULL;
-	ipx_interface *intrfc;
+	struct ipx_interface *intrfc;
 	int err;
 
 	if (idef->ipx_special == IPX_INTERNAL) {
@@ -1173,11 +1179,11 @@
 out:	return err;
 }
 
-static int ipxitf_delete(ipx_interface_definition *idef)
+static int ipxitf_delete(struct ipx_interface_definition *idef)
 {
 	struct net_device *dev = NULL;
 	unsigned short dlink_type = 0;
-	ipx_interface *intrfc;
+	struct ipx_interface *intrfc;
 	int ret = 0;
 
 	spin_lock_bh(&ipx_interfaces_lock);
@@ -1211,10 +1217,10 @@
 	return ret;
 }
 
-static ipx_interface *ipxitf_auto_create(struct net_device *dev, 
-					 unsigned short dlink_type)
+static struct ipx_interface *ipxitf_auto_create(struct net_device *dev,
+						unsigned short dlink_type)
 {
-	ipx_interface *intrfc = NULL;
+	struct ipx_interface *intrfc = NULL;
 	struct datalink_proto *datalink;
 
 	if (!dev)
@@ -1269,7 +1275,7 @@
 	switch (cmd) {
 		case SIOCSIFADDR: {
 			struct sockaddr_ipx *sipx;
-			ipx_interface_definition f;
+			struct ipx_interface_definition f;
 
 			if (copy_from_user(&ifr, arg, sizeof(ifr)))
 				return -EFAULT;
@@ -1294,7 +1300,7 @@
 		case SIOCGIFADDR: {
 			int err = 0;
 			struct sockaddr_ipx *sipx;
-			ipx_interface *ipxif;
+			struct ipx_interface *ipxif;
 			struct net_device *dev;
 
 			if (copy_from_user(&ifr, arg, sizeof(ifr)))
@@ -1341,20 +1347,20 @@
 
 /* Routing tables for the IPX socket layer. */
 
-static inline void ipxrtr_hold(ipx_route *rt)
+static __inline__ void ipxrtr_hold(struct ipx_route *rt)
 {
 	atomic_inc(&rt->refcnt);
 }
 
-static inline void ipxrtr_put(ipx_route *rt)
+static __inline__ void ipxrtr_put(struct ipx_route *rt)
 {
 	if (atomic_dec_and_test(&rt->refcnt))
 		kfree(rt);
 }
 
-static ipx_route *ipxrtr_lookup(__u32 net)
+static struct ipx_route *ipxrtr_lookup(__u32 net)
 {
-	ipx_route *r;
+	struct ipx_route *r;
 
 	read_lock_bh(&ipx_routes_lock);
 	for (r = ipx_routes; r && r->ir_net != net; r = r->ir_next)
@@ -1368,16 +1374,16 @@
 
 /* caller must hold a reference to intrfc */
 
-static int ipxrtr_add_route(__u32 network, ipx_interface *intrfc,
-				unsigned char *node)
+static int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc,
+			    unsigned char *node)
 {
-	ipx_route *rt;
+	struct ipx_route *rt;
 	int ret;
 
 	/* Get a route structure; either existing or create */
 	rt = ipxrtr_lookup(network);
 	if (!rt) {
-		rt = kmalloc(sizeof(ipx_route), GFP_ATOMIC);
+		rt = kmalloc(sizeof(*rt), GFP_ATOMIC);
 		ret = -EAGAIN;
 		if (!rt)
 			goto out;
@@ -1410,9 +1416,9 @@
 out:	return ret;
 }
 
-static void ipxrtr_del_routes(ipx_interface *intrfc)
+static void ipxrtr_del_routes(struct ipx_interface *intrfc)
 {
-	ipx_route **r, *tmp;
+	struct ipx_route **r, *tmp;
 
 	write_lock_bh(&ipx_routes_lock);
 	for (r = &ipx_routes; (tmp = *r) != NULL;) {
@@ -1425,9 +1431,9 @@
 	write_unlock_bh(&ipx_routes_lock);
 }
 
-static int ipxrtr_create(ipx_route_definition *rd)
+static int ipxrtr_create(struct ipx_route_definition *rd)
 {
-	ipx_interface *intrfc;
+	struct ipx_interface *intrfc;
 	int ret = -ENETUNREACH;
 
 	/* Find the appropriate interface */
@@ -1441,8 +1447,8 @@
 
 static int ipxrtr_delete(long net)
 {
-	ipx_route **r;
-	ipx_route *tmp;
+	struct ipx_route **r;
+	struct ipx_route *tmp;
 	int err;
 
 	write_lock_bh(&ipx_routes_lock);
@@ -1513,11 +1519,11 @@
 {
 	struct sk_buff *skb;
 	struct ipx_opt *ipxs = ipx_sk(sk);
-	ipx_interface *intrfc;
+	struct ipx_interface *intrfc;
 	struct ipxhdr *ipx;
 	int size;
 	int ipx_offset;
-	ipx_route *rt = NULL;
+	struct ipx_route *rt = NULL;
 	int err;
 
 	/* Find the appropriate interface on which to send packet */
@@ -1544,11 +1550,11 @@
 	skb->sk = sk;
 
 	/* Fill in IPX header */
-	ipx = (struct ipxhdr *)skb_put(skb, sizeof(struct ipxhdr));
+	skb->h.raw = skb->nh.raw = skb_put(skb, sizeof(struct ipxhdr));
+	ipx = ipx_hdr(skb);
 	ipx->ipx_pktsize = htons(len + sizeof(struct ipxhdr));
 	IPX_SKB_CB(skb)->ipx_tctrl = 0;
 	ipx->ipx_type 	 = usipx->sipx_type;
-	skb->h.raw 	 = (void *)skb->nh.ipxh = ipx;
 
 	IPX_SKB_CB(skb)->last_hop.index = -1;
 #ifdef CONFIG_IPX_INTERN
@@ -1596,8 +1602,8 @@
  * modify the packet */
 int ipxrtr_route_skb(struct sk_buff *skb)
 {
-	struct ipxhdr *ipx = skb->nh.ipxh;
-	ipx_route *r = ipxrtr_lookup(IPX_SKB_CB(skb)->ipx_dest_net);
+	struct ipxhdr *ipx = ipx_hdr(skb);
+	struct ipx_route *r = ipxrtr_lookup(IPX_SKB_CB(skb)->ipx_dest_net);
 
 	if (!r) {	/* no known route */
 		kfree_skb(skb);
@@ -1666,7 +1672,7 @@
 	return ret;
 }
 
-static const char *ipx_device_name(ipx_interface *intrfc)
+static const char *ipx_device_name(struct ipx_interface *intrfc)
 {
 	return intrfc->if_internal ? "Internal" :
 		intrfc->if_dev ? intrfc->if_dev->name : "Unknown";
@@ -1676,7 +1682,7 @@
 static int ipx_interface_get_info(char *buffer, char **start, off_t offset,
 				  int length)
 {
-	ipx_interface *i;
+	struct ipx_interface *i;
 	off_t begin = 0, pos = 0;
 	int len = 0;
 
@@ -1728,7 +1734,7 @@
 static int ipx_get_info(char *buffer, char **start, off_t offset, int length)
 {
 	struct sock *s;
-	ipx_interface *i;
+	struct ipx_interface *i;
 	off_t begin = 0, pos = 0;
 	int len = 0;
 
@@ -1808,7 +1814,7 @@
 
 static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length)
 {
-	ipx_route *rt;
+	struct ipx_route *rt;
 	off_t begin = 0, pos = 0;
 	int len = 0;
 
@@ -1927,17 +1933,11 @@
 
 		case SOCK_SEQPACKET:
 			/*
-			 * From this point on SPX sockets are handled
-			 * by af_spx.c and the methods replaced.
+			 * SPX support is not anymore in the kernel sources. If
+			 * you want to ressurrect it, completing it and making
+			 * it understand shared skbs, be fully multithreaded,
+			 * etc, grab the sources in an early 2.5 kernel tree.
 			 */
-			down_read(&spx_family_ops_lock);
-			if (spx_family_ops) {
-				ret = spx_family_ops->create(sock, protocol);
-				up_read(&spx_family_ops_lock);
-				goto decmod;
-			}
-			up_read(&spx_family_ops_lock);
-			/* Fall through if SPX is not loaded */
 		case SOCK_STREAM:       /* Allow higher levels to piggyback */
 		default:
 			goto decmod;
@@ -1978,7 +1978,7 @@
 
 /* caller must hold a reference to intrfc */
 
-static unsigned short ipx_first_free_socketnum(ipx_interface *intrfc)
+static unsigned short ipx_first_free_socketnum(struct ipx_interface *intrfc)
 {
 	unsigned short socketNum = intrfc->if_sknum;
 
@@ -2003,7 +2003,7 @@
 {
 	struct sock *sk = sock->sk;
 	struct ipx_opt *ipxs = ipx_sk(sk);
-	ipx_interface *intrfc;
+	struct ipx_interface *intrfc;
 	struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr;
 	int ret = -EINVAL;
 
@@ -2101,7 +2101,7 @@
 	struct ipx_opt *ipxs = ipx_sk(sk);
 	struct sockaddr_ipx *addr;
 	int ret = -EINVAL;
-	ipx_route *rt;
+	struct ipx_route *rt;
 
 	sk->state	= TCP_CLOSE;
 	sock->state 	= SS_UNCONNECTED;
@@ -2158,7 +2158,7 @@
 static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
 			int *uaddr_len, int peer)
 {
-	ipx_address *addr;
+	struct ipx_address *addr;
 	struct sockaddr_ipx sipx;
 	struct sock *sk = sock->sk;
 	struct ipx_opt *ipxs = ipx_sk(sk);
@@ -2204,7 +2204,7 @@
 int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
 {
 	/* NULL here for pt means the packet was looped back */
-	ipx_interface *intrfc;
+	struct ipx_interface *intrfc;
 	struct ipxhdr *ipx;
 	u16 ipx_pktsize;
 	int ret = 0;
@@ -2216,7 +2216,7 @@
 	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
 		goto out;
 
-	ipx		= skb->nh.ipxh;
+	ipx		= ipx_hdr(skb);
 	ipx_pktsize	= ntohs(ipx->ipx_pktsize);
 	
 	/* Too small or invalid header? */
@@ -2352,7 +2352,7 @@
 	if (!skb)
 		goto out;
 
-	ipx 	= skb->nh.ipxh;
+	ipx 	= ipx_hdr(skb);
 	copied 	= ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr);
 	if (copied > size) {
 		copied = size;
@@ -2462,85 +2462,53 @@
 }
 
 /*
- *      SPX interface support
- */
-
-int ipx_register_spx(struct proto_ops **p, struct net_proto_family *spx)
-{
-	int err;
-
-	err = -EBUSY;
-	down_write(&spx_family_ops_lock);
-        if (!spx_family_ops) {
-	        MOD_INC_USE_COUNT;
-        	*p = &ipx_dgram_ops;
-	        spx_family_ops = spx;
-	}
-        up_write(&spx_family_ops_lock);
-        return 0;
-}
-
-int ipx_unregister_spx(void)
-{
-	down_write(&spx_family_ops_lock);
-	if (spx_family_ops) {
-	        spx_family_ops = NULL;
-        	MOD_DEC_USE_COUNT;
-	}
-	up_write(&spx_family_ops_lock);
-        return 0;
-}
-
-/*
  * Socket family declarations
  */
 
 static struct net_proto_family ipx_family_ops = {
-	family:		PF_IPX,
-	create:		ipx_create,
+	.family		= PF_IPX,
+	.create		= ipx_create,
 };
 
 static struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
-	family:		PF_IPX,
-
-	release:	ipx_release,
-	bind:		ipx_bind,
-	connect:	ipx_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		sock_no_accept,
-	getname:	ipx_getname,
-	poll:		datagram_poll,
-	ioctl:		ipx_ioctl,
-	listen:		sock_no_listen,
-	shutdown:	sock_no_shutdown, /* FIXME: have to support shutdown */
-	setsockopt:	ipx_setsockopt,
-	getsockopt:	ipx_getsockopt,
-	sendmsg:	ipx_sendmsg,
-	recvmsg:	ipx_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.family		= PF_IPX,
+	.release	= ipx_release,
+	.bind		= ipx_bind,
+	.connect	= ipx_connect,
+	.socketpair	= sock_no_socketpair,
+	.accept		= sock_no_accept,
+	.getname	= ipx_getname,
+	.poll		= datagram_poll,
+	.ioctl		= ipx_ioctl,
+	.listen		= sock_no_listen,
+	.shutdown	= sock_no_shutdown, /* FIXME: support shutdown */
+	.setsockopt	= ipx_setsockopt,
+	.getsockopt	= ipx_getsockopt,
+	.sendmsg	= ipx_sendmsg,
+	.recvmsg	= ipx_recvmsg,
+	.mmap		= sock_no_mmap,
+	.sendpage	= sock_no_sendpage,
 };
 
 #include <linux/smp_lock.h>
 SOCKOPS_WRAP(ipx_dgram, PF_IPX);
 
 static struct packet_type ipx_8023_packet_type = {
-	type:		__constant_htons(ETH_P_802_3),
-	func:		ipx_rcv,
-	data:		(void *) 1,	/* yap, I understand shared skbs :-) */
+	.type =		__constant_htons(ETH_P_802_3),
+	.func =		ipx_rcv,
+	.data =		(void *) 1,	/* yap, I understand shared skbs :-) */
 };
 
 static struct packet_type ipx_dix_packet_type = {
-	type:		__constant_htons(ETH_P_IPX),
-	func:		ipx_rcv,
-	data:		(void *) 1,	/* yap, I understand shared skbs :-) */
+	.type =		__constant_htons(ETH_P_IPX),
+	.func =		ipx_rcv,
+	.data =		(void *) 1,	/* yap, I understand shared skbs :-) */
 };
 
 static struct notifier_block ipx_dev_notifier = {
-	notifier_call:	ipxitf_device_event,
+	.notifier_call =ipxitf_device_event,
 };
 
-
 extern struct datalink_proto *make_EII_client(void);
 extern struct datalink_proto *make_8023_client(void);
 extern void destroy_EII_client(struct datalink_proto *);
@@ -2549,9 +2517,13 @@
 static unsigned char ipx_8022_type = 0xE0;
 static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 };
 static char ipx_banner[] __initdata =
-	KERN_INFO "NET4: Linux IPX 0.48 for NET4.0\n"
+	KERN_INFO "NET4: Linux IPX 0.49 for NET4.0\n"
 	KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n" \
 	KERN_INFO "IPX Portions Copyright (c) 2000, 2001 Conectiva, Inc.\n";
+static char ipx_EII_err_msg[] __initdata =
+	KERN_CRIT "IPX: Unable to register with Ethernet II\n";
+static char ipx_8023_err_msg[] __initdata =
+	KERN_CRIT "IPX: Unable to register with 802.3\n";
 static char ipx_llc_err_msg[] __initdata =
 	KERN_CRIT "IPX: Unable to register with 802.2\n";
 static char ipx_snap_err_msg[] __initdata =
@@ -2562,10 +2534,16 @@
 	sock_register(&ipx_family_ops);
 
 	pEII_datalink = make_EII_client();
-	dev_add_pack(&ipx_dix_packet_type);
+	if (pEII_datalink)
+		dev_add_pack(&ipx_dix_packet_type);
+	else
+		printk(ipx_EII_err_msg);
 
 	p8023_datalink = make_8023_client();
-	dev_add_pack(&ipx_8023_packet_type);
+	if (p8023_datalink)
+		dev_add_pack(&ipx_8023_packet_type);
+	else
+		printk(ipx_8023_err_msg);
 
 	p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv);
 	if (!p8022_datalink)
@@ -2587,26 +2565,6 @@
 }
 
 module_init(ipx_init);
-
-/* Higher layers need this info to prep tx pkts */
-int ipx_if_offset(unsigned long ipx_net_number)
-{
-	ipx_route *rt = ipxrtr_lookup(ipx_net_number);
-	int ret = -ENETUNREACH;
-
-	if (!rt)
-		goto out;
-	ret = rt->ir_intrfc->if_ipx_offset;
-	ipxrtr_put(rt);
-out:	return ret;
-}
-
-/* Export symbols for higher layers */
-EXPORT_SYMBOL(ipxrtr_route_skb);
-EXPORT_SYMBOL(ipx_if_offset);
-EXPORT_SYMBOL(ipx_remove_socket);
-EXPORT_SYMBOL(ipx_register_spx);
-EXPORT_SYMBOL(ipx_unregister_spx);
 
 /* Note on MOD_{INC,DEC}_USE_COUNT:
  *
diff -Nru a/net/ipx/af_spx.c b/net/ipx/af_spx.c
--- a/net/ipx/af_spx.c	Sat Aug 10 18:42:23 2002
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,897 +0,0 @@
-/*
- *	This module implements the (SPP-derived) Sequenced Packet eXchange
- *	(SPX) protocol for Linux 2.1.X as specified in
- *		NetWare SPX Services Specification, Semantics and API
- *		 Revision:       1.00
- *		 Revision Date:  February 9, 1993
- *
- *	Developers:
- *      Jay Schulist    <jschlst@samba.org>
- *	Jim Freeman	<jfree@caldera.com>
- *	Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- *
- *	Changes:
- *	Alan Cox	:	Fixed an skb_unshare check for NULL
- *				that crashed it under load. Renamed and
- *				made static the ipx ops. Removed the hack
- *				ipx methods interface. Dropped AF_SPX - its
- *				the wrong abstraction.
- *	Eduardo Trapani	:	Added a check for the return value of
- *				ipx_if_offset that crashed sock_alloc_send_skb.
- *				Added spx_datagram_poll() so that select()
- *				works now on SPX sockets.  Added updating
- *				of the alloc count to follow rmt_seq.
- *	Arnaldo C. Melo :	Use a private slabcache for the old tp_pinfo
- *				struct sock member, use spx_sk and ipx_sk
- *	Arnaldo C. Melo :	Big CodingStyle cleanup, fixes some lock leaks,
- *				removes a leftover of the slabcache patch.
- *
- *	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.
- *
- *	None of the authors or maintainers or their employers admit
- *	liability nor provide warranty for any of this software.
- *	This material is provided "as is" and at no charge.
- */
-
-#include <linux/module.h>
-#include <net/ipx.h>
-#include <net/spx.h>
-#include <net/tcp.h>
-#include <net/sock.h>
-#include <asm/byteorder.h>
-#include <asm/uaccess.h>
-#include <linux/uio.h>
-#include <linux/unistd.h>
-#include <linux/poll.h>
-
-static struct proto_ops *ipx_ops;
-static struct proto_ops spx_ops;
-static __u16  connids;
-
-/* Functions needed for SPX connection start up */
-static int spx_transmit(struct sock *sk,struct sk_buff *skb,int type,int len);
-static void spx_retransmit(unsigned long data);
-static void spx_watchdog(unsigned long data);
-void spx_rcv(struct sock *sk, int bytes);
-
-extern void ipx_remove_socket(struct sock *sk);
-
-/* Datagram poll:	the same code as datagram_poll() in net/core
-			but the right spx buffers are looked at and
-			there is no question on the type of the socket
-			*/
-static unsigned int spx_datagram_poll(struct file * file, struct socket *sock,
-				      poll_table *wait)
-{
-	struct sock *sk = sock->sk;
-	struct spx_opt *pdata = spx_sk(sk);
-	unsigned int mask;
-
-	poll_wait(file, sk->sleep, wait);
-	mask = 0;
-
-	/* exceptional events? */
-	if (sk->err || !skb_queue_empty(&sk->error_queue))
-		mask |= POLLERR;
-	if (sk->shutdown & RCV_SHUTDOWN)
-		mask |= POLLHUP;
-
-	/* readable? */
-	if (!skb_queue_empty(&pdata->rcv_queue))
-		mask |= POLLIN | POLLRDNORM;
-
-	/* Need to check for termination and startup */
-	if (sk->state==TCP_CLOSE)
-		mask |= POLLHUP;
-	/* connection hasn't started yet? */
-	if (sk->state == TCP_SYN_SENT)
-		goto out;
-
-	/* writable? */
-	if (sock_writeable(sk))
-		mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-	else
-		set_bit(SOCK_ASYNC_NOSPACE,&sk->socket->flags);
-out:	return mask;
-}
-
-/* Create the SPX specific data */
-static int spx_sock_init(struct sock *sk)
-{
-        struct spx_opt *pdata = spx_sk(sk);
-
-        pdata->state            = SPX_CLOSED;
-        pdata->sequence         = 0;
-	pdata->acknowledge	= 0;
-        pdata->source_connid    = htons(connids);
-	pdata->rmt_seq		= 0;
-        connids++;
-
-        pdata->owner            = (void *)sk;
-        pdata->sndbuf           = sk->sndbuf;
-
-        pdata->watchdog.function = spx_watchdog;
-        pdata->watchdog.data    = (unsigned long)sk;
-        pdata->wd_interval      = VERIFY_TIMEOUT;
-	pdata->retransmit.function = spx_retransmit;
-	pdata->retransmit.data	= (unsigned long)sk;
-	pdata->retransmits	= 0;
-        pdata->retries          = 0;
-        pdata->max_retries      = RETRY_COUNT;
-
-	skb_queue_head_init(&pdata->rcv_queue);
-	skb_queue_head_init(&pdata->transmit_queue);
-	skb_queue_head_init(&pdata->retransmit_queue);
-
-        return 0;
-}
-
-static int spx_create(struct socket *sock, int protocol)
-{
-	struct sock *sk;
-	int rc = -ENOMEM;
-
-        MOD_INC_USE_COUNT;
-
-	/* Called on connection receive so cannot be GFP_KERNEL */
-	sk = sk_alloc(PF_IPX, GFP_ATOMIC, 1);
-	if (!sk)
-		goto decmod;
-
-	rc = -ESOCKTNOSUPPORT;
-	switch (sock->type) {
-                case SOCK_SEQPACKET:
-			sock->ops = &spx_ops;
-			break;
-		default:
-			sk_free(sk);
-			goto out;
-        }
-
-	rc = 0;
-	sock_init_data(sock, sk);
-	spx_sock_init(sk);
-	sk->data_ready  = spx_rcv;
-	sk->destruct 	= NULL;
-        sk->no_check 	= 1;
-out:	return rc;
-decmod:	MOD_DEC_USE_COUNT;
-	goto out;
-}
-
-void spx_close_socket(struct sock *sk)
-{
-	struct spx_opt *pdata = spx_sk(sk);
-
-	pdata->state	= SPX_CLOSED;
-	sk->state 	= TCP_CLOSE;
-	del_timer(&pdata->retransmit);
-	del_timer(&pdata->watchdog);
-}
-
-void spx_destroy_socket(struct sock *sk)
-{
-	struct spx_opt *pdata = spx_sk(sk);
-
-        ipx_remove_socket(sk);
-	skb_queue_purge(&sk->receive_queue);
-	skb_queue_purge(&pdata->transmit_queue);
-	skb_queue_purge(&pdata->retransmit_queue);
-	skb_queue_purge(&pdata->rcv_queue);
-        sk_free(sk);
-	MOD_DEC_USE_COUNT;
-}
-
-/* Release an SPX socket */
-static int spx_release(struct socket *sock)
-{
- 	struct sock *sk = sock->sk;
-	struct spx_opt *pdata = spx_sk(sk);
-
-	if (!sk)
-		goto out;
-	if (!sk->dead)
-                sk->state_change(sk);
-        sk->dead = 1;
-
-	if (pdata->state != SPX_CLOSED) {
-		spx_transmit(sk, NULL, DISCON, 0);
-		spx_close_socket(sk);
-	}
-
-	sock->sk	= NULL;
-	sk->socket 	= NULL;
-	spx_destroy_socket(sk);
-out:	return 0;
-}
-
-/* Move a socket into listening state. */
-static int spx_listen(struct socket *sock, int backlog)
-{
-        struct sock *sk = sock->sk;
-	int rc = -EINVAL;
-
-        if (sock->state != SS_UNCONNECTED)
-		goto out;
-	rc = -EOPNOTSUPP;
-	if (sock->type != SOCK_SEQPACKET)
-		goto out;
-	rc = -EAGAIN;
-        if (sk->zapped)
-		goto out;
-	rc = 0;
-        sk->max_ack_backlog = backlog;
-        if (sk->state != TCP_LISTEN) {
-                sk->ack_backlog = 0;
-                sk->state = TCP_LISTEN;
-        }
-        sk->socket->flags |= __SO_ACCEPTCON;
-out:	return rc;
-}
-
-/* Accept a pending SPX connection */
-static int spx_accept(struct socket *sock, struct socket *newsock, int flags)
-{
-        struct sock *sk = sock->sk;
-        struct sock *newsk;
-        struct sk_buff *skb;
-	int rc = -EINVAL;
-
-	if (!sk || sk->state != TCP_LISTEN ||
-	    sock->state != SS_UNCONNECTED || !(sock->flags & __SO_ACCEPTCON))
-		goto out;
-	rc = -EOPNOTSUPP;
-        if (sock->type != SOCK_SEQPACKET)
-		goto out;
-	cli();
-	do {
-		skb = skb_dequeue(&sk->receive_queue);
-		if (!skb) {
-			rc = -EWOULDBLOCK;
-                	if (flags & O_NONBLOCK)
-				goto out_unlock;
-                	interruptible_sleep_on(sk->sleep);
-                        rc = -ERESTARTSYS;
-                	if (signal_pending(current))
-				goto out_unlock;
-		}
-	} while (!skb);
-
-	newsk 		= skb->sk;
-        newsk->pair 	= NULL;
-	sti();
-
-	rc = spx_transmit(newsk, skb, CONACK, 0);   /* Connection ACK */
-	if (rc)
-		goto out;
-	/* Now attach up the new socket */
-	sock->sk 	= NULL;
-        sk->ack_backlog--;
-        newsock->sk 	= newsk;
-	newsk->state 	= TCP_ESTABLISHED;
-	ipx_sk(newsk)->dest_addr = spx_sk(newsk)->dest_addr;
-out:	return rc;
-out_unlock:
-	sti();
-	goto out;
-}
-
-/* Build a connection to an SPX socket */
-static int spx_connect(struct socket *sock, struct sockaddr *uaddr,
-		       int addr_len, int flags)
-{
-	struct sock *sk = sock->sk;
-        struct spx_opt *pdata = spx_sk(sk);
-        struct sockaddr_ipx src;
-	struct sk_buff *skb;
-	int size = sizeof(src);
-	int rc = ipx_ops->getname(sock, (struct sockaddr *)&src, &size, 0);
-
-	if (rc)
-		goto out;
-
-        pdata->source_addr.net	= src.sipx_network;
-        memcpy(pdata->source_addr.node, src.sipx_node, IPX_NODE_LEN);
-        pdata->source_addr.sock = (unsigned short)src.sipx_port;
-
-	rc = ipx_ops->connect(sock, uaddr, addr_len, flags);
-        if (rc)
-                goto out;
-
-        pdata->dest_addr = ipx_sk(sk)->dest_addr;
-	pdata->state	 = SPX_CONNECTING;
-	sock->state	 = SS_CONNECTING;
-        sk->state	 = TCP_SYN_SENT;
-
-        /* Send Connection request */
-	rc = spx_transmit(sk, NULL, CONREQ, 0);
-        if (rc)
-                goto out;
-
-	cli();
-        do {
-                skb = skb_dequeue(&sk->receive_queue);
-                if (!skb) {
-			rc = -EWOULDBLOCK;
-                        if (flags & O_NONBLOCK)
-				goto unlock;
-                        interruptible_sleep_on(sk->sleep);
-			rc = -ERESTARTSYS;
-                        if (signal_pending(current))
-				goto unlock;
-                }
-        } while (!skb);
-
-	rc = -ETIMEDOUT;
-        if (pdata->state == SPX_CLOSED) {
-                del_timer(&pdata->watchdog);
-		goto unlock;
-        }
-
-	rc = 0;
-	sock->state	= SS_CONNECTED;
-	sk->state 	= TCP_ESTABLISHED;
-	kfree_skb(skb);
-unlock:	sti();
-out:	return rc;
-}
-
-/*
- * Calculate the timeout for a packet. Thankfully SPX has a large
- * fudge factor (3/4 secs) and does not pay much attention to RTT.
- * As we simply have a default retry time of 1*HZ and a max retry
- * time of 5*HZ. Between those values we increase the timeout based
- * on the number of retransmit tries.
- *
- * FixMe: This is quite fake, but will work for now. (JS)
- */
-static inline unsigned long spx_calc_rtt(int tries)
-{
-	int rc;
-
-        if (tries < 1)
-                rc = RETRY_TIME;
-	else if (tries > 5)
-                rc = MAX_RETRY_DELAY;
-	else
-		rc = tries * HZ;
-	return rc;
-}
-
-static int spx_route_skb(struct spx_opt *pdata, struct sk_buff *skb, int type)
-{
-	int rc = -ENOBUFS;
-
-	skb = skb_unshare(skb, GFP_ATOMIC);
-	if (!skb)
-		goto out;
-	rc = 0;
-
-	switch (type) {
-		case CONREQ:
-		case DATA:
-			if (!skb_queue_empty(&pdata->retransmit_queue)) {
-				skb_queue_tail(&pdata->transmit_queue, skb);
-				goto out;
-			}
-		case TQUEUE: {
-			struct sk_buff *skb2;
-			pdata->retransmit.expires = jiffies + spx_calc_rtt(0);
-			add_timer(&pdata->retransmit);
-
-			skb2 = skb_clone(skb, GFP_NOIO);
-	                if (!skb2) {
-				rc = -ENOBUFS;
-        	                goto out;
-			}
-        	        skb_queue_tail(&pdata->retransmit_queue, skb2);
-			/* Fall thru */
-		}
-		case ACK:
-		case CONACK:
-		case WDREQ:
-		case WDACK:
-		case DISCON:
-		case DISACK:
-		case RETRAN:
-		default: /* Send data */
-        		rc = ipxrtr_route_skb(skb);
-        		if (rc)
-                		kfree_skb(skb);
-	}
-out:	return rc;
-}
-
-/* SPX packet transmit engine */
-static int spx_transmit(struct sock *sk, struct sk_buff *skb, int type, int len)
-{
-        struct spx_opt *pdata = spx_sk(sk);
-        struct ipxspxhdr *ipxh;
-	unsigned long flags;
-	int rc;
-
-	if (!skb) {
-		int offset  = ipx_if_offset(pdata->dest_addr.net);
-        	int size    = offset + sizeof(struct ipxspxhdr);
-
-		rc = -ENETUNREACH;
-        	if (offset < 0)
-        		goto out;
-
-		save_flags(flags);
-		cli();
-        	skb = sock_alloc_send_skb(sk, size, 0, &err);
-		rc = -ENOMEM;
-        	if (!skb) {
-			restore_flags(flags);
-                	goto out;
-		}
-        	skb_reserve(skb, offset);
-        	skb->h.raw = skb->nh.raw =
-				skb_put(skb, sizeof(struct ipxspxhdr));
-		restore_flags(flags);
-	}
-
-	/* IPX header */
-	ipxh = (struct ipxspxhdr *)skb->nh.raw;
-	ipxh->ipx.ipx_checksum  = 0xFFFF;
-	ipxh->ipx.ipx_pktsize   = htons(SPX_SYS_PKT_LEN);
-        ipxh->ipx.ipx_tctrl     = 0;
-	ipxh->ipx.ipx_type 	= IPX_TYPE_SPX;
-        ipxh->ipx.ipx_dest      = pdata->dest_addr;
-        ipxh->ipx.ipx_source    = pdata->source_addr;
-
-	/* SPX header */
-        ipxh->spx.dtype         = 0;
-	ipxh->spx.sequence      = htons(pdata->sequence);
-	ipxh->spx.ackseq        = htons(pdata->rmt_seq);
-	ipxh->spx.sconn         = pdata->source_connid;
-        ipxh->spx.dconn         = pdata->dest_connid;
-        ipxh->spx.allocseq      = htons(pdata->alloc);
-
-	/* Reset/Set WD timer */
-        mod_timer(&pdata->watchdog, jiffies+VERIFY_TIMEOUT);
-
-	switch (type) {
-		case DATA:	/* Data */
-			ipxh->ipx.ipx_pktsize 	= htons(SPX_SYS_PKT_LEN + len);
-			ipxh->spx.cctl 		= (CCTL_ACK | CCTL_EOM);
-                	pdata->sequence++;
-			break;
-
-		case ACK:	/* ACK */
-			pdata->rmt_seq++;
-		case WDACK:	/* WD ACK */
-		case CONACK:	/* Connection ACK */
-			ipxh->spx.cctl 		= CCTL_SYS;
-			ipxh->spx.ackseq 	= htons(pdata->rmt_seq);
-			break;
-
-		case CONREQ:	/* Connection Request */
-			del_timer(&pdata->watchdog);
-		case WDREQ:	/* WD Request */
-			pdata->source_connid    = htons(connids++);
-                	pdata->dest_connid      = 0xFFFF;
-                	pdata->alloc 		= 3 + pdata->rmt_seq;
-			ipxh->spx.cctl          = CCTL_ACK | CCTL_SYS;
-			ipxh->spx.sconn         = pdata->source_connid;
-		        ipxh->spx.dconn         = pdata->dest_connid;
-		        ipxh->spx.allocseq      = htons(pdata->alloc);
-			break;
-
-		case DISCON:	/* Informed Disconnect */
-			ipxh->spx.cctl 		= CCTL_ACK;
-			ipxh->spx.dtype 	= SPX_DTYPE_ECONN;
-			break;
-
-		case DISACK:	/* Informed Disconnect ACK */
-			ipxh->spx.cctl  	= 0;
-			ipxh->spx.dtype 	= SPX_DTYPE_ECACK;
-			ipxh->spx.sequence 	= 0;
-			ipxh->spx.ackseq 	= htons(pdata->rmt_seq++);
-			break;
-
-		default:
-			rc = -EOPNOTSUPP;
-			goto out;
-	}
-
-	/* Send data */
-        rc = spx_route_skb(pdata, skb, type);
-out:	return rc;
-}
-
-/* Check the state of the connection and send a WD request if needed. */
-static void spx_watchdog(unsigned long data)
-{
-	struct sock *sk = (struct sock*)data;
-        struct spx_opt *pdata = spx_sk(sk);
-
-        del_timer(&pdata->watchdog);
-	if (pdata->state == SPX_CLOSED)
-                goto out;
-	if (pdata->retries > pdata->max_retries) {
-		spx_close_socket(sk);	/* Unilateral Abort */
-                goto out;
-        }
-        /* Send WD request */
-	spx_transmit(sk, NULL, WDREQ, 0);
-	pdata->retries++;
-out:;
-}
-
-static void spx_retransmit(unsigned long data)
-{
-	struct sock *sk = (struct sock*)data;
-        struct spx_opt *pdata = spx_sk(sk);
-	struct sk_buff *skb;
-	unsigned long flags;
-
-	del_timer(&pdata->retransmit);
-	if (pdata->state == SPX_CLOSED)
-		goto out;
-	if (pdata->retransmits > RETRY_COUNT) {
-		spx_close_socket(sk);   /* Unilateral Abort */
-                goto out;
-        }
-	/* Need to leave skb on the queue, aye the fear */
-	save_flags(flags);
-	cli();
-	skb = skb_peek(&pdata->retransmit_queue);
-	if (skb_cloned(skb))
-                skb = skb_copy(skb, GFP_ATOMIC);
-        else
-                skb = skb_clone(skb, GFP_ATOMIC);
-	restore_flags(flags);
-
-	pdata->retransmit.expires = jiffies + spx_calc_rtt(pdata->retransmits);
-	add_timer(&pdata->retransmit);
-
-	spx_route_skb(pdata, skb, RETRAN);
-	pdata->retransmits++;
-out:;
-}
-
-/* Check packet for retransmission, ConReqAck aware */
-static int spx_retransmit_chk(struct spx_opt *pdata, int ackseq, int type)
-{
-	struct ipxspxhdr *ipxh;
-	int rc = -ENOENT;
-	struct sk_buff *skb = skb_dequeue(&pdata->retransmit_queue);
-
-	if (!skb)
-		goto out;
-	rc = 0;
-	/* Check Data/ACK seq */
-	switch (type) {
-		case ACK:	/* Check Sequence, Should == 1 */
-			ipxh = (struct ipxspxhdr *)skb->nh.raw;
-			if (!(ntohs(ipxh->spx.sequence) - htons(ackseq)))
-				break;
-		case CONACK:
-			del_timer(&pdata->retransmit);
-			pdata->retransmits = 0;
-			kfree_skb(skb);
-			if (skb_queue_empty(&pdata->retransmit_queue)) {
-				skb = skb_dequeue(&pdata->transmit_queue);
-				if (skb)
-					spx_route_skb(pdata, skb, TQUEUE);
-			}
-			goto out;
-	}
-
-	skb_queue_head(&pdata->retransmit_queue, skb);
-	rc = -1;
-out:	return rc;
-}
-
-/* SPX packet receive engine */
-void spx_rcv(struct sock *sk, int bytes)
-{
-	struct ipxspxhdr *ipxh;
-	struct spx_opt *pdata = spx_sk(sk);
-	struct sk_buff *skb = skb_dequeue(&sk->receive_queue);
-
-	if (!skb)
-		goto out;
-	ipxh = (struct ipxspxhdr *)skb->nh.raw;
-
-	/* Can't receive on a closed connection */
-        if ((pdata->state == SPX_CLOSED && ipxh->spx.sequence) ||
-	    ntohs(ipxh->ipx.ipx_pktsize) < SPX_SYS_PKT_LEN ||
-            ipxh->ipx.ipx_type != IPX_TYPE_SPX ||
-            ntohs(ipxh->spx.ackseq) > pdata->sequence)
-		goto toss_skb;
-
-	/* Reset WD timer on any received packet */
-	del_timer(&pdata->watchdog);
-	pdata->retries = 0;
-	pdata->watchdog.expires = jiffies + ABORT_TIMEOUT;
-        add_timer(&pdata->watchdog);
-
-	switch (ipxh->spx.cctl) {
-		case (CCTL_SYS | CCTL_ACK):
-			if (!ipxh->spx.sequence	&& /* ConReq */
-			    !ipxh->spx.ackseq &&
-			    ipxh->spx.dconn == 0xFFFF) {
-				pdata->state		= SPX_CONNECTED;
-				pdata->dest_addr        = ipxh->ipx.ipx_source;
-				pdata->source_addr      = ipxh->ipx.ipx_dest;
-				pdata->dest_connid      = ipxh->spx.sconn;
-				pdata->alloc = 3 + ntohs(ipxh->spx.sequence);
-
-				skb_queue_tail(&sk->receive_queue, skb);
-				wake_up_interruptible(sk->sleep);
-			} else	/* WD Request */
-				spx_transmit(sk, skb, WDACK, 0);
-			goto out;
-
-		case CCTL_SYS:	/* ACK */
-			if (!ipxh->spx.dtype &&      /* ConReq ACK */
-                            ipxh->spx.sconn != 0xFFFF &&
-                            ipxh->spx.dconn != 0xFFFF &&
-                            !ipxh->spx.sequence &&
-                            !ipxh->spx.ackseq &&
-                            pdata->state != SPX_CONNECTED) {
-                                pdata->state = SPX_CONNECTED;
-				pdata->dest_connid = ipxh->spx.sconn;
-
-				if (spx_retransmit_chk(pdata, 0, CONACK) < 0)
-					goto toss_skb;
-
-                                skb_queue_tail(&sk->receive_queue, skb);
-                                wake_up_interruptible(sk->sleep);
-                                goto out;
-                        }
-
-			spx_retransmit_chk(pdata, ipxh->spx.ackseq, ACK);
-			goto toss_skb;
-
-		case CCTL_ACK:
-			/* Informed Disconnect */
-			if (ipxh->spx.dtype == SPX_DTYPE_ECONN) {
-				spx_transmit(sk, skb, DISACK, 0);
-				spx_close_socket(sk);
-				goto out;
-			}
-			/* Fall through */
-		default:
-			if (ntohs(ipxh->spx.sequence) == pdata->rmt_seq) {
-				pdata->rmt_seq = ntohs(ipxh->spx.sequence);
-				pdata->rmt_ack = ntohs(ipxh->spx.ackseq);
-				pdata->alloc   = pdata->rmt_seq + 3;
-				if (pdata->rmt_ack > 0 || !pdata->rmt_ack)
-					spx_retransmit_chk(pdata,
-							   pdata->rmt_ack, ACK);
-
-				skb_queue_tail(&pdata->rcv_queue, skb);
-				wake_up_interruptible(sk->sleep);
-				if (ipxh->spx.cctl&CCTL_ACK)
-					spx_transmit(sk, NULL, ACK, 0);
-				goto out;
-			}
-
-			if (ipxh->spx.dtype == SPX_DTYPE_ECACK) {
-				if (pdata->state != SPX_CLOSED)
-					spx_close_socket(sk);
-				goto toss_skb;
-			}
-	}
-
-toss_skb:	/* Catch All */
-	kfree_skb(skb);
-out:;
-}
-
-/* Get message/packet data from user-land */
-static int spx_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-		       struct scm_cookie *scm)
-{
-	struct sock *sk = sock->sk;
-	int flags = msg->msg_flags;
-	struct sk_buff *skb;
-	int offset, size, rc = -EMSGSIZE;
-
-	if (len > 534)
-		goto out;
-	rc = -ENOTCONN; /* Socket not bound */
-        if (sk->zapped)
-		goto out;
-	rc = -EINVAL;
-	if (flags & ~MSG_DONTWAIT)
-		goto out;
-
-	offset	= ipx_if_offset(spx_sk(sk)->dest_addr.net);
-        size 	= offset + sizeof(struct ipxspxhdr) + len;
-
-	cli();
-        skb = sock_alloc_send_skb(sk, size, flags&MSG_DONTWAIT, &rc);
-	sti();
-        if (!skb)
-                goto out;
-	skb->sk = sk;
-        skb_reserve(skb, offset);
-	skb->h.raw = skb->nh.raw = skb_put(skb, sizeof(struct ipxspxhdr));
-
-	rc = -EFAULT;
-	if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
-                kfree_skb(skb);
-		goto out;
-        }
-	rc = len;
-	if (!spx_transmit(sk, skb, DATA, len))
-		rc = -EAGAIN;
-out:	return rc;
-}
-
-/* Send message/packet data to user-land */
-static int spx_recvmsg(struct socket *sock, struct msghdr *msg, int size,
-			int flags, struct scm_cookie *scm)
-{
-	struct sk_buff *skb;
-	struct ipxspxhdr *ispxh;
-	struct sock *sk = sock->sk;
-	struct spx_opt *pdata = spx_sk(sk);
-	struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)msg->msg_name;
-	int copied, rc = -ENOTCONN;
-
-        if (sk->zapped) /* Socket not bound */
-		goto out;
-	lock_sock(sk);
-restart:
-        while (skb_queue_empty(&pdata->rcv_queue)) {      /* No data */
-                /* Socket errors? */
-                rc = sock_error(sk);
-                if (rc)
-			goto out_release_sock;
-                /* Socket shut down? */
-		rc = -ESHUTDOWN;
-                if (sk->shutdown & RCV_SHUTDOWN)
-			goto out_release_sock;
-                /* handle signals */
-		rc = -ERESTARTSYS;
-                if (signal_pending(current))
-			goto out_release_sock;
-                /* User doesn't want to wait */
-		rc = -EAGAIN;
-                if (flags & MSG_DONTWAIT)
-			goto out_release_sock;
-		release_sock(sk);
-        	save_flags(flags);
-        	cli();
-        	if (!skb_peek(&pdata->rcv_queue))
-                	interruptible_sleep_on(sk->sleep);
-        	restore_flags(flags);
-        	lock_sock(sk);
-        }
-
-        skb = skb_dequeue(&pdata->rcv_queue);
-        if (!skb) 
-		goto restart;
-
-	ispxh 	= (struct ipxspxhdr *)skb->nh.raw;
-	copied 	= ntohs(ispxh->ipx.ipx_pktsize) - SPX_SYS_PKT_LEN;
-        if (copied > size) {
-                copied = size;
-                msg->msg_flags |= MSG_TRUNC;
-        }
-
-	rc = -EFAULT;
-	if (memcpy_toiovec(msg->msg_iov, skb->nh.raw + SPX_SYS_PKT_LEN, copied))
-		goto out_kfree_skb;
-
-	msg->msg_namelen = sizeof(*sipx);
-	if (sipx) {
-		sipx->sipx_family	= AF_IPX;
-                sipx->sipx_port		= ispxh->ipx.ipx_source.sock;
-                memcpy(sipx->sipx_node,ispxh->ipx.ipx_source.node,IPX_NODE_LEN);
-                sipx->sipx_network	= ispxh->ipx.ipx_source.net;
-                sipx->sipx_type 	= ispxh->ipx.ipx_type;
-        }
-	rc = copied;
-out_kfree_skb:
-	kfree_skb(skb);
-out_release_sock:
-	release_sock(sk);
-out:	return rc;
-}
-
-/*
- * Functions which just wrap their IPX cousins
- */
-
-static int spx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
-{
-        return ipx_ops->bind(sock, uaddr, addr_len);
-}
-
-static int spx_getname (struct socket *sock, struct sockaddr *uaddr,
-                         int *usockaddr_len, int peer)
-{
-	return ipx_ops->getname(sock, uaddr, usockaddr_len, peer);
-}
-
-static int spx_ioctl (struct socket *sock, unsigned int cmd,
-                         unsigned long arg)
-{
-	return ipx_ops->ioctl(sock, cmd, arg);
-}
-
-static int spx_setsockopt(struct socket *sock, int level, int optname,
-                         char *optval, int optlen)
-{
-	return ipx_ops->setsockopt(sock, level, optname, optval, optlen);
-}
-
-static int spx_getsockopt(struct socket *sock, int level, int optname,
-                         char *optval, int *optlen)
-{
-	return ipx_ops->getsockopt(sock, level, optname, optval, optlen);
-}
-
-static struct proto_ops SOCKOPS_WRAPPED(spx_ops) = {
-	family:		PF_IPX,
-
-	release:	spx_release,
-	bind:		spx_bind,
-	connect:	spx_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		spx_accept,
-	getname:	spx_getname,
-	poll:		spx_datagram_poll,
-	ioctl:		spx_ioctl,
-	listen:		spx_listen,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	spx_setsockopt,
-	getsockopt:	spx_getsockopt,
-	sendmsg:	spx_sendmsg,
-	recvmsg:	spx_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
-};
-
-#include <linux/smp_lock.h>
-SOCKOPS_WRAP(spx, PF_IPX);
-
-static struct net_proto_family spx_family_ops = {
-	family:	 PF_IPX,
-	create:	 spx_create,
-};
-
-static char banner[] __initdata =
-	KERN_INFO "NET4: Sequenced Packet eXchange (SPX) 0.03\n";
-
-static int __init spx_proto_init(void)
-{
-	connids = (__u16)jiffies;	/* initalize random */
-
-        /* allocate our sock slab cache */
-
-        spx_family_ops.sk_cachep = kmem_cache_create("spx_sock",
-                                                      spx_family_ops.sk_size,
-                                                      0, SLAB_HWCACHE_ALIGN,
-                                                      0, 0);
-        if (!spx_family_ops.sk_cachep)
-                printk(KERN_CRIT __FUNCTION__
-                        ": Cannot create spx_sock SLAB cache!\n");
-
-	if (ipx_register_spx(&ipx_ops, &spx_family_ops))
-                printk(KERN_ERR "SPX: unable to register with IPX.\n");
-
-	/* route socket(PF_IPX, SOCK_SEQPACKET) calls through spx_create() */
-
-	printk(banner);
-	return 0;
-}
-
-static void __exit spx_proto_finito(void)
-{
-	ipx_unregister_spx();
-}
-
-module_init(spx_proto_init);
-module_exit(spx_proto_finito);
-MODULE_LICENSE("GPL");
diff -Nru a/net/ipx/sysctl_net_ipx.c b/net/ipx/sysctl_net_ipx.c
--- a/net/ipx/sysctl_net_ipx.c	Sat Aug 10 18:42:23 2002
+++ b/net/ipx/sysctl_net_ipx.c	Sat Aug 10 18:42:23 2002
@@ -17,21 +17,36 @@
 /* From af_ipx.c */
 extern int sysctl_ipx_pprop_broadcasting;
 
-ctl_table ipx_table[] = {
-	{ NET_IPX_PPROP_BROADCASTING, "ipx_pprop_broadcasting",
-	  &sysctl_ipx_pprop_broadcasting, sizeof(int), 0644, NULL,
-	  &proc_dointvec },
-	{ 0 }
+static struct ctl_table ipx_table[] = {
+	{
+		.ctl_name	= NET_IPX_PPROP_BROADCASTING,
+		.procname	= "ipx_pprop_broadcasting",
+		.data		= &sysctl_ipx_pprop_broadcasting,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{ 0 },
 };
 
-static ctl_table ipx_dir_table[] = {
-	{ NET_IPX, "ipx", NULL, 0, 0555, ipx_table },
-	{ 0 }
+static struct ctl_table ipx_dir_table[] = {
+	{
+		.ctl_name	= NET_IPX,
+		.procname	= "ipx",
+		.mode		= 0555,
+		.child		= ipx_table,
+       	},
+	{ 0 },
 };
 
-static ctl_table ipx_root_table[] = {
-	{ CTL_NET, "net", NULL, 0, 0555, ipx_dir_table },
-	{ 0 }
+static struct ctl_table ipx_root_table[] = {
+	{
+		.ctl_name	= CTL_NET,
+		.procname	= "net",
+		.mode		= 0555,
+		.child		= ipx_dir_table,
+	},
+	{ 0 },
 };
 
 static struct ctl_table_header *ipx_table_header;
diff -Nru a/net/irda/af_irda.c b/net/irda/af_irda.c
--- a/net/irda/af_irda.c	Sat Aug 10 18:42:22 2002
+++ b/net/irda/af_irda.c	Sat Aug 10 18:42:22 2002
@@ -2414,93 +2414,93 @@
 }
 
 static struct net_proto_family irda_family_ops = {
-	family:	PF_IRDA,
-	create:	irda_create,
+	.family =PF_IRDA,
+	.create =irda_create,
 };
 
 static struct proto_ops SOCKOPS_WRAPPED(irda_stream_ops) = {
-	family:		PF_IRDA,
+	.family =	PF_IRDA,
 
-	release:	irda_release,
-	bind:		irda_bind,
-	connect:	irda_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		irda_accept,
-	getname:	irda_getname,
-	poll:		irda_poll,
-	ioctl:		irda_ioctl,
-	listen:		irda_listen,
-	shutdown:	irda_shutdown,
-	setsockopt:	irda_setsockopt,
-	getsockopt:	irda_getsockopt,
-	sendmsg:	irda_sendmsg,
-	recvmsg:	irda_recvmsg_stream,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	irda_release,
+	.bind =		irda_bind,
+	.connect =	irda_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	irda_accept,
+	.getname =	irda_getname,
+	.poll =		irda_poll,
+	.ioctl =	irda_ioctl,
+	.listen =	irda_listen,
+	.shutdown =	irda_shutdown,
+	.setsockopt =	irda_setsockopt,
+	.getsockopt =	irda_getsockopt,
+	.sendmsg =	irda_sendmsg,
+	.recvmsg =	irda_recvmsg_stream,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 static struct proto_ops SOCKOPS_WRAPPED(irda_seqpacket_ops) = {
-	family:		PF_IRDA,
+	.family =	PF_IRDA,
 
-	release:	irda_release,
-	bind:		irda_bind,
-	connect:	irda_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		irda_accept,
-	getname:	irda_getname,
-	poll:		datagram_poll,
-	ioctl:		irda_ioctl,
-	listen:		irda_listen,
-	shutdown:	irda_shutdown,
-	setsockopt:	irda_setsockopt,
-	getsockopt:	irda_getsockopt,
-	sendmsg:	irda_sendmsg,
-	recvmsg:	irda_recvmsg_dgram,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	irda_release,
+	.bind =		irda_bind,
+	.connect =	irda_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	irda_accept,
+	.getname =	irda_getname,
+	.poll =		datagram_poll,
+	.ioctl =	irda_ioctl,
+	.listen =	irda_listen,
+	.shutdown =	irda_shutdown,
+	.setsockopt =	irda_setsockopt,
+	.getsockopt =	irda_getsockopt,
+	.sendmsg =	irda_sendmsg,
+	.recvmsg =	irda_recvmsg_dgram,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 static struct proto_ops SOCKOPS_WRAPPED(irda_dgram_ops) = {
-	family:		PF_IRDA,
+	.family =	PF_IRDA,
 
-	release:	irda_release,
-	bind:		irda_bind,
-	connect:	irda_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		irda_accept,
-	getname:	irda_getname,
-	poll:		datagram_poll,
-	ioctl:		irda_ioctl,
-	listen:		irda_listen,
-	shutdown:	irda_shutdown,
-	setsockopt:	irda_setsockopt,
-	getsockopt:	irda_getsockopt,
-	sendmsg:	irda_sendmsg_dgram,
-	recvmsg:	irda_recvmsg_dgram,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	irda_release,
+	.bind =		irda_bind,
+	.connect =	irda_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	irda_accept,
+	.getname =	irda_getname,
+	.poll =		datagram_poll,
+	.ioctl =	irda_ioctl,
+	.listen =	irda_listen,
+	.shutdown =	irda_shutdown,
+	.setsockopt =	irda_setsockopt,
+	.getsockopt =	irda_getsockopt,
+	.sendmsg =	irda_sendmsg_dgram,
+	.recvmsg =	irda_recvmsg_dgram,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 #ifdef CONFIG_IRDA_ULTRA
 static struct proto_ops SOCKOPS_WRAPPED(irda_ultra_ops) = {
-	family:		PF_IRDA,
+	.family =	PF_IRDA,
 
-	release:	irda_release,
-	bind:		irda_bind,
-	connect:	sock_no_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		sock_no_accept,
-	getname:	irda_getname,
-	poll:		datagram_poll,
-	ioctl:		irda_ioctl,
-	listen:		sock_no_listen,
-	shutdown:	irda_shutdown,
-	setsockopt:	irda_setsockopt,
-	getsockopt:	irda_getsockopt,
-	sendmsg:	irda_sendmsg_ultra,
-	recvmsg:	irda_recvmsg_dgram,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	irda_release,
+	.bind =		irda_bind,
+	.connect =	sock_no_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	sock_no_accept,
+	.getname =	irda_getname,
+	.poll =		datagram_poll,
+	.ioctl =	irda_ioctl,
+	.listen =	sock_no_listen,
+	.shutdown =	irda_shutdown,
+	.setsockopt =	irda_setsockopt,
+	.getsockopt =	irda_getsockopt,
+	.sendmsg =	irda_sendmsg_ultra,
+	.recvmsg =	irda_recvmsg_dgram,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 #endif /* CONFIG_IRDA_ULTRA */
 
diff -Nru a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
--- a/net/llc/llc_c_ac.c	Sat Aug 10 18:42:23 2002
+++ b/net/llc/llc_c_ac.c	Sat Aug 10 18:42:23 2002
@@ -46,12 +46,13 @@
 
 	if (llc->remote_busy_flag) {
 		u8 nr;
-		llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+		struct llc_pdu_sn *pdu =
+				(struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 		llc->remote_busy_flag = 0;
 		del_timer(&llc->busy_state_timer.timer);
 		llc->busy_state_timer.running = 0;
-		nr = LLC_I_GET_NR(rx_pdu);
+		nr = LLC_I_GET_NR(pdu);
 		llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
 	}
 	return 0;
@@ -147,16 +148,17 @@
 	struct llc_prim_if_block *prim = &llc_ind_prim;
 
 	if (ev->type == LLC_CONN_EV_TYPE_PDU) {
-		llc_pdu_un_t *rx_pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+		struct llc_pdu_un *pdu =
+				(struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
-		if (!LLC_PDU_IS_RSP(rx_pdu) &&
-		    !LLC_PDU_TYPE_IS_U(rx_pdu) &&
-		    LLC_U_PDU_RSP(rx_pdu) == LLC_2_PDU_RSP_DM) {
+		if (!LLC_PDU_IS_RSP(pdu) &&
+		    !LLC_PDU_TYPE_IS_U(pdu) &&
+		    LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM) {
 			reason = LLC_DISC_REASON_RX_DM_RSP_PDU;
 			rc = 0;
-		} else if (!LLC_PDU_IS_CMD(rx_pdu) &&
-			   !LLC_PDU_TYPE_IS_U(rx_pdu) &&
-			   LLC_U_PDU_CMD(rx_pdu) == LLC_2_PDU_CMD_DISC) {
+		} else if (!LLC_PDU_IS_CMD(pdu) &&
+			   !LLC_PDU_TYPE_IS_U(pdu) &&
+			   LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC) {
 			reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;
 			rc = 0;
 		}
@@ -200,21 +202,21 @@
 {
 	u8 reason = 0;
 	int rc = 1;
-	llc_pdu_un_t *rx_pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 	union llc_u_prim_data *prim_data = llc_ind_prim.data;
 	struct llc_prim_if_block *prim = &llc_ind_prim;
 	struct llc_opt *llc = llc_sk(sk);
 
 	switch (ev->type) {
 		case LLC_CONN_EV_TYPE_PDU:
-			if (!LLC_PDU_IS_RSP(rx_pdu) &&
-			    !LLC_PDU_TYPE_IS_U(rx_pdu) &&
-			    LLC_U_PDU_RSP(rx_pdu) == LLC_2_PDU_RSP_FRMR) {
+			if (!LLC_PDU_IS_RSP(pdu) &&
+			    !LLC_PDU_TYPE_IS_U(pdu) &&
+			    LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR) {
 				reason = LLC_RESET_REASON_LOCAL;
 				rc = 0;
-			} else if (!LLC_PDU_IS_CMD(rx_pdu) &&
-				   !LLC_PDU_TYPE_IS_U(rx_pdu) &&
-				   LLC_U_PDU_CMD(rx_pdu) ==
+			} else if (!LLC_PDU_IS_CMD(pdu) &&
+				   !LLC_PDU_TYPE_IS_U(pdu) &&
+				   LLC_U_PDU_CMD(pdu) ==
 				   			LLC_2_PDU_CMD_SABME) {
 				reason = LLC_RESET_REASON_REMOTE;
 				rc = 0;
@@ -270,11 +272,11 @@
 int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk,
 					struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
-	if (!LLC_PDU_IS_RSP(rx_pdu) &&
-	    !LLC_PDU_TYPE_IS_I(rx_pdu) &&
-	    !LLC_I_PF_IS_1(rx_pdu) && llc_sk(sk)->ack_pf)
+	if (!LLC_PDU_IS_RSP(pdu) &&
+	    !LLC_PDU_TYPE_IS_I(pdu) &&
+	    !LLC_I_PF_IS_1(pdu) && llc_sk(sk)->ack_pf)
 		llc_conn_ac_clear_remote_busy(sk, ev);
 	return 0;
 }
@@ -386,11 +388,11 @@
 	u8 f_bit;
 	int rc = 1;
 	struct sk_buff *skb, *ev_skb = ev->data.pdu.skb;
-	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev_skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev_skb->nh.raw;
 	struct llc_opt *llc = llc_sk(sk);
 
-	llc->rx_pdu_hdr = (u32)*((u32 *)rx_pdu);
-	if (!LLC_PDU_IS_CMD(rx_pdu))
+	llc->rx_pdu_hdr = *((u32 *)pdu);
+	if (!LLC_PDU_IS_CMD(pdu))
 		llc_pdu_decode_pf_bit(ev_skb, &f_bit);
 	else
 		f_bit = 0;
@@ -401,7 +403,7 @@
 		skb->dev = llc->dev;
 		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 				    llc->daddr.lsap, LLC_PDU_RSP);
-		llc_pdu_init_as_frmr_rsp(skb, rx_pdu, f_bit, llc->vS,
+		llc_pdu_init_as_frmr_rsp(skb, pdu, f_bit, llc->vS,
 					 llc->vR, INCORRECT);
 		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 		rc = 0;
@@ -420,12 +422,12 @@
 		u8 f_bit = 0;
 		struct llc_opt *llc = llc_sk(sk);
 		struct llc_sap *sap = llc->sap;
-		llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)&llc->rx_pdu_hdr;
+		struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr;
 
 		skb->dev = llc->dev;
 		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 				    llc->daddr.lsap, LLC_PDU_RSP);
-		llc_pdu_init_as_frmr_rsp(skb, rx_pdu, f_bit, llc->vS,
+		llc_pdu_init_as_frmr_rsp(skb, pdu, f_bit, llc->vS,
 					 llc->vR, INCORRECT);
 		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 		rc = 0;
@@ -446,12 +448,13 @@
 	if (skb) {
 		struct llc_opt *llc = llc_sk(sk);
 		struct llc_sap *sap = llc->sap;
-		llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+		struct llc_pdu_sn *pdu =
+				(struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 		skb->dev = llc->dev;
 		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 				    llc->daddr.lsap, LLC_PDU_RSP);
-		llc_pdu_init_as_frmr_rsp(skb, rx_pdu, f_bit, llc->vS,
+		llc_pdu_init_as_frmr_rsp(skb, pdu, f_bit, llc->vS,
 					 llc->vR, INCORRECT);
 		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
 		rc = 0;
@@ -497,9 +500,8 @@
 int llc_conn_ac_resend_i_cmd_p_set_1(struct sock *sk,
 				     struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
-
-	u8 nr = LLC_I_GET_NR(rx_pdu);
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
+	u8 nr = LLC_I_GET_NR(pdu);
 
 	llc_conn_resend_i_pdu_as_cmd(sk, nr, 1);
 	return 0;
@@ -508,9 +510,8 @@
 int llc_conn_ac_resend_i_cmd_p_set_1_or_send_rr(struct sock *sk,
 						struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
-
-	u8 nr = LLC_I_GET_NR(rx_pdu);
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
+	u8 nr = LLC_I_GET_NR(pdu);
 	int rc = llc_conn_ac_send_rr_cmd_p_set_1(sk, ev);
 
 	if (!rc)
@@ -538,8 +539,8 @@
 int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk,
 				     struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
-	u8 nr = LLC_I_GET_NR(rx_pdu);
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
+	u8 nr = LLC_I_GET_NR(pdu);
 
 	llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
 	return 0;
@@ -550,7 +551,7 @@
 {
 	u8 nr;
 	u8 f_bit = 0;
-	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 	int rc = 1;
 	struct sk_buff *skb = llc_alloc_frame();
 
@@ -567,7 +568,7 @@
 		llc_conn_send_pdu(sk, skb);
 	}
 	if (rc) {
-		nr = LLC_I_GET_NR(rx_pdu);
+		nr = LLC_I_GET_NR(pdu);
 		rc = 0;
 		llc_conn_resend_i_pdu_as_cmd(sk, nr, f_bit);
 	}
@@ -577,8 +578,8 @@
 int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk,
 				     struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
-	u8 nr = LLC_I_GET_NR(rx_pdu);
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
+	u8 nr = LLC_I_GET_NR(pdu);
 
 	llc_conn_resend_i_pdu_as_rsp(sk, nr, 1);
 	return 0;
@@ -1336,10 +1337,10 @@
 	u16 unacked = 0;
 	u8 fbit;
 	struct sk_buff *skb = ev->data.pdu.skb;
-	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 	struct llc_opt *llc = llc_sk(sk);
 
-	llc->last_nr = PDU_SUPV_GET_Nr(rx_pdu);
+	llc->last_nr = PDU_SUPV_GET_Nr(pdu);
 	acked = llc_conn_remove_acked_pdus(sk, llc->last_nr, &unacked);
 	/* On loopback we don't queue I frames in unack_pdu_q queue. */
 	if (acked > 0 || (llc->dev->flags & IFF_LOOPBACK)) {
@@ -1375,10 +1376,10 @@
 int llc_conn_ac_upd_p_flag(struct sock *sk, struct llc_conn_state_ev *ev)
 {
 	struct sk_buff *skb = ev->data.pdu.skb;
-	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 	u8 f_bit;
 
-	if (!LLC_PDU_IS_RSP(rx_pdu) &&
+	if (!LLC_PDU_IS_RSP(pdu) &&
 	    !llc_pdu_decode_pf_bit(skb, &f_bit) && f_bit) {
 		llc_sk(sk)->p_flag = 0;
 		llc_conn_ac_stop_p_timer(sk, ev);
@@ -1556,8 +1557,8 @@
 
 int llc_conn_ac_upd_vs(struct sock *sk, struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
-	u8 nr = PDU_SUPV_GET_Nr(rx_pdu);
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
+	u8 nr = PDU_SUPV_GET_Nr(pdu);
 
 	if (llc_circular_between(llc_sk(sk)->vS, nr, llc_sk(sk)->X))
 		llc_conn_ac_set_vs_nr(sk, ev);
diff -Nru a/net/llc/llc_c_ev.c b/net/llc/llc_c_ev.c
--- a/net/llc/llc_c_ev.c	Sat Aug 10 18:42:21 2002
+++ b/net/llc/llc_c_ev.c	Sat Aug 10 18:42:21 2002
@@ -77,7 +77,7 @@
 {
 	u8 nr1, nr2;
 	struct sk_buff *skb;
-	llc_pdu_sn_t *pdu;
+	struct llc_pdu_sn *pdu;
 	struct llc_opt *llc = llc_sk(sk);
 	int rc = 0;
 
@@ -87,10 +87,10 @@
 	if (!skb_queue_len(&llc->pdu_unack_q))
 		goto out;
 	skb = skb_peek(&llc->pdu_unack_q);
-	pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	pdu = (struct llc_pdu_sn *)skb->nh.raw;
 	nr1 = LLC_I_GET_NS(pdu);
 	skb = skb_peek_tail(&llc->pdu_unack_q);
-	pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	pdu = (struct llc_pdu_sn *)skb->nh.raw;
 	nr2 = LLC_I_GET_NS(pdu);
 	rc = !llc_circular_between(nr1, nr, (nr2 + 1) % LLC_2_SEQ_NBR_MODULO);
 out:
@@ -155,7 +155,7 @@
 int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk,
 				       struct llc_conn_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
@@ -164,7 +164,7 @@
 int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk,
 				     struct llc_conn_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
@@ -173,7 +173,7 @@
 int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk,
 				       struct llc_conn_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
@@ -182,7 +182,7 @@
 int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk,
 				    struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
 	       !LLC_I_PF_IS_0(pdu) &&
@@ -192,7 +192,7 @@
 int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk,
 				    struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
 	       !LLC_I_PF_IS_1(pdu) &&
@@ -202,7 +202,7 @@
 int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
 					      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
 
@@ -214,7 +214,7 @@
 int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
 					      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
 
@@ -226,7 +226,7 @@
 int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
 					     struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t * pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn * pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
 	u16 rc = !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
@@ -241,7 +241,7 @@
 int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk,
 				    struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
 	       !LLC_I_PF_IS_0(pdu) &&
@@ -251,7 +251,7 @@
 int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk,
 				    struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
 	       !LLC_I_PF_IS_1(pdu) &&
@@ -261,7 +261,7 @@
 int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk,
 				    struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
@@ -270,7 +270,7 @@
 int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
 					      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
 
@@ -282,7 +282,7 @@
 int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
 					      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
 
@@ -294,7 +294,7 @@
 int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
 					      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
 
@@ -305,7 +305,7 @@
 int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
 					     struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
 	u16 rc = !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
@@ -320,7 +320,7 @@
 int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk,
 				      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       !LLC_S_PF_IS_0(pdu) &&
@@ -330,7 +330,7 @@
 int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk,
 				      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       !LLC_S_PF_IS_1(pdu) &&
@@ -340,7 +340,7 @@
 int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk,
 				      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       !LLC_S_PF_IS_0(pdu) &&
@@ -350,7 +350,7 @@
 int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk,
 				      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       !LLC_S_PF_IS_1(pdu) &&
@@ -360,7 +360,7 @@
 int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk,
 				      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
@@ -369,7 +369,7 @@
 int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk,
 				      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       !LLC_S_PF_IS_0(pdu) &&
@@ -379,7 +379,7 @@
 int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk,
 				      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       !LLC_S_PF_IS_1(pdu) &&
@@ -389,7 +389,7 @@
 int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk,
 				      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       !LLC_S_PF_IS_0(pdu) &&
@@ -399,7 +399,7 @@
 int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk,
 				      struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       !LLC_S_PF_IS_1(pdu) &&
@@ -409,7 +409,7 @@
 int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk,
 				     struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       !LLC_S_PF_IS_0(pdu) &&
@@ -419,7 +419,7 @@
 int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk,
 				     struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       !LLC_S_PF_IS_1(pdu) &&
@@ -429,7 +429,7 @@
 int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk,
 				     struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       !LLC_S_PF_IS_0(pdu) &&
@@ -439,7 +439,7 @@
 int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk,
 				     struct llc_conn_state_ev *ev)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
 	       !LLC_S_PF_IS_1(pdu) &&
@@ -449,7 +449,7 @@
 int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk,
 					struct llc_conn_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
@@ -458,7 +458,7 @@
 int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk,
 				     struct llc_conn_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA ? 0 : 1;
@@ -468,7 +468,7 @@
 				      struct llc_conn_state_ev *ev)
 {
 	u16 rc = 1;
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	if (!LLC_PDU_IS_CMD(pdu)) {
 		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
@@ -484,7 +484,7 @@
 				      struct llc_conn_state_ev *ev)
 {
 	u16 rc = 1;
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	if (!LLC_PDU_IS_CMD(pdu)) {
 		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
@@ -506,7 +506,7 @@
 				      struct llc_conn_state_ev *ev)
 {
 	u16 rc = 1;
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	if (!LLC_PDU_IS_CMD(pdu)) {
 		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu))
@@ -526,7 +526,7 @@
 				      struct llc_conn_state_ev *ev)
 {
 	u16 rc = 1;
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 	if (!LLC_PDU_IS_RSP(pdu)) {
 		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
@@ -549,7 +549,7 @@
 				      struct llc_conn_state_ev *ev)
 {
 	u16 rc = 1;
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	if (!LLC_PDU_IS_RSP(pdu)) {
 		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu))
@@ -570,7 +570,7 @@
 int llc_conn_ev_rx_xxx_yyy(struct sock *sk, struct llc_conn_state_ev *ev)
 {
 	u16 rc = 1;
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu))
 		rc = 0;
@@ -591,7 +591,7 @@
 					       struct llc_conn_state_ev *ev)
 {
 	u16 rc = 1;
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 	u8 vs = llc_sk(sk)->vS;
 	u8 nr = LLC_I_GET_NR(pdu);
 
@@ -613,7 +613,7 @@
 					       struct llc_conn_state_ev *ev)
 {
 	u16 rc = 1;
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 	u8 vs = llc_sk(sk)->vS;
 	u8 nr = LLC_I_GET_NR(pdu);
 
diff -Nru a/net/llc/llc_c_st.c b/net/llc/llc_c_st.c
--- a/net/llc/llc_c_st.c	Sat Aug 10 18:42:22 2002
+++ b/net/llc/llc_c_st.c	Sat Aug 10 18:42:22 2002
@@ -2808,20 +2808,20 @@
 	[36] = &llc_reject_state_trans_8a,
 	[37] = &llc_reject_state_trans_8b,
 	[38] = &llc_reject_state_trans_9,
-	[40] = &llc_reject_state_trans_10a,
-	[41] = &llc_reject_state_trans_10b,
-	[42] = &llc_reject_state_trans_10c,
-	[43] = &llc_reject_state_trans_11,
-	[44] = &llc_reject_state_trans_12a,
-	[45] = &llc_reject_state_trans_12b,
-	[46] = &llc_reject_state_trans_12c,
-	[47] = &llc_reject_state_trans_13,
-	[48] = &llc_reject_state_trans_14a,
-	[49] = &llc_reject_state_trans_14b,
-	[50] = &llc_reject_state_trans_15a,
-	[51] = &llc_reject_state_trans_15b,
-	[52] = &llc_reject_state_trans_16,
-	[53] = &llc_common_state_trans_n,
+	[39] = &llc_reject_state_trans_10a,
+	[40] = &llc_reject_state_trans_10b,
+	[41] = &llc_reject_state_trans_10c,
+	[42] = &llc_reject_state_trans_11,
+	[43] = &llc_reject_state_trans_12a,
+	[44] = &llc_reject_state_trans_12b,
+	[45] = &llc_reject_state_trans_12c,
+	[46] = &llc_reject_state_trans_13,
+	[47] = &llc_reject_state_trans_14a,
+	[48] = &llc_reject_state_trans_14b,
+	[49] = &llc_reject_state_trans_15a,
+	[50] = &llc_reject_state_trans_15b,
+	[51] = &llc_reject_state_trans_16,
+	[52] = &llc_common_state_trans_n,
 };
 
 /* LLC_CONN_STATE_AWAIT transitions */
@@ -4896,51 +4896,51 @@
 /* Connection State Transition Table */
 struct llc_conn_state llc_conn_state_table[] = {
 	{
-		current_state:	LLC_CONN_STATE_ADM,
-		transitions:	llc_adm_state_transitions,
+		.current_state =LLC_CONN_STATE_ADM,
+		.transitions =	llc_adm_state_transitions,
 	},
 	{
-		current_state:	LLC_CONN_STATE_SETUP,
-		transitions:	llc_setup_state_transitions,
+		.current_state =LLC_CONN_STATE_SETUP,
+		.transitions =	llc_setup_state_transitions,
 	},
 	{
-		current_state:	LLC_CONN_STATE_NORMAL,
-		transitions:	llc_normal_state_transitions,
+		.current_state =LLC_CONN_STATE_NORMAL,
+		.transitions =	llc_normal_state_transitions,
 	},
 	{
-		current_state:	LLC_CONN_STATE_BUSY,
-		transitions:	llc_busy_state_transitions,
+		.current_state =LLC_CONN_STATE_BUSY,
+		.transitions =	llc_busy_state_transitions,
 	},
 	{
-		current_state:	LLC_CONN_STATE_REJ,
-		transitions:	llc_reject_state_transitions,
+		.current_state =LLC_CONN_STATE_REJ,
+		.transitions =	llc_reject_state_transitions,
 	},
 	{
-		current_state:	LLC_CONN_STATE_AWAIT,
-		transitions:	llc_await_state_transitions,
+		.current_state =LLC_CONN_STATE_AWAIT,
+		.transitions =	llc_await_state_transitions,
 	},
 	{
-		current_state:	LLC_CONN_STATE_AWAIT_BUSY,
-		transitions:	llc_await_busy_state_transitions,
+		.current_state =LLC_CONN_STATE_AWAIT_BUSY,
+		.transitions =	llc_await_busy_state_transitions,
 	},
 	{
-		current_state:	LLC_CONN_STATE_AWAIT_REJ,
-		transitions:	llc_await_rejct_state_transitions,
+		.current_state =LLC_CONN_STATE_AWAIT_REJ,
+		.transitions =	llc_await_rejct_state_transitions,
 	},
 	{
-		current_state:	LLC_CONN_STATE_D_CONN,
-		transitions:	llc_d_conn_state_transitions,
+		.current_state =LLC_CONN_STATE_D_CONN,
+		.transitions =	llc_d_conn_state_transitions,
 	},
 	{
-		current_state:	LLC_CONN_STATE_RESET,
-		transitions:	llc_rst_state_transitions,
+		.current_state =LLC_CONN_STATE_RESET,
+		.transitions =	llc_rst_state_transitions,
 	},
 	{
-		current_state:	LLC_CONN_STATE_ERROR,
-		transitions:	llc_error_state_transitions,
+		.current_state =LLC_CONN_STATE_ERROR,
+		.transitions =	llc_error_state_transitions,
 	},
 	{
-		current_state:	LLC_CONN_STATE_TEMP,
-		transitions:	llc_temp_state_transitions,
+		.current_state =LLC_CONN_STATE_TEMP,
+		.transitions =	llc_temp_state_transitions,
 	},
 };
diff -Nru a/net/llc/llc_conn.c b/net/llc/llc_conn.c
--- a/net/llc/llc_conn.c	Sat Aug 10 18:42:21 2002
+++ b/net/llc/llc_conn.c	Sat Aug 10 18:42:21 2002
@@ -162,7 +162,7 @@
 void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit)
 {
 	struct sk_buff *skb;
-	llc_pdu_sn_t *pdu;
+	struct llc_pdu_sn *pdu;
 	u16 nbr_unack_pdus;
 	u8 howmany_resend = 0;
 
@@ -173,7 +173,7 @@
 	 * appropriate PDUs, fix them up, and put them on mac_pdu_q.
 	 */
 	while ((skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q)) != NULL) {
-		pdu = (llc_pdu_sn_t *)skb->nh.raw;
+		pdu = (struct llc_pdu_sn *)skb->nh.raw;
 		llc_pdu_set_cmd_rsp(skb, LLC_PDU_CMD);
 		llc_pdu_set_pf_bit(skb, first_p_bit);
 		skb_queue_tail(&sk->write_queue, skb);
@@ -201,7 +201,7 @@
 void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit)
 {
 	struct sk_buff *skb;
-	llc_pdu_sn_t *pdu;
+	struct llc_pdu_sn *pdu;
 	u16 nbr_unack_pdus;
 	u8 howmany_resend = 0;
 
@@ -212,7 +212,7 @@
 	 * appropriate PDUs, fix them up, and put them on mac_pdu_q
 	 */
 	while ((skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q)) != NULL) {
-		pdu = (llc_pdu_sn_t *)skb->nh.raw;
+		pdu = (struct llc_pdu_sn *)skb->nh.raw;
 		llc_pdu_set_cmd_rsp(skb, LLC_PDU_RSP);
 		llc_pdu_set_pf_bit(skb, first_f_bit);
 		skb_queue_tail(&sk->write_queue, skb);
@@ -240,14 +240,14 @@
 {
 	int pdu_pos, i;
 	struct sk_buff *skb;
-	llc_pdu_sn_t *pdu;
+	struct llc_pdu_sn *pdu;
 	int nbr_acked = 0;
 	int q_len = skb_queue_len(&llc_sk(sk)->pdu_unack_q);
 
 	if (!q_len)
 		goto out;
 	skb = skb_peek(&llc_sk(sk)->pdu_unack_q);
-	pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	pdu = (struct llc_pdu_sn *)skb->nh.raw;
 
 	/* finding position of last acked pdu in queue */
 	pdu_pos = ((int)LLC_2_SEQ_NBR_MODULO + (int)nr -
@@ -275,7 +275,7 @@
 	struct sk_buff *skb;
 
 	while ((skb = skb_dequeue(&sk->write_queue)) != NULL) {
-		llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+		struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 
 		if (!LLC_PDU_TYPE_IS_I(pdu) &&
 		    !(skb->dev->flags & IFF_LOOPBACK))
@@ -297,7 +297,8 @@
 {
 	if (ev->type == LLC_CONN_EV_TYPE_PDU) {
 		/* free the frame that binded to this event */
-		llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+		struct llc_pdu_sn *pdu =
+				(struct llc_pdu_sn *)ev->data.pdu.skb->nh.raw;
 
 		if (LLC_PDU_TYPE_IS_I(pdu) || !ev->flag || !ev->ind_prim)
 			kfree_skb(ev->data.pdu.skb);
@@ -488,7 +489,6 @@
 	struct llc_conn_state *curr_state;
 	int state, ev_type, next_offset;
 
-	memset(llc_offset_table, 0, sizeof(llc_offset_table));
 	for (state = 0; state < NBR_CONN_STATES; state++) {
 		curr_state = &llc_conn_state_table[state];
 		next_offset = 0;
diff -Nru a/net/llc/llc_evnt.c b/net/llc/llc_evnt.c
--- a/net/llc/llc_evnt.c	Sat Aug 10 18:42:21 2002
+++ b/net/llc/llc_evnt.c	Sat Aug 10 18:42:21 2002
@@ -56,7 +56,7 @@
 int llc_stat_ev_rx_null_dsap_xid_c(struct llc_station *station,
 				   struct llc_station_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return ev->type == LLC_STATION_EV_TYPE_PDU &&
 	       !LLC_PDU_IS_CMD(pdu) &&			/* command PDU */
@@ -68,7 +68,7 @@
 int llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq(struct llc_station *station,
 					        struct llc_station_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return ev->type == LLC_STATION_EV_TYPE_PDU &&
 	       !LLC_PDU_IS_RSP(pdu) &&			/* response PDU */
@@ -81,7 +81,7 @@
 int llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq(struct llc_station *station,
 					        struct llc_station_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return ev->type == LLC_STATION_EV_TYPE_PDU &&
 	       !LLC_PDU_IS_RSP(pdu) &&			/* response PDU */
@@ -94,7 +94,7 @@
 int llc_stat_ev_rx_null_dsap_test_c(struct llc_station *station,
 				    struct llc_station_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return ev->type == LLC_STATION_EV_TYPE_PDU &&
 	       !LLC_PDU_IS_CMD(pdu) &&			/* command PDU */
diff -Nru a/net/llc/llc_if.c b/net/llc/llc_if.c
--- a/net/llc/llc_if.c	Sat Aug 10 18:42:23 2002
+++ b/net/llc/llc_if.c	Sat Aug 10 18:42:23 2002
@@ -77,8 +77,8 @@
  *	@sap: pointer to allocated SAP (output argument).
  *
  *	Interface function to upper layer. each one who wants to get a SAP
- *	(for example NetBEUI) should call this function. Returns 0 for
- *	success, 1 for failure.
+ *	(for example NetBEUI) should call this function. Returns the opened
+ *	SAP for success, NULL for failure.
  */
 struct llc_sap *llc_sap_open(llc_prim_call_t nw_indicate,
 			     llc_prim_call_t nw_confirm, u8 lsap)
diff -Nru a/net/llc/llc_mac.c b/net/llc/llc_mac.c
--- a/net/llc/llc_mac.c	Sat Aug 10 18:42:23 2002
+++ b/net/llc/llc_mac.c	Sat Aug 10 18:42:23 2002
@@ -25,10 +25,8 @@
 #include <net/llc_evnt.h>
 #include <net/llc_c_ev.h>
 #include <net/llc_s_ev.h>
-#ifdef CONFIG_TR
-extern void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh,
-			    struct net_device *dev);
-#endif
+#include <linux/trdevice.h>
+
 /* function prototypes */
 static void fix_up_incoming_skb(struct sk_buff *skb);
 
@@ -78,7 +76,7 @@
 		 struct packet_type *pt)
 {
 	struct llc_sap *sap;
-	llc_pdu_sn_t *pdu;
+	struct llc_pdu_sn *pdu;
 	u8 dest;
 
 	/* When the interface is in promisc. mode, drop all the crap that it
@@ -92,7 +90,7 @@
 	if (!skb)
 		goto out;
 	fix_up_incoming_skb(skb);
-	pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	pdu = (struct llc_pdu_sn *)skb->nh.raw;
 	if (!pdu->dsap) { /* NULL DSAP, refer to station */
 		llc_pdu_router(NULL, NULL, skb, 0);
 		goto out;
@@ -165,11 +163,12 @@
 static void fix_up_incoming_skb(struct sk_buff *skb)
 {
 	u8 llc_len = 2;
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->data;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->data;
 
 	if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U)
 		llc_len = 1;
 	llc_len += 2;
+	skb->h.raw += llc_len;
 	skb_pull(skb, llc_len);
 	if (skb->protocol == htons(ETH_P_802_2)) {
 		u16 pdulen = ((struct ethhdr *)skb->mac.raw)->h_proto,
@@ -197,7 +196,7 @@
 int llc_pdu_router(struct llc_sap *sap, struct sock* sk,
 		   struct sk_buff *skb, u8 type)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 	int rc = 0;
 
 	if (!pdu->dsap) {
@@ -246,17 +245,15 @@
  */
 u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da)
 {
-	u8 *saddr;
-	u8 *daddr;
 	u16 rc = 0;
 
 	switch (skb->dev->type) {
 #ifdef CONFIG_TR
 		case ARPHRD_IEEE802_TR: {
-			struct trh_hdr *trh = (struct trh_hdr *)
-						    skb_push(skb, sizeof(*trh));
+			struct trh_hdr *trh;
 			struct net_device *dev = skb->dev;
 
+			trh = (struct trh_hdr *)skb_push(skb, sizeof(*trh));
 			trh->ac = AC;
 			trh->fc = LLC_FRAME;
 			if (sa)
@@ -274,14 +271,13 @@
 		case ARPHRD_ETHER:
 		case ARPHRD_LOOPBACK: {
 			unsigned short len = skb->len;
+			struct ethhdr *eth;
 
-			skb->mac.raw = skb_push(skb, sizeof(struct ethhdr));
-			memset(skb->mac.raw, 0, sizeof(struct ethhdr));
-			((struct ethhdr *)skb->mac.raw)->h_proto = htons(len);
-			daddr = ((struct ethhdr *)skb->mac.raw)->h_dest;
-			saddr = ((struct ethhdr *)skb->mac.raw)->h_source;
-			memcpy(daddr, da, ETH_ALEN);
-			memcpy(saddr, sa, ETH_ALEN);
+			skb->mac.raw = skb_push(skb, sizeof(*eth));
+			eth = (struct ethhdr *)skb->mac.raw;
+			eth->h_proto = htons(len);
+			memcpy(eth->h_dest, da, ETH_ALEN);
+			memcpy(eth->h_source, sa, ETH_ALEN);
 			break;
 		}
 		default:
diff -Nru a/net/llc/llc_main.c b/net/llc/llc_main.c
--- a/net/llc/llc_main.c	Sat Aug 10 18:42:22 2002
+++ b/net/llc/llc_main.c	Sat Aug 10 18:42:22 2002
@@ -600,23 +600,23 @@
 	ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
 	if (!ev)
 		goto err;
+	llc_build_offset_table();
 	memset(ev, 0, sizeof(*ev));
 	if(dev_base->next)
 		memcpy(llc_main_station.mac_sa, dev_base->next->dev_addr, ETH_ALEN);
 	else
 		memset(llc_main_station.mac_sa, 0, ETH_ALEN);
 	llc_main_station.ack_timer.expires = jiffies + 3 * HZ;
-	/* initialize the station component */
-	llc_register_sap(0, mac_indicate);
 	llc_main_station.maximum_retry	= 1;
 	llc_main_station.state		= LLC_STATION_STATE_DOWN;
 	ev->type	= LLC_STATION_EV_TYPE_SIMPLE;
 	ev->data.a.ev	= LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
 	rc = llc_station_next_state(&llc_main_station, ev);
-	llc_build_offset_table();
 	llc_ind_prim.data = &llc_ind_data_prim;
 	llc_cfm_prim.data = &llc_cfm_data_prim;
 	proc_net_create("802.2", 0, llc_proc_get_info);
+	/* initialize the station component */
+	llc_register_sap(0, mac_indicate);
 	llc_ui_init();
 out:
 	return rc;
diff -Nru a/net/llc/llc_pdu.c b/net/llc/llc_pdu.c
--- a/net/llc/llc_pdu.c	Sat Aug 10 18:42:21 2002
+++ b/net/llc/llc_pdu.c	Sat Aug 10 18:42:21 2002
@@ -20,7 +20,7 @@
 
 static int llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type);
 static int llc_get_llc_hdr_length(u8 pdu_type);
-static u8 llc_pdu_get_pf_bit(llc_pdu_sn_t *pdu);
+static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu);
 
 /**
  *	llc_pdu_header_init - initializes pdu header
@@ -35,18 +35,18 @@
 void llc_pdu_header_init(struct sk_buff *skb, u8 pdu_type, u8 ssap,
 			 u8 dsap, u8 cr)
 {
-	llc_pdu_un_t *p;
+	struct llc_pdu_un *pdu;
 
 	skb->nh.raw = skb_push(skb, llc_get_llc_hdr_length(pdu_type));
-	p = (llc_pdu_un_t *)skb->nh.raw;
-	p->dsap = dsap;
-	p->ssap = ssap;
-	p->ssap |= cr;
+	pdu = (struct llc_pdu_un *)skb->nh.raw;
+	pdu->dsap = dsap;
+	pdu->ssap = ssap;
+	pdu->ssap |= cr;
 }
 
 void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 pdu_type)
 {
-	((llc_pdu_un_t *)skb->nh.raw)->ssap |= pdu_type;
+	((struct llc_pdu_un *)skb->nh.raw)->ssap |= pdu_type;
 }
 
 /**
@@ -61,20 +61,20 @@
 void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value)
 {
 	u8 pdu_type;
+	struct llc_pdu_sn *pdu;
 
 	if (llc_pdu_decode_pdu_type(skb, &pdu_type))
 		goto out;
+
+	pdu = (struct llc_pdu_sn *)skb->nh.raw;
+	
 	switch (pdu_type) {
 		case LLC_PDU_TYPE_I:
 		case LLC_PDU_TYPE_S:
-			((llc_pdu_sn_t *)skb->nh.raw)->ctrl_2 =
-				(((llc_pdu_sn_t *)skb->nh.raw)->ctrl_2 & 0xFE) |
-				bit_value;
+			pdu->ctrl_2 = (pdu->ctrl_2 & 0xFE) | bit_value;
 			break;
 		case LLC_PDU_TYPE_U:
-			((llc_pdu_un_t *)skb->nh.raw)->ctrl_1 |=
-				(((llc_pdu_un_t *)skb->nh.raw)->ctrl_1 & 0xEF) |
-				(bit_value << 4);
+			pdu->ctrl_1 |= (pdu->ctrl_1 & 0xEF) | (bit_value << 4);
 			break;
 	}
 out:;
@@ -92,19 +92,21 @@
 int llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit)
 {
 	u8 pdu_type;
+	struct llc_pdu_sn *pdu;
 	int rc = llc_pdu_decode_pdu_type(skb, &pdu_type);
 
 	if (rc)
 		goto out;
+
+	pdu = (struct llc_pdu_sn *)skb->nh.raw;
+
 	switch (pdu_type) {
 		case LLC_PDU_TYPE_I:
 		case LLC_PDU_TYPE_S:
-			*pf_bit = ((llc_pdu_sn_t *)skb->nh.raw)->ctrl_2 &
-				  LLC_S_PF_BIT_MASK;
+			*pf_bit = pdu->ctrl_2 & LLC_S_PF_BIT_MASK;
 			break;
 		case LLC_PDU_TYPE_U:
-			*pf_bit = (((llc_pdu_un_t *)skb->nh.raw)->ctrl_1 &
-				  LLC_U_PF_BIT_MASK) >> 4;
+			*pf_bit = (pdu->ctrl_1 & LLC_U_PF_BIT_MASK) >> 4;
 			break;
 	}
 out:
@@ -121,7 +123,8 @@
  */
 int llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit)
 {
-	*cr_bit = ((llc_pdu_un_t *)skb->nh.raw)->ssap & LLC_PDU_CMD_RSP_MASK;
+	*cr_bit = ((struct llc_pdu_un *)skb->nh.raw)->ssap &
+		  LLC_PDU_CMD_RSP_MASK;
 	return 0;
 }
 
@@ -167,7 +170,7 @@
  */
 int llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap)
 {
-	*dsap = ((llc_pdu_un_t *)skb->nh.raw)->dsap & 0xFE;
+	*dsap = ((struct llc_pdu_un *)skb->nh.raw)->dsap & 0xFE;
 	return 0;
 }
 
@@ -181,7 +184,7 @@
  */
 int llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap)
 {
-	*ssap = ((llc_pdu_un_t *)skb->nh.raw)->ssap & 0xFE;
+	*ssap = ((struct llc_pdu_un *)skb->nh.raw)->ssap & 0xFE;
 	return 0;
 }
 
@@ -193,7 +196,7 @@
  */
 int llc_pdu_init_as_ui_cmd(struct sk_buff *skb)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_U;
 	pdu->ctrl_1 |= LLC_1_PDU_CMD_UI;
@@ -210,13 +213,13 @@
 int llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported,
 			    u8 rx_window)
 {
-	llc_xid_info_t *xid_info;
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+	struct llc_xid_info *xid_info;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)skb->nh.raw;
 
 	pdu->ctrl_1	 = LLC_PDU_TYPE_U;
 	pdu->ctrl_1	|= LLC_1_PDU_CMD_XID;
 	pdu->ctrl_1	|= LLC_U_PF_BIT_MASK;
-	xid_info	 = (llc_xid_info_t *)(((u8 *)&pdu->ctrl_1) + 1);
+	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 */
@@ -232,7 +235,7 @@
  */
 int llc_pdu_init_as_test_cmd(struct sk_buff *skb)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_U;
 	pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
@@ -249,7 +252,7 @@
  */
 int llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_U;
 	pdu->ctrl_1 |= LLC_2_PDU_CMD_DISC;
@@ -268,7 +271,7 @@
  */
 int llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_I;
 	pdu->ctrl_2  = 0;
@@ -288,7 +291,7 @@
  */
 int llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_S;
 	pdu->ctrl_1 |= LLC_2_PDU_CMD_REJ;
@@ -309,7 +312,7 @@
  */
 int llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_S;
 	pdu->ctrl_1 |= LLC_2_PDU_CMD_RNR;
@@ -330,7 +333,7 @@
  */
 int llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_S;
 	pdu->ctrl_1 |= LLC_2_PDU_CMD_RR;
@@ -349,7 +352,7 @@
  */
 int llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_U;
 	pdu->ctrl_1 |= LLC_2_PDU_CMD_SABME;
@@ -366,7 +369,7 @@
  */
 int llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_U;
 	pdu->ctrl_1 |= LLC_2_PDU_RSP_DM;
@@ -385,14 +388,14 @@
 int llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported,
 			    u8 rx_window)
 {
-	llc_xid_info_t *xid_info;
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+	struct llc_xid_info *xid_info;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)skb->nh.raw;
 
 	pdu->ctrl_1	 = LLC_PDU_TYPE_U;
 	pdu->ctrl_1	|= LLC_1_PDU_CMD_XID;
 	pdu->ctrl_1	|= LLC_U_PF_BIT_MASK;
 
-	xid_info	 = (llc_xid_info_t *)(((u8 *)&pdu->ctrl_1) + 1);
+	xid_info	 = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
 	xid_info->fmt_id = LLC_XID_FMT_ID;
 	xid_info->type	 = svcs_supported;
 	xid_info->rw	 = rx_window << 1;
@@ -410,7 +413,7 @@
 int llc_pdu_init_as_test_rsp(struct sk_buff *skb, struct sk_buff *ev_skb)
 {
 	int dsize;
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_U;
 	pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
@@ -435,19 +438,19 @@
  *
  *	Builds a pdu frame as a FRMR response.
  */
-int llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, llc_pdu_sn_t *prev_pdu,
+int llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu,
 			     u8 f_bit, u8 vs, u8 vr, u8 vzyxw)
 {
-	llc_frmr_info_t *frmr_info;
+	struct llc_frmr_info *frmr_info;
 	u8 prev_pf = 0;
 	u8 *ctrl;
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_U;
 	pdu->ctrl_1 |= LLC_2_PDU_RSP_FRMR;
 	pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
 
-	frmr_info = (llc_frmr_info_t *)&pdu->ctrl_2;
+	frmr_info = (struct llc_frmr_info *)&pdu->ctrl_2;
 	ctrl = (u8 *)&prev_pdu->ctrl_1;
 	FRMR_INFO_SET_REJ_CNTRL(frmr_info,ctrl);
 	FRMR_INFO_SET_Vs(frmr_info, vs);
@@ -473,7 +476,7 @@
  */
 int llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_S;
 	pdu->ctrl_1 |= LLC_2_PDU_RSP_RR;
@@ -494,7 +497,7 @@
  */
 int llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_S;
 	pdu->ctrl_1 |= LLC_2_PDU_RSP_REJ;
@@ -515,7 +518,7 @@
  */
 int llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
 {
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_S;
 	pdu->ctrl_1 |= LLC_2_PDU_RSP_RNR;
@@ -535,7 +538,7 @@
  */
 int llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)skb->nh.raw;
 
 	pdu->ctrl_1  = LLC_PDU_TYPE_U;
 	pdu->ctrl_1 |= LLC_2_PDU_RSP_UA;
@@ -552,7 +555,7 @@
  */
 static int llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)skb->nh.raw;
 
 	if (pdu->ctrl_1 & 1) {
 		if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U)
@@ -574,7 +577,7 @@
 int llc_decode_pdu_type(struct sk_buff *skb, u8 *dest)
 {
 	u8 type = LLC_DEST_CONN; /* I-PDU or S-PDU type */
-	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)skb->nh.raw;
 
 	if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) != LLC_PDU_TYPE_U)
 		goto out;
@@ -629,7 +632,7 @@
  *	This function extracts p/f bit of input PDU. at first examines type of
  *	PDU and then extracts p/f bit. Returns the p/f bit.
  */
-static u8 llc_pdu_get_pf_bit(llc_pdu_sn_t *pdu)
+static u8 llc_pdu_get_pf_bit(struct llc_pdu_sn *pdu)
 {
 	u8 pdu_type;
 	u8 pf_bit = 0;
diff -Nru a/net/llc/llc_s_ev.c b/net/llc/llc_s_ev.c
--- a/net/llc/llc_s_ev.c	Sat Aug 10 18:42:21 2002
+++ b/net/llc/llc_s_ev.c	Sat Aug 10 18:42:21 2002
@@ -28,7 +28,7 @@
 
 int llc_sap_ev_rx_ui(struct llc_sap *sap, struct llc_sap_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_CMD(pdu) &&
 	       !LLC_PDU_TYPE_IS_U(pdu) &&
@@ -52,7 +52,7 @@
 
 int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct llc_sap_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_CMD(pdu) &&
 	       !LLC_PDU_TYPE_IS_U(pdu) &&
@@ -61,7 +61,7 @@
 
 int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct llc_sap_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_RSP(pdu) &&
 	       !LLC_PDU_TYPE_IS_U(pdu) &&
@@ -77,7 +77,7 @@
 
 int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct llc_sap_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_CMD(pdu) &&
 	       !LLC_PDU_TYPE_IS_U(pdu) &&
@@ -86,7 +86,7 @@
 
 int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct llc_sap_state_ev *ev)
 {
-	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	struct llc_pdu_un *pdu = (struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_RSP(pdu) &&
 	       !LLC_PDU_TYPE_IS_U(pdu) &&
diff -Nru a/net/llc/llc_s_st.c b/net/llc/llc_s_st.c
--- a/net/llc/llc_s_st.c	Sat Aug 10 18:42:20 2002
+++ b/net/llc/llc_s_st.c	Sat Aug 10 18:42:20 2002
@@ -173,11 +173,11 @@
 /* SAP state transition table */
 struct llc_sap_state llc_sap_state_table[] = {
 	{
-		curr_state:	LLC_SAP_STATE_INACTIVE,
-		transitions:	llc_sap_inactive_state_transitions,
+		.curr_state =	LLC_SAP_STATE_INACTIVE,
+		.transitions =	llc_sap_inactive_state_transitions,
        	},
 	{
-		curr_state:	LLC_SAP_STATE_ACTIVE,
-		transitions:	llc_sap_active_state_transitions,
+		.curr_state =	LLC_SAP_STATE_ACTIVE,
+		.transitions =	llc_sap_active_state_transitions,
 	},
 };
diff -Nru a/net/llc/llc_sap.c b/net/llc/llc_sap.c
--- a/net/llc/llc_sap.c	Sat Aug 10 18:42:23 2002
+++ b/net/llc/llc_sap.c	Sat Aug 10 18:42:23 2002
@@ -111,7 +111,7 @@
 void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb,
 		     struct llc_sap_state_ev *ev)
 {
-	llc_pdu_un_t *pdu;
+	struct llc_pdu_un *pdu;
 	struct llc_prim_if_block *prim = &llc_ind_prim;
 	union llc_u_prim_data *prim_data = llc_ind_prim.data;
 	u8 lfb;
@@ -122,7 +122,7 @@
 	llc_pdu_decode_ssap(skb, &prim_data->udata.saddr.lsap);
 	prim_data->udata.pri = 0;
 	prim_data->udata.skb = skb;
-	pdu = (llc_pdu_un_t *)skb->nh.raw;
+	pdu = (struct llc_pdu_un *)skb->nh.raw;
 	switch (LLC_U_PDU_RSP(pdu)) {
 		case LLC_1_PDU_CMD_TEST:
 			prim->prim = LLC_TEST_PRIM;
@@ -170,7 +170,8 @@
 static void llc_sap_free_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev)
 {
 	if (ev->type == LLC_SAP_EV_TYPE_PDU) {
-		llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+		struct llc_pdu_un *pdu =
+				(struct llc_pdu_un *)ev->data.pdu.skb->nh.raw;
 
 		if (LLC_U_PDU_CMD(pdu) != LLC_1_PDU_CMD_UI)
 			kfree_skb(ev->data.pdu.skb);
diff -Nru a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
--- a/net/netlink/af_netlink.c	Sat Aug 10 18:42:23 2002
+++ b/net/netlink/af_netlink.c	Sat Aug 10 18:42:23 2002
@@ -987,29 +987,29 @@
 }
                 
 struct proto_ops netlink_ops = {
-	family:		PF_NETLINK,
+	.family =	PF_NETLINK,
 
-	release:	netlink_release,
-	bind:		netlink_bind,
-	connect:	netlink_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		sock_no_accept,
-	getname:	netlink_getname,
-	poll:		datagram_poll,
-	ioctl:		sock_no_ioctl,
-	listen:		sock_no_listen,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	sock_no_setsockopt,
-	getsockopt:	sock_no_getsockopt,
-	sendmsg:	netlink_sendmsg,
-	recvmsg:	netlink_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	netlink_release,
+	.bind =		netlink_bind,
+	.connect =	netlink_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	sock_no_accept,
+	.getname =	netlink_getname,
+	.poll =		datagram_poll,
+	.ioctl =	sock_no_ioctl,
+	.listen =	sock_no_listen,
+	.shutdown =	sock_no_shutdown,
+	.setsockopt =	sock_no_setsockopt,
+	.getsockopt =	sock_no_getsockopt,
+	.sendmsg =	netlink_sendmsg,
+	.recvmsg =	netlink_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 struct net_proto_family netlink_family_ops = {
-	family:	PF_NETLINK,
-	create:	netlink_create,
+	.family =PF_NETLINK,
+	.create =netlink_create,
 };
 
 static int __init netlink_proto_init(void)
diff -Nru a/net/netlink/netlink_dev.c b/net/netlink/netlink_dev.c
--- a/net/netlink/netlink_dev.c	Sat Aug 10 18:42:22 2002
+++ b/net/netlink/netlink_dev.c	Sat Aug 10 18:42:22 2002
@@ -160,14 +160,14 @@
 
 
 static struct file_operations netlink_fops = {
-	owner:		THIS_MODULE,
-	llseek:		no_llseek,
-	read:		netlink_read,
-	write:		netlink_write,
-	poll:		netlink_poll,
-	ioctl:		netlink_ioctl,
-	open:		netlink_open,
-	release:	netlink_release,
+	.owner =	THIS_MODULE,
+	.llseek =	no_llseek,
+	.read =		netlink_read,
+	.write =	netlink_write,
+	.poll =		netlink_poll,
+	.ioctl =	netlink_ioctl,
+	.open =		netlink_open,
+	.release =	netlink_release,
 };
 
 static devfs_handle_t devfs_handle;
diff -Nru a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
--- a/net/netrom/af_netrom.c	Sat Aug 10 18:42:23 2002
+++ b/net/netrom/af_netrom.c	Sat Aug 10 18:42:23 2002
@@ -1251,36 +1251,36 @@
 } 
 
 static struct net_proto_family nr_family_ops = {
-	family:		PF_NETROM,
-	create:		nr_create,
+	.family =	PF_NETROM,
+	.create =	nr_create,
 };
 
 static struct proto_ops SOCKOPS_WRAPPED(nr_proto_ops) = {
-	family:		PF_NETROM,
+	.family =	PF_NETROM,
 
-	release:	nr_release,
-	bind:		nr_bind,
-	connect:	nr_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		nr_accept,
-	getname:	nr_getname,
-	poll:		datagram_poll,
-	ioctl:		nr_ioctl,
-	listen:		nr_listen,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	nr_setsockopt,
-	getsockopt:	nr_getsockopt,
-	sendmsg:	nr_sendmsg,
-	recvmsg:	nr_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	nr_release,
+	.bind =		nr_bind,
+	.connect =	nr_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	nr_accept,
+	.getname =	nr_getname,
+	.poll =		datagram_poll,
+	.ioctl =	nr_ioctl,
+	.listen =	nr_listen,
+	.shutdown =	sock_no_shutdown,
+	.setsockopt =	nr_setsockopt,
+	.getsockopt =	nr_getsockopt,
+	.sendmsg =	nr_sendmsg,
+	.recvmsg =	nr_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 #include <linux/smp_lock.h>
 SOCKOPS_WRAP(nr_proto, PF_NETROM);
 
 static struct notifier_block nr_dev_notifier = {
-	notifier_call:	nr_device_event,
+	.notifier_call =nr_device_event,
 };
 
 static struct net_device *dev_nr;
diff -Nru a/net/netsyms.c b/net/netsyms.c
--- a/net/netsyms.c	Sat Aug 10 18:42:22 2002
+++ b/net/netsyms.c	Sat Aug 10 18:42:22 2002
@@ -320,6 +320,7 @@
 EXPORT_SYMBOL(udp_connect);
 EXPORT_SYMBOL(udp_disconnect);
 EXPORT_SYMBOL(udp_sendmsg);
+EXPORT_SYMBOL(tcp_bind_hash);
 EXPORT_SYMBOL(tcp_close);
 EXPORT_SYMBOL(tcp_disconnect);
 EXPORT_SYMBOL(tcp_accept);
diff -Nru a/net/packet/af_packet.c b/net/packet/af_packet.c
--- a/net/packet/af_packet.c	Sat Aug 10 18:42:21 2002
+++ b/net/packet/af_packet.c	Sat Aug 10 18:42:21 2002
@@ -1609,8 +1609,8 @@
 }
 
 static struct vm_operations_struct packet_mmap_ops = {
-	open:	packet_mm_open,
-	close:	packet_mm_close,
+	.open =	packet_mm_open,
+	.close =packet_mm_close,
 };
 
 static void free_pg_vec(unsigned long *pg_vec, unsigned order, unsigned len)
@@ -1796,55 +1796,55 @@
 
 #ifdef CONFIG_SOCK_PACKET
 struct proto_ops packet_ops_spkt = {
-	family:		PF_PACKET,
+	.family =	PF_PACKET,
 
-	release:	packet_release,
-	bind:		packet_bind_spkt,
-	connect:	sock_no_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		sock_no_accept,
-	getname:	packet_getname_spkt,
-	poll:		datagram_poll,
-	ioctl:		packet_ioctl,
-	listen:		sock_no_listen,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	sock_no_setsockopt,
-	getsockopt:	sock_no_getsockopt,
-	sendmsg:	packet_sendmsg_spkt,
-	recvmsg:	packet_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	packet_release,
+	.bind =		packet_bind_spkt,
+	.connect =	sock_no_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	sock_no_accept,
+	.getname =	packet_getname_spkt,
+	.poll =		datagram_poll,
+	.ioctl =	packet_ioctl,
+	.listen =	sock_no_listen,
+	.shutdown =	sock_no_shutdown,
+	.setsockopt =	sock_no_setsockopt,
+	.getsockopt =	sock_no_getsockopt,
+	.sendmsg =	packet_sendmsg_spkt,
+	.recvmsg =	packet_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 #endif
 
 struct proto_ops packet_ops = {
-	family:		PF_PACKET,
+	.family =	PF_PACKET,
 
-	release:	packet_release,
-	bind:		packet_bind,
-	connect:	sock_no_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		sock_no_accept,
-	getname:	packet_getname, 
-	poll:		packet_poll,
-	ioctl:		packet_ioctl,
-	listen:		sock_no_listen,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	packet_setsockopt,
-	getsockopt:	packet_getsockopt,
-	sendmsg:	packet_sendmsg,
-	recvmsg:	packet_recvmsg,
-	mmap:		packet_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	packet_release,
+	.bind =		packet_bind,
+	.connect =	sock_no_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	sock_no_accept,
+	.getname =	packet_getname, 
+	.poll =		packet_poll,
+	.ioctl =	packet_ioctl,
+	.listen =	sock_no_listen,
+	.shutdown =	sock_no_shutdown,
+	.setsockopt =	packet_setsockopt,
+	.getsockopt =	packet_getsockopt,
+	.sendmsg =	packet_sendmsg,
+	.recvmsg =	packet_recvmsg,
+	.mmap =		packet_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 static struct net_proto_family packet_family_ops = {
-	family:		PF_PACKET,
-	create:		packet_create,
+	.family =	PF_PACKET,
+	.create =	packet_create,
 };
 
 static struct notifier_block packet_netdev_notifier = {
-	notifier_call:	packet_notifier,
+	.notifier_call =packet_notifier,
 };
 
 #ifdef CONFIG_PROC_FS
diff -Nru a/net/rose/af_rose.c b/net/rose/af_rose.c
--- a/net/rose/af_rose.c	Sat Aug 10 18:42:23 2002
+++ b/net/rose/af_rose.c	Sat Aug 10 18:42:23 2002
@@ -1430,36 +1430,36 @@
 } 
 
 static struct net_proto_family rose_family_ops = {
-	family:		PF_ROSE,
-	create:		rose_create,
+	.family =	PF_ROSE,
+	.create =	rose_create,
 };
 
 static struct proto_ops SOCKOPS_WRAPPED(rose_proto_ops) = {
-	family:		PF_ROSE,
+	.family =	PF_ROSE,
 
-	release:	rose_release,
-	bind:		rose_bind,
-	connect:	rose_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		rose_accept,
-	getname:	rose_getname,
-	poll:		datagram_poll,
-	ioctl:		rose_ioctl,
-	listen:		rose_listen,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	rose_setsockopt,
-	getsockopt:	rose_getsockopt,
-	sendmsg:	rose_sendmsg,
-	recvmsg:	rose_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	rose_release,
+	.bind =		rose_bind,
+	.connect =	rose_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	rose_accept,
+	.getname =	rose_getname,
+	.poll =		datagram_poll,
+	.ioctl =	rose_ioctl,
+	.listen =	rose_listen,
+	.shutdown =	sock_no_shutdown,
+	.setsockopt =	rose_setsockopt,
+	.getsockopt =	rose_getsockopt,
+	.sendmsg =	rose_sendmsg,
+	.recvmsg =	rose_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 #include <linux/smp_lock.h>
 SOCKOPS_WRAP(rose_proto, PF_ROSE);
 
 static struct notifier_block rose_dev_notifier = {
-	notifier_call:	rose_device_event,
+	.notifier_call =rose_device_event,
 };
 
 static struct net_device *dev_rose;
diff -Nru a/net/sched/Config.help b/net/sched/Config.help
--- a/net/sched/Config.help	Sat Aug 10 18:42:19 2002
+++ b/net/sched/Config.help	Sat Aug 10 18:42:19 2002
@@ -20,6 +20,20 @@
   whenever you want).  If you want to compile it as a module, say M
   here and read <file:Documentation/modules.txt>.
 
+CONFIG_NET_SCH_HTB
+  Say Y here if you want to use the Hierarchical Token Buckets (HTB)
+  packet scheduling algorithm for some of your network devices. See
+  URL http://luxik.cdi.cz/~devik/qos/htb/ for complete manual and
+  in-depth articles.
+
+  HTB is very similar to the CBQ regarding its goals however is has 
+  different properties and different algorithm.
+
+  This code is also available as a module called sch_htb.o ( = code
+  which can be inserted in and removed from the running kernel
+  whenever you want).  If you want to compile it as a module, say M
+  here and read <file:Documentation/modules.txt>.
+
 CONFIG_NET_SCH_CSZ
   Say Y here if you want to use the Clark-Shenker-Zhang (CSZ) packet
   scheduling algorithm for some of your network devices.  At the
diff -Nru a/net/sched/Config.in b/net/sched/Config.in
--- a/net/sched/Config.in	Sat Aug 10 18:42:20 2002
+++ b/net/sched/Config.in	Sat Aug 10 18:42:20 2002
@@ -2,6 +2,7 @@
 # Traffic control configuration.
 # 
 tristate '  CBQ packet scheduler' CONFIG_NET_SCH_CBQ
+tristate '  HTB packet scheduler' CONFIG_NET_SCH_HTB
 tristate '  CSZ packet scheduler' CONFIG_NET_SCH_CSZ
 #tristate '  H-PFQ packet scheduler' CONFIG_NET_SCH_HPFQ
 #tristate '  H-FSC packet scheduler' CONFIG_NET_SCH_HFCS
diff -Nru a/net/sched/Makefile b/net/sched/Makefile
--- a/net/sched/Makefile	Sat Aug 10 18:42:23 2002
+++ b/net/sched/Makefile	Sat Aug 10 18:42:23 2002
@@ -13,6 +13,7 @@
 obj-$(CONFIG_NET_SCH_CSZ)	+= sch_csz.o
 obj-$(CONFIG_NET_SCH_HPFQ)	+= sch_hpfq.o
 obj-$(CONFIG_NET_SCH_HFSC)	+= sch_hfsc.o
+obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o
 obj-$(CONFIG_NET_SCH_SFQ)	+= sch_sfq.o
 obj-$(CONFIG_NET_SCH_RED)	+= sch_red.o
 obj-$(CONFIG_NET_SCH_TBF)	+= sch_tbf.o
diff -Nru a/net/sched/sch_api.c b/net/sched/sch_api.c
--- a/net/sched/sch_api.c	Sat Aug 10 18:42:22 2002
+++ b/net/sched/sch_api.c	Sat Aug 10 18:42:22 2002
@@ -1205,6 +1205,9 @@
 #ifdef CONFIG_NET_SCH_CBQ
 	INIT_QDISC(cbq);
 #endif
+#ifdef CONFIG_NET_SCH_HTB
+	INIT_QDISC(htb);
+#endif
 #ifdef CONFIG_NET_SCH_CSZ
 	INIT_QDISC(csz);
 #endif
diff -Nru a/net/sched/sch_htb.c b/net/sched/sch_htb.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/net/sched/sch_htb.c	Sat Aug 10 18:42:24 2002
@@ -0,0 +1,1648 @@
+/* vim: ts=8 sw=8
+ * net/sched/sch_htb.c	Hierarchical token bucket, feed tree version
+ *
+ *		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.
+ *
+ * Authors:	Martin Devera, <devik@cdi.cz>
+ *
+ * Credits (in time order) for older HTB versions:
+ *		Ondrej Kraus, <krauso@barr.cz> 
+ *			found missing INIT_QDISC(htb)
+ *		Vladimir Smelhaus, Aamer Akhter, Bert Hubert
+ *			helped a lot to locate nasty class stall bug
+ *		Andi Kleen, Jamal Hadi, Bert Hubert
+ *			code review and helpful comments on shaping
+ *		and many others. thanks.
+ *
+ * $Id: sch_htb.c,v 1.13 2002/05/25 09:04:50 devik Exp $
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/in.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/notifier.h>
+#include <net/ip.h>
+#include <net/route.h>
+#include <linux/skbuff.h>
+#include <linux/list.h>
+#include <linux/compiler.h>
+#include <net/sock.h>
+#include <net/pkt_sched.h>
+#include <linux/rbtree.h>
+
+/* HTB algorithm.
+    Author: devik@cdi.cz
+    ========================================================================
+    HTB is like TBF with multiple classes. It is also similar to CBQ because
+    it allows to assign priority to each class in hierarchy. 
+    In fact it is another implementation of Floyd's formal sharing.
+
+    Levels:
+    Each class is assigned level. Leaf has ALWAYS level 0 and root 
+    classes have level TC_HTB_MAXDEPTH-1. Interior nodes has level
+    one less than their parent.
+*/
+
+#define HTB_HSIZE 16	/* classid hash size */
+#define HTB_EWMAC 2	/* rate average over HTB_EWMAC*HTB_HSIZE sec */
+#define HTB_DEBUG 1	/* compile debugging support (activated by tc tool) */
+#define HTB_RATECM 1    /* whether to use rate computer */
+#define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */
+#define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
+#define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock)
+#define HTB_VER 0x30006	/* major must be matched with number suplied by TC as version */
+
+#if HTB_VER >> 16 != TC_HTB_PROTOVER
+#error "Mismatched sch_htb.c and pkt_sch.h"
+#endif
+
+/* temporary debug defines to be removed after beta stage */
+#define DEVIK_MEND(N)
+#define DEVIK_MSTART(N)
+
+/* debugging support; S is subsystem, these are defined:
+  0 - netlink messages
+  1 - enqueue
+  2 - drop & requeue
+  3 - dequeue main
+  4 - dequeue one prio DRR part
+  5 - dequeue class accounting
+  6 - class overlimit status computation
+  7 - hint tree
+  8 - event queue
+ 10 - rate estimator
+ 11 - classifier 
+ 12 - fast dequeue cache
+
+ L is level; 0 = none, 1 = basic info, 2 = detailed, 3 = full
+ q->debug uint32 contains 16 2-bit fields one for subsystem starting
+ from LSB
+ */
+#ifdef HTB_DEBUG
+#define HTB_DBG(S,L,FMT,ARG...) if (((q->debug>>(2*S))&3) >= L) \
+	printk(KERN_DEBUG FMT,##ARG)
+#define HTB_CHCL(cl) BUG_TRAP((cl)->magic == HTB_CMAGIC)
+#define HTB_PASSQ q,
+#define HTB_ARGQ struct htb_sched *q,
+#define static
+#define __inline__
+#define inline
+#define HTB_CMAGIC 0xFEFAFEF1
+#define htb_safe_rb_erase(N,R) do { BUG_TRAP((N)->rb_color != -1); \
+		if ((N)->rb_color == -1) break; \
+		rb_erase(N,R); \
+		(N)->rb_color = -1; } while (0)
+#else
+#define HTB_DBG(S,L,FMT,ARG...)
+#define HTB_PASSQ
+#define HTB_ARGQ
+#define HTB_CHCL(cl)
+#define htb_safe_rb_erase(N,R) rb_erase(N,R)
+#endif
+
+
+/* used internaly to keep status of single class */
+enum htb_cmode {
+    HTB_CANT_SEND,		/* class can't send and can't borrow */
+    HTB_MAY_BORROW,		/* class can't send but may borrow */
+    HTB_CAN_SEND		/* class can send */
+};
+
+/* interior & leaf nodes; props specific to leaves are marked L: */
+struct htb_class
+{
+#ifdef HTB_DEBUG
+	unsigned magic;
+#endif
+    /* general class parameters */
+    u32 classid;
+    struct tc_stats	stats;	/* generic stats */
+    struct tc_htb_xstats xstats;/* our special stats */
+    int refcnt;			/* usage count of this class */
+
+#ifdef HTB_RATECM
+    /* rate measurement counters */
+    unsigned long rate_bytes,sum_bytes;
+    unsigned long rate_packets,sum_packets;
+#endif
+
+    /* topology */
+    int level;			/* our level (see above) */
+    struct htb_class *parent;	/* parent class */
+    struct list_head hlist;	/* classid hash list item */
+    struct list_head sibling;	/* sibling list item */
+    struct list_head children;	/* children list */
+
+    union {
+	    struct htb_class_leaf {
+		    struct Qdisc *q;
+		    int prio;
+		    int aprio;	
+		    int quantum;
+		    int deficit[TC_HTB_MAXDEPTH];
+		    struct list_head drop_list;
+	    } leaf;
+	    struct htb_class_inner {
+		    rb_root_t feed[TC_HTB_NUMPRIO];	/* feed trees */
+		    rb_node_t *ptr[TC_HTB_NUMPRIO];	/* current class ptr */
+	    } inner;
+    } un;
+    rb_node_t node[TC_HTB_NUMPRIO];	/* node for self or feed tree */
+    rb_node_t pq_node;			/* node for event queue */
+    unsigned long pq_key;	/* the same type as jiffies global */
+    
+    int prio_activity;		/* for which prios are we active */
+    enum htb_cmode cmode;	/* current mode of the class */
+
+    /* class attached filters */
+    struct tcf_proto *filter_list;
+    int filter_cnt;
+
+    int warned;		/* only one warning about non work conserving .. */
+
+    /* token bucket parameters */
+    struct qdisc_rate_table *rate;	/* rate table of the class itself */
+    struct qdisc_rate_table *ceil;	/* ceiling rate (limits borrows too) */
+    long buffer,cbuffer;		/* token bucket depth/rate */
+    long mbuffer;			/* max wait time */
+    long tokens,ctokens;		/* current number of tokens */
+    psched_time_t t_c;			/* checkpoint time */
+};
+
+/* TODO: maybe compute rate when size is too large .. or drop ? */
+static __inline__ long L2T(struct htb_class *cl,struct qdisc_rate_table *rate,
+	int size)
+{ 
+    int slot = size >> rate->rate.cell_log;
+    if (slot > 255) {
+	cl->xstats.giants++;
+	slot = 255;
+    }
+    return rate->data[slot];
+}
+
+struct htb_sched
+{
+    struct list_head root;			/* root classes list */
+    struct list_head hash[HTB_HSIZE];		/* hashed by classid */
+    struct list_head drops[TC_HTB_NUMPRIO];	/* active leaves (for drops) */
+    
+    /* self list - roots of self generating tree */
+    rb_root_t row[TC_HTB_MAXDEPTH][TC_HTB_NUMPRIO];
+    int row_mask[TC_HTB_MAXDEPTH];
+    rb_node_t *ptr[TC_HTB_MAXDEPTH][TC_HTB_NUMPRIO];
+
+    /* self wait list - roots of wait PQs per row */
+    rb_root_t wait_pq[TC_HTB_MAXDEPTH];
+
+    /* time of nearest event per level (row) */
+    unsigned long near_ev_cache[TC_HTB_MAXDEPTH];
+
+    /* whether we hit non-work conserving class during this dequeue; we use */
+    int nwc_hit;	/* this to disable mindelay complaint in dequeue */
+
+    int defcls;		/* class where unclassified flows go to */
+    u32 debug;		/* subsystem debug levels */
+
+    /* filters for qdisc itself */
+    struct tcf_proto *filter_list;
+    int filter_cnt;
+
+    int rate2quantum;		/* quant = rate / rate2quantum */
+    psched_time_t now;		/* cached dequeue time */
+    struct timer_list timer;	/* send delay timer */
+#ifdef HTB_RATECM
+    struct timer_list rttim;	/* rate computer timer */
+    int recmp_bucket;		/* which hash bucket to recompute next */
+#endif
+    
+    /* non shaped skbs; let them go directly thru */
+    struct sk_buff_head direct_queue;
+    int direct_qlen;  /* max qlen of above */
+
+    long direct_pkts;
+};
+
+/* compute hash of size HTB_HSIZE for given handle */
+static __inline__ int htb_hash(u32 h) 
+{
+#if HTB_HSIZE != 16
+ #error "Declare new hash for your HTB_HSIZE"
+#endif
+    h ^= h>>8;	/* stolen from cbq_hash */
+    h ^= h>>4;
+    return h & 0xf;
+}
+
+/* find class in global hash table using given handle */
+static __inline__ struct htb_class *htb_find(u32 handle, struct Qdisc *sch)
+{
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	struct list_head *p;
+	if (TC_H_MAJ(handle) != sch->handle) 
+		return NULL;
+	
+	list_for_each (p,q->hash+htb_hash(handle)) {
+		struct htb_class *cl = list_entry(p,struct htb_class,hlist);
+		if (cl->classid == handle)
+			return cl;
+	}
+	return NULL;
+}
+
+/**
+ * htb_classify - classify a packet into class
+ *
+ * It returns NULL if the packet should be dropped or -1 if the packet
+ * should be passed directly thru. In all other cases leaf class is returned.
+ * We allow direct class selection by classid in priority. The we examine
+ * filters in qdisc and in inner nodes (if higher filter points to the inner
+ * node). If we end up with classid MAJOR:0 we enqueue the skb into special
+ * internal fifo (direct). These packets then go directly thru. If we still 
+ * have no valid leaf we try to use MAJOR:default leaf. It still unsuccessfull
+ * then finish and return direct queue.
+ */
+#define HTB_DIRECT (struct htb_class*)-1
+static struct htb_class *htb_classify(struct sk_buff *skb, struct Qdisc *sch)
+{
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	struct htb_class *cl;
+	struct tcf_result res;
+	struct tcf_proto *tcf;
+	int result;
+
+	/* allow to select class by setting skb->priority to valid classid;
+	   note that nfmark can be used too by attaching filter fw with no
+	   rules in it */
+	if (skb->priority == sch->handle)
+		return HTB_DIRECT;  /* X:0 (direct flow) selected */
+	if ((cl = htb_find(skb->priority,sch)) != NULL) 
+		return cl;
+
+	tcf = q->filter_list;
+	while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
+#ifdef CONFIG_NET_CLS_POLICE
+		if (result == TC_POLICE_SHOT)
+			return NULL;
+#endif
+		if ((cl = (void*)res.class) == NULL) {
+			if (res.classid == sch->handle)
+				return HTB_DIRECT;  /* X:0 (direct flow) */
+			if ((cl = htb_find(res.classid,sch)) == NULL)
+				break; /* filter selected invalid classid */
+		}
+		if (!cl->level)
+			return cl; /* we hit leaf; return it */
+
+		/* we have got inner class; apply inner filter chain */
+		tcf = cl->filter_list;
+	}
+	/* classification failed; try to use default class */
+	cl = htb_find(TC_H_MAKE(TC_H_MAJ(sch->handle),q->defcls),sch);
+	if (!cl || cl->level)
+		return HTB_DIRECT; /* bad default .. this is safe bet */
+	return cl;
+}
+
+#ifdef HTB_DEBUG
+static void htb_next_rb_node(rb_node_t **n);
+#define HTB_DUMTREE(root,memb) if(root) { \
+	rb_node_t *n = (root)->rb_node; \
+	while (n->rb_left) n = n->rb_left; \
+	while (n) { \
+		struct htb_class *cl = rb_entry(n, struct htb_class, memb); \
+		printk(" %x",cl->classid); htb_next_rb_node (&n); \
+	} }
+
+static void htb_debug_dump (struct htb_sched *q)
+{
+	int i,p;
+	printk(KERN_DEBUG "htb*g j=%lu\n",jiffies);
+	/* rows */
+	for (i=TC_HTB_MAXDEPTH-1;i>=0;i--) {
+		printk(KERN_DEBUG "htb*r%d m=%x",i,q->row_mask[i]);
+		for (p=0;p<TC_HTB_NUMPRIO;p++) {
+			if (!q->row[i][p].rb_node) continue;
+			printk(" p%d:",p);
+			HTB_DUMTREE(q->row[i]+p,node[p]);
+		}
+		printk("\n");
+	}
+	/* classes */
+	for (i = 0; i < HTB_HSIZE; i++) {
+		struct list_head *l;
+		list_for_each (l,q->hash+i) {
+			struct htb_class *cl = list_entry(l,struct htb_class,hlist);
+			long diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32)cl->mbuffer, 0);
+			printk(KERN_DEBUG "htb*c%x m=%d t=%ld c=%ld pq=%lu df=%ld ql=%d "
+					"pa=%x f:",
+				cl->classid,cl->cmode,cl->tokens,cl->ctokens,
+				cl->pq_node.rb_color==-1?0:cl->pq_key,diff,
+				cl->level?0:cl->un.leaf.q->q.qlen,cl->prio_activity);
+			if (cl->level)
+			for (p=0;p<TC_HTB_NUMPRIO;p++) {
+				if (!cl->un.inner.feed[p].rb_node) continue;
+				printk(" p%d a=%x:",p,cl->un.inner.ptr[p]?rb_entry(cl->un.inner.ptr[p], struct htb_class,node[p])->classid:0);
+				HTB_DUMTREE(cl->un.inner.feed+p,node[p]);
+			}
+			printk("\n");
+		}
+	}
+}
+#endif
+/**
+ * htb_add_to_id_tree - adds class to the round robin list
+ *
+ * Routine adds class to the list (actually tree) sorted by classid.
+ * Make sure that class is not already on such list for given prio.
+ */
+static void htb_add_to_id_tree (HTB_ARGQ rb_root_t *root,
+		struct htb_class *cl,int prio)
+{
+	rb_node_t **p = &root->rb_node, *parent = NULL;
+	HTB_DBG(7,3,"htb_add_id_tree cl=%X prio=%d\n",cl->classid,prio);
+#ifdef HTB_DEBUG
+	if (cl->node[prio].rb_color != -1) { BUG_TRAP(0); return; }
+	HTB_CHCL(cl);
+	if (*p) {
+		struct htb_class *x = rb_entry(*p,struct htb_class,node[prio]);
+		HTB_CHCL(x);
+	}
+#endif
+	while (*p) {
+		struct htb_class *c; parent = *p;
+		c = rb_entry(parent, struct htb_class, node[prio]);
+		HTB_CHCL(c);
+		if (cl->classid > c->classid)
+			p = &parent->rb_right;
+		else 
+			p = &parent->rb_left;
+	}
+	rb_link_node(&cl->node[prio], parent, p);
+	rb_insert_color(&cl->node[prio], root);
+}
+
+/**
+ * htb_add_to_wait_tree - adds class to the event queue with delay
+ *
+ * The class is added to priority event queue to indicate that class will
+ * change its mode in cl->pq_key microseconds. Make sure that class is not
+ * already in the queue.
+ */
+static void htb_add_to_wait_tree (struct htb_sched *q,
+		struct htb_class *cl,long delay,int debug_hint)
+{
+	rb_node_t **p = &q->wait_pq[cl->level].rb_node, *parent = NULL;
+	HTB_DBG(7,3,"htb_add_wt cl=%X key=%lu\n",cl->classid,cl->pq_key);
+#ifdef HTB_DEBUG
+	if (cl->pq_node.rb_color != -1) { BUG_TRAP(0); return; }
+	HTB_CHCL(cl);
+	if ((delay <= 0 || delay > cl->mbuffer) && net_ratelimit())
+		printk(KERN_ERR "HTB: suspicious delay in wait_tree d=%ld cl=%X h=%d\n",delay,cl->classid,debug_hint);
+#endif
+	DEVIK_MSTART(9);
+	cl->pq_key = jiffies + PSCHED_US2JIFFIE(delay);
+	if (cl->pq_key == jiffies)
+		cl->pq_key++;
+
+	/* update the nearest event cache */
+	if (q->near_ev_cache[cl->level] - cl->pq_key < 0x80000000)
+		q->near_ev_cache[cl->level] = cl->pq_key;
+	
+	while (*p) {
+		struct htb_class *c; parent = *p;
+		c = rb_entry(parent, struct htb_class, pq_node);
+		if (cl->pq_key - c->pq_key < 0x80000000)
+			p = &parent->rb_right;
+		else 
+			p = &parent->rb_left;
+	}
+	rb_link_node(&cl->pq_node, parent, p);
+	rb_insert_color(&cl->pq_node, &q->wait_pq[cl->level]);
+	DEVIK_MEND(9);
+}
+
+/**
+ * htb_next_rb_node - finds next node in binary tree
+ *
+ * When we are past last key we return NULL.
+ * Average complexity is 2 steps per call.
+ */
+static void htb_next_rb_node(rb_node_t **n)
+{
+	rb_node_t *p;
+	if ((*n)->rb_right) {
+		*n = (*n)->rb_right;
+		while ((*n)->rb_left) 
+			*n = (*n)->rb_left;
+		return;
+	}
+	while ((p = (*n)->rb_parent) != NULL) {
+		if (p->rb_left == *n) break;
+		*n = p;
+	}
+	*n = p;
+}
+
+/**
+ * htb_add_class_to_row - add class to its row
+ *
+ * The class is added to row at priorities marked in mask.
+ * It does nothing if mask == 0.
+ */
+static inline void htb_add_class_to_row(struct htb_sched *q, 
+		struct htb_class *cl,int mask)
+{
+	HTB_DBG(7,2,"htb_addrow cl=%X mask=%X rmask=%X\n",
+			cl->classid,mask,q->row_mask[cl->level]);
+	HTB_CHCL(cl);
+	q->row_mask[cl->level] |= mask;
+	while (mask) {
+		int prio = ffz(~mask);
+		mask &= ~(1 << prio);
+		htb_add_to_id_tree(HTB_PASSQ q->row[cl->level]+prio,cl,prio);
+	}
+}
+
+/**
+ * htb_remove_class_from_row - removes class from its row
+ *
+ * The class is removed from row at priorities marked in mask.
+ * It does nothing if mask == 0.
+ */
+static __inline__ void htb_remove_class_from_row(struct htb_sched *q,
+		struct htb_class *cl,int mask)
+{
+	int m = 0;
+	HTB_CHCL(cl);
+	while (mask) {
+		int prio = ffz(~mask);
+		mask &= ~(1 << prio);
+		if (q->ptr[cl->level][prio] == cl->node+prio)
+			htb_next_rb_node(q->ptr[cl->level]+prio);
+		htb_safe_rb_erase(cl->node + prio,q->row[cl->level]+prio);
+		if (!q->row[cl->level][prio].rb_node) 
+			m |= 1 << prio;
+	}
+	HTB_DBG(7,2,"htb_delrow cl=%X mask=%X rmask=%X maskdel=%X\n",
+			cl->classid,mask,q->row_mask[cl->level],m);
+	q->row_mask[cl->level] &= ~m;
+}
+
+/**
+ * htb_activate_prios - creates active classe's feed chain
+ *
+ * The class is connected to ancestors and/or appropriate rows
+ * for priorities it is participating on. cl->cmode must be new 
+ * (activated) mode. It does nothing if cl->prio_activity == 0.
+ */
+static void htb_activate_prios(struct htb_sched *q,struct htb_class *cl)
+{
+	struct htb_class *p = cl->parent;
+	long m,mask = cl->prio_activity;
+	HTB_DBG(7,2,"htb_act_prios cl=%X mask=%lX cmode=%d\n",cl->classid,mask,cl->cmode);
+	HTB_CHCL(cl);
+
+	while (cl->cmode == HTB_MAY_BORROW && p && mask) {
+		HTB_CHCL(p);
+		m = mask; while (m) {
+			int prio = ffz(~m);
+			m &= ~(1 << prio);
+			
+			if (p->un.inner.feed[prio].rb_node)
+				/* parent already has its feed in use so that
+				   reset bit in mask as parent is already ok */
+				mask &= ~(1 << prio);
+			
+			htb_add_to_id_tree(HTB_PASSQ p->un.inner.feed+prio,cl,prio);
+		}
+		HTB_DBG(7,3,"htb_act_pr_aft p=%X pact=%X mask=%lX pmode=%d\n",
+				p->classid,p->prio_activity,mask,p->cmode);
+		p->prio_activity |= mask;
+		cl = p; p = cl->parent;
+		HTB_CHCL(cl);
+	}
+	if (cl->cmode == HTB_CAN_SEND && mask)
+		htb_add_class_to_row(q,cl,mask);
+}
+
+/**
+ * htb_deactivate_prios - remove class from feed chain
+ *
+ * cl->cmode must represent old mode (before deactivation). It does 
+ * nothing if cl->prio_activity == 0. Class is removed from all feed
+ * chains and rows.
+ */
+static void htb_deactivate_prios(struct htb_sched *q, struct htb_class *cl)
+{
+	struct htb_class *p = cl->parent;
+	long m,mask = cl->prio_activity;
+	HTB_DBG(7,2,"htb_deact_prios cl=%X mask=%lX cmode=%d\n",cl->classid,mask,cl->cmode);
+	HTB_CHCL(cl);
+
+	while (cl->cmode == HTB_MAY_BORROW && p && mask) {
+		m = mask; mask = 0; 
+		while (m) {
+			int prio = ffz(~m);
+			m &= ~(1 << prio);
+			
+			if (p->un.inner.ptr[prio] == cl->node+prio)
+				htb_next_rb_node(p->un.inner.ptr + prio);
+			
+			htb_safe_rb_erase(cl->node + prio,p->un.inner.feed + prio);
+			
+			if (!p->un.inner.feed[prio].rb_node) 
+				mask |= 1 << prio;
+		}
+		HTB_DBG(7,3,"htb_deact_pr_aft p=%X pact=%X mask=%lX pmode=%d\n",
+				p->classid,p->prio_activity,mask,p->cmode);
+		p->prio_activity &= ~mask;
+		cl = p; p = cl->parent;
+		HTB_CHCL(cl);
+	}
+	if (cl->cmode == HTB_CAN_SEND && mask) 
+		htb_remove_class_from_row(q,cl,mask);
+}
+
+/**
+ * htb_class_mode - computes and returns current class mode
+ *
+ * It computes cl's mode at time cl->t_c+diff and returns it. If mode
+ * is not HTB_CAN_SEND then cl->pq_key is updated to time difference
+ * from now to time when cl will change its state. 
+ * Also it is worth to note that class mode doesn't change simply
+ * at cl->{c,}tokens == 0 but there can rather be hysteresis of 
+ * 0 .. -cl->{c,}buffer range. It is meant to limit number of
+ * mode transitions per time unit. The speed gain is about 1/6.
+ */
+static __inline__ enum htb_cmode 
+htb_class_mode(struct htb_class *cl,long *diff)
+{
+    long toks;
+
+    if ((toks = (cl->ctokens + *diff)) < (
+#ifdef HTB_HYSTERESIS
+	    cl->cmode != HTB_CANT_SEND ? -cl->cbuffer :
+#endif
+       	    0)) {
+	    *diff = -toks;
+	    return HTB_CANT_SEND;
+    }
+    if ((toks = (cl->tokens + *diff)) >= (
+#ifdef HTB_HYSTERESIS
+	    cl->cmode == HTB_CAN_SEND ? -cl->buffer :
+#endif
+	    0))
+	    return HTB_CAN_SEND;
+
+    *diff = -toks;
+    return HTB_MAY_BORROW;
+}
+
+/**
+ * htb_change_class_mode - changes classe's mode
+ *
+ * This should be the only way how to change classe's mode under normal
+ * cirsumstances. Routine will update feed lists linkage, change mode
+ * and add class to the wait event queue if appropriate. New mode should
+ * be different from old one and cl->pq_key has to be valid if changing
+ * to mode other than HTB_CAN_SEND (see htb_add_to_wait_tree).
+ */
+static void 
+htb_change_class_mode(struct htb_sched *q, struct htb_class *cl, long *diff)
+{ 
+	enum htb_cmode new_mode = htb_class_mode(cl,diff);
+	
+	HTB_CHCL(cl);
+	HTB_DBG(7,1,"htb_chging_clmode %d->%d cl=%X\n",cl->cmode,new_mode,cl->classid);
+
+	if (new_mode == cl->cmode)
+		return;	
+	
+	if (cl->prio_activity) { /* not neccessary: speed optimization */
+		if (cl->cmode != HTB_CANT_SEND) 
+			htb_deactivate_prios(q,cl);
+		cl->cmode = new_mode;
+		if (new_mode != HTB_CANT_SEND) 
+			htb_activate_prios(q,cl);
+	} else 
+		cl->cmode = new_mode;
+}
+
+/**
+ * htb_activate - inserts leaf cl into appropriate active feeds 
+ *
+ * Routine learns (new) priority of leaf and activates feed chain
+ * for the prio. It can be called on already active leaf safely.
+ * It also adds leaf into droplist.
+ */
+static __inline__ void htb_activate(struct htb_sched *q,struct htb_class *cl)
+{
+	BUG_TRAP(!cl->level && cl->un.leaf.q && cl->un.leaf.q->q.qlen);
+	HTB_CHCL(cl);
+	if (!cl->prio_activity) {
+		cl->prio_activity = 1 << (cl->un.leaf.aprio = cl->un.leaf.prio);
+		htb_activate_prios(q,cl);
+		list_add_tail(&cl->un.leaf.drop_list,q->drops+cl->un.leaf.aprio);
+	}
+}
+
+/**
+ * htb_deactivate - remove leaf cl from active feeds 
+ *
+ * Make sure that leaf is active. In the other words it can't be called
+ * with non-active leaf. It also removes class from the drop list.
+ */
+static __inline__ void 
+htb_deactivate(struct htb_sched *q,struct htb_class *cl)
+{
+	BUG_TRAP(cl->prio_activity);
+	HTB_CHCL(cl);
+	htb_deactivate_prios(q,cl);
+	cl->prio_activity = 0;
+	list_del_init(&cl->un.leaf.drop_list);
+}
+
+static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+{
+    struct htb_sched *q = (struct htb_sched *)sch->data;
+    struct htb_class *cl = htb_classify(skb,sch);
+
+    DEVIK_MSTART(0);
+    if (cl == HTB_DIRECT || !cl) {
+	/* enqueue to helper queue */
+	if (q->direct_queue.qlen < q->direct_qlen && cl) {
+	    __skb_queue_tail(&q->direct_queue, skb);
+	    q->direct_pkts++;
+	} else {
+	    kfree_skb (skb);
+	    sch->stats.drops++;
+	    DEVIK_MEND(0);
+	    return NET_XMIT_DROP;
+	}
+    } else if (cl->un.leaf.q->enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) {
+	sch->stats.drops++;
+	cl->stats.drops++;
+	DEVIK_MEND(0);
+	return NET_XMIT_DROP;
+    } else {
+	cl->stats.packets++; cl->stats.bytes += skb->len;
+	DEVIK_MSTART(1);
+	htb_activate (q,cl);
+	DEVIK_MEND(1);
+    }
+
+    sch->q.qlen++;
+    sch->stats.packets++; sch->stats.bytes += skb->len;
+    HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",cl?cl->classid:0,skb);
+    DEVIK_MEND(0);
+    return NET_XMIT_SUCCESS;
+}
+
+/* TODO: requeuing packet charges it to policers again !! */
+static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
+{
+    struct htb_sched *q = (struct htb_sched *)sch->data;
+    struct htb_class *cl = htb_classify(skb,sch);
+
+    if (cl == HTB_DIRECT || !cl) {
+	/* enqueue to helper queue */
+	if (q->direct_queue.qlen < q->direct_qlen && cl) {
+	    __skb_queue_tail(&q->direct_queue, skb);
+	    q->direct_pkts++;
+	} else {
+	    kfree_skb (skb);
+	    sch->stats.drops++;
+	    return NET_XMIT_DROP;
+	}
+    } else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) {
+	sch->stats.drops++;
+	cl->stats.drops++;
+	return NET_XMIT_DROP;
+    } else 
+	    htb_activate (q,cl);
+
+    sch->q.qlen++;
+    HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",cl?cl->classid:0,skb);
+    return NET_XMIT_SUCCESS;
+}
+
+static void htb_timer(unsigned long arg)
+{
+    struct Qdisc *sch = (struct Qdisc*)arg;
+    sch->flags &= ~TCQ_F_THROTTLED;
+    wmb();
+    netif_schedule(sch->dev);
+}
+
+#ifdef HTB_RATECM
+#define RT_GEN(D,R) R+=D-(R/HTB_EWMAC);D=0
+static void htb_rate_timer(unsigned long arg)
+{
+	struct Qdisc *sch = (struct Qdisc*)arg;
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	struct list_head *p;
+
+	/* lock queue so that we can muck with it */
+	HTB_QLOCK(sch);
+	HTB_DBG(10,1,"htb_rttmr j=%ld\n",jiffies);
+
+	q->rttim.expires = jiffies + HZ;
+	add_timer(&q->rttim);
+
+	/* scan and recompute one bucket at time */
+	if (++q->recmp_bucket >= HTB_HSIZE) 
+		q->recmp_bucket = 0;
+	list_for_each (p,q->hash+q->recmp_bucket) {
+		struct htb_class *cl = list_entry(p,struct htb_class,hlist);
+		HTB_DBG(10,2,"htb_rttmr_cl cl=%X sbyte=%lu spkt=%lu\n",
+				cl->classid,cl->sum_bytes,cl->sum_packets);
+		RT_GEN (cl->sum_bytes,cl->rate_bytes);
+		RT_GEN (cl->sum_packets,cl->rate_packets);
+	}
+	HTB_QUNLOCK(sch);
+}
+#endif
+
+/**
+ * htb_charge_class - charges ammount "bytes" to leaf and ancestors
+ *
+ * Routine assumes that packet "bytes" long was dequeued from leaf cl
+ * borrowing from "level". It accounts bytes to ceil leaky bucket for
+ * leaf and all ancestors and to rate bucket for ancestors at levels
+ * "level" and higher. It also handles possible change of mode resulting
+ * from the update. Note that mode can also increase here (MAY_BORROW to
+ * CAN_SEND) because we can use more precise clock that event queue here.
+ * In such case we remove class from event queue first.
+ */
+static void htb_charge_class(struct htb_sched *q,struct htb_class *cl,
+		int level,int bytes)
+{	
+	long toks,diff;
+	enum htb_cmode old_mode;
+	HTB_DBG(5,1,"htb_chrg_cl cl=%X lev=%d len=%d\n",cl->classid,level,bytes);
+
+#define HTB_ACCNT(T,B,R) toks = diff + cl->T; \
+	if (toks > cl->B) toks = cl->B; \
+	toks -= L2T(cl, cl->R, bytes); \
+	if (toks <= -cl->mbuffer) toks = 1-cl->mbuffer; \
+	cl->T = toks
+
+	while (cl) {
+		HTB_CHCL(cl);
+		diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32)cl->mbuffer, 0);
+#ifdef HTB_DEBUG
+		if (diff > cl->mbuffer || diff < 0 || PSCHED_TLESS(q->now, cl->t_c)) {
+			if (net_ratelimit())
+				printk(KERN_ERR "HTB: bad diff in charge, cl=%X diff=%lX now=%Lu then=%Lu j=%lu\n",
+				       cl->classid, diff,
+				       (unsigned long long) q->now,
+				       (unsigned long long) cl->t_c,
+				       jiffies);
+			diff = 1000;
+		}
+#endif
+		if (cl->level >= level) {
+			if (cl->level == level) cl->xstats.lends++;
+			HTB_ACCNT (tokens,buffer,rate);
+		} else {
+			cl->xstats.borrows++;
+			cl->tokens += diff; /* we moved t_c; update tokens */
+		}
+		HTB_ACCNT (ctokens,cbuffer,ceil);
+		cl->t_c = q->now;
+		HTB_DBG(5,2,"htb_chrg_clp cl=%X diff=%ld tok=%ld ctok=%ld\n",cl->classid,diff,cl->tokens,cl->ctokens);
+
+		old_mode = cl->cmode; diff = 0;
+		htb_change_class_mode(q,cl,&diff);
+		if (old_mode != cl->cmode) {
+			if (old_mode != HTB_CAN_SEND)
+				htb_safe_rb_erase(&cl->pq_node,q->wait_pq+cl->level);
+			if (cl->cmode != HTB_CAN_SEND)
+				htb_add_to_wait_tree (q,cl,diff,1);
+		}
+		
+#ifdef HTB_RATECM
+		/* update rate counters */
+		cl->sum_bytes += bytes; cl->sum_packets++;
+#endif
+
+		/* update byte stats except for leaves which are already updated */
+		if (cl->level) {
+			cl->stats.bytes += bytes;
+			cl->stats.packets++;
+		}
+		cl = cl->parent;
+	}
+}
+
+/**
+ * htb_do_events - make mode changes to classes at the level
+ *
+ * Scans event queue for pending events and applies them. Returns jiffies to
+ * next pending event (0 for no event in pq).
+ */
+static long htb_do_events(struct htb_sched *q,int level)
+{
+	int i;
+	HTB_DBG(8,1,"htb_do_events l=%d root=%p rmask=%X\n",
+			level,q->wait_pq[level].rb_node,q->row_mask[level]);
+	for (i = 0; i < 500; i++) {
+		struct htb_class *cl;
+		long diff;
+		rb_node_t *p = q->wait_pq[level].rb_node;
+		if (!p) return 0;
+		while (p->rb_left) p = p->rb_left;
+
+		cl = rb_entry(p, struct htb_class, pq_node);
+		if (cl->pq_key - (jiffies+1) < 0x80000000) {
+			HTB_DBG(8,3,"htb_do_ev_ret delay=%ld\n",cl->pq_key - jiffies);
+			return cl->pq_key - jiffies;
+		}
+		htb_safe_rb_erase(p,q->wait_pq+level);
+		diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32)cl->mbuffer, 0);
+#ifdef HTB_DEBUG
+		if (diff > cl->mbuffer || diff < 0 || PSCHED_TLESS(q->now, cl->t_c)) {
+			if (net_ratelimit())
+				printk(KERN_ERR "HTB: bad diff in events, cl=%X diff=%lX now=%Lu then=%Lu j=%lu\n",
+				       cl->classid, diff,
+				       (unsigned long long) q->now,
+				       (unsigned long long) cl->t_c,
+				       jiffies);
+			diff = 1000;
+		}
+#endif
+		htb_change_class_mode(q,cl,&diff);
+		if (cl->cmode != HTB_CAN_SEND)
+			htb_add_to_wait_tree (q,cl,diff,2);
+	}
+	if (net_ratelimit())
+		printk(KERN_WARNING "htb: too many events !\n");
+	return HZ/10;
+}
+
+/**
+ * htb_lookup_leaf - returns next leaf class in DRR order
+ *
+ * Find leaf where current feed pointers points to.
+ */
+static struct htb_class *
+htb_lookup_leaf(rb_root_t *tree,int prio,rb_node_t **pptr)
+{
+	int i;
+	struct {
+		rb_node_t *root;
+		rb_node_t **pptr;
+	} stk[TC_HTB_MAXDEPTH],*sp = stk;
+	
+	sp->root = tree->rb_node;
+	sp->pptr = pptr;
+
+	for (i = 0; i < 65535; i++) {
+		if (!*sp->pptr) { /* we are at right end; rewind & go up */
+			*sp->pptr = sp->root;
+			while ((*sp->pptr)->rb_left) 
+				*sp->pptr = (*sp->pptr)->rb_left;
+			if (sp > stk) {
+				sp--;
+				BUG_TRAP(*sp->pptr); if(!*sp->pptr) return NULL;
+				htb_next_rb_node (sp->pptr);
+			}
+		} else {
+			struct htb_class *cl;
+			cl = rb_entry(*sp->pptr,struct htb_class,node[prio]);
+			HTB_CHCL(cl);
+			if (!cl->level) 
+				return cl;
+			(++sp)->root = cl->un.inner.feed[prio].rb_node;
+			sp->pptr = cl->un.inner.ptr+prio;
+		}
+	}
+	BUG_TRAP(0);
+	return NULL;
+}
+
+/* dequeues packet at given priority and level; call only if
+   you are sure that there is active class at prio/level */
+static struct sk_buff *
+htb_dequeue_tree(struct htb_sched *q,int prio,int level)
+{
+	struct sk_buff *skb = NULL;
+	//struct htb_sched *q = (struct htb_sched *)sch->data;
+	struct htb_class *cl,*start;
+	/* look initial class up in the row */
+	DEVIK_MSTART(6);
+	start = cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio);
+	
+	do {
+		BUG_TRAP(cl && cl->un.leaf.q->q.qlen); if (!cl) return NULL;
+		HTB_DBG(4,1,"htb_deq_tr prio=%d lev=%d cl=%X defic=%d\n",
+				prio,level,cl->classid,cl->un.leaf.deficit[level]);
+	
+		if (likely((skb = cl->un.leaf.q->dequeue(cl->un.leaf.q)) != NULL)) 
+			break;
+		if (!cl->warned) {
+			printk(KERN_WARNING "htb: class %X isn't work conserving ?!\n",cl->classid);
+			cl->warned = 1;
+		}
+		q->nwc_hit++;
+		htb_next_rb_node((level?cl->parent->un.inner.ptr:q->ptr[0])+prio);
+		cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio);
+	} while (cl != start);
+
+	DEVIK_MEND(6);
+	DEVIK_MSTART(7);
+	if (likely(skb != NULL)) {
+		if ((cl->un.leaf.deficit[level] -= skb->len) < 0) {
+			HTB_DBG(4,2,"htb_next_cl oldptr=%p quant_add=%d\n",
+				level?cl->parent->un.inner.ptr[prio]:q->ptr[0][prio],cl->un.leaf.quantum);
+			cl->un.leaf.deficit[level] += cl->un.leaf.quantum;
+			htb_next_rb_node((level?cl->parent->un.inner.ptr:q->ptr[0])+prio);
+		}
+		/* this used to be after charge_class but this constelation
+		   gives us slightly better performance */
+		if (!cl->un.leaf.q->q.qlen)
+			htb_deactivate (q,cl);
+	DEVIK_MSTART(8);
+		htb_charge_class (q,cl,level,skb->len);
+	DEVIK_MEND(8);
+	}
+	DEVIK_MEND(7);
+	return skb;
+}
+
+static void htb_delay_by(struct Qdisc *sch,long delay)
+{
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	if (netif_queue_stopped(sch->dev)) return;
+	if (delay <= 0) delay = 1;
+	if (unlikely(delay > 5*HZ)) {
+		if (net_ratelimit())
+			printk(KERN_INFO "HTB delay %ld > 5sec\n", delay);
+		delay = 5*HZ;
+	}
+	del_timer(&q->timer);
+	q->timer.expires = jiffies + delay;
+	add_timer(&q->timer);
+	sch->flags |= TCQ_F_THROTTLED;
+	sch->stats.overlimits++;
+	HTB_DBG(3,1,"htb_deq t_delay=%ld\n",delay);
+}
+
+static struct sk_buff *htb_dequeue(struct Qdisc *sch)
+{
+	struct sk_buff *skb = NULL;
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	int level;
+	long min_delay;
+
+	HTB_DBG(3,1,"htb_deq dircnt=%d qlen=%d\n",skb_queue_len(&q->direct_queue),
+			sch->q.qlen);
+
+	/* try to dequeue direct packets as high prio (!) to minimize cpu work */
+	if ((skb = __skb_dequeue(&q->direct_queue)) != NULL) {
+		sch->flags &= ~TCQ_F_THROTTLED;
+		sch->q.qlen--;
+		return skb;
+	}
+
+	DEVIK_MSTART(2);
+	if (!sch->q.qlen) goto fin;
+	PSCHED_GET_TIME(q->now);
+
+	min_delay = HZ*5;
+	q->nwc_hit = 0;
+	for (level = 0; level < TC_HTB_MAXDEPTH; level++) {
+		/* common case optimization - skip event handler quickly */
+		int m;
+		long delay;
+	DEVIK_MSTART(3);
+		if (jiffies - q->near_ev_cache[level] < 0x80000000 || 0) {
+			delay = htb_do_events(q,level);
+			q->near_ev_cache[level] += delay ? delay : HZ;
+		} else
+			delay = q->near_ev_cache[level] - jiffies;	
+		
+		if (delay && min_delay > delay) 
+			min_delay = delay;
+	DEVIK_MEND(3);
+	DEVIK_MSTART(5);
+		m = ~q->row_mask[level];
+		while (m != (int)(-1)) {
+			int prio = ffz (m);
+			m |= 1 << prio;
+			skb = htb_dequeue_tree(q,prio,level);
+			if (likely(skb != NULL)) {
+				sch->q.qlen--;
+				sch->flags &= ~TCQ_F_THROTTLED;
+	DEVIK_MEND(5);
+				goto fin;
+			}
+		}
+	DEVIK_MEND(5);
+	}
+	DEVIK_MSTART(4);
+#ifdef HTB_DEBUG
+	if (!q->nwc_hit && min_delay >= 5*HZ && net_ratelimit()) { 
+		printk(KERN_ERR "HTB: mindelay=%ld, report it please !\n",min_delay);
+		htb_debug_dump(q);
+	}
+#endif
+	htb_delay_by (sch,min_delay);
+	DEVIK_MEND(4);
+fin:
+	HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,jiffies,skb);
+	DEVIK_MEND(2);
+	return skb;
+}
+
+/* try to drop from each class (by prio) until one succeed */
+static int htb_drop(struct Qdisc* sch)
+{
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	int prio;
+
+	for (prio = TC_HTB_NUMPRIO - 1; prio >= 0; prio--) {
+		struct list_head *p;
+		list_for_each (p,q->drops+prio) {
+			struct htb_class *cl = list_entry(p,struct htb_class,
+					un.leaf.drop_list);
+			if (cl->un.leaf.q->ops->drop && 
+				cl->un.leaf.q->ops->drop(cl->un.leaf.q)) {
+				sch->q.qlen--;
+				if (!cl->un.leaf.q->q.qlen)
+					htb_deactivate (q,cl);
+				return 1;
+			}
+		}
+	}
+	return 0;
+}
+
+/* reset all classes */
+/* always caled under BH & queue lock */
+static void htb_reset(struct Qdisc* sch)
+{
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	int i;
+	HTB_DBG(0,1,"htb_reset sch=%p, handle=%X\n",sch,sch->handle);
+
+	for (i = 0; i < HTB_HSIZE; i++) {
+		struct list_head *p;
+		list_for_each (p,q->hash+i) {
+			struct htb_class *cl = list_entry(p,struct htb_class,hlist);
+			if (cl->level)
+				memset(&cl->un.inner,0,sizeof(cl->un.inner));
+			else {
+				if (cl->un.leaf.q) 
+					qdisc_reset(cl->un.leaf.q);
+				INIT_LIST_HEAD(&cl->un.leaf.drop_list);
+			}
+			cl->prio_activity = 0;
+			cl->cmode = HTB_CAN_SEND;
+#ifdef HTB_DEBUG
+			cl->pq_node.rb_color = -1;
+			memset(cl->node,255,sizeof(cl->node));
+#endif
+
+		}
+	}
+	sch->flags &= ~TCQ_F_THROTTLED;
+	del_timer(&q->timer);
+	__skb_queue_purge(&q->direct_queue);
+	sch->q.qlen = 0;
+	memset(q->row,0,sizeof(q->row));
+	memset(q->row_mask,0,sizeof(q->row_mask));
+	memset(q->wait_pq,0,sizeof(q->wait_pq));
+	memset(q->ptr,0,sizeof(q->ptr));
+	for (i = 0; i < TC_HTB_NUMPRIO; i++)
+		INIT_LIST_HEAD(q->drops+i);
+}
+
+static int htb_init(struct Qdisc *sch, struct rtattr *opt)
+{
+	struct htb_sched *q = (struct htb_sched*)sch->data;
+	struct rtattr *tb[TCA_HTB_INIT];
+	struct tc_htb_glob *gopt;
+	int i;
+#ifdef HTB_DEBUG
+	printk(KERN_INFO "HTB init, kernel part version %d.%d\n",
+			  HTB_VER >> 16,HTB_VER & 0xffff);
+#endif
+	if (!opt || rtattr_parse(tb, TCA_HTB_INIT, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
+			tb[TCA_HTB_INIT-1] == NULL ||
+			RTA_PAYLOAD(tb[TCA_HTB_INIT-1]) < sizeof(*gopt)) {
+		printk(KERN_ERR "HTB: hey probably you have bad tc tool ?\n");
+		return -EINVAL;
+	}
+	gopt = RTA_DATA(tb[TCA_HTB_INIT-1]);
+	if (gopt->version != HTB_VER >> 16) {
+		printk(KERN_ERR "HTB: need tc/htb version %d (minor is %d), you have %d\n",
+				HTB_VER >> 16,HTB_VER & 0xffff,gopt->version);
+		return -EINVAL;
+	}
+	memset(q,0,sizeof(*q));
+	q->debug = gopt->debug;
+	HTB_DBG(0,1,"htb_init sch=%p handle=%X r2q=%d\n",sch,sch->handle,gopt->rate2quantum);
+
+	INIT_LIST_HEAD(&q->root);
+	for (i = 0; i < HTB_HSIZE; i++)
+		INIT_LIST_HEAD(q->hash+i);
+	for (i = 0; i < TC_HTB_NUMPRIO; i++)
+		INIT_LIST_HEAD(q->drops+i);
+
+	init_timer(&q->timer);
+	skb_queue_head_init(&q->direct_queue);
+
+	q->direct_qlen = sch->dev->tx_queue_len;
+	q->timer.function = htb_timer;
+	q->timer.data = (unsigned long)sch;
+
+#ifdef HTB_RATECM
+	init_timer(&q->rttim);
+	q->rttim.function = htb_rate_timer;
+	q->rttim.data = (unsigned long)sch;
+	q->rttim.expires = jiffies + HZ;
+	add_timer(&q->rttim);
+#endif
+	if ((q->rate2quantum = gopt->rate2quantum) < 1)
+		q->rate2quantum = 1;
+	q->defcls = gopt->defcls;
+
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+	struct htb_sched *q = (struct htb_sched*)sch->data;
+	unsigned char	 *b = skb->tail;
+	struct rtattr *rta;
+	struct tc_htb_glob gopt;
+	HTB_DBG(0,1,"htb_dump sch=%p, handle=%X\n",sch,sch->handle);
+	/* stats */
+	HTB_QLOCK(sch);
+	gopt.direct_pkts = q->direct_pkts;
+
+#ifdef HTB_DEBUG
+	htb_debug_dump(q);
+#endif
+	gopt.version = HTB_VER;
+	gopt.rate2quantum = q->rate2quantum;
+	gopt.defcls = q->defcls;
+	gopt.debug = q->debug;
+	rta = (struct rtattr*)b;
+	RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+	RTA_PUT(skb, TCA_HTB_INIT, sizeof(gopt), &gopt);
+	rta->rta_len = skb->tail - b;
+	sch->stats.qlen = sch->q.qlen;
+	RTA_PUT(skb, TCA_STATS, sizeof(sch->stats), &sch->stats);
+	HTB_QUNLOCK(sch);
+	return skb->len;
+rtattr_failure:
+	HTB_QUNLOCK(sch);
+	skb_trim(skb, skb->tail - skb->data);
+	return -1;
+}
+
+static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
+	struct sk_buff *skb, struct tcmsg *tcm)
+{
+#ifdef HTB_DEBUG
+	struct htb_sched *q = (struct htb_sched*)sch->data;
+#endif
+	struct htb_class *cl = (struct htb_class*)arg;
+	unsigned char	 *b = skb->tail;
+	struct rtattr *rta;
+	struct tc_htb_opt opt;
+
+	HTB_DBG(0,1,"htb_dump_class handle=%X clid=%X\n",sch->handle,cl->classid);
+
+	HTB_QLOCK(sch);
+	tcm->tcm_parent = cl->parent ? cl->parent->classid : TC_H_ROOT;
+	tcm->tcm_handle = cl->classid;
+	if (!cl->level && cl->un.leaf.q) {
+		tcm->tcm_info = cl->un.leaf.q->handle;
+		cl->stats.qlen = cl->un.leaf.q->q.qlen;
+	}
+
+	rta = (struct rtattr*)b;
+	RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+
+	memset (&opt,0,sizeof(opt));
+
+	opt.rate = cl->rate->rate; opt.buffer = cl->buffer;
+	opt.ceil = cl->ceil->rate; opt.cbuffer = cl->cbuffer;
+	opt.quantum = cl->un.leaf.quantum; opt.prio = cl->un.leaf.prio;
+	opt.level = cl->level; 
+	RTA_PUT(skb, TCA_HTB_PARMS, sizeof(opt), &opt);
+	rta->rta_len = skb->tail - b;
+
+#ifdef HTB_RATECM
+	cl->stats.bps = cl->rate_bytes/(HTB_EWMAC*HTB_HSIZE);
+	cl->stats.pps = cl->rate_packets/(HTB_EWMAC*HTB_HSIZE);
+#endif
+
+	cl->xstats.tokens = cl->tokens;
+	cl->xstats.ctokens = cl->ctokens;
+	RTA_PUT(skb, TCA_STATS, sizeof(cl->stats), &cl->stats);
+	RTA_PUT(skb, TCA_XSTATS, sizeof(cl->xstats), &cl->xstats);
+	HTB_QUNLOCK(sch);
+	return skb->len;
+rtattr_failure:
+	HTB_QUNLOCK(sch);
+	skb_trim(skb, b - skb->data);
+	return -1;
+}
+
+static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
+	struct Qdisc **old)
+{
+	struct htb_class *cl = (struct htb_class*)arg;
+
+	if (cl && !cl->level) {
+		if (new == NULL && (new = qdisc_create_dflt(sch->dev, 
+					&pfifo_qdisc_ops)) == NULL)
+					return -ENOBUFS;
+		sch_tree_lock(sch);
+		if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) {
+			/* TODO: is it correct ? Why CBQ doesn't do it ? */
+			sch->q.qlen -= (*old)->q.qlen;	
+			qdisc_reset(*old);
+		}
+		sch_tree_unlock(sch);
+		return 0;
+	}
+	return -ENOENT;
+}
+
+static struct Qdisc * htb_leaf(struct Qdisc *sch, unsigned long arg)
+{
+	struct htb_class *cl = (struct htb_class*)arg;
+	return (cl && !cl->level) ? cl->un.leaf.q : NULL;
+}
+
+static unsigned long htb_get(struct Qdisc *sch, u32 classid)
+{
+#ifdef HTB_DEBUG
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+#endif
+	struct htb_class *cl = htb_find(classid,sch);
+	HTB_DBG(0,1,"htb_get clid=%X q=%p cl=%p ref=%d\n",classid,q,cl,cl?cl->refcnt:0);
+	if (cl) 
+		cl->refcnt++;
+	return (unsigned long)cl;
+}
+
+static void htb_destroy_filters(struct tcf_proto **fl)
+{
+	struct tcf_proto *tp;
+
+	while ((tp = *fl) != NULL) {
+		*fl = tp->next;
+		tp->ops->destroy(tp);
+	}
+}
+
+static void htb_destroy_class(struct Qdisc* sch,struct htb_class *cl)
+{
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	HTB_DBG(0,1,"htb_destrycls clid=%X ref=%d\n", cl?cl->classid:0,cl?cl->refcnt:0);
+	if (!cl->level) {
+		BUG_TRAP(cl->un.leaf.q);
+		sch->q.qlen -= cl->un.leaf.q->q.qlen;
+		qdisc_destroy(cl->un.leaf.q);
+	}
+	qdisc_put_rtab(cl->rate);
+	qdisc_put_rtab(cl->ceil);
+	
+#ifdef CONFIG_NET_ESTIMATOR
+	qdisc_kill_estimator(&cl->stats);
+#endif
+	htb_destroy_filters (&cl->filter_list);
+	
+	while (!list_empty(&cl->children)) 
+		htb_destroy_class (sch,list_entry(cl->children.next,
+					struct htb_class,sibling));
+
+	/* note: this delete may happen twice (see htb_delete) */
+	list_del(&cl->hlist);
+	list_del(&cl->sibling);
+	
+	if (cl->prio_activity)
+		htb_deactivate (q,cl);
+	
+	if (cl->cmode != HTB_CAN_SEND)
+		htb_safe_rb_erase(&cl->pq_node,q->wait_pq+cl->level);
+	
+	kfree(cl);
+}
+
+/* always caled under BH & queue lock */
+static void htb_destroy(struct Qdisc* sch)
+{
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	HTB_DBG(0,1,"htb_destroy q=%p\n",q);
+
+	del_timer_sync (&q->timer);
+#ifdef HTB_RATECM
+	del_timer_sync (&q->rttim);
+#endif
+	while (!list_empty(&q->root)) 
+		htb_destroy_class (sch,list_entry(q->root.next,
+					struct htb_class,sibling));
+
+	htb_destroy_filters(&q->filter_list);
+	__skb_queue_purge(&q->direct_queue);
+	MOD_DEC_USE_COUNT;
+}
+
+static int htb_delete(struct Qdisc *sch, unsigned long arg)
+{
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	struct htb_class *cl = (struct htb_class*)arg;
+	HTB_DBG(0,1,"htb_delete q=%p cl=%X ref=%d\n",q,cl?cl->classid:0,cl?cl->refcnt:0);
+
+	// TODO: why don't allow to delete subtree ? references ? does
+	// tc subsys quarantee us that in htb_destroy it holds no class
+	// refs so that we can remove children safely there ?
+	if (!list_empty(&cl->children) || cl->filter_cnt)
+		return -EBUSY;
+	
+	sch_tree_lock(sch);
+	
+	/* delete from hash and active; remainder in destroy_class */
+	list_del_init(&cl->hlist);
+	if (cl->prio_activity)
+		htb_deactivate (q,cl);
+
+	if (--cl->refcnt == 0)
+		htb_destroy_class(sch,cl);
+
+	sch_tree_unlock(sch);
+	return 0;
+}
+
+static void htb_put(struct Qdisc *sch, unsigned long arg)
+{
+#ifdef HTB_DEBUG
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+#endif
+	struct htb_class *cl = (struct htb_class*)arg;
+	HTB_DBG(0,1,"htb_put q=%p cl=%X ref=%d\n",q,cl?cl->classid:0,cl?cl->refcnt:0);
+
+	if (--cl->refcnt == 0)
+		htb_destroy_class(sch,cl);
+}
+
+static int htb_change_class(struct Qdisc *sch, u32 classid, 
+		u32 parentid, struct rtattr **tca, unsigned long *arg)
+{
+	int err = -EINVAL;
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	struct htb_class *cl = (struct htb_class*)*arg,*parent;
+	struct rtattr *opt = tca[TCA_OPTIONS-1];
+	struct qdisc_rate_table *rtab = NULL, *ctab = NULL;
+	struct rtattr *tb[TCA_HTB_RTAB];
+	struct tc_htb_opt *hopt;
+
+	/* extract all subattrs from opt attr */
+	if (!opt || rtattr_parse(tb, TCA_HTB_RTAB, RTA_DATA(opt), RTA_PAYLOAD(opt)) ||
+			tb[TCA_HTB_PARMS-1] == NULL ||
+			RTA_PAYLOAD(tb[TCA_HTB_PARMS-1]) < sizeof(*hopt))
+		goto failure;
+	
+	parent = parentid == TC_H_ROOT ? NULL : htb_find (parentid,sch);
+
+	hopt = RTA_DATA(tb[TCA_HTB_PARMS-1]);
+	HTB_DBG(0,1,"htb_chg cl=%p, clid=%X, opt/prio=%d, rate=%u, buff=%d, quant=%d\n", cl,cl?cl->classid:0,(int)hopt->prio,hopt->rate.rate,hopt->buffer,hopt->quantum);
+	rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB-1]);
+	ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB-1]);
+	if (!rtab || !ctab) goto failure;
+
+	if (!cl) { /* new class */
+		/* check maximal depth */
+		if (parent && parent->parent && parent->parent->level < 2) {
+			printk(KERN_ERR "htb: tree is too deep\n");
+			goto failure;
+		}
+		err = -ENOBUFS;
+		if ((cl = kmalloc(sizeof(*cl), GFP_KERNEL)) == NULL)
+			goto failure;
+		
+		memset(cl, 0, sizeof(*cl));
+		cl->refcnt = 1;
+		INIT_LIST_HEAD(&cl->sibling);
+		INIT_LIST_HEAD(&cl->hlist);
+		INIT_LIST_HEAD(&cl->children);
+		INIT_LIST_HEAD(&cl->un.leaf.drop_list);
+#ifdef HTB_DEBUG
+		cl->magic = HTB_CMAGIC;
+#endif
+
+		sch_tree_lock(sch);
+		if (parent && !parent->level) {
+			/* turn parent into inner node */
+			sch->q.qlen -= parent->un.leaf.q->q.qlen;
+			qdisc_destroy (parent->un.leaf.q);
+			if (parent->prio_activity) 
+				htb_deactivate (q,parent);
+
+			/* remove from evt list because of level change */
+			if (parent->cmode != HTB_CAN_SEND) {
+				htb_safe_rb_erase(&parent->pq_node,q->wait_pq /*+0*/);
+				parent->cmode = HTB_CAN_SEND;
+			}
+			parent->level = (parent->parent ? parent->parent->level
+					: TC_HTB_MAXDEPTH) - 1;
+			memset (&parent->un.inner,0,sizeof(parent->un.inner));
+		}
+		/* leaf (we) needs elementary qdisc */
+		if (!(cl->un.leaf.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)))
+			cl->un.leaf.q = &noop_qdisc;
+
+		cl->classid = classid; cl->parent = parent;
+
+		/* set class to be in HTB_CAN_SEND state */
+		cl->tokens = hopt->buffer;
+		cl->ctokens = hopt->cbuffer;
+		cl->mbuffer = 60000000; /* 1min */
+		PSCHED_GET_TIME(cl->t_c);
+		cl->cmode = HTB_CAN_SEND;
+
+		/* attach to the hash list and parent's family */
+		list_add_tail(&cl->hlist, q->hash+htb_hash(classid));
+		list_add_tail(&cl->sibling, parent ? &parent->children : &q->root);
+#ifdef HTB_DEBUG
+		{ 
+			int i;
+			for (i = 0; i < TC_HTB_NUMPRIO; i++) cl->node[i].rb_color = -1;
+			cl->pq_node.rb_color = -1;
+		}
+#endif
+	} else sch_tree_lock(sch);
+
+	cl->un.leaf.quantum = rtab->rate.rate / q->rate2quantum;
+	if (!hopt->quantum && cl->un.leaf.quantum < 1000) {
+		printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.", cl->classid);
+		cl->un.leaf.quantum = 1000;
+	}
+	if (!hopt->quantum && cl->un.leaf.quantum > 200000) {
+		printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.", cl->classid);
+		cl->un.leaf.quantum = 200000;
+	}
+	if (hopt->quantum)
+		cl->un.leaf.quantum = hopt->quantum;
+	if ((cl->un.leaf.prio = hopt->prio) >= TC_HTB_NUMPRIO)
+		cl->un.leaf.prio = TC_HTB_NUMPRIO - 1;
+
+	cl->buffer = hopt->buffer;
+	cl->cbuffer = hopt->cbuffer;
+	if (cl->rate) qdisc_put_rtab(cl->rate); cl->rate = rtab;
+	if (cl->ceil) qdisc_put_rtab(cl->ceil); cl->ceil = ctab;
+	sch_tree_unlock(sch);
+
+	*arg = (unsigned long)cl;
+	return 0;
+
+failure:
+	if (rtab) qdisc_put_rtab(rtab);
+	if (ctab) qdisc_put_rtab(ctab);
+	return err;
+}
+
+static struct tcf_proto **htb_find_tcf(struct Qdisc *sch, unsigned long arg)
+{
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	struct htb_class *cl = (struct htb_class *)arg;
+	struct tcf_proto **fl = cl ? &cl->filter_list : &q->filter_list;
+	HTB_DBG(0,2,"htb_tcf q=%p clid=%X fref=%d fl=%p\n",q,cl?cl->classid:0,cl?cl->filter_cnt:q->filter_cnt,*fl);
+	return fl;
+}
+
+static unsigned long htb_bind_filter(struct Qdisc *sch, unsigned long parent,
+	u32 classid)
+{
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	struct htb_class *cl = htb_find (classid,sch);
+	HTB_DBG(0,2,"htb_bind q=%p clid=%X cl=%p fref=%d\n",q,classid,cl,cl?cl->filter_cnt:q->filter_cnt);
+	/*if (cl && !cl->level) return 0;
+	  The line above used to be there to prevent attaching filters to 
+	  leaves. But at least tc_index filter uses this just to get class 
+	  for other reasons so that we have to allow for it.
+	  ----
+	  19.6.2002 As Werner explained it is ok - bind filter is just
+	  another way to "lock" the class - unlike "get" this lock can
+	  be broken by class during destroy IIUC.
+	 */
+	if (cl) 
+		cl->filter_cnt++; 
+	else 
+		q->filter_cnt++;
+	return (unsigned long)cl;
+}
+
+static void htb_unbind_filter(struct Qdisc *sch, unsigned long arg)
+{
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	struct htb_class *cl = (struct htb_class *)arg;
+	HTB_DBG(0,2,"htb_unbind q=%p cl=%p fref=%d\n",q,cl,cl?cl->filter_cnt:q->filter_cnt);
+	if (cl) 
+		cl->filter_cnt--; 
+	else 
+		q->filter_cnt--;
+}
+
+static void htb_walk(struct Qdisc *sch, struct qdisc_walker *arg)
+{
+	struct htb_sched *q = (struct htb_sched *)sch->data;
+	int i;
+
+	if (arg->stop)
+		return;
+
+	for (i = 0; i < HTB_HSIZE; i++) {
+		struct list_head *p;
+		list_for_each (p,q->hash+i) {
+			struct htb_class *cl = list_entry(p,struct htb_class,hlist);
+			if (arg->count < arg->skip) {
+				arg->count++;
+				continue;
+			}
+			if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
+				arg->stop = 1;
+				return;
+			}
+			arg->count++;
+		}
+	}
+}
+
+static struct Qdisc_class_ops htb_class_ops =
+{
+    htb_graft,
+    htb_leaf,
+    htb_get,
+    htb_put,
+    htb_change_class,
+    htb_delete,
+    htb_walk,
+
+    htb_find_tcf,
+    htb_bind_filter,
+    htb_unbind_filter,
+
+    htb_dump_class,
+};
+
+struct Qdisc_ops htb_qdisc_ops =
+{
+    NULL,
+    &htb_class_ops,
+    "htb",
+    sizeof(struct htb_sched),
+
+    htb_enqueue,
+    htb_dequeue,
+    htb_requeue,
+    htb_drop,
+
+    htb_init,
+    htb_reset,
+    htb_destroy,
+    NULL /* htb_change */,
+
+    htb_dump,
+};
+
+#ifdef MODULE
+int init_module(void)
+{
+    return register_qdisc(&htb_qdisc_ops);
+}
+
+void cleanup_module(void) 
+{
+    unregister_qdisc(&htb_qdisc_ops);
+}
+MODULE_LICENSE("GPL");
+#endif
diff -Nru a/net/socket.c b/net/socket.c
--- a/net/socket.c	Sat Aug 10 18:42:22 2002
+++ b/net/socket.c	Sat Aug 10 18:42:22 2002
@@ -112,18 +112,18 @@
  */
 
 static struct file_operations socket_file_ops = {
-	llseek:		no_llseek,
-	read:		sock_read,
-	write:		sock_write,
-	poll:		sock_poll,
-	ioctl:		sock_ioctl,
-	mmap:		sock_mmap,
-	open:		sock_no_open,	/* special open code to disallow open via /proc */
-	release:	sock_close,
-	fasync:		sock_fasync,
-	readv:		sock_readv,
-	writev:		sock_writev,
-	sendpage:	sock_sendpage
+	.llseek =	no_llseek,
+	.read =		sock_read,
+	.write =	sock_write,
+	.poll =		sock_poll,
+	.ioctl =	sock_ioctl,
+	.mmap =		sock_mmap,
+	.open =		sock_no_open,	/* special open code to disallow open via /proc */
+	.release =	sock_close,
+	.fasync =	sock_fasync,
+	.readv =	sock_readv,
+	.writev =	sock_writev,
+	.sendpage =	sock_sendpage
 };
 
 /*
@@ -312,9 +312,9 @@
 }
 
 static struct super_operations sockfs_ops = {
-	alloc_inode:	sock_alloc_inode,
-	destroy_inode:	sock_destroy_inode,
-	statfs:		simple_statfs,
+	.alloc_inode =	sock_alloc_inode,
+	.destroy_inode =sock_destroy_inode,
+	.statfs =	simple_statfs,
 };
 
 static struct super_block *sockfs_get_sb(struct file_system_type *fs_type,
@@ -326,16 +326,16 @@
 static struct vfsmount *sock_mnt;
 
 static struct file_system_type sock_fs_type = {
-	name:		"sockfs",
-	get_sb:		sockfs_get_sb,
-	kill_sb:	kill_anon_super,
+	.name =		"sockfs",
+	.get_sb =	sockfs_get_sb,
+	.kill_sb =	kill_anon_super,
 };
 static int sockfs_delete_dentry(struct dentry *dentry)
 {
 	return 1;
 }
 static struct dentry_operations sockfs_dentry_operations = {
-	d_delete:	sockfs_delete_dentry,
+	.d_delete =	sockfs_delete_dentry,
 };
 
 /*
diff -Nru a/net/sysctl_net.c b/net/sysctl_net.c
--- a/net/sysctl_net.c	Sat Aug 10 18:42:23 2002
+++ b/net/sysctl_net.c	Sat Aug 10 18:42:23 2002
@@ -17,37 +17,61 @@
 #include <linux/sysctl.h>
 
 #ifdef CONFIG_INET
-extern ctl_table ipv4_table[];
+extern struct ctl_table ipv4_table[];
 #endif
 
-extern ctl_table core_table[];
+extern struct ctl_table core_table[];
 
 #ifdef CONFIG_NET
-extern ctl_table ether_table[], e802_table[];
+extern struct ctl_table ether_table[];
 #endif
 
 #ifdef CONFIG_IPV6
-extern ctl_table ipv6_table[];
+extern struct ctl_table ipv6_table[];
 #endif
 
 #ifdef CONFIG_TR
-extern ctl_table tr_table[];
+extern struct ctl_table tr_table[];
 #endif
 
-ctl_table net_table[] = {
-	{NET_CORE,   "core",      NULL, 0, 0555, core_table},      
+struct ctl_table net_table[] = {
+	{
+		.ctl_name	= NET_CORE,
+		.procname	= "core",
+		.mode		= 0555,
+		.child		= core_table,
+	},
 #ifdef CONFIG_NET
-	{NET_802,    "802",       NULL, 0, 0555, e802_table},
-	{NET_ETHER,  "ethernet",  NULL, 0, 0555, ether_table},
+	{
+		.ctl_name	= NET_ETHER,
+		.procname	= "ethernet",
+		.mode		= 0555,
+		.child		= ether_table,
+	},
 #endif
 #ifdef CONFIG_INET
-	{NET_IPV4,   "ipv4",      NULL, 0, 0555, ipv4_table},
+	{
+		.ctl_name	= NET_IPV4,
+		.procname	= "ipv4",
+		.mode		= 0555,
+		.child		= ipv4_table
+	},
 #endif
 #ifdef CONFIG_IPV6
-	{NET_IPV6, "ipv6", NULL, 0, 0555, ipv6_table},
+	{
+		.ctl_name	= NET_IPV6,
+		.procname	= "ipv6",
+		.mode		= 0555,
+		.child		= ipv6_table,
+	},
 #endif
 #ifdef CONFIG_TR
-	{NET_TR, "token-ring", NULL, 0, 0555, tr_table},
+	{
+		.ctl_name	= NET_TR,
+		.procname	= "token-ring",
+		.mode		= 0555,
+		.child		= tr_table,
+	},
 #endif
-	{0}
+	{ 0 },
 };
diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c
--- a/net/unix/af_unix.c	Sat Aug 10 18:42:23 2002
+++ b/net/unix/af_unix.c	Sat Aug 10 18:42:23 2002
@@ -1816,50 +1816,50 @@
 #endif
 
 struct proto_ops unix_stream_ops = {
-	family:		PF_UNIX,
+	.family =	PF_UNIX,
 	
-	release:	unix_release,
-	bind:		unix_bind,
-	connect:	unix_stream_connect,
-	socketpair:	unix_socketpair,
-	accept:		unix_accept,
-	getname:	unix_getname,
-	poll:		unix_poll,
-	ioctl:		unix_ioctl,
-	listen:		unix_listen,
-	shutdown:	unix_shutdown,
-	setsockopt:	sock_no_setsockopt,
-	getsockopt:	sock_no_getsockopt,
-	sendmsg:	unix_stream_sendmsg,
-	recvmsg:	unix_stream_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	unix_release,
+	.bind =		unix_bind,
+	.connect =	unix_stream_connect,
+	.socketpair =	unix_socketpair,
+	.accept =	unix_accept,
+	.getname =	unix_getname,
+	.poll =		unix_poll,
+	.ioctl =	unix_ioctl,
+	.listen =	unix_listen,
+	.shutdown =	unix_shutdown,
+	.setsockopt =	sock_no_setsockopt,
+	.getsockopt =	sock_no_getsockopt,
+	.sendmsg =	unix_stream_sendmsg,
+	.recvmsg =	unix_stream_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 struct proto_ops unix_dgram_ops = {
-	family:		PF_UNIX,
+	.family =	PF_UNIX,
 
-	release:	unix_release,
-	bind:		unix_bind,
-	connect:	unix_dgram_connect,
-	socketpair:	unix_socketpair,
-	accept:		sock_no_accept,
-	getname:	unix_getname,
-	poll:		datagram_poll,
-	ioctl:		unix_ioctl,
-	listen:		sock_no_listen,
-	shutdown:	unix_shutdown,
-	setsockopt:	sock_no_setsockopt,
-	getsockopt:	sock_no_getsockopt,
-	sendmsg:	unix_dgram_sendmsg,
-	recvmsg:	unix_dgram_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	unix_release,
+	.bind =		unix_bind,
+	.connect =	unix_dgram_connect,
+	.socketpair =	unix_socketpair,
+	.accept =	sock_no_accept,
+	.getname =	unix_getname,
+	.poll =		datagram_poll,
+	.ioctl =	unix_ioctl,
+	.listen =	sock_no_listen,
+	.shutdown =	unix_shutdown,
+	.setsockopt =	sock_no_setsockopt,
+	.getsockopt =	sock_no_getsockopt,
+	.sendmsg =	unix_dgram_sendmsg,
+	.recvmsg =	unix_dgram_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 struct net_proto_family unix_family_ops = {
-	family:	 PF_UNIX,
-	create:	 unix_create,
+	.family = PF_UNIX,
+	.create = unix_create,
 };
 
 #ifdef CONFIG_SYSCTL
diff -Nru a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
--- a/net/wanrouter/af_wanpipe.c	Sat Aug 10 18:42:23 2002
+++ b/net/wanrouter/af_wanpipe.c	Sat Aug 10 18:42:23 2002
@@ -2697,22 +2697,22 @@
 
 #ifdef LINUX_2_4
 struct proto_ops wanpipe_ops = {
-	family: 	PF_WANPIPE,
+	.family = 	PF_WANPIPE,
 
-	release: 	wanpipe_release,
-	bind: 		wanpipe_bind,
-	connect: 	wanpipe_connect,
-	socketpair: 	sock_no_socketpair,
-	accept: 	wanpipe_accept,
-	getname: 	wanpipe_getname, 
-	poll: 		wanpipe_poll,
-	ioctl: 		wanpipe_ioctl,
-	listen: 	wanpipe_listen, 
-	shutdown: 	sock_no_shutdown,
-	setsockopt: 	sock_no_setsockopt,
-	getsockopt: 	sock_no_getsockopt,
-	sendmsg: 	wanpipe_sendmsg,
-	recvmsg: 	wanpipe_recvmsg
+	.release = 	wanpipe_release,
+	.bind = 		wanpipe_bind,
+	.connect = 	wanpipe_connect,
+	.socketpair = 	sock_no_socketpair,
+	.accept = 	wanpipe_accept,
+	.getname = 	wanpipe_getname, 
+	.poll = 		wanpipe_poll,
+	.ioctl = 		wanpipe_ioctl,
+	.listen = 	wanpipe_listen, 
+	.shutdown = 	sock_no_shutdown,
+	.setsockopt = 	sock_no_setsockopt,
+	.getsockopt = 	sock_no_getsockopt,
+	.sendmsg = 	wanpipe_sendmsg,
+	.recvmsg = 	wanpipe_recvmsg
 };
 #else
 struct proto_ops wanpipe_ops = {
@@ -2739,12 +2739,12 @@
 
 
 static struct net_proto_family wanpipe_family_ops = {
-	family:	PF_WANPIPE,
-	create:	wanpipe_create,
+	.family =PF_WANPIPE,
+	.create =wanpipe_create,
 };
 
 struct notifier_block wanpipe_netdev_notifier = {
-	notifier_call:	wanpipe_notifier,
+	.notifier_call =wanpipe_notifier,
 };
 
 
diff -Nru a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c
--- a/net/wanrouter/wanproc.c	Sat Aug 10 18:42:22 2002
+++ b/net/wanrouter/wanproc.c	Sat Aug 10 18:42:22 2002
@@ -81,7 +81,7 @@
 
 static struct inode_operations router_inode =
 {
-	permission:	router_proc_perms,
+	.permission =	router_proc_perms,
 };
 
 /*
@@ -194,17 +194,17 @@
 }
 
 static struct seq_operations config_op = {
-	start:	r_start,
-	next:	r_next,
-	stop:	r_stop,
-	show:	config_show
+	.start =r_start,
+	.next =	r_next,
+	.stop =	r_stop,
+	.show =	config_show
 };
 
 static struct seq_operations status_op = {
-	start:	r_start,
-	next:	r_next,
-	stop:	r_stop,
-	show:	status_show
+	.start =r_start,
+	.next =	r_next,
+	.stop =	r_stop,
+	.show =	status_show
 };
 
 static int config_open(struct inode *inode, struct file *file)
@@ -219,18 +219,18 @@
 
 static struct file_operations config_fops =
 {
-	open:		config_open,
-	read:		seq_read,
-	llseek:		seq_lseek,
-	release:	seq_release,
+	.open =		config_open,
+	.read =		seq_read,
+	.llseek =	seq_lseek,
+	.release =	seq_release,
 };
 
 static struct file_operations status_fops =
 {
-	open:		status_open,
-	read:		seq_read,
-	llseek:		seq_lseek,
-	release:	seq_release,
+	.open =		status_open,
+	.read =		seq_read,
+	.llseek =	seq_lseek,
+	.release =	seq_release,
 };
 
 static int wandev_show(struct seq_file *m, void *v)
@@ -302,11 +302,11 @@
 
 static struct file_operations wandev_fops =
 {
-	open:		wandev_open,
-	read:		seq_read,
-	llseek:		seq_lseek,
-	release:	single_release,
-	ioctl:		wanrouter_ioctl,
+	.open =		wandev_open,
+	.read =		seq_read,
+	.llseek =	seq_lseek,
+	.release =	single_release,
+	.ioctl =	wanrouter_ioctl,
 };
 
 /*
diff -Nru a/net/x25/af_x25.c b/net/x25/af_x25.c
--- a/net/x25/af_x25.c	Sat Aug 10 18:42:23 2002
+++ b/net/x25/af_x25.c	Sat Aug 10 18:42:23 2002
@@ -1278,29 +1278,29 @@
 } 
 
 struct net_proto_family x25_family_ops = {
-	family:		AF_X25,
-	create:		x25_create,
+	.family =	AF_X25,
+	.create =	x25_create,
 };
 
 static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
-	family:		AF_X25,
+	.family =	AF_X25,
 
-	release:	x25_release,
-	bind:		x25_bind,
-	connect:	x25_connect,
-	socketpair:	sock_no_socketpair,
-	accept:		x25_accept,
-	getname:	x25_getname,
-	poll:		datagram_poll,
-	ioctl:		x25_ioctl,
-	listen:		x25_listen,
-	shutdown:	sock_no_shutdown,
-	setsockopt:	x25_setsockopt,
-	getsockopt:	x25_getsockopt,
-	sendmsg:	x25_sendmsg,
-	recvmsg:	x25_recvmsg,
-	mmap:		sock_no_mmap,
-	sendpage:	sock_no_sendpage,
+	.release =	x25_release,
+	.bind =		x25_bind,
+	.connect =	x25_connect,
+	.socketpair =	sock_no_socketpair,
+	.accept =	x25_accept,
+	.getname =	x25_getname,
+	.poll =		datagram_poll,
+	.ioctl =	x25_ioctl,
+	.listen =	x25_listen,
+	.shutdown =	sock_no_shutdown,
+	.setsockopt =	x25_setsockopt,
+	.getsockopt =	x25_getsockopt,
+	.sendmsg =	x25_sendmsg,
+	.recvmsg =	x25_recvmsg,
+	.mmap =		sock_no_mmap,
+	.sendpage =	sock_no_sendpage,
 };
 
 #include <linux/smp_lock.h>
@@ -1308,12 +1308,12 @@
 
 
 static struct packet_type x25_packet_type = {
-	type:		__constant_htons(ETH_P_X25),
-	func:		x25_lapb_receive_frame,
+	.type =		__constant_htons(ETH_P_X25),
+	.func =		x25_lapb_receive_frame,
 };
 
 struct notifier_block x25_dev_notifier = {
-	notifier_call:	x25_device_event,
+	.notifier_call =x25_device_event,
 };
 
 void x25_kill_by_neigh(struct x25_neigh *neigh)
diff -Nru a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c
--- a/sound/arm/sa11xx-uda1341.c	Sat Aug 10 18:42:21 2002
+++ b/sound/arm/sa11xx-uda1341.c	Sat Aug 10 18:42:21 2002
@@ -101,9 +101,9 @@
 #define RATES sizeof(rates) / sizeof(rates[0])
 
 static snd_pcm_hw_constraint_list_t hw_constraints_rates = {
-	count: RATES,
-	list: rates,
-	mask: 0,
+	.count	= RATES,
+	.list	= rates,
+	.mask	= 0,
 };
 
 /* }}} */
@@ -545,46 +545,46 @@
 
 static snd_pcm_hardware_t snd_sa11xx_uda1341_capture =
 {
-	info:			(SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
-	formats:		SNDRV_PCM_FMTBIT_S16_LE,
-	rates:			(SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
-				 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |\
-				 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
-				 SNDRV_PCM_RATE_KNOT),
-	rate_min:		8000,
-	rate_max:		48000,
-	channels_min:		2,
-	channels_max:		2,
-	buffer_bytes_max:	16380,
-	period_bytes_min:	64,
-	period_bytes_max:	8190, /* <= MAX_DMA_SIZE from ams/arch-sa1100/dma.h */
-	periods_min:		2,
-	periods_max:		255,
-	fifo_size:		0,
+	.info			= (SNDRV_PCM_INFO_INTERLEAVED |
+				   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				   SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
+	.formats		= SNDRV_PCM_FMTBIT_S16_LE,
+	.rates			= (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+				   SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |\
+				   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
+				   SNDRV_PCM_RATE_KNOT),
+	.rate_min		= 8000,
+	.rate_max		= 48000,
+	.channels_min:		= 2,
+	.channels_max:		= 2,
+	.buffer_bytes_max:	= 16380,
+	.period_bytes_min:	= 64,
+	.period_bytes_max:	= 8190, /* <= MAX_DMA_SIZE from ams/arch-sa1100/dma.h */
+	.periods_min		= 2,
+	.periods_max		= 255,
+	.fifo_size		= 0,
 };
 
 static snd_pcm_hardware_t snd_sa11xx_uda1341_playback =
 {
-	info:			(SNDRV_PCM_INFO_INTERLEAVED |
-				 SNDRV_PCM_INFO_BLOCK_TRANSFER |
-				 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
-	formats:		SNDRV_PCM_FMTBIT_S16_LE,
-	rates:			(SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
-                                 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |\
-				 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
-				 SNDRV_PCM_RATE_KNOT),
-	rate_min:		8000,
-	rate_max:		48000,
-	channels_min:		2,
-	channels_max:		2,
-	buffer_bytes_max:	16380,
-	period_bytes_min:	64,
-	period_bytes_max:	8190, /* <= MAX_DMA_SIZE from ams/arch-sa1100/dma.h */
-	periods_min:		2,
-	periods_max:		255,
-	fifo_size:		0,
+	.info			= (SNDRV_PCM_INFO_INTERLEAVED |
+				   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+				   SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
+	.formats		= SNDRV_PCM_FMTBIT_S16_LE,
+	.rates			= (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+                                   SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |\
+				   SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
+				   SNDRV_PCM_RATE_KNOT),
+	.rate_min		= 8000,
+	.rate_max		= 48000,
+	.channels_min		= 2,
+	.channels_max		= 2,
+	.buffer_bytes_max	= 16380,
+	.period_bytes_min	= 64,
+	.period_bytes_max	= 8190, /* <= MAX_DMA_SIZE from ams/arch-sa1100/dma.h */
+	.periods_min		= 2,
+	.periods_max		= 255,
+	.fifo_size		= 0,
 };
 
 /* {{{ snd_card_sa11xx_uda1341_playback functions */
@@ -752,25 +752,25 @@
 /* }}} */
 
 static snd_pcm_ops_t snd_card_sa11xx_uda1341_playback_ops = {
-	open:			snd_card_sa11xx_uda1341_playback_open,
-	close:			snd_card_sa11xx_uda1341_playback_close,
-	ioctl:			snd_card_sa11xx_uda1341_playback_ioctl,
-	hw_params:	        snd_sa11xx_uda1341_hw_params,
-	hw_free:	        snd_sa11xx_uda1341_hw_free,
-	prepare:		snd_card_sa11xx_uda1341_playback_prepare,
-	trigger:		snd_card_sa11xx_uda1341_playback_trigger,
-	pointer:		snd_card_sa11xx_uda1341_playback_pointer,
+	.open			= snd_card_sa11xx_uda1341_playback_open,
+	.close			= snd_card_sa11xx_uda1341_playback_close,
+	.ioctl			= snd_card_sa11xx_uda1341_playback_ioctl,
+	.hw_params	        = snd_sa11xx_uda1341_hw_params,
+	.hw_free	        = snd_sa11xx_uda1341_hw_free,
+	.prepare		= snd_card_sa11xx_uda1341_playback_prepare,
+	.trigger		= snd_card_sa11xx_uda1341_playback_trigger,
+	.pointer		= snd_card_sa11xx_uda1341_playback_pointer,
 };
 
 static snd_pcm_ops_t snd_card_sa11xx_uda1341_capture_ops = {
-	open:			snd_card_sa11xx_uda1341_capture_open,
-	close:			snd_card_sa11xx_uda1341_capture_close,
-	ioctl:			snd_card_sa11xx_uda1341_capture_ioctl,
-	hw_params:	        snd_sa11xx_uda1341_hw_params,
-	hw_free:	        snd_sa11xx_uda1341_hw_free,
-	prepare:		snd_card_sa11xx_uda1341_capture_prepare,
-	trigger:		snd_card_sa11xx_uda1341_capture_trigger,
-	pointer:		snd_card_sa11xx_uda1341_capture_pointer,
+	.open			= snd_card_sa11xx_uda1341_capture_open,
+	.close			= snd_card_sa11xx_uda1341_capture_close,
+	.ioctl			= snd_card_sa11xx_uda1341_capture_ioctl,
+	.hw_params	        = snd_sa11xx_uda1341_hw_params,
+	.hw_free	        = snd_sa11xx_uda1341_hw_free,
+	.prepare		= snd_card_sa11xx_uda1341_capture_prepare,
+	.trigger		= snd_card_sa11xx_uda1341_capture_trigger,
+	.pointer		= snd_card_sa11xx_uda1341_capture_pointer,
 };
 
 static int __init snd_card_sa11xx_uda1341_pcm(sa11xx_uda1341_t *sa11xx_uda1341, int device, int substreams)
diff -Nru a/sound/oss/es1371.c b/sound/oss/es1371.c
--- a/sound/oss/es1371.c	Sat Aug 10 18:42:21 2002
+++ b/sound/oss/es1371.c	Sat Aug 10 18:42:21 2002
@@ -2972,6 +2972,11 @@
  err_gp:
 	if (s->gameport.io)
 		release_region(s->gameport.io, JOY_EXTENT);
+#ifdef ES1371_DEBUG
+	if (s->ps)
+		remove_proc_entry("es1371", NULL);
+#endif
+	unregister_sound_midi(s->dev_midi);
  err_dev4:
 	unregister_sound_dsp(s->dev_dac);
  err_dev3:
diff -Nru a/sound/oss/esssolo1.c b/sound/oss/esssolo1.c
--- a/sound/oss/esssolo1.c	Sat Aug 10 18:42:21 2002
+++ b/sound/oss/esssolo1.c	Sat Aug 10 18:42:21 2002
@@ -2384,9 +2384,9 @@
 	return 0;
 
  err:
-	unregister_sound_dsp(s->dev_dmfm);
+	unregister_sound_special(s->dev_dmfm);
  err_dev4:
-	unregister_sound_dsp(s->dev_midi);
+	unregister_sound_midi(s->dev_midi);
  err_dev3:
 	unregister_sound_mixer(s->dev_mixer);
  err_dev2:
@@ -2397,13 +2397,13 @@
  err_irq:
 	if (s->gameport.io)
 		release_region(s->gameport.io, GAMEPORT_EXTENT);
-	release_region(s->iobase, IOBASE_EXTENT);
+	release_region(s->mpubase, MPUBASE_EXTENT);
  err_region4:
-	release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
- err_region3:
 	release_region(s->ddmabase, DDMABASE_EXTENT);
+ err_region3:
+	release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
  err_region2:
-	release_region(s->mpubase, MPUBASE_EXTENT);
+	release_region(s->iobase, IOBASE_EXTENT);
  err_region1:
 	kfree(s);
 	return ret;
