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

diff -urN linux-2.5.73-bk2/Documentation/DocBook/gadget.tmpl linux-2.5.73-bk3/Documentation/DocBook/gadget.tmpl
--- linux-2.5.73-bk2/Documentation/DocBook/gadget.tmpl	2003-06-22 11:32:45.000000000 -0700
+++ linux-2.5.73-bk3/Documentation/DocBook/gadget.tmpl	2003-06-25 04:46:47.000000000 -0700
@@ -6,31 +6,32 @@
     <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>
-
+       <para>
+	 This documentation is free software; you can redistribute
+	 it and/or modify it under the terms of the GNU General Public
+	 License as published by the Free Software Foundation; either
+	 version 2 of the License, or (at your option) any later
+	 version.
+       </para>
+	  
+       <para>
+	 This program is distributed in the hope that it will be
+	 useful, but WITHOUT ANY WARRANTY; without even the implied
+	 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+	 See the GNU General Public License for more details.
+       </para>
+	  
+       <para>
+	 You should have received a copy of the GNU General Public
+	 License along with this program; if not, write to the Free
+	 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+	 MA 02111-1307 USA
+       </para>
+	  
+       <para>
+	 For more details see the file COPYING in the source
+	 distribution of Linux.
+       </para>
     </legalnotice>
     <copyright>
       <year>2003</year>
@@ -325,9 +326,10 @@
 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)
+(N bytes per frame, multipoint addressing, host as the primary
+station and devices as secondary stations)
 more than asynchronous ones
-(tty style, like 8 bytes, no parity, one stop bit).
+(tty style:  8 data bits per frame, 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
@@ -528,438 +530,6 @@
 </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.73-bk2/Makefile linux-2.5.73-bk3/Makefile
--- linux-2.5.73-bk2/Makefile	2003-06-25 04:46:43.000000000 -0700
+++ linux-2.5.73-bk3/Makefile	2003-06-25 04:46:47.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 73
-EXTRAVERSION = -bk2
+EXTRAVERSION = -bk3
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -urN linux-2.5.73-bk2/arch/i386/kernel/apic.c linux-2.5.73-bk3/arch/i386/kernel/apic.c
--- linux-2.5.73-bk2/arch/i386/kernel/apic.c	2003-06-22 11:33:35.000000000 -0700
+++ linux-2.5.73-bk3/arch/i386/kernel/apic.c	2003-06-25 04:46:47.000000000 -0700
@@ -616,7 +616,7 @@
 		goto no_apic;
 	case X86_VENDOR_INTEL:
 		if (boot_cpu_data.x86 == 6 ||
-		    (boot_cpu_data.x86 == 15 && cpu_has_apic) ||
+		    boot_cpu_data.x86 == 15 ||
 		    (boot_cpu_data.x86 == 5 && cpu_has_apic))
 			break;
 		goto no_apic;
diff -urN linux-2.5.73-bk2/arch/i386/kernel/io_apic.c linux-2.5.73-bk3/arch/i386/kernel/io_apic.c
--- linux-2.5.73-bk2/arch/i386/kernel/io_apic.c	2003-06-22 11:32:40.000000000 -0700
+++ linux-2.5.73-bk3/arch/i386/kernel/io_apic.c	2003-06-25 04:46:47.000000000 -0700
@@ -1275,6 +1275,7 @@
 	struct IO_APIC_reg_00 reg_00;
 	struct IO_APIC_reg_01 reg_01;
 	struct IO_APIC_reg_02 reg_02;
+	struct IO_APIC_reg_03 reg_03;
 	unsigned long flags;
 
  	printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
@@ -1295,6 +1296,8 @@
 	*(int *)&reg_01 = io_apic_read(apic, 1);
 	if (reg_01.version >= 0x10)
 		*(int *)&reg_02 = io_apic_read(apic, 2);
+	if (reg_01.version >= 0x20)
+		*(int *)&reg_03 = io_apic_read(apic, 3);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	printk("\n");
@@ -1332,13 +1335,31 @@
 	if (reg_01.__reserved_1 || reg_01.__reserved_2)
 		UNEXPECTED_IO_APIC();
 
-	if (reg_01.version >= 0x10) {
+	/*
+	 * Some Intel chipsets with IO APIC VERSION of 0x1? don't have reg_02,
+	 * but the value of reg_02 is read as the previous read register
+	 * value, so ignore it if reg_02 == reg_01.
+	 */
+	if (reg_01.version >= 0x10 && *(int *)&reg_02 != *(int *)&reg_01) {
 		printk(KERN_DEBUG ".... register #02: %08X\n", *(int *)&reg_02);
 		printk(KERN_DEBUG ".......     : arbitration: %02X\n", reg_02.arbitration);
 		if (reg_02.__reserved_1 || reg_02.__reserved_2)
 			UNEXPECTED_IO_APIC();
 	}
 
+	/*
+	 * Some Intel chipsets with IO APIC VERSION of 0x2? don't have reg_02
+	 * or reg_03, but the value of reg_0[23] is read as the previous read
+	 * register value, so ignore it if reg_03 == reg_0[12].
+	 */
+	if (reg_01.version >= 0x20 && *(int *)&reg_03 != *(int *)&reg_02 &&
+	    *(int *)&reg_03 != *(int *)&reg_01) {
+		printk(KERN_DEBUG ".... register #03: %08X\n", *(int *)&reg_03);
+		printk(KERN_DEBUG ".......     : Boot DT    : %X\n", reg_03.boot_DT);
+		if (reg_03.__reserved_1)
+			UNEXPECTED_IO_APIC();
+	}
+
 	printk(KERN_DEBUG ".... IRQ redirection table:\n");
 
 	printk(KERN_DEBUG " NR Log Phy Mask Trig IRR Pol"
diff -urN linux-2.5.73-bk2/arch/ia64/Kconfig linux-2.5.73-bk3/arch/ia64/Kconfig
--- linux-2.5.73-bk2/arch/ia64/Kconfig	2003-06-22 11:33:18.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/Kconfig	2003-06-25 04:46:47.000000000 -0700
@@ -544,6 +544,8 @@
 
 source "drivers/block/Kconfig"
 
+source "drivers/ide/Kconfig"
+
 source "drivers/ieee1394/Kconfig"
 
 source "drivers/message/i2o/Kconfig"
@@ -787,6 +789,10 @@
 	bool "Early printk on VGA"
 	depends on IA64_EARLY_PRINTK
 
+config IA64_EARLY_PRINTK_SGI_SN
+	bool "Early printk on SGI SN serial console"
+	depends on IA64_EARLY_PRINTK && (IA64_GENERIC || IA64_SGI_SN2)
+
 config DEBUG_SLAB
 	bool "Debug memory allocations"
 	depends on DEBUG_KERNEL
diff -urN linux-2.5.73-bk2/arch/ia64/Makefile linux-2.5.73-bk3/arch/ia64/Makefile
--- linux-2.5.73-bk2/arch/ia64/Makefile	2003-06-22 11:32:31.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/Makefile	2003-06-25 04:46:47.000000000 -0700
@@ -27,7 +27,7 @@
 
 GAS_STATUS=$(shell arch/ia64/scripts/check-gas $(CC) $(OBJDUMP))
 
-arch-cppflags	:= $(shell arch/ia64/scripts/toolchain-flags $(CC) $(LD) $(OBJDUMP))
+arch-cppflags	:= $(shell arch/ia64/scripts/toolchain-flags $(CC) $(OBJDUMP))
 cflags-y	+= $(arch-cppflags)
 AFLAGS		+= $(arch-cppflags)
 
@@ -66,7 +66,8 @@
 drivers-$(CONFIG_PCI)		+= arch/ia64/pci/
 drivers-$(CONFIG_IA64_HP_SIM)	+= arch/ia64/hp/sim/
 drivers-$(CONFIG_IA64_HP_ZX1)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/
-drivers-$(CONFIG_IA64_GENERIC)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/
+drivers-$(CONFIG_IA64_GENERIC)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ \
+				   arch/ia64/sn/
 
 boot := arch/ia64/boot
 
diff -urN linux-2.5.73-bk2/arch/ia64/defconfig linux-2.5.73-bk3/arch/ia64/defconfig
--- linux-2.5.73-bk2/arch/ia64/defconfig	2003-06-22 11:32:32.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/defconfig	2003-06-25 04:46:47.000000000 -0700
@@ -10,30 +10,38 @@
 #
 # General setup
 #
-CONFIG_NET=y
+CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_SYSCTL=y
+CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_EMBEDDED is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
 
 #
 # Loadable module support
 #
 CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_OBSOLETE_MODPARM=y
 CONFIG_MODVERSIONS=y
-# CONFIG_KMOD is not set
+CONFIG_KMOD=y
 
 #
 # Processor type and features
 #
 CONFIG_IA64=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_ITANIUM=y
-# CONFIG_MCKINLEY is not set
+CONFIG_MMU=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_TIME_INTERPOLATION=y
+# CONFIG_ITANIUM is not set
+CONFIG_MCKINLEY=y
 # CONFIG_IA64_GENERIC is not set
-CONFIG_IA64_DIG=y
+# CONFIG_IA64_DIG is not set
 # CONFIG_IA64_HP_SIM is not set
-# CONFIG_IA64_HP_ZX1 is not set
-# CONFIG_IA64_SGI_SN1 is not set
+CONFIG_IA64_HP_ZX1=y
 # CONFIG_IA64_SGI_SN2 is not set
 # CONFIG_IA64_PAGE_SIZE_4KB is not set
 # CONFIG_IA64_PAGE_SIZE_8KB is not set
@@ -43,41 +51,64 @@
 CONFIG_ACPI_EFI=y
 CONFIG_ACPI_INTERPRETER=y
 CONFIG_ACPI_KERNEL_CONFIG=y
-CONFIG_IA64_BRL_EMU=y
-# CONFIG_ITANIUM_BSTEP_SPECIFIC is not set
-CONFIG_IA64_L1_CACHE_SHIFT=6
+CONFIG_IA64_L1_CACHE_SHIFT=7
+# CONFIG_MCKINLEY_ASTEP_SPECIFIC is not set
 # CONFIG_NUMA is not set
+CONFIG_VIRTUAL_MEM_MAP=y
 CONFIG_IA64_MCA=y
 CONFIG_PM=y
 CONFIG_IOSAPIC=y
 CONFIG_KCORE_ELF=y
 CONFIG_FORCE_MAX_ZONEORDER=18
-# CONFIG_HUGETLB_PAGE is not set
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_HUGETLB_PAGE_SIZE_4GB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1GB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256MB is not set
+CONFIG_HUGETLB_PAGE_SIZE_64MB=y
+# CONFIG_HUGETLB_PAGE_SIZE_16MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_4MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_1MB is not set
+# CONFIG_HUGETLB_PAGE_SIZE_256KB is not set
+CONFIG_IA64_PAL_IDLE=y
 CONFIG_SMP=y
+# CONFIG_PREEMPT is not set
 CONFIG_IA32_SUPPORT=y
+CONFIG_COMPAT=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
 CONFIG_EFI_VARS=y
 CONFIG_NR_CPUS=16
 CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
+CONFIG_BINFMT_MISC=y
 
 #
 # ACPI Support
 #
 CONFIG_ACPI_BOOT=y
 CONFIG_ACPI_BUTTON=y
-CONFIG_ACPI_FAN=m
-CONFIG_ACPI_PROCESSOR=m
-CONFIG_ACPI_THERMAL=m
+CONFIG_ACPI_FAN=y
+CONFIG_ACPI_PROCESSOR=y
+CONFIG_ACPI_THERMAL=y
 # CONFIG_ACPI_DEBUG is not set
 CONFIG_ACPI_BUS=y
 CONFIG_ACPI_POWER=y
 CONFIG_ACPI_PCI=y
 CONFIG_ACPI_SYSTEM=y
 CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_LEGACY_PROC=y
 CONFIG_PCI_NAMES=y
-# CONFIG_HOTPLUG is not set
+CONFIG_HOTPLUG=y
+
+#
+# PCI Hotplug Support
+#
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
 
 #
 # Parallel port support
@@ -85,12 +116,17 @@
 # CONFIG_PARPORT is not set
 
 #
+# Generic Driver Options
+#
+# CONFIG_FW_LOADER is not set
+
+#
 # Memory Technology Devices (MTD)
 #
 # CONFIG_MTD is not set
 
 #
-# Plug and Play configuration
+# Plug and Play support
 #
 # CONFIG_PNP is not set
 
@@ -104,7 +140,9 @@
 # CONFIG_BLK_DEV_UMEM is not set
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
 
 #
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -124,64 +162,11 @@
 #
 # Fusion MPT device support
 #
-# CONFIG_FUSION is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_IDEDISK_STROKE is not set
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDEFLOPPY=y
-CONFIG_BLK_DEV_IDESCSI=y
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_BLK_DEV_GENERIC is not set
-CONFIG_IDEPCI_SHARE_IRQ=y
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDE_TCQ is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_PCI_WIP is not set
-CONFIG_BLK_DEV_ADMA=y
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_NFORCE is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_IDEDMA_IVB is not set
+CONFIG_FUSION=y
+CONFIG_FUSION_BOOT=y
+CONFIG_FUSION_MAX_SGE=40
+# CONFIG_FUSION_ISENSE is not set
+# CONFIG_FUSION_CTL is not set
 
 #
 # SCSI support
@@ -192,16 +177,17 @@
 # SCSI support type (disk, tape, CD-ROM)
 #
 CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_CHR_DEV_ST=y
+CONFIG_CHR_DEV_OSST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_REPORT_LUNS is not set
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_REPORT_LUNS=y
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_LOGGING=y
 
@@ -212,57 +198,76 @@
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AACRAID is not set
 # CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
+CONFIG_SCSI_AIC7XXX_OLD=y
+# CONFIG_SCSI_AIC79XX is not set
 # CONFIG_SCSI_DPT_I2O is not set
 # CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
+CONFIG_SCSI_MEGARAID=y
 # CONFIG_SCSI_BUSLOGIC is not set
 # CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
 # CONFIG_SCSI_EATA_PIO is not set
 # CONFIG_SCSI_FUTURE_DOMAIN is not set
 # CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_NCR53C8XX is not set
-# CONFIG_SCSI_SYM53C8XX is not set
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
+CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
+CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
+# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
 # CONFIG_SCSI_PCI2000 is not set
 # CONFIG_SCSI_PCI2220I is not set
 # CONFIG_SCSI_QLOGIC_ISP is not set
 # CONFIG_SCSI_QLOGIC_FC is not set
 CONFIG_SCSI_QLOGIC_1280=y
+# CONFIG_SCSI_DC395x is not set
 # CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 
 #
+# Networking support
+#
+CONFIG_NET=y
+
+#
 # Networking options
 #
 CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
+# CONFIG_PACKET_MMAP is not set
 # CONFIG_NETLINK_DEV is not set
-# CONFIG_NETFILTER is not set
-CONFIG_FILTER=y
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
 CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 # CONFIG_IP_PNP is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
 # CONFIG_ARPD is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_IP_NF_CONNTRACK is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+CONFIG_IP_NF_ARPTABLES=y
+# CONFIG_IP_NF_ARPFILTER is not set
+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 # CONFIG_IPV6 is not set
+# CONFIG_XFRM_USER is not set
 
 #
 # SCTP Configuration (EXPERIMENTAL)
@@ -288,8 +293,9 @@
 # CONFIG_NET_SCHED is not set
 
 #
-# Network device support
+# Network testing
 #
+# CONFIG_NET_PKTGEN is not set
 CONFIG_NETDEVICES=y
 
 #
@@ -297,7 +303,7 @@
 #
 # CONFIG_ARCNET is not set
 CONFIG_DUMMY=y
-# CONFIG_BONDING is not set
+CONFIG_BONDING=y
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_ETHERTAP is not set
@@ -306,11 +312,10 @@
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
 
 #
 # Tulip family network device support
@@ -319,9 +324,12 @@
 # CONFIG_HP100 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
+# CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_B44 is not set
 # CONFIG_DGRS is not set
 CONFIG_EEPRO100=y
+# CONFIG_EEPRO100_PIO is not set
 # CONFIG_E100 is not set
 # CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
@@ -333,19 +341,25 @@
 # CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_NET_POCKET is not set
 
 #
 # Ethernet (1000 Mbit)
 #
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
+CONFIG_E1000=y
+# CONFIG_E1000_NAPI is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
 # CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
+CONFIG_TIGON3=m
+
+#
+# Ethernet (10000 Mbit)
+#
+# CONFIG_IXGB is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PPP is not set
@@ -357,9 +371,8 @@
 # CONFIG_NET_RADIO is not set
 
 #
-# Token Ring devices
+# Token Ring devices (depends on LLC=y)
 #
-# CONFIG_TR is not set
 # CONFIG_NET_FC is not set
 # CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
@@ -393,10 +406,10 @@
 # Userland interfaces
 #
 CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_JOYDEV=y
 # CONFIG_INPUT_TSDEV is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_EVBUG is not set
@@ -407,26 +420,19 @@
 # CONFIG_GAMEPORT is not set
 CONFIG_SOUND_GAMEPORT=y
 CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_CT82C710 is not set
+# CONFIG_SERIO_PCIPS2 is not set
 
 #
 # Input Device Drivers
 #
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
-CONFIG_INPUT_MISC=y
-# CONFIG_INPUT_PCSPKR is not set
-# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_MISC is not set
 
 #
 # Character devices
@@ -441,12 +447,9 @@
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_EXTENDED=y
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_RSA is not set
+CONFIG_SERIAL_8250_ACPI=y
+CONFIG_SERIAL_8250_HCDP=y
+# CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
 # Non-8250 serial port support
@@ -459,14 +462,16 @@
 #
 # I2C support
 #
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-# CONFIG_I2C_ELV is not set
-# CONFIG_I2C_VELLEMAN is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_PROC=y
+# CONFIG_I2C is not set
+
+#
+# I2C Hardware Sensors Mainboard support
+#
+
+#
+# I2C Hardware Sensors Chip support
+#
+# CONFIG_I2C_SENSOR is not set
 
 #
 # Mice
@@ -475,12 +480,16 @@
 # CONFIG_QIC02_TAPE is not set
 
 #
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
+# CONFIG_HW_RANDOM is not set
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
 # CONFIG_GEN_RTC is not set
 CONFIG_EFI_RTC=y
 # CONFIG_DTLK is not set
@@ -491,25 +500,17 @@
 # Ftape, the floppy tape device driver
 #
 # CONFIG_FTAPE is not set
-CONFIG_AGP=y
-CONFIG_AGP_INTEL=y
-CONFIG_AGP_I810=y
-CONFIG_AGP_VIA=y
-CONFIG_AGP_AMD=y
-CONFIG_AGP_SIS=y
-CONFIG_AGP_ALI=y
-CONFIG_AGP_SWORKS=y
-# CONFIG_AGP_AMD_8151 is not set
-CONFIG_AGP_I460=y
-CONFIG_AGP_HP_ZX1=y
+CONFIG_AGP=m
+CONFIG_AGP_I460=m
+CONFIG_AGP_HP_ZX1=m
 CONFIG_DRM=y
-CONFIG_DRM_TDFX=y
-CONFIG_DRM_R128=y
-CONFIG_DRM_RADEON=y
-CONFIG_DRM_I810=y
-CONFIG_DRM_I830=y
-CONFIG_DRM_MGA=y
+# CONFIG_DRM_TDFX is not set
+# CONFIG_DRM_GAMMA is not set
+# CONFIG_DRM_R128 is not set
+CONFIG_DRM_RADEON=m
+# CONFIG_DRM_MGA is not set
 # CONFIG_RAW_DRIVER is not set
+# CONFIG_HANGCHECK_TIMER is not set
 
 #
 # Multimedia devices
@@ -517,51 +518,79 @@
 # CONFIG_VIDEO_DEV is not set
 
 #
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
 # File systems
 #
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+# CONFIG_EXT2_FS_POSIX_ACL is not set
+# CONFIG_EXT2_FS_SECURITY is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
 # CONFIG_QUOTA is not set
 CONFIG_AUTOFS_FS=y
 # CONFIG_AUTOFS4_FS is not set
-# CONFIG_REISERFS_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_ZISOFS is not set
+CONFIG_UDF_FS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_DEVPTS_FS_XATTR is not set
+CONFIG_TMPFS=y
+CONFIG_HUGETLBFS=y
+CONFIG_RAMFS=y
+
+#
+# Miscellaneous filesystems
+#
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BEFS_FS is not set
 # CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=y
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_CRAMFS is not set
-# CONFIG_TMPFS is not set
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
 # CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_XFS_FS is not set
 
 #
 # Network File Systems
 #
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 CONFIG_NFS_V4=y
@@ -569,13 +598,16 @@
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V4 is not set
 # CONFIG_NFSD_TCP is not set
-CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
-# CONFIG_CIFS is not set
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
 # CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_INTERMEZZO_FS is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -593,6 +625,7 @@
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
 # CONFIG_LDM_PARTITION is not set
+# CONFIG_NEC98_PARTITION is not set
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
@@ -603,53 +636,84 @@
 # Native Language Support
 #
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
 # CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+
+#
+# Graphics support
+#
+CONFIG_FB=y
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_IMSTT is not set
+CONFIG_FB_RIVA=m
+# CONFIG_FB_MATROX is not set
+CONFIG_FB_RADEON=y
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_VIRTUAL is not set
 
 #
-# Console drivers
+# Console display driver support
 #
 CONFIG_VGA_CONSOLE=y
+# CONFIG_MDA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_PCI_CONSOLE=y
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
 
 #
-# Frame-buffer support
-#
-# CONFIG_FB is not set
+# Logo configuration
+#
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
 
 #
 # Sound
@@ -659,31 +723,62 @@
 #
 # Advanced Linux Sound Architecture
 #
-# CONFIG_SND is not set
+CONFIG_SND=m
+CONFIG_SND_SEQUENCER=m
+# CONFIG_SND_SEQ_DUMMY is not set
+# CONFIG_SND_OSSEMUL is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_VIRMIDI is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# PCI devices
+#
+# CONFIG_SND_ALI5451 is not set
+# CONFIG_SND_AZT3328 is not set
+# CONFIG_SND_CS46XX is not set
+# CONFIG_SND_CS4281 is not set
+# CONFIG_SND_EMU10K1 is not set
+# CONFIG_SND_KORG1212 is not set
+# CONFIG_SND_NM256 is not set
+# CONFIG_SND_RME32 is not set
+# CONFIG_SND_RME96 is not set
+# CONFIG_SND_RME9652 is not set
+# CONFIG_SND_HDSP is not set
+# CONFIG_SND_TRIDENT is not set
+# CONFIG_SND_YMFPCI is not set
+# CONFIG_SND_ALS4000 is not set
+# CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_ENS1370 is not set
+# CONFIG_SND_ENS1371 is not set
+# CONFIG_SND_ES1938 is not set
+# CONFIG_SND_ES1968 is not set
+# CONFIG_SND_MAESTRO3 is not set
+CONFIG_SND_FM801=m
+# CONFIG_SND_ICE1712 is not set
+# CONFIG_SND_ICE1724 is not set
+# CONFIG_SND_INTEL8X0 is not set
+# CONFIG_SND_SONICVIBES is not set
+# CONFIG_SND_VIA82XX is not set
+# CONFIG_SND_VX222 is not set
+
+#
+# ALSA USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
 
 #
 # Open Sound System
 #
-CONFIG_SOUND_PRIME=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-CONFIG_SOUND_CS4281=y
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_TVMIXER is not set
+# CONFIG_SOUND_PRIME is not set
 
 #
 # USB support
@@ -694,17 +789,16 @@
 #
 # Miscellaneous USB options
 #
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_LONG_TIMEOUT is not set
-# CONFIG_USB_BANDWIDTH is not set
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_BANDWIDTH=y
 # CONFIG_USB_DYNAMIC_MINORS is not set
 
 #
 # USB Host Controller Drivers
 #
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_OHCI_HCD is not set
-CONFIG_USB_UHCI_HCD_ALT=y
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_UHCI_HCD=m
 
 #
 # USB Device Class drivers
@@ -725,6 +819,7 @@
 CONFIG_USB_HIDDEV=y
 # CONFIG_USB_AIPTEK is not set
 # CONFIG_USB_WACOM is not set
+# CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
 # CONFIG_USB_XPAD is not set
 
@@ -748,8 +843,8 @@
 #
 # USB Network adaptors
 #
+# CONFIG_USB_AX8817X is not set
 # CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
 # CONFIG_USB_KAWETH is not set
 # CONFIG_USB_PEGASUS is not set
 # CONFIG_USB_RTL8150 is not set
@@ -772,17 +867,17 @@
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_BRLVGER is not set
 # CONFIG_USB_LCD is not set
-# CONFIG_USB_TEST is not set
+# CONFIG_USB_GADGET is not set
 
 #
-# Library routines
+# Bluetooth support
 #
-# CONFIG_CRC32 is not set
+# CONFIG_BT is not set
 
 #
-# Bluetooth support
+# Library routines
 #
-# CONFIG_BT is not set
+CONFIG_CRC32=y
 
 #
 # Kernel hacking
@@ -794,18 +889,17 @@
 CONFIG_IA64_PRINT_HAZARDS=y
 # CONFIG_DISABLE_VHPT is not set
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_IA64_EARLY_PRINTK=y
-# CONFIG_IA64_EARLY_PRINTK_UART is not set
-CONFIG_IA64_EARLY_PRINTK_VGA=y
+# CONFIG_IA64_EARLY_PRINTK is not set
 # CONFIG_DEBUG_SLAB is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
 # CONFIG_IA64_DEBUG_CMPXCHG is not set
 # CONFIG_IA64_DEBUG_IRQ is not set
 
 #
 # Security options
 #
-CONFIG_SECURITY_CAPABILITIES=y
+# CONFIG_SECURITY is not set
 
 #
 # Cryptographic options
diff -urN linux-2.5.73-bk2/arch/ia64/kernel/acpi.c linux-2.5.73-bk3/arch/ia64/kernel/acpi.c
--- linux-2.5.73-bk2/arch/ia64/kernel/acpi.c	2003-06-22 11:32:45.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/kernel/acpi.c	2003-06-25 04:46:47.000000000 -0700
@@ -575,59 +575,6 @@
 }
 
 
-#ifdef CONFIG_SERIAL_8250_ACPI
-
-#include <linux/acpi_serial.h>
-
-static int __init
-acpi_parse_spcr (unsigned long phys_addr, unsigned long size)
-{
-	acpi_ser_t *spcr;
-	unsigned int gsi;
-
-	if (!phys_addr || !size)
-		return -EINVAL;
-
-	if (!iosapic_register_intr)
-		return -ENODEV;
-
-	/*
-	 * ACPI is able to describe serial ports that live at non-standard
-	 * memory addresses and use non-standard interrupts, either via
-	 * direct SAPIC mappings or via PCI interrupts.  We handle interrupt
-	 * routing for SAPIC-based (non-PCI) devices here.  Interrupt routing
-	 * for PCI devices will be handled when processing the PCI Interrupt
-	 * Routing Table (PRT).
-	 */
-
-	spcr = (acpi_ser_t *) __va(phys_addr);
-
-	setup_serial_acpi(spcr);
-
-	if (spcr->length < sizeof(acpi_ser_t))
-		/* Table not long enough for full info, thus no interrupt */
-		return -ENODEV;
-
-	if ((spcr->base_addr.space_id != ACPI_SERIAL_PCICONF_SPACE) &&
-	    (spcr->int_type == ACPI_SERIAL_INT_SAPIC))
-	{
-		int vector;
-
-		/* We have a UART in memory space with an SAPIC interrupt */
-
-		gsi = (  (spcr->global_int[3] << 24) |
-			 (spcr->global_int[2] << 16) |
-			 (spcr->global_int[1] << 8)  |
-			 (spcr->global_int[0])  );
-
-		vector = iosapic_register_intr(gsi, IOSAPIC_POL_HIGH, IOSAPIC_EDGE);
-	}
-	return 0;
-}
-
-#endif /* CONFIG_SERIAL_8250_ACPI */
-
-
 int __init
 acpi_boot_init (void)
 {
@@ -682,16 +629,6 @@
 	if (acpi_table_parse(ACPI_FADT, acpi_parse_fadt) < 1)
 		printk(KERN_ERR PREFIX "Can't find FADT\n");
 
-#ifdef CONFIG_SERIAL_8250_ACPI
-	/*
-	 * TBD: Need phased approach to table parsing (only do those absolutely
-	 *      required during boot-up).  Recommend expanding concept of fix-
-	 *      feature devices (LDM) to include table-based devices such as
-	 *      serial ports, EC, SMBus, etc.
-	 */
-	acpi_table_parse(ACPI_SPCR, acpi_parse_spcr);
-#endif
-
 #ifdef CONFIG_SMP
 	smp_boot_data.cpu_count = available_cpus;
 	if (available_cpus == 0) {
diff -urN linux-2.5.73-bk2/arch/ia64/kernel/efi.c linux-2.5.73-bk3/arch/ia64/kernel/efi.c
--- linux-2.5.73-bk2/arch/ia64/kernel/efi.c	2003-06-22 11:32:31.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/kernel/efi.c	2003-06-25 04:46:47.000000000 -0700
@@ -46,7 +46,7 @@
  * prior to creating their own entries under /proc/efi.
  */
 #ifdef CONFIG_PROC_FS
-struct proc_dir_entry *efi_dir = NULL;
+struct proc_dir_entry *efi_dir;
 #endif
 
 static unsigned long mem_limit = ~0UL;
diff -urN linux-2.5.73-bk2/arch/ia64/kernel/efivars.c linux-2.5.73-bk3/arch/ia64/kernel/efivars.c
--- linux-2.5.73-bk2/arch/ia64/kernel/efivars.c	2003-06-22 11:32:43.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/kernel/efivars.c	2003-06-25 04:46:47.000000000 -0700
@@ -119,7 +119,7 @@
 */
 static spinlock_t efivars_lock = SPIN_LOCK_UNLOCKED;
 static LIST_HEAD(efivar_list);
-static struct proc_dir_entry *efi_vars_dir = NULL;
+static struct proc_dir_entry *efi_vars_dir;
 
 #define efivar_entry(n) list_entry(n, efivar_entry_t, list)
 
diff -urN linux-2.5.73-bk2/arch/ia64/kernel/gate.S linux-2.5.73-bk3/arch/ia64/kernel/gate.S
--- linux-2.5.73-bk2/arch/ia64/kernel/gate.S	2003-06-22 11:33:08.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/kernel/gate.S	2003-06-25 04:46:47.000000000 -0700
@@ -199,7 +199,7 @@
 	cmp.ne p8,p0=r15,r0		// do we need to switch the rbs?
 	mov.m r9=ar.bsp			// fetch ar.bsp
 	.spillsp.p p8, ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
-(p8)	br.cond.spnt setup_rbs		// yup -> (clobbers r14, r15, and r16)
+(p8)	br.cond.spnt setup_rbs		// yup -> (clobbers p8, r14-r16, and r18-r20)
 back_from_setup_rbs:
 	alloc r8=ar.pfs,0,0,3,0
 	ld8 out0=[base0],16		// load arg0 (signum)
@@ -268,26 +268,30 @@
 setup_rbs:
 	mov ar.rsc=0				// put RSE into enforced lazy mode
 	;;
-	.save ar.rnat, r16
-	mov r16=ar.rnat				// save RNaT before switching backing store area
+	.save ar.rnat, r19
+	mov r19=ar.rnat				// save RNaT before switching backing store area
 	adds r14=(RNAT_OFF+SIGCONTEXT_OFF),sp
 
+	mov r18=ar.bspstore
 	mov ar.bspstore=r15			// switch over to new register backing store area
 	;;
+
 	.spillsp ar.rnat, RNAT_OFF+SIGCONTEXT_OFF
-	st8 [r14]=r16				// save sc_ar_rnat
+	st8 [r14]=r19				// save sc_ar_rnat
 	.body
-	adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp
-
 	mov.m r16=ar.bsp			// sc_loadrs <- (new bsp - new bspstore) << 16
+	adds r14=(LOADRS_OFF+SIGCONTEXT_OFF),sp
 	;;
 	invala
 	sub r15=r16,r15
+	extr.u r20=r18,3,6
 	;;
+	mov ar.rsc=0xf				// set RSE into eager mode, pl 3
+	cmp.eq p8,p0=63,r20
 	shl r15=r15,16
 	;;
 	st8 [r14]=r15				// save sc_loadrs
-	mov ar.rsc=0xf				// set RSE into eager mode, pl 3
+(p8)	st8 [r18]=r19		// if bspstore points at RNaT slot, store RNaT there now
 	.restore sp				// pop .prologue
 	br.cond.sptk back_from_setup_rbs
 
diff -urN linux-2.5.73-bk2/arch/ia64/kernel/head.S linux-2.5.73-bk3/arch/ia64/kernel/head.S
--- linux-2.5.73-bk2/arch/ia64/kernel/head.S	2003-06-22 11:32:58.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/kernel/head.S	2003-06-25 04:46:47.000000000 -0700
@@ -144,13 +144,13 @@
 	movl r3=task_for_booting_cpu
  	;;
 	ld8 r3=[r3]
-	movl r2=init_thread_union
+	movl r2=init_task
 	;;
 	cmp.eq isBP,isAP=r3,r0
 	;;
 (isAP)	mov r2=r3
 #else
-	movl r2=init_thread_union
+	movl r2=init_task
 	cmp.eq isBP,isAP=r0,r0
 #endif
 	;;
diff -urN linux-2.5.73-bk2/arch/ia64/kernel/init_task.c linux-2.5.73-bk3/arch/ia64/kernel/init_task.c
--- linux-2.5.73-bk2/arch/ia64/kernel/init_task.c	2003-06-22 11:33:34.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/kernel/init_task.c	2003-06-25 04:46:47.000000000 -0700
@@ -26,17 +26,17 @@
  * We need to make sure that this is properly aligned due to the way process stacks are
  * handled. This is done by having a special ".data.init_task" section...
  */
-#define init_thread_info	init_thread_union.s.thread_info
+#define init_thread_info	init_task_mem.s.thread_info
 
-union init_thread {
+static union {
 	struct {
 		struct task_struct task;
 		struct thread_info thread_info;
 	} s;
 	unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
-} init_thread_union __attribute__((section(".data.init_task"))) = {{
-	.task =		INIT_TASK(init_thread_union.s.task),
-	.thread_info =	INIT_THREAD_INFO(init_thread_union.s.task)
+} init_task_mem __attribute__((section(".data.init_task"))) = {{
+	.task =		INIT_TASK(init_task_mem.s.task),
+	.thread_info =	INIT_THREAD_INFO(init_task_mem.s.task)
 }};
 
-asm (".global init_task; init_task = init_thread_union");
+asm (".global init_task; init_task = init_task_mem");
diff -urN linux-2.5.73-bk2/arch/ia64/kernel/iosapic.c linux-2.5.73-bk3/arch/ia64/kernel/iosapic.c
--- linux-2.5.73-bk2/arch/ia64/kernel/iosapic.c	2003-06-22 11:32:44.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/kernel/iosapic.c	2003-06-25 04:46:47.000000000 -0700
@@ -382,7 +382,7 @@
 static void
 iosapic_ack_edge_irq (unsigned int irq)
 {
-	irq_desc_t *idesc = irq_desc(irq);
+	irq_desc_t *idesc = irq_descp(irq);
 	/*
 	 * Once we have recorded IRQ_PENDING already, we can mask the
 	 * interrupt for real. This prevents IRQ storms from unhandled
@@ -478,7 +478,7 @@
 	else
 		irq_type = &irq_type_iosapic_level;
 
-	idesc = irq_desc(vector);
+	idesc = irq_descp(vector);
 	if (idesc->handler != irq_type) {
 		if (idesc->handler != &no_irq_type)
 			printk(KERN_WARNING "%s: changing vector %d from %s to %s\n",
@@ -724,7 +724,7 @@
 		 * If vector was previously initialized to a different
 		 * handler, re-initialize.
 		 */
-		idesc = irq_desc(vector);
+		idesc = irq_descp(vector);
 		if (idesc->handler != irq_type)
 			register_intr(gsi, vector, IOSAPIC_LOWEST_PRIORITY, IOSAPIC_POL_LOW,
 				      IOSAPIC_LEVEL);
diff -urN linux-2.5.73-bk2/arch/ia64/kernel/irq.c linux-2.5.73-bk3/arch/ia64/kernel/irq.c
--- linux-2.5.73-bk2/arch/ia64/kernel/irq.c	2003-06-22 11:33:15.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/kernel/irq.c	2003-06-25 04:46:47.000000000 -0700
@@ -74,7 +74,7 @@
 };
 
 #ifdef CONFIG_IA64_GENERIC
-struct irq_desc * __ia64_irq_desc (unsigned int irq)
+irq_desc_t * __ia64_irq_desc (unsigned int irq)
 {
 	return _irq_desc + irq;
 }
@@ -171,7 +171,7 @@
 	seq_putc(p, '\n');
 
 	for (i = 0 ; i < NR_IRQS ; i++) {
-		idesc = irq_desc(i);
+		idesc = irq_descp(i);
 		spin_lock_irqsave(&idesc->lock, flags);
 		action = idesc->action;
 		if (!action)
@@ -218,7 +218,7 @@
 #ifdef CONFIG_SMP
 inline void synchronize_irq(unsigned int irq)
 {
-	while (irq_desc(irq)->status & IRQ_INPROGRESS)
+	while (irq_descp(irq)->status & IRQ_INPROGRESS)
 		cpu_relax();
 }
 #endif
@@ -352,7 +352,7 @@
 
 inline void disable_irq_nosync(unsigned int irq)
 {
-	irq_desc_t *desc = irq_desc(irq);
+	irq_desc_t *desc = irq_descp(irq);
 	unsigned long flags;
 
 	spin_lock_irqsave(&desc->lock, flags);
@@ -395,7 +395,7 @@
 
 void enable_irq(unsigned int irq)
 {
-	irq_desc_t *desc = irq_desc(irq);
+	irq_desc_t *desc = irq_descp(irq);
 	unsigned long flags;
 
 	spin_lock_irqsave(&desc->lock, flags);
@@ -437,7 +437,7 @@
 	 * 0 return value means that this irq is already being
 	 * handled by some other CPU. (or is disabled)
 	 */
-	irq_desc_t *desc = irq_desc(irq);
+	irq_desc_t *desc = irq_descp(irq);
 	struct irqaction * action;
 	irqreturn_t action_ret;
 	unsigned int status;
@@ -620,7 +620,7 @@
 	if (irq >= NR_IRQS)
 		return;
 
-	desc = irq_desc(irq);
+	desc = irq_descp(irq);
 	spin_lock_irqsave(&desc->lock,flags);
 	p = &desc->action;
 	for (;;) {
@@ -682,7 +682,7 @@
 	 * flush such a longstanding irq before considering it as spurious.
 	 */
 	for (i = NR_IRQS-1; i > 0; i--)  {
-		desc = irq_desc(i);
+		desc = irq_descp(i);
 
 		spin_lock_irq(&desc->lock);
 		if (!desc->action)
@@ -700,7 +700,7 @@
 	 * happened in the previous stage, it may have masked itself)
 	 */
 	for (i = NR_IRQS-1; i > 0; i--) {
-		desc = irq_desc(i);
+		desc = irq_descp(i);
 
 		spin_lock_irq(&desc->lock);
 		if (!desc->action) {
@@ -722,7 +722,7 @@
 	 */
 	val = 0;
 	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc(i);
+		irq_desc_t *desc = irq_descp(i);
 		unsigned int status;
 
 		spin_lock_irq(&desc->lock);
@@ -762,7 +762,7 @@
 
 	mask = 0;
 	for (i = 0; i < 16; i++) {
-		irq_desc_t *desc = irq_desc(i);
+		irq_desc_t *desc = irq_descp(i);
 		unsigned int status;
 
 		spin_lock_irq(&desc->lock);
@@ -807,7 +807,7 @@
 	nr_irqs = 0;
 	irq_found = 0;
 	for (i = 0; i < NR_IRQS; i++) {
-		irq_desc_t *desc = irq_desc(i);
+		irq_desc_t *desc = irq_descp(i);
 		unsigned int status;
 
 		spin_lock_irq(&desc->lock);
@@ -836,7 +836,7 @@
 	int shared = 0;
 	unsigned long flags;
 	struct irqaction *old, **p;
-	irq_desc_t *desc = irq_desc(irq);
+	irq_desc_t *desc = irq_descp(irq);
 
 	if (desc->handler == &no_irq_type)
 		return -ENOSYS;
@@ -963,15 +963,16 @@
 }
 
 static int irq_affinity_write_proc (struct file *file, const char *buffer,
-					unsigned long count, void *data)
+				    unsigned long count, void *data)
 {
 	unsigned int irq = (unsigned long) data;
 	int full_count = count, err;
 	unsigned long new_value;
 	const char *buf = buffer;
+	irq_desc_t *desc = irq_descp(irq);
 	int redir;
 
-	if (!irq_desc(irq)->handler->set_affinity)
+	if (!desc->handler->set_affinity)
 		return -EIO;
 
 	if (buf[0] == 'r' || buf[0] == 'R') {
@@ -993,8 +994,7 @@
 	if (!(new_value & cpu_online_map))
 		return -EINVAL;
 
-	irq_desc(irq)->handler->set_affinity(irq | (redir? IA64_IRQ_REDIRECTED : 0), new_value);
-
+	desc->handler->set_affinity(irq | (redir? IA64_IRQ_REDIRECTED : 0), new_value);
 	return full_count;
 }
 
@@ -1030,7 +1030,7 @@
 {
 	char name [MAX_NAMELEN];
 
-	if (!root_irq_dir || (irq_desc(irq)->handler == &no_irq_type) || irq_dir[irq])
+	if (!root_irq_dir || (irq_descp(irq)->handler == &no_irq_type) || irq_dir[irq])
 		return;
 
 	memset(name, 0, MAX_NAMELEN);
@@ -1083,7 +1083,7 @@
 	 * Create entries for all existing IRQs.
 	 */
 	for (i = 0; i < NR_IRQS; i++) {
-		if (irq_desc(i)->handler == &no_irq_type)
+		if (irq_descp(i)->handler == &no_irq_type)
 			continue;
 		register_irq_proc(i);
 	}
diff -urN linux-2.5.73-bk2/arch/ia64/kernel/irq_ia64.c linux-2.5.73-bk3/arch/ia64/kernel/irq_ia64.c
--- linux-2.5.73-bk2/arch/ia64/kernel/irq_ia64.c	2003-06-22 11:32:42.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/kernel/irq_ia64.c	2003-06-25 04:46:47.000000000 -0700
@@ -162,7 +162,7 @@
 
 	for (irq = 0; irq < NR_IRQS; ++irq)
 		if (irq_to_vector(irq) == vec) {
-			desc = irq_desc(irq);
+			desc = irq_descp(irq);
 			desc->status |= IRQ_PER_CPU;
 			desc->handler = &irq_type_ia64_lsapic;
 			if (action)
diff -urN linux-2.5.73-bk2/arch/ia64/kernel/mca.c linux-2.5.73-bk3/arch/ia64/kernel/mca.c
--- linux-2.5.73-bk2/arch/ia64/kernel/mca.c	2003-06-22 11:32:44.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/kernel/mca.c	2003-06-25 04:46:47.000000000 -0700
@@ -734,7 +734,7 @@
 		if (cpev >= 0) {
 			for (irq = 0; irq < NR_IRQS; ++irq)
 				if (irq_to_vector(irq) == cpev) {
-					desc = irq_desc(irq);
+					desc = irq_descp(irq);
 					desc->status |= IRQ_PER_CPU;
 					desc->handler = &irq_type_iosapic_level;
 					setup_irq(irq, &mca_cpe_irqaction);
diff -urN linux-2.5.73-bk2/arch/ia64/kernel/perfmon.c linux-2.5.73-bk3/arch/ia64/kernel/perfmon.c
--- linux-2.5.73-bk2/arch/ia64/kernel/perfmon.c	2003-06-22 11:33:17.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/kernel/perfmon.c	2003-06-25 04:46:47.000000000 -0700
@@ -115,6 +115,8 @@
 #define PMD_IS_COUNTING(i) ((pmu_conf.pmd_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING)
 #define PMC_IS_COUNTING(i) ((pmu_conf.pmc_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING)
 #define PMC_IS_MONITOR(i)  ((pmu_conf.pmc_desc[i].type & PFM_REG_MONITOR)  == PFM_REG_MONITOR)
+#define PMC_IS_CONTROL(i)  ((pmu_conf.pmc_desc[i].type & PFM_REG_CONTROL)  == PFM_REG_CONTROL)
+
 #define PMC_DFL_VAL(i)     pmu_conf.pmc_desc[i].default_value
 #define PMC_RSVD_MASK(i)   pmu_conf.pmc_desc[i].reserved_mask
 #define PMD_PMD_DEP(i)	   pmu_conf.pmd_desc[i].dep_pmd[0]
@@ -232,6 +234,8 @@
  */
 #define PMC0_HAS_OVFL(cmp0)  (cmp0 & ~0x1UL)
 
+#define PFMFS_MAGIC 0xa0b4d889
+
 /*
  * debugging
  */
@@ -328,7 +332,7 @@
 
 	pfm_counter_t		ctx_pmds[IA64_NUM_PMD_REGS]; /* software state for PMDS */
 
-	u64			ctx_saved_psr;		/* copy of psr used for ctxsw */
+	u64			ctx_saved_psr_up;	/* only contains psr.up value */
 
 	unsigned long		ctx_last_activation;	/* context last activation number for last_cpu */
 	unsigned int		ctx_last_cpu;		/* CPU id of current or last CPU used (SMP only) */
@@ -560,100 +564,6 @@
 	close: pfm_vm_close
 };
 
-/*
- * Linux 2.5 vs. 2.4 helper macros and definitions
- *
- * if not at least 2.5.69, then assume 2.4.x.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
-
-#define PFM_COMPILED_FOR_2_4 1
-
-#include <linux/wrapper.h>
-
-#define pfm_get_cpu_var(v)	local_cpu_data->v
-#define pfm_get_cpu_data(a,b)	cpu_data((b))->a
-typedef	void pfm_irq_handler_t;
-#define PFM_IRQ_HANDLER_RET(v)
-
-#define DEFINE_PER_CPU(a,b)
-
-static inline int
-pfm_wait_task_inactive(struct task_struct *task)
-{
-#ifdef CONFIG_SMP
-	/* Make sure the child gets off its CPU.. */
-	for (;;) {
-		task_lock(task);
-		if (!task_has_cpu(task)) break;
-		task_unlock(task);
-		do {
-			if (task->state != TASK_STOPPED)
-				return -ESRCH;
-			barrier();
-			cpu_relax();
-		} while (task_has_cpu(task));
-	}
-	task_unlock(task);
-#endif
-	return 0;
-}
-
-static inline void
-pfm_put_task(struct task_struct *task)
-{
-	if (task != current) free_task_struct(task);
-}
-
-static inline void
-pfm_set_task_notify(struct task_struct *task)
-{
-}
-
-static inline void
-pfm_clear_task_notify(void)
-{
-}
-
-static inline void
-pfm_reserve_page(unsigned long a)
-{
-	unsigned long page;
-
-	page = ia64_tpa(a);
-	mem_map_reserve(virt_to_page(__va(page)));
-}
-
-static inline void
-pfm_unreserve_page(unsigned long a)
-{
-	unsigned long page;
-
-	page = ia64_tpa(a);
-	mem_map_unreserve(virt_to_page(__va(page)));
-}
-
-static inline int
-pfm_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot)
-{
-	return remap_page_range(from, phys_addr, size, prot);
-}
-
-static inline unsigned long
-pfm_protect_ctx_ctxsw(pfm_context_t *x)
-{
-	unsigned long f;
-	spin_lock(&(x)->ctx_lock);
-	return f;
-}
-
-static inline unsigned long
-pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f)
-{
-	spin_unlock(&(x)->ctx_lock);
-}
-
-#else /* 2.5.69 or higher */
 
 #define pfm_wait_task_inactive(t)	wait_task_inactive(t)
 #define pfm_get_cpu_var(v)		__get_cpu_var(v)
@@ -705,7 +615,7 @@
 static inline unsigned long
 pfm_protect_ctx_ctxsw(pfm_context_t *x)
 {
-	spin_lock_irq(&(x)->ctx_lock);
+	spin_lock(&(x)->ctx_lock);
 	return 0UL;
 }
 
@@ -715,7 +625,30 @@
 	spin_unlock(&(x)->ctx_lock);
 }
 
-#endif /* 2.5 vs. 2.4 */
+static inline unsigned int
+pfm_do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct)
+{
+	return do_munmap(mm, addr, len);
+}
+
+static inline unsigned long 
+pfm_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags, unsigned long exec)
+{
+	return get_unmapped_area(file, addr, len, pgoff, flags);
+}
+
+
+static struct super_block *
+pfmfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data)
+{
+	return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC);
+}
+
+static struct file_system_type pfm_fs_type = {
+	.name     = "pfmfs",
+	.get_sb   = pfmfs_get_sb,
+	.kill_sb  = kill_anon_super,
+};
 
 DEFINE_PER_CPU(unsigned long, pfm_syst_info);
 DEFINE_PER_CPU(struct task_struct *, pmu_owner);
@@ -758,13 +691,13 @@
 static inline void
 pfm_clear_psr_up(void)
 {
-	__asm__ __volatile__ ("rum psr.up;; srlz.i;;"::: "memory");
+	__asm__ __volatile__ ("rsm psr.up;; srlz.i;;"::: "memory");
 }
 
 static inline void
 pfm_set_psr_up(void)
 {
-	__asm__ __volatile__ ("sum psr.up;; srlz.i;;"::: "memory");
+	__asm__ __volatile__ ("ssm psr.up;; srlz.i;;"::: "memory");
 }
 
 static inline unsigned long
@@ -1502,7 +1435,7 @@
 
 	DPRINT(("down_write done smpl_vaddr=%p size=%lu\n", vaddr, size));
 
-	r = do_munmap(task->mm, (unsigned long)vaddr, size);
+	r = pfm_do_munmap(task->mm, (unsigned long)vaddr, size, 0);
 
 	up_write(&task->mm->mmap_sem);
 	if (r !=0) {
@@ -1569,68 +1502,6 @@
  * d_name - pfm: will go nicely and kill the special-casing in procfs.
  */
 static struct vfsmount *pfmfs_mnt;
-#define PFMFS_MAGIC 0xa0b4d889
-
-#ifdef PFM_COMPILED_FOR_2_4
-
-static int
-pfmfs_statfs(struct super_block *sb, struct statfs *buf)
-{
-	buf->f_type = PFMFS_MAGIC;
-	buf->f_bsize = 1024;
-	buf->f_namelen = 255;
-	return 0;
-}
-
-static struct super_operations pfmfs_ops = {
-	statfs:		pfmfs_statfs,
-};
-
-static struct super_block *
-pfmfs_read_super(struct super_block *sb, void *data, int silent)
-{
-	struct inode *root = new_inode(sb);
-	if (!root)
-		return NULL;
-	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
-	root->i_uid = root->i_gid = 0;
-	root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
-	sb->s_blocksize = 1024;
-	sb->s_blocksize_bits = 10;
-	sb->s_magic = PFMFS_MAGIC;
-	sb->s_op	= &pfmfs_ops;
-	sb->s_root = d_alloc(NULL, &(const struct qstr) { "pfm:", 4, 0 });
-	if (!sb->s_root) {
-		iput(root);
-		return NULL;
-	}
-	sb->s_root->d_sb = sb;
-	sb->s_root->d_parent = sb->s_root;
-	d_instantiate(sb->s_root, root);
-	return sb;
-}
-
-//static DECLARE_FSTYPE(pfm_fs_type, "pfmfs", pfmfs_read_super, FS_NOMOUNT);
-static struct file_system_type pfm_fs_type = {
-	name:		"pfmfs",
-	read_super:	pfmfs_read_super,
-	fs_flags:	FS_NOMOUNT,
-};
-
-#else /* ! COMPILED_FOR_2_4 */
-
-static struct super_block *
-pfmfs_get_sb(struct file_system_type *fs_type, int flags, char *dev_name, void *data)
-{
-	return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC);
-}
-
-static struct file_system_type pfm_fs_type = {
-	.name     = "pfmfs",
-	.get_sb   = pfmfs_get_sb,
-	.kill_sb  = kill_anon_super,
-};
-#endif /* COMPILED_FOR_2_4 */
 
 static int __init
 init_pfm_fs(void)
@@ -2453,7 +2324,7 @@
 	down_write(&task->mm->mmap_sem);
 
 	/* find some free area in address space, must have mmap sem held */
-	vma->vm_start = get_unmapped_area(NULL, 0, size, 0, MAP_PRIVATE|MAP_ANONYMOUS);
+	vma->vm_start = pfm_get_unmapped_area(NULL, 0, size, 0, MAP_PRIVATE|MAP_ANONYMOUS, 0);
 	if (vma->vm_start == 0UL) {
 		DPRINT(("Cannot find unmapped area for size %ld\n", size));
 		up_write(&task->mm->mmap_sem);
@@ -3020,7 +2891,7 @@
 		 * as attempts to modify PMC[0-3] which are used
 		 * as status registers by the PMU
 		 */
-		if (!PMC_IS_IMPL(cnum) || cnum < 4) {
+		if (PMC_IS_IMPL(cnum) == 0 || PMC_IS_CONTROL(cnum)) {
 			DPRINT(("pmc%u is unimplemented or invalid\n", cnum));
 			goto error;
 		}
@@ -4124,7 +3995,7 @@
 		/*
 		 * monitoring disabled in kernel at next reschedule
 		 */
-		ctx->ctx_saved_psr &= ~IA64_PSR_UP;
+		ctx->ctx_saved_psr_up = 0;
 		printk("pfm_stop: current [%d] task=[%d]\n", current->pid, ctx->ctx_task->pid);
 	}
 	return 0;
@@ -4198,7 +4069,7 @@
 		 * start monitoring at the kernel level the next
 		 * time the task is scheduled
 		 */
-		ctx->ctx_saved_psr |= IA64_PSR_UP;
+		ctx->ctx_saved_psr_up = IA64_PSR_UP;
 
 		/*
 		 * activate monitoring at user level
@@ -4429,7 +4300,7 @@
 		SET_LAST_CPU(ctx, -1);
 
 		/* initial saved psr (stopped) */
-		ctx->ctx_saved_psr = pfm_get_psr() & ~(IA64_PSR_PP|IA64_PSR_UP);
+		ctx->ctx_saved_psr_up = 0UL;
 		ia64_psr(regs)->up = ia64_psr(regs)->pp = 0;
 
 		if (ctx->ctx_fl_unsecure) {
@@ -5640,6 +5511,7 @@
 	unsigned long flags;
 	u64 psr;
 
+
 	ctx = PFM_GET_CTX(task);
 	if (ctx == NULL) goto save_error;
 	t = &task->thread;
@@ -5672,9 +5544,9 @@
 	 * sanity check
 	 */
 	if (ctx->ctx_last_activation != GET_ACTIVATION()) {
-		DPRINT(("ctx_activation=%lu activation=%lu state=%d: no save\n",
+		printk("ctx_activation=%lu activation=%lu state=%d: no save\n",
 				ctx->ctx_last_activation,
-				GET_ACTIVATION(), ctx->ctx_state));
+				GET_ACTIVATION(), ctx->ctx_state);
 
 		pfm_unprotect_ctx_ctxsw(ctx, flags);
 
@@ -5684,8 +5556,11 @@
 	/*
 	 * save current PSR: needed because we modify it
 	 */
+	ia64_srlz_d();
 	psr = pfm_get_psr();
 
+	BUG_ON(psr & (IA64_PSR_I));
+
 	/*
 	 * stop monitoring:
 	 * This is the last instruction which may generate an overflow
@@ -5696,9 +5571,13 @@
 	pfm_clear_psr_up();
 
 	/*
-	 * keep a copy of the saved psr (for reload)
+	 * keep a copy of psr.up (for reload)
 	 */
-	ctx->ctx_saved_psr = psr;
+	ctx->ctx_saved_psr_up = psr & IA64_PSR_UP;
+
+	{ u64 foo = pfm_get_psr();
+	  BUG_ON(foo & ((IA64_PSR_UP|IA64_PSR_PP)));
+	}
 
 	/*
 	 * release ownership of this PMU.
@@ -5772,18 +5651,16 @@
 	pfm_clear_psr_up();
 
 	/*
-	 * keep a copy of the saved psr (for reload)
+	 * keep a copy of psr.up (for reload)
 	 */
-	ctx->ctx_saved_psr = psr;
+	ctx->ctx_saved_psr_up = psr & IA64_PSR_UP;
 
-	psr = pfm_get_psr();
-	if (psr & IA64_PSR_UP) {
-		printk(KERN_ERR " perfmon: pfm_save_regs: psr.up set current [%d] owner [%d] psr=0x%lx\n", current->pid, GET_PMU_OWNER()->pid, psr);
-	}
-	if (psr & IA64_PSR_I) {
-		printk(KERN_ERR " perfmon: pfm_save_regs: psr.i set current [%d] owner [%d] psr=0x%lx\n", current->pid, GET_PMU_OWNER()->pid, psr);
+#if 1
+	{ u64 foo = pfm_get_psr();
+	  BUG_ON(foo & (IA64_PSR_I));
+	  BUG_ON(foo & ((IA64_PSR_UP|IA64_PSR_PP)));
 	}
-
+#endif
 	return;
 save_error:
 	printk(KERN_ERR "perfmon: pfm_save_regs CPU%d [%d] NULL context PM_VALID=%ld\n",
@@ -5797,13 +5674,10 @@
 	pfm_context_t *ctx;
 	struct thread_struct *t;
 	unsigned long flags;
-	unsigned long psr;
 
 #if 1
-	psr = pfm_get_psr();
-	if (psr & IA64_PSR_UP) {
-		printk(KERN_ERR " perfmon: pfm_lazy_save_regs: psr.up set current [%d] owner [%d] psr=0x%lx\n", current->pid, task->pid, psr);
-		pfm_clear_psr_up();
+	{ u64 foo  = pfm_get_psr();
+	  BUG_ON(foo & IA64_PSR_UP);
 	}
 #endif
 
@@ -5864,10 +5738,9 @@
 {
 	pfm_context_t *ctx;
 	struct thread_struct *t;
-	struct task_struct *owner;
 	unsigned long pmc_mask = 0UL, pmd_mask = 0UL;
 	unsigned long flags;
-	u64 psr;
+	u64 psr, psr_up;
 
 	ctx = PFM_GET_CTX(task);
 	if (unlikely(ctx == NULL)) {
@@ -5875,22 +5748,21 @@
 		return;
 	}
 
-	owner = GET_PMU_OWNER();
+	BUG_ON(GET_PMU_OWNER());
+
 	t     = &task->thread;
+	psr   = pfm_get_psr();
 
 #if 1
-	psr = pfm_get_psr();
-	BUG_ON(psr & IA64_PSR_UP);
-	psr = pfm_get_psr();
+	BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP));
 	BUG_ON(psr & IA64_PSR_I);
 #endif
 
-
 	/*
 	 * possible on unload
 	 */
 	if (unlikely((t->flags & IA64_THREAD_PM_VALID) == 0)) {
-		DPRINT(("[%d] PM_VALID=0, nothing to do\n", task->pid));
+		printk("[%d] PM_VALID=0, nothing to do\n", task->pid);
 		return;
 	}
 
@@ -5923,19 +5795,15 @@
 	/*
 	 * we restore ALL the debug registers to avoid picking up
 	 * stale state.
-	 *
-	 * This must be done even when the task is still the owner
-	 * as the registers may have been modified via ptrace()
-	 * (not perfmon) by the previous task.
 	 */
 	if (ctx->ctx_fl_using_dbreg) {
 		pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf.num_ibrs);
 		pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf.num_dbrs);
 	}
 	/*
-	 * retrieve saved psr
+	 * retrieve saved psr.up
 	 */
-	psr = ctx->ctx_saved_psr;
+	psr_up = ctx->ctx_saved_psr_up;
 
 	/*
 	 * if we were the last user of the PMU on that CPU,
@@ -5968,8 +5836,8 @@
 	 	 */
 		pmc_mask = ctx->ctx_all_pmcs[0];
 
-		DPRINT(("full reload for [%d] owner=%d activation=%lu last_activation=%lu last_cpu=%d pmd_mask=0x%lx pmc_mask=0x%lx\n",
-			task->pid, owner ? owner->pid : -1,
+		DPRINT(("full reload for [%d] activation=%lu last_activation=%lu last_cpu=%d pmd_mask=0x%lx pmc_mask=0x%lx\n",
+			task->pid,
 			GET_ACTIVATION(), ctx->ctx_last_activation,
 			GET_LAST_CPU(ctx), pmd_mask, pmc_mask));
 
@@ -6026,9 +5894,9 @@
 	SET_PMU_OWNER(task, ctx);
 
 	/*
-	 * restore the psr we changed
+	 * restore the psr.up bit 
 	 */
-	pfm_set_psr_l(psr);
+	if (likely(psr_up)) pfm_set_psr_up();
 
 	/*
 	 * allow concurrent access to context
@@ -6047,21 +5915,16 @@
 	pfm_context_t *ctx;
 	struct task_struct *owner;
 	unsigned long pmd_mask, pmc_mask;
-	u64 psr;
+	u64 psr, psr_up;
 
-	owner      = GET_PMU_OWNER();
-	ctx        = PFM_GET_CTX(task);
-	t          = &task->thread;
+	owner = GET_PMU_OWNER();
+	ctx   = PFM_GET_CTX(task);
+	t     = &task->thread;
+	psr   = pfm_get_psr();
 
 #if 1
-	psr = pfm_get_psr();
-	if (psr & IA64_PSR_UP) {
-		printk(KERN_ERR " perfmon: pfm_load_regs: psr.up set current [%d] owner [%d] psr=0x%lx\n", current->pid, owner->pid, psr);
-	}
-	psr = pfm_get_psr();
-	if (psr & IA64_PSR_I) {
-		printk(KERN_ERR " perfmon: pfm_load_regs: psr.i set current [%d] owner [%d] psr=0x%lx\n", current->pid, owner->pid, psr);
-	}
+	BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP));
+	BUG_ON(psr & IA64_PSR_I);
 #endif
 
 	/*
@@ -6078,9 +5941,9 @@
 	}
 
 	/*
-	 * retrieved save psr
+	 * retrieved saved psr.up
 	 */
-	psr = ctx->ctx_saved_psr;
+	psr_up = ctx->ctx_saved_psr_up;
 
 	/*
 	 * short path, our state is still there, just
@@ -6091,7 +5954,7 @@
 	 * concurrency even without interrupt masking.
 	 */
 	if (likely(owner == task)) {
-		pfm_set_psr_l(psr);
+		if (likely(psr_up)) pfm_set_psr_up();
 		return;
 	}
 
@@ -6163,8 +6026,7 @@
 	 * restore the psr. This is the point at which
 	 * new overflow interrupts can be generated again.
 	 */
-	pfm_set_psr_l(psr);
-
+	if (likely(psr_up)) pfm_set_psr_up();
 }
 #endif /* CONFIG_SMP */
 
@@ -6469,13 +6331,13 @@
 		printk("pmd[%d]=0x%lx tpmd=0x%lx\n", i, ia64_get_pmd(i), t->pmds[i]);
 	}
 	if (ctx) {
-		printk("ctx_state=%d vaddr=%p addr=%p fd=%d ctx_task=[%d] saved_psr=0x%lx\n",
+		printk("ctx_state=%d vaddr=%p addr=%p fd=%d ctx_task=[%d] saved_psr_up=0x%lx\n",
 				ctx->ctx_state,
 				ctx->ctx_smpl_vaddr,
 				ctx->ctx_smpl_hdr,
 				ctx->ctx_msgq_head,
 				ctx->ctx_msgq_tail,
-				ctx->ctx_saved_psr);
+				ctx->ctx_saved_psr_up);
 	}
 }
 
diff -urN linux-2.5.73-bk2/arch/ia64/kernel/smpboot.c linux-2.5.73-bk3/arch/ia64/kernel/smpboot.c
--- linux-2.5.73-bk2/arch/ia64/kernel/smpboot.c	2003-06-22 11:32:37.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/kernel/smpboot.c	2003-06-25 04:46:47.000000000 -0700
@@ -452,7 +452,7 @@
 		sapicid = smp_boot_data.cpu_phys_id[i];
 		if (sapicid == boot_cpu_id)
 			continue;
-		phys_cpu_present_map |= (1 << cpu);
+		phys_cpu_present_map |= (1UL << cpu);
 		ia64_cpu_to_sapicid[cpu] = sapicid;
 		cpu++;
 	}
diff -urN linux-2.5.73-bk2/arch/ia64/lib/Makefile linux-2.5.73-bk3/arch/ia64/lib/Makefile
--- linux-2.5.73-bk2/arch/ia64/lib/Makefile	2003-06-22 11:33:18.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/lib/Makefile	2003-06-25 04:46:47.000000000 -0700
@@ -12,12 +12,7 @@
 lib-$(CONFIG_ITANIUM)	+= copy_page.o copy_user.o memcpy.o
 lib-$(CONFIG_MCKINLEY)	+= copy_page_mck.o memcpy_mck.o
 lib-$(CONFIG_PERFMON)	+= carta_random.o
-
-ifeq ($(CONFIG_MD_RAID5),m)
-	lib-y += xor.o
-else
-	lib-$(CONFIG_MD_RAID5)	+= xor.o
-endif
+lib-$(CONFIG_MD_RAID5)	+= xor.o
 
 IGNORE_FLAGS_OBJS =	__divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
 			__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o
diff -urN linux-2.5.73-bk2/arch/ia64/pci/pci.c linux-2.5.73-bk3/arch/ia64/pci/pci.c
--- linux-2.5.73-bk2/arch/ia64/pci/pci.c	2003-06-25 04:46:43.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/pci/pci.c	2003-06-25 04:46:47.000000000 -0700
@@ -364,8 +364,6 @@
 	return;
 }
 
-#warning pcibios_update_resource() is now a generic implementation - please check
-
 void __devinit
 pcibios_update_irq (struct pci_dev *dev, int irq)
 {
diff -urN linux-2.5.73-bk2/arch/ia64/scripts/toolchain-flags linux-2.5.73-bk3/arch/ia64/scripts/toolchain-flags
--- linux-2.5.73-bk2/arch/ia64/scripts/toolchain-flags	2003-06-22 11:33:32.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/scripts/toolchain-flags	2003-06-25 04:46:47.000000000 -0700
@@ -3,15 +3,13 @@
 # Check whether linker can handle cross-segment @segrel():
 #
 CC=$1
-LD=$2
-OBJDUMP=$3
+OBJDUMP=$2
 dir=$(dirname $0)
 tmp=${TMPDIR:-/tmp}
 out=$tmp/out$$
-$CC -c $dir/check-segrel.S -o $out.o
-$LD -static -T$dir/check-segrel.lds $out.o -o $out
+$CC -nostdlib -static -Wl,-T$dir/check-segrel.lds $dir/check-segrel.S -o $out
 res=$($OBJDUMP --full --section .rodata $out | fgrep 000 | cut -f3 -d' ')
-rm -f $out $out.o
+rm -f $out
 if [ $res != 00000a00 ]; then
     echo " -DHAVE_BUGGY_SEGREL"
     cat >&2 <<EOF
diff -urN linux-2.5.73-bk2/arch/ia64/sn/io/drivers/Makefile linux-2.5.73-bk3/arch/ia64/sn/io/drivers/Makefile
--- linux-2.5.73-bk2/arch/ia64/sn/io/drivers/Makefile	2003-06-22 11:33:09.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/sn/io/drivers/Makefile	2003-06-25 04:46:47.000000000 -0700
@@ -9,4 +9,4 @@
 
 EXTRA_CFLAGS    := -DLITTLE_ENDIAN
 
-obj-y				+= ioconfig_bus.o ifconfig_net.o
+obj-y				+= ioconfig_bus.o
diff -urN linux-2.5.73-bk2/arch/ia64/sn/io/drivers/ifconfig_net.c linux-2.5.73-bk3/arch/ia64/sn/io/drivers/ifconfig_net.c
--- linux-2.5.73-bk2/arch/ia64/sn/io/drivers/ifconfig_net.c	2003-06-22 11:32:41.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/sn/io/drivers/ifconfig_net.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,298 +0,0 @@
-/* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- *  ifconfig_net - SGI's Persistent Network Device names.
- *
- * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/ifconfig_net.h>
-
-#define SGI_IFCONFIG_NET "SGI-PERSISTENT NETWORK DEVICE NAME DRIVER"
-#define SGI_IFCONFIG_NET_VERSION "1.0"
-
-/*
- * Some Global definitions.
- */
-static devfs_handle_t ifconfig_net_handle;
-static unsigned long ifconfig_net_debug;
-
-/*
- * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net".
- */
-static int ifconfig_net_open(struct inode * inode, struct file * filp)
-{
-	if (ifconfig_net_debug) {
-        	printk("ifconfig_net_open called.\n");
-	}
-
-        return(0);
-
-}
-
-/*
- * ifconfig_net_close - Closes the special device node "/devhw/.ifconfig_net".
- */
-static int ifconfig_net_close(struct inode * inode, struct file * filp)
-{
-
-	if (ifconfig_net_debug) {
-        	printk("ifconfig_net_close called.\n");
-	}
-
-        return(0);
-}
-
-/*
- * assign_ifname - Assign the next available interface name from the persistent list.
- */
-void
-assign_ifname(struct net_device *dev,
-		  struct ifname_num *ifname_num)
-
-{
-
-	/*
-	 * Handle eth devices.
-	 */
-        if ( (memcmp(dev->name, "eth", 3) == 0) ) {
-		if (ifname_num->next_eth != -1) {
-			/*
-			 * Assign it the next available eth interface number. 
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "eth%d", (int)ifname_num->next_eth);
-			ifname_num->next_eth++;
-		} 
-
-                return;
-        }
-
-	/*
-	 * Handle fddi devices.
-	 */
-	if ( (memcmp(dev->name, "fddi", 4) == 0) ) {
-		if (ifname_num->next_fddi != -1) {
-			/*
-			 * Assign it the next available fddi interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "fddi%d", (int)ifname_num->next_fddi);
-			ifname_num->next_fddi++;
-		}
-
-		return;
-	}
-
-	/*
-	 * Handle hip devices.
-	 */
-	if ( (memcmp(dev->name, "hip", 3) == 0) ) {
-		if (ifname_num->next_hip != -1) {
-			/*
-			 * Assign it the next available hip interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "hip%d", (int)ifname_num->next_hip);
-			ifname_num->next_hip++;
-		}
-
-		return;
-	}
-
-	/*
-	 * Handle tr devices.
-	 */
-	if ( (memcmp(dev->name, "tr", 2) == 0) ) {
-		if (ifname_num->next_tr != -1) {
-			/*
-			 * Assign it the next available tr interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "tr%d", (int)ifname_num->next_tr);
-			ifname_num->next_tr++;
-		}
-
-		return;
-	}
-
-	/*
-	 * Handle fc devices.
-	 */
-	if ( (memcmp(dev->name, "fc", 2) == 0) ) {
-		if (ifname_num->next_fc != -1) {
-			/*
-			 * Assign it the next available fc interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "fc%d", (int)ifname_num->next_fc);
-			ifname_num->next_fc++;
-		}
-
-		return;
-	}
-}
-
-/*
- * find_persistent_ifname: Returns the entry that was seen in previous boot.
- */
-struct ifname_MAC *
-find_persistent_ifname(struct net_device *dev,
-	struct ifname_MAC *ifname_MAC)
-
-{
-
-	while (ifname_MAC->addr_len) {
-		if (memcmp(dev->dev_addr, ifname_MAC->dev_addr, dev->addr_len) == 0)
-			return(ifname_MAC);
-
-		ifname_MAC++;
-	}
-
-	return(NULL);
-}
-
-/*
- * ifconfig_net_ioctl: ifconfig_net driver ioctl interface.
- */
-static int ifconfig_net_ioctl(struct inode * inode, struct file * file,
-        unsigned int cmd, unsigned long arg)
-{
-
-	extern struct net_device *__dev_get_by_name(const char *);
-#ifdef CONFIG_NET
-	struct net_device *dev;
-	struct ifname_MAC *found;
-	char temp[64];
-#endif
-	struct ifname_MAC *ifname_MAC;
-	struct ifname_MAC *new_devices, *temp_new_devices;
-	struct ifname_num *ifname_num;
-	unsigned long size;
-
-
-	if (ifconfig_net_debug) {
-		printk("HCL: hcl_ioctl called.\n");
-	}
-
-	/*
-	 * Read in the header and see how big of a buffer we really need to 
-	 * allocate.
-	 */
-	ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), 
-			GFP_KERNEL);
-	copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num));
-	size = ifname_num->size;
-	kfree(ifname_num);
-	ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL);
-	ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) );
-
-	copy_from_user( ifname_num, (char *) arg, size);
-	new_devices =  kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL);
-	temp_new_devices = new_devices;
-
-	memset(new_devices, 0, size - sizeof(struct ifname_num));
-
-#ifdef CONFIG_NET
-	/*
-	 * Go through the net device entries and make them persistent!
-	 */
-	for (dev = dev_base; dev != NULL; dev = dev->next) {
-		/*
-		 * Skip NULL entries or "lo"
-		 */
-		if ( (dev->addr_len == 0) || ( !strncmp(dev->name, "lo", strlen(dev->name))) ){
-			continue;
-		}
-
-		/*
-		 * See if we have a persistent interface name for this device.
-		 */
-		found = NULL;
-		found = find_persistent_ifname(dev, ifname_MAC);
-		if (found) {
-			strcpy(dev->name, found->name);
-		} else {
-			/* Never seen this before .. */
-			assign_ifname(dev, ifname_num);
-
-			/* 
-			 * Save the information for the next boot.
-			 */
- 			sprintf(temp,"%s %02x:%02x:%02x:%02x:%02x:%02x\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]);
-			strcpy(temp_new_devices->name, dev->name);
-			temp_new_devices->addr_len = dev->addr_len;
-			memcpy(temp_new_devices->dev_addr, dev->dev_addr, dev->addr_len);
-			temp_new_devices++;
-		}
-		
-	}
-#endif
-
-	/*
-	 * Copy back to the User Buffer area any new devices encountered.
-	 */
-	copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, 
-			size - sizeof(struct ifname_num));
-
-	return(0);
-
-}
-
-struct file_operations ifconfig_net_fops = {
-	ioctl:ifconfig_net_ioctl,	/* ioctl */
-	open:ifconfig_net_open,		/* open */
-	release:ifconfig_net_close	/* release */
-};
-
-
-/*
- * init_ifconfig_net() - Boot time initialization.  Ensure that it is called 
- *	after devfs has been initialized.
- *
- */
-#ifdef MODULE
-int init_module (void)
-#else
-int __init init_ifconfig_net(void)
-#endif
-{
-	ifconfig_net_handle = NULL;
-	ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net",
- 		        0, 0,
-			0, 0,
-			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-			&ifconfig_net_fops, NULL);
-
-	if (ifconfig_net_handle == NULL) {
-		panic("Unable to create SGI PERSISTENT NETWORK DEVICE Name Driver.\n");
-	}
-
-	return(0);
-
-}
diff -urN linux-2.5.73-bk2/arch/ia64/sn/io/hwgfs/hcl.c linux-2.5.73-bk3/arch/ia64/sn/io/hwgfs/hcl.c
--- linux-2.5.73-bk2/arch/ia64/sn/io/hwgfs/hcl.c	2003-06-22 11:32:55.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/sn/io/hwgfs/hcl.c	2003-06-25 04:46:47.000000000 -0700
@@ -113,22 +113,10 @@
 }
 
 struct file_operations hcl_fops = {
-	(struct module *)0,
-	NULL,		/* lseek - default */
-	NULL,		/* read - general block-dev read */
-	NULL,		/* write - general block-dev write */
-	NULL,		/* readdir - bad */
-	NULL,		/* poll */
-	hcl_ioctl,      /* ioctl */
-	NULL,		/* mmap */
-	hcl_open,	/* open */
-	NULL,		/* flush */
-	hcl_close,	/* release */
-	NULL,		/* fsync */
-	NULL,		/* fasync */
-	NULL,		/* lock */
-	NULL,		/* readv */
-	NULL,		/* writev */
+	.owner = (struct module *)0,
+	.ioctl = hcl_ioctl,
+	.open = hcl_open,
+	.release = hcl_close,
 };
 
 
@@ -140,7 +128,6 @@
 {
 	extern void string_table_init(struct string_table *);
 	extern struct string_table label_string_table;
-	extern int init_ifconfig_net(void);
 	extern int init_ioconfig_bus(void);
 	extern int init_hwgfs_fs(void);
 	int rv = 0;
@@ -195,7 +182,6 @@
 	 * Initialize the ifconfgi_net driver that does network devices 
 	 * Persistent Naming.
 	 */
-	init_ifconfig_net();
 	init_ioconfig_bus();
 
 	return(0);
@@ -258,6 +244,7 @@
 
 	if (!de) {
 		printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n");
+		dump_stack();
 		return(-1);
 	}
 
@@ -568,7 +555,7 @@
 	 * In this case the vertex was previous created with a REAL pathname.
 	 */
 	rv = hwgfs_mk_symlink (from, (const char *)name,
-			       DEVFS_FL_DEFAULT, link,
+			       0, link,
 			       &handle, NULL);
 	kfree(path);
 	kfree(link);
diff -urN linux-2.5.73-bk2/arch/ia64/sn/io/machvec/pci.c linux-2.5.73-bk3/arch/ia64/sn/io/machvec/pci.c
--- linux-2.5.73-bk2/arch/ia64/sn/io/machvec/pci.c	2003-06-22 11:32:38.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/sn/io/machvec/pci.c	2003-06-25 04:46:47.000000000 -0700
@@ -49,6 +49,8 @@
 	vertex_hdl_t device_vertex;
 
 	device_vertex = devfn_to_vertex(bus->number, devfn);
+	if (!device_vertex)
+		return PCIBIOS_DEVICE_NOT_FOUND;
 	res = pciio_config_get(device_vertex, (unsigned) where, size);
 	*val = (unsigned int) res;
 	return PCIBIOS_SUCCESSFUL;
@@ -59,6 +61,8 @@
 	vertex_hdl_t device_vertex;
 
 	device_vertex = devfn_to_vertex(bus->number, devfn);
+	if (!device_vertex)
+		return PCIBIOS_DEVICE_NOT_FOUND;
 	pciio_config_set( device_vertex, (unsigned)where, size, (uint64_t) val);
 	return PCIBIOS_SUCCESSFUL;
 }
diff -urN linux-2.5.73-bk2/arch/ia64/sn/io/machvec/pci_dma.c linux-2.5.73-bk3/arch/ia64/sn/io/machvec/pci_dma.c
--- linux-2.5.73-bk2/arch/ia64/sn/io/machvec/pci_dma.c	2003-06-22 11:32:38.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/sn/io/machvec/pci_dma.c	2003-06-25 04:46:47.000000000 -0700
@@ -280,7 +280,7 @@
 	 */
 	for (i = 0; i < nents; i++, sg++) {
 		phys_addr = __pa(sg->dma_address ? sg->dma_address :
-			page_address(sg->page) + sg->offset);
+			(unsigned long)page_address(sg->page) + sg->offset);
 
 		/*
 		 * Handle the most common case: 64 bit cards.  This
@@ -578,7 +578,7 @@
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	return pci_dma_supported(to_pci_dev(dev), mask);
+	return sn_pci_dma_supported(to_pci_dev(dev), mask);
 }
 EXPORT_SYMBOL(sn_dma_supported);
 
@@ -587,7 +587,11 @@
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
+	if (!sn_dma_supported(dev, dma_mask))
+		return 0;
+
+	dev->dma_mask = dma_mask;
+	return 1;
 }
 EXPORT_SYMBOL(sn_dma_set_mask);
 
@@ -597,7 +601,7 @@
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
+	return sn_pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
 }
 EXPORT_SYMBOL(sn_dma_alloc_coherent);
 
@@ -607,7 +611,7 @@
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle);
+	sn_pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle);
 }
 EXPORT_SYMBOL(sn_dma_free_coherent);
 
@@ -617,7 +621,7 @@
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	return pci_map_single(to_pci_dev(dev), cpu_addr, size, (int)direction);
+	return sn_pci_map_single(to_pci_dev(dev), cpu_addr, size, (int)direction);
 }
 EXPORT_SYMBOL(sn_dma_map_single);
 
@@ -627,7 +631,7 @@
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction);
+	sn_pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction);
 }
 EXPORT_SYMBOL(sn_dma_unmap_single);
 
@@ -658,7 +662,7 @@
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction);
+	return sn_pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction);
 }
 EXPORT_SYMBOL(sn_dma_map_sg);
 
@@ -668,7 +672,7 @@
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction);
+	sn_pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction);
 }
 EXPORT_SYMBOL(sn_dma_unmap_sg);
 
@@ -678,7 +682,7 @@
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	pci_dma_sync_single(to_pci_dev(dev), dma_handle, size, (int)direction);
+	sn_pci_dma_sync_single(to_pci_dev(dev), dma_handle, size, (int)direction);
 }
 EXPORT_SYMBOL(sn_dma_sync_single);
 
@@ -688,7 +692,7 @@
 {
 	BUG_ON(dev->bus != &pci_bus_type);
 
-	pci_dma_sync_sg(to_pci_dev(dev), sg, nelems, (int)direction);
+	sn_pci_dma_sync_sg(to_pci_dev(dev), sg, nelems, (int)direction);
 }
 EXPORT_SYMBOL(sn_dma_sync_sg);
 
diff -urN linux-2.5.73-bk2/arch/ia64/sn/kernel/Makefile linux-2.5.73-bk3/arch/ia64/sn/kernel/Makefile
--- linux-2.5.73-bk2/arch/ia64/sn/kernel/Makefile	2003-06-22 11:32:33.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/sn/kernel/Makefile	2003-06-25 04:46:47.000000000 -0700
@@ -9,7 +9,8 @@
 
 EXTRA_CFLAGS := -DLITTLE_ENDIAN
 
-obj-y				:= probe.o setup.o sv.o bte.o irq.o mca.o sn2/
+obj-y				:= probe.o setup.o sv.o bte.o irq.o mca.o \
+				   idle.o sn2/
 
 obj-$(CONFIG_IA64_GENERIC)      += machvec.o
 obj-$(CONFIG_MODULES)           += sn_ksyms.o
diff -urN linux-2.5.73-bk2/arch/ia64/sn/kernel/idle.c linux-2.5.73-bk3/arch/ia64/sn/kernel/idle.c
--- linux-2.5.73-bk2/arch/ia64/sn/kernel/idle.c	2003-06-22 11:33:35.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/sn/kernel/idle.c	2003-06-25 04:46:47.000000000 -0700
@@ -12,7 +12,7 @@
 
 void snidle(int state) {
 	if (state) {
-		if (pda.idle_flag == 0) {
+		if (pda->idle_flag == 0) {
 			/* 
 			 * Turn the activity LED off.
 			 */
@@ -24,13 +24,13 @@
 			SIMULATOR_SLEEP();
 #endif
 
-		pda.idle_flag = 1;
+		pda->idle_flag = 1;
 	} else {
 		/* 
 		 * Turn the activity LED on.
 		 */
 		set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY);
 
-		pda.idle_flag = 0;
+		pda->idle_flag = 0;
 	}
 }
diff -urN linux-2.5.73-bk2/arch/ia64/sn/kernel/machvec.c linux-2.5.73-bk3/arch/ia64/sn/kernel/machvec.c
--- linux-2.5.73-bk2/arch/ia64/sn/kernel/machvec.c	2003-06-22 11:32:55.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/sn/kernel/machvec.c	2003-06-25 04:46:47.000000000 -0700
@@ -31,4 +31,5 @@
  */
 
 #define MACHVEC_PLATFORM_NAME	sn2
+#define MACHVEC_PLATFORM_HEADER	<asm/machvec_sn2.h>
 #include <asm/machvec_init.h>
diff -urN linux-2.5.73-bk2/arch/ia64/sn/kernel/setup.c linux-2.5.73-bk3/arch/ia64/sn/kernel/setup.c
--- linux-2.5.73-bk2/arch/ia64/sn/kernel/setup.c	2003-06-22 11:32:38.000000000 -0700
+++ linux-2.5.73-bk3/arch/ia64/sn/kernel/setup.c	2003-06-25 04:46:47.000000000 -0700
@@ -75,11 +75,13 @@
 
 #define pxm_to_nasid(pxm) ((pxm)<<1)
 
+#define MAX_PHYS_MEMORY		(1UL << 49)     /* 1 TB */
+
 extern void bte_init_node (nodepda_t *, cnodeid_t);
 extern void bte_init_cpu (void);
-extern void sn_timer_init (void);
+extern void sn_timer_init(void);
 extern void (*ia64_mark_idle)(int);
-void snidle(int);
+extern void snidle(int);
 
 unsigned long sn_rtc_cycles_per_second;   
 
@@ -296,21 +298,20 @@
 	 */
 	sn_check_for_wars();
 
+	ia64_mark_idle = &snidle;
+
 	/* 
 	 * For the bootcpu, we do this here. All other cpus will make the
 	 * call as part of cpu_init in slave cpu initialization.
 	 */
 	sn_cpu_init();
 
-
 #ifdef CONFIG_SMP
 	init_smp_config();
 #endif
 	screen_info = sn_screen_info;
 
 	sn_timer_init();
-
-	ia64_mark_idle = &snidle;
 }
 
 /**
@@ -438,19 +439,3 @@
 
 	bte_init_cpu();
 }
-
-void snidle(int idleness)
-{
-	if (!idleness) {
-		if (pda->idle_flag == 0) {
-			set_led_bits(0, LED_CPU_ACTIVITY);
-		}
-
-		pda->idle_flag = 1;
-	}
-	else {
-		set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY);
-
-		pda->idle_flag = 0;
-	}
-}
diff -urN linux-2.5.73-bk2/arch/sparc64/defconfig linux-2.5.73-bk3/arch/sparc64/defconfig
--- linux-2.5.73-bk2/arch/sparc64/defconfig	2003-06-22 11:32:41.000000000 -0700
+++ linux-2.5.73-bk3/arch/sparc64/defconfig	2003-06-25 04:46:48.000000000 -0700
@@ -27,7 +27,7 @@
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
 CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
+CONFIG_MODVERSIONS=y
 CONFIG_KMOD=y
 
 #
@@ -162,7 +162,9 @@
 #
 CONFIG_SERIAL_SUNCORE=y
 CONFIG_SERIAL_SUNZILOG=y
+CONFIG_SERIAL_SUNZILOG_CONSOLE=y
 CONFIG_SERIAL_SUNSU=y
+CONFIG_SERIAL_SUNSU_CONSOLE=y
 CONFIG_SERIAL_SUNSAB=m
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -197,8 +199,8 @@
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
+CONFIG_MD_RAID5=m
+CONFIG_MD_MULTIPATH=m
 CONFIG_BLK_DEV_DM=m
 # CONFIG_BLK_DEV_RAM is not set
 
@@ -243,26 +245,27 @@
 # CONFIG_BLK_DEV_AEC62XX is not set
 CONFIG_BLK_DEV_ALI15X3=y
 # CONFIG_WDC_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
+CONFIG_BLK_DEV_AMD74XX=m
+CONFIG_BLK_DEV_CMD64X=m
+CONFIG_BLK_DEV_TRIFLEX=m
+CONFIG_BLK_DEV_CY82C693=m
+CONFIG_BLK_DEV_CS5520=m
+CONFIG_BLK_DEV_HPT34X=m
+CONFIG_BLK_DEV_HPT366=m
+CONFIG_BLK_DEV_SC1200=m
+CONFIG_BLK_DEV_PIIX=m
+CONFIG_BLK_DEV_NS87415=m
+CONFIG_BLK_DEV_OPTI621=m
+CONFIG_BLK_DEV_PDC202XX_OLD=m
+CONFIG_BLK_DEV_PDC202XX_NEW=m
+CONFIG_BLK_DEV_SVWKS=m
+CONFIG_BLK_DEV_SIIMAGE=m
+CONFIG_BLK_DEV_SLC90E66=m
+CONFIG_BLK_DEV_TRM290=m
+CONFIG_BLK_DEV_VIA82CXXX=m
 CONFIG_IDEDMA_AUTO=y
 # CONFIG_IDEDMA_IVB is not set
+CONFIG_BLK_DEV_PDC202XX=y
 CONFIG_BLK_DEV_IDE_MODES=y
 
 #
@@ -408,14 +411,18 @@
 CONFIG_UNIX=y
 CONFIG_NET_KEY=m
 CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 # CONFIG_IP_PNP is not set
 CONFIG_NET_IPIP=m
 CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
 CONFIG_ARPD=y
 CONFIG_INET_ECN=y
-# CONFIG_SYN_COOKIES is not set
+CONFIG_SYN_COOKIES=y
 CONFIG_INET_AH=y
 CONFIG_INET_ESP=y
 CONFIG_INET_IPCOMP=y
@@ -436,6 +443,7 @@
 CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
 CONFIG_IP_NF_MATCH_DSCP=m
 CONFIG_IP_NF_MATCH_AH_ESP=m
@@ -553,9 +561,9 @@
 CONFIG_BRIDGE_EBT_DNAT=m
 CONFIG_BRIDGE_EBT_REDIRECT=m
 CONFIG_BRIDGE_EBT_MARK_T=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
+CONFIG_X25=m
+CONFIG_LAPB=m
+CONFIG_NET_DIVERT=y
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_FASTROUTE is not set
@@ -661,11 +669,13 @@
 #
 # Ethernet (1000 Mbit)
 #
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
+CONFIG_ACENIC=m
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
+CONFIG_DL2K=m
+CONFIG_E1000=m
+CONFIG_E1000_NAPI=y
 CONFIG_MYRI_SBUS=m
-# CONFIG_NS83820 is not set
+CONFIG_NS83820=m
 CONFIG_HAMACHI=m
 CONFIG_YELLOWFIN=m
 CONFIG_R8169=m
@@ -710,8 +720,11 @@
 #
 # Wireless 802.11b ISA/PCI cards support
 #
-# CONFIG_AIRO is not set
-# CONFIG_HERMES is not set
+CONFIG_AIRO=m
+CONFIG_HERMES=m
+CONFIG_PLX_HERMES=m
+CONFIG_TMD_HERMES=m
+CONFIG_PCI_HERMES=m
 CONFIG_NET_WIRELESS=y
 
 #
@@ -934,7 +947,6 @@
 # CONFIG_KEYBOARD_NEWTON is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
-CONFIG_MOUSE_PS2_SYNAPTICS=y
 CONFIG_MOUSE_SERIAL=y
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
diff -urN linux-2.5.73-bk2/drivers/block/loop.c linux-2.5.73-bk3/drivers/block/loop.c
--- linux-2.5.73-bk2/drivers/block/loop.c	2003-06-25 04:46:44.000000000 -0700
+++ linux-2.5.73-bk3/drivers/block/loop.c	2003-06-25 04:46:48.000000000 -0700
@@ -43,15 +43,6 @@
  * - Advisory locking is ignored here.
  * - Should use an own CAP_* category instead of CAP_SYS_ADMIN
  *
- * WARNING/FIXME:
- * - The block number as IV passing to low level transfer functions is broken:
- *   it passes the underlying device's block number instead of the
- *   offset. This makes it change for a given block when the file is
- *   moved/restored/copied and also doesn't work over NFS.
- * AV, Feb 12, 2000: we pass the logical block number now. It fixes the
- *   problem above. Encryption modules that used to rely on the old scheme
- *   should just call ->i_mapping->bmap() to calculate the physical block
- *   number.
  */
 
 #include <linux/config.h>
@@ -118,26 +109,26 @@
 	return 0;
 }
 
-static int xor_status(struct loop_device *lo, const struct loop_info64 *info)
+static int xor_init(struct loop_device *lo, const struct loop_info64 *info)
 {
 	if (info->lo_encrypt_key_size <= 0)
 		return -EINVAL;
 	return 0;
 }
 
-struct loop_func_table none_funcs = {
+static struct loop_func_table none_funcs = {
 	.number = LO_CRYPT_NONE,
 	.transfer = transfer_none,
 }; 	
 
-struct loop_func_table xor_funcs = {
+static struct loop_func_table xor_funcs = {
 	.number = LO_CRYPT_XOR,
 	.transfer = transfer_xor,
-	.init = xor_status
+	.init = xor_init
 }; 	
 
 /* xfer_funcs[0] is special - its release function is never called */
-struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {
+static struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {
 	&none_funcs,
 	&xor_funcs
 };
@@ -145,13 +136,21 @@
 static int
 figure_loop_size(struct loop_device *lo)
 {
-	loff_t size = lo->lo_backing_file->f_dentry->d_inode->i_mapping->host->i_size;
+	loff_t size, offset, loopsize;
 	sector_t x;
+
+	/* Compute loopsize in bytes */
+	size = lo->lo_backing_file->f_dentry->d_inode->i_mapping->host->i_size;
+	offset = lo->lo_offset;
+	loopsize = size - offset;
+	if (lo->lo_sizelimit > 0 && lo->lo_sizelimit < loopsize)
+		loopsize = lo->lo_sizelimit;
+
 	/*
 	 * Unfortunately, if we want to do I/O on the device,
 	 * the number of 512-byte sectors has to fit into a sector_t.
 	 */
-	size = (size - lo->lo_offset) >> 9;
+	size = loopsize >> 9;
 	x = (sector_t)size;
 
 	if ((loff_t)x != size)
@@ -190,9 +189,11 @@
 	data = kmap(bvec->bv_page) + bvec->bv_offset;
 	len = bvec->bv_len;
 	while (len > 0) {
-		sector_t IV = index * (PAGE_CACHE_SIZE/bsize) + offset/bsize;
+		sector_t IV;
 		int transfer_result;
 
+		IV = ((sector_t)index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9);
+
 		size = PAGE_CACHE_SIZE - offset;
 		if (size > len)
 			size = len;
@@ -203,7 +204,8 @@
 		if (aops->prepare_write(file, page, offset, offset+size))
 			goto unlock;
 		kaddr = kmap(page);
-		transfer_result = lo_do_transfer(lo, WRITE, kaddr + offset, data, size, IV);
+		transfer_result = lo_do_transfer(lo, WRITE, kaddr + offset,
+						 data, size, IV);
 		if (transfer_result) {
 			/*
 			 * The transfer failed, but we still write the data to
@@ -272,7 +274,9 @@
 	unsigned long count = desc->count;
 	struct lo_read_data *p = (struct lo_read_data*)desc->buf;
 	struct loop_device *lo = p->lo;
-	int IV = page->index * (PAGE_CACHE_SIZE/p->bsize) + offset/p->bsize;
+	sector_t IV;
+
+	IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9);
 
 	if (size > count)
 		size = count;
@@ -327,20 +331,6 @@
 	return ret;
 }
 
-static inline unsigned long
-loop_get_iv(struct loop_device *lo, unsigned long sector)
-{
-	int bs = lo->lo_blocksize;
-	unsigned long offset, IV;
-
-	IV = sector / (bs >> 9) + lo->lo_offset / bs;
-	offset = ((sector % (bs >> 9)) << 9) + lo->lo_offset % bs;
-	if (offset >= bs)
-		IV++;
-
-	return IV;
-}
-
 static int do_bio_filebacked(struct loop_device *lo, struct bio *bio)
 {
 	loff_t pos;
@@ -504,11 +494,13 @@
 static int loop_transfer_bio(struct loop_device *lo,
 			     struct bio *to_bio, struct bio *from_bio)
 {
-	unsigned long IV = loop_get_iv(lo, from_bio->bi_sector);
+	sector_t IV;
 	struct bio_vec *from_bvec, *to_bvec;
 	char *vto, *vfrom;
 	int ret = 0, i;
 
+	IV = from_bio->bi_sector + (lo->lo_offset >> 9);
+
 	__bio_for_each_segment(from_bvec, from_bio, i, 0) {
 		to_bvec = &to_bio->bi_io_vec[i];
 
@@ -728,6 +720,7 @@
 	lo->lo_backing_file = file;
 	lo->transfer = NULL;
 	lo->ioctl = NULL;
+	lo->lo_sizelimit = 0;
 	if (figure_loop_size(lo)) {
 		error = -EFBIG;
 		fput(file);
@@ -842,6 +835,7 @@
 	lo->lo_device = NULL;
 	lo->lo_encryption = NULL;
 	lo->lo_offset = 0;
+	lo->lo_sizelimit = 0;
 	lo->lo_encrypt_key_size = 0;
 	lo->lo_flags = 0;
 	lo->lo_queue.queuedata = NULL;
@@ -890,8 +884,10 @@
 	if (err)
 		return err;
 
-	if (lo->lo_offset != info->lo_offset) {
+	if (lo->lo_offset != info->lo_offset ||
+	    lo->lo_sizelimit != info->lo_sizelimit) {
 		lo->lo_offset = info->lo_offset;
+		lo->lo_sizelimit = info->lo_sizelimit;
 		if (figure_loop_size(lo))
 			return -EFBIG;
 	}
@@ -933,6 +929,7 @@
 	info->lo_inode = stat.ino;
 	info->lo_rdevice = lo->lo_device ? stat.rdev : stat.dev;
 	info->lo_offset = lo->lo_offset;
+	info->lo_sizelimit = lo->lo_sizelimit;
 	info->lo_flags = lo->lo_flags;
 	strlcpy(info->lo_name, lo->lo_name, LO_NAME_SIZE);
 	info->lo_encrypt_type =
@@ -948,11 +945,13 @@
 static void
 loop_info64_from_old(const struct loop_info *info, struct loop_info64 *info64)
 {
+	memset(info64, 0, sizeof(*info64));
 	info64->lo_number = info->lo_number;
 	info64->lo_device = info->lo_device;
 	info64->lo_inode = info->lo_inode;
 	info64->lo_rdevice = info->lo_rdevice;
 	info64->lo_offset = info->lo_offset;
+	info64->lo_sizelimit = 0;
 	info64->lo_encrypt_type = info->lo_encrypt_type;
 	info64->lo_encrypt_key_size = info->lo_encrypt_key_size;
 	info64->lo_flags = info->lo_flags;
@@ -965,6 +964,7 @@
 static int
 loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
 {
+	memset(info, 0, sizeof(*info));
 	info->lo_number = info64->lo_number;
 	info->lo_device = info64->lo_device;
 	info->lo_inode = info64->lo_inode;
@@ -1152,7 +1152,7 @@
 {
 	int	i;
 
-	if ((max_loop < 1) || (max_loop > 256)) {
+	if (max_loop < 1 || max_loop > 256) {
 		printk(KERN_WARNING "loop: invalid max_loop (must be between"
 				    " 1 and 256), using default (8)\n");
 		max_loop = 8;
@@ -1161,22 +1161,22 @@
 	if (register_blkdev(LOOP_MAJOR, "loop"))
 		return -EIO;
 
-	devfs_mk_dir("loop");
-
 	loop_dev = kmalloc(max_loop * sizeof(struct loop_device), GFP_KERNEL);
 	if (!loop_dev)
-		return -ENOMEM;
+		goto out_mem1;
 
 	disks = kmalloc(max_loop * sizeof(struct gendisk *), GFP_KERNEL);
 	if (!disks)
-		goto out_mem;
+		goto out_mem2;
 
 	for (i = 0; i < max_loop; i++) {
 		disks[i] = alloc_disk(1);
 		if (!disks[i])
-			goto out_mem2;
+			goto out_mem3;
 	}
 
+	devfs_mk_dir("loop");
+
 	for (i = 0; i < max_loop; i++) {
 		struct loop_device *lo = &loop_dev[i];
 		struct gendisk *disk = disks[i];
@@ -1198,12 +1198,14 @@
 	printk(KERN_INFO "loop: loaded (max %d devices)\n", max_loop);
 	return 0;
 
-out_mem2:
+out_mem3:
 	while (i--)
 		put_disk(disks[i]);
 	kfree(disks);
-out_mem:
+out_mem2:
 	kfree(loop_dev);
+out_mem1:
+	unregister_blkdev(LOOP_MAJOR, "loop");
 	printk(KERN_ERR "loop: ran out of memory\n");
 	return -ENOMEM;
 }
diff -urN linux-2.5.73-bk2/drivers/ide/ide.c linux-2.5.73-bk3/drivers/ide/ide.c
--- linux-2.5.73-bk2/drivers/ide/ide.c	2003-06-22 11:32:38.000000000 -0700
+++ linux-2.5.73-bk3/drivers/ide/ide.c	2003-06-25 04:46:48.000000000 -0700
@@ -216,7 +216,7 @@
 EXPORT_SYMBOL(idescsi);
 
 extern ide_driver_t idedefault_driver;
-static void setup_driver_defaults (ide_drive_t *drive);
+static void setup_driver_defaults(ide_driver_t *driver);
 
 /*
  * Do not even *think* about calling this!
@@ -275,7 +275,6 @@
 		drive->using_dma		= 0;
 		drive->is_flash			= 0;
 		drive->driver			= &idedefault_driver;
-		setup_driver_defaults(drive);
 		drive->vdma			= 0;
 		INIT_LIST_HEAD(&drive->list);
 	}
@@ -308,6 +307,8 @@
 		return;		/* already initialized */
 	magic_cookie = 0;
 
+	setup_driver_defaults(&idedefault_driver);
+
 	/* Initialise all interface structures */
 	for (index = 0; index < MAX_HWIFS; ++index)
 		init_hwif_data(index);
@@ -673,8 +674,8 @@
 		blk_cleanup_queue(&drive->queue);
 	}
 	if (hwif->next == hwif) {
-		kfree(hwgroup);
 		BUG_ON(hwgroup->hwif != hwif);
+		kfree(hwgroup);
 	} else {
 		/* There is another interface in hwgroup.
 		 * Unlink us, and set hwgroup->drive and ->hwif to
@@ -1134,13 +1135,12 @@
  *
  *	Automatically remove all the driver specific settings for this
  *	drive. This function may sleep and must not be called from IRQ
- *	context. Takes the settings_lock
+ *	context. The caller must hold ide_setting_sem.
  */
  
 static void auto_remove_settings (ide_drive_t *drive)
 {
 	ide_settings_t *setting;
-	down(&ide_setting_sem);
 repeat:
 	setting = drive->settings;
 	while (setting) {
@@ -1150,7 +1150,6 @@
 		}
 		setting = setting->next;
 	}
-	up(&ide_setting_sem);
 }
 
 /**
@@ -2346,10 +2345,8 @@
 	return ide_abort(drive, msg);
 }
 
-static void setup_driver_defaults (ide_drive_t *drive)
+static void setup_driver_defaults (ide_driver_t *d)
 {
-	ide_driver_t *d = drive->driver;
-
 	if (d->cleanup == NULL)		d->cleanup = default_cleanup;
 	if (d->shutdown == NULL)	d->shutdown = default_shutdown;
 	if (d->flushcache == NULL)	d->flushcache = default_flushcache;
@@ -2377,7 +2374,6 @@
 		return 1;
 	}
 	drive->driver = driver;
-	setup_driver_defaults(drive);
 	spin_unlock_irqrestore(&ide_lock, flags);
 	spin_lock(&drives_lock);
 	list_add_tail(&drive->list, &driver->drives);
@@ -2408,9 +2404,11 @@
 {
 	unsigned long flags;
 	
+	down(&ide_setting_sem);
 	spin_lock_irqsave(&ide_lock, flags);
 	if (drive->usage || drive->driver == &idedefault_driver || DRIVER(drive)->busy) {
 		spin_unlock_irqrestore(&ide_lock, flags);
+		up(&ide_setting_sem);
 		return 1;
 	}
 #if defined(CONFIG_BLK_DEV_IDEPNP) && defined(CONFIG_PNP) && defined(MODULE)
@@ -2422,8 +2420,8 @@
 #endif
 	auto_remove_settings(drive);
 	drive->driver = &idedefault_driver;
-	setup_driver_defaults(drive);
 	spin_unlock_irqrestore(&ide_lock, flags);
+	up(&ide_setting_sem);
 	spin_lock(&drives_lock);
 	list_del_init(&drive->list);
 	spin_unlock(&drives_lock);
@@ -2446,6 +2444,8 @@
 	struct list_head *list_loop;
 	struct list_head *tmp_storage;
 
+	setup_driver_defaults(driver);
+
 	spin_lock(&drivers_lock);
 	list_add(&driver->drivers, &drivers);
 	spin_unlock(&drivers_lock);
diff -urN linux-2.5.73-bk2/drivers/ide/legacy/pdc4030.c linux-2.5.73-bk3/drivers/ide/legacy/pdc4030.c
--- linux-2.5.73-bk2/drivers/ide/legacy/pdc4030.c	2003-06-22 11:32:46.000000000 -0700
+++ linux-2.5.73-bk3/drivers/ide/legacy/pdc4030.c	2003-06-25 04:46:48.000000000 -0700
@@ -613,8 +613,6 @@
 		 */
 		taskfile_output_data(drive, buffer, nsect<<7);
 	} while (mcount);
-
-	return 0;
 }
 #endif
 
@@ -624,7 +622,9 @@
 static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive)
 {
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
+#ifdef CONFIG_IDE_TASKFILE_IO
 	struct request *rq = hwgroup->rq;
+#endif
 
 	if (HWIF(drive)->INB(IDE_NSECTOR_REG) != 0) {
 		if (time_before(jiffies, hwgroup->poll_timeout)) {
@@ -818,7 +818,8 @@
 	   Feature register.
 	   FIXME: Is promise_selectproc now redundant??
 	*/
-	int drive_number = (HWIF(drive)->channel << 1) + drive->select.b.unit;
+	ide_hwif_t *hwif = HWIF(drive);
+	int drive_number = (hwif->channel << 1) + drive->select.b.unit;
 #ifdef CONFIG_IDE_TASKFILE_IO
 	struct hd_drive_task_hdr taskfile;
 	ide_task_t args;
diff -urN linux-2.5.73-bk2/drivers/ide/pci/sc1200.c linux-2.5.73-bk3/drivers/ide/pci/sc1200.c
--- linux-2.5.73-bk2/drivers/ide/pci/sc1200.c	2003-06-22 11:32:56.000000000 -0700
+++ linux-2.5.73-bk3/drivers/ide/pci/sc1200.c	2003-06-25 04:46:48.000000000 -0700
@@ -32,17 +32,6 @@
 #include "ide_modes.h"
 #include "sc1200.h"
 
-#define DISPLAY_SC1200_TIMINGS
-
-#if defined(DISPLAY_SC1200_TIMINGS) && defined(CONFIG_PROC_FS)
-#include <linux/stat.h>
-#include <linux/proc_fs.h>
-
-static int sc1200_get_info(char *, char **, off_t, int);
-extern int (*sc1200_display_info)(char *, char **, off_t, int); /* ide-proc.c */
-extern char *ide_media_verbose(ide_drive_t *);
-static u8 sc1200_proc = 0;
-
 #define SC1200_REV_A	0x00
 #define SC1200_REV_B1	0x01
 #define SC1200_REV_B3	0x02
@@ -81,6 +70,17 @@
 	return pci_clock;
 }
 
+#define DISPLAY_SC1200_TIMINGS
+
+#if defined(DISPLAY_SC1200_TIMINGS) && defined(CONFIG_PROC_FS)
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+
+static int sc1200_get_info(char *, char **, off_t, int);
+extern int (*sc1200_display_info)(char *, char **, off_t, int); /* ide-proc.c */
+extern char *ide_media_verbose(ide_drive_t *);
+static u8 sc1200_proc = 0;
+
 static struct pci_dev *bmide_dev;
 
 static int sc1200_get_info (char *buffer, char **addr, off_t offset, int count)
diff -urN linux-2.5.73-bk2/drivers/pci/pci.c linux-2.5.73-bk3/drivers/pci/pci.c
--- linux-2.5.73-bk2/drivers/pci/pci.c	2003-06-22 11:32:38.000000000 -0700
+++ linux-2.5.73-bk3/drivers/pci/pci.c	2003-06-25 04:46:49.000000000 -0700
@@ -747,6 +747,7 @@
 EXPORT_SYMBOL(isa_bridge);
 #endif
 
+EXPORT_SYMBOL(pci_enable_device_bars);
 EXPORT_SYMBOL(pci_enable_device);
 EXPORT_SYMBOL(pci_disable_device);
 EXPORT_SYMBOL(pci_max_busnr);
diff -urN linux-2.5.73-bk2/drivers/pnp/interface.c linux-2.5.73-bk3/drivers/pnp/interface.c
--- linux-2.5.73-bk2/drivers/pnp/interface.c	2003-06-22 11:32:33.000000000 -0700
+++ linux-2.5.73-bk3/drivers/pnp/interface.c	2003-06-25 04:46:49.000000000 -0700
@@ -323,14 +323,14 @@
 	if (!strnicmp(buf,"auto",4)) {
 		if (dev->active)
 			goto done;
-		pnp_init_resources(&dev->res);
+		pnp_init_resource_table(&dev->res);
 		retval = pnp_auto_config_dev(dev);
 		goto done;
 	}
 	if (!strnicmp(buf,"clear",5)) {
 		if (dev->active)
 			goto done;
-		pnp_init_resources(&dev->res);
+		pnp_init_resource_table(&dev->res);
 		goto done;
 	}
 	if (!strnicmp(buf,"get",3)) {
@@ -345,7 +345,7 @@
 		if (dev->active)
 			goto done;
 		buf += 3;
-		pnp_init_resources(&dev->res);
+		pnp_init_resource_table(&dev->res);
 		down(&pnp_res_mutex);
 		while (1) {
 			while (isspace(*buf))
diff -urN linux-2.5.73-bk2/drivers/pnp/isapnp/core.c linux-2.5.73-bk3/drivers/pnp/isapnp/core.c
--- linux-2.5.73-bk2/drivers/pnp/isapnp/core.c	2003-06-22 11:32:55.000000000 -0700
+++ linux-2.5.73-bk3/drivers/pnp/isapnp/core.c	2003-06-25 04:46:49.000000000 -0700
@@ -458,7 +458,7 @@
 	dev->capabilities |= PNP_READ;
 	dev->capabilities |= PNP_WRITE;
 	dev->capabilities |= PNP_DISABLE;
-	pnp_init_resources(&dev->res);
+	pnp_init_resource_table(&dev->res);
 	return dev;
 }
 
@@ -1020,7 +1020,7 @@
 static int isapnp_get_resources(struct pnp_dev *dev, struct pnp_resource_table * res)
 {
 	int ret;
-	pnp_init_resources(res);
+	pnp_init_resource_table(res);
 	isapnp_cfg_begin(dev->card->number, dev->number);
 	ret = isapnp_read_resources(dev, res);
 	isapnp_cfg_end();
diff -urN linux-2.5.73-bk2/drivers/pnp/manager.c linux-2.5.73-bk3/drivers/pnp/manager.c
--- linux-2.5.73-bk2/drivers/pnp/manager.c	2003-06-22 11:33:18.000000000 -0700
+++ linux-2.5.73-bk3/drivers/pnp/manager.c	2003-06-25 04:46:49.000000000 -0700
@@ -190,10 +190,9 @@
  * @table: pointer to the desired resource table
  *
  */
-void pnp_init_resources(struct pnp_resource_table *table)
+void pnp_init_resource_table(struct pnp_resource_table *table)
 {
 	int idx;
-	down(&pnp_res_mutex);
 	for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
 		table->irq_resource[idx].name = NULL;
 		table->irq_resource[idx].start = -1;
@@ -218,7 +217,6 @@
 		table->mem_resource[idx].end = 0;
 		table->mem_resource[idx].flags = IORESOURCE_AUTO;
 	}
-	up(&pnp_res_mutex);
 }
 
 /**
@@ -226,7 +224,7 @@
  * @res - the resources to clean
  *
  */
-static void pnp_clean_resources(struct pnp_resource_table * res)
+static void pnp_clean_resource_table(struct pnp_resource_table * res)
 {
 	int idx;
 	for (idx = 0; idx < PNP_MAX_IRQ; idx++) {
@@ -278,7 +276,7 @@
 		return -ENODEV;
 
 	down(&pnp_res_mutex);
-	pnp_clean_resources(&dev->res); /* start with a fresh slate */
+	pnp_clean_resource_table(&dev->res); /* start with a fresh slate */
 	if (dev->independent) {
 		port = dev->independent->port;
 		mem = dev->independent->mem;
@@ -351,7 +349,7 @@
 	return 1;
 
 fail:
-	pnp_clean_resources(&dev->res);
+	pnp_clean_resource_table(&dev->res);
 	up(&pnp_res_mutex);
 	return 0;
 }
@@ -510,7 +508,7 @@
 
 	/* release the resources so that other devices can use them */
 	down(&pnp_res_mutex);
-	pnp_clean_resources(&dev->res);
+	pnp_clean_resource_table(&dev->res);
 	up(&pnp_res_mutex);
 
 	return 1;
@@ -539,4 +537,4 @@
 EXPORT_SYMBOL(pnp_activate_dev);
 EXPORT_SYMBOL(pnp_disable_dev);
 EXPORT_SYMBOL(pnp_resource_change);
-EXPORT_SYMBOL(pnp_init_resources);
+EXPORT_SYMBOL(pnp_init_resource_table);
diff -urN linux-2.5.73-bk2/drivers/pnp/pnpbios/core.c linux-2.5.73-bk3/drivers/pnp/pnpbios/core.c
--- linux-2.5.73-bk2/drivers/pnp/pnpbios/core.c	2003-06-22 11:32:31.000000000 -0700
+++ linux-2.5.73-bk3/drivers/pnp/pnpbios/core.c	2003-06-25 04:46:49.000000000 -0700
@@ -937,7 +937,7 @@
 
 	/* clear out the damaged flags */
 	if (!dev->active)
-		pnp_init_resources(&dev->res);
+		pnp_init_resource_table(&dev->res);
 
 	pnp_add_device(dev);
 	pnpbios_interface_attach_device(node);
diff -urN linux-2.5.73-bk2/drivers/pnp/support.c linux-2.5.73-bk3/drivers/pnp/support.c
--- linux-2.5.73-bk2/drivers/pnp/support.c	2003-06-22 11:32:36.000000000 -0700
+++ linux-2.5.73-bk3/drivers/pnp/support.c	2003-06-25 04:46:49.000000000 -0700
@@ -123,7 +123,7 @@
 		return NULL;
 
 	/* Blank the resource table values */
-	pnp_init_resources(res);
+	pnp_init_resource_table(res);
 
 	while ((char *)p < (char *)end) {
 
diff -urN linux-2.5.73-bk2/drivers/serial/Kconfig linux-2.5.73-bk3/drivers/serial/Kconfig
--- linux-2.5.73-bk2/drivers/serial/Kconfig	2003-06-25 04:46:44.000000000 -0700
+++ linux-2.5.73-bk3/drivers/serial/Kconfig	2003-06-25 04:46:49.000000000 -0700
@@ -326,6 +326,14 @@
 	  This driver supports the Zilog8530 serial ports found on many Sparc
 	  systems.  Say Y or M if you want to be able to these serial ports.
 
+config SERIAL_SUNZILOG_CONSOLE
+	bool "Console on Sun Zilog8530 serial port"
+	depends on SERIAL_SUNZILOG=y
+	help
+	  If you would like to be able to use the Zilog8530 serial port
+	  on your Sparc system as the console, you can do so by answering
+	  Y to this option.
+
 config SERIAL_SUNSU
 	tristate "Sun SU serial support"
 	depends on (SPARC32 || SPARC64) && PCI
@@ -334,6 +342,14 @@
 	  mouse on (PCI) UltraSPARC systems.  Say Y or M if you want to be able
 	  to these serial ports.
 
+config SERIAL_SUNSU_CONSOLE
+	bool "Console on Sun SU serial port"
+	depends on SERIAL_SUNSU=y
+	help
+	  If you would like to be able to use the SU serial port
+	  on your Sparc system as the console, you can do so by answering
+	  Y to this option.
+
 config SERIAL_MUX
 	tristate "Serial MUX support"
 	depends on PARISC
@@ -380,6 +396,14 @@
 	  (PCI) UltraSPARC systems.  Say Y or M if you want to be able to these
 	  serial ports.
 
+config SERIAL_SUNSAB_CONSOLE
+	bool "Console on Sun Siemens SAB82532 serial port"
+	depends on SERIAL_SUNSAB=y
+	help
+	  If you would like to be able to use the SAB82532 serial port
+	  on your Sparc system as the console, you can do so by answering
+	  Y to this option.
+
 config V850E_NB85E_UART
 	bool "NEC V850E on-chip UART support"
 	depends on V850E_NB85E || V850E2_ANNA || V850E_AS85EP1
@@ -407,7 +431,7 @@
 
 config SERIAL_CORE_CONSOLE
 	bool
-	depends on SERIAL_AMBA_CONSOLE || SERIAL_CLPS711X_CONSOLE || SERIAL_21285_CONSOLE || SERIAL_SA1100_CONSOLE || SERIAL_ANAKIN_CONSOLE || SERIAL_UART00_CONSOLE || SERIAL_8250_CONSOLE || SERIAL_MUX_CONSOLE || SERIAL_SUNCORE || V850E_NB85E_UART_CONSOLE || SERIAL98_CONSOLE
+	depends on SERIAL_AMBA_CONSOLE || SERIAL_CLPS711X_CONSOLE || SERIAL_21285_CONSOLE || SERIAL_SA1100_CONSOLE || SERIAL_ANAKIN_CONSOLE || SERIAL_UART00_CONSOLE || SERIAL_8250_CONSOLE || SERIAL_MUX_CONSOLE || SERIAL_SUNZILOG_CONSOLE || SERIAL_SUNSU_CONSOLE || SERIAL_SUNSAB_CONSOLE || V850E_NB85E_UART_CONSOLE || SERIAL98_CONSOLE
 	default y
 
 config SERIAL_68328
diff -urN linux-2.5.73-bk2/drivers/serial/sunsab.c linux-2.5.73-bk3/drivers/serial/sunsab.c
--- linux-2.5.73-bk2/drivers/serial/sunsab.c	2003-06-22 11:32:42.000000000 -0700
+++ linux-2.5.73-bk3/drivers/serial/sunsab.c	2003-06-25 04:46:49.000000000 -0700
@@ -28,6 +28,7 @@
 #include <linux/ioport.h>
 #include <linux/circ_buf.h>
 #include <linux/serial.h>
+#include <linux/sysrq.h>
 #include <linux/console.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
@@ -38,6 +39,10 @@
 #include <asm/oplib.h>
 #include <asm/ebus.h>
 
+#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
 #include <linux/serial_core.h>
 
 #include "suncore.h"
@@ -838,6 +843,8 @@
 static struct uart_sunsab_port *sunsab_ports;
 static int num_channels;
 
+#ifdef CONFIG_SERIAL_SUNSAB_CONSOLE
+
 static __inline__ void sunsab_console_putchar(struct uart_sunsab_port *up, char c)
 {
 	unsigned long flags;
@@ -929,6 +936,7 @@
 	.index	=	-1,
 	.data	=	&sunsab_reg,
 };
+#define SUNSAB_CONSOLE	(&sunsab_console)
 
 static void __init sunsab_console_init(void)
 {
@@ -949,6 +957,10 @@
 	sunsab_console.index = i;
 	register_console(&sunsab_console);
 }
+#else
+#define SUNSAB_CONSOLE		(NULL)
+#define sunsab_console_init()	do { } while (0)
+#endif
 
 static void __init for_each_sab_edev(void (*callback)(struct linux_ebus_device *, void *), void *arg)
 {
@@ -1091,7 +1103,7 @@
 
 	sunsab_reg.minor = sunserial_current_minor;
 	sunsab_reg.nr = num_channels;
-	sunsab_reg.cons = &sunsab_console;
+	sunsab_reg.cons = SUNSAB_CONSOLE;
 
 	ret = uart_register_driver(&sunsab_reg);
 	if (ret < 0) {
diff -urN linux-2.5.73-bk2/drivers/serial/sunsu.c linux-2.5.73-bk3/drivers/serial/sunsu.c
--- linux-2.5.73-bk2/drivers/serial/sunsu.c	2003-06-22 11:32:36.000000000 -0700
+++ linux-2.5.73-bk3/drivers/serial/sunsu.c	2003-06-25 04:46:49.000000000 -0700
@@ -46,8 +46,7 @@
 #include <asm/isa.h>
 #endif
 
-/* #if defined(CONFIG_SERIAL_8250_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) */
-#if defined(CONFIG_MAGIC_SYSRQ)
+#if defined(CONFIG_SERIAL_SUNSU_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 #define SUPPORT_SYSRQ
 #endif
 
@@ -1347,6 +1346,8 @@
  * ------------------------------------------------------------
  */
 
+#ifdef CONFIG_SERIAL_SUNSU_CONSOLE
+
 #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
 
 /*
@@ -1465,6 +1466,7 @@
 	.index	=	-1,
 	.data	=	&sunsu_reg,
 };
+#define SUNSU_CONSOLE	(&sunsu_cons)
 
 /*
  *	Register console.
@@ -1492,6 +1494,10 @@
 	register_console(&sunsu_cons);
 	return 0;
 }
+#else
+#define SUNSU_CONSOLE			(NULL)
+#define sunsu_serial_console_init()	do { } while (0)
+#endif
 
 static int __init sunsu_serial_init(void)
 {
@@ -1522,7 +1528,7 @@
 	sunserial_current_minor += instance;
 
 	sunsu_reg.nr = instance;
-	sunsu_reg.cons = &sunsu_cons;
+	sunsu_reg.cons = SUNSU_CONSOLE;
 
 	ret = uart_register_driver(&sunsu_reg);
 	if (ret < 0)
diff -urN linux-2.5.73-bk2/drivers/serial/sunzilog.c linux-2.5.73-bk3/drivers/serial/sunzilog.c
--- linux-2.5.73-bk2/drivers/serial/sunzilog.c	2003-06-22 11:33:34.000000000 -0700
+++ linux-2.5.73-bk3/drivers/serial/sunzilog.c	2003-06-25 04:46:49.000000000 -0700
@@ -28,6 +28,7 @@
 #include <linux/slab.h>
 #include <linux/circ_buf.h>
 #include <linux/serial.h>
+#include <linux/sysrq.h>
 #include <linux/console.h>
 #include <linux/spinlock.h>
 #ifdef CONFIG_SERIO
@@ -42,6 +43,10 @@
 #endif
 #include <asm/sbus.h>
 
+#if defined(CONFIG_SERIAL_SUNZILOG_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
+#define SUPPORT_SYSRQ
+#endif
+
 #include <linux/serial_core.h>
 
 #include "suncore.h"
@@ -1331,6 +1336,7 @@
 
 #endif /* CONFIG_SERIO */
 
+#ifdef CONFIG_SERIAL_SUNZILOG_CONSOLE
 static void
 sunzilog_console_write(struct console *con, const char *s, unsigned int count)
 {
@@ -1400,6 +1406,7 @@
 	.index	=	-1,
 	.data   =	&sunzilog_reg,
 };
+#define SUNZILOG_CONSOLE	(&sunzilog_console)
 
 static int __init sunzilog_console_init(void)
 {
@@ -1422,6 +1429,10 @@
 	register_console(&sunzilog_console);
 	return 0;
 }
+#else
+#define SUNZILOG_CONSOLE	(NULL)
+#define sunzilog_console_init() do { } while (0)
+#endif
 
 /*
  * We scan the PROM tree recursively. This is the most reliable way
@@ -1639,7 +1650,7 @@
 	 * in the system.
 	 */
 	sunzilog_reg.nr = NUM_CHANNELS;
-	sunzilog_reg.cons = &sunzilog_console;
+	sunzilog_reg.cons = SUNZILOG_CONSOLE;
 
 	sunzilog_reg.minor = sunserial_current_minor;
 	sunserial_current_minor += NUM_CHANNELS;
diff -urN linux-2.5.73-bk2/drivers/usb/host/uhci-debug.c linux-2.5.73-bk3/drivers/usb/host/uhci-debug.c
--- linux-2.5.73-bk2/drivers/usb/host/uhci-debug.c	2003-06-22 11:32:34.000000000 -0700
+++ linux-2.5.73-bk3/drivers/usb/host/uhci-debug.c	2003-06-25 04:46:49.000000000 -0700
@@ -513,7 +513,7 @@
 }
 
 #ifdef CONFIG_PROC_FS
-#define MAX_OUTPUT	(PAGE_SIZE * 16)
+#define MAX_OUTPUT	(64 * 1024)
 
 static struct proc_dir_entry *uhci_proc_root = NULL;
 
diff -urN linux-2.5.73-bk2/drivers/usb/net/cdc-ether.c linux-2.5.73-bk3/drivers/usb/net/cdc-ether.c
--- linux-2.5.73-bk2/drivers/usb/net/cdc-ether.c	2003-06-22 11:32:31.000000000 -0700
+++ linux-2.5.73-bk3/drivers/usb/net/cdc-ether.c	1969-12-31 16:00:00.000000000 -0800
@@ -1,1397 +0,0 @@
-// Portions of this file taken from
-// Petko Manolov - Petkan (petkan@dce.bg)
-// from his driver pegasus.c
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/types.h>
-#include <linux/jiffies.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/usb.h>
-#include <linux/module.h>
-#include "cdc-ether.h"
-
-static const char *version = __FILE__ ": v0.98.5 22 Sep 2001 Brad Hards and another";
-
-/* Take any CDC device, and sort it out in probe() */
-static struct usb_device_id CDCEther_ids[] = {
-	{ USB_DEVICE_INFO(USB_CLASS_COMM, 0, 0) },
-	{ } /* Terminating null entry */
-};
-
-/* 
- * module parameter that provides an alternate upper limit on the 
- * number of multicast filters we use, with a default to use all
- * the filters available to us. Note that the actual number used
- * is the lesser of this parameter and the number returned in the
- * descriptor for the particular device. See Table 41 of the CDC
- * spec for more info on the descriptor limit.
- */
-static int multicast_filter_limit = 32767;
-
-
-//////////////////////////////////////////////////////////////////////////////
-// Callback routines from USB device /////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-static void read_bulk_callback( struct urb *urb, struct pt_regs *regs )
-{
-	ether_dev_t *ether_dev = urb->context;
-	struct net_device *net;
-	int count = urb->actual_length, res;
-	struct sk_buff	*skb;
-
-	// Sanity check 
-	if ( !ether_dev || !(ether_dev->flags & CDC_ETHER_RUNNING) ) {
-		dbg("BULK IN callback but driver is not active!");
-		return;
-	}
-
-	net = ether_dev->net;
-	if ( !netif_device_present(net) ) {
-		// Somebody killed our network interface...
-		return;
-	}
-
-	if ( ether_dev->flags & CDC_ETHER_RX_BUSY ) {
-		// Are we already trying to receive a frame???
-		ether_dev->stats.rx_errors++;
-		dbg("ether_dev Rx busy");
-		return;
-	}
-
-	// We are busy, leave us alone!
-	ether_dev->flags |= CDC_ETHER_RX_BUSY;
-
-	switch ( urb->status ) {
-		case 0:
-			break;
-		case -ETIMEDOUT:
-			dbg( "no repsonse in BULK IN" );
-			ether_dev->flags &= ~CDC_ETHER_RX_BUSY;
-			break;
-		default:
-			dbg( "%s: RX status %d", net->name, urb->status );
-			goto goon;
-	}
-
-	// Check to make sure we got some data...
-	if ( !count ) {
-		// We got no data!!!
-		goto goon;
-	}
-
-	// Tell the kernel we want some memory
-	if ( !(skb = dev_alloc_skb(count)) ) {
-		// We got no receive buffer.
-		goto goon;
-	}
-
-	// Here's where it came from
-	skb->dev = net;
-	
-	// Now we copy it over
-	eth_copy_and_sum(skb, ether_dev->rx_buff, count, 0);
-	
-	// Not sure
-	skb_put(skb, count);
-	// Not sure here either
-	skb->protocol = eth_type_trans(skb, net);
-	
-	// Ship it off to the kernel
-	netif_rx(skb);
-	
-	// update out statistics
-	ether_dev->stats.rx_packets++;
-	ether_dev->stats.rx_bytes += count;
-
-goon:
-	// Prep the USB to wait for another frame
-	usb_fill_bulk_urb( ether_dev->rx_urb, ether_dev->usb,
-			usb_rcvbulkpipe(ether_dev->usb, ether_dev->data_ep_in),
-			ether_dev->rx_buff, ether_dev->wMaxSegmentSize, 
-			read_bulk_callback, ether_dev );
-
-	// Give this to the USB subsystem so it can tell us
-	// when more data arrives.
-	if ( (res = usb_submit_urb(ether_dev->rx_urb, GFP_ATOMIC)) ) {
-		warn("%s failed submint rx_urb %d", __FUNCTION__, res);
-	}
-
-	// We are no longer busy, show us the frames!!!
-	ether_dev->flags &= ~CDC_ETHER_RX_BUSY;
-}
-
-static void write_bulk_callback( struct urb *urb, struct pt_regs *regs )
-{
-	ether_dev_t *ether_dev = urb->context;
-
-	// Sanity check
-	if ( !ether_dev || !(ether_dev->flags & CDC_ETHER_RUNNING) ) {
-		// We are insane!!!
-		err( "write_bulk_callback: device not running" );
-		return;
-	}
-
-	// Do we still have a valid kernel network device?
-	if ( !netif_device_present(ether_dev->net) ) {
-		// Someone killed our network interface.
-		err( "write_bulk_callback: net device not present" );
-		return;
-	}
-
-	// Hmm...  What on Earth could have happened???
-	if ( urb->status ) {
-		info("%s: TX status %d", ether_dev->net->name, urb->status);
-	}
-
-	// Update the network interface and tell it we are
-	// ready for another frame
-	ether_dev->net->trans_start = jiffies;
-	netif_wake_queue( ether_dev->net );
-}
-
-//static void intr_callback( struct urb *urb )
-//{
-//	ether_dev_t *ether_dev = urb->context;
-//	struct net_device *net;
-//	__u8	*d;
-//
-//	if ( !ether_dev )
-//		return;
-//		
-//	switch ( urb->status ) {
-//		case 0:
-//			break;
-//		case -ENOENT:
-//			return;
-//		default:
-//			info("intr status %d", urb->status);
-//	}
-//
-//	d = urb->transfer_buffer;
-//	net = ether_dev->net;
-//	if ( d[0] & 0xfc ) {
-//		ether_dev->stats.tx_errors++;
-//		if ( d[0] & TX_UNDERRUN )
-//			ether_dev->stats.tx_fifo_errors++;
-//		if ( d[0] & (EXCESSIVE_COL | JABBER_TIMEOUT) )
-//			ether_dev->stats.tx_aborted_errors++;
-//		if ( d[0] & LATE_COL )
-//			ether_dev->stats.tx_window_errors++;
-//		if ( d[0] & (NO_CARRIER | LOSS_CARRIER) )
-//			ether_dev->stats.tx_carrier_errors++;
-//	}
-//}
-
-//////////////////////////////////////////////////////////////////////////////
-// Routines for turning net traffic on and off on the USB side ///////////////
-//////////////////////////////////////////////////////////////////////////////
-
-static inline int enable_net_traffic( ether_dev_t *ether_dev )
-{
-	struct usb_device *usb = ether_dev->usb;
-
-	// Here would be the time to set the data interface to the configuration where
-	// it has two endpoints that use a protocol we can understand.
-
-	if (usb_set_interface( usb, 
-	                        ether_dev->data_bInterfaceNumber, 
-	                        ether_dev->data_bAlternateSetting_with_traffic ) )  {
-		err("usb_set_interface() failed" );
-		err("Attempted to set interface %d", ether_dev->data_bInterfaceNumber);
-		err("To alternate setting       %d", ether_dev->data_bAlternateSetting_with_traffic);
-		return -1;
-	}
-	return 0;
-}
-
-static inline void disable_net_traffic( ether_dev_t *ether_dev )
-{
-	// The thing to do is to set the data interface to the alternate setting that has
-	// no endpoints.  This is what the spec suggests.
-
-	if (ether_dev->data_interface_altset_num_without_traffic >= 0 ) {
-		if (usb_set_interface( ether_dev->usb, 
-		                        ether_dev->data_bInterfaceNumber, 
-		                        ether_dev->data_bAlternateSetting_without_traffic ) ) 	{
-			err("usb_set_interface() failed");
-		}
-	} else {
-		// Some devices just may not support this...
-		warn("No way to disable net traffic");
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Callback routines for kernel Ethernet Device //////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-static void CDCEther_tx_timeout( struct net_device *net )
-{
-	ether_dev_t *ether_dev = net->priv;
-
-	// Sanity check
-	if ( !ether_dev ) {
-		// Seems to be a case of insanity here
-		return;
-	}
-
-	// Tell syslog we are hosed.
-	warn("%s: Tx timed out.", net->name);
-	
-	// Tear the waiting frame off the list
-	ether_dev->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
-	usb_unlink_urb( ether_dev->tx_urb );
-	
-	// Update statistics
-	ether_dev->stats.tx_errors++;
-}
-
-static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net )
-{
-	ether_dev_t	*ether_dev = net->priv;
-	int 	res;
-
-	// Tell the kernel, "No more frames 'til we are done
-	// with this one.'
-	netif_stop_queue( net );
-
-	// Copy it from kernel memory to OUR memory
-	memcpy(ether_dev->tx_buff, skb->data, skb->len);
-
-	// Fill in the URB for shipping it out.
-	usb_fill_bulk_urb( ether_dev->tx_urb, ether_dev->usb,
-			usb_sndbulkpipe(ether_dev->usb, ether_dev->data_ep_out),
-			ether_dev->tx_buff, ether_dev->wMaxSegmentSize, 
-			write_bulk_callback, ether_dev );
-
-	// Tell the URB how much it will be transporting today
-	ether_dev->tx_urb->transfer_buffer_length = skb->len;
-
-	/* Deal with the zero length problem, I hope */
-	ether_dev->tx_urb->transfer_flags |= URB_ZERO_PACKET;
-	
-	// Send the URB on its merry way.
-	if ((res = usb_submit_urb(ether_dev->tx_urb, GFP_ATOMIC)))  {
-		// Hmm...  It didn't go. Tell someone...
-		warn("failed tx_urb %d", res);
-		// update some stats...
-		ether_dev->stats.tx_errors++;
-		// and tell the kernel to give us another.
-		// Maybe we'll get it right next time.
-		netif_start_queue( net );
-	} else {
-		// Okay, it went out.
-		// Update statistics
-		ether_dev->stats.tx_packets++;
-		ether_dev->stats.tx_bytes += skb->len;
-		// And tell the kernel when the last transmit occurred.
-		net->trans_start = jiffies;
-	}
-
-	// We are done with the kernel's memory
-	dev_kfree_skb(skb);
-
-	// We are done here.
-	return 0;
-}
-
-static struct net_device_stats *CDCEther_netdev_stats( struct net_device *net )
-{
-	// Easy enough!
-	return &((ether_dev_t *)net->priv)->stats;
-}
-
-static int CDCEther_open(struct net_device *net)
-{
-	ether_dev_t *ether_dev = (ether_dev_t *)net->priv;
-	int	res;
-
-	// Turn on the USB and let the packets flow!!!
-	if ( (res = enable_net_traffic( ether_dev )) ) {
-		err("%s can't enable_net_traffic() - %d", __FUNCTION__, res );
-		return -EIO;
-	}
-
-	// Prep a receive URB
-	usb_fill_bulk_urb( ether_dev->rx_urb, ether_dev->usb,
-			usb_rcvbulkpipe(ether_dev->usb, ether_dev->data_ep_in),
-			ether_dev->rx_buff, ether_dev->wMaxSegmentSize, 
-			read_bulk_callback, ether_dev );
-
-	// Put it out there so the device can send us stuff
-	if ( (res = usb_submit_urb(ether_dev->rx_urb, GFP_KERNEL)) )
-	{
-		// Hmm...  Okay...
-		warn("%s failed rx_urb %d", __FUNCTION__, res );
-	}
-
-	// Tell the kernel we are ready to start receiving from it
-	netif_start_queue( net );
-	
-	// We are up and running.
-	ether_dev->flags |= CDC_ETHER_RUNNING;
-
-	// Let's get ready to move frames!!!
-	return 0;
-}
-
-static int CDCEther_close( struct net_device *net )
-{
-	ether_dev_t	*ether_dev = net->priv;
-
-	// We are no longer running.
-	ether_dev->flags &= ~CDC_ETHER_RUNNING;
-	
-	// Tell the kernel to stop sending us stuff
-	netif_stop_queue( net );
-	
-	// If we are not already unplugged, turn off USB
-	// traffic
-	if ( !(ether_dev->flags & CDC_ETHER_UNPLUG) ) {
-		disable_net_traffic( ether_dev );
-	}
-
-	// We don't need the URBs anymore.
-	usb_unlink_urb( ether_dev->rx_urb );
-	usb_unlink_urb( ether_dev->tx_urb );
-	usb_unlink_urb( ether_dev->intr_urb );
-	
-	// That's it.  I'm done.
-	return 0;
-}
-
-static int CDCEther_ioctl( struct net_device *net, struct ifreq *rq, int cmd )
-{
-	//__u16 *data = (__u16 *)&rq->ifr_data;
-	//ether_dev_t	*ether_dev = net->priv;
-
-	// No support here yet.
-	// Do we need support???
-	switch(cmd) {
-		case SIOCDEVPRIVATE:
-			return -EOPNOTSUPP;
-		case SIOCDEVPRIVATE+1:
-			return -EOPNOTSUPP;
-		case SIOCDEVPRIVATE+2:
-			//return 0;
-			return -EOPNOTSUPP;
-		default:
-			return -EOPNOTSUPP;
-	}
-}
-
-#if 0
-static void CDC_SetEthernetPacketFilter (ether_dev_t *ether_dev)
-{
-	usb_control_msg(ether_dev->usb,
-			usb_sndctrlpipe(ether_dev->usb, 0),
-			SET_ETHERNET_PACKET_FILTER, /* request */
-			USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, /* request type */
-			cpu_to_le16(ether_dev->mode_flags), /* value */
-			cpu_to_le16((u16)ether_dev->comm_interface), /* index */
-			NULL,
-			0, /* size */
-			HZ); /* timeout */
-}
-#endif
-
-
-static void CDCEther_set_multicast( struct net_device *net )
-{
-	ether_dev_t *ether_dev = net->priv;
-	int i;
-	__u8 *buff;
-
-
-	// Tell the kernel to stop sending us frames while we get this
-	// all set up.
-//	netif_stop_queue(net);
-
-// FIXME: We hold xmit_lock. If you want to do the queue stuff you need
-//	  to enable it from a completion handler
-
-      /* Note: do not reorder, GCC is clever about common statements. */
-        if (net->flags & IFF_PROMISC) {
-                /* Unconditionally log net taps. */
-                info( "%s: Promiscuous mode enabled", net->name);
-		ether_dev->mode_flags = MODE_FLAG_PROMISCUOUS |
-			MODE_FLAG_ALL_MULTICAST |
-			MODE_FLAG_DIRECTED |
-			MODE_FLAG_BROADCAST |
-			MODE_FLAG_MULTICAST;
-        } else if (net->mc_count > ether_dev->wNumberMCFilters) {
-                /* Too many to filter perfectly -- accept all multicasts. */
-		info("%s: set too many MC filters, using allmulti", net->name);
-		ether_dev->mode_flags = MODE_FLAG_ALL_MULTICAST |
-			MODE_FLAG_DIRECTED |
-			MODE_FLAG_BROADCAST |
-			MODE_FLAG_MULTICAST;
-	} else if (net->flags & IFF_ALLMULTI) {
-                /* Filter in software */
-		info("%s: using allmulti", net->name);
-		ether_dev->mode_flags = MODE_FLAG_ALL_MULTICAST |
-			MODE_FLAG_DIRECTED |
-			MODE_FLAG_BROADCAST |
-			MODE_FLAG_MULTICAST;
-        } else {
-		/* do multicast filtering in hardware */
-                struct dev_mc_list *mclist;
-		info("%s: set multicast filters", net->name);
-		ether_dev->mode_flags = MODE_FLAG_ALL_MULTICAST |
-			MODE_FLAG_DIRECTED |
-			MODE_FLAG_BROADCAST |
-			MODE_FLAG_MULTICAST;
-		buff = kmalloc(6 * net->mc_count, GFP_ATOMIC);
-                for (i = 0, mclist = net->mc_list;
-		     mclist && i < net->mc_count;
-                     i++, mclist = mclist->next) {
-			memcpy(&mclist->dmi_addr, &buff[i * 6], 6);
-		}
-#if 0
-		usb_control_msg(ether_dev->usb,
-// FIXME: We hold a spinlock. You must not use a synchronous API
-				usb_sndctrlpipe(ether_dev->usb, 0),
-				SET_ETHERNET_MULTICAST_FILTER, /* request */
-				USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, /* request type */
-				cpu_to_le16(net->mc_count), /* value */
-				cpu_to_le16((u16)ether_dev->comm_interface), /* index */
-				buff,
-				(6* net->mc_count), /* size */
-				HZ); /* timeout */
-#endif
-		kfree(buff);
-	}
-
-#if 0 
-	CDC_SetEthernetPacketFilter(ether_dev);
-#endif	
-        // Tell the kernel to start giving frames to us again.
-//	netif_wake_queue(net);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Routines used to parse out the Functional Descriptors /////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-static int parse_header_functional_descriptor( int *bFunctionLength, 
-                                               int bDescriptorType, 
-                                               int bDescriptorSubtype,
-                                               unsigned char *data,
-                                               ether_dev_t *ether_dev,
-                                               int *requirements )
-{
-	// Check to make sure we haven't seen one of these already.
-	if ( (~*requirements) & REQ_HDR_FUNC_DESCR ) {
-		err( "Multiple Header Functional Descriptors found." );
-		return -1;
-	}
-	
-	// Is it the right size???
-	if (*bFunctionLength != 5) {
-		info( "Invalid length in Header Functional Descriptor" );
-		// This is a hack to get around a particular device (NO NAMES)
-		// It has this function length set to the length of the
-		// whole class-specific descriptor
-		*bFunctionLength = 5;
-	}
-	
-	// Nothing extremely useful here.
-	// We'll keep it for posterity
-	ether_dev->bcdCDC = data[0] + (data[1] << 8);
-	dbg( "Found Header descriptor, CDC version %x", ether_dev->bcdCDC);
-
-	// We've seen one of these
-	*requirements &= ~REQ_HDR_FUNC_DESCR;
-	
-	// It's all good.
-	return 0;
-}
-
-static int parse_union_functional_descriptor( int *bFunctionLength, 
-                                              int bDescriptorType, 
-                                              int bDescriptorSubtype,
-                                              unsigned char *data,
-                                              ether_dev_t *ether_dev,
-                                              int *requirements )
-{
-	// Check to make sure we haven't seen one of these already.
-	if ( (~*requirements) & REQ_UNION_FUNC_DESCR ) {
-		err( "Multiple Union Functional Descriptors found." );
-		return -1;
-	}
-
-	// Is it the right size?
-	if (*bFunctionLength != 5) {
-		// It is NOT the size we expected.
-		err( "Unsupported length in Union Functional Descriptor" );
-		return -1;
-	}
-	
-	// Sanity check of sorts
-	if (ether_dev->comm_interface != data[0]) {
-		// This tells us that we are chasing the wrong comm
-		// interface or we are crazy or something else weird.
-		if (ether_dev->comm_interface == data[1]) {
-			info( "Probably broken Union descriptor, fudging data interface" );
-			// We'll need this in a few microseconds, 
-			// so guess here, and hope for the best
-			ether_dev->data_interface = data[0];
-		} else {
-			err( "Union Functional Descriptor is broken beyond repair" );
-			return -1;
-		}
-	} else{ // Descriptor is OK
-       		// We'll need this in a few microseconds!
-		ether_dev->data_interface = data[1];
-	}
-
-	// We've seen one of these now.
-	*requirements &= ~REQ_UNION_FUNC_DESCR;
-	
-	// Done
-	return 0;
-}
-
-static int parse_ethernet_functional_descriptor( int *bFunctionLength, 
-                                                 int bDescriptorType, 
-                                                 int bDescriptorSubtype,
-                                                 unsigned char *data,
-                                                 ether_dev_t *ether_dev,
-                                                 int *requirements )
-{
-	// Check to make sure we haven't seen one of these already.
-	if ( (~*requirements) & REQ_ETH_FUNC_DESCR ) {
-		err( "Multiple Ethernet Functional Descriptors found." );
-		return -1;
-	}
-	
-	// Is it the right size?
-	if (*bFunctionLength != 13) {
-		err( "Invalid length in Ethernet Networking Functional Descriptor" );
-		return -1;
-	}
-	
-	// Lots of goodies from this one.  They are all important.
-	ether_dev->iMACAddress = data[0];
-	ether_dev->bmEthernetStatistics = data[1] + (data[2] << 8) + (data[3] << 16) + (data[4] << 24);
-	ether_dev->wMaxSegmentSize = data[5] + (data[6] << 8);
-	ether_dev->wNumberMCFilters = (data[7] + (data[8] << 8)) & 0x00007FFF;
-	if (ether_dev->wNumberMCFilters > multicast_filter_limit) {
-		ether_dev->wNumberMCFilters = multicast_filter_limit;
-		}	
-	ether_dev->bNumberPowerFilters = data[9];
-	
-	// We've seen one of these now.
-	*requirements &= ~REQ_ETH_FUNC_DESCR;
-	
-	// That's all she wrote.
-	return 0;
-}
-
-static int parse_protocol_unit_functional_descriptor( int *bFunctionLength, 
-                                                      int bDescriptorType, 
-                                                      int bDescriptorSubtype,
-                                                      unsigned char *data,
-                                                      ether_dev_t *ether_dev,
-                                                      int *requirements )
-{
-	// There should only be one type if we are sane
-	if (bDescriptorType != CS_INTERFACE) {
-		info( "Invalid bDescriptorType found." );
-		return -1;
-	}
-
-	// The Subtype tells the tale.
-	switch (bDescriptorSubtype){
-		case 0x00:	// Header Functional Descriptor
-			return parse_header_functional_descriptor( bFunctionLength,
-			                                           bDescriptorType,
-			                                           bDescriptorSubtype,
-			                                           data,
-			                                           ether_dev,
-			                                           requirements );
-			break;
-		case 0x06:	// Union Functional Descriptor
-			return parse_union_functional_descriptor( bFunctionLength,
-			                                          bDescriptorType,
-			                                          bDescriptorSubtype,
-			                                          data,
-			                                          ether_dev,
-			                                          requirements );
-			break;
-		case 0x0F:	// Ethernet Networking Functional Descriptor
-			return parse_ethernet_functional_descriptor( bFunctionLength,
-			                                             bDescriptorType,
-			                                             bDescriptorSubtype,
-			                                             data,
-			                                             ether_dev,
-			                                             requirements );
-			break;
-		default:	// We don't support this at this time...
-			// However that doesn't necessarily indicate an error.
-			dbg( "Unexpected header type %x:", bDescriptorSubtype );
-			return 0;
-	}
-	// How did we get here???
-	return -1;
-}
-
-static int parse_ethernet_class_information( unsigned char *data, int length, ether_dev_t *ether_dev )
-{
-	int loc = 0;
-	int rc;
-	int bFunctionLength;
-	int bDescriptorType;
-	int bDescriptorSubtype;
-	int requirements = REQUIREMENTS_TOTAL;
-
-	// As long as there is something here, we will try to parse it
-	while (loc < length) {
-		// Length
-		bFunctionLength = data[loc];
-		loc++;
-		
-		// Type
-		bDescriptorType = data[loc];
-		loc++;
-		
-		// Subtype
-		bDescriptorSubtype = data[loc];
-		loc++;
-		
-		// ship this off to be processed elsewhere.
-		rc = parse_protocol_unit_functional_descriptor( &bFunctionLength, 
-		                                                bDescriptorType, 
-		                                                bDescriptorSubtype, 
-		                                                &data[loc],
-		                                                ether_dev,
-		                                                &requirements );
-		// Did it process okay?
-		if (rc)	{
-			// Something was hosed somewhere.
-			// No need to continue;
-			err("Bad descriptor parsing: %x", rc );
-			return -1;
-		}
-		// We have already taken three bytes.
-		loc += (bFunctionLength - 3);
-	}
-	// Check to see if we got everything we need.
-	if (requirements) {
-		// We missed some of the requirements...
-		err( "Not all required functional descriptors present 0x%08X", requirements );
-		return -1;
-	}
-	// We got everything.
-	return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Routine to check for the existence of the Functional Descriptors //////////
-//////////////////////////////////////////////////////////////////////////////
-
-static int find_and_parse_ethernet_class_information( struct usb_device *device, ether_dev_t *ether_dev )
-{
-	struct usb_host_config *conf = NULL;
-	struct usb_interface *comm_intf_group = NULL;
-	struct usb_host_interface *comm_intf = NULL;
-	int rc = -1;
-	// The assumption here is that find_ethernet_comm_interface
-	// and find_valid_configuration 
-	// have already filled in the information about where to find
-	// the a valid commication interface.
-
-	conf = &( device->config[ether_dev->configuration_num] );
-	comm_intf_group = &( conf->interface[ether_dev->comm_interface] );
-	comm_intf = &( comm_intf_group->altsetting[ether_dev->comm_interface_altset_num] );
-	// Let's check and see if it has the extra information we need...
-
-	if (comm_intf->extralen > 0) {
-		// This is where the information is SUPPOSED to be.
-		rc = parse_ethernet_class_information( comm_intf->extra, comm_intf->extralen, ether_dev );
-	} else if (conf->extralen > 0) {
-		// This is a hack.  The spec says it should be at the interface 
-		// location checked above.  However I have seen it here also.
-		// This is the same device that requires the functional descriptor hack above
-		warn( "Ethernet information found at device configuration.  This is broken." );
-		rc = parse_ethernet_class_information( conf->extra, conf->extralen, ether_dev );
-	} else 	{
-		// I don't know where else to look.
-		warn( "No ethernet information found." );
-		rc = -1;
-	}
-	return rc;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Routines to verify the data interface /////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-static int get_data_interface_endpoints( struct usb_device *device, ether_dev_t *ether_dev )
-{
-	struct usb_host_config *conf = NULL;
-	struct usb_interface *data_intf_group = NULL;
-	struct usb_host_interface *data_intf = NULL;
-	
-	// Walk through and get to the data interface we are checking.
-	conf = &( device->config[ether_dev->configuration_num] );
-	data_intf_group = &( conf->interface[ether_dev->data_interface] );
-	data_intf = &( data_intf_group->altsetting[ether_dev->data_interface_altset_num_with_traffic] );
-
-	// Start out assuming we won't find anything we can use
-	ether_dev->data_ep_in = 0;
-	ether_dev->data_ep_out = 0;
-	
-	// If these are not BULK endpoints, we don't want them
-	if ( data_intf->endpoint[0].desc.bmAttributes != 0x02 ) {
-		return -1;
-	} if ( data_intf->endpoint[1].desc.bmAttributes != 0x02 ) {
-		return -1;
-	}
-
-	// Check the first endpoint to see if it is IN or OUT
-	if ( data_intf->endpoint[0].desc.bEndpointAddress & 0x80 ) {
-		// This endpoint is IN
-		ether_dev->data_ep_in = data_intf->endpoint[0].desc.bEndpointAddress & 0x7F;
-	} else {
-		// This endpoint is OUT
-		ether_dev->data_ep_out = data_intf->endpoint[0].desc.bEndpointAddress & 0x7F;
-		ether_dev->data_ep_out_size = data_intf->endpoint[0].desc.wMaxPacketSize;
-	}
-
-	// Check the second endpoint to see if it is IN or OUT
-	if ( data_intf->endpoint[1].desc.bEndpointAddress & 0x80 ) {
-		// This endpoint is IN
-		ether_dev->data_ep_in = data_intf->endpoint[1].desc.bEndpointAddress & 0x7F;
-	} else	{
-		// This endpoint is OUT
-		ether_dev->data_ep_out = data_intf->endpoint[1].desc.bEndpointAddress & 0x7F;
-		ether_dev->data_ep_out_size = data_intf->endpoint[1].desc.wMaxPacketSize;
-	}
-	
-	// Now make sure we got both an IN and an OUT
-	if (ether_dev->data_ep_in && ether_dev->data_ep_out) {
-		// We did get both, we are in good shape...
-		info( "detected BULK OUT packets of size %d", ether_dev->data_ep_out_size );
-		return 0;
-	}
-	return -1;
-}
-
-static int verify_ethernet_data_interface( struct usb_device *device, ether_dev_t *ether_dev )
-{
-	struct usb_host_config *conf = NULL;
-	struct usb_interface *data_intf_group = NULL;
-	struct usb_interface_descriptor *data_intf = NULL;
-	int rc = -1;
-	int status;
-	int altset_num;
-
-	// The assumption here is that parse_ethernet_class_information()
-	// and find_valid_configuration() 
-	// have already filled in the information about where to find
-	// a data interface
-	conf = &( device->config[ether_dev->configuration_num] );
-	data_intf_group = &( conf->interface[ether_dev->data_interface] );
-
-	// start out assuming we won't find what we are looking for.
-	ether_dev->data_interface_altset_num_with_traffic = -1;
-	ether_dev->data_bAlternateSetting_with_traffic = -1;
-	ether_dev->data_interface_altset_num_without_traffic = -1;
-	ether_dev->data_bAlternateSetting_without_traffic = -1;
-
-	// Walk through every possible setting for this interface until
-	// we find what makes us happy.
-	for ( altset_num = 0; altset_num < data_intf_group->num_altsetting; altset_num++ ) {
-		data_intf = &( data_intf_group->altsetting[altset_num].desc );
-
-		// Is this a data interface we like?
-		if ( ( data_intf->bInterfaceClass == 0x0A )
-		   && ( data_intf->bInterfaceSubClass == 0x00 )
-		   && ( data_intf->bInterfaceProtocol == 0x00 ) ) {
-			if ( data_intf->bNumEndpoints == 2 ) {
-				// We are required to have one of these.
-				// An interface with 2 endpoints to send Ethernet traffic back and forth
-				// It actually may be possible that the device might only
-				// communicate in a vendor specific manner.
-				// That would not be very nice.
-				// We can add that one later.
-				ether_dev->data_bInterfaceNumber = data_intf->bInterfaceNumber;
-				ether_dev->data_interface_altset_num_with_traffic = altset_num;
-				ether_dev->data_bAlternateSetting_with_traffic = data_intf->bAlternateSetting;
-				status = get_data_interface_endpoints( device, ether_dev );
-				if (!status) {
-					rc = 0;
-				}
-			}
-			if ( data_intf->bNumEndpoints == 0 ) {
-				// According to the spec we are SUPPOSED to have one of these
-				// In fact the device is supposed to come up in this state.
-				// However, I have seen a device that did not have such an interface.
-				// So it must be just optional for our driver...
-				ether_dev->data_bInterfaceNumber = data_intf->bInterfaceNumber;
-				ether_dev->data_interface_altset_num_without_traffic = altset_num;
-				ether_dev->data_bAlternateSetting_without_traffic = data_intf->bAlternateSetting;
-			}
-		}
-	}
-	return rc;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Routine to find a communication interface /////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-static int find_ethernet_comm_interface( struct usb_device *device, ether_dev_t *ether_dev )
-{
-	struct usb_host_config *conf = NULL;
-	struct usb_interface *comm_intf_group = NULL;
-	struct usb_interface_descriptor *comm_intf = NULL;
-	int intf_num;
-	int altset_num;
-	int rc;
-
-	conf = &( device->config[ether_dev->configuration_num] );
-
-	// We need to check and see if any of these interfaces are something we want.
-	// Walk through each interface one at a time
-	for ( intf_num = 0; intf_num < conf->desc.bNumInterfaces; intf_num++ ) {
-		comm_intf_group = &( conf->interface[intf_num] );
-		// Now for each of those interfaces, check every possible
-		// alternate setting.
-		for ( altset_num = 0; altset_num < comm_intf_group->num_altsetting; altset_num++ ) {
-			comm_intf = &( comm_intf_group->altsetting[altset_num].desc);
-
-			// Is this a communication class of interface of the
-			// ethernet subclass variety.
-			if ( ( comm_intf->bInterfaceClass == 0x02 )
-			   && ( comm_intf->bInterfaceSubClass == 0x06 )
-			   && ( comm_intf->bInterfaceProtocol == 0x00 ) ) {
-				if ( comm_intf->bNumEndpoints == 1 ) {
-					// Good, we found one, we will try this one
-					// Fill in the structure...
-					ether_dev->comm_interface = intf_num;
-					ether_dev->comm_bInterfaceNumber = comm_intf->bInterfaceNumber;
-					ether_dev->comm_interface_altset_num = altset_num;
-					ether_dev->comm_bAlternateSetting = comm_intf->bAlternateSetting;
-
-					// Look for the Ethernet Functional Descriptors
-					rc = find_and_parse_ethernet_class_information( device, ether_dev );
-					if (rc) {
-						// Nope this was no good after all.
-						continue;
-					}
-
-					// Check that we really can talk to the data
-					// interface 
-					// This includes # of endpoints, protocols,
-					// etc.
-					rc = verify_ethernet_data_interface( device, ether_dev );
-					if (rc)	{
-						// We got something we didn't like
-						continue;
-					}
-					// This communication interface seems to give us everything
-					// we require.  We have all the ethernet info we need.
-					// Let's get out of here and go home right now.
-					return 0;
-				} else {
-                                        // bNumEndPoints != 1
-					// We found an interface that had the wrong number of 
-					// endpoints but would have otherwise been okay
-				} // end bNumEndpoints check.
-			} // end interface specifics check.
-		} // end for altset_num
-	} // end for intf_num
-	return -1;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Routine to go through all configurations and find one that ////////////////
-// is an Ethernet Networking Device //////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-static int find_valid_configuration( struct usb_device *device, ether_dev_t *ether_dev )
-{
-	struct usb_host_config *conf = NULL;
-	int conf_num;
-	int rc;
-
-	// We will try each and every possible configuration
-	for ( conf_num = 0; conf_num < device->descriptor.bNumConfigurations; conf_num++ ) {
-		conf = &( device->config[conf_num] );
-
-		// Our first requirement : 2 interfaces
-		if ( conf->desc.bNumInterfaces != 2 ) {
-			// I currently don't know how to handle devices with any number of interfaces
-			// other than 2.
-			continue;
-		}
-
-		// This one passed our first check, fill in some 
-		// useful data
-		ether_dev->configuration_num = conf_num;
-		ether_dev->bConfigurationValue = conf->desc.bConfigurationValue;
-
-		// Now run it through the ringers and see what comes
-		// out the other side.
-		rc = find_ethernet_comm_interface( device, ether_dev );
-
-		// Check if we found an ethernet Communcation Device
-		if ( !rc ) {
-			// We found one.
-			return 0;
-		}
-	}
-	// None of the configurations suited us.
-	return -1;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Routine that checks a given configuration to see if any driver ////////////
-// has claimed any of the devices interfaces /////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-static int check_for_claimed_interfaces( struct usb_host_config *config )
-{
-	struct usb_interface *comm_intf_group;
-	int intf_num;
-
-	// Go through all the interfaces and make sure none are 
-	// claimed by anybody else.
-	for ( intf_num = 0; intf_num < config->desc.bNumInterfaces; intf_num++ ) {
-		comm_intf_group = &( config->interface[intf_num] );
-		if ( usb_interface_claimed( comm_intf_group ) )	{
-			// Somebody has beat us to this guy.
-			// We can't change the configuration out from underneath of whoever
-			// is using this device, so we will go ahead and give up.
-			return -1;
-		}
-	}
-	// We made it all the way through.
-	// I guess no one has claimed any of these interfaces.
-	return 0;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Routines to ask for and set the kernel network interface's MAC address ////
-// Used by driver's probe routine ////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-static inline unsigned char hex2dec( unsigned char digit )
-{
-	// Is there a standard way to do this???
-	// I have written this code TOO MANY times.
-	if ( (digit >= '0') && (digit <= '9') )	{
-		return (digit - '0');
-	}
-	if ( (digit >= 'a') && (digit <= 'f') )	{
-		return (digit - 'a' + 10);
-	}
-	if ( (digit >= 'A') && (digit <= 'F') )	{
-		return (digit - 'A' + 10);
-	}
-	return 0;
-}
-
-static void set_ethernet_addr( ether_dev_t *ether_dev )
-{
-	unsigned char	mac_addr[6];
-	int		i;
-	int 		len;
-	unsigned char	buffer[13];
-
-	// Let's assume we don't get anything...
-	mac_addr[0] = 0x00;
-	mac_addr[1] = 0x00;
-	mac_addr[2] = 0x00;
-	mac_addr[3] = 0x00;
-	mac_addr[4] = 0x00;
-	mac_addr[5] = 0x00;
-
-	// Let's ask the device...
-	len = usb_string(ether_dev->usb, ether_dev->iMACAddress, buffer, 13);
-
-	// Sanity check!
-	if (len != 12)	{
-		// You gotta love failing sanity checks
-		err("Attempting to get MAC address returned %d bytes", len);
-		return;
-	}
-
-	// Fill in the mac_addr
-	for (i = 0; i < 6; i++)	{
-		mac_addr[i] = ( hex2dec( buffer[2 * i] ) << 4 ) + hex2dec( buffer[2 * i + 1] );
-	}
-
-	// Now copy it over to the kernel's network driver.
-	memcpy( ether_dev->net->dev_addr, mac_addr, sizeof(mac_addr) );
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Routine to print to syslog information about the driver ///////////////////
-// Used by driver's probe routine ////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-static void log_device_info(ether_dev_t *ether_dev)
-{
-	int len;
-	int string_num;
-	unsigned char *manu = NULL;
-	unsigned char *prod = NULL;
-	unsigned char *sern = NULL;
-	unsigned char *mac_addr;
-
-	manu = kmalloc(256, GFP_KERNEL);
-	prod = kmalloc(256, GFP_KERNEL);
-	sern = kmalloc(256, GFP_KERNEL);
-	if (!manu || !prod || !sern) {
-		dbg("no mem for log_device_info");
-		goto fini;
-	}
-
-	// Default empty strings in case we don't find a real one
-	manu[0] = 0x00;
-	prod[0] = 0x00;
-	sern[0] = 0x00;
-
-	// Try to get the device Manufacturer
-	string_num = ether_dev->usb->descriptor.iManufacturer;
-	if (string_num)	{
-		// Put it into its buffer
-		len = usb_string(ether_dev->usb, string_num, manu, 255);
-		// Just to be safe
-		manu[len] = 0x00;
-	}
-
-	// Try to get the device Product Name
-	string_num = ether_dev->usb->descriptor.iProduct;
-	if (string_num)	{
-		// Put it into its buffer
-		len = usb_string(ether_dev->usb, string_num, prod, 255);
-		// Just to be safe
-		prod[len] = 0x00;
-	}
-
-	// Try to get the device Serial Number
-	string_num = ether_dev->usb->descriptor.iSerialNumber;
-	if (string_num)	{
-		// Put it into its buffer
-		len = usb_string(ether_dev->usb, string_num, sern, 255);
-		// Just to be safe
-		sern[len] = 0x00;
-	}
-
-	// This makes it easier for us to print
-	mac_addr = ether_dev->net->dev_addr;
-
-	// Now send everything we found to the syslog
-	info( "%s: %s %s %s %02X:%02X:%02X:%02X:%02X:%02X", 
-	      ether_dev->net->name, manu, prod, sern, mac_addr[0], 
-	      mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], 
-	      mac_addr[5] );
-fini:
-	kfree(manu);
-	kfree(prod);
-	kfree(sern);
-}
-
-/* Forward declaration */
-static struct usb_driver CDCEther_driver ;
-
-//////////////////////////////////////////////////////////////////////////////
-// Module's probe routine ////////////////////////////////////////////////////
-// claims interfaces if they are for an Ethernet CDC /////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-static int CDCEther_probe( struct usb_interface *intf,
-			   const struct usb_device_id *id)
-{
-	struct usb_device	*usb = interface_to_usbdev(intf);
-	struct net_device	*net;
-	ether_dev_t		*ether_dev;
-	int 			rc;
-
-	// First we should check the active configuration to see if 
-	// any other driver has claimed any of the interfaces.
-	if ( check_for_claimed_interfaces( usb->actconfig ) ) {
-		// Someone has already put there grubby paws on this device.
-		// We don't want it now...
-		return -ENODEV;
-	}
-
-	// We might be finding a device we can use.
-	// We all go ahead and allocate our storage space.
-	// We need to because we have to start filling in the data that
-	// we are going to need later.
-	if(!(ether_dev = kmalloc(sizeof(ether_dev_t), GFP_KERNEL))) {
-		err("out of memory allocating device structure");
-		return -ENOMEM;
-	}
-
-	// Zero everything out.
-	memset(ether_dev, 0, sizeof(ether_dev_t));
-
-	ether_dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!ether_dev->rx_urb) {
-		kfree(ether_dev);
-		return -ENOMEM;
-	}
-	ether_dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!ether_dev->tx_urb) {
-		usb_free_urb(ether_dev->rx_urb);
-		kfree(ether_dev);
-		return -ENOMEM;
-	}
-	ether_dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!ether_dev->intr_urb) {
-		usb_free_urb(ether_dev->tx_urb);
-		usb_free_urb(ether_dev->rx_urb);
-		kfree(ether_dev);
-		return -ENOMEM;
-	}
-
-	// Let's see if we can find a configuration we can use.
-	rc = find_valid_configuration( usb, ether_dev );
-	if (rc)	{
-		// Nope we couldn't find one we liked.
-		// This device was not meant for us to control.
-		goto error_all;
-	}
-
-	// Now that we FOUND a configuration. let's try to make the
-	// device go into it.
-	if ( usb_set_configuration( usb, ether_dev->bConfigurationValue ) ) {
-		err("usb_set_configuration() failed");
-		goto error_all;
-	}
-
-	// Now set the communication interface up as required.
-	if (usb_set_interface(usb, ether_dev->comm_bInterfaceNumber, ether_dev->comm_bAlternateSetting)) {
-		err("usb_set_interface() failed");
-		goto error_all;
-	}
-
-	// Only turn traffic on right now if we must...
-	if (ether_dev->data_interface_altset_num_without_traffic >= 0)	{
-		// We found an alternate setting for the data
-		// interface that allows us to turn off traffic.
-		// We should use it.
-		if (usb_set_interface( usb,
-		                       ether_dev->data_bInterfaceNumber,
-		                       ether_dev->data_bAlternateSetting_without_traffic)) {
-			err("usb_set_interface() failed");
-			goto error_all;
-		}
-	} else	{
-		// We didn't find an alternate setting for the data
-		// interface that would let us turn off traffic.
-		// Oh well, let's go ahead and do what we must...
-		if (usb_set_interface( usb,
-		                       ether_dev->data_bInterfaceNumber,
-		                       ether_dev->data_bAlternateSetting_with_traffic)) {
-			err("usb_set_interface() failed");
-			goto error_all;
-		}
-	}
-
-	// Now we need to get a kernel Ethernet interface.
-	net = alloc_etherdev(0);
-	if ( !net ) {
-		// Hmm...  The kernel is not sharing today...
-		// Fine, we didn't want it anyway...
-		err( "Unable to initialize ethernet device" );
-		goto error_all;
-	}
-
-	// Now that we have an ethernet device, let's set it up
-	// (And I don't mean "set [it] up the bomb".)
-	net->priv = ether_dev;
-	SET_MODULE_OWNER(net);
-	net->open = CDCEther_open;
-	net->stop = CDCEther_close;
-	net->watchdog_timeo = CDC_ETHER_TX_TIMEOUT;
-	net->tx_timeout = CDCEther_tx_timeout;   // TX timeout function
-	net->do_ioctl = CDCEther_ioctl;
-	net->hard_start_xmit = CDCEther_start_xmit;
-	net->set_multicast_list = CDCEther_set_multicast;
-	net->get_stats = CDCEther_netdev_stats;
-	net->mtu = ether_dev->wMaxSegmentSize - 14;
-
-	// We'll keep track of this information for later...
-	ether_dev->usb = usb;
-	ether_dev->net = net;
-
-	// and don't forget the MAC address.
-	set_ethernet_addr( ether_dev );
-
-	// Send a message to syslog about what we are handling
-	log_device_info( ether_dev );
-
-	// I claim this interface to be a CDC Ethernet Networking device
-	usb_driver_claim_interface( &CDCEther_driver,
-	                            &(usb->config[ether_dev->configuration_num].interface[ether_dev->comm_interface]),
-	                            ether_dev );
-	// I claim this interface to be a CDC Ethernet Networking device
-	usb_driver_claim_interface( &CDCEther_driver,
-	                            &(usb->config[ether_dev->configuration_num].interface[ether_dev->data_interface]),
-	                            ether_dev );
-
-	// Does this REALLY do anything???
-	usb_get_dev( usb );
-
-	// TODO - last minute HACK
-	ether_dev->comm_ep_in = 5;
-
-	if (register_netdev(net) != 0) {
-		usb_put_dev(usb);
-		goto out;
-	}
-
-/* FIXME!!! This driver needs to be fixed to work with the new USB interface logic
- * this is not the correct thing to be doing here, we need to set the interface
- * driver specific data field.
- */
-	// Okay, we are finally done...
-	return 0;
-
-
-out:
-	usb_driver_release_interface( &CDCEther_driver, 
-	                              &(usb->config[ether_dev->configuration_num].interface[ether_dev->comm_interface]) );
-
-	usb_driver_release_interface( &CDCEther_driver, 
-	                              &(usb->config[ether_dev->configuration_num].interface[ether_dev->data_interface]) );
-	// bailing out with our tail between our knees
-error_all:
-	usb_free_urb(ether_dev->tx_urb);
-	usb_free_urb(ether_dev->rx_urb);
-	usb_free_urb(ether_dev->intr_urb);
-	kfree( ether_dev );
-	return -EIO;
-}
-
-
-//////////////////////////////////////////////////////////////////////////////
-// Module's disconnect routine ///////////////////////////////////////////////
-// Called when the driver is unloaded or the device is unplugged /////////////
-// (Whichever happens first assuming the driver suceeded at its probe) ///////
-//////////////////////////////////////////////////////////////////////////////
-
-static void CDCEther_disconnect( struct usb_interface *intf )
-{
-	ether_dev_t *ether_dev = usb_get_intfdata(intf);
-	struct usb_device *usb;
-
-	usb_set_intfdata(intf, NULL);
-
-	// Sanity check!!!
-	if ( !ether_dev || !ether_dev->usb ) {
-		// We failed.  We are insane!!!
-		warn("unregistering non-existant device");
-		return;
-	}
-
-	// Make sure we fail the sanity check if we try this again.
-	ether_dev->usb = NULL;
-	
-	usb = interface_to_usbdev(intf);
-
-	// It is possible that this function is called before
-	// the "close" function.
-	// This tells the close function we are already disconnected
-	ether_dev->flags |= CDC_ETHER_UNPLUG;
-	
-	// We don't need the network device any more
-	unregister_netdev( ether_dev->net );
-	
-	// For sanity checks
-	ether_dev->net = NULL;
-
-	// I ask again, does this do anything???
-	usb_put_dev( usb );
-
-	// We are done with this interface
-	usb_driver_release_interface( &CDCEther_driver, 
-	                              &(usb->config[ether_dev->configuration_num].interface[ether_dev->comm_interface]) );
-
-	// We are done with this interface too
-	usb_driver_release_interface( &CDCEther_driver, 
-	                              &(usb->config[ether_dev->configuration_num].interface[ether_dev->data_interface]) );
-
-	// No more tied up kernel memory
-	usb_free_urb(ether_dev->intr_urb);
-	usb_free_urb(ether_dev->rx_urb);
-	usb_free_urb(ether_dev->rx_urb);
-	kfree( ether_dev );
-	
-	// This does no good, but it looks nice!
-	ether_dev = NULL;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Driver info ///////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-static struct usb_driver CDCEther_driver = {
-	.owner =	THIS_MODULE,
-	.name =		"CDCEther",
-	.probe =	CDCEther_probe,
-	.disconnect =	CDCEther_disconnect,
-	.id_table =	CDCEther_ids,
-};
-
-//////////////////////////////////////////////////////////////////////////////
-// init and exit routines called when driver is installed and uninstalled ////
-//////////////////////////////////////////////////////////////////////////////
-
-int __init CDCEther_init(void)
-{
-	info( "%s", version );
-	return usb_register( &CDCEther_driver );
-}
-
-void __exit CDCEther_exit(void)
-{
-	usb_deregister( &CDCEther_driver );
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Module info ///////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-module_init( CDCEther_init );
-module_exit( CDCEther_exit );
-
-MODULE_AUTHOR("Brad Hards and another");
-MODULE_DESCRIPTION("USB CDC Ethernet driver");
-MODULE_LICENSE("GPL");
-
-MODULE_PARM (multicast_filter_limit, "i");
-MODULE_PARM_DESC (multicast_filter_limit, "CDCEther maximum number of filtered multicast addresses");
-
-MODULE_DEVICE_TABLE (usb, CDCEther_ids);
-
-//////////////////////////////////////////////////////////////////////////////
-// End of file ///////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
diff -urN linux-2.5.73-bk2/drivers/usb/net/cdc-ether.h linux-2.5.73-bk3/drivers/usb/net/cdc-ether.h
--- linux-2.5.73-bk2/drivers/usb/net/cdc-ether.h	2003-06-22 11:32:35.000000000 -0700
+++ linux-2.5.73-bk3/drivers/usb/net/cdc-ether.h	1969-12-31 16:00:00.000000000 -0800
@@ -1,98 +0,0 @@
-// Portions of this file taken from 
-// Petko Manolov - Petkan (petkan@dce.bg)
-// from his driver pegasus.h
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#define CS_INTERFACE			0x24
-
-#define	CDC_ETHER_MAX_MTU		1536
-
-#define	CDC_ETHER_PRESENT		0x00000001
-#define	CDC_ETHER_RUNNING		0x00000002
-#define	CDC_ETHER_TX_BUSY		0x00000004
-#define	CDC_ETHER_RX_BUSY		0x00000008
-#define	CDC_ETHER_UNPLUG		0x00000040
-
-#define	CDC_ETHER_TX_TIMEOUT	(HZ*10)
-
-#define	TX_UNDERRUN				0x80
-#define	EXCESSIVE_COL			0x40
-#define	LATE_COL				0x20
-#define	NO_CARRIER				0x10
-#define	LOSS_CARRIER			0x08
-#define	JABBER_TIMEOUT			0x04
-
-#define	CDC_ETHER_REQT_READ		0xc0
-#define	CDC_ETHER_REQT_WRITE	0x40
-#define	CDC_ETHER_REQ_GET_REGS	0xf0
-#define	CDC_ETHER_REQ_SET_REGS	0xf1
-#define	CDC_ETHER_REQ_SET_REG	PIPERIDER_REQ_SET_REGS
-#define	L1_ALIGN(x)		x __attribute__((aligned(L1_CACHE_BYTES)))
-
-#define MODE_FLAG_PROMISCUOUS   (1<<0)
-#define MODE_FLAG_ALL_MULTICAST (1<<1)
-#define MODE_FLAG_DIRECTED      (1<<2)
-#define MODE_FLAG_BROADCAST     (1<<3)
-#define MODE_FLAG_MULTICAST     (1<<4)
-
-#define SET_ETHERNET_MULTICAST_FILTER    0x40
-#define SET_ETHERNET_PACKET_FILTER       0x43
-
-typedef struct _ether_dev_t {
-	struct usb_device	*usb;
-	struct net_device	*net;
-	struct net_device_stats	stats;
-	unsigned		flags;
-	int			configuration_num;
-	int			bConfigurationValue;
-	int			comm_interface;
-	int			comm_bInterfaceNumber;
-	int			comm_interface_altset_num;
-	int			comm_bAlternateSetting;
-	int			comm_ep_in;
-	int			data_interface;
-	int			data_bInterfaceNumber;
-	int			data_interface_altset_num_with_traffic;
-	int			data_bAlternateSetting_with_traffic;
-	int			data_interface_altset_num_without_traffic;
-	int			data_bAlternateSetting_without_traffic;
-	int			data_ep_in;
-	int			data_ep_out;
-	int			data_ep_out_size;
-	__u16			bcdCDC;
-	__u8			iMACAddress;
-	__u32			bmEthernetStatistics;
-	__u16			wMaxSegmentSize;
-	__u16                   mode_flags;
-	__u16			wNumberMCFilters;
-	__u8			bNumberPowerFilters;
-	int			intr_interval;
-	struct urb		*rx_urb, *tx_urb, *intr_urb;
-	unsigned char		L1_ALIGN(rx_buff[CDC_ETHER_MAX_MTU]);
-	unsigned char		L1_ALIGN(tx_buff[CDC_ETHER_MAX_MTU]);
-	unsigned char		L1_ALIGN(intr_buff[8]);
-} ether_dev_t;
-
-#define REQ_HDR_FUNC_DESCR	0x0001
-#define REQ_UNION_FUNC_DESCR	0x0002
-#define REQ_ETH_FUNC_DESCR	0x0004
-#define REQUIREMENTS_TOTAL	0x0007
-
-
-
diff -urN linux-2.5.73-bk2/drivers/usb/net/kaweth.c linux-2.5.73-bk3/drivers/usb/net/kaweth.c
--- linux-2.5.73-bk2/drivers/usb/net/kaweth.c	2003-06-22 11:33:00.000000000 -0700
+++ linux-2.5.73-bk3/drivers/usb/net/kaweth.c	2003-06-25 04:46:49.000000000 -0700
@@ -56,6 +56,8 @@
 #include <linux/usb.h>
 #include <linux/types.h>
 #include <linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/dma-mapping.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #include <asm/byteorder.h>
@@ -215,8 +217,10 @@
 	__u32 status;
 	int end;
 	int removed;
-	int suspend_lowmem;
+	int suspend_lowmem_rx;
+	int suspend_lowmem_ctrl;
 	int linkstate;
+	struct work_struct lowmem_work;
 
 	struct usb_device *dev;
 	struct net_device *net;
@@ -475,14 +479,29 @@
 /****************************************************************
 	int_callback
 *****************************************************************/
+
+static void kaweth_resubmit_int_urb(struct kaweth_device *kaweth, int mf)
+{
+	int status;
+
+	status = usb_submit_urb (kaweth->irq_urb, mf);
+	if (unlikely(status == -ENOMEM)) {
+		kaweth->suspend_lowmem_ctrl = 1;
+		schedule_delayed_work(&kaweth->lowmem_work, HZ/4);
+	} else {
+		kaweth->suspend_lowmem_ctrl = 0;
+	}
+
+	if (status)
+		err ("can't resubmit intr, %s-%s, status %d",
+				kaweth->dev->bus->bus_name,
+				kaweth->dev->devpath, status);
+}
+
 static void int_callback(struct urb *u, struct pt_regs *regs)
 {
 	struct kaweth_device *kaweth = u->context;
-	int act_state, status;
-
-	/* we abuse the interrupt urb for rebsubmitting under low memory saving a timer */
-	if (kaweth->suspend_lowmem)
-		kaweth_resubmit_rx_urb(kaweth, GFP_ATOMIC);
+	int act_state;
 
 	switch (u->status) {
 	case 0:			/* success */
@@ -506,13 +525,24 @@
 		kaweth->linkstate = act_state;
 	}
 resubmit:
-	status = usb_submit_urb (u, SLAB_ATOMIC);
-	if (status)
-		err ("can't resubmit intr, %s-%s, status %d",
-				kaweth->dev->bus->bus_name,
-				kaweth->dev->devpath, status);
+	kaweth_resubmit_int_urb(kaweth, GFP_ATOMIC);
+}
+
+static void kaweth_resubmit_tl(void *d)
+{
+	struct kaweth_device *kaweth = (struct kaweth_device *)d;
+
+	if (kaweth->status | KAWETH_STATUS_CLOSING)
+		return;
+
+	if (kaweth->suspend_lowmem_rx)
+		kaweth_resubmit_rx_urb(kaweth, GFP_NOIO);
+
+	if (kaweth->suspend_lowmem_ctrl)
+		kaweth_resubmit_int_urb(kaweth, GFP_NOIO);
 }
 
+
 /****************************************************************
  *     kaweth_resubmit_rx_urb
  ****************************************************************/
@@ -532,11 +562,13 @@
 	kaweth->rx_urb->transfer_dma = kaweth->rxbufferhandle;
 
 	if((result = usb_submit_urb(kaweth->rx_urb, mem_flags))) {
-		if (result == -ENOMEM)
-			kaweth->suspend_lowmem = 1;
+		if (result == -ENOMEM) {
+			kaweth->suspend_lowmem_rx = 1;
+			schedule_delayed_work(&kaweth->lowmem_work, HZ/4);
+		}
 		kaweth_err("resubmitting rx_urb %d failed", result);
 	} else {
-		kaweth->suspend_lowmem = 0;
+		kaweth->suspend_lowmem_rx = 0;
 	}
 
 	return result;
@@ -665,6 +697,13 @@
 	usb_unlink_urb(kaweth->irq_urb);
 	usb_unlink_urb(kaweth->rx_urb);
 
+	flush_scheduled_work();
+
+	/* a scheduled work may have resubmitted,
+	   we hit them again */
+	usb_unlink_urb(kaweth->irq_urb);
+	usb_unlink_urb(kaweth->rx_urb);
+
 	kaweth->status &= ~KAWETH_STATUS_CLOSING;
 
 	return 0;
@@ -1075,10 +1114,15 @@
 
 	memset(&kaweth->stats, 0, sizeof(kaweth->stats));
 
+	INIT_WORK(&kaweth->lowmem_work, kaweth_resubmit_tl, (void *)kaweth);
+
 	SET_MODULE_OWNER(netdev);
 
 	usb_set_intfdata(intf, kaweth);
 
+	if (dma_supported (&intf->dev, 0xffffffffffffffffULL))
+		kaweth->net->features |= NETIF_F_HIGHDMA;
+
 	if (register_netdev(netdev) != 0) {
 		kaweth_err("Error calling init_etherdev.");
 		goto err_intfdata;
@@ -1092,7 +1136,6 @@
 
 err_intfdata:
 	usb_set_intfdata(intf, NULL);
-err_all:
 	usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
 err_all_but_rxbuf:
 	usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
diff -urN linux-2.5.73-bk2/drivers/usb/serial/io_edgeport.c linux-2.5.73-bk3/drivers/usb/serial/io_edgeport.c
--- linux-2.5.73-bk2/drivers/usb/serial/io_edgeport.c	2003-06-22 11:32:32.000000000 -0700
+++ linux-2.5.73-bk3/drivers/usb/serial/io_edgeport.c	2003-06-25 04:46:49.000000000 -0700
@@ -412,6 +412,7 @@
 // MCR.7 = 0.
 //
 static struct divisor_table_entry divisor_table[] = {
+	{   50,		4608},  
 	{   75,		3072},  
 	{   110,	2095},		/* 2094.545455 => 230450   => .0217 % over */
 	{   134,	1713},		/* 1713.011152 => 230398.5 => .00065% under */
@@ -2591,7 +2592,7 @@
 	// We have tried all of the standard baud rates
 	// lets try to calculate the divisor for this baud rate
 	// Make sure the baud rate is reasonable
-	if (baudrate > 75 &&  baudrate < 230400) {
+	if (baudrate < 230400) {
 		// get divisor
 		custom = (__u16)(230400L  / baudrate);
 
diff -urN linux-2.5.73-bk2/drivers/usb/serial/pl2303.c linux-2.5.73-bk3/drivers/usb/serial/pl2303.c
--- linux-2.5.73-bk2/drivers/usb/serial/pl2303.c	2003-06-22 11:32:43.000000000 -0700
+++ linux-2.5.73-bk3/drivers/usb/serial/pl2303.c	2003-06-25 04:46:49.000000000 -0700
@@ -537,16 +537,20 @@
 	struct pl2303_private *priv = usb_get_serial_port_data(port);
 	unsigned long flags;
 	unsigned int mcr;
+	unsigned int status;
 	unsigned int result;
 
 	dbg("%s (%d)", __FUNCTION__, port->number);
 
 	spin_lock_irqsave (&priv->lock, flags);
 	mcr = priv->line_control;
+	status = priv->line_status;
 	spin_unlock_irqrestore (&priv->lock, flags);
 
 	result = ((mcr & CONTROL_DTR)		? TIOCM_DTR : 0)
-		  | ((mcr & CONTROL_RTS)	? TIOCM_RTS : 0);
+		  | ((mcr & CONTROL_RTS)	? TIOCM_RTS : 0)
+		  | ((status & UART_CTS)	? TIOCM_CTS : 0)
+		  | ((status & UART_DSR)	? TIOCM_DSR : 0);
 
 	dbg("%s - result = %x", __FUNCTION__, result);
 
diff -urN linux-2.5.73-bk2/drivers/usb/serial/visor.c linux-2.5.73-bk3/drivers/usb/serial/visor.c
--- linux-2.5.73-bk2/drivers/usb/serial/visor.c	2003-06-22 11:32:39.000000000 -0700
+++ linux-2.5.73-bk3/drivers/usb/serial/visor.c	2003-06-25 04:46:49.000000000 -0700
@@ -12,6 +12,10 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  *
+ * (06/03/2003) Judd Montgomery <judd at jpilot.org>
+ *     Added support for module parameter options for untested/unknown
+ *     devices.
+ *
  * (03/09/2003) gkh
  *	Added support for the Sony Clie NZ90V device.  Thanks to Martin Brachtl
  *	<brachtl@redgrep.cz> for the information.
@@ -188,6 +192,9 @@
 static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id);
 static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_id *id);
 
+/* Parameters that may be passed into the module. */
+static int vendor = -1;
+static int product = -1;
 
 static struct usb_device_id id_table [] = {
 	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID),
@@ -223,6 +230,7 @@
 		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID),
 		.driver_info = (kernel_ulong_t)&palm_os_4_probe },
+	{ },					/* optional parameter entry */
 	{ }					/* Terminating entry */
 };
 
@@ -250,6 +258,7 @@
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) },
 	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) },
+	{ },					/* optional parameter entry */
 	{ }					/* Terminating entry */
 };
 
@@ -942,6 +951,33 @@
 
 static int __init visor_init (void)
 {
+	int i;
+	/* Only if parameters were passed to us */
+	if ((vendor>0) && (product>0)) {
+		struct usb_device_id usb_dev_temp[]=
+			{{USB_DEVICE(vendor, product),
+			.driver_info = (kernel_ulong_t)&palm_os_4_probe }};
+
+		/* Find the last entry in id_table */
+		for (i=0; ; i++) {
+			if (id_table[i].idVendor==0) {
+				id_table[i] = usb_dev_temp[0];
+				break;
+			}
+		}
+		/* Find the last entry in id_table_combined */
+		for (i=0; ; i++) {
+			if (id_table_combined[i].idVendor==0) {
+				id_table_combined[i] = usb_dev_temp[0];
+				break;
+			}
+		}
+		info("Untested USB device specified at time of module insertion");
+		info("Warning: This is not guaranteed to work");
+		info("Using a newer kernel is preferred to this method");
+		info("Adding Palm OS protocol 4.x support for unknown device: 0x%x/0x%x",
+			vendor, product);
+	}
 	usb_serial_register (&handspring_device);
 	usb_serial_register (&clie_3_5_device);
 	usb_register (&visor_driver);
@@ -969,3 +1005,7 @@
 MODULE_PARM(debug, "i");
 MODULE_PARM_DESC(debug, "Debug enabled or not");
 
+MODULE_PARM(vendor, "i");
+MODULE_PARM_DESC(vendor, "User specified vendor ID");
+MODULE_PARM(product, "i");
+MODULE_PARM_DESC(product, "User specified product ID");
diff -urN linux-2.5.73-bk2/drivers/usb/storage/initializers.c linux-2.5.73-bk3/drivers/usb/storage/initializers.c
--- linux-2.5.73-bk2/drivers/usb/storage/initializers.c	2003-06-22 11:32:42.000000000 -0700
+++ linux-2.5.73-bk3/drivers/usb/storage/initializers.c	2003-06-25 04:46:49.000000000 -0700
@@ -41,6 +41,7 @@
 #include <linux/errno.h>
 #include "initializers.h"
 #include "debug.h"
+#include "transport.h"
 
 /* This places the Shuttle/SCM USB<->SCSI bridge devices in multi-target
  * mode */
@@ -59,4 +60,50 @@
 	return 0;
 }
 
+/* This function is required to activate all four slots on the UCR-61S2B
+ * flash reader */
 
+int usb_stor_ucr61s2b_init(struct us_data *us)
+{
+	struct bulk_cb_wrap *bcb;
+	struct bulk_cs_wrap *bcs;
+	int res, partial;
+
+	bcb = kmalloc(sizeof *bcb, in_interrupt() ? GFP_ATOMIC : GFP_NOIO);
+	if (!bcb) {
+		return(-1);
+	}
+	bcs = kmalloc(sizeof *bcs, in_interrupt() ? GFP_ATOMIC : GFP_NOIO);
+	if (!bcs) {
+		kfree(bcb);
+		return(-1);
+	}
+
+	US_DEBUGP("Sending UCR-61S2B initialization packet...\n");
+
+	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
+	bcb->Tag = 0;
+	bcb->DataTransferLength = cpu_to_le32(0);
+	bcb->Flags = bcb->Lun = 0;
+	bcb->Length = sizeof(UCR61S2B_INIT);
+	memset(bcb->CDB, 0, sizeof(bcb->CDB));
+	memcpy(bcb->CDB, UCR61S2B_INIT, sizeof(UCR61S2B_INIT));
+
+	res = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb,
+			US_BULK_CB_WRAP_LEN, &partial);
+	US_DEBUGP("-- result is %d\n", res);
+	kfree(bcb);
+
+	if(res) {
+		kfree(bcs);
+		return(res);
+	}
+
+	res = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
+			US_BULK_CS_WRAP_LEN, &partial);
+	US_DEBUGP("-- result of status read is %d\n", res);
+
+	kfree(bcs);
+
+	return(res ? -1 : 0);
+}
diff -urN linux-2.5.73-bk2/drivers/usb/storage/initializers.h linux-2.5.73-bk3/drivers/usb/storage/initializers.h
--- linux-2.5.73-bk2/drivers/usb/storage/initializers.h	2003-06-22 11:32:46.000000000 -0700
+++ linux-2.5.73-bk3/drivers/usb/storage/initializers.h	2003-06-25 04:46:49.000000000 -0700
@@ -48,3 +48,9 @@
 #ifdef CONFIG_USB_STORAGE_SDDR09
 int sddr09_init(struct us_data *us);
 #endif
+
+#define UCR61S2B_INIT "\xec\x0a\x06\x00$PCCHIPS"
+
+/* This function is required to activate all four slots on the UCR-61S2B
+ * flash reader */
+int usb_stor_ucr61s2b_init(struct us_data *us);
diff -urN linux-2.5.73-bk2/drivers/usb/storage/unusual_devs.h linux-2.5.73-bk3/drivers/usb/storage/unusual_devs.h
--- linux-2.5.73-bk2/drivers/usb/storage/unusual_devs.h	2003-06-22 11:33:07.000000000 -0700
+++ linux-2.5.73-bk3/drivers/usb/storage/unusual_devs.h	2003-06-25 04:46:49.000000000 -0700
@@ -595,6 +595,16 @@
 		US_SC_SCSI, US_PR_BULK, NULL,
 		US_FL_FIX_INQUIRY ),
 		
+/* Pentax Optio S digital camera
+ * adapted from http://www2.goldfisch.at/knowledge/233
+ * (Peter Pilsl <pilsl@goldfisch.at>)
+ * by Christoph Weidemann <cweidema@indiana.edu> */
+UNUSUAL_DEV(  0x0a17, 0x0006, 0x0000, 0xffff,
+		"Pentax",
+		"Optio S",
+		US_SC_8070, US_PR_CB, NULL,
+		US_FL_MODE_XLATE|US_FL_FIX_INQUIRY),
+
 #ifdef CONFIG_USB_STORAGE_ISD200
 UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
 		"ATI",
@@ -610,6 +620,16 @@
 		US_SC_SCSI, US_PR_BULK, NULL,
 		US_FL_MODE_XLATE | US_FL_FIX_INQUIRY ),
 
+/* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu>
+ * Tested on hardware version 1.10.
+ * Entry is needed only for the initializer function override.
+ */
+UNUSUAL_DEV(  0x1019, 0x0c55, 0x0000, 0x9999,
+		"Desknote",
+		"UCR-61S2B",
+		US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init,
+		0 ),
+
 /* Reported by Dan Pilone <pilone@slac.com>
  * The device needs the flags only.
  * Also reported by Brian Hall <brihall@pcisys.net>, again for flags.
diff -urN linux-2.5.73-bk2/fs/xfs/xfs_inode.c linux-2.5.73-bk3/fs/xfs/xfs_inode.c
--- linux-2.5.73-bk2/fs/xfs/xfs_inode.c	2003-06-25 04:46:44.000000000 -0700
+++ linux-2.5.73-bk3/fs/xfs/xfs_inode.c	2003-06-25 04:46:49.000000000 -0700
@@ -657,9 +657,7 @@
 	int		nex;
 	int		real_size;
 	int		size;
-#if ARCH_CONVERT != ARCH_NOCONVERT
 	int		i;
-#endif
 
 	ifp = XFS_IFORK_PTR(ip, whichfork);
 	nex = XFS_DFORK_NEXTENTS_ARCH(dip, whichfork, ARCH_CONVERT);
diff -urN linux-2.5.73-bk2/include/asm-i386/io_apic.h linux-2.5.73-bk3/include/asm-i386/io_apic.h
--- linux-2.5.73-bk2/include/asm-i386/io_apic.h	2003-06-22 11:32:58.000000000 -0700
+++ linux-2.5.73-bk3/include/asm-i386/io_apic.h	2003-06-25 04:46:49.000000000 -0700
@@ -44,6 +44,11 @@
 		__reserved_1	:  4;
 } __attribute__ ((packed));
 
+struct IO_APIC_reg_03 {
+	__u32	boot_DT		:  1,
+		__reserved_1	: 31;
+} __attribute__ ((packed));
+
 /*
  * # of IO-APICs and # of IRQ routing registers
  */
diff -urN linux-2.5.73-bk2/include/asm-ia64/agp.h linux-2.5.73-bk3/include/asm-ia64/agp.h
--- linux-2.5.73-bk2/include/asm-ia64/agp.h	2003-06-22 11:32:55.000000000 -0700
+++ linux-2.5.73-bk3/include/asm-ia64/agp.h	2003-06-25 04:46:49.000000000 -0700
@@ -4,7 +4,7 @@
 /*
  * IA-64 specific AGP definitions.
  *
- * Copyright (C) 2002 Hewlett-Packard Co
+ * Copyright (C) 2002-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -18,7 +18,4 @@
 #define flush_agp_mappings()		/* nothing */
 #define flush_agp_cache()		mb()
 
-/* Page-protection value to be used for AGP memory mapped into kernel space.  */
-#define PAGE_AGP			PAGE_KERNEL
-
 #endif /* _ASM_IA64_AGP_H */
diff -urN linux-2.5.73-bk2/include/asm-ia64/hw_irq.h linux-2.5.73-bk3/include/asm-ia64/hw_irq.h
--- linux-2.5.73-bk2/include/asm-ia64/hw_irq.h	2003-06-22 11:32:44.000000000 -0700
+++ linux-2.5.73-bk3/include/asm-ia64/hw_irq.h	2003-06-25 04:46:49.000000000 -0700
@@ -2,7 +2,7 @@
 #define _ASM_IA64_HW_IRQ_H
 
 /*
- * Copyright (C) 2001-2002 Hewlett-Packard Co
+ * Copyright (C) 2001-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -91,10 +91,10 @@
  * Default implementations for the irq-descriptor API:
  */
 
-extern struct irq_desc _irq_desc[NR_IRQS];
+extern irq_desc_t _irq_desc[NR_IRQS];
 
 #ifndef CONFIG_IA64_GENERIC
-static inline struct irq_desc *
+static inline irq_desc_t *
 __ia64_irq_desc (unsigned int irq)
 {
 	return _irq_desc + irq;
@@ -124,8 +124,8 @@
  */
 
 /* Return a pointer to the irq descriptor for IRQ.  */
-static inline struct irq_desc *
-irq_desc (int irq)
+static inline irq_desc_t *
+irq_descp (int irq)
 {
 	return platform_irq_desc(irq);
 }
diff -urN linux-2.5.73-bk2/include/asm-ia64/thread_info.h linux-2.5.73-bk3/include/asm-ia64/thread_info.h
--- linux-2.5.73-bk2/include/asm-ia64/thread_info.h	2003-06-22 11:33:36.000000000 -0700
+++ linux-2.5.73-bk3/include/asm-ia64/thread_info.h	2003-06-25 04:46:49.000000000 -0700
@@ -37,7 +37,6 @@
 	struct restart_block restart_block;
 };
 
-#define INIT_THREAD_SIZE		/* tell sched.h not to declare the thread_union */
 #define THREAD_SIZE			KERNEL_STACK_SIZE
 
 #define INIT_THREAD_INFO(tsk)			\
diff -urN linux-2.5.73-bk2/include/asm-ia64/timex.h linux-2.5.73-bk3/include/asm-ia64/timex.h
--- linux-2.5.73-bk2/include/asm-ia64/timex.h	2003-06-22 11:33:12.000000000 -0700
+++ linux-2.5.73-bk3/include/asm-ia64/timex.h	2003-06-25 04:46:49.000000000 -0700
@@ -15,8 +15,15 @@
 typedef unsigned long cycles_t;
 
 /*
- * Something low processor frequency like 100Mhz but 
- * yet multiple of HZ to avoid truncation in some formulas.
+ * For performance reasons, we don't want to define CLOCK_TICK_TRATE as
+ * local_cpu_data->itc_rate.  Fortunately, we don't have to, either: according to George
+ * Anzinger, 1/CLOCK_TICK_RATE is taken as the resolution of the timer clock.  The time
+ * calculation assumes that you will use enough of these so that your tick size <= 1/HZ.
+ * If the calculation shows that your CLOCK_TICK_RATE can not supply exactly 1/HZ ticks,
+ * the actual value is calculated and used to update the wall clock each jiffie.  Setting
+ * the CLOCK_TICK_RATE to x*HZ insures that the calculation will find no errors.  Hence we
+ * pick a multiple of HZ which gives us a (totally virtual) CLOCK_TICK_RATE of about
+ * 100MHz.
  */
 #define CLOCK_TICK_RATE		(HZ * 100000UL)
 
diff -urN linux-2.5.73-bk2/include/asm-ia64/tlb.h linux-2.5.73-bk3/include/asm-ia64/tlb.h
--- linux-2.5.73-bk2/include/asm-ia64/tlb.h	2003-06-22 11:32:42.000000000 -0700
+++ linux-2.5.73-bk3/include/asm-ia64/tlb.h	2003-06-25 04:46:49.000000000 -0700
@@ -39,6 +39,7 @@
  */
 #include <linux/config.h>
 #include <linux/mm.h>
+#include <linux/swap.h>
 
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
diff -urN linux-2.5.73-bk2/include/asm-ia64/topology.h linux-2.5.73-bk3/include/asm-ia64/topology.h
--- linux-2.5.73-bk2/include/asm-ia64/topology.h	2003-06-22 11:32:28.000000000 -0700
+++ linux-2.5.73-bk3/include/asm-ia64/topology.h	2003-06-25 04:46:49.000000000 -0700
@@ -28,11 +28,6 @@
  */
 #define node_to_cpumask(node) (node_to_cpu_mask[node])
 
-#else
-#define cpu_to_node(cpu) (0)
-#define node_to_cpumask(node) (phys_cpu_present_map)
-#endif
-
 /*
  * Returns the number of the node containing MemBlk 'memblk'
  */
@@ -65,4 +60,8 @@
 
 void build_cpu_to_node_map(void);
 
+#endif /* CONFIG_NUMA */
+
+#include <asm-generic/topology.h>
+
 #endif /* _ASM_IA64_TOPOLOGY_H */
diff -urN linux-2.5.73-bk2/include/linux/loop.h linux-2.5.73-bk3/include/linux/loop.h
--- linux-2.5.73-bk2/include/linux/loop.h	2003-06-25 04:46:44.000000000 -0700
+++ linux-2.5.73-bk3/include/linux/loop.h	2003-06-25 04:46:49.000000000 -0700
@@ -30,7 +30,8 @@
 struct loop_device {
 	int		lo_number;
 	int		lo_refcnt;
-	int		lo_offset;
+	loff_t		lo_offset;
+	loff_t		lo_sizelimit;
 	int		lo_flags;
 	int		(*transfer)(struct loop_device *, int cmd,
 				    char *raw_buf, char *loop_buf, int size,
@@ -64,10 +65,6 @@
 	request_queue_t		lo_queue;
 };
 
-typedef	int (* transfer_proc_t)(struct loop_device *, int cmd,
-				char *raw_buf, char *loop_buf, int size,
-				int real_block);
-
 #endif /* __KERNEL__ */
 
 /*
@@ -96,13 +93,14 @@
 };
 
 struct loop_info64 {
-	__u64		   lo_device; 		/* ioctl r/o */
-	__u64		   lo_inode; 		/* ioctl r/o */
-	__u64		   lo_rdevice; 		/* ioctl r/o */
+	__u64		   lo_device;			/* ioctl r/o */
+	__u64		   lo_inode;			/* ioctl r/o */
+	__u64		   lo_rdevice;			/* ioctl r/o */
 	__u64		   lo_offset;
-	__u32		   lo_number;		/* ioctl r/o */
+	__u64		   lo_sizelimit;/* bytes, 0 == max available */
+	__u32		   lo_number;			/* ioctl r/o */
 	__u32		   lo_encrypt_type;
-	__u32		   lo_encrypt_key_size; 	/* ioctl w/o */
+	__u32		   lo_encrypt_key_size;		/* ioctl w/o */
 	__u32		   lo_flags;			/* ioctl r/o */
 	__u8		   lo_name[LO_NAME_SIZE];
 	__u8		   lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
@@ -113,21 +111,22 @@
  * Loop filter types
  */
 
-#define LO_CRYPT_NONE	  0
-#define LO_CRYPT_XOR	  1
-#define LO_CRYPT_DES	  2
-#define LO_CRYPT_FISH2    3    /* Brand new Twofish encryption */
-#define LO_CRYPT_BLOW     4
-#define LO_CRYPT_CAST128  5
-#define LO_CRYPT_IDEA     6
-#define LO_CRYPT_DUMMY    9
-#define LO_CRYPT_SKIPJACK 10
-#define MAX_LO_CRYPT	20
+#define LO_CRYPT_NONE		0
+#define LO_CRYPT_XOR		1
+#define LO_CRYPT_DES		2
+#define LO_CRYPT_FISH2		3    /* Twofish encryption */
+#define LO_CRYPT_BLOW		4
+#define LO_CRYPT_CAST128	5
+#define LO_CRYPT_IDEA		6
+#define LO_CRYPT_DUMMY		9
+#define LO_CRYPT_SKIPJACK	10
+#define LO_CRYPT_CRYPTOAPI	18
+#define MAX_LO_CRYPT		20
 
 #ifdef __KERNEL__
 /* Support for loadable transfer modules */
 struct loop_func_table {
-	int number; 	/* filter type */ 
+	int number;	/* filter type */ 
 	int (*transfer)(struct loop_device *lo, int cmd, char *raw_buf,
 			char *loop_buf, int size, sector_t real_block);
 	int (*init)(struct loop_device *, const struct loop_info64 *); 
diff -urN linux-2.5.73-bk2/include/linux/netfilter.h linux-2.5.73-bk3/include/linux/netfilter.h
--- linux-2.5.73-bk2/include/linux/netfilter.h	2003-06-22 11:32:46.000000000 -0700
+++ linux-2.5.73-bk3/include/linux/netfilter.h	2003-06-25 04:46:49.000000000 -0700
@@ -19,9 +19,10 @@
 #define NF_REPEAT 4
 #define NF_MAX_VERDICT NF_REPEAT
 
-/* Generic cache responses from hook functions. */
-#define NFC_ALTERED 0x8000
+/* Generic cache responses from hook functions.
+   <= 0x2000 is used for protocol-flags. */
 #define NFC_UNKNOWN 0x4000
+#define NFC_ALTERED 0x8000
 
 #ifdef __KERNEL__
 #include <linux/config.h>
diff -urN linux-2.5.73-bk2/include/linux/netfilter_ipv4/ipt_recent.h linux-2.5.73-bk3/include/linux/netfilter_ipv4/ipt_recent.h
--- linux-2.5.73-bk2/include/linux/netfilter_ipv4/ipt_recent.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.73-bk3/include/linux/netfilter_ipv4/ipt_recent.h	2003-06-25 04:46:49.000000000 -0700
@@ -0,0 +1,27 @@
+#ifndef _IPT_RECENT_H
+#define _IPT_RECENT_H
+
+#define RECENT_NAME	"ipt_recent"
+#define RECENT_VER	"v0.3.1"
+
+#define IPT_RECENT_CHECK  1
+#define IPT_RECENT_SET    2
+#define IPT_RECENT_UPDATE 4
+#define IPT_RECENT_REMOVE 8
+#define IPT_RECENT_TTL   16
+
+#define IPT_RECENT_SOURCE 0
+#define IPT_RECENT_DEST   1
+
+#define IPT_RECENT_NAME_LEN 200
+
+struct ipt_recent_info {
+	u_int32_t   seconds;
+	u_int32_t   hit_count;
+	u_int8_t    check_set;
+	u_int8_t    invert;
+	char        name[IPT_RECENT_NAME_LEN];
+	u_int8_t    side;
+};
+
+#endif /*_IPT_RECENT_H*/
diff -urN linux-2.5.73-bk2/include/linux/netfilter_ipv4/listhelp.h linux-2.5.73-bk3/include/linux/netfilter_ipv4/listhelp.h
--- linux-2.5.73-bk2/include/linux/netfilter_ipv4/listhelp.h	2003-06-22 11:32:33.000000000 -0700
+++ linux-2.5.73-bk3/include/linux/netfilter_ipv4/listhelp.h	2003-06-25 04:46:49.000000000 -0700
@@ -39,6 +39,22 @@
 	(type)__i;				\
 })
 
+/* Just like LIST_FIND but we search backwards */
+#define LIST_FIND_B(head, cmpfn, type, args...)		\
+({							\
+	const struct list_head *__i = (head);		\
+							\
+	ASSERT_READ_LOCK(head);				\
+	do {						\
+		__i = __i->prev;			\
+		if (__i == (head)) {			\
+			__i = NULL;			\
+			break;				\
+		}					\
+	} while (!cmpfn((const type)__i , ## args));	\
+	(type)__i;					\
+})
+
 static inline int
 __list_cmp_same(const void *p1, const void *p2) { return p1 == p2; }
 
diff -urN linux-2.5.73-bk2/include/linux/netfilter_ipv4/lockhelp.h linux-2.5.73-bk3/include/linux/netfilter_ipv4/lockhelp.h
--- linux-2.5.73-bk2/include/linux/netfilter_ipv4/lockhelp.h	2003-06-22 11:32:32.000000000 -0700
+++ linux-2.5.73-bk3/include/linux/netfilter_ipv4/lockhelp.h	2003-06-25 04:46:49.000000000 -0700
@@ -42,22 +42,22 @@
 	printk("ASSERT %s:%u %s locked\n", __FILE__, __LINE__, #l);	\
 } while(0)
 
-/* Write locked OK as well. */						    \
+/* Write locked OK as well. */
 #define MUST_BE_READ_LOCKED(l)						    \
-do { if (!((l)->read_locked_map & (1 << smp_processor_id()))		    \
-	 && !((l)->write_locked_map & (1 << smp_processor_id())))	    \
+do { if (!((l)->read_locked_map & (1UL << smp_processor_id()))		    \
+	 && !((l)->write_locked_map & (1UL << smp_processor_id())))	    \
 	printk("ASSERT %s:%u %s not readlocked\n", __FILE__, __LINE__, #l); \
 } while(0)
 
 #define MUST_BE_WRITE_LOCKED(l)						     \
-do { if (!((l)->write_locked_map & (1 << smp_processor_id())))		     \
+do { if (!((l)->write_locked_map & (1UL << smp_processor_id())))	     \
 	printk("ASSERT %s:%u %s not writelocked\n", __FILE__, __LINE__, #l); \
 } while(0)
 
 #define MUST_BE_READ_WRITE_UNLOCKED(l)					  \
-do { if ((l)->read_locked_map & (1 << smp_processor_id()))		  \
+do { if ((l)->read_locked_map & (1UL << smp_processor_id()))		  \
 	printk("ASSERT %s:%u %s readlocked\n", __FILE__, __LINE__, #l);	  \
- else if ((l)->write_locked_map & (1 << smp_processor_id()))		  \
+ else if ((l)->write_locked_map & (1UL << smp_processor_id()))		  \
 	 printk("ASSERT %s:%u %s writelocked\n", __FILE__, __LINE__, #l); \
 } while(0)
 
@@ -91,7 +91,7 @@
 
 #define READ_UNLOCK(lk)							\
 do {									\
-	if (!((lk)->read_locked_map & (1 << smp_processor_id())))	\
+	if (!((lk)->read_locked_map & (1UL << smp_processor_id())))	\
 		printk("ASSERT: %s:%u %s not readlocked\n", 		\
 		       __FILE__, __LINE__, #lk);			\
 	clear_bit(smp_processor_id(), &(lk)->read_locked_map);		\
diff -urN linux-2.5.73-bk2/include/linux/pnp.h linux-2.5.73-bk3/include/linux/pnp.h
--- linux-2.5.73-bk2/include/linux/pnp.h	2003-06-22 11:33:34.000000000 -0700
+++ linux-2.5.73-bk3/include/linux/pnp.h	2003-06-25 04:46:49.000000000 -0700
@@ -400,7 +400,7 @@
 int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data);
 int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data);
 int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data);
-void pnp_init_resources(struct pnp_resource_table *table);
+void pnp_init_resource_table(struct pnp_resource_table *table);
 int pnp_assign_resources(struct pnp_dev *dev, int depnum);
 int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode);
 int pnp_auto_config_dev(struct pnp_dev *dev);
@@ -448,7 +448,7 @@
 static inline int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) { return -ENODEV; }
 static inline int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) { return -ENODEV; }
 static inline int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) { return -ENODEV; }
-static inline void pnp_init_resources(struct pnp_resource_table *table) { }
+static inline void pnp_init_resource_table(struct pnp_resource_table *table) { }
 static inline int pnp_assign_resources(struct pnp_dev *dev, int depnum) { return -ENODEV; }
 static inline int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int mode) { return -ENODEV; }
 static inline int pnp_auto_config_dev(struct pnp_dev *dev) { return -ENODEV; }
diff -urN linux-2.5.73-bk2/include/linux/usb_gadget.h linux-2.5.73-bk3/include/linux/usb_gadget.h
--- linux-2.5.73-bk2/include/linux/usb_gadget.h	2003-06-22 11:32:43.000000000 -0700
+++ linux-2.5.73-bk3/include/linux/usb_gadget.h	2003-06-25 04:46:49.000000000 -0700
@@ -10,11 +10,6 @@
  * All Rights Reserved.
  *
  * This software is licensed under the GNU GPL version 2.
- *
- * ALTERNATIVELY, the kernel API documentation which is included in this
- * software may also be licenced under the "GNU Free Documentation
- * License" (version 1.2 or, at your choice, any later version), when
- * used as part of the "USB Gadget API for Linux" documentation.
  */
 
 #ifndef __LINUX_USB_GADGET_H
diff -urN linux-2.5.73-bk2/include/net/ipv6.h linux-2.5.73-bk3/include/net/ipv6.h
--- linux-2.5.73-bk2/include/net/ipv6.h	2003-06-22 11:33:08.000000000 -0700
+++ linux-2.5.73-bk3/include/net/ipv6.h	2003-06-25 04:46:49.000000000 -0700
@@ -23,6 +23,8 @@
 
 #define SIN6_LEN_RFC2133	24
 
+#define IPV6_MAXPLEN		65535
+
 /*
  *	NextHeader field of IPv6 header
  */
diff -urN linux-2.5.73-bk2/kernel/ksyms.c linux-2.5.73-bk3/kernel/ksyms.c
--- linux-2.5.73-bk2/kernel/ksyms.c	2003-06-22 11:32:30.000000000 -0700
+++ linux-2.5.73-bk3/kernel/ksyms.c	2003-06-25 04:46:49.000000000 -0700
@@ -523,6 +523,7 @@
 EXPORT_SYMBOL(csum_partial); /* for networking and md */
 EXPORT_SYMBOL(seq_escape);
 EXPORT_SYMBOL(seq_printf);
+EXPORT_SYMBOL(seq_path);
 EXPORT_SYMBOL(seq_open);
 EXPORT_SYMBOL(seq_release);
 EXPORT_SYMBOL(seq_read);
diff -urN linux-2.5.73-bk2/kernel/sys.c linux-2.5.73-bk3/kernel/sys.c
--- linux-2.5.73-bk2/kernel/sys.c	2003-06-22 11:32:32.000000000 -0700
+++ linux-2.5.73-bk3/kernel/sys.c	2003-06-25 04:46:49.000000000 -0700
@@ -220,6 +220,7 @@
 cond_syscall(sys_send)
 cond_syscall(sys_recvfrom)
 cond_syscall(sys_recv)
+cond_syscall(sys_socket)
 cond_syscall(sys_setsockopt)
 cond_syscall(sys_getsockopt)
 cond_syscall(sys_shutdown)
diff -urN linux-2.5.73-bk2/net/ipv4/igmp.c linux-2.5.73-bk3/net/ipv4/igmp.c
--- linux-2.5.73-bk2/net/ipv4/igmp.c	2003-06-22 11:33:34.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/igmp.c	2003-06-25 04:46:49.000000000 -0700
@@ -2011,7 +2011,7 @@
 			break;
 	}
 	if (!pmc)
-		return 0;
+		return 1;
 	psl = pmc->sflist;
 	if (!psl)
 		return pmc->sfmode == MCAST_EXCLUDE;
@@ -2020,11 +2020,11 @@
 		if (psl->sl_addr[i] == rmt_addr)
 			break;
 	}
-	if (pmc->sfmode == MCAST_INCLUDE && i < psl->sl_count)
-		return 1;
-	if (pmc->sfmode == MCAST_EXCLUDE && i >= psl->sl_count)
-		return 1;
-	return 0;
+	if (pmc->sfmode == MCAST_INCLUDE && i >= psl->sl_count)
+		return 0;
+	if (pmc->sfmode == MCAST_EXCLUDE && i < psl->sl_count)
+		return 0;
+	return 1;
 }
 
 /*
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/Kconfig linux-2.5.73-bk3/net/ipv4/netfilter/Kconfig
--- linux-2.5.73-bk2/net/ipv4/netfilter/Kconfig	2003-06-25 04:46:44.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/netfilter/Kconfig	2003-06-25 04:46:49.000000000 -0700
@@ -63,7 +63,7 @@
 	tristate "Amanda backup protocol support"
 	depends on IP_NF_CONNTRACK
 	help
-	  If you are running the Amanda backup package (http://www.amanda.org/)
+	  If you are running the Amanda backup package <http://www.amanda.org/>
 	  on this machine or machines that will be MASQUERADED through this
 	  machine, then you may want to enable this feature.  This allows the
 	  connection tracking and natting code to allow the sub-channels that
@@ -161,6 +161,19 @@
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+config IP_NF_MATCH_RECENT
+	tristate "recent match support"
+	depends on IP_NF_IPTABLES
+	help
+	  This match is used for creating one or many lists of recently
+	  used addresses and then matching against that/those list(s).
+
+	  Short options are available by using 'iptables -m recent -h'
+	  Official Website: <http://snowman.net/projects/ipt_recent/>
+
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.  If unsure, say `N'.
+
 config IP_NF_MATCH_ECN
 	tristate "ECN match support"
 	depends on IP_NF_IPTABLES
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/Makefile linux-2.5.73-bk3/net/ipv4/netfilter/Makefile
--- linux-2.5.73-bk2/net/ipv4/netfilter/Makefile	2003-06-22 11:32:37.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/netfilter/Makefile	2003-06-25 04:46:49.000000000 -0700
@@ -49,6 +49,9 @@
 obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o
 obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
 obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
+
+obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
+
 obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
 obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o
 obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/ip_conntrack_core.c linux-2.5.73-bk3/net/ipv4/netfilter/ip_conntrack_core.c
--- linux-2.5.73-bk2/net/ipv4/netfilter/ip_conntrack_core.c	2003-06-22 11:32:27.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/netfilter/ip_conntrack_core.c	2003-06-25 04:46:49.000000000 -0700
@@ -168,8 +168,8 @@
 static void
 destroy_expect(struct ip_conntrack_expect *exp)
 {
-	DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(exp->use));
-	IP_NF_ASSERT(atomic_read(exp->use));
+	DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(&exp->use));
+	IP_NF_ASSERT(atomic_read(&exp->use));
 	IP_NF_ASSERT(!timer_pending(&exp->timeout));
 
 	kfree(exp);
@@ -258,9 +258,7 @@
 
 	DEBUGP("remove_expectations(%p)\n", ct);
 
-	for (exp_entry = ct->sibling_list.next;
-	     exp_entry != &ct->sibling_list; exp_entry = next) {
-		next = exp_entry->next;
+	list_for_each_safe(exp_entry, next, &ct->sibling_list) {
 		exp = list_entry(exp_entry, struct ip_conntrack_expect,
 				 expected_list);
 
@@ -307,9 +305,6 @@
 	IP_NF_ASSERT(atomic_read(&nfct->use) == 0);
 	IP_NF_ASSERT(!timer_pending(&ct->timeout));
 
-	if (ct->master && master_ct(ct))
-		ip_conntrack_put(master_ct(ct));
-
 	/* To make sure we don't get any weird locking issues here:
 	 * destroy_conntrack() MUST NOT be called with a write lock
 	 * to ip_conntrack_lock!!! -HW */
@@ -326,9 +321,12 @@
 
 	/* Delete our master expectation */
 	if (ct->master) {
-		/* can't call __unexpect_related here,
-		 * since it would screw up expect_list */
-		list_del(&ct->master->expected_list);
+		if (ct->master->expectant) {
+			/* can't call __unexpect_related here,
+			 * since it would screw up expect_list */
+			list_del(&ct->master->expected_list);
+			ip_conntrack_put(ct->master->expectant);
+		}
 		kfree(ct->master);
 	}
 	WRITE_UNLOCK(&ip_conntrack_lock);
@@ -576,7 +574,7 @@
 	int dropped = 0;
 
 	READ_LOCK(&ip_conntrack_lock);
-	h = LIST_FIND(chain, unreplied, struct ip_conntrack_tuple_hash *);
+	h = LIST_FIND_B(chain, unreplied, struct ip_conntrack_tuple_hash *);
 	if (h)
 		atomic_inc(&h->ctrack->ct_general.use);
 	READ_UNLOCK(&ip_conntrack_lock);
@@ -675,9 +673,6 @@
 
 	INIT_LIST_HEAD(&conntrack->sibling_list);
 
-	/* Mark clearly that it's not in the hash table. */
-	conntrack->tuplehash[IP_CT_DIR_ORIGINAL].list.next = NULL;
-
 	WRITE_LOCK(&ip_conntrack_lock);
 	/* Need finding and deleting of expected ONLY if we win race */
 	READ_LOCK(&ip_conntrack_expect_tuple_lock);
@@ -685,6 +680,14 @@
 			     struct ip_conntrack_expect *, tuple);
 	READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
 
+	/* If master is not in hash table yet (ie. packet hasn't left
+	   this machine yet), how can other end know about expected?
+	   Hence these are not the droids you are looking for (if
+	   master ct never got confirmed, we'd hold a reference to it
+	   and weird things would happen to future packets). */
+	if (expected && !is_confirmed(expected->expectant))
+		expected = NULL;
+
 	/* Look up the conntrack helper for master connections only */
 	if (!expected)
 		conntrack->helper = ip_ct_find_helper(&repl_tuple);
@@ -695,12 +698,7 @@
 	    && ! del_timer(&expected->timeout))
 		expected = NULL;
 
-	/* If master is not in hash table yet (ie. packet hasn't left
-	   this machine yet), how can other end know about expected?
-	   Hence these are not the droids you are looking for (if
-	   master ct never got confirmed, we'd hold a reference to it
-	   and weird things would happen to future packets). */
-	if (expected && is_confirmed(expected->expectant)) {
+	if (expected) {
 		DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
 			conntrack, expected);
 		/* Welcome, Mr. Bond.  We've been expecting you... */
@@ -1012,18 +1010,11 @@
 		return -ENOMEM;
 	}
 	
-	/* Zero out the new structure, then fill out it with the data */
 	DEBUGP("new expectation %p of conntrack %p\n", new, related_to);
-	memset(new, 0, sizeof(*expect));
-	INIT_LIST_HEAD(&new->list);
-	INIT_LIST_HEAD(&new->expected_list);
 	memcpy(new, expect, sizeof(*expect));
 	new->expectant = related_to;
 	new->sibling = NULL;
-	/* increase usage count. This sucks. The memset above overwrites
-	 * old usage count [if still present] and we increase to one.  Only
-	 * works because everything is done under ip_conntrack_lock() */
-	atomic_inc(&new->use);
+	atomic_set(&new->use, 1);
 	
 	/* add to expected list for this connection */	
 	list_add(&new->expected_list, &related_to->sibling_list);
@@ -1282,9 +1273,9 @@
 	struct inet_opt *inet = inet_sk(sk);
 	struct ip_conntrack_tuple_hash *h;
 	struct ip_conntrack_tuple tuple = { { inet->rcv_saddr,
-						{ inet->sport } },
+						{ .tcp = { inet->sport } } },
 					    { inet->daddr,
-						{ inet->dport },
+						{ .tcp = { inet->dport } },
 					      IPPROTO_TCP } };
 
 	/* We only do TCP at the moment: is there a better way? */
@@ -1473,8 +1464,10 @@
 	ip_ct_attach = ip_conntrack_attach;
 	return ret;
 
+#ifdef CONFIG_SYSCTL
 err_free_ct_cachep:
 	kmem_cache_destroy(ip_conntrack_cachep);
+#endif /*CONFIG_SYSCTL*/
 err_free_hash:
 	vfree(ip_conntrack_hash);
 err_unreg_sockopt:
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/ip_conntrack_ftp.c linux-2.5.73-bk3/net/ipv4/netfilter/ip_conntrack_ftp.c
--- linux-2.5.73-bk2/net/ipv4/netfilter/ip_conntrack_ftp.c	2003-06-22 11:33:07.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/netfilter/ip_conntrack_ftp.c	2003-06-25 04:46:49.000000000 -0700
@@ -367,11 +367,11 @@
 		    { 0 } },
 		  { htonl((array[0] << 24) | (array[1] << 16)
 			  | (array[2] << 8) | array[3]),
-		    { htons(array[4] << 8 | array[5]) },
+		    { .tcp = { htons(array[4] << 8 | array[5]) } },
 		    IPPROTO_TCP }});
 	exp->mask = ((struct ip_conntrack_tuple)
 		{ { 0xFFFFFFFF, { 0 } },
-		  { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
+		  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFFFF }});
 
 	exp->expectfn = NULL;
 
@@ -406,7 +406,6 @@
 		ports[0] = FTP_PORT;
 
 	for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
-		memset(&ftp[i], 0, sizeof(struct ip_conntrack_helper));
 		ftp[i].tuple.src.u.tcp.port = htons(ports[i]);
 		ftp[i].tuple.dst.protonum = IPPROTO_TCP;
 		ftp[i].mask.src.u.tcp.port = 0xFFFF;
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/ip_conntrack_irc.c linux-2.5.73-bk3/net/ipv4/netfilter/ip_conntrack_irc.c
--- linux-2.5.73-bk2/net/ipv4/netfilter/ip_conntrack_irc.c	2003-06-22 11:33:07.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/netfilter/ip_conntrack_irc.c	2003-06-25 04:46:49.000000000 -0700
@@ -192,11 +192,11 @@
 
 			exp->tuple = ((struct ip_conntrack_tuple)
 				{ { 0, { 0 } },
-				  { htonl(dcc_ip), { htons(dcc_port) },
+				  { htonl(dcc_ip), { .tcp = { htons(dcc_port) } },
 				    IPPROTO_TCP }});
 			exp->mask = ((struct ip_conntrack_tuple)
 				{ { 0, { 0 } },
-				  { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }});
+				  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFFFF }});
 
 			exp->expectfn = NULL;
 
@@ -243,8 +243,6 @@
 
 	for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
 		hlpr = &irc_helpers[i];
-		memset(hlpr, 0,
-		       sizeof(struct ip_conntrack_helper));
 		hlpr->tuple.src.u.tcp.port = htons(ports[i]);
 		hlpr->tuple.dst.protonum = IPPROTO_TCP;
 		hlpr->mask.src.u.tcp.port = 0xFFFF;
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/ip_nat_amanda.c linux-2.5.73-bk3/net/ipv4/netfilter/ip_nat_amanda.c
--- linux-2.5.73-bk2/net/ipv4/netfilter/ip_nat_amanda.c	2003-06-22 11:32:36.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/netfilter/ip_nat_amanda.c	2003-06-25 04:46:49.000000000 -0700
@@ -84,7 +84,7 @@
 		mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
 		mr.range[0].min = mr.range[0].max
 			= ((union ip_conntrack_manip_proto)
-				{ htons(port) });
+				{ .udp = { htons(port) } });
 	}
 
 	return ip_nat_setup_info(ct, &mr, hooknum);
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/ip_nat_core.c linux-2.5.73-bk3/net/ipv4/netfilter/ip_nat_core.c
--- linux-2.5.73-bk2/net/ipv4/netfilter/ip_nat_core.c	2003-06-22 11:32:34.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/netfilter/ip_nat_core.c	2003-06-25 04:46:49.000000000 -0700
@@ -763,6 +763,11 @@
 	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 	int proto = (*pskb)->nh.iph->protocol;
 
+	/* Skip everything and don't call helpers if there are no
+	 * manips for this connection */
+	if (info->num_manips == 0)
+		return NF_ACCEPT;
+
 	/* Need nat lock to protect against modification, but neither
 	   conntrack (referenced) and helper (deleted with
 	   synchronize_bh()) can vanish. */
@@ -791,6 +796,7 @@
 		struct ip_conntrack_expect *exp = NULL;
 		struct list_head *cur_item;
 		int ret = NF_ACCEPT;
+		int helper_called = 0;
 
 		DEBUGP("do_bindings: helper existing for (%p)\n", ct);
 
@@ -809,19 +815,21 @@
 				continue;
 
 			if (exp_for_packet(exp, *pskb)) {
-				/* FIXME: May be true multiple times in the case of UDP!! */
-				DEBUGP("calling nat helper (exp=%p) for packet\n",
-					exp);
+				/* FIXME: May be true multiple times in the
+				 * case of UDP!! */
+				DEBUGP("calling nat helper (exp=%p) for packet\n", exp);
 				ret = helper->help(ct, exp, info, ctinfo, 
 						   hooknum, pskb);
 				if (ret != NF_ACCEPT) {
 					READ_UNLOCK(&ip_conntrack_lock);
 					return ret;
 				}
+				helper_called = 1;
 			}
 		}
-		/* Helper might want to manip the packet even when there is no expectation */
-		if (!exp && helper->flags & IP_NAT_HELPER_F_ALWAYS) {
+		/* Helper might want to manip the packet even when there is no
+		 * matching expectation for this packet */
+		if (!helper_called && helper->flags & IP_NAT_HELPER_F_ALWAYS) {
 			DEBUGP("calling nat helper for packet without expectation\n");
 			ret = helper->help(ct, NULL, info, ctinfo, 
 					   hooknum, pskb);
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/ip_nat_ftp.c linux-2.5.73-bk3/net/ipv4/netfilter/ip_nat_ftp.c
--- linux-2.5.73-bk2/net/ipv4/netfilter/ip_nat_ftp.c	2003-06-22 11:32:58.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/netfilter/ip_nat_ftp.c	2003-06-25 04:46:49.000000000 -0700
@@ -84,7 +84,7 @@
 		mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
 		mr.range[0].min = mr.range[0].max
 			= ((union ip_conntrack_manip_proto)
-				{ htons(exp_ftp_info->port) });
+				{ .tcp = { htons(exp_ftp_info->port) } });
 	}
 	return ip_nat_setup_info(ct, &mr, hooknum);
 }
@@ -306,9 +306,6 @@
 		ports[0] = FTP_PORT;
 
 	for (i = 0; (i < MAX_PORTS) && ports[i]; i++) {
-
-		memset(&ftp[i], 0, sizeof(struct ip_nat_helper));
-
 		ftp[i].tuple.dst.protonum = IPPROTO_TCP;
 		ftp[i].tuple.src.u.tcp.port = htons(ports[i]);
 		ftp[i].mask.dst.protonum = 0xFFFF;
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/ip_nat_irc.c linux-2.5.73-bk3/net/ipv4/netfilter/ip_nat_irc.c
--- linux-2.5.73-bk2/net/ipv4/netfilter/ip_nat_irc.c	2003-06-22 11:33:35.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/netfilter/ip_nat_irc.c	2003-06-25 04:46:49.000000000 -0700
@@ -243,9 +243,6 @@
 
 	for (i = 0; (i < MAX_PORTS) && ports[i] != 0; i++) {
 		hlpr = &ip_nat_irc_helpers[i];
-		memset(hlpr, 0,
-		       sizeof(struct ip_nat_helper));
-
 		hlpr->tuple.dst.protonum = IPPROTO_TCP;
 		hlpr->tuple.src.u.tcp.port = htons(ports[i]);
 		hlpr->mask.src.u.tcp.port = 0xFFFF;
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/ip_nat_snmp_basic.c linux-2.5.73-bk3/net/ipv4/netfilter/ip_nat_snmp_basic.c
--- linux-2.5.73-bk2/net/ipv4/netfilter/ip_nat_snmp_basic.c	2003-06-22 11:33:08.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/netfilter/ip_nat_snmp_basic.c	2003-06-25 04:46:49.000000000 -0700
@@ -1308,9 +1308,9 @@
 	"snmp",
 	0,
 	THIS_MODULE,
-	{ { 0, { __constant_htons(SNMP_PORT) } },
+	{ { 0, { .udp = { __constant_htons(SNMP_PORT) } } },
 	  { 0, { 0 }, IPPROTO_UDP } },
-	{ { 0, { 0xFFFF } },
+	{ { 0, { .udp = { 0xFFFF } } },
 	  { 0, { 0 }, 0xFFFF } },
 	nat_help, NULL };
  
@@ -1319,9 +1319,9 @@
 	"snmp_trap",
 	0,
 	THIS_MODULE,
-	{ { 0, { __constant_htons(SNMP_TRAP_PORT) } },
+	{ { 0, { .udp = { __constant_htons(SNMP_TRAP_PORT) } } },
 	  { 0, { 0 }, IPPROTO_UDP } },
-	{ { 0, { 0xFFFF } },
+	{ { 0, { .udp = { 0xFFFF } } },
 	  { 0, { 0 }, 0xFFFF } },
 	nat_help, NULL };
 
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/ip_tables.c linux-2.5.73-bk3/net/ipv4/netfilter/ip_tables.c
--- linux-2.5.73-bk2/net/ipv4/netfilter/ip_tables.c	2003-06-22 11:32:37.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/netfilter/ip_tables.c	2003-06-25 04:46:49.000000000 -0700
@@ -1703,14 +1703,15 @@
 };
 
 #ifdef CONFIG_PROC_FS
-static inline int print_name(const struct ipt_table *t,
+static inline int print_name(const char *i,
 			     off_t start_offset, char *buffer, int length,
 			     off_t *pos, unsigned int *count)
 {
 	if ((*count)++ >= start_offset) {
 		unsigned int namelen;
 
-		namelen = sprintf(buffer + *pos, "%s\n", t->name);
+		namelen = sprintf(buffer + *pos, "%s\n",
+				  i + sizeof(struct list_head));
 		if (*pos + namelen > length) {
 			/* Stop iterating */
 			return 1;
@@ -1728,7 +1729,7 @@
 	if (down_interruptible(&ipt_mutex) != 0)
 		return 0;
 
-	LIST_FIND(&ipt_tables, print_name, struct ipt_table *,
+	LIST_FIND(&ipt_tables, print_name, void *,
 		  offset, buffer, length, &pos, &count);
 
 	up(&ipt_mutex);
@@ -1737,6 +1738,46 @@
 	*start=(char *)((unsigned long)count-offset);
 	return pos;
 }
+
+static int ipt_get_targets(char *buffer, char **start, off_t offset, int length)
+{
+	off_t pos = 0;
+	unsigned int count = 0;
+
+	if (down_interruptible(&ipt_mutex) != 0)
+		return 0;
+
+	LIST_FIND(&ipt_target, print_name, void *,
+		  offset, buffer, length, &pos, &count);
+	
+	up(&ipt_mutex);
+
+	*start = (char *)((unsigned long)count - offset);
+	return pos;
+}
+
+static int ipt_get_matches(char *buffer, char **start, off_t offset, int length)
+{
+	off_t pos = 0;
+	unsigned int count = 0;
+
+	if (down_interruptible(&ipt_mutex) != 0)
+		return 0;
+	
+	LIST_FIND(&ipt_match, print_name, void *,
+		  offset, buffer, length, &pos, &count);
+
+	up(&ipt_mutex);
+
+	*start = (char *)((unsigned long)count - offset);
+	return pos;
+}
+
+static struct { char *name; get_info_t *get_info; } ipt_proc_entry[] =
+{ { "ip_tables_names", ipt_get_tables },
+  { "ip_tables_targets", ipt_get_targets },
+  { "ip_tables_matches", ipt_get_matches },
+  { NULL, NULL} };
 #endif /*CONFIG_PROC_FS*/
 
 static int __init init(void)
@@ -1762,13 +1803,19 @@
 #ifdef CONFIG_PROC_FS
 	{
 	struct proc_dir_entry *proc;
+	int i;
 
-	proc = proc_net_create("ip_tables_names", 0, ipt_get_tables);
-	if (!proc) {
-		nf_unregister_sockopt(&ipt_sockopts);
-		return -ENOMEM;
+	for (i = 0; ipt_proc_entry[i].name; i++) {
+		proc = proc_net_create(ipt_proc_entry[i].name, 0,
+				       ipt_proc_entry[i].get_info);
+		if (!proc) {
+			while (--i >= 0)
+				proc_net_remove(ipt_proc_entry[i].name);
+			nf_unregister_sockopt(&ipt_sockopts);
+			return -ENOMEM;
+		}
+		proc->owner = THIS_MODULE;
 	}
-	proc->owner = THIS_MODULE;
 	}
 #endif
 
@@ -1780,7 +1827,11 @@
 {
 	nf_unregister_sockopt(&ipt_sockopts);
 #ifdef CONFIG_PROC_FS
-	proc_net_remove("ip_tables_names");
+	{
+	int i;
+	for (i = 0; ipt_proc_entry[i].name; i++)
+		proc_net_remove(ipt_proc_entry[i].name);
+	}
 #endif
 }
 
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/ipt_ULOG.c linux-2.5.73-bk3/net/ipv4/netfilter/ipt_ULOG.c
--- linux-2.5.73-bk2/net/ipv4/netfilter/ipt_ULOG.c	2003-06-22 11:32:41.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/netfilter/ipt_ULOG.c	2003-06-25 04:46:49.000000000 -0700
@@ -325,7 +325,6 @@
 
 	/* initialize ulog_buffers */
 	for (i = 0; i < ULOG_MAXNLGROUPS; i++) {
-		memset(&ulog_buffers[i], 0, sizeof(ulog_buff_t));
 		init_timer(&ulog_buffers[i].timer);
 		ulog_buffers[i].timer.function = ulog_timer;
 		ulog_buffers[i].timer.data = i;
diff -urN linux-2.5.73-bk2/net/ipv4/netfilter/ipt_recent.c linux-2.5.73-bk3/net/ipv4/netfilter/ipt_recent.c
--- linux-2.5.73-bk2/net/ipv4/netfilter/ipt_recent.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.73-bk3/net/ipv4/netfilter/ipt_recent.c	2003-06-25 04:46:49.000000000 -0700
@@ -0,0 +1,986 @@
+/* Kernel module to check if the source address has been seen recently. */
+/* Copyright 2002-2003, Stephen Frost, 2.5.x port by laforge@netfilter.org */
+/* Author: Stephen Frost <sfrost@snowman.net> */
+/* Project Page: http://snowman.net/projects/ipt_recent/ */
+/* This software is distributed under the terms of the GPL, Version 2 */
+/* This copyright does not cover user programs that use kernel services
+ * by normal system calls. */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <asm/uaccess.h>
+#include <linux/ctype.h>
+#include <linux/ip.h>
+#include <linux/vmalloc.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_recent.h>
+
+#undef DEBUG
+#define HASH_LOG 9
+
+/* Defaults, these can be overridden on the module command-line. */
+static int ip_list_tot = 100;
+static int ip_pkt_list_tot = 20;
+static int ip_list_hash_size = 0;
+static int ip_list_perms = 0644;
+#ifdef DEBUG
+static int debug = 1;
+#endif
+
+static char version[] =
+KERN_INFO RECENT_NAME " " RECENT_VER ": Stephen Frost <sfrost@snowman.net>.  http://snowman.net/projects/ipt_recent/\n";
+
+MODULE_AUTHOR("Stephen Frost <sfrost@snowman.net>");
+MODULE_DESCRIPTION("IP tables recently seen matching module " RECENT_VER);
+MODULE_LICENSE("GPL");
+MODULE_PARM(ip_list_tot,"i");
+MODULE_PARM(ip_pkt_list_tot,"i");
+MODULE_PARM(ip_list_hash_size,"i");
+MODULE_PARM(ip_list_perms,"i");
+#ifdef DEBUG
+MODULE_PARM(debug,"i");
+MODULE_PARM_DESC(debug,"debugging level, defaults to 1");
+#endif
+MODULE_PARM_DESC(ip_list_tot,"number of IPs to remember per list");
+MODULE_PARM_DESC(ip_pkt_list_tot,"number of packets per IP to remember");
+MODULE_PARM_DESC(ip_list_hash_size,"size of hash table used to look up IPs");
+MODULE_PARM_DESC(ip_list_perms,"permissions on /proc/net/ipt_recent/* files");
+
+/* Structure of our list of recently seen addresses. */
+struct recent_ip_list {
+	u_int32_t addr;
+	u_int8_t  ttl;
+	unsigned long last_seen;
+	unsigned long *last_pkts;
+	u_int32_t oldest_pkt;
+	u_int32_t hash_entry;
+	u_int32_t time_pos;
+};
+
+struct time_info_list {
+	u_int32_t position;
+	u_int32_t time;
+};
+
+/* Structure of our linked list of tables of recent lists. */
+struct recent_ip_tables {
+	char name[IPT_RECENT_NAME_LEN];
+	int count;
+	int time_pos;
+	struct recent_ip_list *table;
+	struct recent_ip_tables *next;
+	spinlock_t list_lock;
+	int *hash_table;
+	struct time_info_list *time_info;
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry *status_proc;
+#endif /* CONFIG_PROC_FS */
+};
+
+/* Our current list of addresses we have recently seen.
+ * Only added to on a --set, and only updated on --set || --update 
+ */
+static struct recent_ip_tables *r_tables = NULL;
+
+/* We protect r_list with this spinlock so two processors are not modifying
+ * the list at the same time. 
+ */
+static spinlock_t recent_lock = SPIN_LOCK_UNLOCKED;
+
+/* Our /proc/net/ipt_recent entry */
+static struct proc_dir_entry *proc_net_ipt_recent = NULL;
+
+/* Function declaration for later. */
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      int *hotdrop);
+
+/* Function to hash a given address into the hash table of table_size size */
+int hash_func(unsigned int addr, int table_size)
+{
+	int result = 0;
+	unsigned int value = addr;
+	do { result ^= value; } while((value >>= HASH_LOG));
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": %d = hash_func(%u,%d)\n",
+			 result & (table_size - 1),
+			 addr,
+			 table_size);
+#endif
+
+	return(result & (table_size - 1));
+}
+
+#ifdef CONFIG_PROC_FS
+/* This is the function which produces the output for our /proc output
+ * interface which lists each IP address, the last seen time and the 
+ * other recent times the address was seen.
+ */
+
+static int ip_recent_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
+{
+	int len = 0, count, last_len = 0, pkt_count;
+	off_t pos = 0;
+	off_t begin = 0;
+	struct recent_ip_tables *curr_table;
+
+	curr_table = (struct recent_ip_tables*) data;
+
+	spin_lock_bh(&curr_table->list_lock);
+	for(count = 0; count < ip_list_tot; count++) {
+		if(!curr_table->table[count].addr) continue;
+		last_len = len;
+		len += sprintf(buffer+len,"src=%u.%u.%u.%u ",NIPQUAD(curr_table->table[count].addr));
+		len += sprintf(buffer+len,"ttl: %u ",curr_table->table[count].ttl);
+		len += sprintf(buffer+len,"last_seen: %lu ",curr_table->table[count].last_seen);
+		len += sprintf(buffer+len,"oldest_pkt: %u ",curr_table->table[count].oldest_pkt);
+		len += sprintf(buffer+len,"last_pkts: %lu",curr_table->table[count].last_pkts[0]);
+		for(pkt_count = 1; pkt_count < ip_pkt_list_tot; pkt_count++) {
+			if(!curr_table->table[count].last_pkts[pkt_count]) break;
+			len += sprintf(buffer+len,", %lu",curr_table->table[count].last_pkts[pkt_count]);
+		}
+		len += sprintf(buffer+len,"\n");
+		pos = begin + len;
+		if(pos < offset) { len = 0; begin = pos; }
+		if(pos > offset + length) { len = last_len; break; }
+	}
+
+	*start = buffer + (offset - begin);
+	len -= (offset - begin);
+	if(len > length) len = length;
+
+	spin_unlock_bh(&curr_table->list_lock);
+	return len;
+}
+
+/* ip_recent_ctrl provides an interface for users to modify the table
+ * directly.  This allows adding entries, removing entries, and
+ * flushing the entire table.
+ * This is done by opening up the appropriate table for writing and
+ * sending one of:
+ * xx.xx.xx.xx   -- Add entry to table with current time
+ * +xx.xx.xx.xx  -- Add entry to table with current time
+ * -xx.xx.xx.xx  -- Remove entry from table
+ * clear         -- Flush table, remove all entries
+ */
+
+static int ip_recent_ctrl(struct file *file, const char *input, unsigned long size, void *data)
+{
+	static const u_int32_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
+	u_int32_t val;
+	int base, used = 0;
+	char c, *cp;
+	union iaddr {
+		uint8_t bytes[4];
+		uint32_t word;
+	} res;
+	uint8_t *pp = res.bytes;
+	int digit;
+
+	char buffer[20];
+	int len, check_set = 0, count;
+	u_int32_t addr = 0;
+	struct sk_buff *skb;
+	struct ipt_recent_info *info;
+	struct recent_ip_tables *curr_table;
+
+	curr_table = (struct recent_ip_tables*) data;
+
+	if(size > 20) len = 20; else len = size;
+
+	if(copy_from_user(buffer,input,len)) return -EFAULT;
+
+	if(len < 20) buffer[len] = '\0';
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": ip_recent_ctrl len: %d, input: `%.20s'\n",len,buffer);
+#endif
+
+	cp = buffer;
+	while(isspace(*cp)) { cp++; used++; if(used >= len-5) return used; }
+
+	/* Check if we are asked to flush the entire table */
+	if(!memcmp(cp,"clear",5)) {
+		used += 5;
+		spin_lock_bh(&curr_table->list_lock);
+		curr_table->time_pos = 0;
+		for(count = 0; count < ip_list_hash_size; count++) {
+			curr_table->hash_table[count] = -1;
+		}
+		for(count = 0; count < ip_list_tot; count++) {
+			curr_table->table[count].last_seen = 0;
+			curr_table->table[count].addr = 0;
+			curr_table->table[count].ttl = 0;
+			memset(curr_table->table[count].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t));
+			curr_table->table[count].oldest_pkt = 0;
+			curr_table->table[count].time_pos = 0;
+			curr_table->time_info[count].position = count;
+			curr_table->time_info[count].time = 0;
+		}
+		spin_unlock_bh(&curr_table->list_lock);
+		return used;
+	}
+
+        check_set = IPT_RECENT_SET;
+	switch(*cp) {
+		case '+': check_set = IPT_RECENT_SET; cp++; used++; break;
+		case '-': check_set = IPT_RECENT_REMOVE; cp++; used++; break;
+		default: if(!isdigit(*cp)) return (used+1); break;
+	}
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": ip_recent_ctrl cp: `%c', check_set: %d\n",*cp,check_set);
+#endif
+	/* Get addr (effectively inet_aton()) */
+	/* Shamelessly stolen from libc, a function in the kernel for doing
+	 * this would, of course, be greatly preferred, but our options appear
+	 * to be rather limited, so we will just do it ourselves here.
+	 */
+	res.word = 0;
+
+	c = *cp;
+	for(;;) {
+		if(!isdigit(c)) return used;
+		val = 0; base = 10; digit = 0;
+		if(c == '0') {
+			c = *++cp;
+			if(c == 'x' || c == 'X') base = 16, c = *++cp;
+			else { base = 8; digit = 1; }
+		}
+		for(;;) {
+			if(isascii(c) && isdigit(c)) {
+				if(base == 8 && (c == '8' || c == '0')) return used;
+				val = (val * base) + (c - '0');
+				c = *++cp;
+				digit = 1;
+			} else if(base == 16 && isascii(c) && isxdigit(c)) {
+				val = (val << 4) | (c + 10 - (islower(c) ? 'a' : 'A'));
+				c = *++cp;
+				digit = 1;
+			} else break;
+		}
+		if(c == '.') {
+			if(pp > res.bytes + 2 || val > 0xff) return used;
+			*pp++ = val;
+			c = *++cp;
+		} else break;
+	}
+	used = cp - buffer;
+	if(c != '\0' && (!isascii(c) || !isspace(c))) return used;
+	if(c == '\n') used++;
+	if(!digit) return used;
+
+	if(val > max[pp - res.bytes]) return used;
+	addr = res.word | htonl(val);
+
+	if(!addr && check_set == IPT_RECENT_SET) return used;
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": ip_recent_ctrl c: %c, addr: %u used: %d\n",c,addr,used);
+#endif
+
+	/* Set up and just call match */
+	info = kmalloc(sizeof(struct ipt_recent_info),GFP_KERNEL);
+	if(!info) { return -ENOMEM; }
+	info->seconds = 0;
+	info->hit_count = 0;
+	info->check_set = check_set;
+	info->invert = 0;
+	info->side = IPT_RECENT_SOURCE;
+	strncpy(info->name,curr_table->name,IPT_RECENT_NAME_LEN);
+	info->name[IPT_RECENT_NAME_LEN-1] = '\0';
+
+	skb = kmalloc(sizeof(struct sk_buff),GFP_KERNEL);
+	if(!skb) { return -ENOMEM; }
+	skb->nh.iph = kmalloc(sizeof(struct iphdr),GFP_KERNEL);
+	if(!skb->nh.iph) { return -ENOMEM; }
+
+	skb->nh.iph->saddr = addr;
+	skb->nh.iph->daddr = 0;
+	/* Clear ttl since we have no way of knowing it */
+	skb->nh.iph->ttl = 0;
+	match(skb,NULL,NULL,info,0,NULL);
+
+	kfree(skb->nh.iph);
+	kfree(skb);
+	kfree(info);
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": Leaving ip_recent_ctrl addr: %u used: %d\n",addr,used);
+#endif
+	return used;
+}
+
+#endif /* CONFIG_PROC_FS */
+
+/* 'match' is our primary function, called by the kernel whenever a rule is
+ * hit with our module as an option to it.
+ * What this function does depends on what was specifically asked of it by
+ * the user:
+ * --set -- Add or update last seen time of the source address of the packet
+ *   -- matchinfo->check_set == IPT_RECENT_SET
+ * --rcheck -- Just check if the source address is in the list
+ *   -- matchinfo->check_set == IPT_RECENT_CHECK
+ * --update -- If the source address is in the list, update last_seen
+ *   -- matchinfo->check_set == IPT_RECENT_UPDATE
+ * --remove -- If the source address is in the list, remove it
+ *   -- matchinfo->check_set == IPT_RECENT_REMOVE
+ * --seconds -- Option to --rcheck/--update, only match if last_seen within seconds
+ *   -- matchinfo->seconds
+ * --hitcount -- Option to --rcheck/--update, only match if seen hitcount times
+ *   -- matchinfo->hit_count
+ * --seconds and --hitcount can be combined
+ */
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset,
+      int *hotdrop)
+{
+	int pkt_count, hits_found, ans;
+	unsigned long now;
+	const struct ipt_recent_info *info = matchinfo;
+	u_int32_t addr = 0, time_temp;
+	u_int8_t ttl = skb->nh.iph->ttl;
+	int *hash_table;
+	int orig_hash_result, hash_result, temp, location = 0, time_loc, end_collision_chain = -1;
+	struct time_info_list *time_info;
+	struct recent_ip_tables *curr_table;
+	struct recent_ip_tables *last_table;
+	struct recent_ip_list *r_list;
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": match() called\n");
+#endif
+
+	/* Default is false ^ info->invert */
+	ans = info->invert;
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": match(): name = '%s'\n",info->name);
+#endif
+
+	/* if out != NULL then routing has been done and TTL changed.
+	 * We change it back here internally for match what came in before routing. */
+	if(out) ttl++;
+
+	/* Find the right table */
+	spin_lock_bh(&recent_lock);
+	curr_table = r_tables;
+	while( (last_table = curr_table) && strncmp(info->name,curr_table->name,IPT_RECENT_NAME_LEN) && (curr_table = curr_table->next) );
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": match(): table found('%s')\n",info->name);
+#endif
+
+	spin_unlock_bh(&recent_lock);
+
+	/* Table with this name not found, match impossible */
+	if(!curr_table) { return ans; }
+
+	/* Make sure no one is changing the list while we work with it */
+	spin_lock_bh(&curr_table->list_lock);
+
+	r_list = curr_table->table;
+	if(info->side == IPT_RECENT_DEST) addr = skb->nh.iph->daddr; else addr = skb->nh.iph->saddr;
+
+	if(!addr) { 
+#ifdef DEBUG
+		if(debug) printk(KERN_INFO RECENT_NAME ": match() address (%u) invalid, leaving.\n",addr);
+#endif
+		spin_unlock_bh(&curr_table->list_lock);
+		return ans;
+	}
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": match(): checking table, addr: %u, ttl: %u, orig_ttl: %u\n",addr,ttl,skb->nh.iph->ttl);
+#endif
+
+	/* Get jiffies now in case they changed while we were waiting for a lock */
+	now = jiffies;
+	hash_table = curr_table->hash_table;
+	time_info = curr_table->time_info;
+
+	orig_hash_result = hash_result = hash_func(addr,ip_list_hash_size);
+	/* Hash entry at this result used */
+	/* Check for TTL match if requested.  If TTL is zero then a match would never
+	 * happen, so match regardless of existing TTL in that case.  Zero means the
+	 * entry was added via the /proc interface anyway, so we will just use the
+	 * first TTL we get for that IP address. */
+	if(info->check_set & IPT_RECENT_TTL) {
+		while(hash_table[hash_result] != -1 && !(r_list[hash_table[hash_result]].addr == addr &&
+			(!r_list[hash_table[hash_result]].ttl || r_list[hash_table[hash_result]].ttl == ttl))) {
+			/* Collision in hash table */
+			hash_result = (hash_result + 1) % ip_list_hash_size;
+		}
+	} else {
+		while(hash_table[hash_result] != -1 && r_list[hash_table[hash_result]].addr != addr) {
+			/* Collision in hash table */
+			hash_result = (hash_result + 1) % ip_list_hash_size;
+		}
+	}
+
+	if(hash_table[hash_result] == -1 && !(info->check_set & IPT_RECENT_SET)) {
+		/* IP not in list and not asked to SET */
+		spin_unlock_bh(&curr_table->list_lock);
+		return ans;
+	}
+
+	/* Check if we need to handle the collision, do not need to on REMOVE */
+	if(orig_hash_result != hash_result && !(info->check_set & IPT_RECENT_REMOVE)) {
+#ifdef DEBUG
+		if(debug) printk(KERN_INFO RECENT_NAME ": match(): Collision in hash table. (or: %d,hr: %d,oa: %u,ha: %u)\n",
+				 orig_hash_result,
+				 hash_result,
+				 r_list[hash_table[orig_hash_result]].addr,
+				 addr);
+#endif
+
+		/* We had a collision.
+		 * orig_hash_result is where we started, hash_result is where we ended up.
+		 * So, swap them because we are likely to see the same guy again sooner */
+#ifdef DEBUG
+		if(debug) {
+		  printk(KERN_INFO RECENT_NAME ": match(): Collision; hash_table[orig_hash_result] = %d\n",hash_table[orig_hash_result]);
+		  printk(KERN_INFO RECENT_NAME ": match(): Collision; r_list[hash_table[orig_hash_result]].hash_entry = %d\n",
+				r_list[hash_table[orig_hash_result]].hash_entry);
+		}
+#endif
+
+		r_list[hash_table[orig_hash_result]].hash_entry = hash_result;
+
+
+		temp = hash_table[orig_hash_result];
+#ifdef DEBUG
+		if(debug) printk(KERN_INFO RECENT_NAME ": match(): Collision; hash_table[hash_result] = %d\n",hash_table[hash_result]);
+#endif
+		hash_table[orig_hash_result] = hash_table[hash_result];
+		hash_table[hash_result] = temp;
+		temp = hash_result;
+		hash_result = orig_hash_result;
+		orig_hash_result = temp;
+		time_info[r_list[hash_table[orig_hash_result]].time_pos].position = hash_table[orig_hash_result];
+		if(hash_table[hash_result] != -1) {
+			r_list[hash_table[hash_result]].hash_entry = hash_result;
+			time_info[r_list[hash_table[hash_result]].time_pos].position = hash_table[hash_result];
+		}
+
+#ifdef DEBUG
+		if(debug) printk(KERN_INFO RECENT_NAME ": match(): Collision handled.\n");
+#endif
+	}
+
+	if(hash_table[hash_result] == -1) {
+#ifdef DEBUG
+		if(debug) printk(KERN_INFO RECENT_NAME ": match(): New table entry. (hr: %d,ha: %u)\n",
+				 hash_result, addr);
+#endif
+
+		/* New item found and IPT_RECENT_SET, so we need to add it */
+		location = time_info[curr_table->time_pos].position;
+		hash_table[r_list[location].hash_entry] = -1;
+		hash_table[hash_result] = location;
+		memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t));
+		r_list[location].time_pos = curr_table->time_pos;
+		r_list[location].addr = addr;
+		r_list[location].ttl = ttl;
+		r_list[location].last_seen = now;
+		r_list[location].oldest_pkt = 1;
+		r_list[location].last_pkts[0] = now;
+		r_list[location].hash_entry = hash_result;
+		time_info[curr_table->time_pos].time = r_list[location].last_seen;
+		curr_table->time_pos = (curr_table->time_pos + 1) % ip_list_tot;
+
+		ans = !info->invert;
+	} else {
+#ifdef DEBUG
+		if(debug) printk(KERN_INFO RECENT_NAME ": match(): Existing table entry. (hr: %d,ha: %u)\n",
+				 hash_result,
+				 addr);
+#endif
+
+		/* Existing item found */
+		location = hash_table[hash_result];
+		/* We have a match on address, now to make sure it meets all requirements for a
+		 * full match. */
+		if(info->check_set & IPT_RECENT_CHECK || info->check_set & IPT_RECENT_UPDATE) {
+			if(!info->seconds && !info->hit_count) ans = !info->invert; else ans = info->invert;
+			if(info->seconds && !info->hit_count) {
+				if(time_before_eq(now,r_list[location].last_seen+info->seconds*HZ)) ans = !info->invert; else ans = info->invert;
+			}
+			if(info->seconds && info->hit_count) {
+				for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) {
+					if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++;
+				}
+				if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert;
+			}
+			if(info->hit_count && !info->seconds) {
+				for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) {
+					if(r_list[location].last_pkts[pkt_count] == 0) break;
+					hits_found++;
+				}
+				if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert;
+			}
+		}
+#ifdef DEBUG
+		if(debug) {
+			if(ans)
+				printk(KERN_INFO RECENT_NAME ": match(): match addr: %u\n",addr);
+			else
+				printk(KERN_INFO RECENT_NAME ": match(): no match addr: %u\n",addr);
+		}
+#endif
+
+		/* If and only if we have been asked to SET, or to UPDATE (on match) do we add the
+		 * current timestamp to the last_seen. */
+		if((info->check_set & IPT_RECENT_SET && (ans = !info->invert)) || (info->check_set & IPT_RECENT_UPDATE && ans)) {
+#ifdef DEBUG
+			if(debug) printk(KERN_INFO RECENT_NAME ": match(): SET or UPDATE; updating time info.\n");
+#endif
+			/* Have to update our time info */
+			time_loc = r_list[location].time_pos;
+			time_info[time_loc].time = now;
+			time_info[time_loc].position = location;
+			while((time_info[(time_loc+1) % ip_list_tot].time < time_info[time_loc].time) && ((time_loc+1) % ip_list_tot) != curr_table->time_pos) {
+				time_temp = time_info[time_loc].time;
+				time_info[time_loc].time = time_info[(time_loc+1)%ip_list_tot].time;
+				time_info[(time_loc+1)%ip_list_tot].time = time_temp;
+				time_temp = time_info[time_loc].position;
+				time_info[time_loc].position = time_info[(time_loc+1)%ip_list_tot].position;
+				time_info[(time_loc+1)%ip_list_tot].position = time_temp;
+				r_list[time_info[time_loc].position].time_pos = time_loc;
+				r_list[time_info[(time_loc+1)%ip_list_tot].position].time_pos = (time_loc+1)%ip_list_tot;
+				time_loc = (time_loc+1) % ip_list_tot;
+			}
+			r_list[location].time_pos = time_loc;
+			r_list[location].ttl = ttl;
+			r_list[location].last_pkts[r_list[location].oldest_pkt] = now;
+			r_list[location].oldest_pkt = ++r_list[location].oldest_pkt % ip_pkt_list_tot;
+			r_list[location].last_seen = now;
+		}
+		/* If we have been asked to remove the entry from the list, just set it to 0 */
+		if(info->check_set & IPT_RECENT_REMOVE) {
+#ifdef DEBUG
+			if(debug) printk(KERN_INFO RECENT_NAME ": match(): REMOVE; clearing entry (or: %d, hr: %d).\n",orig_hash_result,hash_result);
+#endif
+			/* Check if this is part of a collision chain */
+			while(hash_table[(orig_hash_result+1) % ip_list_hash_size] != -1) {
+				orig_hash_result++;
+				if(hash_func(r_list[hash_table[orig_hash_result]].addr,ip_list_hash_size) == hash_result) {
+					/* Found collision chain, how deep does this rabbit hole go? */
+#ifdef DEBUG
+					if(debug) printk(KERN_INFO RECENT_NAME ": match(): REMOVE; found collision chain.\n");
+#endif
+					end_collision_chain = orig_hash_result;
+				}
+			}
+			if(end_collision_chain != -1) {
+#ifdef DEBUG
+				if(debug) printk(KERN_INFO RECENT_NAME ": match(): REMOVE; part of collision chain, moving to end.\n");
+#endif
+				/* Part of a collision chain, swap it with the end of the chain
+				 * before removing. */
+				r_list[hash_table[end_collision_chain]].hash_entry = hash_result;
+				temp = hash_table[end_collision_chain];
+				hash_table[end_collision_chain] = hash_table[hash_result];
+				hash_table[hash_result] = temp;
+				time_info[r_list[hash_table[hash_result]].time_pos].position = hash_table[hash_result];
+				hash_result = end_collision_chain;
+				r_list[hash_table[hash_result]].hash_entry = hash_result;
+				time_info[r_list[hash_table[hash_result]].time_pos].position = hash_table[hash_result];
+			}
+			location = hash_table[hash_result];
+			hash_table[r_list[location].hash_entry] = -1;
+			time_loc = r_list[location].time_pos;
+			time_info[time_loc].time = 0;
+			time_info[time_loc].position = location;
+			while((time_info[(time_loc+1) % ip_list_tot].time < time_info[time_loc].time) && ((time_loc+1) % ip_list_tot) != curr_table->time_pos) {
+				time_temp = time_info[time_loc].time;
+				time_info[time_loc].time = time_info[(time_loc+1)%ip_list_tot].time;
+				time_info[(time_loc+1)%ip_list_tot].time = time_temp;
+				time_temp = time_info[time_loc].position;
+				time_info[time_loc].position = time_info[(time_loc+1)%ip_list_tot].position;
+				time_info[(time_loc+1)%ip_list_tot].position = time_temp;
+				r_list[time_info[time_loc].position].time_pos = time_loc;
+				r_list[time_info[(time_loc+1)%ip_list_tot].position].time_pos = (time_loc+1)%ip_list_tot;
+				time_loc = (time_loc+1) % ip_list_tot;
+			}
+			r_list[location].time_pos = time_loc;
+			r_list[location].last_seen = 0;
+			r_list[location].addr = 0;
+			r_list[location].ttl = 0;
+			memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t));
+			r_list[location].oldest_pkt = 0;
+			ans = !info->invert;
+		}
+		spin_unlock_bh(&curr_table->list_lock);
+		return ans;
+	}
+
+	spin_unlock_bh(&curr_table->list_lock);
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": match() left.\n");
+#endif
+	return ans;
+}
+
+/* This function is to verify that the rule given during the userspace iptables
+ * command is correct.
+ * If the command is valid then we check if the table name referred to by the
+ * rule exists, if not it is created.
+ */
+static int
+checkentry(const char *tablename,
+           const struct ipt_ip *ip,
+           void *matchinfo,
+           unsigned int matchsize,
+           unsigned int hook_mask)
+{
+	int flag = 0, c;
+	unsigned long *hold;
+	const struct ipt_recent_info *info = matchinfo;
+	struct recent_ip_tables *curr_table, *find_table, *last_table;
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() entered.\n");
+#endif
+
+	if (matchsize != IPT_ALIGN(sizeof(struct ipt_recent_info))) return 0;
+
+	/* seconds and hit_count only valid for CHECK/UPDATE */
+	if(info->check_set & IPT_RECENT_SET) { flag++; if(info->seconds || info->hit_count) return 0; }
+	if(info->check_set & IPT_RECENT_REMOVE) { flag++; if(info->seconds || info->hit_count) return 0; }
+	if(info->check_set & IPT_RECENT_CHECK) flag++;
+	if(info->check_set & IPT_RECENT_UPDATE) flag++;
+
+	/* One and only one of these should ever be set */
+	if(flag != 1) return 0;
+
+	/* Name must be set to something */
+	if(!info->name || !info->name[0]) return 0;
+
+	/* Things look good, create a list for this if it does not exist */
+	/* Lock the linked list while we play with it */
+	spin_lock_bh(&recent_lock);
+
+	/* Look for an entry with this name already created */
+	/* Finds the end of the list and the entry before the end if current name does not exist */
+	find_table = r_tables;
+	while( (last_table = find_table) && strncmp(info->name,find_table->name,IPT_RECENT_NAME_LEN) && (find_table = find_table->next) );
+
+	/* If a table already exists just increment the count on that table and return */
+	if(find_table) { 
+#ifdef DEBUG
+		if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: table found (%s), incrementing count.\n",info->name);
+#endif
+		find_table->count++;
+		spin_unlock_bh(&recent_lock);
+		return 1;
+	}
+
+	spin_unlock_bh(&recent_lock);
+
+	/* Table with this name not found */
+	/* Allocate memory for new linked list item */
+
+#ifdef DEBUG
+	if(debug) {
+		printk(KERN_INFO RECENT_NAME ": checkentry: no table found (%s)\n",info->name);
+		printk(KERN_INFO RECENT_NAME ": checkentry: Allocationg %d for link-list entry.\n",sizeof(struct recent_ip_tables));
+	}
+#endif
+
+	curr_table = vmalloc(sizeof(struct recent_ip_tables));
+	if(curr_table == NULL) return -ENOMEM;
+
+	curr_table->list_lock = SPIN_LOCK_UNLOCKED;
+	curr_table->next = NULL;
+	curr_table->count = 1;
+	curr_table->time_pos = 0;
+	strncpy(curr_table->name,info->name,IPT_RECENT_NAME_LEN);
+	curr_table->name[IPT_RECENT_NAME_LEN-1] = '\0';
+
+	/* Allocate memory for this table and the list of packets in each entry. */
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for table (%s).\n",
+			sizeof(struct recent_ip_list)*ip_list_tot,
+			info->name);
+#endif
+
+	curr_table->table = vmalloc(sizeof(struct recent_ip_list)*ip_list_tot);
+	if(curr_table->table == NULL) { vfree(curr_table); return -ENOMEM; }
+	memset(curr_table->table,0,sizeof(struct recent_ip_list)*ip_list_tot);
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for pkt_list.\n",
+			sizeof(u_int32_t)*ip_pkt_list_tot*ip_list_tot);
+#endif
+
+	hold = vmalloc(sizeof(u_int32_t)*ip_pkt_list_tot*ip_list_tot);
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: After pkt_list allocation.\n");
+#endif
+	if(hold == NULL) { 
+		printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for pkt_list.\n");
+		vfree(curr_table->table); 
+		vfree(curr_table);
+		return -ENOMEM;
+	}
+	for(c = 0; c < ip_list_tot; c++) {
+		curr_table->table[c].last_pkts = hold + c*ip_pkt_list_tot;
+	}
+
+	/* Allocate memory for the hash table */
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for hash_table.\n",
+			sizeof(int)*ip_list_hash_size);
+#endif
+
+	curr_table->hash_table = vmalloc(sizeof(int)*ip_list_hash_size);
+	if(!curr_table->hash_table) {
+		printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for hash_table.\n");
+		vfree(hold);
+		vfree(curr_table->table); 
+		vfree(curr_table);
+		return -ENOMEM;
+	}
+
+	for(c = 0; c < ip_list_hash_size; c++) {
+		curr_table->hash_table[c] = -1;
+	}
+
+	/* Allocate memory for the time info */
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for time_info.\n",
+			sizeof(struct time_info_list)*ip_list_tot);
+#endif
+
+	curr_table->time_info = vmalloc(sizeof(struct time_info_list)*ip_list_tot);
+	if(!curr_table->time_info) {
+		printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for time_info.\n");
+		vfree(curr_table->hash_table);
+		vfree(hold);
+		vfree(curr_table->table); 
+		vfree(curr_table);
+		return -ENOMEM;
+	}
+	for(c = 0; c < ip_list_tot; c++) {
+		curr_table->time_info[c].position = c;
+		curr_table->time_info[c].time = 0;
+	}
+
+	/* Put the new table in place */
+	spin_lock_bh(&recent_lock);
+	find_table = r_tables;
+	while( (last_table = find_table) && strncmp(info->name,find_table->name,IPT_RECENT_NAME_LEN) && (find_table = find_table->next) );
+
+	/* If a table already exists just increment the count on that table and return */
+	if(find_table) { 
+		find_table->count++;	
+		spin_unlock_bh(&recent_lock);
+#ifdef DEBUG
+		if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: table found (%s), created by other process.\n",info->name);
+#endif
+		vfree(curr_table->time_info);
+		vfree(curr_table->hash_table);
+		vfree(hold);
+		vfree(curr_table->table);
+		vfree(curr_table);
+		return 1;
+	}
+	if(!last_table) r_tables = curr_table; else last_table->next = curr_table;
+
+	spin_unlock_bh(&recent_lock);
+
+#ifdef CONFIG_PROC_FS
+	/* Create our proc 'status' entry. */
+	curr_table->status_proc = create_proc_entry(curr_table->name, ip_list_perms, proc_net_ipt_recent);
+	if (!curr_table->status_proc) {
+		printk(KERN_INFO RECENT_NAME ": checkentry: unable to allocate for /proc entry.\n");
+		/* Destroy the created table */
+		spin_lock_bh(&recent_lock);
+		last_table = NULL;
+		curr_table = r_tables;
+		if(!curr_table) {
+#ifdef DEBUG
+			if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() create_proc failed, no tables.\n");
+#endif
+			spin_unlock_bh(&recent_lock);
+			return -ENOMEM;
+		}
+		while( strncmp(info->name,curr_table->name,IPT_RECENT_NAME_LEN) && (last_table = curr_table) && (curr_table = curr_table->next) );
+		if(!curr_table) {
+#ifdef DEBUG
+			if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() create_proc failed, table already destroyed.\n");
+#endif
+			spin_unlock_bh(&recent_lock);
+			return -ENOMEM;
+		}
+		if(last_table) last_table->next = curr_table->next; else r_tables = curr_table->next;
+		spin_unlock_bh(&recent_lock);
+		vfree(curr_table->time_info);
+		vfree(curr_table->hash_table);
+		vfree(hold);
+		vfree(curr_table->table);
+		vfree(curr_table);
+		return -ENOMEM;
+	}
+	
+	curr_table->status_proc->owner = THIS_MODULE;
+	curr_table->status_proc->data = curr_table;
+	wmb();
+	curr_table->status_proc->read_proc = ip_recent_get_info;
+	curr_table->status_proc->write_proc = ip_recent_ctrl;
+#endif /* CONFIG_PROC_FS */
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": checkentry() left.\n");
+#endif
+
+	return 1;
+}
+
+/* This function is called in the event that a rule matching this module is
+ * removed.
+ * When this happens we need to check if there are no other rules matching
+ * the table given.  If that is the case then we remove the table and clean
+ * up its memory.
+ */
+static void
+destroy(void *matchinfo, unsigned int matchsize)
+{
+	const struct ipt_recent_info *info = matchinfo;
+	struct recent_ip_tables *curr_table, *last_table;
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": destroy() entered.\n");
+#endif
+
+	if(matchsize != IPT_ALIGN(sizeof(struct ipt_recent_info))) return;
+
+	/* Lock the linked list while we play with it */
+	spin_lock_bh(&recent_lock);
+
+	/* Look for an entry with this name already created */
+	/* Finds the end of the list and the entry before the end if current name does not exist */
+	last_table = NULL;
+	curr_table = r_tables;
+	if(!curr_table) { 
+#ifdef DEBUG
+		if(debug) printk(KERN_INFO RECENT_NAME ": destroy() No tables found, leaving.\n");
+#endif
+		spin_unlock_bh(&recent_lock);
+		return;
+	}
+	while( strncmp(info->name,curr_table->name,IPT_RECENT_NAME_LEN) && (last_table = curr_table) && (curr_table = curr_table->next) );
+
+	/* If a table does not exist then do nothing and return */
+	if(!curr_table) { 
+#ifdef DEBUG
+		if(debug) printk(KERN_INFO RECENT_NAME ": destroy() table not found, leaving.\n");
+#endif
+		spin_unlock_bh(&recent_lock);
+		return;
+	}
+
+	curr_table->count--;
+
+	/* If count is still non-zero then there are still rules referenceing it so we do nothing */
+	if(curr_table->count) { 
+#ifdef DEBUG
+		if(debug) printk(KERN_INFO RECENT_NAME ": destroy() table found, non-zero count, leaving.\n");
+#endif
+		spin_unlock_bh(&recent_lock);
+		return;
+	}
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": destroy() table found, zero count, removing.\n");
+#endif
+
+	/* Count must be zero so we remove this table from the list */
+	if(last_table) last_table->next = curr_table->next; else r_tables = curr_table->next;
+
+	spin_unlock_bh(&recent_lock);
+
+	/* lock to make sure any late-runners still using this after we removed it from
+	 * the list finish up then remove everything */
+	spin_lock_bh(&curr_table->list_lock);
+	spin_unlock_bh(&curr_table->list_lock);
+
+#ifdef CONFIG_PROC_FS
+	if(curr_table->status_proc) remove_proc_entry(curr_table->name,proc_net_ipt_recent);
+#endif /* CONFIG_PROC_FS */
+	vfree(curr_table->table[0].last_pkts);
+	vfree(curr_table->table);
+	vfree(curr_table->hash_table);
+	vfree(curr_table->time_info);
+	vfree(curr_table);
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": destroy() left.\n");
+#endif
+
+	return;
+}
+
+/* This is the structure we pass to ipt_register to register our
+ * module with iptables.
+ */
+static struct ipt_match recent_match = { 
+  .name = "recent", 
+  .match = &match, 
+  .checkentry = &checkentry, 
+  .destroy = &destroy, 
+  .me = THIS_MODULE
+};
+
+/* Kernel module initialization. */
+static int __init init(void)
+{
+	int count;
+
+	printk(version);
+	proc_net_ipt_recent = proc_mkdir("ipt_recent",proc_net);
+	if(!proc_net_ipt_recent) return -ENOMEM;
+
+	if(ip_list_hash_size && ip_list_hash_size <= ip_list_tot) {
+	  printk(KERN_WARNING RECENT_NAME ": ip_list_hash_size too small, resetting to default.\n");
+	  ip_list_hash_size = 0;
+	}
+
+	if(!ip_list_hash_size) {
+		ip_list_hash_size = ip_list_tot*3;
+		count = 2*2;
+		while(ip_list_hash_size > count) count = count*2;
+		ip_list_hash_size = count;
+	}
+
+#ifdef DEBUG
+	if(debug) printk(KERN_INFO RECENT_NAME ": ip_list_hash_size: %d\n",ip_list_hash_size);
+#endif
+
+	return ipt_register_match(&recent_match);
+}
+
+/* Kernel module destruction. */
+static void __exit fini(void)
+{
+	ipt_unregister_match(&recent_match);
+
+	remove_proc_entry("ipt_recent",proc_net);
+}
+
+/* Register our module with the kernel. */
+module_init(init);
+module_exit(fini);
diff -urN linux-2.5.73-bk2/net/ipv4/utils.c linux-2.5.73-bk3/net/ipv4/utils.c
--- linux-2.5.73-bk2/net/ipv4/utils.c	2003-06-22 11:32:44.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv4/utils.c	2003-06-25 04:46:49.000000000 -0700
@@ -21,26 +21,8 @@
  *		2 of the License, or (at your option) any later version.
  */
 
-#include <asm/uaccess.h>
-#include <asm/system.h>
 #include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/stat.h>
-#include <stdarg.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <net/ip.h>
-#include <net/protocol.h>
-#include <net/tcp.h>
-#include <linux/skbuff.h>
-
+#include <asm/byteorder.h>
 
 /*
  *	Convert an ASCII string to binary IP. 
diff -urN linux-2.5.73-bk2/net/ipv6/exthdrs.c linux-2.5.73-bk3/net/ipv6/exthdrs.c
--- linux-2.5.73-bk2/net/ipv6/exthdrs.c	2003-06-22 11:32:31.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv6/exthdrs.c	2003-06-25 04:46:49.000000000 -0700
@@ -432,7 +432,7 @@
 	}
 
 	pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2));
-	if (pkt_len < 0x10000) {
+	if (pkt_len <= IPV6_MAXPLEN) {
 		icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
 		return 0;
 	}
diff -urN linux-2.5.73-bk2/net/ipv6/ip6_output.c linux-2.5.73-bk3/net/ipv6/ip6_output.c
--- linux-2.5.73-bk2/net/ipv6/ip6_output.c	2003-06-22 11:32:31.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv6/ip6_output.c	2003-06-25 04:46:49.000000000 -0700
@@ -621,7 +621,7 @@
 		if (opt)
 			pktlength += opt->opt_flen + opt->opt_nflen;
 
-		if (pktlength > 0xFFFF + sizeof(struct ipv6hdr)) {
+		if (pktlength > sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
 			/* Jumbo datagram.
 			   It is assumed, that in the case of hdrincl
 			   jumbo option is supplied by user.
@@ -1264,8 +1264,8 @@
 	fragheaderlen = sizeof(struct ipv6hdr) + (opt ? opt->opt_nflen : 0);
 	maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr);
 
-	if (mtu < 65576) {
-		if (inet->cork.length + length > 0xFFFF - fragheaderlen) {
+	if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
+		if (inet->cork.length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) {
 			ipv6_local_error(sk, EMSGSIZE, fl, mtu-exthdrlen);
 			return -EMSGSIZE;
 		}
@@ -1461,7 +1461,7 @@
 	
 	*(u32*)hdr = fl->fl6_flowlabel | htonl(0x60000000);
 
-	if (skb->len < 65536)
+	if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN)
 		hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
 	else
 		hdr->payload_len = 0;
diff -urN linux-2.5.73-bk2/net/ipv6/mcast.c linux-2.5.73-bk3/net/ipv6/mcast.c
--- linux-2.5.73-bk2/net/ipv6/mcast.c	2003-06-22 11:33:14.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv6/mcast.c	2003-06-25 04:46:49.000000000 -0700
@@ -582,7 +582,7 @@
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct ipv6_mc_socklist *mc;
 	struct ip6_sf_socklist *psl;
-	int rv = 0;
+	int rv = 1;
 
 	read_lock(&ipv6_sk_mc_lock);
 	for (mc = np->ipv6_mc_list; mc; mc = mc->next) {
@@ -591,7 +591,7 @@
 	}
 	if (!mc) {
 		read_unlock(&ipv6_sk_mc_lock);
-		return 0;
+		return 1;
 	}
 	psl = mc->sflist;
 	if (!psl) {
@@ -603,8 +603,10 @@
 			if (ipv6_addr_cmp(&psl->sl_addr[i], src_addr) == 0)
 				break;
 		}
-		rv = (mc->sfmode == MCAST_INCLUDE && i < psl->sl_count);
-		rv |= (mc->sfmode == MCAST_EXCLUDE && i >= psl->sl_count);
+		if (mc->sfmode == MCAST_INCLUDE && i >= psl->sl_count);
+			rv = 0;
+		if (mc->sfmode == MCAST_EXCLUDE && i < psl->sl_count);
+			rv = 0;
 	}
 	read_unlock(&ipv6_sk_mc_lock);
 
diff -urN linux-2.5.73-bk2/net/ipv6/netfilter/ip6_tables.c linux-2.5.73-bk3/net/ipv6/netfilter/ip6_tables.c
--- linux-2.5.73-bk2/net/ipv6/netfilter/ip6_tables.c	2003-06-22 11:33:16.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv6/netfilter/ip6_tables.c	2003-06-25 04:46:49.000000000 -0700
@@ -101,10 +101,8 @@
 	unsigned int hook_entry[NF_IP6_NUMHOOKS];
 	unsigned int underflow[NF_IP6_NUMHOOKS];
 
-	char padding[SMP_ALIGN((NF_IP6_NUMHOOKS*2+2)*sizeof(unsigned int))];
-
 	/* ip6t_entry tables: one per CPU */
-	char entries[0];
+	char entries[0] ____cacheline_aligned;
 };
 
 static LIST_HEAD(ip6t_target);
@@ -1451,7 +1449,7 @@
 	int ret;
 	struct ip6t_table_info *newinfo;
 	static struct ip6t_table_info bootstrap
-		= { 0, 0, 0, { 0 }, { 0 }, { }, { } };
+		= { 0, 0, 0, { 0 }, { 0 }, { } };
 
 	newinfo = vmalloc(sizeof(struct ip6t_table_info)
 			  + SMP_ALIGN(table->table->size) * NR_CPUS);
@@ -1782,14 +1780,15 @@
 };
 
 #ifdef CONFIG_PROC_FS
-static inline int print_name(const struct ip6t_table *t,
+static inline int print_name(const char *i,
 			     off_t start_offset, char *buffer, int length,
 			     off_t *pos, unsigned int *count)
 {
 	if ((*count)++ >= start_offset) {
 		unsigned int namelen;
 
-		namelen = sprintf(buffer + *pos, "%s\n", t->name);
+		namelen = sprintf(buffer + *pos, "%s\n",
+				  i + sizeof(struct list_head));
 		if (*pos + namelen > length) {
 			/* Stop iterating */
 			return 1;
@@ -1807,7 +1806,7 @@
 	if (down_interruptible(&ip6t_mutex) != 0)
 		return 0;
 
-	LIST_FIND(&ip6t_tables, print_name, struct ip6t_table *,
+	LIST_FIND(&ip6t_tables, print_name, char *,
 		  offset, buffer, length, &pos, &count);
 
 	up(&ip6t_mutex);
@@ -1816,6 +1815,46 @@
 	*start=(char *)((unsigned long)count-offset);
 	return pos;
 }
+
+static int ip6t_get_targets(char *buffer, char **start, off_t offset, int length)
+{
+	off_t pos = 0;
+	unsigned int count = 0;
+
+	if (down_interruptible(&ip6t_mutex) != 0)
+		return 0;
+
+	LIST_FIND(&ip6t_target, print_name, char *,
+		  offset, buffer, length, &pos, &count);
+
+	up(&ip6t_mutex);
+
+	*start = (char *)((unsigned long)count - offset);
+	return pos;
+}
+
+static int ip6t_get_matches(char *buffer, char **start, off_t offset, int length)
+{
+	off_t pos = 0;
+	unsigned int count = 0;
+
+	if (down_interruptible(&ip6t_mutex) != 0)
+		return 0;
+
+	LIST_FIND(&ip6t_match, print_name, char *,
+		  offset, buffer, length, &pos, &count);
+
+	up(&ip6t_mutex);
+
+	*start = (char *)((unsigned long)count - offset);
+	return pos;
+}
+
+static struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] =
+{ { "ip6_tables_names", ip6t_get_tables },
+  { "ip6_tables_targets", ip6t_get_targets },
+  { "ip6_tables_matches", ip6t_get_matches },
+  { NULL, NULL} };
 #endif /*CONFIG_PROC_FS*/
 
 static int __init init(void)
@@ -1841,13 +1880,19 @@
 #ifdef CONFIG_PROC_FS
 	{
 		struct proc_dir_entry *proc;
-		proc = proc_net_create("ip6_tables_names", 0,
-					ip6t_get_tables);
-		if (!proc) {
-			nf_unregister_sockopt(&ip6t_sockopts);
-			return -ENOMEM;
+		int i;
+
+		for (i = 0; ip6t_proc_entry[i].name; i++) {
+			proc = proc_net_create(ip6t_proc_entry[i].name, 0,
+					       ip6t_proc_entry[i].get_info);
+			if (!proc) {
+				while (--i >= 0)
+				       proc_net_remove(ip6t_proc_entry[i].name);
+				nf_unregister_sockopt(&ip6t_sockopts);
+				return -ENOMEM;
+			}
+			proc->owner = THIS_MODULE;
 		}
-		proc->owner = THIS_MODULE;
 	}
 #endif
 
@@ -1859,7 +1904,11 @@
 {
 	nf_unregister_sockopt(&ip6t_sockopts);
 #ifdef CONFIG_PROC_FS
-	proc_net_remove("ip6_tables_names");
+	{
+		int i;
+		for (i = 0; ip6t_proc_entry[i].name; i++)
+			proc_net_remove(ip6t_proc_entry[i].name);
+	}
 #endif
 }
 
diff -urN linux-2.5.73-bk2/net/ipv6/reassembly.c linux-2.5.73-bk3/net/ipv6/reassembly.c
--- linux-2.5.73-bk2/net/ipv6/reassembly.c	2003-06-22 11:32:39.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv6/reassembly.c	2003-06-25 04:46:49.000000000 -0700
@@ -425,7 +425,7 @@
 	end = offset + (ntohs(skb->nh.ipv6h->payload_len) -
 			((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
 
-	if ((unsigned int)end >= 65536) {
+	if ((unsigned int)end > IPV6_MAXPLEN) {
  		icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw);
  		return;
 	}
@@ -597,7 +597,7 @@
 
 	/* Unfragmented part is taken from the first segment. */
 	payload_len = (head->data - head->nh.raw) - sizeof(struct ipv6hdr) + fq->len - sizeof(struct frag_hdr);
-	if (payload_len > 65535)
+	if (payload_len > IPV6_MAXPLEN)
 		goto out_oversize;
 
 	/* Head of list must not be cloned. */
diff -urN linux-2.5.73-bk2/net/ipv6/route.c linux-2.5.73-bk3/net/ipv6/route.c
--- linux-2.5.73-bk2/net/ipv6/route.c	2003-06-25 04:46:44.000000000 -0700
+++ linux-2.5.73-bk3/net/ipv6/route.c	2003-06-25 04:46:49.000000000 -0700
@@ -606,13 +606,13 @@
 		mtu = ip6_rt_min_advmss;
 
 	/*
-	 * Maximal non-jumbo IPv6 payload is 65535 and 
-	 * corresponding MSS is 65535 - tcp_header_size. 
-	 * 65535 is also valid and means: "any MSS, 
+	 * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and 
+	 * corresponding MSS is IPV6_MAXPLEN - tcp_header_size. 
+	 * IPV6_MAXPLEN is also valid and means: "any MSS, 
 	 * rely only on pmtu discovery"
 	 */
-	if (mtu > 65535 - sizeof(struct tcphdr))
-		mtu = 65535;
+	if (mtu > IPV6_MAXPLEN - sizeof(struct tcphdr))
+		mtu = IPV6_MAXPLEN;
 	return mtu;
 }
 
