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

diff -urN linux-2.5.70-bk10/Documentation/00-INDEX linux-2.5.70-bk11/Documentation/00-INDEX
--- linux-2.5.70-bk10/Documentation/00-INDEX	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk11/Documentation/00-INDEX	2003-06-06 04:38:19.000000000 -0700
@@ -182,6 +182,8 @@
 	- short guide on how to set up and use the RAM disk.
 riscom8.txt
 	- notes on using the RISCom/8 multi-port serial driver.
+rocket.txt
+	- info on installing/using the Comtrol RocketPort multiport serial driver
 rtc.txt
 	- notes on how to use the Real Time Clock (aka CMOS clock) driver.
 s390/
diff -urN linux-2.5.70-bk10/Documentation/DocBook/Makefile linux-2.5.70-bk11/Documentation/DocBook/Makefile
--- linux-2.5.70-bk10/Documentation/DocBook/Makefile	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk11/Documentation/DocBook/Makefile	2003-06-06 04:38:19.000000000 -0700
@@ -11,7 +11,8 @@
 	    kernel-locking.sgml via-audio.sgml mousedrivers.sgml \
 	    deviceiobook.sgml procfs-guide.sgml tulip-user.sgml \
 	    writing_usb_driver.sgml scsidrivers.sgml sis900.sgml \
-	    kernel-api.sgml journal-api.sgml lsm.sgml usb.sgml
+	    kernel-api.sgml journal-api.sgml lsm.sgml usb.sgml \
+	    gadget.sgml
 
 ###
 # The build process is as follows (targets):
diff -urN linux-2.5.70-bk10/Documentation/DocBook/gadget.tmpl linux-2.5.70-bk11/Documentation/DocBook/gadget.tmpl
--- linux-2.5.70-bk10/Documentation/DocBook/gadget.tmpl	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk11/Documentation/DocBook/gadget.tmpl	2003-06-06 04:38:19.000000000 -0700
@@ -0,0 +1,966 @@
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[]>
+<book id="USB-Gadget-API">
+  <bookinfo>
+    <title>USB Gadget API for Linux</title>
+    <date>02 June 2003</date>
+    <edition>02 June 2003</edition>
+  
+    <legalnotice>
+      <para>Permission is granted to copy, distribute, and/or modify
+      this document under the terms of the GNU Free Documentation
+      License, version 1.2, or any later version published by the
+      Free Software Foundation; with the Invariant Sections being
+      the "GNU Free Documentation License",
+      no Front-Cover Texts,
+      and
+      no Back-Cover Texts.
+      </para>
+      
+      <para>This documentation 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 Free Documentation License for more details.
+      </para>
+
+      <para>Note that certain sections of this document are merged
+      into Linux kernel source code.
+      That content is the bulk of 
+      <xref linkend="core" /> and
+      <xref linkend="utils" />,
+      where the "GNU Free Documentation License" is identified
+      as an alternate licence for its documentation.
+      </para>
+
+    </legalnotice>
+    <copyright>
+      <year>2003</year>
+      <holder>David Brownell</holder>
+    </copyright>
+
+    <author>
+      <firstname>David</firstname> 
+      <surname>Brownell</surname>
+      <affiliation>
+        <address><email>dbrownell@users.sourceforge.net</email></address>
+      </affiliation>
+    </author>
+  </bookinfo>
+
+<toc></toc>
+
+<chapter><title>Introduction</title>
+
+<para>This document presents a Linux-USB "Gadget"
+kernel mode
+API, for use within peripherals and other USB devices
+that embed Linux.
+It provides an overview of the API structure,
+and shows how that fits into a system development project.
+This is the first such API released on Linux to address
+a number of important problems, including: </para>
+
+<itemizedlist>
+    <listitem><para>Supports USB 2.0, for high speed devices which
+	can stream data at several dozen megabytes per second.
+	</para></listitem>
+    <listitem><para>Handles devices with dozens of endpoints just as
+	well as ones with just two fixed-function ones.  Gadget drivers
+	can be written so they're easy to port to new hardware.
+	</para></listitem>
+    <listitem><para>Flexible enough to expose more complex USB device
+	capabilities such as multiple configurations, multiple interfaces,
+	composite devices,
+	and alternate interface settings.
+	</para></listitem>
+    <listitem><para>Sharing data structures and API models with the
+	Linux-USB host side API.  This looks forward to USB "On-The-Go"
+	(OTG) and similar more-symmetric frameworks.
+	</para></listitem>
+    <listitem><para>Minimalist, so it's easier to support new device
+	controller hardware.  I/O processing doesn't imply large
+	demands for memory or CPU resources.
+	</para></listitem>
+</itemizedlist>
+
+
+<para>Most Linux developers will not be able to use this API, since they
+have USB "host" hardware in a PC, workstation, or server.
+Linux users with embedded systems are more likely to
+have USB peripheral hardware.
+To distinguish drivers running inside such hardware from the
+more familiar Linux "USB device drivers",
+which are host side proxies for the real USB devices,
+a different term is used:
+the drivers inside the peripherals are "USB gadget drivers".
+In USB protocol interactions, the device driver is the master
+(or "client driver")
+and the gadget driver is the slave (or "function driver").
+</para>
+
+<para>The gadget API resembles the host side Linux-USB API in that both
+use queues of request objects to package I/O buffers, and those requests
+may be submitted or canceled.
+They share common definitions for the standard USB
+<emphasis>Chapter 9</emphasis> messages, structures, and constants.
+Also, both APIs bind and unbind drivers to devices.
+The APIs differ in detail, since the host side's current
+URB framework exposes a number of implementation details
+and assumptions that are inappropriate for a gadget API.
+While the model for control transfers and configuration
+management is necessarily different (one side is a hardware-neutral master,
+the other is a hardware-aware slave), the endpoint I/0 API used here
+should also be usable for an overhead-reduced host side API.
+</para>
+
+</chapter>
+
+<chapter id="structure"><title>Structure of Gadget Drivers</title>
+
+<para>A system running inside a USB peripheral
+normally has at least three layers inside the kernel to handle
+USB protocol processing, and may have additional layers in
+user space code.
+The "gadget" API is used by the middle layer to interact
+with the lowest level (which directly handles hardware).
+</para>
+
+<para>In Linux, from the bottom up, these layers are:
+</para>
+
+<variablelist>
+
+    <varlistentry>
+        <term><emphasis>USB Controller Driver</emphasis></term>
+
+	<listitem>
+	<para>This is the lowest software level.
+	It is the only layer that talks to hardware,
+	through registers, fifos, dma, irqs, and the like.
+	The <filename>&lt;linux/usb_gadget.h&gt;</filename> API abstracts
+	the peripheral controller endpoint hardware.
+	That hardware is exposed through endpoint objects, which accept
+	streams of IN/OUT buffers, and through callbacks that interact
+	with gadget drivers.
+	Since normal USB devices only have one upstream
+	port, they only have one of these drivers.
+	The controller driver can support any number of different
+	gadget drivers, but only one of them can be used at a time.
+	</para>
+
+	<para>Examples of such controller hardware include
+	the PCI-based NetChip 2280 USB 2.0 high speed controller,
+	the SA-11x0 or PXA-25x UDC (found within many PDAs),
+	and a variety of other products.
+	</para>
+	</listitem></varlistentry>
+
+    <varlistentry>
+	<term><emphasis>Gadget Driver</emphasis></term>
+
+	<listitem>
+	<para>The lower boundary of this driver implements hardware-neutral
+	USB functions, using calls to the controller driver.
+	Because such hardware varies widely in capabilities and restrictions,
+	the gadget driver is normally configured at compile time
+	to work with endpoints supported by one particular controller.
+	Gadget drivers may be portable to several different controllers,
+	using conditional compilation.
+	Gadget driver responsibilities include:
+	</para>
+	<itemizedlist>
+	    <listitem><para>handling setup requests (ep0 protocol responses)
+		possibly including class-specific functionality
+		</para></listitem>
+	    <listitem><para>returning configuration and string descriptors
+		</para></listitem>
+	    <listitem><para>(re)setting configurations and interface
+		altsettings, including enabling and configuring endpoints
+		</para></listitem>
+	    <listitem><para>handling life cycle events, such as managing
+		bindings
+	        to hardware, and disconnection from the USB host.
+		</para></listitem>
+	    <listitem><para>managing IN and OUT transfers on all currently
+		enabled endpoints
+		</para></listitem>
+	</itemizedlist>
+
+	<para>
+	Such drivers may be modules of proprietary code, although
+	that approach is discouraged in the Linux community.
+	</para>
+	</listitem></varlistentry>
+
+    <varlistentry>
+	<term><emphasis>Upper Level</emphasis></term>
+
+	<listitem>
+	<para>Most gadget drivers have an upper boundary that connects
+	to some Linux driver or framework in Linux.
+	Through that boundary flows the data which the gadget driver
+	produces and/or consumes through protocol transfers over USB.
+	Examples include:
+	</para>
+	<itemizedlist>
+	    <listitem><para>user mode code, using generic (gadgetfs)
+	        or application specific files in
+		<filename>/dev</filename>
+		</para></listitem>
+	    <listitem><para>networking subsystem (for network gadgets,
+		like the CDC Ethernet Model gadget driver)
+		</para></listitem>
+	    <listitem><para>data capture drivers, perhaps video4Linux or
+		 a scanner driver; or test and measurement hardware.
+		 </para></listitem>
+	    <listitem><para>input subsystem (for HID gadgets)
+		</para></listitem>
+	    <listitem><para>sound subsystem (for audio gadgets)
+		</para></listitem>
+	    <listitem><para>file system (for PTP gadgets)
+		</para></listitem>
+	    <listitem><para>block i/o subsystem (for usb-storage gadgets)
+		</para></listitem>
+	    <listitem><para>... and more </para></listitem>
+	</itemizedlist>
+	</listitem></varlistentry>
+
+    <varlistentry>
+	<term><emphasis>Additional Layers</emphasis></term>
+
+	<listitem>
+	<para>Other layers may exist.
+	These could include kernel layers, such as network protocol stacks,
+	as well as user mode applications building on standard POSIX
+	system call APIs such as
+	<emphasis>open()</emphasis>, <emphasis>close()</emphasis>,
+	<emphasis>read()</emphasis> and <emphasis>write()</emphasis>.
+	On newer systems, POSIX Async I/O calls may be an option.
+	Such user mode code will not necessarily be subject to
+	the GNU General Public License (GPL).
+	</para>
+	</listitem></varlistentry>
+
+
+</variablelist>
+
+<para>Over time, reusable utilities should evolve to help make some
+gadget driver tasks simpler.  An example of particular interest
+is code implementing standard USB-IF protocols for
+HID, networking, storage, or audio classes.
+Some developers are interested in KDB or KGDB hooks, to let
+target hardware be remotely debugged.
+Most such USB protocol code doesn't need to be hardware-specific,
+any more than network protocols like X11, HTTP, or NFS are.
+Such interface drivers might be combined, to support composite devices.
+</para>
+
+</chapter>
+
+
+<chapter id="api"><title>Kernel Mode Gadget API</title>
+
+<para>Gadget drivers declare themselves through a
+<emphasis>struct usb_gadget_driver</emphasis>, which is responsible for
+most parts of enumeration for a <emphasis>struct usb_gadget</emphasis>.
+The response to a set_configuration usually involves
+enabling one or more of the <emphasis>struct usb_ep</emphasis> objects
+exposed by the gadget, and submitting one or more
+<emphasis>struct usb_request</emphasis> buffers to transfer data.
+Understand those four data types, and their operations, and
+you will understand how this API works.
+</para> 
+
+<note><title>Incomplete Data Type Descriptions</title>
+
+<para>This documentation was prepared using the standard Linux
+kernel <filename>docproc</filename> tool, which turns text
+and in-code comments into SGML DocBook and then into usable
+formats such as HTML or PDF.
+Other than the "Chapter 9" data types, most of the significant
+data types and functions are described here.
+</para>
+
+<para>However, docproc does not understand all the C constructs
+that are used, so some relevant information is likely omitted from
+what you are reading.  
+One example of such information is several per-request flags.
+You'll have to read the header file, and use example source
+code (such as that for "Gadget Zero"), to fully understand the API.
+</para>
+
+<para>The part of the API implementing some basic
+driver capabilities is specific to the version of the
+Linux kernel that's in use.
+The 2.5 kernel includes a <emphasis>driver model</emphasis>
+framework that has no analogue on earlier kernels;
+so those parts of the gadget API are not fully portable.
+(They are implemented on 2.4 kernels, but in a different way.)
+The driver model state is another part of this API that is
+ignored by the kerneldoc tools.
+</para>
+</note>
+
+<para>The core API does not expose
+every possible hardware feature, only the most widely available ones.
+There are significant hardware features, such as device-to-device DMA
+(without temporary storage in a memory buffer)
+that would be added using hardware-specific APIs.
+</para>
+
+<para>This API expects drivers to use conditional compilation to handle
+endpoint capabilities of different hardware.
+Those tend to have arbitrary restrictions, relating to
+transfer types, addressing, packet sizes, buffering, and availability.
+As a rule, such differences only matter for "endpoint zero" logic
+that handles device configuration and management.
+The API only supports limited run-time
+detection of capabilities, through naming conventions for endpoints.
+Although a gadget driver could scan the endpoints available to it and
+choose to map those capabilities onto driver functionality in some way,
+few drivers will want to reconfigure themselves at run-time.
+</para>
+
+<para>Like the Linux-USB host side API, this API exposes
+the "chunky" nature of USB messages:  I/O requests are in terms
+of one or more "packets", and packet boundaries are visible to drivers.
+Compared to RS-232 serial protocols, USB resembles
+synchronous protocols like HDLC
+(N bytes per frame, multipoint addressing from the host)
+more than asynchronous ones
+(tty style, like 8 bytes, no parity, one stop bit).
+So for example the controller drivers won't buffer
+two single byte writes into a single two-byte USB IN packet,
+although gadget drivers may do so when they implement
+protocols where packet boundaries (and "short packets")
+are not significant.
+</para>
+
+<sect1 id="lifecycle"><title>Driver Life Cycle</title>
+
+<para>Gadget drivers make endpoint I/O requests to hardware without
+needing to know many details of the hardware, but driver
+setup/configuration code needs to handle some differences.
+Use the API like this:
+</para>
+
+<orderedlist numeration='arabic'>
+
+<listitem><para>Register a driver for the particular device side
+usb controller hardware,
+such as the net2280 on PCI (USB 2.0),
+sa11x0 or pxa25x as found in Linux PDAs,
+and so on.
+At this point the device is logically in the USB ch9 initial state
+("attached"), drawing no power and not usable
+(since it does not yet support enumeration).
+</para></listitem>
+
+<listitem><para>Register a gadget driver that implements some higher level
+device function.  That will then bind() to a usb_gadget.
+</para></listitem>
+
+<listitem><para>The hardware driver can now start enumerating.
+The steps it handles are to accept USB power and set_address requests.
+Other steps are handled by the gadget driver.
+If the gadget driver module is unloaded before the host starts to
+enumerate, steps before step 7 are skipped.
+</para></listitem>
+
+<listitem><para>The gadget driver's setup() call returns usb descriptors,
+based both on what the bus interface hardware provides and on the
+functionality being implemented.
+That can involve alternate settings or configurations,
+unless the hardware prevents such operation.
+</para></listitem>
+
+<listitem><para>The gadget driver handles the last step of enumeration,
+when the USB host issues a set_configuration call.
+It enables all endpoints used in that configuration,
+with all interfaces in their default settings.
+That involves using a list of the hardware's endpoints, enabling each
+endpoint according to its descriptor.
+</para></listitem>
+
+<listitem><para>Do real work and perform data transfers, possibly involving
+changes to interface settings or switching to new configurations, until the
+device is disconnect()ed from the host.
+Queue any number of transfer requests to each endpoint.
+The drivers then go back to step 3 (above).
+</para></listitem>
+
+<listitem><para>When the gadget driver module is being unloaded,
+the driver unbind() callback is issued.  That lets the controller
+driver be unloaded.
+</para></listitem>
+
+</orderedlist>
+
+<para>Drivers will normally be arranged so that just loading the
+gadget driver module (or statically linking it into a Linux kernel)
+allows the peripheral device to be enumerated.
+Note that at this lowest level there are no policies about how
+ep0 configuration logic is implemented,
+except that it should obey USB specifications.
+Such issues are in the domain of gadget drivers,
+including knowing about implementation constraints
+imposed by some USB controllers
+or understanding that composite devices might happen to
+be built by integrating reusable components.
+</para>
+
+</sect1>
+
+<sect1 id="ch9"><title>USB 2.0 Chapter 9 Types and Constants</title>
+
+<para>Gadget drivers
+rely on common USB structures and constants
+defined in the
+<filename>&lt;linux/usb_ch9.h&gt;</filename>
+header file, which is standard in Linux 2.5 kernels.
+These are the same types and constants used by host
+side drivers.
+</para>
+
+!Iinclude/linux/usb_ch9.h
+</sect1>
+
+<sect1 id="core"><title>Core Objects and Methods</title>
+
+<para>These are declared in
+<filename>&lt;linux/usb_gadget.h&gt;</filename>,
+and are used by gadget drivers to interact with
+USB peripheral controller drivers.
+</para>
+
+	<!-- yeech, this is ugly in nsgmls PDF output.
+
+	     the PDF bookmark and refentry output nesting is wrong,
+	     and the member/argument documentation indents ugly.
+
+	     plus something (docproc?) adds whitespace before the
+	     descriptive paragraph text, so it can't line up right
+	     unless the explanations are trivial.
+	  -->
+
+!Iinclude/linux/usb_gadget.h
+</sect1>
+
+<sect1 id="utils"><title>Optional Utilities</title>
+
+<para>The core API is sufficient for writing a USB Gadget Driver,
+but some optional utilities are provided to simplify common tasks.
+</para>
+
+!Edrivers/usb/gadget/usbstring.c
+</sect1>
+
+</chapter>
+
+<chapter id="controllers"><title>Peripheral Controller Drivers</title>
+
+<para>The first hardware supporting this API is the NetChip 2280
+controller, which supports USB 2.0 high speed and is based on PCI.
+This is the <filename>net2280</filename> driver module.
+The driver supports Linux kernel versions 2.4 and 2.5;
+contact NetChip Technologies for development boards and product
+information.
+</para> 
+
+<!-- !Edrivers/usb/gadget/net2280.c -->
+
+<para>A partial USB simulator,
+the <filename>dummy_hcd</filename> driver, is available.
+It can act like a net2280, a pxa25x, or an sa11x0 in terms
+of available endpoints and device speeds; and it simulates
+control, bulk, and to some extent interrupt transfers.
+That lets you develop some parts of a gadget driver on a normal PC,
+without any special hardware, and perhaps with the assistance
+of tools such as GDB running with User Mode Linux.
+At least one person has expressed interest in adapting that
+approach, hooking it up to a simulator for a microcontroller.
+Such simulators can help debug subsystems where the runtime hardware
+is unfriendly to software development, or is not yet available.
+</para>
+
+<para>Support for other controllers is expected to be developed
+and contributed
+over time, as this driver framework evolves.
+</para>
+
+</chapter>
+
+<chapter id="gadget"><title>Gadget Drivers</title>
+
+<para>In addition to <emphasis>Gadget Zero</emphasis>
+(used primarily for testing and development with drivers
+for usb controller hardware), other gadget drivers exist.
+</para>
+
+<para>There's an <emphasis>ethernet</emphasis> gadget
+driver, which implements one of the most useful
+<emphasis>Communications Device Class</emphasis> models.  
+One of the standards for cable modem interoperability even
+specifies the use of this ethernet model as one of two
+mandatory options.
+Gadgets using this code look to a USB host as if they're
+an Ethernet adapter.
+It provides access to a network where the gadget's CPU is one host,
+which could easily be bridging, routing, or firewalling
+access to other networks.
+</para>
+
+<para>There is also support for user mode gadget drivers,
+using <emphasis>gadgetfs</emphasis>.
+This provides a <emphasis>User Mode API</emphasis> that presents
+each endpoint as a single file descriptor.  I/O is done using
+normal <emphasis>read()</emphasis> and <emphasis>read()</emphasis> calls.
+Familiar tools like GDB and pthreads can be used to
+develop and debug user mode drivers, so that once a robust
+controller driver is available many applications for it
+won't require new kernel mode software.
+</para>
+
+<para>Support for other kinds of gadget is expected to
+be developed and contributed
+over time, as this driver framework evolves.
+</para>
+
+</chapter>
+
+
+<appendix id="gfdl">
+<title>GNU Free Documentation License</title>
+<subtitle>Version 1.2, November 2002</subtitle>
+
+<blockquote id="fsf-copyright">
+ <para>Copyright (C) 2000,2001,2002  Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.</para>
+</blockquote>
+
+<sect1 id="gfdl-0"><title>PREAMBLE</title>
+
+<para>The purpose of this License is to make a manual, textbook, or
+other functional and useful document "free" in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it, with
+or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible for
+modifications made by others.</para>
+
+<para>This License is a kind of "copyleft", which means that derivative
+works of the document must themselves be free in the same sense.  It
+complements the GNU General Public License, which is a copyleft license
+designed for free software.</para>
+
+<para>We have designed this License in order to use it for manuals for
+free software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does.  But this License is not limited to software manuals; it
+can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book.  We recommend this License
+principally for works whose purpose is instruction or reference.</para>
+</sect1>
+
+<sect1 id="gfdl-1"><title>APPLICABILITY AND DEFINITIONS</title>
+
+<para id="gfdl-doc">This License applies to any manual or other work, in
+any medium, that contains a notice placed by the copyright holder saying
+it can be distributed under the terms of this License.  Such a notice
+grants a world-wide, royalty-free license, unlimited in duration, to use
+that work under the conditions stated herein.  The "Document", below,
+refers to any such manual or work.  Any member of the public is a
+licensee, and is addressed as "you".  You accept the license if you
+copy, modify or distribute the work in a way requiring permission under
+copyright law.</para>
+
+<para id="gfdl-mod-ver">A "Modified Version" of the Document means any
+work containing the Document or a portion of it, either copied verbatim,
+or with modifications and/or translated into another language.</para>
+
+<para id="gfdl-secnd-sect">A "Secondary Section" is a named appendix or
+a front-matter section of the Document that deals exclusively with the
+relationship of the publishers or authors of the Document to the
+Document's overall subject (or to related matters) and contains nothing
+that could fall directly within that overall subject.  (Thus, if the
+Document is in part a textbook of mathematics, a Secondary Section may
+not explain any mathematics.)  The relationship could be a matter of
+historical connection with the subject or with related matters, or of
+legal, commercial, philosophical, ethical or political position
+regarding them.</para>
+
+<para id="gfdl-inv-sect">The "Invariant Sections" are certain Secondary
+Sections whose titles are designated, as being those of Invariant
+Sections, in the notice that says that the Document is released under
+this License.  If a section does not fit the above definition of
+Secondary then it is not allowed to be designated as Invariant.  The
+Document may contain zero Invariant Sections.  If the Document does not
+identify any Invariant Sections then there are none.</para>
+
+<para id="gfdl-cov-text">The "Cover Texts" are certain short passages of
+text that are listed, as Front-Cover Texts or Back-Cover Texts, in the
+notice that says that the Document is released under this License.  A
+Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at
+most 25 words.</para>
+
+<para id="gfdl-transparent">A "Transparent" copy of the Document means a
+machine-readable copy, represented in a format whose specification is
+available to the general public, that is suitable for revising the
+document straightforwardly with generic text editors or (for images
+composed of pixels) generic paint programs or (for drawings) some widely
+available drawing editor, and that is suitable for input to text
+formatters or for automatic translation to a variety of formats suitable
+for input to text formatters.  A copy made in an otherwise Transparent
+file format whose markup, or absence of markup, has been arranged to
+thwart or discourage subsequent modification by readers is not
+Transparent.  An image format is not Transparent if used for any
+substantial amount of text.  A copy that is not "Transparent" is called
+"Opaque".</para>
+
+<para>Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, LaTeX input format, SGML or
+XML using a publicly available DTD, and standard-conforming simple HTML,
+PostScript or PDF designed for human modification.  Examples of
+transparent image formats include PNG, XCF and JPG.  Opaque formats
+include proprietary formats that can be read and edited only by
+proprietary word processors, SGML or XML for which the DTD and/or
+processing tools are not generally available, and the machine-generated
+HTML, PostScript or PDF produced by some word processors for output
+purposes only.</para>
+
+<para id="gfdl-title-page">The "Title Page" means, for a printed book,
+the title page itself, plus such following pages as are needed to hold,
+legibly, the material this License requires to appear in the title page.
+For works in formats which do not have any title page as such, "Title
+Page" means the text near the most prominent appearance of the work's
+title, preceding the beginning of the body of the text.</para>
+
+<para id="gfdl-entitled">A section "Entitled XYZ" means a named subunit
+of the Document whose title either is precisely XYZ or contains XYZ in
+parentheses following text that translates XYZ in another language.
+(Here XYZ stands for a specific section name mentioned below, such as
+"Acknowledgements", "Dedications", "Endorsements", or "History".)  To
+"Preserve the Title" of such a section when you modify the Document
+means that it remains a section "Entitled XYZ" according to this
+definition.</para>
+
+<para>The Document may include Warranty Disclaimers next to the notice
+which states that this License applies to the Document.  These Warranty
+Disclaimers are considered to be included by reference in this License,
+but only as regards disclaiming warranties: any other implication that
+these Warranty Disclaimers may have is void and has no effect on the
+meaning of this License.</para>
+</sect1>
+
+<sect1 id="gfdl-2"><title>VERBATIM COPYING</title>
+
+<para>You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies to
+the Document are reproduced in all copies, and that you add no other
+conditions whatsoever to those of this License.  You may not use
+technical measures to obstruct or control the reading or further copying
+of the copies you make or distribute.  However, you may accept
+compensation in exchange for copies.  If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+</para>
+
+<para>You may also lend copies, under the same conditions stated above,
+and you may publicly display copies.</para>
+</sect1>
+
+<sect1 id="gfdl-3"><title>COPYING IN QUANTITY</title>
+
+<para>If you publish printed copies (or copies in media that commonly
+have printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover Texts:
+Front-Cover Texts on the front cover, and Back-Cover Texts on the back
+cover.  Both covers must also clearly and legibly identify you as the
+publisher of these copies.  The front cover must present the full title
+with all words of the title equally prominent and visible.  You may add
+other material on the covers in addition.  Copying with changes limited
+to the covers, as long as they preserve the title of the Document and
+satisfy these conditions, can be treated as verbatim copying in other
+respects.</para>
+
+<para>If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.</para>
+
+<para>If you publish or distribute Opaque copies of the Document
+numbering more than 100, you must either include a machine-readable
+Transparent copy along with each Opaque copy, or state in or with each
+Opaque copy a computer-network location from which the general
+network-using public has access to download using public-standard
+network protocols a complete Transparent copy of the Document, free of
+added material.  If you use the latter option, you must take reasonably
+prudent steps, when you begin distribution of Opaque copies in quantity,
+to ensure that this Transparent copy will remain thus accessible at the
+stated location until at least one year after the last time you
+distribute an Opaque copy (directly or through your agents or retailers)
+of that edition to the public.</para>
+
+<para>It is requested, but not required, that you contact the authors of
+the Document well before redistributing any large number of copies, to
+give them a chance to provide you with an updated version of the
+Document.</para>
+</sect1>
+
+<sect1 id="gfdl-4"><title>MODIFICATIONS</title>
+
+<para>You may copy and distribute a Modified Version of the Document
+under the conditions of sections 2 and 3 above, provided that you
+release the Modified Version under precisely this License, with the
+Modified Version filling the role of the Document, thus licensing
+distribution and modification of the Modified Version to whoever
+possesses a copy of it.  In addition, you must do these things in the
+Modified Version:</para>
+
+<orderedlist id="gfdl-modif-cond" numeration="upperalpha">
+<listitem><simpara>Use in the Title Page (and on the covers, if any) a
+  title distinct from that of the Document, and from those of previous
+  versions (which should, if there were any, be listed in the History
+  section of the Document).  You may use the same title as a previous
+  version if the original publisher of that version gives permission.
+</simpara></listitem>
+<listitem><simpara>List on the Title Page, as authors, one or more
+  persons or entities responsible for authorship of the modifications in
+  the Modified Version, together with at least five of the principal
+  authors of the Document (all of its principal authors, if it has fewer
+  than five), unless they release you from this requirement.
+</simpara></listitem>
+<listitem><simpara>State on the Title page the name of the publisher of
+  the Modified Version, as the publisher.</simpara></listitem>
+<listitem><simpara>Preserve all the copyright notices of the Document.
+</simpara></listitem>
+<listitem><simpara>Add an appropriate copyright notice for your
+  modifications adjacent to the other copyright notices.
+</simpara></listitem>
+<listitem><simpara>Include, immediately after the copyright notices, a
+  license notice giving the public permission to use the Modified
+  Version under the terms of this License, in the form shown in the
+  <link linkend="gfdl-addendum">Addendum</link> below.
+</simpara></listitem>
+<listitem><simpara>Preserve in that license notice the full lists of
+  Invariant Sections and required Cover Texts given in the Document's
+  license notice.</simpara></listitem>
+<listitem><simpara>Include an unaltered copy of this License.
+</simpara></listitem>
+<listitem><simpara>Preserve the section Entitled "History", Preserve its
+  Title, and add to it an item stating at least the title, year, new
+  authors, and publisher of the Modified Version as given on the Title
+  Page.  If there is no section Entitled "History" in the Document,
+  create one stating the title, year, authors, and publisher of the
+  Document as given on its Title Page, then add an item describing the
+  Modified Version as stated in the previous sentence.
+</simpara></listitem>
+<listitem><simpara>Preserve the network location, if any, given in the
+  Document for public access to a Transparent copy of the Document, and
+  likewise the network locations given in the Document for previous
+  versions it was based on.  These may be placed in the "History"
+  section.  You may omit a network location for a work that was
+  published at least four years before the Document itself, or if the
+  original publisher of the version it refers to gives permission.
+</simpara></listitem>
+<listitem><simpara>For any section Entitled "Acknowledgements" or
+  "Dedications", Preserve the Title of the section, and preserve in the
+  section all the substance and tone of each of the contributor
+  acknowledgements and/or dedications given therein.
+</simpara></listitem>
+<listitem><simpara>Preserve all the Invariant Sections of the Document,
+  unaltered in their text and in their titles.  Section numbers or the
+  equivalent are not considered part of the section titles.
+</simpara></listitem>
+<listitem><simpara>Delete any section Entitled "Endorsements".
+  Such a section may not be included in the Modified Version.
+</simpara></listitem>
+<listitem><simpara>Do not retitle any existing section to be Entitled
+  "Endorsements" or to conflict in title with any Invariant Section.
+</simpara></listitem>
+<listitem><simpara>Preserve any Warranty Disclaimers.
+</simpara></listitem>
+</orderedlist>
+
+<para>If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant.  To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.</para>
+
+<para>You may add a section Entitled "Endorsements", provided it
+contains nothing but endorsements of your Modified Version by various
+parties--for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.</para>
+
+<para>You may add a passage of up to five words as a Front-Cover Text,
+and a passage of up to 25 words as a Back-Cover Text, to the end of the
+list of Cover Texts in the Modified Version.  Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or through
+arrangements made by) any one entity.  If the Document already includes
+a cover text for the same cover, previously added by you or by
+arrangement made by the same entity you are acting on behalf of, you may
+not add another; but you may replace the old one, on explicit permission
+from the previous publisher that added the old one.</para>
+
+<para>The author(s) and publisher(s) of the Document do not by this
+License give permission to use their names for publicity for or to
+assert or imply endorsement of any Modified Version.</para>
+</sect1>
+
+<sect1 id="gfdl-5"><title>COMBINING DOCUMENTS</title>
+
+<para>You may combine the Document with other documents released under
+this License, under the terms defined in <link linkend="gfdl-4">section
+4</link> above for modified versions, provided that you include in the
+combination all of the Invariant Sections of all of the original
+documents, unmodified, and list them all as Invariant Sections of your
+combined work in its license notice, and that you preserve all their
+Warranty Disclaimers.</para>
+
+<para>The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy.  If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by adding
+at the end of it, in parentheses, the name of the original author or
+publisher of that section if known, or else a unique number.  Make the
+same adjustment to the section titles in the list of Invariant Sections
+in the license notice of the combined work.</para>
+
+<para>In the combination, you must combine any sections Entitled
+"History" in the various original documents, forming one section
+Entitled "History"; likewise combine any sections Entitled
+"Acknowledgements", and any sections Entitled "Dedications".  You must
+delete all sections Entitled "Endorsements".</para>
+</sect1>
+
+<sect1 id="gfdl-6"><title>COLLECTIONS OF DOCUMENTS</title>
+
+<para>You may make a collection consisting of the Document and other
+documents released under this License, and replace the individual copies
+of this License in the various documents with a single copy that is
+included in the collection, provided that you follow the rules of this
+License for verbatim copying of each of the documents in all other
+respects.</para>
+
+<para>You may extract a single document from such a collection, and
+distribute it individually under this License, provided you insert a
+copy of this License into the extracted document, and follow this
+License in all other respects regarding verbatim copying of that
+document.</para>
+</sect1>
+
+<sect1 id="gfdl-7"><title>AGGREGATION WITH INDEPENDENT WORKS</title>
+
+<para>A compilation of the Document or its derivatives with other
+separate and independent documents or works, in or on a volume of a
+storage or distribution medium, is called an "aggregate" if the
+copyright resulting from the compilation is not used to limit the legal
+rights of the compilation's users beyond what the individual works
+permit.  When the Document is included an aggregate, this License does
+not apply to the other works in the aggregate which are not themselves
+derivative works of the Document.</para>
+
+<para>If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on covers
+that bracket the Document within the aggregate, or the electronic
+equivalent of covers if the Document is in electronic form.  Otherwise
+they must appear on printed covers that bracket the whole
+aggregate.</para>
+</sect1>
+
+<sect1 id="gfdl-8"><title>TRANSLATION</title>
+
+<para>Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections.  You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers.  In case of a disagreement between the
+translation and the original version of this License or a notice or
+disclaimer, the original version will prevail.</para>
+
+<para>If a section in the Document is Entitled "Acknowledgements",
+"Dedications", or "History", the requirement (section 4) to Preserve its
+Title (section 1) will typically require changing the actual
+title.</para>
+</sect1>
+
+<sect1 id="gfdl-9"><title>TERMINATION</title>
+
+<para>You may not copy, modify, sublicense, or distribute the Document
+except as expressly provided for under this License.  Any other attempt
+to copy, modify, sublicense or distribute the Document is void, and will
+automatically terminate your rights under this License.  However,
+parties who have received copies, or rights, from you under this License
+will not have their licenses terminated so long as such parties remain
+in full compliance.</para>
+</sect1>
+
+<sect1 id="gfdl-10"><title>FUTURE REVISIONS OF THIS LICENSE</title>
+
+<para>The Free Software Foundation may publish new, revised versions of
+the GNU Free Documentation License from time to time.  Such new versions
+will be similar in spirit to the present version, but may differ in
+detail to address new problems or concerns.  See
+http://www.gnu.org/copyleft/.</para>
+
+<para>Each version of the License is given a distinguishing version
+number.  If the Document specifies that a particular numbered version of
+this License "or any later version" applies to it, you have the option
+of following the terms and conditions either of that specified version
+or of any later version that has been published (not as a draft) by the
+Free Software Foundation.  If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation.</para>
+</sect1>
+
+<sect1 id="gfdl-addendum"><title>ADDENDUM: How to use this License for
+  your documents</title>
+
+<para>To use this License in a document you have written, include a copy
+of the License in the document and put the following copyright and
+license notices just after the title page:</para>
+
+<blockquote id="copyright-sample"><para>
+    Copyright (c)  YEAR  YOUR NAME.
+    Permission is granted to copy, distribute and/or modify this document
+    under the terms of the GNU Free Documentation License, Version 1.2
+    or any later version published by the Free Software Foundation;
+    with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+    A copy of the license is included in the section entitled "GNU
+    Free Documentation License".
+</para></blockquote>
+
+<para>If you have Invariant Sections, Front-Cover Texts and Back-Cover
+Texts, replace the "with...Texts." line with this:</para>
+
+<blockquote id="inv-cover-sample"><para>
+    with the Invariant Sections being LIST THEIR TITLES, with the
+    Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+</para></blockquote>
+
+<para>If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.</para>
+
+<para>If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of free
+software license, such as the GNU General Public License, to permit
+their use in free software.</para>
+</sect1>
+</appendix>
+
+</book>
+<!--
+	vim:syntax=sgml:sw=4
+-->
diff -urN linux-2.5.70-bk10/Documentation/rocket.txt linux-2.5.70-bk11/Documentation/rocket.txt
--- linux-2.5.70-bk10/Documentation/rocket.txt	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk11/Documentation/rocket.txt	2003-06-06 04:38:19.000000000 -0700
@@ -0,0 +1,87 @@
+Comtrol(tm) RocketPort(R)/RocketModem(TM) Series 
+Device Driver for the Linux Operating System
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+PRODUCT OVERVIEW
+----------------
+
+This driver provides a loadable kernel driver for the Comtrol RocketPort
+and RocketModem PCI boards. These boards provide, 2, 4, 8, 16, or 32 
+high-speed serial ports or modems.  This driver supports up to a combination
+of four RocketPort or RocketModems boards in one machine simultaneously.
+This file assumes that you are using the RocketPort driver which is
+integrated into the kernel sources.  
+
+The driver can also be installed as an external module using the usual 
+"make;make install" routine.  This external module driver, obtainable 
+from the Comtrol website listed below, is useful for updating the driver
+or installing it into kernels which do not have the driver configured
+into them.  Installations instructions for the external module
+are in the included README and HW_INSTALL files.
+
+RocketPort ISA and RocketModem II PCI boards are also supported by this
+driver, but must use the external module driver for configuration reasons.  
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+INSTALLATION PROCEDURES
+-----------------------
+
+RocketPort/RocketModem PCI cards require no driver configuration, they are 
+automatically detected and configured.
+
+The RocketPort driver can be installed as a module (recommended) or built 
+into the kernel. This is selected, as for other drivers, through the `make config`
+command from the root of the Linux source tree during the kernel build process. 
+
+The RocketPort/RocketModem serial ports installed by this driver are assigned
+device major number 46, and will be named /dev/ttyRx, where x is the port number 
+starting at zero (ex. /dev/ttyR0, /devttyR1, ...).  If you have multiple cards
+installed in the system, the mapping of port names to serial ports is displayed
+in the system log at /var/log/messages.
+
+If installed as a module, the module must be loaded.  This can be done
+manually by entering "modprobe rocket".  To have the module loaded automatically
+upon system boot, edit the /etc/modules.conf file and add the line
+"alias char-major-46 rocket".
+
+In order to use the ports, their device names (nodes) must be created with mknod.
+This is only required once, the system will retain the names once created.  To 
+create the RocketPort/RocketModem device names, use the command 
+"mknod /dev/ttyRx c 46 x" where x is the port number starting at zero.  For example:
+
+>mknod /dev/ttyR0 c 46 0
+>mknod /dev/ttyR1 c 46 1
+>mknod /dev/ttyR2 c 46 2  
+
+The Linux script MAKEDEV will create the first 16 ttyRx device names (nodes) for you:
+
+>/dev/MAKEDEV ttyR
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+REPORTING BUGS
+--------------
+
+For technical support, please provide the following
+information: Driver version, kernel release, distribution of
+kernel, and type of board you are using. Error messages and log
+printouts port configuration details are especially helpful.
+
+USA
+    Phone: (612) 494-4100
+      FAX: (612) 494-4199
+    email: support@comtrol.com
+
+Comtrol Europe
+    Phone: +44 (0) 1 869 323-220
+      FAX: +44 (0) 1 869 323-211
+    email: support@comtrol.co.uk
+
+Web:	http://www.comtrol.com
+FTP:	ftp.comtrol.com
+
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+
diff -urN linux-2.5.70-bk10/MAINTAINERS linux-2.5.70-bk11/MAINTAINERS
--- linux-2.5.70-bk10/MAINTAINERS	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk11/MAINTAINERS	2003-06-06 04:38:19.000000000 -0700
@@ -281,6 +281,13 @@
 W:	http://linux-atm.sourceforge.net
 S:	Maintained
 
+ATMEL WIRELESS DRIVER
+P:	Simon Kelley
+M:	simon@thekelleys.org.uk
+W:	http://www.thekelleys.org.uk/atmel
+W:	http://atmelwlandriver.sourceforge.net/
+S:	Maintained
+
 AX.25 NETWORK LAYER
 P:	Ralf Baechle
 M:	ralf@linux-mips.org
@@ -1524,6 +1531,12 @@
 W:	http://www.namesys.com
 S:	Supported
 
+ROCKETPORT DRIVER
+P:	Comtrol Corp.
+M:	support@comtrol.com
+W:	http://www.comtrol.com
+S:	Maintained
+
 ROSE NETWORK LAYER
 P:	Ralf Baechle
 M:	ralf@linux-mips.org
diff -urN linux-2.5.70-bk10/Makefile linux-2.5.70-bk11/Makefile
--- linux-2.5.70-bk10/Makefile	2003-06-06 04:38:11.000000000 -0700
+++ linux-2.5.70-bk11/Makefile	2003-06-06 04:38:19.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 70
-EXTRAVERSION = -bk10
+EXTRAVERSION = -bk11
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -urN linux-2.5.70-bk10/arch/alpha/kernel/core_marvel.c linux-2.5.70-bk11/arch/alpha/kernel/core_marvel.c
--- linux-2.5.70-bk10/arch/alpha/kernel/core_marvel.c	2003-05-26 18:00:22.000000000 -0700
+++ linux-2.5.70-bk11/arch/alpha/kernel/core_marvel.c	2003-06-06 04:38:19.000000000 -0700
@@ -980,7 +980,7 @@
 }
 
 static int 
-marvel_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, agp_memory *mem)
+marvel_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *mem)
 {
 	struct marvel_agp_aperture *aper = agp->aperture.sysdata;
 	return iommu_bind(aper->arena, aper->pg_start + pg_start, 
@@ -988,7 +988,7 @@
 }
 
 static int 
-marvel_agp_unbind_memory(alpha_agp_info *agp, off_t pg_start, agp_memory *mem)
+marvel_agp_unbind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *mem)
 {
 	struct marvel_agp_aperture *aper = agp->aperture.sysdata;
 	return iommu_unbind(aper->arena, aper->pg_start + pg_start,
diff -urN linux-2.5.70-bk10/arch/alpha/kernel/core_titan.c linux-2.5.70-bk11/arch/alpha/kernel/core_titan.c
--- linux-2.5.70-bk10/arch/alpha/kernel/core_titan.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk11/arch/alpha/kernel/core_titan.c	2003-06-06 04:38:19.000000000 -0700
@@ -679,7 +679,7 @@
 }
 
 static int 
-titan_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, agp_memory *mem)
+titan_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *mem)
 {
 	struct titan_agp_aperture *aper = agp->aperture.sysdata;
 	return iommu_bind(aper->arena, aper->pg_start + pg_start, 
@@ -687,7 +687,7 @@
 }
 
 static int 
-titan_agp_unbind_memory(alpha_agp_info *agp, off_t pg_start, agp_memory *mem)
+titan_agp_unbind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *mem)
 {
 	struct titan_agp_aperture *aper = agp->aperture.sysdata;
 	return iommu_unbind(aper->arena, aper->pg_start + pg_start,
diff -urN linux-2.5.70-bk10/arch/alpha/kernel/systbls.S linux-2.5.70-bk11/arch/alpha/kernel/systbls.S
--- linux-2.5.70-bk10/arch/alpha/kernel/systbls.S	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk11/arch/alpha/kernel/systbls.S	2003-06-06 04:38:19.000000000 -0700
@@ -433,6 +433,15 @@
 	.quad sys_set_tid_address
 	.quad sys_restart_syscall
 	.quad sys_fadvise64
+	.quad sys_timer_create
+	.quad sys_timer_settime			/* 415 */
+	.quad sys_timer_gettime
+	.quad sys_timer_getoverrun
+	.quad sys_timer_delete
+	.quad sys_clock_settime
+	.quad sys_clock_gettime			/* 420 */
+	.quad sys_clock_getres
+	.quad sys_clock_nanosleep
 
 	.size sys_call_table, . - sys_call_table
 	.type sys_call_table, @object
diff -urN linux-2.5.70-bk10/arch/cris/drivers/ethernet.c linux-2.5.70-bk11/arch/cris/drivers/ethernet.c
--- linux-2.5.70-bk10/arch/cris/drivers/ethernet.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk11/arch/cris/drivers/ethernet.c	2003-06-06 04:38:19.000000000 -0700
@@ -292,37 +292,19 @@
  */
 
 static int __init
-etrax_ethernet_init(struct net_device *dev)
+etrax_ethernet_init(void)
 {
-	int i;
+	struct net_device *dev;
+	int i, err;
 	int anOffset = 0;
 
 	printk("ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2001 Axis Communications AB\n");
 
-	dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */
-
-	printk("%s initialized\n", dev->name);
-
-	/* make Linux aware of the new hardware  */
-
-	if (!dev) {
-		printk(KERN_WARNING "%s: dev == NULL. Should this happen?\n",
-		       cardname);
-		dev = init_etherdev(dev, sizeof(struct net_local));
-		if (!dev)
-			panic("init_etherdev failed\n");
-	}
-
-	/* setup generic handlers and stuff in the dev struct */
-
-	ether_setup(dev);
-
-	/* make room for the local structure containing stats etc */
-
-	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-	if (dev->priv == NULL)
+	dev = alloc_etherdev(sizeof(struct net_local));
+	if (!dev)
 		return -ENOMEM;
-	memset(dev->priv, 0, sizeof(struct net_local));
+
+	dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */
 
 	/* now setup our etrax specific stuff */
 
@@ -340,10 +322,6 @@
 	dev->do_ioctl           = e100_ioctl;
 	dev->tx_timeout         = e100_tx_timeout;
 
-	/* set the default MAC address */
-
-	e100_set_mac_address(dev, &default_mac);
-
 	/* Initialise the list of Etrax DMA-descriptors */
 
 	/* Initialise receive descriptors */
@@ -371,6 +349,16 @@
 	myLastRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
 	myPrevRxDesc = &RxDescList[NBR_OF_RX_DESC - 1];
 
+	err = register_netdev(dev);
+	if (err) {
+		kfree(dev);
+		return err;
+	}
+
+	/* set the default MAC address */
+
+	e100_set_mac_address(dev, &default_mac);
+
 	/* Initialize speed indicator stuff. */
 
 	current_speed = 10;
@@ -1349,19 +1337,10 @@
 	}
 }
 
-static struct net_device dev_etrax_ethernet;  /* only got one */
-
 static int
 etrax_init_module(void)
 {
-	struct net_device *d = &dev_etrax_ethernet;
-
-	d->init = etrax_ethernet_init;
-
-	if (register_netdev(d) == 0)
-		return 0;
-	else
-		return -ENODEV;
+	return etrax_ethernet_init();
 }
 
 module_init(etrax_init_module);
diff -urN linux-2.5.70-bk10/arch/cris/drivers/lpslave/e100lpslavenet.c linux-2.5.70-bk11/arch/cris/drivers/lpslave/e100lpslavenet.c
--- linux-2.5.70-bk10/arch/cris/drivers/lpslave/e100lpslavenet.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk11/arch/cris/drivers/lpslave/e100lpslavenet.c	2003-06-06 04:38:19.000000000 -0700
@@ -162,37 +162,19 @@
  * (detachable devices only).
  */
 static int __init
-etrax_ethernet_lpslave_init(struct net_device *dev)
+etrax_ethernet_lpslave_init(void)
 {
-	int i;
+	struct net_device *dev;
+	int i, err;
 	int anOffset = 0;
 
 	printk("Etrax/100 lpslave ethernet driver v0.3, (c) 1999 Axis Communications AB\n");
 
-	dev->base_addr = 2;
-
-	printk("%s initialized\n", dev->name);
-
-	/* make Linux aware of the new hardware  */
-
-	if (!dev) {
-		printk(KERN_WARNING "%s: dev == NULL. Should this happen?\n",
-                       cardname);
-		dev = init_etherdev(dev, sizeof(struct net_local));
-		if (!dev)
-			panic("init_etherdev failed\n");
-	}
-
-	/* setup generic handlers and stuff in the dev struct */
-
-	ether_setup(dev);
-
-	/* make room for the local structure containing stats etc */
-
-	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
-	if (dev->priv == NULL)
+	dev = alloc_etherdev(sizeof(struct net_lock));
+	if (!dev)
 		return -ENOMEM;
-	memset(dev->priv, 0, sizeof(struct net_local));
+
+	dev->base_addr = 2;
 
 	/* now setup our etrax specific stuff */
 
@@ -242,7 +224,11 @@
 	TxDescList[0].buf = virt_to_phys(&host_command);
 	TxDescList[0].next = virt_to_phys(&TxDescList[1]);
 
-	return 0;
+	err = register_netdev(dev);
+	if (err)
+		kfree(dev);
+
+	return err;
 }
 
 /* set MAC address of the interface. called from the core after a
@@ -1017,19 +1003,10 @@
 }
 #endif /* ETHDEBUG */
 
-static struct net_device dev_etrax_slave_ethernet;
-
 static int
 etrax_init_module(void)
 {
-	struct net_device *d = &dev_etrax_slave_ethernet;
-
-	d->init = etrax_ethernet_lpslave_init;
-
-	if(register_netdev(d) == 0)
-		return 0;
-	else
-		return -ENODEV;
+	return etrax_ethernet_lpslave_init();
 }
 
 module_init(etrax_init_module);
diff -urN linux-2.5.70-bk10/arch/ia64/hp/sim/simeth.c linux-2.5.70-bk11/arch/ia64/hp/sim/simeth.c
--- linux-2.5.70-bk10/arch/ia64/hp/sim/simeth.c	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk11/arch/ia64/hp/sim/simeth.c	2003-06-06 04:38:19.000000000 -0700
@@ -191,7 +191,7 @@
 	unsigned char mac_addr[ETH_ALEN];
 	struct simeth_local *local;
 	struct net_device *dev;
-	int fd, i;
+	int fd, i, err;
 
 	/*
 	 * XXX Fix me
@@ -207,22 +207,12 @@
 	if (fd == -1)
 		return -ENODEV;
 
-	dev = init_etherdev(NULL, sizeof(struct simeth_local));
+	dev = alloc_etherdev(sizeof(struct simeth_local));
 	if (!dev)
 		return -ENOMEM;
 
 	memcpy(dev->dev_addr, mac_addr, sizeof(mac_addr));
 
-	dev->irq = ia64_alloc_vector();
-
-	/*
-	 * attach the interrupt in the simulator, this does enable interrupts
-	 * until a netdev_attach() is called
-	 */
-	netdev_connect(dev->irq);
-
-	memset(dev->priv, 0, sizeof(struct simeth_local));
-
 	local = dev->priv;
 	local->simfd = fd; /* keep track of underlying file descriptor */
 
@@ -232,8 +222,19 @@
 	dev->get_stats		= simeth_get_stats;
 	dev->set_multicast_list = set_multicast_list; /* no yet used */
 
-	/* Fill in the fields of the device structure with ethernet-generic values. */
-	ether_setup(dev);
+	err = register_netdev(dev);
+	if (dev) {
+		kfree(dev);
+		return err;
+	}
+
+	dev->irq = ia64_alloc_vector();
+
+	/*
+	 * attach the interrupt in the simulator, this does enable interrupts
+	 * until a netdev_attach() is called
+	 */
+	netdev_connect(dev->irq);
 
 	printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr",
 	       dev->name, simeth_device, local->simfd);
@@ -242,7 +243,7 @@
 	}
 	printk(", IRQ %d\n", dev->irq);
 
-		return 0;
+	return 0;
 }
 
 /*
diff -urN linux-2.5.70-bk10/arch/m68k/atari/hades-pci.c linux-2.5.70-bk11/arch/m68k/atari/hades-pci.c
--- linux-2.5.70-bk10/arch/m68k/atari/hades-pci.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk11/arch/m68k/atari/hades-pci.c	2003-06-06 04:38:20.000000000 -0700
@@ -297,14 +297,14 @@
 			    IRQ_TT_MFP_SCC,	/* Slot 2. */
 			    IRQ_TT_MFP_SCSIDMA	/* Slot 3. */
 			  };
-	struct pci_dev *dev;
+	struct pci_dev *dev = NULL;
 	unsigned char slot;
 
 	/*
 	 * Go through all devices, fixing up irqs as we see fit:
 	 */
 
-	for (dev = pci_devices; dev; dev = dev->next)
+	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL)
 	{
 		if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE)
 		{
diff -urN linux-2.5.70-bk10/arch/ppc/8260_io/enet.c linux-2.5.70-bk11/arch/ppc/8260_io/enet.c
--- linux-2.5.70-bk10/arch/ppc/8260_io/enet.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/8260_io/enet.c	2003-06-06 04:38:20.000000000 -0700
@@ -630,19 +630,15 @@
 
 	bd = (bd_t *)__res;
 
-	/* Allocate some private information.
+	/* Create an Ethernet device instance.
 	*/
-	cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
-	if (cep == NULL)
+	dev = alloc_etherdev(sizeof(*cep));
+	if (!dev)
 		return -ENOMEM;
 
-	__clear_user(cep,sizeof(*cep));
+	cep = dev->priv;
 	spin_lock_init(&cep->lock);
 
-	/* Create an Ethernet device instance.
-	*/
-	dev = init_etherdev(0, 0);
-
 	/* Get pointer to SCC area in parameter RAM.
 	*/
 	ep = (scc_enet_t *)(&immap->im_dprambase[PROFF_ENET]);
@@ -771,6 +767,7 @@
 		/* Allocate a page.
 		*/
 		mem_addr = __get_free_page(GFP_KERNEL);
+		/* BUG: no check for failure */
 
 		/* Initialize the BD for every fragment in the page.
 		*/
@@ -808,6 +805,7 @@
 	/* Install our interrupt handler.
 	*/
 	request_irq(SIU_INT_ENET, scc_enet_interrupt, 0, "enet", dev);
+	/* BUG: no check for failure */
 
 	/* Set GSMR_H to enable all normal operating modes.
 	 * Set GSMR_L to enable Ethernet to MC68160.
@@ -837,7 +835,6 @@
 	io->iop_pdatc |= PC_EST8260_ENET_NOTFD;
 
 	dev->base_addr = (unsigned long)ep;
-	dev->priv = cep;
 
 	/* The CPM Ethernet specific entries in the device structure. */
 	dev->open = scc_enet_open;
@@ -852,6 +849,12 @@
 	*/
 	sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
 
+	err = register_netdev(dev);
+	if (err) {
+		kfree(dev);
+		return err;
+	}
+
 	printk("%s: SCC ENET Version 0.1, ", dev->name);
 	for (i=0; i<5; i++)
 		printk("%02x:", dev->dev_addr[i]);
diff -urN linux-2.5.70-bk10/arch/ppc/8260_io/fcc_enet.c linux-2.5.70-bk11/arch/ppc/8260_io/fcc_enet.c
--- linux-2.5.70-bk10/arch/ppc/8260_io/fcc_enet.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/8260_io/fcc_enet.c	2003-06-06 04:38:20.000000000 -0700
@@ -1328,7 +1328,7 @@
 	struct net_device *dev;
 	struct fcc_enet_private *cep;
 	fcc_info_t	*fip;
-	int	i, np;
+	int	i, np, err;
 	volatile	immap_t		*immap;
 	volatile	iop8260_t	*io;
 
@@ -1339,23 +1339,16 @@
 	fip = fcc_ports;
 
 	while (np-- > 0) {
-
-		/* Allocate some private information.
+		/* Create an Ethernet device instance.
 		*/
-		cep = (struct fcc_enet_private *)
-					kmalloc(sizeof(*cep), GFP_KERNEL);
-		if (cep == NULL)
+		dev = alloc_etherdev(sizeof(*cep));
+		if (!dev)
 			return -ENOMEM;
 
-		__clear_user(cep,sizeof(*cep));
+		cep = dev->priv;
 		spin_lock_init(&cep->lock);
 		cep->fip = fip;
 
-		/* Create an Ethernet device instance.
-		*/
-		dev = init_etherdev(0, 0);
-		dev->priv = cep;
-
 		init_fcc_shutdown(fip, cep, immap);
 		init_fcc_ioports(fip, io, immap);
 		init_fcc_param(fip, dev, immap);
@@ -1376,6 +1369,12 @@
 
 		init_fcc_startup(fip, dev);
 
+		err = register_netdev(dev);
+		if (err) {
+			kfree(dev);
+			return err;
+		}
+
 		printk("%s: FCC ENET Version 0.3, ", dev->name);
 		for (i=0; i<5; i++)
 			printk("%02x:", dev->dev_addr[i]);
diff -urN linux-2.5.70-bk10/arch/ppc/8xx_io/enet.c linux-2.5.70-bk11/arch/ppc/8xx_io/enet.c
--- linux-2.5.70-bk10/arch/ppc/8xx_io/enet.c	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/8xx_io/enet.c	2003-06-06 04:38:20.000000000 -0700
@@ -643,7 +643,7 @@
 {
 	struct net_device *dev;
 	struct scc_enet_private *cep;
-	int i, j, k;
+	int i, j, k, err;
 	unsigned char	*eap, *ba;
 	dma_addr_t	mem_addr;
 	bd_t		*bd;
@@ -659,19 +659,13 @@
 
 	bd = (bd_t *)__res;
 
-	/* Allocate some private information.
-	*/
-	cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
-	if (cep == NULL)
+	dev = alloc_etherdev(sizeof(*cep));
+	if (!dev)
 		return -ENOMEM;
 
-	__clear_user(cep,sizeof(*cep));
+	cep = dev->priv;
 	spin_lock_init(&cep->lock);
 
-	/* Create an Ethernet device instance.
-	*/
-	dev = init_etherdev(0, 0);
-
 	/* Get pointer to SCC area in parameter RAM.
 	*/
 	ep = (scc_enet_t *)(&cp->cp_dparam[PROFF_ENET]);
@@ -841,6 +835,7 @@
 		/* Allocate a page.
 		*/
 		ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
+		/* BUG: no check for failure */
 
 		/* Initialize the BD for every fragment in the page.
 		*/
@@ -939,7 +934,6 @@
 #endif
 
 	dev->base_addr = (unsigned long)ep;
-	dev->priv = cep;
 #if 0
 	dev->name = "CPM_ENET";
 #endif
@@ -953,6 +947,12 @@
 	dev->get_stats = scc_enet_get_stats;
 	dev->set_multicast_list = set_multicast_list;
 
+	err = register_netdev(dev);
+	if (err) {
+		kfree(dev);
+		return err;
+	}
+
 	/* And last, enable the transmit and receive processing.
 	*/
 	sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT);
diff -urN linux-2.5.70-bk10/arch/ppc/8xx_io/fec.c linux-2.5.70-bk11/arch/ppc/8xx_io/fec.c
--- linux-2.5.70-bk10/arch/ppc/8xx_io/fec.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/8xx_io/fec.c	2003-06-06 04:38:20.000000000 -0700
@@ -1570,7 +1570,7 @@
 {
 	struct net_device *dev;
 	struct fec_enet_private *fep;
-	int i, j, k;
+	int i, j, k, err;
 	unsigned char	*eap, *iap, *ba;
 	unsigned long	mem_addr;
 	volatile	cbd_t	*bdp;
@@ -1586,17 +1586,11 @@
 
 	bd = (bd_t *)__res;
 
-	/* Allocate some private information.
-	*/
-	fep = (struct fec_enet_private *)kmalloc(sizeof(*fep), GFP_KERNEL);
-	if (fep == NULL)
+	dev = alloc_etherdev(sizeof(*fep));
+	if (!dev)
 		return -ENOMEM;
 
-	__clear_user(fep,sizeof(*fep));
-
-	/* Create an Ethernet device instance.
-	*/
-	dev = init_etherdev(0, 0);
+	fep = dev->priv;
 
 	fecp = &(immap->im_cpm.cp_fec);
 
@@ -1661,6 +1655,7 @@
 		/* Allocate a page.
 		*/
 		ba = (unsigned char *)consistent_alloc(GFP_KERNEL, PAGE_SIZE, &mem_addr);
+		/* BUG: no check for failure */
 
 		/* Initialize the BD for every fragment in the page.
 		*/
@@ -1715,7 +1710,6 @@
 #endif
 
 	dev->base_addr = (unsigned long)fecp;
-	dev->priv = fep;
 
 	/* The FEC Ethernet specific entries in the device structure. */
 	dev->open = fec_enet_open;
@@ -1752,6 +1746,12 @@
 	fecp->fec_mii_speed = 0;	/* turn off MDIO */
 #endif	/* CONFIG_USE_MDIO */
 
+	err = register_netdev(dev);
+	if (err) {
+		kfree(dev);
+		return err;
+	}
+
 	printk ("%s: FEC ENET Version 0.2, FEC irq %d"
 #ifdef PHY_INTERRUPT
 		", MII irq %d"
diff -urN linux-2.5.70-bk10/arch/ppc/Kconfig linux-2.5.70-bk11/arch/ppc/Kconfig
--- linux-2.5.70-bk10/arch/ppc/Kconfig	2003-05-26 18:01:00.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/Kconfig	2003-06-06 04:38:20.000000000 -0700
@@ -97,32 +97,6 @@
 	depends on POWER3
 	default y
 
-config ALL_PPC
-	bool
-	depends on ALL_PPC_CH || POWER3
-	default y
-	---help---
-	  Linux currently supports several different kinds of PowerPC-based
-	  machines: Apple Power Macintoshes and clones (such as the Motorola
-	  Starmax series), PReP (PowerPC Reference Platform) machines (such
-	  as the Motorola PowerStacks, Motorola cPCI/VME embedded systems,
-	  and some IBM RS/6000 systems), CHRP (Common Hardware Reference
-	  Platform) machines (including all of the recent IBM RS/6000 and
-	  pSeries machines), and several embedded PowerPC systems containing
-	  4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors.  Currently, the
-	  default option is to build a kernel which works on the first three.
-
-	  Select CHRP/PowerMac/PReP if configuring for an IBM RS/6000 or
-	  pSeries machine, a Power Macintosh (including iMacs, iBooks and
-	  Powerbooks), or a PReP machine.
-
-	  Select Gemini if configuring for a Synergy Microsystems' Gemini
-	  series Single Board Computer.  More information is available at:
-	  <http://www.synergymicro.com/PressRel/97_10_15.html>.
-
-	  Select APUS if configuring for a PowerUP Amiga.  More information is
-	  available at: <http://linux-apus.sourceforge.net/>.
-
 config PPC_STD_MMU
 	bool
 	depends on 6xx || POWER3
@@ -424,12 +398,34 @@
 	bool
 	depends on 8xx || 8260
 	default y
+
 choice
 	prompt "Machine Type"
-	depends on 6xx && !8260
-	default ALL_PPC_CH
+	depends on (6xx || POWER3) && !8260
+	default PPC_MULTIPLATFORM
+	---help---
+	  Linux currently supports several different kinds of PowerPC-based
+	  machines: Apple Power Macintoshes and clones (such as the Motorola
+	  Starmax series), PReP (PowerPC Reference Platform) machines (such
+	  as the Motorola PowerStacks, Motorola cPCI/VME embedded systems,
+	  and some IBM RS/6000 systems), CHRP (Common Hardware Reference
+	  Platform) machines (including all of the recent IBM RS/6000 and
+	  pSeries machines), and several embedded PowerPC systems containing
+	  4xx, 6xx, 7xx, 8xx, 74xx, and 82xx processors.  Currently, the
+	  default option is to build a kernel which works on the first three.
 
-config ALL_PPC_CH
+	  Select CHRP/PowerMac/PReP if configuring for an IBM RS/6000 or
+	  pSeries machine, a Power Macintosh (including iMacs, iBooks and
+	  Powerbooks), or a PReP machine.
+
+	  Select Gemini if configuring for a Synergy Microsystems' Gemini
+	  series Single Board Computer.  More information is available at:
+	  <http://www.synergymicro.com/PressRel/97_10_15.html>.
+
+	  Select APUS if configuring for a PowerUP Amiga.  More information is
+	  available at: <http://linux-apus.sourceforge.net/>.
+
+config PPC_MULTIPLATFORM
 	bool "CHRP/PowerMac/PReP"
 
 config APUS
@@ -499,6 +495,26 @@
 
 endchoice
 
+config PPC_CHRP
+	bool
+	depends on PPC_MULTIPLATFORM
+	default y
+
+config PPC_PMAC
+	bool
+	depends on PPC_MULTIPLATFORM
+	default y
+
+config PPC_PREP
+	bool
+	depends on PPC_MULTIPLATFORM
+	default y
+
+config PPC_OF
+	bool
+	depends on PPC_PMAC || PPC_CHRP
+	default y
+
 config SANDPOINT_X3
 	bool "Sandpoint X3"
 	depends on SANDPOINT
@@ -721,7 +737,7 @@
 
 config ISA
 	bool "Support for ISA-bus hardware"
-	depends on ALL_PPC
+	depends on PREP || CHRP
 	help
 	  Find out whether you have ISA slots on your motherboard.  ISA is the
 	  name of a bus system, i.e. the way the CPU talks to the other stuff
@@ -851,7 +867,7 @@
 
 config PPC601_SYNC_FIX
 	bool "Workarounds for PPC601 bugs"
-	depends on ALL_PPC && !POWER3
+	depends on 6xx && !POWER3
 	help
 	  Some versions of the PPC601 (the first PowerPC chip) have bugs which
 	  mean that extra synchronization instructions are required near
@@ -865,7 +881,7 @@
 
 config PROC_DEVICETREE
 	bool "Support for Open Firmware device tree in /proc"
-	depends on ALL_PPC && PROC_FS
+	depends on PPC_OF && PROC_FS
 	help
 	  This option adds a device-tree directory under /proc which contains
 	  an image of the device tree that the kernel copies from Open
@@ -873,7 +889,7 @@
 
 config PPC_RTAS
 	bool "Support for RTAS (RunTime Abstraction Services) in /proc"
-	depends on ALL_PPC && PROC_FS
+	depends on PPC_OF && PROC_FS
 	---help---
 	  When you use this option, you will be able to use RTAS from
 	  userspace.
@@ -906,7 +922,7 @@
 
 config PREP_RESIDUAL
 	bool "Support for PReP Residual Data"
-	depends on ALL_PPC
+	depends on PPC_PREP
 	help
 	  Some PReP systems have residual data passed to the kernel by the
 	  firmware.  This allows detection of memory size, devices present and
@@ -927,7 +943,7 @@
 
 config PPCBUG_NVRAM
 	bool "Enable reading PPCBUG NVRAM during boot" if PPLUS || LOPEC
-	default y if ALL_PPC
+	default y if PPC_PREP
 
 config CMDLINE_BOOL
 	bool "Default bootloader kernel arguments"
@@ -1156,7 +1172,7 @@
 
 config BOOT_LOAD_BOOL
 	bool "Set the boot link/load address"
-	depends on ADVANCED_OPTIONS && !ALL_PPC
+	depends on ADVANCED_OPTIONS && !PPC_MULTIPLATFORM
 	help
 	  This option allows you to set the initial load address of the zImage
 	  or zImage.initrd file.  This can be useful if you are on a board
@@ -1292,7 +1308,7 @@
 # we want to change this to something like CONFIG_SYSCTRL_CUDA/PMU
 config ADB_CUDA
 	bool "Support for CUDA based PowerMacs"
-	depends on ALL_PPC
+	depends on PPC_PMAC
 	help
 	  This provides support for CUDA based Power Macintosh systems.  This
 	  includes most OldWorld PowerMacs, the first generation iMacs, the
@@ -1304,7 +1320,7 @@
 
 config ADB_PMU
 	bool "Support for PMU  based PowerMacs"
-	depends on ALL_PPC
+	depends on PPC_PMAC
 	help
 	  On PowerBooks, iBooks, and recent iMacs and Power Macintoshes, the
 	  PMU is an embedded microprocessor whose primary function is to
@@ -1336,7 +1352,7 @@
 
 config PM
 	bool
-	depends on ALL_PPC && ADB_PMU && PMAC_PBOOK
+	depends on PPC_PMAC && ADB_PMU && PMAC_PBOOK
 	default y
 
 config PMAC_APM_EMU
@@ -1357,14 +1373,14 @@
 
 config MAC_FLOPPY
 	bool "Support for PowerMac floppy"
-	depends on ALL_PPC
+	depends on PPC_PMAC
 	help
 	  If you have a SWIM-3 (Super Woz Integrated Machine 3; from Apple)
 	  floppy controller, say Y here. Most commonly found in PowerMacs.
 
 config MAC_SERIAL
 	tristate "Support for PowerMac serial ports"
-	depends on ALL_PPC
+	depends on PPC_PMAC
 	help
 	  If you have Macintosh style serial ports (8 pin mini-DIN), say Y
 	  here. If you also have regular serial ports and enable the driver
@@ -1372,11 +1388,11 @@
 
 config SERIAL_CONSOLE
 	bool "Support for console on serial port"
-	depends on ALL_PPC && MAC_SERIAL=y
+	depends on PPC_PMAC && MAC_SERIAL=y
 
 config ADB
 	bool "Apple Desktop Bus (ADB) support"
-	depends on ALL_PPC
+	depends on PPC_PMAC
 	help
 	  Apple Desktop Bus (ADB) support is for support of devices which
 	  are connected to an ADB port.  ADB devices tend to have 4 pins.
@@ -1610,7 +1626,7 @@
 
 config BOOTX_TEXT
 	bool "Support for early boot text console (BootX or OpenFirmware only)"
-	depends on ALL_PPC
+	depends PPC_OF
 	help
 	  Say Y here to see progress messages from the boot firmware in text
 	  mode. Requires either BootX or Open Firmware.
diff -urN linux-2.5.70-bk10/arch/ppc/boot/Makefile linux-2.5.70-bk11/arch/ppc/boot/Makefile
--- linux-2.5.70-bk10/arch/ppc/boot/Makefile	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/boot/Makefile	2003-06-06 04:38:20.000000000 -0700
@@ -16,9 +16,10 @@
 BOOT_TARGETS	= zImage zImage.initrd znetboot znetboot.initrd
 
 bootdir-y			:= simple
-bootdir-$(CONFIG_ALL_PPC)	:= openfirmware prep
+bootdir-$(CONFIG_PPC_OF)	:= openfirmware
+bootdir-$(CONFIG_PPC_PREP)	+= prep
 subdir-y			:= lib/ common/ images/
-subdir-$(CONFIG_ALL_PPC)	+= of1275/
+subdir-$(CONFIG_PPC_OF)		+= of1275/
 
 # for cleaning
 subdir-				+= simple/ openfirmware/ prep/
diff -urN linux-2.5.70-bk10/arch/ppc/boot/common/Makefile linux-2.5.70-bk11/arch/ppc/boot/common/Makefile
--- linux-2.5.70-bk10/arch/ppc/boot/common/Makefile	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/boot/common/Makefile	2003-06-06 04:38:20.000000000 -0700
@@ -11,7 +11,7 @@
 L_TARGET				:= lib.a
 
 obj-y					:= string.o util.o misc-common.o
-obj-$(CONFIG_ALL_PPC)			+= mpc10x_memory.o
+obj-$(CONFIG_PPC_PREP)			+= mpc10x_memory.o
 obj-$(CONFIG_LOPEC)			+= mpc10x_memory.o
 obj-$(CONFIG_PAL4)			+= cpc700_memory.o
 obj-$(CONFIG_SERIAL_8250_CONSOLE)	+= ns16550.o
diff -urN linux-2.5.70-bk10/arch/ppc/boot/common/misc-common.c linux-2.5.70-bk11/arch/ppc/boot/common/misc-common.c
--- linux-2.5.70-bk10/arch/ppc/boot/common/misc-common.c	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/boot/common/misc-common.c	2003-06-06 04:38:20.000000000 -0700
@@ -20,10 +20,10 @@
 #include "zlib.h"
 #include "nonstdio.h"
 
-/* If we're on a ALL_PPC, assume we have a keyboard controller
- * Also note, if we're not ALL_PPC, we assume you are a serial
+/* If we're on a PReP, assume we have a keyboard controller
+ * Also note, if we're not PReP, we assume you are a serial
  * console - Tom */
-#if defined(CONFIG_ALL_PPC) && defined(CONFIG_VGA_CONSOLE)
+#if defined(CONFIG_PPC_PREP) && defined(CONFIG_VGA_CONSOLE)
 extern void cursor(int x, int y);
 extern void scroll(void);
 extern char *vidmem;
diff -urN linux-2.5.70-bk10/arch/ppc/boot/common/mpc10x_memory.c linux-2.5.70-bk11/arch/ppc/boot/common/mpc10x_memory.c
--- linux-2.5.70-bk10/arch/ppc/boot/common/mpc10x_memory.c	2003-05-26 18:00:28.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/boot/common/mpc10x_memory.c	2003-06-06 04:38:20.000000000 -0700
@@ -50,7 +50,7 @@
 /*
  * Read the memory controller registers to determine the amount of memory in
  * the system.  This assumes that the firmware has correctly set up the memory
- * controller registers.  On CONFIG_ALL_PPC, we know we are being called
+ * controller registers.  On CONFIG_PPC_PREP, we know we are being called
  * under a PReP memory map. On all other machines, we assume we are under
  * a CHRP memory map.
  */
@@ -62,7 +62,7 @@
 	int i;
 	unsigned char bank_enables;
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PREP
 	config_addr = (unsigned int *)MPC10X_MAPA_CNFG_ADDR;
 	config_data = (unsigned int *)MPC10X_MAPA_CNFG_DATA;
 #else
diff -urN linux-2.5.70-bk10/arch/ppc/kernel/entry.S linux-2.5.70-bk11/arch/ppc/kernel/entry.S
--- linux-2.5.70-bk10/arch/ppc/kernel/entry.S	2003-06-06 04:38:11.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/kernel/entry.S	2003-06-06 04:38:20.000000000 -0700
@@ -820,7 +820,7 @@
  * here so it's easy to add arch-specific sections later.
  * -- Cort
  */
-#if defined(CONFIG_ALL_PPC)
+#ifdef CONFIG_PPC_OF
 /*
  * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
  * called with the MMU off.
@@ -865,4 +865,4 @@
 	twi	31,0,0
 	/* XXX load up BATs and panic */
 
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_OF */
diff -urN linux-2.5.70-bk10/arch/ppc/kernel/head.S linux-2.5.70-bk11/arch/ppc/kernel/head.S
--- linux-2.5.70-bk10/arch/ppc/kernel/head.S	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/kernel/head.S	2003-06-06 04:38:20.000000000 -0700
@@ -363,21 +363,21 @@
 	mtspr	SPRG0,r10
 	mtspr	SPRG1,r11
 	mfcr	r10
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_CHRP
 	mfspr	r11,SPRG2
 	cmpwi	0,r11,0
 	bne	7f
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_CHRP */
 	EXCEPTION_PROLOG_1
 7:	EXCEPTION_PROLOG_2
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_CHRP
 	mfspr	r4,SPRG2
 	cmpwi	cr1,r4,0
 	bne	cr1,1f
 #endif
 	EXC_XFER_STD(0x200, MachineCheckException)
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_CHRP
 1:	b	machine_check_in_rtas
 #endif
 
diff -urN linux-2.5.70-bk10/arch/ppc/kernel/pci.c linux-2.5.70-bk11/arch/ppc/kernel/pci.c
--- linux-2.5.70-bk10/arch/ppc/kernel/pci.c	2003-06-06 04:38:11.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/kernel/pci.c	2003-06-06 04:38:20.000000000 -0700
@@ -45,8 +45,10 @@
 static int reparent_resources(struct resource *parent, struct resource *res);
 static void fixup_rev1_53c810(struct pci_dev* dev);
 static void fixup_cpc710_pci64(struct pci_dev* dev);
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 static void pcibios_fixup_cardbus(struct pci_dev* dev);
+#endif
+#ifdef CONFIG_PPC_OF
 static u8* pci_to_OF_bus_map;
 #endif
 
@@ -65,10 +67,10 @@
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_NCR,	PCI_DEVICE_ID_NCR_53C810,	fixup_rev1_53c810 },
 	{ PCI_FIXUP_HEADER,	PCI_VENDOR_ID_IBM,	PCI_DEVICE_ID_IBM_CPC710_PCI64,	fixup_cpc710_pci64},
 	{ PCI_FIXUP_HEADER,	PCI_ANY_ID,		PCI_ANY_ID,			pcibios_fixup_resources },
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 	/* We should add per-machine fixup support in xxx_setup.c or xxx_pci.c */
 	{ PCI_FIXUP_FINAL,	PCI_VENDOR_ID_TI,	PCI_ANY_ID,			pcibios_fixup_cardbus }, 
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
  	{ 0 }
 };
 
@@ -153,7 +155,7 @@
 		ppc_md.pcibios_fixup_resources(dev);
 }
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 static void
 pcibios_fixup_cardbus(struct pci_dev* dev)
 {
@@ -188,7 +190,7 @@
 			pci_write_config_byte(dev, 0x92, val & ~0x06);
 	}
 }
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 
 void
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
@@ -676,7 +678,7 @@
 	return hose;
 }
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 /*
  * Functions below are used on OpenFirmware machines.
  */
@@ -1026,7 +1028,9 @@
 		prom_add_property(find_path_device("/"), of_prop);
 	}
 }
+#endif /* CONFIG_PPC_OF */
 
+#ifdef CONFIG_PPC_PMAC
 /*
  * This set of routines checks for PCI<->PCI bridges that have closed
  * IO resources and have child devices. It tries to re-open an IO
@@ -1235,7 +1239,7 @@
 	}
 }
 
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 
 static int __init
 pcibios_init(void)
@@ -1277,9 +1281,9 @@
 	pcibios_allocate_bus_resources(&pci_root_buses);
 	pcibios_allocate_resources(0);
 	pcibios_allocate_resources(1);
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 	pcibios_fixup_p2p_bridges();
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 	pcibios_assign_resources();
 
 	/* Call machine dependent post-init code */
diff -urN linux-2.5.70-bk10/arch/ppc/kernel/ppc_ksyms.c linux-2.5.70-bk11/arch/ppc/kernel/ppc_ksyms.c
--- linux-2.5.70-bk10/arch/ppc/kernel/ppc_ksyms.c	2003-05-26 18:00:57.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/kernel/ppc_ksyms.c	2003-06-06 04:38:20.000000000 -0700
@@ -94,7 +94,7 @@
 EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
 EXPORT_SYMBOL_NOVERS(DMA_MODE_READ);
 EXPORT_SYMBOL(DMA_MODE_WRITE);
-#if defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_PPC_PREP)
 EXPORT_SYMBOL(_prep_type);
 EXPORT_SYMBOL(ucSystemType);
 #endif
@@ -238,9 +238,14 @@
 EXPORT_SYMBOL(set_backlight_enable);
 EXPORT_SYMBOL(register_backlight_controller);
 #endif /* CONFIG_PMAC_BACKLIGHT */
-#if defined(CONFIG_ALL_PPC)
+#ifdef CONFIG_PPC_MULTIPLATFORM
 EXPORT_SYMBOL(_machine);
+#endif
+#ifdef CONFIG_PPC_PMAC
 EXPORT_SYMBOL_NOVERS(sys_ctrler);
+EXPORT_SYMBOL(pmac_newworld);
+#endif
+#ifdef CONFIG_PPC_OF
 EXPORT_SYMBOL(find_devices);
 EXPORT_SYMBOL(find_type_devices);
 EXPORT_SYMBOL(find_compatible_devices);
@@ -254,12 +259,11 @@
 EXPORT_SYMBOL(pci_busdev_to_OF_node);
 EXPORT_SYMBOL(pci_device_to_OF_node);
 EXPORT_SYMBOL(pci_device_from_OF_node);
-EXPORT_SYMBOL(pmac_newworld);
-#endif /* defined(CONFIG_ALL_PPC) */
+#endif /* CONFIG_PPC_OF */
 #if defined(CONFIG_BOOTX_TEXT)
 EXPORT_SYMBOL(btext_update_display);
 #endif
-#if defined(CONFIG_SCSI) && defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_SCSI) && defined(CONFIG_PPC_PMAC)
 EXPORT_SYMBOL(note_scsi_host);
 #endif
 #ifdef CONFIG_VT
@@ -337,7 +341,7 @@
 EXPORT_SYMBOL(cpm_install_handler);
 EXPORT_SYMBOL(cpm_free_handler);
 #endif /* CONFIG_8xx */
-#if defined(CONFIG_8xx) || defined(CONFIG_4xx)
+#if defined(CONFIG_8xx) || defined(CONFIG_40x)
 EXPORT_SYMBOL(__res);
 #endif
 #if defined(CONFIG_8xx)
@@ -354,7 +358,7 @@
 EXPORT_SYMBOL(intercept_table);
 #endif
 EXPORT_SYMBOL(cur_cpu_spec);
-#if defined(CONFIG_ALL_PPC)
+#ifdef CONFIG_PPC_PMAC
 extern unsigned long agp_special_page;
 EXPORT_SYMBOL_NOVERS(agp_special_page);
-#endif /* defined(CONFIG_ALL_PPC) */
+#endif
diff -urN linux-2.5.70-bk10/arch/ppc/kernel/setup.c linux-2.5.70-bk11/arch/ppc/kernel/setup.c
--- linux-2.5.70-bk10/arch/ppc/kernel/setup.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/kernel/setup.c	2003-06-06 04:38:20.000000000 -0700
@@ -68,7 +68,7 @@
 unsigned long ISA_DMA_THRESHOLD;
 unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_MULTIPLATFORM
 int _machine = 0;
 
 extern void prep_init(unsigned long r3, unsigned long r4,
@@ -77,7 +77,7 @@
 		unsigned long r5, unsigned long r6, unsigned long r7);
 extern void chrp_init(unsigned long r3, unsigned long r4,
 		unsigned long r5, unsigned long r6, unsigned long r7);
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_MULTIPLATFORM */
 
 #ifdef CONFIG_MAGIC_SYSRQ
 unsigned long SYSRQ_KEY = 0x54;
@@ -286,7 +286,7 @@
 	identify_cpu(offset, 0);
 	do_cpu_ftr_fixups(offset);
 
-#if defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_PPC_MULTIPLATFORM)
 	reloc_got2(offset);
 
 	/* If we came here from BootX, clear the screen,
@@ -308,7 +308,7 @@
 	return phys;
 }
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 /*
  * Assume here that all clock rates are the same in a
  * smp system.  -- Cort
@@ -351,9 +351,11 @@
 		}
 	}
 }
+#endif
 
+#ifdef CONFIG_PPC_MULTIPLATFORM
 /*
- * The ALL_PPC version of platform_init...
+ * The PPC_MULTIPLATFORM version of platform_init...
  */
 void __init
 platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
@@ -459,7 +461,7 @@
 		break;
 	}
 }
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_MULTIPLATFORM */
 
 struct bi_record *find_bootinfo(void)
 {
@@ -501,11 +503,11 @@
 			initrd_end = data[0] + data[1] + KERNELBASE;
 			break;
 #endif /* CONFIG_BLK_DEV_INITRD */
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_MULTIPLATFORM
 		case BI_MACHTYPE:
 			_machine = data[0];
 			break;
-#endif /* CONFIG_ALL_PPC */
+#endif
 		case BI_MEMSIZE:
 			boot_mem_size = data[0];
 			break;
@@ -596,13 +598,13 @@
 	/* so udelay does something sensible, assume <= 1000 bogomips */
 	loops_per_jiffy = 500000000 / HZ;
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_MULTIPLATFORM
 	/* This could be called "early setup arch", it must be done
 	 * now because xmon need it
 	 */
 	if (_machine == _MACH_Pmac)
 		pmac_feature_init();	/* New cool way */
-#endif /* CONFIG_ALL_PPC */
+#endif
 
 #ifdef CONFIG_XMON
 	xmon_map_scc();
diff -urN linux-2.5.70-bk10/arch/ppc/kernel/traps.c linux-2.5.70-bk11/arch/ppc/kernel/traps.c
--- linux-2.5.70-bk10/arch/ppc/kernel/traps.c	2003-06-06 04:38:11.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/kernel/traps.c	2003-06-06 04:38:20.000000000 -0700
@@ -117,7 +117,7 @@
  */
 static inline int check_io_access(struct pt_regs *regs)
 {
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 	unsigned long msr = regs->msr;
 	const struct exception_table_entry *entry;
 	unsigned int *nip = (unsigned int *)regs->nip;
@@ -150,7 +150,7 @@
 			return 1;
 		}
 	}
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 	return 0;
 }
 
diff -urN linux-2.5.70-bk10/arch/ppc/mm/init.c linux-2.5.70-bk11/arch/ppc/mm/init.c
--- linux-2.5.70-bk10/arch/ppc/mm/init.c	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/mm/init.c	2003-06-06 04:38:20.000000000 -0700
@@ -64,7 +64,7 @@
 int mem_init_done;
 int init_bootmem_done;
 int boot_mapsize;
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 unsigned long agp_special_page;
 #endif
 
@@ -411,16 +411,18 @@
 	}
 #endif /* CONFIG_BLK_DEV_INITRD */
 
-#if defined(CONFIG_ALL_PPC)
+#ifdef CONFIG_PPC_OF
 	/* mark the RTAS pages as reserved */
 	if ( rtas_data )
 		for (addr = (ulong)__va(rtas_data);
 		     addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ;
 		     addr += PAGE_SIZE)
 			SetPageReserved(virt_to_page(addr));
+#endif
+#ifdef CONFIG_PPC_PMAC
 	if (agp_special_page)
 		SetPageReserved(virt_to_page(agp_special_page));
-#endif /* defined(CONFIG_ALL_PPC) */
+#endif
 	if ( sysmap )
 		for (addr = (unsigned long)sysmap;
 		     addr < PAGE_ALIGN((unsigned long)sysmap+sysmap_size) ;
@@ -465,10 +467,10 @@
 	if (sysmap)
 		printk("System.map loaded at 0x%08x for debugger, size: %ld bytes\n",
 			(unsigned int)sysmap, sysmap_size);
-#if defined(CONFIG_ALL_PPC)
+#ifdef CONFIG_PPC_PMAC
 	if (agp_special_page)
 		printk(KERN_INFO "AGP special page: 0x%08lx\n", agp_special_page);
-#endif /* defined(CONFIG_ALL_PPC) */
+#endif
 
 	/* Make sure all our pagetable pages have page->mapping
 	   and page->index set correctly. */
@@ -521,13 +523,15 @@
 				  initrd_end - initrd_start, 1);
 	}
 #endif /* CONFIG_BLK_DEV_INITRD */
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 	/* remove the RTAS pages from the available memory */
 	if (rtas_data)
 		mem_pieces_remove(&phys_avail, rtas_data, rtas_size, 1);
+#endif
 	/* remove the sysmap pages from the available memory */
 	if (sysmap)
 		mem_pieces_remove(&phys_avail, __pa(sysmap), sysmap_size, 1);
+#ifdef CONFIG_PPC_PMAC
 	/* Because of some uninorth weirdness, we need a page of
 	 * memory as high as possible (it must be outside of the
 	 * bus address seen as the AGP aperture). It will be used
@@ -542,7 +546,7 @@
 		mem_pieces_remove(&phys_avail, agp_special_page, PAGE_SIZE, 0);	
 		agp_special_page = (unsigned long)__va(agp_special_page);
 	}
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 }
 
 /* Mark some memory as reserved by removing it from phys_avail. */
diff -urN linux-2.5.70-bk10/arch/ppc/mm/mem_pieces.c linux-2.5.70-bk11/arch/ppc/mm/mem_pieces.c
--- linux-2.5.70-bk10/arch/ppc/mm/mem_pieces.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/mm/mem_pieces.c	2003-06-06 04:38:20.000000000 -0700
@@ -120,7 +120,7 @@
 	printk("\n");
 }
 
-#if defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_APUS) || defined(CONFIG_PPC_OF)
 /*
  * Add some memory to an array of pieces
  */
@@ -135,7 +135,7 @@
 	rp->address = start;
 	rp->size = size;
 }
-#endif /* CONFIG_APUS || CONFIG_ALL_PPC */
+#endif /* CONFIG_APUS || CONFIG_PPC_OF */
 
 void __init
 mem_pieces_sort(struct mem_pieces *mp)
diff -urN linux-2.5.70-bk10/arch/ppc/platforms/Makefile linux-2.5.70-bk11/arch/ppc/platforms/Makefile
--- linux-2.5.70-bk10/arch/ppc/platforms/Makefile	2003-05-26 18:01:03.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/platforms/Makefile	2003-06-06 04:38:20.000000000 -0700
@@ -16,17 +16,15 @@
 ifeq ($(CONFIG_APUS),y)
 obj-$(CONFIG_PCI)		+= apus_pci.o
 endif
-obj-$(CONFIG_ALL_PPC)		+= pmac_pic.o pmac_setup.o pmac_time.o \
-					pmac_feature.o pmac_pci.o chrp_setup.o\
-					chrp_time.o chrp_pci.o prep_pci.o \
-					prep_time.o prep_setup.o pmac_sleep.o
-ifeq ($(CONFIG_ALL_PPC),y)
+obj-$(CONFIG_PPC_PMAC)		+= pmac_pic.o pmac_setup.o pmac_time.o \
+					pmac_feature.o pmac_pci.o pmac_sleep.o
+obj-$(CONFIG_PPC_CHRP)		+= chrp_setup.o chrp_time.o chrp_pci.o
+obj-$(CONFIG_PPC_PREP)		+= prep_pci.o prep_time.o prep_setup.o
+ifeq ($(CONFIG_PPC_PMAC),y)
 obj-$(CONFIG_NVRAM)		+= pmac_nvram.o
-endif
-obj-$(CONFIG_PMAC_BACKLIGHT)	+= pmac_backlight.o
-ifeq ($(CONFIG_ALL_PPC),y)
 obj-$(CONFIG_CPU_FREQ_PMAC)	+= pmac_cpufreq.o
 endif
+obj-$(CONFIG_PMAC_BACKLIGHT)	+= pmac_backlight.o
 obj-$(CONFIG_PPC_RTAS)		+= error_log.o proc_rtas.o
 obj-$(CONFIG_PREP_RESIDUAL)	+= residual.o
 obj-$(CONFIG_ADIR)		+= adir_setup.o adir_pic.o adir_pci.o
@@ -50,5 +48,6 @@
 obj-$(CONFIG_ZX4500)		+= zx4500_setup.o zx4500_pci.o
 
 ifeq ($(CONFIG_SMP),y)
-obj-$(CONFIG_ALL_PPC)		+= pmac_smp.o chrp_smp.o
+obj-$(CONFIG_PPC_PMAC)		+= pmac_smp.o
+obj-$(CONFIG_PPC_CHRP)		+= chrp_smp.o
 endif
diff -urN linux-2.5.70-bk10/arch/ppc/syslib/Makefile linux-2.5.70-bk11/arch/ppc/syslib/Makefile
--- linux-2.5.70-bk10/arch/ppc/syslib/Makefile	2003-05-26 18:00:22.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/syslib/Makefile	2003-06-06 04:38:20.000000000 -0700
@@ -27,8 +27,10 @@
 ifeq ($(CONFIG_8xx),y)
 obj-$(CONFIG_PCI)		+= qspan_pci.o i8259.o
 endif
-obj-$(CONFIG_ALL_PPC)		+= prom_init.o prom.o open_pic.o \
-					indirect_pci.o i8259.o
+obj-$(CONFIG_PPC_OF)		+= prom_init.o prom.o
+obj-$(CONFIG_PPC_PMAC)		+= open_pic.o indirect_pci.o
+obj-$(CONFIG_PPC_CHRP)		+= open_pic.o indirect_pci.o i8259.o
+obj-$(CONFIG_PPC_PREP)		+= open_pic.o indirect_pci.o i8259.o
 obj-$(CONFIG_ADIR)		+= i8259.o indirect_pci.o pci_auto.o \
 					todc_time.o
 obj-$(CONFIG_EV64260)		+= gt64260_common.o gt64260_pic.o \
diff -urN linux-2.5.70-bk10/arch/ppc/xmon/start.c linux-2.5.70-bk11/arch/ppc/xmon/start.c
--- linux-2.5.70-bk10/arch/ppc/xmon/start.c	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk11/arch/ppc/xmon/start.c	2003-06-06 04:38:20.000000000 -0700
@@ -52,7 +52,7 @@
 
 extern int adb_init(void);
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_CHRP
 /*
  * This looks in the "ranges" property for the primary PCI host bridge
  * to find the physical address of the start of PCI/ISA I/O space.
@@ -90,7 +90,7 @@
 	}
 	return base;
 }
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_CHRP */
 
 #ifdef CONFIG_MAGIC_SYSRQ
 static void sysrq_handle_xmon(int key, struct pt_regs *regs,
@@ -110,7 +110,7 @@
 void
 xmon_map_scc(void)
 {
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_MULTIPLATFORM
 	volatile unsigned char *base;
 	
 	if (_machine == _MACH_Pmac) {
diff -urN linux-2.5.70-bk10/arch/sparc/prom/console.c linux-2.5.70-bk11/arch/sparc/prom/console.c
--- linux-2.5.70-bk10/arch/sparc/prom/console.c	2003-05-26 18:00:37.000000000 -0700
+++ linux-2.5.70-bk11/arch/sparc/prom/console.c	2003-06-06 04:38:20.000000000 -0700
@@ -105,7 +105,7 @@
 
 /* Query for input device type */
 enum prom_input_device
-prom_query_input_device()
+prom_query_input_device(void)
 {
 	unsigned long flags;
 	int st_p;
@@ -155,7 +155,7 @@
 /* Query for output device type */
 
 enum prom_output_device
-prom_query_output_device()
+prom_query_output_device(void)
 {
 	unsigned long flags;
 	int st_p;
diff -urN linux-2.5.70-bk10/arch/sparc64/boot/Makefile linux-2.5.70-bk11/arch/sparc64/boot/Makefile
--- linux-2.5.70-bk10/arch/sparc64/boot/Makefile	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk11/arch/sparc64/boot/Makefile	2003-06-06 04:38:20.000000000 -0700
@@ -15,7 +15,7 @@
 quiet_cmd_piggy     = PIGGY    $@
       cmd_piggy     = $(obj)/piggyback $@ System.map $(ROOT_IMG)
 quiet_cmd_strip     = STRIP $@
-      cmd_strip     = $(STRIP) -R .comment -R .note vmlinux -o $@
+      cmd_strip     = $(STRIP) -R .comment -R .note -K sun4u_init -K _end -K _start vmlinux -o $@
 
 
 # Actual linking
diff -urN linux-2.5.70-bk10/arch/sparc64/prom/console.c linux-2.5.70-bk11/arch/sparc64/prom/console.c
--- linux-2.5.70-bk10/arch/sparc64/prom/console.c	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk11/arch/sparc64/prom/console.c	2003-06-06 04:38:20.000000000 -0700
@@ -76,7 +76,7 @@
 
 /* Query for input device type */
 enum prom_input_device
-prom_query_input_device()
+prom_query_input_device(void)
 {
 	int st_p;
 	char propb[64];
@@ -111,7 +111,7 @@
 /* Query for output device type */
 
 enum prom_output_device
-prom_query_output_device()
+prom_query_output_device(void)
 {
 	int st_p;
 	char propb[64];
diff -urN linux-2.5.70-bk10/arch/um/sys-ppc/Makefile linux-2.5.70-bk11/arch/um/sys-ppc/Makefile
--- linux-2.5.70-bk10/arch/um/sys-ppc/Makefile	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk11/arch/um/sys-ppc/Makefile	2003-06-06 04:38:20.000000000 -0700
@@ -6,7 +6,7 @@
 OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \
 	ptrace_user.o sysrq.o
 
-EXTRA_AFLAGS := -DCONFIG_ALL_PPC -I. -I$(TOPDIR)/arch/ppc/kernel
+EXTRA_AFLAGS := -DCONFIG_PPC32 -I. -I$(TOPDIR)/arch/ppc/kernel
 
 all: $(OBJ)
 
diff -urN linux-2.5.70-bk10/drivers/Makefile linux-2.5.70-bk11/drivers/Makefile
--- linux-2.5.70-bk10/drivers/Makefile	2003-06-06 04:38:11.000000000 -0700
+++ linux-2.5.70-bk11/drivers/Makefile	2003-06-06 04:38:20.000000000 -0700
@@ -31,7 +31,7 @@
 obj-$(CONFIG_DIO)		+= dio/
 obj-$(CONFIG_SBUS)		+= sbus/
 obj-$(CONFIG_ZORRO)		+= zorro/
-obj-$(CONFIG_ALL_PPC)		+= macintosh/
+obj-$(CONFIG_PPC_PMAC)		+= macintosh/
 obj-$(CONFIG_MAC)		+= macintosh/
 obj-$(CONFIG_SGI)		+= sgi/
 obj-$(CONFIG_PARIDE) 		+= block/paride/
diff -urN linux-2.5.70-bk10/drivers/base/class.c linux-2.5.70-bk11/drivers/base/class.c
--- linux-2.5.70-bk10/drivers/base/class.c	2003-06-06 04:38:12.000000000 -0700
+++ linux-2.5.70-bk11/drivers/base/class.c	2003-06-06 04:38:20.000000000 -0700
@@ -191,7 +191,7 @@
 	pr_debug("device class '%s': release.\n",cd->class_id);
 
 	if (cls->release)
-		cd->release(cd);
+		cls->release(cd);
 }
 
 static struct kobj_type ktype_class_device = {
diff -urN linux-2.5.70-bk10/drivers/base/core.c linux-2.5.70-bk11/drivers/base/core.c
--- linux-2.5.70-bk10/drivers/base/core.c	2003-06-06 04:38:12.000000000 -0700
+++ linux-2.5.70-bk11/drivers/base/core.c	2003-06-06 04:38:20.000000000 -0700
@@ -343,11 +343,40 @@
 	put_device(dev);
 }
 
+/**
+ *	device_for_each_child - device child iterator.
+ *	@dev:	parent struct device.
+ *	@data:	data for the callback.
+ *	@fn:	function to be called for each device.
+ *
+ *	Iterate over @dev's child devices, and call @fn for each,
+ *	passing it @data. 
+ *
+ *	We check the return of @fn each time. If it returns anything
+ *	other than 0, we break out and return that value.
+ */
+int device_for_each_child(struct device * dev, void * data,
+		     int (*fn)(struct device *, void *))
+{
+	struct device * child;
+	int error = 0;
+
+	down_read(&devices_subsys.rwsem);
+	list_for_each_entry(child,&dev->children,node) {
+		if((error = fn(child,data)))
+			break;
+	}
+	up_read(&devices_subsys.rwsem);
+	return error;
+}
+
 int __init devices_init(void)
 {
 	return subsystem_register(&devices_subsys);
 }
 
+EXPORT_SYMBOL(device_for_each_child);
+
 EXPORT_SYMBOL(device_initialize);
 EXPORT_SYMBOL(device_add);
 EXPORT_SYMBOL(device_register);
diff -urN linux-2.5.70-bk10/drivers/block/cciss.c linux-2.5.70-bk11/drivers/block/cciss.c
--- linux-2.5.70-bk10/drivers/block/cciss.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk11/drivers/block/cciss.c	2003-06-06 04:38:20.000000000 -0700
@@ -1961,7 +1961,7 @@
 
 	goto queue;
 startio:
-	__blk_stop_queue(q);
+	blk_stop_queue(q);
 	start_io(h);
 }
 
@@ -2021,8 +2021,8 @@
 	/*
 	 * See if we can queue up some more IO
 	 */
-	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
 	blk_start_queue(&h->queue);
+	spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
 	return IRQ_HANDLED;
 }
 /* 
diff -urN linux-2.5.70-bk10/drivers/block/ll_rw_blk.c linux-2.5.70-bk11/drivers/block/ll_rw_blk.c
--- linux-2.5.70-bk10/drivers/block/ll_rw_blk.c	2003-06-06 04:38:12.000000000 -0700
+++ linux-2.5.70-bk11/drivers/block/ll_rw_blk.c	2003-06-06 04:38:20.000000000 -0700
@@ -391,12 +391,6 @@
 	q->dma_alignment = mask;
 }
 
-void blk_queue_assign_lock(request_queue_t *q, spinlock_t *lock)
-{
-	spin_lock_init(lock);
-	q->queue_lock = lock;
-}
-
 /**
  * blk_queue_find_tag - find a request by its tag and queue
  *
@@ -1076,30 +1070,12 @@
  *   blk_start_queue() will clear the stop flag on the queue, and call
  *   the request_fn for the queue if it was in a stopped state when
  *   entered. Also see blk_stop_queue(). Must not be called from driver
- *   request function due to recursion issues.
+ *   request function due to recursion issues. Queue lock must be held.
  **/
 void blk_start_queue(request_queue_t *q)
 {
-	if (test_and_clear_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)) {
-		unsigned long flags;
-
-		spin_lock_irqsave(q->queue_lock, flags);
-		if (!elv_queue_empty(q))
-			q->request_fn(q);
-		spin_unlock_irqrestore(q->queue_lock, flags);
-	}
-}
-
-/**
- * __blk_stop_queue: see blk_stop_queue()
- *
- * Description:
- *  Like blk_stop_queue(), but queue_lock must be held
- **/
-void __blk_stop_queue(request_queue_t *q)
-{
-	blk_remove_plug(q);
-	set_bit(QUEUE_FLAG_STOPPED, &q->queue_flags);
+	if (test_and_clear_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))
+		schedule_work(&q->unplug_work);
 }
 
 /**
@@ -1114,15 +1090,12 @@
  *   or if it simply chooses not to queue more I/O at one point, it can
  *   call this function to prevent the request_fn from being called until
  *   the driver has signalled it's ready to go again. This happens by calling
- *   blk_start_queue() to restart queue operations.
+ *   blk_start_queue() to restart queue operations. Queue lock must be held.
  **/
 void blk_stop_queue(request_queue_t *q)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(q->queue_lock, flags);
-	__blk_stop_queue(q);
-	spin_unlock_irqrestore(q->queue_lock, flags);
+	blk_remove_plug(q);
+	set_bit(QUEUE_FLAG_STOPPED, &q->queue_flags);
 }
 
 /**
@@ -2364,7 +2337,6 @@
 EXPORT_SYMBOL(blk_nohighio);
 EXPORT_SYMBOL(blk_dump_rq_flags);
 EXPORT_SYMBOL(submit_bio);
-EXPORT_SYMBOL(blk_queue_assign_lock);
 EXPORT_SYMBOL(blk_phys_contig_segment);
 EXPORT_SYMBOL(blk_hw_contig_segment);
 EXPORT_SYMBOL(blk_get_request);
@@ -2383,7 +2355,6 @@
 
 EXPORT_SYMBOL(blk_start_queue);
 EXPORT_SYMBOL(blk_stop_queue);
-EXPORT_SYMBOL(__blk_stop_queue);
 EXPORT_SYMBOL(blk_run_queue);
 EXPORT_SYMBOL(blk_run_queues);
 
diff -urN linux-2.5.70-bk10/drivers/char/Kconfig linux-2.5.70-bk11/drivers/char/Kconfig
--- linux-2.5.70-bk10/drivers/char/Kconfig	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk11/drivers/char/Kconfig	2003-06-06 04:38:20.000000000 -0700
@@ -94,18 +94,21 @@
 	  two modules called ip2 and ip2main.
 
 config ROCKETPORT
-	tristate "Comtrol Rocketport support"
+	tristate "Comtrol RocketPort support"
 	depends on SERIAL_NONSTANDARD
 	help
-	  This is a driver for the Comtrol Rocketport cards which provide
-	  multiple serial ports. You would need something like this to connect
-	  more than two modems to your Linux box, for instance in order to
-	  become a dial-in server.
+	  This driver supports Comtrol RocketPort and RocketModem PCI boards.   
+          These boards provide 2, 4, 8, 16, or 32 high-speed serial ports or
+          modems.  For information about the RocketPort/RocketModem  boards
+          and this driver read <file:Documentation/rocket.txt>.
 
 	  If you want to compile this driver as a module, say M here and read
 	  <file:Documentation/modules.txt>.  The module will be called
 	  rocket.
 
+	  If you want to compile this driver into the kernel, say Y here.  If
+          you don't have a Comtrol RocketPort/RocketModem card installed, say N.
+
 config CYCLADES
 	tristate "Cyclades async mux support"
 	depends on SERIAL_NONSTANDARD
diff -urN linux-2.5.70-bk10/drivers/char/agp/Kconfig linux-2.5.70-bk11/drivers/char/agp/Kconfig
--- linux-2.5.70-bk10/drivers/char/agp/Kconfig	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk11/drivers/char/agp/Kconfig	2003-06-06 04:38:20.000000000 -0700
@@ -134,7 +134,7 @@
 
 config AGP_UNINORTH
 	tristate "Apple UniNorth AGP support"
-	depends on AGP && ALL_PPC
+	depends on AGP && PPC_PMAC
 	help
 	  This option gives you AGP support for Apple machines with a
 	  UniNorth bridge.
diff -urN linux-2.5.70-bk10/drivers/char/rocket.c linux-2.5.70-bk11/drivers/char/rocket.c
--- linux-2.5.70-bk10/drivers/char/rocket.c	2003-06-06 04:38:12.000000000 -0700
+++ linux-2.5.70-bk11/drivers/char/rocket.c	2003-06-06 04:38:21.000000000 -0700
@@ -1,9 +1,9 @@
 /*
- * Rocketport device driver for Linux
+ * RocketPort device driver for Linux
  *
- * Written by Theodore Ts'o, 1995, 1996, 1997.
+ * Written by Theodore Ts'o, 1995, 1996, 1997, 1998, 1999, 2000.
  * 
- * Copyright (C) 1995, 1996, 1997 by Comtrol, Inc.
+ * Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2003 by Comtrol, Inc.
  * 
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -21,60 +21,46 @@
  */
 
 /*
- * Minor number schema:
+ * Kernel Synchronization:
  *
- * +-------------------------------+
- * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
- * +---+-------+-------+-----------+
- * | C | Board |  AIOP | Port #    |
- * +---+-------+-------+-----------+
+ * This driver has 2 kernel control paths - exception handlers (calls into the driver
+ * from user mode) and the timer bottom half (tasklet).  This is a polled driver, interrupts
+ * are not used.
  *
- * C=0 implements normal POSIX tty.
- * C=1 is reserved for the callout device.
+ * Critical data: 
+ * -  rp_table[], accessed through passed "info" pointers, is a global (static) array of 
+ *    serial port state information and the xmit_buf circular buffer.  Protected by 
+ *    a per port spinlock.
+ * -  xmit_flags[], an array of ints indexed by line (port) number, indicating that there
+ *    is data to be transmitted.  Protected by atomic bit operations.
+ * -  rp_num_ports, int indicating number of open ports, protected by atomic operations.
  * 
- * Normally, the user won't have to worry about the AIOP; as far as
- * the user is concerned, the lower 5 bits of the minor number address
- * the ports on a particular board (from 0 up to 32).
+ * rp_write() and rp_write_char() functions use a per port semaphore to protect against
+ * simultaneous access to the same port by more than one process.
  */
 
-/* Kernel includes */
-
+/****** Defines ******/
 #include <linux/config.h>
 #include <linux/version.h>
 
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/major.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/string.h>
-#include <linux/fcntl.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-	
-#include "rocket_int.h"
-#ifdef LOCAL_ROCKET_H
-#include "rocket.h"
-#include "version.h"
+#ifdef PCI_NUM_RESOURCES
+#define PCI_BASE_ADDRESS(dev, r) ((dev)->resource[r].start)
 #else
-#include <linux/rocket.h>
-#define ROCKET_VERSION "1.14c"
-#define ROCKET_DATE "24-Aug-98"
-#endif /* LOCAL_ROCKET_H */
+#define PCI_BASE_ADDRESS(dev, r) ((dev)->base_address[r])
+#endif
+
+#ifndef VERSION_CODE
+#  define VERSION_CODE(vers,rel,seq) ( ((vers)<<16) | ((rel)<<8) | (seq) )
+#endif
+
+#if LINUX_VERSION_CODE < VERSION_CODE(2,2,9)	/*  No version < 2.2 */
+#  error "This kernel is too old: not supported by this file"
+#endif
 
 #define ROCKET_PARANOIA_CHECK
-#define ROCKET_SOFT_FLOW
+#define ROCKET_DISABLE_SIMUSAGE
 
+#undef ROCKET_SOFT_FLOW
 #undef ROCKET_DEBUG_OPEN
 #undef ROCKET_DEBUG_INTR
 #undef ROCKET_DEBUG_WRITE
@@ -83,7 +69,11 @@
 #undef ROCKET_DEBUG_WAIT_UNTIL_SENT
 #undef ROCKET_DEBUG_RECEIVE
 #undef ROCKET_DEBUG_HANGUP
-	
+#undef REV_PCI_ORDER
+#undef ROCKET_DEBUG_IO
+
+#undef CONFIG_DEVFS_FS
+
 
 /*   CAUTION!!!!!  The TIME_STAT Function relies on the Pentium 64 bit
  *    register.  For various reasons related to 1.2.13, the test for this
@@ -96,46 +86,132 @@
  *    CPU, there is probably something funny about your CPU.
  */
 
-#undef TIME_STAT	/* For performing timing statistics on driver. */
+#undef TIME_STAT		/* For performing timing statistics on driver. */
 			/* Produces printks, one every TIME_COUNTER loops, eats */
 			/* some of your CPU time.  Good for testing or */
 			/* other checking, otherwise, leave it undefed */
 			/* Doug Ledford */
-#define TIME_STAT_CPU 100      /* This needs to be set to your processor speed */
-                               /* For example, 100Mhz CPU, set this to 100 */
-#define TIME_COUNTER 180000    /* This is how many iterations to run before */
+#define TIME_STAT_CPU 100	/* This needs to be set to your processor speed */
+			       /* For example, 100Mhz CPU, set this to 100 */
+#define TIME_COUNTER 180000	/* This is how many iterations to run before */
 			      /* performing the printk statements.   */
 			      /* 6000 = 1 minute, 360000 = 1 hour, etc. */
 			      /* Since time_stat is long long, this */
 			      /* Can be really high if you want :)  */
-#undef TIME_STAT_VERBOSE   /* Undef this if you want a terse log message. */
+#undef TIME_STAT_VERBOSE	/* Undef this if you want a terse log message. */
 
-#define _INLINE_ inline
+#if LINUX_VERSION_CODE < VERSION_CODE(2,4,0)
+#define TTY_DRIVER_NO_DEVFS 0
+#endif
 
-static struct r_port *rp_table[MAX_RP_PORTS];
-static struct tty_struct *rocket_table[MAX_RP_PORTS];
-static unsigned int xmit_flags[NUM_BOARDS];
+#define POLL_PERIOD HZ/100	/*  Polling period .01 seconds (10ms) */
+
+/****** Kernel includes ******/
+
+#ifdef MODVERSIONS
+#if LINUX_VERSION_CODE < VERSION_CODE(2,5,00)
+#include <linux/modversions.h>
+#else
+#include <config/modversions.h>
+#endif
+#endif				
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+
+#if LINUX_VERSION_CODE < VERSION_CODE(2,4,0)
+#include <linux/malloc.h>
+#else
+#include <linux/slab.h>
+#endif
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/major.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <asm/bitops.h>
+#include <linux/spinlock.h>
+#include <asm/semaphore.h>
+#include <linux/init.h>
+
+/****** RocketPort includes ******/
+
+#include "rocket_int.h"
+#include "rocket.h"
+
+#ifdef LOCAL_ROCKET_H
+#include "version.h"
+#else
+#define ROCKET_VERSION "2.08"
+#define ROCKET_DATE "02-June-2003"
+#endif				/* LOCAL_ROCKET_H */
+
+/*
+ * All of the compatibilty code so we can compile serial.c against
+ * older kernels is hidden in rocket_compat.h
+ */
+#if defined(LOCAL_ROCKET_H) || (LINUX_VERSION_CODE < VERSION_CODE(2,3,23))
+#include "rocket_compat.h"
+#endif
+
+/****** RocketPort Local Variables ******/
+
+static struct tty_struct *rocket_table[MAX_RP_PORTS];	/*  TTY required variables */
 static struct termios *rocket_termios[MAX_RP_PORTS];
 static struct termios *rocket_termios_locked[MAX_RP_PORTS];
-static void rp_wait_until_sent(struct tty_struct *tty, int timeout);
-static void rp_flush_buffer(struct tty_struct *tty);
-
 static struct tty_driver rocket_driver;
 static int rocket_refcount;
 
-static int rp_num_ports_open;
+static struct rocket_version driver_version = {	
+	ROCKET_VERSION, ROCKET_DATE
+};
 
+static struct r_port *rp_table[MAX_RP_PORTS];	       /*  The main repository of serial port state information. */
+static unsigned int xmit_flags[NUM_BOARDS];	       /*  Bit significant, indicates port had data to transmit. */
+						       /*  eg.  Bit 0 indicates port 0 has xmit data, ...        */
+static atomic_t rp_num_ports_open;	               /*  Number of serial ports open                           */
 static struct timer_list rocket_timer;
 
-unsigned long board1;
-unsigned long board2;
-unsigned long board3;
-unsigned long board4;
-unsigned long controller;
-unsigned long support_low_speed;
-int rp_baud_base = 460800;
+static unsigned long board1;	                       /* ISA addresses, retrieved from rocketport.conf          */
+static unsigned long board2;
+static unsigned long board3;
+static unsigned long board4;
+static unsigned long controller;
+static unsigned long support_low_speed;
+static unsigned long modem1;
+static unsigned long modem2;
+static unsigned long modem3;
+static unsigned long modem4;
+static unsigned long pc104_1[8];
+static unsigned long pc104_2[8];
+static unsigned long pc104_3[8];
+static unsigned long pc104_4[8];
+static unsigned long *pc104[4] = { pc104_1, pc104_2, pc104_3, pc104_4 };
+
+static int rp_baud_base[NUM_BOARDS];	               /*  Board config info (Someday make a per-board structure)  */
 static unsigned long rcktpt_io_addr[NUM_BOARDS];
+static int rcktpt_type[NUM_BOARDS];
+static int is_PCI[NUM_BOARDS];
+static rocketModel_t rocketModel[NUM_BOARDS];
 static int max_board;
+
 #ifdef TIME_STAT
 static unsigned long long time_stat;
 static unsigned long time_stat_short;
@@ -143,83 +219,140 @@
 static unsigned long time_counter;
 #endif
 
+/*
+ * The following arrays define the interrupt bits corresponding to each AIOP.
+ * These bits are different between the ISA and regular PCI boards and the
+ * Universal PCI boards.
+ */
+
+static Word_t aiop_intr_bits[AIOP_CTL_SIZE] = {
+	AIOP_INTR_BIT_0,
+	AIOP_INTR_BIT_1,
+	AIOP_INTR_BIT_2,
+	AIOP_INTR_BIT_3
+};
+
+static Word_t upci_aiop_intr_bits[AIOP_CTL_SIZE] = {
+	UPCI_AIOP_INTR_BIT_0,
+	UPCI_AIOP_INTR_BIT_1,
+	UPCI_AIOP_INTR_BIT_2,
+	UPCI_AIOP_INTR_BIT_3
+};
+
+/*
+ *  Line number is the ttySIx number (x), the Minor number.  We 
+ *  assign them sequentially, starting at zero.  The following 
+ *  array keeps track of the line number assigned to a given board/aiop/channel.
+ */
+static unsigned char lineNumbers[MAX_RP_PORTS];
+static unsigned long nextLineNumber;
+
+/*****  RocketPort Static Prototypes   *********/
+static int __init init_ISA(int i, int *reserved_controller);
+static void rp_wait_until_sent(struct tty_struct *tty, int timeout);
+static void rp_flush_buffer(struct tty_struct *tty);
+static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model);
+static unsigned char GetLineNumber(int ctrl, int aiop, int ch);
+static unsigned char SetLineNumber(int ctrl, int aiop, int ch);
+static void rp_start(struct tty_struct *tty);
+
+#ifdef MODULE
 MODULE_AUTHOR("Theodore Ts'o");
-MODULE_DESCRIPTION("Comtrol Rocketport driver");
-MODULE_LICENSE("GPL");
-MODULE_PARM(board1,     "i");
+MODULE_DESCRIPTION("Comtrol RocketPort driver");
+MODULE_PARM(board1, "i");
 MODULE_PARM_DESC(board1, "I/O port for (ISA) board #1");
-MODULE_PARM(board2,     "i");
+MODULE_PARM(board2, "i");
 MODULE_PARM_DESC(board2, "I/O port for (ISA) board #2");
-MODULE_PARM(board3,     "i");
+MODULE_PARM(board3, "i");
 MODULE_PARM_DESC(board3, "I/O port for (ISA) board #3");
-MODULE_PARM(board4,     "i");
+MODULE_PARM(board4, "i");
 MODULE_PARM_DESC(board4, "I/O port for (ISA) board #4");
 MODULE_PARM(controller, "i");
 MODULE_PARM_DESC(controller, "I/O port for (ISA) rocketport controller");
 MODULE_PARM(support_low_speed, "i");
-MODULE_PARM_DESC(support_low_speed, "0 means support 50 baud, 1 means support 460400 baud");	
+MODULE_PARM_DESC(support_low_speed, "1 means support 50 baud, 0 means support 460400 baud");
+MODULE_PARM(modem1, "i");
+MODULE_PARM_DESC(modem1, "1 means (ISA) board #1 is a RocketModem");
+MODULE_PARM(modem2, "i");
+MODULE_PARM_DESC(modem2, "1 means (ISA) board #2 is a RocketModem");
+MODULE_PARM(modem3, "i");
+MODULE_PARM_DESC(modem3, "1 means (ISA) board #3 is a RocketModem");
+MODULE_PARM(modem4, "i");
+MODULE_PARM_DESC(modem4, "1 means (ISA) board #4 is a RocketModem");
+MODULE_PARM(pc104_1, "1-8i");
+MODULE_PARM_DESC(pc104_1, "set interface types for ISA(PC104) board #1 (e.g. pc104_1=232,232,485,485,...");
+MODULE_PARM(pc104_2, "1-8i");
+MODULE_PARM_DESC(pc104_2, "set interface types for ISA(PC104) board #2 (e.g. pc104_2=232,232,485,485,...");
+MODULE_PARM(pc104_3, "1-8i");
+MODULE_PARM_DESC(pc104_3, "set interface types for ISA(PC104) board #3 (e.g. pc104_3=232,232,485,485,...");
+MODULE_PARM(pc104_4, "1-8i");
+MODULE_PARM_DESC(pc104_4, "set interface types for ISA(PC104) board #4 (e.g. pc104_4=232,232,485,485,...");
+
+int rp_init(void);
+static void rp_cleanup_module(void);
+
+module_init(rp_init);
+module_exit(rp_cleanup_module);
 
-#include <asm/uaccess.h>
+#endif
 
-/*
- * tmp_buf is used as a temporary buffer by rp_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);
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("Dual BSD/GPL");
+#endif
 
-static void rp_start(struct tty_struct *tty);
+/*************************************************************************/
+/*                     Module code starts here                           */
 
 static inline int rocket_paranoia_check(struct r_port *info,
-					char *name, const char *routine)
+					const char *routine)
 {
 #ifdef ROCKET_PARANOIA_CHECK
-	static const char *badmagic =
-		"Warning: bad magic number for rocketport struct %s in %s\n";
 	if (!info)
 		return 1;
 	if (info->magic != RPORT_MAGIC) {
-		printk(badmagic, name, routine);
+		printk(KERN_INFO "Warning: bad magic number for rocketport struct in %s\n",
+		     routine);
 		return 1;
 	}
 #endif
 	return 0;
 }
 
-/*
- * Here begins the interrupt/polling routine for the Rocketport!
+
+/*  Serial port receive data function.  Called (from timer poll) when an AIOPIC signals 
+ *  that receive data is present on a serial port.  Pulls data from FIFO, moves it into the 
+ *  tty layer.  
  */
-static _INLINE_ void rp_do_receive(struct r_port *info, struct tty_struct *tty,
-				   CHANNEL_t *cp, unsigned int ChanStatus)
+static void rp_do_receive(struct r_port *info,
+			  struct tty_struct *tty,
+			  CHANNEL_t * cp, unsigned int ChanStatus)
 {
 	unsigned int CharNStat;
 	int ToRecv, wRecv, space, count;
-	unsigned char	*cbuf;
-	char		*fbuf;
-	
-	ToRecv= sGetRxCnt(cp);
-	space = 2*TTY_FLIPBUF_SIZE;
+	unsigned char *cbuf;
+	char *fbuf;
+
+	ToRecv = sGetRxCnt(cp);
+	space = tty->ldisc.receive_room(tty);
+	if (space > 2 * TTY_FLIPBUF_SIZE)
+		space = 2 * TTY_FLIPBUF_SIZE;
 	cbuf = tty->flip.char_buf;
 	fbuf = tty->flip.flag_buf;
 	count = 0;
 #ifdef ROCKET_DEBUG_INTR
-	printk("rp_do_receive(%d, %d)...", ToRecv, space);
+	printk(KERN_INFO "rp_do_receive(%d, %d)...", ToRecv, space);
 #endif
-	if (ToRecv == 0 || (space <= 0))
-		return;
-	
+
 	/*
 	 * determine how many we can actually read in.  If we can't
 	 * read any in then we have a software overrun condition.
 	 */
 	if (ToRecv > space)
 		ToRecv = space;
-	
+
+	if (ToRecv <= 0)
+		return;
+
 	/*
 	 * if status indicates there are errored characters in the
 	 * FIFO, then enter status mode (a word in FIFO holds
@@ -228,7 +361,7 @@
 	if (ChanStatus & (RXFOVERFL | RXBREAK | RXFRAME | RXPARITY)) {
 		if (!(ChanStatus & STATMODE)) {
 #ifdef ROCKET_DEBUG_RECEIVE
-			printk("Entering STATMODE...");
+			printk(KERN_INFO "Entering STATMODE...");
 #endif
 			ChanStatus |= STATMODE;
 			sEnRxStatusMode(cp);
@@ -242,16 +375,14 @@
 	 */
 	if (ChanStatus & STATMODE) {
 #ifdef ROCKET_DEBUG_RECEIVE
-		printk("Ignore %x, read %x...", info->ignore_status_mask,
+		printk(KERN_INFO "Ignore %x, read %x...", info->ignore_status_mask,
 		       info->read_status_mask);
 #endif
 		while (ToRecv) {
-			CharNStat= sInW(sGetTxRxDataIO(cp));
-
+			CharNStat = sInW(sGetTxRxDataIO(cp));
 #ifdef ROCKET_DEBUG_RECEIVE
-			printk("%x...", CharNStat);
+			printk(KERN_INFO "%x...", CharNStat);
 #endif
-
 			if (CharNStat & STMBREAKH)
 				CharNStat &= ~(STMFRAMEH | STMPARITYH);
 			if (CharNStat & info->ignore_status_mask) {
@@ -259,18 +390,14 @@
 				continue;
 			}
 			CharNStat &= info->read_status_mask;
-			if (CharNStat & STMBREAKH) {
+			if (CharNStat & STMBREAKH)
 				*fbuf++ = TTY_BREAK;
-#if 0
-				if (info->flags & ROCKET_SAK)
-					do_SAK(tty);
-#endif
-			} else if (CharNStat & STMPARITYH)
+			else if (CharNStat & STMPARITYH)
 				*fbuf++ = TTY_PARITY;
 			else if (CharNStat & STMFRAMEH)
 				*fbuf++ = TTY_FRAME;
 			else if (CharNStat & STMRCVROVRH)
-				*fbuf++ =TTY_OVERRUN;
+				*fbuf++ = TTY_OVERRUN;
 			else
 				*fbuf++ = 0;
 			*cbuf++ = CharNStat & 0xff;
@@ -284,7 +411,7 @@
 		 */
 		if (sGetRxCnt(cp) == 0) {
 #ifdef ROCKET_DEBUG_RECEIVE
-			printk("Status mode off.\n");
+			printk(KERN_INFO "Status mode off.\n");
 #endif
 			sDisRxStatusMode(cp);
 		}
@@ -294,86 +421,93 @@
 		 * characters at time by doing repeated word IO
 		 * transfer.
 		 */
-		wRecv= ToRecv >> 1;
+		wRecv = ToRecv >> 1;
 		if (wRecv)
-			sInStrW(sGetTxRxDataIO(cp), cbuf,
-				wRecv);
+			sInStrW(sGetTxRxDataIO(cp), (unsigned short *) cbuf, wRecv);
 		if (ToRecv & 1)
-			cbuf[ToRecv-1] = sInB(sGetTxRxDataIO(cp));
+			cbuf[ToRecv - 1] = sInB(sGetTxRxDataIO(cp));
 		memset(fbuf, 0, ToRecv);
 		cbuf += ToRecv;
 		fbuf += ToRecv;
 		count += ToRecv;
 	}
-	tty->ldisc.receive_buf(tty, tty->flip.char_buf,
-			       tty->flip.flag_buf, count);
+	/*  Push the data up to the tty layer */
+	tty->ldisc.receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);
 }
 
 /*
- * This routine is called when a transmit interrupt is found.  It's
- * responsible for pushing data found in the transmit buffer out to
- * the serial card.
+ *  Serial port transmit data function.  Called from the timer polling loop as a 
+ *  result of a bit set in xmit_flags[], indicating data (from the tty layer) is ready
+ *  to be sent out the serial port.  Data is buffered in rp_table[line].xmit_buf, it is 
+ *  moved to the port's xmit FIFO.  *info is critical data, protected by spinlocks.
  */
-static _INLINE_ void rp_do_transmit(struct r_port *info)
+static void rp_do_transmit(struct r_port *info)
 {
-	int	c;
+	int c;
 	CHANNEL_t *cp = &info->channel;
 	struct tty_struct *tty;
-	
+	unsigned long flags;
+
 #ifdef ROCKET_DEBUG_INTR
-	printk("rp_do_transmit ");
+	printk(KERN_INFO "rp_do_transmit ");
 #endif
 	if (!info)
 		return;
 	if (!info->tty) {
-		printk("rp: WARNING rp_do_transmit called with info->tty==NULL\n");
-		xmit_flags[info->line >> 5] &= ~(1 << (info->line & 0x1f));
+		printk(KERN_INFO  "rp: WARNING rp_do_transmit called with info->tty==NULL\n");
+		clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
 		return;
 	}
+
+	spin_lock_irqsave(&info->slock, flags);
 	tty = info->tty;
 	info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
+
+	/*  Loop sending data to FIFO until done or FIFO full */
 	while (1) {
 		if (tty->stopped || tty->hw_stopped)
 			break;
-		c = MIN(info->xmit_fifo_room,
-			MIN(info->xmit_cnt,
-			    XMIT_BUF_SIZE - info->xmit_tail));
+		c = MIN(info->xmit_fifo_room, MIN(info->xmit_cnt, XMIT_BUF_SIZE - info->xmit_tail));
 		if (c <= 0 || info->xmit_fifo_room <= 0)
 			break;
-		sOutStrW(sGetTxRxDataIO(cp),
-			 info->xmit_buf + info->xmit_tail, c/2);
+		sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) (info->xmit_buf + info->xmit_tail), c / 2);
 		if (c & 1)
-			sOutB(sGetTxRxDataIO(cp),
-			      info->xmit_buf[info->xmit_tail + c -
-					     1]);
+			sOutB(sGetTxRxDataIO(cp), info->xmit_buf[info->xmit_tail + c - 1]);
 		info->xmit_tail += c;
-		info->xmit_tail &= XMIT_BUF_SIZE-1;
+		info->xmit_tail &= XMIT_BUF_SIZE - 1;
 		info->xmit_cnt -= c;
 		info->xmit_fifo_room -= c;
 #ifdef ROCKET_DEBUG_INTR
-		printk("tx %d chars...", c);
+		printk(KERN_INFO "tx %d chars...", c);
 #endif
 	}
+
 	if (info->xmit_cnt == 0)
-		xmit_flags[info->line >> 5] &= ~(1 << (info->line & 0x1f));
+		clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
+
 	if (info->xmit_cnt < WAKEUP_CHARS) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup) (tty);
 		wake_up_interruptible(&tty->write_wait);
+#ifdef ROCKETPORT_HAVE_POLL_WAIT
+		wake_up_interruptible(&tty->poll_wait);
+#endif
 	}
+
+	spin_unlock_irqrestore(&info->slock, flags);
+
 #ifdef ROCKET_DEBUG_INTR
-	printk("(%d,%d,%d,%d)...", info->xmit_cnt, info->xmit_head,
+	printk(KERN_INFO "(%d,%d,%d,%d)...", info->xmit_cnt, info->xmit_head,
 	       info->xmit_tail, info->xmit_fifo_room);
 #endif
 }
 
 /*
- * This function is called for each port which has signalled an
- * interrupt.  It checks what interrupts are pending and services
- * them. 
+ *  Called when a serial port signals it has read data in it's RX FIFO.
+ *  It checks what interrupts are pending and services them, including
+ *  receiving serial data.  
  */
-static _INLINE_ void rp_handle_port(struct r_port *info)
+static void rp_handle_port(struct r_port *info)
 {
 	CHANNEL_t *cp;
 	struct tty_struct *tty;
@@ -381,12 +515,13 @@
 
 	if (!info)
 		return;
-	if ( (info->flags & ROCKET_INITIALIZED) == 0 ) {
-		printk("rp: WARNING: rp_handle_port called with info->flags & NOT_INIT\n");
+
+	if ((info->flags & ROCKET_INITIALIZED) == 0) {
+		printk(KERN_INFO "rp: WARNING: rp_handle_port called with info->flags & NOT_INIT\n");
 		return;
 	}
 	if (!info->tty) {
-		printk("rp: WARNING: rp_handle_port called with info->tty==NULL\n");
+		printk(KERN_INFO "rp: WARNING: rp_handle_port called with info->tty==NULL\n");
 		return;
 	}
 	cp = &info->channel;
@@ -394,25 +529,20 @@
 
 	IntMask = sGetChanIntID(cp) & info->intmask;
 #ifdef ROCKET_DEBUG_INTR
-	printk("rp_interrupt %02x...", IntMask);
+	printk(KERN_INFO "rp_interrupt %02x...", IntMask);
 #endif
-	ChanStatus= sGetChanStatus(cp);
+	ChanStatus = sGetChanStatus(cp);
 	if (IntMask & RXF_TRIG) {	/* Rx FIFO trigger level */
 		rp_do_receive(info, tty, cp, ChanStatus);
 	}
-#if 0
-	if (IntMask & SRC_INT) {	/* Special receive condition */
-	}
-#endif
 	if (IntMask & DELTA_CD) {	/* CD change  */
-#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || \
-     defined(ROCKET_DEBUG_HANGUP))
-		printk("ttyR%d CD now %s...", info->line,
+#if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_INTR) || defined(ROCKET_DEBUG_HANGUP))
+		printk(KERN_INFO "ttyR%d CD now %s...", info->line,
 		       (ChanStatus & CD_ACT) ? "on" : "off");
 #endif
 		if (!(ChanStatus & CD_ACT) && info->cd_status) {
 #ifdef ROCKET_DEBUG_HANGUP
-			printk("CD drop, calling hangup.\n");
+			printk(KERN_INFO "CD drop, calling hangup.\n");
 #endif
 			tty_hangup(tty);
 		}
@@ -421,125 +551,166 @@
 	}
 #ifdef ROCKET_DEBUG_INTR
 	if (IntMask & DELTA_CTS) {	/* CTS change */
-		printk("CTS change...\n");
+		printk(KERN_INFO "CTS change...\n");
 	}
 	if (IntMask & DELTA_DSR) {	/* DSR change */
-		printk("DSR change...\n");
+		printk(KERN_INFO "DSR change...\n");
 	}
 #endif
 }
 
 /*
- * The top level polling routine.
+ *  The top level polling routine.  Repeats every 1/100 HZ (10ms).
  */
 static void rp_do_poll(unsigned long dummy)
 {
 	CONTROLLER_t *ctlp;
-	int ctrl, aiop, ch, line;
+	int ctrl, aiop, ch, line, i;
 	unsigned int xmitmask;
-	unsigned char CtlMask, AiopMask;
+	unsigned int CtlMask;
+	unsigned char AiopMask;
+	Word_t bit;
 
 #ifdef TIME_STAT
-	unsigned long loop_time;
-	unsigned long long time_stat_tmp=0, time_stat_tmp2=0;
+	unsigned long low = 0, high = 0, loop_time;
+	unsigned long long time_stat_tmp = 0, time_stat_tmp2 = 0;
 
-	rdtscll(time_stat_tmp);
-#endif /* TIME_STAT */
+      __asm__(".byte 0x0f,0x31":"=a"(low), "=d"(high));
+	time_stat_tmp = high;
+	time_stat_tmp <<= 32;
+	time_stat_tmp += low;
+#endif				/* TIME_STAT */
 
-	for (ctrl=0; ctrl < max_board; ctrl++) {
+	/*  Walk through all the boards (ctrl's) */
+	for (ctrl = 0; ctrl < max_board; ctrl++) {
 		if (rcktpt_io_addr[ctrl] <= 0)
 			continue;
-		ctlp= sCtlNumToCtlPtr(ctrl);
 
+		/*  Get a ptr to the board's control struct */
+		ctlp = sCtlNumToCtlPtr(ctrl);
+
+		/*  Get the interupt status from the board */
 #ifdef CONFIG_PCI
-		if(ctlp->BusType == isPCI)
-			CtlMask= sPCIGetControllerIntStatus(ctlp);
+		if (ctlp->BusType == isPCI)
+			CtlMask = sPCIGetControllerIntStatus(ctlp);
 		else
 #endif
-			CtlMask= sGetControllerIntStatus(ctlp);
-		for (aiop=0; CtlMask; CtlMask >>= 1, aiop++) {
-			if (CtlMask & 1) {
-				AiopMask= sGetAiopIntStatus(ctlp, aiop);
-				for (ch=0; AiopMask; AiopMask >>= 1, ch++) {
+			CtlMask = sGetControllerIntStatus(ctlp);
+
+		/*  Check if any AIOP read bits are set */
+		for (aiop = 0; CtlMask; aiop++) {
+			bit = ctlp->AiopIntrBits[aiop];
+			if (CtlMask & bit) {
+				CtlMask &= ~bit;
+				AiopMask = sGetAiopIntStatus(ctlp, aiop);
+
+				/*  Check if any port read bits are set */
+				for (ch = 0; AiopMask;  AiopMask >>= 1, ch++) {
 					if (AiopMask & 1) {
-						line = (ctrl << 5) | 
-							(aiop << 3) | ch;
+
+						/*  Get the line number (/dev/ttyRx number). */
+						/*  Read the data from the port. */
+						line = GetLineNumber(ctrl, aiop, ch);
 						rp_handle_port(rp_table[line]);
 					}
 				}
 			}
 		}
+
 		xmitmask = xmit_flags[ctrl];
-		for (line = ctrl << 5; xmitmask; xmitmask >>= 1, line++) {
-			if (xmitmask & 1)
-				rp_do_transmit(rp_table[line]);
+
+		/*
+		 *  xmit_flags contains bit-significant flags, indicating there is data
+		 *  to xmit on the port. Bit 0 is port 0 on this board, bit 1 is port 
+		 *  1, ... (32 total possible).  The variable i has the aiop and ch 
+		 *  numbers encoded in it (port 0-7 are aiop0, 8-15 are aiop1, etc).
+		 */
+		if (xmitmask) {
+			for (i = 0; i < rocketModel[ctrl].numPorts; i++) {
+				if (xmitmask & (1 << i)) {
+					aiop = (i & 0x18) >> 3;
+					ch = i & 0x07;
+					line = GetLineNumber(ctrl, aiop, ch);
+					rp_do_transmit(rp_table[line]);
+				}
+			}
 		}
 	}
 
 	/*
-	 * Reset the timer so we get called at the next clock tick.
+	 * Reset the timer so we get called at the next clock tick (10ms).
 	 */
-	if (rp_num_ports_open) {
-		mod_timer(&rocket_timer, jiffies + 1);
-	}
+	if (atomic_read(&rp_num_ports_open))
+		mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
+
 #ifdef TIME_STAT
-	rdtscll(time_stat_tmp2);
+      __asm__(".byte 0x0f,0x31":"=a"(low), "=d"(high));
+	time_stat_tmp2 = high;
+	time_stat_tmp2 <<= 32;
+	time_stat_tmp2 += low;
 	time_stat_tmp2 -= time_stat_tmp;
 	time_stat += time_stat_tmp2;
-	if (time_counter == 0) 
+	if (time_counter == 0)
 		time_stat_short = time_stat_long = time_stat_tmp2;
 	else {
-		if ( time_stat_tmp2 < time_stat_short )
+		if (time_stat_tmp2 < time_stat_short)
 			time_stat_short = time_stat_tmp2;
-		else if ( time_stat_tmp2 > time_stat_long )
+		else if (time_stat_tmp2 > time_stat_long)
 			time_stat_long = time_stat_tmp2;
 	}
-	if ( ++time_counter == TIME_COUNTER ) {
-		loop_time = (unsigned long) ( ((unsigned long)(time_stat >> 32) * ( (unsigned long)(0xffffffff)/(TIME_STAT_CPU * TIME_COUNTER) ) ) + ((unsigned long)time_stat/(TIME_STAT_CPU*TIME_COUNTER)));
+	if (++time_counter == TIME_COUNTER) {
+		loop_time =
+		    (unsigned
+		     long) (((unsigned long) (time_stat >> 32) *
+			     ((unsigned long) (0xffffffff) /
+			      (TIME_STAT_CPU * TIME_COUNTER))) +
+			    ((unsigned long) time_stat /
+			     (TIME_STAT_CPU * TIME_COUNTER)));
 #ifdef TIME_STAT_VERBOSE
-		printk("rp_do_poll: Interrupt Timings\n");
-		printk("     %5ld iterations; %ld us min,\n",
-		       (long)TIME_COUNTER, (time_stat_short/TIME_STAT_CPU));
-		printk("     %5ld us max, %ld us average per iteration.\n",
-		       (time_stat_long/TIME_STAT_CPU), loop_time);
-		printk("We want to use < 5,000 us for an iteration.\n");
-#else /* TIME_STAT_VERBOSE */
-		printk("rp: %ld loops: %ld min, %ld max, %ld us/loop.\n",
-		       (long)TIME_COUNTER, (time_stat_short/TIME_STAT_CPU),
-		       (time_stat_long/TIME_STAT_CPU), loop_time);
-#endif /* TIME_STAT_VERBOSE */
+		printk(KERN_INFO "rp_do_poll: Interrupt Timings\n");
+		printk(KERN_INFO "     %5ld iterations; %ld us min,\n",
+		       (long) TIME_COUNTER,
+		       (time_stat_short / TIME_STAT_CPU));
+		printk(KERN_INFO "     %5ld us max, %ld us average per iteration.\n",
+		       (time_stat_long / TIME_STAT_CPU), loop_time);
+		printk(KERN_INFO "We want to use < 5,000 us for an iteration.\n");
+#else				/* TIME_STAT_VERBOSE */
+		printk(KERN_INFO "rp: %ld loops: %ld min, %ld max, %ld us/loop.\n",
+		       (long) TIME_COUNTER,
+		       (time_stat_short / TIME_STAT_CPU),
+		       (time_stat_long / TIME_STAT_CPU), loop_time);
+#endif				/* TIME_STAT_VERBOSE */
 		time_counter = time_stat = 0;
 		time_stat_short = time_stat_long = 0;
 	}
-#endif /* TIME_STAT */
+#endif				/* TIME_STAT */
 }
-/*
- * Here ends the interrupt/polling routine.
- */
-
 
 /*
- * This function initializes the r_port structure, as well as enabling
- * the port on the RocketPort board.
+ *  Initializes the r_port structure for a port, as well as enabling the port on 
+ *  the board.  
+ *  Inputs:  board, aiop, chan numbers
  */
-static void init_r_port(int board, int aiop, int chan)
+static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
 {
+	unsigned rocketMode;
 	struct r_port *info;
 	int line;
 	CONTROLLER_T *ctlp;
-	CHANNEL_t	*cp;
-	
-	line = (board << 5) | (aiop << 3) | chan;
 
-	ctlp= sCtlNumToCtlPtr(board);
+	/*  Get the next available line number */
+	line = SetLineNumber(board, aiop, chan);
 
-	info = kmalloc(sizeof(struct r_port), GFP_KERNEL);
+	ctlp = sCtlNumToCtlPtr(board);
+
+	/*  Get a r_port struct for the port, fill it in and save it globally, indexed by line number */
+	info = kmalloc(sizeof (struct r_port), GFP_KERNEL);
 	if (!info) {
-		printk("Couldn't allocate info struct for line #%d\n", line);
+		printk(KERN_INFO "Couldn't allocate info struct for line #%d\n", line);
 		return;
 	}
-	memset(info, 0, sizeof(struct r_port));
-	
+	memset(info, 0, sizeof (struct r_port));
+
 	info->magic = RPORT_MAGIC;
 	info->line = line;
 	info->ctlp = ctlp;
@@ -551,31 +722,73 @@
 	info->normal_termios = rocket_driver.init_termios;
 	init_waitqueue_head(&info->open_wait);
 	init_waitqueue_head(&info->close_wait);
+	info->flags &= ~ROCKET_MODE_MASK;
+	switch (pc104[board][line]) {
+	case 422:
+		info->flags |= ROCKET_MODE_RS422;
+		break;
+	case 485:
+		info->flags |= ROCKET_MODE_RS485;
+		break;
+	case 232:
+	default:
+		info->flags |= ROCKET_MODE_RS232;
+		break;
+	}
 
-	info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD |
-		DELTA_CTS | DELTA_DSR;
+	info->intmask = RXF_TRIG | TXFIFO_MT | SRC_INT | DELTA_CD | DELTA_CTS | DELTA_DSR;
 	if (sInitChan(ctlp, &info->channel, aiop, chan) == 0) {
-		printk("Rocketport sInitChan(%d, %d, %d) failed!\n",
-		       board, aiop, chan);
+		printk(KERN_INFO "RocketPort sInitChan(%d, %d, %d) failed!\n", board, aiop, chan);
 		kfree(info);
 		return;
 	}
-	cp = &info->channel;
+
+	rocketMode = info->flags & ROCKET_MODE_MASK;
+
+	if ((info->flags & ROCKET_RTS_TOGGLE) || (rocketMode == ROCKET_MODE_RS485))
+		sEnRTSToggle(&info->channel);
+	else
+		sDisRTSToggle(&info->channel);
+
+	if (ctlp->boardType == ROCKET_TYPE_PC104) {
+		switch (rocketMode) {
+		case ROCKET_MODE_RS485:
+			sSetInterfaceMode(&info->channel, InterfaceModeRS485);
+			break;
+		case ROCKET_MODE_RS422:
+			sSetInterfaceMode(&info->channel, InterfaceModeRS422);
+			break;
+		case ROCKET_MODE_RS232:
+		default:
+			if (info->flags & ROCKET_RTS_TOGGLE)
+				sSetInterfaceMode(&info->channel, InterfaceModeRS232T);
+			else
+				sSetInterfaceMode(&info->channel, InterfaceModeRS232);
+			break;
+		}
+	}
+	spin_lock_init(&info->slock);
+	sema_init(&info->write_sem, 1);
 	rp_table[line] = info;
+#if LINUX_VERSION_CODE > VERSION_CODE(2,5,0)
+	if (pci_dev)
+		tty_register_device(&rocket_driver, line, &pci_dev->dev);
+#endif
 }
 
-
 /*
- * This routine configures a rocketport port so according to its
- * termio settings.
+ *  Configures a rocketport port according to its termio settings.  Called from 
+ *  user mode into the driver (exception handler).  *info CD manipulation is spinlock protected.
  */
-static void configure_r_port(struct r_port *info)
+static void configure_r_port(struct r_port *info,
+			     struct termios *old_termios)
 {
 	unsigned cflag;
-	unsigned long 	flags;
-	int	bits, baud;
-	CHANNEL_t	*cp;
-	
+	unsigned long flags;
+	unsigned rocketMode;
+	int bits, baud, divisor;
+	CHANNEL_t *cp;
+
 	if (!info->tty || !info->tty->termios)
 		return;
 	cp = &info->channel;
@@ -589,13 +802,13 @@
 		sSetData7(cp);
 		bits = 9;
 	}
-        if (cflag & CSTOPB) {
+	if (cflag & CSTOPB) {
 		sSetStop2(cp);
 		bits++;
 	} else {
 		sSetStop1(cp);
 	}
-	
+
 	if (cflag & PARENB) {
 		sEnParity(cp);
 		bits++;
@@ -607,14 +820,28 @@
 	} else {
 		sDisParity(cp);
 	}
-	
+
 	/* baud rate */
 	baud = tty_get_baud_rate(info->tty);
 	if (!baud)
 		baud = 9600;
+	divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1;
+	if ((divisor >= 8192 || divisor < 0) && 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;
+		divisor = (rp_baud_base[info->board] / baud) - 1;
+	}
+	if (divisor >= 8192 || divisor < 0) {
+		baud = 9600;
+		divisor = (rp_baud_base[info->board] / baud) - 1;
+	}
 	info->cps = baud / bits;
-	sSetBaud(cp, (rp_baud_base/baud) - 1);
-	
+	sSetBaud(cp, divisor);
+
 	if (cflag & CRTSCTS) {
 		info->intmask |= DELTA_CTS;
 		sEnCTSFlowCtl(cp);
@@ -622,17 +849,16 @@
 		info->intmask &= ~DELTA_CTS;
 		sDisCTSFlowCtl(cp);
 	}
-	sSetRTS(&info->channel);
-	if (cflag & CLOCAL)
+	if (cflag & CLOCAL) {
 		info->intmask &= ~DELTA_CD;
-	else {
-		save_flags(flags); cli();
+	} else {
+		spin_lock_irqsave(&info->slock, flags);
 		if (sGetChanStatus(cp) & CD_ACT)
 			info->cd_status = 1;
 		else
 			info->cd_status = 0;
 		info->intmask |= DELTA_CD;
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->slock, flags);
 	}
 
 	/*
@@ -654,7 +880,7 @@
 		sClrTxXOFF(cp);
 	}
 #endif
-	
+
 	/*
 	 * Set up ignore/read mask words
 	 */
@@ -679,263 +905,281 @@
 		if (I_IGNPAR(info->tty))
 			info->ignore_status_mask |= STMRCVROVRH;
 	}
+
+	rocketMode = info->flags & ROCKET_MODE_MASK;
+
+	if ((info->flags & ROCKET_RTS_TOGGLE)
+	    || (rocketMode == ROCKET_MODE_RS485))
+		sEnRTSToggle(cp);
+	else
+		sDisRTSToggle(cp);
+
+	sSetRTS(&info->channel);
+
+	if (cp->CtlP->boardType == ROCKET_TYPE_PC104) {
+		switch (rocketMode) {
+		case ROCKET_MODE_RS485:
+			sSetInterfaceMode(cp, InterfaceModeRS485);
+			break;
+		case ROCKET_MODE_RS422:
+			sSetInterfaceMode(cp, InterfaceModeRS422);
+			break;
+		case ROCKET_MODE_RS232:
+		default:
+			if (info->flags & ROCKET_RTS_TOGGLE)
+				sSetInterfaceMode(cp, InterfaceModeRS232T);
+			else
+				sSetInterfaceMode(cp, InterfaceModeRS232);
+			break;
+		}
+	}
 }
 
-static int block_til_ready(struct tty_struct *tty, struct file * filp,
+/*  info->count is considered critical, protected by spinlocks.  */
+static int block_til_ready(struct tty_struct *tty, struct file *filp,
 			   struct r_port *info)
 {
 	DECLARE_WAITQUEUE(wait, current);
-	int		retval;
-	int		do_clocal = 0, extra_count = 0;
-	unsigned long	flags;
+	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))
-		return ((info->flags & ROCKET_HUP_NOTIFY) ? 
-			-EAGAIN : -ERESTARTSYS);
+		return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
 	if (info->flags & ROCKET_CLOSING) {
 		interruptible_sleep_on(&info->close_wait);
-		return ((info->flags & ROCKET_HUP_NOTIFY) ? 
-			-EAGAIN : -ERESTARTSYS);
+		return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
 	}
 
 	/*
 	 * 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 ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) {
 		info->flags |= ROCKET_NORMAL_ACTIVE;
 		return 0;
 	}
-
 	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
-	 * rp_close() knows when to free things.  We restore it upon
-	 * exit, either normal or abnormal.
+	 * Block waiting for the carrier detect and the line to become free.  While we are in
+	 * this loop, info->count is dropped by one, so that rp_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 ROCKET_DEBUG_OPEN
-	printk("block_til_ready before block: ttyR%d, count = %d\n",
-	       info->line, info->count);
+	printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, info->count);
 #endif
-	save_flags(flags); cli();
+	spin_lock_irqsave(&info->slock, flags);
+
+#ifdef ROCKET_DISABLE_SIMUSAGE
+	info->flags |= ROCKET_NORMAL_ACTIVE;
+#else
 	if (!tty_hung_up_p(filp)) {
 		extra_count = 1;
 		info->count--;
 	}
-	restore_flags(flags);
+#endif
 	info->blocked_open++;
+
+	spin_unlock_irqrestore(&info->slock, flags);
+
 	while (1) {
-		if ((tty->termios->c_cflag & CBAUD)) {
+		if (tty->termios->c_cflag & CBAUD) {
 			sSetDTR(&info->channel);
 			sSetRTS(&info->channel);
 		}
 		set_current_state(TASK_INTERRUPTIBLE);
-		if (tty_hung_up_p(filp) ||
-		    !(info->flags & ROCKET_INITIALIZED)) {
+		if (tty_hung_up_p(filp) || !(info->flags & ROCKET_INITIALIZED)) {
 			if (info->flags & ROCKET_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
-				retval = -ERESTARTSYS;	
+				retval = -ERESTARTSYS;
 			break;
 		}
-		if (!(info->flags & ROCKET_CLOSING) &&
-		    (do_clocal || (sGetChanStatusLo(&info->channel) &
-				   CD_ACT)))
+		if (!(info->flags & ROCKET_CLOSING) && (do_clocal || (sGetChanStatusLo(&info->channel) & CD_ACT)))
 			break;
 		if (signal_pending(current)) {
 			retval = -ERESTARTSYS;
 			break;
 		}
 #ifdef ROCKET_DEBUG_OPEN
-		printk("block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n",
-		       info->line, info->count, info->flags);
+		printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n",
+		     info->line, info->count, info->flags);
 #endif
-		schedule();
+		schedule();	/*  Don't hold spinlock here, will hang PC */
 	}
 	current->state = TASK_RUNNING;
 	remove_wait_queue(&info->open_wait, &wait);
-	cli();
+
+	spin_lock_irqsave(&info->slock, flags);
+
 	if (extra_count)
 		info->count++;
-	restore_flags(flags);
 	info->blocked_open--;
+
+	spin_unlock_irqrestore(&info->slock, flags);
+
 #ifdef ROCKET_DEBUG_OPEN
-	printk("block_til_ready after blocking: ttyR%d, count = %d\n",
+	printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n",
 	       info->line, info->count);
 #endif
 	if (retval)
 		return retval;
 	info->flags |= ROCKET_NORMAL_ACTIVE;
 	return 0;
-}	
+}
 
 /*
- * This routine is called whenever a rocketport board is opened.
+ *  Exception handler that opens a serial port.  Creates xmit_buf storage, fills in 
+ *  port's r_port struct.  Initializes the port hardware.  
  */
-static int rp_open(struct tty_struct *tty, struct file * filp)
+static int rp_open(struct tty_struct *tty, struct file *filp)
 {
 	struct r_port *info;
-	int	line, retval;
-	CHANNEL_t	*cp;
+	int line = 0, retval;
+	CHANNEL_t *cp;
 	unsigned long page;
-	
-	line = tty->index;
-	if ((line < 0) || (line >= MAX_RP_PORTS))
-		return -ENODEV;
-	if (!tmp_buf) {
-		page = get_zeroed_page(GFP_KERNEL);
-		if (!page)
-			return -ENOMEM;
-		if (tmp_buf)
-			free_page(page);
-		else
-			tmp_buf = (unsigned char *) page;
-	}
-	page = get_zeroed_page(GFP_KERNEL);
+
+#if LINUX_VERSION_CODE > VERSION_CODE(2,5,0)
+	line = TTY_GET_LINE(tty);
+#else
+	line = MINOR(tty->device) - TTY_DRIVER_MINOR_START(tty);
+#endif
+
+	if ((line < 0) || (line >= MAX_RP_PORTS) || ((info = rp_table[line]) == NULL))
+		return -ENXIO;
+
+	page = __get_free_page(GFP_KERNEL);
 	if (!page)
 		return -ENOMEM;
 
-	tty->driver_data = info = rp_table[line];
-	
 	if (info->flags & ROCKET_CLOSING) {
 		interruptible_sleep_on(&info->close_wait);
 		free_page(page);
-		return ((info->flags & ROCKET_HUP_NOTIFY) ?
-			-EAGAIN : -ERESTARTSYS);
+		return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS);
 	}
-	
+
 	/*
-	 * We must not sleep from here until the port is marked fully
-	 * in use.
+	 * We must not sleep from here until the port is marked fully in use.
 	 */
-	if (rp_table[line] == NULL) {
-		tty->flags = (1 << TTY_IO_ERROR);
-		free_page(page);
-		return 0;
-	}
-	if (!info) {
-		printk("rp_open: rp_table[%d] is NULL!\n", line);
-		free_page(page);
-		return -EIO;
-	}
 	if (info->xmit_buf)
 		free_page(page);
 	else
 		info->xmit_buf = (unsigned char *) page;
-	info->tty = tty;
 
-	if (info->flags & ROCKET_CLOSING) {
-		interruptible_sleep_on(&info->close_wait);
-		return ((info->flags & ROCKET_HUP_NOTIFY) ? 
-			-EAGAIN : -ERESTARTSYS);
-	}
+	tty->driver_data = info;
+	info->tty = tty;
 
 	if (info->count++ == 0) {
-		rp_num_ports_open++;
+#if ((LINUX_VERSION_CODE < VERSION_CODE(2,5,0)) && defined(MODULE))
+		MOD_INC_USE_COUNT;
+#endif
+		atomic_inc(&rp_num_ports_open);
+
 #ifdef ROCKET_DEBUG_OPEN
-		printk("rocket mod++ = %d...", rp_num_ports_open);
+		printk(KERN_INFO "rocket mod++ = %d...", atomic_read(&rp_num_ports_open));
 #endif
 	}
 #ifdef ROCKET_DEBUG_OPEN
-	printk("rp_open ttyR%d, count=%d\n", info->line, info->count);
+	printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->count);
 #endif
+
 	/*
 	 * Info->count is now 1; so it's safe to sleep now.
 	 */
-	
-	cp = &info->channel;
-	sSetRxTrigger(cp, TRIG_1);
-	if (sGetChanStatus(cp) & CD_ACT)
-		info->cd_status = 1;
-	else
-		info->cd_status = 0;
-	sDisRxStatusMode(cp);
-	sFlushRxFIFO(cp);	
-	sFlushTxFIFO(cp);	
-
-	sEnInterrupts(cp, (TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN));
-	sSetRxTrigger(cp, TRIG_1);
+	info->session = current->session;
+	info->pgrp = current->pgrp;
 
-	sGetChanStatus(cp);
-	sDisRxStatusMode(cp);
-	sClrTxXOFF(cp);
-
-	sDisCTSFlowCtl(cp);
-	sDisTxSoftFlowCtl(cp);
-
-	sEnRxFIFO(cp);
-	sEnTransmit(cp);
+	if ((info->flags & ROCKET_INITIALIZED) == 0) {
+		cp = &info->channel;
+		sSetRxTrigger(cp, TRIG_1);
+		if (sGetChanStatus(cp) & CD_ACT)
+			info->cd_status = 1;
+		else
+			info->cd_status = 0;
+		sDisRxStatusMode(cp);
+		sFlushRxFIFO(cp);
+		sFlushTxFIFO(cp);
 
-	info->flags |= ROCKET_INITIALIZED;
+		sEnInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
+		sSetRxTrigger(cp, TRIG_1);
 
-	/*
-	 * Set up the tty->alt_speed kludge
-	 */
-	if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
-		info->tty->alt_speed = 57600;
-	if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
-		info->tty->alt_speed = 115200;
-	if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
-		info->tty->alt_speed = 230400;
-	if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
-		info->tty->alt_speed = 460800;
+		sGetChanStatus(cp);
+		sDisRxStatusMode(cp);
+		sClrTxXOFF(cp);
 
-	configure_r_port(info);
-	if (tty->termios->c_cflag & CBAUD) {
-		sSetDTR(cp);
-		sSetRTS(cp);
+		sDisCTSFlowCtl(cp);
+		sDisTxSoftFlowCtl(cp);
+
+		sEnRxFIFO(cp);
+		sEnTransmit(cp);
+
+		info->flags |= ROCKET_INITIALIZED;
+
+		/*
+		 * Set up the tty->alt_speed kludge
+		 */
+		if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
+			info->tty->alt_speed = 460800;
+
+		configure_r_port(info, NULL);
+		if (tty->termios->c_cflag & CBAUD) {
+			sSetDTR(cp);
+			sSetRTS(cp);
+		}
 	}
-	
-	mod_timer(&rocket_timer, jiffies + 1);
+	/*  Starts (or resets) the maint polling loop */
+	mod_timer(&rocket_timer, jiffies + POLL_PERIOD);
 
 	retval = block_til_ready(tty, filp, info);
 	if (retval) {
 #ifdef ROCKET_DEBUG_OPEN
-		printk("rp_open returning after block_til_ready with %d\n",
-		       retval);
+		printk(KERN_INFO "rp_open returning after block_til_ready with %d\n", retval);
 #endif
 		return retval;
 	}
 
 	if ((info->count == 1) && (info->flags & ROCKET_SPLIT_TERMIOS)) {
 		*tty->termios = info->normal_termios;
-		configure_r_port(info);
+		configure_r_port(info, NULL);
 	}
-
 	return 0;
 }
 
-static void rp_close(struct tty_struct *tty, struct file * filp)
+/*
+ *  Exception handler that closes a serial port. info->count is considered critical. 
+ */
+static void rp_close(struct tty_struct *tty, struct file *filp)
 {
-	struct r_port * info = (struct r_port *)tty->driver_data;
+	struct r_port *info = (struct r_port *) tty->driver_data;
 	unsigned long flags;
 	int timeout;
-	CHANNEL_t	*cp;
+	CHANNEL_t *cp;
 
-	if (rocket_paranoia_check(info, tty->name, "rp_close"))
+	if (rocket_paranoia_check(info, "rp_close"))
 		return;
 
 #ifdef ROCKET_DEBUG_OPEN
-	printk("rp_close ttyR%d, count = %d\n", info->line, info->count);
+	printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->count);
 #endif
-	
-	save_flags(flags); cli();
-	
-	if (tty_hung_up_p(filp)) {
-		restore_flags(flags);
+
+	if (tty_hung_up_p(filp))
 		return;
-	}
+	spin_lock_irqsave(&info->slock, flags);
+
 	if ((tty->count == 1) && (info->count != 1)) {
 		/*
 		 * Uh, oh.  tty->count is 1, which means that the tty
@@ -944,27 +1188,23 @@
 		 * one, we've got real problems, since it means the
 		 * serial port won't be shutdown.
 		 */
-		printk("rp_close: bad serial port count; tty->count is 1, "
+		printk(KERN_INFO "rp_close: bad serial port count; tty->count is 1, "
 		       "info->count is %d\n", info->count);
 		info->count = 1;
 	}
 	if (--info->count < 0) {
-		printk("rp_close: bad serial port count for ttyR%d: %d\n",
+		printk(KERN_INFO "rp_close: bad serial port count for ttyR%d: %d\n",
 		       info->line, info->count);
 		info->count = 0;
 	}
 	if (info->count) {
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->slock, flags);
 		return;
 	}
 	info->flags |= ROCKET_CLOSING;
-	/*
-	 * Save the termios structure, since this port may have
-	 * separate termios for callout and dialin.
-	 */
-	if (info->flags & ROCKET_NORMAL_ACTIVE)
-		info->normal_termios = *tty->termios;
-	
+	spin_unlock_irqrestore(&info->slock, flags);
+
+	info->normal_termios = *tty->termios;
 	cp = &info->channel;
 
 	/*
@@ -989,29 +1229,30 @@
 	 * has completely drained; this is especially
 	 * important if there is a transmit FIFO!
 	 */
-	timeout = (sGetTxCnt(cp)+1) * HZ / info->cps;
+	timeout = (sGetTxCnt(cp) + 1) * HZ / info->cps;
 	if (timeout == 0)
 		timeout = 1;
 	rp_wait_until_sent(tty, timeout);
-	
-	xmit_flags[info->line >> 5] &= ~(1 << (info->line & 0x1f));
+	clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
+
 	sDisTransmit(cp);
-	sDisInterrupts(cp, (TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN));
+	sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
 	sDisCTSFlowCtl(cp);
 	sDisTxSoftFlowCtl(cp);
 	sClrTxXOFF(cp);
-	sFlushRxFIFO(cp);	
+	sFlushRxFIFO(cp);
 	sFlushTxFIFO(cp);
 	sClrRTS(cp);
-	if (C_HUPCL(tty)) {
+	if (C_HUPCL(tty))
 		sClrDTR(cp);
-	}
-	if (tty->driver->flush_buffer)
-		tty->driver->flush_buffer(tty);
+
+	if (TTY_DRIVER_FLUSH_BUFFER_EXISTS(tty))
+		TTY_DRIVER_FLUSH_BUFFER(tty);
 	if (tty->ldisc.flush_buffer)
 		tty->ldisc.flush_buffer(tty);
 
-	xmit_flags[info->line >> 5] &= ~(1 << (info->line & 0x1f));
+	clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
+
 	if (info->blocked_open) {
 		if (info->close_delay) {
 			current->state = TASK_INTERRUPTIBLE;
@@ -1027,27 +1268,27 @@
 	info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE);
 	tty->closing = 0;
 	wake_up_interruptible(&info->close_wait);
-	
-	rp_num_ports_open--;
-#ifdef ROCKET_DEBUG_OPEN
-	printk("rocket mod-- = %d...", rp_num_ports_open);
+
+#if ((LINUX_VERSION_CODE < VERSION_CODE(2,5,0)) && defined(MODULE))
+	MOD_DEC_USE_COUNT;
 #endif
-	restore_flags(flags);
-	
+	atomic_dec(&rp_num_ports_open);
+
 #ifdef ROCKET_DEBUG_OPEN
-	printk("rp_close ttyR%d complete shutdown\n", info->line);
+	printk(KERN_INFO "rocket mod-- = %d...", atomic_read(&rp_num_ports_open));
+	printk(KERN_INFO "rp_close ttyR%d complete shutdown\n", info->line);
 #endif
-	
+
 }
 
-static void rp_set_termios(struct tty_struct *tty, struct termios *old_termios)
+static void rp_set_termios(struct tty_struct *tty,
+			   struct termios *old_termios)
 {
-	struct r_port * info = (struct r_port *)tty->driver_data;
+	struct r_port *info = (struct r_port *) tty->driver_data;
 	CHANNEL_t *cp;
 	unsigned cflag;
-	
 
-	if (rocket_paranoia_check(info, tty->name, "rp_set_termios"))
+	if (rocket_paranoia_check(info, "rp_set_termios"))
 		return;
 
 	cflag = tty->termios->c_cflag;
@@ -1058,88 +1299,103 @@
 	/*
 	 * This driver doesn't support CS5 or CS6
 	 */
-	if (((cflag & CSIZE) == CS5) ||
-	    ((cflag & CSIZE) == CS6))
-		tty->termios->c_cflag = ((cflag & ~CSIZE) |
-					 (old_termios->c_cflag & CSIZE));
+	if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6))
+		tty->termios->c_cflag =
+		    ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE));
 
-	configure_r_port(info);
+	configure_r_port(info, old_termios);
 
 	cp = &info->channel;
 
 	/* Handle transition to B0 status */
-	if ((old_termios->c_cflag & CBAUD) &&
-	    !(tty->termios->c_cflag & CBAUD)) {
+	if ((old_termios->c_cflag & CBAUD) && !(tty->termios->c_cflag & CBAUD)) {
 		sClrDTR(cp);
 		sClrRTS(cp);
 	}
-	
+
 	/* Handle transition away from B0 status */
-	if (!(old_termios->c_cflag & CBAUD) &&
-	    (tty->termios->c_cflag & CBAUD)) {
-		if (!tty->hw_stopped ||
-		    !(tty->termios->c_cflag & CRTSCTS)) {
+	if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) {
+		if (!tty->hw_stopped || !(tty->termios->c_cflag & CRTSCTS))
 			sSetRTS(cp);
-		}
 		sSetDTR(cp);
 	}
-	
-	if ((old_termios->c_cflag & CRTSCTS) &&
-	    !(tty->termios->c_cflag & CRTSCTS)) {
+
+	if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
 		tty->hw_stopped = 0;
 		rp_start(tty);
 	}
 }
 
-/*
- * Here are the routines used by rp_ioctl
- */
 static void rp_break(struct tty_struct *tty, int break_state)
 {
-	struct r_port * info = (struct r_port *)tty->driver_data;
+	struct r_port *info = (struct r_port *) tty->driver_data;
 	unsigned long flags;
-	
-	if (rocket_paranoia_check(info, tty->name, "rp_break"))
+
+	if (rocket_paranoia_check(info, "rp_break"))
 		return;
 
-	save_flags(flags); cli();
-	if (break_state == -1) {
+	spin_lock_irqsave(&info->slock, flags);
+	if (break_state == -1)
 		sSendBreak(&info->channel);
-	} else {
+	else
 		sClrBreak(&info->channel);
-	}
-	restore_flags(flags);
+	spin_unlock_irqrestore(&info->slock, flags);
+}
+
+/*
+ * sGetChanRI used to be a macro in rocket_int.h. When the functionality for
+ * the UPCI boards was added, it was decided to make this a function because
+ * the macro was getting too complicated. All cases except the first one
+ * (UPCIRingInd) are taken directly from the original macro.
+ */
+static int sGetChanRI(CHANNEL_T * ChP)
+{
+	CONTROLLER_t *CtlP = ChP->CtlP;
+	int ChanNum = ChP->ChanNum;
+	int RingInd = 0;
+
+	if (CtlP->UPCIRingInd)
+		RingInd = !(sInB(CtlP->UPCIRingInd) & sBitMapSetTbl[ChanNum]);
+	else if (CtlP->AltChanRingIndicator)
+		RingInd = sInB((ByteIO_t) (ChP->ChanStat + 8)) & DSR_ACT;
+	else if (CtlP->boardType == ROCKET_TYPE_PC104)
+		RingInd = !(sInB(CtlP->AiopIO[3]) & sBitMapSetTbl[ChanNum]);
+
+	return RingInd;
 }
 
-static int get_modem_info(struct r_port * info, unsigned int *value)
+/********************************************************************************************/
+/*  Here are the routines used by rp_ioctl.  These are all called from exception handlers.  */
+
+static int get_modem_info(struct r_port *info, unsigned int *value)
 {
 	unsigned int control, result, ChanStatus;
 
 	ChanStatus = sGetChanStatusLo(&info->channel);
-	
+
 	control = info->channel.TxControl[3];
-	result =  ((control & SET_RTS) ? TIOCM_RTS : 0)
-		| ((control & SET_DTR) ? TIOCM_DTR : 0)
-		| ((ChanStatus  & CD_ACT) ? TIOCM_CAR : 0)
-			/* TIOCM_RNG not supported */
-		| ((ChanStatus  & DSR_ACT) ? TIOCM_DSR : 0)
-		| ((ChanStatus  & CTS_ACT) ? TIOCM_CTS : 0);
+	result = ((control & SET_RTS) ? TIOCM_RTS : 0) | 
+		((control & SET_DTR) ?  TIOCM_DTR : 0) |
+		((ChanStatus & CD_ACT) ? TIOCM_CAR : 0) |
+		(sGetChanRI(&info->channel) ? TIOCM_RNG : 0) |
+		((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0) |
+		((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0);
 
-	if (copy_to_user(value, &result, sizeof(int)))
+	if (copy_to_user(value, &result, sizeof (int)))
 		return -EFAULT;
 	return 0;
 }
 
-static int set_modem_info(struct r_port * info, unsigned int cmd,
+static int set_modem_info(struct r_port *info, unsigned int cmd,
 			  unsigned int *value)
 {
 	unsigned int arg;
 
-	if (copy_from_user(&arg, value, sizeof(int)))
+	if (copy_from_user(&arg, value, sizeof (int)))
 		return -EFAULT;
 
 	switch (cmd) {
-	case TIOCMBIS: 
+	case TIOCMBIS:
 		if (arg & TIOCM_RTS)
 			info->channel.TxControl[3] |= SET_RTS;
 		if (arg & TIOCM_DTR)
@@ -1152,59 +1408,103 @@
 			info->channel.TxControl[3] &= ~SET_DTR;
 		break;
 	case TIOCMSET:
-		info->channel.TxControl[3] =
-			((info->channel.TxControl[3] & ~(SET_RTS | SET_DTR))
-			 | ((arg & TIOCM_RTS) ? SET_RTS : 0)
-			 | ((arg & TIOCM_DTR) ? SET_DTR : 0));
+		info->channel.TxControl[3] = ((info->channel.TxControl[3] & ~(SET_RTS | SET_DTR)) | 
+					      ((arg & TIOCM_RTS) ? SET_RTS : 0) | 
+					      ((arg & TIOCM_DTR) ? SET_DTR : 0));
 		break;
 	default:
 		return -EINVAL;
 	}
 
-	sOutDW(info->channel.IndexAddr,
-	       *(DWord_t *) &(info->channel.TxControl[0]));
-	
+	sOutDW(info->channel.IndexAddr, *(DWord_t *) & (info->channel.TxControl[0]));
+	return 0;
+}
+
+#if LINUX_VERSION_CODE > VERSION_CODE(2,5,0)
+
+/*
+ *  Returns the state of the serial modem control lines.  These next 2 functions 
+ *  are the way kernel versions > 2.5 handle modem control lines rather than IOCTLs.
+ */
+static int rp_tiocmget(struct tty_struct *tty, struct file *file)
+{
+	struct r_port *info = (struct r_port *)tty->driver_data;
+	unsigned int control, result, ChanStatus;
+
+	ChanStatus = sGetChanStatusLo(&info->channel);
+	control = info->channel.TxControl[3];
+	result = ((control & SET_RTS) ? TIOCM_RTS : 0) | 
+		((control & SET_DTR) ?  TIOCM_DTR : 0) |
+		((ChanStatus & CD_ACT) ? TIOCM_CAR : 0) |
+		(sGetChanRI(&info->channel) ? TIOCM_RNG : 0) |
+		((ChanStatus & DSR_ACT) ? TIOCM_DSR : 0) |
+		((ChanStatus & CTS_ACT) ? TIOCM_CTS : 0);
+
+	return result;
+}
+
+/* 
+ *  Sets the modem control lines
+ */
+static int rp_tiocmset(struct tty_struct *tty, struct file *file,
+		    unsigned int set, unsigned int clear)
+{
+	struct r_port *info = (struct r_port *)tty->driver_data;
+
+	if (set & TIOCM_RTS)
+		info->channel.TxControl[3] |= SET_RTS;
+	if (set & TIOCM_DTR)
+		info->channel.TxControl[3] |= SET_DTR;
+	if (clear & TIOCM_RTS)
+		info->channel.TxControl[3] &= ~SET_RTS;
+	if (clear & TIOCM_DTR)
+		info->channel.TxControl[3] &= ~SET_DTR;
+
+	sOutDW(info->channel.IndexAddr, *(DWord_t *) & (info->channel.TxControl[0]));
 	return 0;
 }
 
-static int get_config(struct r_port * info, struct rocket_config * retinfo)
+#endif /*  Linux > 2.5 */
+
+static int get_config(struct r_port *info, struct rocket_config *retinfo)
 {
 	struct rocket_config tmp;
-  
+
 	if (!retinfo)
 		return -EFAULT;
-	memset(&tmp, 0, sizeof(tmp));
+	memset(&tmp, 0, sizeof (tmp));
 	tmp.line = info->line;
 	tmp.flags = info->flags;
 	tmp.close_delay = info->close_delay;
 	tmp.closing_wait = info->closing_wait;
 	tmp.port = rcktpt_io_addr[(info->line >> 5) & 3];
-	
-	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+
+	if (copy_to_user(retinfo, &tmp, sizeof (*retinfo)))
 		return -EFAULT;
 	return 0;
 }
 
-static int set_config(struct r_port * info, struct rocket_config * new_info)
+static int set_config(struct r_port *info, struct rocket_config *new_info)
 {
 	struct rocket_config new_serial;
 
-	if (copy_from_user(&new_serial, new_info, sizeof(new_serial)))
+	if (copy_from_user(&new_serial, new_info, sizeof (new_serial)))
 		return -EFAULT;
 
+#ifdef CAP_SYS_ADMIN
 	if (!capable(CAP_SYS_ADMIN))
+#else
+	if (!suser())
+#endif
 	{
-		if ((new_serial.flags & ~ROCKET_USR_MASK) !=
-		    (info->flags & ~ROCKET_USR_MASK))
+		if ((new_serial.flags & ~ROCKET_USR_MASK) != (info->flags & ~ROCKET_USR_MASK))
 			return -EPERM;
-		info->flags = ((info->flags & ~ROCKET_USR_MASK) |
-			       (new_serial.flags & ROCKET_USR_MASK));
-		configure_r_port(info);
+		info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK));
+		configure_r_port(info, 0);
 		return 0;
 	}
-	
-	info->flags = ((info->flags & ~ROCKET_FLAGS) |
-			(new_serial.flags & ROCKET_FLAGS));
+
+	info->flags = ((info->flags & ~ROCKET_FLAGS) | (new_serial.flags & ROCKET_FLAGS));
 	info->close_delay = new_serial.close_delay;
 	info->closing_wait = new_serial.closing_wait;
 
@@ -1216,117 +1516,162 @@
 		info->tty->alt_speed = 230400;
 	if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
 		info->tty->alt_speed = 460800;
-	
-	configure_r_port(info);
+
+	configure_r_port(info, 0);
 	return 0;
 }
 
-static int get_ports(struct r_port * info, struct rocket_ports * retports)
+/*
+ *  This function fills in a rocket_ports struct with information
+ *  about what boards/ports are in the system.  This info is passed
+ *  to user space.  See setrocket.c where the info is used to create
+ *  the /dev/ttyRx ports.
+ */
+static int get_ports(struct r_port *info, struct rocket_ports *retports)
 {
 	struct rocket_ports tmp;
-	int	board, port, index;
-  
+	int board;
+
 	if (!retports)
 		return -EFAULT;
-	memset(&tmp, 0, sizeof(tmp));
+	memset(&tmp, 0, sizeof (tmp));
 	tmp.tty_major = rocket_driver.major;
-	tmp.callout_major = 0;
+
 	for (board = 0; board < 4; board++) {
-		index = board << 5;
-		for (port = 0; port < 32; port++, index++) {
-			if (rp_table[index])
-				tmp.port_bitmap[board] |= 1 << port;
-		}
+		tmp.rocketModel[board].model = rocketModel[board].model;
+		strcpy(tmp.rocketModel[board].modelString, rocketModel[board].modelString);
+		tmp.rocketModel[board].numPorts = rocketModel[board].numPorts;
+		tmp.rocketModel[board].loadrm2 = rocketModel[board].loadrm2;
+		tmp.rocketModel[board].startingPortNumber = rocketModel[board].startingPortNumber;
 	}
-	if (copy_to_user(retports,&tmp,sizeof(*retports)))
+	if (copy_to_user(retports, &tmp, sizeof (*retports)))
 		return -EFAULT;
 	return 0;
 }
 
-static int rp_ioctl(struct tty_struct *tty, struct file * file,
+static int reset_rm2(struct r_port *info, unsigned long arg)
+{
+	int reset;
+
+	if (copy_from_user(&reset, (void *) arg, sizeof (int)))
+		return -EFAULT;
+	if (reset)
+		reset = 1;
+
+	if (rcktpt_type[info->board] != ROCKET_TYPE_MODEMII &&
+            rcktpt_type[info->board] != ROCKET_TYPE_MODEMIII)
+		return -EINVAL;
+
+	if (info->ctlp->BusType == isISA)
+		sModemReset(info->ctlp, info->chan, reset);
+	else
+		sPCIModemReset(info->ctlp, info->chan, reset);
+
+	return 0;
+}
+
+static int get_version(struct r_port *info, struct rocket_version *retvers)
+{
+	if (copy_to_user(retvers, &driver_version, sizeof (*retvers)))
+		return -EFAULT;
+	return 0;
+}
+
+/*  IOCTL call handler into the driver */
+static int rp_ioctl(struct tty_struct *tty, struct file *file,
 		    unsigned int cmd, unsigned long arg)
 {
-	struct r_port * info = (struct r_port *)tty->driver_data;
+	struct r_port *info = (struct r_port *) tty->driver_data;
 
-	if (cmd != RCKP_GET_PORTS &&
-	    rocket_paranoia_check(info, tty->name, "rp_ioctl"))
-		return -ENODEV;
+	if (cmd != RCKP_GET_PORTS && rocket_paranoia_check(info, "rp_ioctl"))
+		return -ENXIO;
 
 	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 RCKP_GET_STRUCT:
-			if (copy_to_user((void *) arg, info,
-					 sizeof(struct r_port)))
-				return -EFAULT;
-			return 0;
-
-		case RCKP_GET_CONFIG:
-			return get_config(info, (struct rocket_config *) arg);
-		case RCKP_SET_CONFIG:
-			return set_config(info, (struct rocket_config *) arg);
-			
-		case RCKP_GET_PORTS:
-			return get_ports(info, (struct rocket_ports *) arg);
-		default:
-			return -ENOIOCTLCMD;
-		}
+	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 RCKP_GET_STRUCT:
+		if (copy_to_user((void *) arg, info, sizeof (struct r_port)))
+			return -EFAULT;
+		return 0;
+	case RCKP_GET_CONFIG:
+		return get_config(info, (struct rocket_config *) arg);
+	case RCKP_SET_CONFIG:
+		return set_config(info, (struct rocket_config *) arg);
+	case RCKP_GET_PORTS:
+		return get_ports(info, (struct rocket_ports *) arg);
+	case RCKP_RESET_RM2:
+		return reset_rm2(info, arg);
+	case RCKP_GET_VERSION:
+		return get_version(info, (struct rocket_version *) arg);
+	default:
+		return -ENOIOCTLCMD;
+	}
 	return 0;
 }
 
+#if (defined(ROCKET_DEBUG_FLOW) || defined(ROCKET_DEBUG_THROTTLE))
+static char *rp_tty_name(struct tty_struct *tty, char *buf)
+{
+	if (tty)
+		sprintf(buf, "%s%d", TTY_DRIVER_NAME(tty), MINOR(tty->device) - TTY_DRIVER_MINOR_START(tty) + TTY_DRIVER_NAME_BASE);
+	else
+		strcpy(buf, "NULL tty");
+	return buf;
+}
+#endif
+
 static void rp_send_xchar(struct tty_struct *tty, char ch)
 {
-	struct r_port *info = (struct r_port *)tty->driver_data;
+	struct r_port *info = (struct r_port *) tty->driver_data;
 	CHANNEL_t *cp;
 
-	if (rocket_paranoia_check(info, tty->name, "rp_send_xchar"))
+	if (rocket_paranoia_check(info, "rp_send_xchar"))
 		return;
 
 	cp = &info->channel;
-	if (sGetTxCnt(cp)) 
+	if (sGetTxCnt(cp))
 		sWriteTxPrioByte(cp, ch);
 	else
 		sWriteTxByte(sGetTxRxDataIO(cp), ch);
 }
 
-static void rp_throttle(struct tty_struct * tty)
+static void rp_throttle(struct tty_struct *tty)
 {
-	struct r_port *info = (struct r_port *)tty->driver_data;
+	struct r_port *info = (struct r_port *) tty->driver_data;
 	CHANNEL_t *cp;
 #ifdef ROCKET_DEBUG_THROTTLE
-	char	buf[64];
-	
-	printk("throttle %s: %d....\n", tty->name,
+	char buf[64];
+
+	printk(KERN_INFO "throttle %s: %d....\n", rp_tty_name(tty, buf),
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
-	if (rocket_paranoia_check(info, tty->name, "rp_throttle"))
+	if (rocket_paranoia_check(info, "rp_throttle"))
 		return;
 
 	cp = &info->channel;
 	if (I_IXOFF(tty))
 		rp_send_xchar(tty, STOP_CHAR(tty));
-	
+
 	sClrRTS(&info->channel);
 }
 
-static void rp_unthrottle(struct tty_struct * tty)
+static void rp_unthrottle(struct tty_struct *tty)
 {
-	struct r_port *info = (struct r_port *)tty->driver_data;
+	struct r_port *info = (struct r_port *) tty->driver_data;
 	CHANNEL_t *cp;
 #ifdef ROCKET_DEBUG_THROTTLE
-	char	buf[64];
-	
-	printk("unthrottle %s: %d....\n", tty->name,
+	char buf[64];
+
+	printk(KERN_INFO "unthrottle %s: %d....\n", rp_tty_name(tty, buf),
 	       tty->ldisc.chars_in_buffer(tty));
 #endif
 
-	if (rocket_paranoia_check(info, tty->name, "rp_throttle"))
+	if (rocket_paranoia_check(info, "rp_throttle"))
 		return;
 
 	cp = &info->channel;
@@ -1346,15 +1691,15 @@
  */
 static void rp_stop(struct tty_struct *tty)
 {
-	struct r_port * info = (struct r_port *)tty->driver_data;
+	struct r_port *info = (struct r_port *) tty->driver_data;
 #ifdef ROCKET_DEBUG_FLOW
-	char	buf[64];
-	
-	printk("stop %s: %d %d....\n", tty->name,
+	char buf[64];
+
+	printk(KERN_INFO "stop %s: %d %d....\n", rp_tty_name(tty, buf),
 	       info->xmit_cnt, info->xmit_fifo_room);
 #endif
 
-	if (rocket_paranoia_check(info, tty->name, "rp_stop"))
+	if (rocket_paranoia_check(info, "rp_stop"))
 		return;
 
 	if (sGetTxCnt(&info->channel))
@@ -1363,19 +1708,20 @@
 
 static void rp_start(struct tty_struct *tty)
 {
-	struct r_port * info = (struct r_port *)tty->driver_data;
+	struct r_port *info = (struct r_port *) tty->driver_data;
 #ifdef ROCKET_DEBUG_FLOW
-	char	buf[64];
-	
-	printk("start %s: %d %d....\n", tty->name,
+	char buf[64];
+
+	printk(KERN_INFO "start %s: %d %d....\n", rp_tty_name(tty, buf),
 	       info->xmit_cnt, info->xmit_fifo_room);
 #endif
 
-	if (rocket_paranoia_check(info, tty->name, "rp_stop"))
+	if (rocket_paranoia_check(info, "rp_stop"))
 		return;
 
 	sEnTransmit(&info->channel);
-	xmit_flags[info->line >> 5] |= (1 << (info->line & 0x1f));
+	set_bit((info->aiop * 8) + info->chan,
+		(void *) &xmit_flags[info->board]);
 }
 
 /*
@@ -1383,21 +1729,22 @@
  */
 static void rp_wait_until_sent(struct tty_struct *tty, int timeout)
 {
-	struct r_port *info = (struct r_port *)tty->driver_data;
+	struct r_port *info = (struct r_port *) tty->driver_data;
 	CHANNEL_t *cp;
 	unsigned long orig_jiffies;
 	int check_time, exit_time;
 	int txcnt;
-	
-	if (rocket_paranoia_check(info, tty->name, "rp_wait_until_sent"))
+
+	if (rocket_paranoia_check(info, "rp_wait_until_sent"))
 		return;
 
 	cp = &info->channel;
 
 	orig_jiffies = jiffies;
 #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
-	printk("In RP_wait_until_sent(%d) (jiff=%lu)...", timeout, jiffies);
-	printk("cps=%d...", info->cps);
+	printk(KERN_INFO "In RP_wait_until_sent(%d) (jiff=%lu)...", timeout,
+	       jiffies);
+	printk(KERN_INFO "cps=%d...", info->cps);
 #endif
 	while (1) {
 		txcnt = sGetTxCnt(cp);
@@ -1405,8 +1752,9 @@
 			if (sGetChanStatusLo(cp) & TXSHRMT)
 				break;
 			check_time = (HZ / info->cps) / 5;
-		} else
+		} else {
 			check_time = HZ * txcnt / info->cps;
+		}
 		if (timeout) {
 			exit_time = orig_jiffies + timeout - jiffies;
 			if (exit_time <= 0)
@@ -1417,8 +1765,7 @@
 		if (check_time == 0)
 			check_time = 1;
 #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
-		printk("txcnt = %d (jiff=%lu,check=%d)...", txcnt,
-		       jiffies, check_time);
+		printk(KERN_INFO "txcnt = %d (jiff=%lu,check=%d)...", txcnt, jiffies, check_time);
 #endif
 		current->state = TASK_INTERRUPTIBLE;
 		schedule_timeout(check_time);
@@ -1427,7 +1774,7 @@
 	}
 	current->state = TASK_RUNNING;
 #ifdef ROCKET_DEBUG_WAIT_UNTIL_SENT
-	printk("txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
+	printk(KERN_INFO "txcnt = %d (jiff=%lu)...done\n", txcnt, jiffies);
 #endif
 }
 
@@ -1436,32 +1783,26 @@
  */
 static void rp_hangup(struct tty_struct *tty)
 {
-	CHANNEL_t	*cp;
-	struct r_port * info = (struct r_port *)tty->driver_data;
-	
-	if (rocket_paranoia_check(info, tty->name, "rp_hangup"))
+	CHANNEL_t *cp;
+	struct r_port *info = (struct r_port *) tty->driver_data;
+
+	if (rocket_paranoia_check(info, "rp_hangup"))
 		return;
 
 #if (defined(ROCKET_DEBUG_OPEN) || defined(ROCKET_DEBUG_HANGUP))
-	printk("rp_hangup of ttyR%d...", info->line);
+	printk(KERN_INFO "rp_hangup of ttyR%d...", info->line);
 #endif
-	/*
-	 * If the port is in the process of being closed, just force
-	 * the transmit buffer to be empty, and let rp_close handle
-	 * the clean up.
-	 */
-	if (info->flags & ROCKET_CLOSING) {
-		cli();
-		info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-		sti();
-		wake_up_interruptible(&tty->write_wait);
+	rp_flush_buffer(tty);
+	if (info->flags & ROCKET_CLOSING)
 		return;
-	}
 	if (info->count) {
-		rp_num_ports_open--;
+#if ((LINUX_VERSION_CODE < VERSION_CODE(2,5,0)) && defined(MODULE))
+		MOD_DEC_USE_COUNT;
+#endif
+		atomic_dec(&rp_num_ports_open);
 	}
-	
-	xmit_flags[info->line >> 5] &= ~(1 << (info->line & 0x1f));
+	clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
+
 	info->count = 0;
 	info->flags &= ~ROCKET_NORMAL_ACTIVE;
 	info->tty = 0;
@@ -1469,149 +1810,168 @@
 	cp = &info->channel;
 	sDisRxFIFO(cp);
 	sDisTransmit(cp);
-	sDisInterrupts(cp, (TXINT_EN|MCINT_EN|RXINT_EN|SRCINT_EN|CHANINT_EN));
+	sDisInterrupts(cp, (TXINT_EN | MCINT_EN | RXINT_EN | SRCINT_EN | CHANINT_EN));
 	sDisCTSFlowCtl(cp);
 	sDisTxSoftFlowCtl(cp);
 	sClrTxXOFF(cp);
 	info->flags &= ~ROCKET_INITIALIZED;
-	
+
 	wake_up_interruptible(&info->open_wait);
 }
 
 /*
- * The Rocketport write routines.  The Rocketport driver uses a
- * double-buffering strategy, with the twist that if the in-memory CPU
- * buffer is empty, and there's space in the transmit FIFO, the
- * writing routines will write directly to transmit FIFO.
- *
- * This gets a little tricky, but I'm pretty sure I got it all right.
+ *  Exception handler - write char routine.  The RocketPort driver uses a
+ *  double-buffering strategy, with the twist that if the in-memory CPU
+ *  buffer is empty, and there's space in the transmit FIFO, the
+ *  writing routines will write directly to transmit FIFO.
+ *  Write buffer and counters protected by spinlocks
  */
 static void rp_put_char(struct tty_struct *tty, unsigned char ch)
 {
-	struct r_port * info = (struct r_port *)tty->driver_data;
-	CHANNEL_t	*cp;
+	struct r_port *info = (struct r_port *) tty->driver_data;
+	CHANNEL_t *cp;
+	unsigned long flags;
 
-	if (rocket_paranoia_check(info, tty->name, "rp_put_char"))
+	if (rocket_paranoia_check(info, "rp_put_char"))
 		return;
 
+	/*  Grab the port write semaphore, locking out other processes that try to write to this port */
+	down(&info->write_sem);
+
 #ifdef ROCKET_DEBUG_WRITE
-	printk("rp_put_char %c...", ch);
+	printk(KERN_INFO "rp_put_char %c...", ch);
 #endif
-	
+
+	spin_lock_irqsave(&info->slock, flags);
 	cp = &info->channel;
 
 	if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room == 0)
 		info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
 
-	if (tty->stopped || tty->hw_stopped ||
-	    info->xmit_fifo_room == 0 || info->xmit_cnt != 0) {
+	if (tty->stopped || tty->hw_stopped || info->xmit_fifo_room == 0 || info->xmit_cnt != 0) {
 		info->xmit_buf[info->xmit_head++] = ch;
-		info->xmit_head &= XMIT_BUF_SIZE-1;
+		info->xmit_head &= XMIT_BUF_SIZE - 1;
 		info->xmit_cnt++;
-		xmit_flags[info->line >> 5] |= (1 << (info->line & 0x1f));
+		set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
 	} else {
 		sOutB(sGetTxRxDataIO(cp), ch);
 		info->xmit_fifo_room--;
 	}
+	spin_unlock_irqrestore(&info->slock, flags);
+	up(&info->write_sem);
 }
 
-static int rp_write(struct tty_struct * tty, int from_user,
+/*
+ *  Exception handler - write routine, called when user app writes to the device.
+ *  A per port write semaphore is used to protect from another process writing to
+ *  this port at the same time.  This other process could be running on the other CPU
+ *  or get control of the CPU if the copy_from_user() blocks due to a page fault (swapped out). 
+ *  Spinlocks protect the info xmit members.
+ */
+static int rp_write(struct tty_struct *tty, int from_user,
 		    const unsigned char *buf, int count)
 {
-	struct r_port * info = (struct r_port *)tty->driver_data;
-	CHANNEL_t	*cp;
-	const unsigned char	*b;
-	int		c, retval = 0;
-	unsigned long	flags;
+	struct r_port *info = (struct r_port *) tty->driver_data;
+	CHANNEL_t *cp;
+	const unsigned char *b;
+	int c, retval = 0;
+	unsigned long flags;
 
-	if (count <= 0 || rocket_paranoia_check(info, tty->name, "rp_write"))
+	if (count <= 0 || rocket_paranoia_check(info, "rp_write"))
 		return 0;
 
+	down_interruptible(&info->write_sem);
+
 #ifdef ROCKET_DEBUG_WRITE
-	printk("rp_write %d chars...", count);
+	printk(KERN_INFO "rp_write %d chars...", count);
 #endif
 	cp = &info->channel;
 
-	if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room == 0)
+	if (!tty->stopped && !tty->hw_stopped && info->xmit_fifo_room < count)
 		info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
 
-	if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0
-	    && info->xmit_fifo_room >= 0) {
+        /*
+	 *  If the write queue for the port is empty, and there is FIFO space, stuff bytes 
+	 *  into FIFO.  Use the write queue for temp storage.
+         */
+	if (!tty->stopped && !tty->hw_stopped && info->xmit_cnt == 0 && info->xmit_fifo_room > 0) {
 		c = MIN(count, info->xmit_fifo_room);
 		b = buf;
 		if (from_user) {
-			down(&tmp_buf_sem);
-			c -= copy_from_user(tmp_buf, buf, c);
-			b = tmp_buf;
-			up(&tmp_buf_sem);
-			/* In case we got pre-empted */
-			if (!c) {
+			if (copy_from_user(info->xmit_buf, buf, c)) {
 				retval = -EFAULT;
 				goto end;
 			}
 			if (info->tty == 0)
 				goto end;
+			b = info->xmit_buf;
 			c = MIN(c, info->xmit_fifo_room);
 		}
-		sOutStrW(sGetTxRxDataIO(cp), b, c/2);
+
+		/*  Push data into FIFO, 2 bytes at a time */
+		sOutStrW(sGetTxRxDataIO(cp), (unsigned short *) b, c / 2);
+
+		/*  If there is a byte remaining, write it */
 		if (c & 1)
-			sOutB(sGetTxRxDataIO(cp), b[c-1]);
+			sOutB(sGetTxRxDataIO(cp), b[c - 1]);
+
 		retval += c;
 		buf += c;
 		count -= c;
+
+		spin_lock_irqsave(&info->slock, flags);
 		info->xmit_fifo_room -= c;
+		spin_unlock_irqrestore(&info->slock, flags);
 	}
+
+	/* If count is zero, we wrote it all and are done */
 	if (!count)
 		goto end;
-	
-	save_flags(flags);
+
+	/*  Write remaining data into the port's xmit_buf */
 	while (1) {
-		if (info->tty == 0) {
-			restore_flags(flags);
+		if (info->tty == 0)	/*   Seemingly obligatory check... */
 			goto end;
-		}
-		c = MIN(count, MIN(XMIT_BUF_SIZE - info->xmit_cnt - 1,
-				   XMIT_BUF_SIZE - info->xmit_head));
+
+		c = MIN(count, MIN(XMIT_BUF_SIZE - info->xmit_cnt - 1, XMIT_BUF_SIZE - info->xmit_head));
 		if (c <= 0)
 			break;
 
 		b = buf;
 		if (from_user) {
-			down(&tmp_buf_sem);
-			c -= copy_from_user(tmp_buf, buf, c);
-			b = tmp_buf;
-			up(&tmp_buf_sem);
-			if (!c) {
-				if (retval == 0)
-					retval = -EFAULT;
+			if (copy_from_user(info->xmit_buf + info->xmit_head, b, c)) {
+				retval = -EFAULT;
 				goto end_intr;
+			} else {
+				memcpy(info->xmit_buf + info->xmit_head, b, c);
 			}
-			/* In case we got pre-empted */
-			if (info->tty == 0)
-				goto end_intr;
 		}
-		cli();
-		c = MIN(c, MIN(XMIT_BUF_SIZE - info->xmit_cnt - 1,
-			       XMIT_BUF_SIZE - info->xmit_head));
-		memcpy(info->xmit_buf + info->xmit_head, b, c);
-		info->xmit_head = (info->xmit_head + c) & (XMIT_BUF_SIZE-1);
+
+		spin_lock_irqsave(&info->slock, flags);
+		info->xmit_head =
+		    (info->xmit_head + c) & (XMIT_BUF_SIZE - 1);
 		info->xmit_cnt += c;
-		restore_flags(flags);
+		spin_unlock_irqrestore(&info->slock, flags);
+
 		buf += c;
 		count -= c;
 		retval += c;
 	}
+
 end_intr:
 	if ((retval > 0) && !tty->stopped && !tty->hw_stopped)
-		xmit_flags[info->line >> 5] |= (1 << (info->line & 0x1f));
-	restore_flags(flags);
+		set_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
+	
 end:
-	if (info->xmit_cnt < WAKEUP_CHARS) {
-		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-		    tty->ldisc.write_wakeup)
-			(tty->ldisc.write_wakeup)(tty);
+ 	if (info->xmit_cnt < WAKEUP_CHARS) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))  && tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup) (tty);
 		wake_up_interruptible(&tty->write_wait);
+#ifdef ROCKETPORT_HAVE_POLL_WAIT
+		wake_up_interruptible(&tty->poll_wait);
+#endif
 	}
+	up(&info->write_sem);
 	return retval;
 }
 
@@ -1622,17 +1982,17 @@
  */
 static int rp_write_room(struct tty_struct *tty)
 {
-	struct r_port * info = (struct r_port *)tty->driver_data;
-	int	ret;
+	struct r_port *info = (struct r_port *) tty->driver_data;
+	int ret;
 
-	if (rocket_paranoia_check(info, tty->name, "rp_write_room"))
+	if (rocket_paranoia_check(info, "rp_write_room"))
 		return 0;
 
 	ret = XMIT_BUF_SIZE - info->xmit_cnt - 1;
 	if (ret < 0)
 		ret = 0;
 #ifdef ROCKET_DEBUG_WRITE
-	printk("rp_write_room returns %d...", ret);
+	printk(KERN_INFO "rp_write_room returns %d...", ret);
 #endif
 	return ret;
 }
@@ -1643,332 +2003,655 @@
  */
 static int rp_chars_in_buffer(struct tty_struct *tty)
 {
-	struct r_port * info = (struct r_port *)tty->driver_data;
-	CHANNEL_t	*cp;
+	struct r_port *info = (struct r_port *) tty->driver_data;
+	CHANNEL_t *cp;
 
-	if (rocket_paranoia_check(info, tty->name, "rp_chars_in_buffer"))
+	if (rocket_paranoia_check(info, "rp_chars_in_buffer"))
 		return 0;
 
 	cp = &info->channel;
 
 #ifdef ROCKET_DEBUG_WRITE
-	printk("rp_chars_in_buffer returns %d...", info->xmit_cnt);
+	printk(KERN_INFO "rp_chars_in_buffer returns %d...", info->xmit_cnt);
 #endif
 	return info->xmit_cnt;
 }
 
+/*
+ *  Flushes the TX fifo for a port, deletes data in the xmit_buf stored in the
+ *  r_port struct for the port.  Note that spinlock are used to protect info members,
+ *  do not call this function if the spinlock is already held.
+ */
 static void rp_flush_buffer(struct tty_struct *tty)
 {
-	struct r_port * info = (struct r_port *)tty->driver_data;
-	CHANNEL_t	*cp;
+	struct r_port *info = (struct r_port *) tty->driver_data;
+	CHANNEL_t *cp;
+	unsigned long flags;
 
-	if (rocket_paranoia_check(info, tty->name, "rp_flush_buffer"))
+	if (rocket_paranoia_check(info, "rp_flush_buffer"))
 		return;
 
-	cli();
+	spin_lock_irqsave(&info->slock, flags);
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-	sti();
+	spin_unlock_irqrestore(&info->slock, flags);
+
 	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
-		(tty->ldisc.write_wakeup)(tty);
-	
+#ifdef ROCKETPORT_HAVE_POLL_WAIT
+	wake_up_interruptible(&tty->poll_wait);
+#endif
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup) (tty);
+
 	cp = &info->channel;
-	
 	sFlushTxFIFO(cp);
 }
 
 #ifdef CONFIG_PCI
-     
-int __init register_PCI(int i, unsigned int bus, unsigned int device_fn)
+
+/*
+ *  Called when a PCI card is found.  Retrieves and stores model information,
+ *  init's aiopic and serial port hardware.
+ *  Inputs:  i is the board number (0-n)
+ */
+__init int register_PCI(int i, struct pci_dev *dev)
 {
-	int	num_aiops, aiop, max_num_aiops, num_chan, chan;
-	unsigned int	aiopio[MAX_AIOPS_PER_BOARD];
-	char *str;
-	CONTROLLER_t	*ctlp;
-	struct pci_dev *dev = pci_find_slot(bus, device_fn);
+	int num_aiops, aiop, max_num_aiops, num_chan, chan;
+	unsigned int aiopio[MAX_AIOPS_PER_BOARD];
+	char *str, *board_type;
+	CONTROLLER_t *ctlp;
 
-	if (!dev)
+	int fast_clock = 0;
+	int altChanRingIndicator = 0;
+	int ports_per_aiop = 8;
+	int ret;
+	unsigned int class_rev;
+	WordIO_t ConfigIO = 0;
+	ByteIO_t UPCIRingInd = 0;
+
+	if (!dev || pci_enable_device(dev))
 		return 0;
 
-	if (pci_enable_device(dev))
+	rcktpt_io_addr[i] = pci_resource_start(dev, 0);
+	ret = pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
+
+	if (ret) {
+		printk(KERN_INFO "  Error during register_PCI(), unable to read config dword \n");
 		return 0;
+	}
+
+	rcktpt_type[i] = ROCKET_TYPE_NORMAL;
+	rocketModel[i].loadrm2 = 0;
+	rocketModel[i].startingPortNumber = nextLineNumber;
 
-	rcktpt_io_addr[i] = pci_resource_start (dev, 0);
-	switch(dev->device) {
+	/*  Depending on the model, set up some config variables */
+	switch (dev->device) {
 	case PCI_DEVICE_ID_RP4QUAD:
 		str = "Quadcable";
 		max_num_aiops = 1;
+		ports_per_aiop = 4;
+		rocketModel[i].model = MODEL_RP4QUAD;
+		strcpy(rocketModel[i].modelString, "RocketPort 4 port w/quad cable");
+		rocketModel[i].numPorts = 4;
 		break;
 	case PCI_DEVICE_ID_RP8OCTA:
 		str = "Octacable";
 		max_num_aiops = 1;
+		rocketModel[i].model = MODEL_RP8OCTA;
+		strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable");
+		rocketModel[i].numPorts = 8;
+		break;
+	case PCI_DEVICE_ID_URP8OCTA:
+		str = "Octacable";
+		max_num_aiops = 1;
+		rocketModel[i].model = MODEL_UPCI_RP8OCTA;
+		strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable");
+		rocketModel[i].numPorts = 8;
 		break;
 	case PCI_DEVICE_ID_RP8INTF:
 		str = "8";
 		max_num_aiops = 1;
+		rocketModel[i].model = MODEL_RP8INTF;
+		strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F");
+		rocketModel[i].numPorts = 8;
+		break;
+	case PCI_DEVICE_ID_URP8INTF:
+		str = "8";
+		max_num_aiops = 1;
+		rocketModel[i].model = MODEL_UPCI_RP8INTF;
+		strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F");
+		rocketModel[i].numPorts = 8;
 		break;
 	case PCI_DEVICE_ID_RP8J:
 		str = "8J";
 		max_num_aiops = 1;
+		rocketModel[i].model = MODEL_RP8J;
+		strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors");
+		rocketModel[i].numPorts = 8;
+		break;
+	case PCI_DEVICE_ID_RP4J:
+		str = "4J";
+		max_num_aiops = 1;
+		ports_per_aiop = 4;
+		rocketModel[i].model = MODEL_RP4J;
+		strcpy(rocketModel[i].modelString, "RocketPort 4 port w/RJ45 connectors");
+		rocketModel[i].numPorts = 4;
+		break;
+	case PCI_DEVICE_ID_RP8SNI:
+		str = "8 (DB78 Custom)";
+		max_num_aiops = 1;
+		rocketModel[i].model = MODEL_RP8SNI;
+		strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78");
+		rocketModel[i].numPorts = 8;
+		break;
+	case PCI_DEVICE_ID_RP16SNI:
+		str = "16 (DB78 Custom)";
+		max_num_aiops = 2;
+		rocketModel[i].model = MODEL_RP16SNI;
+		strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78");
+		rocketModel[i].numPorts = 16;
+		break;
+	case PCI_DEVICE_ID_RP16INTF:
+		str = "16";
+		max_num_aiops = 2;
+		rocketModel[i].model = MODEL_RP16INTF;
+		strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F");
+		rocketModel[i].numPorts = 16;
+		break;
+	case PCI_DEVICE_ID_URP16INTF:
+		str = "16";
+		max_num_aiops = 2;
+		rocketModel[i].model = MODEL_UPCI_RP16INTF;
+		strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F");
+		rocketModel[i].numPorts = 16;
+		break;
+	case PCI_DEVICE_ID_CRP16INTF:
+		str = "16";
+		max_num_aiops = 2;
+		rocketModel[i].model = MODEL_CPCI_RP16INTF;
+		strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F");
+		rocketModel[i].numPorts = 16;
+		break;
+	case PCI_DEVICE_ID_RP32INTF:
+		str = "32";
+		max_num_aiops = 4;
+		rocketModel[i].model = MODEL_RP32INTF;
+		strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F");
+		rocketModel[i].numPorts = 32;
+		break;
+	case PCI_DEVICE_ID_URP32INTF:
+		str = "32";
+		max_num_aiops = 4;
+		rocketModel[i].model = MODEL_UPCI_RP32INTF;
+		strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F");
+		rocketModel[i].numPorts = 32;
+		break;
+	case PCI_DEVICE_ID_RPP4:
+		str = "Plus Quadcable";
+		max_num_aiops = 1;
+		ports_per_aiop = 4;
+		altChanRingIndicator++;
+		fast_clock++;
+		rocketModel[i].model = MODEL_RPP4;
+		strcpy(rocketModel[i].modelString, "RocketPort Plus 4 port");
+		rocketModel[i].numPorts = 4;
+		break;
+	case PCI_DEVICE_ID_RPP8:
+		str = "Plus Octacable";
+		max_num_aiops = 2;
+		ports_per_aiop = 4;
+		altChanRingIndicator++;
+		fast_clock++;
+		rocketModel[i].model = MODEL_RPP8;
+		strcpy(rocketModel[i].modelString, "RocketPort Plus 8 port");
+		rocketModel[i].numPorts = 8;
+		break;
+	case PCI_DEVICE_ID_RP2_232:
+		str = "Plus 2 (RS-232)";
+		max_num_aiops = 1;
+		ports_per_aiop = 2;
+		altChanRingIndicator++;
+		fast_clock++;
+		rocketModel[i].model = MODEL_RP2_232;
+		strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS232");
+		rocketModel[i].numPorts = 2;
+		break;
+	case PCI_DEVICE_ID_RP2_422:
+		str = "Plus 2 (RS-422)";
+		max_num_aiops = 1;
+		ports_per_aiop = 2;
+		altChanRingIndicator++;
+		fast_clock++;
+		rocketModel[i].model = MODEL_RP2_422;
+		strcpy(rocketModel[i].modelString, "RocketPort Plus 2 port RS422");
+		rocketModel[i].numPorts = 2;
+		break;
+	case PCI_DEVICE_ID_RP6M:
+
+		max_num_aiops = 1;
+		ports_per_aiop = 6;
+		str = "6-port";
+
+		/*  If class_rev is 1, the rocketmodem flash must be loaded.  If it is 2 it is a "socketed" version. */
+		if ((class_rev & 0xFF) == 1) {
+			rcktpt_type[i] = ROCKET_TYPE_MODEMII;
+			rocketModel[i].loadrm2 = 1;
+		} else {
+			rcktpt_type[i] = ROCKET_TYPE_MODEM;
+		}
+
+		rocketModel[i].model = MODEL_RP6M;
+		strcpy(rocketModel[i].modelString, "RocketModem 6 port");
+		rocketModel[i].numPorts = 6;
+		break;
+	case PCI_DEVICE_ID_RP4M:
+		max_num_aiops = 1;
+		ports_per_aiop = 4;
+		str = "4-port";
+		if ((class_rev & 0xFF) == 1) {
+			rcktpt_type[i] = ROCKET_TYPE_MODEMII;
+			rocketModel[i].loadrm2 = 1;
+		} else {
+			rcktpt_type[i] = ROCKET_TYPE_MODEM;
+		}
+
+		rocketModel[i].model = MODEL_RP4M;
+		strcpy(rocketModel[i].modelString, "RocketModem 4 port");
+		rocketModel[i].numPorts = 4;
 		break;
-	case PCI_DEVICE_ID_RP16INTF:
-		str = "16";
-		max_num_aiops = 2;
+	default:
+		str = "(unknown/unsupported)";
+		max_num_aiops = 0;
 		break;
-	case PCI_DEVICE_ID_RP32INTF:
-		str = "32";
-		max_num_aiops = 4;
+	}
+
+	/*
+	 * Check for UPCI boards.
+	 */
+
+	switch (dev->device) {
+	case PCI_DEVICE_ID_URP32INTF:
+	case PCI_DEVICE_ID_URP8INTF:
+	case PCI_DEVICE_ID_URP16INTF:
+	case PCI_DEVICE_ID_CRP16INTF:
+	case PCI_DEVICE_ID_URP8OCTA:
+		rcktpt_io_addr[i] = pci_resource_start(dev, 2);
+		ConfigIO = pci_resource_start(dev, 1);
+		if (dev->device == PCI_DEVICE_ID_URP8OCTA) {
+			UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
+
+			/*
+			 * Check for octa or quad cable.
+			 */
+			if (!
+			    (sInW(ConfigIO + _PCI_9030_GPIO_CTRL) &
+			     PCI_GPIO_CTRL_8PORT)) {
+				str = "Quadcable";
+				ports_per_aiop = 4;
+				rocketModel[i].numPorts = 4;
+			}
+		}
 		break;
-	case PCI_DEVICE_ID_RPP4:
-		str = "Plus Quadcable";
+	case PCI_DEVICE_ID_UPCI_RM3_8PORT:
+		str = "8 ports";
 		max_num_aiops = 1;
+		rocketModel[i].model = MODEL_UPCI_RM3_8PORT;
+		strcpy(rocketModel[i].modelString, "RocketModem III 8 port");
+		rocketModel[i].numPorts = 8;
+		rcktpt_io_addr[i] = pci_resource_start(dev, 2);
+		UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
+		ConfigIO = pci_resource_start(dev, 1);
+		rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
 		break;
-	case PCI_DEVICE_ID_RPP8:
-		str = "Plus Octacable";
+	case PCI_DEVICE_ID_UPCI_RM3_4PORT:
+		str = "4 ports";
 		max_num_aiops = 1;
+		rocketModel[i].model = MODEL_UPCI_RM3_4PORT;
+		strcpy(rocketModel[i].modelString, "RocketModem III 4 port");
+		rocketModel[i].numPorts = 4;
+		rcktpt_io_addr[i] = pci_resource_start(dev, 2);
+		UPCIRingInd = rcktpt_io_addr[i] + _PCI_9030_RING_IND;
+		ConfigIO = pci_resource_start(dev, 1);
+		rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
 		break;
-	case PCI_DEVICE_ID_RP8M:
-		str = "8-port Modem";
-		max_num_aiops = 1;
+	default:
 		break;
-	case 0x8:
-		str = "mysterious 8 port";
-		max_num_aiops = 1;
+	}
+
+	switch (rcktpt_type[i]) {
+	case ROCKET_TYPE_MODEM:
+		board_type = "RocketModem";
+		break;
+	case ROCKET_TYPE_MODEMII:
+		board_type = "RocketModem II";
+		break;
+	case ROCKET_TYPE_MODEMIII:
+		board_type = "RocketModem III";
 		break;
 	default:
-		str = "(unknown/unsupported)";
-		max_num_aiops = 0;
+		board_type = "RocketPort";
 		break;
 	}
-	for(aiop=0;aiop < max_num_aiops;aiop++)
+
+	if (fast_clock) {
+		sClockPrescale = 0x12;	/* mod 2 (divide by 3) */
+		rp_baud_base[i] = 921600;
+	} else {
+		/*
+		 * If support_low_speed is set, use the slow clock
+		 * prescale, which supports 50 bps
+		 */
+		if (support_low_speed) {
+			/* mod 9 (divide by 10) prescale */
+			sClockPrescale = 0x19;
+			rp_baud_base[i] = 230400;
+		} else {
+			/* mod 4 (devide by 5) prescale */
+			sClockPrescale = 0x14;
+			rp_baud_base[i] = 460800;
+		}
+	}
+
+	for (aiop = 0; aiop < max_num_aiops; aiop++)
 		aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x40);
 	ctlp = sCtlNumToCtlPtr(i);
-	num_aiops = sPCIInitController(ctlp, i,
-					aiopio, max_num_aiops, 0,
-					FREQ_DIS, 0);
-	printk("Rocketport controller #%d found at %02x:%02x, "
-	       "%d AIOP(s) (PCI Rocketport %s)\n", i, bus, device_fn,
-	       num_aiops, str);
-	if(num_aiops <= 0) {
+	num_aiops = sPCIInitController(ctlp, i, aiopio, max_num_aiops, ConfigIO, 0, FREQ_DIS, 0, altChanRingIndicator, UPCIRingInd);
+	for (aiop = 0; aiop < max_num_aiops; aiop++)
+		ctlp->AiopNumChan[aiop] = ports_per_aiop;
+
+#if LINUX_VERSION_CODE < VERSION_CODE(2,3,99)
+	printk(KERN_INFO "Comtrol PCI controller #%d ID 0x%x found at 0x%lx, "
+	       "%d AIOP(s) (%s)\n", i, dev->device, rcktpt_io_addr[i],
+	       num_aiops, rocketModel[i].modelString);
+#else
+	printk
+	    ("Comtrol PCI controller #%d ID 0x%x found in bus:slot:fn %s at address %04lx, "
+	     "%d AIOP(s) (%s)\n", i, dev->device, dev->slot_name,
+	     rcktpt_io_addr[i], num_aiops, rocketModel[i].modelString);
+#endif
+
+	printk(KERN_INFO "Installing %s, creating /dev/ttyR%d - %ld\n",
+	       rocketModel[i].modelString,
+	       rocketModel[i].startingPortNumber,
+	       rocketModel[i].startingPortNumber +
+	       rocketModel[i].numPorts - 1);
+
+	if (num_aiops <= 0) {
 		rcktpt_io_addr[i] = 0;
-		return(0);
+		return (0);
 	}
-	for(aiop = 0;aiop < num_aiops; aiop++) {
+	is_PCI[i] = 1;
+
+	/*  Reset the AIOPIC, init the serial ports */
+	for (aiop = 0; aiop < num_aiops; aiop++) {
 		sResetAiopByNum(ctlp, aiop);
-		sEnAiop(ctlp, aiop);
-		num_chan = sGetAiopNumChan(ctlp, aiop);
-		for(chan=0;chan < num_chan; chan++)
-			init_r_port(i, aiop, chan);
+		num_chan = ports_per_aiop;
+		for (chan = 0; chan < num_chan; chan++)
+			init_r_port(i, aiop, chan, dev);
+	}
+
+	/*  Rocket modems must be reset */
+	if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) ||
+	    (rcktpt_type[i] == ROCKET_TYPE_MODEMII) ||
+	    (rcktpt_type[i] == ROCKET_TYPE_MODEMIII)) {
+		num_chan = ports_per_aiop;
+		for (chan = 0; chan < num_chan; chan++)
+			sPCIModemReset(ctlp, chan, 1);
+		mdelay(500);
+		for (chan = 0; chan < num_chan; chan++)
+			sPCIModemReset(ctlp, chan, 0);
+		mdelay(500);
+		rmSpeakerReset(ctlp, rocketModel[i].model);
 	}
-	return(1);
+	return (1);
 }
 
+#if LINUX_VERSION_CODE > VERSION_CODE(2,3,99)	/*  Linux version 2.4 and greater */
+
+
+/*
+ *  Probes for PCI cards, inits them if found
+ *  Input:   board_found = number of ISA boards already found, or the
+ *           starting board number
+ *  Returns: Number of PCI boards found
+ */
 static int __init init_PCI(int boards_found)
 {
-	unsigned char	bus, device_fn;
-	int	i, count = 0;
+	struct pci_dev *dev = NULL;
+	int count = 0;
 
-	for(i=0; i < (NUM_BOARDS - boards_found); i++) {
-		if (!pcibios_find_device(PCI_VENDOR_ID_RP,
-			PCI_DEVICE_ID_RP4QUAD, i, &bus, &device_fn)) 
-			if (register_PCI(count+boards_found, bus, device_fn))
-				count++;
-		if (!pcibios_find_device(PCI_VENDOR_ID_RP,
-			PCI_DEVICE_ID_RP8J, i, &bus, &device_fn)) 
-			if (register_PCI(count+boards_found, bus, device_fn))
-				count++;
-		if(!pcibios_find_device(PCI_VENDOR_ID_RP,
-			PCI_DEVICE_ID_RP8OCTA, i, &bus, &device_fn)) 
-			if(register_PCI(count+boards_found, bus, device_fn))
-				count++;
-		if(!pcibios_find_device(PCI_VENDOR_ID_RP,
-			PCI_DEVICE_ID_RP8INTF, i, &bus, &device_fn)) 
-			if(register_PCI(count+boards_found, bus, device_fn))
-				count++;
-		if(!pcibios_find_device(PCI_VENDOR_ID_RP,
-			PCI_DEVICE_ID_RP16INTF, i, &bus, &device_fn)) 
-			if(register_PCI(count+boards_found, bus, device_fn))
-				count++;
-		if(!pcibios_find_device(PCI_VENDOR_ID_RP,
-			PCI_DEVICE_ID_RP32INTF, i, &bus, &device_fn)) 
-			if(register_PCI(count+boards_found, bus, device_fn))
-				count++;
-		if(!pcibios_find_device(PCI_VENDOR_ID_RP,
-			PCI_DEVICE_ID_RP4QUAD, i, &bus, &device_fn)) 
-			if(register_PCI(count+boards_found, bus, device_fn))
-				count++;
-		if(!pcibios_find_device(PCI_VENDOR_ID_RP,
-			PCI_DEVICE_ID_RP8J, i, &bus, &device_fn)) 
-			if(register_PCI(count+boards_found, bus, device_fn))
-				count++;
-		if(!pcibios_find_device(PCI_VENDOR_ID_RP,
-			PCI_DEVICE_ID_RPP4, i, &bus, &device_fn)) 
-			if(register_PCI(count+boards_found, bus, device_fn))
-				count++;
-		if(!pcibios_find_device(PCI_VENDOR_ID_RP,
-			PCI_DEVICE_ID_RPP8, i, &bus, &device_fn)) 
-			if(register_PCI(count+boards_found, bus, device_fn))
-				count++;
-		if(!pcibios_find_device(PCI_VENDOR_ID_RP,
-			PCI_DEVICE_ID_RP8M, i, &bus, &device_fn)) 
-			if(register_PCI(count+boards_found, bus, device_fn))
-				count++;
-		if(!pcibios_find_device(PCI_VENDOR_ID_RP,
-			0x8, i, &bus, &device_fn)) 
-			if(register_PCI(count+boards_found, bus, device_fn))
-				count++;
+	/*  Work through the PCI device list, pulling out ours */
+	while ((dev = pci_find_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) {
+		if (register_PCI(count + boards_found, dev))
+			count++;
 	}
-	return(count);
+	return (count);
+}
+
+#else				/*  Linux version 2.2 */
+
+/*
+ *  Linux 2.2 pci_find_device() does not allow a search of all devices for a certain vendor,
+ *  you have to try each device ID.  Comtrol device ID's are 0x0000 -0x000F for the original
+ *  boards.  Newer board are 0x08xx (see upci_ids[]).
+ */
+static int __init init_PCI(int boards_found)
+{
+	int j, count = 0;
+	struct pci_dev *dev = NULL;
+
+	static int upci_ids[] = {
+		PCI_DEVICE_ID_URP32INTF,
+		PCI_DEVICE_ID_URP8INTF,
+		PCI_DEVICE_ID_URP16INTF,
+		PCI_DEVICE_ID_CRP16INTF,
+		PCI_DEVICE_ID_URP8OCTA,
+		PCI_DEVICE_ID_UPCI_RM3_8PORT,
+		PCI_DEVICE_ID_UPCI_RM3_4PORT
+	};
+
+#define NUM_UPCI_IDS	(sizeof(upci_ids) / sizeof(upci_ids[0]))
+
+	/*  Try finding devices with PCI ID's 0x0000 - 0x000F */
+	for (j = 0; j < 16; j++) {
+		while ((dev = pci_find_device(PCI_VENDOR_ID_RP, j, dev))) {
+			register_PCI(count + boards_found, dev);
+			count++;
+		}
+	}
+
+	/*  Now try finding the UPCI devices,  which have PCI ID's 0x0800 - 0x080F */
+	for (j = 0; j < NUM_UPCI_IDS; j++) {
+		while ((dev =
+			pci_find_device(PCI_VENDOR_ID_RP, upci_ids[j], dev))) {
+			register_PCI(count + boards_found, dev);
+			count++;
+		}
+	}
+	return (count);
 }
-#endif
 
+#endif				/*  Linux version 2.2/2.4 */
+
+#endif				/* CONFIG_PCI */
+
+/*
+ *  Probes for ISA cards
+ *  Input:   i = the board number to look for
+ *  Returns: 1 if board found, 0 else
+ */
 static int __init init_ISA(int i, int *reserved_controller)
 {
-	int	num_aiops, num_chan;
-	int	aiop, chan;
-	int     extent = 0;
-	unsigned int	aiopio[MAX_AIOPS_PER_BOARD];	
-	CONTROLLER_t	*ctlp;
+	int num_aiops, num_chan = 0, total_num_chan = 0;
+	int aiop, chan;
+	unsigned int aiopio[MAX_AIOPS_PER_BOARD];
+	CONTROLLER_t *ctlp;
+	char *type_string;
 
-	if (rcktpt_io_addr[i] == 0)
-		return(0);
+	if (rcktpt_io_addr[i] == 0 || controller == 0)
+		return (0);
 
+	if (check_region(rcktpt_io_addr[i], 64)) {
+		printk(KERN_INFO "RocketPort board address 0x%lx in use...\n", rcktpt_io_addr[i]);
+		rcktpt_io_addr[i] = 0;
+		return (0);
+	}
 	if (rcktpt_io_addr[i] + 0x40 == controller) {
 		*reserved_controller = 1;
-		extent = 68;
+		request_region(rcktpt_io_addr[i], 68, "Comtrol RocketPort");
 	} else {
-		extent = 64;
+		request_region(rcktpt_io_addr[i], 64, "Comtrol RocketPort");
 	}
-	if (!request_region(rcktpt_io_addr[i], extent,
-			    "Comtrol Rocketport")) {
-		printk("RocketPort board address 0x%lx in use...\n",
-		       rcktpt_io_addr[i]);
-		rcktpt_io_addr[i] = 0;
-		return(0);
+
+	ctlp = sCtlNumToCtlPtr(i);
+
+	ctlp->boardType = rcktpt_type[i];
+
+	switch (rcktpt_type[i]) {
+	case ROCKET_TYPE_PC104:
+		type_string = "(PC104)";
+		break;
+	case ROCKET_TYPE_MODEM:
+		type_string = "(RocketModem)";
+		break;
+	case ROCKET_TYPE_MODEMII:
+		type_string = "(RocketModem II)";
+		break;
+	default:
+		type_string = "";
+		break;
 	}
-	
-	for (aiop=0; aiop<MAX_AIOPS_PER_BOARD; aiop++)
-		aiopio[aiop]= rcktpt_io_addr[i] + (aiop * 0x400);
-	ctlp= sCtlNumToCtlPtr(i);
-	num_aiops = sInitController(ctlp, i, controller + (i*0x400),
-				    aiopio, MAX_AIOPS_PER_BOARD, 0,
-				    FREQ_DIS, 0);
+
+	/*
+	 * If support_low_speed is set, use the slow clock prescale,
+	 * which supports 50 bps
+	 */
+	if (support_low_speed) {
+		sClockPrescale = 0x19;	/* mod 9 (divide by 10) prescale */
+		rp_baud_base[i] = 230400;
+	} else {
+		sClockPrescale = 0x14;	/* mod 4 (devide by 5) prescale */
+		rp_baud_base[i] = 460800;
+	}
+
+	for (aiop = 0; aiop < MAX_AIOPS_PER_BOARD; aiop++)
+		aiopio[aiop] = rcktpt_io_addr[i] + (aiop * 0x400);
+
+	num_aiops =
+	    sInitController(ctlp, i, controller + (i * 0x400), aiopio,  MAX_AIOPS_PER_BOARD, 0, FREQ_DIS, 0);
+
+	if (ctlp->boardType == ROCKET_TYPE_PC104) {
+		sEnAiop(ctlp, 2);	/* only one AIOPIC, but these */
+		sEnAiop(ctlp, 3);	/* CSels used for other stuff */
+	}
+
 	if (num_aiops <= 0) {
-		release_region(rcktpt_io_addr[i], extent);
+		if (rcktpt_io_addr[i] + 0x40 == controller) {
+			*reserved_controller = 0;
+			release_region(rcktpt_io_addr[i], 68);
+		} else {
+			release_region(rcktpt_io_addr[i], 64);
+		}
 		rcktpt_io_addr[i] = 0;
-		return(0);
+		return (0);
 	}
 	for (aiop = 0; aiop < num_aiops; aiop++) {
 		sResetAiopByNum(ctlp, aiop);
 		sEnAiop(ctlp, aiop);
-		num_chan = sGetAiopNumChan(ctlp,aiop);
-		for (chan=0; chan < num_chan; chan++)
-			init_r_port(i, aiop, chan);
-	}
-	printk("Rocketport controller #%d found at 0x%lx, "
-	       "%d AIOPs\n", i, rcktpt_io_addr[i],
-	       num_aiops);
-	return(1);
-}
+		num_chan = sGetAiopNumChan(ctlp, aiop);
+		total_num_chan += num_chan;
+		for (chan = 0; chan < num_chan; chan++)
+			init_r_port(i, aiop, chan, NULL);
+	}
+	is_PCI[i] = 0;
+	if ((rcktpt_type[i] == ROCKET_TYPE_MODEM) || (rcktpt_type[i] == ROCKET_TYPE_MODEMII)) {
+		num_chan = sGetAiopNumChan(ctlp, 0);
+		total_num_chan = num_chan;
+		for (chan = 0; chan < num_chan; chan++)
+			sModemReset(ctlp, chan, 1);
+		mdelay(500);
+		for (chan = 0; chan < num_chan; chan++)
+			sModemReset(ctlp, chan, 0);
+		mdelay(500);
+		strcpy(rocketModel[i].modelString, "RocketModem ISA");
+	} else {
+		strcpy(rocketModel[i].modelString, "RocketPort ISA");
+	}
+	rocketModel[i].numPorts = total_num_chan;
+	rocketModel[i].model = MODEL_ISA;
+
+	printk(KERN_INFO "Comtrol ISA controller #%d found at 0x%lx, "
+	       "%d AIOPs %s\n", i, rcktpt_io_addr[i], num_aiops,
+	       type_string);
+	printk(KERN_INFO "Installing %s, creating /dev/ttyR%d - %ld\n",
+	       rocketModel[i].modelString,
+	       rocketModel[i].startingPortNumber,
+	       rocketModel[i].startingPortNumber +
+	       rocketModel[i].numPorts - 1);
 
+	return (1);
+}
 
 /*
  * The module "startup" routine; it's run when the module is loaded.
  */
 int __init rp_init(void)
 {
-	int i, retval, pci_boards_found, isa_boards_found;
-	int	reserved_controller = 0;
+	int retval, pci_boards_found, isa_boards_found, i;
+	int reserved_controller = 0;
 
-	printk("Rocketport device driver module, version %s, %s\n",
+	printk(KERN_INFO "RocketPort device driver module, version %s, %s\n",
 	       ROCKET_VERSION, ROCKET_DATE);
 
 	/*
-	 * Set up the timer channel.  If it is already in use by
-	 * some other driver, give up.
+	 * Set up the timer channel.
 	 */
-	if (rocket_timer.function) {
-		printk("rocket.o: Timer already in use!\n");
-		return -EBUSY;
-	}
 	init_timer(&rocket_timer);
 	rocket_timer.function = rp_do_poll;
-	
+
 	/*
 	 * Initialize the array of pointers to our own internal state
 	 * structures.
 	 */
-	memset(rp_table, 0, sizeof(rp_table));
-	memset(xmit_flags, 0, sizeof(xmit_flags));
+	memset(rp_table, 0, sizeof (rp_table));
+	memset(xmit_flags, 0, sizeof (xmit_flags));
+
+	for (i = 0; i < MAX_RP_PORTS; i++)
+		lineNumbers[i] = 0;
+	nextLineNumber = 0;
+	memset(rocketModel, 0, sizeof (rocketModel));
 
-	if (board1 == 0)
-		board1 = 0x180;
-	if (controller == 0)
+	if (board1 && controller == 0)
 		controller = board1 + 0x40;
 
-	if (check_region(controller, 4)) {
-		printk("Controller IO addresses in use, unloading driver.\n");
+	if (controller && check_region(controller, 4)) {
+		printk(KERN_INFO "Controller IO addresses in use, unloading driver.\n");
 		return -EBUSY;
 	}
-	
+
+	/*  Store ISA variable retrieved from command line or .conf file. */
 	rcktpt_io_addr[0] = board1;
 	rcktpt_io_addr[1] = board2;
 	rcktpt_io_addr[2] = board3;
 	rcktpt_io_addr[3] = board4;
 
-	/*
-	 * If support_low_speed is set, use the slow clock prescale,
-	 * which supports 50 bps
-	 */
-	if (support_low_speed) {
-		sClockPrescale = 0x19;	/* mod 9 (divide by 10) prescale */
-		rp_baud_base = 230400;
-	} else {
-		sClockPrescale = 0x14; /* mod 4 (devide by 5) prescale */
-		rp_baud_base = 460800;
-	}
-	
-	/*
-	 * OK, let's probe each of the controllers looking for boards.
-	 */
-	isa_boards_found = 0;
-	pci_boards_found = 0;
-	for (i=0; i < NUM_BOARDS; i++) {
-		if(init_ISA(i, &reserved_controller))
-			isa_boards_found++;
-	}
-#ifdef CONFIG_PCI
-	if (pci_present()) {
-		if(isa_boards_found < NUM_BOARDS)
-			pci_boards_found = init_PCI(isa_boards_found);
-	} else {
-		printk("No PCI BIOS found\n");
-	}
-#endif
-	max_board = pci_boards_found + isa_boards_found;
-	
-	if (max_board == 0) {
-		printk("No rocketport ports found; unloading driver.\n");
-		rocket_timer.function = 0;
-		return -ENODEV;
-	}
-
-	if (reserved_controller == 0)
-		request_region(controller, 4, "Comtrol Rocketport");
+	rcktpt_type[0] = modem1 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
+	rcktpt_type[0] = pc104_1[0] ? ROCKET_TYPE_PC104 : rcktpt_type[0];
+	rcktpt_type[1] = modem2 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
+	rcktpt_type[1] = pc104_2[0] ? ROCKET_TYPE_PC104 : rcktpt_type[1];
+	rcktpt_type[2] = modem3 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
+	rcktpt_type[2] = pc104_3[0] ? ROCKET_TYPE_PC104 : rcktpt_type[2];
+	rcktpt_type[3] = modem4 ? ROCKET_TYPE_MODEM : ROCKET_TYPE_NORMAL;
+	rcktpt_type[3] = pc104_4[0] ? ROCKET_TYPE_PC104 : rcktpt_type[3];
 
 	/*
 	 * Set up the tty driver structure and then register this
 	 * driver with the tty layer.
 	 */
-	memset(&rocket_driver, 0, sizeof(struct tty_driver));
+	memset(&rocket_driver, 0, sizeof (struct tty_driver));
 	rocket_driver.magic = TTY_DRIVER_MAGIC;
-	rocket_driver.owner = THIS_MODULE;
-#ifdef CONFIG_DEVFS_FS
-	rocket_driver.name = "tts/R";
-#else
+	rocket_driver.flags = TTY_DRIVER_NO_DEVFS;
 	rocket_driver.name = "ttyR";
-#endif
+	rocket_driver.driver_name = "Comtrol RocketPort";
 	rocket_driver.major = TTY_ROCKET_MAJOR;
 	rocket_driver.minor_start = 0;
 	rocket_driver.num = MAX_RP_PORTS;
@@ -1976,8 +2659,10 @@
 	rocket_driver.subtype = SERIAL_TYPE_NORMAL;
 	rocket_driver.init_termios = tty_std_termios;
 	rocket_driver.init_termios.c_cflag =
-		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-	rocket_driver.flags = TTY_DRIVER_REAL_RAW;
+	    B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+#ifdef ROCKET_SOFT_FLOW
+	rocket_driver.flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+#endif
 	rocket_driver.refcount = &rocket_refcount;
 	rocket_driver.table = rocket_table;
 	rocket_driver.termios = rocket_termios;
@@ -2001,58 +2686,93 @@
 	rocket_driver.send_xchar = rp_send_xchar;
 	rocket_driver.wait_until_sent = rp_wait_until_sent;
 
+#if (LINUX_VERSION_CODE > VERSION_CODE(2,5,0))
+	rocket_driver.owner = THIS_MODULE;
+	rocket_driver.tiocmget = rp_tiocmget;
+	rocket_driver.tiocmset = rp_tiocmset;
+#endif /* Kernel > 2.5 */
+
 	retval = tty_register_driver(&rocket_driver);
 	if (retval < 0) {
-		printk("Couldn't install tty Rocketport driver "
-		       "(error %d)\n", -retval);
-		release_region(controller, 4);
+		printk(KERN_INFO "Couldn't install tty RocketPort driver (error %d)\n", -retval);
 		return -1;
 	}
+
 #ifdef ROCKET_DEBUG_OPEN
-	printk("Rocketport driver is major %d\n",
-	       rocket_driver.major);
+	printk(KERN_INFO "RocketPort driver is major %d\n", rocket_driver.major);
+#endif
+
+	/*
+	 *  OK, let's probe each of the controllers looking for boards.  Any boards found
+         *  will be initialized here.
+	 */
+	isa_boards_found = 0;
+	pci_boards_found = 0;
+
+	for (i = 0; i < NUM_BOARDS; i++) {
+		if (init_ISA(i, &reserved_controller))
+			isa_boards_found++;
+	}
+
+#ifdef CONFIG_PCI
+	if (pci_present()) {
+		if (isa_boards_found < NUM_BOARDS)
+			pci_boards_found = init_PCI(isa_boards_found);
+	} else {
+		printk(KERN_INFO "No PCI BIOS found\n");
+	}
 #endif
 
+	max_board = pci_boards_found + isa_boards_found;
+
+	if (max_board == 0) {
+		printk(KERN_INFO "No rocketport ports found; unloading driver.\n");
+		del_timer_sync(&rocket_timer);
+		return -ENXIO;
+	}
+
+	if (isa_boards_found) {
+		if (reserved_controller == 0)
+			request_region(controller, 4, "Comtrol RocketPort");
+	} else {
+		controller = 0;
+	}
+
 	return 0;
 }
 
 #ifdef MODULE
-int init_module(void)
-{
-	return rp_init();
-}
 
-void
-cleanup_module( void) {
-	int	retval;
-	int	i;
-	int	released_controller = 0;
+static void rp_cleanup_module(void)
+{
+	int retval;
+	int i;
+	int released_controller = 0;
 
 	del_timer_sync(&rocket_timer);
 
 	retval = tty_unregister_driver(&rocket_driver);
-	if (retval) {
-		printk("Error %d while trying to unregister "
+	if (retval)
+		printk(KERN_INFO "Error %d while trying to unregister "
 		       "rocketport driver\n", -retval);
-	}
+
 	for (i = 0; i < MAX_RP_PORTS; i++) {
 		if (rp_table[i])
 			kfree(rp_table[i]);
 	}
-	for (i=0; i < NUM_BOARDS; i++) {
-		if (rcktpt_io_addr[i] <= 0)
+
+	for (i = 0; i < NUM_BOARDS; i++) {
+		if (rcktpt_io_addr[i] <= 0 || is_PCI[i])
 			continue;
 		if (rcktpt_io_addr[i] + 0x40 == controller) {
 			released_controller++;
 			release_region(rcktpt_io_addr[i], 68);
-		} else
+		} else {
 			release_region(rcktpt_io_addr[i], 64);
-		if (released_controller == 0)
-			release_region(controller, 4);
+		}
 	}
-	if (tmp_buf)
-		free_page((unsigned long) tmp_buf);
-	rocket_timer.function = 0;
+	if (controller && released_controller == 0)
+		release_region(controller, 4);
 }
 #endif
 
@@ -2088,69 +2808,60 @@
 #define FALSE 0
 #endif
 
-static Byte_t RData[RDATASIZE] =
-{
-   0x00, 0x09, 0xf6, 0x82,
-   0x02, 0x09, 0x86, 0xfb,
-   0x04, 0x09, 0x00, 0x0a,
-   0x06, 0x09, 0x01, 0x0a,
-   0x08, 0x09, 0x8a, 0x13,
-   0x0a, 0x09, 0xc5, 0x11,
-   0x0c, 0x09, 0x86, 0x85,
-   0x0e, 0x09, 0x20, 0x0a,
-   0x10, 0x09, 0x21, 0x0a,
-   0x12, 0x09, 0x41, 0xff,
-   0x14, 0x09, 0x82, 0x00,
-   0x16, 0x09, 0x82, 0x7b,
-   0x18, 0x09, 0x8a, 0x7d,
-   0x1a, 0x09, 0x88, 0x81,
-   0x1c, 0x09, 0x86, 0x7a,
-   0x1e, 0x09, 0x84, 0x81,
-   0x20, 0x09, 0x82, 0x7c,
-   0x22, 0x09, 0x0a, 0x0a 
-};
-
-static Byte_t RRegData[RREGDATASIZE]=
-{
-   0x00, 0x09, 0xf6, 0x82,             /* 00: Stop Rx processor */
-   0x08, 0x09, 0x8a, 0x13,             /* 04: Tx software flow control */
-   0x0a, 0x09, 0xc5, 0x11,             /* 08: XON char */
-   0x0c, 0x09, 0x86, 0x85,             /* 0c: XANY */
-   0x12, 0x09, 0x41, 0xff,             /* 10: Rx mask char */
-   0x14, 0x09, 0x82, 0x00,             /* 14: Compare/Ignore #0 */
-   0x16, 0x09, 0x82, 0x7b,             /* 18: Compare #1 */
-   0x18, 0x09, 0x8a, 0x7d,             /* 1c: Compare #2 */
-   0x1a, 0x09, 0x88, 0x81,             /* 20: Interrupt #1 */
-   0x1c, 0x09, 0x86, 0x7a,             /* 24: Ignore/Replace #1 */
-   0x1e, 0x09, 0x84, 0x81,             /* 28: Interrupt #2 */
-   0x20, 0x09, 0x82, 0x7c,             /* 2c: Ignore/Replace #2 */
-   0x22, 0x09, 0x0a, 0x0a              /* 30: Rx FIFO Enable */
+static Byte_t RData[RDATASIZE] = {
+	0x00, 0x09, 0xf6, 0x82,
+	0x02, 0x09, 0x86, 0xfb,
+	0x04, 0x09, 0x00, 0x0a,
+	0x06, 0x09, 0x01, 0x0a,
+	0x08, 0x09, 0x8a, 0x13,
+	0x0a, 0x09, 0xc5, 0x11,
+	0x0c, 0x09, 0x86, 0x85,
+	0x0e, 0x09, 0x20, 0x0a,
+	0x10, 0x09, 0x21, 0x0a,
+	0x12, 0x09, 0x41, 0xff,
+	0x14, 0x09, 0x82, 0x00,
+	0x16, 0x09, 0x82, 0x7b,
+	0x18, 0x09, 0x8a, 0x7d,
+	0x1a, 0x09, 0x88, 0x81,
+	0x1c, 0x09, 0x86, 0x7a,
+	0x1e, 0x09, 0x84, 0x81,
+	0x20, 0x09, 0x82, 0x7c,
+	0x22, 0x09, 0x0a, 0x0a
 };
 
-CONTROLLER_T sController[CTL_SIZE] =
-{
-   {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}},
-   {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}},
-   {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}},
-   {-1,-1,0,0,0,0,0,0,0,0,0,{0,0,0,0},{0,0,0,0},{-1,-1,-1,-1},{0,0,0,0}}
+static Byte_t RRegData[RREGDATASIZE] = {
+	0x00, 0x09, 0xf6, 0x82,	/* 00: Stop Rx processor */
+	0x08, 0x09, 0x8a, 0x13,	/* 04: Tx software flow control */
+	0x0a, 0x09, 0xc5, 0x11,	/* 08: XON char */
+	0x0c, 0x09, 0x86, 0x85,	/* 0c: XANY */
+	0x12, 0x09, 0x41, 0xff,	/* 10: Rx mask char */
+	0x14, 0x09, 0x82, 0x00,	/* 14: Compare/Ignore #0 */
+	0x16, 0x09, 0x82, 0x7b,	/* 18: Compare #1 */
+	0x18, 0x09, 0x8a, 0x7d,	/* 1c: Compare #2 */
+	0x1a, 0x09, 0x88, 0x81,	/* 20: Interrupt #1 */
+	0x1c, 0x09, 0x86, 0x7a,	/* 24: Ignore/Replace #1 */
+	0x1e, 0x09, 0x84, 0x81,	/* 28: Interrupt #2 */
+	0x20, 0x09, 0x82, 0x7c,	/* 2c: Ignore/Replace #2 */
+	0x22, 0x09, 0x0a, 0x0a	/* 30: Rx FIFO Enable */
 };
 
-#if 0
-/* IRQ number to MUDBAC register 2 mapping */
-Byte_t sIRQMap[16] =
-{
-   0,0,0,0x10,0x20,0x30,0,0,0,0x40,0x50,0x60,0x70,0,0,0x80
+CONTROLLER_T sController[CTL_SIZE] = {
+	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
+	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
+	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}},
+	{-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0, 0},
+	 {0, 0, 0, 0}, {-1, -1, -1, -1}, {0, 0, 0, 0}}
 };
-#endif
 
-Byte_t sBitMapClrTbl[8] =
-{
-   0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f
+Byte_t sBitMapClrTbl[8] = {
+	0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
 };
 
-Byte_t sBitMapSetTbl[8] =
-{
-   0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
+Byte_t sBitMapSetTbl[8] = {
+	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
 };
 
 int sClockPrescale = 0x14;
@@ -2225,76 +2936,68 @@
           After this function all AIOPs on the controller are disabled,
           they can be enabled with sEnAiop().
 */
-int sInitController(	CONTROLLER_T *CtlP,
-			int CtlNum,
-			ByteIO_t MudbacIO,
-			ByteIO_t *AiopIOList,
-			int AiopIOListSize,
-			int IRQNum,
-			Byte_t Frequency,
-			int PeriodicOnly)
-{
-	int		i;
-	ByteIO_t	io;
-
-   CtlP->CtlNum = CtlNum;
-   CtlP->CtlID = CTLID_0001;        /* controller release 1 */
-   CtlP->BusType = isISA;     
-   CtlP->MBaseIO = MudbacIO;
-   CtlP->MReg1IO = MudbacIO + 1;
-   CtlP->MReg2IO = MudbacIO + 2;
-   CtlP->MReg3IO = MudbacIO + 3;
+int sInitController(CONTROLLER_T * CtlP, int CtlNum, ByteIO_t MudbacIO,
+		    ByteIO_t * AiopIOList, int AiopIOListSize, int IRQNum,
+		    Byte_t Frequency, int PeriodicOnly)
+{
+	int i;
+	ByteIO_t io;
+	int done;
+
+	CtlP->AiopIntrBits = aiop_intr_bits;
+	CtlP->AltChanRingIndicator = 0;
+	CtlP->CtlNum = CtlNum;
+	CtlP->CtlID = CTLID_0001;	/* controller release 1 */
+	CtlP->BusType = isISA;
+	CtlP->MBaseIO = MudbacIO;
+	CtlP->MReg1IO = MudbacIO + 1;
+	CtlP->MReg2IO = MudbacIO + 2;
+	CtlP->MReg3IO = MudbacIO + 3;
 #if 1
-   CtlP->MReg2 = 0;                 /* interrupt disable */
-   CtlP->MReg3 = 0;                 /* no periodic interrupts */
+	CtlP->MReg2 = 0;	/* interrupt disable */
+	CtlP->MReg3 = 0;	/* no periodic interrupts */
 #else
-   if(sIRQMap[IRQNum] == 0)            /* interrupts globally disabled */
-   {
-      CtlP->MReg2 = 0;                 /* interrupt disable */
-      CtlP->MReg3 = 0;                 /* no periodic interrupts */
-   }
-   else
-   {
-      CtlP->MReg2 = sIRQMap[IRQNum];   /* set IRQ number */
-      CtlP->MReg3 = Frequency;         /* set frequency */
-      if(PeriodicOnly)                 /* periodic interrupt only */
-      {
-         CtlP->MReg3 |= PERIODIC_ONLY;
-      }
-   }
-#endif
-   sOutB(CtlP->MReg2IO,CtlP->MReg2);
-   sOutB(CtlP->MReg3IO,CtlP->MReg3);
-   sControllerEOI(CtlP);               /* clear EOI if warm init */
-   /* Init AIOPs */
-   CtlP->NumAiop = 0;
-   for(i=0; i < AiopIOListSize; i++)
-   {
-      io = AiopIOList[i];
-      CtlP->AiopIO[i] = (WordIO_t)io;
-      CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
-      sOutB(CtlP->MReg2IO,CtlP->MReg2 | (i & 0x03)); /* AIOP index */
-      sOutB(MudbacIO,(Byte_t)(io >> 6));	/* set up AIOP I/O in MUDBAC */
-      sEnAiop(CtlP,i);                         /* enable the AIOP */
-
-      CtlP->AiopID[i] = sReadAiopID(io);       /* read AIOP ID */
-      if(CtlP->AiopID[i] == AIOPID_NULL)       /* if AIOP does not exist */
-      {
-         sDisAiop(CtlP,i);                     /* disable AIOP */
-         break;                                /* done looking for AIOPs */
-      }
-
-      CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t)io); /* num channels in AIOP */
-      sOutW((WordIO_t)io + _INDX_ADDR,_CLK_PRE);      /* clock prescaler */
-      sOutB(io + _INDX_DATA,sClockPrescale);
-      CtlP->NumAiop++;                         /* bump count of AIOPs */
-      sDisAiop(CtlP,i);                        /* disable AIOP */
-   }
-
-   if(CtlP->NumAiop == 0)
-      return(-1);
-   else
-      return(CtlP->NumAiop);
+	if (sIRQMap[IRQNum] == 0) {	/* interrupts globally disabled */
+		CtlP->MReg2 = 0;	/* interrupt disable */
+		CtlP->MReg3 = 0;	/* no periodic interrupts */
+	} else {
+		CtlP->MReg2 = sIRQMap[IRQNum];	/* set IRQ number */
+		CtlP->MReg3 = Frequency;	/* set frequency */
+		if (PeriodicOnly) {	/* periodic interrupt only */
+			CtlP->MReg3 |= PERIODIC_ONLY;
+		}
+	}
+#endif
+	sOutB(CtlP->MReg2IO, CtlP->MReg2);
+	sOutB(CtlP->MReg3IO, CtlP->MReg3);
+	sControllerEOI(CtlP);	/* clear EOI if warm init */
+	/* Init AIOPs */
+	CtlP->NumAiop = 0;
+	for (i = done = 0; i < AiopIOListSize; i++) {
+		io = AiopIOList[i];
+		CtlP->AiopIO[i] = (WordIO_t) io;
+		CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
+		sOutB(CtlP->MReg2IO, CtlP->MReg2 | (i & 0x03));	/* AIOP index */
+		sOutB(MudbacIO, (Byte_t) (io >> 6));	/* set up AIOP I/O in MUDBAC */
+		if (done)
+			continue;
+		sEnAiop(CtlP, i);	/* enable the AIOP */
+		CtlP->AiopID[i] = sReadAiopID(io);	/* read AIOP ID */
+		if (CtlP->AiopID[i] == AIOPID_NULL)	/* if AIOP does not exist */
+			done = 1;	/* done looking for AIOPs */
+		else {
+			CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io);	/* num channels in AIOP */
+			sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE);	/* clock prescaler */
+			sOutB(io + _INDX_DATA, sClockPrescale);
+			CtlP->NumAiop++;	/* bump count of AIOPs */
+		}
+		sDisAiop(CtlP, i);	/* disable AIOP */
+	}
+
+	if (CtlP->NumAiop == 0)
+		return (-1);
+	else
+		return (CtlP->NumAiop);
 }
 
 /***************************************************************************
@@ -2366,46 +3069,55 @@
           After this function all AIOPs on the controller are disabled,
           they can be enabled with sEnAiop().
 */
-int sPCIInitController(	CONTROLLER_T *CtlP,
-			int CtlNum,
-			ByteIO_t *AiopIOList,
-			int AiopIOListSize,
-			int IRQNum,
-			Byte_t Frequency,
-			int PeriodicOnly)
-{
-	int		i;
-	ByteIO_t	io;
-
-   CtlP->CtlNum = CtlNum;
-   CtlP->CtlID = CTLID_0001;        /* controller release 1 */
-   CtlP->BusType = isPCI;        /* controller release 1 */
-
-   CtlP->PCIIO = (WordIO_t)((ByteIO_t)AiopIOList[0] + _PCI_INT_FUNC);
-
-   sPCIControllerEOI(CtlP);               /* clear EOI if warm init */
-   /* Init AIOPs */
-   CtlP->NumAiop = 0;
-   for(i=0; i < AiopIOListSize; i++)
-   {
-      io = AiopIOList[i];
-      CtlP->AiopIO[i] = (WordIO_t)io;
-      CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
-
-      CtlP->AiopID[i] = sReadAiopID(io);       /* read AIOP ID */
-      if(CtlP->AiopID[i] == AIOPID_NULL)       /* if AIOP does not exist */
-         break;                                /* done looking for AIOPs */
-
-      CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t)io); /* num channels in AIOP */
-      sOutW((WordIO_t)io + _INDX_ADDR,_CLK_PRE);      /* clock prescaler */
-      sOutB(io + _INDX_DATA,sClockPrescale);
-      CtlP->NumAiop++;                         /* bump count of AIOPs */
-   }
-
-   if(CtlP->NumAiop == 0)
-      return(-1);
-   else
-      return(CtlP->NumAiop);
+int sPCIInitController(CONTROLLER_T * CtlP, int CtlNum,
+		       ByteIO_t * AiopIOList, int AiopIOListSize,
+		       WordIO_t ConfigIO, int IRQNum, Byte_t Frequency,
+		       int PeriodicOnly, int altChanRingIndicator,
+		       int UPCIRingInd)
+{
+	int i;
+	ByteIO_t io;
+
+	CtlP->AltChanRingIndicator = altChanRingIndicator;
+	CtlP->UPCIRingInd = UPCIRingInd;
+	CtlP->CtlNum = CtlNum;
+	CtlP->CtlID = CTLID_0001;	/* controller release 1 */
+	CtlP->BusType = isPCI;	/* controller release 1 */
+
+	if (ConfigIO) {
+		CtlP->isUPCI = 1;
+		CtlP->PCIIO = ConfigIO + _PCI_9030_INT_CTRL;
+		CtlP->PCIIO2 = ConfigIO + _PCI_9030_GPIO_CTRL;
+		CtlP->AiopIntrBits = upci_aiop_intr_bits;
+	} else {
+		CtlP->isUPCI = 0;
+		CtlP->PCIIO =
+		    (WordIO_t) ((ByteIO_t) AiopIOList[0] + _PCI_INT_FUNC);
+		CtlP->AiopIntrBits = aiop_intr_bits;
+	}
+
+	sPCIControllerEOI(CtlP);	/* clear EOI if warm init */
+	/* Init AIOPs */
+	CtlP->NumAiop = 0;
+	for (i = 0; i < AiopIOListSize; i++) {
+		io = AiopIOList[i];
+		CtlP->AiopIO[i] = (WordIO_t) io;
+		CtlP->AiopIntChanIO[i] = io + _INT_CHAN;
+
+		CtlP->AiopID[i] = sReadAiopID(io);	/* read AIOP ID */
+		if (CtlP->AiopID[i] == AIOPID_NULL)	/* if AIOP does not exist */
+			break;	/* done looking for AIOPs */
+
+		CtlP->AiopNumChan[i] = sReadAiopNumChan((WordIO_t) io);	/* num channels in AIOP */
+		sOutW((WordIO_t) io + _INDX_ADDR, _CLK_PRE);	/* clock prescaler */
+		sOutB(io + _INDX_DATA, sClockPrescale);
+		CtlP->NumAiop++;	/* bump count of AIOPs */
+	}
+
+	if (CtlP->NumAiop == 0)
+		return (-1);
+	else
+		return (CtlP->NumAiop);
 }
 
 /***************************************************************************
@@ -2421,15 +3133,15 @@
 */
 int sReadAiopID(ByteIO_t io)
 {
-   Byte_t AiopID;               /* ID byte from AIOP */
+	Byte_t AiopID;		/* ID byte from AIOP */
 
-   sOutB(io + _CMD_REG,RESET_ALL);     /* reset AIOP */
-   sOutB(io + _CMD_REG,0x0);
-   AiopID = sInB(io + _CHN_STAT0) & 0x07;
-   if(AiopID == 0x06)
-      return(1);
-   else                                /* AIOP does not exist */
-      return(-1);
+	sOutB(io + _CMD_REG, RESET_ALL);	/* reset AIOP */
+	sOutB(io + _CMD_REG, 0x0);
+	AiopID = sInW(io + _CHN_STAT0) & 0x07;
+	if (AiopID == 0x06)
+		return (1);
+	else			/* AIOP does not exist */
+		return (-1);
 }
 
 /***************************************************************************
@@ -2447,16 +3159,18 @@
 */
 int sReadAiopNumChan(WordIO_t io)
 {
-   Word_t x;
+	Word_t x;
+	static Byte_t R[4] = { 0x00, 0x00, 0x34, 0x12 };
 
-   sOutDW((DWordIO_t)io + _INDX_ADDR,0x12340000L); /* write to chan 0 SRAM */
-   sOutW(io + _INDX_ADDR,0);       /* read from SRAM, chan 0 */
-   x = sInW(io + _INDX_DATA);
-   sOutW(io + _INDX_ADDR,0x4000);  /* read from SRAM, chan 4 */
-   if(x != sInW(io + _INDX_DATA))  /* if different must be 8 chan */
-      return(8);
-   else
-      return(4);
+	/* write to chan 0 SRAM */
+	sOutDW((DWordIO_t) io + _INDX_ADDR, *((DWord_t *) & R[0]));
+	sOutW(io + _INDX_ADDR, 0);	/* read from SRAM, chan 0 */
+	x = sInW(io + _INDX_DATA);
+	sOutW(io + _INDX_ADDR, 0x4000);	/* read from SRAM, chan 4 */
+	if (x != sInW(io + _INDX_DATA))	/* if different must be 8 chan */
+		return (8);
+	else
+		return (4);
 }
 
 /***************************************************************************
@@ -2474,138 +3188,134 @@
 
           No context switches are allowed while executing this function.
 */
-int sInitChan(	CONTROLLER_T *CtlP,
-		CHANNEL_T *ChP,
-		int AiopNum,
-		int ChanNum)
-{
-   int i;
-   WordIO_t AiopIO;
-   WordIO_t ChIOOff;
-   Byte_t *ChR;
-   Word_t ChOff;
-   static Byte_t R[4];
-   int brd9600;
-
-   if(ChanNum >= CtlP->AiopNumChan[AiopNum])
-      return(FALSE);                   /* exceeds num chans in AIOP */
-
-   /* Channel, AIOP, and controller identifiers */
-   ChP->CtlP = CtlP;
-   ChP->ChanID = CtlP->AiopID[AiopNum];
-   ChP->AiopNum = AiopNum;
-   ChP->ChanNum = ChanNum;
-
-   /* Global direct addresses */
-   AiopIO = CtlP->AiopIO[AiopNum];
-   ChP->Cmd = (ByteIO_t)AiopIO + _CMD_REG;
-   ChP->IntChan = (ByteIO_t)AiopIO + _INT_CHAN;
-   ChP->IntMask = (ByteIO_t)AiopIO + _INT_MASK;
-   ChP->IndexAddr = (DWordIO_t)AiopIO + _INDX_ADDR;
-   ChP->IndexData = AiopIO + _INDX_DATA;
-
-   /* Channel direct addresses */
-   ChIOOff = AiopIO + ChP->ChanNum * 2;
-   ChP->TxRxData = ChIOOff + _TD0;
-   ChP->ChanStat = ChIOOff + _CHN_STAT0;
-   ChP->TxRxCount = ChIOOff + _FIFO_CNT0;
-   ChP->IntID = (ByteIO_t)AiopIO + ChP->ChanNum + _INT_ID0;
-
-   /* Initialize the channel from the RData array */
-   for(i=0; i < RDATASIZE; i+=4)
-   {
-      R[0] = RData[i];
-      R[1] = RData[i+1] + 0x10 * ChanNum;
-      R[2] = RData[i+2];
-      R[3] = RData[i+3];
-      sOutDW(ChP->IndexAddr,*((DWord_t *)&R[0]));
-   }
-
-   ChR = ChP->R;
-   for(i=0; i < RREGDATASIZE; i+=4)
-   {
-      ChR[i] = RRegData[i];
-      ChR[i+1] = RRegData[i+1] + 0x10 * ChanNum;
-      ChR[i+2] = RRegData[i+2];
-      ChR[i+3] = RRegData[i+3];
-   }
-
-   /* Indexed registers */
-   ChOff = (Word_t)ChanNum * 0x1000;
-
-   if (sClockPrescale == 0x14)
-	   brd9600 = 47;
-   else
-	   brd9600 = 23;
-
-   ChP->BaudDiv[0] = (Byte_t)(ChOff + _BAUD);
-   ChP->BaudDiv[1] = (Byte_t)((ChOff + _BAUD) >> 8);
-   ChP->BaudDiv[2] = (Byte_t)brd9600;
-   ChP->BaudDiv[3] = (Byte_t)(brd9600 >> 8);
-   sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->BaudDiv[0]);
-
-   ChP->TxControl[0] = (Byte_t)(ChOff + _TX_CTRL);
-   ChP->TxControl[1] = (Byte_t)((ChOff + _TX_CTRL) >> 8);
-   ChP->TxControl[2] = 0;
-   ChP->TxControl[3] = 0;
-   sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]);
-
-   ChP->RxControl[0] = (Byte_t)(ChOff + _RX_CTRL);
-   ChP->RxControl[1] = (Byte_t)((ChOff + _RX_CTRL) >> 8);
-   ChP->RxControl[2] = 0;
-   ChP->RxControl[3] = 0;
-   sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]);
-
-   ChP->TxEnables[0] = (Byte_t)(ChOff + _TX_ENBLS);
-   ChP->TxEnables[1] = (Byte_t)((ChOff + _TX_ENBLS) >> 8);
-   ChP->TxEnables[2] = 0;
-   ChP->TxEnables[3] = 0;
-   sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxEnables[0]);
-
-   ChP->TxCompare[0] = (Byte_t)(ChOff + _TXCMP1);
-   ChP->TxCompare[1] = (Byte_t)((ChOff + _TXCMP1) >> 8);
-   ChP->TxCompare[2] = 0;
-   ChP->TxCompare[3] = 0;
-   sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxCompare[0]);
-
-   ChP->TxReplace1[0] = (Byte_t)(ChOff + _TXREP1B1);
-   ChP->TxReplace1[1] = (Byte_t)((ChOff + _TXREP1B1) >> 8);
-   ChP->TxReplace1[2] = 0;
-   ChP->TxReplace1[3] = 0;
-   sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxReplace1[0]);
-
-   ChP->TxReplace2[0] = (Byte_t)(ChOff + _TXREP2);
-   ChP->TxReplace2[1] = (Byte_t)((ChOff + _TXREP2) >> 8);
-   ChP->TxReplace2[2] = 0;
-   ChP->TxReplace2[3] = 0;
-   sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxReplace2[0]);
-
-   ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
-   ChP->TxFIFO = ChOff + _TX_FIFO;
-
-   sOutB(ChP->Cmd,(Byte_t)ChanNum | RESTXFCNT); /* apply reset Tx FIFO count */
-   sOutB(ChP->Cmd,(Byte_t)ChanNum);  /* remove reset Tx FIFO count */
-   sOutW((WordIO_t)ChP->IndexAddr,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
-   sOutW(ChP->IndexData,0);
-   ChP->RxFIFOPtrs = ChOff + _RXF_OUTP;
-   ChP->RxFIFO = ChOff + _RX_FIFO;
-
-   sOutB(ChP->Cmd,(Byte_t)ChanNum | RESRXFCNT); /* apply reset Rx FIFO count */
-   sOutB(ChP->Cmd,(Byte_t)ChanNum);  /* remove reset Rx FIFO count */
-   sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs); /* clear Rx out ptr */
-   sOutW(ChP->IndexData,0);
-   sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
-   sOutW(ChP->IndexData,0);
-   ChP->TxPrioCnt = ChOff + _TXP_CNT;
-   sOutW((WordIO_t)ChP->IndexAddr,ChP->TxPrioCnt);
-   sOutB(ChP->IndexData,0);
-   ChP->TxPrioPtr = ChOff + _TXP_PNTR;
-   sOutW((WordIO_t)ChP->IndexAddr,ChP->TxPrioPtr);
-   sOutB(ChP->IndexData,0);
-   ChP->TxPrioBuf = ChOff + _TXP_BUF;
-   sEnRxProcessor(ChP);                /* start the Rx processor */
+int sInitChan(CONTROLLER_T * CtlP, CHANNEL_T * ChP, int AiopNum,
+	      int ChanNum)
+{
+	int i;
+	WordIO_t AiopIO;
+	WordIO_t ChIOOff;
+	Byte_t *ChR;
+	Word_t ChOff;
+	static Byte_t R[4];
+	int brd9600;
+
+	if (ChanNum >= CtlP->AiopNumChan[AiopNum])
+		return (FALSE);	/* exceeds num chans in AIOP */
+
+	/* Channel, AIOP, and controller identifiers */
+	ChP->CtlP = CtlP;
+	ChP->ChanID = CtlP->AiopID[AiopNum];
+	ChP->AiopNum = AiopNum;
+	ChP->ChanNum = ChanNum;
+
+	/* Global direct addresses */
+	AiopIO = CtlP->AiopIO[AiopNum];
+	ChP->Cmd = (ByteIO_t) AiopIO + _CMD_REG;
+	ChP->IntChan = (ByteIO_t) AiopIO + _INT_CHAN;
+	ChP->IntMask = (ByteIO_t) AiopIO + _INT_MASK;
+	ChP->IndexAddr = (DWordIO_t) AiopIO + _INDX_ADDR;
+	ChP->IndexData = AiopIO + _INDX_DATA;
+
+	/* Channel direct addresses */
+	ChIOOff = AiopIO + ChP->ChanNum * 2;
+	ChP->TxRxData = ChIOOff + _TD0;
+	ChP->ChanStat = ChIOOff + _CHN_STAT0;
+	ChP->TxRxCount = ChIOOff + _FIFO_CNT0;
+	ChP->IntID = (ByteIO_t) AiopIO + ChP->ChanNum + _INT_ID0;
+
+	/* Initialize the channel from the RData array */
+	for (i = 0; i < RDATASIZE; i += 4) {
+		R[0] = RData[i];
+		R[1] = RData[i + 1] + 0x10 * ChanNum;
+		R[2] = RData[i + 2];
+		R[3] = RData[i + 3];
+		sOutDW(ChP->IndexAddr, *((DWord_t *) & R[0]));
+	}
+
+	ChR = ChP->R;
+	for (i = 0; i < RREGDATASIZE; i += 4) {
+		ChR[i] = RRegData[i];
+		ChR[i + 1] = RRegData[i + 1] + 0x10 * ChanNum;
+		ChR[i + 2] = RRegData[i + 2];
+		ChR[i + 3] = RRegData[i + 3];
+	}
+
+	/* Indexed registers */
+	ChOff = (Word_t) ChanNum *0x1000;
+
+	if (sClockPrescale == 0x14)
+		brd9600 = 47;
+	else
+		brd9600 = 23;
+
+	ChP->BaudDiv[0] = (Byte_t) (ChOff + _BAUD);
+	ChP->BaudDiv[1] = (Byte_t) ((ChOff + _BAUD) >> 8);
+	ChP->BaudDiv[2] = (Byte_t) brd9600;
+	ChP->BaudDiv[3] = (Byte_t) (brd9600 >> 8);
+	sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->BaudDiv[0]);
+
+	ChP->TxControl[0] = (Byte_t) (ChOff + _TX_CTRL);
+	ChP->TxControl[1] = (Byte_t) ((ChOff + _TX_CTRL) >> 8);
+	ChP->TxControl[2] = 0;
+	ChP->TxControl[3] = 0;
+	sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxControl[0]);
+
+	ChP->RxControl[0] = (Byte_t) (ChOff + _RX_CTRL);
+	ChP->RxControl[1] = (Byte_t) ((ChOff + _RX_CTRL) >> 8);
+	ChP->RxControl[2] = 0;
+	ChP->RxControl[3] = 0;
+	sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->RxControl[0]);
+
+	ChP->TxEnables[0] = (Byte_t) (ChOff + _TX_ENBLS);
+	ChP->TxEnables[1] = (Byte_t) ((ChOff + _TX_ENBLS) >> 8);
+	ChP->TxEnables[2] = 0;
+	ChP->TxEnables[3] = 0;
+	sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxEnables[0]);
+
+	ChP->TxCompare[0] = (Byte_t) (ChOff + _TXCMP1);
+	ChP->TxCompare[1] = (Byte_t) ((ChOff + _TXCMP1) >> 8);
+	ChP->TxCompare[2] = 0;
+	ChP->TxCompare[3] = 0;
+	sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxCompare[0]);
+
+	ChP->TxReplace1[0] = (Byte_t) (ChOff + _TXREP1B1);
+	ChP->TxReplace1[1] = (Byte_t) ((ChOff + _TXREP1B1) >> 8);
+	ChP->TxReplace1[2] = 0;
+	ChP->TxReplace1[3] = 0;
+	sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxReplace1[0]);
+
+	ChP->TxReplace2[0] = (Byte_t) (ChOff + _TXREP2);
+	ChP->TxReplace2[1] = (Byte_t) ((ChOff + _TXREP2) >> 8);
+	ChP->TxReplace2[2] = 0;
+	ChP->TxReplace2[3] = 0;
+	sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxReplace2[0]);
+
+	ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
+	ChP->TxFIFO = ChOff + _TX_FIFO;
+
+	sOutB(ChP->Cmd, (Byte_t) ChanNum | RESTXFCNT);	/* apply reset Tx FIFO count */
+	sOutB(ChP->Cmd, (Byte_t) ChanNum);	/* remove reset Tx FIFO count */
+	sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs);	/* clear Tx in/out ptrs */
+	sOutW(ChP->IndexData, 0);
+	ChP->RxFIFOPtrs = ChOff + _RXF_OUTP;
+	ChP->RxFIFO = ChOff + _RX_FIFO;
+
+	sOutB(ChP->Cmd, (Byte_t) ChanNum | RESRXFCNT);	/* apply reset Rx FIFO count */
+	sOutB(ChP->Cmd, (Byte_t) ChanNum);	/* remove reset Rx FIFO count */
+	sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs);	/* clear Rx out ptr */
+	sOutW(ChP->IndexData, 0);
+	sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2);	/* clear Rx in ptr */
+	sOutW(ChP->IndexData, 0);
+	ChP->TxPrioCnt = ChOff + _TXP_CNT;
+	sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioCnt);
+	sOutB(ChP->IndexData, 0);
+	ChP->TxPrioPtr = ChOff + _TXP_PNTR;
+	sOutW((WordIO_t) ChP->IndexAddr, ChP->TxPrioPtr);
+	sOutB(ChP->IndexData, 0);
+	ChP->TxPrioBuf = ChOff + _TXP_BUF;
+	sEnRxProcessor(ChP);	/* start the Rx processor */
 
-   return(TRUE);
+	return (TRUE);
 }
 
 /***************************************************************************
@@ -2626,15 +3336,15 @@
           After calling this function a delay of 4 uS is required to ensure
           that the receive processor is no longer processing this channel.
 */
-void sStopRxProcessor(CHANNEL_T *ChP)
+void sStopRxProcessor(CHANNEL_T * ChP)
 {
-   Byte_t R[4];
+	Byte_t R[4];
 
-   R[0] = ChP->R[0];
-   R[1] = ChP->R[1];
-   R[2] = 0x0a;
-   R[3] = ChP->R[3];
-   sOutDW(ChP->IndexAddr,*(DWord_t *)&R[0]);
+	R[0] = ChP->R[0];
+	R[1] = ChP->R[1];
+	R[2] = 0x0a;
+	R[3] = ChP->R[3];
+	sOutDW(ChP->IndexAddr, *(DWord_t *) & R[0]);
 }
 
 /***************************************************************************
@@ -2651,33 +3361,32 @@
           this function.
 Warnings: No context switches are allowed while executing this function.
 */
-void sFlushRxFIFO(CHANNEL_T *ChP)
+void sFlushRxFIFO(CHANNEL_T * ChP)
 {
-   int i;
-   Byte_t Ch;                   /* channel number within AIOP */
-   int RxFIFOEnabled;                  /* TRUE if Rx FIFO enabled */
-
-   if(sGetRxCnt(ChP) == 0)             /* Rx FIFO empty */
-      return;                          /* don't need to flush */
-
-   RxFIFOEnabled = FALSE;
-   if(ChP->R[0x32] == 0x08) /* Rx FIFO is enabled */
-   {
-      RxFIFOEnabled = TRUE;
-      sDisRxFIFO(ChP);                 /* disable it */
-      for(i=0; i < 2000/200; i++)	/* delay 2 uS to allow proc to disable FIFO*/
-         sInB(ChP->IntChan);		/* depends on bus i/o timing */
-   }
-   sGetChanStatus(ChP);          /* clear any pending Rx errors in chan stat */
-   Ch = (Byte_t)sGetChanNum(ChP);
-   sOutB(ChP->Cmd,Ch | RESRXFCNT);     /* apply reset Rx FIFO count */
-   sOutB(ChP->Cmd,Ch);                 /* remove reset Rx FIFO count */
-   sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs); /* clear Rx out ptr */
-   sOutW(ChP->IndexData,0);
-   sOutW((WordIO_t)ChP->IndexAddr,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
-   sOutW(ChP->IndexData,0);
-   if(RxFIFOEnabled)
-      sEnRxFIFO(ChP);                  /* enable Rx FIFO */
+	int i;
+	Byte_t Ch;		/* channel number within AIOP */
+	int RxFIFOEnabled;	/* TRUE if Rx FIFO enabled */
+
+	if (sGetRxCnt(ChP) == 0)	/* Rx FIFO empty */
+		return;		/* don't need to flush */
+
+	RxFIFOEnabled = FALSE;
+	if (ChP->R[0x32] == 0x08) {	/* Rx FIFO is enabled */
+		RxFIFOEnabled = TRUE;
+		sDisRxFIFO(ChP);	/* disable it */
+		for (i = 0; i < 2000 / 200; i++)	/* delay 2 uS to allow proc to disable FIFO */
+			sInB(ChP->IntChan);	/* depends on bus i/o timing */
+	}
+	sGetChanStatus(ChP);	/* clear any pending Rx errors in chan stat */
+	Ch = (Byte_t) sGetChanNum(ChP);
+	sOutB(ChP->Cmd, Ch | RESRXFCNT);	/* apply reset Rx FIFO count */
+	sOutB(ChP->Cmd, Ch);	/* remove reset Rx FIFO count */
+	sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs);	/* clear Rx out ptr */
+	sOutW(ChP->IndexData, 0);
+	sOutW((WordIO_t) ChP->IndexAddr, ChP->RxFIFOPtrs + 2);	/* clear Rx in ptr */
+	sOutW(ChP->IndexData, 0);
+	if (RxFIFOEnabled)
+		sEnRxFIFO(ChP);	/* enable Rx FIFO */
 }
 
 /***************************************************************************
@@ -2694,32 +3403,31 @@
           this function.
 Warnings: No context switches are allowed while executing this function.
 */
-void sFlushTxFIFO(CHANNEL_T *ChP)
+void sFlushTxFIFO(CHANNEL_T * ChP)
 {
-   int i;
-   Byte_t Ch;                   /* channel number within AIOP */
-   int TxEnabled;                      /* TRUE if transmitter enabled */
-
-   if(sGetTxCnt(ChP) == 0)             /* Tx FIFO empty */
-      return;                          /* don't need to flush */
-
-   TxEnabled = FALSE;
-   if(ChP->TxControl[3] & TX_ENABLE)
-   {
-      TxEnabled = TRUE;
-      sDisTransmit(ChP);               /* disable transmitter */
-   }
-   sStopRxProcessor(ChP);              /* stop Rx processor */
-   for(i = 0; i < 4000/200; i++)         /* delay 4 uS to allow proc to stop */
-      sInB(ChP->IntChan);	/* depends on bus i/o timing */
-   Ch = (Byte_t)sGetChanNum(ChP);
-   sOutB(ChP->Cmd,Ch | RESTXFCNT);     /* apply reset Tx FIFO count */
-   sOutB(ChP->Cmd,Ch);                 /* remove reset Tx FIFO count */
-   sOutW((WordIO_t)ChP->IndexAddr,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
-   sOutW(ChP->IndexData,0);
-   if(TxEnabled)
-      sEnTransmit(ChP);                /* enable transmitter */
-   sStartRxProcessor(ChP);             /* restart Rx processor */
+	int i;
+	Byte_t Ch;		/* channel number within AIOP */
+	int TxEnabled;		/* TRUE if transmitter enabled */
+
+	if (sGetTxCnt(ChP) == 0)	/* Tx FIFO empty */
+		return;		/* don't need to flush */
+
+	TxEnabled = FALSE;
+	if (ChP->TxControl[3] & TX_ENABLE) {
+		TxEnabled = TRUE;
+		sDisTransmit(ChP);	/* disable transmitter */
+	}
+	sStopRxProcessor(ChP);	/* stop Rx processor */
+	for (i = 0; i < 4000 / 200; i++)	/* delay 4 uS to allow proc to stop */
+		sInB(ChP->IntChan);	/* depends on bus i/o timing */
+	Ch = (Byte_t) sGetChanNum(ChP);
+	sOutB(ChP->Cmd, Ch | RESTXFCNT);	/* apply reset Tx FIFO count */
+	sOutB(ChP->Cmd, Ch);	/* remove reset Tx FIFO count */
+	sOutW((WordIO_t) ChP->IndexAddr, ChP->TxFIFOPtrs);	/* clear Tx in/out ptrs */
+	sOutW(ChP->IndexData, 0);
+	if (TxEnabled)
+		sEnTransmit(ChP);	/* enable transmitter */
+	sStartRxProcessor(ChP);	/* restart Rx processor */
 }
 
 /***************************************************************************
@@ -2735,36 +3443,34 @@
 
 Warnings: No context switches are allowed while executing this function.
 */
-int sWriteTxPrioByte(CHANNEL_T *ChP, Byte_t Data)
+int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data)
 {
-   Byte_t DWBuf[4];             /* buffer for double word writes */
-   Word_t *WordPtr;          /* must be far because Win SS != DS */
-   register DWordIO_t IndexAddr;
-
-   if(sGetTxCnt(ChP) > 1)              /* write it to Tx priority buffer */
-   {
-      IndexAddr = ChP->IndexAddr;
-      sOutW((WordIO_t)IndexAddr,ChP->TxPrioCnt); /* get priority buffer status */
-      if(sInB((ByteIO_t)ChP->IndexData) & PRI_PEND) /* priority buffer busy */
-         return(0);                    /* nothing sent */
-
-      WordPtr = (Word_t *)(&DWBuf[0]);
-      *WordPtr = ChP->TxPrioBuf;       /* data byte address */
-
-      DWBuf[2] = Data;                 /* data byte value */
-      sOutDW(IndexAddr,*((DWord_t *)(&DWBuf[0]))); /* write it out */
-
-      *WordPtr = ChP->TxPrioCnt;       /* Tx priority count address */
-
-      DWBuf[2] = PRI_PEND + 1;         /* indicate 1 byte pending */
-      DWBuf[3] = 0;                    /* priority buffer pointer */
-      sOutDW(IndexAddr,*((DWord_t *)(&DWBuf[0]))); /* write it out */
-   }
-   else                                /* write it to Tx FIFO */
-   {
-      sWriteTxByte(sGetTxRxDataIO(ChP),Data);
-   }
-   return(1);                          /* 1 byte sent */
+	Byte_t DWBuf[4];	/* buffer for double word writes */
+	Word_t *WordPtr;	/* must be far because Win SS != DS */
+	register DWordIO_t IndexAddr;
+
+	if (sGetTxCnt(ChP) > 1) {	/* write it to Tx priority buffer */
+		IndexAddr = ChP->IndexAddr;
+		sOutW((WordIO_t) IndexAddr, ChP->TxPrioCnt);	/* get priority buffer status */
+		if (sInB((ByteIO_t) ChP->IndexData) & PRI_PEND)	/* priority buffer busy */
+			return (0);	/* nothing sent */
+
+		WordPtr = (Word_t *) (&DWBuf[0]);
+		*WordPtr = ChP->TxPrioBuf;	/* data byte address */
+
+		DWBuf[2] = Data;	/* data byte value */
+		sOutDW(IndexAddr, *((DWord_t *) (&DWBuf[0])));	/* write it out */
+
+		*WordPtr = ChP->TxPrioCnt;	/* Tx priority count address */
+
+		DWBuf[2] = PRI_PEND + 1;	/* indicate 1 byte pending */
+		DWBuf[3] = 0;	/* priority buffer pointer */
+		sOutDW(IndexAddr, *((DWord_t *) (&DWBuf[0])));	/* write it out */
+	} else {		/* write it to Tx FIFO */
+
+		sWriteTxByte(sGetTxRxDataIO(ChP), Data);
+	}
+	return (1);		/* 1 byte sent */
 }
 
 /***************************************************************************
@@ -2799,24 +3505,23 @@
           enable channel interrupts.  This would allow the global interrupt
           status register to be used to determine which AIOPs need service.
 */
-void sEnInterrupts(CHANNEL_T *ChP,Word_t Flags)
+void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags)
 {
-   Byte_t Mask;                 /* Interrupt Mask Register */
+	Byte_t Mask;		/* Interrupt Mask Register */
 
-   ChP->RxControl[2] |=
-      ((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
+	ChP->RxControl[2] |=
+	    ((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
 
-   sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]);
+	sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->RxControl[0]);
 
-   ChP->TxControl[2] |= ((Byte_t)Flags & TXINT_EN);
+	ChP->TxControl[2] |= ((Byte_t) Flags & TXINT_EN);
 
-   sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]);
+	sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxControl[0]);
 
-   if(Flags & CHANINT_EN)
-   {
-      Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum];
-      sOutB(ChP->IntMask,Mask);
-   }
+	if (Flags & CHANINT_EN) {
+		Mask = sInB(ChP->IntMask) | sBitMapSetTbl[ChP->ChanNum];
+		sOutB(ChP->IntMask, Mask);
+	}
 }
 
 /***************************************************************************
@@ -2844,19 +3549,98 @@
           this channel's bit from being set in the AIOP's Interrupt Channel
           Register.
 */
-void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags)
+void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags)
 {
-   Byte_t Mask;                 /* Interrupt Mask Register */
+	Byte_t Mask;		/* Interrupt Mask Register */
 
-   ChP->RxControl[2] &=
-         ~((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
-   sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->RxControl[0]);
-   ChP->TxControl[2] &= ~((Byte_t)Flags & TXINT_EN);
-   sOutDW(ChP->IndexAddr,*(DWord_t *)&ChP->TxControl[0]);
-
-   if(Flags & CHANINT_EN)
-   {
-      Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum];
-      sOutB(ChP->IntMask,Mask);
-   }
+	ChP->RxControl[2] &=
+	    ~((Byte_t) Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
+	sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->RxControl[0]);
+	ChP->TxControl[2] &= ~((Byte_t) Flags & TXINT_EN);
+	sOutDW(ChP->IndexAddr, *(DWord_t *) & ChP->TxControl[0]);
+
+	if (Flags & CHANINT_EN) {
+		Mask = sInB(ChP->IntMask) & sBitMapClrTbl[ChP->ChanNum];
+		sOutB(ChP->IntMask, Mask);
+	}
+}
+
+void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode)
+{
+	sOutB(ChP->CtlP->AiopIO[2], (mode & 0x18) | ChP->ChanNum);
+}
+
+/*
+ *  Not an official SSCI function, but how to reset RocketModems.
+ *  ISA bus version
+ */
+void sModemReset(CONTROLLER_T * CtlP, int chan, int on)
+{
+	ByteIO_t addr;
+	Byte_t val;
+
+	addr = CtlP->AiopIO[0] + 0x400;
+	val = sInB(CtlP->MReg3IO);
+	/* if AIOP[1] is not enabled, enable it */
+	if ((val & 2) == 0) {
+		val = sInB(CtlP->MReg2IO);
+		sOutB(CtlP->MReg2IO, (val & 0xfc) | (1 & 0x03));
+		sOutB(CtlP->MBaseIO, (unsigned char) (addr >> 6));
+	}
+
+	sEnAiop(CtlP, 1);
+	if (!on)
+		addr += 8;
+	sOutB(addr + chan, 0);	/* apply or remove reset */
+	sDisAiop(CtlP, 1);
+}
+
+/*
+ *  Not an official SSCI function, but how to reset RocketModems.
+ *  PCI bus version
+ */
+void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on)
+{
+	ByteIO_t addr;
+
+	addr = CtlP->AiopIO[0] + 0x40;	/* 2nd AIOP */
+	if (!on)
+		addr += 8;
+	sOutB(addr + chan, 0);	/* apply or remove reset */
+}
+
+/*  Resets the speaker controller on RocketModem II and III devices */
+static void rmSpeakerReset(CONTROLLER_T * CtlP, unsigned long model)
+{
+	ByteIO_t addr;
+
+	/* RocketModem II speaker control is at the 8th port location of offset 0x40 */
+	if ((model == MODEL_RP4M) || (model == MODEL_RP6M)) {
+		addr = CtlP->AiopIO[0] + 0x4F;
+		sOutB(addr, 0);
+	}
+
+	/* RocketModem III speaker control is at the 1st port location of offset 0x80 */
+	if ((model == MODEL_UPCI_RM3_8PORT)
+	    || (model == MODEL_UPCI_RM3_4PORT)) {
+		addr = CtlP->AiopIO[0] + 0x88;
+		sOutB(addr, 0);
+	}
+}
+
+/*  Returns the line number given the controller (board), aiop and channel number */
+static unsigned char GetLineNumber(int ctrl, int aiop, int ch)
+{
+	return lineNumbers[(ctrl << 5) | (aiop << 3) | ch];
+}
+
+/*
+ *  Stores the line number associated with a given controller (board), aiop
+ *  and channel number.  
+ *  Returns:  The line number assigned 
+ */
+static unsigned char SetLineNumber(int ctrl, int aiop, int ch)
+{
+	lineNumbers[(ctrl << 5) | (aiop << 3) | ch] = nextLineNumber++;
+	return (nextLineNumber - 1);
 }
diff -urN linux-2.5.70-bk10/drivers/char/rocket.h linux-2.5.70-bk11/drivers/char/rocket.h
--- linux-2.5.70-bk10/drivers/char/rocket.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk11/drivers/char/rocket.h	2003-06-06 04:38:21.000000000 -0700
@@ -0,0 +1,131 @@
+/*
+ * rocket.h --- the exported interface of the rocket driver to
+ * its configuration program.
+ *
+ * Written by Theodore Ts'o, Copyright 1997.
+ *
+ * Copyright 1994, 1997, 2003 Comtrol Corporation.    All Rights Reserved.
+ * 
+ * The following source code is subject to Comtrol Corporation's
+ * Developer's License Agreement.
+ * 
+ * This source code is protected by United States copyright law and 
+ * international copyright treaties.
+ * 
+ * This source code may only be used to develop software products that
+ * will operate with Comtrol brand hardware.
+ * 
+ * You may not reproduce nor distribute this source code in its original
+ * form but must produce a derivative work which includes portions of
+ * this source code only.
+ * 
+ * The portions of this source code which you use in your derivative
+ * work must bear Comtrol's copyright notice:
+ * 
+ * 		Copyright 1994 Comtrol Corporation.
+ * 
+ */
+
+/*  Model Information Struct */
+typedef struct {
+	unsigned long model;
+	char modelString[80];
+	unsigned long numPorts;
+	int loadrm2;
+	int startingPortNumber;
+} rocketModel_t;
+
+struct rocket_config {
+	int line;
+	int flags;
+	int closing_wait;
+	int close_delay;
+	int port;
+	int reserved[32];
+};
+
+struct rocket_ports {
+	int tty_major;
+	int callout_major;
+	rocketModel_t rocketModel[8];
+};
+
+struct rocket_version {
+	char rocket_version[32];
+	char rocket_date[32];
+	char reserved[64];
+};
+
+/*
+ * Rocketport flags
+ */
+#define ROCKET_CALLOUT_NOHUP    0x00000001
+#define ROCKET_FORCE_CD		0x00000002
+#define ROCKET_HUP_NOTIFY	0x00000004
+#define ROCKET_SPLIT_TERMIOS	0x00000008
+#define ROCKET_SPD_MASK		0x00000070
+#define ROCKET_SPD_HI		0x00000010	/* Use 56000 instead of 38400 bps */
+#define ROCKET_SPD_VHI		0x00000020	/* Use 115200 instead of 38400 bps */
+#define ROCKET_SPD_SHI		0x00000030	/* Use 230400 instead of 38400 bps */
+#define ROCKET_SPD_WARP	        0x00000040	/* Use 460800 instead of 38400 bps */
+#define ROCKET_SAK		0x00000080
+#define ROCKET_SESSION_LOCKOUT	0x00000100
+#define ROCKET_PGRP_LOCKOUT	0x00000200
+#define ROCKET_RTS_TOGGLE	0x00000400
+#define ROCKET_MODE_MASK        0x00003000
+#define ROCKET_MODE_RS232       0x00000000
+#define ROCKET_MODE_RS485       0x00001000
+#define ROCKET_MODE_RS422       0x00002000
+#define ROCKET_FLAGS		0x00003FFF
+
+#define ROCKET_USR_MASK 0x0071	/* Legal flags that non-privileged
+				 * users can set or reset */
+
+/*
+ * For closing_wait and closing_wait2
+ */
+#define ROCKET_CLOSING_WAIT_NONE	65535
+#define ROCKET_CLOSING_WAIT_INF		0
+
+/*
+ * Rocketport ioctls -- "RP"
+ */
+#define RCKP_GET_STRUCT		0x00525001
+#define RCKP_GET_CONFIG		0x00525002
+#define RCKP_SET_CONFIG		0x00525003
+#define RCKP_GET_PORTS		0x00525004
+#define RCKP_RESET_RM2		0x00525005
+#define RCKP_GET_VERSION	0x00525006
+
+/*  Rocketport Models */
+#define MODEL_RP32INTF        0x0001	/* RP 32 port w/external I/F   */
+#define MODEL_RP8INTF         0x0002	/* RP 8 port w/external I/F    */
+#define MODEL_RP16INTF        0x0003	/* RP 16 port w/external I/F   */
+#define MODEL_RP8OCTA         0x0005	/* RP 8 port w/octa cable      */
+#define MODEL_RP4QUAD         0x0004	/* RP 4 port w/quad cable      */
+#define MODEL_RP8J            0x0006	/* RP 8 port w/RJ11 connectors */
+#define MODEL_RP4J            0x0007	/* RP 4 port w/RJ45 connectors */
+#define MODEL_RP8SNI          0x0008	/* RP 8 port w/ DB78 SNI connector */
+#define MODEL_RP16SNI         0x0009	/* RP 16 port w/ DB78 SNI connector */
+#define MODEL_RPP4            0x000A	/* RP Plus 4 port              */
+#define MODEL_RPP8            0x000B	/* RP Plus 8 port              */
+#define MODEL_RP2_232         0x000E	/* RP Plus 2 port RS232        */
+#define MODEL_RP2_422         0x000F	/* RP Plus 2 port RS232        */
+
+/*  Rocketmodem II Models */
+#define MODEL_RP6M            0x000C	/* RM 6 port                   */
+#define MODEL_RP4M            0x000D	/* RM 4 port                   */
+
+/* Universal PCI boards */
+#define MODEL_UPCI_RP32INTF   0x0801	/* RP UPCI 32 port w/external I/F     */
+#define MODEL_UPCI_RP8INTF    0x0802	/* RP UPCI 8 port w/external I/F      */
+#define MODEL_UPCI_RP16INTF   0x0803	/* RP UPCI 16 port w/external I/F     */
+#define MODEL_UPCI_RP8OCTA    0x0805	/* RP UPCI 8 port w/octa cable        */ 
+#define MODEL_UPCI_RM3_8PORT  0x080C	/* RP UPCI Rocketmodem III 8 port     */
+#define MODEL_UPCI_RM3_4PORT  0x080C	/* RP UPCI Rocketmodem III 4 port     */
+
+/*  Compact PCI 16 port  */
+#define MODEL_CPCI_RP16INTF   0x0903	/* RP Compact PCI 16 port w/external I/F */
+
+/* All ISA boards */
+#define MODEL_ISA             0x1000
diff -urN linux-2.5.70-bk10/drivers/char/rocket_int.h linux-2.5.70-bk11/drivers/char/rocket_int.h
--- linux-2.5.70-bk10/drivers/char/rocket_int.h	2003-06-06 04:38:12.000000000 -0700
+++ linux-2.5.70-bk11/drivers/char/rocket_int.h	2003-06-06 04:38:21.000000000 -0700
@@ -3,9 +3,7 @@
  *
  * Written by Theodore Ts'o, Copyright 1997.
  *
- * Portions of this file are....
- * 
- * Copyright 1994 Comtrol Corporation.    All Rights Reserved.
+ * Copyright 1994, 1997, 2003 Comtrol Corporation.    All Rights Reserved.
  * 
  * The following source code is subject to Comtrol Corporation's
  * Developer's License Agreement.
@@ -28,23 +26,16 @@
  */
 
 /*
- * Begin Comtrol-provided headers, et. al.
+ * Definition of the types in rcktpt_type
  */
-
-/*
-	user definitions for Rocket Toolkit
-
-	The following typedefs and defines must be established
-	depending on the platform the toolkit is being used
-	with.
-
-*/
-
-/************************************************************
-The following sets up the world for use with Linux
-************************************************************/
+#define ROCKET_TYPE_NORMAL	0
+#define ROCKET_TYPE_MODEM	1
+#define ROCKET_TYPE_MODEMII	2
+#define ROCKET_TYPE_MODEMIII	3
+#define ROCKET_TYPE_PC104       4
 
 #include <asm/io.h>
+#include <asm/byteorder.h>
 
 typedef unsigned char Byte_t;
 typedef unsigned int ByteIO_t;
@@ -55,17 +46,71 @@
 typedef unsigned long DWord_t;
 typedef unsigned int DWordIO_t;
 
+/*
+ * Note!  Normally the Linux I/O macros already take care of
+ * byte-swapping the I/O instructions.  However, all accesses using
+ * sOutDW aren't really 32-bit accesses, but should be handled in byte
+ * order.  Hence the use of the cpu_to_le32() macro to byte-swap
+ * things to no-op the byte swapping done by the big-endian outl()
+ * instruction.
+ */
+
+#ifdef ROCKET_DEBUG_IO
+static inline void sOutB(unsigned short port, unsigned char value)
+{
+#ifdef ROCKET_DEBUG_IO
+	printk("sOutB(%x, %x)...", port, value);
+#endif
+	outb_p(value, port);
+}
+
+static inline void sOutW(unsigned short port, unsigned short value)
+{
+#ifdef ROCKET_DEBUG_IO
+	printk("sOutW(%x, %x)...", port, value);
+#endif
+	outw_p(value, port);
+}
+
+static inline void sOutDW(unsigned short port, unsigned long value)
+{
+#ifdef ROCKET_DEBUG_IO
+	printk("sOutDW(%x, %lx)...", port, value);
+#endif
+	outl_p(cpu_to_le32(value), port);
+}
+
+static inline unsigned char sInB(unsigned short port)
+{
+	return inb_p(port);
+}
+
+static inline unsigned short sInW(unsigned short port)
+{
+	return inw_p(port);
+}
+
+#else				/* !ROCKET_DEBUG_IO */
 #define sOutB(a, b) outb_p(b, a)
 #define sOutW(a, b) outw_p(b, a)
-#define sOutDW(a, b) outl_p(b, a)
+#define sOutDW(port, value) outl_p(cpu_to_le32(value), port)
 #define sInB(a) (inb_p(a))
 #define sInW(a) (inw_p(a))
+#endif				/* ROCKET_DEBUG_IO */
 
-#define sOutStrW(port, addr, count) outsw(port, addr, count)
+/* This is used to move arrays of bytes so byte swapping isn't
+ * appropriate.  On Linux 2.3 and above outsw is the same as
+ * outsw_ns, but we use the old form for compatibility with
+ * old kernels. */
+#if  defined(__BIG_ENDIAN) && (LINUX_VERSION_CODE < VERSION_CODE(2,3,0))
+#define sOutStrW(port, addr, count) if (count) outsw_ns(port, addr, count)
+#define sInStrW(port, addr, count) if (count) insw_ns(port, addr, count)
+#else
+#define sOutStrW(port, addr, count) if (count) outsw(port, addr, count)
+#define sInStrW(port, addr, count) if (count) insw(port, addr, count)
+#endif
 
-#define sInStrW(port, addr, count) insw(port, addr, count)
-	
-#define CTL_SIZE 4
+#define CTL_SIZE 8
 #define AIOP_CTL_SIZE 4
 #define CHAN_AIOP_SIZE 8
 #define MAX_PORTS_PER_AIOP 8
@@ -78,219 +123,159 @@
 #define	isMC	2
 
 /* Controller ID numbers */
-#define CTLID_NULL  -1              /* no controller exists */
-#define CTLID_0001  0x0001          /* controller release 1 */
+#define CTLID_NULL  -1		/* no controller exists */
+#define CTLID_0001  0x0001	/* controller release 1 */
 
 /* AIOP ID numbers, identifies AIOP type implementing channel */
-#define AIOPID_NULL -1              /* no AIOP or channel exists */
-#define AIOPID_0001 0x0001          /* AIOP release 1 */
+#define AIOPID_NULL -1		/* no AIOP or channel exists */
+#define AIOPID_0001 0x0001	/* AIOP release 1 */
 
-#define NULLDEV -1                  /* identifies non-existant device */
-#define NULLCTL -1                  /* identifies non-existant controller */
-#define NULLCTLPTR (CONTROLLER_T *)0 /* identifies non-existant controller */
-#define NULLAIOP -1                 /* identifies non-existant AIOP */
-#define NULLCHAN -1                 /* identifies non-existant channel */
+#define NULLDEV -1		/* identifies non-existant device */
+#define NULLCTL -1		/* identifies non-existant controller */
+#define NULLCTLPTR (CONTROLLER_T *)0	/* identifies non-existant controller */
+#define NULLAIOP -1		/* identifies non-existant AIOP */
+#define NULLCHAN -1		/* identifies non-existant channel */
 
 /************************************************************************
  Global Register Offsets - Direct Access - Fixed values
 ************************************************************************/
 
-#define _CMD_REG   0x38   /* Command Register            8    Write */
-#define _INT_CHAN  0x39   /* Interrupt Channel Register  8    Read */
-#define _INT_MASK  0x3A   /* Interrupt Mask Register     8    Read / Write */
-#define _UNUSED    0x3B   /* Unused                      8 */
-#define _INDX_ADDR 0x3C   /* Index Register Address      16   Write */
-#define _INDX_DATA 0x3E   /* Index Register Data         8/16 Read / Write */
+#define _CMD_REG   0x38		/* Command Register            8    Write */
+#define _INT_CHAN  0x39		/* Interrupt Channel Register  8    Read */
+#define _INT_MASK  0x3A		/* Interrupt Mask Register     8    Read / Write */
+#define _UNUSED    0x3B		/* Unused                      8 */
+#define _INDX_ADDR 0x3C		/* Index Register Address      16   Write */
+#define _INDX_DATA 0x3E		/* Index Register Data         8/16 Read / Write */
 
 /************************************************************************
  Channel Register Offsets for 1st channel in AIOP - Direct Access
 ************************************************************************/
-#define _TD0       0x00  /* Transmit Data               16   Write */
-#define _RD0       0x00  /* Receive Data                16   Read */
-#define _CHN_STAT0 0x20  /* Channel Status              8/16 Read / Write */
-#define _FIFO_CNT0 0x10  /* Transmit/Receive FIFO Count 16   Read */
-#define _INT_ID0   0x30  /* Interrupt Identification    8    Read */
+#define _TD0       0x00		/* Transmit Data               16   Write */
+#define _RD0       0x00		/* Receive Data                16   Read */
+#define _CHN_STAT0 0x20		/* Channel Status              8/16 Read / Write */
+#define _FIFO_CNT0 0x10		/* Transmit/Receive FIFO Count 16   Read */
+#define _INT_ID0   0x30		/* Interrupt Identification    8    Read */
 
 /************************************************************************
  Tx Control Register Offsets - Indexed - External - Fixed
 ************************************************************************/
-#define _TX_ENBLS  0x980    /* Tx Processor Enables Register 8 Read / Write */
-#define _TXCMP1    0x988    /* Transmit Compare Value #1     8 Read / Write */
-#define _TXCMP2    0x989    /* Transmit Compare Value #2     8 Read / Write */
-#define _TXREP1B1  0x98A    /* Tx Replace Value #1 - Byte 1  8 Read / Write */
-#define _TXREP1B2  0x98B    /* Tx Replace Value #1 - Byte 2  8 Read / Write */
-#define _TXREP2    0x98C    /* Transmit Replace Value #2     8 Read / Write */
+#define _TX_ENBLS  0x980	/* Tx Processor Enables Register 8 Read / Write */
+#define _TXCMP1    0x988	/* Transmit Compare Value #1     8 Read / Write */
+#define _TXCMP2    0x989	/* Transmit Compare Value #2     8 Read / Write */
+#define _TXREP1B1  0x98A	/* Tx Replace Value #1 - Byte 1  8 Read / Write */
+#define _TXREP1B2  0x98B	/* Tx Replace Value #1 - Byte 2  8 Read / Write */
+#define _TXREP2    0x98C	/* Transmit Replace Value #2     8 Read / Write */
 
 /************************************************************************
 Memory Controller Register Offsets - Indexed - External - Fixed
 ************************************************************************/
-#define _RX_FIFO    0x000    /* Rx FIFO */
-#define _TX_FIFO    0x800    /* Tx FIFO */
-#define _RXF_OUTP   0x990    /* Rx FIFO OUT pointer        16 Read / Write */
-#define _RXF_INP    0x992    /* Rx FIFO IN pointer         16 Read / Write */
-#define _TXF_OUTP   0x994    /* Tx FIFO OUT pointer        8  Read / Write */
-#define _TXF_INP    0x995    /* Tx FIFO IN pointer         8  Read / Write */
-#define _TXP_CNT    0x996    /* Tx Priority Count          8  Read / Write */
-#define _TXP_PNTR   0x997    /* Tx Priority Pointer        8  Read / Write */
-
-#define PRI_PEND    0x80     /* Priority data pending (bit7, Tx pri cnt) */
-#define TXFIFO_SIZE 255      /* size of Tx FIFO */
-#define RXFIFO_SIZE 1023     /* size of Rx FIFO */
+#define _RX_FIFO    0x000	/* Rx FIFO */
+#define _TX_FIFO    0x800	/* Tx FIFO */
+#define _RXF_OUTP   0x990	/* Rx FIFO OUT pointer        16 Read / Write */
+#define _RXF_INP    0x992	/* Rx FIFO IN pointer         16 Read / Write */
+#define _TXF_OUTP   0x994	/* Tx FIFO OUT pointer        8  Read / Write */
+#define _TXF_INP    0x995	/* Tx FIFO IN pointer         8  Read / Write */
+#define _TXP_CNT    0x996	/* Tx Priority Count          8  Read / Write */
+#define _TXP_PNTR   0x997	/* Tx Priority Pointer        8  Read / Write */
+
+#define PRI_PEND    0x80	/* Priority data pending (bit7, Tx pri cnt) */
+#define TXFIFO_SIZE 255		/* size of Tx FIFO */
+#define RXFIFO_SIZE 1023	/* size of Rx FIFO */
 
 /************************************************************************
 Tx Priority Buffer - Indexed - External - Fixed
 ************************************************************************/
-#define _TXP_BUF    0x9C0    /* Tx Priority Buffer  32  Bytes   Read / Write */
-#define TXP_SIZE    0x20     /* 32 bytes */
+#define _TXP_BUF    0x9C0	/* Tx Priority Buffer  32  Bytes   Read / Write */
+#define TXP_SIZE    0x20	/* 32 bytes */
 
 /************************************************************************
 Channel Register Offsets - Indexed - Internal - Fixed
 ************************************************************************/
 
-#define _TX_CTRL    0xFF0    /* Transmit Control               16  Write */
-#define _RX_CTRL    0xFF2    /* Receive Control                 8  Write */
-#define _BAUD       0xFF4    /* Baud Rate                      16  Write */
-#define _CLK_PRE    0xFF6    /* Clock Prescaler                 8  Write */
-
-#if 0
-#define CLOCK_PRESC 0x14          /* ?????? new mod 4 (divide by 5) prescale */
-
-#define BRD50             9215
-#define BRD75             6143  
-#define BRD110            4188
-#define BRD134            3438
-#define BRD150            3071
-#define BRD200            2303
-#define BRD300            1535
-#define BRD600            767
-#define BRD1200           383
-#define BRD1800           255
-#define BRD2000           229
-#define BRD2400           191
-#define BRD3600           127
-#define BRD4800           95
-#define BRD7200           63
-#define BRD9600           47
-#define BRD14400          31 
-#define BRD19200          23
-#define BRD38400          11
-#define BRD57600          7
-#define BRD76800          5
-#define BRD115200         3
-#define BRD230400         1
-#define BRD460800	  0
-#endif
-
-#if 0
-
-/* Old clock prescale definition and baud rates associated with it */
-
-#define CLOCK_PRESC 0x19            /* mod 9 (divide by 10) prescale */
-#define BRD50             4607
-#define BRD75             3071
-#define BRD110            2094
-#define BRD134            1712
-#define BRD150            1535
-#define BRD200            1151
-#define BRD300            767
-#define BRD600            383
-#define BRD1200           191
-#define BRD1800           127
-#define BRD2000           114
-#define BRD2400           95
-#define BRD3600           64
-#define BRD4800           47
-#define BRD7200           31
-#define BRD9600           23
-#define BRD14400          15
-#define BRD19200          11
-#define BRD38400          5
-#define BRD57600          3
-#define BRD76800          2
-#define BRD115200         1
-#define BRD230400         0
-
-#endif
-
-#define STMBREAK   0x08        /* BREAK */
-#define STMFRAME   0x04        /* framing error */
-#define STMRCVROVR 0x02        /* receiver over run error */
-#define STMPARITY  0x01        /* parity error */
+#define _TX_CTRL    0xFF0	/* Transmit Control               16  Write */
+#define _RX_CTRL    0xFF2	/* Receive Control                 8  Write */
+#define _BAUD       0xFF4	/* Baud Rate                      16  Write */
+#define _CLK_PRE    0xFF6	/* Clock Prescaler                 8  Write */
+
+#define STMBREAK   0x08		/* BREAK */
+#define STMFRAME   0x04		/* framing error */
+#define STMRCVROVR 0x02		/* receiver over run error */
+#define STMPARITY  0x01		/* parity error */
 #define STMERROR   (STMBREAK | STMFRAME | STMPARITY)
-#define STMBREAKH   0x800      /* BREAK */
-#define STMFRAMEH   0x400      /* framing error */
-#define STMRCVROVRH 0x200      /* receiver over run error */
-#define STMPARITYH  0x100      /* parity error */
+#define STMBREAKH   0x800	/* BREAK */
+#define STMFRAMEH   0x400	/* framing error */
+#define STMRCVROVRH 0x200	/* receiver over run error */
+#define STMPARITYH  0x100	/* parity error */
 #define STMERRORH   (STMBREAKH | STMFRAMEH | STMPARITYH)
 
-#define CTS_ACT   0x20        /* CTS input asserted */
-#define DSR_ACT   0x10        /* DSR input asserted */
-#define CD_ACT    0x08        /* CD input asserted */
-#define TXFIFOMT  0x04        /* Tx FIFO is empty */
-#define TXSHRMT   0x02        /* Tx shift register is empty */
-#define RDA       0x01        /* Rx data available */
-#define DRAINED (TXFIFOMT | TXSHRMT)  /* indicates Tx is drained */
-
-#define STATMODE  0x8000      /* status mode enable bit */
-#define RXFOVERFL 0x2000      /* receive FIFO overflow */
-#define RX2MATCH  0x1000      /* receive compare byte 2 match */
-#define RX1MATCH  0x0800      /* receive compare byte 1 match */
-#define RXBREAK   0x0400      /* received BREAK */
-#define RXFRAME   0x0200      /* received framing error */
-#define RXPARITY  0x0100      /* received parity error */
+#define CTS_ACT   0x20		/* CTS input asserted */
+#define DSR_ACT   0x10		/* DSR input asserted */
+#define CD_ACT    0x08		/* CD input asserted */
+#define TXFIFOMT  0x04		/* Tx FIFO is empty */
+#define TXSHRMT   0x02		/* Tx shift register is empty */
+#define RDA       0x01		/* Rx data available */
+#define DRAINED (TXFIFOMT | TXSHRMT)	/* indicates Tx is drained */
+
+#define STATMODE  0x8000	/* status mode enable bit */
+#define RXFOVERFL 0x2000	/* receive FIFO overflow */
+#define RX2MATCH  0x1000	/* receive compare byte 2 match */
+#define RX1MATCH  0x0800	/* receive compare byte 1 match */
+#define RXBREAK   0x0400	/* received BREAK */
+#define RXFRAME   0x0200	/* received framing error */
+#define RXPARITY  0x0100	/* received parity error */
 #define STATERROR (RXBREAK | RXFRAME | RXPARITY)
 
-#define CTSFC_EN  0x80        /* CTS flow control enable bit */
-#define RTSTOG_EN 0x40        /* RTS toggle enable bit */
-#define TXINT_EN  0x10        /* transmit interrupt enable */
-#define STOP2     0x08        /* enable 2 stop bits (0 = 1 stop) */
-#define PARITY_EN 0x04        /* enable parity (0 = no parity) */
-#define EVEN_PAR  0x02        /* even parity (0 = odd parity) */
-#define DATA8BIT  0x01        /* 8 bit data (0 = 7 bit data) */
-
-#define SETBREAK  0x10        /* send break condition (must clear) */
-#define LOCALLOOP 0x08        /* local loopback set for test */
-#define SET_DTR   0x04        /* assert DTR */
-#define SET_RTS   0x02        /* assert RTS */
-#define TX_ENABLE 0x01        /* enable transmitter */
-
-#define RTSFC_EN  0x40        /* RTS flow control enable */
-#define RXPROC_EN 0x20        /* receive processor enable */
-#define TRIG_NO   0x00        /* Rx FIFO trigger level 0 (no trigger) */
-#define TRIG_1    0x08        /* trigger level 1 char */
-#define TRIG_1_2  0x10        /* trigger level 1/2 */
-#define TRIG_7_8  0x18        /* trigger level 7/8 */
-#define TRIG_MASK 0x18        /* trigger level mask */
-#define SRCINT_EN 0x04        /* special Rx condition interrupt enable */
-#define RXINT_EN  0x02        /* Rx interrupt enable */
-#define MCINT_EN  0x01        /* modem change interrupt enable */
-
-#define RXF_TRIG  0x20        /* Rx FIFO trigger level interrupt */
-#define TXFIFO_MT 0x10        /* Tx FIFO empty interrupt */
-#define SRC_INT   0x08        /* special receive condition interrupt */
-#define DELTA_CD  0x04        /* CD change interrupt */
-#define DELTA_CTS 0x02        /* CTS change interrupt */
-#define DELTA_DSR 0x01        /* DSR change interrupt */
-
-#define REP1W2_EN 0x10        /* replace byte 1 with 2 bytes enable */
-#define IGN2_EN   0x08        /* ignore byte 2 enable */
-#define IGN1_EN   0x04        /* ignore byte 1 enable */
-#define COMP2_EN  0x02        /* compare byte 2 enable */
-#define COMP1_EN  0x01        /* compare byte 1 enable */
-
-#define RESET_ALL 0x80        /* reset AIOP (all channels) */
-#define TXOVERIDE 0x40        /* Transmit software off override */
-#define RESETUART 0x20        /* reset channel's UART */
-#define RESTXFCNT 0x10        /* reset channel's Tx FIFO count register */
-#define RESRXFCNT 0x08        /* reset channel's Rx FIFO count register */
-
-#define INTSTAT0  0x01        /* AIOP 0 interrupt status */
-#define INTSTAT1  0x02        /* AIOP 1 interrupt status */
-#define INTSTAT2  0x04        /* AIOP 2 interrupt status */
-#define INTSTAT3  0x08        /* AIOP 3 interrupt status */
+#define CTSFC_EN  0x80		/* CTS flow control enable bit */
+#define RTSTOG_EN 0x40		/* RTS toggle enable bit */
+#define TXINT_EN  0x10		/* transmit interrupt enable */
+#define STOP2     0x08		/* enable 2 stop bits (0 = 1 stop) */
+#define PARITY_EN 0x04		/* enable parity (0 = no parity) */
+#define EVEN_PAR  0x02		/* even parity (0 = odd parity) */
+#define DATA8BIT  0x01		/* 8 bit data (0 = 7 bit data) */
+
+#define SETBREAK  0x10		/* send break condition (must clear) */
+#define LOCALLOOP 0x08		/* local loopback set for test */
+#define SET_DTR   0x04		/* assert DTR */
+#define SET_RTS   0x02		/* assert RTS */
+#define TX_ENABLE 0x01		/* enable transmitter */
+
+#define RTSFC_EN  0x40		/* RTS flow control enable */
+#define RXPROC_EN 0x20		/* receive processor enable */
+#define TRIG_NO   0x00		/* Rx FIFO trigger level 0 (no trigger) */
+#define TRIG_1    0x08		/* trigger level 1 char */
+#define TRIG_1_2  0x10		/* trigger level 1/2 */
+#define TRIG_7_8  0x18		/* trigger level 7/8 */
+#define TRIG_MASK 0x18		/* trigger level mask */
+#define SRCINT_EN 0x04		/* special Rx condition interrupt enable */
+#define RXINT_EN  0x02		/* Rx interrupt enable */
+#define MCINT_EN  0x01		/* modem change interrupt enable */
+
+#define RXF_TRIG  0x20		/* Rx FIFO trigger level interrupt */
+#define TXFIFO_MT 0x10		/* Tx FIFO empty interrupt */
+#define SRC_INT   0x08		/* special receive condition interrupt */
+#define DELTA_CD  0x04		/* CD change interrupt */
+#define DELTA_CTS 0x02		/* CTS change interrupt */
+#define DELTA_DSR 0x01		/* DSR change interrupt */
+
+#define REP1W2_EN 0x10		/* replace byte 1 with 2 bytes enable */
+#define IGN2_EN   0x08		/* ignore byte 2 enable */
+#define IGN1_EN   0x04		/* ignore byte 1 enable */
+#define COMP2_EN  0x02		/* compare byte 2 enable */
+#define COMP1_EN  0x01		/* compare byte 1 enable */
+
+#define RESET_ALL 0x80		/* reset AIOP (all channels) */
+#define TXOVERIDE 0x40		/* Transmit software off override */
+#define RESETUART 0x20		/* reset channel's UART */
+#define RESTXFCNT 0x10		/* reset channel's Tx FIFO count register */
+#define RESRXFCNT 0x08		/* reset channel's Rx FIFO count register */
+
+#define INTSTAT0  0x01		/* AIOP 0 interrupt status */
+#define INTSTAT1  0x02		/* AIOP 1 interrupt status */
+#define INTSTAT2  0x04		/* AIOP 2 interrupt status */
+#define INTSTAT3  0x08		/* AIOP 3 interrupt status */
 
-#define INTR_EN   0x08        /* allow interrupts to host */
-#define INT_STROB 0x04        /* strobe and clear interrupt line (EOI) */
+#define INTR_EN   0x08		/* allow interrupts to host */
+#define INT_STROB 0x04		/* strobe and clear interrupt line (EOI) */
 
 /**************************************************************************
  MUDBAC remapped for PCI
@@ -299,14 +284,22 @@
 #define _CFG_INT_PCI  0x40
 #define _PCI_INT_FUNC 0x3A
 
-#define PCI_STROB 0x2000        /* bit 13 of int aiop register */
-#define INTR_EN_PCI   0x0010        /* allow interrupts to host */
-
+#define PCI_STROB 0x2000	/* bit 13 of int aiop register */
+#define INTR_EN_PCI   0x0010	/* allow interrupts to host */
 
-#define CHAN3_EN  0x08        /* enable AIOP 3 */
-#define CHAN2_EN  0x04        /* enable AIOP 2 */
-#define CHAN1_EN  0x02        /* enable AIOP 1 */
-#define CHAN0_EN  0x01        /* enable AIOP 0 */
+/*
+ * Definitions for Universal PCI board registers
+ */
+#define _PCI_9030_INT_CTRL	0x4c          /* Offsets from BAR1 */
+#define _PCI_9030_GPIO_CTRL	0x54
+#define PCI_INT_CTRL_AIOP	0x0001
+#define PCI_GPIO_CTRL_8PORT	0x4000
+#define _PCI_9030_RING_IND	0xc0          /* Offsets from BAR1 */
+
+#define CHAN3_EN  0x08		/* enable AIOP 3 */
+#define CHAN2_EN  0x04		/* enable AIOP 2 */
+#define CHAN1_EN  0x02		/* enable AIOP 1 */
+#define CHAN0_EN  0x01		/* enable AIOP 0 */
 #define FREQ_DIS  0x00
 #define FREQ_274HZ 0x60
 #define FREQ_137HZ 0x50
@@ -314,75 +307,110 @@
 #define FREQ_34HZ  0x30
 #define FREQ_17HZ  0x20
 #define FREQ_9HZ   0x10
-#define PERIODIC_ONLY 0x80    /* only PERIODIC interrupt */
+#define PERIODIC_ONLY 0x80	/* only PERIODIC interrupt */
 
-#define CHANINT_EN 0x0100           /* flags to enable/disable channel ints */
+#define CHANINT_EN 0x0100	/* flags to enable/disable channel ints */
 
 #define RDATASIZE 72
 #define RREGDATASIZE 52
 
+/*
+ * AIOP interrupt bits for ISA/PCI boards and UPCI boards.
+ */
+#define AIOP_INTR_BIT_0		0x0001
+#define AIOP_INTR_BIT_1		0x0002
+#define AIOP_INTR_BIT_2		0x0004
+#define AIOP_INTR_BIT_3		0x0008
+
+#define AIOP_INTR_BITS ( \
+	AIOP_INTR_BIT_0 \
+	| AIOP_INTR_BIT_1 \
+	| AIOP_INTR_BIT_2 \
+	| AIOP_INTR_BIT_3)
+
+#define UPCI_AIOP_INTR_BIT_0	0x0004
+#define UPCI_AIOP_INTR_BIT_1	0x0020
+#define UPCI_AIOP_INTR_BIT_2	0x0100
+#define UPCI_AIOP_INTR_BIT_3	0x0800
+
+#define UPCI_AIOP_INTR_BITS ( \
+	UPCI_AIOP_INTR_BIT_0 \
+	| UPCI_AIOP_INTR_BIT_1 \
+	| UPCI_AIOP_INTR_BIT_2 \
+	| UPCI_AIOP_INTR_BIT_3)
+
 /* Controller level information structure */
-typedef struct
-{
-	int		CtlID;
-	int		CtlNum;
-	int		BusType;
-	WordIO_t	PCIIO;
-	ByteIO_t	MBaseIO;
-	ByteIO_t	MReg1IO;
-	ByteIO_t	MReg2IO;
-	ByteIO_t	MReg3IO;
-	Byte_t		MReg2;
-	Byte_t		MReg3;
-	int		NumAiop;
-	WordIO_t	AiopIO[AIOP_CTL_SIZE];
-	ByteIO_t	AiopIntChanIO[AIOP_CTL_SIZE];
-	int		AiopID[AIOP_CTL_SIZE];
-	int		AiopNumChan[AIOP_CTL_SIZE];
+typedef struct {
+	int CtlID;
+	int CtlNum;
+	int BusType;
+	int boardType;
+	int isUPCI;
+	WordIO_t PCIIO;
+	WordIO_t PCIIO2;
+	ByteIO_t MBaseIO;
+	ByteIO_t MReg1IO;
+	ByteIO_t MReg2IO;
+	ByteIO_t MReg3IO;
+	Byte_t MReg2;
+	Byte_t MReg3;
+	int NumAiop;
+	int AltChanRingIndicator;
+	ByteIO_t UPCIRingInd;
+	WordIO_t AiopIO[AIOP_CTL_SIZE];
+	ByteIO_t AiopIntChanIO[AIOP_CTL_SIZE];
+	int AiopID[AIOP_CTL_SIZE];
+	int AiopNumChan[AIOP_CTL_SIZE];
+	Word_t *AiopIntrBits;
 } CONTROLLER_T;
 
 typedef CONTROLLER_T CONTROLLER_t;
 
 /* Channel level information structure */
-typedef struct
-{
-	CONTROLLER_T	*CtlP;
-	int		AiopNum;
-	int		ChanID;
-	int		ChanNum;
-
-	ByteIO_t	Cmd;
-	ByteIO_t	IntChan;
-	ByteIO_t	IntMask;
-	DWordIO_t	IndexAddr;
-	WordIO_t	IndexData;
-
-	WordIO_t	TxRxData;
-	WordIO_t	ChanStat;
-	WordIO_t	TxRxCount;
-	ByteIO_t	IntID;
-
-	Word_t		TxFIFO;
-	Word_t		TxFIFOPtrs;
-	Word_t		RxFIFO;
-	Word_t		RxFIFOPtrs;
-	Word_t		TxPrioCnt;
-	Word_t		TxPrioPtr;
-	Word_t		TxPrioBuf;
-
-	Byte_t		R[RREGDATASIZE];
-
-	Byte_t		BaudDiv[4];
-	Byte_t		TxControl[4];
-	Byte_t		RxControl[4];
-	Byte_t		TxEnables[4];
-	Byte_t		TxCompare[4];
-	Byte_t		TxReplace1[4];
-	Byte_t		TxReplace2[4];
+typedef struct {
+	CONTROLLER_T *CtlP;
+	int AiopNum;
+	int ChanID;
+	int ChanNum;
+	int rtsToggle;
+
+	ByteIO_t Cmd;
+	ByteIO_t IntChan;
+	ByteIO_t IntMask;
+	DWordIO_t IndexAddr;
+	WordIO_t IndexData;
+
+	WordIO_t TxRxData;
+	WordIO_t ChanStat;
+	WordIO_t TxRxCount;
+	ByteIO_t IntID;
+
+	Word_t TxFIFO;
+	Word_t TxFIFOPtrs;
+	Word_t RxFIFO;
+	Word_t RxFIFOPtrs;
+	Word_t TxPrioCnt;
+	Word_t TxPrioPtr;
+	Word_t TxPrioBuf;
+
+	Byte_t R[RREGDATASIZE];
+
+	Byte_t BaudDiv[4];
+	Byte_t TxControl[4];
+	Byte_t RxControl[4];
+	Byte_t TxEnables[4];
+	Byte_t TxCompare[4];
+	Byte_t TxReplace1[4];
+	Byte_t TxReplace2[4];
 } CHANNEL_T;
 
 typedef CHANNEL_T CHANNEL_t;
-typedef CHANNEL_T * CHANPTR_T;
+typedef CHANNEL_T *CHANPTR_T;
+
+#define InterfaceModeRS232  0x00
+#define InterfaceModeRS422  0x08
+#define InterfaceModeRS485  0x10
+#define InterfaceModeRS232T 0x18
 
 /***************************************************************************
 Function: sClrBreak
@@ -391,10 +419,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sClrBreak(ChP) \
-{ \
+do { \
    (ChP)->TxControl[3] &= ~SETBREAK; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sClrDTR
@@ -403,10 +431,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sClrDTR(ChP) \
-{ \
+do { \
    (ChP)->TxControl[3] &= ~SET_DTR; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sClrRTS
@@ -415,10 +443,11 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sClrRTS(ChP) \
-{ \
+do { \
+   if ((ChP)->rtsToggle) break; \
    (ChP)->TxControl[3] &= ~SET_RTS; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sClrTxXOFF
@@ -427,10 +456,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sClrTxXOFF(ChP) \
-{ \
+do { \
    sOutB((ChP)->Cmd,TXOVERIDE | (Byte_t)(ChP)->ChanNum); \
    sOutB((ChP)->Cmd,(Byte_t)(ChP)->ChanNum); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sCtlNumToCtlPtr
@@ -452,10 +481,22 @@
 /***************************************************************************
 Function: sPCIControllerEOI
 Purpose:  Strobe the PCI End Of Interrupt bit.
+          For the UPCI boards, toggle the AIOP interrupt enable bit
+	  (this was taken from the Windows driver).
 Call:     sPCIControllerEOI(CtlP)
           CONTROLLER_T *CtlP; Ptr to controller structure
 */
-#define sPCIControllerEOI(CTLP) sOutW((CTLP)->PCIIO, PCI_STROB)
+#define sPCIControllerEOI(CTLP) \
+do { \
+    if ((CTLP)->isUPCI) { \
+	Word_t w = sInW((CTLP)->PCIIO); \
+	sOutW((CTLP)->PCIIO, (w ^ PCI_INT_CTRL_AIOP)); \
+	sOutW((CTLP)->PCIIO, w); \
+    } \
+    else { \
+	sOutW((CTLP)->PCIIO, PCI_STROB); \
+    } \
+} while (0)
 
 /***************************************************************************
 Function: sDisAiop
@@ -465,10 +506,10 @@
           int AiopNum; Number of AIOP on controller
 */
 #define sDisAiop(CTLP,AIOPNUM) \
-{ \
+do { \
    (CTLP)->MReg3 &= sBitMapClrTbl[AIOPNUM]; \
    sOutB((CTLP)->MReg3IO,(CTLP)->MReg3); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sDisCTSFlowCtl
@@ -477,10 +518,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sDisCTSFlowCtl(ChP) \
-{ \
+do { \
    (ChP)->TxControl[2] &= ~CTSFC_EN; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sDisIXANY
@@ -489,10 +530,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sDisIXANY(ChP) \
-{ \
+do { \
    (ChP)->R[0x0e] = 0x86; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x0c]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: DisParity
@@ -503,10 +544,23 @@
           sDisParity(), sSetOddParity(), and sSetEvenParity().
 */
 #define sDisParity(ChP) \
-{ \
+do { \
    (ChP)->TxControl[2] &= ~PARITY_EN; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
+
+/***************************************************************************
+Function: sDisRTSToggle
+Purpose:  Disable RTS toggle
+Call:     sDisRTSToggle(ChP)
+          CHANNEL_T *ChP; Ptr to channel structure
+*/
+#define sDisRTSToggle(ChP) \
+do { \
+   (ChP)->TxControl[2] &= ~RTSTOG_EN; \
+   sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+   (ChP)->rtsToggle = 0; \
+} while (0)
 
 /***************************************************************************
 Function: sDisRxFIFO
@@ -515,10 +569,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sDisRxFIFO(ChP) \
-{ \
+do { \
    (ChP)->R[0x32] = 0x0a; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x30]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sDisRxStatusMode
@@ -542,10 +596,10 @@
           and transmit shift register going completely empty.
 */
 #define sDisTransmit(ChP) \
-{ \
+do { \
    (ChP)->TxControl[3] &= ~TX_ENABLE; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sDisTxSoftFlowCtl
@@ -554,10 +608,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sDisTxSoftFlowCtl(ChP) \
-{ \
+do { \
    (ChP)->R[0x06] = 0x8a; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x04]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sEnAiop
@@ -567,10 +621,10 @@
           int AiopNum; Number of AIOP on controller
 */
 #define sEnAiop(CTLP,AIOPNUM) \
-{ \
+do { \
    (CTLP)->MReg3 |= sBitMapSetTbl[AIOPNUM]; \
    sOutB((CTLP)->MReg3IO,(CTLP)->MReg3); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sEnCTSFlowCtl
@@ -579,10 +633,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sEnCTSFlowCtl(ChP) \
-{ \
+do { \
    (ChP)->TxControl[2] |= CTSFC_EN; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sEnIXANY
@@ -591,10 +645,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sEnIXANY(ChP) \
-{ \
+do { \
    (ChP)->R[0x0e] = 0x21; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x0c]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: EnParity
@@ -608,10 +662,28 @@
           functions sSetOddParity() or sSetEvenParity().
 */
 #define sEnParity(ChP) \
-{ \
+do { \
    (ChP)->TxControl[2] |= PARITY_EN; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
+
+/***************************************************************************
+Function: sEnRTSToggle
+Purpose:  Enable RTS toggle
+Call:     sEnRTSToggle(ChP)
+          CHANNEL_T *ChP; Ptr to channel structure
+Comments: This function will disable RTS flow control and clear the RTS
+          line to allow operation of RTS toggle.
+*/
+#define sEnRTSToggle(ChP) \
+do { \
+   (ChP)->RxControl[2] &= ~RTSFC_EN; \
+   sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->RxControl[0]); \
+   (ChP)->TxControl[2] |= RTSTOG_EN; \
+   (ChP)->TxControl[3] &= ~SET_RTS; \
+   sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
+   (ChP)->rtsToggle = 1; \
+} while (0)
 
 /***************************************************************************
 Function: sEnRxFIFO
@@ -620,10 +692,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sEnRxFIFO(ChP) \
-{ \
+do { \
    (ChP)->R[0x32] = 0x08; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x30]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sEnRxProcessor
@@ -641,10 +713,10 @@
           microcode has been downloaded.
 */
 #define sEnRxProcessor(ChP) \
-{ \
+do { \
    (ChP)->RxControl[2] |= RXPROC_EN; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->RxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sEnRxStatusMode
@@ -665,10 +737,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sEnTransmit(ChP) \
-{ \
+do { \
    (ChP)->TxControl[3] |= TX_ENABLE; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sEnTxSoftFlowCtl
@@ -677,10 +749,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sEnTxSoftFlowCtl(ChP) \
-{ \
+do { \
    (ChP)->R[0x06] = 0xc5; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x04]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sGetAiopIntStatus
@@ -774,6 +846,18 @@
 */
 #define sGetChanStatusLo(ChP) sInB((ByteIO_t)(ChP)->ChanStat)
 
+/**********************************************************************
+ * Get RI status of channel
+ * Defined as a function in rocket.c   -aes
+ */
+#if 0
+#define sGetChanRI(ChP) ((ChP)->CtlP->AltChanRingIndicator ? \
+                          (sInB((ByteIO_t)((ChP)->ChanStat+8)) & DSR_ACT) : \
+                            (((ChP)->CtlP->boardType == ROCKET_TYPE_PC104) ? \
+                               (!(sInB((ChP)->CtlP->AiopIO[3]) & sBitMapSetTbl[(ChP)->ChanNum])) : \
+                             0))
+#endif
+
 /***************************************************************************
 Function: sGetControllerIntStatus
 Purpose:  Get the controller interrupt status
@@ -798,7 +882,10 @@
 			 was generated from periodic. If a bit is set the
 			 AIOP is interrupting.
 */
-#define sPCIGetControllerIntStatus(CTLP) ((sInW((CTLP)->PCIIO) >> 8) & 0x1f)
+#define sPCIGetControllerIntStatus(CTLP) \
+	((CTLP)->isUPCI ? \
+	  (sInW((CTLP)->PCIIO2) & UPCI_AIOP_INTR_BITS) : \
+	  ((sInW((CTLP)->PCIIO) >> 8) & AIOP_INTR_BITS))
 
 /***************************************************************************
 
@@ -834,7 +921,7 @@
 
 /***************************************************************************
 Function: sInitChanDefaults
-Purpose:  Initialize a channel structure to its default state.
+Purpose:  Initialize a channel structure to it's default state.
 Call:     sInitChanDefaults(ChP)
           CHANNEL_T *ChP; Ptr to the channel structure
 Comments: This function must be called once for every channel structure
@@ -842,12 +929,12 @@
 
 */
 #define sInitChanDefaults(ChP) \
-{ \
+do { \
    (ChP)->CtlP = NULLCTLPTR; \
    (ChP)->AiopNum = NULLAIOP; \
    (ChP)->ChanID = AIOPID_NULL; \
    (ChP)->ChanNum = NULLCHAN; \
-}
+} while (0)
 
 /***************************************************************************
 Function: sResetAiopByNum
@@ -857,10 +944,10 @@
 	AIOPNUM; AIOP index 
 */
 #define sResetAiopByNum(CTLP,AIOPNUM) \
-{ \
+do { \
    sOutB((CTLP)->AiopIO[(AIOPNUM)]+_CMD_REG,RESET_ALL); \
    sOutB((CTLP)->AiopIO[(AIOPNUM)]+_CMD_REG,0x0); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSendBreak
@@ -869,10 +956,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sSendBreak(ChP) \
-{ \
+do { \
    (ChP)->TxControl[3] |= SETBREAK; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSetBaud
@@ -882,11 +969,11 @@
           Word_t Divisor; 16 bit baud rate divisor for channel
 */
 #define sSetBaud(ChP,DIVISOR) \
-{ \
+do { \
    (ChP)->BaudDiv[2] = (Byte_t)(DIVISOR); \
    (ChP)->BaudDiv[3] = (Byte_t)((DIVISOR) >> 8); \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->BaudDiv[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSetData7
@@ -895,10 +982,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sSetData7(ChP) \
-{ \
+do { \
    (ChP)->TxControl[2] &= ~DATA8BIT; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSetData8
@@ -907,10 +994,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sSetData8(ChP) \
-{ \
+do { \
    (ChP)->TxControl[2] |= DATA8BIT; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSetDTR
@@ -919,10 +1006,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sSetDTR(ChP) \
-{ \
+do { \
    (ChP)->TxControl[3] |= SET_DTR; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSetEvenParity
@@ -936,10 +1023,10 @@
           sEnParity().
 */
 #define sSetEvenParity(ChP) \
-{ \
+do { \
    (ChP)->TxControl[2] |= EVEN_PAR; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSetOddParity
@@ -953,10 +1040,10 @@
           sEnParity().
 */
 #define sSetOddParity(ChP) \
-{ \
+do { \
    (ChP)->TxControl[2] &= ~EVEN_PAR; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSetRTS
@@ -965,10 +1052,11 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sSetRTS(ChP) \
-{ \
+do { \
+   if ((ChP)->rtsToggle) break; \
    (ChP)->TxControl[3] |= SET_RTS; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSetRxTrigger
@@ -990,11 +1078,11 @@
 
 */
 #define sSetRxTrigger(ChP,LEVEL) \
-{ \
+do { \
    (ChP)->RxControl[2] &= ~TRIG_MASK; \
    (ChP)->RxControl[2] |= LEVEL; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->RxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSetStop1
@@ -1003,10 +1091,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sSetStop1(ChP) \
-{ \
+do { \
    (ChP)->TxControl[2] &= ~STOP2; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSetStop2
@@ -1015,10 +1103,10 @@
           CHANNEL_T *ChP; Ptr to channel structure
 */
 #define sSetStop2(ChP) \
-{ \
+do { \
    (ChP)->TxControl[2] |= STOP2; \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->TxControl[0]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSetTxXOFFChar
@@ -1028,10 +1116,10 @@
           Byte_t Ch; The value to set the Tx XOFF character to
 */
 #define sSetTxXOFFChar(ChP,CH) \
-{ \
+do { \
    (ChP)->R[0x07] = (CH); \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x04]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sSetTxXONChar
@@ -1041,10 +1129,10 @@
           Byte_t Ch; The value to set the Tx XON character to
 */
 #define sSetTxXONChar(ChP,CH) \
-{ \
+do { \
    (ChP)->R[0x0b] = (CH); \
    sOutDW((ChP)->IndexAddr,*(DWord_t *)&(ChP)->R[0x08]); \
-}
+} while (0)
 
 /***************************************************************************
 Function: sStartRxProcessor
@@ -1069,37 +1157,38 @@
 */
 #define sWriteTxByte(IO,DATA) sOutB(IO,DATA)
 
-int sInitController(	CONTROLLER_T *CtlP,
-			int CtlNum,
-			ByteIO_t MudbacIO,
-			ByteIO_t *AiopIOList,
-			int AiopIOListSize,
-			int IRQNum,
-			Byte_t Frequency,
-			int PeriodicOnly);
-
-int sPCIInitController(	CONTROLLER_T *CtlP,
-			int CtlNum,
-			ByteIO_t *AiopIOList,
-			int AiopIOListSize,
-			int IRQNum,
-			Byte_t Frequency,
-			int PeriodicOnly);
+int sInitController(CONTROLLER_T * CtlP,
+		    int CtlNum,
+		    ByteIO_t MudbacIO,
+		    ByteIO_t * AiopIOList,
+		    int AiopIOListSize,
+		    int IRQNum, Byte_t Frequency, int PeriodicOnly);
+
+int sPCIInitController(CONTROLLER_T * CtlP,
+		       int CtlNum,
+		       ByteIO_t * AiopIOList,
+		       int AiopIOListSize,
+		       WordIO_t ConfigIO,
+		       int IRQNum,
+		       Byte_t Frequency,
+		       int PeriodicOnly,
+		       int altChanRingIndicator, int UPCIRingInd);
 
 int sReadAiopID(ByteIO_t io);
 int sReadAiopNumChan(WordIO_t io);
-int sInitChan(	CONTROLLER_T *CtlP,
-		CHANNEL_T *ChP,
-		int AiopNum,
-		int ChanNum);
-Byte_t sGetRxErrStatus(CHANNEL_T *ChP);
-void sStopRxProcessor(CHANNEL_T *ChP);
-void sStopSWInFlowCtl(CHANNEL_T *ChP);
-void sFlushRxFIFO(CHANNEL_T *ChP);
-void sFlushTxFIFO(CHANNEL_T *ChP);
-int sWriteTxPrioByte(CHANNEL_T *ChP, Byte_t Data);
-void sEnInterrupts(CHANNEL_T *ChP,Word_t Flags);
-void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags);
+int sInitChan(CONTROLLER_T * CtlP,
+	      CHANNEL_T * ChP, int AiopNum, int ChanNum);
+Byte_t sGetRxErrStatus(CHANNEL_T * ChP);
+void sStopRxProcessor(CHANNEL_T * ChP);
+void sStopSWInFlowCtl(CHANNEL_T * ChP);
+void sFlushRxFIFO(CHANNEL_T * ChP);
+void sFlushTxFIFO(CHANNEL_T * ChP);
+int sWriteTxPrioByte(CHANNEL_T * ChP, Byte_t Data);
+void sEnInterrupts(CHANNEL_T * ChP, Word_t Flags);
+void sDisInterrupts(CHANNEL_T * ChP, Word_t Flags);
+void sModemReset(CONTROLLER_T * CtlP, int chan, int on);
+void sPCIModemReset(CONTROLLER_T * CtlP, int chan, int on);
+void sSetInterfaceMode(CHANNEL_T * ChP, Byte_t mode);
 
 extern Byte_t R[RDATASIZE];
 extern CONTROLLER_T sController[CTL_SIZE];
@@ -1108,7 +1197,6 @@
 extern Byte_t sBitMapSetTbl[8];
 extern int sClockPrescale;
 
-
 /*
  * Begin Linux specific definitions for the Rocketport driver
  *
@@ -1116,34 +1204,45 @@
  */
 
 struct r_port {
-	int			magic;
-	int			line;
-	int			flags;
-	int			count;
-	int			blocked_open;
-	struct tty_struct 	*tty;
-	int			board:2;
-	int			aiop:2;
-	int			chan:3;
+	int magic;
+	int line;
+	int flags;
+	int count;
+	int blocked_open;
+	struct tty_struct *tty;
+	unsigned int board:3;
+	unsigned int aiop:2;
+	unsigned int chan:3;
 	CONTROLLER_t *ctlp;
-	CHANNEL_t 		channel;
-	int			closing_wait;
-	int			close_delay;
-	int			intmask;
-	int			xmit_fifo_room;	/* room in xmit fifo */
-	unsigned char 		*xmit_buf;
-	int			xmit_head;
-	int			xmit_tail;
-	int			xmit_cnt;
-	int			cd_status;
-	int		        ignore_status_mask;
-	int			read_status_mask;
-	int			cps;
-	struct termios		normal_termios;
-	wait_queue_head_t	open_wait;
-	wait_queue_head_t	close_wait;
+	CHANNEL_t channel;
+	int closing_wait;
+	int close_delay;
+	int intmask;
+	int xmit_fifo_room;	/* room in xmit fifo */
+	unsigned char *xmit_buf;
+	int xmit_head;
+	int xmit_tail;
+	int xmit_cnt;
+	int session;
+	int pgrp;
+	int cd_status;
+	int ignore_status_mask;
+	int read_status_mask;
+	int cps;
+	struct termios normal_termios;
+	struct termios callout_termios;
+
+#ifdef DECLARE_WAITQUEUE
+	wait_queue_head_t open_wait;
+	wait_queue_head_t close_wait;
+#else
+	struct wait_queue *open_wait;
+	struct wait_queue *close_wait;
+#endif
+	spinlock_t slock;
+	struct semaphore write_sem;
 };
-	
+
 #define RPORT_MAGIC 0x525001
 
 #define NUM_BOARDS 8
@@ -1158,16 +1257,14 @@
 #define WAKEUP_CHARS 256
 
 /* Internal flags used only by the rocketport driver */
-#define ROCKET_INITIALIZED	0x80000000 /* Port is active */
-#define ROCKET_CLOSING		0x40000000 /* Serial port is closing */
-#define ROCKET_NORMAL_ACTIVE	0x20000000 /* Normal port is active */
-#define ROCKET_CALLOUT_ACTIVE	0x10000000 /* Callout port is active */
+#define ROCKET_INITIALIZED	0x80000000	/* Port is active */
+#define ROCKET_CLOSING		0x40000000	/* Serial port is closing */
+#define ROCKET_NORMAL_ACTIVE	0x20000000	/* Normal port is active */
+#define ROCKET_CALLOUT_ACTIVE	0x10000000	/* Callout port is active */
 
-/*
- * tty subtypes
- *
- */
+/* tty subtypes */
 #define SERIAL_TYPE_NORMAL 1
+#define SERIAL_TYPE_CALLOUT 2
 
 /*
  * Assigned major numbers for the Comtrol Rocketport
@@ -1175,9 +1272,6 @@
 #define TTY_ROCKET_MAJOR	46
 #define CUA_ROCKET_MAJOR	47
 
-/*
- * Utility function.
- */
 #ifndef MIN
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
 #endif
@@ -1188,27 +1282,65 @@
 #undef PCI_DEVICE_ID_RP8INTF
 #undef PCI_DEVICE_ID_RP16INTF
 #undef PCI_DEVICE_ID_RP32INTF
+#undef PCI_DEVICE_ID_URP8OCTA
+#undef PCI_DEVICE_ID_URP8INTF
+#undef PCI_DEVICE_ID_URP16INTF
+#undef PCI_DEVICE_ID_CRP16INTF
+#undef PCI_DEVICE_ID_URP32INTF
 #endif
 
+/*  Comtrol PCI Vendor ID */
 #define PCI_VENDOR_ID_RP		0x11fe
-#define PCI_DEVICE_ID_RP32INTF		0x0001
-#define PCI_DEVICE_ID_RP8INTF		0x0002
-#define PCI_DEVICE_ID_RP16INTF		0x0003
-#define PCI_DEVICE_ID_RP8OCTA		0x0005
 
-#ifndef PCI_DEVICE_ID_RP4QUAD
-#define PCI_DEVICE_ID_RP4QUAD		0x0004
-#endif
-#ifndef PCI_DEVICE_ID_RP8J
-#define PCI_DEVICE_ID_RP8J		0x0006
-#endif
-#ifndef PCI_DEVICE_ID_RPP4
-#define PCI_DEVICE_ID_RPP4		0x000A
-#endif
-#ifndef PCI_DEVICE_ID_RPP8
-#define PCI_DEVICE_ID_RPP8		0x000B
-#endif
-#ifndef PCI_DEVICE_ID_RP8M
-#define PCI_DEVICE_ID_RP8M		0x000C
-#endif	
+/*  Comtrol Device ID's */
+#define PCI_DEVICE_ID_RP32INTF		0x0001	/* Rocketport 32 port w/external I/F     */
+#define PCI_DEVICE_ID_RP8INTF		0x0002	/* Rocketport 8 port w/external I/F      */
+#define PCI_DEVICE_ID_RP16INTF		0x0003	/* Rocketport 16 port w/external I/F     */
+#define PCI_DEVICE_ID_RP4QUAD		0x0004	/* Rocketport 4 port w/quad cable        */
+#define PCI_DEVICE_ID_RP8OCTA		0x0005	/* Rocketport 8 port w/octa cable        */
+#define PCI_DEVICE_ID_RP8J		0x0006	/* Rocketport 8 port w/RJ11 connectors   */
+#define PCI_DEVICE_ID_RP4J		0x0007	/* Rocketport 4 port w/RJ11 connectors   */
+#define PCI_DEVICE_ID_RP8SNI		0x0008	/* Rocketport 8 port w/ DB78 SNI (Siemens) connector */
+#define PCI_DEVICE_ID_RP16SNI		0x0009	/* Rocketport 16 port w/ DB78 SNI (Siemens) connector   */
+#define PCI_DEVICE_ID_RPP4		0x000A	/* Rocketport Plus 4 port                */
+#define PCI_DEVICE_ID_RPP8		0x000B	/* Rocketport Plus 8 port                */
+#define PCI_DEVICE_ID_RP6M		0x000C	/* RocketModem 6 port                    */
+#define PCI_DEVICE_ID_RP4M		0x000D	/* RocketModem 4 port                    */
+#define PCI_DEVICE_ID_RP2_232           0x000E	/* Rocketport Plus 2 port RS232          */
+#define PCI_DEVICE_ID_RP2_422           0x000F	/* Rocketport Plus 2 port RS422          */ 
+
+/* Universal PCI boards  */
+#define PCI_DEVICE_ID_URP32INTF		0x0801	/* Rocketport UPCI 32 port w/external I/F */ 
+#define PCI_DEVICE_ID_URP8INTF		0x0802	/* Rocketport UPCI 8 port w/external I/F  */
+#define PCI_DEVICE_ID_URP16INTF		0x0803	/* Rocketport UPCI 16 port w/external I/F */
+#define PCI_DEVICE_ID_URP8OCTA		0x0805	/* Rocketport UPCI 8 port w/octa cable    */
+#define PCI_DEVICE_ID_UPCI_RM3_8PORT    0x080C	/* Rocketmodem III 8 port                 */
+#define PCI_DEVICE_ID_UPCI_RM3_4PORT    0x080D	/* Rocketmodem III 4 port                 */
+
+/* Compact PCI device */ 
+#define PCI_DEVICE_ID_CRP16INTF		0x0903	/* Rocketport Compact PCI 16 port w/external I/F */
+
+/*  Taking care of some kernel incompatibilities... */
+#if LINUX_VERSION_CODE > VERSION_CODE(2,5,68)
+
+#define TTY_GET_LINE(t) t->index
+
+#define TTY_DRIVER_MINOR_START(t) t->driver->minor_start
+#define TTY_DRIVER_SUBTYPE(t) t->driver->subtype
+#define TTY_DRIVER_NAME(t) t->driver->name
+#define TTY_DRIVER_NAME_BASE(t) t->driver->name_base
+#define TTY_DRIVER_FLUSH_BUFFER_EXISTS(t) t->driver->flush_buffer
+#define TTY_DRIVER_FLUSH_BUFFER(t) t->driver->flush_buffer(t)
+
+#else
+
+#define TTY_GET_LINE(t) minor(t->device) - TTY_DRIVER_MINOR_START(t)
+
+#define TTY_DRIVER_MINOR_START(t) t->driver.minor_start
+#define TTY_DRIVER_SUBTYPE(t) t->driver.subtype
+#define TTY_DRIVER_NAME(t) t->driver.name
+#define TTY_DRIVER_NAME_BASE(t) t->driver.name_base
+#define TTY_DRIVER_FLUSH_BUFFER_EXISTS(t) t->driver.flush_buffer
+#define TTY_DRIVER_FLUSH_BUFFER(t) t->driver.flush_buffer(t)
 
+#endif
diff -urN linux-2.5.70-bk10/drivers/char/tty_io.c linux-2.5.70-bk11/drivers/char/tty_io.c
--- linux-2.5.70-bk10/drivers/char/tty_io.c	2003-06-06 04:38:12.000000000 -0700
+++ linux-2.5.70-bk11/drivers/char/tty_io.c	2003-06-06 04:38:22.000000000 -0700
@@ -2093,10 +2093,6 @@
 # define tty_unregister_devfs(driver, index)	do { } while (0)
 #endif /* CONFIG_DEVFS_FS */
 
-static struct class tty_class = {
-	.name	= "tty",
-};
-
 struct tty_dev {
 	struct list_head node;
 	dev_t dev;
@@ -2104,6 +2100,17 @@
 };
 #define to_tty_dev(d) container_of(d, struct tty_dev, class_dev)
 
+static void release_tty_dev(struct class_device *class_dev)
+{
+	struct tty_dev *tty_dev = to_tty_dev(class_dev);
+	kfree(tty_dev);
+}
+
+static struct class tty_class = {
+	.name		= "tty",
+	.release	= &release_tty_dev,
+};
+
 static LIST_HEAD(tty_dev_list);
 static spinlock_t tty_dev_list_lock = SPIN_LOCK_UNLOCKED;
 
@@ -2167,7 +2174,6 @@
 		list_del(&tty_dev->node);
 		spin_unlock(&tty_dev_list_lock);
 		class_device_unregister(&tty_dev->class_dev);
-		kfree(tty_dev);
 	} else {
 		spin_unlock(&tty_dev_list_lock);
 	}
diff -urN linux-2.5.70-bk10/drivers/i2c/Kconfig linux-2.5.70-bk11/drivers/i2c/Kconfig
--- linux-2.5.70-bk10/drivers/i2c/Kconfig	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk11/drivers/i2c/Kconfig	2003-06-06 04:38:22.000000000 -0700
@@ -144,7 +144,7 @@
 
 config I2C_KEYWEST
 	tristate "Powermac Keywest I2C interface"
-	depends on I2C && ALL_PPC
+	depends on I2C && PPC_PMAC
 	help
 	  This supports the use of the I2C interface in the combo-I/O
 	  chip on recent Apple machines.  Say Y if you have such a machine.
diff -urN linux-2.5.70-bk10/drivers/i2c/chips/w83781d.c linux-2.5.70-bk11/drivers/i2c/chips/w83781d.c
--- linux-2.5.70-bk10/drivers/i2c/chips/w83781d.c	2003-05-26 18:00:19.000000000 -0700
+++ linux-2.5.70-bk11/drivers/i2c/chips/w83781d.c	2003-06-06 04:38:22.000000000 -0700
@@ -1031,27 +1031,129 @@
 	return i2c_detect(adapter, &addr_data, w83781d_detect);
 }
 
+/* Assumes that adapter is of I2C, not ISA variety.
+ * OTHERWISE DON'T CALL THIS
+ */
+static int
+w83781d_detect_subclients(struct i2c_adapter *adapter, int address, int kind,
+		struct i2c_client *new_client)
+{
+	int i, val1 = 0, id;
+	int err;
+	const char *client_name;
+	struct w83781d_data *data = i2c_get_clientdata(new_client);
+
+	if (!(data->lm75 = kmalloc(2 * sizeof (struct i2c_client),
+			GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto ERROR_SC_0;
+	}
+	memset(data->lm75, 0x00, 2 * sizeof (struct i2c_client));
+
+	id = i2c_adapter_id(adapter);
+
+	if (force_subclients[0] == id && force_subclients[1] == address) {
+		for (i = 2; i <= 3; i++) {
+			if (force_subclients[i] < 0x48 ||
+			    force_subclients[i] > 0x4f) {
+				dev_err(&new_client->dev, "Invalid subclient "
+					"address %d; must be 0x48-0x4f\n",
+					force_subclients[i]);
+				err = -EINVAL;
+				goto ERROR_SC_1;
+			}
+		}
+		w83781d_write_value(new_client, W83781D_REG_I2C_SUBADDR,
+				(force_subclients[2] & 0x07) |
+				((force_subclients[3] & 0x07) << 4));
+		data->lm75[0].addr = force_subclients[2];
+	} else {
+		val1 = w83781d_read_value(new_client, W83781D_REG_I2C_SUBADDR);
+		data->lm75[0].addr = 0x48 + (val1 & 0x07);
+	}
+
+	if (kind != w83783s) {
+		if (force_subclients[0] == id &&
+		    force_subclients[1] == address) {
+			data->lm75[1].addr = force_subclients[3];
+		} else {
+			data->lm75[1].addr = 0x48 + ((val1 >> 4) & 0x07);
+		}
+		if (data->lm75[0].addr == data->lm75[1].addr) {
+			dev_err(&new_client->dev,
+			       "Duplicate addresses 0x%x for subclients.\n",
+			       data->lm75[0].addr);
+			err = -EBUSY;
+			goto ERROR_SC_1;
+		}
+	}
+
+	if (kind == w83781d)
+		client_name = "W83781D subclient";
+	else if (kind == w83782d)
+		client_name = "W83782D subclient";
+	else if (kind == w83783s)
+		client_name = "W83783S subclient";
+	else if (kind == w83627hf)
+		client_name = "W83627HF subclient";
+	else if (kind == as99127f)
+		client_name = "AS99127F subclient";
+	else
+		client_name = "unknown subclient?";
+
+	for (i = 0; i <= 1; i++) {
+		/* store all data in w83781d */
+		i2c_set_clientdata(&data->lm75[i], NULL);
+		data->lm75[i].adapter = adapter;
+		data->lm75[i].driver = &w83781d_driver;
+		data->lm75[i].flags = 0;
+		strlcpy(data->lm75[i].dev.name, client_name,
+			DEVICE_NAME_SIZE);
+		if ((err = i2c_attach_client(&(data->lm75[i])))) {
+			dev_err(&new_client->dev, "Subclient %d "
+				"registration at address 0x%x "
+				"failed.\n", i, data->lm75[i].addr);
+			if (i == 1)
+				goto ERROR_SC_2;
+			goto ERROR_SC_1;
+		}
+		if (kind == w83783s)
+			break;
+	}
+
+	return 0;
+
+/* Undo inits in case of errors */
+ERROR_SC_2:
+	i2c_detach_client(&(data->lm75[0]));
+ERROR_SC_1:
+	kfree(data->lm75);
+ERROR_SC_0:
+	return err;
+}
+
 static int
 w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
 {
-	int i = 0, val1 = 0, val2, id;
+	int i = 0, val1 = 0, val2;
 	struct i2c_client *new_client;
 	struct w83781d_data *data;
-	int err = 0;
-	const char *type_name = "";
+	int err;
 	const char *client_name = "";
 	int is_isa = i2c_is_isa_adapter(adapter);
 	enum vendor { winbond, asus } vendid;
 
 	if (!is_isa
-	    && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+	    && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+		err = -EINVAL;
 		goto ERROR0;
+	}
 
-	if (is_isa) {
-		if (!request_region(address, W83781D_EXTENT, "w83781d"))
+	if (is_isa)
+		if (!request_region(address, W83781D_EXTENT, "w83781d")) {
+			err = -EBUSY;
 			goto ERROR0;
-		release_region(address, W83781D_EXTENT);
-	}
+		}
 
 	/* Probe whether there is anything available on this address. Already
 	   done for SMBus clients */
@@ -1059,15 +1161,21 @@
 		if (is_isa) {
 
 #define REALLY_SLOW_IO
-			/* We need the timeouts for at least some LM78-like chips. But only
-			   if we read 'undefined' registers. */
+			/* We need the timeouts for at least some LM78-like
+			   chips. But only if we read 'undefined' registers. */
 			i = inb_p(address + 1);
-			if (inb_p(address + 2) != i)
-				goto ERROR0;
-			if (inb_p(address + 3) != i)
-				goto ERROR0;
-			if (inb_p(address + 7) != i)
-				goto ERROR0;
+			if (inb_p(address + 2) != i) {
+				err = -ENODEV;
+				goto ERROR1;
+			}
+			if (inb_p(address + 3) != i) {
+				err = -ENODEV;
+				goto ERROR1;
+			}
+			if (inb_p(address + 7) != i) {
+				err = -ENODEV;
+				goto ERROR1;
+			}
 #undef REALLY_SLOW_IO
 
 			/* Let's just hope nothing breaks here */
@@ -1075,7 +1183,8 @@
 			outb_p(~i & 0x7f, address + 5);
 			if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
 				outb_p(i, address + 5);
-				return 0;
+				err = -ENODEV;
+				goto ERROR1;
 			}
 		}
 	}
@@ -1087,7 +1196,7 @@
 	if (!(new_client = kmalloc(sizeof (struct i2c_client) +
 				   sizeof (struct w83781d_data), GFP_KERNEL))) {
 		err = -ENOMEM;
-		goto ERROR0;
+		goto ERROR1;
 	}
 
 	memset(new_client, 0x00, sizeof (struct i2c_client) +
@@ -1108,8 +1217,10 @@
 	   force_*=... parameter, and the Winbond will be reset to the right
 	   bank. */
 	if (kind < 0) {
-		if (w83781d_read_value(new_client, W83781D_REG_CONFIG) & 0x80)
-			goto ERROR1;
+		if (w83781d_read_value(new_client, W83781D_REG_CONFIG) & 0x80){
+			err = -ENODEV;
+			goto ERROR2;
+		}
 		val1 = w83781d_read_value(new_client, W83781D_REG_BANK);
 		val2 = w83781d_read_value(new_client, W83781D_REG_CHIPMAN);
 		/* Check for Winbond or Asus ID if in bank 0 */
@@ -1117,14 +1228,19 @@
 		    (((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3)
 		      && (val2 != 0x94))
 		     || ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)
-			 && (val2 != 0x06))))
-			goto ERROR1;
-		/* If Winbond SMBus, check address at 0x48. Asus doesn't support */
+			 && (val2 != 0x06)))) {
+			err = -ENODEV;
+			goto ERROR2;
+		}
+		/* If Winbond SMBus, check address at 0x48.
+		   Asus doesn't support */
 		if ((!is_isa) && (((!(val1 & 0x80)) && (val2 == 0xa3)) ||
 				  ((val1 & 0x80) && (val2 == 0x5c)))) {
 			if (w83781d_read_value
-			    (new_client, W83781D_REG_I2C_ADDR) != address)
-				goto ERROR1;
+			    (new_client, W83781D_REG_I2C_ADDR) != address) {
+				err = -ENODEV;
+				goto ERROR2;
+			}
 		}
 	}
 
@@ -1143,8 +1259,11 @@
 			vendid = winbond;
 		else if ((val2 == 0x12) || (val2 == 0x06))
 			vendid = asus;
-		else
-			goto ERROR1;
+		else {
+			err = -ENODEV;
+			goto ERROR2;
+		}
+
 		/* mask off lower bit, not reliable */
 		val1 =
 		    w83781d_read_value(new_client, W83781D_REG_WCHIPID) & 0xfe;
@@ -1166,38 +1285,31 @@
 				       "Ignoring 'force' parameter for unknown chip at"
 				       "adapter %d, address 0x%02x\n",
 				       i2c_adapter_id(adapter), address);
-			goto ERROR1;
+			err = -EINVAL;
+			goto ERROR2;
 		}
 	}
 
 	if (kind == w83781d) {
-		type_name = "w83781d";
 		client_name = "W83781D chip";
 	} else if (kind == w83782d) {
-		type_name = "w83782d";
 		client_name = "W83782D chip";
 	} else if (kind == w83783s) {
-		type_name = "w83783s";
 		client_name = "W83783S chip";
 	} else if (kind == w83627hf) {
-		type_name = "w83627hf";
 		client_name = "W83627HF chip";
 	} else if (kind == as99127f) {
-		type_name = "as99127f";
 		client_name = "AS99127F chip";
 	} else if (kind == w83697hf) {
-		type_name = "w83697hf";
 		client_name = "W83697HF chip";
 	} else {
-		dev_err(&new_client->dev, "Internal error: unknown kind (%d)?!?", kind);
-		goto ERROR1;
+		dev_err(&new_client->dev, "Internal error: unknown "
+						"kind (%d)?!?", kind);
+		err = -ENODEV;
+		goto ERROR2;
 	}
 
-	/* Reserve the ISA region */
-	if (is_isa)
-		request_region(address, W83781D_EXTENT, type_name);
-
-	/* Fill in the remaining client fields and put it into the global list */
+	/* Fill in the remaining client fields and put into the global list */
 	strlcpy(new_client->dev.name, client_name, DEVICE_NAME_SIZE);
 	data->type = kind;
 
@@ -1206,76 +1318,13 @@
 
 	/* Tell the I2C layer a new client has arrived */
 	if ((err = i2c_attach_client(new_client)))
-		goto ERROR3;
+		goto ERROR2;
 
 	/* attach secondary i2c lm75-like clients */
 	if (!is_isa) {
-		if (!(data->lm75 = kmalloc(2 * sizeof (struct i2c_client),
-					   GFP_KERNEL))) {
-			err = -ENOMEM;
-			goto ERROR4;
-		}
-
-		memset(data->lm75, 0x00, 2 * sizeof (struct i2c_client));
-
-		id = i2c_adapter_id(adapter);
-		if (force_subclients[0] == id && force_subclients[1] == address) {
-			for (i = 2; i <= 3; i++) {
-				if (force_subclients[i] < 0x48 ||
-				    force_subclients[i] > 0x4f) {
-					dev_err(&new_client->dev,
-					       "Invalid subclient address %d; must be 0x48-0x4f\n",
-					       force_subclients[i]);
-					goto ERROR5;
-				}
-			}
-			w83781d_write_value(new_client,
-					    W83781D_REG_I2C_SUBADDR,
-					    (force_subclients[2] & 0x07) |
-					    ((force_subclients[3] & 0x07) <<
-					     4));
-			data->lm75[0].addr = force_subclients[2];
-		} else {
-			val1 = w83781d_read_value(new_client,
-						  W83781D_REG_I2C_SUBADDR);
-			data->lm75[0].addr = 0x48 + (val1 & 0x07);
-		}
-		if (kind != w83783s) {
-			if (force_subclients[0] == id &&
-			    force_subclients[1] == address) {
-				data->lm75[1].addr = force_subclients[3];
-			} else {
-				data->lm75[1].addr =
-				    0x48 + ((val1 >> 4) & 0x07);
-			}
-			if (data->lm75[0].addr == data->lm75[1].addr) {
-				dev_err(&new_client->dev,
-				       "Duplicate addresses 0x%x for subclients.\n",
-				       data->lm75[0].addr);
-				goto ERROR5;
-			}
-		}
-		if (kind == w83781d)
-			client_name = "W83781D subclient";
-		else if (kind == w83782d)
-			client_name = "W83782D subclient";
-		else if (kind == w83783s)
-			client_name = "W83783S subclient";
-		else if (kind == w83627hf)
-			client_name = "W83627HF subclient";
-		else if (kind == as99127f)
-			client_name = "AS99127F subclient";
-
-		for (i = 0; i <= 1; i++) {
-			i2c_set_clientdata(&data->lm75[i], NULL);	/* store all data in w83781d */
-			data->lm75[i].adapter = adapter;
-			data->lm75[i].driver = &w83781d_driver;
-			data->lm75[i].flags = 0;
-			strlcpy(data->lm75[i].dev.name, client_name,
-				DEVICE_NAME_SIZE);
-			if (kind == w83783s)
-				break;
-		}
+		if ((err = w83781d_detect_subclients(adapter, address,
+				kind, new_client)))
+			goto ERROR3;
 	} else {
 		data->lm75 = NULL;
 	}
@@ -1346,24 +1395,14 @@
 	w83781d_init_client(new_client);
 	return 0;
 
-/* OK, this is not exactly good programming practice, usually. But it is
-   very code-efficient in this case. */
-
-      ERROR5:
-	if (!is_isa) {
-		i2c_detach_client(&data->lm75[0]);
-		if (data->type != w83783s)
-			i2c_detach_client(&data->lm75[1]);
-		kfree(data->lm75);
-	}
-      ERROR4:
+ERROR3:
 	i2c_detach_client(new_client);
-      ERROR3:
+ERROR2:
+	kfree(new_client);
+ERROR1:
 	if (is_isa)
 		release_region(address, W83781D_EXTENT);
-      ERROR1:
-	kfree(new_client);
-      ERROR0:
+ERROR0:
 	return err;
 }
 
@@ -1373,12 +1412,7 @@
 	struct w83781d_data *data = i2c_get_clientdata(client);
 	int err;
 
-	if ((err = i2c_detach_client(client))) {
-		dev_err(&client->dev,
-		       "Client deregistration failed, client not detached.\n");
-		return err;
-	}
-
+	/* release ISA region or I2C subclients first */
 	if (i2c_is_isa_client(client)) {
 		release_region(client->addr, W83781D_EXTENT);
 	} else {
@@ -1387,6 +1421,14 @@
 			i2c_detach_client(&data->lm75[1]);
 		kfree(data->lm75);
 	}
+
+	/* now it's safe to scrap the rest */
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev,
+		       "Client deregistration failed, client not detached.\n");
+		return err;
+	}
+
 	kfree(client);
 
 	return 0;
diff -urN linux-2.5.70-bk10/drivers/i2c/i2c-core.c linux-2.5.70-bk11/drivers/i2c/i2c-core.c
--- linux-2.5.70-bk10/drivers/i2c/i2c-core.c	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk11/drivers/i2c/i2c-core.c	2003-06-06 04:38:22.000000000 -0700
@@ -124,7 +124,7 @@
 
 int i2c_del_adapter(struct i2c_adapter *adap)
 {
-	struct list_head  *item;
+	struct list_head  *item, *_n;
 	struct i2c_driver *driver;
 	struct i2c_client *client;
 	int res = 0;
@@ -144,7 +144,7 @@
 
 	/* detach any active clients. This must be done first, because
 	 * it can fail; in which case we give upp. */
-	list_for_each(item,&adap->clients) {
+	list_for_each_safe(item, _n, &adap->clients) {
 		client = list_entry(item, struct i2c_client, list);
 
 		/* detaching devices is unconditional of the set notify
@@ -215,8 +215,7 @@
 
 int i2c_del_driver(struct i2c_driver *driver)
 {
-	struct list_head   *item1;
-	struct list_head   *item2;
+	struct list_head   *item1, *item2, *_n;
 	struct i2c_client  *client;
 	struct i2c_adapter *adap;
 	
@@ -245,7 +244,7 @@
 				goto out_unlock;
 			}
 		} else {
-			list_for_each(item2,&adap->clients) {
+			list_for_each_safe(item2, _n, &adap->clients) {
 				client = list_entry(item2, struct i2c_client, list);
 				if (client->driver != driver)
 					continue;
diff -urN linux-2.5.70-bk10/drivers/ide/Kconfig linux-2.5.70-bk11/drivers/ide/Kconfig
--- linux-2.5.70-bk10/drivers/ide/Kconfig	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk11/drivers/ide/Kconfig	2003-06-06 04:38:22.000000000 -0700
@@ -268,7 +268,7 @@
 config BLK_DEV_IDEPCI
 	bool "PCI IDE chipset support" if PCI
 	depends on BLK_DEV_IDE
-	default BLK_DEV_IDEDMA_PMAC if ALL_PPC && BLK_DEV_IDEDMA_PMAC
+	default BLK_DEV_IDEDMA_PMAC if PPC_PMAC && BLK_DEV_IDEDMA_PMAC
 	help
 	  Say Y here for PCI systems which use IDE drive(s).
 	  This option helps the IDE driver to automatically detect and
@@ -409,7 +409,7 @@
 	bool
 	depends on BLK_DEV_IDE
 	default BLK_DEV_IDEDMA_ICS if ARCH_ACORN
-	default BLK_DEV_IDEDMA_PMAC if ALL_PPC && BLK_DEV_IDE_PMAC
+	default BLK_DEV_IDEDMA_PMAC if PPC_PMAC && BLK_DEV_IDE_PMAC
 	default BLK_DEV_IDEDMA_PCI if PCI && BLK_DEV_IDEPCI
 
 config IDEDMA_PCI_WIP
@@ -734,7 +734,7 @@
 
 config BLK_DEV_IDE_PMAC
 	bool "Builtin PowerMac IDE support"
-	depends on BLK_DEV_IDE && ALL_PPC
+	depends on BLK_DEV_IDE && PPC_PMAC
 	help
 	  This driver provides support for the built-in IDE controller on
 	  most of the recent Apple Power Macintoshes and PowerBooks.
diff -urN linux-2.5.70-bk10/drivers/ide/setup-pci.c linux-2.5.70-bk11/drivers/ide/setup-pci.c
--- linux-2.5.70-bk10/drivers/ide/setup-pci.c	2003-06-06 04:38:12.000000000 -0700
+++ linux-2.5.70-bk11/drivers/ide/setup-pci.c	2003-06-06 04:38:23.000000000 -0700
@@ -880,7 +880,7 @@
 			ide_scan_pcidev(dev);
 		}
 	} else {
-		pci_for_each_dev_reverse(dev) {
+		while ((dev = pci_find_device_reverse(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
 			ide_scan_pcidev(dev);
 		}
 	}
diff -urN linux-2.5.70-bk10/drivers/ieee1394/ohci1394.c linux-2.5.70-bk11/drivers/ieee1394/ohci1394.c
--- linux-2.5.70-bk10/drivers/ieee1394/ohci1394.c	2003-06-06 04:38:12.000000000 -0700
+++ linux-2.5.70-bk11/drivers/ieee1394/ohci1394.c	2003-06-06 04:38:23.000000000 -0700
@@ -111,7 +111,7 @@
 #include <linux/vmalloc.h>
 #include <linux/init.h>
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 #include <asm/machdep.h>
 #include <asm/pmac_feature.h>
 #include <asm/prom.h>
@@ -3508,7 +3508,7 @@
 				   OHCI1394_REGISTER_SIZE);
 #endif
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 	/* On UniNorth, power down the cable and turn off the chip
 	 * clock when the module is removed to save power on
 	 * laptops. Turning it back ON is done by the arch code when
@@ -3522,7 +3522,7 @@
 			pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, of_node, 0, 0);
 		}
 	}
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 
 	case OHCI_INIT_ALLOC_HOST:
 		pci_set_drvdata(ohci->dev, NULL);
diff -urN linux-2.5.70-bk10/drivers/macintosh/via-pmu68k.c linux-2.5.70-bk11/drivers/macintosh/via-pmu68k.c
--- linux-2.5.70-bk10/drivers/macintosh/via-pmu68k.c	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk11/drivers/macintosh/via-pmu68k.c	2003-06-06 04:38:23.000000000 -0700
@@ -839,11 +839,11 @@
 pbook_pci_save(void)
 {
 	int npci;
-	struct pci_dev *pd;
+	struct pci_dev *pd = NULL;
 	struct pci_save *ps;
 
 	npci = 0;
-	for (pd = pci_devices; pd != NULL; pd = pd->next)
+	while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL)
 		++npci;
 	n_pbook_pci_saves = npci;
 	if (npci == 0)
@@ -853,7 +853,8 @@
 	if (ps == NULL)
 		return;
 
-	for (pd = pci_devices; pd != NULL && npci != 0; pd = pd->next) {
+	pd = NULL;
+	while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
 		pci_read_config_word(pd, PCI_COMMAND, &ps->command);
 		pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat);
 		pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr);
@@ -867,10 +868,10 @@
 {
 	u16 cmd;
 	struct pci_save *ps = pbook_pci_saves;
-	struct pci_dev *pd;
+	struct pci_dev *pd = NULL;
 	int j;
 
-	for (pd = pci_devices; pd != NULL; pd = pd->next, ++ps) {
+	while ((pd = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
 		if (ps->command == 0)
 			continue;
 		pci_read_config_word(pd, PCI_COMMAND, &cmd);
diff -urN linux-2.5.70-bk10/drivers/media/video/Kconfig linux-2.5.70-bk11/drivers/media/video/Kconfig
--- linux-2.5.70-bk10/drivers/media/video/Kconfig	2003-05-26 18:00:58.000000000 -0700
+++ linux-2.5.70-bk11/drivers/media/video/Kconfig	2003-06-06 04:38:23.000000000 -0700
@@ -45,7 +45,7 @@
 
 config VIDEO_PLANB
 	tristate "PlanB Video-In on PowerMac"
-	depends on ALL_PPC && VIDEO_DEV
+	depends on PPC_PMAC && VIDEO_DEV
 	help
 	  PlanB is the V4L driver for the PowerMac 7x00/8x00 series video
 	  input hardware. If you want to experiment with this, say Y.
diff -urN linux-2.5.70-bk10/drivers/message/fusion/linux_compat.h linux-2.5.70-bk11/drivers/message/fusion/linux_compat.h
--- linux-2.5.70-bk10/drivers/message/fusion/linux_compat.h	2003-05-26 18:00:28.000000000 -0700
+++ linux-2.5.70-bk11/drivers/message/fusion/linux_compat.h	2003-06-06 04:38:23.000000000 -0700
@@ -147,9 +147,7 @@
 
 
 /* PCI/driver subsystem { */
-#ifndef pci_for_each_dev
-#define pci_for_each_dev(dev)		for((dev)=pci_devices; (dev)!=NULL; (dev)=(dev)->next)
-#define pci_peek_next_dev(dev)		((dev)->next ? (dev)->next : NULL)
+#if 0	/* FIXME Don't know what to use to check for the proper kernel version */
 #define DEVICE_COUNT_RESOURCE           6
 #define PCI_BASEADDR_FLAGS(idx)         base_address[idx]
 #define PCI_BASEADDR_START(idx)         base_address[idx] & ~0xFUL
@@ -169,11 +167,10 @@
 	(4 - size); \
 })
 #else
-#define pci_peek_next_dev(dev)		((dev) != pci_dev_g(&pci_devices) ? pci_dev_g((dev)->global_list.next) : NULL)
 #define PCI_BASEADDR_FLAGS(idx)         resource[idx].flags
 #define PCI_BASEADDR_START(idx)         resource[idx].start
 #define PCI_BASEADDR_SIZE(dev,idx)      (dev)->resource[idx].end - (dev)->resource[idx].start + 1
-#endif		/* } ifndef pci_for_each_dev */
+#endif		/* } ifndef 0 */
 
 
 /* Compatability for the 2.3.x PCI DMA API. */
diff -urN linux-2.5.70-bk10/drivers/message/fusion/mptbase.c linux-2.5.70-bk11/drivers/message/fusion/mptbase.c
--- linux-2.5.70-bk10/drivers/message/fusion/mptbase.c	2003-06-06 04:38:12.000000000 -0700
+++ linux-2.5.70-bk11/drivers/message/fusion/mptbase.c	2003-06-06 04:38:23.000000000 -0700
@@ -1184,7 +1184,7 @@
 		 * Do some kind of look ahead here...
 		 */
 		if (pdev->devfn & 1) {
-			pdev2 = pci_peek_next_dev(pdev);
+			pdev2 = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev);
 			if (pdev2 && (pdev2->vendor == 0x1000) &&
 			    (PCI_SLOT(pdev2->devfn) == PCI_SLOT(pdev->devfn)) &&
 			    (pdev2->device == pdev->device) &&
diff -urN linux-2.5.70-bk10/drivers/net/8139cp.c linux-2.5.70-bk11/drivers/net/8139cp.c
--- linux-2.5.70-bk10/drivers/net/8139cp.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/8139cp.c	2003-06-06 04:38:24.000000000 -0700
@@ -1846,7 +1846,7 @@
 	}
 
 	/* Configure DMA attributes. */
-	if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) {
+	if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL)) {
 		cp->pci_using_dac = 1;
 	} else {
 		rc = pci_set_dma_mask(pdev, (u64) 0xffffffff);
diff -urN linux-2.5.70-bk10/drivers/net/Kconfig linux-2.5.70-bk11/drivers/net/Kconfig
--- linux-2.5.70-bk10/drivers/net/Kconfig	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/Kconfig	2003-06-06 04:38:24.000000000 -0700
@@ -225,7 +225,7 @@
 
 config MACE
 	tristate "MACE (Power Mac ethernet) support"
-	depends on NET_ETHERNET && PPC && ALL_PPC
+	depends on NET_ETHERNET && PPC_PMAC
 	help
 	  Power Macintoshes and clones with Ethernet built-in on the
 	  motherboard will usually use a MACE (Medium Access Control for
@@ -249,7 +249,7 @@
 
 config BMAC
 	tristate "BMAC (G3 ethernet) support"
-	depends on NET_ETHERNET && PPC && ALL_PPC
+	depends on NET_ETHERNET && PPC_PMAC
 	help
 	  Say Y for support of BMAC Ethernet interfaces. These are used on G3
 	  computers.
diff -urN linux-2.5.70-bk10/drivers/net/Makefile linux-2.5.70-bk11/drivers/net/Makefile
--- linux-2.5.70-bk10/drivers/net/Makefile	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/Makefile	2003-06-06 04:38:24.000000000 -0700
@@ -173,7 +173,7 @@
 obj-$(CONFIG_TUN) += tun.o
 obj-$(CONFIG_DL2K) += dl2k.o
 obj-$(CONFIG_R8169) += r8169.o
-obj-$(CONFIG_AMD8111_ETH) += amd8111e.o
+obj-$(CONFIG_AMD8111_ETH) += amd8111e.o mii.o
 
 # non-drivers/net drivers who want mii lib
 obj-$(CONFIG_PCMCIA_SMC91C92) += mii.o
diff -urN linux-2.5.70-bk10/drivers/net/arcnet/arc-rawmode.c linux-2.5.70-bk11/drivers/net/arcnet/arc-rawmode.c
--- linux-2.5.70-bk10/drivers/net/arcnet/arc-rawmode.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/arcnet/arc-rawmode.c	2003-06-06 04:38:24.000000000 -0700
@@ -45,11 +45,11 @@
 
 struct ArcProto rawmode_proto =
 {
-	'r',
-	XMTU,
-	rx,
-	build_header,
-	prepare_tx
+	.suffix		= 'r',
+	.mtu		= XMTU,
+	.rx		= rx,
+	.build_header	= build_header,
+	.prepare_tx	= prepare_tx,
 };
 
 
diff -urN linux-2.5.70-bk10/drivers/net/arcnet/arcnet.c linux-2.5.70-bk11/drivers/net/arcnet/arcnet.c
--- linux-2.5.70-bk10/drivers/net/arcnet/arcnet.c	2003-05-26 18:00:43.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/arcnet/arcnet.c	2003-06-06 04:38:24.000000000 -0700
@@ -73,11 +73,11 @@
 
 struct ArcProto arc_proto_null =
 {
-	'?',
-	XMTU,
-	null_rx,
-	null_build_header,
-	null_prepare_tx
+	.suffix		= '?',
+	.mtu		= XMTU,
+	.rx		= null_rx,
+	.build_header	= null_build_header,
+	.prepare_tx	= null_prepare_tx,
 };
 
 static spinlock_t arcnet_lock = SPIN_LOCK_UNLOCKED;
diff -urN linux-2.5.70-bk10/drivers/net/arcnet/rfc1051.c linux-2.5.70-bk11/drivers/net/arcnet/rfc1051.c
--- linux-2.5.70-bk10/drivers/net/arcnet/rfc1051.c	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/arcnet/rfc1051.c	2003-06-06 04:38:24.000000000 -0700
@@ -45,11 +45,11 @@
 
 struct ArcProto rfc1051_proto =
 {
-	's',
-	XMTU - RFC1051_HDR_SIZE,
-	rx,
-	build_header,
-	prepare_tx
+	.suffix		= 's',
+	.mtu		= XMTU - RFC1051_HDR_SIZE,
+	.rx		= rx,
+	.build_header	= build_header,
+	.prepare_tx	= prepare_tx,
 };
 
 
diff -urN linux-2.5.70-bk10/drivers/net/arcnet/rfc1201.c linux-2.5.70-bk11/drivers/net/arcnet/rfc1201.c
--- linux-2.5.70-bk10/drivers/net/arcnet/rfc1201.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/arcnet/rfc1201.c	2003-06-06 04:38:24.000000000 -0700
@@ -44,12 +44,12 @@
 
 struct ArcProto rfc1201_proto =
 {
-	'a',
-	1500,			/* could be more, but some receivers can't handle it... */
-	rx,
-	build_header,
-	prepare_tx,
-	continue_tx
+	.suffix		= 'a',
+	.mtu		= 1500,	/* could be more, but some receivers can't handle it... */
+	.rx		= rx,
+	.build_header	= build_header,
+	.prepare_tx	= prepare_tx,
+	.continue_tx	= continue_tx,
 };
 
 
diff -urN linux-2.5.70-bk10/drivers/net/bmac.c linux-2.5.70-bk11/drivers/net/bmac.c
--- linux-2.5.70-bk10/drivers/net/bmac.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/bmac.c	2003-06-06 04:38:24.000000000 -0700
@@ -1331,12 +1331,13 @@
 		}
 	}
 
-	dev = init_etherdev(NULL, PRIV_BYTES);
+	dev = alloc_etherdev(PRIV_BYTES);
 	if (!dev) {
-		printk(KERN_ERR "init_etherdev failed, out of memory for BMAC %s\n",
+		printk(KERN_ERR "alloc_etherdev failed, out of memory for BMAC %s\n",
 		       bmac->full_name);
 		return;
 	}
+		
 	bp = (struct bmac_data *) dev->priv;
 	SET_MODULE_OWNER(dev);
 	bp->node = bmac;
@@ -1344,21 +1345,22 @@
 
 	if (!request_OF_resource(bmac, 0, " (bmac)")) {
 		printk(KERN_ERR "BMAC: can't request IO resource !\n");
-		goto err_out;
+		goto out1;
 	}
 	if (!request_OF_resource(bmac, 1, " (bmac tx dma)")) {
 		printk(KERN_ERR "BMAC: can't request TX DMA resource !\n");
-		goto err_out;
+		goto out2;
 	}
-
 	if (!request_OF_resource(bmac, 2, " (bmac rx dma)")) {
 		printk(KERN_ERR "BMAC: can't request RX DMA resource !\n");
-		goto err_out;
+		goto out3;
 	}
+
 	dev->base_addr = (unsigned long)
 		ioremap(bmac->addrs[0].address, bmac->addrs[0].size);
 	if (!dev->base_addr)
-		goto err_out;
+		goto out4;
+
 	dev->irq = bmac->intrs[0].line;
 
 	bmac_enable_and_reset_chip(dev);
@@ -1429,11 +1431,19 @@
 	 */
 	disable_irq(dev->irq);
 	pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
+
+	if (register_netdev(dev) != 0) {
+		printk(KERN_ERR "registration failed for BMAC %s\n",
+		       bmac->full_name);
+		goto err_out_irq2;
+	}
 	
 	bp->next_bmac = bmac_devs;
 	bmac_devs = dev;
 	return;
 
+err_out_irq2:
+	free_irq(bmac->intrs[2].line, dev);
 err_out_irq1:
 	free_irq(bmac->intrs[1].line, dev);
 err_out_irq0:
@@ -1444,14 +1454,14 @@
 	iounmap((void *)bp->tx_dma);
 err_out_iounmap:
 	iounmap((void *)dev->base_addr);
-err_out:
-	if (bp->node) {
-		release_OF_resource(bp->node, 0);
-		release_OF_resource(bp->node, 1);
-		release_OF_resource(bp->node, 2);
-		pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
-	}
-	unregister_netdev(dev);
+out4:
+	release_OF_resource(bp->node, 2);
+out3:
+	release_OF_resource(bp->node, 1);
+out2:
+	release_OF_resource(bp->node, 0);
+out1:
+	pmac_call_feature(PMAC_FTR_BMAC_ENABLE, bp->node, 0, 0);
 	kfree(dev);
 }
 
diff -urN linux-2.5.70-bk10/drivers/net/dl2k.h linux-2.5.70-bk11/drivers/net/dl2k.h
--- linux-2.5.70-bk10/drivers/net/dl2k.h	2003-05-26 18:00:57.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/dl2k.h	2003-06-06 04:38:24.000000000 -0700
@@ -243,7 +243,6 @@
 	VLANTagInsert = 0x0000000010000000,
 	TFDDone = 0x80000000,
 	VIDShift = 32,
-	CFI = 0x0000100000000000,
 	UsePriorityShift = 48,
 };
 
diff -urN linux-2.5.70-bk10/drivers/net/hamradio/mkiss.c linux-2.5.70-bk11/drivers/net/hamradio/mkiss.c
--- linux-2.5.70-bk10/drivers/net/hamradio/mkiss.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/hamradio/mkiss.c	2003-06-06 04:38:24.000000000 -0700
@@ -329,6 +329,12 @@
 				return;
 			}
 			ax->rcount -= 2;
+                        /* dl9sau bugfix: the trailling two bytes flexnet crc
+                         * will not be passed to the kernel. thus we have
+                         * to correct the kissparm signature, because it
+                         * indicates a crc but there's none
+			 */
+                        *ax->rbuff &= ~0x20;
 		}
  	}
 
diff -urN linux-2.5.70-bk10/drivers/net/ns83820.c linux-2.5.70-bk11/drivers/net/ns83820.c
--- linux-2.5.70-bk10/drivers/net/ns83820.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/ns83820.c	2003-06-06 04:38:24.000000000 -0700
@@ -1769,7 +1769,7 @@
 	int using_dac = 0;
 
 	/* See if we can set the dma mask early on; failure is fatal. */
-	if (TRY_DAC && !pci_set_dma_mask(pci_dev, 0xffffffffffffffff)) {
+	if (TRY_DAC && !pci_set_dma_mask(pci_dev, 0xffffffffffffffffULL)) {
 		using_dac = 1;
 	} else if (!pci_set_dma_mask(pci_dev, 0xffffffff)) {
 		using_dac = 0;
diff -urN linux-2.5.70-bk10/drivers/net/pcmcia/fmvj18x_cs.c linux-2.5.70-bk11/drivers/net/pcmcia/fmvj18x_cs.c
--- linux-2.5.70-bk10/drivers/net/pcmcia/fmvj18x_cs.c	2003-05-26 18:00:43.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/pcmcia/fmvj18x_cs.c	2003-06-06 04:38:24.000000000 -0700
@@ -923,8 +923,7 @@
 	   htons(inw(ioaddr +14)));
     lp->stats.tx_errors++;
     /* ToDo: We should try to restart the adaptor... */
-    cli();
-
+    local_irq_disable();
     fjn_reset(dev);
 
     lp->tx_started = 0;
@@ -932,7 +931,7 @@
     lp->tx_queue_len = 0;
     lp->sent = 0;
     lp->open_time = jiffies;
-    sti();
+    local_irq_enable();
     netif_wake_queue(dev);
 }
 
@@ -1361,9 +1360,8 @@
 	    mc_filter[bit >> 3] |= (1 << bit);
 	}
     }
-    
-    save_flags(flags);
-    cli();
+
+    local_irq_save(flags); 
     if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
 	int saved_bank = inb(ioaddr + CONFIG_1);
 	/* Switch to bank 1 and set the multicast table. */
@@ -1373,5 +1371,5 @@
 	memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));
 	outb(saved_bank, ioaddr + CONFIG_1);
     }
-    restore_flags(flags);
+    local_irq_restore(flags);
 }
diff -urN linux-2.5.70-bk10/drivers/net/sb1000.c linux-2.5.70-bk11/drivers/net/sb1000.c
--- linux-2.5.70-bk10/drivers/net/sb1000.c	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/sb1000.c	2003-06-06 04:38:24.000000000 -0700
@@ -162,10 +162,17 @@
 		
 	irq = pnp_irq(pdev, 0);
 
-	if (!request_region(ioaddr[0], 16, dev->name))
+	if (!request_region(ioaddr[0], 16, "sb1000"))
 		goto out_disable;
-	if (!request_region(ioaddr[1], 16, dev->name))
+	if (!request_region(ioaddr[1], 16, "sb1000"))
 		goto out_release_region0;
+
+	dev = alloc_etherdev(sizeof(struct sb1000_private));
+	if (!dev) {
+		error = -ENOMEM;
+		goto out_release_regions;
+	}
+
 		 
 	dev->base_addr = ioaddr[0];
 	/* mem_start holds the second I/O address */
@@ -177,12 +184,6 @@
 			"S/N %#8.8x, IRQ %d.\n", dev->name, dev->base_addr,
 			dev->mem_start, serial_number, dev->irq);
 
-	dev = alloc_etherdev(sizeof(struct sb1000_private));
-	if (!dev) {
-		error = -ENOMEM;
-		goto out_release_regions;
-	}
-
 	/*
 	 * The SB1000 is an rx-only cable modem device.  The uplink is a modem
 	 * and we do not want to arp on it.
@@ -212,11 +213,9 @@
 
 	error = register_netdev(dev);
 	if (error)
-		goto out_unregister;
+		goto out_release_regions;
 	return 0;
 
- out_unregister:
-	unregister_netdev(dev);
  out_release_regions:
 	release_region(ioaddr[1], 16);
  out_release_region0:
@@ -236,6 +235,7 @@
 	unregister_netdev(dev);
 	release_region(dev->base_addr, 16);
 	release_region(dev->mem_start, 16);
+	kfree(dev);
 }
 
 static struct pnp_driver sb1000_driver = {
diff -urN linux-2.5.70-bk10/drivers/net/sk98lin/skge.c linux-2.5.70-bk11/drivers/net/sk98lin/skge.c
--- linux-2.5.70-bk10/drivers/net/sk98lin/skge.c	2003-06-06 04:38:13.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/sk98lin/skge.c	2003-06-06 04:38:24.000000000 -0700
@@ -421,7 +421,7 @@
 			continue;
 
 		/* Configure DMA attributes. */
-		if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff) &&
+		if (pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL) &&
 		    pci_set_dma_mask(pdev, (u64) 0xffffffff))
 				continue;
 
diff -urN linux-2.5.70-bk10/drivers/net/sungem.c linux-2.5.70-bk11/drivers/net/sungem.c
--- linux-2.5.70-bk10/drivers/net/sungem.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/sungem.c	2003-06-06 04:38:24.000000000 -0700
@@ -48,7 +48,7 @@
 #include <asm/pbm.h>
 #endif
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 #include <asm/pci-bridge.h>
 #include <asm/prom.h>
 #include <asm/machdep.h>
@@ -1491,7 +1491,7 @@
 	mifcfg &= ~MIF_CFG_BBMODE;
 	writel(mifcfg, gp->regs + MIF_CFG);
 	
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 	if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
 		int i, j;
 
@@ -1525,7 +1525,7 @@
 				break;
 		}
 	}
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 
 	if (gp->pdev->vendor == PCI_VENDOR_ID_SUN &&
 	    gp->pdev->device == PCI_DEVICE_ID_SUN_GEM) {
@@ -1924,7 +1924,7 @@
 	}
 }
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 /* Enable the chip's clock and make sure it's config space is
  * setup properly. There appear to be no need to restore the
  * base addresses.
@@ -1963,7 +1963,7 @@
 	pmac_call_feature(PMAC_FTR_GMAC_ENABLE, gp->of_node, 0, 0);
 }
 
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 
 /* Must be invoked under gp->lock. */
 static void gem_stop_phy(struct gem *gp)
@@ -2028,10 +2028,10 @@
 
 		spin_unlock_irq(&gp->lock);
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 		/* Power down the chip */
 		gem_apple_powerdown(gp);
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 	} else {
 		gem_stop(gp);
 
@@ -2085,13 +2085,13 @@
 	 * etc. state so it is safe to do this bit without gp->lock
 	 */
 	if (!gp->hw_running) {
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 		/* First, we need to bring up the chip */
 		if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
 			gem_apple_powerup(gp);
 			gem_check_invariants(gp);
 		}
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 
 		/* Reset the chip */
 		spin_lock_irq(&gp->lock);
@@ -2112,10 +2112,10 @@
 
 		printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name);
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 		if (!hw_was_up && gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
 			gem_apple_powerdown(gp);
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 		/* Fire the PM timer that will shut us down in about 10 seconds */
 		gp->pm_timer.expires = jiffies + 10*HZ;
 		add_timer(&gp->pm_timer);
@@ -2227,13 +2227,13 @@
 	printk(KERN_INFO "%s: resuming\n", dev->name);
 
 	if (gp->opened) {
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 		/* First, we need to bring up the chip */
 		if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
 			gem_apple_powerup(gp);
 			gem_check_invariants(gp);
 		}
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 		spin_lock_irq(&gp->lock);
 
 		gem_stop(gp);
@@ -2541,7 +2541,7 @@
 	return rc;
 }
 
-#if (!defined(__sparc__) && !defined(CONFIG_ALL_PPC))
+#if (!defined(__sparc__) && !defined(CONFIG_PPC))
 /* Fetch MAC address from vital product data of PCI ROM. */
 static void find_eth_addr_in_vpd(void *rom_base, int len, unsigned char *dev_addr)
 {
@@ -2604,7 +2604,7 @@
 
 static int __devinit gem_get_device_address(struct gem *gp)
 {
-#if defined(__sparc__) || defined(CONFIG_ALL_PPC)
+#if defined(__sparc__) || defined(CONFIG_PPC_PMAC)
 	struct net_device *dev = gp->dev;
 #endif
 
@@ -2623,7 +2623,7 @@
 	}
 	if (node == -1)
 		memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
-#elif defined(CONFIG_ALL_PPC)
+#elif defined(CONFIG_PPC_PMAC)
 	unsigned char *addr;
 
 	addr = get_property(gp->of_node, "local-mac-address", NULL);
@@ -2748,7 +2748,7 @@
 	 * invariants to work, but also because the firmware might
 	 * not have properly shut down the PHY.
 	 */
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 	if (pdev->vendor == PCI_VENDOR_ID_APPLE)
 		gem_apple_powerup(gp);
 #endif
@@ -2779,7 +2779,7 @@
 		goto err_out_iounmap;
 	}
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 	gp->of_node = pci_device_to_OF_node(pdev);
 #endif	
 	if (gem_get_device_address(gp))
diff -urN linux-2.5.70-bk10/drivers/net/sungem.h linux-2.5.70-bk11/drivers/net/sungem.h
--- linux-2.5.70-bk10/drivers/net/sungem.h	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/sungem.h	2003-06-06 04:38:24.000000000 -0700
@@ -998,7 +998,7 @@
 	dma_addr_t gblock_dvma;
 	struct pci_dev *pdev;
 	struct net_device *dev;
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 	struct device_node	*of_node;
 #endif
 };
diff -urN linux-2.5.70-bk10/drivers/net/sunqe.c linux-2.5.70-bk11/drivers/net/sunqe.c
--- linux-2.5.70-bk10/drivers/net/sunqe.c	2003-06-06 04:38:13.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/sunqe.c	2003-06-06 04:38:24.000000000 -0700
@@ -722,34 +722,31 @@
 	struct net_device *qe_devs[4];
 	struct sunqe *qeps[4];
 	struct sbus_dev *qesdevs[4];
+	struct sbus_dev *child;
 	struct sunqec *qecp = NULL;
 	u8 bsizes, bsizes_more;
-	int i, j, res = ENOMEM;
+	int i, j, res = -ENOMEM;
 
-	dev = init_etherdev(0, sizeof(struct sunqe));
-	qe_devs[0] = dev;
-	qeps[0] = (struct sunqe *) dev->priv;
-	qeps[0]->channel = 0;
-	spin_lock_init(&qeps[0]->lock);
-	for (j = 0; j < 6; j++)
-		qe_devs[0]->dev_addr[j] = idprom->id_ethaddr[j];
+	for (i = 0; i < 4; i++) {
+		qe_devs[i] = alloc_etherdev(sizeof(struct sunqe));
+		if (!qe_devs[i])
+			goto out;
+	}
 
 	if (version_printed++ == 0)
 		printk(KERN_INFO "%s", version);
 
-	qe_devs[1] = qe_devs[2] = qe_devs[3] = NULL;
-	for (i = 1; i < 4; i++) {
-		qe_devs[i] = init_etherdev(0, sizeof(struct sunqe));
-		if (qe_devs[i] == NULL || qe_devs[i]->priv == NULL)
-			goto qec_free_devs;
+	for (i = 0; i < 4; i++) {
 		qeps[i] = (struct sunqe *) qe_devs[i]->priv;
 		for (j = 0; j < 6; j++)
 			qe_devs[i]->dev_addr[j] = idprom->id_ethaddr[j];
 		qeps[i]->channel = i;
+		spin_lock_init(&qeps[i]->lock);
 	}
+
 	qecp = kmalloc(sizeof(struct sunqec), GFP_KERNEL);
 	if (qecp == NULL)
-		goto qec_free_devs;
+		goto out1;
 	qecp->qec_sdev = sdev;
 
 	for (i = 0; i < 4; i++) {
@@ -758,25 +755,15 @@
 		qeps[i]->parent = qecp;
 	}
 
-	/* Link in channel 0. */
-	i = prom_getintdefault(sdev->child->prom_node, "channel#", -1);
-	if (i == -1) { res=ENODEV; goto qec_free_devs; }
-	qesdevs[i] = sdev->child;
-
-	/* Link in channel 1. */
-	i = prom_getintdefault(sdev->child->next->prom_node, "channel#", -1);
-	if (i == -1) { res=ENODEV; goto qec_free_devs; }
-	qesdevs[i] = sdev->child->next;
-
-	/* Link in channel 2. */
-	i = prom_getintdefault(sdev->child->next->next->prom_node, "channel#", -1);
-	if (i == -1) { res=ENODEV; goto qec_free_devs; }
-	qesdevs[i] = sdev->child->next->next;
-
-	/* Link in channel 3. */
-	i = prom_getintdefault(sdev->child->next->next->next->prom_node, "channel#", -1);
-	if (i == -1) { res=ENODEV; goto qec_free_devs; }
-	qesdevs[i] = sdev->child->next->next->next;
+	res = -ENODEV;
+
+	for (i = 0, child = sdev->child; i < 4; i++, child = child->next) {
+		/* Link in channel */
+		j = prom_getintdefault(child->prom_node, "channel#", -1);
+		if (j == -1)
+			goto out2;
+		qesdevs[j] = child;
+	}
 
 	for (i = 0; i < 4; i++)
 		qeps[i]->qe_sdev = qesdevs[i];
@@ -786,22 +773,18 @@
 				   GLOB_REG_SIZE, "QEC Global Registers");
 	if (!qecp->gregs) {
 		printk(KERN_ERR "QuadEther: Cannot map QEC global registers.\n");
-		res = ENODEV;
-		goto qec_free_devs;
+		goto out2;
 	}
 
 	/* Make sure the QEC is in MACE mode. */
 	if ((sbus_readl(qecp->gregs + GLOB_CTRL) & 0xf0000000) != GLOB_CTRL_MMODE) {
 		printk(KERN_ERR "QuadEther: AIEEE, QEC is not in MACE mode!\n");
-		res = ENODEV;
-		goto qec_free_devs;
+		goto out3;
 	}
 
 	/* Reset the QEC. */
-	if (qec_global_reset(qecp->gregs)) {
-		res = ENODEV;
-		goto qec_free_devs;
-	}
+	if (qec_global_reset(qecp->gregs))
+		goto out3;
 
 	/* Find and set the burst sizes for the QEC, since it does
 	 * the actual dma for all 4 channels.
@@ -824,40 +807,36 @@
 	qec_init_once(qecp, sdev);
 
 	for (i = 0; i < 4; i++) {
+		struct sunqe *qe = qeps[i];
 		/* Map in QEC per-channel control registers. */
-		qeps[i]->qcregs = sbus_ioremap(&qesdevs[i]->resource[0], 0,
-					       CREG_REG_SIZE, "QEC Channel Registers");
-		if (!qeps[i]->qcregs) {
+		qe->qcregs = sbus_ioremap(&qe->qe_sdev->resource[0], 0,
+				       CREG_REG_SIZE, "QEC Channel Registers");
+		if (!qe->qcregs) {
 			printk(KERN_ERR "QuadEther: Cannot map QE %d's channel registers.\n", i);
-			res = ENODEV;
-			goto qec_free_devs;
+			goto out4;
 		}
 
 		/* Map in per-channel AMD MACE registers. */
-		qeps[i]->mregs = sbus_ioremap(&qesdevs[i]->resource[1], 0,
-					      MREGS_REG_SIZE, "QE MACE Registers");
-		if (!qeps[i]->mregs) {
+		qe->mregs = sbus_ioremap(&qe->qe_sdev->resource[1], 0,
+				      MREGS_REG_SIZE, "QE MACE Registers");
+		if (!qe->mregs) {
 			printk(KERN_ERR "QuadEther: Cannot map QE %d's MACE registers.\n", i);
-			res = ENODEV;
-			goto qec_free_devs;
+			goto out4;
 		}
 
-		qeps[i]->qe_block = sbus_alloc_consistent(qesdevs[i],
-							  PAGE_SIZE,
-							  &qeps[i]->qblock_dvma);
-		qeps[i]->buffers = sbus_alloc_consistent(qesdevs[i],
-							 sizeof(struct sunqe_buffers),
-							 &qeps[i]->buffers_dvma);
-		if (qeps[i]->qe_block == NULL ||
-		    qeps[i]->qblock_dvma == 0 ||
-		    qeps[i]->buffers == NULL ||
-		    qeps[i]->buffers_dvma == 0) {
-			res = ENODEV;
-			goto qec_free_devs;
+		qe->qe_block = sbus_alloc_consistent(qe->qe_sdev,
+						  PAGE_SIZE,
+						  &qe->qblock_dvma);
+		qe->buffers = sbus_alloc_consistent(qe->qe_sdev,
+						 sizeof(struct sunqe_buffers),
+						 &qe->buffers_dvma);
+		if (qe->qe_block == NULL || qe->qblock_dvma == 0 ||
+		    qe->buffers == NULL || qe->buffers_dvma == 0) {
+			goto out4;
 		}
 
 		/* Stop this QE. */
-		qe_stop(qeps[i]);
+		qe_stop(qe);
 	}
 
 	for (i = 0; i < 4; i++) {
@@ -871,7 +850,6 @@
 		qe_devs[i]->watchdog_timeo = 5*HZ;
 		qe_devs[i]->irq = sdev->irqs[0];
 		qe_devs[i]->dma = 0;
-		ether_setup(qe_devs[i]);
 	}
 
 	/* QEC receives interrupts from each QE, then it sends the actual
@@ -882,8 +860,13 @@
 	if (request_irq(sdev->irqs[0], &qec_interrupt,
 			SA_SHIRQ, "QuadEther", (void *) qecp)) {
 		printk(KERN_ERR "QuadEther: Can't register QEC master irq handler.\n");
-		res = EAGAIN;
-		goto qec_free_devs;
+		res = -EAGAIN;
+		goto out4;
+	}
+
+	for (i = 0; i < 4; i++) {
+		if (register_netdev(qe_devs[i]) != 0)
+			goto out5;
 	}
 
 	/* Report the QE channels. */
@@ -899,42 +882,43 @@
 	/* We are home free at this point, link the qe's into
 	 * the master list for later driver exit.
 	 */
-	for (i = 0; i < 4; i++)
-		qe_devs[i]->ifindex = dev_new_index();
 	qecp->next_module = root_qec_dev;
 	root_qec_dev = qecp;
 
 	return 0;
 
-qec_free_devs:
+out5:
+	while (i--)
+		unregister_netdev(qe_devs[i]);
+	free_irq(sdev->irqs[0], (void *)qecp);
+out4:
 	for (i = 0; i < 4; i++) {
-		if (qe_devs[i] != NULL) {
-			if (qe_devs[i]->priv) {
-				struct sunqe *qe = (struct sunqe *)qe_devs[i]->priv;
-
-				if (qe->qcregs)
-					sbus_iounmap(qe->qcregs, CREG_REG_SIZE);
-				if (qe->mregs)
-					sbus_iounmap(qe->mregs, MREGS_REG_SIZE);
-				if (qe->qe_block != NULL)
-					sbus_free_consistent(qe->qe_sdev,
-							     PAGE_SIZE,
-							     qe->qe_block,
-							     qe->qblock_dvma);
-				if (qe->buffers != NULL)
-					sbus_free_consistent(qe->qe_sdev,
-							     sizeof(struct sunqe_buffers),
-							     qe->buffers,
-							     qe->buffers_dvma);
-			}
-			kfree(qe_devs[i]);
-		}
-	}
-	if (qecp != NULL) {
-		if (qecp->gregs)
-			sbus_iounmap(qecp->gregs, GLOB_REG_SIZE);
-		kfree(qecp);
+		struct sunqe *qe = (struct sunqe *)qe_devs[i]->priv;
+
+		if (qe->qcregs)
+			sbus_iounmap(qe->qcregs, CREG_REG_SIZE);
+		if (qe->mregs)
+			sbus_iounmap(qe->mregs, MREGS_REG_SIZE);
+		if (qe->qe_block)
+			sbus_free_consistent(qe->qe_sdev,
+					     PAGE_SIZE,
+					     qe->qe_block,
+					     qe->qblock_dvma);
+		if (qe->buffers)
+			sbus_free_consistent(qe->qe_sdev,
+					     sizeof(struct sunqe_buffers),
+					     qe->buffers,
+					     qe->buffers_dvma);
 	}
+out3:
+	sbus_iounmap(qecp->gregs, GLOB_REG_SIZE);
+out2:
+	kfree(qecp);
+out1:
+	i = 4;
+out:
+	while (i--)
+		kfree(qe_devs[i]);
 	return res;
 }
 
diff -urN linux-2.5.70-bk10/drivers/net/tg3.c linux-2.5.70-bk11/drivers/net/tg3.c
--- linux-2.5.70-bk10/drivers/net/tg3.c	2003-06-06 04:38:14.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/tg3.c	2003-06-06 04:38:24.000000000 -0700
@@ -6740,7 +6740,7 @@
 	}
 
 	/* Configure DMA attributes. */
-	if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffff)) {
+	if (!pci_set_dma_mask(pdev, (u64) 0xffffffffffffffffULL)) {
 		pci_using_dac = 1;
 		if (pci_set_consistent_dma_mask(pdev,
 						(u64) 0xffffffffffffffff)) {
diff -urN linux-2.5.70-bk10/drivers/net/tun.c linux-2.5.70-bk11/drivers/net/tun.c
--- linux-2.5.70-bk10/drivers/net/tun.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/tun.c	2003-06-06 04:38:24.000000000 -0700
@@ -551,10 +551,12 @@
 	if (!(tun->flags & TUN_PERSIST)) {
 		dev_close(&tun->dev);
 		unregister_netdevice(&tun->dev);
-		kfree(tun);
 	}
 
 	rtnl_unlock();
+
+	if (!(tun->flags & TUN_PERSIST)) 
+		kfree(tun);
 	return 0;
 }
 
diff -urN linux-2.5.70-bk10/drivers/net/wireless/Kconfig linux-2.5.70-bk11/drivers/net/wireless/Kconfig
--- linux-2.5.70-bk10/drivers/net/wireless/Kconfig	2003-06-06 04:38:14.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/wireless/Kconfig	2003-06-06 04:38:24.000000000 -0700
@@ -149,7 +149,7 @@
 	  unsure, say N.
 
 comment "Wireless 802.11b ISA/PCI cards support"
-	depends on NET_RADIO && (ISA || PCI || ALL_PPC || PCMCIA)
+	depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA)
 
 config AIRO
 	tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
@@ -169,7 +169,7 @@
 
 config HERMES
 	tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
-	depends on NET_RADIO && (ALL_PPC || PCI || PCMCIA)
+	depends on NET_RADIO && (PPC_PMAC || PCI || PCMCIA)
 	---help---
 	  A driver for 802.11b wireless cards based based on the "Hermes" or
 	  Intersil HFA384x (Prism 2) MAC controller.  This includes the vast
@@ -191,7 +191,7 @@
 
 config APPLE_AIRPORT
 	tristate "Apple Airport support (built-in)"
-	depends on ALL_PPC && HERMES
+	depends on PPC_PMAC && HERMES
 	help
 	  Say Y here to support the Airport 802.11b wireless Ethernet hardware
 	  built into the Macintosh iBook and other recent PowerPC-based
@@ -281,10 +281,25 @@
 	  for location).  You also want to check out the PCMCIA-HOWTO,
 	  available from <http://www.tldp.org/docs.html#howto>.
 
+config PCMCIA_ATMEL
+      tristate "Atmel at76c502/at76c504 PCMCIA cards"
+      depends on NET_RADIO && EXPERIMENTAL && PCMCIA
+       ---help---
+         A driver for PCMCIA 802.11 wireless cards based on the 
+         Atmel fast-vnet chips. This driver supports standard
+         Linux wireless extensions. 
+ 
+         Many  cards based on this chipset do not have flash memory
+         and need their firmware loaded at start-up. If yours is 
+         one of these, you will need to provide a firmware image
+	 to be loaded into the card by the driver. The Atmel
+	 firmware package can be downloaded from
+	 http://www.thekelleys.org.uk/atmel/atmel_firmware.tar.gz
+
 # yes, this works even when no drivers are selected
 config NET_WIRELESS
 	bool
-	depends on NET_RADIO && (ISA || PCI || ALL_PPC || PCMCIA)
+	depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA)
 	default y
 
 endmenu
diff -urN linux-2.5.70-bk10/drivers/net/wireless/Makefile linux-2.5.70-bk11/drivers/net/wireless/Makefile
--- linux-2.5.70-bk10/drivers/net/wireless/Makefile	2003-06-06 04:38:14.000000000 -0700
+++ linux-2.5.70-bk11/drivers/net/wireless/Makefile	2003-06-06 04:38:24.000000000 -0700
@@ -22,4 +22,5 @@
 
 # 16-bit wireless PCMCIA client drivers
 obj-$(CONFIG_PCMCIA_RAYCS)	+= ray_cs.o
+obj-$(CONFIG_PCMCIA_ATMEL)      += atmel_cs.o atmel.o 
 
diff -urN linux-2.5.70-bk10/drivers/net/wireless/atmel.c linux-2.5.70-bk11/drivers/net/wireless/atmel.c
--- linux-2.5.70-bk10/drivers/net/wireless/atmel.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk11/drivers/net/wireless/atmel.c	2003-06-06 04:38:24.000000000 -0700
@@ -0,0 +1,3943 @@
+/*** -*- linux-c -*- **********************************************************
+
+     Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
+
+        Copyright 2000-2001 ATMEL Corporation.
+        Copyright 2003 Simon Kelley.
+
+    This code was developed from version 2.1.1 of the Atmel drivers, 
+    released by Atmel corp. under the GPL in December 2002. It also 
+    includes code from the Linux aironet drivers (C) Benjamin Reed, 
+    and the Linux PCMCIA package, (C) David Hinds and the Linux wireless
+    extensions, (C) Jean Tourrilhes.
+
+    The firmware module for reading the MAC address of the card comes from
+    net.russotto.AtmelMACFW, written by Matthew T. Russotto and copyright
+    by him. net.russotto.AtmelMACFW is used under the GPL license version 2.
+    This file contains the module in binary form and, under the terms
+    of the GPL, in source form. The source is located at the end of the file.
+
+    For all queries about this code, please contact the current author, 
+    Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
+
+    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 software 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 Atmel wireless lan drivers; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+******************************************************************************/
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/delay.h>
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+#include <linux/byteorder/generic.h>
+#include <linux/crc32.h>
+#include <linux/proc_fs.h>
+#include <linux/device.h>
+#include <linux/moduleparam.h>
+#ifdef CONFIG_FW_LOADER
+#include <linux/firmware.h>
+#endif
+#include "ieee802_11.h"
+
+#define DRIVER_MAJOR 0
+#define DRIVER_MINOR 7
+
+MODULE_AUTHOR("Simon Kelley");
+MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards");
+
+/* The name of the firmware file to be loaded 
+   over-rides any automatic selection */
+static char *firmware = NULL;
+module_param(firmware, charp, 0);
+
+#define MAX_SSID_LENGTH 32
+#define MGMT_JIFFIES (256 * HZ / 100)
+
+#define MAX_BSS_ENTRIES	64	
+
+/* registers */
+#define GCR  0x00    //      (SIR0)  General Configuration Register        
+#define BSR  0x02    //      (SIR1)  Bank Switching Select Register 
+#define AR   0x04
+#define DR   0x08
+#define MR1  0x12    //      Mirror Register 1                  
+#define MR2  0x14    //      Mirror Register 2  
+#define MR3  0x16    //      Mirror Register 3  
+#define MR4  0x18    //      Mirror Register 4   
+
+#define GPR1                            0x0c
+#define GPR2                            0x0e
+#define GPR3                            0x10
+//
+// Constants for the GCR register.
+//
+#define GCR_REMAP     0x0400          // Remap internal SRAM to 0
+#define GCR_SWRES     0x0080          // BIU reset (ARM and PAI are NOT reset) 
+#define GCR_CORES     0x0060          // Core Reset (ARM and PAI are reset)
+#define GCR_ENINT     0x0002          // Enable Interrupts    
+#define GCR_ACKINT    0x0008          // Acknowledge Interrupts
+
+#define BSS_SRAM      0x0200          // AMBA module selection --> SRAM
+#define BSS_IRAM      0x0100          // AMBA module selection --> IRAM
+//
+// Constants for the MR registers.
+//
+#define MAC_INIT_COMPLETE       0x0001        // MAC init has been completed
+#define MAC_BOOT_COMPLETE       0x0010        // MAC boot has been completed
+#define MAC_INIT_OK             0x0002        // MAC boot has been completed
+
+#define C80211_SUBTYPE_MGMT_ASS_REQUEST                 0x00
+#define C80211_SUBTYPE_MGMT_ASS_RESPONSE                0x10
+#define C80211_SUBTYPE_MGMT_REASS_REQUEST               0x20
+#define C80211_SUBTYPE_MGMT_REASS_RESPONSE              0x30
+#define C80211_SUBTYPE_MGMT_ProbeRequest                0x40
+#define C80211_SUBTYPE_MGMT_ProbeResponse               0x50
+#define C80211_SUBTYPE_MGMT_BEACON                      0x80
+#define C80211_SUBTYPE_MGMT_ATIM                        0x90
+#define C80211_SUBTYPE_MGMT_DISASSOSIATION              0xA0
+#define C80211_SUBTYPE_MGMT_Authentication              0xB0
+#define C80211_SUBTYPE_MGMT_Deauthentication    0xC0
+
+#define C80211_MGMT_AAN_OPENSYSTEM              0x0000
+#define C80211_MGMT_AAN_SHAREDKEY               0x0001
+
+#define C80211_MGMT_CAPABILITY_ESS              0x0001  // see 802.11 p.58
+#define C80211_MGMT_CAPABILITY_IBSS             0x0002  //      - " -
+#define C80211_MGMT_CAPABILITY_CFPollable       0x0004  //      - " -
+#define C80211_MGMT_CAPABILITY_CFPollRequest    0x0008  //      - " -
+#define C80211_MGMT_CAPABILITY_Privacy          0x0010  //      - " -
+
+#define C80211_MGMT_SC_Success                  0
+#define C80211_MGMT_SC_Unspecified              1
+#define C80211_MGMT_SC_SupportCapabilities      10
+#define C80211_MGMT_SC_ReassDenied              11
+#define C80211_MGMT_SC_AssDenied                12
+#define C80211_MGMT_SC_AuthAlgNotSupported      13
+#define C80211_MGMT_SC_AuthTransSeqNumError     14
+#define C80211_MGMT_SC_AuthRejectChallenge      15
+#define C80211_MGMT_SC_AuthRejectTimeout        16
+#define C80211_MGMT_SC_AssDeniedHandleAP        17
+#define C80211_MGMT_SC_AssDeniedBSSRate         18
+
+#define C80211_MGMT_ElementID_SSID              0
+#define C80211_MGMT_ElementID_SupportedRates    1
+#define C80211_MGMT_ElementID_ChallengeText     16
+#define C80211_MGMT_CAPABILITY_ShortPreamble    0x0020
+
+struct get_set_mib {
+        u8 type;
+        u8 size;
+        u8 index;
+        u8 reserved;
+        u8 data[72];
+};
+
+struct rx_desc {
+        u32          Next;
+        u16          MsduPos;
+        u16          MsduSize;
+	
+        u8           State;
+        u8           Status;
+        u8           Rate;
+        u8           Rssi;
+        u8           LinkQuality;
+        u8           PreambleType;
+        u16          Duration;
+        u32          RxTime;
+
+};
+
+#define RX_DESC_FLAG_VALID       0x80
+#define RX_DESC_FLAG_CONSUMED    0x40
+#define RX_DESC_FLAG_IDLE        0x00
+
+#define RX_STATUS_SUCCESS        0x00
+
+#define RX_DESC_MSDU_POS_OFFSET      4
+#define RX_DESC_MSDU_SIZE_OFFSET     6
+#define RX_DESC_FLAGS_OFFSET         8
+#define RX_DESC_STATUS_OFFSET        9
+#define RX_DESC_RSSI_OFFSET          11
+#define RX_DESC_LINK_QUALITY_OFFSET  12
+#define RX_DESC_PREAMBLE_TYPE_OFFSET 13
+#define RX_DESC_DURATION_OFFSET      14
+#define RX_DESC_RX_TIME_OFFSET       16
+
+
+struct tx_desc {
+   u32       NextDescriptor;
+   u16       TxStartOfFrame;
+   u16       TxLength;
+   
+   u8        TxState;
+   u8        TxStatus;
+   u8        RetryCount;
+
+   u8        TxRate;
+   u32       TxTime;
+   u8        Reserved;
+   u8        PacketType;
+   u16       HostTxLength;
+
+};
+
+
+#define TX_DESC_NEXT_OFFSET        0
+#define TX_DESC_POS_OFFSET         4
+#define TX_DESC_SIZE_OFFSET        6
+#define TX_DESC_FLAGS_OFFSET       8
+#define TX_DESC_STATUS_OFFSET      9
+#define TX_DESC_RETRY_OFFSET       10
+#define TX_DESC_RATE_OFFSET        11
+#define TX_DESC_PACKET_TYPE_OFFSET 17
+#define TX_DESC_HOST_LENGTH_OFFSET 18
+
+
+
+///////////////////////////////////////////////////////
+// Host-MAC interface
+///////////////////////////////////////////////////////
+
+#define TX_STATUS_SUCCESS       0x00
+
+#define TX_FIRM_OWN             0x80
+#define TX_DONE                 0x40
+
+
+#define TX_ERROR                0x01
+
+#define TX_PACKET_TYPE_DATA     0x01
+#define TX_PACKET_TYPE_MGMT     0x02
+
+#define ISR_EMPTY               0x00        // no bits set in ISR
+#define ISR_TxCOMPLETE          0x01        // packet transmitted
+#define ISR_RxCOMPLETE          0x02        // packet received
+#define ISR_RxFRAMELOST         0x04        // Rx Frame lost
+#define ISR_FATAL_ERROR         0x08        // Fatal error
+#define ISR_COMMAND_COMPLETE    0x10        // command completed
+#define ISR_OUT_OF_RANGE        0x20        // command completed
+#define ISR_IBSS_MERGE          0x40        // (4.1.2.30): IBSS merge
+#define ISR_GENERIC_IRQ         0x80                
+
+
+#define Local_Mib_Type          0x01
+#define Mac_Address_Mib_Type    0x02
+#define Mac_Mib_Type            0x03
+#define Statistics_Mib_Type     0x04
+#define Mac_Mgmt_Mib_Type       0x05
+#define Mac_Wep_Mib_Type        0x06
+#define Phy_Mib_Type            0x07
+#define Multi_Domain_MIB        0x08
+
+#define MAC_MGMT_MIB_CUR_BSSID_POS            14
+#define MAC_MIB_FRAG_THRESHOLD_POS            8
+#define MAC_MIB_RTS_THRESHOLD_POS             10
+#define MAC_MIB_SHORT_RETRY_POS               16
+#define MAC_MIB_LONG_RETRY_POS                17
+#define MAC_MIB_SHORT_RETRY_LIMIT_POS         16
+#define MAC_MGMT_MIB_BEACON_PER_POS           0
+#define MAC_MGMT_MIB_STATION_ID_POS           6
+#define MAC_MGMT_MIB_CUR_PRIVACY_POS          11
+#define MAC_MGMT_MIB_CUR_BSSID_POS            14
+#define MAC_MGMT_MIB_PS_MODE_POS              53
+#define MAC_MGMT_MIB_LISTEN_INTERVAL_POS      54
+#define MAC_MGMT_MIB_MULTI_DOMAIN_IMPLEMENTED 56
+#define MAC_MGMT_MIB_MULTI_DOMAIN_ENABLED     57
+#define PHY_MIB_CHANNEL_POS                   14
+#define PHY_MIB_RATE_SET_POS                  20
+#define PHY_MIB_REG_DOMAIN_POS                26
+#define LOCAL_MIB_AUTO_TX_RATE_POS            3
+#define LOCAL_MIB_SSID_SIZE                   5
+#define LOCAL_MIB_TX_PROMISCUOUS_POS          6
+#define LOCAL_MIB_TX_MGMT_RATE_POS            7
+#define LOCAL_MIB_TX_CONTROL_RATE_POS         8
+#define LOCAL_MIB_PREAMBLE_TYPE               9
+#define MAC_ADDR_MIB_MAC_ADDR_POS             0
+
+
+#define         CMD_Set_MIB_Vars              0x01
+#define         CMD_Get_MIB_Vars              0x02
+#define         CMD_Scan                      0x03
+#define         CMD_Join                      0x04
+#define         CMD_Start                     0x05
+#define         CMD_EnableRadio               0x06
+#define         CMD_DisableRadio              0x07
+#define         CMD_SiteSurvey                0x0B
+
+#define         CMD_STATUS_IDLE                   0x00
+#define         CMD_STATUS_COMPLETE               0x01
+#define         CMD_STATUS_UNKNOWN                0x02
+#define         CMD_STATUS_INVALID_PARAMETER      0x03
+#define         CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04
+#define         CMD_STATUS_TIME_OUT               0x07
+#define         CMD_STATUS_IN_PROGRESS            0x08
+#define         CMD_STATUS_REJECTED_RADIO_OFF     0x09
+#define         CMD_STATUS_HOST_ERROR             0xFF
+#define         CMD_STATUS_BUSY                   0xFE
+
+
+#define CMD_BLOCK_COMMAND_OFFSET        0
+#define CMD_BLOCK_STATUS_OFFSET         1
+#define CMD_BLOCK_PARAMETERS_OFFSET     4
+
+#define SCAN_OPTIONS_SITE_SURVEY        0x80
+
+#define MGMT_FRAME_BODY_OFFSET		24
+#define MAX_AUTHENTICATION_RETRIES	3
+#define MAX_ASSOCIATION_RETRIES 	3
+
+#define AUTHENTICATION_RESPONSE_TIME_OUT  1000
+
+#define MAX_WIRELESS_BODY  2316 /* mtu is 2312, CRC is 4 */
+#define LOOP_RETRY_LIMIT   500000
+
+#define ACTIVE_MODE 	1
+#define PS_MODE 	2
+
+///////////////////////////////////////////////////////////////////////////
+// 802.11 related definitions
+///////////////////////////////////////////////////////////////////////////
+
+//
+// Regulatory Domains
+//
+
+#define REG_DOMAIN_FCC		0x10	//Channels	1-11	USA
+#define REG_DOMAIN_DOC		0x20	//Channel	1-11	Canada
+#define REG_DOMAIN_ETSI		0x30	//Channel	1-13	Europe (ex Spain/France)
+#define REG_DOMAIN_SPAIN	0x31	//Channel	10-11	Spain
+#define REG_DOMAIN_FRANCE	0x32	//Channel	10-13	France
+#define REG_DOMAIN_MKK		0x40	//Channel	14	Japan
+#define REG_DOMAIN_MKK1		0x41	//Channel	1-14	Japan(MKK1)
+#define REG_DOMAIN_ISRAEL	0x50	//Channel	3-9	ISRAEL
+
+#define BSS_TYPE_AD_HOC 	1
+#define BSS_TYPE_INFRASTRUCTURE 2
+
+#define SCAN_TYPE_ACTIVE	0
+#define SCAN_TYPE_PASSIVE	1
+
+#define LONG_PREAMBLE		0
+#define SHORT_PREAMBLE		1
+#define AUTO_PREAMBLE		2
+
+#define DATA_FRAME_WS_HEADER_SIZE   30
+
+/* promiscuous mode control */ 
+#define PROM_MODE_OFF			0x0
+#define PROM_MODE_UNKNOWN		0x1
+#define PROM_MODE_CRC_FAILED		0x2
+#define PROM_MODE_DUPLICATED		0x4
+#define PROM_MODE_MGMT			0x8
+#define PROM_MODE_CTRL			0x10
+#define PROM_MODE_BAD_PROTOCOL		0x20
+
+
+#define IFACE_INT_STATUS_OFFSET 	0
+#define IFACE_INT_MASK_OFFSET		1
+#define IFACE_LOCKOUT_HOST_OFFSET	2
+#define IFACE_LOCKOUT_MAC_OFFSET	3
+#define IFACE_FUNC_CTRL_OFFSET		28
+#define IFACE_MAC_STAT_OFFSET		30
+#define IFACE_GENERIC_INT_TYPE_OFFSET	32
+//
+// IFACE MACROS & definitions
+//
+//
+
+// FuncCtrl field: 
+//
+#define FUNC_CTRL_TxENABLE		0x10
+#define FUNC_CTRL_RxENABLE		0x20
+#define FUNC_CTRL_INIT_COMPLETE 	0x01
+
+/* A stub firmware image which reads the MAC address from NVRAM on the card.
+   For copyright information and source see the end of this file. */
+static u8 mac_reader[] = {
+	0x06,0x00,0x00,0xea,0x04,0x00,0x00,0xea,0x03,0x00,0x00,0xea,0x02,0x00,0x00,0xea,
+	0x01,0x00,0x00,0xea,0x00,0x00,0x00,0xea,0xff,0xff,0xff,0xea,0xfe,0xff,0xff,0xea,
+	0xd3,0x00,0xa0,0xe3,0x00,0xf0,0x21,0xe1,0x0e,0x04,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
+	0x81,0x11,0xa0,0xe1,0x00,0x10,0x81,0xe3,0x00,0x10,0x80,0xe5,0x1c,0x10,0x90,0xe5,
+	0x10,0x10,0xc1,0xe3,0x1c,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,0x08,0x10,0x80,0xe5,
+	0x02,0x03,0xa0,0xe3,0x00,0x10,0xa0,0xe3,0xb0,0x10,0xc0,0xe1,0xb4,0x10,0xc0,0xe1,
+	0xb8,0x10,0xc0,0xe1,0xbc,0x10,0xc0,0xe1,0x56,0xdc,0xa0,0xe3,0x21,0x00,0x00,0xeb,
+	0x0a,0x00,0xa0,0xe3,0x1a,0x00,0x00,0xeb,0x10,0x00,0x00,0xeb,0x07,0x00,0x00,0xeb,
+	0x02,0x03,0xa0,0xe3,0x02,0x14,0xa0,0xe3,0xb4,0x10,0xc0,0xe1,0x4c,0x10,0x9f,0xe5,
+	0xbc,0x10,0xc0,0xe1,0x10,0x10,0xa0,0xe3,0xb8,0x10,0xc0,0xe1,0xfe,0xff,0xff,0xea,
+	0x00,0x40,0x2d,0xe9,0x00,0x20,0xa0,0xe3,0x02,0x3c,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
+	0x28,0x00,0x9f,0xe5,0x37,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
+	0x00,0x40,0x2d,0xe9,0x12,0x2e,0xa0,0xe3,0x06,0x30,0xa0,0xe3,0x00,0x10,0xa0,0xe3,
+	0x02,0x04,0xa0,0xe3,0x2f,0x00,0x00,0xeb,0x00,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,
+	0x00,0x02,0x00,0x02,0x80,0x01,0x90,0xe0,0x01,0x00,0x00,0x0a,0x01,0x00,0x50,0xe2,
+	0xfc,0xff,0xff,0xea,0x1e,0xff,0x2f,0xe1,0x80,0x10,0xa0,0xe3,0xf3,0x06,0xa0,0xe3,
+	0x00,0x10,0x80,0xe5,0x00,0x10,0xa0,0xe3,0x00,0x10,0x80,0xe5,0x01,0x10,0xa0,0xe3,
+	0x04,0x10,0x80,0xe5,0x00,0x10,0x80,0xe5,0x0e,0x34,0xa0,0xe3,0x1c,0x10,0x93,0xe5,
+	0x02,0x1a,0x81,0xe3,0x1c,0x10,0x83,0xe5,0x58,0x11,0x9f,0xe5,0x30,0x10,0x80,0xe5,
+	0x54,0x11,0x9f,0xe5,0x34,0x10,0x80,0xe5,0x38,0x10,0x80,0xe5,0x3c,0x10,0x80,0xe5,
+	0x10,0x10,0x90,0xe5,0x08,0x00,0x90,0xe5,0x1e,0xff,0x2f,0xe1,0xf3,0x16,0xa0,0xe3,
+	0x08,0x00,0x91,0xe5,0x05,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,0x10,0x00,0x91,0xe5,
+	0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0xff,0x00,0xa0,0xe3,0x0c,0x00,0x81,0xe5,
+	0x10,0x00,0x91,0xe5,0x02,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
+	0x10,0x00,0x91,0xe5,0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x91,0xe5,
+	0xff,0x00,0x00,0xe2,0x1e,0xff,0x2f,0xe1,0x30,0x40,0x2d,0xe9,0x00,0x50,0xa0,0xe1,
+	0x03,0x40,0xa0,0xe1,0xa2,0x02,0xa0,0xe1,0x08,0x00,0x00,0xe2,0x03,0x00,0x80,0xe2,
+	0xd8,0x10,0x9f,0xe5,0x00,0x00,0xc1,0xe5,0x01,0x20,0xc1,0xe5,0xe2,0xff,0xff,0xeb,
+	0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x1a,0x14,0x00,0xa0,0xe3,0xc4,0xff,0xff,0xeb,
+	0x04,0x20,0xa0,0xe1,0x05,0x10,0xa0,0xe1,0x02,0x00,0xa0,0xe3,0x01,0x00,0x00,0xeb,
+	0x30,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x70,0x40,0x2d,0xe9,0xf3,0x46,0xa0,0xe3,
+	0x00,0x30,0xa0,0xe3,0x00,0x00,0x50,0xe3,0x08,0x00,0x00,0x9a,0x8c,0x50,0x9f,0xe5,
+	0x03,0x60,0xd5,0xe7,0x0c,0x60,0x84,0xe5,0x10,0x60,0x94,0xe5,0x02,0x00,0x16,0xe3,
+	0xfc,0xff,0xff,0x0a,0x01,0x30,0x83,0xe2,0x00,0x00,0x53,0xe1,0xf7,0xff,0xff,0x3a,
+	0xff,0x30,0xa0,0xe3,0x0c,0x30,0x84,0xe5,0x08,0x00,0x94,0xe5,0x10,0x00,0x94,0xe5,
+	0x01,0x00,0x10,0xe3,0xfc,0xff,0xff,0x0a,0x08,0x00,0x94,0xe5,0x00,0x00,0xa0,0xe3,
+	0x00,0x00,0x52,0xe3,0x0b,0x00,0x00,0x9a,0x10,0x50,0x94,0xe5,0x02,0x00,0x15,0xe3,
+	0xfc,0xff,0xff,0x0a,0x0c,0x30,0x84,0xe5,0x10,0x50,0x94,0xe5,0x01,0x00,0x15,0xe3,
+	0xfc,0xff,0xff,0x0a,0x08,0x50,0x94,0xe5,0x01,0x50,0xc1,0xe4,0x01,0x00,0x80,0xe2,
+	0x02,0x00,0x50,0xe1,0xf3,0xff,0xff,0x3a,0xc8,0x00,0xa0,0xe3,0x98,0xff,0xff,0xeb,
+	0x70,0x40,0xbd,0xe8,0x1e,0xff,0x2f,0xe1,0x01,0x0c,0x00,0x02,0x01,0x02,0x00,0x02,
+	0x00,0x01,0x00,0x02
+};
+
+struct atmel_private {
+	void *card; /* Bus dependent stucture varies for PCcard */
+	int (*present_callback)(void *); /* And callback which uses it */
+	char firmware_id[32];
+	unsigned char *firmware;
+	int firmware_length;
+	struct timer_list management_timer;
+	struct net_device *dev;
+	struct device *sys_dev;
+	struct iw_statistics wstats;
+	struct net_device_stats	stats;	// device stats
+	spinlock_t irqlock, timerlock;	// spinlocks
+	enum { BUS_TYPE_PCCARD, BUS_TYPE_PCI } bus_type;
+	enum { 
+		CARD_TYPE_PARALLEL_FLASH, 
+		CARD_TYPE_SPI_FLASH,
+		CARD_TYPE_EEPROM 
+	} card_type;
+	int is3com; /* is this a 3com card? they are uniquely borken */
+	int do_rx_crc; /* If we need to CRC incoming packets */
+	int probe_crc; /* set if we don't yet know */
+	int crc_ok_cnt, crc_ko_cnt; /* counters for probing */
+	u16 rx_desc_head;
+	u16 tx_desc_free, tx_desc_head, tx_desc_tail, tx_desc_previous;
+	u16 tx_free_mem, tx_buff_head, tx_buff_tail;
+	
+	u16 frag_seq, frag_len, frag_no;
+	u8 frag_source[6]; 
+	
+	int wep_key_len[4]; /* need to know these and not stored in Mib. */
+	struct { /* NB this is matched to the hardware, don't change. */
+		u8 wep_is_on;                 
+		u8 default_key; /* 0..3 */
+		u8 reserved;
+		u8 exclude_unencrypted;
+		
+		u32 WEPICV_error_count;
+		u32 WEP_excluded_count;
+		
+		u8 wep_keys[4][13];
+		u8 encryption_level; /* 0, 1, 2 */
+		u8 reserved2[3];
+	} wep;
+
+	u16 host_info_base;
+	struct host_info_struct { 
+		/* NB this is matched to the hardware, don't change. */
+		u8 volatile int_status;
+		u8 volatile int_mask;
+		u8 volatile lockout_host;
+		u8 volatile lockout_mac;
+
+		u16 tx_buff_pos;
+		u16 tx_buff_size;
+		u16 tx_desc_pos;
+		u16 tx_desc_count;
+
+		u16 rx_buff_pos;
+		u16 rx_buff_size;
+		u16 rx_desc_pos;
+		u16 rx_desc_count;
+		
+		u16 build_version;
+		u16 command_pos; 	
+		
+		u16 major_version;
+		u16 minor_version;
+		
+		u16 func_ctrl;
+		u16 mac_status;
+		u16 generic_IRQ_type;
+		u8  reserved[2];
+	} host_info;
+
+	enum { 
+		STATION_STATE_INITIALIZING,
+		STATION_STATE_SCANNING,
+		STATION_STATE_JOINNING,
+		STATION_STATE_AUTHENTICATING,
+		STATION_STATE_ASSOCIATING,
+		STATION_STATE_READY,
+		STATION_STATE_REASSOCIATING,
+		STATION_STATE_FORCED_JOINNING,
+		STATION_STATE_FORCED_JOIN_FAILURE,
+		STATION_STATE_DOWN,
+		STATION_STATE_NO_CARD,
+		STATION_STATE_MGMT_ERROR 
+	} station_state;
+	
+	int operating_mode, power_mode;
+	time_t last_qual;
+	int beacons_this_sec;
+	u64 last_beacon_timestamp;
+	int channel;
+	int reg_domain;
+	int tx_rate;
+	int auto_tx_rate;;
+	int rts_threshold;
+	int frag_threshold;
+	int long_retry, short_retry;
+	int preamble;
+	int default_beacon_period, beacon_period, listen_interval;
+	int CurrentAuthentTransactionSeqNum, ExpectedAuthentTransactionSeqNum;	
+	int AuthenticationRequestRetryCnt, AssociationRequestRetryCnt, ReAssociationRequestRetryCnt;
+	enum {
+		SITE_SURVEY_IDLE,
+		SITE_SURVEY_IN_PROGRESS,
+		SITE_SURVEY_COMPLETED 
+	} site_survey_state;
+	time_t last_survey;
+
+	int station_was_associated, station_is_associated;
+	int fast_scan;
+				
+	struct bss_info {
+		int channel;
+		int SSIDsize;
+		int RSSI;
+		int UsingWEP;
+		int preamble;
+		int beacon_period;
+		int BSStype;
+		u8 BSSID[6];
+		u8 SSID[MAX_SSID_LENGTH];
+	} BSSinfo[MAX_BSS_ENTRIES];
+	int BSS_list_entries, current_BSS;
+	int connect_to_any_BSS; 
+	int SSID_size, new_SSID_size;
+	u8 CurrentBSSID[6], BSSID[6];
+	u8 SSID[MAX_SSID_LENGTH], new_SSID[MAX_SSID_LENGTH];
+	u8 rx_buf[MAX_WIRELESS_BODY];
+	
+};
+
+static u8 atmel_basic_rates[4] = {0x82,0x84,0x0b,0x16};
+
+static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *src, u16 len);
+static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len);
+static void atmel_set_gcr(struct net_device *dev, u16 mask);
+static void atmel_clear_gcr(struct net_device *dev, u16 mask);
+static int atmel_lock_mac(struct atmel_private *priv);
+static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
+static void atmel_command_irq(struct atmel_private *priv);
+static int atmel_validate_channel(struct atmel_private *priv, int channel);
+static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, 
+				   u16 frame_len, u8 rssi);
+static void atmel_management_timer(u_long a);
+static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
+static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
+static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header,
+					    u8 *body, int body_len);
+
+static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
+static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data);
+static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 data);
+static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len);
+static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len);
+static void atmel_scan(struct atmel_private *priv, int specific_ssid);
+static void atmel_join_bss(struct atmel_private *priv, int bss_index);
+static void atmel_smooth_qual(struct atmel_private *priv);
+static void atmel_writeAR(struct net_device *dev, u16 data);
+static int probe_atmel_card(struct net_device *dev);
+int reset_atmel_card(struct net_device *dev );
+static void atmel_enter_state(struct atmel_private *priv, int new_state);
+
+static inline u16 atmel_hi(struct atmel_private *priv, u16 offset)
+{
+	return priv->host_info_base + offset;
+}
+
+static inline u16 atmel_co(struct atmel_private *priv, u16 offset)
+{
+	return priv->host_info.command_pos + offset;
+}
+
+static inline u16 atmel_rx(struct atmel_private *priv, u16 offset, u16  desc)
+{
+	return priv->host_info.rx_desc_pos + (sizeof(struct rx_desc) * desc) + offset;
+}
+
+static inline u16 atmel_tx(struct atmel_private *priv, u16 offset, u16  desc)
+{
+	return priv->host_info.tx_desc_pos + (sizeof(struct tx_desc) * desc) + offset;
+}
+
+static inline u8 atmel_read8(struct net_device *dev, u16 offset)
+{
+	return inb(dev->base_addr + offset);
+}
+
+static inline void atmel_write8(struct net_device *dev, u16 offset, u8 data)
+{
+	outb(data, dev->base_addr + offset);
+}
+
+static inline u16 atmel_read16(struct net_device *dev, u16 offset)
+{
+	return inw(dev->base_addr + offset);
+}
+
+static inline void atmel_write16(struct net_device *dev, u16 offset, u16 data)
+{
+	outw(data, dev->base_addr + offset);
+}
+
+
+static inline u8 atmel_rmem8(struct atmel_private *priv, u16 pos)
+{
+	atmel_writeAR(priv->dev, pos);	
+	return atmel_read8(priv->dev, DR);
+}
+
+static inline void atmel_wmem8(struct atmel_private *priv, u16 pos, u16 data)
+{
+	atmel_writeAR(priv->dev, pos);	
+	atmel_write8(priv->dev, DR, data);
+}
+
+static inline u16 atmel_rmem16(struct atmel_private *priv, u16 pos)
+{
+       	atmel_writeAR(priv->dev, pos);	
+	return atmel_read16(priv->dev, DR);
+}
+
+static inline void atmel_wmem16(struct atmel_private *priv, u16 pos, u16 data)
+{
+       	atmel_writeAR(priv->dev, pos);	
+	atmel_write16(priv->dev, DR, data);
+}
+
+static const struct iw_handler_def atmel_handler_def;
+
+static void tx_done_irq(struct atmel_private *priv)
+{
+	int i;
+
+	for (i = 0; 
+	     atmel_rmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head)) == TX_DONE &&
+		     i < priv->host_info.tx_desc_count;
+	     i++) {
+		
+		u8 status = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_STATUS_OFFSET, priv->tx_desc_head));
+		u16 msdu_size = atmel_rmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_head));
+		u8 type = atmel_rmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_head));
+
+		atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_head), 0);
+
+		priv->tx_free_mem += msdu_size;
+		priv->tx_desc_free++;
+
+		if (priv->tx_buff_head + msdu_size > (priv->host_info.tx_buff_pos + priv->host_info.tx_buff_size))
+			priv->tx_buff_head = 0;
+		else
+			priv->tx_buff_head += msdu_size;
+			
+		if (priv->tx_desc_head < (priv->host_info.tx_desc_count - 1))
+			priv->tx_desc_head++ ;					
+		else
+			priv->tx_desc_head = 0;
+		
+		if (type == TX_PACKET_TYPE_DATA) {
+			if (status == TX_STATUS_SUCCESS)
+				priv->stats.tx_packets++;
+			else 
+				priv->stats.tx_errors++;
+			netif_wake_queue(priv->dev);
+		}
+	}
+}
+
+static u16 find_tx_buff(struct atmel_private *priv, u16 len)
+{
+	u16 bottom_free = priv->host_info.tx_buff_size - priv->tx_buff_tail;
+
+	if (priv->tx_desc_free == 3 || priv->tx_free_mem < len) 
+		return 0;
+	
+	if (bottom_free >= len)
+		return priv->host_info.tx_buff_pos + priv->tx_buff_tail;
+	
+	if (priv->tx_free_mem - bottom_free >= len) {
+		priv->tx_buff_tail = 0;
+		return priv->host_info.tx_buff_pos;
+	}
+	
+	return 0;
+}
+
+static void tx_update_descriptor(struct atmel_private *priv, u16 len, u16 buff, u8 type)
+{
+	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, priv->tx_desc_tail), buff);
+	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, priv->tx_desc_tail), len);
+	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_HOST_LENGTH_OFFSET, priv->tx_desc_tail), len);
+	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_PACKET_TYPE_OFFSET, priv->tx_desc_tail), type);
+	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RATE_OFFSET, priv->tx_desc_tail), priv->tx_rate);
+	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_RETRY_OFFSET, priv->tx_desc_tail), 0);
+	atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_tail), 0x80000000L);
+	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, priv->tx_desc_tail), TX_FIRM_OWN);
+	if (priv->tx_desc_previous != priv->tx_desc_tail)
+		atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, priv->tx_desc_previous), 0);
+	priv->tx_desc_previous = priv->tx_desc_tail;
+	if (priv->tx_desc_tail < (priv->host_info.tx_desc_count -1 ))
+		priv->tx_desc_tail++;
+	else
+		priv->tx_desc_tail = 0;
+	priv->tx_desc_free--;
+	priv->tx_free_mem -= len;
+
+}
+
+static int start_tx (struct sk_buff *skb, struct net_device *dev)
+{
+	struct atmel_private *priv = (struct atmel_private *)dev->priv;
+	struct ieee802_11_hdr header;
+	unsigned long flags;
+	u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
+	
+	if(priv->station_state != STATION_STATE_READY) {
+		priv->stats.tx_errors++;
+		return 0;
+	}
+	
+	if (priv->card && priv->present_callback && 
+	    !(*priv->present_callback)(priv->card)) {
+		priv->stats.tx_errors++;
+		return 0;
+	}
+	
+	/* first ensure the timer func cannot run */
+	spin_lock_bh(&priv->timerlock); 
+	/* then stop the hardware ISR */
+	spin_lock_irqsave(&priv->irqlock, flags); 
+	/* nb doing the above in the opposite order will deadlock */
+	
+	/* The Wireless Header is 30 bytes. In the Ethernet packet we "cut" the
+	   12 first bytes (containing DA/SA) and put them in the appropriate fields of
+	   the Wireless Header. Thus the packet length is then the initial + 18 (+30-12) */
+	
+	if (!(buff = find_tx_buff(priv, len + 18))) {
+		priv->stats.tx_dropped++;
+		spin_unlock_irqrestore(&priv->irqlock, flags);
+		spin_unlock_bh(&priv->timerlock);
+		netif_stop_queue(dev);
+		return 1;
+	}
+	
+	frame_ctl = IEEE802_11_FTYPE_DATA;
+	header.duration_id = 0;
+	header.seq_ctl = 0;
+	if (priv->wep.wep_is_on)
+		frame_ctl |= IEEE802_11_FCTL_WEP;
+	if (priv->operating_mode == IW_MODE_ADHOC) {
+		memcpy(&header.addr1, skb->data, 6);
+		memcpy(&header.addr2, dev->dev_addr, 6);
+		memcpy(&header.addr3, priv->BSSID, 6);
+	} else {
+		frame_ctl |= IEEE802_11_FCTL_TODS;
+		memcpy(&header.addr1, priv->CurrentBSSID, 6);
+		memcpy(&header.addr2, dev->dev_addr, 6);
+		memcpy(&header.addr3, skb->data, 6);
+	}
+	
+	header.frame_ctl = cpu_to_le16(frame_ctl);
+	/* Copy the wireless header into the card */
+	atmel_copy_to_card(dev, buff, (unsigned char *)&header, DATA_FRAME_WS_HEADER_SIZE);
+	/* Copy the packet sans its 802.3 header addresses which have been replaced */
+	atmel_copy_to_card(dev, buff + DATA_FRAME_WS_HEADER_SIZE, skb->data + 12, len - 12);
+	priv->tx_buff_tail += len - 12 + DATA_FRAME_WS_HEADER_SIZE;
+	
+	tx_update_descriptor(priv, len + 18, buff, TX_PACKET_TYPE_DATA);
+	dev->trans_start = jiffies;
+	priv->stats.tx_bytes += len;
+	
+	spin_unlock_irqrestore(&priv->irqlock, flags);
+	spin_unlock_bh(&priv->timerlock);
+	dev_kfree_skb(skb);
+	
+	return 0;	
+}
+
+static void atmel_transmit_management_frame(struct atmel_private *priv, 
+				     struct ieee802_11_hdr *header,
+				     u8 *body, int body_len)
+{
+	u16 buff;
+	int len =  MGMT_FRAME_BODY_OFFSET + body_len;
+	
+	if (!(buff = find_tx_buff(priv, len))) 
+		return;
+
+	atmel_copy_to_card(priv->dev, buff, (u8 *)header, MGMT_FRAME_BODY_OFFSET);
+	atmel_copy_to_card(priv->dev, buff + MGMT_FRAME_BODY_OFFSET, body, body_len);
+	priv->tx_buff_tail += len;
+	tx_update_descriptor(priv, len, buff, TX_PACKET_TYPE_MGMT);
+}
+	
+static void fast_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *header, 
+			 u16 msdu_size, u16 rx_packet_loc, u32 crc)
+{
+	/* fast path: unfragmented packet copy directly into skbuf */
+	u8 mac4[6]; 
+	struct sk_buff 	*skb;
+	unsigned char *skbp;
+	
+	/* get the final, mac 4 header field, this tells us encapsulation */
+	atmel_copy_to_host(priv->dev, mac4, rx_packet_loc + 24, 6);
+	msdu_size -= 6;
+	
+	if (priv->do_rx_crc) {
+		crc = crc32_le(crc, mac4, 6);
+		msdu_size -= 4;
+	}
+	
+	if (!(skb = dev_alloc_skb(msdu_size + 14))) {
+		priv->stats.rx_dropped++;
+		return;
+	}
+
+	skb_reserve(skb, 2);
+	skbp = skb_put(skb, msdu_size + 12);
+	atmel_copy_to_host(priv->dev, skbp + 12, rx_packet_loc + 30, msdu_size);
+	
+	if (priv->do_rx_crc) {
+		u32 netcrc;
+		crc = crc32_le(crc, skbp + 12, msdu_size);
+		atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + 30 + msdu_size, 4);
+		if ((crc ^ 0xffffffff) != netcrc) {
+			priv->stats.rx_crc_errors++;
+			dev_kfree_skb(skb);
+			return;
+		}
+	}
+	
+	memcpy(skbp, header->addr1, 6); /* destination address */
+	if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS) 
+		memcpy(&skbp[6], header->addr3, 6);
+	else
+		memcpy(&skbp[6], header->addr2, 6); /* source address */
+	
+	priv->dev->last_rx=jiffies;
+	skb->dev = priv->dev;
+	skb->protocol = eth_type_trans(skb, priv->dev);
+	skb->ip_summed = CHECKSUM_NONE;	
+	netif_rx(skb);
+	priv->stats.rx_bytes += 12 + msdu_size;
+	priv->stats.rx_packets++;
+}
+
+/* Test to see if the packet in card memory at packet_loc has a valid CRC
+   It doesn't matter that this is slow: it is only used to proble the first few packets. */
+static int probe_crc(struct atmel_private *priv, u16 packet_loc, u16 msdu_size)
+{
+	int i = msdu_size - 4;
+	u32 netcrc, crc = 0xffffffff;
+
+	if (msdu_size < 4)
+		return 0;
+
+	atmel_copy_to_host(priv->dev, (void *)&netcrc, packet_loc + i, 4);
+	
+	atmel_writeAR(priv->dev, packet_loc);
+	while (i--) {
+		u8 octet = atmel_read8(priv->dev, DR);
+		crc = crc32_le(crc, &octet, 1);
+	}
+
+	return (crc ^ 0xffffffff) == netcrc;
+}
+
+static void frag_rx_path(struct atmel_private *priv, struct ieee802_11_hdr *header, 
+			 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
+{
+	u8 mac4[6]; 
+	u8 source[6];
+	struct sk_buff *skb;
+
+	if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS) 
+		memcpy(source, header->addr3, 6);
+	else
+		memcpy(source, header->addr2, 6); 
+	
+	rx_packet_loc += 24; /* skip header */
+	
+	if (priv->do_rx_crc)
+		msdu_size -= 4;
+
+	if (frag_no == 0) { /* first fragment */
+		atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, 6);
+		msdu_size -= 6;
+		rx_packet_loc += 6;
+
+		if (priv->do_rx_crc) 
+			crc = crc32_le(crc, mac4, 6);
+	       
+		priv->frag_seq = seq_no;
+		priv->frag_no = 1;
+		priv->frag_len = msdu_size;
+		memcpy(priv->frag_source, source, 6); 
+		memcpy(&priv->rx_buf[6], source, 6);
+		memcpy(priv->rx_buf, header->addr1, 6);
+				
+		atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size);
+
+		if (priv->do_rx_crc) {
+			u32 netcrc;
+			crc = crc32_le(crc, &priv->rx_buf[12], msdu_size);
+			atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
+			if ((crc ^ 0xffffffff) != netcrc) {
+				priv->stats.rx_crc_errors++;
+				memset(priv->frag_source, 0xff, 6);
+			}
+		}
+		
+	} else if (priv->frag_no == frag_no &&
+		   priv->frag_seq == seq_no &&
+		   memcmp(priv->frag_source, source, 6) == 0) {
+		
+		atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len], 
+				   rx_packet_loc, msdu_size);
+		if (priv->do_rx_crc) {
+			u32 netcrc;
+			crc = crc32_le(crc, 
+				       &priv->rx_buf[12 + priv->frag_len], 
+				       msdu_size);
+			atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4);
+			if ((crc ^ 0xffffffff) != netcrc) {
+				priv->stats.rx_crc_errors++;
+				memset(priv->frag_source, 0xff, 6);
+				more_frags = 1; /* don't send broken assembly */
+			}
+		}
+		
+		priv->frag_len += msdu_size;
+		priv->frag_no++;
+
+		if (!more_frags) { /* last one */
+			memset(priv->frag_source, 0xff, 6);
+			if (!(skb = dev_alloc_skb(priv->frag_len + 14))) {
+				priv->stats.rx_dropped++;
+			} else {
+				skb_reserve(skb, 2);
+				memcpy(skb_put(skb, priv->frag_len + 12), 
+				       priv->rx_buf,
+				       priv->frag_len + 12);
+				priv->dev->last_rx = jiffies;
+				skb->dev = priv->dev;
+				skb->protocol = eth_type_trans(skb, priv->dev);
+				skb->ip_summed = CHECKSUM_NONE;	
+				netif_rx(skb);
+				priv->stats.rx_bytes += priv->frag_len + 12;
+				priv->stats.rx_packets++;
+			}
+		}
+		
+	} else
+		priv->wstats.discard.fragment++;
+}
+		
+static void rx_done_irq(struct atmel_private *priv)
+{
+	int i;
+	struct ieee802_11_hdr header;
+	
+	for (i = 0; 
+	     atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
+		     i < priv->host_info.rx_desc_count;
+	     i++) {
+				
+		u16 msdu_size, rx_packet_loc, frame_ctl, seq_control;
+		u8 status = atmel_rmem8(priv, atmel_rx(priv, RX_DESC_STATUS_OFFSET, priv->rx_desc_head));
+		u32 crc = 0xffffffff;
+		
+		if (status != RX_STATUS_SUCCESS) {
+			if (status == 0xc1) /* determined by experiment */
+				priv->wstats.discard.nwid++;
+			else
+				priv->stats.rx_errors++; 
+			goto next;
+		}
+
+		msdu_size = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_SIZE_OFFSET, priv->rx_desc_head));
+		rx_packet_loc = atmel_rmem16(priv, atmel_rx(priv, RX_DESC_MSDU_POS_OFFSET, priv->rx_desc_head));
+		
+		if (msdu_size < 30) {
+			priv->stats.rx_errors++; 
+			goto next;
+		}
+		
+		/* Get header as far as end of seq_ctl */
+		atmel_copy_to_host(priv->dev, (char *)&header, rx_packet_loc, 24);
+		frame_ctl = le16_to_cpu(header.frame_ctl);
+		seq_control = le16_to_cpu(header.seq_ctl);
+
+		/* probe for CRC use here if needed  once five packets have arrived with
+		   the same crc status, we assume we know what's happening and stop probing */
+		if (priv->probe_crc) {
+			if (!priv->wep.wep_is_on || !(frame_ctl & IEEE802_11_FCTL_WEP)) {
+				priv->do_rx_crc = probe_crc(priv, rx_packet_loc, msdu_size);
+			} else {
+				priv->do_rx_crc = probe_crc(priv, rx_packet_loc + 24, msdu_size - 24);
+			}
+			if (priv->do_rx_crc) {
+				if (priv->crc_ok_cnt++ > 5)
+					priv->probe_crc = 0;
+			} else {
+				if (priv->crc_ko_cnt++ > 5)
+					priv->probe_crc = 0;
+			}
+		}
+		    
+		/* don't CRC header when WEP in use */
+		if (priv->do_rx_crc && (!priv->wep.wep_is_on || !(frame_ctl & IEEE802_11_FCTL_WEP))) {
+			crc = crc32_le(0xffffffff, (unsigned char *)&header, 24);
+		}
+		msdu_size -= 24; /* header */
+
+		if ((frame_ctl & IEEE802_11_FCTL_FTYPE) == IEEE802_11_FTYPE_DATA) { 
+			
+			int more_fragments = frame_ctl & IEEE802_11_FCTL_MOREFRAGS;
+			u8 packet_fragment_no = seq_control & IEEE802_11_SCTL_FRAG;
+			u16 packet_sequence_no = (seq_control & IEEE802_11_SCTL_SEQ) >> 4;
+			
+			if (!more_fragments && packet_fragment_no == 0 ) {
+				fast_rx_path(priv, &header, msdu_size, rx_packet_loc, crc);
+			} else {
+				frag_rx_path(priv, &header, msdu_size, rx_packet_loc, crc,
+					     packet_sequence_no, packet_fragment_no, more_fragments);
+			}
+		}
+		
+		if ((frame_ctl & IEEE802_11_FCTL_FTYPE) == IEEE802_11_FTYPE_MGMT) {
+			/* copy rest of packet into buffer */
+			atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size);
+			
+			/* we use the same buffer for frag reassembly and control packets */
+			memset(priv->frag_source, 0xff, 6);
+			
+			if (priv->do_rx_crc) {
+				/* last 4 octets is crc */
+				msdu_size -= 4;
+				crc = crc32_le(crc, (unsigned char *)&priv->rx_buf, msdu_size);
+				if ((crc ^ 0xffffffff) != (*((u32 *)&priv->rx_buf[msdu_size]))) {
+					priv->stats.rx_crc_errors++;
+					goto next;
+				}
+			}
+
+			atmel_management_frame(priv, &header, msdu_size,
+					       atmel_rmem8(priv, atmel_rx(priv, RX_DESC_RSSI_OFFSET, priv->rx_desc_head)));
+		} 
+
+	next:
+		/* release descriptor */
+		atmel_wmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head), RX_DESC_FLAG_CONSUMED);  
+		
+		if (priv->rx_desc_head < (priv->host_info.rx_desc_count - 1))
+			priv->rx_desc_head++;					
+		else
+			priv->rx_desc_head = 0;
+	}
+}	
+
+static void reset_irq_status(struct atmel_private *priv, u8 mask)
+{
+	u8 isr;
+	
+	atmel_lock_mac(priv);
+	isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
+	isr ^= mask;
+	atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET), isr);
+	atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
+}
+
+static irqreturn_t service_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct atmel_private *priv = (struct atmel_private *) dev->priv;
+	u8 isr;
+	
+	if (priv->card && priv->present_callback && 
+	    !(*priv->present_callback)(priv->card))
+		return IRQ_HANDLED;
+     	
+	atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
+	
+	while (1) {
+		if (!atmel_lock_mac(priv)) {
+			printk(KERN_ALERT "%s: MAC gone away in ISR.\n", dev->name);
+			/* bad things - don't re-enable interrupts */
+			return IRQ_HANDLED;
+		}
+			
+		isr = atmel_rmem8(priv, atmel_hi(priv, IFACE_INT_STATUS_OFFSET));
+		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
+		if (isr)
+			atmel_set_gcr(dev, GCR_ACKINT); /* acknowledge interrupt */
+		else
+			break; /* no pending irqs */
+
+		if (isr & ISR_OUT_OF_RANGE) {
+			reset_irq_status(priv, ISR_OUT_OF_RANGE);
+			if(priv->operating_mode == IW_MODE_INFRA && 
+			   priv->station_state == STATION_STATE_READY) {
+				priv->station_is_associated = 0;
+				atmel_scan(priv, 1);
+			}
+		} else if (isr & ISR_RxCOMPLETE) {
+			reset_irq_status(priv, ISR_RxCOMPLETE);
+			rx_done_irq(priv); 
+		} else if (isr & ISR_TxCOMPLETE) {
+			reset_irq_status(priv, ISR_TxCOMPLETE);
+			tx_done_irq(priv); 
+		} else if (isr & ISR_RxFRAMELOST) {
+			reset_irq_status(priv, ISR_RxFRAMELOST);
+			priv->wstats.discard.misc++;
+			rx_done_irq(priv);
+		} else if (isr & ISR_FATAL_ERROR) {
+			reset_irq_status(priv, ISR_FATAL_ERROR);
+			printk(KERN_ALERT "%s: *** FATAL error interrupt ***\n", dev->name);
+			atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+		} else if (isr & ISR_COMMAND_COMPLETE) {
+			reset_irq_status(priv, ISR_COMMAND_COMPLETE);
+			atmel_command_irq(priv);	
+		} else if (isr & ISR_IBSS_MERGE) {
+			reset_irq_status(priv, ISR_IBSS_MERGE);
+			atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS, 
+				      priv->CurrentBSSID, 6);
+		} else if (isr & ISR_GENERIC_IRQ) {
+			reset_irq_status(priv, ISR_GENERIC_IRQ);
+			printk(KERN_INFO "%s: Generic_irq recieved.\n", dev->name);
+		}
+	}	
+
+	atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
+	return IRQ_HANDLED;
+}
+
+
+static struct net_device_stats *atmel_get_stats (struct net_device *dev)
+{
+	struct atmel_private *priv = (struct atmel_private *)dev->priv;
+	return &priv->stats;
+}
+
+static struct iw_statistics *atmel_get_wireless_stats (struct net_device *dev)
+{
+	struct atmel_private *priv = (struct atmel_private *)dev->priv;
+
+	/* update the link quality here in case we are seeing no beacons 
+	   at all to drive the process */
+	atmel_smooth_qual(priv);
+	
+	priv->wstats.status = priv->station_state;
+
+	if (priv->operating_mode == IW_MODE_INFRA) {
+		if (priv->station_state != STATION_STATE_READY) {
+			priv->wstats.qual.qual = 0;
+			priv->wstats.qual.level	= 0;
+		}
+		priv->wstats.qual.noise = 0;
+		priv->wstats.qual.updated = 7;
+	} else {
+		// Quality levels cannot be determined in ad-hoc mode,
+		// because we can 'hear' more that one remote station.
+		priv->wstats.qual.qual = 0;
+		priv->wstats.qual.level	= 0;
+		priv->wstats.qual.noise	= 0;
+		priv->wstats.qual.updated = 0;
+		priv->wstats.miss.beacon = 0;
+	}
+	
+	return (&priv->wstats);
+}
+
+static int atmel_change_mtu(struct net_device *dev, int new_mtu)
+{
+        if ((new_mtu < 68) || (new_mtu > 2312))
+                return -EINVAL;
+        dev->mtu = new_mtu;
+        return 0;
+}
+
+static int atmel_set_mac_address(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+        
+        memcpy (dev->dev_addr, addr->sa_data, dev->addr_len);
+	reset_atmel_card(dev);
+	return 0;
+}
+
+static int atmel_open (struct net_device *dev)
+{
+	struct atmel_private *priv = (struct atmel_private *) dev->priv;
+	priv->station_state = STATION_STATE_INITIALIZING;
+	if (!reset_atmel_card(dev)) {
+		priv->station_state = STATION_STATE_DOWN;
+		return -EAGAIN;
+	}
+	return 0;
+}
+
+static int atmel_close (struct net_device *dev)
+{
+	struct atmel_private *priv = (struct atmel_private *) dev->priv;
+		
+	if (netif_running(dev))
+		netif_stop_queue(dev);
+	
+	priv->station_state = STATION_STATE_DOWN;
+	if (priv->bus_type == BUS_TYPE_PCCARD) 
+		atmel_write16(dev, GCR, 0x0060);
+	atmel_write16(dev, GCR, 0x0040);
+	return 0;
+}
+
+static int atmel_proc_output (char *buf, struct atmel_private *priv)
+{
+	char *p = buf;
+	char *s, *r, *c;
+	
+	p += sprintf(p, "Driver version:\t\t%d.%d\n", DRIVER_MAJOR, DRIVER_MINOR);
+	
+	if (priv->station_state != STATION_STATE_DOWN) {
+		p += sprintf(p, "Firmware version:\t%d.%d build %d ", 
+			     priv->host_info.major_version,
+			     priv->host_info.minor_version,
+			     priv->host_info.build_version);
+		
+		if (priv->card_type != CARD_TYPE_EEPROM) 
+			p += sprintf(p, "[built-in]\n");
+		else if (priv->firmware) 
+			p += sprintf(p, "[%s loaded by host]\n", priv->firmware_id);
+		else
+			p += sprintf(p, "[%s loaded by hotplug]\n", priv->firmware_id);
+		
+		switch(priv->card_type) {
+		case CARD_TYPE_PARALLEL_FLASH: c = "Parallel flash"; break;
+		case CARD_TYPE_SPI_FLASH: c = "SPI flash\n"; break;
+		case CARD_TYPE_EEPROM: c = "EEPROM"; break;
+		default: c = "<unknown>";
+		}
+
+		switch (priv->reg_domain) {
+		case REG_DOMAIN_FCC: r = "USA"; break;
+		case REG_DOMAIN_DOC: r = "Canada"; break;
+		case REG_DOMAIN_ETSI: r = "Europe"; break;
+		case REG_DOMAIN_SPAIN: r = "Spain"; break;
+		case REG_DOMAIN_FRANCE: r = "France"; break;
+		case REG_DOMAIN_MKK: r = "Japan (MKK)"; break;
+		case REG_DOMAIN_MKK1: r = "Japan (MKK1)"; break;
+		case REG_DOMAIN_ISRAEL: r = "Israel"; break;
+		default: r = "<unknown>";
+		}
+		p += sprintf(p, "MAC memory type:\t%s\n", c);
+		p += sprintf(p, "Regulatory domain:\t%s\n", r);
+		p += sprintf(p, "Host CRC checking:\t%s\n", 
+			     priv->do_rx_crc ? "On" : "Off");
+	}
+	
+	switch(priv->station_state) {
+	case STATION_STATE_INITIALIZING: s = "Initialising"; break;
+	case STATION_STATE_SCANNING: s = "Scanning"; break;
+	case STATION_STATE_JOINNING: s = "Joining"; break;
+	case STATION_STATE_AUTHENTICATING: s = "Authenticating"; break;
+	case STATION_STATE_ASSOCIATING: s = "Associating"; break;
+	case STATION_STATE_READY: s = "Ready"; break;
+	case STATION_STATE_REASSOCIATING: s = "Reassociating"; break;
+	case STATION_STATE_FORCED_JOINNING: s = "Forced joining"; break;
+	case STATION_STATE_FORCED_JOIN_FAILURE: s = "Forced join failure"; break;
+	case STATION_STATE_NO_CARD: s = "No card"; break;
+	case STATION_STATE_MGMT_ERROR: s = "Management error"; break;
+	case STATION_STATE_DOWN: s = "Down"; break;
+	default: s = "<unknown>";
+	}
+      
+	p += sprintf(p, "Current state:\t\t%s\n", s);
+	return  p - buf;
+}
+
+static int atmel_read_proc(char *page, char **start, off_t off,
+			   int count, int *eof, void *data)
+{
+        struct atmel_private *priv = (struct atmel_private *)data;
+	int len = atmel_proc_output (page, priv);
+        if (len <= off+count) *eof = 1;
+        *start = page + off;
+        len -= off;
+        if (len>count) len = count;
+        if (len<0) len = 0;
+        return len;
+}
+
+struct net_device *init_atmel_card( unsigned short irq, int port, char *firmware_id, int is3com,  
+				    struct device *sys_dev, int (*card_present)(void *), void *card)
+{
+	struct net_device *dev;
+	struct atmel_private *priv;
+	int rc;
+
+	/* Create the network device object. */
+        dev = alloc_etherdev(sizeof(*priv));
+        if (!dev) {
+		printk(KERN_ERR "atmel:  Couldn't alloc_etherdev\n");
+		return NULL;
+        }
+	if (dev_alloc_name(dev, dev->name) < 0) {
+		printk(KERN_ERR "atmel:  Couldn't get name!\n");
+		goto err_out_free;
+	}
+
+	priv = dev->priv;
+	priv->dev = dev;
+	priv->sys_dev = sys_dev;
+	priv->present_callback = card_present;
+	priv->card = card;
+	priv->firmware = NULL;
+	if (firmware) /* module parameter */
+		strcpy(priv->firmware_id, firmware);
+	else if (firmware_id) /* from PCMCIA card-matching or PCI */
+		strcpy(priv->firmware_id, firmware_id);
+	else
+		priv->firmware_id[0] = '\0';
+	priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
+	priv->station_state = STATION_STATE_DOWN;
+	priv->is3com = is3com;
+	priv->do_rx_crc = 0;
+	/* For PCMCIA cards, some chips need CRC, some don't
+	   so we have to probe. */
+	if (priv->bus_type == BUS_TYPE_PCCARD) {
+		priv->probe_crc = 1;
+		priv->crc_ok_cnt = priv->crc_ko_cnt = 0;
+	} else
+		priv->probe_crc = 0;
+	memset(&priv->stats, 0, sizeof(priv->stats));
+	memset(&priv->wstats, 0, sizeof(priv->wstats));
+	priv->last_qual = jiffies;
+	priv->last_beacon_timestamp = 0;
+	memset(priv->frag_source, 0xff, sizeof(priv->frag_source));
+	memset(priv->BSSID, 0, 6);
+	priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */
+	priv->station_was_associated = 0;
+	
+	priv->last_survey = jiffies;
+	priv->preamble = LONG_PREAMBLE;
+	priv->operating_mode = IW_MODE_INFRA;
+	priv->connect_to_any_BSS = 0;
+	priv->tx_rate = 3;
+	priv->auto_tx_rate = 1;
+	priv->channel = 4;
+	priv->power_mode = 0;
+	priv->SSID[0] = '\0';
+	priv->SSID_size = 0;
+	priv->new_SSID_size = 0;
+	priv->frag_threshold = 2346;
+	priv->rts_threshold = 2347;
+	priv->short_retry = 7;
+	priv->long_retry = 4;
+	priv->wep.wep_is_on = 0;
+	priv->wep.default_key = 0;
+	priv->wep.encryption_level = 0;
+	priv->default_beacon_period = priv->beacon_period = 100;
+	priv->listen_interval = 1;
+
+	init_timer(&priv->management_timer);
+	spin_lock_init(&priv->irqlock);
+	spin_lock_init(&priv->timerlock);
+	priv->management_timer.function = atmel_management_timer;
+	priv->management_timer.data = (unsigned long) dev;
+	
+	dev->open = atmel_open;
+	dev->stop = atmel_close;
+	dev->change_mtu = atmel_change_mtu;
+	dev->set_mac_address = atmel_set_mac_address;
+	dev->hard_start_xmit = start_tx;
+	dev->get_stats = atmel_get_stats;
+	dev->get_wireless_stats = atmel_get_wireless_stats;
+	dev->wireless_handlers = (struct iw_handler_def *)&atmel_handler_def;
+	dev->do_ioctl = atmel_ioctl;
+	dev->irq = irq;
+	dev->base_addr = port;
+	
+	if ((rc = request_irq(dev->irq, service_interrupt, SA_SHIRQ, dev->name, dev))) {
+		printk(KERN_ERR "%s: register interrupt %d failed, rc %d\n", dev->name, irq, rc );
+		goto err_out_free;
+	}
+
+	if (priv->bus_type == BUS_TYPE_PCI &&
+	    !request_region( dev->base_addr, 64, dev->name )) {
+		goto err_out_irq;
+	}
+	
+	if (register_netdev(dev))
+		goto err_out_res;
+	
+	if (!probe_atmel_card(dev))
+		goto err_out_res;
+	
+	create_proc_read_entry ("driver/atmel", 0, 0, atmel_read_proc, priv);	
+	
+	printk(KERN_INFO "%s: Atmel at76c50x wireless. Version %d.%d simon@thekelleys.org.uk\n",
+	       dev->name, DRIVER_MAJOR, DRIVER_MINOR);
+	
+	SET_MODULE_OWNER(dev);
+	return dev;
+	
+ err_out_res:
+	if (priv->bus_type == BUS_TYPE_PCI)
+	        release_region( dev->base_addr, 64 );
+ err_out_irq:
+	free_irq(dev->irq, dev);
+ err_out_free:
+	kfree(dev);
+	return NULL;
+}
+
+EXPORT_SYMBOL(init_atmel_card);
+
+void stop_atmel_card(struct net_device *dev, int freeres)
+{
+	struct atmel_private *priv = dev->priv;
+	unregister_netdev(dev);
+	
+	/* put a brick on it... */
+
+	if (priv->bus_type == BUS_TYPE_PCCARD) 
+		atmel_write16(dev, GCR, 0x0060);
+	atmel_write16(dev, GCR, 0x0040);
+
+	remove_proc_entry("driver/atmel", NULL);
+	del_timer_sync(&priv->management_timer);
+	free_irq(dev->irq, dev);
+	if (priv->firmware)
+		kfree(priv->firmware);
+	if (freeres) {
+		/* PCMCIA frees this stuff, so only for PCI */
+	        release_region(dev->base_addr, 64);
+        }
+	kfree(dev);
+}
+
+EXPORT_SYMBOL(stop_atmel_card);
+
+static const struct {
+	int reg_domain;
+	int min, max;
+} channel_table[] = { { REG_DOMAIN_FCC, 1, 11},
+		      { REG_DOMAIN_DOC, 1, 11},
+		      { REG_DOMAIN_ETSI, 1, 13},
+		      { REG_DOMAIN_SPAIN, 10, 11},
+		      { REG_DOMAIN_FRANCE, 10, 13},
+		      { REG_DOMAIN_MKK, 14, 14},
+		      { REG_DOMAIN_MKK1, 1, 14},
+		      { REG_DOMAIN_ISRAEL, 9} };
+
+
+static int atmel_validate_channel(struct atmel_private *priv, int channel)
+{
+	/* check that channel is OK, if so return zero,
+	   else return suitable default channel */
+	int i;
+
+	for (i = 0; i < sizeof(channel_table)/sizeof(channel_table[0]); i++)
+		if (priv->reg_domain == channel_table[i].reg_domain) {
+			if (channel >= channel_table[i].min &&
+			    channel <= channel_table[i].max)
+				return 0;
+			else
+				return channel_table[i].min;
+		}
+	return 1;
+}
+
+static int atmel_set_essid(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *dwrq,
+			   char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+
+	/* Check if we asked for `any' */
+	if(dwrq->flags == 0) {
+		priv->connect_to_any_BSS = 1;
+	} else {
+		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+
+		priv->connect_to_any_BSS = 0;
+		
+		/* Check the size of the string */
+		if (dwrq->length > MAX_SSID_LENGTH + 1)
+			 return -E2BIG ;
+		if (index != 0)
+			return -EINVAL;
+		
+		memcpy(priv->new_SSID, extra, dwrq->length - 1);
+		priv->new_SSID_size = dwrq->length - 1;
+	}
+
+	return -EINPROGRESS;
+}
+
+static int atmel_get_essid(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *dwrq,
+			   char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+
+	/* Get the current SSID */
+	if (priv->SSID_size == 0) {
+		memcpy(extra, priv->new_SSID, priv->new_SSID_size);
+		extra[priv->new_SSID_size] = '\0';
+		dwrq->length = priv->new_SSID_size + 1;
+	} else {
+		memcpy(extra, priv->SSID, priv->SSID_size);
+		extra[priv->SSID_size] = '\0';
+		dwrq->length = priv->SSID_size + 1;
+	}
+	
+	dwrq->flags = !priv->connect_to_any_BSS; /* active */
+
+	return 0;
+}
+
+static int atmel_get_wap(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct sockaddr *awrq,
+			 char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	memcpy(awrq->sa_data, priv->CurrentBSSID, 6);
+	awrq->sa_family = ARPHRD_ETHER;
+
+	return 0;
+}
+
+static int atmel_set_encode(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct iw_point *dwrq,
+			    char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+
+	/* Basic checking: do we have a key to set ?
+	 * Note : with the new API, it's impossible to get a NULL pointer.
+	 * Therefore, we need to check a key size == 0 instead.
+	 * New version of iwconfig properly set the IW_ENCODE_NOKEY flag
+	 * when no key is present (only change flags), but older versions
+	 * don't do it. - Jean II */
+	if (dwrq->length > 0) {
+		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+		int current_index = priv->wep.default_key;
+		/* Check the size of the key */
+		if (dwrq->length > 13) {
+			return -EINVAL;
+		}
+		/* Check the index (none -> use current) */
+		if (index < 0 || index >= 4)
+			index = current_index;
+		else
+			priv->wep.default_key = index;
+		/* Set the length */
+		if (dwrq->length > 5)
+			priv->wep_key_len[index] = 13;
+		else
+			if (dwrq->length > 0)
+				priv->wep_key_len[index] = 5;
+			else
+				/* Disable the key */
+				priv->wep_key_len[index] = 0;
+		/* Check if the key is not marked as invalid */
+		if(!(dwrq->flags & IW_ENCODE_NOKEY)) {
+			/* Cleanup */
+			memset(priv->wep.wep_keys[index], 0, 13);
+			/* Copy the key in the driver */
+			memcpy(priv->wep.wep_keys[index], extra, dwrq->length);
+		}
+		/* WE specify that if a valid key is set, encryption
+		 * should be enabled (user may turn it off later)
+		 * This is also how "iwconfig ethX key on" works */
+		if (index == current_index && 
+		    priv->wep_key_len[index] > 0) {
+			priv->wep.wep_is_on = 1;
+			priv->wep.exclude_unencrypted = 1;
+			if (priv->wep_key_len[index] > 5)
+				priv->wep.encryption_level = 2;
+			else
+				priv->wep.encryption_level = 1;
+		}
+	} else {
+		/* Do we want to just set the transmit key index ? */
+		int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+		if ( index>=0 && index < 4 ) {
+			priv->wep.default_key = index;
+		} else
+			/* Don't complain if only change the mode */
+			if(!dwrq->flags & IW_ENCODE_MODE) {
+				return -EINVAL;
+			}
+	}
+	/* Read the flags */
+	if(dwrq->flags & IW_ENCODE_DISABLED) {
+		priv->wep.wep_is_on = 0;
+		priv->wep.encryption_level = 0; 
+	} else {
+		priv->wep.wep_is_on = 1;
+		if (priv->wep_key_len[priv->wep.default_key] > 5)
+			priv->wep.encryption_level = 2;
+		else
+			priv->wep.encryption_level = 1;
+	}
+	if(dwrq->flags & IW_ENCODE_RESTRICTED)
+		priv->wep.exclude_unencrypted = 1;
+	if(dwrq->flags & IW_ENCODE_OPEN)
+		priv->wep.exclude_unencrypted = 0;
+	
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
+
+static int atmel_get_encode(struct net_device *dev,
+			    struct iw_request_info *info,
+			    struct iw_point *dwrq,
+			    char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	int index = (dwrq->flags & IW_ENCODE_INDEX) - 1;
+	
+	if (!priv->wep.wep_is_on)
+		dwrq->flags = IW_ENCODE_DISABLED;
+	else if (priv->wep.exclude_unencrypted)
+		dwrq->flags = IW_ENCODE_RESTRICTED;
+	else
+		dwrq->flags = IW_ENCODE_OPEN;
+		
+		/* Which key do we want ? -1 -> tx index */
+	if (index < 0 || index >= 4)
+		index = priv->wep.default_key;
+	dwrq->flags |= index + 1;
+	/* Copy the key to the user buffer */
+	dwrq->length = priv->wep_key_len[index];
+	if (dwrq->length > 16) {
+		dwrq->length=0;
+	} else {
+		memset(extra, 0, 16);
+		memcpy(extra, priv->wep.wep_keys[index], dwrq->length);
+	}
+	
+	return 0;
+}
+
+static int atmel_get_name(struct net_device *dev,
+			  struct iw_request_info *info,
+			  char *cwrq,
+			  char *extra)
+{
+	strcpy(cwrq, "IEEE 802.11-DS");
+	return 0;
+}
+
+static int atmel_set_rate(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *vwrq,
+			  char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	
+	if (vwrq->fixed == 0) {
+		priv->tx_rate = 3;
+		priv->auto_tx_rate = 1;
+	} else {
+		priv->auto_tx_rate = 0;
+		
+		/* Which type of value ? */
+		if((vwrq->value < 4) && (vwrq->value >= 0)) {
+			/* Setting by rate index */
+		priv->tx_rate = vwrq->value;
+		} else {
+		/* Setting by frequency value */
+			switch (vwrq->value) {
+			case (int)1e6: priv->tx_rate = 0; break;
+			case (int)2e6: priv->tx_rate = 1; break;
+			case (int)5.5e6: priv->tx_rate = 2; break;
+			case (int)11e6:  priv->tx_rate = 3; break;
+			default: return -EINVAL;
+			}
+		}
+	}
+
+	return -EINPROGRESS;
+}
+
+static int atmel_set_mode(struct net_device *dev,
+			  struct iw_request_info *info,
+			  __u32 *uwrq,
+			  char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+
+	if (*uwrq != IW_MODE_ADHOC && *uwrq != IW_MODE_INFRA)
+		return -EINVAL;
+
+	priv->operating_mode = *uwrq;
+	return -EINPROGRESS;  
+}
+
+static int atmel_get_mode(struct net_device *dev,
+			  struct iw_request_info *info,
+			  __u32 *uwrq,
+			  char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	
+	*uwrq = priv->operating_mode;
+	return 0;
+}
+
+static int atmel_get_rate(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct iw_param *vwrq,
+			 char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+
+	if (priv->auto_tx_rate) {
+		vwrq->fixed = 0;
+		vwrq->value = 11e6;
+	} else {
+		vwrq->fixed = 1;
+		switch(priv->tx_rate) {
+		case 0: vwrq->value = 1e6; break;
+		case 1: vwrq->value = 2e6; break;
+		case 2: vwrq->value = 5.5e6; break;
+		case 3: vwrq->value = 11e6; break;
+		}
+	}
+	return 0;
+}
+
+static int atmel_set_power(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_param *vwrq,
+			   char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	priv->power_mode = vwrq->disabled ? 0 : 1;
+	return -EINPROGRESS;
+}
+
+static int atmel_get_power(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_param *vwrq,
+			   char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	vwrq->disabled = priv->power_mode ? 0 : 1;
+	vwrq->flags = IW_POWER_ON;
+	return 0;
+}
+
+static int atmel_set_retry(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_param *vwrq,
+			   char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	
+	if(!vwrq->disabled && (vwrq->flags & IW_RETRY_LIMIT)) {
+		if(vwrq->flags & IW_RETRY_MAX)
+			priv->long_retry = vwrq->value;
+		else if (vwrq->flags & IW_RETRY_MIN)
+			priv->short_retry = vwrq->value;
+		else {
+			/* No modifier : set both */
+			priv->long_retry = vwrq->value;
+			priv->short_retry = vwrq->value;
+		}
+		return -EINPROGRESS;		
+	}
+	   
+	return -EINVAL;
+}
+
+static int atmel_get_retry(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_param *vwrq,
+			   char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+
+	vwrq->disabled = 0;      /* Can't be disabled */
+
+	/* Note : by default, display the min retry number */
+	if((vwrq->flags & IW_RETRY_MAX)) {
+		vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
+		vwrq->value = priv->long_retry;
+	} else {
+		vwrq->flags = IW_RETRY_LIMIT;
+		vwrq->value = priv->short_retry;
+		if(priv->long_retry != priv->short_retry)
+			vwrq->flags |= IW_RETRY_MIN;
+	}
+
+	return 0;
+}
+
+static int atmel_set_rts(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct iw_param *vwrq,
+			 char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	int rthr = vwrq->value;
+
+	if(vwrq->disabled)
+		rthr = 2347;
+	if((rthr < 0) || (rthr > 2347)) {
+		return -EINVAL;
+	}
+	priv->rts_threshold = rthr;
+	
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
+static int atmel_get_rts(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct iw_param *vwrq,
+			 char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	
+	vwrq->value = priv->rts_threshold;
+	vwrq->disabled = (vwrq->value >= 2347);
+	vwrq->fixed = 1;
+
+	return 0;
+}
+
+static int atmel_set_frag(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *vwrq,
+			  char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	int fthr = vwrq->value;
+
+	if(vwrq->disabled)
+		fthr = 2346;
+	if((fthr < 256) || (fthr > 2346)) {
+		return -EINVAL;
+	}
+	fthr &= ~0x1;	/* Get an even value - is it really needed ??? */
+	priv->frag_threshold = fthr;
+	
+	return -EINPROGRESS;		/* Call commit handler */
+}
+
+static int atmel_get_frag(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *vwrq,
+			  char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+
+	vwrq->value = priv->frag_threshold;
+	vwrq->disabled = (vwrq->value >= 2346);
+	vwrq->fixed = 1;
+
+	return 0;
+}
+
+const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+				2447, 2452, 2457, 2462, 2467, 2472, 2484 };
+
+static int atmel_set_freq(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_freq *fwrq,
+			  char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	int rc = -EINPROGRESS;		/* Call commit handler */
+	
+	/* If setting by frequency, convert to a channel */
+	if((fwrq->e == 1) &&
+	   (fwrq->m >= (int) 2.412e8) &&
+	   (fwrq->m <= (int) 2.487e8)) {
+		int f = fwrq->m / 100000;
+		int c = 0;
+		while((c < 14) && (f != frequency_list[c]))
+			c++;
+		/* Hack to fall through... */
+		fwrq->e = 0;
+		fwrq->m = c + 1;
+	}
+	/* Setting by channel number */
+	if((fwrq->m > 1000) || (fwrq->e > 0))
+		rc = -EOPNOTSUPP;
+	else {
+		int channel = fwrq->m;
+		if (atmel_validate_channel(priv, channel) == 0) {
+			priv->channel = channel;
+		} else {
+			rc = -EINVAL;
+		} 
+	}
+	return rc;
+}
+
+static int atmel_get_freq(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_freq *fwrq,
+			  char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+
+	fwrq->m = priv->channel;
+	fwrq->e = 0;
+	return 0;
+}
+
+static int atmel_set_scan(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_param *vwrq,
+			  char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+
+	/* Note : you may have realised that, as this is a SET operation,
+	 * this is privileged and therefore a normal user can't
+	 * perform scanning.
+	 * This is not an error, while the device perform scanning,
+	 * traffic doesn't flow, so it's a perfect DoS...
+	 * Jean II */
+	
+	if (priv->station_state == STATION_STATE_DOWN ||
+	    priv->station_state == STATION_STATE_NO_CARD)
+		return -EAGAIN;
+
+	/* Timeout old surveys. */
+	if ((jiffies - priv->last_survey) > (20 * HZ))
+		priv->site_survey_state = SITE_SURVEY_IDLE;
+	priv->last_survey = jiffies;
+
+	/* Initiate a scan command */
+	if (priv->site_survey_state == SITE_SURVEY_IN_PROGRESS)
+		return -EBUSY;
+	
+	priv->site_survey_state = SITE_SURVEY_IN_PROGRESS;
+	
+	atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
+	del_timer_sync(&priv->management_timer);
+	atmel_scan(priv, 0);
+	atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
+	
+	return 0;
+}
+
+static int atmel_get_scan(struct net_device *dev,
+			  struct iw_request_info *info,
+			  struct iw_point *dwrq,
+			  char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	int i;
+	char *current_ev = extra;
+	struct iw_event	iwe;
+	
+	if (priv->site_survey_state != SITE_SURVEY_COMPLETED)
+		return -EAGAIN;
+	
+	for(i=0; i<priv->BSS_list_entries; i++) { 
+		iwe.cmd = SIOCGIWAP;
+		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+		memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
+		current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN);
+
+		iwe.u.data.length =  priv->BSSinfo[i].SSIDsize;
+		if (iwe.u.data.length > 32)
+			iwe.u.data.length = 32;
+		iwe.cmd = SIOCGIWESSID;
+		iwe.u.data.flags = 1;
+		current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID);
+		
+		iwe.cmd = SIOCGIWMODE;
+		iwe.u.mode = priv->BSSinfo[i].BSStype;
+		current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN);
+	
+		iwe.cmd = SIOCGIWFREQ;
+		iwe.u.freq.m = priv->BSSinfo[i].channel;
+		iwe.u.freq.e = 0;
+		current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN);
+		
+		iwe.cmd = SIOCGIWENCODE;
+		if (priv->BSSinfo[i].UsingWEP)
+			iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+		else
+			iwe.u.data.flags = IW_ENCODE_DISABLED;
+		iwe.u.data.length = 0;
+		current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL);
+		
+	}
+
+	/* Length of data */
+	dwrq->length = (current_ev - extra);
+	dwrq->flags = 0;	/* todo */
+	
+	return 0;
+}
+
+static int atmel_get_range(struct net_device *dev,
+			   struct iw_request_info *info,
+			   struct iw_point *dwrq,
+			   char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	struct iw_range *range = (struct iw_range *) extra;
+	int k,i,j;
+
+	dwrq->length = sizeof(struct iw_range);
+	memset(range, 0, sizeof(range));
+	range->min_nwid = 0x0000;
+	range->max_nwid = 0x0000;
+	range->num_channels = 0;
+	for (j = 0; j < sizeof(channel_table)/sizeof(channel_table[0]); j++)
+		if (priv->reg_domain == channel_table[j].reg_domain) {
+			range->num_channels = channel_table[j].max - channel_table[j].min + 1; 
+		}
+	if (range->num_channels != 0) {
+		for(k = 0, i = channel_table[j].min; i <= channel_table[j].max; i++) {
+			range->freq[k].i = i + 1; /* List index */
+			range->freq[k].m = frequency_list[i] * 100000;
+			range->freq[k++].e = 1;	/* Values in table in MHz -> * 10^5 * 10 */
+		}
+		range->num_frequency = k;
+	}
+	
+	range->max_qual.qual = 100;
+	range->max_qual.level = 100;
+	range->max_qual.noise = 0;
+	range->sensitivity = 0;
+
+	range->bitrate[0] = 1e6;
+	range->bitrate[1] = 2e6;
+	range->bitrate[2] = 5.5e6;
+	range->bitrate[3] = 11e6;
+	range->num_bitrates = 4;
+
+	range->min_rts = 0;
+	range->max_rts = 2347;
+	range->min_frag = 256;
+	range->max_frag = 2346;
+
+	range->encoding_size[0] = 5;
+	range->encoding_size[1] = 13;
+	range->num_encoding_sizes = 2;
+	range->max_encoding_tokens = 4;
+	
+	range->pmp_flags = IW_POWER_ON;
+	range->pmt_flags = IW_POWER_ON;
+	range->pm_capa = 0;
+	
+	range->we_version_source = WIRELESS_EXT;
+	range->we_version_compiled = WIRELESS_EXT;
+	range->retry_capa = IW_RETRY_LIMIT ;
+	range->retry_flags = IW_RETRY_LIMIT;
+	range->r_time_flags = 0;
+	range->min_retry = 1;
+	range->max_retry = 65535;
+	range->avg_qual.qual = 50;
+	range->avg_qual.level = 50;
+	range->avg_qual.noise = 0;
+
+	return 0;
+}
+
+static int atmel_set_wap(struct net_device *dev,
+			 struct iw_request_info *info,
+			 struct sockaddr *awrq,
+			 char *extra)
+{
+	struct atmel_private *priv = dev->priv;
+	int i;
+	static const u8 bcast[] = { 255, 255, 255, 255, 255, 255 };
+	
+	if (awrq->sa_family != ARPHRD_ETHER)
+		return -EINVAL;
+	
+	if (memcmp(bcast, awrq->sa_data, 6) == 0) {
+		atmel_clear_gcr(dev, GCR_ENINT); /* disable interrupts */
+		del_timer_sync(&priv->management_timer);
+		atmel_scan(priv, 1);
+		atmel_set_gcr(dev, GCR_ENINT); /* enable interrupts */
+		return 0;
+	}
+	
+	for(i=0; i<priv->BSS_list_entries; i++) {
+		if (memcmp(priv->BSSinfo[i].BSSID, awrq->sa_data, 6) == 0) {
+			if (!priv->wep.wep_is_on && priv->BSSinfo[i].UsingWEP) {
+				return -EINVAL;
+			} else if  (priv->wep.wep_is_on && !priv->BSSinfo[i].UsingWEP) {
+				return -EINVAL;
+			} else 
+				atmel_join_bss(priv, i);  
+			return 0;
+		}
+	}
+		
+	return -EINVAL;
+}
+	
+static int atmel_config_commit(struct net_device *dev,
+			       struct iw_request_info *info,	/* NULL */
+			       void *zwrq,			/* NULL */
+			       char *extra)			/* NULL */
+{
+	reset_atmel_card(dev);
+	return 0;
+}
+
+static const iw_handler		atmel_handler[] =
+{
+	(iw_handler) atmel_config_commit,	/* SIOCSIWCOMMIT */
+	(iw_handler) atmel_get_name,    	/* SIOCGIWNAME */
+	(iw_handler) NULL,			/* SIOCSIWNWID */
+	(iw_handler) NULL,			/* SIOCGIWNWID */
+	(iw_handler) atmel_set_freq,		/* SIOCSIWFREQ */
+	(iw_handler) atmel_get_freq,		/* SIOCGIWFREQ */
+	(iw_handler) atmel_set_mode,		/* SIOCSIWMODE */
+	(iw_handler) atmel_get_mode,		/* SIOCGIWMODE */
+	(iw_handler) NULL,                  	/* SIOCSIWSENS */
+	(iw_handler) NULL,           		/* SIOCGIWSENS */
+	(iw_handler) NULL,			/* SIOCSIWRANGE */
+	(iw_handler) atmel_get_range,           /* SIOCGIWRANGE */
+	(iw_handler) NULL,			/* SIOCSIWPRIV */
+	(iw_handler) NULL,			/* SIOCGIWPRIV */
+	(iw_handler) NULL,			/* SIOCSIWSTATS */
+	(iw_handler) NULL,			/* SIOCGIWSTATS */
+	(iw_handler) NULL,			/* SIOCSIWSPY */
+	(iw_handler) NULL,			/* SIOCGIWSPY */
+	(iw_handler) NULL,			/* -- hole -- */
+	(iw_handler) NULL,			/* -- hole -- */
+	(iw_handler) atmel_set_wap,		/* SIOCSIWAP */
+	(iw_handler) atmel_get_wap,		/* SIOCGIWAP */
+	(iw_handler) NULL,			/* -- hole -- */
+	(iw_handler) NULL,       		/* SIOCGIWAPLIST */
+	(iw_handler) atmel_set_scan,		/* SIOCSIWSCAN */
+	(iw_handler) atmel_get_scan,		/* SIOCGIWSCAN */
+	(iw_handler) atmel_set_essid,		/* SIOCSIWESSID */
+	(iw_handler) atmel_get_essid,		/* SIOCGIWESSID */
+	(iw_handler) NULL,         		/* SIOCSIWNICKN */
+	(iw_handler) NULL,          		/* SIOCGIWNICKN */
+	(iw_handler) NULL,			/* -- hole -- */
+	(iw_handler) NULL,			/* -- hole -- */
+	(iw_handler) atmel_set_rate,		/* SIOCSIWRATE */
+	(iw_handler) atmel_get_rate,		/* SIOCGIWRATE */
+	(iw_handler) atmel_set_rts,		/* SIOCSIWRTS */
+	(iw_handler) atmel_get_rts,		/* SIOCGIWRTS */
+	(iw_handler) atmel_set_frag,		/* SIOCSIWFRAG */
+	(iw_handler) atmel_get_frag,		/* SIOCGIWFRAG */
+	(iw_handler) NULL,         		/* SIOCSIWTXPOW */
+	(iw_handler) NULL,          		/* SIOCGIWTXPOW */
+	(iw_handler) atmel_set_retry,		/* SIOCSIWRETRY */
+	(iw_handler) atmel_get_retry,		/* SIOCGIWRETRY */
+	(iw_handler) atmel_set_encode,		/* SIOCSIWENCODE */
+	(iw_handler) atmel_get_encode,		/* SIOCGIWENCODE */
+	(iw_handler) atmel_set_power,		/* SIOCSIWPOWER */
+	(iw_handler) atmel_get_power,		/* SIOCGIWPOWER */
+};
+
+
+static const iw_handler		atmel_private_handler[] =
+{
+	NULL,				/* SIOCIWFIRSTPRIV */
+};
+
+typedef struct atmel_priv_ioctl {
+	char id[32];
+	unsigned char *data;		
+	unsigned short len;		
+} atmel_priv_ioctl;
+
+	
+#define ATMELFWL SIOCIWFIRSTPRIV
+#define ATMELIDIFC ATMELFWL + 1
+#define ATMELMAGIC 0x51807 
+
+static const struct iw_priv_args atmel_private_args[] = {
+/*{ cmd,         set_args,                            get_args, name } */
+  { ATMELFWL, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | sizeof (atmel_priv_ioctl), IW_PRIV_TYPE_NONE, "atmelfwl" },
+  { ATMELIDIFC, IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "atmelidifc" },
+};
+
+static const struct iw_handler_def	atmel_handler_def =
+{
+	.num_standard	= sizeof(atmel_handler)/sizeof(iw_handler),
+	.num_private	= sizeof(atmel_private_handler)/sizeof(iw_handler), 
+	.num_private_args = sizeof(atmel_private_args)/sizeof(struct iw_priv_args), 
+	.standard	= (iw_handler *) atmel_handler,
+	.private	= (iw_handler *) atmel_private_handler, 
+	.private_args	= (struct iw_priv_args *) atmel_private_args
+};
+
+static int atmel_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	int rc = 0;
+	struct atmel_private *priv = (struct atmel_private *) dev->priv;
+	atmel_priv_ioctl com;
+	struct iwreq *wrq = (struct iwreq *) rq;
+	unsigned char *new_firmware;
+
+	switch (cmd) {
+	case SIOCGIWPRIV:
+		if(wrq->u.data.pointer) {
+			/* Set the number of ioctl available */
+			wrq->u.data.length = sizeof(atmel_private_args) / sizeof(atmel_private_args[0]);
+			
+			/* Copy structure to the user buffer */
+			if (copy_to_user(wrq->u.data.pointer,
+					 (u_char *) atmel_private_args,
+					 sizeof(atmel_private_args)))
+				rc = -EFAULT;
+		}
+		break;
+
+	case ATMELIDIFC:
+		wrq->u.param.value = ATMELMAGIC;		
+		break;
+	
+	case ATMELFWL:
+		if (copy_from_user(&com, rq->ifr_data, sizeof(com))) {
+			rc = -EFAULT;
+			break;
+		}
+
+		if (!capable(CAP_NET_ADMIN)) {
+			rc = -EPERM;
+			break;
+		}
+
+		if (!(new_firmware = kmalloc(com.len, GFP_KERNEL))) {
+			rc = -ENOMEM;
+			break;
+		}
+		
+		if (copy_from_user(new_firmware, com.data, com.len)) {
+			rc = -EFAULT;
+			break;
+		}
+		
+		if (priv->firmware)
+			kfree(priv->firmware);
+		
+		priv->firmware = new_firmware;
+		priv->firmware_length = com.len;
+		strncpy(priv->firmware_id, com.id, 31);
+		priv->firmware_id[31] = '\0';
+		break;
+
+	default:
+		rc = -EOPNOTSUPP;
+	}
+	
+	return rc;
+}
+
+struct auth_body {
+	u16 alg;
+	u16 trans_seq;
+	u16 status;
+	u8 el_id;
+	u8 chall_text_len;
+	u8 chall_text[253];
+}; 
+
+static void atmel_enter_state(struct atmel_private *priv, int new_state)
+{
+	int old_state = priv->station_state;
+
+	if (new_state == old_state)
+		return;
+
+	if (new_state == STATION_STATE_READY)
+		netif_start_queue(priv->dev);
+
+	if (old_state == STATION_STATE_READY) {
+		netif_stop_queue(priv->dev);
+		priv->last_beacon_timestamp = 0;
+	}
+
+	priv->station_state = new_state;
+
+}
+
+static void atmel_scan(struct atmel_private *priv, int specific_ssid)
+{
+	struct {
+		u8 BSSID[6];
+		u8 SSID[MAX_SSID_LENGTH];
+		u8 scan_type;
+		u8 channel;
+		u16 BSS_type;
+		u16 min_channel_time;
+		u16 max_channel_time;
+		u8 options;
+		u8 SSID_size;
+	} cmd;
+	
+	atmel_enter_state(priv, STATION_STATE_SCANNING);
+	
+	memset(cmd.BSSID, 0xff, 6);
+
+	if (priv->fast_scan) {
+		cmd.SSID_size = priv->SSID_size;
+		memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
+		cmd.min_channel_time = cpu_to_le16(10);
+		cmd.max_channel_time = cpu_to_le16(50);
+	} else {
+		priv->BSS_list_entries = 0;
+		cmd.SSID_size = 0;
+		cmd.min_channel_time = cpu_to_le16(10);
+		cmd.max_channel_time = cpu_to_le16(120);
+	}
+	
+	cmd.options = 0;
+	
+	if (!specific_ssid)
+		cmd.options |= SCAN_OPTIONS_SITE_SURVEY;
+	
+	cmd.channel = (priv->channel & 0x7f); 
+	cmd.scan_type = SCAN_TYPE_ACTIVE;
+	cmd.BSS_type = cpu_to_le16(priv->operating_mode == IW_MODE_ADHOC ? 
+		BSS_TYPE_AD_HOC : BSS_TYPE_INFRASTRUCTURE);
+	
+	atmel_send_command(priv, CMD_Scan, &cmd, sizeof(cmd));
+}
+
+static void join(struct atmel_private *priv, int type)
+{
+	struct {
+		u8 BSSID[6];
+		u8 SSID[MAX_SSID_LENGTH];
+		u8 BSS_type; /* this is a short in a scan command - wierd */                                
+		u8 channel;
+		u16 timeout;
+		u8 SSID_size;
+		u8 reserved;
+	} cmd;
+
+	cmd.SSID_size = priv->SSID_size;
+	memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
+	memcpy(cmd.BSSID, priv->CurrentBSSID, 6);
+	cmd.channel = (priv->channel & 0x7f);
+	cmd.BSS_type = type;
+	cmd.timeout = cpu_to_le16(2000);
+
+ 	atmel_send_command(priv, CMD_Join, &cmd, sizeof(cmd));
+}
+
+
+static void start(struct atmel_private *priv, int type)
+{
+	struct {
+		u8 BSSID[6];
+		u8 SSID[MAX_SSID_LENGTH];
+		u8 BSS_type;                                
+		u8 channel;
+		u8 SSID_size;
+		u8 reserved[3];
+	} cmd;
+
+	cmd.SSID_size = priv->SSID_size;
+	memcpy(cmd.SSID, priv->SSID, priv->SSID_size);
+	memcpy(cmd.BSSID, priv->BSSID, 6);
+	cmd.BSS_type = type;
+	cmd.channel = (priv->channel & 0x7f);
+
+	atmel_send_command(priv, CMD_Start, &cmd, sizeof(cmd)); 
+}
+
+static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 channel)
+{
+	int rejoin = 0;
+	int new = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ? 
+		SHORT_PREAMBLE : LONG_PREAMBLE;
+
+	if (priv->preamble != new) {
+		priv->preamble = new;
+		rejoin = 1;
+		atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, new);
+	}
+		
+	if (priv->channel != channel) {
+		priv->channel = channel;
+		rejoin = 1;
+		atmel_set_mib8(priv, Phy_Mib_Type, PHY_MIB_CHANNEL_POS, channel);
+	}
+	
+	if (rejoin) {
+		priv->station_is_associated = 0;
+		atmel_enter_state(priv, STATION_STATE_JOINNING);
+		
+		if (priv->operating_mode == IW_MODE_INFRA)
+			join(priv, BSS_TYPE_INFRASTRUCTURE);
+		else 
+			join(priv, BSS_TYPE_AD_HOC);
+	} 
+}
+
+ 
+static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
+{
+	struct ieee802_11_hdr header;
+	struct auth_body auth;
+	
+	header.frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT | IEEE802_11_STYPE_AUTH); 
+	header.duration_id	= cpu_to_le16(0x8000);	
+	header.seq_ctl = 0;
+	memcpy(header.addr1, priv->CurrentBSSID, 6);
+	memcpy(header.addr2, priv->dev->dev_addr, 6);
+	memcpy(header.addr3, priv->CurrentBSSID, 6);
+	
+	if (priv->wep.wep_is_on) {
+		auth.alg = C80211_MGMT_AAN_SHAREDKEY; 
+		/* no WEP for authentication frames with TrSeqNo 1 */
+		if (priv->CurrentAuthentTransactionSeqNum != 1)
+			header.frame_ctl |=  cpu_to_le16(IEEE802_11_FCTL_WEP); 
+	} else {
+		auth.alg = C80211_MGMT_AAN_OPENSYSTEM;
+	}
+
+	auth.status = 0;
+	auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
+	priv->ExpectedAuthentTransactionSeqNum = priv->CurrentAuthentTransactionSeqNum+1; 
+	priv->CurrentAuthentTransactionSeqNum += 2;
+	
+	if (challenge_len != 0)	{
+		auth.el_id = 16; /* challenge_text */
+		auth.chall_text_len = challenge_len;
+		memcpy(auth.chall_text, challenge, challenge_len);
+		atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 8 + challenge_len);
+	} else {
+		atmel_transmit_management_frame(priv, &header, (u8 *)&auth, 6);
+	}
+}
+
+static void send_association_request(struct atmel_private *priv, int is_reassoc)
+{
+	u8 *ssid_el_p;
+	int bodysize;
+	struct ieee802_11_hdr header;
+	struct ass_req_format {
+		u16 capability;
+		u16 listen_interval; 
+		u8 ap[6]; /* nothing after here directly accessible */
+		u8 ssid_el_id;
+		u8 ssid_len;
+		u8 ssid[MAX_SSID_LENGTH];
+		u8 sup_rates_el_id;
+		u8 sup_rates_len;
+		u8 rates[4];
+	} body;
+		
+	header.frame_ctl = cpu_to_le16(IEEE802_11_FTYPE_MGMT | 
+		(is_reassoc ? IEEE802_11_STYPE_REASSOC_REQ : IEEE802_11_STYPE_ASSOC_REQ));
+	header.duration_id = cpu_to_le16(0x8000);
+	header.seq_ctl = 0;
+
+	memcpy(header.addr1, priv->CurrentBSSID, 6); 
+	memcpy(header.addr2, priv->dev->dev_addr, 6);
+	memcpy(header.addr3, priv->CurrentBSSID, 6); 
+
+	body.capability = cpu_to_le16(C80211_MGMT_CAPABILITY_ESS);
+	if (priv->wep.wep_is_on)
+		body.capability |= cpu_to_le16(C80211_MGMT_CAPABILITY_Privacy);
+	if (priv->preamble == SHORT_PREAMBLE)
+		body.capability |= cpu_to_le16(C80211_MGMT_CAPABILITY_ShortPreamble);
+
+	body.listen_interval = cpu_to_le16(priv->listen_interval * priv->beacon_period);
+	
+	/* current AP address - only in reassoc frame */
+	if (is_reassoc) {
+		memcpy(body.ap,  priv->CurrentBSSID, 6);
+		ssid_el_p = (u8 *)&body.ssid_el_id;
+		bodysize = 18 + priv->SSID_size;
+	} else {
+		ssid_el_p = (u8 *)&body.ap[0];
+		bodysize = 12 + priv->SSID_size;
+	}
+		
+	ssid_el_p[0]= C80211_MGMT_ElementID_SSID;
+	ssid_el_p[1] = priv->SSID_size;
+	memcpy(ssid_el_p + 2, priv->SSID, priv->SSID_size);
+	ssid_el_p[2 + priv->SSID_size] = C80211_MGMT_ElementID_SupportedRates;
+	ssid_el_p[3 + priv->SSID_size] = 4; /* len of suported rates */
+	memcpy(ssid_el_p + 4 + priv->SSID_size, atmel_basic_rates, 4);
+
+	atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
+}
+
+static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee802_11_hdr *header)
+{
+	if (le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_FROMDS)
+		return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
+	else
+		return memcmp(header->addr2, priv->CurrentBSSID, 6) == 0;
+}
+
+static int retrieve_bss(struct atmel_private *priv)
+{
+	int i;
+	int max_rssi = -128;
+	int max_index = -1;
+	
+	if (priv->BSS_list_entries == 0)
+		return -1;
+			
+	if (priv->connect_to_any_BSS) {
+		/* Select a BSS with the max-RSSI but of the same type and of the same WEP mode
+		   and that it is not marked as 'bad' (i.e. we had previously failed to connect to
+		   this BSS with the settings that we currently use) */
+		priv->current_BSS = 0;
+		for(i=0; i<priv->BSS_list_entries; i++) { 
+			if (priv->operating_mode == priv->BSSinfo[i].BSStype &&
+			    ((!priv->wep.wep_is_on && !priv->BSSinfo[i].UsingWEP) || 
+			     (priv->wep.wep_is_on && priv->BSSinfo[i].UsingWEP)) &&
+			    !(priv->BSSinfo[i].channel & 0x80)) {
+				max_rssi = priv->BSSinfo[i].RSSI;
+				priv->current_BSS = max_index = i;
+			}
+			
+		}
+		return max_index;
+	}
+		
+	for(i=0; i<priv->BSS_list_entries; i++) {
+		if (priv->SSID_size == priv->BSSinfo[i].SSIDsize &&
+		    memcmp(priv->SSID, priv->BSSinfo[i].SSID, priv->SSID_size) == 0 &&
+		    priv->operating_mode == priv->BSSinfo[i].BSStype &&
+		    atmel_validate_channel(priv, priv->BSSinfo[i].channel) == 0) {
+			if (priv->BSSinfo[i].RSSI >= max_rssi) {
+				max_rssi = priv->BSSinfo[i].RSSI;
+				max_index = i;
+			}
+		}
+	}
+	return max_index;
+}
+
+
+static void store_bss_info(struct atmel_private *priv, struct ieee802_11_hdr *header,
+			   u16 capability, u16 beacon_period, u8 channel, u8 rssi, 
+			   u8 ssid_len, u8 *ssid, int is_beacon)
+{
+	u8 *bss = capability & C80211_MGMT_CAPABILITY_ESS ? header->addr2 : header->addr3;
+	int i, index;
+		
+	for (index = -1, i = 0; i < priv->BSS_list_entries; i++) 
+		if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0) 
+			index = i;
+
+        /* If we process a probe and an entry from this BSS exists 
+	   we will update the BSS entry with the info from this BSS.
+	   If we process a beacon we will only update RSSI */
+
+	if (index == -1) {
+		if (priv->BSS_list_entries == MAX_BSS_ENTRIES)
+			return;
+		index = priv->BSS_list_entries++;
+		memcpy(priv->BSSinfo[index].BSSID, bss, 6);
+		priv->BSSinfo[index].RSSI = rssi;
+	} else {
+		if (rssi > priv->BSSinfo[index].RSSI)
+			priv->BSSinfo[index].RSSI = rssi;
+		if (is_beacon)
+			return;
+	}
+
+	priv->BSSinfo[index].channel = channel;
+	priv->BSSinfo[index].beacon_period = beacon_period;
+	priv->BSSinfo[index].UsingWEP = capability & C80211_MGMT_CAPABILITY_Privacy;
+	memcpy(priv->BSSinfo[index].SSID, ssid, ssid_len);
+	priv->BSSinfo[index].SSIDsize = ssid_len;
+
+	if (capability & C80211_MGMT_CAPABILITY_IBSS)
+		priv->BSSinfo[index].BSStype = IW_MODE_ADHOC;
+	else if (capability & C80211_MGMT_CAPABILITY_ESS)
+		priv->BSSinfo[index].BSStype =IW_MODE_INFRA;
+	
+	priv->BSSinfo[index].preamble = capability  & C80211_MGMT_CAPABILITY_ShortPreamble ? 
+		SHORT_PREAMBLE : LONG_PREAMBLE;
+}
+
+static void authenticate(struct atmel_private *priv, u16 frame_len)
+{
+	struct auth_body *auth = (struct auth_body *)priv->rx_buf;
+	u16 status = le16_to_cpu(auth->status);
+	u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
+	
+	if (status == C80211_MGMT_SC_Success && !priv->wep.wep_is_on) { 
+		/* no WEP */
+		if (priv->station_was_associated) {
+			atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
+			send_association_request(priv, 1);
+			return;
+		} else {
+			atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
+			send_association_request(priv, 0);
+			return;
+		} 
+	}
+		
+	if (status == C80211_MGMT_SC_Success && priv->wep.wep_is_on) { 
+		/* WEP */
+		if (trans_seq_no != priv->ExpectedAuthentTransactionSeqNum)
+			return;
+				
+		if (trans_seq_no == 0x0002 &&
+		    auth->el_id == C80211_MGMT_ElementID_ChallengeText) {
+			send_authentication_request(priv, auth->chall_text, auth->chall_text_len);
+			return;
+		}
+		
+		if (trans_seq_no == 0x0004) {
+			if(priv->station_was_associated) {
+				atmel_enter_state(priv, STATION_STATE_REASSOCIATING);
+				send_association_request(priv, 1);
+				return;
+			} else {
+				atmel_enter_state(priv, STATION_STATE_ASSOCIATING);
+				send_association_request(priv, 0);
+				return;
+			} 
+		}
+	}			
+	
+	if (status == C80211_MGMT_SC_AuthAlgNotSupported && priv->connect_to_any_BSS) {
+		int bss_index;
+		
+		priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
+		
+		if ((bss_index  = retrieve_bss(priv)) != -1) {
+			atmel_join_bss(priv, bss_index);
+			return;
+		}
+	}
+	
+	
+	priv->AuthenticationRequestRetryCnt = 0;
+	atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
+	priv->station_is_associated = 0;
+}
+
+static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype)
+{
+	struct ass_resp_format {
+		u16 capability;
+		u16 status;
+		u16 ass_id;
+		u8 el_id;
+		u8 length;
+		u8 rates[4];
+	} *ass_resp = (struct ass_resp_format *)priv->rx_buf;
+	
+       	u16 status = le16_to_cpu(ass_resp->status);
+	u16 ass_id = le16_to_cpu(ass_resp->ass_id);
+   	u16 rates_len = ass_resp->length > 4 ? 4 : ass_resp->length;
+	
+	if (frame_len < 8 + rates_len)
+		return;
+	
+	if (status == C80211_MGMT_SC_Success) {
+		if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE)
+			priv->AssociationRequestRetryCnt = 0;
+		else
+			priv->ReAssociationRequestRetryCnt = 0;
+		
+		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_STATION_ID_POS, ass_id & 0x3fff);
+		atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, ass_resp->rates, rates_len);
+		if (priv->power_mode == 0) {
+			priv->listen_interval = 1;
+			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
+			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
+		} else {
+			priv->listen_interval = 2;
+			atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  PS_MODE);
+			atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 2);
+		}
+		
+		priv->station_is_associated = 1;
+		priv->station_was_associated = 1;
+		atmel_enter_state(priv, STATION_STATE_READY);
+		return;
+	}
+	
+	if (subtype == C80211_SUBTYPE_MGMT_ASS_RESPONSE &&
+	    status != C80211_MGMT_SC_AssDeniedBSSRate &&
+	    status != C80211_MGMT_SC_SupportCapabilities &&
+	    priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
+		mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+		priv->AssociationRequestRetryCnt++;
+		send_association_request(priv, 0);
+		return;
+	}
+		
+	if (subtype == C80211_SUBTYPE_MGMT_REASS_RESPONSE &&
+	    status != C80211_MGMT_SC_AssDeniedBSSRate &&
+	    status != C80211_MGMT_SC_SupportCapabilities &&
+	    priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) {
+		mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+		priv->ReAssociationRequestRetryCnt++;
+		send_association_request(priv, 1);
+		return;
+	}
+	
+	atmel_enter_state(priv,  STATION_STATE_MGMT_ERROR);
+	priv->station_is_associated = 0;
+	
+	if(priv->connect_to_any_BSS) {
+		int bss_index;
+		priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
+		
+		if ((bss_index = retrieve_bss(priv)) != -1) 
+			atmel_join_bss(priv, bss_index);
+		
+	}
+}
+
+void atmel_join_bss(struct atmel_private *priv, int bss_index)
+{
+	struct bss_info *bss =  &priv->BSSinfo[bss_index];
+
+	memcpy(priv->CurrentBSSID, bss->BSSID, 6);
+	memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize);
+	
+	/* When switching to AdHoc turn OFF Power Save if needed */
+
+	if (bss->BSStype == IW_MODE_ADHOC &&
+	    priv->operating_mode != IW_MODE_ADHOC &&
+	    priv->power_mode) {
+		priv->power_mode = 0;
+		priv->listen_interval = 1;
+		atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS,  ACTIVE_MODE);
+		atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
+	}
+		
+	priv->operating_mode = bss->BSStype;
+	priv->channel = bss->channel & 0x7f; 	
+	priv->beacon_period = bss->beacon_period;
+	
+	if (priv->preamble != bss->preamble) {
+		priv->preamble = bss->preamble;
+		atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, bss->preamble);
+	}
+	
+	if (!priv->wep.wep_is_on && bss->UsingWEP) {
+		atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+		priv->station_is_associated = 0;
+		return;
+	}
+		
+	if (priv->wep.wep_is_on && !bss->UsingWEP) {
+		atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+		priv->station_is_associated = 0;
+		return;
+	}
+
+	atmel_enter_state(priv, STATION_STATE_JOINNING);
+	
+	if (priv->operating_mode == IW_MODE_INFRA)
+		join(priv, BSS_TYPE_INFRASTRUCTURE);
+	else 
+		join(priv, BSS_TYPE_AD_HOC);
+}
+
+
+static void restart_search(struct atmel_private *priv)
+{
+	int bss_index;
+	
+	if (!priv->connect_to_any_BSS) {
+		atmel_scan(priv, 1);
+	} else {
+		priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
+		
+		if ((bss_index = retrieve_bss(priv)) != -1) 
+			atmel_join_bss(priv, bss_index);
+		else
+			atmel_scan(priv, 0);
+		
+	} 
+}	
+
+static void smooth_rssi(struct atmel_private *priv, u8 rssi)
+{
+	u8 old = priv->wstats.qual.level;
+
+	/* 502-rmfd-revd gives max signal level as 42, by experiment.
+	   This is going to break for other hardware variants. */
+
+	rssi = rssi * 100 / 42;
+	if((rssi + old) % 2)
+		priv->wstats.qual.level =  ((rssi + old)/2) + 1;
+	else
+		priv->wstats.qual.level =  ((rssi + old)/2);		
+	
+}
+
+static void atmel_smooth_qual(struct atmel_private *priv)
+{
+	unsigned long time_diff = (jiffies - priv->last_qual)/HZ;
+	while (time_diff--) {
+		priv->last_qual += HZ;
+		priv->wstats.qual.qual = priv->wstats.qual.qual/2;
+		priv->wstats.qual.qual += 
+			priv->beacons_this_sec * priv->beacon_period * (priv->wstats.qual.level + 100) / 4000;
+		priv->beacons_this_sec = 0;
+	}
+}
+	
+/* deals with incoming managment frames. */
+static void atmel_management_frame(struct atmel_private *priv, struct ieee802_11_hdr *header, 
+		      u16 frame_len, u8 rssi)
+{
+	u16 subtype;
+	
+	switch (subtype = le16_to_cpu(header->frame_ctl) & IEEE802_11_FCTL_STYPE) {
+	case C80211_SUBTYPE_MGMT_BEACON :
+	case C80211_SUBTYPE_MGMT_ProbeResponse:
+		
+		/* beacon frame has multiple variable-length fields -
+		   never let an engineer loose with a data structure design. */
+		{
+			struct beacon_format {
+				u64 timestamp;
+				u16 interval;
+				u16 capability;
+				u8 ssid_el_id;
+				u8 ssid_length;
+				/* ssid here */
+				u8 rates_el_id;
+				u8 rates_length;
+				/* rates here */
+				u8 ds_el_id;
+				u8 ds_length;
+				/* ds here */
+			} *beacon = (struct beacon_format *)priv->rx_buf;
+			
+			u8 channel, rates_length, ssid_length;
+			u64 timestamp = le64_to_cpu(beacon->timestamp);
+			u16 beacon_interval = le16_to_cpu(beacon->interval);
+			u16 capability = le16_to_cpu(beacon->capability);
+			u8 *beaconp = priv->rx_buf;
+			ssid_length = beacon->ssid_length;
+			/* this blows chunks. */
+			if (frame_len < 14 || frame_len < ssid_length + 15) 
+				return;
+			rates_length = beaconp[beacon->ssid_length + 15];
+			if (frame_len < ssid_length + rates_length + 18)
+				return;
+			if (ssid_length >  MAX_SSID_LENGTH)
+				return;
+			channel = beaconp[ssid_length + rates_length + 18];
+		       
+			if (priv->station_state == STATION_STATE_READY) {
+				smooth_rssi(priv, rssi);
+				if (is_frame_from_current_bss(priv, header)) { 
+					priv->beacons_this_sec++;
+					atmel_smooth_qual(priv);
+					if (priv->last_beacon_timestamp) {
+						/* Note truncate this to 32 bits - kernel can't divide a long long */
+						u32 beacon_delay = timestamp - priv->last_beacon_timestamp;
+						int beacons = beacon_delay / (beacon_interval * 1000);
+						if (beacons > 1)
+							priv->wstats.miss.beacon += beacons - 1;
+					}
+					priv->last_beacon_timestamp = timestamp;
+					handle_beacon_probe(priv, capability, channel);
+				}
+			}
+			
+			if (priv->station_state == STATION_STATE_SCANNING ) 
+				store_bss_info(priv, header, capability, beacon_interval, channel,
+					       rssi, ssid_length, &beacon->rates_el_id,
+					       subtype == C80211_SUBTYPE_MGMT_BEACON) ;
+		}
+		break;
+		
+	case C80211_SUBTYPE_MGMT_Authentication:
+
+		if (priv->station_state == STATION_STATE_AUTHENTICATING)
+			authenticate(priv, frame_len);
+	
+		break;
+		
+	case C80211_SUBTYPE_MGMT_ASS_RESPONSE:
+	case C80211_SUBTYPE_MGMT_REASS_RESPONSE:
+		
+		if (priv->station_state == STATION_STATE_ASSOCIATING || 
+		    priv->station_state == STATION_STATE_REASSOCIATING)
+			associate(priv, frame_len, subtype);
+		
+		break;
+
+	case C80211_SUBTYPE_MGMT_DISASSOSIATION:
+		if (priv->station_is_associated && 
+		    priv->operating_mode == IW_MODE_INFRA && 
+		    is_frame_from_current_bss(priv, header)) {
+			priv->station_was_associated = 0;
+			priv->station_is_associated = 0;
+			
+			atmel_enter_state(priv, STATION_STATE_JOINNING);
+			join(priv, BSS_TYPE_INFRASTRUCTURE);
+		}
+		
+		break;
+
+	case C80211_SUBTYPE_MGMT_Deauthentication:
+		if (priv->operating_mode == IW_MODE_INFRA &&
+		    is_frame_from_current_bss(priv, header)) {
+			priv->station_was_associated = 0;
+
+			atmel_enter_state(priv, STATION_STATE_JOINNING);
+			join(priv, BSS_TYPE_INFRASTRUCTURE);
+		}
+		
+		break;
+	}
+}
+
+/* run when timer expires */
+static void atmel_management_timer(u_long a)
+{
+  struct net_device *dev = (struct net_device *) a;
+  struct atmel_private *priv = (struct atmel_private *)dev->priv;
+  unsigned long flags;
+  
+  /* Check if the card has been yanked. */
+  if (priv->card && priv->present_callback && 
+      !(*priv->present_callback)(priv->card))
+	  return;
+
+  if (priv->station_state == STATION_STATE_NO_CARD)
+	  return;
+
+  spin_lock_irqsave(&priv->irqlock, flags);
+
+  switch (priv->station_state) {
+	  
+  case STATION_STATE_AUTHENTICATING:
+	  
+	  if (priv->AuthenticationRequestRetryCnt >= MAX_AUTHENTICATION_RETRIES) {
+		  atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+		  priv->station_is_associated = 0;
+		  priv->AuthenticationRequestRetryCnt = 0;
+		  restart_search(priv);
+	  } else {
+		  priv->AuthenticationRequestRetryCnt++;
+		  priv->CurrentAuthentTransactionSeqNum = 0x0001;
+		  mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+		  send_authentication_request(priv, NULL, 0);
+	  }
+	  
+	  break;
+
+  case STATION_STATE_ASSOCIATING:
+
+	  if (priv->AssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
+		  atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+		  priv->station_is_associated = 0;
+		  priv->AssociationRequestRetryCnt = 0;
+		  restart_search(priv);
+	  } else {
+		  priv->AssociationRequestRetryCnt++;
+		  mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+		  send_association_request(priv, 0);
+	  }
+
+	  break;
+		  
+  case STATION_STATE_REASSOCIATING:	
+	  
+	  if (priv->ReAssociationRequestRetryCnt == MAX_ASSOCIATION_RETRIES) {
+		  atmel_enter_state(priv, STATION_STATE_MGMT_ERROR);
+		  priv->station_is_associated = 0;
+		  priv->ReAssociationRequestRetryCnt = 0;
+		  restart_search(priv);
+	  } else {
+		  priv->ReAssociationRequestRetryCnt++;
+		  mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+		  send_association_request(priv, 1);
+	  }
+
+	  break;
+	  
+  default:
+	  break;
+  }
+  
+  spin_unlock_irqrestore(&priv->irqlock, flags);
+}
+  
+static void atmel_command_irq(struct atmel_private *priv)
+{
+	u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
+	u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
+	int fast_scan;
+	
+	if (status == CMD_STATUS_IDLE || 
+	    status == CMD_STATUS_IN_PROGRESS)
+		return;
+
+	switch (command){
+
+	case CMD_Start:
+		if (status == CMD_STATUS_COMPLETE) {
+			priv->station_was_associated = priv->station_is_associated;
+			atmel_get_mib(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_BSSID_POS,
+				      (u8 *)priv->CurrentBSSID, 6);
+			atmel_enter_state(priv, STATION_STATE_READY);
+		}			
+		break;
+		
+	case CMD_Scan:
+		fast_scan = priv->fast_scan;
+		priv->fast_scan = 0;
+		
+		if (status != CMD_STATUS_COMPLETE) {
+			atmel_scan(priv, 1);
+		} else {
+			int bss_index = retrieve_bss(priv);
+			if (bss_index != -1) {
+				atmel_join_bss(priv, bss_index);
+			} else if (priv->operating_mode == IW_MODE_ADHOC && 
+				   priv->SSID_size != 0) {
+				start(priv, BSS_TYPE_AD_HOC);
+			} else {
+				priv->fast_scan = !fast_scan;
+				atmel_scan(priv, 1);
+			}
+		}
+		break;
+		
+	case CMD_SiteSurvey:
+		priv->fast_scan = 0;
+		
+		if (status != CMD_STATUS_COMPLETE)
+			return;
+		
+		priv->site_survey_state = SITE_SURVEY_COMPLETED;
+		if (priv->station_is_associated) {
+			atmel_enter_state(priv, STATION_STATE_READY);				
+		} else {
+			atmel_scan(priv, 1);
+		}
+		break;
+
+	case CMD_Join:
+		if (status == CMD_STATUS_COMPLETE) {
+			if (priv->operating_mode == IW_MODE_ADHOC) {
+				priv->station_was_associated = priv->station_is_associated;
+				atmel_enter_state(priv, STATION_STATE_READY);
+			} else {
+				priv->AuthenticationRequestRetryCnt = 0;
+				atmel_enter_state(priv, STATION_STATE_AUTHENTICATING);
+				
+				mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
+				priv->CurrentAuthentTransactionSeqNum = 0x0001;
+				send_authentication_request(priv, NULL, 0);
+			}
+			return;
+		}
+		
+
+		if (priv->station_state == STATION_STATE_FORCED_JOINNING) {
+			atmel_enter_state(priv, STATION_STATE_FORCED_JOIN_FAILURE); 
+		} else {
+			atmel_scan(priv, 1);
+		}
+	}
+}
+
+static int atmel_wakeup_firmware(struct atmel_private *priv)
+{
+	struct host_info_struct *iface = &priv->host_info;
+	u16 mr1, mr3;
+	int i;
+	
+	if (priv->card_type == CARD_TYPE_SPI_FLASH)
+		atmel_set_gcr(priv->dev, GCR_REMAP);
+	
+	/* wake up on-board processor */
+	atmel_clear_gcr(priv->dev, 0x0040);
+	atmel_write16(priv->dev, BSR, BSS_SRAM);
+	
+	if (priv->card_type == CARD_TYPE_SPI_FLASH)
+		mdelay(100);
+
+	/* and wait for it */
+	for (i =  LOOP_RETRY_LIMIT; i; i--) {
+		mr1 = atmel_read16(priv->dev, MR1);
+		mr3 = atmel_read16(priv->dev, MR3);
+		
+		if (mr3 & MAC_BOOT_COMPLETE) 
+			break;
+		if (mr1 & MAC_BOOT_COMPLETE &&
+		    priv->bus_type == BUS_TYPE_PCCARD)
+			break;
+	}
+
+	if (i == 0) {
+		printk(KERN_ALERT "%s: MAC failed to boot.\n", priv->dev->name);
+		return 0;
+	}
+		
+	if ((priv->host_info_base = atmel_read16(priv->dev, MR2)) == 0xffff) {
+		printk(KERN_ALERT "%s: card missing.\n", priv->dev->name);
+		priv->station_state = STATION_STATE_NO_CARD;
+		return 0;
+	}
+	
+	/* now check for completion of MAC initialization through  
+	   the FunCtrl field of the IFACE, poll MR1 to detect completion of	  
+	   MAC initialization, check completion status, set interrupt mask,  
+	   enables interrupts and calls Tx and Rx initialization functions */  
+	
+	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), FUNC_CTRL_INIT_COMPLETE);
+	
+	for (i =  LOOP_RETRY_LIMIT; i; i--) {
+		mr1 = atmel_read16(priv->dev, MR1);
+		mr3 = atmel_read16(priv->dev, MR3);
+		
+		if (mr3 & MAC_INIT_COMPLETE) 
+			break;
+		if (mr1 & MAC_INIT_COMPLETE &&
+		    priv->bus_type == BUS_TYPE_PCCARD)
+			break;
+	}
+	
+	if (i == 0) {
+		printk(KERN_ALERT "%s: MAC failed to initialise.\n", priv->dev->name);
+		return 0;
+	}
+	
+	/* Check for MAC_INIT_OK only on the register that the MAC_INIT_OK was set */
+	if ((mr3 & MAC_INIT_COMPLETE) &&
+	    !(atmel_read16(priv->dev, MR3) & MAC_INIT_OK)) {
+		printk(KERN_ALERT "%s: MAC failed MR3 self-test.\n", priv->dev->name);
+		return 0;
+	}
+	if ((mr1 & MAC_INIT_COMPLETE) &&
+	    !(atmel_read16(priv->dev, MR1) & MAC_INIT_OK)) {
+		printk(KERN_ALERT "%s: MAC failed MR1 self-test.\n", priv->dev->name);
+		return 0;
+	}
+	
+	atmel_copy_to_host(priv->dev, (unsigned char *)iface, 
+			   priv->host_info_base, sizeof(*iface));
+	
+	iface->tx_buff_pos = le16_to_cpu(iface->tx_buff_pos);
+	iface->tx_buff_size = le16_to_cpu(iface->tx_buff_size);
+	iface->tx_desc_pos = le16_to_cpu(iface->tx_desc_pos);
+	iface->tx_desc_count = le16_to_cpu(iface->tx_desc_count);
+	iface->rx_buff_pos = le16_to_cpu(iface->rx_buff_pos);
+	iface->rx_buff_size = le16_to_cpu(iface->rx_buff_size);
+	iface->rx_desc_pos = le16_to_cpu(iface->rx_desc_pos);
+	iface->rx_desc_count = le16_to_cpu(iface->rx_desc_count);
+	iface->build_version = le16_to_cpu(iface->build_version);
+	iface->command_pos = le16_to_cpu(iface->command_pos);
+	iface->major_version = le16_to_cpu(iface->major_version);
+	iface->minor_version = le16_to_cpu(iface->minor_version);
+	iface->func_ctrl = le16_to_cpu(iface->func_ctrl);
+	iface->mac_status = le16_to_cpu(iface->mac_status);
+
+	return 1;
+}
+
+/* determine type of memory and MAC address */
+static int probe_atmel_card(struct net_device *dev)
+{
+	int rc = 0;
+	struct atmel_private *priv = dev->priv;
+	 
+	/* reset pccard */
+	if (priv->bus_type == BUS_TYPE_PCCARD) 
+		atmel_write16(dev, GCR, 0x0060);
+	
+	atmel_write16(dev, GCR, 0x0040);
+	mdelay(500);
+	
+	if (atmel_read16(dev, MR2) == 0) {
+		/* No stored firmware so load a small stub which just 
+		   tells us the MAC address */
+		int i;
+		priv->card_type = CARD_TYPE_EEPROM;
+		atmel_write16(dev, BSR, BSS_IRAM);
+		atmel_copy_to_card(dev, 0, mac_reader, sizeof(mac_reader));
+		atmel_set_gcr(dev, GCR_REMAP);
+		atmel_clear_gcr(priv->dev, 0x0040);
+		atmel_write16(dev, BSR, BSS_SRAM);
+		for (i =  LOOP_RETRY_LIMIT; i; i--) 
+			if (atmel_read16(dev, MR3) & MAC_BOOT_COMPLETE)
+				break;
+		if (i == 0) {
+			printk(KERN_ALERT "%s: MAC failed to boot MAC address reader.\n", dev->name);
+		} else {
+			atmel_copy_to_host(dev, dev->dev_addr, atmel_read16(dev, MR2), 6);
+			
+			/* got address, now squash it again until the network
+			   interface is opened */
+			if (priv->bus_type == BUS_TYPE_PCCARD) 
+				atmel_write16(dev, GCR, 0x0060);
+			atmel_write16(dev, GCR, 0x0040);
+			rc = 1;
+		}
+	} else if (atmel_read16(dev, MR4) == 0) {
+		/* Mac address easy in this case. */
+		priv->card_type = CARD_TYPE_PARALLEL_FLASH;
+		atmel_write16(dev,  BSR, 1);	
+		atmel_copy_to_host(dev, dev->dev_addr, 0xc000, 6);
+		atmel_write16(dev,  BSR, 0x200);
+		rc = 1;
+	} else {
+		/* Standard firmware in flash, boot it up and ask
+		   for the Mac Address */
+		priv->card_type = CARD_TYPE_SPI_FLASH;
+		if (atmel_wakeup_firmware(priv)) {
+			atmel_get_mib(priv, Mac_Address_Mib_Type, 0, dev->dev_addr, 6);
+			
+			/* got address, now squash it again until the network
+			   interface is opened */
+			if (priv->bus_type == BUS_TYPE_PCCARD) 
+				atmel_write16(dev, GCR, 0x0060);
+			atmel_write16(dev, GCR, 0x0040);
+			rc = 1;
+		}
+	}
+	
+	if (rc) {
+		if (dev->dev_addr[0] == 0xFF) {
+			u8 default_mac[] = {0x00,0x04, 0x25, 0x00, 0x00, 0x00};
+			printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
+			memcpy(dev->dev_addr, default_mac, 6);
+		}
+		printk(KERN_INFO "%s: MAC address %x:%x:%x:%x:%x:%x\n",
+		       dev->name,
+		       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+		       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
+		
+	}
+	
+	return rc;
+}
+
+int reset_atmel_card(struct net_device *dev) 
+{
+	/* do everything necessary to wake up the hardware, including
+	   waiting for the lightning strike and throwing the knife switch....
+
+	   set all the Mib values which matter in the card to match 
+	   their settings in the atmel_private structure. Some of these
+	   can be altered on the fly, but many (WEP, infrastucture or ad-hoc)
+	   can only be changed by tearing down the world and coming back through
+	   here.
+
+	   This routine is also responsible for initialising some 
+	   hardware-specific fields in the atmel_private structure, 
+	   including a copy of the firmware's hostinfo stucture
+	   which is the route into the rest of the firmare datastructures. */
+
+	int channel;
+	struct atmel_private *priv = dev->priv;
+	u8 configuration;
+	
+	if (priv->station_state == STATION_STATE_NO_CARD ||
+	    priv->station_state == STATION_STATE_DOWN)
+		return 0;
+	
+	/* reset pccard */
+	if (priv->bus_type == BUS_TYPE_PCCARD) 
+		atmel_write16(priv->dev, GCR, 0x0060);
+		
+	/* stop card , disable interrupts */
+	atmel_write16(priv->dev, GCR, 0x0040);
+	
+	/* any scheduled timer is no longer needed and might screw things up.. */
+	del_timer_sync(&priv->management_timer);
+	if (priv->new_SSID_size) {
+		memcpy(priv->SSID, priv->new_SSID, priv->new_SSID_size);
+		priv->SSID_size = priv->new_SSID_size;
+		priv->new_SSID_size = 0;
+	}
+	priv->BSS_list_entries = 0;
+
+	priv->AuthenticationRequestRetryCnt = 0;
+	priv->AssociationRequestRetryCnt = 0;
+	priv->ReAssociationRequestRetryCnt = 0;
+	priv->CurrentAuthentTransactionSeqNum = 0x0001;
+	priv->ExpectedAuthentTransactionSeqNum = 0x0002;
+
+	priv->station_state = STATION_STATE_INITIALIZING;
+	priv->site_survey_state = SITE_SURVEY_IDLE;
+	priv->station_is_associated = 0;
+	
+	if (priv->card_type == CARD_TYPE_EEPROM) {
+		/* copy in firmware if needed */
+#ifdef CONFIG_FW_LOADER
+		const struct firmware *fw_entry = NULL;
+#endif
+		unsigned char *fw;
+		int len = priv->firmware_length;
+		if (!(fw = priv->firmware)) { 
+#ifdef CONFIG_FW_LOADER
+			if (strlen(priv->firmware_id) == 0) {
+				printk(KERN_INFO
+				       "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
+				       dev->name);
+				printk(KERN_INFO
+				       "%s: if not, use the firmware= module parameter.\n", 
+				       dev->name);
+				strcpy(priv->firmware_id, "atmel_at76c502.bin");
+			}
+			if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) != 0) {
+				printk(KERN_ALERT 
+				       "%s: firmware %s is missing, cannot start.\n", 
+				       dev->name, priv->firmware_id);
+				return 0;
+			}
+			fw = fw_entry->data;
+			len = fw_entry->size;
+#else
+			printk(KERN_ALERT 
+			       "%s: no firmware supplied, cannot start.\n", dev->name);
+			return 0;
+#endif
+		}
+		
+		if (len <= 0x6000) {
+			atmel_write16(priv->dev, BSR, BSS_IRAM);
+			atmel_copy_to_card(priv->dev, 0, fw, len);
+			atmel_set_gcr(priv->dev, GCR_REMAP);
+		} else {
+			/* Remap */ 
+			atmel_set_gcr(priv->dev, GCR_REMAP);
+			atmel_write16(priv->dev, BSR, BSS_IRAM);
+			atmel_copy_to_card(priv->dev, 0, fw, 0x6000);
+			atmel_write16(priv->dev, BSR, 0x2ff);
+			atmel_copy_to_card(priv->dev, 0x8000, &fw[0x6000], len - 0x6000);
+		}
+
+#ifdef CONFIG_FW_LOADER
+		if (fw_entry)
+			release_firmware(fw_entry);
+#endif
+	}
+
+	if (!atmel_wakeup_firmware(priv))
+		return 0;
+	
+        /* unmask all irq sources */
+	atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
+	
+	/* int Tx system and enable Tx */
+	atmel_wmem8(priv, atmel_tx(priv, TX_DESC_FLAGS_OFFSET, 0), 0);
+	atmel_wmem32(priv, atmel_tx(priv, TX_DESC_NEXT_OFFSET, 0), 0x80000000L);
+	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_POS_OFFSET, 0), 0);
+	atmel_wmem16(priv, atmel_tx(priv, TX_DESC_SIZE_OFFSET, 0), 0);
+
+	priv->tx_desc_free = priv->host_info.tx_desc_count;		
+	priv->tx_desc_head = 0;									
+	priv->tx_desc_tail = 0;									
+	priv->tx_desc_previous = 0;
+	priv->tx_free_mem = priv->host_info.tx_buff_size;
+	priv->tx_buff_head = 0;	
+	priv->tx_buff_tail = 0;	
+		
+	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET)); 
+	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), 
+				   configuration | FUNC_CTRL_TxENABLE);
+
+	/* init Rx system and enable */
+	priv->rx_desc_head = 0;
+	
+	configuration = atmel_rmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET)); 
+	atmel_wmem8(priv, atmel_hi(priv, IFACE_FUNC_CTRL_OFFSET), 
+				   configuration | FUNC_CTRL_RxENABLE);
+	
+	priv->reg_domain = atmel_get_mib8(priv, Phy_Mib_Type, PHY_MIB_REG_DOMAIN_POS);
+	if (priv->reg_domain != REG_DOMAIN_FCC &&
+	    priv->reg_domain != REG_DOMAIN_DOC &&
+	    priv->reg_domain != REG_DOMAIN_ETSI &&
+	    priv->reg_domain != REG_DOMAIN_SPAIN &&
+	    priv->reg_domain != REG_DOMAIN_FRANCE &&
+	    priv->reg_domain != REG_DOMAIN_MKK &&
+	    priv->reg_domain != REG_DOMAIN_MKK1 &&
+	    priv->reg_domain != REG_DOMAIN_ISRAEL) {
+		priv->reg_domain = REG_DOMAIN_MKK1;
+		printk(KERN_ALERT "%s: failed to get regulatory domain: assuming MKK1.\n", dev->name);
+	} 
+	if ((channel = atmel_validate_channel(priv, priv->channel)))
+		priv->channel = channel;
+	
+	if (!priv->is3com) {
+		if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) == 
+		    CMD_STATUS_REJECTED_RADIO_OFF) {
+			printk(KERN_INFO 
+			       "%s: cannot turn the radio on. (Hey radio, you're beautiful!)\n",
+			       dev->name);
+			return 0;
+		}
+	}
+	
+	/* set up enough MIB values to run. */
+	atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_AUTO_TX_RATE_POS, priv->auto_tx_rate);
+	atmel_set_mib8(priv, Local_Mib_Type,  LOCAL_MIB_TX_PROMISCUOUS_POS,  PROM_MODE_OFF);
+	atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_RTS_THRESHOLD_POS, priv->rts_threshold);
+	atmel_set_mib16(priv, Mac_Mib_Type, MAC_MIB_FRAG_THRESHOLD_POS, priv->frag_threshold);
+	atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_SHORT_RETRY_POS, priv->short_retry);
+	atmel_set_mib8(priv, Mac_Mib_Type, MAC_MIB_LONG_RETRY_POS, priv->long_retry);
+	atmel_set_mib8(priv, Local_Mib_Type, LOCAL_MIB_PREAMBLE_TYPE, priv->preamble);
+	atmel_set_mib(priv, Mac_Address_Mib_Type, MAC_ADDR_MIB_MAC_ADDR_POS, 
+		      priv->dev->dev_addr, 6);
+	atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_PS_MODE_POS, ACTIVE_MODE);
+	atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_LISTEN_INTERVAL_POS, 1);
+	atmel_set_mib16(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_BEACON_PER_POS, priv->default_beacon_period);
+	atmel_set_mib(priv, Phy_Mib_Type, PHY_MIB_RATE_SET_POS, atmel_basic_rates, 4);
+	atmel_set_mib8(priv, Mac_Mgmt_Mib_Type, MAC_MGMT_MIB_CUR_PRIVACY_POS, priv->wep.wep_is_on);
+	atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&priv->wep, sizeof(priv->wep));
+		
+	atmel_scan(priv, 1);
+	
+	atmel_set_gcr(priv->dev, GCR_ENINT); /* enable interrupts */
+	
+	return 1;
+}
+
+EXPORT_SYMBOL(reset_atmel_card); 
+
+static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size)
+{
+	if (cmd)
+		atmel_copy_to_card(priv->dev, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET), 
+				   cmd, cmd_size);
+	
+	atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET), command);
+	atmel_wmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET), 0);
+}
+	
+static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size)
+{
+	int i, status;
+	
+	atmel_send_command(priv, command, cmd, cmd_size);
+
+	for (i = LOOP_RETRY_LIMIT; i; i--) {
+		status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
+		if (status != CMD_STATUS_IDLE && 
+		    status != CMD_STATUS_IN_PROGRESS)
+			break;
+	}
+
+	if (i == 0) {
+		printk(KERN_ALERT "%s: command %d failed to complete.\n", priv->dev->name, command);
+		status =  CMD_STATUS_HOST_ERROR;
+	} else { 
+		if (command != CMD_EnableRadio)
+			status = CMD_STATUS_COMPLETE;
+	}
+	
+	return status;
+}
+
+static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index)
+{
+	struct get_set_mib m;
+	m.type = type;
+	m.size = 1;
+	m.index = index;
+
+	atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, sizeof(m));
+	return atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + 4));
+}
+
+static void atmel_set_mib8(struct atmel_private *priv, u8 type, u8 index, u8 data)
+{
+	struct get_set_mib m;
+	m.type = type;
+	m.size = 1;
+	m.index = index;
+	m.data[0] = data;
+
+	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, sizeof(m));
+}
+
+static void atmel_set_mib16(struct atmel_private *priv, u8 type, u8 index, u16 data)
+{
+	struct get_set_mib m;
+	m.type = type;
+	m.size = 2;
+	m.index = index;
+	m.data[0] = data;
+	m.data[1] = data >> 8;
+
+	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, sizeof(m));
+}
+
+static void atmel_set_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len)
+{
+	struct get_set_mib m;
+	m.type = type;
+	m.size = data_len;
+	m.index = index;
+
+	memcpy(m.data, data, data_len);
+	atmel_send_command_wait(priv, CMD_Set_MIB_Vars, &m, sizeof(m));
+}
+
+static void atmel_get_mib(struct atmel_private *priv, u8 type, u8 index, u8 *data, int data_len)
+{
+	struct get_set_mib m;
+	m.type = type;
+	m.size = data_len;
+	m.index = index;
+	
+	atmel_send_command_wait(priv, CMD_Get_MIB_Vars, &m, sizeof(m));
+	atmel_copy_to_host(priv->dev, data, atmel_co(priv, CMD_BLOCK_PARAMETERS_OFFSET + 4), data_len);
+}
+	
+static void atmel_writeAR(struct net_device *dev, u16 data)
+{
+	int i;
+	outw(data, dev->base_addr + AR);
+	/* Address register appears to need some convincing..... */
+	for (i = 0; data != inw(dev->base_addr + AR) && i<10; i++)
+		outw(data, dev->base_addr + AR);
+}
+
+static void atmel_copy_to_card(struct net_device *dev, u16 dest, unsigned char *src, u16 len)
+{
+	int i;
+	atmel_writeAR(dev, dest);
+	if (dest % 2) {
+		atmel_write8(dev, DR, *src);
+		src++; len--;
+	}
+	for (i = len; i > 1 ; i -= 2) {
+		u8 lb = *src++;
+		u8 hb = *src++;
+		atmel_write16(dev, DR, lb | (hb << 8));
+	}
+	if (i)
+		atmel_write8(dev, DR, *src);
+}
+
+static void atmel_copy_to_host(struct net_device *dev, unsigned char *dest, u16 src, u16 len)
+{
+	int i;
+	atmel_writeAR(dev, src);
+	if (src % 2) {
+		*dest = atmel_read8(dev, DR);
+		dest++; len--;
+	}
+	for (i = len; i > 1 ; i -= 2) {
+		u16 hw = atmel_read16(dev, DR);
+		*dest++ = hw;
+		*dest++ = hw >> 8;
+	}
+	if (i)
+		*dest = atmel_read8(dev, DR);
+}
+
+static void atmel_set_gcr(struct net_device *dev, u16 mask)
+{
+	outw(inw(dev->base_addr + GCR) | mask, dev->base_addr + GCR);
+}
+
+static void atmel_clear_gcr(struct net_device *dev, u16 mask)
+{
+	outw(inw(dev->base_addr + GCR) & ~mask, dev->base_addr + GCR);
+}
+
+static int atmel_lock_mac(struct atmel_private *priv)
+{
+	int i, j = 100;
+ retry:
+	for (i = LOOP_RETRY_LIMIT ; atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET)) && i ; i--);
+	
+	if (!i) return 0; /* timed out */
+	
+	atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 1);
+	if (atmel_rmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_HOST_OFFSET))) {
+		atmel_wmem8(priv, atmel_hi(priv, IFACE_LOCKOUT_MAC_OFFSET), 0);
+		if (!j--) return 0; /* timed out */
+		goto retry;
+	}
+	
+	return 1;
+}
+
+static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
+{
+       	atmel_writeAR(priv->dev, pos);	
+	atmel_write16(priv->dev, DR, data); /* card is little-endian */
+	atmel_write16(priv->dev, DR, data >> 16);
+}
+
+
+/***************************************************************************/
+/* There follows the source form of the MAC address reading firmware       */
+/***************************************************************************/
+#if 0
+
+/* Copyright 2003 Matthew T. Russotto                                      */
+/* But derived from the Atmel 76C502 firmware written by Atmel and         */
+/* included in "atmel wireless lan drivers" package                        */
+/**
+    This file is part of net.russotto.AtmelMACFW, hereto referred to
+    as AtmelMACFW
+
+    AtmelMACFW is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License version 2
+    as published by the Free Software Foundation.
+
+    AtmelMACFW 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 AtmelMACFW; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+****************************************************************************/
+/* This firmware should work on the 76C502 RFMD, RFMD_D, and RFMD_E        */
+/* It will probably work on the 76C504 and 76C502 RFMD_3COM                */
+/* It only works on SPI EEPROM versions of the card.                       */
+
+/* This firmware initializes the SPI controller and clock, reads the MAC   */
+/* address from the EEPROM into SRAM, and puts the SRAM offset of the MAC  */
+/* address in MR2, and sets MR3 to 0x10 to indicate it is done             */
+/* It also puts a complete copy of the EEPROM in SRAM with the offset in   */
+/* MR4, for investigational purposes (maybe we can determine chip type     */
+/* from that?)                                                             */
+
+	.org 0
+    .set MRBASE, 0x8000000
+	.set CPSR_INITIAL, 0xD3 /* IRQ/FIQ disabled, ARM mode, Supervisor state */
+	.set CPSR_USER, 0xD1 /* IRQ/FIQ disabled, ARM mode, USER state */
+	.set SRAM_BASE,  0x02000000
+	.set SP_BASE,    0x0F300000
+	.set UNK_BASE,   0x0F000000 /* Some internal device, but which one? */
+	.set SPI_CGEN_BASE,  0x0E000000 /* Some internal device, but which one? */
+	.set UNK3_BASE,  0x02014000 /* Some internal device, but which one? */
+	.set STACK_BASE, 0x5600
+	.set SP_SR, 0x10
+	.set SP_TDRE, 2 /* status register bit -- TDR empty */
+	.set SP_RDRF, 1 /* status register bit -- RDR full */
+	.set SP_SWRST, 0x80
+	.set SP_SPIEN, 0x1
+	.set SP_CR, 0   /* control register */
+	.set SP_MR, 4   /* mode register */
+	.set SP_RDR, 0x08 /* Read Data Register */
+	.set SP_TDR, 0x0C /* Transmit Data Register */
+	.set SP_CSR0, 0x30 /* chip select registers */
+	.set SP_CSR1, 0x34
+	.set SP_CSR2, 0x38
+	.set SP_CSR3, 0x3C
+	.set NVRAM_CMD_RDSR, 5 /* read status register */
+	.set NVRAM_CMD_READ, 3 /* read data */
+	.set NVRAM_SR_RDY, 1 /* RDY bit.  This bit is inverted */
+	.set SPI_8CLOCKS, 0xFF /* Writing this to the TDR doesn't do anything to the
+				  serial output, since SO is normally high.  But it
+				  does cause 8 clock cycles and thus 8 bits to be
+				  clocked in to the chip.  See Atmel's SPI
+				  controller (e.g. AT91M55800) timing and 4K 
+				  SPI EEPROM manuals */
+				 
+	.set NVRAM_SCRATCH, 0x02000100  /* arbitrary area for scratchpad memory */
+	.set NVRAM_IMAGE, 0x02000200
+	.set NVRAM_LENGTH, 0x0200
+	.set MAC_ADDRESS_MIB, SRAM_BASE
+	.set MAC_ADDRESS_LENGTH, 6
+        .set MAC_BOOT_FLAG, 0x10
+	.set MR1, 0
+	.set MR2, 4
+	.set MR3, 8
+	.set MR4, 0xC
+RESET_VECTOR:
+        b RESET_HANDLER
+UNDEF_VECTOR:  
+        b HALT1
+SWI_VECTOR:            
+        b HALT1
+IABORT_VECTOR: 
+        b HALT1
+DABORT_VECTOR:         
+RESERVED_VECTOR:    
+        b HALT1
+IRQ_VECTOR:    
+        b HALT1
+FIQ_VECTOR:    
+	b HALT1
+HALT1:	b HALT1
+RESET_HANDLER:
+	mov     r0, #CPSR_INITIAL
+	msr	CPSR_c, r0	/* This is probably unnecessary */
+			
+/* I'm guessing this is initializing clock generator electronics for SPI */
+	ldr	r0, =SPI_CGEN_BASE
+	mov	r1, #0
+	mov	r1, r1, lsl #3
+	orr	r1,r1, #0
+	str	r1, [r0]
+	ldr	r1, [r0, #28]
+	bic	r1, r1, #16
+	str	r1, [r0, #28]
+	mov	r1, #1
+	str	r1, [r0, #8]
+	
+	ldr	r0, =MRBASE
+	mov	r1, #0
+	strh	r1, [r0, #MR1]
+	strh	r1, [r0, #MR2]
+	strh	r1, [r0, #MR3]
+	strh	r1, [r0, #MR4]
+
+	mov	sp, #STACK_BASE
+	bl	SP_INIT
+	mov	r0, #10
+	bl	DELAY9
+	bl	GET_MAC_ADDR
+	bl	GET_WHOLE_NVRAM
+	ldr	r0, =MRBASE
+	ldr	r1, =MAC_ADDRESS_MIB
+	strh	r1, [r0, #MR2]
+	ldr	r1, =NVRAM_IMAGE
+	strh	r1, [r0, #MR4]
+	mov	r1, #MAC_BOOT_FLAG
+	strh	r1, [r0, #MR3]
+HALT2:	b HALT2
+.func Get_Whole_NVRAM, GET_WHOLE_NVRAM
+GET_WHOLE_NVRAM:
+	stmdb	sp!, {lr}
+	mov	r2, #0 /* 0th bytes of NVRAM */
+	mov	r3, #NVRAM_LENGTH
+	mov	r1, #0		/* not used in routine */
+	ldr	r0, =NVRAM_IMAGE
+	bl	NVRAM_XFER
+	ldmia	sp!, {lr}
+	bx	lr
+.endfunc
+	
+.func Get_MAC_Addr, GET_MAC_ADDR
+GET_MAC_ADDR:
+	stmdb	sp!, {lr}
+	mov	r2, #0x120	/* address of MAC Address within NVRAM */
+	mov	r3, #MAC_ADDRESS_LENGTH
+	mov	r1, #0		/* not used in routine */
+	ldr	r0, =MAC_ADDRESS_MIB
+	bl	NVRAM_XFER
+	ldmia	sp!, {lr}
+	bx	lr
+.endfunc
+.ltorg
+.func Delay9, DELAY9
+DELAY9:
+	adds	r0, r0, r0, LSL #3   /* r0 = r0 * 9 */
+DELAYLOOP:	
+	beq	DELAY9_done
+	subs	r0, r0, #1
+	b	DELAYLOOP
+DELAY9_done:	
+	bx	lr
+.endfunc	
+
+.func SP_Init, SP_INIT
+SP_INIT:
+	mov	r1, #SP_SWRST
+	ldr	r0, =SP_BASE
+	str	r1, [r0, #SP_CR] /* reset the SPI */
+	mov	r1, #0
+	str	r1, [r0, #SP_CR] /* release SPI from reset state */
+	mov	r1, #SP_SPIEN
+	str	r1, [r0, #SP_MR] /* set the SPI to MASTER mode*/
+	str	r1, [r0, #SP_CR] /* enable the SPI */
+
+/*  My guess would be this turns on the SPI clock */
+	ldr	r3, =SPI_CGEN_BASE
+	ldr	r1, [r3, #28]
+	orr	r1, r1, #0x2000
+	str	r1, [r3, #28]
+
+	ldr	r1, =0x2000c01
+	str	r1, [r0, #SP_CSR0]
+	ldr	r1, =0x2000201
+	str	r1, [r0, #SP_CSR1]
+	str	r1, [r0, #SP_CSR2]
+	str	r1, [r0, #SP_CSR3]
+	ldr	r1, [r0, #SP_SR]
+	ldr	r0, [r0, #SP_RDR]
+	bx	lr
+.endfunc
+.func NVRAM_Init, NVRAM_INIT	
+NVRAM_INIT:
+	ldr	r1, =SP_BASE
+	ldr	r0, [r1, #SP_RDR]
+	mov	r0, #NVRAM_CMD_RDSR
+	str	r0, [r1, #SP_TDR]
+SP_loop1:	
+	ldr	r0, [r1, #SP_SR]
+	tst	r0, #SP_TDRE
+	beq	SP_loop1
+
+	mov	r0, #SPI_8CLOCKS
+	str	r0, [r1, #SP_TDR] 
+SP_loop2:	
+	ldr	r0, [r1, #SP_SR]
+	tst	r0, #SP_TDRE
+	beq	SP_loop2
+
+	ldr	r0, [r1, #SP_RDR]
+SP_loop3:	
+	ldr	r0, [r1, #SP_SR]
+	tst	r0, #SP_RDRF
+	beq	SP_loop3
+
+	ldr	r0, [r1, #SP_RDR]
+	and	r0, r0, #255
+	bx	lr
+.endfunc
+	
+.func NVRAM_Xfer, NVRAM_XFER
+	/* r0 = dest address */
+	/* r1 = not used */
+	/* r2 = src address within NVRAM */
+	/* r3 = length */
+NVRAM_XFER:
+	stmdb	sp!, {r4, r5, lr}
+	mov	r5, r0		/* save r0 (dest address) */
+	mov	r4, r3		/* save r3 (length) */
+	mov	r0, r2, LSR #5 /*  SPI memories put A8 in the command field */
+	and	r0, r0, #8
+	add	r0, r0, #NVRAM_CMD_READ 
+	ldr	r1, =NVRAM_SCRATCH
+	strb	r0, [r1, #0]	/* save command in NVRAM_SCRATCH[0] */
+	strb	r2, [r1, #1]    /* save low byte of source address in NVRAM_SCRATCH[1] */
+_local1:	
+	bl	NVRAM_INIT
+	tst	r0, #NVRAM_SR_RDY
+	bne	_local1
+	mov	r0, #20
+	bl	DELAY9
+	mov	r2, r4		/* length */
+	mov	r1, r5		/* dest address */
+	mov	r0, #2		/* bytes to transfer in command */
+	bl	NVRAM_XFER2
+	ldmia	sp!, {r4, r5, lr}
+	bx	lr
+.endfunc
+
+.func NVRAM_Xfer2, NVRAM_XFER2
+NVRAM_XFER2:
+	stmdb	sp!, {r4, r5, r6, lr}
+	ldr	r4, =SP_BASE
+	mov	r3, #0
+	cmp	r0, #0
+	bls	_local2
+	ldr	r5, =NVRAM_SCRATCH
+_local4:	
+	ldrb	r6, [r5, r3]
+	str	r6, [r4, #SP_TDR]
+_local3:
+	ldr	r6, [r4, #SP_SR]
+	tst	r6, #SP_TDRE
+	beq	_local3
+	add	r3, r3, #1
+	cmp	r3, r0 /* r0 is # of bytes to send out (command+addr) */
+	blo	_local4
+_local2:
+	mov	r3, #SPI_8CLOCKS
+	str	r3, [r4, #SP_TDR]
+	ldr	r0, [r4, #SP_RDR]
+_local5:	
+	ldr	r0, [r4, #SP_SR]
+	tst	r0, #SP_RDRF
+	beq	_local5
+	ldr	r0, [r4, #SP_RDR] /* what's this byte?  It's the byte read while writing the TDR -- nonsense, because the NVRAM doesn't read and write at the same time */
+	mov	r0, #0
+	cmp	r2, #0  /* r2 is # of bytes to copy in */
+	bls	_local6
+_local7:	
+	ldr	r5, [r4, #SP_SR]
+	tst	r5, #SP_TDRE
+	beq	_local7
+	str	r3, [r4, #SP_TDR]  /* r3 has SPI_8CLOCKS */
+_local8:	
+	ldr	r5, [r4, #SP_SR]
+	tst	r5, #SP_RDRF
+	beq	_local8
+	ldr	r5, [r4, #SP_RDR] /* but didn't we read this byte above? */
+	strb	r5, [r1], #1 /* postindexed */
+	add	r0, r0, #1
+	cmp	r0, r2
+	blo	_local7 /* since we don't send another address, the NVRAM must be capable of sequential reads */
+_local6:
+	mov	r0, #200
+	bl	DELAY9
+	ldmia	sp!, {r4, r5, r6, lr}
+	bx	lr
+#endif
diff -urN linux-2.5.70-bk10/drivers/net/wireless/atmel_cs.c linux-2.5.70-bk11/drivers/net/wireless/atmel_cs.c
--- linux-2.5.70-bk10/drivers/net/wireless/atmel_cs.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.70-bk11/drivers/net/wireless/atmel_cs.c	2003-06-06 04:38:24.000000000 -0700
@@ -0,0 +1,768 @@
+/*** -*- linux-c -*- **********************************************************
+
+     Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
+
+        Copyright 2000-2001 ATMEL Corporation.
+        Copyright 2003 Simon Kelley.
+
+    This code was developed from version 2.1.1 of the Atmel drivers, 
+    released by Atmel corp. under the GPL in December 2002. It also 
+    includes code from the Linux aironet drivers (C) Benjamin Reed, 
+    and the Linux PCMCIA package, (C) David Hinds. 
+
+    For all queries about this code, please contact the current author, 
+    Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
+
+    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 software 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 Atmel wireless lan drivers; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+******************************************************************************/
+
+#include <linux/config.h>
+#ifdef __IN_PCMCIA_PACKAGE__
+#include <pcmcia/k_compat.h>
+#endif
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/netdevice.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+#include <pcmcia/ciscode.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+#include <linux/wireless.h>
+#include <linux/802_11.h>
+
+
+/*
+   All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
+   you do not define PCMCIA_DEBUG at all, all the debug code will be
+   left out.  If you compile with PCMCIA_DEBUG=0, the debug code will
+   be present but disabled -- but it can then be enabled for specific
+   modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+MODULE_PARM(pc_debug, "i");
+static char *version = "$Revision: 1.2 $";
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+/* Parameters that can be set with 'insmod' */
+
+/* The old way: bit map of interrupts to choose from */
+/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
+static u_int irq_mask = 0xdeb8;
+/* Newer, simpler way of listing specific interrupts */
+static int irq_list[4] = { -1 };
+
+MODULE_AUTHOR("Simon Kelley");
+MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethnet cards.");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
+MODULE_PARM(irq_mask, "i");
+MODULE_PARM(irq_list, "1-4i");
+
+/*====================================================================*/
+
+/*
+   The event() function is this driver's Card Services event handler.
+   It will be called by Card Services when an appropriate card status
+   event is received.  The config() and release() entry points are
+   used to configure or release a socket, in response to card
+   insertion and ejection events.  They are invoked from the atmel_cs
+   event handler. 
+*/
+
+struct net_device *init_atmel_card(int, int, char *, int, struct device *, 
+				    int (*present_func)(void *), void * );
+void stop_atmel_card( struct net_device *, int );
+int reset_atmel_card( struct net_device * );
+
+static void atmel_config(dev_link_t *link);
+static void atmel_release(u_long arg);
+static int atmel_event(event_t event, int priority,
+		       event_callback_args_t *args);
+
+/*
+   The attach() and detach() entry points are used to create and destroy
+   "instances" of the driver, where each instance represents everything
+   needed to manage one actual PCMCIA card.
+*/
+
+static dev_link_t *atmel_attach(void);
+static void atmel_detach(dev_link_t *);
+
+/*
+   You'll also need to prototype all the functions that will actually
+   be used to talk to your device.  See 'pcmem_cs' for a good example
+   of a fully self-sufficient driver; the other drivers rely more or
+   less on other parts of the kernel.
+*/
+
+/*
+   The dev_info variable is the "key" that is used to match up this
+   device driver with appropriate cards, through the card configuration
+   database.
+*/
+
+static dev_info_t dev_info = "atmel_cs";
+
+/*
+   A linked list of "instances" of the  atmelnet device.  Each actual
+   PCMCIA card corresponds to one device instance, and is described
+   by one dev_link_t structure (defined in ds.h).
+
+   You may not want to use a linked list for this -- for example, the
+   memory card driver uses an array of dev_link_t pointers, where minor
+   device numbers are used to derive the corresponding array index.
+*/
+
+static dev_link_t *dev_list = NULL;
+
+/*
+   A dev_link_t structure has fields for most things that are needed
+   to keep track of a socket, but there will usually be some device
+   specific information that also needs to be kept track of.  The
+   'priv' pointer in a dev_link_t structure can be used to point to
+   a device-specific private data structure, like this.
+
+   A driver needs to provide a dev_node_t structure for each device
+   on a card.  In some cases, there is only one device per card (for
+   example, ethernet cards, modems).  In other cases, there may be
+   many actual or logical devices (SCSI adapters, memory cards with
+   multiple partitions).  The dev_node_t structures need to be kept
+   in a linked list starting at the 'dev' field of a dev_link_t
+   structure.  We allocate them in the card's private data structure,
+   because they generally shouldn't be allocated dynamically.
+
+   In this case, we also provide a flag to indicate if a device is
+   "stopped" due to a power management event, or card ejection.  The
+   device IO routines can use a flag like this to throttle IO to a
+   card that is not ready to accept it.
+*/
+   
+typedef struct local_info_t {
+	dev_node_t	node;
+	struct net_device *eth_dev;
+} local_info_t;
+
+/*======================================================================
+  
+  This bit of code is used to avoid unregistering network devices
+  at inappropriate times.  2.2 and later kernels are fairly picky
+  about when this can happen.
+  
+  ======================================================================*/
+
+static void flush_stale_links(void)
+{
+	dev_link_t *link, *next;
+	for (link = dev_list; link; link = next) {
+		next = link->next;
+		if (link->state & DEV_STALE_LINK)
+			atmel_detach(link);
+	}
+}
+ 
+/*======================================================================
+  
+  atmel_attach() creates an "instance" of the driver, allocating
+  local data structures for one device.  The device is registered
+  with Card Services.
+  
+  The dev_link structure is initialized, but we don't actually
+  configure the card at this point -- we wait until we receive a
+  card insertion event.
+  
+  ======================================================================*/
+
+static dev_link_t *atmel_attach(void)
+{
+	client_reg_t client_reg;
+	dev_link_t *link;
+	local_info_t *local;
+	int ret, i;
+	
+	DEBUG(0, "atmel_attach()\n");
+	flush_stale_links();
+	
+	/* Initialize the dev_link_t structure */
+	link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+	if (!link) {
+		printk(KERN_ERR "atmel_cs: no memory for new device\n");
+		return NULL;
+	}
+	memset(link, 0, sizeof(struct dev_link_t));
+	init_timer(&link->release);
+	link->release.function = &atmel_release;
+	link->release.data = (u_long)link;
+	
+	/* Interrupt setup */
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+	link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
+	if (irq_list[0] == -1)
+		link->irq.IRQInfo2 = irq_mask;
+	else
+		for (i = 0; i < 4; i++)
+			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.Handler = NULL;
+	
+	/*
+	  General socket configuration defaults can go here.  In this
+	  client, we assume very little, and rely on the CIS for almost
+	  everything.  In most clients, many details (i.e., number, sizes,
+	  and attributes of IO windows) are fixed by the nature of the
+	  device, and can be hard-wired here.
+	*/
+	link->conf.Attributes = 0;
+	link->conf.Vcc = 50;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+	
+	/* Allocate space for private device-specific data */
+	local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
+	if (!local) {
+		printk(KERN_ERR "atmel_cs: no memory for new device\n");
+		kfree (link);
+		return NULL;
+	}
+	memset(local, 0, sizeof(local_info_t));
+	link->priv = local;
+	
+	/* Register with Card Services */
+	link->next = dev_list;
+	dev_list = link;
+	client_reg.dev_info = &dev_info;
+	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+	client_reg.EventMask =
+		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+		CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+	client_reg.event_handler = &atmel_event;
+	client_reg.Version = 0x0210;
+	client_reg.event_callback_args.client_data = link;
+	ret = CardServices(RegisterClient, &link->handle, &client_reg);
+	if (ret != 0) {
+		cs_error(link->handle, RegisterClient, ret);
+		atmel_detach(link);
+		return NULL;
+	}
+	
+	return link;
+} /* atmel_attach */
+
+/*======================================================================
+  
+  This deletes a driver "instance".  The device is de-registered
+  with Card Services.  If it has been released, all local data
+  structures are freed.  Otherwise, the structures will be freed
+  when the device is released.
+  
+  ======================================================================*/
+
+static void atmel_detach(dev_link_t *link)
+{
+	dev_link_t **linkp;
+	
+	DEBUG(0, "atmel_detach(0x%p)\n", link);
+	
+	/* Locate device structure */
+	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+		if (*linkp == link) break;
+	if (*linkp == NULL)
+		return;
+
+	del_timer(&link->release);
+	if ( link->state & DEV_CONFIG ) {
+		atmel_release( (int)link );
+		if ( link->state & DEV_STALE_CONFIG ) {
+			link->state |= DEV_STALE_LINK;
+			return;
+		}
+	}
+	
+		
+	/* Break the link with Card Services */
+	if (link->handle)
+		CardServices(DeregisterClient, link->handle);
+	
+	
+	
+	/* Unlink device structure, free pieces */
+	*linkp = link->next;
+	if (link->priv) {
+		kfree(link->priv);
+	}
+	kfree(link);
+	
+} /* atmel_detach */
+
+/*======================================================================
+  
+  atmel_config() is scheduled to run after a CARD_INSERTION event
+  is received, to configure the PCMCIA socket, and to make the
+  device available to the system.
+  
+  ======================================================================*/
+
+#define CS_CHECK(fn, args...) \
+while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
+
+#define CFG_CHECK(fn, args...) \
+if (CardServices(fn, args) != 0) goto next_entry
+
+/* Call-back function to interrogate PCMCIA-specific information
+   about the current existance of the card */
+static int card_present(void *arg)
+{ 
+	dev_link_t *link = (dev_link_t *)arg;
+	if (link->state & DEV_SUSPEND)
+		return 0;
+	else if (link->state & DEV_PRESENT)
+		return 1;
+	
+	return 0;
+}
+
+/* list of cards we know about and their firmware requirements.
+   Go either by Manfid or version strings.
+   Cards not in this list will need a firmware parameter to the module
+   in all probability. Note that the SMC 2632 V2 and V3 have the same
+   manfids, so we ignore those and use the version1 strings. */
+
+static struct { 
+	int manf, card;
+	char *ver1;
+	char *firmware;
+	char *name;
+} card_table[] = {
+	{ 0, 0, "WLAN/802.11b PC CARD", "atmel_at76c502d.bin", "Actiontec 802CAT1" },  
+	{ 0, 0, "ATMEL/AT76C502AR", "atmel_at76c502.bin", "NoName-RFMD" }, 
+	{ 0, 0, "ATMEL/AT76C502AR_D", "atmel_at76c502d.bin", "NoName-revD" }, 
+	{ 0, 0, "ATMEL/AT76C502AR_E", "atmel_at76c502e.bin", "NoName-revE" },
+	{ 0, 0, "ATMEL/AT76C504", "atmel_at76c504.bin", "NoName-504" },
+	{ MANFID_3COM, 0x0620, NULL, "atmel_at76c502_3com.bin", "3com 3CRWE62092B" }, 
+	{ MANFID_3COM, 0x0696, NULL, "atmel_at76c502_3com.bin", "3com 3CRSHPW_96" }, 
+	{ 0, 0, "SMC/2632W-V2", "atmel_at76c502.bin", "SMC 2632W-V2" },
+        { 0, 0, "SMC/2632W", "atmel_at76c502d.bin", "SMC 2632W-V3" },
+	{ 0xd601, 0x0007, NULL, "atmel_at76c502.bin", "Sitecom WLAN-011"}, /* suspect - from a usenet posting. */
+	{ 0x01bf, 0x3302, NULL, "atmel_at76c502d.bin", "Belkin F5D6060u"},  /*    "        "  "    "      "     */
+};
+
+/* This is strictly temporary, until PCMCIA devices get integrated into the device model. */
+static struct device atmel_device = {
+        .name      = "Atmel at76c50x wireless",
+        .bus_id    = "pcmcia",
+};
+
+static void atmel_config(dev_link_t *link)
+{
+	client_handle_t handle;
+	tuple_t tuple;
+	cisparse_t parse;
+	local_info_t *dev;
+	int last_fn, last_ret;
+	u_char buf[64];
+	int card_index = -1;
+	
+	handle = link->handle;
+	dev = link->priv;
+
+	DEBUG(0, "atmel_config(0x%p)\n", link);
+	
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = sizeof(buf);
+	tuple.TupleOffset = 0;
+	
+	tuple.DesiredTuple = CISTPL_MANFID;
+	if (CardServices(GetFirstTuple, handle, &tuple) == 0) {
+		int i;
+		cistpl_manfid_t *manfid;
+		CS_CHECK(GetTupleData, handle, &tuple);
+		CS_CHECK(ParseTuple, handle, &tuple, &parse);
+		manfid = &(parse.manfid);
+		for (i = 0; i < sizeof(card_table)/sizeof(card_table[0]); i++) {
+			if (!card_table[i].ver1 &&
+			    manfid->manf == card_table[i].manf &&
+			    manfid->card == card_table[i].card) {
+				card_index = i;
+				goto done;
+			}
+		}
+	}
+
+	tuple.DesiredTuple = CISTPL_VERS_1;
+	if (CardServices(GetFirstTuple, handle, &tuple) == 0) {
+		int i, j, k;
+		cistpl_vers_1_t *ver1;
+		CS_CHECK(GetTupleData, handle, &tuple);
+		CS_CHECK(ParseTuple, handle, &tuple, &parse);
+		ver1 = &(parse.version_1);
+		
+		for (i = 0; i < sizeof(card_table)/sizeof(card_table[0]); i++) {
+			for (j = 0; j < ver1->ns; j++) {
+				char *p = card_table[i].ver1;
+				char *q = &ver1->str[ver1->ofs[j]];
+				if (!p)
+					goto mismatch;
+				for (k = 0; k < j; k++) {
+					while ((*p != '\0') && (*p != '/')) p++;
+					if (*p == '\0')
+						goto mismatch;
+					p++;
+				}
+				while((*q != '\0') && (*p != '\0') && 
+				      (*p != '/') && (*p == *q)) p++, q++;
+				if (((*p != '\0') && *p != '/') || *q != '\0')
+					goto mismatch;
+			}
+			card_index = i;
+			goto done;
+			
+		mismatch:
+			
+		}
+	done:
+	}		
+
+	/*
+	  This reads the card's CONFIG tuple to find its configuration
+	  registers.
+	*/
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	CS_CHECK(GetTupleData, handle, &tuple);
+	CS_CHECK(ParseTuple, handle, &tuple, &parse);
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+	
+	/* Configure card */
+	link->state |= DEV_CONFIG;
+	
+	/*
+	  In this loop, we scan the CIS for configuration table entries,
+	  each of which describes a valid card configuration, including
+	  voltage, IO window, memory window, and interrupt settings.
+	  
+	  We make no assumptions about the card to be configured: we use
+	  just the information available in the CIS.  In an ideal world,
+	  this would work for any PCMCIA card, but it requires a complete
+	  and accurate CIS.  In practice, a driver usually "knows" most of
+	  these things without consulting the CIS, and most client drivers
+	  will only use the CIS to fill in implementation-defined details.
+	*/
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	while (1) {
+		cistpl_cftable_entry_t dflt = { 0 };
+		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+		CFG_CHECK(GetTupleData, handle, &tuple);
+		CFG_CHECK(ParseTuple, handle, &tuple, &parse);
+		
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
+		if (cfg->index == 0) goto next_entry;
+		link->conf.ConfigIndex = cfg->index;
+		
+		/* Does this card need audio output? */
+		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+			link->conf.Attributes |= CONF_ENABLE_SPKR;
+			link->conf.Status = CCSR_AUDIO_ENA;
+		}
+		
+		/* Use power settings for Vcc and Vpp if present */
+		/*  Note that the CIS values need to be rescaled */
+		if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))
+			link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
+		else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))
+			link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
+		
+		if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
+			link->conf.Vpp1 = link->conf.Vpp2 =
+				cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
+		else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
+			link->conf.Vpp1 = link->conf.Vpp2 =
+				dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
+		
+		/* Do we need to allocate an interrupt? */
+		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+			link->conf.Attributes |= CONF_ENABLE_IRQ;
+		
+		/* IO window settings */
+		link->io.NumPorts1 = link->io.NumPorts2 = 0;
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+			if (!(io->flags & CISTPL_IO_8BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+			if (!(io->flags & CISTPL_IO_16BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.NumPorts1 = io->win[0].len;
+			if (io->nwin > 1) {
+				link->io.Attributes2 = link->io.Attributes1;
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = io->win[1].len;
+			}
+		}
+		
+		/* This reserves IO space but doesn't actually enable it */
+		CFG_CHECK(RequestIO, link->handle, &link->io); 
+		/* If we got this far, we're cool! */
+		break;
+		
+	next_entry:
+		CS_CHECK(GetNextTuple, handle, &tuple);
+	}
+	
+	/*
+	  Allocate an interrupt line.  Note that this does not assign a
+	  handler to the interrupt, unless the 'Handler' member of the
+	  irq structure is initialized.
+	*/
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		CS_CHECK(RequestIRQ, link->handle, &link->irq);
+	
+	/*
+	  This actually configures the PCMCIA socket -- setting up
+	  the I/O windows and the interrupt mapping, and putting the
+	  card and host interface into "Memory and IO" mode.
+	*/
+	CS_CHECK(RequestConfiguration, link->handle, &link->conf);
+	
+	if (link->irq.AssignedIRQ == 0) {
+		printk(KERN_ALERT 
+		       "atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
+		goto cs_failed;
+	}
+	
+	((local_info_t*)link->priv)->eth_dev = 
+		init_atmel_card(link->irq.AssignedIRQ,
+				link->io.BasePort1,
+				card_index == -1 ? NULL :  card_table[card_index].firmware,
+				card_index == -1 ? 0 : (card_table[card_index].manf == MANFID_3COM),
+				&atmel_device,
+				card_present, 
+				link);
+	if (!((local_info_t*)link->priv)->eth_dev) 
+		goto cs_failed;
+	
+	/*
+	  At this point, the dev_node_t structure(s) need to be
+	  initialized and arranged in a linked list at link->dev.
+	*/
+	strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
+	dev->node.major = dev->node.minor = 0;
+	link->dev = &dev->node;
+	
+	/* Finally, report what we've done */
+	printk(KERN_INFO "%s: %s%sindex 0x%02x: Vcc %d.%d",
+	       dev->node.dev_name,
+	       card_index == -1 ? "" :  card_table[card_index].name,
+	       card_index == -1 ? "" : " ",
+	       link->conf.ConfigIndex,
+	       link->conf.Vcc/10, link->conf.Vcc%10);
+	if (link->conf.Vpp1)
+		printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		printk(", irq %d", link->irq.AssignedIRQ);
+	if (link->io.NumPorts1)
+		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+		       link->io.BasePort1+link->io.NumPorts1-1);
+	if (link->io.NumPorts2)
+		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+		       link->io.BasePort2+link->io.NumPorts2-1);
+	printk("\n");
+	
+	link->state &= ~DEV_CONFIG_PENDING;
+	return;
+	
+ cs_failed:
+	cs_error(link->handle, last_fn, last_ret);
+	atmel_release((u_long)link);
+	
+} /* atmel_config */
+
+/*======================================================================
+  
+  After a card is removed, atmel_release() will unregister the
+  device, and release the PCMCIA configuration.  If the device is
+  still open, this will be postponed until it is closed.
+  
+  ======================================================================*/
+
+static void atmel_release(u_long arg)
+{
+	dev_link_t *link = (dev_link_t *)arg;
+	struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
+		
+	DEBUG(0, "atmel_release(0x%p)\n", link);
+	
+	/* Unlink the device chain */
+	link->dev = NULL;
+	
+	if (dev) 
+		stop_atmel_card(dev, 0);
+	((local_info_t*)link->priv)->eth_dev = 0; 
+	
+	/* Don't bother checking to see if these succeed or not */
+	CardServices(ReleaseConfiguration, link->handle);
+	if (link->io.NumPorts1)
+		CardServices(ReleaseIO, link->handle, &link->io);
+	if (link->irq.AssignedIRQ)
+		CardServices(ReleaseIRQ, link->handle, &link->irq);
+	link->state &= ~DEV_CONFIG;
+	
+} /* atmel_release */
+
+/*======================================================================
+  
+  The card status event handler.  Mostly, this schedules other
+  stuff to run after an event is received.
+
+  When a CARD_REMOVAL event is received, we immediately set a
+  private flag to block future accesses to this device.  All the
+  functions that actually access the device should check this flag
+  to make sure the card is still present.
+  
+  ======================================================================*/
+
+static int atmel_event(event_t event, int priority,
+		      event_callback_args_t *args)
+{
+	dev_link_t *link = args->client_data;
+	local_info_t *local = link->priv;
+	
+	DEBUG(1, "atmel_event(0x%06x)\n", event);
+	
+	switch (event) {
+	case CS_EVENT_CARD_REMOVAL:
+		link->state &= ~DEV_PRESENT;
+		if (link->state & DEV_CONFIG) {
+			netif_device_detach(local->eth_dev);
+			mod_timer(&link->release, jiffies + HZ/20);
+		}
+		break;
+	case CS_EVENT_CARD_INSERTION:
+		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+		atmel_config(link);
+		break;
+	case CS_EVENT_PM_SUSPEND:
+		link->state |= DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_RESET_PHYSICAL:
+		if (link->state & DEV_CONFIG) {
+			netif_device_detach(local->eth_dev);
+			CardServices(ReleaseConfiguration, link->handle);
+		}
+		break;
+	case CS_EVENT_PM_RESUME:
+		link->state &= ~DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_CARD_RESET:
+		if (link->state & DEV_CONFIG) {
+			CardServices(RequestConfiguration, link->handle, &link->conf);
+			reset_atmel_card(local->eth_dev);
+			netif_device_attach(local->eth_dev);
+		}
+		break;
+	}
+	return 0;
+} /* atmel_event */
+
+/*====================================================================*/
+static struct pcmcia_driver atmel_driver = {
+        .owner          = THIS_MODULE,
+        .drv            = {
+                .name   = "atmel_cs",
+        },
+        .attach         = atmel_attach,
+        .detach         = atmel_detach,
+};
+
+static int atmel_cs_init(void)
+{
+        return pcmcia_register_driver(&atmel_driver);
+}
+
+static void atmel_cs_cleanup(void)
+{
+        pcmcia_unregister_driver(&atmel_driver);
+
+        /* XXX: this really needs to move into generic code.. */
+        while (dev_list != NULL) {
+                if (dev_list->state & DEV_CONFIG)
+                        atmel_release((u_long)dev_list);
+                atmel_detach(dev_list);
+        }
+}
+
+/*
+    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.
+
+    In addition:
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. The name of the author may not be used to endorse or promote
+       products derived from this software without specific prior written
+       permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.    
+*/
+
+module_init(atmel_cs_init);
+module_exit(atmel_cs_cleanup);
diff -urN linux-2.5.70-bk10/drivers/pci/pci.h linux-2.5.70-bk11/drivers/pci/pci.h
--- linux-2.5.70-bk10/drivers/pci/pci.h	2003-06-06 04:38:14.000000000 -0700
+++ linux-2.5.70-bk11/drivers/pci/pci.h	2003-06-06 04:38:24.000000000 -0700
@@ -25,7 +25,6 @@
 /* Functions for PCI Hotplug drivers to use */
 extern struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
 extern unsigned int pci_do_scan_bus(struct pci_bus *bus);
-extern void pci_remove_bus_device(struct pci_dev *dev);
 extern int pci_remove_device_safe(struct pci_dev *dev);
 extern unsigned char pci_max_busnr(void);
 extern unsigned char pci_bus_max_busnr(struct pci_bus *bus);
diff -urN linux-2.5.70-bk10/drivers/pci/pci.ids linux-2.5.70-bk11/drivers/pci/pci.ids
--- linux-2.5.70-bk10/drivers/pci/pci.ids	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk11/drivers/pci/pci.ids	2003-06-06 04:38:24.000000000 -0700
@@ -3745,19 +3745,26 @@
 11fc  Silicon Magic
 11fd  High Street Consultants
 11fe  Comtrol Corporation
-	0001  RocketPort 8 Oct
-	0002  RocketPort 8 Intf
-	0003  RocketPort 16 Intf
-	0004  RocketPort 32 Intf
-	0005  RocketPort Octacable
-	0006  RocketPort 8J
-	0007  RocketPort 4-port
-	0008  RocketPort 8-port
-	0009  RocketPort 16-port
-	000a  RocketPort Plus Quadcable
-	000b  RocketPort Plus Octacable
-	000c  RocketPort 8-port Modem
-	8015  RocketPort 4-port UART 16954
+	0001  Rocketport 32 port w/external I/F
+	0002  Rocketport 8 port w/external I/F
+	0003  Rocketport 16 port w/external I/F
+	0004  Rocketport 4 port w/quad cable
+	0005  Rocketport 8 port w/octa cable
+	0006  Rocketport 8 port w/RJ11 connectors
+	0007  Rocketport 4 port w/RJ11 connectors
+	000a  Rocketport Plus 4 port
+	000b  Rocketport Plus 8 port
+	000c  RocketModem 6 port
+	000d  RocketModem 4-port
+	000e  Rocketport Plus 2 port RS232
+	000f  Rocketport Plus 2 port RS422
+	0801  Rocketport UPCI 32 port w/external I/F
+	0802  Rocketport UPCI 8 port w/external I/F
+	0803  Rocketport UPCI 16 port w/external I/F
+	0805  Rocketport UPCI 8 port w/octa cable
+	080C  RocketModem III 8 port
+	080D  RocketModem III 4 port
+	0903  Rocketport Compact PCI 16 port w/external I/F
 11ff  Scion Corporation
 1200  CSS Corporation
 1201  Vista Controls Corp
diff -urN linux-2.5.70-bk10/drivers/pci/probe.c linux-2.5.70-bk11/drivers/pci/probe.c
--- linux-2.5.70-bk10/drivers/pci/probe.c	2003-06-06 04:38:14.000000000 -0700
+++ linux-2.5.70-bk11/drivers/pci/probe.c	2003-06-06 04:38:24.000000000 -0700
@@ -689,7 +689,6 @@
 }
 EXPORT_SYMBOL(pci_scan_bus_parented);
 
-EXPORT_SYMBOL(pci_devices);
 EXPORT_SYMBOL(pci_root_buses);
 
 #ifdef CONFIG_HOTPLUG
diff -urN linux-2.5.70-bk10/drivers/pci/search.c linux-2.5.70-bk11/drivers/pci/search.c
--- linux-2.5.70-bk10/drivers/pci/search.c	2003-06-06 04:38:14.000000000 -0700
+++ linux-2.5.70-bk11/drivers/pci/search.c	2003-06-06 04:38:25.000000000 -0700
@@ -118,6 +118,34 @@
 
 
 /**
+ * pci_find_device_reverse - begin or continue searching for a PCI device by vendor/device id
+ * @vendor: PCI vendor id to match, or %PCI_ANY_ID to match all vendor ids
+ * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids
+ * @from: Previous PCI device found in search, or %NULL for new search.
+ *
+ * Iterates through the list of known PCI devices in the reverse order of pci_find_device().
+ * If a PCI device is found with a matching @vendor and @device, a pointer to
+ * its device structure is returned.  Otherwise, %NULL is returned.
+ * A new search is initiated by passing %NULL to the @from argument.
+ * Otherwise if @from is not %NULL, searches continue from previous device on the global list.
+ */
+struct pci_dev *
+pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct pci_dev *from)
+{
+	struct list_head *n = from ? from->global_list.prev : pci_devices.prev;
+
+	while (n != &pci_devices) {
+		struct pci_dev *dev = pci_dev_g(n);
+		if ((vendor == PCI_ANY_ID || dev->vendor == vendor) &&
+		    (device == PCI_ANY_ID || dev->device == device))
+			return dev;
+		n = n->prev;
+	}
+	return NULL;
+}
+
+
+/**
  * pci_find_class - begin or continue searching for a PCI device by class
  * @class: search for a PCI device with this class designation
  * @from: Previous PCI device found in search, or %NULL for new search.
@@ -143,8 +171,20 @@
 	return NULL;
 }
 
+/**
+ * pci_present - determine if there are any pci devices on this system
+ *
+ * Returns 0 if no pci devices are present, 1 if pci devices are present.
+ */
+int pci_present(void)
+{
+	return !list_empty(&pci_devices);
+}
+
 EXPORT_SYMBOL(pci_find_bus);
 EXPORT_SYMBOL(pci_find_class);
 EXPORT_SYMBOL(pci_find_device);
+EXPORT_SYMBOL(pci_find_device_reverse);
 EXPORT_SYMBOL(pci_find_slot);
 EXPORT_SYMBOL(pci_find_subsys);
+EXPORT_SYMBOL(pci_present);
diff -urN linux-2.5.70-bk10/drivers/scsi/Kconfig linux-2.5.70-bk11/drivers/scsi/Kconfig
--- linux-2.5.70-bk10/drivers/scsi/Kconfig	2003-05-26 18:00:57.000000000 -0700
+++ linux-2.5.70-bk11/drivers/scsi/Kconfig	2003-06-06 04:38:25.000000000 -0700
@@ -1559,7 +1559,7 @@
 
 config SCSI_MESH
 	tristate "MESH (Power Mac internal SCSI) support"
-	depends on ALL_PPC && SCSI
+	depends on PPC_PMAC && SCSI
 	help
 	  Many Power Macintoshes and clones have a MESH (Macintosh Enhanced
 	  SCSI Hardware) SCSI bus adaptor (the 7200 doesn't, but all of the
@@ -1590,7 +1590,7 @@
 
 config SCSI_MAC53C94
 	tristate "53C94 (Power Mac external SCSI) support"
-	depends on ALL_PPC && SCSI
+	depends on PPC_PMAC && SCSI
 	help
 	  On Power Macintoshes (and clones) with two SCSI buses, the external
 	  SCSI bus is usually controlled by a 53C94 SCSI bus adaptor. Older
diff -urN linux-2.5.70-bk10/drivers/serial/sunsab.c linux-2.5.70-bk11/drivers/serial/sunsab.c
--- linux-2.5.70-bk10/drivers/serial/sunsab.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk11/drivers/serial/sunsab.c	2003-06-06 04:38:26.000000000 -0700
@@ -231,8 +231,10 @@
 		set_bit(SAB82532_ALLS, &up->irqflags);
 	}
 
+#if 0 /* bde@nwlink.com says this check causes problems */
 	if (!(stat->sreg.isr1 & SAB82532_ISR1_XPR))
 		return;
+#endif
 
 	if (!(readb(&up->regs->r.star) & SAB82532_STAR_XFW))
 		return;
@@ -242,6 +244,7 @@
 	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
 		up->interrupt_mask1 |= SAB82532_IMR1_XPR;
 		writeb(up->interrupt_mask1, &up->regs->w.imr1);
+		uart_write_wakeup(&up->port);
 		return;
 	}
 
diff -urN linux-2.5.70-bk10/drivers/usb/image/hpusbscsi.c linux-2.5.70-bk11/drivers/usb/image/hpusbscsi.c
--- linux-2.5.70-bk10/drivers/usb/image/hpusbscsi.c	2003-06-06 04:38:14.000000000 -0700
+++ linux-2.5.70-bk11/drivers/usb/image/hpusbscsi.c	2003-06-06 04:38:26.000000000 -0700
@@ -93,17 +93,6 @@
 		}
 	}
 
-	/* USB initialisation magic for the simple case */
-	result = usb_set_interface(dev, altsetting->desc.bInterfaceNumber, 0);
-	switch (result) {
-	case 0:		/* no error */
-		break;
-	default:
-		printk(KERN_ERR "unknown error %d from usb_set_interface\n",
-			 result);
-		goto out_free_controlurb;
-	}
-
 	/* build and submit an interrupt URB for status byte handling */
  	usb_fill_int_urb(new->controlurb, new->dev,
 			usb_rcvintpipe(new->dev, new->ep_int),
diff -urN linux-2.5.70-bk10/drivers/usb/input/hid-input.c linux-2.5.70-bk11/drivers/usb/input/hid-input.c
--- linux-2.5.70-bk10/drivers/usb/input/hid-input.c	2003-06-06 04:38:14.000000000 -0700
+++ linux-2.5.70-bk11/drivers/usb/input/hid-input.c	2003-06-06 04:38:26.000000000 -0700
@@ -70,8 +70,11 @@
 
 		hidinput = list_entry(lh, struct hid_input, list);
 
-		for (i = 0; i < hidinput->maxfield; i++)
-			if (hidinput->fields[i] == field)
+		if (! hidinput->report)
+			continue;
+
+		for (i = 0; i < hidinput->report->maxfield; i++)
+			if (hidinput->report->field[i] == field)
 				return &hidinput->input;
 	}
 
@@ -527,7 +530,7 @@
 	struct hid_report *report;
 	struct list_head *list;
 	struct hid_input *hidinput = NULL;
-	int i, j;
+	int i, j, k;
 
 	INIT_LIST_HEAD(&hid->inputs);
 
@@ -539,57 +542,57 @@
 	if (i == hid->maxcollection)
 		return -1;
 
-	report_enum = hid->report_enum + HID_INPUT_REPORT;
-	list = report_enum->report_list.next;
-	while (list != &report_enum->report_list) {
-		report = (struct hid_report *) list;
+	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
+		report_enum = hid->report_enum + k;
+		list = report_enum->report_list.next;
+		while (list != &report_enum->report_list) {
+			report = (struct hid_report *) list;
 
-		if (!report->maxfield)
-			continue;
+			if (!report->maxfield)
+				continue;
 
-		if (!hidinput) {
-			hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL);
 			if (!hidinput) {
-				err("Out of memory during hid input probe");
-				return -1;
-			}
-			memset(hidinput, 0, sizeof(*hidinput));
-
-			list_add_tail(&hidinput->list, &hid->inputs);
+				hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL);
+				if (!hidinput) {
+					err("Out of memory during hid input probe");
+					return -1;
+				}
+				memset(hidinput, 0, sizeof(*hidinput));
 
-			hidinput->input.private = hid;
-			hidinput->input.event = hidinput_input_event;
-			hidinput->input.open = hidinput_open;
-			hidinput->input.close = hidinput_close;
-
-			hidinput->input.name = hid->name;
-			hidinput->input.phys = hid->phys;
-			hidinput->input.uniq = hid->uniq;
-			hidinput->input.id.bustype = BUS_USB;
-			hidinput->input.id.vendor = dev->descriptor.idVendor;
-			hidinput->input.id.product = dev->descriptor.idProduct;
-			hidinput->input.id.version = dev->descriptor.bcdDevice;
-		}
+				list_add_tail(&hidinput->list, &hid->inputs);
 
-		for (i = 0; i < report->maxfield; i++)
-			for (j = 0; j < report->field[i]->maxusage; j++)
-				hidinput_configure_usage(hidinput, report->field[i],
-							 report->field[i]->usage + j);
-
-		if (hid->quirks & HID_QUIRK_MULTI_INPUT) {
-			/* This will leave hidinput NULL, so that it
-			 * allocates another one if we have more inputs on
-			 * the same interface. Some devices (e.g. Happ's
-			 * UGCI) cram a lot of unrelated inputs into the
-			 * same interface. */
-			hidinput->fields = report->field;
-			hidinput->maxfield = report->maxfield;
+				hidinput->input.private = hid;
+				hidinput->input.event = hidinput_input_event;
+				hidinput->input.open = hidinput_open;
+				hidinput->input.close = hidinput_close;
+
+				hidinput->input.name = hid->name;
+				hidinput->input.phys = hid->phys;
+				hidinput->input.uniq = hid->uniq;
+				hidinput->input.id.bustype = BUS_USB;
+				hidinput->input.id.vendor = dev->descriptor.idVendor;
+				hidinput->input.id.product = dev->descriptor.idProduct;
+				hidinput->input.id.version = dev->descriptor.bcdDevice;
+			}
+
+			for (i = 0; i < report->maxfield; i++)
+				for (j = 0; j < report->field[i]->maxusage; j++)
+					hidinput_configure_usage(hidinput, report->field[i],
+								 report->field[i]->usage + j);
+
+			if (hid->quirks & HID_QUIRK_MULTI_INPUT) {
+				/* This will leave hidinput NULL, so that it
+				 * allocates another one if we have more inputs on
+				 * the same interface. Some devices (e.g. Happ's
+				 * UGCI) cram a lot of unrelated inputs into the
+				 * same interface. */
+				hidinput->report = report;
+				input_register_device(&hidinput->input);
+				hidinput = NULL;
+			}
 
-			input_register_device(&hidinput->input);
-			hidinput = NULL;
+			list = list->next;
 		}
-
-		list = list->next;
 	}
 
 	/* This only gets called when we are a single-input (most of the
diff -urN linux-2.5.70-bk10/drivers/usb/input/hid.h linux-2.5.70-bk11/drivers/usb/input/hid.h
--- linux-2.5.70-bk10/drivers/usb/input/hid.h	2003-06-06 04:38:14.000000000 -0700
+++ linux-2.5.70-bk11/drivers/usb/input/hid.h	2003-06-06 04:38:26.000000000 -0700
@@ -324,8 +324,7 @@
 
 struct hid_input {
 	struct list_head list;
-	struct hid_field **fields;
-	int maxfield;
+	struct hid_report *report;
 	struct input_dev input;
 };
 
diff -urN linux-2.5.70-bk10/drivers/usb/serial/empeg.c linux-2.5.70-bk11/drivers/usb/serial/empeg.c
--- linux-2.5.70-bk10/drivers/usb/serial/empeg.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/drivers/usb/serial/empeg.c	2003-06-06 04:38:27.000000000 -0700
@@ -460,14 +460,15 @@
 
 static int  empeg_startup (struct usb_serial *serial)
 {
+	int r;
 
 	dbg("%s", __FUNCTION__);
 
 	dbg("%s - Set config to 1", __FUNCTION__);
-	usb_set_configuration (serial->dev, 1);
+	r = usb_set_configuration (serial->dev, 1);
 
 	/* continue on with initialization */
-	return 0;
+	return r;
 
 }
 
diff -urN linux-2.5.70-bk10/drivers/video/Kconfig linux-2.5.70-bk11/drivers/video/Kconfig
--- linux-2.5.70-bk10/drivers/video/Kconfig	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk11/drivers/video/Kconfig	2003-06-06 04:38:28.000000000 -0700
@@ -235,28 +235,28 @@
 
 config FB_OF
 	bool "Open Firmware frame buffer device support"
-	depends on FB && (PPC64 || (PPC && ALL_PPC))
+	depends on FB && (PPC64 || PPC_OF)
 	help
 	  Say Y if you want support with Open Firmware for your graphics
 	  board.
 
 config FB_CONTROL
 	bool "Apple \"control\" display support"
-	depends on FB && PPC && ALL_PPC
+	depends on FB && PPC_PMAC
 	help
 	  This driver supports a frame buffer for the graphics adapter in the
 	  Power Macintosh 7300 and others.
 
 config FB_PLATINUM
 	bool "Apple \"platinum\" display support"
-	depends on FB && PPC && ALL_PPC
+	depends on FB && PPC_PMAC
 	help
 	  This driver supports a frame buffer for the "platinum" graphics
 	  adapter in some Power Macintoshes.
 
 config FB_VALKYRIE
 	bool "Apple \"valkyrie\" display support"
-	depends on FB && (MAC || PPC && ALL_PPC)
+	depends on FB && (MAC || PPC_PMAC)
 	help
 	  This driver supports a frame buffer for the "valkyrie" graphics
 	  adapter in some Power Macintoshes.
diff -urN linux-2.5.70-bk10/drivers/video/aty/aty128fb.c linux-2.5.70-bk11/drivers/video/aty/aty128fb.c
--- linux-2.5.70-bk10/drivers/video/aty/aty128fb.c	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk11/drivers/video/aty/aty128fb.c	2003-06-06 04:38:28.000000000 -0700
@@ -59,7 +59,7 @@
 #include <linux/ioport.h>
 #include <asm/io.h>
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include "../macmodes.h"
@@ -93,7 +93,7 @@
 #define DBG(fmt, args...)
 #endif
 
-#ifndef CONFIG_ALL_PPC
+#ifndef CONFIG_PPC_PMAC
 /* default mode */
 static struct fb_var_screeninfo default_var __initdata = {
 	/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
@@ -103,7 +103,7 @@
 	0, FB_VMODE_NONINTERLACED
 };
 
-#else /* CONFIG_ALL_PPC */
+#else /* CONFIG_PPC_PMAC */
 /* default to 1024x768 at 75Hz on PPC - this will work
  * on the iMac, the usual 640x480 @ 60Hz doesn't. */
 static struct fb_var_screeninfo default_var = {
@@ -114,7 +114,7 @@
 	FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
 	FB_VMODE_NONINTERLACED
 };
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 
 /* default modedb mode */
 /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
@@ -259,7 +259,7 @@
 
 static char *mode_option __initdata = NULL;
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 static int default_vmode __initdata = VMODE_1024_768_60;
 static int default_cmode __initdata = CMODE_8;
 #endif
@@ -1434,7 +1434,7 @@
 			continue;
 		}
 #endif
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 		/* vmode and cmode deprecated */
 		if (!strncmp(this_opt, "vmode:", 6)) {
 			unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
@@ -1459,7 +1459,7 @@
 			}
 			continue;
 		}
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 		mode_option = this_opt;
 	}
 	return 0;
@@ -1543,7 +1543,7 @@
 #endif
 
 	var = default_var;
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 	if (_machine == _MACH_Pmac) {
 		if (mode_option) {
 			if (!mac_find_mode(&var, info, mode_option, 8))
@@ -1582,7 +1582,7 @@
 				var = default_var;
 		}
 	} else
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 	{
 		if (fb_find_mode(&var, info, mode_option, NULL, 0,
 				 &defaultmode, 8) == 0)
@@ -1872,7 +1872,7 @@
 static void __init
 aty128_timings(struct aty128fb_par *par)
 {
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 	/* instead of a table lookup, assume OF has properly
 	 * setup the PLL registers and use their values
 	 * to set the XCLK values and reference divider values */
@@ -1886,7 +1886,7 @@
 	if (!par->constants.dotclock)
 		par->constants.dotclock = 2950;
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 	x_mpll_ref_fb_div = aty_ld_pll(X_MPLL_REF_FB_DIV);
 	xclk_cntl = aty_ld_pll(XCLK_CNTL) & 0x7;
 	Nx = (x_mpll_ref_fb_div & 0x00ff00) >> 8;
diff -urN linux-2.5.70-bk10/drivers/video/cirrusfb.c linux-2.5.70-bk11/drivers/video/cirrusfb.c
--- linux-2.5.70-bk10/drivers/video/cirrusfb.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk11/drivers/video/cirrusfb.c	2003-06-06 04:38:28.000000000 -0700
@@ -56,7 +56,7 @@
 #ifdef CONFIG_AMIGA
 #include <asm/amigahw.h>
 #endif
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PREP
 #include <asm/processor.h>
 #define isPReP (_machine == _MACH_prep)
 #else
@@ -2395,7 +2395,7 @@
 
 
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PREP
 #define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
 #define PREP_IO_BASE    ((volatile unsigned char *) 0x80000000)
 static void __init get_prep_addrs (unsigned long *display, unsigned long *registers)
@@ -2408,7 +2408,7 @@
 	DPRINTK ("EXIT\n");
 }
 
-#endif				/* CONFIG_ALL_PPC */
+#endif				/* CONFIG_PPC_PREP */
 
 
 
@@ -2543,7 +2543,7 @@
 		pcibios_write_config_dword (0, pdev->devfn, PCI_BASE_ADDRESS_0,
 			0x00000000);
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PREP
 		get_prep_addrs (&board_addr, &info->fbregs_phys);
 #endif
 	} else {
diff -urN linux-2.5.70-bk10/drivers/video/fbmon.c linux-2.5.70-bk11/drivers/video/fbmon.c
--- linux-2.5.70-bk10/drivers/video/fbmon.c	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk11/drivers/video/fbmon.c	2003-06-06 04:38:28.000000000 -0700
@@ -29,7 +29,7 @@
 #include <linux/tty.h>
 #include <linux/fb.h>
 #include <linux/module.h>
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 #include <linux/pci.h>
 #include <asm/prom.h>
 #endif
@@ -828,7 +828,7 @@
 	printk("========================================\n");
 }
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 char *get_EDID_from_OF(struct pci_dev *pdev)
 {
 	static char *propnames[] =
@@ -1256,7 +1256,7 @@
 #ifdef CONFIG_X86
 EXPORT_SYMBOL(get_EDID_from_BIOS);
 #endif
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 EXPORT_SYMBOL(get_EDID_from_OF);
 #endif
 EXPORT_SYMBOL(fb_get_monitor_limits);
diff -urN linux-2.5.70-bk10/drivers/video/matrox/matroxfb_base.c linux-2.5.70-bk11/drivers/video/matrox/matroxfb_base.c
--- linux-2.5.70-bk10/drivers/video/matrox/matroxfb_base.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/drivers/video/matrox/matroxfb_base.c	2003-06-06 04:38:28.000000000 -0700
@@ -115,7 +115,7 @@
 #include <linux/interrupt.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 unsigned char nvram_read_byte(int);
 static int default_vmode = VMODE_NVRAM;
 static int default_cmode = CMODE_NVRAM;
@@ -1763,7 +1763,7 @@
 	}
 
 	/* FIXME: Where to move this?! */
-#if defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_PPC_PMAC)
 #ifndef MODULE
 	if (_machine == _MACH_Pmac) {
 		struct fb_var_screeninfo var;
@@ -1783,7 +1783,7 @@
 		}
 	}
 #endif /* !MODULE */
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 	vesafb_defined.xres_virtual = vesafb_defined.xres;
 	if (nopan) {
 		vesafb_defined.yres_virtual = vesafb_defined.yres;
@@ -2270,7 +2270,7 @@
 			dfp_type = simple_strtoul(this_opt+4, NULL, 0);
 			dfp = 1;
 		}	
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 		else if (!strncmp(this_opt, "vmode:", 6)) {
 			unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
 			if (vmode > 0 && vmode <= VMODE_MAX)
@@ -2441,7 +2441,7 @@
 MODULE_PARM_DESC(dfp, "Specifies whether to use digital flat panel interface of G200/G400 (0 or 1) (default=0)");
 MODULE_PARM(dfp_type, "i");
 MODULE_PARM_DESC(dfp_type, "Specifies DFP interface type (0 to 255) (default=read from hardware)");
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 MODULE_PARM(vmode, "i");
 MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)");
 MODULE_PARM(cmode, "i");
diff -urN linux-2.5.70-bk10/drivers/video/matrox/matroxfb_base.h linux-2.5.70-bk11/drivers/video/matrox/matroxfb_base.h
--- linux-2.5.70-bk10/drivers/video/matrox/matroxfb_base.h	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/drivers/video/matrox/matroxfb_base.h	2003-06-06 04:38:28.000000000 -0700
@@ -52,7 +52,7 @@
 
 #include "../console/fbcon.h"
 
-#if defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_PPC_PMAC)
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <video/macmodes.h>
diff -urN linux-2.5.70-bk10/drivers/video/radeonfb.c linux-2.5.70-bk11/drivers/video/radeonfb.c
--- linux-2.5.70-bk10/drivers/video/radeonfb.c	2003-05-26 18:00:59.000000000 -0700
+++ linux-2.5.70-bk11/drivers/video/radeonfb.c	2003-06-06 04:38:28.000000000 -0700
@@ -707,7 +707,7 @@
 static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo);
 static void radeon_update_default_var(struct radeonfb_info *rinfo);
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 
 static int radeon_read_OF (struct radeonfb_info *rinfo);
 static int radeon_get_EDID_OF(struct radeonfb_info *rinfo);
@@ -728,7 +728,7 @@
 };
 #endif /* CONFIG_PMAC_BACKLIGHT */
 
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_OF */
 
 
 static char *radeon_find_rom(struct radeonfb_info *rinfo)
@@ -830,7 +830,7 @@
 		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",
 			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
 	} else {
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 		if (radeon_read_OF(rinfo)) {
 			unsigned int tmp, Nx, M, ref_div, xclk;
 
@@ -965,7 +965,7 @@
 
 static void radeon_get_EDID(struct radeonfb_info *rinfo)
 {
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 	if (!radeon_get_EDID_OF(rinfo))
 		RTRACE("radeonfb: could not retrieve EDID from OF\n");
 #else
@@ -974,7 +974,7 @@
 }
 
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 static int radeon_get_EDID_OF(struct radeonfb_info *rinfo)
 {
         struct device_node *dp;
@@ -996,7 +996,7 @@
         }
         return 0;
 }
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_OF */
 
 
 static int radeon_dfp_parse_EDID(struct radeonfb_info *rinfo)
@@ -1209,7 +1209,7 @@
 }
 
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 static int radeon_read_OF (struct radeonfb_info *rinfo)
 {
 	struct device_node *dp;
@@ -1957,11 +1957,11 @@
 	}
 	newmode.vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 	/* Gross hack for iBook with M7 until I find out a proper fix */
 	if (machine_is_compatible("PowerBook4,3") && rinfo->arch == RADEON_M7)
 		newmode.ppll_div_3 = 0x000600ad;
-#endif /* CONFIG_ALL_PPC */	
+#endif /* CONFIG_PPC_OF */	
 
 	RTRACE("post div = 0x%x\n", rinfo->post_div);
 	RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
diff -urN linux-2.5.70-bk10/drivers/video/riva/fbdev.c linux-2.5.70-bk11/drivers/video/riva/fbdev.c
--- linux-2.5.70-bk10/drivers/video/riva/fbdev.c	2003-05-26 18:00:44.000000000 -0700
+++ linux-2.5.70-bk11/drivers/video/riva/fbdev.c	2003-06-06 04:38:28.000000000 -0700
@@ -1606,7 +1606,7 @@
 	return 0;
 }
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 static int riva_get_EDID_OF(struct riva_par *par, struct pci_dev *pd)
 {
 	struct device_node *dp;
@@ -1621,7 +1621,7 @@
 	} else
 		return 0;
 }
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_OF */
 
 static int riva_dfp_parse_EDID(struct riva_par *par)
 {
@@ -1699,7 +1699,7 @@
 
 static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
 {
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 	if (!riva_get_EDID_OF(info, pdev))
 		printk("rivafb: could not retrieve EDID from OF\n");
 #else
diff -urN linux-2.5.70-bk10/fs/filesystems.c linux-2.5.70-bk11/fs/filesystems.c
--- linux-2.5.70-bk10/fs/filesystems.c	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk11/fs/filesystems.c	2003-06-06 04:38:28.000000000 -0700
@@ -49,38 +49,6 @@
 	return p;
 }
 
-
-/* define fs_subsys */
-static decl_subsys(fs, NULL, NULL);
-
-static int register_fs_subsys(struct file_system_type * fs)
-{
-	struct subsystem *sub = &fs->subsys;
-
-	snprintf(sub->kset.kobj.name, KOBJ_NAME_LEN, "%s", fs->name);
-	subsys_set_kset(fs, fs_subsys);
-	return subsystem_register(sub);
-}
-
-static int unlink_fs(struct file_system_type * fs)
-{
-	struct file_system_type ** tmp;
-
-	write_lock(&file_systems_lock);
-	tmp = &file_systems;
-	while (*tmp) {
-		if (fs == *tmp) {
-			*tmp = fs->next;
-			fs->next = NULL;
-			write_unlock(&file_systems_lock);
-			return 0;
-		}
-		tmp = &(*tmp)->next;
-	}
-	write_unlock(&file_systems_lock);
-	return -EINVAL;
-}
-
 /**
  *	register_filesystem - register a new filesystem
  *	@fs: the file system structure
@@ -111,12 +79,6 @@
 	else
 		*p = fs;
 	write_unlock(&file_systems_lock);
-
-	if (!res) {
-		/* we implicitly possess reference to @fs during registration,
-		 * so it cannot be unregister from under us. */
-		register_fs_subsys(fs);
-	}
 	return res;
 }
 
@@ -134,44 +96,21 @@
  
 int unregister_filesystem(struct file_system_type * fs)
 {
-	int res;
-
-	res = unlink_fs(fs);
-	if (!res)
-		subsystem_unregister(&fs->subsys);
-	return res;
-}
-
-extern int sysfs_init(void);
-
-/**
- *	fs_subsys_init - initialize sysfs and fs subsystem.
- *
- *	In order to register filesystems in sysfs, it has to be 
- *	initialized. Also, we need the base fs filesystem, so the 
- *	registered filesystems have a home.
- *	
- *	During sysfs_init(), the registration of sysfs into itself
- *	will fail, since it's not mounted yet. To make sure that 
- *	sysfs does show up, we re-register sysfs's embedded subsystem,
- *	which will get added, since sysfs is now mounted.
- */
-
-void __init fs_subsys_init(void)
-{
-	struct file_system_type ** p;
-
-	/* make sure sysfs is up and running */
-	sysfs_init();
-
-	/* register fs_subsys */
-	subsystem_register(&fs_subsys);
-
-	p = find_filesystem("sysfs");
+	struct file_system_type ** tmp;
 
-	if (p)
-		/* make sure it's registered */
-		register_fs_subsys(*p);
+	write_lock(&file_systems_lock);
+	tmp = &file_systems;
+	while (*tmp) {
+		if (fs == *tmp) {
+			*tmp = fs->next;
+			fs->next = NULL;
+			write_unlock(&file_systems_lock);
+			return 0;
+		}
+		tmp = &(*tmp)->next;
+	}
+	write_unlock(&file_systems_lock);
+	return -EINVAL;
 }
 
 static int fs_index(const char __user * __name)
diff -urN linux-2.5.70-bk10/fs/namespace.c linux-2.5.70-bk11/fs/namespace.c
--- linux-2.5.70-bk10/fs/namespace.c	2003-05-26 18:00:42.000000000 -0700
+++ linux-2.5.70-bk11/fs/namespace.c	2003-06-06 04:38:28.000000000 -0700
@@ -24,7 +24,7 @@
 #include <asm/uaccess.h>
 
 extern int __init init_rootfs(void);
-extern int __init fs_subsys_init(void);
+extern int __init sysfs_init(void);
 
 static struct list_head *mount_hashtable;
 static int hash_mask, hash_bits;
@@ -1144,7 +1144,7 @@
 		d++;
 		i--;
 	} while (i);
-	fs_subsys_init();
+	sysfs_init();
 	init_rootfs();
 	init_mount_tree();
 }
diff -urN linux-2.5.70-bk10/fs/partitions/mac.c linux-2.5.70-bk11/fs/partitions/mac.c
--- linux-2.5.70-bk10/fs/partitions/mac.c	2003-05-26 18:00:25.000000000 -0700
+++ linux-2.5.70-bk11/fs/partitions/mac.c	2003-06-06 04:38:28.000000000 -0700
@@ -11,7 +11,7 @@
 #include "check.h"
 #include "mac.h"
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 extern void note_bootable_part(dev_t dev, int part, int goodness);
 #endif
 
@@ -34,7 +34,7 @@
 	unsigned char *data;
 	int blk, blocks_in_map;
 	unsigned secsize;
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 	int found_root = 0;
 	int found_root_goodness = 0;
 #endif
@@ -74,7 +74,7 @@
 			be32_to_cpu(part->start_block) * (secsize/512),
 			be32_to_cpu(part->block_count) * (secsize/512));
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 		/*
 		 * If this is the first bootable partition, tell the
 		 * setup code, in case it wants to make this the root.
@@ -115,11 +115,11 @@
 				found_root_goodness = goodness;
 			}
 		}
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_PMAC */
 
 		++slot;
 	}
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 	if (found_root_goodness)
 		note_bootable_part(bdev->bd_dev, found_root, found_root_goodness);
 #endif
diff -urN linux-2.5.70-bk10/include/asm-alpha/agp_backend.h linux-2.5.70-bk11/include/asm-alpha/agp_backend.h
--- linux-2.5.70-bk10/include/asm-alpha/agp_backend.h	2003-05-26 18:00:19.000000000 -0700
+++ linux-2.5.70-bk11/include/asm-alpha/agp_backend.h	2003-06-06 04:38:28.000000000 -0700
@@ -33,8 +33,8 @@
 	int (*setup)(alpha_agp_info *);
 	void (*cleanup)(alpha_agp_info *);
 	int (*configure)(alpha_agp_info *);
-	int (*bind)(alpha_agp_info *, off_t, agp_memory *);
-	int (*unbind)(alpha_agp_info *, off_t, agp_memory *);
+	int (*bind)(alpha_agp_info *, off_t, struct agp_memory *);
+	int (*unbind)(alpha_agp_info *, off_t, struct agp_memory *);
 	unsigned long (*translate)(alpha_agp_info *, dma_addr_t);
 };
 
diff -urN linux-2.5.70-bk10/include/asm-alpha/unistd.h linux-2.5.70-bk11/include/asm-alpha/unistd.h
--- linux-2.5.70-bk10/include/asm-alpha/unistd.h	2003-05-26 18:00:39.000000000 -0700
+++ linux-2.5.70-bk11/include/asm-alpha/unistd.h	2003-06-06 04:38:28.000000000 -0700
@@ -349,7 +349,16 @@
 #define __NR_set_tid_address		411
 #define __NR_restart_syscall		412
 #define __NR_fadvise64			413
-#define NR_SYSCALLS			414
+#define __NR_timer_create		414
+#define __NR_timer_settime		415
+#define __NR_timer_gettime		416
+#define __NR_timer_getoverrun		417
+#define __NR_timer_delete		418
+#define __NR_clock_settime		419
+#define __NR_clock_gettime		420
+#define __NR_clock_getres		421
+#define __NR_clock_nanosleep		422
+#define NR_SYSCALLS			423
 
 #if defined(__GNUC__)
 
diff -urN linux-2.5.70-bk10/include/asm-ppc/dma.h linux-2.5.70-bk11/include/asm-ppc/dma.h
--- linux-2.5.70-bk10/include/asm-ppc/dma.h	2003-05-26 18:00:56.000000000 -0700
+++ linux-2.5.70-bk11/include/asm-ppc/dma.h	2003-06-06 04:38:28.000000000 -0700
@@ -99,7 +99,7 @@
  */
 
 /* see prep_setup_arch() for detailed informations */
-#if defined(CONFIG_SOUND_CS4232) && defined(CONFIG_ALL_PPC)
+#if defined(CONFIG_SOUND_CS4232) && defined(CONFIG_PPC_PREP)
 extern long ppc_cs4232_dma, ppc_cs4232_dma2;
 #define SND_DMA1 ppc_cs4232_dma
 #define SND_DMA2 ppc_cs4232_dma2
diff -urN linux-2.5.70-bk10/include/asm-ppc/io.h linux-2.5.70-bk11/include/asm-ppc/io.h
--- linux-2.5.70-bk10/include/asm-ppc/io.h	2003-05-26 18:00:46.000000000 -0700
+++ linux-2.5.70-bk11/include/asm-ppc/io.h	2003-06-06 04:38:28.000000000 -0700
@@ -77,7 +77,7 @@
 #define insl(port, buf, nl)	_insl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
 #define outsl(port, buf, nl)	_outsl_ns((u32 *)((port)+_IO_BASE), (buf), (nl))
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_PMAC
 /*
  * On powermacs, we will get a machine check exception if we
  * try to read data from a non-existent I/O port.  Because the
@@ -149,7 +149,7 @@
 #define inl(port)		in_be32((u32 *)((port)+_IO_BASE))
 #define outl(val, port)		out_be32((u32 *)((port)+_IO_BASE), (val))
 
-#else /* not APUS or ALL_PPC */
+#else /* not APUS or PMAC */
 #define inb(port)		in_8((u8 *)((port)+_IO_BASE))
 #define outb(val, port)		out_8((u8 *)((port)+_IO_BASE), (val))
 #define inw(port)		in_le16((u16 *)((port)+_IO_BASE))
diff -urN linux-2.5.70-bk10/include/asm-ppc/processor.h linux-2.5.70-bk11/include/asm-ppc/processor.h
--- linux-2.5.70-bk10/include/asm-ppc/processor.h	2003-05-26 18:00:20.000000000 -0700
+++ linux-2.5.70-bk11/include/asm-ppc/processor.h	2003-06-06 04:38:28.000000000 -0700
@@ -559,7 +559,7 @@
 
 /* We only need to define a new _MACH_xxx for machines which are part of
  * a configuration which supports more than one type of different machine.
- * This is currently limited to CONFIG_ALL_PPC and CHRP/PReP/PMac. -- Tom
+ * This is currently limited to CONFIG_PPC_MULTIPLATFORM and CHRP/PReP/PMac. -- Tom
  */
 #define _MACH_prep	0x00000001
 #define _MACH_Pmac	0x00000002	/* pmac or pmac clone (non-chrp) */
@@ -620,7 +620,7 @@
 #define SR15	15
 
 #ifndef __ASSEMBLY__
-#if defined(CONFIG_ALL_PPC)
+#ifdef CONFIG_PPC_MULTIPLATFORM
 extern int _machine;
 
 /* what kind of prep workstation we are */
@@ -635,7 +635,7 @@
 extern unsigned char ucBoardRevMaj, ucBoardRevMin;
 #else
 #define _machine 0
-#endif /* CONFIG_ALL_PPC */
+#endif /* CONFIG_PPC_MULTIPLATFORM */
 
 struct task_struct;
 void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp);
diff -urN linux-2.5.70-bk10/include/asm-um/processor-ppc.h linux-2.5.70-bk11/include/asm-um/processor-ppc.h
--- linux-2.5.70-bk10/include/asm-um/processor-ppc.h	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk11/include/asm-um/processor-ppc.h	2003-06-06 04:38:28.000000000 -0700
@@ -3,7 +3,7 @@
 
 #if defined(__ASSEMBLY__)
 
-#define CONFIG_ALL_PPC
+#define CONFIG_PPC_MULTIPLATFORM
 #include "arch/processor.h"
 
 #else
diff -urN linux-2.5.70-bk10/include/linux/blkdev.h linux-2.5.70-bk11/include/linux/blkdev.h
--- linux-2.5.70-bk10/include/linux/blkdev.h	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/include/linux/blkdev.h	2003-06-06 04:38:28.000000000 -0700
@@ -431,7 +431,6 @@
 extern void blk_queue_max_segment_size(request_queue_t *, unsigned int);
 extern void blk_queue_hardsect_size(request_queue_t *, unsigned short);
 extern void blk_queue_segment_boundary(request_queue_t *, unsigned long);
-extern void blk_queue_assign_lock(request_queue_t *, spinlock_t *);
 extern void blk_queue_prep_rq(request_queue_t *, prep_rq_fn *pfn);
 extern void blk_queue_merge_bvec(request_queue_t *, merge_bvec_fn *);
 extern void blk_queue_dma_alignment(request_queue_t *, int);
diff -urN linux-2.5.70-bk10/include/linux/device.h linux-2.5.70-bk11/include/linux/device.h
--- linux-2.5.70-bk10/include/linux/device.h	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/include/linux/device.h	2003-06-06 04:38:28.000000000 -0700
@@ -194,7 +194,6 @@
 	void			* class_data;	/* class-specific data */
 
 	char	class_id[BUS_ID_SIZE];	/* unique to this class */
-	void	(*release)(struct class_device * class_dev);
 };
 
 static inline void *
@@ -303,6 +302,8 @@
 extern void device_initialize(struct device * dev);
 extern int device_add(struct device * dev);
 extern void device_del(struct device * dev);
+extern int device_for_each_child(struct device *, void *,
+		     int (*fn)(struct device *, void *));
 
 /*
  * Manual binding of a device to driver. See drivers/base/bus.c 
diff -urN linux-2.5.70-bk10/include/linux/ethtool.h linux-2.5.70-bk11/include/linux/ethtool.h
--- linux-2.5.70-bk10/include/linux/ethtool.h	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk11/include/linux/ethtool.h	2003-06-06 04:38:28.000000000 -0700
@@ -252,23 +252,23 @@
 
 /* CMDs currently supported */
 #define ETHTOOL_GSET		0x00000001 /* Get settings. */
-#define ETHTOOL_SSET		0x00000002 /* Set settings, privileged. */
+#define ETHTOOL_SSET		0x00000002 /* Set settings. */
 #define ETHTOOL_GDRVINFO	0x00000003 /* Get driver info. */
-#define ETHTOOL_GREGS		0x00000004 /* Get NIC registers, privileged. */
+#define ETHTOOL_GREGS		0x00000004 /* Get NIC registers. */
 #define ETHTOOL_GWOL		0x00000005 /* Get wake-on-lan options. */
-#define ETHTOOL_SWOL		0x00000006 /* Set wake-on-lan options, priv. */
+#define ETHTOOL_SWOL		0x00000006 /* Set wake-on-lan options. */
 #define ETHTOOL_GMSGLVL		0x00000007 /* Get driver message level */
-#define ETHTOOL_SMSGLVL		0x00000008 /* Set driver msg level, priv. */
-#define ETHTOOL_NWAY_RST	0x00000009 /* Restart autonegotiation, priv. */
+#define ETHTOOL_SMSGLVL		0x00000008 /* Set driver msg level. */
+#define ETHTOOL_NWAY_RST	0x00000009 /* Restart autonegotiation. */
 #define ETHTOOL_GLINK		0x0000000a /* Get link status (ethtool_value) */
 #define ETHTOOL_GEEPROM		0x0000000b /* Get EEPROM data */
-#define ETHTOOL_SEEPROM		0x0000000c /* Set EEPROM data, priv. */
+#define ETHTOOL_SEEPROM		0x0000000c /* Set EEPROM data. */
 #define ETHTOOL_GCOALESCE	0x0000000e /* Get coalesce config */
-#define ETHTOOL_SCOALESCE	0x0000000f /* Set coalesce config, priv. */
+#define ETHTOOL_SCOALESCE	0x0000000f /* Set coalesce config. */
 #define ETHTOOL_GRINGPARAM	0x00000010 /* Get ring parameters */
-#define ETHTOOL_SRINGPARAM	0x00000011 /* Set ring parameters, priv. */
+#define ETHTOOL_SRINGPARAM	0x00000011 /* Set ring parameters. */
 #define ETHTOOL_GPAUSEPARAM	0x00000012 /* Get pause parameters */
-#define ETHTOOL_SPAUSEPARAM	0x00000013 /* Set pause parameters, priv. */
+#define ETHTOOL_SPAUSEPARAM	0x00000013 /* Set pause parameters. */
 #define ETHTOOL_GRXCSUM		0x00000014 /* Get RX hw csum enable (ethtool_value) */
 #define ETHTOOL_SRXCSUM		0x00000015 /* Set RX hw csum enable (ethtool_value) */
 #define ETHTOOL_GTXCSUM		0x00000016 /* Get TX hw csum enable (ethtool_value) */
@@ -276,8 +276,8 @@
 #define ETHTOOL_GSG		0x00000018 /* Get scatter-gather enable
 					    * (ethtool_value) */
 #define ETHTOOL_SSG		0x00000019 /* Set scatter-gather enable
-					    * (ethtool_value), priv. */
-#define ETHTOOL_TEST		0x0000001a /* execute NIC self-test, priv. */
+					    * (ethtool_value). */
+#define ETHTOOL_TEST		0x0000001a /* execute NIC self-test. */
 #define ETHTOOL_GSTRINGS	0x0000001b /* get specified string set */
 #define ETHTOOL_PHYS_ID		0x0000001c /* identify the NIC */
 #define ETHTOOL_GSTATS		0x0000001d /* get NIC-specific statistics */
@@ -299,6 +299,7 @@
 #define SUPPORTED_MII			(1 << 9)
 #define SUPPORTED_FIBRE			(1 << 10)
 #define SUPPORTED_BNC			(1 << 11)
+#define SUPPORTED_10000baseT_Full	(1 << 12)
 
 /* Indicates what features are advertised by the interface. */
 #define ADVERTISED_10baseT_Half		(1 << 0)
@@ -313,6 +314,7 @@
 #define ADVERTISED_MII			(1 << 9)
 #define ADVERTISED_FIBRE		(1 << 10)
 #define ADVERTISED_BNC			(1 << 11)
+#define ADVERTISED_10000baseT_Full	(1 << 12)
 
 /* The following are all involved in forcing a particular link
  * mode for the device for setting things.  When getting the
@@ -320,10 +322,11 @@
  * it was foced up into this mode or autonegotiated.
  */
 
-/* The forced speed, 10Mb, 100Mb, gigabit. */
+/* The forced speed, 10Mb, 100Mb, gigabit, 10GbE. */
 #define SPEED_10		10
 #define SPEED_100		100
 #define SPEED_1000		1000
+#define SPEED_10000		10000
 
 /* Duplex, half or full. */
 #define DUPLEX_HALF		0x00
diff -urN linux-2.5.70-bk10/include/linux/fs.h linux-2.5.70-bk11/include/linux/fs.h
--- linux-2.5.70-bk10/include/linux/fs.h	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/include/linux/fs.h	2003-06-06 04:38:28.000000000 -0700
@@ -917,7 +917,6 @@
 
 struct file_system_type {
 	const char *name;
-	struct subsystem subsys;
 	int fs_flags;
 	struct super_block *(*get_sb) (struct file_system_type *, int,
 				       const char *, void *);
diff -urN linux-2.5.70-bk10/include/linux/i2c-id.h linux-2.5.70-bk11/include/linux/i2c-id.h
--- linux-2.5.70-bk10/include/linux/i2c-id.h	2003-05-26 18:00:21.000000000 -0700
+++ linux-2.5.70-bk11/include/linux/i2c-id.h	2003-06-06 04:38:28.000000000 -0700
@@ -98,6 +98,7 @@
 #define I2C_DRIVERID_ZR36120	50     /* Zoran 36120 video encoder	*/
 #define I2C_DRIVERID_24LC32A	51	/* Microchip 24LC32A 32k EEPROM	*/
 #define I2C_DRIVERID_STM41T00	52	/* real time clock		*/
+#define I2C_DRIVERID_UDA1342	53	/* UDA1342 audio codec		*/
 
 
 
@@ -178,6 +179,7 @@
 #define I2C_ALGO_MPC8XX 0x110000	/* MPC8xx PowerPC I2C algorithm */
 #define I2C_ALGO_OCP    0x120000	/* IBM or otherwise On-chip I2C algorithm */
 #define I2C_ALGO_BITHS	0x130000	/* enhanced bit style adapters	*/
+#define I2C_ALGO_OCP_IOP3XX  0x140000	/* XSCALE IOP3XX On-chip I2C alg */
 
 #define I2C_ALGO_EXP	0x800000	/* experimental			*/
 
@@ -213,6 +215,9 @@
 #define I2C_HW_B_FRODO  0x13    /* 2d3D, Inc. SA-1110 Development Board */
 #define I2C_HW_B_OMAHA  0x14    /* Omaha I2C interface (ARM)		*/
 #define I2C_HW_B_GUIDE  0x15    /* Guide bit-basher			*/
+#define I2C_HW_B_IXP2000 0x16	/* GPIO on IXP2000 systems              */
+#define I2C_HW_B_IXP425 0x17	/* GPIO on IXP425 systems		*/
+#define I2C_HW_B_S3VIA	0x18	/* S3Via ProSavage adapter		*/
 
 /* --- PCF 8584 based algorithms					*/
 #define I2C_HW_P_LP	0x00	/* Parallel port interface		*/
@@ -234,6 +239,8 @@
 /* --- PowerPC on-chip adapters						*/
 #define I2C_HW_OCP 0x00	/* IBM on-chip I2C adapter 	*/
 
+/* --- XSCALE on-chip adapters                          */
+#define I2C_HW_IOP321 0x00
 
 /* --- SMBus only adapters						*/
 #define I2C_HW_SMBUS_PIIX4	0x00
diff -urN linux-2.5.70-bk10/include/linux/pci.h linux-2.5.70-bk11/include/linux/pci.h
--- linux-2.5.70-bk10/include/linux/pci.h	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/include/linux/pci.h	2003-06-06 04:38:28.000000000 -0700
@@ -468,10 +468,6 @@
 
 #define pci_bus_b(n) list_entry(n, struct pci_bus, node)
 
-extern struct list_head pci_root_buses;	/* list of all known PCI buses */
-extern struct list_head pci_devices;	/* list of all devices */
-extern struct bus_type pci_bus_type;
-
 /*
  * Error values that may be returned by PCI functions.
  */
@@ -522,16 +518,17 @@
 /* these external functions are only available when PCI support is enabled */
 #ifdef CONFIG_PCI
 
-static inline int pci_present(void)
-{
-	return !list_empty(&pci_devices);
-}
+extern struct bus_type pci_bus_type;
+
+/* Do NOT directly access these two variables, unless you are arch specific pci
+ * code, or pci core code. */
+extern struct list_head pci_root_buses;	/* list of all known PCI buses */
+extern struct list_head pci_devices;	/* list of all devices */
 
-#define pci_for_each_dev_reverse(dev) \
-	for(dev = pci_dev_g(pci_devices.prev); dev != pci_dev_g(&pci_devices); dev = pci_dev_g(dev->global_list.prev))
 #define pci_for_each_bus(bus) \
 	for(bus = pci_bus_b(pci_root_buses.next); bus != pci_bus_b(&pci_root_buses); bus = pci_bus_b(bus->node.next))
 
+int pci_present(void);
 void pcibios_fixup_bus(struct pci_bus *);
 int pcibios_enable_device(struct pci_dev *, int mask);
 char *pcibios_setup (char *str);
@@ -559,9 +556,12 @@
 extern struct pci_dev *pci_get_dev(struct pci_dev *dev);
 extern void pci_put_dev(struct pci_dev *dev);
 
+extern void pci_remove_bus_device(struct pci_dev *dev);
+
 /* Generic PCI functions exported to card drivers */
 
 struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from);
+struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int device, const struct pci_dev *from);
 struct pci_dev *pci_find_subsys (unsigned int vendor, unsigned int device,
 				 unsigned int ss_vendor, unsigned int ss_device,
 				 const struct pci_dev *from);
diff -urN linux-2.5.70-bk10/include/linux/pci_ids.h linux-2.5.70-bk11/include/linux/pci_ids.h
--- linux-2.5.70-bk10/include/linux/pci_ids.h	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk11/include/linux/pci_ids.h	2003-06-06 04:38:28.000000000 -0700
@@ -1398,9 +1398,20 @@
 #define PCI_DEVICE_ID_RP4QUAD		0x0004
 #define PCI_DEVICE_ID_RP8OCTA		0x0005
 #define PCI_DEVICE_ID_RP8J		0x0006
+#define PCI_DEVICE_ID_RP4J		0x0007
 #define PCI_DEVICE_ID_RPP4		0x000A
 #define PCI_DEVICE_ID_RPP8		0x000B
 #define PCI_DEVICE_ID_RP8M		0x000C
+#define PCI_DEVICE_ID_RP4M		0x000D
+#define PCI_DEVICE_ID_RP2_232		0x000E
+#define PCI_DEVICE_ID_RP2_422		0x000F
+#define PCI_DEVICE_ID_URP32INTF		0x0801
+#define PCI_DEVICE_ID_URP8INTF		0x0802
+#define PCI_DEVICE_ID_URP16INTF		0x0803
+#define PCI_DEVICE_ID_URP8OCTA		0x0805
+#define PCI_DEVICE_ID_UPCI_RM3_8PORT	0x080C       
+#define PCI_DEVICE_ID_UPCI_RM3_4PORT	0x080D
+#define PCI_DEVICE_ID_CRP16INTF		0x0903       
 
 #define PCI_VENDOR_ID_CYCLADES		0x120e
 #define PCI_DEVICE_ID_CYCLOM_Y_Lo	0x0100
diff -urN linux-2.5.70-bk10/include/linux/rocket.h linux-2.5.70-bk11/include/linux/rocket.h
--- linux-2.5.70-bk10/include/linux/rocket.h	2003-05-26 18:00:19.000000000 -0700
+++ linux-2.5.70-bk11/include/linux/rocket.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,55 +0,0 @@
-/*
- * This file contains the exported interface of the rocket driver to
- * its configuration program.
- */
-
-struct rocket_config {
-	int	line;
-	int	flags;
-	int	closing_wait;
-	int	close_delay;
-	int	port;
-	int	reserved[32];
-};
-
-struct rocket_ports {
-	int	tty_major;
-	int	callout_major;
-	int	port_bitmap[4];
-	int	reserved[32];
-};
-
-/*
- * Rocketport flags
- */
-#define ROCKET_CALLOUT_NOHUP    0x00000001
-#define ROCKET_FORCE_CD		0x00000002
-#define ROCKET_HUP_NOTIFY	0x00000004
-#define ROCKET_SPLIT_TERMIOS	0x00000008
-#define ROCKET_SPD_MASK		0x00000070
-#define ROCKET_SPD_HI		0x00000010 /* Use 56000 instead of 38400 bps */
-#define ROCKET_SPD_VHI		0x00000020 /* Use 115200 instead of 38400 bps*/
-#define ROCKET_SPD_SHI		0x00000030 /* Use 230400 instead of 38400 bps*/
-#define ROCKET_SPD_WARP	        0x00000040 /* Use 460800 instead of 38400 bps*/
-#define ROCKET_SAK		0x00000080
-#define ROCKET_SESSION_LOCKOUT	0x00000100
-#define ROCKET_PGRP_LOCKOUT	0x00000200
-	
-#define ROCKET_FLAGS		0x000003FF
-
-#define ROCKET_USR_MASK 0x0071	/* Legal flags that non-privileged
-				 * users can set or reset */
-
-/*
- * For closing_wait and closing_wait2
- */
-#define ROCKET_CLOSING_WAIT_NONE	65535
-#define ROCKET_CLOSING_WAIT_INF		0
-
-/*
- * Rocketport ioctls -- "RP"
- */
-#define RCKP_GET_STRUCT		0x00525001
-#define RCKP_GET_CONFIG		0x00525002
-#define RCKP_SET_CONFIG		0x00525003
-#define RCKP_GET_PORTS		0x00525004
diff -urN linux-2.5.70-bk10/include/linux/zconf.h linux-2.5.70-bk11/include/linux/zconf.h
--- linux-2.5.70-bk10/include/linux/zconf.h	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk11/include/linux/zconf.h	2003-06-06 04:38:28.000000000 -0700
@@ -8,18 +8,6 @@
 #ifndef _ZCONF_H
 #define _ZCONF_H
 
-#if defined(__GNUC__) || defined(__386__) || defined(i386)
-#  ifndef __32BIT__
-#    define __32BIT__
-#  endif
-#endif
-
-#if defined(__STDC__) || defined(__cplusplus)
-#  ifndef STDC
-#    define STDC
-#  endif
-#endif
-
 /* The memory requirements for deflate are (in bytes):
             (1 << (windowBits+2)) +  (1 << (memLevel+9))
  that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
@@ -49,42 +37,9 @@
 
                         /* Type declarations */
 
-#ifndef OF /* function prototypes */
-#  ifdef STDC
-#    define OF(args)  args
-#  else
-#    define OF(args)  ()
-#  endif
-#endif
-
-#ifndef ZEXPORT
-#  define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-#  define ZEXPORTVA
-#endif
-#ifndef ZEXTERN
-#  define ZEXTERN extern
-#endif
-#ifndef FAR
-#   define FAR
-#endif
-
 typedef unsigned char  Byte;  /* 8 bits */
 typedef unsigned int   uInt;  /* 16 bits or more */
 typedef unsigned long  uLong; /* 32 bits or more */
-
-typedef Byte  FAR Bytef;
-typedef char  FAR charf;
-typedef int   FAR intf;
-typedef uInt  FAR uIntf;
-typedef uLong FAR uLongf;
-
-typedef void FAR *voidpf;
 typedef void     *voidp;
 
-#include <linux/types.h> /* for off_t */
-#include <linux/unistd.h>    /* for SEEK_* and off_t */
-#define z_off_t  off_t
-
 #endif /* _ZCONF_H */
diff -urN linux-2.5.70-bk10/include/linux/zlib.h linux-2.5.70-bk11/include/linux/zlib.h
--- linux-2.5.70-bk10/include/linux/zlib.h	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk11/include/linux/zlib.h	2003-06-06 04:38:28.000000000 -0700
@@ -60,22 +60,19 @@
   crash even in case of corrupted input.
 */
 
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
-
 struct internal_state;
 
 typedef struct z_stream_s {
-    Bytef    *next_in;  /* next input byte */
+    Byte    *next_in;   /* next input byte */
     uInt     avail_in;  /* number of bytes available at next_in */
     uLong    total_in;  /* total nb of input bytes read so far */
 
-    Bytef    *next_out; /* next output byte should be put there */
+    Byte    *next_out;  /* next output byte should be put there */
     uInt     avail_out; /* remaining free space at next_out */
     uLong    total_out; /* total nb of bytes output so far */
 
     char     *msg;      /* last error message, NULL if no error */
-    struct internal_state FAR *state; /* not visible by applications */
+    struct internal_state *state; /* not visible by applications */
 
     void     *workspace; /* memory allocated for this stream */
 
@@ -84,7 +81,7 @@
     uLong   reserved;   /* reserved for future use */
 } z_stream;
 
-typedef z_stream FAR *z_streamp;
+typedef z_stream *z_streamp;
 
 /*
    The application must update next_in and avail_in when avail_in has
@@ -164,14 +161,14 @@
 
                         /* basic functions */
 
-ZEXTERN const char * ZEXPORT zlib_zlibVersion OF((void));
+extern const char * zlib_zlibVersion (void);
 /* The application can compare zlibVersion and ZLIB_VERSION for consistency.
    If the first character differs, the library code actually used is
    not compatible with the zlib.h header file used by the application.
    This check is automatically made by deflateInit and inflateInit.
  */
 
-ZEXTERN int ZEXPORT zlib_deflate_workspacesize OF((void));
+extern int zlib_deflate_workspacesize (void);
 /*
    Returns the number of bytes that needs to be allocated for a per-
    stream workspace.  A pointer to this number of bytes should be
@@ -179,7 +176,7 @@
 */
 
 /* 
-ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+extern int deflateInit (z_streamp strm, int level);
 
      Initializes the internal stream state for compression. The fields
    zalloc, zfree and opaque must be initialized before by the caller.
@@ -201,7 +198,7 @@
 */
 
 
-ZEXTERN int ZEXPORT zlib_deflate OF((z_streamp strm, int flush));
+extern int zlib_deflate (z_streamp strm, int flush);
 /*
     deflate compresses as much data as possible, and stops when the input
   buffer becomes empty or the output buffer becomes full. It may introduce some
@@ -279,7 +276,7 @@
 */
 
 
-ZEXTERN int ZEXPORT zlib_deflateEnd OF((z_streamp strm));
+extern int zlib_deflateEnd (z_streamp strm);
 /*
      All dynamically allocated data structures for this stream are freed.
    This function discards any unprocessed input and does not flush any
@@ -293,7 +290,7 @@
 */
 
 
-ZEXTERN int ZEXPORT zlib_inflate_workspacesize OF((void));
+extern int zlib_inflate_workspacesize (void);
 /*
    Returns the number of bytes that needs to be allocated for a per-
    stream workspace.  A pointer to this number of bytes should be
@@ -301,7 +298,7 @@
 */
 
 /* 
-ZEXTERN int ZEXPORT zlib_inflateInit OF((z_streamp strm));
+extern int zlib_inflateInit (z_streamp strm);
 
      Initializes the internal stream state for decompression. The fields
    next_in, avail_in, and workspace must be initialized before by
@@ -321,7 +318,7 @@
 */
 
 
-ZEXTERN int ZEXPORT zlib_inflate OF((z_streamp strm, int flush));
+extern int zlib_inflate (z_streamp strm, int flush);
 /*
     inflate decompresses as much data as possible, and stops when the input
   buffer becomes empty or the output buffer becomes full. It may some
@@ -390,7 +387,7 @@
 */
 
 
-ZEXTERN int ZEXPORT zlib_inflateEnd OF((z_streamp strm));
+extern int zlib_inflateEnd (z_streamp strm);
 /*
      All dynamically allocated data structures for this stream are freed.
    This function discards any unprocessed input and does not flush any
@@ -408,12 +405,12 @@
 */
 
 /*   
-ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+extern int deflateInit2 (z_streamp strm,
                                      int  level,
                                      int  method,
                                      int  windowBits,
                                      int  memLevel,
-                                     int  strategy));
+                                     int  strategy);
 
      This is another version of deflateInit with more compression options. The
    fields next_in, zalloc, zfree and opaque must be initialized before by
@@ -451,9 +448,9 @@
    not perform any compression: this will be done by deflate().
 */
                             
-ZEXTERN int ZEXPORT zlib_deflateSetDictionary OF((z_streamp strm,
-						     const Bytef *dictionary,
-						     uInt  dictLength));
+extern int zlib_deflateSetDictionary (z_streamp strm,
+						     const Byte *dictionary,
+						     uInt  dictLength);
 /*
      Initializes the compression dictionary from the given byte sequence
    without producing any compressed output. This function must be called
@@ -487,8 +484,7 @@
    perform any compression: this will be done by deflate().
 */
 
-ZEXTERN int ZEXPORT zlib_deflateCopy OF((z_streamp dest,
-					    z_streamp source));
+extern int zlib_deflateCopy (z_streamp dest, z_streamp source);
 /*
      Sets the destination stream as a complete copy of the source stream.
 
@@ -505,7 +501,7 @@
    destination.
 */
 
-ZEXTERN int ZEXPORT zlib_deflateReset OF((z_streamp strm));
+extern int zlib_deflateReset (z_streamp strm);
 /*
      This function is equivalent to deflateEnd followed by deflateInit,
    but does not free and reallocate all the internal compression state.
@@ -516,9 +512,7 @@
    stream state was inconsistent (such as zalloc or state being NULL).
 */
 
-ZEXTERN int ZEXPORT zlib_deflateParams OF((z_streamp strm,
-					      int level,
-					      int strategy));
+extern int zlib_deflateParams (z_streamp strm, int level, int strategy);
 /*
      Dynamically update the compression level and compression strategy.  The
    interpretation of level and strategy is as in deflateInit2.  This can be
@@ -538,8 +532,7 @@
 */
 
 /*   
-ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
-                                     int  windowBits));
+extern int inflateInit2 (z_streamp strm, int  windowBits);
 
      This is another version of inflateInit with an extra parameter. The
    fields next_in, avail_in, zalloc, zfree and opaque must be initialized
@@ -560,9 +553,9 @@
    modified, but next_out and avail_out are unchanged.)
 */
 
-ZEXTERN int ZEXPORT zlib_inflateSetDictionary OF((z_streamp strm,
-						     const Bytef *dictionary,
-						     uInt  dictLength));
+extern int zlib_inflateSetDictionary (z_streamp strm,
+						     const Byte *dictionary,
+						     uInt  dictLength);
 /*
      Initializes the decompression dictionary from the given uncompressed byte
    sequence. This function must be called immediately after a call of inflate
@@ -579,7 +572,7 @@
    inflate().
 */
 
-ZEXTERN int ZEXPORT zlib_inflateSync OF((z_streamp strm));
+extern int zlib_inflateSync (z_streamp strm);
 /* 
     Skips invalid compressed data until a full flush point (see above the
   description of deflate with Z_FULL_FLUSH) can be found, or until all
@@ -594,7 +587,7 @@
   until success or end of the input data.
 */
 
-ZEXTERN int ZEXPORT zlib_inflateReset OF((z_streamp strm));
+extern int zlib_inflateReset (z_streamp strm);
 /*
      This function is equivalent to inflateEnd followed by inflateInit,
    but does not free and reallocate all the internal decompression state.
@@ -604,7 +597,7 @@
    stream state was inconsistent (such as zalloc or state being NULL).
 */
 
-extern int ZEXPORT zlib_inflateIncomp OF((z_stream *strm));
+extern int zlib_inflateIncomp (z_stream *strm);
 /*
      This function adds the data at next_in (avail_in bytes) to the output
    history without performing any output.  There must be no pending output,
@@ -618,16 +611,16 @@
 /* deflateInit and inflateInit are macros to allow checking the zlib version
  * and the compiler's view of z_stream:
  */
-ZEXTERN int ZEXPORT zlib_deflateInit_ OF((z_streamp strm, int level,
-                                     const char *version, int stream_size));
-ZEXTERN int ZEXPORT zlib_inflateInit_ OF((z_streamp strm,
-                                     const char *version, int stream_size));
-ZEXTERN int ZEXPORT zlib_deflateInit2_ OF((z_streamp strm, int  level, int  method,
+extern int zlib_deflateInit_ (z_streamp strm, int level,
+                                     const char *version, int stream_size);
+extern int zlib_inflateInit_ (z_streamp strm,
+                                     const char *version, int stream_size);
+extern int zlib_deflateInit2_ (z_streamp strm, int  level, int  method,
                                       int windowBits, int memLevel,
                                       int strategy, const char *version,
-                                      int stream_size));
-ZEXTERN int ZEXPORT zlib_inflateInit2_ OF((z_streamp strm, int  windowBits,
-                                      const char *version, int stream_size));
+                                      int stream_size);
+extern int zlib_inflateInit2_ (z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size);
 #define zlib_deflateInit(strm, level) \
         zlib_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
 #define zlib_inflateInit(strm) \
@@ -643,9 +636,9 @@
     struct internal_state {int dummy;}; /* hack for buggy compilers */
 #endif
 
-ZEXTERN const char   * ZEXPORT zlib_zError           OF((int err));
-ZEXTERN int            ZEXPORT zlib_inflateSyncPoint OF((z_streamp z));
-ZEXTERN const uLongf * ZEXPORT zlib_get_crc_table    OF((void));
+extern const char  * zlib_zError           (int err);
+extern int           zlib_inflateSyncPoint (z_streamp z);
+extern const uLong * zlib_get_crc_table    (void);
 
 #ifdef __cplusplus
 }
diff -urN linux-2.5.70-bk10/include/linux/zutil.h linux-2.5.70-bk11/include/linux/zutil.h
--- linux-2.5.70-bk10/include/linux/zutil.h	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk11/include/linux/zutil.h	2003-06-06 04:38:28.000000000 -0700
@@ -24,9 +24,7 @@
 /* compile with -Dlocal if your debugger can't find static symbols */
 
 typedef unsigned char  uch;
-typedef uch FAR uchf;
 typedef unsigned short ush;
-typedef ush FAR ushf;
 typedef unsigned long  ulg;
 
         /* common constants */
@@ -64,8 +62,8 @@
 
          /* functions */
 
-typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
-				       uInt len));
+typedef uLong (*check_func) (uLong check, const Byte *buf,
+				       uInt len);
 
 
                         /* checksum functions */
@@ -96,7 +94,7 @@
      if (adler != original_adler) error();
 */
 static inline uLong zlib_adler32(uLong adler,
-				 const Bytef *buf,
+				 const Byte *buf,
 				 uInt len)
 {
     unsigned long s1 = adler & 0xffff;
diff -urN linux-2.5.70-bk10/include/net/xfrm.h linux-2.5.70-bk11/include/net/xfrm.h
--- linux-2.5.70-bk10/include/net/xfrm.h	2003-05-26 18:00:47.000000000 -0700
+++ linux-2.5.70-bk11/include/net/xfrm.h	2003-06-06 04:38:28.000000000 -0700
@@ -9,6 +9,7 @@
 #include <linux/crypto.h>
 #include <linux/pfkeyv2.h>
 #include <linux/in6.h>
+#include <linux/slab.h>
 
 #include <net/sock.h>
 #include <net/dst.h>
diff -urN linux-2.5.70-bk10/include/video/edid.h linux-2.5.70-bk11/include/video/edid.h
--- linux-2.5.70-bk10/include/video/edid.h	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk11/include/video/edid.h	2003-06-06 04:38:28.000000000 -0700
@@ -4,7 +4,7 @@
 #ifdef __KERNEL__
 
 #include <linux/config.h>
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 #include <linux/pci.h>
 #endif
 
@@ -18,7 +18,7 @@
 
 #endif /* CONFIG_X86 */
 
-#ifdef CONFIG_ALL_PPC
+#ifdef CONFIG_PPC_OF
 extern char *get_EDID_from_OF(struct pci_dev *pdev);
 #endif
 
diff -urN linux-2.5.70-bk10/lib/kobject.c linux-2.5.70-bk11/lib/kobject.c
--- linux-2.5.70-bk10/lib/kobject.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/lib/kobject.c	2003-06-06 04:38:28.000000000 -0700
@@ -17,10 +17,6 @@
 #include <linux/module.h>
 #include <linux/stat.h>
 
-/* This lock can be removed entirely when the sysfs_init() code is cleaned up
- * to not try to reference itself before it is initialized. */
-static spinlock_t kobj_lock = SPIN_LOCK_UNLOCKED;
-
 /**
  *	populate_dir - populate directory with attributes.
  *	@kobj:	object we're working on.
@@ -350,14 +346,12 @@
 struct kobject * kobject_get(struct kobject * kobj)
 {
 	struct kobject * ret = kobj;
-	unsigned long flags;
 
-	spin_lock_irqsave(&kobj_lock, flags);
-	if (kobj && atomic_read(&kobj->refcount) > 0)
+	if (kobj) {
+		WARN_ON(!atomic_read(&kobj->refcount));
 		atomic_inc(&kobj->refcount);
-	else
+	} else
 		ret = NULL;
-	spin_unlock_irqrestore(&kobj_lock, flags);
 	return ret;
 }
 
@@ -387,15 +381,8 @@
 
 void kobject_put(struct kobject * kobj)
 {
-	unsigned long flags;
-
-	local_irq_save(flags);
-	if (atomic_dec_and_lock(&kobj->refcount, &kobj_lock)) {
-		spin_unlock_irqrestore(&kobj_lock, flags);
+	if (atomic_dec_and_test(&kobj->refcount))
 		kobject_cleanup(kobj);
-	} else {
-		local_irq_restore(flags);
-	}
 }
 
 
diff -urN linux-2.5.70-bk10/lib/zlib_deflate/deflate.c linux-2.5.70-bk11/lib/zlib_deflate/deflate.c
--- linux-2.5.70-bk10/lib/zlib_deflate/deflate.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_deflate/deflate.c	2003-06-06 04:38:28.000000000 -0700
@@ -63,22 +63,22 @@
     finish_done     /* finish done, accept no more input or output */
 } block_state;
 
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+typedef block_state (*compress_func) (deflate_state *s, int flush);
 /* Compression function. Returns the block state after the call. */
 
-local void fill_window    OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast   OF((deflate_state *s, int flush));
-local block_state deflate_slow   OF((deflate_state *s, int flush));
-local void lm_init        OF((deflate_state *s));
-local void putShortMSB    OF((deflate_state *s, uInt b));
-local void flush_pending  OF((z_streamp strm));
-local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
-local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+local void fill_window    (deflate_state *s);
+local block_state deflate_stored (deflate_state *s, int flush);
+local block_state deflate_fast   (deflate_state *s, int flush);
+local block_state deflate_slow   (deflate_state *s, int flush);
+local void lm_init        (deflate_state *s);
+local void putShortMSB    (deflate_state *s, uInt b);
+local void flush_pending  (z_streamp strm);
+local int read_buf        (z_streamp strm, Byte *buf, unsigned size);
+local uInt longest_match  (deflate_state *s, IPos cur_match);
 
 #ifdef DEBUG_ZLIB
-local  void check_match OF((deflate_state *s, IPos start, IPos match,
-                            int length));
+local  void check_match (deflate_state *s, IPos start, IPos match,
+                         int length);
 #endif
 
 /* ===========================================================================
@@ -161,7 +161,7 @@
  */
 #define CLEAR_HASH(s) \
     s->head[s->hash_size-1] = NIL; \
-    memset((charf *)s->head, 0, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+    memset((char *)s->head, 0, (unsigned)(s->hash_size-1)*sizeof(*s->head));
 
 /* ========================================================================= */
 int zlib_deflateInit_(
@@ -194,7 +194,7 @@
     static char* my_version = ZLIB_VERSION;
     deflate_workspace *mem;
 
-    ushf *overlay;
+    ush *overlay;
     /* We overlay pending_buf and d_buf+l_buf. This works since the average
      * output size for (length,distance) codes is <= 24 bits.
      */
@@ -221,7 +221,7 @@
         return Z_STREAM_ERROR;
     }
     s = (deflate_state *) &(mem->deflate_memory);
-    strm->state = (struct internal_state FAR *)s;
+    strm->state = (struct internal_state *)s;
     s->strm = strm;
 
     s->noheader = noheader;
@@ -234,14 +234,14 @@
     s->hash_mask = s->hash_size - 1;
     s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
 
-    s->window = (Bytef *) mem->window_memory;
-    s->prev   = (Posf *)  mem->prev_memory;
-    s->head   = (Posf *)  mem->head_memory;
+    s->window = (Byte *) mem->window_memory;
+    s->prev   = (Pos *)  mem->prev_memory;
+    s->head   = (Pos *)  mem->head_memory;
 
     s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
 
-    overlay = (ushf *) mem->overlay_memory;
-    s->pending_buf = (uchf *) overlay;
+    overlay = (ush *) mem->overlay_memory;
+    s->pending_buf = (uch *) overlay;
     s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
 
     s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
@@ -257,7 +257,7 @@
 /* ========================================================================= */
 int zlib_deflateSetDictionary(
 	z_streamp strm,
-	const Bytef *dictionary,
+	const Byte *dictionary,
 	uInt  dictLength
 )
 {
@@ -281,7 +281,7 @@
 	dictionary += dictLength - length; /* use the tail of the dictionary */
 #endif
     }
-    memcpy((charf *)s->window, dictionary, length);
+    memcpy((char *)s->window, dictionary, length);
     s->strstart = length;
     s->block_start = (long)length;
 
@@ -580,7 +580,7 @@
 #else
     deflate_state *ds;
     deflate_state *ss;
-    ushf *overlay;
+    ush *overlay;
     deflate_workspace *mem;
 
 
@@ -596,15 +596,15 @@
 
     ds = &(mem->deflate_memory);
 
-    dest->state = (struct internal_state FAR *) ds;
+    dest->state = (struct internal_state *) ds;
     *ds = *ss;
     ds->strm = dest;
 
-    ds->window = (Bytef *) mem->window_memory;
-    ds->prev   = (Posf *)  mem->prev_memory;
-    ds->head   = (Posf *)  mem->head_memory;
-    overlay = (ushf *) mem->overlay_memory;
-    ds->pending_buf = (uchf *) overlay;
+    ds->window = (Byte *) mem->window_memory;
+    ds->prev   = (Pos *)  mem->prev_memory;
+    ds->head   = (Pos *)  mem->head_memory;
+    overlay = (ush *) mem->overlay_memory;
+    ds->pending_buf = (uch *) overlay;
 
     memcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
     memcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
@@ -632,7 +632,7 @@
  */
 local int read_buf(
 	z_streamp strm,
-	Bytef *buf,
+	Byte *buf,
 	unsigned size
 )
 {
@@ -695,8 +695,8 @@
     IPos cur_match;                             /* current match */
 {
     unsigned chain_length = s->max_chain_length;/* max hash chain length */
-    register Bytef *scan = s->window + s->strstart; /* current string */
-    register Bytef *match;                       /* matched string */
+    register Byte *scan = s->window + s->strstart; /* current string */
+    register Byte *match;                       /* matched string */
     register int len;                           /* length of current match */
     int best_len = s->prev_length;              /* best match length so far */
     int nice_match = s->nice_match;             /* stop if match long enough */
@@ -705,18 +705,18 @@
     /* Stop when cur_match becomes <= limit. To simplify the code,
      * we prevent matches with the string of window index 0.
      */
-    Posf *prev = s->prev;
+    Pos *prev = s->prev;
     uInt wmask = s->w_mask;
 
 #ifdef UNALIGNED_OK
     /* Compare two bytes at a time. Note: this is not always beneficial.
      * Try with and without -DUNALIGNED_OK to check.
      */
-    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
-    register ush scan_start = *(ushf*)scan;
-    register ush scan_end   = *(ushf*)(scan+best_len-1);
+    register Byte *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ush*)scan;
+    register ush scan_end   = *(ush*)(scan+best_len-1);
 #else
-    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte *strend = s->window + s->strstart + MAX_MATCH;
     register Byte scan_end1  = scan[best_len-1];
     register Byte scan_end   = scan[best_len];
 #endif
@@ -748,8 +748,8 @@
         /* This code assumes sizeof(unsigned short) == 2. Do not use
          * UNALIGNED_OK if your compiler uses a different size.
          */
-        if (*(ushf*)(match+best_len-1) != scan_end ||
-            *(ushf*)match != scan_start) continue;
+        if (*(ush*)(match+best_len-1) != scan_end ||
+            *(ush*)match != scan_start) continue;
 
         /* It is not necessary to compare scan[2] and match[2] since they are
          * always equal when the other bytes match, given that the hash keys
@@ -763,10 +763,10 @@
         Assert(scan[2] == match[2], "scan[2]?");
         scan++, match++;
         do {
-        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+        } while (*(ush*)(scan+=2) == *(ush*)(match+=2) &&
+                 *(ush*)(scan+=2) == *(ush*)(match+=2) &&
+                 *(ush*)(scan+=2) == *(ush*)(match+=2) &&
+                 *(ush*)(scan+=2) == *(ush*)(match+=2) &&
                  scan < strend);
         /* The funny "do {}" generates better code on most compilers */
 
@@ -815,7 +815,7 @@
             best_len = len;
             if (len >= nice_match) break;
 #ifdef UNALIGNED_OK
-            scan_end = *(ushf*)(scan+best_len-1);
+            scan_end = *(ush*)(scan+best_len-1);
 #else
             scan_end1  = scan[best_len-1];
             scan_end   = scan[best_len];
@@ -838,8 +838,8 @@
     int length;
 {
     /* check that the match is indeed a match */
-    if (memcmp((charf *)s->window + match,
-                (charf *)s->window + start, length) != EQUAL) {
+    if (memcmp((char *)s->window + match,
+                (char *)s->window + start, length) != EQUAL) {
         fprintf(stderr, " start %u, match %u, length %d\n",
 		start, match, length);
         do {
@@ -870,7 +870,7 @@
     deflate_state *s;
 {
     register unsigned n, m;
-    register Posf *p;
+    register Pos *p;
     unsigned more;    /* Amount of free space at the end of the window. */
     uInt wsize = s->w_size;
 
@@ -892,7 +892,7 @@
          */
         } else if (s->strstart >= wsize+MAX_DIST(s)) {
 
-            memcpy((charf *)s->window, (charf *)s->window+wsize,
+            memcpy((char *)s->window, (char *)s->window+wsize,
                    (unsigned)wsize);
             s->match_start -= wsize;
             s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
@@ -961,8 +961,8 @@
  */
 #define FLUSH_BLOCK_ONLY(s, eof) { \
    zlib_tr_flush_block(s, (s->block_start >= 0L ? \
-                   (charf *)&s->window[(unsigned)s->block_start] : \
-                   (charf *)Z_NULL), \
+                   (char *)&s->window[(unsigned)s->block_start] : \
+                   (char *)Z_NULL), \
 		(ulg)((long)s->strstart - s->block_start), \
 		(eof)); \
    s->block_start = s->strstart; \
@@ -1252,7 +1252,7 @@
     return flush == Z_FINISH ? finish_done : block_done;
 }
 
-ZEXTERN int ZEXPORT zlib_deflate_workspacesize ()
+extern int zlib_deflate_workspacesize ()
 {
     return sizeof(deflate_workspace);
 }
diff -urN linux-2.5.70-bk10/lib/zlib_deflate/deftree.c linux-2.5.70-bk11/lib/zlib_deflate/deftree.c
--- linux-2.5.70-bk10/lib/zlib_deflate/deftree.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_deflate/deftree.c	2003-06-06 04:38:28.000000000 -0700
@@ -113,7 +113,7 @@
 
 struct static_tree_desc_s {
     const ct_data *static_tree;  /* static tree or NULL */
-    const intf *extra_bits;      /* extra bits for each code or NULL */
+    const int *extra_bits;       /* extra bits for each code or NULL */
     int     extra_base;          /* base index for extra_bits */
     int     elems;               /* max number of elements in the tree */
     int     max_length;          /* max bit length for the codes */
@@ -132,25 +132,25 @@
  * Local (static) routines in this file.
  */
 
-local void tr_static_init OF((void));
-local void init_block     OF((deflate_state *s));
-local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
-local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree     OF((deflate_state *s, tree_desc *desc));
-local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
-local int  build_bl_tree  OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
-                              int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
-                              ct_data *dtree));
-local void set_data_type  OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup      OF((deflate_state *s));
-local void bi_flush       OF((deflate_state *s));
-local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
-                              int header));
+local void tr_static_init (void);
+local void init_block     (deflate_state *s);
+local void pqdownheap     (deflate_state *s, ct_data *tree, int k);
+local void gen_bitlen     (deflate_state *s, tree_desc *desc);
+local void gen_codes      (ct_data *tree, int max_code, ush *bl_count);
+local void build_tree     (deflate_state *s, tree_desc *desc);
+local void scan_tree      (deflate_state *s, ct_data *tree, int max_code);
+local void send_tree      (deflate_state *s, ct_data *tree, int max_code);
+local int  build_bl_tree  (deflate_state *s);
+local void send_all_trees (deflate_state *s, int lcodes, int dcodes,
+                           int blcodes);
+local void compress_block (deflate_state *s, ct_data *ltree,
+                           ct_data *dtree);
+local void set_data_type  (deflate_state *s);
+local unsigned bi_reverse (unsigned value, int length);
+local void bi_windup      (deflate_state *s);
+local void bi_flush       (deflate_state *s);
+local void copy_block     (deflate_state *s, char *buf, unsigned len,
+                           int header);
 
 #ifndef DEBUG_ZLIB
 #  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
@@ -174,7 +174,7 @@
  * IN assertion: length <= 16 and value fits in length bits.
  */
 #ifdef DEBUG_ZLIB
-local void send_bits      OF((deflate_state *s, int value, int length));
+local void send_bits      (deflate_state *s, int value, int length);
 
 local void send_bits(
 	deflate_state *s,
@@ -414,7 +414,7 @@
     ct_data *tree        = desc->dyn_tree;
     int max_code         = desc->max_code;
     const ct_data *stree = desc->stat_desc->static_tree;
-    const intf *extra    = desc->stat_desc->extra_bits;
+    const int *extra     = desc->stat_desc->extra_bits;
     int base             = desc->stat_desc->extra_base;
     int max_length       = desc->stat_desc->max_length;
     int h;              /* heap index */
@@ -497,7 +497,7 @@
 local void gen_codes(
 	ct_data *tree,             /* the tree to decorate */
 	int max_code,              /* largest code with non zero frequency */
-	ushf *bl_count             /* number of codes at each bit length */
+	ush *bl_count             /* number of codes at each bit length */
 )
 {
     ush next_code[MAX_BITS+1]; /* next code value for each bit length */
@@ -793,7 +793,7 @@
  */
 void zlib_tr_stored_block(
 	deflate_state *s,
-	charf *buf,       /* input block */
+	char *buf,        /* input block */
 	ulg stored_len,   /* length of input block */
 	int eof           /* true if this is the last block for a file */
 )
@@ -857,7 +857,7 @@
  */
 ulg zlib_tr_flush_block(
 	deflate_state *s,
-	charf *buf,       /* input block, or NULL if too old */
+	char *buf,        /* input block, or NULL if too old */
 	ulg stored_len,   /* length of input block */
 	int eof           /* true if this is the last block for a file */
 )
@@ -914,7 +914,7 @@
     if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) {
 #  endif
         /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */
-        if (buf == (charf*)0) error ("block vanished");
+        if (buf == (char*)0) error ("block vanished");
 
         copy_block(s, buf, (unsigned)stored_len, 0); /* without header */
         s->compressed_len = stored_len << 3;
@@ -1090,7 +1090,7 @@
  */
 local void copy_block(
 	deflate_state *s,
-	charf    *buf,    /* the input data */
+	char    *buf,     /* the input data */
 	unsigned len,     /* its length */
 	int      header   /* true if block header must be written */
 )
diff -urN linux-2.5.70-bk10/lib/zlib_deflate/defutil.h linux-2.5.70-bk11/lib/zlib_deflate/defutil.h
--- linux-2.5.70-bk10/lib/zlib_deflate/defutil.h	2003-05-26 18:00:26.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_deflate/defutil.h	2003-06-06 04:38:28.000000000 -0700
@@ -46,7 +46,7 @@
         ush  dad;        /* father node in Huffman tree */
         ush  len;        /* length of bit string */
     } dl;
-} FAR ct_data;
+} ct_data;
 
 #define Freq fc.freq
 #define Code fc.code
@@ -59,10 +59,9 @@
     ct_data *dyn_tree;           /* the dynamic tree */
     int     max_code;            /* largest code with non zero frequency */
     static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
+} tree_desc;
 
 typedef ush Pos;
-typedef Pos FAR Posf;
 typedef unsigned IPos;
 
 /* A Pos is an index in the character window. We use short instead of int to
@@ -72,9 +71,9 @@
 typedef struct deflate_state {
     z_streamp strm;      /* pointer back to this zlib stream */
     int   status;        /* as the name implies */
-    Bytef *pending_buf;  /* output still pending */
+    Byte *pending_buf;   /* output still pending */
     ulg   pending_buf_size; /* size of pending_buf */
-    Bytef *pending_out;  /* next pending byte to output to the stream */
+    Byte *pending_out;   /* next pending byte to output to the stream */
     int   pending;       /* nb of bytes in the pending buffer */
     int   noheader;      /* suppress zlib header and adler32 */
     Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
@@ -87,7 +86,7 @@
     uInt  w_bits;        /* log2(w_size)  (8..16) */
     uInt  w_mask;        /* w_size - 1 */
 
-    Bytef *window;
+    Byte *window;
     /* Sliding window. Input bytes are read into the second half of the window,
      * and move to the first half later to keep a dictionary of at least wSize
      * bytes. With this organization, matches are limited to a distance of
@@ -102,13 +101,13 @@
      * is directly used as sliding window.
      */
 
-    Posf *prev;
+    Pos *prev;
     /* Link to older string with same hash index. To limit the size of this
      * array to 64K, this link is maintained only for the last 32K strings.
      * An index in this array is thus a window index modulo 32K.
      */
 
-    Posf *head; /* Heads of the hash chains or NIL. */
+    Pos *head; /* Heads of the hash chains or NIL. */
 
     uInt  ins_h;          /* hash index of string to be inserted */
     uInt  hash_size;      /* number of elements in hash table */
@@ -188,7 +187,7 @@
     /* Depth of each subtree used as tie breaker for trees of equal frequency
      */
 
-    uchf *l_buf;          /* buffer for literals or lengths */
+    uch *l_buf;          /* buffer for literals or lengths */
 
     uInt  lit_bufsize;
     /* Size of match buffer for literals/lengths.  There are 4 reasons for
@@ -212,7 +211,7 @@
 
     uInt last_lit;      /* running index in l_buf */
 
-    ushf *d_buf;
+    ush *d_buf;
     /* Buffer for distances. To simplify the code, d_buf and l_buf have
      * the same number of elements. To use different lengths, an extra flag
      * array would be necessary.
@@ -237,7 +236,7 @@
      * are always zero.
      */
 
-} FAR deflate_state;
+} deflate_state;
 
 typedef struct deflate_workspace {
     /* State memory for the deflator */
@@ -265,14 +264,14 @@
  */
 
         /* in trees.c */
-void zlib_tr_init         OF((deflate_state *s));
-int  zlib_tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
-ulg  zlib_tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
-			      int eof));
-void zlib_tr_align        OF((deflate_state *s));
-void zlib_tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
-			      int eof));
-void zlib_tr_stored_type_only OF((deflate_state *));
+void zlib_tr_init         (deflate_state *s);
+int  zlib_tr_tally        (deflate_state *s, unsigned dist, unsigned lc);
+ulg  zlib_tr_flush_block  (deflate_state *s, char *buf, ulg stored_len,
+			   int eof);
+void zlib_tr_align        (deflate_state *s);
+void zlib_tr_stored_block (deflate_state *s, char *buf, ulg stored_len,
+			   int eof);
+void zlib_tr_stored_type_only (deflate_state *);
 
 
 /* ===========================================================================
diff -urN linux-2.5.70-bk10/lib/zlib_inflate/infblock.c linux-2.5.70-bk11/lib/zlib_inflate/infblock.c
--- linux-2.5.70-bk10/lib/zlib_inflate/infblock.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_inflate/infblock.c	2003-06-06 04:38:28.000000000 -0700
@@ -68,7 +68,7 @@
 void zlib_inflate_blocks_reset(
 	inflate_blocks_statef *s,
 	z_streamp z,
-	uLongf *c
+	uLong *c
 )
 {
   if (c != Z_NULL)
@@ -80,7 +80,7 @@
   s->bitb = 0;
   s->read = s->write = s->window;
   if (s->checkfn != Z_NULL)
-    z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
+    z->adler = s->check = (*s->checkfn)(0L, (const Byte *)Z_NULL, 0);
 }
 
 inflate_blocks_statef *zlib_inflate_blocks_new(
@@ -111,9 +111,9 @@
   uInt t;               /* temporary storage */
   uLong b;              /* bit buffer */
   uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
+  Byte *p;              /* input data pointer */
   uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
+  Byte *q;              /* output window write pointer */
   uInt m;               /* bytes to end of window or read pointer */
 
   /* copy input/output information to locals (UPDATE macro restores) */
@@ -340,7 +340,7 @@
 
 void zlib_inflate_set_dictionary(
 	inflate_blocks_statef *s,
-	const Bytef *d,
+	const Byte *d,
 	uInt  n
 )
 {
diff -urN linux-2.5.70-bk10/lib/zlib_inflate/infblock.h linux-2.5.70-bk11/lib/zlib_inflate/infblock.h
--- linux-2.5.70-bk10/lib/zlib_inflate/infblock.h	2003-05-26 18:00:41.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_inflate/infblock.h	2003-06-06 04:38:28.000000000 -0700
@@ -12,33 +12,33 @@
 #define _INFBLOCK_H
 
 struct inflate_blocks_state;
-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+typedef struct inflate_blocks_state inflate_blocks_statef;
 
-extern inflate_blocks_statef * zlib_inflate_blocks_new OF((
+extern inflate_blocks_statef * zlib_inflate_blocks_new (
     z_streamp z,
-    check_func c,               /* check function */
-    uInt w));                   /* window size */
+    check_func c,              /* check function */
+    uInt w);                   /* window size */
 
-extern int zlib_inflate_blocks OF((
+extern int zlib_inflate_blocks (
     inflate_blocks_statef *,
     z_streamp ,
-    int));                      /* initial return code */
+    int);                      /* initial return code */
 
-extern void zlib_inflate_blocks_reset OF((
+extern void zlib_inflate_blocks_reset (
     inflate_blocks_statef *,
     z_streamp ,
-    uLongf *));                  /* check value on output */
+    uLong *);                  /* check value on output */
 
-extern int zlib_inflate_blocks_free OF((
+extern int zlib_inflate_blocks_free (
     inflate_blocks_statef *,
-    z_streamp));
+    z_streamp);
 
-extern void zlib_inflate_set_dictionary OF((
+extern void zlib_inflate_set_dictionary (
     inflate_blocks_statef *s,
-    const Bytef *d,  /* dictionary */
-    uInt  n));       /* dictionary length */
+    const Byte *d,  /* dictionary */
+    uInt  n);       /* dictionary length */
 
-extern int zlib_inflate_blocks_sync_point OF((
-    inflate_blocks_statef *s));
+extern int zlib_inflate_blocks_sync_point (
+    inflate_blocks_statef *s);
 
 #endif /* _INFBLOCK_H */
diff -urN linux-2.5.70-bk10/lib/zlib_inflate/infcodes.c linux-2.5.70-bk11/lib/zlib_inflate/infcodes.c
--- linux-2.5.70-bk10/lib/zlib_inflate/infcodes.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_inflate/infcodes.c	2003-06-06 04:38:28.000000000 -0700
@@ -47,11 +47,11 @@
   uInt e;               /* extra bits or operation */
   uLong b;              /* bit buffer */
   uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
+  Byte *p;              /* input data pointer */
   uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
+  Byte *q;              /* output window write pointer */
   uInt m;               /* bytes to end of window or read pointer */
-  Bytef *f;             /* pointer to copy strings from */
+  Byte *f;              /* pointer to copy strings from */
   inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
 
   /* copy input/output information to locals (UPDATE macro restores) */
diff -urN linux-2.5.70-bk10/lib/zlib_inflate/infcodes.h linux-2.5.70-bk11/lib/zlib_inflate/infcodes.h
--- linux-2.5.70-bk10/lib/zlib_inflate/infcodes.h	2003-05-26 18:00:27.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_inflate/infcodes.h	2003-06-06 04:38:28.000000000 -0700
@@ -14,20 +14,20 @@
 #include "infblock.h"
 
 struct inflate_codes_state;
-typedef struct inflate_codes_state FAR inflate_codes_statef;
+typedef struct inflate_codes_state inflate_codes_statef;
 
-extern inflate_codes_statef *zlib_inflate_codes_new OF((
+extern inflate_codes_statef *zlib_inflate_codes_new (
     uInt, uInt,
     inflate_huft *, inflate_huft *,
-    z_streamp ));
+    z_streamp );
 
-extern int zlib_inflate_codes OF((
+extern int zlib_inflate_codes (
     inflate_blocks_statef *,
     z_streamp ,
-    int));
+    int);
 
-extern void zlib_inflate_codes_free OF((
+extern void zlib_inflate_codes_free (
     inflate_codes_statef *,
-    z_streamp ));
+    z_streamp );
 
 #endif /* _INFCODES_H */
diff -urN linux-2.5.70-bk10/lib/zlib_inflate/inffast.c linux-2.5.70-bk11/lib/zlib_inflate/inffast.c
--- linux-2.5.70-bk10/lib/zlib_inflate/inffast.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_inflate/inffast.c	2003-06-06 04:38:28.000000000 -0700
@@ -38,15 +38,15 @@
   uInt e;               /* extra bits or operation */
   uLong b;              /* bit buffer */
   uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
+  Byte *p;              /* input data pointer */
   uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
+  Byte *q;              /* output window write pointer */
   uInt m;               /* bytes to end of window or read pointer */
   uInt ml;              /* mask for literal/length tree */
   uInt md;              /* mask for distance tree */
   uInt c;               /* bytes to copy */
   uInt d;               /* distance back to copy from */
-  Bytef *r;             /* copy source pointer */
+  Byte *r;              /* copy source pointer */
 
   /* load input, output, bit values */
   LOAD
diff -urN linux-2.5.70-bk10/lib/zlib_inflate/inffast.h linux-2.5.70-bk11/lib/zlib_inflate/inffast.h
--- linux-2.5.70-bk10/lib/zlib_inflate/inffast.h	2003-05-26 18:00:24.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_inflate/inffast.h	2003-06-06 04:38:28.000000000 -0700
@@ -8,10 +8,10 @@
    subject to change. Applications should only use zlib.h.
  */
 
-extern int zlib_inflate_fast OF((
+extern int zlib_inflate_fast (
     uInt,
     uInt,
     inflate_huft *,
     inflate_huft *,
     inflate_blocks_statef *,
-    z_streamp ));
+    z_streamp );
diff -urN linux-2.5.70-bk10/lib/zlib_inflate/inflate.c linux-2.5.70-bk11/lib/zlib_inflate/inflate.c
--- linux-2.5.70-bk10/lib/zlib_inflate/inflate.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_inflate/inflate.c	2003-06-06 04:38:28.000000000 -0700
@@ -8,13 +8,13 @@
 #include "infblock.h"
 #include "infutil.h"
 
-int ZEXPORT zlib_inflate_workspacesize(void)
+int zlib_inflate_workspacesize(void)
 {
   return sizeof(struct inflate_workspace);
 }
 
 
-int ZEXPORT zlib_inflateReset(
+int zlib_inflateReset(
 	z_streamp z
 )
 {
@@ -28,7 +28,7 @@
 }
 
 
-int ZEXPORT zlib_inflateEnd(
+int zlib_inflateEnd(
 	z_streamp z
 )
 {
@@ -41,7 +41,7 @@
 }
 
 
-int ZEXPORT zlib_inflateInit2_(
+int zlib_inflateInit2_(
 	z_streamp z,
 	int w,
 	const char *version,
@@ -103,7 +103,7 @@
 }
 
 
-int ZEXPORT zlib_inflateInit_(
+int zlib_inflateInit_(
 	z_streamp z,
 	const char *version,
 	int stream_size
@@ -117,7 +117,7 @@
 #define NEEDBYTE {if(z->avail_in==0)goto empty;r=trv;}
 #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
 
-int ZEXPORT zlib_inflate(
+int zlib_inflate(
 	z_streamp z,
 	int f
 )
@@ -250,12 +250,12 @@
 }
 
 
-int ZEXPORT zlib_inflateSync(
+int zlib_inflateSync(
 	z_streamp z
 )
 {
   uInt n;       /* number of bytes to look at */
-  Bytef *p;     /* pointer to bytes */
+  Byte *p;      /* pointer to bytes */
   uInt m;       /* number of marker bytes found in a row */
   uLong r, w;   /* temporaries to save total_in and total_out */
 
@@ -309,7 +309,7 @@
  * decompressing, PPP checks that at the end of input packet, inflate is
  * waiting for these length bytes.
  */
-int ZEXPORT zlib_inflateSyncPoint(
+int zlib_inflateSyncPoint(
 	z_streamp z
 )
 {
@@ -332,9 +332,9 @@
     uLong b;              /* bit buffer */  /* NOT USED HERE */
     uInt k;               /* bits in bit buffer */ /* NOT USED HERE */
     uInt t;               /* temporary storage */
-    Bytef *p;             /* input data pointer */
+    Byte *p;              /* input data pointer */
     uInt n;               /* bytes available there */
-    Bytef *q;             /* output window write pointer */
+    Byte *q;              /* output window write pointer */
     uInt m;               /* bytes to end of window or read pointer */
 
     if (s->read != s->write)
@@ -380,7 +380,7 @@
  * will have been updated if need be.
  */
 
-int ZEXPORT zlib_inflateIncomp(
+int zlib_inflateIncomp(
 	z_stream *z
 	
 )
diff -urN linux-2.5.70-bk10/lib/zlib_inflate/inftrees.c linux-2.5.70-bk11/lib/zlib_inflate/inftrees.c
--- linux-2.5.70-bk10/lib/zlib_inflate/inftrees.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_inflate/inftrees.c	2003-06-06 04:38:28.000000000 -0700
@@ -22,17 +22,17 @@
 #define bits word.what.Bits
 
 
-local int huft_build OF((
-    uIntf *,            /* code lengths in bits */
+local int huft_build (
+    uInt *,             /* code lengths in bits */
     uInt,               /* number of codes */
     uInt,               /* number of "simple" codes */
-    const uIntf *,      /* list of base values for non-simple codes */
-    const uIntf *,      /* list of extra bits for non-simple codes */
-    inflate_huft * FAR*,/* result: starting table */
-    uIntf *,            /* maximum lookup bits (returns actual) */
+    const uInt *,       /* list of base values for non-simple codes */
+    const uInt *,       /* list of extra bits for non-simple codes */
+    inflate_huft **,    /* result: starting table */
+    uInt *,             /* maximum lookup bits (returns actual) */
     inflate_huft *,     /* space for trees */
     uInt *,             /* hufts used in space */
-    uIntf * ));         /* space for values */
+    uInt * );           /* space for values */
 
 /* Tables for deflate from PKZIP's appnote.txt. */
 local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
@@ -88,16 +88,16 @@
 #define BMAX 15         /* maximum bit length of any code */
 
 local int huft_build(
-	uIntf *b,               /* code lengths in bits (all assumed <= BMAX) */
-	uInt n,                 /* number of codes (assumed <= 288) */
-	uInt s,                 /* number of simple-valued codes (0..s-1) */
-	const uIntf *d,         /* list of base values for non-simple codes */
-	const uIntf *e,         /* list of extra bits for non-simple codes */
-	inflate_huft * FAR *t,  /* result: starting table */
-	uIntf *m,               /* maximum lookup bits, returns actual */
-	inflate_huft *hp,       /* space for trees */
-	uInt *hn,               /* hufts used in space */
-	uIntf *v                /* working area: values in order of bit length */
+	uInt *b,               /* code lengths in bits (all assumed <= BMAX) */
+	uInt n,                /* number of codes (assumed <= 288) */
+	uInt s,                /* number of simple-valued codes (0..s-1) */
+	const uInt *d,         /* list of base values for non-simple codes */
+	const uInt *e,         /* list of extra bits for non-simple codes */
+	inflate_huft **t,      /* result: starting table */
+	uInt *m,               /* maximum lookup bits, returns actual */
+	inflate_huft *hp,      /* space for trees */
+	uInt *hn,              /* hufts used in space */
+	uInt *v                /* working area: values in order of bit length */
 )
 /* Given a list of code lengths and a maximum table size, make a set of
    tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
@@ -116,13 +116,13 @@
   register int k;               /* number of bits in current code */
   int l;                        /* bits per table (returned in m) */
   uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */
-  register uIntf *p;            /* pointer into c[], b[], or v[] */
+  register uInt *p;             /* pointer into c[], b[], or v[] */
   inflate_huft *q;              /* points to current table */
   struct inflate_huft_s r;      /* table entry for structure assignment */
   inflate_huft *u[BMAX];        /* table stack */
   register int w;               /* bits before this table == (l * h) */
   uInt x[BMAX+1];               /* bit offsets, then code stack */
-  uIntf *xp;                    /* pointer into x */
+  uInt *xp;                     /* pointer into x */
   int y;                        /* number of dummy codes added */
   uInt z;                       /* number of entries in current table */
 
@@ -290,19 +290,19 @@
 
 
 int zlib_inflate_trees_bits(
-	uIntf *c,               /* 19 code lengths */
-	uIntf *bb,              /* bits tree desired/actual depth */
-	inflate_huft * FAR *tb, /* bits tree result */
+	uInt *c,                /* 19 code lengths */
+	uInt *bb,               /* bits tree desired/actual depth */
+	inflate_huft **tb,      /* bits tree result */
 	inflate_huft *hp,       /* space for trees */
 	z_streamp z             /* for messages */
 )
 {
   int r;
   uInt hn = 0;          /* hufts used in space */
-  uIntf *v;             /* work area for huft_build */
+  uInt *v;              /* work area for huft_build */
   
   v = WS(z)->tree_work_area_1;
-  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
+  r = huft_build(c, 19, 19, (uInt*)Z_NULL, (uInt*)Z_NULL,
                  tb, bb, hp, &hn, v);
   if (r == Z_DATA_ERROR)
     z->msg = (char*)"oversubscribed dynamic bit lengths tree";
@@ -317,18 +317,18 @@
 int zlib_inflate_trees_dynamic(
 	uInt nl,                /* number of literal/length codes */
 	uInt nd,                /* number of distance codes */
-	uIntf *c,               /* that many (total) code lengths */
-	uIntf *bl,              /* literal desired/actual bit depth */
-	uIntf *bd,              /* distance desired/actual bit depth */
-	inflate_huft * FAR *tl, /* literal/length tree result */
-	inflate_huft * FAR *td, /* distance tree result */
+	uInt *c,                /* that many (total) code lengths */
+	uInt *bl,               /* literal desired/actual bit depth */
+	uInt *bd,               /* distance desired/actual bit depth */
+	inflate_huft **tl,      /* literal/length tree result */
+	inflate_huft **td,      /* distance tree result */
 	inflate_huft *hp,       /* space for trees */
 	z_streamp z             /* for messages */
 )
 {
   int r;
   uInt hn = 0;          /* hufts used in space */
-  uIntf *v;             /* work area for huft_build */
+  uInt *v;              /* work area for huft_build */
 
   /* allocate work area */
   v = WS(z)->tree_work_area_2;
@@ -380,10 +380,10 @@
 
 
 int zlib_inflate_trees_fixed(
-	uIntf *bl,               /* literal desired/actual bit depth */
-	uIntf *bd,               /* distance desired/actual bit depth */
-	inflate_huft * FAR *tl,  /* literal/length tree result */
-	inflate_huft * FAR *td,  /* distance tree result */
+	uInt *bl,                /* literal desired/actual bit depth */
+	uInt *bd,                /* distance desired/actual bit depth */
+	inflate_huft **tl,       /* literal/length tree result */
+	inflate_huft **td,       /* distance tree result */
 	z_streamp z              /* for memory allocation */
 )
 {
diff -urN linux-2.5.70-bk10/lib/zlib_inflate/inftrees.h linux-2.5.70-bk11/lib/zlib_inflate/inftrees.h
--- linux-2.5.70-bk10/lib/zlib_inflate/inftrees.h	2003-05-26 18:01:03.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_inflate/inftrees.h	2003-06-06 04:38:28.000000000 -0700
@@ -14,7 +14,7 @@
 #ifndef _INFTREES_H
 #define _INFTREES_H
 
-typedef struct inflate_huft_s FAR inflate_huft;
+typedef struct inflate_huft_s inflate_huft;
 
 struct inflate_huft_s {
   union {
@@ -35,29 +35,29 @@
    value below is more than safe. */
 #define MANY 1440
 
-extern int zlib_inflate_trees_bits OF((
-    uIntf *,                    /* 19 code lengths */
-    uIntf *,                    /* bits tree desired/actual depth */
-    inflate_huft * FAR *,       /* bits tree result */
+extern int zlib_inflate_trees_bits (
+    uInt *,                     /* 19 code lengths */
+    uInt *,                     /* bits tree desired/actual depth */
+    inflate_huft **,            /* bits tree result */
     inflate_huft *,             /* space for trees */
-    z_streamp));                /* for messages */
+    z_streamp);                 /* for messages */
 
-extern int zlib_inflate_trees_dynamic OF((
+extern int zlib_inflate_trees_dynamic (
     uInt,                       /* number of literal/length codes */
     uInt,                       /* number of distance codes */
-    uIntf *,                    /* that many (total) code lengths */
-    uIntf *,                    /* literal desired/actual bit depth */
-    uIntf *,                    /* distance desired/actual bit depth */
-    inflate_huft * FAR *,       /* literal/length tree result */
-    inflate_huft * FAR *,       /* distance tree result */
+    uInt *,                     /* that many (total) code lengths */
+    uInt *,                     /* literal desired/actual bit depth */
+    uInt *,                     /* distance desired/actual bit depth */
+    inflate_huft **,            /* literal/length tree result */
+    inflate_huft **,            /* distance tree result */
     inflate_huft *,             /* space for trees */
-    z_streamp));                /* for messages */
+    z_streamp);                 /* for messages */
 
-extern int zlib_inflate_trees_fixed OF((
-    uIntf *,                    /* literal desired/actual bit depth */
-    uIntf *,                    /* distance desired/actual bit depth */
-    inflate_huft * FAR *,       /* literal/length tree result */
-    inflate_huft * FAR *,       /* distance tree result */
-    z_streamp));                /* for memory allocation */
+extern int zlib_inflate_trees_fixed (
+    uInt *,                     /* literal desired/actual bit depth */
+    uInt *,                     /* distance desired/actual bit depth */
+    inflate_huft **,            /* literal/length tree result */
+    inflate_huft **,            /* distance tree result */
+    z_streamp);                 /* for memory allocation */
 
 #endif /* _INFTREES_H */
diff -urN linux-2.5.70-bk10/lib/zlib_inflate/infutil.c linux-2.5.70-bk11/lib/zlib_inflate/infutil.c
--- linux-2.5.70-bk10/lib/zlib_inflate/infutil.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_inflate/infutil.c	2003-06-06 04:38:28.000000000 -0700
@@ -27,8 +27,8 @@
 )
 {
   uInt n;
-  Bytef *p;
-  Bytef *q;
+  Byte *p;
+  Byte *q;
 
   /* local copies of source and destination pointers */
   p = z->next_out;
diff -urN linux-2.5.70-bk10/lib/zlib_inflate/infutil.h linux-2.5.70-bk11/lib/zlib_inflate/infutil.h
--- linux-2.5.70-bk10/lib/zlib_inflate/infutil.h	2003-05-26 18:00:45.000000000 -0700
+++ linux-2.5.70-bk11/lib/zlib_inflate/infutil.h	2003-06-06 04:38:28.000000000 -0700
@@ -40,7 +40,7 @@
     struct {
       uInt table;               /* table lengths (14 bits) */
       uInt index;               /* index into blens (or border) */
-      uIntf *blens;             /* bit lengths of codes */
+      uInt *blens;              /* bit lengths of codes */
       uInt bb;                  /* bit length tree depth */
       inflate_huft *tb;         /* bit length decoding tree */
     } trees;            /* if DTREE, decoding info for trees */
@@ -55,10 +55,10 @@
   uInt bitk;            /* bits in bit buffer */
   uLong bitb;           /* bit buffer */
   inflate_huft *hufts;  /* single malloc for tree space */
-  Bytef *window;        /* sliding window */
-  Bytef *end;           /* one byte after sliding window */
-  Bytef *read;          /* window read pointer */
-  Bytef *write;         /* window write pointer */
+  Byte *window;         /* sliding window */
+  Byte *end;            /* one byte after sliding window */
+  Byte *read;           /* window read pointer */
+  Byte *write;          /* window write pointer */
   check_func checkfn;   /* check function */
   uLong check;          /* check on output */
 
@@ -92,10 +92,10 @@
 extern uInt zlib_inflate_mask[17];
 
 /* copy as much as possible from the sliding window to the output area */
-extern int zlib_inflate_flush OF((
+extern int zlib_inflate_flush (
     inflate_blocks_statef *,
     z_streamp ,
-    int));
+    int);
 
 /* inflate private state */
 typedef enum {
diff -urN linux-2.5.70-bk10/net/ax25/ax25_ip.c linux-2.5.70-bk11/net/ax25/ax25_ip.c
--- linux-2.5.70-bk10/net/ax25/ax25_ip.c	2003-05-26 18:00:37.000000000 -0700
+++ linux-2.5.70-bk11/net/ax25/ax25_ip.c	2003-06-06 04:38:29.000000000 -0700
@@ -154,9 +154,15 @@
 				skb_set_owner_w(ourskb, skb->sk);
 
 			kfree_skb(skb);
-
-			src_c = *src;
-			dst_c = *dst;
+			/* dl9sau: bugfix
+			 * after kfree_skb(), dst and src which were pointer
+			 * to bp which is part of skb->data would not be valid
+			 * anymore hope that after skb_pull(ourskb, ..) our
+			 * dsc_c and src_c will not become invalid
+			 */
+			bp  = ourskb->data;
+			dst_c = *(ax25_address *)(bp + 1);
+			src_c = *(ax25_address *)(bp + 8);
 
 			skb_pull(ourskb, AX25_HEADER_LEN - 1);	/* Keep PID */
 			ourskb->nh.raw = ourskb->data;
diff -urN linux-2.5.70-bk10/net/core/flow.c linux-2.5.70-bk11/net/core/flow.c
--- linux-2.5.70-bk10/net/core/flow.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/net/core/flow.c	2003-06-06 04:38:29.000000000 -0700
@@ -11,6 +11,7 @@
 #include <linux/mm.h>
 #include <linux/random.h>
 #include <linux/init.h>
+#include <linux/slab.h>
 #include <net/flow.h>
 #include <asm/atomic.h>
 
diff -urN linux-2.5.70-bk10/net/ipv4/xfrm4_input.c linux-2.5.70-bk11/net/ipv4/xfrm4_input.c
--- linux-2.5.70-bk10/net/ipv4/xfrm4_input.c	2003-05-26 18:00:23.000000000 -0700
+++ linux-2.5.70-bk11/net/ipv4/xfrm4_input.c	2003-06-06 04:38:29.000000000 -0700
@@ -9,6 +9,7 @@
  * 	
  */
 
+#include <linux/slab.h>
 #include <net/ip.h>
 #include <net/xfrm.h>
 
diff -urN linux-2.5.70-bk10/net/xfrm/xfrm_policy.c linux-2.5.70-bk11/net/xfrm/xfrm_policy.c
--- linux-2.5.70-bk10/net/xfrm/xfrm_policy.c	2003-06-06 04:38:15.000000000 -0700
+++ linux-2.5.70-bk11/net/xfrm/xfrm_policy.c	2003-06-06 04:38:29.000000000 -0700
@@ -14,6 +14,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/slab.h>
 #include <net/xfrm.h>
 #include <net/ip.h>
 
diff -urN linux-2.5.70-bk10/sound/oss/awe_wave.c linux-2.5.70-bk11/sound/oss/awe_wave.c
--- linux-2.5.70-bk10/sound/oss/awe_wave.c	2003-05-26 18:00:38.000000000 -0700
+++ linux-2.5.70-bk11/sound/oss/awe_wave.c	2003-06-06 04:38:29.000000000 -0700
@@ -2046,7 +2046,8 @@
 			awe_info.nr_voices = awe_max_voices;
 		else
 			awe_info.nr_voices = AWE_MAX_CHANNELS;
-		memcpy((char*)arg, &awe_info, sizeof(awe_info));
+		if (copy_to_user((char*)arg, &awe_info, sizeof(awe_info)))
+			return -EFAULT;
 		return 0;
 		break;
 
@@ -2063,10 +2064,12 @@
 
 	case SNDCTL_SYNTH_MEMAVL:
 		return memsize - awe_free_mem_ptr() * 2;
+		break;
 
 	default:
 		printk(KERN_WARNING "AWE32: unsupported ioctl %d\n", cmd);
 		return -EINVAL;
+		break;
 	}
 }
 
@@ -4314,7 +4317,8 @@
 	if (((cmd >> 8) & 0xff) != 'M')
 		return -EINVAL;
 
-	level = *(int*)arg;
+	if (get_user(level, (int *)arg))
+		return -EFAULT;
 	level = ((level & 0xff) + (level >> 8)) / 2;
 	DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level));
 
@@ -4370,7 +4374,9 @@
 		level = 0;
 		break;
 	}
-	return *(int*)arg = level;
+	if (put_user(level, (int *)arg))
+		return -EFAULT;
+	return level;
 }
 #endif /* CONFIG_AWE32_MIXER */
 
diff -urN linux-2.5.70-bk10/sound/oss/dmasound/Kconfig linux-2.5.70-bk11/sound/oss/dmasound/Kconfig
--- linux-2.5.70-bk10/sound/oss/dmasound/Kconfig	2003-05-26 18:00:40.000000000 -0700
+++ linux-2.5.70-bk11/sound/oss/dmasound/Kconfig	2003-06-06 04:38:29.000000000 -0700
@@ -14,7 +14,7 @@
 
 config DMASOUND_AWACS
 	tristate "PowerMac DMA sound support"
-	depends on ALL_PPC && SOUND
+	depends on PPC_PMAC && SOUND
 	help
 	  If you want to use the internal audio of your PowerMac in Linux,
 	  answer Y to this question. This will provide a Sun-like /dev/audio,
