diff -u --recursive --new-file v2.4.4/linux/CREDITS linux/CREDITS
--- v2.4.4/linux/CREDITS	Fri Apr 20 16:23:12 2001
+++ linux/CREDITS	Sun May 20 12:11:38 2001
@@ -221,6 +221,14 @@
 S: 62-300 Wrzesnia
 S: Poland
 
+N: Fred Barnes
+E: frmb2@ukc.ac.uk
+D: Various parport/ppdev hacks and fixes
+S: Computing Lab, The University
+S: Canterbury, KENT
+S: CT2 7NF
+S: England
+
 N: Paul Barton-Davis
 E: pbd@op.net
 D: Driver for WaveFront soundcards (Turtle Beach Maui, Tropez, Tropez+)
@@ -1111,8 +1119,10 @@
 S: Germany
 
 N: Christoph Hellwig
-E: chhellwig@gmx.net
-D: Sound/OSS hacking
+E: hch@caldera.de
+E: hch@infradead.org
+D: misc driver & makefile hacking
+D: freevxfs driver
 S: Triftstraße 26
 S: 38644 Goslar
 S: Germany
@@ -1663,6 +1673,7 @@
 N: Jamie Lokier
 E: jamie@imbolc.ucc.ie
 D: Reboot-through-BIOS for broken 486 motherboards
+D: Some parport fixes
 S: 11 Goodson Walk
 S: Marston
 S: Oxford
@@ -1869,10 +1880,13 @@
 
 N: Arnaldo Carvalho de Melo
 E: acme@conectiva.com.br
-W: http://www.conectiva.com.br/~acme
+E: acme@gnu.org
+W: http://bazar.conectiva.com.br/~acme
+W: http://advogato.org/person/acme
+P: 1024D/9224DF01 D5DF E3BB E3C8 BCBB F8AD  841A B6AB 4681 9224 DF01
 D: wanrouter hacking
-D: USB hacking
-D: miscellaneous Makefile & Config.in fixes
+D: misc Makefile, Config.in, drivers and network stacks fixes
+D: IPX Maintainer
 D: Cyclom 2X synchronous card driver
 D: i18n for minicom, net-tools, util-linux, fetchmail, etc
 S: Conectiva S.A.
@@ -2880,7 +2894,7 @@
 S: USA
 
 N: Tim Waugh
-E: tim@cyberelk.demon.co.uk
+E: tim@cyberelk.net
 D: Co-architect of the parallel-port sharing system
 S: 17 Curling Vale
 S: GUILDFORD
diff -u --recursive --new-file v2.4.4/linux/Documentation/Changes linux/Documentation/Changes
--- v2.4.4/linux/Documentation/Changes	Wed Apr 11 19:02:27 2001
+++ linux/Documentation/Changes	Sat May 19 17:43:05 2001
@@ -31,7 +31,7 @@
 Eine deutsche Version dieser Datei finden Sie unter
 <http://www.stefan-winter.de/Changes-2.4.0.txt>.
 
-Last updated: April 6, 2001
+Last updated: May 9, 2001
 
 Chris Ricker (kaboom@gatech.edu or chris.ricker@genetics.utah.edu).
 
@@ -71,7 +71,7 @@
 information about their gcc version requirements from another source.
 
 The recommended compiler for the kernel is egcs 1.1.2 (gcc 2.91.66), and it
-should be used when you need absolute stability. You may use gcc 2.95.2
+should be used when you need absolute stability. You may use gcc 2.95.x
 instead if you wish, although it may cause problems. Later versions of gcc
 have not received much testing for Linux kernel compilation, and there are
 almost certainly bugs (mainly, but not exclusively, in the kernel) that
@@ -83,9 +83,9 @@
 be compiled with it.
 
 In addition, please pay attention to compiler optimization.  Anything
-greater than -O2 may not be wise.  Similarly, if you choose to use gcc-2.95
+greater than -O2 may not be wise.  Similarly, if you choose to use gcc-2.95.x
 or derivatives, be sure not to use -fstrict-aliasing (which, depending on
-your version of gcc 2.95, may necessitate using -fno-strict-aliasing).
+your version of gcc 2.95.x, may necessitate using -fno-strict-aliasing).
 
 Make
 ----
@@ -268,15 +268,15 @@
 ------------------------
 o  <ftp://sourceware.cygnus.com/pub/gcc/releases/egcs-1.1.2/egcs-1.1.2.tar.bz2>
 
-gcc 2.95.2
+gcc 2.95.3
 ----------
-o  <ftp://ftp.gnu.org/pub/gnu/gcc/gcc-2.95.2.tar.gz>
+o  <ftp://ftp.gnu.org/pub/gnu/gcc/gcc-2.95.3.tar.gz>
 
 Gnu Make
 ********
 
 Make 3.77
---------
+---------
 o  <ftp://ftp.gnu.org/gnu/make/make-3.77.tar.gz>
 
 Binutils
diff -u --recursive --new-file v2.4.4/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.4.4/linux/Documentation/Configure.help	Fri Apr 20 16:23:12 2001
+++ linux/Documentation/Configure.help	Tue May 22 10:25:36 2001
@@ -4170,22 +4170,6 @@
 
   It is safe to say N here for now.
 
-IPv6: enable EUI-64 token format
-CONFIG_IPV6_EUI64
-  6bone, the network of computers using the IPv6 protocol, is moving
-  to a new aggregatable address format and a new link local address
-  assignment (EUI-64). Say Y if your site has upgraded already, or
-  has started to upgrade.
-
-IPv6: disable provider based addresses
-CONFIG_IPV6_NO_PB
-  Linux tries to operate correctly when your site has moved to EUI-64
-  only partially. Unfortunately, the two address formats (old:
-  "provider based" and new: "aggregatable") are incompatible. Say Y if
-  your site finished the upgrade to EUI-64, and/or you encountered
-  some problems caused by the presence of two link-local addresses on
-  an interface.
-
 IPv6: routing messages via old netlink
 CONFIG_IPV6_NETLINK
   You can say Y here to receive routing messages from the IPv6 code
@@ -5635,7 +5619,7 @@
   Default: 253
 
 Initial Bus Reset Settle Delay
-CONFIG_AIC7XXX_RESET_DELAY
+CONFIG_AIC7XXX_RESET_DELAY_MS
   The number of milliseconds to delay after an initial bus reset.
   The bus settle delay following all error recovery actions is
   dictated by the SCSI layer and is not affected by this value.
@@ -7188,7 +7172,7 @@
 
   This driver requires a specially patched pppd daemon.  The patch to
   pppd, along with binaries of a patched pppd package can be found at:
-  http://www.math.uwaterloo.ca/~mostrows
+  http://www.shoshin.uwaterloo.ca/~mostrows
  
 Wireless LAN (non-hamradio)
 CONFIG_NET_RADIO
@@ -10933,6 +10917,35 @@
   The module will be called ov511.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
+Philips webcam support
+CONFIG_USB_PWC
+  Say Y or M here if you want to use one of these Philips USB webcams:
+  PCA645, PCA646, PCVC675, PCVC680, PCVC690, PCVC730, PCVC740, or 
+  the Askey VC010. The PCA635, PCVC665 and PCVC720 are not 
+  supported by this driver and never will be.
+
+  This driver has an optional plugin, which is distributed as a 
+  binary module only. It contains code that allow you to use 
+  higher resolutions and framerates but may not be distributed
+  as source. But even without this plugin you can these cams 
+  for most applications.
+
+  See Documentation/usb/philips.txt for more information and 
+  installation instructions.
+
+  The built-in microphone is enabled by selecting USB Audio support.
+
+  This driver uses the Video For Linux API. You must say Y or M to
+  "Video For Linux" (under Character Devices) to use this driver.
+  Information on this API and pointers to "v4l" programs may be found
+  on the WWW at http://roadrunner.swansea.uk.linux.org/v4l.shtml .
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called pwc.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
+
+
 USB ADMtek Pegasus-based ethernet device support
 CONFIG_USB_PEGASUS
   Say Y if you want to use your USB ethernet device. Supported
@@ -11657,6 +11670,23 @@
   The module is called hpfs.o. If you want to compile it as a module,
   say M here and read Documentation/modules.txt. If unsure, say N.
 
+FreeVxFS file system support (VERITAS VxFS(TM) compatible)
+CONFIG_VXFS_FS
+  FreeVxFS is a filesystem driver that support the VERITAS VxFS(TM)
+  filesystem format.  VERITAS VxFS(TM) is the standard filesystem
+  of SCO UnixWare (and possibly others) and optionally available
+  for Sunsoft Solaris, HP-UX and many other operating systems.
+  Currently only readonly access is supported.
+
+  NOTE:	the filesystem type as used by mount(1), mount(2) and fstab(5)
+	is 'vxfs' as it describes the filesystem format, not the
+	actual driver.
+
+  This file system is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module is called freevxfs.o. If you want to compile it as a module,
+  say M here and read Documentation/modules.txt. If unsure, say N.
+
 NTFS support (read only)
 CONFIG_NTFS_FS
   NTFS is the file system of Microsoft Windows NT. Say Y if you want
@@ -12081,10 +12111,7 @@
   The nls settings can be changed at mount time, if your smbmount
   supports that, using the codepage and iocharset parameters.
 
-  Currently no smbmount distributed with samba supports this, it is
-  assumed future versions will. In the meantime you can get an
-  unofficial patch for samba 2.0.7 from:
-  http://www.hojdpunkten.ac.se/054/samba/index.html
+  smbmount from samba 2.2.0 or later supports this.
 
 nls support setting
 CONFIG_SMB_NLS_REMOTE
@@ -12096,10 +12123,7 @@
   The nls settings can be changed at mount time, if your smbmount
   supports that, using the codepage and iocharset parameters.
 
-  Currently no smbmount distributed with samba supports this, it is
-  assumed future versions will. In the meantime you can get an
-  unofficial patch for samba 2.0.7 from:
-  http://www.hojdpunkten.ac.se/054/samba/index.html
+  smbmount from samba 2.2.0 or later supports this.
 
 Coda file system support (advanced network fs)
 CONFIG_CODA_FS
diff -u --recursive --new-file v2.4.4/linux/Documentation/DMA-mapping.txt linux/Documentation/DMA-mapping.txt
--- v2.4.4/linux/Documentation/DMA-mapping.txt	Thu Apr 19 08:38:48 2001
+++ linux/Documentation/DMA-mapping.txt	Sat May 19 17:43:05 2001
@@ -240,6 +240,7 @@
 
 where dev, size are the same as in the above call and cpu_addr and
 dma_handle are the values pci_alloc_consistent returned to you.
+This function may not be called in interrupt context.
 
 If your driver needs lots of smaller memory regions, you can write
 custom code to subdivide pages returned by pci_alloc_consistent,
@@ -262,7 +263,8 @@
 sleeping context (f.e. in_interrupt is true or while holding SMP
 locks), pass SLAB_ATOMIC.  If your device has no boundary crossing
 restrictions, pass 0 for alloc; passing 4096 says memory allocated
-from this pool must not cross 4KByte boundaries.
+from this pool must not cross 4KByte boundaries (but at that time it
+may be better to go for pci_alloc_consistent directly instead).
 
 Allocate memory from a pci pool like this:
 
@@ -270,21 +272,23 @@
 
 flags are SLAB_KERNEL if blocking is permitted (not in_interrupt nor
 holding SMP locks), SLAB_ATOMIC otherwise.  Like pci_alloc_consistent,
-this returns two values, cpu_addr and dma_handle,
+this returns two values, cpu_addr and dma_handle.
 
 Free memory that was allocated from a pci_pool like this:
 
 	pci_pool_free(pool, cpu_addr, dma_handle);
 
 where pool is what you passed to pci_pool_alloc, and cpu_addr and
-dma_handle are the values pci_pool_alloc returned.
+dma_handle are the values pci_pool_alloc returned. This function
+may be called in interrupt context.
 
 Destroy a pci_pool by calling:
 
 	pci_pool_destroy(pool);
 
 Make sure you've called pci_pool_free for all memory allocated
-from a pool before you destroy the pool.
+from a pool before you destroy the pool. This function may not
+be called in interrupt context.
 
 			DMA Direction
 
diff -u --recursive --new-file v2.4.4/linux/Documentation/DocBook/Makefile linux/Documentation/DocBook/Makefile
--- v2.4.4/linux/Documentation/DocBook/Makefile	Fri Apr  6 10:42:55 2001
+++ linux/Documentation/DocBook/Makefile	Mon May  7 12:14:56 2001
@@ -95,6 +95,7 @@
 		$(TOPDIR)/kernel/pm.c \
 		$(TOPDIR)/kernel/ksyms.c \
 		$(TOPDIR)/kernel/kmod.c \
+		$(TOPDIR)/kernel/module.c \
 		$(TOPDIR)/kernel/printk.c \
 		$(TOPDIR)/kernel/sched.c \
 		$(TOPDIR)/kernel/sysctl.c \
diff -u --recursive --new-file v2.4.4/linux/Documentation/DocBook/deviceiobook.tmpl linux/Documentation/DocBook/deviceiobook.tmpl
--- v2.4.4/linux/Documentation/DocBook/deviceiobook.tmpl	Fri Apr  6 10:42:55 2001
+++ linux/Documentation/DocBook/deviceiobook.tmpl	Tue May  1 14:20:25 2001
@@ -171,7 +171,7 @@
 	with 'isa_' and are <function>isa_readb</function>,
 	<function>isa_writeb</function>, <function>isa_readw</function>, 
 	<function>isa_writew</function>, <function>isa_readl</function>,
-	<function>isa_writel</function), <function>isa_memcpy_fromio</function>
+	<function>isa_writel</function>, <function>isa_memcpy_fromio</function>
 	and <function>isa_memcpy_toio</function>
       </para>
       <para>
diff -u --recursive --new-file v2.4.4/linux/Documentation/DocBook/kernel-api.tmpl linux/Documentation/DocBook/kernel-api.tmpl
--- v2.4.4/linux/Documentation/DocBook/kernel-api.tmpl	Fri Apr  6 10:42:55 2001
+++ linux/Documentation/DocBook/kernel-api.tmpl	Mon May  7 12:14:56 2001
@@ -140,8 +140,13 @@
   </chapter>
 
   <chapter id="modload">
-     <title>Module Loading</title>
+     <title>Module Support</title>
+     <sect1><title>Module Loading</title>
 !Ekernel/kmod.c
+     </sect1>
+     <sect1><title>Inter Module support</title>
+!Ekernel/module.c
+     </sect1>
   </chapter>
 
   <chapter id="hardware">
diff -u --recursive --new-file v2.4.4/linux/Documentation/DocBook/kernel-hacking.tmpl linux/Documentation/DocBook/kernel-hacking.tmpl
--- v2.4.4/linux/Documentation/DocBook/kernel-hacking.tmpl	Fri Apr  6 10:42:55 2001
+++ linux/Documentation/DocBook/kernel-hacking.tmpl	Sat May 19 17:43:05 2001
@@ -713,7 +713,8 @@
    </para>
    <para>
    Static data structures marked as <type>__initdata</type> must be initialised
-   (as opposed to ordinary static data which is zeroed BSS).
+   (as opposed to ordinary static data which is zeroed BSS) and cannot be 
+   <type>const</type>.
    </para> 
 
   </sect1>
diff -u --recursive --new-file v2.4.4/linux/Documentation/DocBook/kernel-locking.tmpl linux/Documentation/DocBook/kernel-locking.tmpl
--- v2.4.4/linux/Documentation/DocBook/kernel-locking.tmpl	Fri Apr  6 10:42:55 2001
+++ linux/Documentation/DocBook/kernel-locking.tmpl	Sat May 19 17:43:05 2001
@@ -760,8 +760,11 @@
     </para>
 
     <para>
-      Any atomic operation is defined to act as a memory barrier
-      (ie. as per the <function>mb()</function> macro).  Also,
+      Some atomic operations are defined to act as a memory barrier
+      (ie. as per the <function>mb()</function> macro, but if in
+      doubt, be explicit.
+      <!-- Rusty Russell 2 May 2001, 2.4.4 -->
+      Also,
       spinlock operations act as partial barriers: operations after
       gaining a spinlock will never be moved to precede the
       <function>spin_lock()</function> call, and operations before
diff -u --recursive --new-file v2.4.4/linux/Documentation/cris/README linux/Documentation/cris/README
--- v2.4.4/linux/Documentation/cris/README	Fri Apr  6 10:42:55 2001
+++ linux/Documentation/cris/README	Tue May  1 16:04:56 2001
@@ -1,13 +1,19 @@
 Linux 2.4 on the CRIS architecture
 ==================================
-$Id: README,v 1.6 2001/02/21 15:27:25 bjornw Exp $
+$Id: README,v 1.7 2001/04/19 12:38:32 bjornw Exp $
 
 This is a port of Linux 2.4 to Axis Communications ETRAX 100LX embedded 
 network CPU. For more information about CRIS and ETRAX please see further
 below.
 
-<to come: instructions on how to grab the right gcc, compiling and booting>
+In order to compile this you need a version of gcc with support for the
+ETRAX chip family. Please see this link for more information on how to 
+download the compiler and other tools useful when building and booting
+software for the ETRAX platform:
 
+http://developer.axis.com/doc/software/devboard_lx/install-howto.html
+
+<more specific information should come in this document later>
 
 What is CRIS ?
 --------------
@@ -97,7 +103,7 @@
 ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000 Axis Communications AB
 eth0 initialized
 eth0: changed MAC to 00:40:8C:CD:00:00
-ETRAX 100LX serial-driver $Revision: 1.6 $, (c) 2000 Axis Communications AB
+ETRAX 100LX serial-driver $Revision: 1.7 $, (c) 2000 Axis Communications AB
 ttyS0 at 0xb0000060 is a builtin UART with DMA
 ttyS1 at 0xb0000068 is a builtin UART with DMA
 ttyS2 at 0xb0000070 is a builtin UART with DMA
@@ -127,7 +133,7 @@
 Hostname is bbox1
 Telnetd starting, using port 23.
   using /bin/sash as shell.
-sftpd[15]: sftpd $Revision: 1.6 $ starting up
+sftpd[15]: sftpd $Revision: 1.7 $ starting up
 
 
 
diff -u --recursive --new-file v2.4.4/linux/Documentation/devices.txt linux/Documentation/devices.txt
--- v2.4.4/linux/Documentation/devices.txt	Sat Dec 30 11:26:10 2000
+++ linux/Documentation/devices.txt	Sat May 19 17:43:05 2001
@@ -660,6 +660,12 @@
 
  29 char	Universal frame buffer
 		  0 = /dev/fb0		First frame buffer
+		  1 = /dev/fb1		Second frame buffer
+		    ...
+		 31 = /dev/fb31		32nd frame buffer
+
+		Backward compatibility aliases {2.6}
+
 		 32 = /dev/fb1		Second frame buffer
 		    ...
 		224 = /dev/fb7		Eighth frame buffer
@@ -765,7 +771,7 @@
  36 char	Netlink support
 		  0 = /dev/route	Routing, device updates, kernel to user
 		  1 = /dev/skip		enSKIP security cache control
-		  3 = /dec/fwmonitor	Firewall packet copies
+		  3 = /dev/fwmonitor	Firewall packet copies
 		 16 = /dev/tap0		First Ethertap device
 		    ...
 		 31 = /dev/tap15	16th Ethertap device
@@ -2436,7 +2442,7 @@
 
 224 char	A2232 serial card
 		  0 = /dev/ttyY0		First A2232 port
-		  1 = /dev/cuy0			Second A2232 port
+		  1 = /dev/ttyY1		Second A2232 port
 		    ...
 
 225 char	A2232 serial card (alternate devices)
diff -u --recursive --new-file v2.4.4/linux/Documentation/ioctl-number.txt linux/Documentation/ioctl-number.txt
--- v2.4.4/linux/Documentation/ioctl-number.txt	Fri Mar  2 17:50:22 2001
+++ linux/Documentation/ioctl-number.txt	Sat May 19 17:54:14 2001
@@ -139,7 +139,7 @@
 'p'	00-3F	linux/mc146818rtc.h
 'p'	40-7F	linux/nvram.h
 'p'	80-9F				user-space parport
-					<mailto:tim@cyberelk.demon.co.uk>
+					<mailto:tim@cyberelk.net>
 'q'	00-1F	linux/videotext.h	conflict!
 'q'	80-FF				Internet PhoneJACK, Internet LineJACK
 					<http://www.quicknet.net>
diff -u --recursive --new-file v2.4.4/linux/Documentation/networking/8139too.txt linux/Documentation/networking/8139too.txt
--- v2.4.4/linux/Documentation/networking/8139too.txt	Thu Apr 19 09:32:48 2001
+++ linux/Documentation/networking/8139too.txt	Mon May  7 14:13:19 2001
@@ -185,6 +185,13 @@
 Change History
 --------------
 
+Version 0.9.17 - May 7, 2001
+
+* Fix chipset wakeup bug which prevent media connection for 8139B
+* Print out "media is unconnected..." instead of 
+  "partner ability 0000"
+
+
 Version 0.9.16 - April 14, 2001
 
 * Complete MMIO audit, disable read-after-every-write
diff -u --recursive --new-file v2.4.4/linux/Documentation/networking/cops.txt linux/Documentation/networking/cops.txt
--- v2.4.4/linux/Documentation/networking/cops.txt	Thu Jan  6 14:46:18 2000
+++ linux/Documentation/networking/cops.txt	Wed May 16 10:31:27 2001
@@ -1,5 +1,5 @@
 Text File for the COPS LocalTalk Linux driver (cops.c).
-	By Jay Schulist <jschlst@turbolinux.com>
+	By Jay Schulist <jschlst@samba.org>
 
 This driver has two modes and they are: Dayna mode and Tangent mode.
 Each mode corresponds with the type of card. It has been found
diff -u --recursive --new-file v2.4.4/linux/Documentation/networking/ethertap.txt linux/Documentation/networking/ethertap.txt
--- v2.4.4/linux/Documentation/networking/ethertap.txt	Wed Aug 23 09:30:13 2000
+++ linux/Documentation/networking/ethertap.txt	Wed May 16 10:31:27 2001
@@ -7,7 +7,7 @@
 Ethertap programming mini-HOWTO
 -------------------------------
 
-The ethertap driver was written by Jay Schulist <jschlst@turbolinux.com>,
+The ethertap driver was written by Jay Schulist <jschlst@samba.org>,
 you should contact him for further information. This document was written by
 bert hubert <bert.hubert@netherlabs.nl>. Updates are welcome.
 
diff -u --recursive --new-file v2.4.4/linux/Documentation/networking/filter.txt linux/Documentation/networking/filter.txt
--- v2.4.4/linux/Documentation/networking/filter.txt	Thu Jan  6 14:46:18 2000
+++ linux/Documentation/networking/filter.txt	Wed May 16 10:31:27 2001
@@ -1,5 +1,5 @@
 filter.txt: Linux Socket Filtering
-Written by: Jay Schulist <jschlst@turbolinux.com>
+Written by: Jay Schulist <jschlst@samba.org>
 
 Introduction
 ============
diff -u --recursive --new-file v2.4.4/linux/Documentation/networking/ip-sysctl.txt linux/Documentation/networking/ip-sysctl.txt
--- v2.4.4/linux/Documentation/networking/ip-sysctl.txt	Sun Mar 25 18:14:21 2001
+++ linux/Documentation/networking/ip-sysctl.txt	Wed May 16 10:21:45 2001
@@ -398,4 +398,117 @@
 Updated by:
 Andi Kleen
 ak@muc.de
-$Id: ip-sysctl.txt,v 1.18 2001/03/16 06:49:20 davem Exp $
+
+
+
+
+
+
+/proc/sys/net/ipv6/* Variables:
+
+IPv6 has no global variables such as tcp_*.  tcp_* settings under ipv4/ also
+apply to IPv6 [XXX?].
+
+conf/default/*:
+	Change the interface-specific default settings.
+
+
+conf/all/*:
+	Change all the interface-specific settings.  
+
+	[XXX:  Other special features than forwarding?]
+
+conf/all/forwarding - BOOLEAN
+	Enable global IPv6 forwarding between all interfaces.  
+
+	IPv4 and IPv6 work differently here; e.g. netfilter must be used 
+	to control which interfaces may forward packets and which not.
+
+	This also sets all interfaces' Host/Router setting 
+	'forwarding' to the specified value.  See below for details.
+
+	This referred to as global forwarding.
+
+conf/interface/*:
+	Change special settings per interface.
+
+	The functional behaviour for certain settings is different 
+	depending on whether local forwarding is enabled or not.
+
+accept_ra - BOOLEAN
+	Accept Router Advertisements; autoconfigure using them.
+	
+	Functional default: enabled if local forwarding is disabled.
+			    disabled if local forwarding is enabled.
+
+accept_redirects - BOOLEAN
+	Accept Redirects.
+
+	Functional default: enabled if local forwarding is disabled.
+			    disabled if local forwarding is enabled.
+
+autoconf - BOOLEAN
+	Configure link-local addresses using L2 hardware addresses.
+
+	Default: TRUE
+
+dad_transmits - INTEGER
+	The amount of Duplicate Address Detection probes to send.
+	Default: 1
+	
+forwarding - BOOLEAN
+	Configure interface-specific Host/Router behaviour.  
+
+	Note: It is recommended to have the same setting on all 
+	interfaces; mixed router/host scenarios are rather uncommon.
+
+	FALSE:
+
+	By default, Host behaviour is assumed.  This means:
+
+	1. IsRouter flag is not set in Neighbour Advertisements.
+	2. Router Solicitations are being sent when necessary.
+	3. If accept_ra is TRUE (default), accept Router 
+	   Advertisements (and do autoconfiguration).
+	4. If accept_redirects is TRUE (default), accept Redirects.
+
+	TRUE:
+
+	If local forwarding is enabled, Router behaviour is assumed. 
+	This means exactly the reverse from the above:
+
+	1. IsRouter flag is set in Neighbour Advertisements.
+	2. Router Solicitations are not sent.
+	3. Router Advertisements are ignored.
+	4. Redirects are ignored.
+
+	Default: FALSE if global forwarding is disabled (default),
+		 otherwise TRUE.
+
+hop_limit - INTEGER
+	Default Hop Limit to set.
+	Default: 64
+
+mtu - INTEGER
+	Default Maximum Transfer Unit
+	Default: 1280 (IPv6 required minimum)
+
+router_solicitation_delay - INTEGER
+	Number of seconds to wait after interface is brought up
+	before sending Router Solicitations.
+	Default: 1
+
+router_solicitation_interval - INTEGER
+	Number of seconds to wait between Router Solicitations.
+	Default: 4
+
+router_solicitations - INTEGER
+	Number of Router Solicitations to send until assuming no 
+	routers are present.
+	Default: 3
+
+IPv6 Update by:
+Pekka Savola
+pekkas@netcore.fi
+
+$Id: ip-sysctl.txt,v 1.19 2001/05/16 17:11:04 davem Exp $
diff -u --recursive --new-file v2.4.4/linux/Documentation/networking/ipddp.txt linux/Documentation/networking/ipddp.txt
--- v2.4.4/linux/Documentation/networking/ipddp.txt	Fri Jul 28 12:50:51 2000
+++ linux/Documentation/networking/ipddp.txt	Wed May 16 10:31:27 2001
@@ -1,7 +1,7 @@
 Text file for ipddp.c:
 	AppleTalk-IP Decapsulation and AppleTalk-IP Encapsulation
 
-This text file is written by Jay Schulist <jschlst@turbolinux.com>
+This text file is written by Jay Schulist <jschlst@samba.org>
 
 Introduction
 ------------
@@ -72,7 +72,7 @@
 
 Further Assistance
 -------------------
-You can contact me (Jay Schulist <jschlst@turbolinux.com>) with any
+You can contact me (Jay Schulist <jschlst@samba.org>) with any
 questions regarding decapsulation or encapsulation. Bradford W. Johnson
 <johns393@maroon.tc.umn.edu> originally wrote the ipddp.c driver for IP
 encapsulation in AppleTalk.
diff -u --recursive --new-file v2.4.4/linux/Documentation/networking/smctr.txt linux/Documentation/networking/smctr.txt
--- v2.4.4/linux/Documentation/networking/smctr.txt	Fri Jul 28 12:50:52 2000
+++ linux/Documentation/networking/smctr.txt	Wed May 16 10:31:27 2001
@@ -1,5 +1,5 @@
 Text File for the SMC TokenCard TokenRing Linux driver (smctr.c).
-        By Jay Schulist <jschlst@turbolinux.com>
+        By Jay Schulist <jschlst@samba.org>
 
 The Linux SMC Token Ring driver works with the SMC TokenCard Elite (8115T) 
 ISA and SMC TokenCard Elite/A (8115T/A) MCA adapters.
@@ -22,7 +22,7 @@
 following command will suffice for most:
 
 # modprobe smctr
-smctr.c: v1.00 12/6/99 by jschlst@turbolinux.com
+smctr.c: v1.00 12/6/99 by jschlst@samba.org
 tr0: SMC TokenCard 8115T at Io 0x300, Irq 10, Rom 0xd8000, Ram 0xcc000.
 
 Now just setup the device via ifconfig and set and routes you may have. After
diff -u --recursive --new-file v2.4.4/linux/Documentation/networking/tms380tr.txt linux/Documentation/networking/tms380tr.txt
--- v2.4.4/linux/Documentation/networking/tms380tr.txt	Fri Jul 28 12:50:52 2000
+++ linux/Documentation/networking/tms380tr.txt	Wed May 16 10:31:27 2001
@@ -1,5 +1,5 @@
 Text file for the Linux SysKonnect Token Ring ISA/PCI Adapter Driver.
-	Text file by: Jay Schulist <jschlst@turbolinux.com>
+	Text file by: Jay Schulist <jschlst@samba.org>
 
 The Linux SysKonnect Token Ring driver works with the SysKonnect TR4/16(+) ISA,
 SysKonnect TR4/16(+) PCI, SysKonnect TR4/16 PCI, and older revisions of the
diff -u --recursive --new-file v2.4.4/linux/Documentation/parport.txt linux/Documentation/parport.txt
--- v2.4.4/linux/Documentation/parport.txt	Fri Apr  6 10:42:51 2001
+++ linux/Documentation/parport.txt	Sat May 19 17:54:14 2001
@@ -261,4 +261,4 @@
     io=0x378 irq=7 dma=3 (for DMA)
 --
 Philip.Blundell@pobox.com
-tim@cyberelk.demon.co.uk
+tim@cyberelk.net
diff -u --recursive --new-file v2.4.4/linux/Documentation/pci.txt linux/Documentation/pci.txt
--- v2.4.4/linux/Documentation/pci.txt	Sun Sep 17 09:45:06 2000
+++ linux/Documentation/pci.txt	Sat May 19 17:43:05 2001
@@ -60,8 +60,8 @@
 	remove		Pointer to a function which gets called whenever a device
 			being handled by this driver is removed (either during
 			deregistration of the driver or when it's manually pulled
-			out of a hot-pluggable slot). This function can be called
-			from interrupt context.
+			out of a hot-pluggable slot). This function always gets
+			called from process context, so it can sleep.
 	suspend,	Power management hooks -- called when the device goes to
 	resume		sleep or is resumed.
 
diff -u --recursive --new-file v2.4.4/linux/Documentation/rtc.txt linux/Documentation/rtc.txt
--- v2.4.4/linux/Documentation/rtc.txt	Thu Jan  4 12:50:17 2001
+++ linux/Documentation/rtc.txt	Sat May 19 17:43:05 2001
@@ -89,7 +89,7 @@
 #include <unistd.h>
 #include <errno.h>
 
-void main(void) {
+int main(void) {
 
 int i, fd, retval, irqcount = 0;
 unsigned long tmp, data;
@@ -277,5 +277,6 @@
 								 irqcount);
 
 close(fd);
+return 0;
 
 } /* end main */
diff -u --recursive --new-file v2.4.4/linux/Documentation/scsi-generic.txt linux/Documentation/scsi-generic.txt
--- v2.4.4/linux/Documentation/scsi-generic.txt	Thu Apr 12 12:03:50 2001
+++ linux/Documentation/scsi-generic.txt	Tue May  1 16:04:56 2001
@@ -238,8 +238,8 @@
 open(const char * filename, int flags)
 --------------------------------------
 The filename should be an 'sg' device such as
-/dev/sg[a-z]
 /dev/sg[0,1,2,...]
+/dev/sg[a-z]             <<< now deprecated >>>
 or a symbolic link to one of these. [Devfs has its own sub-directory for
 sg devices with entries like: /dev/scsi/host1/bus2/target3/lun4/generic .]
 It seems as though SCSI devices are allocated to sg minor numbers in the
diff -u --recursive --new-file v2.4.4/linux/Documentation/sound/MAD16 linux/Documentation/sound/MAD16
--- v2.4.4/linux/Documentation/sound/MAD16	Mon Aug 23 10:23:23 1999
+++ linux/Documentation/sound/MAD16	Tue May  1 16:05:00 2001
@@ -1,3 +1,5 @@
+(This recipe has been edited to update the configuration symbols.)
+
 From: Shaw Carruthers <shaw@shawc.demon.co.uk>
 
 I have been using mad16 sound for some time now with no problems, current
@@ -14,9 +16,9 @@
 .config has:
 
 CONFIG_SOUND=m
-CONFIG_ADLIB=m
-CONFIG_MAD16=m
-CONFIG_YM3812=m
+CONFIG_SOUND_ADLIB=m
+CONFIG_SOUND_MAD16=m
+CONFIG_SOUND_YM3812=m
 
 modules.conf has:
 
diff -u --recursive --new-file v2.4.4/linux/Documentation/sound/Opti linux/Documentation/sound/Opti
--- v2.4.4/linux/Documentation/sound/Opti	Wed Mar  8 11:37:03 2000
+++ linux/Documentation/sound/Opti	Tue May  1 16:05:00 2001
@@ -29,21 +29,21 @@
 
 Sound card support should be enabled as a module (chose m).
 Answer 'm' for  these items:
-  Generic OPL2/OPL3 FM synthesizer support			(CONFIG_ADLIB)
-  Microsoft Sound System support				(CONFIG_MSS)
-  Support for OPTi MAD16 and/or Mozart based cards	 	(CONFIG_MAD16)
-  FM synthesizer (YM3812/OPL-3) support				(CONFIG_YM3812)
+  Generic OPL2/OPL3 FM synthesizer support		(CONFIG_SOUND_ADLIB)
+  Microsoft Sound System support			(CONFIG_SOUND_MSS)
+  Support for OPTi MAD16 and/or Mozart based cards	(CONFIG_SOUND_MAD16)
+  FM synthesizer (YM3812/OPL-3) support			(CONFIG_SOUND_YM3812)
 
 The configuration menu may ask for addresses, IRQ lines or DMA
 channels. If the card is used as a module the module loading
 options will override these values.
 
 For the OPTi 931 you can answer 'n' to:
-  Support MIDI in older MAD16 based cards (requires SB)		(CONFIG_MAD16_OLDCARD)
+  Support MIDI in older MAD16 based cards (requires SB)	(CONFIG_SOUND_MAD16_OLDCARD)
 If you do need MIDI support in a Mozart or C928 based card you
 need to answer 'm' to the above question. In that case you will
 also need to answer 'm' to:
-  '100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' (CONFIG_SB)
+  '100% Sound Blaster compatibles (SB16/32/64, ESS, Jazz16) support' (CONFIG_SOUND_SB)
 
 Go on and compile your kernel and modules. Install the modules. Run depmod -a.
 
diff -u --recursive --new-file v2.4.4/linux/Documentation/sound/cs46xx linux/Documentation/sound/cs46xx
--- v2.4.4/linux/Documentation/sound/cs46xx	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/sound/cs46xx	Sat May 19 17:43:05 2001
@@ -0,0 +1,138 @@
+
+Documentation for the Cirrus Logic/Crystal SoundFusion cs46xx/cs4280 audio 
+controller chips (2001/05/11)
+
+The cs46xx audio driver supports the DSP line of Cirrus controllers. 
+Specifically, the cs4610, cs4612, cs4614, cs4622, cs4624, cs4630 and the cs4280
+products.  This driver uses the generic ac97_codec driver for AC97 codec
+support.  
+
+
+Features:
+
+Full Duplex Playback/Capture supported from 8k-48k.
+16Bit Signed LE & 8Bit Unsigned, with Mono or Stereo supported.
+
+APM/PM - 2.2.x PM is enabled and functional. APM can also
+be enabled for 2.4.x by modifying the CS46XX_ACPI_SUPPORT macro
+definition.
+
+DMA playback buffer size is configurable from 16k (defaultorder=2) up to 2Meg 
+(defaultorder=11).  DMA capture buffer size is fixed at a single 4k page as
+two 2k fragments.
+
+MMAP seems to work well with QuakeIII, and test XMMS plugin.
+
+Myth2 works, but the polling logic is not fully correct, but is functional.
+
+The 2.4.4-ac6 gameport code in the cs461x joystick driver has been tested 
+with a Microsoft Sidewinder joystick (cs461x.o and sidewinder.o).  This 
+audio driver must be loaded prior to the joystick driver to enable the
+DSP task image supporting the joystick device.
+
+
+Limitations:
+
+SPDIF is currently not supported.
+
+Primary codec support only.  No secondary codec support is implemented.
+
+
+
+NOTES:
+
+Hercules Game Theatre XP - the EGPIO2 pin controls the external Amp,
+and has been tested.
+Module parameter hercules_egpio_disable set to 1, will force a 0 to EGPIODR
+to disable the external amplifier.
+
+VTB Santa Cruz - the GPIO7/GPIO8 on the Secondary Codec control
+the external amplifier for the "back" speakers, since we do not
+support the secondary codec then this external amp is not
+turned on.  The primary codec external amplifier is supported but
+note that the AC97 EAPD bit is inverted logic (amp_voyetra()).
+
+DMA buffer size - there are issues with many of the Linux applications
+concerning the optimal buffer size.  Several applications request a 
+certain fragment size and number and then do not verify that the driver
+has the ability to support the requested configuration.  
+SNDCTL_DSP_SETFRAGMENT ioctl is used to request a fragment size and
+number of fragments.  Some applications exit if an error is returned
+on this particular ioctl. Therefore, in alignment with the other OSS audio 
+drivers, no error is returned when a SETFRAGs IOCTL is received, but the 
+values passed from the app are not used in any buffer calculation 
+(ossfragshift/ossmaxfrags are not used).
+Use the "defaultorder=N" module parameter to change the buffer size if
+you have an application that requires a specific number of fragments
+or a specific buffer size (see below).
+
+Debug Interface
+---------------
+There is an ioctl debug interface to allow runtime modification of the 
+debug print levels.  This debug interface code can be disabled from the 
+compilation process with commenting the following define:
+#define CSDEBUG_INTERFACE 1
+There is also a debug print methodolgy to select printf statements from
+different areas of the driver.  A debug print level is also used to allow
+additional printfs to be active.  Comment out the following line in the
+driver to disable compilation of the CS_DBGOUT print statements:
+#define CSDEBUG 1
+ 
+Please see the defintions for cs_debuglevel and cs_debugmask for additional
+information on the debug levels and sections.
+
+There is also a csdbg executable to allow runtime manipulation of these 
+parameters.  for a copy email: twoller@crystal.cirrus.com
+
+
+
+MODULE_PARMS definitions
+------------------------
+MODULE_PARM(defaultorder, "i");
+defaultorder=N
+where N is a value from 1 to 12
+The buffer order determines the size of the dma buffer for the driver.
+under Linux, a smaller buffer allows more responsiveness from many of the 
+applications (e.g. games).  A larger buffer allows some of the apps (esound) 
+to not underrun the dma buffer as easily.  As default, use 32k (order=3)
+rather than 64k as some of the games work more responsively.
+(2^N) * PAGE_SIZE = allocated buffer size
+
+MODULE_PARM(cs_debuglevel, "i");
+MODULE_PARM(cs_debugmask, "i");
+cs_debuglevel=N
+cs_debugmask=0xMMMMMMMM
+where N is a value from 0 (no debug printfs), to 9 (maximum)
+0xMMMMMMMM is a debug mask corresponding to the CS_xxx bits (see driver source).
+
+MODULE_PARM(hercules_egpio_disable, "i");
+hercules_egpio_disable=N
+where N is a 0 (enable egpio), or a 1 (disable egpio support)
+
+MODULE_PARM(initdelay, "i");
+initdelay=N
+This value is used to determine the millescond delay during the initialization
+code prior to powering up the PLL.  On laptops this value can be used to
+assist with errors on resume, mostly with IBM laptops.  Basically, if the 
+system is booted under battery power then the mdelay()/udelay() functions fail to 
+properly delay the required time.  Also, if the system is booted under AC power
+and then the power removed, the mdelay()/udelay() functions will not delay properly.
+ 
+MODULE_PARM(powerdown, "i");
+powerdown=N
+where N is 0 (disable any powerdown of the internal blocks) or 1 (enable powerdown)
+
+
+MODULE_PARM(external_amp, "i");
+external_amp=1
+if N is set to 1, then force enabling the EAPD support in the primary AC97 codec.
+override the detection logic and force the external amp bit in the AC97 0x26 register
+to be reset (0).  EAPD should be 0 for powerup, and 1 for powerdown.  The VTB Santa Cruz
+card has inverted logic, so there is a special function for these cards.
+
+MODULE_PARM(thinkpad, "i");
+thinkpad=1
+if N is set to 1, then force enabling the clkrun functionality.
+Currently, when the part is being used, then clkrun is disabled for the entire system,
+but re-enabled when the driver is released or there is no outstanding open count.
+
diff -u --recursive --new-file v2.4.4/linux/Documentation/usb/hotplug.txt linux/Documentation/usb/hotplug.txt
--- v2.4.4/linux/Documentation/usb/hotplug.txt	Tue Jan 16 12:02:51 2001
+++ linux/Documentation/usb/hotplug.txt	Sat May 19 17:49:14 2001
@@ -69,7 +69,10 @@
 
 If "usbdevfs" is configured, DEVICE and DEVFS are also passed.  DEVICE is
 the pathname of the device, and is useful for devices with multiple and/or
-alternate interfaces that complicate driver selection.
+alternate interfaces that complicate driver selection.  By design, USB
+hotplugging is independent of "usbdevfs":  you can do most essential parts
+of USB device setup without using that filesystem, and without running a
+user mode daemon to detect changes in system configuration.
 
 Currently available policy agent implementations can load drivers for
 modules, and can invoke driver-specific setup scripts.  The newest ones
@@ -85,14 +88,26 @@
 
 See <linux/usb.h> for full information about such table entries; or look
 at existing drivers.  Each table entry describes one or more criteria to
-be used when matching a driver to a device or class of devices.
+be used when matching a driver to a device or class of devices.  The
+specific criteria are identified by bits set in "match_flags", paired
+with field values.  You can construct the criteria directly, or with
+macros such as these, and use driver_info to store more information.
+
+    USB_DEVICE (vendorId, productId)
+	... matching devices with specified vendor and product ids
+    USB_DEVICE_VER (vendorId, productId, lo, hi)
+	... like USB_DEVICE with lo <= productversion <= hi
+    USB_INTERFACE_INFO (class, subclass, protocol)
+	... matching specified interface class info
+    USB_DEVICE_INFO (class, subclass, protocol)
+	... matching specified device class info
 
 A short example, for a driver that supports several specific USB devices
 and their quirks, might have a MODULE_DEVICE_TABLE like this:
 
     static const struct usb_device_id mydriver_id_table = {
-	{ idVendor: 0x9999, idProduct 0xaaaa, driver_info: QUIRK_X },
-	{ idVendor: 0xbbbb, idProduct 0x8888, driver_info: QUIRK_Y|QUIRK_Z },
+	{ USB_DEVICE (0x9999, 0xaaaa), driver_info: QUIRK_X },
+	{ USB_DEVICE (0xbbbb, 0x8888), driver_info: QUIRK_Y|QUIRK_Z },
 	...
 	{ } /* end with an all-zeroes entry */
     }
diff -u --recursive --new-file v2.4.4/linux/Documentation/usb/philips.txt linux/Documentation/usb/philips.txt
--- v2.4.4/linux/Documentation/usb/philips.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/usb/philips.txt	Tue May 22 10:25:36 2001
@@ -0,0 +1,141 @@
+This file contains some additional information for the Philips webcams.
+E-mail: webcam@smcc.demon.nl                        Last updated: 2001-04-25
+
+The main webpage for the Philips driver is http://www.smcc.demon.nl/webcam/.
+It contains a lot of extra information, a FAQ, and the binary plugin
+'PWCX'. This plugin contains decompression routines that allow you to
+use higher image sizes and framerates; in addition the webcam uses less
+bandwidth on the USB bus (handy if you want to run more than 1 camera
+simultaneously). These routines fall under an NDA, and may therefor not be
+distributed as source; however, its use is completely optional.
+
+You can build this code either into your kernel, or as a module. I recommend
+the latter, since it makes troubleshooting a lot easier. The built-in
+microphone is supported through the USB Audio class.
+
+(Taken from install.html)
+
+When you load the module you can set some default settings for the
+camera; some programs depend on a particular image-size or -format. The
+options are:
+
+size
+   Can be one of 'sqcif', 'qsif', 'qcif', 'sif', 'cif' or
+   'vga', for an image size of resp. 128x96, 160x120, 176x144,
+   320x240, 352x288 and 640x480 (of course, only for those cameras that support these resolutions).
+
+fps
+   Specifies the desired framerate. Is an integer in the range of 4-30.
+
+palette
+   Specifies the desired colour order that should be delivered by read() and
+   mmap(). The string can be one of bgr24, rgb24, rgb32, bgr32, yuyv,
+   yuv420, yuv420p. If the tool you use produces odd colours (more
+   specificly, red and blue are swapped), try palette=bgr24 or
+   palette=rgb24.
+
+fbufs
+   This paramter specifies the number of internal buffers to use for storing 
+   frames from the cam. This will help if the process that reads images from 
+   the cam is a bit slow or momentarely busy. However, on slow machines it 
+   only introduces lag, so choose carefully. The default is 3, which is 
+   reasonable. You can set it between 2 and 5.
+
+mbufs
+   This is an integer between 1 and 4. It will tell the module the number of
+   buffers to reserve for mmap(), VIDIOCCGMBUF, VIDIOCMCAPTURE and friends.
+   The default is 2, which is adequate for most applications (double
+   buffering).
+      
+   Should you experience a lot of 'Dumping frame...' messages during
+   grabbing with a tool that uses mmap(), you might want to increase if. 
+   However, it doesn't really buffer images, it just gives you a bit more
+   slack when your program is behind. But you need a multi-threaded or
+   forked program to really take advantage of these buffers.
+
+   The absolute maximum is 4, but don't set it too high!  Every buffer takes
+   up 1.22 MB of RAM, so unless you have a lot of memory setting this to
+   something more than 2 is an absolute waste.  This memory is only
+   allocated during open(), so nothing is wasted when the camera is not in
+   use.
+
+power_save
+   When power_save is enabled (set to 1), the module will try to shut down
+   the cam on close() and re-activate on open(). This will save power and
+   turn off the LED. Not all cameras support this though (the 645 and 646
+   don't have power saving at all), and some models don't work either (they
+   will shut down, but never wake up). Consider this experimental. By
+   default this option is disabled.
+
+compression (only useful with the plugin)
+   With this option you can control the compression factor that the camera
+   use to squeeze the image through the USB bus. You can set the 
+   parameter between 0 and 3:
+     0 = prefer uncompressed images; if the requested mode is not available
+         in an uncompressed format, the driver will silently switch to low
+         compression.
+     1 = low compression.
+     2 = medium compression.
+     3 = high compression.
+      
+   High compression takes less bandwidth of course, but it could also
+   introduce some unwanted artefacts. The default is 2, medium compression. 
+   See the FAQ on the website for an overview of which modes require
+   compression.
+      
+   The compression parameter only applies to the Vesta & ToUCam cameras.
+   The 645 and 646 have fixed compression parameters.      
+
+trace
+
+   In order to better detect problems, it is now possible to turn on a
+   'trace' of some of the calls the module makes; it logs all items in your
+   kernel log at debug level.
+
+   The trace variable is a bitmask; each bit represents a certain feature.
+   If you want to trace something, look up the bit value(s) in the table 
+   below, add the values together and supply that to the trace variable.
+
+   Value  Value   Description					   Default
+   (dec)  (hex)
+       1    0x1   Module initialization; this will log messages       On
+                  while loading and unloading the module
+
+       2    0x2   probe() and disconnect() traces                     On
+
+       4    0x4   Trace open() and close() calls                      Off
+
+       8    0x8   read(), mmap() and associated ioctl() calls         Off
+
+      16   0x10   Memory allocation of buffers, etc.                  Off
+
+      32   0x20   Showing underflow, overflow and Dumping frame       On
+                  messages
+
+      64   0x40   Show viewport and image sizes                       Off
+
+
+   For example, to trace the open() & read() fuctions, sum 8 + 4 = 12,
+   so you would supply trace=12 during insmod or modprobe. If
+   you want to turn the initialization and probing tracing off, set trace=0.
+   The default value for trace is 35 (0x23).
+
+   Example:
+     
+     # modprobe pwc size=cif fps=15 power_save=1
+
+The fbufs, mbufs and trace parameters are global and apply to all connected
+cameras. Each camera has its own set of buffers.
+
+size, fps, palette only specify defaults when you open() the device; this is
+to accommodate some tools that don't set the size or colour palette. You can
+change these settings after open() with the Video4Linux ioctl() calls. The
+default of defaults is QCIF size at 10 fps, BGR order.
+
+The compression parameter is semiglobal; it sets the initial compression
+preference for all camera's, but this parameter can be set per camera with
+the VIDIOCPWCSCQUAL ioctl() call.
+
+All parameters are optional.
+
+
diff -u --recursive --new-file v2.4.4/linux/MAINTAINERS linux/MAINTAINERS
--- v2.4.4/linux/MAINTAINERS	Wed Apr 25 14:35:25 2001
+++ linux/MAINTAINERS	Sun May 20 12:11:38 2001
@@ -160,8 +160,8 @@
 
 APPLETALK NETWORK LAYER
 P:	Jay Schulist
-M:	jschlst@turbolinux.com
-L:	linux-atalk@netspace.org
+M:	jschlst@samba.org
+L:	linux-atalk@lists.netspace.org
 S:	Maintained
 
 ARM MFM AND FLOPPY DRIVERS
@@ -280,13 +280,17 @@
 CONFIGURE, MENUCONFIG, XCONFIG
 P:	Michael Elizabeth Chastain
 M:	mec@shout.net
-L:	linux-kbuild@torque.net
-W:	http://www.kernel.org/pub/linux/kernel/projects/kbuild/
+L:	kbuild-devel@lists.sourceforge.net
+W:	http://kbuild.sourceforge.net
 S:	Maintained
 
 CONFIGURE.HELP
-P:	Axel Boldt
-M:	axel@uni-paderborn.de
+P:	Steven P. Cole
+M:	Steven P. Cole <elenstev@mesatop.com>
+P:	Eric S. Raymond
+M:	Eric S. Raymond <esr@thyrsus.com>
+L:	kbuild-devel@lists.sourceforge.net
+W:	http://kbuild.sourceforge.net
 S:	Maintained
 
 COSA/SRP SYNC SERIAL DRIVER
@@ -393,7 +397,7 @@
 
 DISK GEOMETRY AND PARTITION HANDLING
 P:     Andries Brouwer
-M:     aeb@veritas.com
+M:     aeb@cwi.nl
 W:     http://www.win.tue.nl/~aeb/linux/Large-Disk.html
 W:     http://www.win.tue.nl/~aeb/linux/zip/zip-1.html
 W:     http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
@@ -405,6 +409,12 @@
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
+DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER
+P:	Tobias Ringstrom
+M:	tori@unhappy.mine.nu
+L:	linux-kernel@vger.kernel.org
+S:	Maintained
+
 DOUBLETALK DRIVER
 P:	James R. Van Zandt
 M:	jrv@vanzandt.mv.com
@@ -495,6 +505,12 @@
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
+FREEVXFS FILESYSTEM
+P:	Christoph Hellwig
+M:	hch@caldera.de
+W:	ftp://ftp.openlinux.org/pub/people/hch/vxfs
+S:	Maintained
+
 FTAPE/QIC-117
 P:	Claus-Justus Heine
 M:	claus@momo.math.rwth-aachen.de
@@ -548,22 +564,6 @@
 W:	http://www.nt.tuwien.ac.at/~kkudielk/Linux/
 S:	Maintained
 
-KERNEL BUILD (Makefile, Rules.make, scripts/*)
-P:	Keith Owens
-M:	kaos@ocs.com.au
-P:	Michael Elizabeth Chastain
-M:	mec@shout.net
-L:	linux-kbuild@torque.net
-W:	http://www.kernel.org/pub/linux/kernel/projects/kbuild/
-S:	Maintained 
-
-LOGICAL VOLUME MANAGER
-P:     Heinz Mauelshagen
-M:     linux-LVM@EZ-Darmstadt.Telekom.de
-L:     linux-LVM@msede.com
-W:     http://linux.msede.com/lvm
-S:     Maintained 
-
 HIPPI
 P:	Jes Sorensen
 M:	jes@linuxcare.com
@@ -694,9 +694,9 @@
 M:	jjciarla@raiz.uncu.edu.ar
 S:	Maintained
 
-IPX/SPX NETWORK LAYER
-P:	Jay Schulist
-M:	jschlst@turbolinux.com
+IPX NETWORK LAYER
+P:	Arnaldo Carvalho de Melo
+M:	acme@conectiva.com.br
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
@@ -759,6 +759,15 @@
 L:	autofs@linux.kernel.org
 S:	Maintained
 
+KERNEL BUILD (Makefile, Rules.make, scripts/*)
+P:	Keith Owens
+M:	kaos@ocs.com.au
+P:	Michael Elizabeth Chastain
+M:	mec@shout.net
+L:	linux-kbuild@torque.net
+W:	http://www.kernel.org/pub/linux/kernel/projects/kbuild/
+S:	Maintained 
+
 KERNEL NFSD
 P:	Neil Brown
 M:	neilb@cse.unsw.edu.au
@@ -793,6 +802,13 @@
 L:	linuxppc-dev@lists.linuxppc.org
 S:	Maintained
 
+LOGICAL VOLUME MANAGER
+P:     Heinz Mauelshagen
+M:     linux-LVM@EZ-Darmstadt.Telekom.de
+L:     linux-LVM@msede.com
+W:     http://linux.msede.com/lvm
+S:     Maintained 
+
 M68K
 P:	Jes Sorensen
 M:	jes@linuxcare.com
@@ -927,6 +943,8 @@
 M:	ak@muc.de
 P:	Alexey Kuznetsov
 M:	kuznet@ms2.inr.ac.ru
+P:	Pekka Savola (ipv6)
+M:	pekkas@netcore.fi
 L:	netdev@oss.sgi.com
 S:	Maintained
 
@@ -989,7 +1007,7 @@
 P:	Phil Blundell
 M:	Philip.Blundell@pobox.com
 P:	Tim Waugh
-M:	tim@cyberelk.demon.co.uk
+M:	tim@cyberelk.net
 P:	David Campbell
 M:	campbell@torque.net
 P:	Andrea Arcangeli
@@ -1000,7 +1018,7 @@
 
 PARIDE DRIVERS FOR PARALLEL PORT IDE DEVICES
 P:	Tim Waugh
-M:	tim@cyberelk.demon.co.uk
+M:	tim@cyberelk.net
 L:	linux-parport@torque.net
 W:	http://www.torque.net/linux-pp.html
 S:	Maintained
@@ -1171,7 +1189,7 @@
 
 SMB FILESYSTEM
 P:	Urban Widmark
-M:	urban@svenskatest.se
+M:	urban@teststation.com
 W:	http://samba.org/
 L:	samba@samba.org
 S:	Maintained
@@ -1222,13 +1240,13 @@
 
 SPX NETWORK LAYER
 P:	Jay Schulist
-M:	jschlst@turbolinux.com
+M:	jschlst@samba.org
 L:	linux-net@vger.kernel.org
 S:	Supported
 
 SNA NETWORK LAYER
 P:	Jay Schulist
-M:	jschlst@turbolinux.com
+M:	jschlst@samba.org
 L:	linux-sna@turbolinux.com
 W:	http://www.linux-sna.org
 S:	Supported
diff -u --recursive --new-file v2.4.4/linux/Makefile linux/Makefile
--- v2.4.4/linux/Makefile	Fri Apr 27 18:17:19 2001
+++ linux/Makefile	Sat May 19 18:37:22 2001
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
-SUBLEVEL = 4
-EXTRAVERSION =
+SUBLEVEL = 5
+EXTRAVERSION =-pre5
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -118,11 +118,7 @@
 
 CORE_FILES	=kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o
 NETWORKS	=net/network.o
-DRIVERS		=drivers/block/block.o \
-		 drivers/char/char.o \
-		 drivers/misc/misc.o \
-		 drivers/net/net.o \
-		 drivers/media/media.o
+
 LIBS		=$(TOPDIR)/lib/lib.a
 SUBDIRS		=kernel drivers mm fs net ipc lib
 
@@ -132,6 +128,11 @@
 DRIVERS-  :=
 
 DRIVERS-$(CONFIG_PARPORT) += drivers/parport/driver.o
+DRIVERS-y += drivers/char/char.o \
+	drivers/block/block.o \
+	drivers/misc/misc.o \
+	drivers/net/net.o \
+	drivers/media/media.o
 DRIVERS-$(CONFIG_AGP) += drivers/char/agp/agp.o
 DRIVERS-$(CONFIG_DRM) += drivers/char/drm/drm.o
 DRIVERS-$(CONFIG_NUBUS) += drivers/nubus/nubus.a
@@ -144,7 +145,6 @@
 DRIVERS-$(CONFIG_ATM) += drivers/atm/atm.o
 DRIVERS-$(CONFIG_IDE) += drivers/ide/idedriver.o
 DRIVERS-$(CONFIG_SCSI) += drivers/scsi/scsidrv.o
-DRIVERS-$(CONFIG_SCSI_AIC7XXX) += drivers/scsi/aic7xxx/aic7xxx_drv.o
 DRIVERS-$(CONFIG_IEEE1394) += drivers/ieee1394/ieee1394drv.o
 
 ifneq ($(CONFIG_CD_NO_IDESCSI)$(CONFIG_BLK_DEV_IDECD)$(CONFIG_BLK_DEV_SR)$(CONFIG_PARIDE_PCD),)
@@ -178,7 +178,7 @@
 DRIVERS-$(CONFIG_ACPI) += drivers/acpi/acpi.o
 DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o
 
-DRIVERS += $(DRIVERS-y)
+DRIVERS := $(DRIVERS-y)
 
 
 # files removed with 'make clean'
@@ -416,7 +416,7 @@
 distclean: mrproper
 	rm -f core `find . \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
 		-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
-		-o -name '.*.rej' -o -name '.SUMS' -o -size 0 \) -print` TAGS tags
+		-o -name '.*.rej' -o -name '.SUMS' -o -size 0 \) -type f -print` TAGS tags
 
 backup: mrproper
 	cd .. && tar cf - linux/ | gzip -9 > backup.gz
diff -u --recursive --new-file v2.4.4/linux/arch/alpha/boot/tools/objstrip.c linux/arch/alpha/boot/tools/objstrip.c
--- v2.4.4/linux/arch/alpha/boot/tools/objstrip.c	Tue Jul 11 19:02:37 2000
+++ linux/arch/alpha/boot/tools/objstrip.c	Mon May 21 13:41:40 2001
@@ -14,6 +14,8 @@
  * Richard L. Sites and Richard T. Witek.
  */
 #include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
 #include <unistd.h>
 
 #include <sys/fcntl.h>
diff -u --recursive --new-file v2.4.4/linux/arch/alpha/defconfig linux/arch/alpha/defconfig
--- v2.4.4/linux/arch/alpha/defconfig	Sun Mar  4 14:30:18 2001
+++ linux/arch/alpha/defconfig	Fri May  4 15:16:28 2001
@@ -286,7 +286,7 @@
 # CONFIG_SCSI_AHA1740 is not set
 CONFIG_SCSI_AIC7XXX=y
 CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
-CONFIG_AIC7XXX_RESET_DELAY=5000
+CONFIG_AIC7XXX_RESET_DELAY_MS=5000
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
diff -u --recursive --new-file v2.4.4/linux/arch/alpha/kernel/pci.c linux/arch/alpha/kernel/pci.c
--- v2.4.4/linux/arch/alpha/kernel/pci.c	Fri Mar  2 11:12:07 2001
+++ linux/arch/alpha/kernel/pci.c	Mon May 21 13:38:41 2001
@@ -156,7 +156,7 @@
 	else if	(res->flags & IORESOURCE_MEM) {
 		/* Make sure we start at our min on all hoses */
 		if (start - hose->mem_space->start < PCIBIOS_MIN_MEM)
-			start = PCIBIOS_MIN_MEM + hose->io_space->start;
+			start = PCIBIOS_MIN_MEM + hose->mem_space->start;
 
 		/*
 		 * The following holds at least for the Low Cost
@@ -441,15 +441,15 @@
 			if (hose->index == bus) break;
 		if (!hose) return -ENODEV;
 	} else {
-	/* Special hook for ISA access.  */
-	if (bus == 0 && dfn == 0) {
-		hose = pci_isa_hose;
-	} else {
-		dev = pci_find_slot(bus, dfn);
-		if (!dev)
-			return -ENODEV;
-		hose = dev->sysdata;
-	}
+		/* Special hook for ISA access.  */
+		if (bus == 0 && dfn == 0) {
+			hose = pci_isa_hose;
+		} else {
+			dev = pci_find_slot(bus, dfn);
+			if (!dev)
+				return -ENODEV;
+			hose = dev->sysdata;
+		}
 	}
 
 	switch (which & ~IOBASE_FROM_HOSE) {
@@ -468,4 +468,12 @@
 	}
 
 	return -EOPNOTSUPP;
+}
+
+/* Return the index of the PCI controller for device PDEV. */
+int
+pci_controller_num(struct pci_dev *pdev)
+{
+        struct pci_controller *hose = pdev->sysdata;
+	return (hose ? hose->index : -ENXIO);
 }
diff -u --recursive --new-file v2.4.4/linux/arch/alpha/kernel/pci_iommu.c linux/arch/alpha/kernel/pci_iommu.c
--- v2.4.4/linux/arch/alpha/kernel/pci_iommu.c	Fri Mar  2 11:12:07 2001
+++ linux/arch/alpha/kernel/pci_iommu.c	Mon May 21 13:39:43 2001
@@ -402,8 +402,20 @@
 	paddr &= ~PAGE_MASK;
 	npages = calc_npages(paddr + size);
 	dma_ofs = iommu_arena_alloc(arena, npages);
-	if (dma_ofs < 0)
-		return -1;
+	if (dma_ofs < 0) {
+		/* If we attempted a direct map above but failed, die.  */
+		if (leader->dma_address == 0)
+			return -1;
+
+		/* Otherwise, break up the remaining virtually contiguous
+		   hunks into individual direct maps.  */
+		for (sg = leader; sg < end; ++sg)
+			if (sg->dma_address == 2 || sg->dma_address == -2)
+				sg->dma_address = 0;
+
+		/* Retry.  */
+		return sg_fill(leader, end, out, arena, max_dma);
+	}
 
 	out->dma_address = arena->dma_base + dma_ofs*PAGE_SIZE + paddr;
 	out->dma_length = size;
diff -u --recursive --new-file v2.4.4/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
--- v2.4.4/linux/arch/alpha/kernel/setup.c	Fri Mar  2 11:12:07 2001
+++ linux/arch/alpha/kernel/setup.c	Mon May 21 13:41:40 2001
@@ -29,6 +29,7 @@
 #include <linux/string.h>
 #include <linux/ioport.h>
 #include <linux/bootmem.h>
+#include <linux/pci.h>
 
 #ifdef CONFIG_BLK_DEV_INITRD
 #include <linux/blk.h>
@@ -49,7 +50,6 @@
 #include <asm/hwrpb.h>
 #include <asm/dma.h>
 #include <asm/io.h>
-#include <asm/pci.h>
 #include <asm/mmu_context.h>
 #include <asm/console.h>
 
diff -u --recursive --new-file v2.4.4/linux/arch/alpha/kernel/sys_miata.c linux/arch/alpha/kernel/sys_miata.c
--- v2.4.4/linux/arch/alpha/kernel/sys_miata.c	Fri Oct 27 10:55:01 2000
+++ linux/arch/alpha/kernel/sys_miata.c	Sat May 19 17:43:05 2001
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/reboot.h>
 
 #include <asm/ptrace.h>
 #include <asm/system.h>
@@ -223,11 +224,21 @@
 static void
 miata_kill_arch(int mode)
 {
-	/* Who said DEC engineers have no sense of humor? ;-)  */
-	if (alpha_using_srm) {
-		*(vuip) PYXIS_RESET = 0x0000dead;
-		mb();
+	switch(mode) {
+	case LINUX_REBOOT_CMD_RESTART:
+		/* Who said DEC engineers have no sense of humor? ;-)  */ 
+		if (alpha_using_srm) {
+			*(vuip) PYXIS_RESET = 0x0000dead; 
+			mb(); 
+		}
+		break;
+	case LINUX_REBOOT_CMD_HALT:
+		break;
+	case LINUX_REBOOT_CMD_POWER_OFF:
+		break;
 	}
+
+	halt();
 }
 
 
diff -u --recursive --new-file v2.4.4/linux/arch/alpha/kernel/sys_nautilus.c linux/arch/alpha/kernel/sys_nautilus.c
--- v2.4.4/linux/arch/alpha/kernel/sys_nautilus.c	Sun Mar 25 18:24:31 2001
+++ linux/arch/alpha/kernel/sys_nautilus.c	Mon May 21 13:40:39 2001
@@ -55,7 +55,6 @@
 {
 	if (alpha_using_srm) {
 		alpha_mv.device_interrupt = srm_device_interrupt;
-		alpha_mv.kill_arch = NULL;
 	}
 
 	init_i8259a_irqs();
@@ -77,7 +76,7 @@
 {
 	switch (mode) {
 	case LINUX_REBOOT_CMD_RESTART:
-		{
+		if (! alpha_using_srm) {
 			u8 t8;
 			pcibios_read_config_byte(0, 0x38, 0x43, &t8);
 			pcibios_write_config_byte(0, 0x38, 0x43, t8 | 0x80);
diff -u --recursive --new-file v2.4.4/linux/arch/arm/def-configs/clps7500 linux/arch/arm/def-configs/clps7500
--- v2.4.4/linux/arch/arm/def-configs/clps7500	Mon Sep 18 15:15:24 2000
+++ linux/arch/arm/def-configs/clps7500	Sat May 19 17:43:05 2001
@@ -2,7 +2,9 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_ARM=y
+# CONFIG_EISA is not set
 # CONFIG_SBUS is not set
+# CONFIG_MCA is not set
 CONFIG_UID16=y
 
 #
@@ -23,6 +25,7 @@
 CONFIG_ARCH_CLPS7500=y
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_FTVPCI is not set
 # CONFIG_ARCH_TBOX is not set
 # CONFIG_ARCH_SHARK is not set
@@ -30,22 +33,51 @@
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_CLPS711X is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Footbridge Implementations
+#
+
+#
+# SA11x0 Implementations
+#
+
+#
+# CLPS711X/EP721X Implementations
+#
 # CONFIG_ARCH_ACORN is not set
 # CONFIG_FOOTBRIDGE is not set
 # CONFIG_FOOTBRIDGE_HOST is not set
 # CONFIG_FOOTBRIDGE_ADDIN is not set
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
+
+#
+# Processor Type
+#
 CONFIG_CPU_32v3=y
-CONFIG_CPU_ARM7=y
+# CONFIG_CPU_32v4 is not set
+# CONFIG_CPU_ARM610 is not set
+CONFIG_CPU_ARM710=y
+# CONFIG_CPU_ARM720T is not set
+# CONFIG_CPU_ARM920T is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
 # CONFIG_DISCONTIGMEM is not set
-# CONFIG_PCI is not set
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
 
 #
 # General setup
 #
+CONFIG_ANGELBOOT=y
+# CONFIG_PCI is not set
+CONFIG_ISA=y
+# CONFIG_ISA_DMA is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
 CONFIG_NET=y
@@ -60,7 +92,7 @@
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_PM is not set
 # CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="root=/dev/nfs rw"
+CONFIG_CMDLINE="mem=16M root=nfs"
 # CONFIG_ALIGNMENT_TRAP is not set
 
 #
@@ -81,34 +113,35 @@
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
 # CONFIG_MTD_DOC1000 is not set
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOCPROBE is not set
+
+#
+# RAM/ROM Device Drivers
+#
 # CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_PMC551_BUGFIX is not set
+# CONFIG_MTD_PMC551_DEBUG is not set
 # CONFIG_MTD_MTDRAM is not set
 
 #
-# MTD drivers for mapped chips
+# Linearly Mapped Flash Device Drivers
 #
 # CONFIG_MTD_CFI is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_JEDEC is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
-# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_JEDEC is not set
 
 #
 # Drivers for chip mappings
 #
-# CONFIG_MTD_MIXMEM is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_OCTAGON is not set
-# CONFIG_MTD_PNC2000 is not set
-# CONFIG_MTD_RPXLITE is not set
-# CONFIG_MTD_VMAX is not set
 
 #
 # User modules and translation layers for MTD devices
@@ -122,7 +155,6 @@
 # Plug and Play configuration
 #
 # CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
 
 #
 # Block devices
@@ -130,20 +162,12 @@
 # CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
+CONFIG_BLK_DEV_NBD=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_INITRD is not set
-CONFIG_BLK_DEV_FLD7500=y
+# CONFIG_BLK_DEV_FLD7500 is not set
 
 #
 # Networking options
@@ -159,10 +183,8 @@
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
-# CONFIG_IP_ROUTER is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
-# CONFIG_IP_ALIAS is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
@@ -179,6 +201,7 @@
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
 # CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_FASTROUTE is not set
@@ -201,6 +224,7 @@
 CONFIG_DUMMY=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
 # CONFIG_NET_SB1000 is not set
 
 #
@@ -213,16 +237,19 @@
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_AT1700 is not set
 # CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
 # CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
+CONFIG_NET_PCI=y
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+CONFIG_CS89x0=y
+# CONFIG_ZNET is not set
 # CONFIG_NET_POCKET is not set
 
 #
 # Ethernet (1000 Mbit)
 #
-# CONFIG_YELLOWFIN is not set
-# CONFIG_ACENIC is not set
-# CONFIG_SK98LIN is not set
+# CONFIG_ACENIC_OMIT_TIGON_I is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 # CONFIG_PLIP is not set
@@ -283,10 +310,6 @@
 # I2O device support
 #
 # CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
 
 #
 # ISDN subsystem
@@ -294,6 +317,11 @@
 # CONFIG_ISDN is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+
+#
 # Character devices
 #
 CONFIG_VT=y
@@ -305,7 +333,7 @@
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 CONFIG_PRINTER=y
-CONFIG_LP_CONSOLE=y
+# CONFIG_LP_CONSOLE is not set
 # CONFIG_PPDEV is not set
 
 #
@@ -322,16 +350,38 @@
 #
 # Mice
 #
-# CONFIG_BUSMOUSE is not set
+CONFIG_BUSMOUSE=y
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_LOGIBUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
 CONFIG_MOUSE=y
-CONFIG_PSMOUSE=y
+# CONFIG_PSMOUSE is not set
 # CONFIG_82C710_MOUSE is not set
 # CONFIG_PC110_PAD is not set
 
 #
 # Joysticks
 #
-# CONFIG_JOYSTICK is not set
+
+#
+# Game port support
+#
+
+#
+# Gameport joysticks
+#
+
+#
+# Serial port support
+#
+
+#
+# Serial port joysticks
+#
+
+#
+# Parallel port joysticks
+#
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -341,11 +391,6 @@
 CONFIG_CLPS7500_FLASH=y
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -353,45 +398,38 @@
 # CONFIG_DRM is not set
 
 #
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
 # File systems
 #
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
 # CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
 CONFIG_MINIX_FS=y
 # CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
 # CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
-# CONFIG_SYSV_FS_WRITE is not set
 # CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
 
 #
 # Network File Systems
@@ -401,21 +439,10 @@
 # CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
 # CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
 
 #
 # Partition Types
@@ -430,11 +457,14 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
 # Console drivers
 #
+CONFIG_PC_KEYB=y
+CONFIG_PC_KEYMAP=y
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_FB=y
 
@@ -445,15 +475,14 @@
 CONFIG_DUMMY_CONSOLE=y
 CONFIG_FB_ACORN=y
 # CONFIG_CHRONTEL_7003 is not set
-# CONFIG_FB_CYBER2000 is not set
 # CONFIG_FB_VIRTUAL is not set
 CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
+CONFIG_FBCON_MFB=y
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
 CONFIG_FBCON_CFB8=y
-# CONFIG_FBCON_CFB16 is not set
-# CONFIG_FBCON_CFB24 is not set
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
 # CONFIG_FBCON_CFB32 is not set
 # CONFIG_FBCON_AFB is not set
 # CONFIG_FBCON_ILBM is not set
@@ -487,4 +516,4 @@
 # CONFIG_DEBUG_USER is not set
 # CONFIG_DEBUG_INFO is not set
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_LL is not set
+CONFIG_DEBUG_LL=y
diff -u --recursive --new-file v2.4.4/linux/arch/arm/def-configs/ebsa110 linux/arch/arm/def-configs/ebsa110
--- v2.4.4/linux/arch/arm/def-configs/ebsa110	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/def-configs/ebsa110	Wed May 16 10:31:27 2001
@@ -192,8 +192,6 @@
 CONFIG_IP_NF_NAT_NEEDED=y
 # CONFIG_IP_NF_COMPAT_IPFWADM is not set
 CONFIG_IPV6=m
-CONFIG_IPV6_EUI64=y
-# CONFIG_IPV6_NO_PB is not set
 
 #
 #   IPv6: Netfilter Configuration
diff -u --recursive --new-file v2.4.4/linux/arch/arm/def-configs/integrator linux/arch/arm/def-configs/integrator
--- v2.4.4/linux/arch/arm/def-configs/integrator	Mon Nov 27 17:07:59 2000
+++ linux/arch/arm/def-configs/integrator	Sat May 19 17:43:05 2001
@@ -25,6 +25,7 @@
 # CONFIG_ARCH_CLPS7500 is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 CONFIG_ARCH_INTEGRATOR=y
 # CONFIG_ARCH_RPC is not set
@@ -56,18 +57,28 @@
 #
 # Processor Type
 #
+# CONFIG_CPU_32v3 is not set
 CONFIG_CPU_32v4=y
-CONFIG_CPU_ARM720=y
-CONFIG_CPU_ARM920=y
+# CONFIG_CPU_ARM610 is not set
+# CONFIG_CPU_ARM710 is not set
+CONFIG_CPU_ARM720T=y
+CONFIG_CPU_ARM920T=y
 CONFIG_CPU_ARM920_CPU_IDLE=y
 CONFIG_CPU_ARM920_I_CACHE_ON=y
 CONFIG_CPU_ARM920_D_CACHE_ON=y
 # CONFIG_CPU_ARM920_WRITETHROUGH is not set
+# CONFIG_CPU_ARM1020 is not set
+# CONFIG_CPU_SA110 is not set
+# CONFIG_CPU_SA1100 is not set
 # CONFIG_DISCONTIGMEM is not set
 
 #
 # General setup
 #
+
+#
+# Please ensure that you have read the help on the next option
+#
 # CONFIG_ANGELBOOT is not set
 CONFIG_PCI_INTEGRATOR=y
 CONFIG_PCI=y
@@ -103,23 +114,32 @@
 # Memory Technology Devices (MTD)
 #
 CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
 # CONFIG_MTD_DOC1000 is not set
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOCPROBE is not set
+
+#
+# RAM/ROM Device Drivers
+#
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_MTDRAM is not set
 
 #
-# MTD drivers for mapped chips
+# Linearly Mapped Flash Device Drivers
 #
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 # CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_JEDEC is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
+# CONFIG_MTD_JEDEC is not set
 # CONFIG_MTD_PHYSMAP is not set
 
 #
@@ -347,6 +367,8 @@
 CONFIG_SERIAL_AMBA=y
 CONFIG_SERIAL_INTEGRATOR=y
 CONFIG_SERIAL_AMBA_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
 
@@ -403,6 +425,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -457,8 +481,6 @@
 # CONFIG_NCPFS_NFS_NS is not set
 # CONFIG_NCPFS_OS2_NS is not set
 # CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 
@@ -475,6 +497,7 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
@@ -503,7 +526,7 @@
 #
 # Kernel hacking
 #
-CONFIG_FRAME_POINTER=y
+# CONFIG_NO_FRAME_POINTER is not set
 CONFIG_DEBUG_ERRORS=y
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
diff -u --recursive --new-file v2.4.4/linux/arch/arm/defconfig linux/arch/arm/defconfig
--- v2.4.4/linux/arch/arm/defconfig	Mon Jun 19 17:59:33 2000
+++ linux/arch/arm/defconfig	Sat May 19 17:43:05 2001
@@ -2,50 +2,80 @@
 # Automatically generated make config: don't edit
 #
 CONFIG_ARM=y
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
 CONFIG_UID16=y
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
 
 #
-# System and processor type
+# Loadable module support
 #
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-# CONFIG_ARCH_RPC is not set
+# CONFIG_MODULES is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
-CONFIG_FOOTBRIDGE=y
-CONFIG_HOST_FOOTBRIDGE=y
-# CONFIG_ADDIN_FOOTBRIDGE is not set
-CONFIG_ARCH_EBSA285=y
-# CONFIG_ARCH_CATS is not set
-CONFIG_ARCH_NETWINDER=y
-# CONFIG_ARCH_PERSONAL_SERVER is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+CONFIG_ARCH_INTEGRATOR=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_CLPS711X is not set
+
+#
+# Archimedes/A5000 Implementations
+#
+
+#
+# Footbridge Implementations
+#
+
+#
+# SA11x0 Implementations
+#
+
+#
+# CLPS711X/EP721X Implementations
+#
 # CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
 CONFIG_CPU_32=y
 # CONFIG_CPU_26 is not set
-CONFIG_CPU_32v4=y
-CONFIG_CPU_SA110=y
-CONFIG_PCI=y
-CONFIG_PCI_NAMES=y
-CONFIG_ISA=y
-CONFIG_ISA_DMA=y
-# CONFIG_SBUS is not set
-# CONFIG_PCMCIA is not set
-# CONFIG_ALIGNMENT_TRAP is not set
 
 #
-# Loadable module support
+# Processor Type
 #
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
+CONFIG_CPU_32v4=y
+CONFIG_CPU_ARM720=y
+CONFIG_CPU_ARM920=y
+CONFIG_CPU_ARM920_CPU_IDLE=y
+CONFIG_CPU_ARM920_I_CACHE_ON=y
+CONFIG_CPU_ARM920_D_CACHE_ON=y
+# CONFIG_CPU_ARM920_WRITETHROUGH is not set
+# CONFIG_DISCONTIGMEM is not set
 
 #
 # General setup
 #
+# CONFIG_ANGELBOOT is not set
+CONFIG_PCI_INTEGRATOR=y
+CONFIG_PCI=y
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
@@ -56,296 +86,86 @@
 CONFIG_BINFMT_AOUT=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
 # CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=1f04 mem=32M"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
 
 #
 # Parallel port support
 #
-CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=y
-CONFIG_PARPORT_PC_FIFO=y
-# CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_ARC is not set
-# CONFIG_PARPORT_AMIGA is not set
-# CONFIG_PARPORT_MFC3 is not set
-# CONFIG_PARPORT_ATARI is not set
-# CONFIG_PARPORT_SUNBPP is not set
-# CONFIG_PARPORT_OTHER is not set
-CONFIG_PARPORT_1284=y
-CONFIG_CMDLINE="root=/dev/hda1 ro mem=32M parport=0x378,7 ide0=autotune"
-CONFIG_LEDS=y
-CONFIG_LEDS_TIMER=y
-# CONFIG_LEDS_CPU is not set
+# CONFIG_PARPORT is not set
 
 #
-# IEEE 1394 (FireWire) support
+# Memory Technology Devices (MTD)
 #
-# CONFIG_IEEE1394 is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_MTDRAM is not set
 
 #
-# I2O device support
+# MTD drivers for mapped chips
 #
-# CONFIG_I2O is not set
-# CONFIG_I2O_PCI is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_JEDEC is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_PHYSMAP is not set
+
+#
+# Drivers for chip mappings
+#
+# CONFIG_MTD_MIXMEM is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_OCTAGON is not set
+# CONFIG_MTD_PNC2000 is not set
+# CONFIG_MTD_RPXLITE is not set
+# CONFIG_MTD_VMAX is not set
+
+#
+# User modules and translation layers for MTD devices
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+CONFIG_MTD_ARM=y
 
 #
 # Plug and Play configuration
 #
-CONFIG_PNP=y
-CONFIG_ISAPNP=y
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
 
 #
 # Block devices
 #
 # CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE=m
-CONFIG_PARIDE_PARPORT=y
-
-#
-# Parallel IDE high-level drivers
-#
-CONFIG_PARIDE_PD=m
-CONFIG_PARIDE_PCD=m
-CONFIG_PARIDE_PF=m
-CONFIG_PARIDE_PT=m
-CONFIG_PARIDE_PG=m
-
-#
-# Parallel IDE protocol modules
-#
-CONFIG_PARIDE_ATEN=m
-CONFIG_PARIDE_BPCK=m
-CONFIG_PARIDE_COMM=m
-CONFIG_PARIDE_DSTR=m
-CONFIG_PARIDE_FIT2=m
-CONFIG_PARIDE_FIT3=m
-CONFIG_PARIDE_EPAT=m
-CONFIG_PARIDE_EPIA=m
-CONFIG_PARIDE_FRIQ=m
-CONFIG_PARIDE_FRPW=m
-CONFIG_PARIDE_KBIC=m
-CONFIG_PARIDE_KTTI=m
-CONFIG_PARIDE_ON20=m
-CONFIG_PARIDE_ON26=m
+# CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=m
-CONFIG_MD_STRIPED=m
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
 # CONFIG_BLK_DEV_INITRD is not set
 
 #
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-CONFIG_PRINTER=m
-# CONFIG_LP_CONSOLE is not set
-# CONFIG_PPDEV is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=y
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-
-#
-# Joysticks
-#
-# CONFIG_JOYSTICK is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-# CONFIG_WDT is not set
-CONFIG_SOFT_WATCHDOG=y
-# CONFIG_PCWATCHDOG is not set
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_MIXCOMWD is not set
-# CONFIG_21285_WATCHDOG is not set
-CONFIG_977_WATCHDOG=m
-CONFIG_DS1620=y
-CONFIG_NWBUTTON=y
-CONFIG_NWBUTTON_REBOOT=y
-CONFIG_NWFLASH=m
-# CONFIG_NVRAM is not set
-CONFIG_RTC=y
-
-#
-# Video For Linux
-#
-CONFIG_VIDEO_DEV=y
-# CONFIG_I2C_PARPORT is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_MIROPCM20 is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-
-#
-# Video Adapters
-#
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_BWQCAM is not set
-# CONFIG_VIDEO_CQCAM is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_BUZ is not set
-# CONFIG_VIDEO_ZR36120 is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
-# CONFIG_AGP is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=m
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-
-#
-# USB Devices
-#
-CONFIG_USB_PRINTER=m
-# CONFIG_USB_SCANNER is not set
-CONFIG_USB_AUDIO=m
-CONFIG_USB_ACM=m
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_CPIA is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_USS720 is not set
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_PLUSB is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_DSBR is not set
-
-#
-# USB HID
-#
-# CONFIG_USB_HID is not set
-CONFIG_USB_KBD=m
-CONFIG_USB_MOUSE=m
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_WMFORCE is not set
-CONFIG_INPUT_KEYBDEV=m
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_MIX=y
-# CONFIG_INPUT_MOUSEDEV_DIGITIZER is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
-# Console drivers
-#
-CONFIG_VGA_CONSOLE=y
-CONFIG_FB=y
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_CLGEN is not set
-# CONFIG_FB_PM2 is not set
-CONFIG_FB_CYBER2000=y
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-CONFIG_FBCON_CFB8=y
-CONFIG_FBCON_CFB16=y
-CONFIG_FBCON_CFB24=y
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-CONFIG_FBCON_VGA=y
-# CONFIG_FBCON_HGA is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-CONFIG_FONT_ACORN_8x8=y
-
-#
 # Networking options
 #
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
+# CONFIG_PACKET is not set
 # CONFIG_NETLINK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
@@ -356,16 +176,10 @@
 CONFIG_IP_PNP=y
 CONFIG_IP_PNP_BOOTP=y
 # CONFIG_IP_PNP_RARP is not set
-# CONFIG_IP_ROUTER is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
-CONFIG_IP_ALIAS=y
+# CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
-
-#
-# (it is safe to leave these untouched)
-#
-CONFIG_SKB_LARGE=y
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
@@ -376,10 +190,11 @@
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
 # CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_FASTROUTE is not set
@@ -391,16 +206,6 @@
 # CONFIG_NET_SCHED is not set
 
 #
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
 # Network device support
 #
 CONFIG_NETDEVICES=y
@@ -412,68 +217,59 @@
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
 # CONFIG_NET_SB1000 is not set
 
 #
 # Ethernet (10 or 100Mbit)
 #
 CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-CONFIG_NET_VENDOR_3COM=y
-# CONFIG_EL1 is not set
-# CONFIG_EL2 is not set
-# CONFIG_ELPLUS is not set
-# CONFIG_EL16 is not set
-# CONFIG_EL3 is not set
-# CONFIG_3C515 is not set
-CONFIG_VORTEX=y
+# CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_AT1700 is not set
 # CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
 # CONFIG_NET_ISA is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
+CONFIG_TULIP=y
 # CONFIG_DE4X5 is not set
-CONFIG_TULIP=m
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
-# CONFIG_EEPRO100 is not set
+CONFIG_EEPRO100=y
+CONFIG_EEPRO100_PM=y
 # CONFIG_LNE390 is not set
+# CONFIG_NATSEMI is not set
+# CONFIG_NE2K_PCI is not set
 # CONFIG_NE3210 is not set
-CONFIG_NE2K_PCI=y
-# CONFIG_RTL8129 is not set
+# CONFIG_ES3210 is not set
 # CONFIG_8139TOO is not set
+# CONFIG_RTL8129 is not set
 # CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_ES3210 is not set
-# CONFIG_EPIC100 is not set
+# CONFIG_WINBOND_840 is not set
+# CONFIG_HAPPYMEAL is not set
 # CONFIG_NET_POCKET is not set
 
 #
 # Ethernet (1000 Mbit)
 #
-# CONFIG_YELLOWFIN is not set
 # CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
 
 #
 # Wireless LAN (non-hamradio)
@@ -494,71 +290,21 @@
 # CONFIG_WAN is not set
 
 #
-# ATA/IDE/MFM/RLL support
+# Amateur Radio support
 #
-CONFIG_IDE=y
+# CONFIG_HAMRADIO is not set
 
 #
-# IDE, ATA and ATAPI Block devices
+# IrDA (infrared) support
 #
-CONFIG_BLK_DEV_IDE=y
+# CONFIG_IRDA is not set
 
 #
-# Please see Documentation/ide.txt for help/info on IDE drives
+# ATA/IDE/MFM/RLL support
 #
-# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
 # CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_BLK_DEV_IDECS is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_BLK_DEV_OFFBOARD=y
-CONFIG_IDEDMA_PCI_AUTO=y
-CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
-# CONFIG_IDEDMA_PCI_WIP is not set
-# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_AEC62XX_TUNING is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_WDC_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD7409 is not set
-# CONFIG_AMD7409_OVERRIDE is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_CMD64X_RAID is not set
-CONFIG_BLK_DEV_CY82C693=y
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_HPT34X_AUTODMA is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_HPT366_FIP is not set
-# CONFIG_HPT366_MODE3 is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_PDC202XX=y
-# CONFIG_PDC202XX_BURST is not set
-# CONFIG_PDC202XX_MASTER is not set
-# CONFIG_BLK_DEV_SIS5513 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-CONFIG_BLK_DEV_SL82C105=y
-# CONFIG_IDE_CHIPSETS is not set
-CONFIG_IDEDMA_AUTO=y
-CONFIG_BLK_DEV_IDE_MODES=y
 
 #
 # SCSI support
@@ -566,72 +312,115 @@
 # CONFIG_SCSI is not set
 
 #
-# Sound
+# IEEE 1394 (FireWire) support
 #
-CONFIG_SOUND=m
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-CONFIG_SOUND_OSS=m
-# CONFIG_SOUND_TRACEINIT is not set
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_ACI_MIXER is not set
-# CONFIG_SOUND_CS4232 is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_PAS_JOYSTICK is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_SOFTOSS is not set
-CONFIG_SOUND_SB=m
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_AEDSP16 is not set
-# CONFIG_SOUND_VIDC is not set
-CONFIG_SOUND_WAVEARTIST=m
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_SERIAL_AMBA=y
+CONFIG_SERIAL_INTEGRATOR=y
+CONFIG_SERIAL_AMBA_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
 
 #
 # File systems
 #
 # CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
-CONFIG_ADFS_FS=y
+# CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
 # CONFIG_HFS_FS is not set
 # CONFIG_BFS_FS is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
 # CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=m
+# CONFIG_VFAT_FS is not set
 # CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
 CONFIG_PROC_FS=y
 # CONFIG_DEVFS_FS is not set
@@ -639,77 +428,77 @@
 # CONFIG_DEVFS_DEBUG is not set
 CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+CONFIG_ROMFS_FS=y
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
 # CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
 
 #
 # Network File Systems
 #
 # CONFIG_CODA_FS is not set
 CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
 CONFIG_ROOT_NFS=y
-CONFIG_NFSD=m
+# CONFIG_NFSD is not set
 # CONFIG_NFSD_V3 is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
 # CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
 
 #
 # Partition Types
 #
 CONFIG_PARTITION_ADVANCED=y
-CONFIG_ACORN_PARTITION=y
-# CONFIG_ACORN_PARTITION_ICS is not set
-CONFIG_ACORN_PARTITION_ADFS=y
-# CONFIG_ACORN_PARTITION_POWERTEC is not set
-# CONFIG_ACORN_PARTITION_RISCIX is not set
+# CONFIG_ACORN_PARTITION is not set
 # CONFIG_OSF_PARTITION is not set
 # CONFIG_AMIGA_PARTITION is not set
 # CONFIG_ATARI_PARTITION is not set
 # CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_MSDOS_PARTITION is not set
 # CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
-CONFIG_NLS=y
+# CONFIG_NLS is not set
 
 #
-# Native Language Support
+# Console drivers
+#
+CONFIG_KMI_KEYB=y
+CONFIG_PC_KEYMAP=y
+CONFIG_VGA_CONSOLE=y
+# CONFIG_FB is not set
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
 #
-CONFIG_NLS_CODEPAGE_437=m
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-# 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_874 is not set
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-# 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_8 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-CONFIG_NLS_ISO8859_15=m
-# CONFIG_NLS_KOI8_R is not set
+# CONFIG_USB is not set
 
 #
 # Kernel hacking
@@ -719,4 +508,4 @@
 CONFIG_DEBUG_USER=y
 # CONFIG_DEBUG_INFO is not set
 CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_LL is not set
+CONFIG_DEBUG_LL=y
diff -u --recursive --new-file v2.4.4/linux/arch/arm/kernel/setup.c linux/arch/arm/kernel/setup.c
--- v2.4.4/linux/arch/arm/kernel/setup.c	Fri Apr 27 14:10:31 2001
+++ linux/arch/arm/kernel/setup.c	Wed May 16 15:25:16 2001
@@ -51,7 +51,6 @@
 extern void paging_init(struct meminfo *, struct machine_desc *desc);
 extern void bootmem_init(struct meminfo *);
 extern void reboot_setup(char *str);
-extern unsigned long memparse(char *ptr, char **retptr);
 extern int root_mountflags;
 extern int _stext, _text, _etext, _edata, _end;
 
diff -u --recursive --new-file v2.4.4/linux/arch/arm/lib/Makefile linux/arch/arm/lib/Makefile
--- v2.4.4/linux/arch/arm/lib/Makefile	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/lib/Makefile	Wed May 16 15:25:16 2001
@@ -48,3 +48,7 @@
 endif
 
 include $(TOPDIR)/Rules.make
+
+csumpartialcopy.o: csumpartialcopygeneric.S
+csumpartialcopyuser.o: csumpartialcopygeneric.S
+
diff -u --recursive --new-file v2.4.4/linux/arch/arm/lib/csumpartial.S linux/arch/arm/lib/csumpartial.S
--- v2.4.4/linux/arch/arm/lib/csumpartial.S	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/lib/csumpartial.S	Wed May 16 15:25:16 2001
@@ -12,57 +12,119 @@
 
 		.text
 
-/* Function: __u32 csum_partial(const char *src, int len, __u32)
+/*
+ * Function: __u32 csum_partial(const char *src, int len, __u32 sum)
  * Params  : r0 = buffer, r1 = len, r2 = checksum
  * Returns : r0 = new checksum
  */
 
+buf	.req	r0
+len	.req	r1
+sum	.req	r2
+td0	.req	r3
+td1	.req	r4	@ save before use
+td2	.req	r5	@ save before use
+td3	.req	lr
+
+.zero:		mov	r0, sum
+		add	sp, sp, #4
+		ldr	pc, [sp], #4
+
+		/*
+		 * Handle 0 to 7 bytes, with any alignment of source and
+		 * destination pointers.  Note that when we get here, C = 0
+		 */
+.less8:		teq	len, #0			@ check for zero count
+		beq	.zero
+
+		/* we must have at least one byte. */
+		tst	buf, #1			@ odd address?
+		ldrneb	td0, [buf], #1
+		subne	len, len, #1
+		adcnes	sum, sum, td0, lsl #8
+
+.less4:		tst	len, #6
+		beq	.less8_byte
+
+		/* we are now half-word aligned */
+
+.less8_wordlp:
+#ifdef __ARM_ARCH_4__
+		ldrh	td0, [buf], #2
+		sub	len, len, #2
+#else
+		ldrb	td0, [buf], #1
+		ldrb	td3, [buf], #1
+		sub	len, len, #2
+		orr	td0, td0, td3, lsl #8
+#endif
+		adcs	sum, sum, td0
+		tst	len, #6
+		bne	.less8_wordlp
+
+.less8_byte:	tst	len, #1			@ odd number of bytes
+		ldrneb	td0, [buf], #1		@ include last byte
+		adcnes	sum, sum, td0		@ update checksum
+
+.done:		adc	r0, sum, #0		@ collect up the last carry
+		ldr	td0, [sp], #4
+		tst	td0, #1			@ check buffer alignment
+		movne	td0, r0, lsl #8		@ rotate checksum by 8 bits
+		orrne	r0, td0, r0, lsr #24
+		ldr	pc, [sp], #4		@ return
+
+.not_aligned:	tst	buf, #1			@ odd address
+		ldrneb	td0, [buf], #1		@ make even
+		subne	len, len, #1
+		adcnes	sum, sum, td0, lsl #8	@ update checksum
+
+		tst	buf, #2			@ 32-bit aligned?
+#ifdef __ARM_ARCH_4__
+		ldrneh	td0, [buf], #2		@ make 32-bit aligned
+		subne	len, len, #2
+#else
+		ldrneb	td0, [buf], #1
+		ldrneb	ip, [buf], #1
+		subne	len, len, #2
+		orrne	td0, td0, ip, lsl #8
+#endif
+		adcnes	sum, sum, td0		@ update checksum
+		mov	pc, lr
+
 ENTRY(csum_partial)
-		tst	r0, #2
-		beq	1f
-		subs	r1, r1, #2
-		addmi	r1, r1, #2
-		bmi	3f
-		bic	r0, r0, #3
-		ldr	r3, [r0], #4
-		adds	r2, r2, r3, lsr #16
-		adcs	r2, r2, #0
-1:		adds	r2, r2, #0
-		bics	ip, r1, #31
+		stmfd	sp!, {buf, lr}
+		cmp	len, #8			@ Ensure that we have at least
+		blo	.less8			@ 8 bytes to copy.
+
+		adds	sum, sum, #0		@ C = 0
+		tst	buf, #3			@ Test destination alignment
+		blne	.not_aligned		@ aligh destination, return here
+
+1:		bics	ip, len, #31
 		beq	3f
-		stmfd	sp!, {r4 - r6}
-2:		ldmia	r0!, {r3 - r6}
-		adcs	r2, r2, r3
-		adcs	r2, r2, r4
-		adcs	r2, r2, r5
-		adcs	r2, r2, r6
-		ldmia	r0!, {r3 - r6}
-		adcs	r2, r2, r3
-		adcs	r2, r2, r4
-		adcs	r2, r2, r5
-		adcs	r2, r2, r6
+
+		stmfd	sp!, {r4 - r5}
+2:		ldmia	buf!, {td0, td1, td2, td3}
+		adcs	sum, sum, td0
+		adcs	sum, sum, td1
+		adcs	sum, sum, td2
+		adcs	sum, sum, td3
+		ldmia	buf!, {td0, td1, td2, td3}
+		adcs	sum, sum, td0
+		adcs	sum, sum, td1
+		adcs	sum, sum, td2
+		adcs	sum, sum, td3
 		sub	ip, ip, #32
 		teq	ip, #0
 		bne	2b
-		adcs	r2, r2, #0
-		ldmfd	sp!, {r4 - r6}
-3:		ands	ip, r1, #0x1c
-		beq	5f
-4:		ldr	r3, [r0], #4
-		sub	ip, ip, #4
-		adcs	r2, r2, r3
-		teq	ip, #0
-		bne	4b
-		adcs	r2, r2, #0
-5:		ands	ip, r1, #3
-		moveq	r0, r2
-		RETINSTR(moveq,pc,lr)
-		mov	ip, ip, lsl #3
-		ldr	r3, [r0]
-		rsb	ip, ip, #32
-		mov	r3, r3, lsl ip
-		adds	r2, r2, r3, lsr ip
-		adc	r0, r2, #0
-		RETINSTR(mov,pc,lr)
+		ldmfd	sp!, {r4 - r5}
 
+3:		tst	len, #0x1c		@ should not change C
+		beq	.less4
 
+4:		ldr	td0, [buf], #4
+		sub	len, len, #4
+		adcs	sum, sum, td0
+		tst	len, #0x1c
+		bne	4b
+		b	.less4
diff -u --recursive --new-file v2.4.4/linux/arch/arm/lib/csumpartialcopy.S linux/arch/arm/lib/csumpartialcopy.S
--- v2.4.4/linux/arch/arm/lib/csumpartialcopy.S	Mon Sep 18 15:15:25 2000
+++ linux/arch/arm/lib/csumpartialcopy.S	Wed May 16 15:25:16 2001
@@ -18,11 +18,11 @@
  */
 
 		.macro	save_regs
-		stmfd	sp!, {r4 - r8, fp, ip, lr, pc}
+		stmfd	sp!, {r1, r4 - r8, fp, ip, lr, pc}
 		.endm
 
 		.macro	load_regs,flags
-		LOADREGS(\flags,fp,{r4 - r8, fp, sp, pc})
+		LOADREGS(\flags,fp,{r1, r4 - r8, fp, sp, pc})
 		.endm
 
 		.macro	load1b, reg1
@@ -47,250 +47,6 @@
 		ldmia	r0!, {\reg1, \reg2, \reg3, \reg4}
 		.endm
 
-ENTRY(csum_partial_copy_nocheck)
-		mov	ip, sp
-		save_regs
-		sub	fp, ip, #4
-		cmp	r2, #4
-		blt	.too_small
-		tst	r1, #2			@ Test destination alignment
-		beq	.dst_aligned
-		load2b	ip, r8
-		subs	r2, r2, #2		@ We do not know if SRC is aligned...
-		orr	ip, ip, r8, lsl #8
-		adds	r3, r3, ip
-		adcs	r3, r3, #0
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-		strb	ip, [r1], #1		@ Destination now aligned
-.dst_aligned:	tst	r0, #3
-		bne	.src_not_aligned
-		adds	r3, r3, #0
-		bics	ip, r2, #15		@ Routine for src & dst aligned
-		beq	2f
-1:		load4l	r4, r5, r6, r7
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r4, r5
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		tst	ip, #4
-		beq	4f
-3:		load1l	r4
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		load1l	r4
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-.exit:		tst	r2, #1
-		strneb	r4, [r1], #1
-		andne	r4, r4, #255
-		adcnes	r3, r3, r4
-		adcs	r0, r3, #0
-		load_regs	ea
+#define FN_ENTRY	ENTRY(csum_partial_copy_nocheck)
 
-.too_small:	teq	r2, #0
-		load_regs	eqea
-		cmp	r2, #2
-		blt	.too_small1
-		load2b	ip, r8
-		orr	ip, ip, r8, lsl #8
-		adds	r3, r3, ip
-		strb	ip, [r1], #1
-		strb	r8, [r1], #1
-		tst	r2, #1
-.too_small1:				@ C = 0
-		beq	.csum_exit
-		load1b	ip
-		strb	ip, [r1], #1
-		adcs	r3, r3, ip
-.csum_exit:	adc	r0, r3, #0
-		load_regs	ea
-
-.src_not_aligned:
-		cmp	r2, #4
-		blt	.too_small
-		and	ip, r0, #3
-		bic	r0, r0, #3
-		load1l	r4
-		cmp	ip, #2
-		beq	.src2_aligned
-		bhi	.src3_aligned
-		mov	r4, r4, lsr #8
-		adds	r3, r3, #0
-		bics	ip, r2, #15
-		beq	2f
-1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
-		mov	r6, r6, lsr #8
-		orr	r6, r6, r7, lsl #24
-		mov	r7, r7, lsr #8
-		orr	r7, r7, r8, lsl #24
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		mov	r4, r8, lsr #8
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r5, r6
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		mov	r4, r6, lsr #8
-		tst	ip, #4
-		beq	4f
-3:		load1l	r5
-		orr	r4, r4, r5, lsl #24
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-		mov	r4, r5, lsr #8
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		b	.exit
-
-.src2_aligned:	mov	r4, r4, lsr #16
-		adds	r3, r3, #0
-		bics	ip, r2, #15
-		beq	2f
-1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
-		mov	r6, r6, lsr #16
-		orr	r6, r6, r7, lsl #16
-		mov	r7, r7, lsr #16
-		orr	r7, r7, r8, lsl #16
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		mov	r4, r8, lsr #16
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r5, r6
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		mov	r4, r6, lsr #16
-		tst	ip, #4
-		beq	4f
-3:		load1l	r5
-		orr	r4, r4, r5, lsl #16
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-		mov	r4, r5, lsr #16
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [r1], #1
-		tst	r2, #1
-		adceq	r0, r3, #0
-		load_regs	eqea
-		load1b	r4
-		b	.exit
-
-.src3_aligned:	mov	r4, r4, lsr #24
-		adds	r3, r3, #0
-		bics	ip, r2, #15
-		beq	2f
-1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
-		mov	r6, r6, lsr #24
-		orr	r6, r6, r7, lsl #8
-		mov	r7, r7, lsr #24
-		orr	r7, r7, r8, lsl #8
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		mov	r4, r8, lsr #24
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r5, r6
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		mov	r4, r6, lsr #24
-		tst	ip, #4
-		beq	4f
-3:		load1l	r5
-		orr	r4, r4, r5, lsl #8
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-		mov	r4, r5, lsr #24
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		load1l	r4
-		strb	r4, [r1], #1
-		adcs	r3, r3, r4, lsl #24
-		mov	r4, r4, lsr #8
-		b	.exit
+#include "csumpartialcopygeneric.S"
diff -u --recursive --new-file v2.4.4/linux/arch/arm/lib/csumpartialcopygeneric.S linux/arch/arm/lib/csumpartialcopygeneric.S
--- v2.4.4/linux/arch/arm/lib/csumpartialcopygeneric.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/arm/lib/csumpartialcopygeneric.S	Wed May 16 15:25:16 2001
@@ -0,0 +1,327 @@
+/*
+ *  linux/arch/arm/lib/csumpartialcopygeneric.S
+ *
+ *  Copyright (C) 1995-2001 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * unsigned int
+ * csum_partial_copy_xxx(const char *src, char *dst, int len, int sum, )
+ *  r0 = src, r1 = dst, r2 = len, r3 = sum
+ *  Returns : r0 = checksum
+ *
+ * Note that 'tst' and 'teq' preserve the carry flag.
+ */
+
+src	.req	r0
+dst	.req	r1
+len	.req	r2
+sum	.req	r3
+
+.zero:		mov	r0, sum
+		load_regs	ea
+
+		/*
+		 * Align an unaligned destination pointer.  We know that
+		 * we have >= 8 bytes here, so we don't need to check
+		 * the length.  Note that the source pointer hasn't been
+		 * aligned yet.
+		 */
+.dst_unaligned:	tst	dst, #1
+		beq	.dst_16bit
+
+		load1b	ip
+		sub	len, len, #1
+		adcs	sum, sum, ip, lsl #8	@ update checksum
+		strb	ip, [dst], #1
+		tst	dst, #2
+		moveq	pc, lr			@ dst is now 32bit aligned
+
+.dst_16bit:	load2b	r8, ip
+		sub	len, len, #2
+		adcs	sum, sum, r8
+		strb	r8, [dst], #1
+		adcs	sum, sum, ip, lsl #8
+		strb	ip, [dst], #1
+		mov	pc, lr			@ dst is now 32bit aligned
+
+		/*
+		 * Handle 0 to 7 bytes, with any alignment of source and
+		 * destination pointers.  Note that when we get here, C = 0
+		 */
+.less8:		teq	len, #0			@ check for zero count
+		beq	.zero
+
+		/* we must have at least one byte. */
+		tst	dst, #1			@ dst 16-bit aligned
+		beq	.less8_aligned
+
+		/* Align dst */
+		load1b	ip
+		sub	len, len, #1
+		adcs	sum, sum, ip, lsl #8	@ update checksum
+		strb	ip, [dst], #1
+		tst	len, #6
+		beq	.less8_byteonly
+
+1:		load2b	r8, ip
+		sub	len, len, #2
+		adcs	sum, sum, r8
+		strb	r8, [dst], #1
+		adcs	sum, sum, ip, lsl #8
+		strb	ip, [dst], #1
+.less8_aligned:	tst	len, #6
+		bne	1b
+.less8_byteonly:
+		tst	len, #1
+		beq	.done
+		load1b	r8
+		adcs	sum, sum, r8		@ update checksum
+		strb	r8, [dst], #1
+		b	.done
+
+FN_ENTRY
+		mov	ip, sp
+		save_regs
+		sub	fp, ip, #4
+
+		cmp	len, #8			@ Ensure that we have at least
+		blo	.less8			@ 8 bytes to copy.
+
+		adds	sum, sum, #0		@ C = 0
+		tst	dst, #3			@ Test destination alignment
+		blne	.dst_unaligned		@ align destination, return here
+
+		/*
+		 * Ok, the dst pointer is now 32bit aligned, and we know
+		 * that we must have more than 4 bytes to copy.  Note
+		 * that C contains the carry from the dst alignment above.
+		 */
+
+		tst	src, #3			@ Test source alignment
+		bne	.src_not_aligned
+
+		/* Routine for src & dst aligned */
+
+		bics	ip, len, #15
+		beq	2f
+
+1:		load4l	r4, r5, r6, r7
+		stmia	dst!, {r4, r5, r6, r7}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		adcs	sum, sum, r6
+		adcs	sum, sum, r7
+		sub	ip, ip, #16
+		teq	ip, #0
+		bne	1b
+
+2:		ands	ip, len, #12
+		beq	4f
+		tst	ip, #8
+		beq	3f
+		load2l	r4, r5
+		stmia	dst!, {r4, r5}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		tst	ip, #4
+		beq	4f
+
+3:		load1l	r4
+		str	r4, [dst], #4
+		adcs	sum, sum, r4
+
+4:		ands	len, len, #3
+		beq	.done
+		load1l	r4
+		tst	len, #2
+		beq	.exit
+		adcs	sum, sum, r4, lsl #16
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+.exit:		tst	len, #1
+		strneb	r4, [dst], #1
+		andne	r4, r4, #255
+		adcnes	sum, sum, r4
+
+		/*
+		 * If the dst pointer was not 16-bit aligned, we
+		 * need to rotate the checksum here to get around
+		 * the inefficient byte manipulations in the
+		 * architecture independent code.
+		 */
+.done:		adc	r0, sum, #0
+		ldr	sum, [sp, #0]		@ dst
+		tst	sum, #1
+		movne	sum, r0, lsl #8
+		orrne	r0, sum, r0, lsr #24
+		load_regs	ea
+
+.src_not_aligned:
+		adc	sum, sum, #0		@ include C from dst alignment
+		and	ip, src, #3
+		bic	src, src, #3
+		load1l	r4
+		cmp	ip, #2
+		beq	.src2_aligned
+		bhi	.src3_aligned
+		mov	r4, r4, lsr #8		@ C = 0
+		bics	ip, len, #15
+		beq	2f
+1:		load4l	r5, r6, r7, r8
+		orr	r4, r4, r5, lsl #24
+		mov	r5, r5, lsr #8
+		orr	r5, r5, r6, lsl #24
+		mov	r6, r6, lsr #8
+		orr	r6, r6, r7, lsl #24
+		mov	r7, r7, lsr #8
+		orr	r7, r7, r8, lsl #24
+		stmia	dst!, {r4, r5, r6, r7}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		adcs	sum, sum, r6
+		adcs	sum, sum, r7
+		mov	r4, r8, lsr #8
+		sub	ip, ip, #16
+		teq	ip, #0
+		bne	1b
+2:		ands	ip, len, #12
+		beq	4f
+		tst	ip, #8
+		beq	3f
+		load2l	r5, r6
+		orr	r4, r4, r5, lsl #24
+		mov	r5, r5, lsr #8
+		orr	r5, r5, r6, lsl #24
+		stmia	dst!, {r4, r5}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		mov	r4, r6, lsr #8
+		tst	ip, #4
+		beq	4f
+3:		load1l	r5
+		orr	r4, r4, r5, lsl #24
+		str	r4, [dst], #4
+		adcs	sum, sum, r4
+		mov	r4, r5, lsr #8
+4:		ands	len, len, #3
+		beq	.done
+		tst	len, #2
+		beq	.exit
+		adcs	sum, sum, r4, lsl #16
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+		b	.exit
+
+.src2_aligned:	mov	r4, r4, lsr #16
+		adds	sum, sum, #0
+		bics	ip, len, #15
+		beq	2f
+1:		load4l	r5, r6, r7, r8
+		orr	r4, r4, r5, lsl #16
+		mov	r5, r5, lsr #16
+		orr	r5, r5, r6, lsl #16
+		mov	r6, r6, lsr #16
+		orr	r6, r6, r7, lsl #16
+		mov	r7, r7, lsr #16
+		orr	r7, r7, r8, lsl #16
+		stmia	dst!, {r4, r5, r6, r7}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		adcs	sum, sum, r6
+		adcs	sum, sum, r7
+		mov	r4, r8, lsr #16
+		sub	ip, ip, #16
+		teq	ip, #0
+		bne	1b
+2:		ands	ip, len, #12
+		beq	4f
+		tst	ip, #8
+		beq	3f
+		load2l	r5, r6
+		orr	r4, r4, r5, lsl #16
+		mov	r5, r5, lsr #16
+		orr	r5, r5, r6, lsl #16
+		stmia	dst!, {r4, r5}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		mov	r4, r6, lsr #16
+		tst	ip, #4
+		beq	4f
+3:		load1l	r5
+		orr	r4, r4, r5, lsl #16
+		str	r4, [dst], #4
+		adcs	sum, sum, r4
+		mov	r4, r5, lsr #16
+4:		ands	len, len, #3
+		beq	.done
+		tst	len, #2
+		beq	.exit
+		adcs	sum, sum, r4, lsl #16
+		strb	r4, [dst], #1
+		mov	r4, r4, lsr #8
+		strb	r4, [dst], #1
+		tst	len, #1
+		beq	.done
+		load1b	r4
+		b	.exit
+
+.src3_aligned:	mov	r4, r4, lsr #24
+		adds	sum, sum, #0
+		bics	ip, len, #15
+		beq	2f
+1:		load4l	r5, r6, r7, r8
+		orr	r4, r4, r5, lsl #8
+		mov	r5, r5, lsr #24
+		orr	r5, r5, r6, lsl #8
+		mov	r6, r6, lsr #24
+		orr	r6, r6, r7, lsl #8
+		mov	r7, r7, lsr #24
+		orr	r7, r7, r8, lsl #8
+		stmia	dst!, {r4, r5, r6, r7}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		adcs	sum, sum, r6
+		adcs	sum, sum, r7
+		mov	r4, r8, lsr #24
+		sub	ip, ip, #16
+		teq	ip, #0
+		bne	1b
+2:		ands	ip, len, #12
+		beq	4f
+		tst	ip, #8
+		beq	3f
+		load2l	r5, r6
+		orr	r4, r4, r5, lsl #8
+		mov	r5, r5, lsr #24
+		orr	r5, r5, r6, lsl #8
+		stmia	dst!, {r4, r5}
+		adcs	sum, sum, r4
+		adcs	sum, sum, r5
+		mov	r4, r6, lsr #24
+		tst	ip, #4
+		beq	4f
+3:		load1l	r5
+		orr	r4, r4, r5, lsl #8
+		str	r4, [dst], #4
+		adcs	sum, sum, r4
+		mov	r4, r5, lsr #24
+4:		ands	len, len, #3
+		beq	.done
+		tst	len, #2
+		beq	.exit
+		adcs	sum, sum, r4, lsl #16
+		strb	r4, [dst], #1
+		load1l	r4
+		strb	r4, [dst], #1
+		adcs	sum, sum, r4, lsl #24
+		mov	r4, r4, lsr #8
+		b	.exit
diff -u --recursive --new-file v2.4.4/linux/arch/arm/lib/csumpartialcopyuser.S linux/arch/arm/lib/csumpartialcopyuser.S
--- v2.4.4/linux/arch/arm/lib/csumpartialcopyuser.S	Tue Mar  6 19:44:35 2001
+++ linux/arch/arm/lib/csumpartialcopyuser.S	Wed May 16 15:25:16 2001
@@ -15,10 +15,6 @@
 
 		.text
 
-/* Function: __u32 csum_partial_copy_from_user (const char *src, char *dst, int len, __u32 sum, int *err_ptr)
- * Params  : r0 = src, r1 = dst, r2 = len, r3 = sum, [sp, #0] = &err
- * Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
- */
 #if defined(CONFIG_CPU_32)
 
 		.macro	save_regs
@@ -152,253 +148,16 @@
 #error Unknown CPU architecture
 #endif
 
-ENTRY(csum_partial_copy_from_user)
-		mov	ip, sp
-		save_regs
-		sub	fp, ip, #4
-		cmp	r2, #4
-		blt	.too_small
-		tst	r1, #2			@ Test destination alignment
-		beq	.dst_aligned
-		load2b	ip, r8
-		subs	r2, r2, #2		@ We do not know if SRC is aligned...
-		orr	ip, ip, r8, lsl #8
-		adds	r3, r3, ip
-		adcs	r3, r3, #0
-		strb	ip, [r1], #1
-		mov	ip, ip, lsr #8
-		strb	ip, [r1], #1		@ Destination now aligned
-.dst_aligned:	tst	r0, #3
-		bne	.src_not_aligned
-		adds	r3, r3, #0
-		bics	ip, r2, #15		@ Routine for src & dst aligned
-		beq	2f
-1:		load4l	r4, r5, r6, r7
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r4, r5
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		tst	ip, #4
-		beq	4f
-3:		load1l	r4
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		load1l	r4
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-.exit:		tst	r2, #1
-		strneb	r4, [r1], #1
-		andne	r4, r4, #255
-		adcnes	r3, r3, r4
-		adcs	r0, r3, #0
-		load_regs	ea
-
-.too_small:	teq	r2, #0
-		load_regs	eqea
-		cmp	r2, #2
-		blt	.too_small1
-		load2b	ip, r8
-		orr	ip, ip, r8, lsl #8
-		adds	r3, r3, ip
-		strb	ip, [r1], #1
-		strb	r8, [r1], #1
-		tst	r2, #1
-.too_small1:				@ C = 0
-		beq	.csum_exit
-		load1b	ip
-		strb	ip, [r1], #1
-		adcs	r3, r3, ip
-.csum_exit:	adc	r0, r3, #0
-		load_regs	ea
-
-.src_not_aligned:
-		cmp	r2, #4
-		blt	.too_small
-		and	ip, r0, #3
-		bic	r0, r0, #3
-		load1l	r4
-		cmp	ip, #2
-		beq	.src2_aligned
-		bhi	.src3_aligned
-		mov	r4, r4, lsr #8
-		adds	r3, r3, #0
-		bics	ip, r2, #15
-		beq	2f
-1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
-		mov	r6, r6, lsr #8
-		orr	r6, r6, r7, lsl #24
-		mov	r7, r7, lsr #8
-		orr	r7, r7, r8, lsl #24
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		mov	r4, r8, lsr #8
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r5, r6
-		orr	r4, r4, r5, lsl #24
-		mov	r5, r5, lsr #8
-		orr	r5, r5, r6, lsl #24
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		mov	r4, r6, lsr #8
-		tst	ip, #4
-		beq	4f
-3:		load1l	r5
-		orr	r4, r4, r5, lsl #24
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-		mov	r4, r5, lsr #8
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		b	.exit
-
-.src2_aligned:	mov	r4, r4, lsr #16
-		adds	r3, r3, #0
-		bics	ip, r2, #15
-		beq	2f
-1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
-		mov	r6, r6, lsr #16
-		orr	r6, r6, r7, lsl #16
-		mov	r7, r7, lsr #16
-		orr	r7, r7, r8, lsl #16
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		mov	r4, r8, lsr #16
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r5, r6
-		orr	r4, r4, r5, lsl #16
-		mov	r5, r5, lsr #16
-		orr	r5, r5, r6, lsl #16
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		mov	r4, r6, lsr #16
-		tst	ip, #4
-		beq	4f
-3:		load1l	r5
-		orr	r4, r4, r5, lsl #16
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-		mov	r4, r5, lsr #16
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		mov	r4, r4, lsr #8
-		strb	r4, [r1], #1
-		tst	r2, #1
-		adceq	r0, r3, #0
-		load_regs	eqea
-		load1b	r4
-		b	.exit
-
-.src3_aligned:	mov	r4, r4, lsr #24
-		adds	r3, r3, #0
-		bics	ip, r2, #15
-		beq	2f
-1:		load4l	r5, r6, r7, r8
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
-		mov	r6, r6, lsr #24
-		orr	r6, r6, r7, lsl #8
-		mov	r7, r7, lsr #24
-		orr	r7, r7, r8, lsl #8
-		stmia	r1!, {r4, r5, r6, r7}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		adcs	r3, r3, r6
-		adcs	r3, r3, r7
-		mov	r4, r8, lsr #24
-		sub	ip, ip, #16
-		teq	ip, #0
-		bne	1b
-2:		ands	ip, r2, #12
-		beq	4f
-		tst	ip, #8
-		beq	3f
-		load2l	r5, r6
-		orr	r4, r4, r5, lsl #8
-		mov	r5, r5, lsr #24
-		orr	r5, r5, r6, lsl #8
-		stmia	r1!, {r4, r5}
-		adcs	r3, r3, r4
-		adcs	r3, r3, r5
-		mov	r4, r6, lsr #24
-		tst	ip, #4
-		beq	4f
-3:		load1l	r5
-		orr	r4, r4, r5, lsl #8
-		str	r4, [r1], #4
-		adcs	r3, r3, r4
-		mov	r4, r5, lsr #24
-4:		ands	r2, r2, #3
-		adceq	r0, r3, #0
-		load_regs	eqea
-		tst	r2, #2
-		beq	.exit
-		adcs	r3, r3, r4, lsl #16
-		strb	r4, [r1], #1
-		load1l	r4
-		strb	r4, [r1], #1
-		adcs	r3, r3, r4, lsl #24
-		mov	r4, r4, lsr #8
-		b	.exit
+/*
+ * unsigned int
+ * csum_partial_copy_from_user(const char *src, char *dst, int len, int sum, int *err_ptr)
+ *  r0 = src, r1 = dst, r2 = len, r3 = sum, [sp] = *err_ptr
+ *  Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
+ */
+
+#define FN_ENTRY	ENTRY(csum_partial_copy_from_user)
+
+#include "csumpartialcopygeneric.S"
 
 /*
  * FIXME: minor buglet here
@@ -411,13 +170,13 @@
 #endif
 		.align	4
 6001:		mov	r4, #-EFAULT
-		ldr	r5, [fp, #4]
+		ldr	r5, [fp, #4]		@ *err_ptr
 		str	r4, [r5]
-		ldmia	sp, {r1, r2}		@ retrieve original arguments
+		ldmia	sp, {r1, r2}		@ retrieve dst, len
 		add	r2, r2, r1
-		mov	r3, #0			@ zero the buffer
+		mov	r0, #0			@ zero the buffer
 6002:		teq	r2, r1
-		strneb	r3, [r1], #1
+		strneb	r0, [r1], #1
 		bne	6002b
 		load_regs	ea
 #if defined(CONFIG_CPU_32)
diff -u --recursive --new-file v2.4.4/linux/arch/arm/mach-ebsa110/io.c linux/arch/arm/mach-ebsa110/io.c
--- v2.4.4/linux/arch/arm/mach-ebsa110/io.c	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/mach-ebsa110/io.c	Sun May 20 12:11:38 2001
@@ -20,7 +20,6 @@
  * Luckily, the work-around for this is not too horrible.  See
  * __isamem_convert_addr for the details.
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
diff -u --recursive --new-file v2.4.4/linux/arch/arm/mach-sa1100/dma.h linux/arch/arm/mach-sa1100/dma.h
--- v2.4.4/linux/arch/arm/mach-sa1100/dma.h	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/mach-sa1100/dma.h	Sun May 20 12:11:38 2001
@@ -7,6 +7,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/config.h>
 
 /*
  * DMA channel structure.
diff -u --recursive --new-file v2.4.4/linux/arch/arm/mm/fault-armv.c linux/arch/arm/mm/fault-armv.c
--- v2.4.4/linux/arch/arm/mm/fault-armv.c	Thu Apr 12 12:20:31 2001
+++ linux/arch/arm/mm/fault-armv.c	Wed May 16 15:25:16 2001
@@ -132,7 +132,7 @@
 
 #define get8_unaligned_check(val,addr,err)		\
 	__asm__(					\
-	"1:	ldrb	%1, [%2]\n"			\
+	"1:	ldrb	%1, [%2], #1\n"			\
 	"2:\n"						\
 	"	.section .fixup,\"ax\"\n"		\
 	"	.align	2\n"				\
@@ -148,7 +148,7 @@
 
 #define get8t_unaligned_check(val,addr,err)		\
 	__asm__(					\
-	"1:	ldrbt	%1, [%2]\n"			\
+	"1:	ldrbt	%1, [%2], #1\n"			\
 	"2:\n"						\
 	"	.section .fixup,\"ax\"\n"		\
 	"	.align	2\n"				\
diff -u --recursive --new-file v2.4.4/linux/arch/arm/vmlinux-armv.lds.in linux/arch/arm/vmlinux-armv.lds.in
--- v2.4.4/linux/arch/arm/vmlinux-armv.lds.in	Tue Mar  6 19:44:35 2001
+++ linux/arch/arm/vmlinux-armv.lds.in	Wed May 16 15:25:16 2001
@@ -44,11 +44,12 @@
 			*(.rodata)
 			*(.glue_7)
 			*(.glue_7t)
-			*(.kstrtab)
 		*(.got)			/* Global offset table		*/
 
 		_etext = .;		/* End of text section		*/
 	}
+
+	.kstrtab : { *(.kstrtab) }
 
 	. = ALIGN(16);
 	__ex_table : {			/* Exception table		*/
diff -u --recursive --new-file v2.4.4/linux/arch/cris/Makefile linux/arch/cris/Makefile
--- v2.4.4/linux/arch/cris/Makefile	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/Makefile	Tue May  1 16:04:56 2001
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.15 2001/02/16 17:50:04 larsv Exp $
+# $Id: Makefile,v 1.18 2001/04/17 13:58:38 orjanf Exp $
 # cris/Makefile
 #
 # This file is included by the global makefile so that you can add your own
@@ -25,8 +25,8 @@
 # regenerating stuff (even for incremental linking of subsystems!) is
 # even more nauseating.
 LD = if [ ! -e $(LD_SCRIPT).tmp -o $(LD_SCRIPT) -nt $(LD_SCRIPT).tmp ]; then \
-          sed -e s/@ETRAX_DRAM_VIRTUAL_BASE@/0x$(ETRAX_DRAM_VIRTUAL_BASE)/ \
-              -e s/@ETRAX_DRAM_SIZE_M@/$(ETRAX_DRAM_SIZE)/ \
+          sed -e s/@CONFIG_ETRAX_DRAM_VIRTUAL_BASE@/0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE)/ \
+              -e s/@CONFIG_ETRAX_DRAM_SIZE_M@/$(CONFIG_ETRAX_DRAM_SIZE)/ \
               < $(LD_SCRIPT) > $(LD_SCRIPT).tmp; \
      else true; \
      fi && $(CROSS_COMPILE)ld -mcriself
@@ -42,7 +42,7 @@
 
 CFLAGS := $(CFLAGS) -march=v10 -fno-strict-aliasing -pipe -D__linux__
 
-ifdef CONFIG_KGDB
+ifdef CONFIG_ETRAX_KGDB
 CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -g
 CFLAGS += -fno-omit-frame-pointer
 endif
@@ -76,7 +76,7 @@
 
 cramfs:
 ## cramfs      - Creates a cramfs image
-	mkcramfs -b 8192 root cramfs.img
+	mkcramfs -b 8192 -m romfs_meta.txt root cramfs.img
 	cat vmlinux.bin cramfs.img >timage
 
 clinux: vmlinux.bin decompress.bin rescue.bin
diff -u --recursive --new-file v2.4.4/linux/arch/cris/boot/compressed/Makefile linux/arch/cris/boot/compressed/Makefile
--- v2.4.4/linux/arch/cris/boot/compressed/Makefile	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/boot/compressed/Makefile	Tue May  1 16:04:56 2001
@@ -24,7 +24,7 @@
 
 
 vmlinuz: piggy.img decompress.bin
-	cat decompress.bin piggy.img $(TOPDIR)/cramfs.img > vmlinuz
+	cat decompress.bin piggy.img > vmlinuz
 	rm -f piggy.img
 
 head.o: head.S
diff -u --recursive --new-file v2.4.4/linux/arch/cris/boot/compressed/head.S linux/arch/cris/boot/compressed/head.S
--- v2.4.4/linux/arch/cris/boot/compressed/head.S	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/boot/compressed/head.S	Tue May  1 16:04:56 2001
@@ -1,16 +1,19 @@
 /*
- *  arch/etrax100/boot/compressed/head.S
+ *  arch/cris/boot/compressed/head.S
  *
- *  Copyright (C) 1999 Axis Communications AB
+ *  Copyright (C) 1999, 2001 Axis Communications AB
  *
  *  Code that sets up the DRAM registers, calls the
  *  decompressor to unpack the piggybacked kernel, and jumps.
  *
  */
 
+#include <linux/config.h>
 #define ASSEMBLER_MACROS_ONLY
 #include <asm/sv_addr_ag.h>
 
+#define RAM_INIT_MAGIC 0x56902387
+	
 	;; Exported symbols
 	
 	.globl	_input_data
@@ -21,23 +24,28 @@
 	nop
 	di
 
-	;; We need to initialze DRAM registers before we start using the DRAM
-#include "../../lib/dram_init.S"
+;; We need to initialze DRAM registers before we start using the DRAM
 	
-dram_init_finished:
+	cmp.d	RAM_INIT_MAGIC, r8	; Already initialized?
+	beq	dram_init_finished
+	nop
+	
+#include "../../lib/dram_init.S"
 	
+dram_init_finished:	
+		
 	;; Initiate the PA and PB ports
 
-	move.b   DEF_R_PORT_PA_DATA, r0
+	move.b   CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r0
 	move.b   r0, [R_PORT_PA_DATA]
 
-	move.b   DEF_R_PORT_PA_DIR, r0
+	move.b   CONFIG_ETRAX_DEF_R_PORT_PA_DIR, r0
 	move.b   r0, [R_PORT_PA_DIR]
 
-	move.b   DEF_R_PORT_PB_DATA, r0
+	move.b   CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r0
 	move.b   r0, [R_PORT_PB_DATA]
 
-	move.b   DEF_R_PORT_PB_DIR, r0
+	move.b   CONFIG_ETRAX_DEF_R_PORT_PB_DIR, r0
 	move.b   r0, [R_PORT_PB_DIR]
 
 	;; Setup the stack to a suitably high address.
@@ -70,6 +78,7 @@
 
 	move.d	r5, [_input_data] ; for the decompressor
 
+
 	;; Clear the decompressors BSS (between _edata and _end)
 	
 	moveq	0, r0
@@ -81,19 +90,22 @@
 	nop
 	
 	;; Do the decompression and save compressed size in _inptr
-	
+
 	jsr	_decompress_kernel
 	
-	;; Put start address of cramfs in r9 so the kernel can use it
+	;; Put start address of root partition in r9 so the kernel can use it
 	;; when mounting from flash
 
 	move.d	[_input_data], r9	; flash address of compressed kernel
 	add.d	[_inptr], r9		; size of compressed kernel
-
+	 
 	;; Enter the decompressed kernel
+	move.d	RAM_INIT_MAGIC, r8	; Tell kernel that DRAM is initialized
 	jump	0x40004000	; kernel is linked to this address
 	
 	.data
 
 _input_data:
 	.dword	0		; used by the decompressor
+
+#include "../../lib/hw_settings.S"
diff -u --recursive --new-file v2.4.4/linux/arch/cris/boot/compressed/misc.c linux/arch/cris/boot/compressed/misc.c
--- v2.4.4/linux/arch/cris/boot/compressed/misc.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/boot/compressed/misc.c	Tue May  1 16:04:56 2001
@@ -1,7 +1,7 @@
 /*
  * misc.c
  *
- * $Id: misc.c,v 1.3 2001/01/17 15:54:18 jonashg Exp $
+ * $Id: misc.c,v 1.6 2001/04/09 10:00:21 starvik Exp $
  * 
  * This is a collection of several routines from gzip-1.0.3 
  * adapted for Linux.
@@ -21,6 +21,7 @@
 #define KERNEL_LOAD_ADR 0x40004000
 
 #include <linux/config.h>
+
 #include <linux/types.h>
 #include <asm/svinto.h>
 
@@ -143,21 +144,21 @@
 static void
 puts(const char *s)
 {
-#ifndef CONFIG_DEBUG_PORT_NULL
+#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
 	while(*s) {
-#ifdef CONFIG_DEBUG_PORT0
+#ifdef CONFIG_ETRAX_DEBUG_PORT0
 		while(!(*R_SERIAL0_STATUS & (1 << 5))) ;
 		*R_SERIAL0_TR_DATA = *s++;
 #endif
-#ifdef CONFIG_DEBUG_PORT1
+#ifdef CONFIG_ETRAX_DEBUG_PORT1
 		while(!(*R_SERIAL1_STATUS & (1 << 5))) ;
 		*R_SERIAL1_TR_DATA = *s++;
 #endif
-#ifdef CONFIG_DEBUG_PORT2
+#ifdef CONFIG_ETRAX_DEBUG_PORT2
 		while(!(*R_SERIAL2_STATUS & (1 << 5))) ;
 		*R_SERIAL2_TR_DATA = *s++;
 #endif
-#ifdef CONFIG_DEBUG_PORT3
+#ifdef CONFIG_ETRAX_DEBUG_PORT3
 		while(!(*R_SERIAL3_STATUS & (1 << 5))) ;
 		*R_SERIAL3_TR_DATA = *s++;
 #endif
@@ -227,33 +228,45 @@
 void
 decompress_kernel()
 {
+	char revision;
+	
 	/* input_data is set in head.S */
 	inbuf = input_data;
 
-#ifdef CONFIG_DEBUG_PORT0
+#ifdef CONFIG_ETRAX_DEBUG_PORT0
 	*R_SERIAL0_XOFF = 0;
 	*R_SERIAL0_BAUD = 0x99;
 	*R_SERIAL0_TR_CTRL = 0x40;
 #endif
-#ifdef CONFIG_DEBUG_PORT1
+#ifdef CONFIG_ETRAX_DEBUG_PORT1
 	*R_SERIAL1_XOFF = 0;
 	*R_SERIAL1_BAUD = 0x99;
 	*R_SERIAL1_TR_CTRL = 0x40;
 #endif
-#ifdef CONFIG_DEBUG_PORT2
+#ifdef CONFIG_ETRAX_DEBUG_PORT2
+	*R_GEN_CONFIG = 0x08;
 	*R_SERIAL2_XOFF = 0;
 	*R_SERIAL2_BAUD = 0x99;
 	*R_SERIAL2_TR_CTRL = 0x40;
 #endif
-#ifdef CONFIG_DEBUG_PORT3
+#ifdef CONFIG_ETRAX_DEBUG_PORT3
+	*R_GEN_CONFIG = 0x100;
 	*R_SERIAL3_XOFF = 0;
 	*R_SERIAL3_BAUD = 0x99;
 	*R_SERIAL3_TR_CTRL = 0x40;
 #endif
-       
+
 	setup_normal_output_buffer();
 
 	makecrc();
+
+	__asm__ volatile ("move vr,%0" : "=rm" (revision));
+	if (revision < 10)
+	{
+		puts("You need an ETRAX 100LX to run linux 2.4\n");
+		while(1);
+	}
+
 	puts("Uncompressing Linux...\n");
 	gunzip();
 	puts("Done. Now booting the kernel.\n");
diff -u --recursive --new-file v2.4.4/linux/arch/cris/boot/rescue/head.S linux/arch/cris/boot/rescue/head.S
--- v2.4.4/linux/arch/cris/boot/rescue/head.S	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/boot/rescue/head.S	Tue May  1 16:04:56 2001
@@ -1,66 +1,67 @@
-	;; $Id: head.S,v 1.3 2001/02/14 16:57:25 larsv Exp $
-	;; 
-	;; Rescue code, made to reside at the beginning of the
-	;; flash-memory. when it starts, it checks a partition
-	;; table at the first sector after the rescue sector.
-	;; the partition table was generated by the product builder
-	;; script and contains offsets, lengths, types and checksums
-	;; for each partition that this code should check.
-	;;
-	;; If any of the checksums fail, we assume the flash is so
-	;; corrupt that we cant use it to boot into the ftp flash
-	;; loader, and instead we initialize the serial port to
-	;; receive a flash-loader and new flash image. we dont include
-	;; any flash code here, but just accept a certain amount of
-	;; bytes from the serial port and jump into it. the downloaded
-	;; code is put in the cache.
-	;;
-	;; The partitiontable is designed so that it is transparent to
-	;; code execution - it has a relative branch opcode in the
-	;; beginning that jumps over it. each entry contains extra
-	;; data so we can add stuff later.
-	;;
-	;; Partition table format:
-	;;
-	;;     Code transparency:
-	;; 
-	;;     2 bytes    [opcode 'nop']
-	;;     2 bytes    [opcode 'di']
-	;;     4 bytes    [opcode 'ba <offset>', 8-bit or 16-bit version]
-	;;     2 bytes    [opcode 'nop', delay slot]
-	;;
-	;;     Table validation (at +10):	
-	;; 
-	;;     2 bytes    [magic/version word for partitiontable - 0xef, 0xbe]
-	;;     2 bytes    [length of all entries plus the end marker]
-	;;     4 bytes    [checksum for the partitiontable itself]
-	;;
-	;;     Entries, each with the following format, last has offset -1:	
-	;;    
-	;;        4 bytes    [offset in bytes, from start of flash]
-	;;        4 bytes    [length in bytes of partition]
-	;;        4 bytes    [checksum, simple longword sum]
-	;;        2 bytes    [partition type]
-	;;        2 bytes    [flags, only bit 0 used, ro/rw = 1/0]
-	;;        16 bytes   [reserved for future use]
-	;;
-	;;     End marker
-	;;
-	;;        4 bytes    [-1]
-	;; 
-	;;	 10 bytes    [0, padding]
-	;; 
-	;; Bit 0 in flags signifies RW or RO. The rescue code only bothers
-	;; to check the checksum for RO partitions, since the others will
-	;; change its data without updating the checksums. A 1 in bit 0
-	;; means RO, 0 means RW. That way, it is possible to set a partition
-	;; in RO mode initially, and later mark it as RW, since you can always
-	;; write 0's to the flash.
-	;;
-	;; During the wait for serial input, the status LED will flash so the
-	;; user knows something went wrong.
-	;; 
-	;; Copyright (C) 1999 Axis Communications AB
+/* $Id: head.S,v 1.7 2001/04/18 12:05:07 bjornw Exp $
+ * 
+ * Rescue code, made to reside at the beginning of the
+ * flash-memory. when it starts, it checks a partition
+ * table at the first sector after the rescue sector.
+ * the partition table was generated by the product builder
+ * script and contains offsets, lengths, types and checksums
+ * for each partition that this code should check.
+ *
+ * If any of the checksums fail, we assume the flash is so
+ * corrupt that we cant use it to boot into the ftp flash
+ * loader, and instead we initialize the serial port to
+ * receive a flash-loader and new flash image. we dont include
+ * any flash code here, but just accept a certain amount of
+ * bytes from the serial port and jump into it. the downloaded
+ * code is put in the cache.
+ *
+ * The partitiontable is designed so that it is transparent to
+ * code execution - it has a relative branch opcode in the
+ * beginning that jumps over it. each entry contains extra
+ * data so we can add stuff later.
+ *
+ * Partition table format:
+ *
+ *     Code transparency:
+ * 
+ *     2 bytes    [opcode 'nop']
+ *     2 bytes    [opcode 'di']
+ *     4 bytes    [opcode 'ba <offset>', 8-bit or 16-bit version]
+ *     2 bytes    [opcode 'nop', delay slot]
+ *
+ *     Table validation (at +10):	
+ * 
+ *     2 bytes    [magic/version word for partitiontable - 0xef, 0xbe]
+ *     2 bytes    [length of all entries plus the end marker]
+ *     4 bytes    [checksum for the partitiontable itself]
+ *
+ *     Entries, each with the following format, last has offset -1:	
+ *    
+ *        4 bytes    [offset in bytes, from start of flash]
+ *        4 bytes    [length in bytes of partition]
+ *        4 bytes    [checksum, simple longword sum]
+ *        2 bytes    [partition type]
+ *        2 bytes    [flags, only bit 0 used, ro/rw = 1/0]
+ *        16 bytes   [reserved for future use]
+ *
+ *     End marker
+ *
+ *        4 bytes    [-1]
+ * 
+ *	 10 bytes    [0, padding]
+ * 
+ * Bit 0 in flags signifies RW or RO. The rescue code only bothers
+ * to check the checksum for RO partitions, since the others will
+ * change its data without updating the checksums. A 1 in bit 0
+ * means RO, 0 means RW. That way, it is possible to set a partition
+ * in RO mode initially, and later mark it as RW, since you can always
+ * write 0's to the flash.
+ *
+ * During the wait for serial input, the status LED will flash so the
+ * user knows something went wrong.
+ * 
+ * Copyright (C) 1999,2001 Axis Communications AB
+ */
 
 #include <linux/config.h>
 #define ASSEMBLER_MACROS_ONLY
@@ -69,7 +70,7 @@
 	;; The partitiontable is looked for at the first sector after the boot
 	;; sector. Sector size is 65536 bytes in all flashes we use.
 		
-#define PTABLE_START 0x10000
+#define PTABLE_START CONFIG_ETRAX_PTABLE_SECTOR
 #define PTABLE_MAGIC 0xbeef
 
 	;; The normal Etrax100 on-chip boot ROM does serial boot at 0x380000f0.
@@ -82,28 +83,28 @@
 #define CODE_START 0x40000000
 #define CODE_LENGTH 784
 
-#ifdef CONFIG_RESCUE_SER0
+#ifdef CONFIG_ETRAX_RESCUE_SER0
 #define SERXOFF R_SERIAL0_XOFF
 #define SERBAUD R_SERIAL0_BAUD
 #define SERRECC R_SERIAL0_REC_CTRL
 #define SERRDAT R_SERIAL0_REC_DATA
 #define SERSTAT R_SERIAL0_STATUS
 #endif
-#ifdef CONFIG_RESCUE_SER1
+#ifdef CONFIG_ETRAX_RESCUE_SER1
 #define SERXOFF R_SERIAL1_XOFF
 #define SERBAUD R_SERIAL1_BAUD
 #define SERRECC R_SERIAL1_REC_CTRL
 #define SERRDAT R_SERIAL1_REC_DATA
 #define SERSTAT R_SERIAL1_STATUS
 #endif
-#ifdef CONFIG_RESCUE_SER2
+#ifdef CONFIG_ETRAX_RESCUE_SER2
 #define SERXOFF R_SERIAL2_XOFF
 #define SERBAUD R_SERIAL2_BAUD
 #define SERRECC R_SERIAL2_REC_CTRL
 #define SERRDAT R_SERIAL2_REC_DATA
 #define SERSTAT R_SERIAL2_STATUS
 #endif	
-#ifdef CONFIG_RESCUE_SER3
+#ifdef CONFIG_ETRAX_RESCUE_SER3
 #define SERXOFF R_SERIAL3_XOFF
 #define SERBAUD R_SERIAL3_BAUD
 #define SERRECC R_SERIAL3_REC_CTRL
@@ -112,7 +113,8 @@
 #endif
 
 #define NOP_DI 0xf025050f
-	
+#define RAM_INIT_MAGIC 0x56902387
+		
 	.text
 	
 	;; This is the entry point of the rescue code
@@ -221,14 +223,14 @@
 	;; setup port PA and PB default initial directions and data
 	;; (so we can flash LEDs, and so that DTR and others are set)
 	
-	move.b	DEF_R_PORT_PA_DIR, r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, r0
 	move.b	r0, [R_PORT_PA_DIR]
-	move.b	DEF_R_PORT_PA_DATA, r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r0
 	move.b	r0, [R_PORT_PA_DATA]
 	
-	move.b	DEF_R_PORT_PB_DIR, r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, r0
 	move.b	r0, [R_PORT_PB_DIR]
-	move.b	DEF_R_PORT_PB_DATA, r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r0
 	move.b	r0, [R_PORT_PB_DATA]
 
 	;; setup the serial port at 115200 baud
@@ -250,10 +252,10 @@
 	addq	1, r1
 #ifndef CONFIG_ETRAX_NO_LEDS
 #ifdef CONFIG_ETRAX_PA_LEDS
-	move.b	DEF_R_PORT_PA_DATA, r2
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r2
 #endif
 #ifdef CONFIG_ETRAX_PB_LEDS
-	move.b	DEF_R_PORT_PB_DATA, r2
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r2
 #endif
 	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), r0
 	btstq	16, r1
@@ -293,7 +295,8 @@
 	nop
 
 	;; jump into downloaded code
-	
+
+	move.d	RAM_INIT_MAGIC, r8	; Tell next product that DRAM is initialized
 	jump	CODE_START
 
 flash_ok:
@@ -303,7 +306,8 @@
 	bne	1f
 	nop
 	move.d	PTABLE_START, r7; otherwise use the ptable start
-1:	
+1:
+	move.d	RAM_INIT_MAGIC, r8	; Tell next product that DRAM is initialized
 	jump	r7		; boot!
 
 
diff -u --recursive --new-file v2.4.4/linux/arch/cris/boot/rescue/kimagerescue.S linux/arch/cris/boot/rescue/kimagerescue.S
--- v2.4.4/linux/arch/cris/boot/rescue/kimagerescue.S	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/boot/rescue/kimagerescue.S	Tue May  1 16:04:56 2001
@@ -1,41 +1,42 @@
-	;; $Id: kimagerescue.S,v 1.2 2001/02/14 16:57:25 larsv Exp $
-	;; 
-	;; Rescue code to be prepended on a kimage and copied to the
-	;; rescue serial port.
-	;; This is called from the rescue code, it will copy received data to
-	;; 4000500 and after a timeout jump to it.
-	
+/* $Id: kimagerescue.S,v 1.4 2001/04/18 12:04:46 bjornw Exp $
+ * 
+ * Rescue code to be prepended on a kimage and copied to the
+ * rescue serial port.
+ * This is called from the rescue code, it will copy received data to
+ * 4004000 and after a timeout jump to it.
+ */
+
 #include <linux/config.h>
 #define ASSEMBLER_MACROS_ONLY
 #include <asm/sv_addr_ag.h>
 
-#define CODE_START 0x40000500
+#define CODE_START 0x40004000
 #define CODE_LENGTH 784
 #define TIMEOUT_VALUE 1000
 	
 		
-#ifdef CONFIG_RESCUE_SER0
+#ifdef CONFIG_ETRAX_RESCUE_SER0
 #define SERXOFF R_SERIAL0_XOFF
 #define SERBAUD R_SERIAL0_BAUD
 #define SERRECC R_SERIAL0_REC_CTRL
 #define SERRDAT R_SERIAL0_REC_DATA
 #define SERSTAT R_SERIAL0_STATUS
 #endif
-#ifdef CONFIG_RESCUE_SER1
+#ifdef CONFIG_ETRAX_RESCUE_SER1
 #define SERXOFF R_SERIAL1_XOFF
 #define SERBAUD R_SERIAL1_BAUD
 #define SERRECC R_SERIAL1_REC_CTRL
 #define SERRDAT R_SERIAL1_REC_DATA
 #define SERSTAT R_SERIAL1_STATUS
 #endif
-#ifdef CONFIG_RESCUE_SER2
+#ifdef CONFIG_ETRAX_RESCUE_SER2
 #define SERXOFF R_SERIAL2_XOFF
 #define SERBAUD R_SERIAL2_BAUD
 #define SERRECC R_SERIAL2_REC_CTRL
 #define SERRDAT R_SERIAL2_REC_DATA
 #define SERSTAT R_SERIAL2_STATUS
 #endif	
-#ifdef CONFIG_RESCUE_SER3
+#ifdef CONFIG_ETRAX_RESCUE_SER3
 #define SERXOFF R_SERIAL3_XOFF
 #define SERBAUD R_SERIAL3_BAUD
 #define SERRECC R_SERIAL3_REC_CTRL
@@ -55,14 +56,14 @@
 	;; setup port PA and PB default initial directions and data
 	;; (so we can flash LEDs, and so that DTR and others are set)
 	
-	move.b	DEF_R_PORT_PA_DIR, r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, r0
 	move.b	r0, [R_PORT_PA_DIR]
-	move.b	DEF_R_PORT_PA_DATA, r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r0
 	move.b	r0, [R_PORT_PA_DATA]
 	
-	move.b	DEF_R_PORT_PB_DIR, r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, r0
 	move.b	r0, [R_PORT_PB_DIR]
-	move.b	DEF_R_PORT_PB_DATA, r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r0
 	move.b	r0, [R_PORT_PB_DATA]
 	
 	;; We need to setup the bus registers before we start using the DRAM
@@ -99,10 +100,10 @@
 	nop
 #ifndef CONFIG_ETRAX_NO_LEDS
 #ifdef CONFIG_ETRAX_PA_LEDS
-	move.b	DEF_R_PORT_PA_DATA, r2
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r2
 #endif
 #ifdef CONFIG_ETRAX_PB_LEDS
-	move.b	DEF_R_PORT_PB_DATA, r2
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r2
 #endif
 	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), r0
 	btstq	16, r1
diff -u --recursive --new-file v2.4.4/linux/arch/cris/boot/rescue/testrescue.S linux/arch/cris/boot/rescue/testrescue.S
--- v2.4.4/linux/arch/cris/boot/rescue/testrescue.S	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/boot/rescue/testrescue.S	Tue May  1 16:04:56 2001
@@ -1,9 +1,10 @@
-	;; $Id: testrescue.S,v 1.1 2001/01/31 15:32:09 johana Exp $
-	;;
-	;; Simple testcode to download by the rescue block.
-	;; Just lits some LEDs to show it was downloaded correctly.
-	;; 
-	;; Copyright (C) 1999 Axis Communications AB
+/* $Id: testrescue.S,v 1.2 2001/04/18 12:05:07 bjornw Exp $
+ *
+ * Simple testcode to download by the rescue block.
+ * Just lits some LEDs to show it was downloaded correctly.
+ * 
+ * Copyright (C) 1999 Axis Communications AB
+ */
 
 #define ASSEMBLER_MACROS_ONLY
 #include <asm/sv_addr_ag.h>
diff -u --recursive --new-file v2.4.4/linux/arch/cris/config.in linux/arch/cris/config.in
--- v2.4.4/linux/arch/cris/config.in	Tue Apr 17 17:19:24 2001
+++ linux/arch/cris/config.in	Tue May  1 16:04:56 2001
@@ -24,14 +24,10 @@
   tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA
 fi
 
-bool 'Use kernel gdb debugger' CONFIG_KGDB
+bool 'Use kernel gdb debugger' CONFIG_ETRAX_KGDB
 
 bool 'Enable Etrax100 watchdog' CONFIG_ETRAX_WATCHDOG
 
-bool 'Use serial console (on the debug port)' CONFIG_USE_SERIAL_CONSOLE
-
-bool 'Use in-kernel ifconfig/route setup' CONFIG_KERNEL_IFCONFIG
-
 endmenu
 
 mainmenu_option next_comment
@@ -46,20 +42,19 @@
 
 if [ "$CONFIG_ETRAX100LX" = "y" -o "$CONFIG_SVINTO_SIM" = "y" ]; then
 	define_bool CONFIG_CRIS_LOW_MAP y
-	define_hex  ETRAX_DRAM_VIRTUAL_BASE 60000000
+	define_hex  CONFIG_ETRAX_DRAM_VIRTUAL_BASE 60000000
 else
-	define_hex  ETRAX_DRAM_VIRTUAL_BASE c0000000
+	define_hex  CONFIG_ETRAX_DRAM_VIRTUAL_BASE c0000000
 fi
 
-int 'DRAM size (dec, in MB)' ETRAX_DRAM_SIZE 8
+int 'DRAM size (dec, in MB)' CONFIG_ETRAX_DRAM_SIZE 8
 
-int 'Max possible flash size (dec, in MB)' CONFIG_ETRAX_FLASH_LENGTH 2
 int 'Buswidth of flash in bytes' CONFIG_ETRAX_FLASH_BUSWIDTH 2
 
 choice 'Product LED port' \
 	"Port-PA-LEDs	CONFIG_ETRAX_PA_LEDS	\
 	 Port-PB-LEDs	CONFIG_ETRAX_PB_LEDS	\
-	 Mem-0x90000000-LEDs	CONFIG_ETRAX_90000000_LEDS  \
+	 Port-CSP0-LEDs	CONFIG_ETRAX_CSP0_LEDS  \
 	 None	CONFIG_ETRAX_NO_LEDS" Port-PA-LEDs
 
 if [ "$CONFIG_ETRAX_NO_LEDS" != "y" ]; then
@@ -71,38 +66,54 @@
   int '  Third red LED bit' CONFIG_ETRAX_LED3G 2
 fi
 
+if [ "$CONFIG_ETRAX_CSP0_LEDS" = "y" ]; then
+  int '  Fourth red LED bit' CONFIG_ETRAX_LED4R 2
+  int '  Fourth green LED bit' CONFIG_ETRAX_LED4G 2
+  int '  Fifth red LED bit' CONFIG_ETRAX_LED5R 2
+  int '  Fifth green LED bit' CONFIG_ETRAX_LED5G 2
+  int '  Sixth red LED bit' CONFIG_ETRAX_LED6R 2
+  int '  Sixth green LED bit' CONFIG_ETRAX_LED6G 2
+  int '  Seventh red LED bit' CONFIG_ETRAX_LED7R 2
+  int '  Seventh green LED bit' CONFIG_ETRAX_LED7G 2
+  int '  Eigth yellow LED bit' CONFIG_ETRAX_LED8Y 2
+  int '  Ninth yellow LED bit' CONFIG_ETRAX_LED9Y 2
+  int '  Tenth yellow LED bit' CONFIG_ETRAX_LED10Y 2
+  int '  Eleventh yellow LED bit' CONFIG_ETRAX_LED11Y 2
+  int '  Twelfth red LED bit' CONFIG_ETRAX_LED12R 2
+fi  
+
 choice 'Product debug-port' \
-	"Serial-0	CONFIG_DEBUG_PORT0	\
-	 Serial-1	CONFIG_DEBUG_PORT1	\
-	 Serial-2	CONFIG_DEBUG_PORT2	\
-	 Serial-3	CONFIG_DEBUG_PORT3	\
-	 disabled	CONFIG_DEBUG_PORT_NULL" Serial-0 
+	"Serial-0	CONFIG_ETRAX_DEBUG_PORT0	\
+	 Serial-1	CONFIG_ETRAX_DEBUG_PORT1	\
+	 Serial-2	CONFIG_ETRAX_DEBUG_PORT2	\
+	 Serial-3	CONFIG_ETRAX_DEBUG_PORT3	\
+	 disabled	CONFIG_ETRAX_DEBUG_PORT_NULL" Serial-0 
 
 choice 'Product rescue-port' \
-	"Serial-0	CONFIG_RESCUE_SER0	\
-	 Serial-1	CONFIG_RESCUE_SER1	\
-	 Serial-2	CONFIG_RESCUE_SER2	\
-	 Serial-3	CONFIG_RESCUE_SER3" Serial-0
-
-hex 'R_WAITSTATES' DEF_R_WAITSTATES 95a6
-hex 'R_BUS_CONFIG' DEF_R_BUS_CONFIG 104
-
-bool 'SDRAM support' CONFIG_SDRAM n
-if [ "$CONFIG_SDRAM" = "n" ]; then
-	hex 'R_DRAM_CONFIG' DEF_R_DRAM_CONFIG 1a200040
-	hex 'R_DRAM_TIMING' DEF_R_DRAM_TIMING 5611
+	"Serial-0	CONFIG_ETRAX_RESCUE_SER0	\
+	 Serial-1	CONFIG_ETRAX_RESCUE_SER1	\
+	 Serial-2	CONFIG_ETRAX_RESCUE_SER2	\
+	 Serial-3	CONFIG_ETRAX_RESCUE_SER3" Serial-0
+
+hex 'R_WAITSTATES' CONFIG_ETRAX_DEF_R_WAITSTATES 95a6
+hex 'R_BUS_CONFIG' CONFIG_ETRAX_DEF_R_BUS_CONFIG 104
+
+bool 'SDRAM support' CONFIG_ETRAX_SDRAM n
+if [ "$CONFIG_ETRAX_SDRAM" = "n" ]; then
+	hex 'R_DRAM_CONFIG' CONFIG_ETRAX_DEF_R_DRAM_CONFIG 1a200040
+	hex 'R_DRAM_TIMING' CONFIG_ETRAX_DEF_R_DRAM_TIMING 5611
 fi
 
-if [ "$CONFIG_SDRAM" = "y" ]; then
-	hex 'R_SDRAM_CONFIG' DEF_R_SDRAM_CONFIG d2fa7878
-	hex 'R_SDRAM_TIMING' DEF_R_SDRAM_TIMING 80004801
+if [ "$CONFIG_ETRAX_SDRAM" = "y" ]; then
+	hex 'R_SDRAM_CONFIG' CONFIG_ETRAX_DEF_R_SDRAM_CONFIG d2fa7878
+	hex 'R_SDRAM_TIMING' CONFIG_ETRAX_DEF_R_SDRAM_TIMING 80004801
 fi
 
-hex 'R_PORT_PA_DIR' DEF_R_PORT_PA_DIR 1c
-hex 'R_PORT_PA_DATA' DEF_R_PORT_PA_DATA 00
-hex 'R_PORT_PB_CONFIG' DEF_R_PORT_PB_CONFIG 00
-hex 'R_PORT_PB_DIR' DEF_R_PORT_PB_DIR 00
-hex 'R_PORT_PB_DATA' DEF_R_PORT_PB_DATA ff
+hex 'R_PORT_PA_DIR' CONFIG_ETRAX_DEF_R_PORT_PA_DIR 1c
+hex 'R_PORT_PA_DATA' CONFIG_ETRAX_DEF_R_PORT_PA_DATA 00
+hex 'R_PORT_PB_CONFIG' CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG 00
+hex 'R_PORT_PB_DIR' CONFIG_ETRAX_DEF_R_PORT_PB_DIR 00
+hex 'R_PORT_PB_DATA' CONFIG_ETRAX_DEF_R_PORT_PB_DATA ff
 
 endmenu
 
diff -u --recursive --new-file v2.4.4/linux/arch/cris/cris.ld linux/arch/cris/cris.ld
--- v2.4.4/linux/arch/cris/cris.ld	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/cris.ld	Tue May  1 16:04:56 2001
@@ -1,10 +1,16 @@
 /* ld script to make the Linux/CRIS kernel
  * Authors: Bjorn Wesen (bjornw@axis.com)
+ *
+ * It is VERY DANGEROUS to fiddle around with the symbols in this
+ * script. It is for example quite vital that all generated sections
+ * that are used are actually named here, otherwise the linker will
+ * put them at the end, where the init stuff is which is FREED after
+ * the kernel has booted. 
  */	
 
 SECTIONS
 {
-	. = @ETRAX_DRAM_VIRTUAL_BASE@;
+	. = @CONFIG_ETRAX_DRAM_VIRTUAL_BASE@;
 	_dram_start = .;
 	_ibr_start = .;
 	. = . + 0x4000; /* see head.S and pages reserved at the start */
@@ -75,5 +81,5 @@
 		*(.exitcall.exit)
         }
 
-	_dram_end = _dram_start + @ETRAX_DRAM_SIZE_M@*1024*1024;
+	_dram_end = _dram_start + @CONFIG_ETRAX_DRAM_SIZE_M@*1024*1024;
 }
diff -u --recursive --new-file v2.4.4/linux/arch/cris/defconfig linux/arch/cris/defconfig
--- v2.4.4/linux/arch/cris/defconfig	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/defconfig	Tue May  1 16:04:56 2001
@@ -15,10 +15,8 @@
 CONFIG_SYSVIPC=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_JAVA is not set
-# CONFIG_KGDB is not set
+# CONFIG_ETRAX_KGDB is not set
 # CONFIG_ETRAX_WATCHDOG is not set
-CONFIG_USE_SERIAL_CONSOLE=y
-# CONFIG_KERNEL_IFCONFIG is not set
 
 #
 # Hardware setup
@@ -27,8 +25,8 @@
 # CONFIG_ETRAX100LX_V2 is not set
 # CONFIG_SVINTO_SIM is not set
 CONFIG_CRIS_LOW_MAP=y
-ETRAX_DRAM_VIRTUAL_BASE=60000000
-ETRAX_DRAM_SIZE=8
+CONFIG_ETRAX_DRAM_VIRTUAL_BASE=60000000
+CONFIG_ETRAX_DRAM_SIZE=8
 CONFIG_ETRAX_FLASH_LENGTH=2
 CONFIG_ETRAX_FLASH_BUSWIDTH=2
 CONFIG_ETRAX_PA_LEDS=y
@@ -39,24 +37,24 @@
 CONFIG_ETRAX_LED1R=2
 CONFIG_ETRAX_LED2G=2
 CONFIG_ETRAX_LED2R=2
-CONFIG_DEBUG_PORT0=y
-# CONFIG_DEBUG_PORT1 is not set
-# CONFIG_DEBUG_PORT2 is not set
-# CONFIG_DEBUG_PORT3 is not set
-CONFIG_RESCUE_SER0=y
-# CONFIG_RESCUE_SER1 is not set
-# CONFIG_RESCUE_SER2 is not set
-# CONFIG_RESCUE_SER3 is not set
-DEF_R_WAITSTATES=95a6
-DEF_R_BUS_CONFIG=104
-# CONFIG_SDRAM is not set
-DEF_R_DRAM_CONFIG=1a200040
-DEF_R_DRAM_TIMING=5611
-DEF_R_PORT_PA_DIR=1d
-DEF_R_PORT_PA_DATA=f0
-DEF_R_PORT_PB_CONFIG=00
-DEF_R_PORT_PB_DIR=1e
-DEF_R_PORT_PB_DATA=f3
+CONFIG_ETRAX_DEBUG_PORT0=y
+# CONFIG_ETRAX_DEBUG_PORT1 is not set
+# CONFIG_ETRAX_DEBUG_PORT2 is not set
+# CONFIG_ETRAX_DEBUG_PORT3 is not set
+CONFIG_ETRAX_RESCUE_SER0=y
+# CONFIG_ETRAX_RESCUE_SER1 is not set
+# CONFIG_ETRAX_RESCUE_SER2 is not set
+# CONFIG_ETRAX_RESCUE_SER3 is not set
+CONFIG_ETRAX_DEF_R_WAITSTATES=95a6
+CONFIG_ETRAX_DEF_R_BUS_CONFIG=104
+# CONFIG_ETRAX_SDRAM is not set
+CONFIG_ETRAX_DEF_R_DRAM_CONFIG=1a200040
+CONFIG_ETRAX_DEF_R_DRAM_TIMING=5611
+CONFIG_ETRAX_DEF_R_PORT_PA_DIR=1d
+CONFIG_ETRAX_DEF_R_PORT_PA_DATA=f0
+CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG=00
+CONFIG_ETRAX_DEF_R_PORT_PB_DIR=1e
+CONFIG_ETRAX_DEF_R_PORT_PB_DATA=f3
 
 #
 # Drivers for Etrax built-in interfaces
@@ -69,7 +67,7 @@
 # CONFIG_ETRAX_SER1_DTR_RI_DSR_CD_ON_PB is not set
 # CONFIG_ETRAX_SERIAL_PORT2 is not set
 # CONFIG_ETRAX_SERIAL_PORT3 is not set
-# CONFIG_RS485 is not set
+# CONFIG_ETRAX_RS485 is not set
 # CONFIG_ETRAX_SYNCHRONOUS_SERIAL is not set
 # CONFIG_ETRAX_IDE is not set
 CONFIG_ETRAX_AXISFLASHMAP=y
@@ -84,15 +82,10 @@
 CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C=y
 CONFIG_ETRAX_GPIO=y
 CONFIG_ETRAX_PA_BUTTON_BITMASK=02
-CONFIG_PA_CHANGEABLE_DIR=00
-CONFIG_PA_CHANGEABLE_BITS=FF
-CONFIG_PB_CHANGEABLE_DIR=00
-CONFIG_PB_CHANGEABLE_BITS=FF
-# CONFIG_JULIETTE is not set
-# CONFIG_JULIETTE_VIDEO is not set
-# CONFIG_JULIETTE_CCD is not set
-# CONFIG_JULIETTE_SS1M is not set
-# CONFIG_JULIETTE_MEGCCD is not set
+CONFIG_ETRAX_PA_CHANGEABLE_DIR=00
+CONFIG_ETRAX_PA_CHANGEABLE_BITS=FF
+CONFIG_ETRAX_PB_CHANGEABLE_DIR=00
+CONFIG_ETRAX_PB_CHANGEABLE_BITS=FF
 # CONFIG_ETRAX_USB_HOST is not set
 
 #
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/Config.in linux/arch/cris/drivers/Config.in
--- v2.4.4/linux/arch/cris/drivers/Config.in	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/drivers/Config.in	Tue May  1 16:04:56 2001
@@ -1,5 +1,5 @@
 mainmenu_option next_comment
-comment 'Drivers for Etrax built-in interfaces'
+comment 'Drivers for ETRAX 100LX built-in interfaces'
 
 bool 'Ethernet support' CONFIG_ETRAX_ETHERNET
 if [ "$CONFIG_ETRAX_ETHERNET" = "y" ]; then
@@ -46,13 +46,13 @@
     fi 
   fi
   bool '  Serial port 3 enabled' CONFIG_ETRAX_SERIAL_PORT3
-  bool '  RS-485 support' CONFIG_RS485
-  if [ "$CONFIG_RS485" = "y" ]; then
-    bool '    RS-485 mode on PA' CONFIG_RS485_ON_PA
-    if [ "$CONFIG_RS485_ON_PA" = "y" ]; then
-      int '      RS-485 mode on PA bit' CONFIG_RS485_ON_PA_BIT 3
+  bool '  RS-485 support' CONFIG_ETRAX_RS485
+  if [ "$CONFIG_ETRAX_RS485" = "y" ]; then
+    bool '    RS-485 mode on PA' CONFIG_ETRAX_RS485_ON_PA
+    if [ "$CONFIG_ETRAX_RS485_ON_PA" = "y" ]; then
+      int '      RS-485 mode on PA bit' CONFIG_ETRAX_RS485_ON_PA_BIT 3
     fi
-    bool '    Disable serial receiver' CONFIG_RS485_DISABLE_RECEIVER
+    bool '    Disable serial receiver' CONFIG_ETRAX_RS485_DISABLE_RECEIVER
   fi
 fi
 
@@ -60,14 +60,29 @@
 if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL" = "y" ]; then 
   bool '  Synchronous serial port 0 enabled' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0
   if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT0" = "y" ]; then
-    bool '    Synchronous serial port 0 uses DMA' CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA y
+    bool '    Synchronous serial port 0 uses DMA' CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA
   fi
   bool '  Synchronous serial port 1 enabled' CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1
   if [ "$CONFIG_ETRAX_SYNCHRONOUS_SERIAL_PORT1" = "y" ]; then
-    bool '    Synchronous serial port 1 uses DMA' CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA y
+    bool '    Synchronous serial port 1 uses DMA' CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA
   fi 
 fi
 
+bool 'Parallel port support' CONFIG_ETRAX_PARPORT
+if [ "$CONFIG_ETRAX_PARPORT" = "y" ]; then
+	bool '  Parallel port 0 enabled' CONFIG_ETRAX_PARALLEL_PORT0
+	bool '  Parallel port 1 enabled' CONFIG_ETRAX_PARALLEL_PORT1
+# here we define the CONFIG_'s necessary to enable parallel port support
+	define_tristate CONFIG_PARPORT y
+        define_bool CONFIG_PARPORT_1284 y
+        define_tristate CONFIG_PRINTER y
+else
+	define_tristate CONFIG_PARPORT n
+        define_bool CONFIG_PARPORT_1284 n
+        define_tristate CONFIG_PRINTER n
+fi
+
+
 bool 'ATA/IDE support' CONFIG_ETRAX_IDE
 
 if [ "$CONFIG_ETRAX_IDE" = "y" ]; then
@@ -89,7 +104,8 @@
 	choice 'IDE reset pin' \
   	"Port_PB_Bit_7  CONFIG_ETRAX_IDE_PB7_RESET\
    	 Port_G_Bit_27  CONFIG_ETRAX_IDE_G27_RESET\
-   	 Port_CSE1_Bit_16  CONFIG_ETRAX_IDE_CSE1_16_RESET" Port_PB_Bit_7 
+	 Port_CSE1_Bit_16  CONFIG_ETRAX_IDE_CSE1_16_RESET\
+	 Port_CSP0_Bit_08   CONFIG_ETRAX_IDE_CSP0_8_RESET"  Port_PB_Bit_7
 else
 	define_bool CONFIG_IDE n
 fi
@@ -97,6 +113,7 @@
 bool 'Axis flash-map support' CONFIG_ETRAX_AXISFLASHMAP
 
 if [ "$CONFIG_ETRAX_AXISFLASHMAP" = "y" ]; then
+        int  '  Byte-offset of partition table sector' CONFIG_ETRAX_PTABLE_SECTOR 65536
 # here we define the CONFIG_'s necessary to enable MTD support
 # for the flash
 	define_bool CONFIG_MTD y
@@ -118,16 +135,25 @@
 	bool 'I2C uses PB not PB-I2C' CONFIG_ETRAX_I2C_USES_PB_NOT_PB_I2C
 fi
 
+bool 'I2C EEPROM (non-volatile RAM) support' CONFIG_ETRAX_I2C_EEPROM
+if [ "$CONFIG_ETRAX_I2C_EEPROM" = "y" ]; then
+  choice '  EEPROM size' \
+    "Probed CONFIG_ETRAX_I2C_EEPROM_PROBE \
+     2kB    CONFIG_ETRAX_I2C_EEPROM_2KB   \
+     8kB    CONFIG_ETRAX_I2C_EEPROM_8KB   \
+     16kB   CONFIG_ETRAX_I2C_EEPROM_16KB" Probed
+fi
+
 bool 'GPIO support' CONFIG_ETRAX_GPIO
 if [ "$CONFIG_ETRAX_GPIO" = "y" ]; then
   hex  '  PA-buttons bitmask' CONFIG_ETRAX_PA_BUTTON_BITMASK 02
-  hex  '  PA user changeable dir mask' CONFIG_PA_CHANGEABLE_DIR 00
-  hex  '  PA user changeable bits mask' CONFIG_PA_CHANGEABLE_BITS FF
-  hex  '  PB user changeable dir mask' CONFIG_PB_CHANGEABLE_DIR 00
-  hex  '  PB user changeable bits mask' CONFIG_PB_CHANGEABLE_BITS FF
+  hex  '  PA user changeable dir mask' CONFIG_ETRAX_PA_CHANGEABLE_DIR 00
+  hex  '  PA user changeable bits mask' CONFIG_ETRAX_PA_CHANGEABLE_BITS FF
+  hex  '  PB user changeable dir mask' CONFIG_ETRAX_PB_CHANGEABLE_DIR 00
+  hex  '  PB user changeable bits mask' CONFIG_ETRAX_PB_CHANGEABLE_BITS FF
 fi
 
-bool 'Juliette support' CONFIG_JULIETTE n
+bool 'ARTPEC-1 support' CONFIG_JULIETTE
 
 if [ "$CONFIG_JULIETTE" = "y" ]; then
    source arch/cris/drivers/juliette/Config.in
@@ -136,8 +162,18 @@
 bool 'USB host' CONFIG_ETRAX_USB_HOST
 if [ "$CONFIG_ETRAX_USB_HOST" = "y" ]; then
 	define_bool CONFIG_USB y
-	bool '  USB port 1 enabled' CONFIG_ETRAX_USB_HOST_PORT1 n
-	bool '  USB port 2 enabled' CONFIG_ETRAX_USB_HOST_PORT2 n
+	bool '  USB port 1 enabled' CONFIG_ETRAX_USB_HOST_PORT1
+	bool '  USB port 2 enabled' CONFIG_ETRAX_USB_HOST_PORT2
+else
+	define_bool CONFIG_USB n
+fi
+
+bool 'DS1302 Real Time Clock support' CONFIG_ETRAX_DS1302
+if [ "$CONFIG_ETRAX_DS1302" = "y" ]; then
+  bool '  DS1302 RST on Generic Port' CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
+  int '  DS1302 RST bit number' CONFIG_ETRAX_DS1302_RSTBIT 2
+  int '  DS1302 SCL bit number' CONFIG_ETRAX_DS1302_SCLBIT 1
+  int '  DS1302 SDA bit number' CONFIG_ETRAX_DS1302_SDABIT 0
 fi
 
 endmenu
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/Makefile linux/arch/cris/drivers/Makefile
--- v2.4.4/linux/arch/cris/drivers/Makefile	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/drivers/Makefile	Tue May  1 16:04:56 2001
@@ -12,10 +12,13 @@
 obj-$(CONFIG_ETRAX_IDE)                += ide.o
 obj-$(CONFIG_ETRAX_AXISFLASHMAP)       += axisflashmap.o
 obj-$(CONFIG_ETRAX_I2C) 	       += i2c.o
+obj-$(CONFIG_ETRAX_I2C_EEPROM)         += eeprom.o
 obj-$(CONFIG_ETRAX_GPIO) 	       += gpio.o
 obj-$(CONFIG_ETRAX_USB_HOST)           += usb-host.o
 obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
-obj-$(CONFIG_JULIETTE)                 += juliette/juliette.o
-subdir-$(CONFIG_JULIETTE)              += juliette
+obj-$(CONFIG_ETRAX_PARPORT)            += parport.o
+obj-$(CONFIG_ETRAX_DS1302)             += ds1302.o
+
+
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/axisflashmap.c linux/arch/cris/drivers/axisflashmap.c
--- v2.4.4/linux/arch/cris/drivers/axisflashmap.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/drivers/axisflashmap.c	Tue May  1 16:04:56 2001
@@ -11,6 +11,15 @@
  * partition split defined below.
  *
  * $Log: axisflashmap.c,v $
+ * Revision 1.7  2001/04/05 13:41:46  markusl
+ * Updated according to review remarks
+ *
+ * Revision 1.6  2001/03/07 09:21:21  bjornw
+ * No need to waste .data
+ *
+ * Revision 1.5  2001/03/06 16:27:01  jonashg
+ * Probe the entire flash area for flash devices.
+ *
  * Revision 1.4  2001/02/23 12:47:15  bjornw
  * Uncached flash in LOW_MAP moved from 0xe to 0x8
  *
@@ -50,19 +59,13 @@
 #endif
 
 /*
- * WINDOW_SIZE is the total size where the flash chips are mapped,
- * my guess is that this can be the total memory area even if there
- * are many flash chips inside the area or if they are not all mounted.
- * So possibly we can get rid of the CONFIG_ here and just write something
- * like 32 MB always.
- */
-
-#define WINDOW_SIZE  (CONFIG_ETRAX_FLASH_LENGTH * 1024 * 1024)
-
-/* Byte-offset where the partition-table is placed in the first chip
+ * WINDOW_SIZE is the total size where the flash chips may be mapped.
+ * MTD probes should find all devices there and it does not matter
+ * if there are unmapped gaps or aliases (mirrors of flash devices).
+ * The MTD probes will ignore them.
  */
 
-#define PTABLE_SECTOR 65536
+#define WINDOW_SIZE  (128 * 1024 * 1024)
 
 /* 
  * Map driver
@@ -70,8 +73,6 @@
  * Ok this is the scoop - we need to access the flash both with and without
  * the cache - without when doing all the fancy flash interfacing, and with
  * when we do actual copying because otherwise it will be slow like molasses.
- * I hope this works the way it's intended, so that there won't be any cases
- * of non-synchronicity because of the different access modes below...
  */
 
 static __u8 flash_read8(struct map_info *map, unsigned long ofs)
@@ -110,12 +111,6 @@
 	*(__u32 *)(FLASH_UNCACHED_ADDR + adr) = d;
 }
 
-static void flash_copy_to(struct map_info *map, unsigned long to,
-			  const void *from, ssize_t len)
-{
-	memcpy((void *)(FLASH_CACHED_ADDR + to), from, len);
-}
-
 static struct map_info axis_map = {
 	name: "Axis flash",
 	size: WINDOW_SIZE,
@@ -127,7 +122,6 @@
 	write8: flash_write8,
 	write16: flash_write16,
 	write32: flash_write32,
-	copy_to: flash_copy_to
 };
 
 /* If no partition-table was found, we use this default-set.
@@ -139,18 +133,18 @@
 static struct mtd_partition axis_default_partitions[NUM_DEFAULT_PARTITIONS] = {
 	{
 		name: "boot firmware",
-		size: PTABLE_SECTOR,
+		size: CONFIG_ETRAX_PTABLE_SECTOR,
 		offset: 0
 	},
 	{
 		name: "kernel",
 		size: 0x1a0000,
-		offset: PTABLE_SECTOR
+		offset: CONFIG_ETRAX_PTABLE_SECTOR
 	},
 	{
 		name: "filesystem",
 		size: 0x50000,
-		offset: (0x1a0000 + PTABLE_SECTOR)
+		offset: (0x1a0000 + CONFIG_ETRAX_PTABLE_SECTOR)
 	}
 };
 
@@ -214,11 +208,11 @@
 	printk(KERN_NOTICE "Axis flash mapping: %x at %x\n",
 	       WINDOW_SIZE, FLASH_CACHED_ADDR);
 
-	mymtd = do_cfi_probe(&axis_map);
+	mymtd = (struct mtd_info *)do_cfi_probe(&axis_map);
 
 #ifdef CONFIG_MTD_AMDSTD
 	if (!mymtd) {
-		mymtd = do_amd_flash_probe(&axis_map);
+		mymtd = (struct mtd_info *)do_amd_flash_probe(&axis_map);
 	}
 #endif
 
@@ -236,18 +230,15 @@
 	 */
 
 	ptable_head = (struct partitiontable_head *)(FLASH_CACHED_ADDR +
-		PTABLE_SECTOR + PARTITION_TABLE_OFFSET);
+		CONFIG_ETRAX_PTABLE_SECTOR + PARTITION_TABLE_OFFSET);
 	pidx++;  /* first partition is always set to the default */
 
 	if ((ptable_head->magic == PARTITION_TABLE_MAGIC)
-	    && (ptable_head->size
-		< (MAX_PARTITIONS
-		   * sizeof(struct partitiontable_entry) + 4))
-	    && (*(unsigned long*)
-		((void*)ptable_head
-		 + sizeof(*ptable_head)
-		 + ptable_head->size - 4)
-		==  PARTITIONTABLE_END_MARKER)) {
+	    && (ptable_head->size <
+		(MAX_PARTITIONS * sizeof(struct partitiontable_entry) + 4))
+	    && (*(unsigned long*)((void*)ptable_head + sizeof(*ptable_head) +
+				  ptable_head->size - 4)
+		== PARTITIONTABLE_END_MARKER)) {
 		/* Looks like a start, sane length and end of a
 		 * partition table, lets check csum etc.
 		 */
@@ -256,7 +247,7 @@
 			(struct partitiontable_entry *)
 			((unsigned long)ptable_head + sizeof(*ptable_head) +
 			 ptable_head->size);
-		unsigned long offset = PTABLE_SECTOR;
+		unsigned long offset = CONFIG_ETRAX_PTABLE_SECTOR;
 		unsigned char *p;
 		unsigned long csum = 0;
 		
@@ -293,16 +284,7 @@
 		       && ptable->offset != 0xffffffff
 		       && ptable < max_addr
 		       && pidx < MAX_PARTITIONS) {
-#if 0
-			/* wait with multi-chip support until we know
-			 * how mtd detects multiple chips
-			 */
-			if ((offset + ptable->offset) >= chips[0].size) {
-				partitions[pidx].start
-					= offset + chips[1].start
-					+ ptable->offset - chips[0].size;
-			}
-#endif
+
 			axis_partitions[pidx].offset = offset + ptable->offset;
 			axis_partitions[pidx].size = ptable->size;
 
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/ds1302.c linux/arch/cris/drivers/ds1302.c
--- v2.4.4/linux/arch/cris/drivers/ds1302.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/ds1302.c	Tue May  1 16:04:56 2001
@@ -0,0 +1,488 @@
+/*!***************************************************************************
+*!
+*! FILE NAME  : ds1302.c
+*!
+*! DESCRIPTION: Implements an interface for the DS1302 RTC through Etrax I/O
+*!
+*! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status
+*!
+*! $Log: ds1302.c,v $
+*! Revision 1.3  2001/03/26 16:03:06  bjornw
+*! Needs linux/config.h
+*!
+*! Revision 1.2  2001/03/20 19:42:00  bjornw
+*! Use the ETRAX prefix on the DS1302 options
+*!
+*! Revision 1.1  2001/03/20 09:13:50  magnusmn
+*! Linux 2.4 port
+*!
+*! Revision 1.10  2000/07/05 15:38:23  bjornw
+*! Dont update kernel time when a RTC_SET_TIME is done
+*!
+*! Revision 1.9  2000/03/02 15:42:59  macce
+*! * Hack to make RTC work on all 2100/2400
+*!
+*! Revision 1.8  2000/02/23 16:59:18  torbjore
+*! added setup of R_GEN_CONFIG when RTC is connected to the generic port.
+*!
+*! Revision 1.7  2000/01/17 15:51:43  johana
+*! Added RTC_SET_CHARGE ioctl to enable trickle charger.
+*!
+*! Revision 1.6  1999/10/27 13:19:47  bjornw
+*! Added update_xtime_from_cmos which reads back the updated RTC into the kernel.
+*! /dev/rtc calls it now.
+*!
+*! Revision 1.5  1999/10/27 12:39:37  bjornw
+*! Disabled superuser check. Anyone can now set the time.
+*!
+*! Revision 1.4  1999/09/02 13:27:46  pkj
+*! Added shadow for R_PORT_PB_CONFIG.
+*! Renamed port_g_shadow to port_g_data_shadow.
+*!
+*! Revision 1.3  1999/09/02 08:28:06  pkj
+*! Made it possible to select either port PB or the generic port for the RST
+*! signal line to the DS1302 RTC.
+*! Also make sure the RST bit is configured as output on Port PB (if used).
+*!
+*! Revision 1.2  1999/09/01 14:47:20  bjornw
+*! Added support for /dev/rtc operations with ioctl RD_TIME and SET_TIME to read
+*! and set the date. Register as major 121.
+*!
+*! Revision 1.1  1999/09/01 09:45:29  bjornw
+*! Implemented a DS1302 RTC driver.
+*!
+*!
+*! ---------------------------------------------------------------------------
+*!
+*! (C) Copyright 1999, 2000, 2001  Axis Communications AB, LUND, SWEDEN
+*!
+*! $Id: ds1302.c,v 1.3 2001/03/26 16:03:06 bjornw Exp $
+*!
+*!***************************************************************************/
+
+#include <linux/config.h>
+
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/delay.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/svinto.h>
+#include <asm/io.h>
+#include <asm/rtc.h>
+
+#define RTC_MAJOR_NR 121 /* local major, change later */
+
+/* The DS1302 might be connected to different bits on different products. 
+ * It has three signals - SDA, SCL and RST. RST and SCL are always outputs,
+ * but SDA can have a selected direction.
+ * For now, only PORT_PB is hardcoded.
+ */
+
+/* The RST bit may be on either the Generic Port or Port PB */
+#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
+#define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_G_DATA,  port_g_data_shadow,  CONFIG_ETRAX_DS1302_RSTBIT, x)
+#define TK_RST_DIR(x)
+#else
+#define TK_RST_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_RSTBIT, x)
+#define TK_RST_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR,  port_pb_dir_shadow,  CONFIG_ETRAX_DS1302_RSTBIT, x)
+#endif
+
+
+#define TK_SDA_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_SDABIT, x)
+#define TK_SCL_OUT(x) REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, CONFIG_ETRAX_DS1302_SCLBIT, x)
+
+#define TK_SDA_IN()   ((*R_PORT_PB_READ >> CONFIG_ETRAX_DS1302_SDABIT) & 1)
+/* 1 is out, 0 is in */
+#define TK_SDA_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR,  port_pb_dir_shadow,  CONFIG_ETRAX_DS1302_SDABIT, x)
+#define TK_SCL_DIR(x) REG_SHADOW_SET(R_PORT_PB_DIR,  port_pb_dir_shadow,  CONFIG_ETRAX_DS1302_SCLBIT, x)
+
+
+/*
+ * The reason for tempudelay and not udelay is that loops_per_usec
+ * (used in udelay) is not set when functions here are called from time.c 
+ */
+
+static void tempudelay(int time) 
+{
+	int i;
+	for(i = 0; i < time * 10000; i++);	
+}
+
+
+/* send 8 bits */
+static void
+out_byte(int x) 
+{
+	int i;
+	TK_SDA_DIR(1);
+	for (i = 8; i--;) {
+		/* the chip latches incoming bits on the rising edge of SCL */
+		TK_SCL_OUT(0);
+		TK_SDA_OUT(x & 1);
+		tempudelay(1);
+		TK_SCL_OUT(1);
+		tempudelay(1);
+		x >>= 1;
+	}
+	TK_SDA_DIR(0);
+}
+
+static unsigned char
+in_byte(void) 
+{
+	unsigned char x = 0;
+	int i;
+
+	/* Read byte. Bits come LSB first, on the falling edge of SCL.
+	 * Assume SDA is in input direction already
+	 */
+	TK_SDA_DIR(0);
+
+	for (i = 8; i--;) {
+		TK_SCL_OUT(0);
+		tempudelay(1);
+		x >>= 1;
+		x |= (TK_SDA_IN() << 7);
+		TK_SCL_OUT(1);
+		tempudelay(1);
+	}
+
+	return x;
+}
+
+/* prepares for a transaction by de-activating RST (active-low) */
+
+static void
+start(void) 
+{
+	TK_SCL_OUT(0);
+	tempudelay(1);
+	TK_RST_OUT(0);
+	tempudelay(5);
+	TK_RST_OUT(1);	
+}
+
+/* ends a transaction by taking RST active again */
+
+static void
+stop(void) 
+{
+	tempudelay(2);
+	TK_RST_OUT(0);
+}
+
+/* enable writing */
+
+static void
+ds1302_wenable(void) 
+{
+	start(); 	
+	out_byte(0x8e); /* Write control register  */
+	out_byte(0x00); /* Disable write protect bit 7 = 0 */
+	stop();
+}
+
+/* disable writing */
+
+static void
+ds1302_wdisable(void) 
+{
+	start();
+	out_byte(0x8e); /* Write control register  */
+	out_byte(0x80); /* Disable write protect bit 7 = 0 */
+	stop();
+}
+
+/* probe for the chip by writing something to its RAM and try reading it back */
+
+static int
+ds1302_probe(void) 
+{
+	int retval, res; 
+
+	TK_RST_DIR(1);
+	TK_SCL_DIR(1);
+	TK_SDA_DIR(0);
+	
+	/* try to talk to timekeeper */
+
+	ds1302_wenable();  
+	start();
+	out_byte(0xc0); /* write RAM byte 0 */	
+	out_byte(0x42); /* write something magic */
+	start();
+	out_byte(0xc1); /* read RAM byte 0 */
+
+	if((res = in_byte()) == 0x42) {
+		char buf[100];
+		stop();
+		ds1302_wdisable();
+		printk("DS1302 RTC found.\n");
+                printk("SDA, SCL, RST on PB%i, PB%i, %s%i\n",
+                       CONFIG_ETRAX_DS1302_SDABIT,
+                       CONFIG_ETRAX_DS1302_SCLBIT,
+#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
+                       "GENIO",
+#else
+                       "PB",
+#endif
+                       CONFIG_ETRAX_DS1302_RSTBIT
+                       );
+                get_rtc_status(buf);
+                printk(buf);
+		retval = 1;
+	} else {
+		stop();
+		printk("DS1302 RTC not found.\n");
+		retval = 0;
+	}
+
+	return retval;
+}
+
+
+/* read a byte from the selected register in the DS1302 */
+
+unsigned char
+ds1302_readreg(int reg) 
+{
+	unsigned char x;
+
+	start();
+	out_byte(0x81 | (reg << 1)); /* Read register */
+	x = in_byte();
+	stop();
+
+	return x;
+}
+
+/* write a byte to the selected register */
+
+void
+ds1302_writereg(int reg, unsigned char val) 
+{
+	ds1302_wenable();
+	start();
+	out_byte(0x80 | (reg << 1)); /* Write register */
+	out_byte(val);
+	stop();
+	ds1302_wdisable();
+}
+
+void
+get_rtc_time(struct rtc_time *rtc_tm) 
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	rtc_tm->tm_sec = CMOS_READ(RTC_SECONDS);
+	rtc_tm->tm_min = CMOS_READ(RTC_MINUTES);
+	rtc_tm->tm_hour = CMOS_READ(RTC_HOURS);
+	rtc_tm->tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);
+	rtc_tm->tm_mon = CMOS_READ(RTC_MONTH);
+	rtc_tm->tm_year = CMOS_READ(RTC_YEAR);
+
+	restore_flags(flags);
+	
+	BCD_TO_BIN(rtc_tm->tm_sec);
+	BCD_TO_BIN(rtc_tm->tm_min);
+	BCD_TO_BIN(rtc_tm->tm_hour);
+	BCD_TO_BIN(rtc_tm->tm_mday);
+	BCD_TO_BIN(rtc_tm->tm_mon);
+	BCD_TO_BIN(rtc_tm->tm_year);
+
+	/*
+	 * Account for differences between how the RTC uses the values
+	 * and how they are defined in a struct rtc_time;
+	 */
+
+	if (rtc_tm->tm_year <= 69)
+		rtc_tm->tm_year += 100;
+
+	rtc_tm->tm_mon--;
+}
+
+static unsigned char days_in_mo[] = 
+    {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+/* ioctl that supports RTC_RD_TIME and RTC_SET_TIME (read and set time/date) */
+
+static int
+rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	  unsigned long arg) 
+{
+        unsigned long flags;
+
+	switch(cmd) {
+		case RTC_RD_TIME:	/* Read the time/date from RTC	*/
+		{
+			struct rtc_time rtc_tm;
+						
+			get_rtc_time(&rtc_tm);						
+			if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
+				return -EFAULT;	
+			return 0;
+		}
+
+		case RTC_SET_TIME:	/* Set the RTC */
+		{
+			struct rtc_time rtc_tm;
+			unsigned char mon, day, hrs, min, sec, leap_yr;
+			unsigned char save_control, save_freq_select;
+			unsigned int yrs;
+#if 0
+			if (!suser())
+				return -EACCES;
+#endif			
+			if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
+				return -EFAULT;    	
+
+			yrs = rtc_tm.tm_year + 1900;
+			mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
+			day = rtc_tm.tm_mday;
+			hrs = rtc_tm.tm_hour;
+			min = rtc_tm.tm_min;
+			sec = rtc_tm.tm_sec;
+			
+			
+			if ((yrs < 1970) || (yrs > 2069))
+				return -EINVAL;
+
+			leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
+
+			if ((mon > 12) || (day == 0))
+				return -EINVAL;
+
+			if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
+				return -EINVAL;
+			
+			if ((hrs >= 24) || (min >= 60) || (sec >= 60))
+				return -EINVAL;
+
+			if (yrs >= 2000)
+				yrs -= 2000;	/* RTC (0, 1, ... 69) */
+			else
+				yrs -= 1900;	/* RTC (70, 71, ... 99) */
+
+			BIN_TO_BCD(sec);
+			BIN_TO_BCD(min);
+			BIN_TO_BCD(hrs);
+			BIN_TO_BCD(day);
+			BIN_TO_BCD(mon);
+			BIN_TO_BCD(yrs);
+
+			save_flags(flags);
+			cli();
+			CMOS_WRITE(yrs, RTC_YEAR);
+			CMOS_WRITE(mon, RTC_MONTH);
+			CMOS_WRITE(day, RTC_DAY_OF_MONTH);
+			CMOS_WRITE(hrs, RTC_HOURS);
+			CMOS_WRITE(min, RTC_MINUTES);
+			CMOS_WRITE(sec, RTC_SECONDS);
+			restore_flags(flags);
+
+			/* notice that at this point, the RTC is updated but the kernel
+			 * is still running with the old time. you need to set that
+			 * separately with settimeofday or adjtimex.
+			 */
+			return 0;
+		}
+
+		case RTC_SET_CHARGE: /* Set the RTC TRICKLE CHARGE register */
+		{
+			int tcs_val;                        
+			unsigned char save_control, save_freq_select;
+#if 0
+			if (!suser())
+				return -EACCES;
+#endif
+			
+			if(copy_from_user(&tcs_val, (int*)arg, sizeof(int)))
+				return -EFAULT;
+
+			tcs_val = RTC_TCR_PATTERN | (tcs_val & 0x0F);
+			ds1302_writereg(RTC_TRICKLECHARGER, tcs_val);
+			return 0;
+		}                
+		default:
+			return -ENOIOCTLCMD;
+	}
+}
+
+/*
+ *	Info exported via "/proc/rtc".
+ */
+
+int
+get_rtc_status(char *buf) 
+{
+	char *p;
+	struct rtc_time tm;
+
+	p = buf;
+
+	get_rtc_time(&tm);
+
+	/*
+	 * There is no way to tell if the luser has the RTC set for local
+	 * time or for Universal Standard Time (GMT). Probably local though.
+	 */
+
+	p += sprintf(p,
+		"rtc_time\t: %02d:%02d:%02d\n"
+		"rtc_date\t: %04d-%02d-%02d\n",
+		tm.tm_hour, tm.tm_min, tm.tm_sec,
+		tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
+
+	return  p - buf;
+}
+
+
+/*
+ *	The various file operations we support.
+ */
+
+static struct file_operations rtc_fops = {
+        owner:          THIS_MODULE,
+        ioctl:          rtc_ioctl,	
+}; 
+
+/* just probe for the RTC and register the device to handle the ioctl needed */
+
+int
+ds1302_init(void) 
+{ 
+  
+ /* Ugly hack to handle both 2100 and 2400 hardware.
+    Remove...
+ */
+	if(!ds1302_probe()) {
+#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
+    	/*
+     	* Make sure that R_GEN_CONFIG is 
+     	* setup correct.
+     	*/
+    		genconfig_shadow = ( (genconfig_shadow & ~IO_MASK(R_GEN_CONFIG, ata) ) | 
+                           ( IO_STATE( R_GEN_CONFIG, ata, select ) ) );    
+    		*R_GEN_CONFIG = genconfig_shadow;
+    		if(!ds1302_probe())
+      			return -1;
+#else
+    		return -1;
+#endif
+  	}
+  
+	if (register_chrdev(RTC_MAJOR_NR, "rtc", &rtc_fops)) {
+		printk("unable to get major %d for rtc\n", RTC_MAJOR_NR);
+		return -1;
+	}
+	return 0;
+}
+
+
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/eeprom.c linux/arch/cris/drivers/eeprom.c
--- v2.4.4/linux/arch/cris/drivers/eeprom.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/eeprom.c	Tue May  1 16:04:56 2001
@@ -0,0 +1,1161 @@
+/*!**************************************************************************
+*!
+*!  FILE NAME:      e100eeprom.c
+*!
+*!  DESCRIPTION:    Implements an interface for i2c compatible eeproms to run
+*!                  under linux.
+*!                  Supports 2k, 8k(?) and 16k
+*!                  Uses adaptive timing adjustents by Johan.Adolfsson@axis.com
+*!                  Probing results:
+*!                    8k or not is detected (the assumes 2k or 16k)
+*!                    2k or 16k detected using test reads and writes.
+*!
+*!  FUNCTIONS:
+*!
+*!  (Exported)
+*!              eeprom_init()
+*!
+*!  (Local)
+*!
+*!              eeprom_open()
+*!              eeprom_lseek()
+*!              eeprom_read()
+*!              eeprom_write()
+*!              eeprom_close()
+*!              eeprom_address()
+*!              eeprom_disable_write_protect()
+*!
+*!
+*!  $Id: eeprom.c,v 1.3 2001/03/19 16:04:46 markusl Exp $
+*!
+*!------------------------------------------------------------------------
+*!  HISTORY
+*!
+*!  DATE          NAME              CHANGES
+*!  ----          ----              -------
+*!  Aug  28 1999  Edgar Iglesias    Initial Version
+*!  Aug  31 1999  Edgar Iglesias    Allow simultaneous users.
+*!  Sep  03 1999  Edgar Iglesias    Updated probe.
+*!  Sep  03 1999  Edgar Iglesias    Added bail-out stuff if we get interrupted
+*!                                  in the spin-lock.
+*!
+*!  $Log: eeprom.c,v $
+*!  Revision 1.3  2001/03/19 16:04:46  markusl
+*!  Fixed init of fops struct
+*!
+*!  Revision 1.2  2001/03/19 10:35:07  markusl
+*!  2.4 port of eeprom driver
+*!
+*!  Revision 1.8  2000/05/18 10:42:25  edgar
+*!  Make sure to end write cycle on _every_ write
+*!
+*!  Revision 1.7  2000/01/17 17:41:01  johana
+*!  Adjusted probing and return -ENOSPC when writing outside EEPROM
+*!
+*!  Revision 1.6  2000/01/17 15:50:36  johana
+*!  Added adaptive timing adjustments and fixed autoprobing for 2k and 16k(?)
+*!  EEPROMs
+*!
+*!  Revision 1.5  1999/09/03 15:07:37  edgar
+*!  Added bail-out check to the spinlock
+*!
+*!  Revision 1.4  1999/09/03 12:11:17  bjornw
+*!  Proper atomicity (need to use spinlocks, not if's). users -> busy.
+*!
+*!
+*!        (c) 1999 Axis Communications AB, Lund, Sweden
+*!**************************************************************************/
+
+/********************** INCLUDE FILES SECTION ******************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include "i2c.h"
+
+/********************** CONSTANT AND MACRO SECTION *************************/
+#define D(x) 
+
+/* If we should use adaptive timing or not: */
+//#define EEPROM_ADAPTIVE_TIMING      
+
+#define EEPROM_MAJOR_NR 122  /* use a LOCAL/EXPERIMENTAL major for now */
+#define EEPROM_MINOR_NR 0
+
+#define MAX_WRITEDELAY_US 10000 /* 10 ms according to spec for 2KB EEPROM */
+/*
+ *  this one defines how many times to try when eeprom fails.
+ */
+#define EEPROM_RETRIES 10
+
+#define EEPROM_2KB (2 * 1024)
+/*#define EEPROM_4KB (4 * 1024)*/ /* Exists but not used in Axis products */
+#define EEPROM_8KB (8 * 1024 - 1 ) /* Last byte has write protection bit */
+#define EEPROM_16KB (16 * 1024)
+
+#define i2c_delay(x) udelay(x)
+
+/********************** TYPE DEFINITION SECTION ****************************/
+
+/*
+ *  This structure describes the attached eeprom chip.
+ *  The values are probed for.
+ */
+
+struct eeprom_type
+{
+  unsigned long size;
+  unsigned long sequential_write_pagesize;
+  unsigned char select_cmd;
+  unsigned long usec_delay_writecycles; /* Min time between write cycles (up to 10ms for some models) */
+  unsigned long int usec_delay_step; /* For adaptive algorithm */
+  int adapt_state; /* 1 = To high , 0 = Even, -1 = To low */
+  
+  /* this one is to keep the read/write operations atomic */
+  wait_queue_head_t wait_q;
+  int busy;
+  int retry_cnt_addr; /* Used to keep track of number of retries for
+                     adaptive timing adjustments */
+  int retry_cnt_read;
+
+  
+  
+};
+
+/********************** LOCAL FUNCTION DECLARATION SECTION *****************/
+
+static int  eeprom_open (struct inode * inode, struct file * file);
+static loff_t  eeprom_lseek(struct file * file, loff_t offset, int orig);
+static ssize_t  eeprom_read (struct file * file, char * buf, size_t count, loff_t *off);
+static ssize_t  eeprom_write(struct file * file, const char * buf, size_t count, loff_t *off);
+static int eeprom_close(struct inode * inode, struct file * file);
+
+static int  eeprom_address(unsigned long addr);
+static int  read_from_eeprom(char * buf, int count);
+static int eeprom_write_buf(unsigned long int addr,
+                            const char * buf, int count);
+static int eeprom_read_buf(unsigned long addr,
+                           char * buf, int count);
+
+static void eeprom_disable_write_protect(void);
+
+
+/********************** GLOBAL VARIABLE DECLARATION SECTION ****************/
+
+/********************** LOCAL VARIABLE DECLARATION SECTION *****************/
+
+/* chip description */
+static struct eeprom_type eeprom;
+
+/*
+ *  This is the exported file-operations structure
+ *  for this device.
+ */
+
+struct file_operations eeprom_fops =
+{
+  llseek:  eeprom_lseek,
+  read:    eeprom_read,
+  write:   eeprom_write,
+  open:    eeprom_open,
+  release: eeprom_close
+};
+
+/********************** FUNCTION DEFINITION SECTION ************************/
+
+/*#**************************************************************************
+*#                                                            
+*# FUNCTION NAME: eeprom_init
+*#                                                            
+*# PARAMETERS   : none
+*#                                                            
+*# RETURNS      : 0 if OK
+*#                                                            
+*# SIDE EFFECTS : 
+*#                                                            
+*# DESCRIPTION  : eeprom init call. Probes for different eeprom models.
+*#                                                            
+*#---------------------------------------------------------------------------
+*# HISTORY                                                    
+*#                                                            
+*# DATE         NAME            CHANGES                       
+*# ----         ----            -------                       
+*# Aug 28 1999  Edgar Iglesias  Initial version               
+*# Sep 03 1999  Edgar Iglesias  Updated probing. Added forced values.
+*#
+*#**************************************************************************/
+
+int __init eeprom_init(void)
+{
+  init_waitqueue_head(&eeprom.wait_q);
+  eeprom.busy = 0;
+
+#if CONFIG_ETRAX_I2C_EEPROM_PROBE
+#define EETEXT "Found"
+#else
+#define EETEXT "Assuming"
+#endif
+  if (register_chrdev(EEPROM_MAJOR_NR, "mem", &eeprom_fops))
+  {
+    printk("unable to get major %d for eeprom device\n", EEPROM_MAJOR_NR);
+    return -1;
+  }
+  
+  printk("EEPROM char device v0.3, (c) 2000 Axis Communications AB\n");
+
+  /*
+   *  Note: Most of this probing method was taken from the printserver (5470e)
+   *        codebase. It did not contain a way of finding the 16Kb chips
+   *        (M24128 or variants). The method used here might not work
+   *        for all models. If you encounter problems the easiest way
+   *        is probably to define your model within #ifdef's, and hard-
+   *        code it.
+   *
+   */
+
+  eeprom.size = 0;
+  eeprom.usec_delay_writecycles = 4000;/*MAX_WRITEDELAY_US / EEPROM_RETRIES;*/
+  eeprom.usec_delay_step = 128;
+  eeprom.adapt_state = 0;
+  
+#if CONFIG_ETRAX_I2C_EEPROM_PROBE
+  i2c_start();
+  i2c_outbyte(0x80);
+  if(!i2c_getack())
+  {
+    /* It's not 8k.. */
+    int success = 0;
+    unsigned char buf_2k_start[16];
+    
+    /* Im not sure this will work... :) */
+    /* assume 2Kb, if failure go for 16Kb */
+    /* Test with 16kB settings.. */
+    /* If it's a 2kB EEPROM and we address it outside it's range
+     * it will mirror the address space:
+     * 1. We read two locations (that are mirrored), 
+     *    if the content differs * it's a 16kB EEPROM.
+     * 2. if it doesn't differ - write diferent value to one of the locations,
+     *    check the other - if content still is the same it's a 2k EEPROM,
+     *    restore original data.
+     *    
+     */
+#define LOC1 8
+#define LOC2 (0x1fb) /*1fb, 3ed, 5df, 7d1 */
+
+   /* 2k settings */  
+    i2c_stop();
+    eeprom.size = EEPROM_2KB;
+    eeprom.select_cmd = 0xA0;   
+    eeprom.sequential_write_pagesize = 16;
+    if( eeprom_read_buf( 0, buf_2k_start, 16 ) == 16 )
+    {
+      D(printk("2k start: '%16.16s'\n", buf_2k_start));
+    }
+    else
+    {
+      printk("Failed to read in 2k mode!\n");  
+    }
+    
+    /* 16k settings */
+    eeprom.size = EEPROM_16KB;
+    eeprom.select_cmd = 0xA0;   
+    eeprom.sequential_write_pagesize = 64;
+
+    {
+      unsigned char loc1[4], loc2[4], tmp[4];
+      if( eeprom_read_buf(LOC2, loc2, 4) == 4)
+      {
+        if( eeprom_read_buf(LOC1, loc1, 4) == 4)
+        {
+          D(printk("0 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'\n", 
+                   LOC1, loc1, LOC2, loc2));
+#if 0
+          if (memcmp(loc1, loc2, 4) != 0 )
+          {
+            /* It's 16k */
+            printk("16k detected in step 1\n");
+            eeprom.size = EEPROM_16KB;     
+            success = 1;
+          }
+          else
+#endif
+          {
+            /* Do step 2 check */
+            /* Invert value */
+            loc1[0] = ~loc1[0];
+            if (eeprom_write_buf(LOC1, loc1, 1) == 1)
+            {
+              /* If 2k EEPROM this write will actually write 10 bytes
+               * from pos 0
+               */
+              D(printk("1 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'\n", 
+                       LOC1, loc1, LOC2, loc2));
+              if( eeprom_read_buf(LOC1, tmp, 4) == 4)
+              {
+                D(printk("2 loc1: (%i) '%4.4s' tmp '%4.4s'\n", 
+                         LOC1, loc1, tmp));
+                if (memcmp(loc1, tmp, 4) != 0 )
+                {
+                  printk("read and write differs! Not 16kB\n");
+                  loc1[0] = ~loc1[0];
+                  
+                  if (eeprom_write_buf(LOC1, loc1, 1) == 1)
+                  {
+                    success = 1;
+                  }
+                  else
+                  {
+                    printk("eeprom: Restore 2k failed during probe EEPROM might be corrupt!\n");
+                    
+                  }
+                  i2c_stop();
+                  /* Go to 2k mode and write original data */
+                  eeprom.size = EEPROM_2KB;
+                  eeprom.select_cmd = 0xA0;   
+                  eeprom.sequential_write_pagesize = 16;
+                  if( eeprom_write_buf(0, buf_2k_start, 16) == 16)
+                  {
+                  }
+                  else
+                  {
+                    printk("Failed to write back 2k start!\n");
+                  }
+                  
+                  eeprom.size = EEPROM_2KB;
+                }
+              }
+                
+              if(!success)
+              {
+                if( eeprom_read_buf(LOC2, loc2, 1) == 1)
+                {
+                  D(printk("0 loc1: (%i) '%4.4s' loc2 (%i) '%4.4s'\n", 
+                           LOC1, loc1, LOC2, loc2));
+                  if (memcmp(loc1, loc2, 4) == 0 )
+                  {
+                    /* Data the same, must be mirrored -> 2k */
+                    /* Restore data */
+                    printk("2k detected in step 2\n");
+                    loc1[0] = ~loc1[0];
+                    if (eeprom_write_buf(LOC1, loc1, 1) == 1)
+                    {
+                      success = 1;
+                    }
+                    else
+                    {
+                      printk("eeprom: Restore 2k failed during probe EEPROM might be corrupt!\n");
+                      
+                    }
+                    
+                    eeprom.size = EEPROM_2KB;     
+                  }
+                  else
+                  {
+                    printk("16k detected in step 2\n");
+                    loc1[0] = ~loc1[0];
+                    /* Data differs, assume 16k */
+                    /* Restore data */
+                    if (eeprom_write_buf(LOC1, loc1, 1) == 1)
+                    {
+                      success = 1;
+                    }
+                    else
+                    {
+                      printk("eeprom: Restore 16k failed during probe EEPROM might be corrupt!\n");
+                    }
+                    
+                    eeprom.size = EEPROM_16KB;
+                  }
+                }
+              }
+            }
+          } /* read LOC1 */
+        } /* address LOC1 */
+        if (!success)
+        {
+          printk("eeprom: Probing failed!, using 2KB!\n");
+          eeprom.size = EEPROM_2KB;               
+        }
+      } /* read */
+    }
+  }
+  else
+  {
+    i2c_outbyte(0x00);
+    if(!i2c_getack())
+    {
+      /* No 8k */
+      eeprom.size = EEPROM_2KB;
+    }
+    else
+    {
+      i2c_start();
+      i2c_outbyte(0x81);
+      if (!i2c_getack())
+      {
+        eeprom.size = EEPROM_2KB;
+      }
+      else
+      {
+        /* It's a 8kB */
+        i2c_inbyte();
+        eeprom.size = EEPROM_8KB;
+      }
+    }
+  }
+  i2c_stop();
+#elif defined(CONFIG_ETRAX_I2C_EEPROM_16KB)
+  eeprom.size = EEPROM_16KB;
+#elif defined(CONFIG_ETRAX_I2C_EEPROM_8KB)
+  eeprom.size = EEPROM_8KB;
+#elif defined(CONFIG_ETRAX_I2C_EEPROM_2KB)
+  eeprom.size = EEPROM_2KB;
+#endif
+
+  switch(eeprom.size)
+  {
+   case (EEPROM_2KB):
+     printk("e100eeprom: " EETEXT " i2c compatible 2Kb eeprom.\n");
+     eeprom.sequential_write_pagesize = 16;
+     eeprom.select_cmd = 0xA0;
+     break;
+   case (EEPROM_8KB):
+     printk("e100eeprom: " EETEXT " i2c compatible 8Kb eeprom.\n");
+     eeprom.sequential_write_pagesize = 16;
+     eeprom.select_cmd = 0x80;
+     break;
+   case (EEPROM_16KB):
+     printk("e100eeprom: " EETEXT " i2c compatible 16Kb eeprom.\n");
+     eeprom.sequential_write_pagesize = 64;
+     eeprom.select_cmd = 0xA0;     
+     break;
+   default:
+     eeprom.size = 0;
+     printk("e100eeprom: Did not find a supported eeprom\n");
+     break;
+  }
+
+  
+
+  eeprom_disable_write_protect();
+
+  return 0;
+}
+
+/*#**************************************************************************
+*#                                                            
+*# FUNCTION NAME: eeprom_open
+*#                                                            
+*# PARAMETERS   : inode    : Pointer to the inode
+*#                file     : Pointer to the file
+*#                                                            
+*# RETURNS      : 0 if OK
+*#                                                            
+*# SIDE EFFECTS : 
+*#                                                            
+*# DESCRIPTION  : Opens the device.
+*#                                                            
+*#---------------------------------------------------------------------------
+*# HISTORY                                                    
+*#                                                            
+*# DATE         NAME            CHANGES                       
+*# ----         ----            -------                       
+*# Aug 28 1999  Edgar Iglesias  Initial version               
+*# Sep 03 1999  Edgar Iglesias  Removed users check.
+*#
+*#**************************************************************************/
+
+static int eeprom_open(struct inode * inode, struct file * file)
+{
+
+  if(MINOR(inode->i_rdev) != EEPROM_MINOR_NR)
+     return -ENXIO;
+  if(MAJOR(inode->i_rdev) != EEPROM_MAJOR_NR)
+     return -ENXIO;
+
+  if( eeprom.size > 0 )
+  {
+    /* OK */
+    return 0;
+  }
+
+  /* No EEprom found */
+  return -EFAULT;
+}
+
+/*#**************************************************************************
+*#                                                            
+*# FUNCTION NAME: eeprom_lseek
+*#                                                            
+*# PARAMETERS   : file     : Pointer to the file
+*#                offset   : The offset (in bytes)
+*#                orig     : look at the note
+*#                                                            
+*# RETURNS      : 0 if OK
+*#                                                            
+*# SIDE EFFECTS : 
+*#                                                            
+*# DESCRIPTION  : Changes the current file position.
+*#                                                            
+*#---------------------------------------------------------------------------
+*# HISTORY                                                    
+*#                                                            
+*# DATE         NAME            CHANGES                       
+*# ----         ----            -------                       
+*# Aug 28 1999  Edgar Iglesias  Initial version
+*# Sep 03 1999  Edgar Iglesias  Return -EOVERFLOW when beyond eeprom size.
+*#
+*#**************************************************************************/
+
+static loff_t eeprom_lseek(struct file * file, loff_t offset, int orig)
+{
+/*
+ *  orig 0: position from begning of eeprom
+ *  orig 1: relative from current position
+ *  orig 2: position from last eeprom address
+ */
+  
+  switch (orig)
+  {
+   case 0:
+     file->f_pos = offset;
+     break;
+   case 1:
+     file->f_pos += offset;
+     break;
+   case 2:
+     file->f_pos = eeprom.size - offset;
+     break;
+   default:
+     return -EINVAL;
+  }
+
+  /* truncate position */
+  if (file->f_pos < 0)
+  {
+    file->f_pos = 0;    
+    return(-EOVERFLOW);
+  }
+  
+  if (file->f_pos >= eeprom.size)
+  {
+    file->f_pos = eeprom.size - 1;
+    return(-EOVERFLOW);
+  }
+
+  return ( file->f_pos );
+}
+
+/*#**************************************************************************
+*#                                                            
+*# FUNCTION NAME: eeprom_read
+*#                                                            
+*# PARAMETERS   : inode    : Pointer to the inode
+*#                file     : Pointer to the file
+*#                buf      : Destination buffer
+*#                count    : max nr bytes to read
+*#                                                            
+*# RETURNS      : number of read bytes.
+*#                                                            
+*# SIDE EFFECTS : updates file->f_pos
+*#                                                            
+*# DESCRIPTION  : Reads data from eeprom.
+*#                                                            
+*#---------------------------------------------------------------------------
+*# HISTORY                                                    
+*#                                                            
+*# DATE         NAME            CHANGES                       
+*# ----         ----            -------                       
+*# Jan 17 2000  Johan Adolfsson Initial version
+*#
+*#**************************************************************************/
+static int eeprom_read_buf(unsigned long addr,
+                           char * buf, int count)
+{
+  struct file f;
+
+  f.f_pos = addr;
+  return eeprom_read(&f, buf, count, &addr);
+}
+
+
+
+/*#**************************************************************************
+*#                                                            
+*# FUNCTION NAME: eeprom_read
+*#                                                            
+*# PARAMETERS   : file     : Pointer to the file
+*#                buf      : Destination buffer
+*#                count    : max nr bytes to read
+*#                                                            
+*# RETURNS      : number of read bytes.
+*#                                                            
+*# SIDE EFFECTS : updates file->f_pos
+*#                                                            
+*# DESCRIPTION  : Reads data from eeprom.
+*#                                                            
+*#---------------------------------------------------------------------------
+*# HISTORY                                                    
+*#                                                            
+*# DATE         NAME            CHANGES                       
+*# ----         ----            -------                       
+*# Aug 28 1999  Edgar Iglesias  Initial version               
+*# Aug 31 1999  Edgar Iglesias  Made operation atomic with wait queues
+*# Sep 03 1999  Edgar Iglesias  Added bail-out stuff if we get interrupted
+*#                              in the spin-lock.
+*#
+*#**************************************************************************/
+
+static ssize_t eeprom_read(struct file * file, char * buf, size_t count, loff_t *off)
+{
+  int i, read=0;
+  unsigned long p = file->f_pos;
+
+  unsigned char page;
+
+  if(p >= eeprom.size)  /* Address i 0 - (size-1) */
+  {
+    return -EFAULT;
+  }
+  
+  while(eeprom.busy)
+  {
+    interruptible_sleep_on(&eeprom.wait_q);
+
+    /* bail out if we get interrupted */
+    if (signal_pending(current))
+      return -EINTR;
+    
+  }
+  eeprom.busy++;
+
+  page = (unsigned char) (p >> 8);
+  
+  if(!eeprom_address(p))
+  {
+    printk("eeprom: Read failed to address the eeprom: "
+           "0x%08X (%i) page: %i\n", p, p, page);
+    i2c_stop();
+    
+    /* don't forget to wake them up */
+    eeprom.busy--;
+    wake_up_interruptible(&eeprom.wait_q);  
+    return -EFAULT;
+  }
+
+  if( (p + count) > eeprom.size)
+  {
+    /* truncate count */
+    count = eeprom.size - p;
+  }
+
+  /* stop dummy write op and initiate the read op */
+  i2c_start();
+
+  /* special case for small eeproms */
+  if(eeprom.size < EEPROM_16KB)
+  {
+    i2c_outbyte( eeprom.select_cmd | 1 | (page << 1) );
+  }
+
+  /* go on with the actual read */
+  read = read_from_eeprom( buf, count);
+  
+  if(read > 0)
+  {
+    file->f_pos += read;
+  }
+
+  eeprom.busy--;
+  wake_up_interruptible(&eeprom.wait_q);
+  return read;
+}
+
+/*#**************************************************************************
+*#                                                            
+*# FUNCTION NAME: eeprom_write_buf
+*#                                                            
+*# PARAMETERS   : addr     : Address to write to
+*#                buf      : Data buffer to write from
+*#                count    : number bytes to write
+*#                                                            
+*# RETURNS      : number of bytes actualy written.
+*#                                                            
+*# SIDE EFFECTS : None
+*#             
+*# DESCRIPTION  : Writes data to eeprom.
+*#                                                            
+*#---------------------------------------------------------------------------
+*# HISTORY                                                    
+*#                                                            
+*# DATE         NAME            CHANGES                       
+*# ----         ----            -------                       
+*# Jan 17 2000  Johan Adolfsson Initial vesion
+*#
+*#**************************************************************************/
+static int eeprom_write_buf(unsigned long int addr,
+                            const char * buf, int count)
+{
+  struct file f;
+
+  f.f_pos = addr;
+  
+  return eeprom_write(&f, buf, count, &addr);
+}
+
+
+/*#**************************************************************************
+*#                                                            
+*# FUNCTION NAME: eeprom_write
+*#                                                            
+*# PARAMETERS   : file     : Pointer to the file
+*#                buf      : Data buffer to write from
+*#                count    : number bytes to write
+*#                                                            
+*# RETURNS      : number of bytes actualy written.
+*#                                                            
+*# SIDE EFFECTS : updates file->f_pos
+*#             
+*# DESCRIPTION  : Writes data to eeprom.
+*#                                                            
+*#---------------------------------------------------------------------------
+*# HISTORY                                                    
+*#                                                            
+*# DATE         NAME            CHANGES                       
+*# ----         ----            -------                       
+*# Aug 28 1999  Edgar Iglesias  Initial version               
+*# Aug 31 1999  Edgar Iglesias  Made operation atomic with wait queues
+*# Sep 03 1999  Edgar Iglesias  Moved the actual reading to read_from_eeprom
+*# Sep 03 1999  Edgar Iglesias  Added bail-out stuff if we get interrupted
+*#                              in the spin-lock.
+*# May 18 2000  Edgar Iglesias  Make sure to end write cycle after every write.
+*#
+*#**************************************************************************/
+
+static ssize_t eeprom_write(struct file * file, const char * buf, size_t count,
+                            loff_t *off)
+{
+  int i, written, restart=1;
+  unsigned long p;
+
+  while(eeprom.busy)
+  {
+    interruptible_sleep_on(&eeprom.wait_q);
+    /* bail out if we get interrupted */
+    if (signal_pending(current))
+      return -EINTR;
+  }
+  eeprom.busy++;
+  for(i = 0; (i < EEPROM_RETRIES) && (restart > 0); i++)
+  {
+    restart = 0;
+    written = 0;
+    p = file->f_pos;
+   
+    
+    while( (written < count) && (p < eeprom.size))
+    {
+      /* address the eeprom */
+      if(!eeprom_address(p))
+      {
+        printk("eeprom: Write failed to address the eeprom: 0x%08X (%i) \n", 
+               p, p);
+        i2c_stop();
+        
+        /* don't forget to wake them up */
+        eeprom.busy--;
+        wake_up_interruptible(&eeprom.wait_q);
+        return -EFAULT;
+      }
+#ifdef EEPROM_ADAPTIVE_TIMING      
+      /* Adaptive algorithm to adjust timing */
+      if (eeprom.retry_cnt_addr > 0)
+      {
+        /* To Low now */
+        D(printk(">D=%i d=%i\n",
+               eeprom.usec_delay_writecycles, eeprom.usec_delay_step));
+
+        if (eeprom.usec_delay_step < 4)
+        {
+          eeprom.usec_delay_step++;
+          eeprom.usec_delay_writecycles += eeprom.usec_delay_step;
+        }
+        else
+        {
+
+          if (eeprom.adapt_state > 0)
+          {
+            /* To Low before */
+            eeprom.usec_delay_step *= 2;
+            if (eeprom.usec_delay_step > 2)
+            {
+              eeprom.usec_delay_step--;
+            }
+            eeprom.usec_delay_writecycles += eeprom.usec_delay_step;
+          }
+          else if (eeprom.adapt_state < 0)
+          {
+            /* To High before (toggle dir) */
+            eeprom.usec_delay_writecycles += eeprom.usec_delay_step;
+            if (eeprom.usec_delay_step > 1)
+            {
+              eeprom.usec_delay_step /= 2;
+              eeprom.usec_delay_step--;
+            }
+          }
+        }
+
+        eeprom.adapt_state = 1;
+      }
+      else
+      {
+        /* To High (or good) now */
+        D(printk("<D=%i d=%i\n",
+               eeprom.usec_delay_writecycles, eeprom.usec_delay_step));
+        
+        if (eeprom.adapt_state < 0)
+        {
+          /* To High before */
+          if (eeprom.usec_delay_step > 1)
+          {
+            if (eeprom.usec_delay_step > 0)
+            {
+              eeprom.usec_delay_step *= 2;
+              eeprom.usec_delay_step--;
+            }
+            
+            if (eeprom.usec_delay_writecycles > eeprom.usec_delay_step)
+            {
+              eeprom.usec_delay_writecycles -= eeprom.usec_delay_step;
+            }
+          }
+        }
+        else if (eeprom.adapt_state > 0)
+        {
+          /* To Low before (toggle dir) */
+          if (eeprom.usec_delay_writecycles > eeprom.usec_delay_step)
+          {
+            eeprom.usec_delay_writecycles -= eeprom.usec_delay_step;
+          }
+          if (eeprom.usec_delay_step > 1)
+          {
+            eeprom.usec_delay_step /= 2;
+            eeprom.usec_delay_step--;
+          }
+          
+          eeprom.adapt_state = -1;
+        }
+
+        if (eeprom.adapt_state > -100)
+        {
+          eeprom.adapt_state--;
+        }
+        else
+        {
+          /* Restart adaption */
+          D(printk("#Restart\n"));
+          eeprom.usec_delay_step++;
+        }
+      }
+#endif /* EEPROM_ADAPTIVE_TIMING */
+      /* write until we hit a page boundary or count */
+      do
+      {
+        i2c_outbyte(buf[written]);        
+        if(!i2c_getack())
+        {
+          restart=1;
+          printk("eeprom: write error, retrying. %d\n", i);
+          i2c_stop();
+          break;
+        }
+        written++;
+        p++;        
+      } while( written < count && ( p % eeprom.sequential_write_pagesize ));
+
+      /* end write cycle */
+      i2c_stop();
+      i2c_delay(eeprom.usec_delay_writecycles);
+    } /* while */
+  } /* for  */
+
+  eeprom.busy--;
+  wake_up_interruptible(&eeprom.wait_q);
+  if (written == 0 && file->f_pos >= eeprom.size){
+    return -ENOSPC;
+  }
+  file->f_pos += written;
+  return written;
+}
+
+/*#**************************************************************************
+*#                                                            
+*# FUNCTION NAME: eeprom_close
+*#                                                            
+*# PARAMETERS   : inode    : Pointer to the inode
+*#                file     : Pointer to the file
+*#
+*# RETURNS      : nothing
+*#
+*# SIDE EFFECTS :
+*#
+*# DESCRIPTION  : Closes the device.
+*#
+*#---------------------------------------------------------------------------
+*# HISTORY                                                    
+*#
+*# DATE         NAME            CHANGES                       
+*# ----         ----            -------                       
+*# Aug 28 1999  Edgar Iglesias  Initial version               
+*# Sep 03 1999  Edgar Iglesias  Removed eeprom.users stuff.
+*#
+*#**************************************************************************/
+
+static int eeprom_close(struct inode * inode, struct file * file)
+{
+  /* do nothing for now */
+  return 0;
+}
+
+/*#**************************************************************************
+*#                                                            
+*# FUNCTION NAME: eeprom_address
+*#                                                            
+*# PARAMETERS   : addr     : Address to be given to eeprom
+*#
+*# RETURNS      : 1 if OK, 0 if failure.
+*#
+*# SIDE EFFECTS :
+*#
+*# DESCRIPTION  : Sets the current address of the eeprom.
+*#
+*#---------------------------------------------------------------------------
+*# HISTORY                                                    
+*#
+*# DATE         NAME            CHANGES                       
+*# ----         ----            -------                       
+*# Aug 28 1999  Edgar Iglesias  Initial version               
+*# Sep 03 1999  Edgar Iglesias  Corrected typo.
+*#
+*#**************************************************************************/
+
+static int eeprom_address(unsigned long addr)
+{
+  int i, j;
+  unsigned char page, offset;
+
+  page   = (unsigned char) (addr >> 8);
+  offset = (unsigned char)  addr;
+
+  for(i = 0; i < EEPROM_RETRIES; i++)
+  {
+    /* start a dummy write for addressing */
+    i2c_start();
+
+    if(eeprom.size == EEPROM_16KB)
+    {
+      i2c_outbyte( eeprom.select_cmd ); 
+      i2c_getack();
+      i2c_outbyte(page); 
+    }
+    else
+    {
+      i2c_outbyte( eeprom.select_cmd | (page << 1) ); 
+    }
+    if(!i2c_getack())
+    {
+      /* retry */
+      i2c_stop();
+      /* Must have a delay here.. 500 works, >50, 100->works 5th time*/
+      i2c_delay(MAX_WRITEDELAY_US / EEPROM_RETRIES * i);
+      /* The chip needs up to 10 ms from write stop to next start */
+     
+    }
+    else
+    {
+      i2c_outbyte(offset);
+      
+      if(!i2c_getack())
+      {
+        /* retry */
+        i2c_stop();
+      }
+      else
+        break;
+    }
+  }    
+
+  
+  eeprom.retry_cnt_addr = i;
+  D(printk("%i\n", eeprom.retry_cnt_addr));
+  if(eeprom.retry_cnt_addr == EEPROM_RETRIES)
+  {
+    /* failed */
+    return 0;
+  }
+  return 1;
+}
+
+/*#**************************************************************************
+*#                                                            
+*# FUNCTION NAME: read_from_eeprom
+*#                                                            
+*# PARAMETERS   : buf      : Destination buffer.
+*#                count    : Number of bytes to read.
+*#
+*# RETURNS      : number of read bytes or -EFAULT.
+*#
+*# SIDE EFFECTS :
+*#
+*# DESCRIPTION  : Reads from current adress.
+*#
+*#---------------------------------------------------------------------------
+*# HISTORY                                                    
+*#
+*# DATE         NAME            CHANGES                       
+*# ----         ----            -------                       
+*# Sep 03 1999  Edgar Iglesias  Initial version               
+*#
+*#**************************************************************************/
+
+static int read_from_eeprom(char * buf, int count)
+{
+  int i, read=0;
+
+  for(i = 0; i < EEPROM_RETRIES; i++)
+  {    
+    if(eeprom.size == EEPROM_16KB)
+    {
+      i2c_outbyte( eeprom.select_cmd | 1 );
+    }
+
+    if(i2c_getack());
+    {
+      break;
+    }
+  }
+  
+  if(i == EEPROM_RETRIES)
+  {
+    printk("eeprom: failed to read from eeprom\n");
+    i2c_stop();
+    
+    return -EFAULT;
+  }
+
+  while( (read < count))
+  {    
+    buf[read++] = i2c_inbyte();      
+
+    /*
+     *  make sure we don't ack last byte or you will get very strange
+     *  results!
+     */
+    if(read < count)
+    {
+      i2c_sendack();
+    }
+  }
+
+  /* stop the operation */
+  i2c_stop();
+
+  return read;
+}
+
+/*#**************************************************************************
+*#                                                            
+*# FUNCTION NAME: eeprom_disable_write_protect
+*#                                                            
+*# PARAMETERS   : None
+*#
+*# RETURNS      : Nothing
+*#
+*# SIDE EFFECTS :
+*#
+*# DESCRIPTION  : Disables write protection if applicable
+*#
+*#---------------------------------------------------------------------------
+*# HISTORY                                                    
+*#
+*# DATE         NAME            CHANGES                       
+*# ----         ----            -------                       
+*# Jan 14 2000  Johan Adolfsson Initial version (from PS pareerom.c)
+*#
+*#**************************************************************************/
+#define DBP_SAVE(x)
+#define ax_printf printk
+static void eeprom_disable_write_protect(void)
+{
+  /* Disable write protect */
+  if (eeprom.size == EEPROM_8KB)
+  {
+    /* Step 1 Set WEL = 1 (write 00000010 to address 1FFFh */
+    i2c_start();
+    i2c_outbyte(0xbe);
+    if(!i2c_getack())
+    {
+      DBP_SAVE(ax_printf("Get ack returns false\n"));
+    }
+    i2c_outbyte(0xFF);
+    if(!i2c_getack())
+    {
+      DBP_SAVE(ax_printf("Get ack returns false 2\n"));
+    }
+    i2c_outbyte(0x02);
+    if(!i2c_getack())
+    {
+      DBP_SAVE(ax_printf("Get ack returns false 3\n"));
+    }
+    i2c_stop();
+
+    i2c_delay(1000);
+
+    /* Step 2 Set RWEL = 1 (write 00000110 to address 1FFFh */
+    i2c_start();
+    i2c_outbyte(0xbe);
+    if(!i2c_getack())
+    {
+      DBP_SAVE(ax_printf("Get ack returns false 55\n"));
+    }
+    i2c_outbyte(0xFF);
+    if(!i2c_getack())
+    {
+      DBP_SAVE(ax_printf("Get ack returns false 52\n"));
+    }
+    i2c_outbyte(0x06);
+    if(!i2c_getack())
+    {
+      DBP_SAVE(ax_printf("Get ack returns false 53\n"));
+    }
+    i2c_stop();
+    
+    /* Step 3 Set BP1, BP0, and/or WPEN bits (write 00000110 to address 1FFFh*/
+    i2c_start();
+    i2c_outbyte(0xbe);
+    if(!i2c_getack())
+    {
+      DBP_SAVE(ax_printf("Get ack returns false 56\n"));
+    }
+    i2c_outbyte(0xFF);
+    if(!i2c_getack())
+    {
+      DBP_SAVE(ax_printf("Get ack returns false 57\n"));
+    }
+    i2c_outbyte(0x06);
+    if(!i2c_getack())
+    {
+      DBP_SAVE(ax_printf("Get ack returns false 58\n"));
+    }
+    i2c_stop();
+    
+    /* Write protect disabled */
+  }
+}
+
+module_init(eeprom_init);
+
+/********************** END OF FILE e100eeprom.c *****************************/
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/ethernet.c linux/arch/cris/drivers/ethernet.c
--- v2.4.4/linux/arch/cris/drivers/ethernet.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/drivers/ethernet.c	Tue May  1 16:04:56 2001
@@ -1,4 +1,4 @@
-/* $Id: ethernet.c,v 1.8 2001/02/27 13:52:48 bjornw Exp $
+/* $Id: ethernet.c,v 1.12 2001/04/05 11:43:11 tobiasa Exp $
  *
  * e100net.c: A network driver for the ETRAX 100LX network controller.
  *
@@ -7,6 +7,21 @@
  * The outline of this driver comes from skeleton.c.
  *
  * $Log: ethernet.c,v $
+ * Revision 1.12  2001/04/05 11:43:11  tobiasa
+ * Check dev before panic.
+ *
+ * Revision 1.11  2001/04/04 11:21:05  markusl
+ * Updated according to review remarks
+ *
+ * Revision 1.10  2001/03/26 16:03:06  bjornw
+ * Needs linux/config.h
+ *
+ * Revision 1.9  2001/03/19 14:47:48  pkj
+ * * Make sure there is always a pause after the network LEDs are
+ *   changed so they will not look constantly lit during heavy traffic.
+ * * Always use HZ when setting times relative to jiffies.
+ * * Use LED_NETWORK_SET() when setting the network LEDs.
+ *
  * Revision 1.8  2001/02/27 13:52:48  bjornw
  * malloc.h -> slab.h
  *
@@ -40,10 +55,13 @@
  *
  */
 
+#include <linux/config.h>
+
 #include <linux/module.h>
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/delay.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
 #include <linux/interrupt.h>
@@ -52,11 +70,7 @@
 #include <linux/in.h>
 #include <linux/slab.h>
 #include <linux/string.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/dma.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 
@@ -65,11 +79,17 @@
 #include <linux/skbuff.h>
 
 #include <asm/svinto.h>     /* DMA and register descriptions */
+#include <asm/io.h>         /* LED_* I/O functions */
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
 
 //#define ETHDEBUG
-
 #define D(x)
 
+#define ETH_TX_DMA 0
+#define ETH_RX_DMA 1
+
 /*
  * The name of the card. Is used for messages and in the requests for
  * io regions, irqs and dma channels
@@ -126,12 +146,12 @@
 #define MDIO_PHYS_ADDR                      0x0
 
 /* Network flash constants */
-#define NET_FLASH_TIME                        2 /* 20 ms */
-#define NET_LINK_UP_CHECK_INTERVAL          200 /* 2 s   */
+#define NET_FLASH_TIME                  (HZ/50) /* 20 ms */
+#define NET_FLASH_PAUSE                (HZ/100) /* 10 ms */
+#define NET_LINK_UP_CHECK_INTERVAL       (2*HZ) /* 2 s   */
 
-/* RX_DESC_BUF_SIZE should be a multiple of four to avoid the buffer
- * alignment bug in Etrax 100 release 1
- */
+#define NO_NETWORK_ACTIVITY 0
+#define NETWORK_ACTIVITY    1
 
 #define RX_DESC_BUF_SIZE   256
 #define NBR_OF_RX_DESC     (RX_BUF_SIZE / \
@@ -146,8 +166,8 @@
 
 static unsigned char RxBuf[RX_BUF_SIZE];
 
-static etrax_dma_descr RxDescList[NBR_OF_RX_DESC];
-static etrax_dma_descr TxDesc;
+static etrax_dma_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(4)));
+static etrax_dma_descr TxDesc __attribute__ ((aligned(4)));
 
 static struct sk_buff *tx_skb;
 
@@ -155,8 +175,8 @@
 static struct timer_list speed_timer;
 static struct timer_list clear_led_timer;
 static int current_speed;
-static int led_clear_time;
-static int nolink;
+static int led_next_time;
+static int led_active;
 
 /* Index to functions, as function prototypes. */
 
@@ -184,6 +204,7 @@
 static void e100_reset_tranceiver(void);
 
 static void e100_clear_network_leds(unsigned long dummy);
+static void e100_set_network_leds(int active);
 
 #define tx_done(dev) (*R_DMA_CH0_CMD == 0)
 
@@ -201,7 +222,7 @@
 	int i;
 	int anOffset = 0;
 
-	printk("ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000 Axis Communications AB\n");
+	printk("ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2001 Axis Communications AB\n");
 
 	dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */
 
@@ -212,6 +233,8 @@
 	if (!dev) {
 		printk("dev == NULL. Should this happen?\n");
 		dev = init_etherdev(dev, sizeof(struct net_local));
+		if (!dev)
+			panic("init_etherdev failed\n");
 	}
 
 	/* setup generic handlers and stuff in the dev struct */
@@ -272,13 +295,12 @@
 
 	/* Initialize speed indicator stuff. */
 
-	nolink = 0;
 	current_speed = 10;
 	speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL;
 	speed_timer.function = e100_check_speed;
 	add_timer(&speed_timer);
 	clear_led_timer.function = e100_clear_network_leds;
-	clear_led_timer.expires = jiffies + 10;
+	clear_led_timer.expires = jiffies + HZ/10;
 	add_timer(&clear_led_timer);
 
 	return 0;
@@ -345,8 +367,17 @@
 
 	*R_NETWORK_MGM_CTRL = IO_STATE(R_NETWORK_MGM_CTRL, mdoe, enable);
 
-	*R_IRQ_MASK0_CLR = 0xe0000; /* clear excessive_col, over/underrun irq mask */
-	*R_IRQ_MASK2_CLR = 0xf; /* clear dma0 and 1 eop and descr irq masks */
+	*R_IRQ_MASK0_CLR =
+		IO_STATE(R_IRQ_MASK0_CLR, overrun, clr) |
+		IO_STATE(R_IRQ_MASK0_CLR, underrun, clr) |
+		IO_STATE(R_IRQ_MASK0_CLR, excessive_col, clr);
+	
+	/* clear dma0 and 1 eop and descr irq masks */
+	*R_IRQ_MASK2_CLR =
+		IO_STATE(R_IRQ_MASK2_CLR, dma0_descr, clr) |
+		IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr) |
+		IO_STATE(R_IRQ_MASK2_CLR, dma1_descr, clr) |
+		IO_STATE(R_IRQ_MASK2_CLR, dma1_eop, clr);
 
 	/* Reset and wait for the DMA channels */
 
@@ -383,17 +414,17 @@
 	 * and clean up on failure.
 	 */
 
-	if(request_dma(0, cardname)) {
+	if(request_dma(ETH_TX_DMA, cardname)) {
 		goto grace_exit;
 	}
 
-	if(request_dma(1, cardname)) {
+	if(request_dma(ETH_RX_DMA, cardname)) {
 	grace_exit:
 		/* this will cause some 'trying to free free irq' but what the heck... */
-		free_dma(0);
-		free_irq(NETWORK_DMARX_IRQ, NULL);
-		free_irq(NETWORK_DMATX_IRQ, NULL);
-		free_irq(NETWORK_STATUS_IRQ, NULL);
+		free_dma(ETH_TX_DMA);
+		free_irq(NETWORK_DMARX_IRQ, (void *)dev);
+		free_irq(NETWORK_DMATX_IRQ, (void *)dev);
+		free_irq(NETWORK_STATUS_IRQ, (void *)dev);
 		return -EAGAIN;
 	}
 
@@ -466,21 +497,19 @@
 e100_check_speed(unsigned long dummy)
 {
 	unsigned long data;
+	int old_speed = current_speed;
+
 	data = e100_get_mdio_reg(MDIO_BASE_STATUS_REG);
 	if (!(data & MDIO_LINK_UP_MASK)) {
-		nolink = 1;
-		LED_NETWORK_TX_SET(1); /* Make it red, link is down. */
+		current_speed = 0;
 	} else {
-		nolink = 0;
-		LED_NETWORK_TX_SET(0); /* Link is up again, clear red LED. */
 		data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG);
-		if (data & MDIO_SPEED) {
-			current_speed = 100;
-		} else {
-			current_speed = 10;
-		}
+		current_speed = (data & MDIO_SPEED ? 100 : 10);
 	}
 	
+	if (old_speed != current_speed)
+		e100_set_network_leds(NO_NETWORK_ACTIVITY);
+
 	/* Reinitialize the timer. */
 	speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL;
 	add_timer(&speed_timer);
@@ -534,23 +563,26 @@
 static void
 e100_send_mdio_bit(unsigned char bit)
 {
-	volatile int i;
-	*R_NETWORK_MGM_CTRL = 2 | bit&1;
-	for (i=40; i; i--);
-	*R_NETWORK_MGM_CTRL = 6 | bit&1;
-	for (i=40; i; i--);
+	*R_NETWORK_MGM_CTRL =
+		IO_STATE(R_NETWORK_MGM_CTRL, mdoe, enable) |
+		IO_FIELD(R_NETWORK_MGM_CTRL, mdio, bit);
+	udelay(1);
+	*R_NETWORK_MGM_CTRL =
+		IO_STATE(R_NETWORK_MGM_CTRL, mdoe, enable) |
+		IO_MASK(R_NETWORK_MGM_CTRL, mdck) |
+		IO_FIELD(R_NETWORK_MGM_CTRL, mdio, bit);
+	udelay(1);
 }
 
 static unsigned char
 e100_receive_mdio_bit()
 {
 	unsigned char bit;
-	volatile int i;
 	*R_NETWORK_MGM_CTRL = 0;
-	bit = *R_NETWORK_STAT & 1;
-	for (i=40; i; i--);
-	*R_NETWORK_MGM_CTRL = 4;
-	for (i=40; i; i--);
+	bit = IO_EXTRACT(R_NETWORK_STAT, mdio, *R_NETWORK_STAT);
+	udelay(1);
+	*R_NETWORK_MGM_CTRL = IO_MASK(R_NETWORK_MGM_CTRL, mdck);
+	udelay(1);
 	return bit;
 }
 
@@ -566,7 +598,7 @@
 
 	cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (MDIO_PHYS_ADDR << 7) | (MDIO_BASE_CONTROL_REG << 2);
 
-	e100_send_mdio_cmd(cmd, 0);
+	e100_send_mdio_cmd(cmd, 1);
 	
 	data |= 0x8000;
 	
@@ -656,8 +688,8 @@
 {
 	struct net_device *dev = (struct net_device *)dev_id;
 	unsigned long irqbits = *R_IRQ_MASK2_RD;
-
-	if(irqbits & (1U << 3)) {
+ 
+	if(irqbits & IO_STATE(R_IRQ_MASK2_RD, dma1_eop, active)) {
 
 		/* acknowledge the eop interrupt */
 
@@ -671,10 +703,15 @@
 			 */
 			e100_rx(dev);
 			((struct net_local *)dev->priv)->stats.rx_packets++;
-			*R_DMA_CH1_CMD = 3; /* restart/continue on the channel, for safety */
-			*R_DMA_CH1_CLR_INTR = 3; /* clear dma channel 1 eop/descr irq bits */
-			/* now, we might have gotten another packet so we have to loop back
-			   and check if so */
+			/* restart/continue on the channel, for safety */
+			*R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, restart);
+			/* clear dma channel 1 eop/descr irq bits */
+			*R_DMA_CH1_CLR_INTR =
+				IO_STATE(R_DMA_CH1_CLR_INTR, clr_eop, do) |
+				IO_STATE(R_DMA_CH1_CLR_INTR, clr_descr, do);
+			
+			/* now, we might have gotten another packet
+			   so we have to loop back and check if so */
 		}
 	}
 }
@@ -692,8 +729,9 @@
 	unsigned long irqbits = *R_IRQ_MASK2_RD;
 	struct net_local *np = (struct net_local *)dev->priv;
 
-	if(irqbits & 2) { /* check for a dma0_eop interrupt */
-
+	/* check for a dma0_eop interrupt */
+	if(irqbits & IO_STATE(R_IRQ_MASK2_RD, dma0_eop, active)) { 
+		
 		/* This protects us from concurrent execution of
 		 * our dev->hard_start_xmit function above.
 		 */
@@ -727,12 +765,14 @@
 	struct net_local *np = (struct net_local *)dev->priv;
 	unsigned long irqbits = *R_IRQ_MASK0_RD;
 
-	if(irqbits & (1 << 19)) { /* check for overrun irq */
+	/* check for overrun irq */
+	if(irqbits & IO_STATE(R_IRQ_MASK0_RD, overrun, active)) { 
 		update_rx_stats(&np->stats); /* this will ack the irq */
 		D(printk("ethernet receiver overrun!\n"));
 	}
-	if(irqbits & (1 << 17)) { /* check for excessive collision irq */
-		*R_NETWORK_TR_CTRL = 1 << 8; /* clear the interrupt */
+	/* check for excessive collision irq */
+	if(irqbits & IO_STATE(R_IRQ_MASK0_RD, excessive_col, active)) { 
+		*R_NETWORK_TR_CTRL = IO_STATE(R_NETWORK_TR_CTRL, clr_error, clr);
 		np->stats.tx_errors++;
 		D(printk("ethernet excessive collisions!\n"));
 	}
@@ -746,23 +786,19 @@
 	struct sk_buff *skb;
 	int length=0;
 	int i;
+	struct net_local *np = (struct net_local *)dev->priv;
 	struct etrax_dma_descr *mySaveRxDesc = myNextRxDesc;
 	unsigned char *skb_data_ptr;
 
-	/* light the network rx packet depending on the current speed.
-	** But only if link has been detected.
-	*/
-	if (!nolink)
-		if (current_speed == 10) {
-			LED_NETWORK_TX_SET(1);
-			LED_NETWORK_RX_SET(1);
-		} else
-			LED_NETWORK_RX_SET(1);
-  
-	/* Set the earliest time we may clear the LED */
+	if (!led_active && jiffies > led_next_time) {
+		/* light the network leds depending on the current speed. */
+		e100_set_network_leds(NETWORK_ACTIVITY);
+
+		/* Set the earliest time we may clear the LED */
+		led_next_time = jiffies + NET_FLASH_TIME;
+		led_active = 1;
+	}
 
-	led_clear_time = jiffies + NET_FLASH_TIME;
-  
 	/* If the packet is broken down in many small packages then merge
 	 * count how much space we will need to alloc with skb_alloc() for
 	 * it to fit.
@@ -790,6 +826,7 @@
 
 	skb = dev_alloc_skb(length - ETHER_HEAD_LEN);
 	if (!skb) {
+		np->stats.rx_errors++;
 		printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n",
 		       dev->name);
 		return;
@@ -798,7 +835,7 @@
 	skb_put(skb, length - ETHER_HEAD_LEN);        /* allocate room for the packet body */
 	skb_data_ptr = skb_push(skb, ETHER_HEAD_LEN); /* allocate room for the header */
 
-#if 0
+#ifdef ETHDEBUG
 	printk("head = 0x%x, data = 0x%x, tail = 0x%x, end = 0x%x\n",
 	       skb->head, skb->data, skb->tail, skb->end);
 	printk("copying packet to 0x%x.\n", skb_data_ptr);
@@ -849,9 +886,17 @@
 	*R_NETWORK_GEN_CONFIG =
 		IO_STATE(R_NETWORK_GEN_CONFIG, phy,    mii_clk) |
 		IO_STATE(R_NETWORK_GEN_CONFIG, enable, off);
-
-	*R_IRQ_MASK0_CLR = 0xe0000; /* clear excessive_col, over/underrun irq mask */
-	*R_IRQ_MASK2_CLR = 0xf; /* clear dma0 and 1 eop and descr irq masks */
+	
+	*R_IRQ_MASK0_CLR =
+		IO_STATE(R_IRQ_MASK0_CLR, overrun, clr) |
+		IO_STATE(R_IRQ_MASK0_CLR, underrun, clr) |
+		IO_STATE(R_IRQ_MASK0_CLR, excessive_col, clr);
+	
+	*R_IRQ_MASK2_CLR =
+		IO_STATE(R_IRQ_MASK2_CLR, dma0_descr, clr) |
+		IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr) |
+		IO_STATE(R_IRQ_MASK2_CLR, dma1_descr, clr) |
+		IO_STATE(R_IRQ_MASK2_CLR, dma1_eop, clr);
 
 	/* Stop the receiver and the transmitter */
 
@@ -864,8 +909,8 @@
 	free_irq(NETWORK_DMATX_IRQ, (void *)dev);
 	free_irq(NETWORK_STATUS_IRQ, (void *)dev);
 
-	free_dma(0);
-	free_dma(1);
+	free_dma(ETH_TX_DMA);
+	free_dma(ETH_RX_DMA);
 
 	/* Update the statistics here. */
 
@@ -997,22 +1042,16 @@
 e100_hardware_send_packet(char *buf, int length)
 {
 	D(printk("e100 send pack, buf 0x%x len %d\n", buf, length));
-	/* light the network leds depending on the current speed.
-	** But only if link has been detected.
-	*/
-	if (!nolink) {
-		if (current_speed == 10) {
-			LED_NETWORK_TX_SET(1);
-			LED_NETWORK_RX_SET(1);
-		} else {
-			LED_NETWORK_RX_SET(1);
-		}
-	}
 
-	/* Set the earliest time we may clear the LED */
+	if (!led_active && jiffies > led_next_time) {
+		/* light the network leds depending on the current speed. */
+		e100_set_network_leds(NETWORK_ACTIVITY);
+
+		/* Set the earliest time we may clear the LED */
+		led_next_time = jiffies + NET_FLASH_TIME;
+		led_active = 1;
+	}
 
-	led_clear_time = jiffies + NET_FLASH_TIME;
-	
 	/* configure the tx dma descriptor */
 
 	TxDesc.sw_len = length;
@@ -1028,16 +1067,41 @@
 static void
 e100_clear_network_leds(unsigned long dummy)
 {
-	if (jiffies > led_clear_time) {
-		if (nolink)
-			LED_NETWORK_TX_SET(1);
-		else
-			LED_NETWORK_TX_SET(0);
-		LED_NETWORK_RX_SET(0); 
+        if (led_active && jiffies > led_next_time) {
+		e100_set_network_leds(NO_NETWORK_ACTIVITY);
+
+		/* Set the earliest time we may set the LED */
+		led_next_time = jiffies + NET_FLASH_PAUSE;
+		led_active = 0;
 	}
-	
-	clear_led_timer.expires = jiffies + 10;
+
+        clear_led_timer.expires = jiffies + HZ/10;
 	add_timer(&clear_led_timer);
+}
+
+static void
+e100_set_network_leds(int active)
+{
+#ifdef CONFIG_LED_OFF_DURING_ACTIVITY
+	int light_leds = (active == NO_NETWORK_ACTIVITY);
+#else
+	int light_leds = (active == NETWORK_ACTIVITY);
+#endif
+
+	if (!current_speed) {
+		/* Make LED red, link is down */
+		LED_NETWORK_SET(LED_RED);
+	}
+	else if (light_leds) {
+		if (current_speed == 10) {
+			LED_NETWORK_SET(LED_ORANGE);
+		} else {
+			LED_NETWORK_SET(LED_GREEN);
+		}
+	}
+	else {
+		LED_NETWORK_SET(LED_OFF);
+	}
 }
 
 static struct net_device dev_etrax_ethernet;  /* only got one */
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/gpio.c linux/arch/cris/drivers/gpio.c
--- v2.4.4/linux/arch/cris/drivers/gpio.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/drivers/gpio.c	Sat May 19 17:43:05 2001
@@ -1,4 +1,4 @@
-/* $Id: gpio.c,v 1.4 2001/02/27 13:52:48 bjornw Exp $
+/* $Id: gpio.c,v 1.7 2001/04/04 13:30:08 matsfg Exp $
  *
  * Etrax general port I/O device
  *
@@ -9,6 +9,15 @@
  *             Johan Adolfsson  (read/set directions)
  *
  * $Log: gpio.c,v $
+ * Revision 1.7  2001/04/04 13:30:08  matsfg
+ * Added bitset and bitclear for leds. Calls init_ioremap to set up memmapping
+ *
+ * Revision 1.6  2001/03/26 16:03:06  bjornw
+ * Needs linux/config.h
+ *
+ * Revision 1.5  2001/03/26 14:22:03  bjornw
+ * Namechange of some config options
+ *
  * Revision 1.4  2001/02/27 13:52:48  bjornw
  * malloc.h -> slab.h
  *
@@ -25,6 +34,7 @@
  */
 
 #include <linux/config.h>
+
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
@@ -78,25 +88,25 @@
 	&port_pa_data_shadow, &port_pb_data_shadow };
 
 /* What direction bits that are user changeable 1=changeable*/
-#ifndef CONFIG_PA_CHANGEABLE_DIR
-#define CONFIG_PA_CHANGEABLE_DIR 0x00
+#ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
+#define CONFIG_ETRAX_PA_CHANGEABLE_DIR 0x00
 #endif
-#ifndef CONFIG_PB_CHANGEABLE_DIR
-#define CONFIG_PB_CHANGEABLE_DIR 0x00
+#ifndef CONFIG_ETRAX_PB_CHANGEABLE_DIR
+#define CONFIG_ETRAX_PB_CHANGEABLE_DIR 0x00
 #endif
 
-#ifndef CONFIG_PA_CHANGEABLE_BITS
-#define CONFIG_PA_CHANGEABLE_BITS 0xFF
+#ifndef CONFIG_ETRAX_PA_CHANGEABLE_BITS
+#define CONFIG_ETRAX_PA_CHANGEABLE_BITS 0xFF
 #endif
-#ifndef CONFIG_PB_CHANGEABLE_BITS
-#define CONFIG_PB_CHANGEABLE_BITS 0xFF
+#ifndef CONFIG_ETRAX_PB_CHANGEABLE_BITS
+#define CONFIG_ETRAX_PB_CHANGEABLE_BITS 0xFF
 #endif
 
 
-static unsigned char changeable_dir[2] = { CONFIG_PA_CHANGEABLE_DIR,
-                                           CONFIG_PB_CHANGEABLE_DIR };
-static unsigned char changeable_bits[2] = { CONFIG_PA_CHANGEABLE_BITS,
-                                            CONFIG_PB_CHANGEABLE_BITS };
+static unsigned char changeable_dir[2] = { CONFIG_ETRAX_PA_CHANGEABLE_DIR,
+                                           CONFIG_ETRAX_PB_CHANGEABLE_DIR };
+static unsigned char changeable_bits[2] = { CONFIG_ETRAX_PA_CHANGEABLE_BITS,
+                                            CONFIG_ETRAX_PB_CHANGEABLE_BITS };
 
 static volatile unsigned char *dir[2] = { R_PORT_PA_DIR, R_PORT_PB_DIR };
 
@@ -240,7 +250,7 @@
 		default:
 			if(priv->minor == LEDS)
 				return gpio_leds_ioctl(cmd, arg);
-			else
+                        else
 				return -EINVAL;
 	}
 	
@@ -252,7 +262,12 @@
 {
 	unsigned char green;
 	unsigned char red;
-
+        static int initialized = 0;
+        if(!initialized)
+        {
+          initialized = 1;
+          init_ioremap();
+        }
 	switch (_IOC_NR(cmd)) {
 		case IO_LEDACTIVE_SET:
 			green = ((unsigned char) arg) & 1;
@@ -260,6 +275,11 @@
 			LED_ACTIVE_SET_G(green);
 			LED_ACTIVE_SET_R(red);
 			break;
+                case IO_LED_SETBIT:                 
+                        LED_BIT_SET(arg);
+                       break;
+                case IO_LED_CLRBIT:
+                        LED_BIT_CLR(arg);
 		default:
 			return -EINVAL;
 	}
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/i2c.c linux/arch/cris/drivers/i2c.c
--- v2.4.4/linux/arch/cris/drivers/i2c.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/drivers/i2c.c	Sat May 19 17:43:05 2001
@@ -12,6 +12,12 @@
 *!                                 don't use PB_I2C if DS1302 uses same bits,
 *!                                 use PB.
 *! $Log: i2c.c,v $
+*! Revision 1.7  2001/04/04 13:11:36  markusl
+*! Updated according to review remarks
+*!
+*! Revision 1.6  2001/03/19 12:43:00  markusl
+*! Made some symbols unstatic (used by the eeprom driver)
+*!
 *! Revision 1.5  2001/02/27 13:52:48  bjornw
 *! malloc.h -> slab.h
 *!
@@ -37,7 +43,7 @@
 *! (C) Copyright 1999, 2000, 2001 Axis Communications AB, LUND, SWEDEN
 *!
 *!***************************************************************************/
-/* $Id: i2c.c,v 1.5 2001/02/27 13:52:48 bjornw Exp $ */
+/* $Id: i2c.c,v 1.7 2001/04/04 13:11:36 markusl Exp $ */
 /****************** INCLUDE FILES SECTION ***********************************/
 
 #include <linux/module.h>
@@ -144,50 +150,50 @@
 
 /* generate i2c start condition */
 
-static void
+void
 i2c_start(void)
 {
-	//
-	// SCL=1 SDA=1
-	//
+	/*
+	 * SCL=1 SDA=1
+	 */
 	i2c_dir_out();
 	i2c_delay(CLOCK_HIGH_TIME/6);
 	i2c_data(I2C_DATA_HIGH);
 	i2c_clk(I2C_CLOCK_HIGH);
 	i2c_delay(CLOCK_HIGH_TIME);
-	//
-	// SCL=1 SDA=0
-	//
+	/*
+	 * SCL=1 SDA=0
+	 */
 	i2c_data(I2C_DATA_LOW);
 	i2c_delay(START_CONDITION_HOLD_TIME);
-	//
-	// SCL=0 SDA=0
-	//
+	/*
+	 * SCL=0 SDA=0
+	 */
 	i2c_clk(I2C_CLOCK_LOW);
 	i2c_delay(CLOCK_LOW_TIME);
 }
 
 /* generate i2c stop condition */
 
-static void
+void
 i2c_stop(void)
 {
 	i2c_dir_out();
 
-	//
-	// SCL=0 SDA=0
-	//
+	/*
+	 * SCL=0 SDA=0
+	 */
 	i2c_clk(I2C_CLOCK_LOW);
 	i2c_data(I2C_DATA_LOW);
 	i2c_delay(CLOCK_LOW_TIME*2);
-	//
-	// SCL=1 SDA=0
-	//
+	/*
+	 * SCL=1 SDA=0
+	 */
 	i2c_clk(I2C_CLOCK_HIGH);
 	i2c_delay(CLOCK_HIGH_TIME*2);
-	//
-	// SCL=1 SDA=1
-	//
+	/*
+	 * SCL=1 SDA=1
+	 */
 	i2c_data(I2C_DATA_HIGH);
 	i2c_delay(STOP_CONDITION_HOLD_TIME);
 
@@ -196,7 +202,7 @@
 
 /* write a byte to the i2c interface */
 
-static void
+void
 i2c_outbyte(unsigned char x)
 {
 	int i;
@@ -219,78 +225,75 @@
 	i2c_data(I2C_DATA_LOW);
 	i2c_delay(CLOCK_LOW_TIME/2);
 
-	//
-	// enable input
-	//
+	/*
+	 * enable input
+	 */
 	i2c_dir_in();
 }
 
 /* read a byte from the i2c interface */
 
-static unsigned char
+unsigned char
 i2c_inbyte(void)
 {
 	unsigned char aBitByte = 0;
 	int i;
 	int iaa;
-	//int dd= 0;
 
-	//
-	// enable output
-	//
+	/*
+	 * enable output
+	 */
 	i2c_dir_out();
-	//
-	// Release data bus by setting
-	// data high
-	//
+	/*
+	 * Release data bus by setting
+	 * data high
+	 */
 	i2c_data(I2C_DATA_HIGH);
-	//
-	// enable input
-	//
+	/*
+	 * enable input
+	 */
 	i2c_dir_in();
-	//
-	// Use PORT PB instead of I2C
-	// for input. (I2C not working)
-	//
+	/*
+	 * Use PORT PB instead of I2C
+	 * for input. (I2C not working)
+	 */
 	i2c_clk(1);
 	i2c_data(1);
-/*	*R_PORT_PB_DATA = *R_PORT_PB_READ | 0x03;*/
-	//
-	// get bits
-	//
+	/*
+	 * get bits
+	 */
 	for (i = 0; i < 8; i++) {
 		i2c_delay(CLOCK_LOW_TIME/2);
-		//
-		// low clock period
-		//
+		/*
+		 * low clock period
+		 */
 		i2c_clk(I2C_CLOCK_HIGH);
-		//
-		// switch off I2C
-		//
+		/*
+		 * switch off I2C
+		 */
 		i2c_data(1);
 		i2c_disable();
 		i2c_dir_in();
-		//
-		// wait before getting bit
-		//
+		/*
+		 * wait before getting bit
+		 */
 		i2c_delay(CLOCK_HIGH_TIME/2);
 		aBitByte = (aBitByte << 1);
 		iaa = i2c_getbit();
 		aBitByte = aBitByte | iaa ;
-		//if (iaa > 0) dd++;
-		//
-		// wait
-		//
+		/*
+		 * wait
+		 */
 		i2c_delay(CLOCK_HIGH_TIME/2);
-		//
-		// end clock puls
-		//
+		/*
+		 * end clock puls
+		 */
 		i2c_enable();
 		i2c_dir_out();
 		i2c_clk(I2C_CLOCK_LOW);
-		//
-		// low clock period
-		//
+		/*
+		 * low clock period
+		 */
 		i2c_delay(CLOCK_LOW_TIME/2);
 	}
 	i2c_dir_out();
@@ -305,49 +308,47 @@
 *#
 *#--------------------------------------------------------------------------*/
 
-static int
+int
 i2c_getack(void)
 {
 	int ack = 1;
-	//
-	// enable output
-	//
+	/*
+	 * enable output
+	 */
 	i2c_dir_out();
-	//
-	// Release data bus by setting
-	// data high
-	//
+	/*
+	 * Release data bus by setting
+	 * data high
+	 */
 	i2c_data(I2C_DATA_HIGH);
-	//
-	// enable input
-	//
+	/*
+	 * enable input
+	 */
 	i2c_dir_in();
 	i2c_delay(CLOCK_HIGH_TIME/4);
-	//
-	// generate ACK clock pulse
-	//
+	/*
+	 * generate ACK clock pulse
+	 */
 	i2c_clk(I2C_CLOCK_HIGH);
-	//
-	// Use PORT PB instead of I2C
-	// for input. (I2C not working)
-	//
+	/*
+	 * Use PORT PB instead of I2C
+	 * for input. (I2C not working)
+	 */
 	i2c_clk(1);
 	i2c_data(1);
-  
-/*	*R_PORT_PB_DATA = *R_PORT_PB_READ | 0x03;*/
-	//
-	// switch off I2C
-	//
+	/*
+	 * switch off I2C
+	 */
 	i2c_data(1);
 	i2c_disable();
 	i2c_dir_in();
-	//
-	// now wait for ack
-	//
+	/*
+	 * now wait for ack
+	 */
 	i2c_delay(CLOCK_HIGH_TIME/2);
-	//
-	// check for ack
-	//
+	/*
+	 * check for ack
+	 */
 	if(i2c_getbit())
 		ack = 0;
 	i2c_delay(CLOCK_HIGH_TIME/2);
@@ -357,20 +358,20 @@
 		i2c_delay(CLOCK_HIGH_TIME/2);
 	}
 
-	//
-	// end clock pulse
-	//
+	/*
+	 * end clock pulse
+	 */
 	i2c_enable();
 	i2c_dir_out();
 	i2c_clk(I2C_CLOCK_LOW);
 	i2c_delay(CLOCK_HIGH_TIME/4);
-	//
-	// enable output
-	//
+	/*
+	 * enable output
+	 */
 	i2c_dir_out();
-	//
-	// remove ACK clock pulse
-	//
+	/*
+	 * remove ACK clock pulse
+	 */
 	i2c_data(I2C_DATA_HIGH);
 	i2c_delay(CLOCK_LOW_TIME/2);
 	return ack;
@@ -383,32 +384,32 @@
 *# DESCRIPTION  : Send ACK on received data
 *#
 *#--------------------------------------------------------------------------*/
-static void
+void
 i2c_sendack(void)
 {
-	//
-	// enable output
-	//
+	/*
+	 * enable output
+	 */
 	i2c_delay(CLOCK_LOW_TIME);
 	i2c_dir_out();
-	//
-	// set ack pulse high
-	//
+	/*
+	 * set ack pulse high
+	 */
 	i2c_data(I2C_DATA_LOW);
-	//
-	// generate clock pulse
-	//
+	/*
+	 * generate clock pulse
+	 */
 	i2c_delay(CLOCK_HIGH_TIME/6);
 	i2c_clk(I2C_CLOCK_HIGH);
 	i2c_delay(CLOCK_HIGH_TIME);
 	i2c_clk(I2C_CLOCK_LOW);
 	i2c_delay(CLOCK_LOW_TIME/6);
-	//
-	// reset data out
-	//
+	/*
+	 * reset data out
+	 */
 	i2c_data(I2C_DATA_HIGH);
 	i2c_delay(CLOCK_LOW_TIME);
-	//
+	
 	i2c_dir_in();
 }
 
@@ -424,20 +425,22 @@
 	     unsigned char theValue)
 {
 	int error, cntr = 3;
+	unsigned long flags;
 		
 	do {
 		error = 0;
-		//
-		// we don't like to be interrupted
-		//
+		/*
+		 * we don't like to be interrupted
+		 */
+		save_flags(flags);
 		cli();
-		//
-		// generate start condition
-		//
+		/*
+		 * generate start condition
+		 */
 		i2c_start();
-		//
-		// dummy preamble
-		//
+		/*
+		 * dummy preamble
+		 */
 		i2c_outbyte(0x01);
 		i2c_data(I2C_DATA_HIGH);
 		i2c_clk(I2C_CLOCK_HIGH);
@@ -452,42 +455,42 @@
 		i2c_delay(CLOCK_LOW_TIME);
 
 		i2c_start();
-		//
-		// send slave address
-		//
+		/*
+		 * send slave address
+		 */
 		i2c_outbyte(theSlave);
-		//
-		// wait for ack
-		//
+		/*
+		 * wait for ack
+		 */
 		if(!i2c_getack())
 			error = 1;
-		//
-		// now select register
-		//
+		/*
+		 * now select register
+		 */
 		i2c_dir_out();
 		i2c_outbyte(theReg);
-		//
-		// now it's time to wait for ack
-		//
+		/*
+		 * now it's time to wait for ack
+		 */
 		if(!i2c_getack())
 			error |= 2;
-		//
-		// send register register data
-		//
+		/*
+		 * send register register data
+		 */
 		i2c_outbyte(theValue);
-		//
-		// now it's time to wait for ack
-		//
+		/*
+		 * now it's time to wait for ack
+		 */
 		if(!i2c_getack())
 			error |= 4;
-		//
-		// end byte stream
-		//
+		/*
+		 * end byte stream
+		 */
 		i2c_stop();
-		//
-		// enable interrupt again
-		//
-		sti();
+		/*
+		 * enable interrupt again
+		 */
+		restore_flags(flags);
 		
 	} while(error && cntr--);
 	
@@ -508,20 +511,22 @@
 {
 	unsigned char b = 0;
 	int error, cntr = 3;
+	unsigned long flags;
 		
 	do {
 		error = 0;
-		//
-		// we don't like to be interrupted
-		//
+		/*
+		 * we don't like to be interrupted
+		 */
+		save_flags(flags);
 		cli();
-		//
-		// generate start condition
-		//
+		/*
+		 * generate start condition
+		 */
 		i2c_start();
-		//
-		// dummy preamble
-		//
+		/*
+		 * dummy preamble
+		 */
 		i2c_outbyte(0x01);
 		i2c_data(I2C_DATA_HIGH);
 		i2c_clk(I2C_CLOCK_HIGH);
@@ -537,55 +542,56 @@
     
 		i2c_start();
     
-		//
-		// send slave address
-		//
+		/*
+		 * send slave address
+		 */
 		i2c_outbyte(theSlave);
-		//
-		// wait for ack
-		//
+		/*
+		 * wait for ack
+		 */
 		if(!i2c_getack())
 			error = 1;
-		//
-		// now select register
-		//
+		/*
+		 * now select register
+		 */
 		i2c_dir_out();
 		i2c_outbyte(theReg);
-		//
-		// now it's time to wait for ack
-		//
+		/*
+		 * now it's time to wait for ack
+		 */
 		if(!i2c_getack())
 			error = 1;
-		//
-		// repeat start condition
-		//
+		/*
+		 * repeat start condition
+		 */
 		i2c_delay(CLOCK_LOW_TIME);
 		i2c_start();
-		//
-		// send slave address
-		//
+		/*
+		 * send slave address
+		 */
 		i2c_outbyte(theSlave | 0x01);
-		//
-		// wait for ack
-		//
+		/*
+		 * wait for ack
+		 */
 		if(!i2c_getack())
 			error = 1;
-		//
-		// fetch register
-		//
+		/*
+		 * fetch register
+		 */
 		b = i2c_inbyte();
-		//
-		// send Ack
-		//
+		/*
+		 * send Ack
+		 */
 		i2c_sendack();
-		//
-		// end sequence
-		//
+		/*
+		 * end sequence
+		 */
 		i2c_stop();
-		//
-		// enable interrupt again
-		//
-		sti();	
+		/*
+		 * enable interrupt again
+		 */
+		restore_flags(flags);
+		
 	} while(error && cntr--);
 
 	return b;
@@ -616,7 +622,7 @@
 
 	switch (_IOC_NR(cmd)) {
 		case I2C_WRITEREG:
-			// write to an i2c slave
+			/* write to an i2c slave */
 			D(printk("i2cw %d %d %d\n", 
 				 I2C_ARGSLAVE(arg),
 				 I2C_ARGREG(arg),
@@ -628,7 +634,7 @@
 		case I2C_READREG:
 		{
 			unsigned char val;
-			// read from an i2c slave
+			/* read from an i2c slave */
 			D(printk("i2cr %d %d ", 
 				I2C_ARGSLAVE(arg),
 				I2C_ARGREG(arg)));
@@ -682,6 +688,8 @@
 	}
 
 	printk("I2C driver v2.2, (c) 1999-2001 Axis Communications AB\n");
+	
+	return 0;
 }
 
 /* this makes sure that i2c_init is called during boot */
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/i2c.h linux/arch/cris/drivers/i2c.h
--- v2.4.4/linux/arch/cris/drivers/i2c.h	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/drivers/i2c.h	Sat May 19 17:43:05 2001
@@ -1,16 +1,16 @@
-/* $Id: i2c.h,v 1.2 2001/01/18 15:49:30 bjornw Exp $ */
+/* $Id: i2c.h,v 1.3 2001/03/19 12:43:01 markusl Exp $ */
 
 /* High level I2C actions */
 int i2c_writereg(unsigned char theSlave, unsigned char theReg, unsigned char theValue);
 unsigned char i2c_readreg(unsigned char theSlave, unsigned char theReg);
 
 /* Low level I2C */
-static void i2c_start(void);
-static void i2c_stop(void);
-static void i2c_outbyte(unsigned char x);
-static unsigned char i2c_inbyte(void);
-static int i2c_getack(void);
-static void i2c_sendack(void);
+void i2c_start(void);
+void i2c_stop(void);
+void i2c_outbyte(unsigned char x);
+unsigned char i2c_inbyte(void);
+int i2c_getack(void);
+void i2c_sendack(void);
 
 
 
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/parport.c linux/arch/cris/drivers/parport.c
--- v2.4.4/linux/arch/cris/drivers/parport.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/drivers/parport.c	Tue May  1 16:04:56 2001
@@ -0,0 +1,591 @@
+/* $Id: parport.c,v 1.4 2001/04/06 13:04:02 hugo Exp $
+ * 
+ * Elinux parallel port driver
+ * NOTE!
+ *   Since par0 shares DMA with ser2 and par 1 shares DMA with ser3
+ *   this should be handled if both are enabled at the same time.
+ *   THIS IS NOT HANDLED YET!
+ *
+ * Copyright (c) 2001 Axis Communications AB
+ * 
+ * Author: Fredrik Hugosson
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/parport.h>
+#include <linux/ioport.h>
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+
+#include <asm/segment.h>
+#include <asm/system.h>
+
+#include <asm/svinto.h>
+
+
+#undef DEBUG
+#ifdef DEBUG
+#define DPRINTK printk
+#else
+static inline int DPRINTK(void *nothing, ...) {return 0;}
+#endif
+
+/*
+ * Etrax100 DMAchannels:
+ * Par0 out : DMA2
+ * Par0 in  : DMA3
+ * Par1 out : DMA4
+ * Par1 in  : DMA5
+ * NOTE! par0 is hared with ser2 and par1 is shared with ser3 regarding
+ *       DMA and DMA irq
+ */
+
+//#define CONFIG_PAR0_INT 1
+//#define CONFIG_PAR1_INT 1
+
+#define SETF(var, reg, field, val) \
+	var = (var & ~IO_MASK(##reg##, field)) | IO_FIELD(##reg##, field, val)
+
+#define SETS(var, reg, field, val) \
+	var = (var & ~IO_MASK(##reg##, field)) | IO_STATE(##reg##, field, val)
+
+struct etrax100par_struct {
+	/* parallell port control */
+	volatile u32 *reg_ctrl_data; /* R_PARx_CTRL_DATA */
+	const volatile u32 *reg_status_data; /* R_PARx_STATUS_DATA */
+	volatile u32 *reg_config; /* R_PARx_CONFIG */
+	volatile u32 *reg_delay; /* R_PARx_DELAY */
+	
+	/* DMA control */
+	int odma;
+	unsigned long dma_irq;  /* bitnr in R_IRQ_MASK2 for dmaX_descr */
+
+	volatile char *oclrintradr; /* adr to R_DMA_CHx_CLR_INTR, output */
+	volatile u32 *ofirstadr;   /* adr to R_DMA_CHx_FIRST, output */
+	volatile char *ocmdadr;     /* adr to R_DMA_CHx_CMD, output */
+	
+	volatile char *iclrintradr; /* adr to R_DMA_CHx_CLR_INTR, input */
+	volatile u32 *ifirstadr;   /* adr to R_DMA_CHx_FIRST, input */
+	volatile char *icmdadr;     /* adr to R_DMA_CHx_CMD, input */
+	const volatile u8 *istatusadr;  /* adr to R_DMA_CHx_STATUS, input */
+	volatile u32 *ihwswadr;    /* adr to R_DMA_CHx_HWSW, input */
+
+	/* Non DMA interrupt stuff */
+	unsigned long int_irq; /* R_VECT_MASK_RD */
+	const volatile u32 *irq_mask_rd; /* R_IRQ_MASKX_RD */
+	volatile u32 *irq_mask_clr; /* R_IRQ_MASKX_RD */
+	const volatile u32 *irq_read; /* R_IRQ_READX */
+	volatile u32 *irq_mask_set; /* R_IRQ_MASKX_SET */
+	unsigned long irq_mask_tx;  /* bitmask in R_IRQ_ for tx (ready) int */
+	unsigned long irq_mask_rx;  /* bitmask in R_IRQ_ for rx (data) int */
+	unsigned long irq_mask_ecp_cmd;  /* mask in R_IRQ_ for ecp_cmd int */
+	unsigned long irq_mask_peri;  /* bitmask in R_IRQ_ for peri int */
+	int portnr;
+  
+	/* ----- end of fields initialised in port_table[] below ----- */
+
+	//  struct etrax_dma_descr tr_descr;
+	//  unsigned char tr_buf[LP_BUFFER_SIZE];
+	//  const unsigned char *tr_buf_curr; /* current char sent */
+	//  const unsigned char *tr_buf_last; /* last char in buf */
+  
+	//  int fifo_magic; /* fifo amount - bytes left in dma buffer */
+	//  unsigned char         fifo_didmagic; /* a fifo eop has been forced */
+	//  volatile int          tr_running; /* 1 if output is running */
+	
+	struct parport *port;
+  
+	/* Shadow registers */
+	volatile unsigned long reg_ctrl_data_shadow; /* for R_PARx_CTRL_DATA */
+	volatile unsigned long reg_config_shadow;    /* for R_PARx_CONFIG */
+	volatile unsigned long reg_delay_shadow;    /* for R_PARx_DELAY */
+};
+
+/* Always have the complete structs here, even if the port is not used!
+ *  (that way we can index this by the port number)
+ */
+static struct etrax100par_struct port_table[] = {
+	{ 
+		R_PAR0_CTRL_DATA,
+		R_PAR0_STATUS_DATA,
+		R_PAR0_CONFIG,
+		R_PAR0_DELAY,
+		/* DMA interrupt stuff */
+		2,
+		1U << 4, /* uses DMA 2 and 3 */
+		R_DMA_CH2_CLR_INTR,
+		R_DMA_CH2_FIRST,
+		R_DMA_CH2_CMD,
+		R_DMA_CH3_CLR_INTR,
+		R_DMA_CH3_FIRST,
+		R_DMA_CH3_CMD,
+		R_DMA_CH3_STATUS,
+		R_DMA_CH3_HWSW,
+		/* Non DMA interrupt stuff */
+		IO_BITNR(R_VECT_MASK_RD, par0),
+		R_IRQ_MASK0_RD,
+		R_IRQ_MASK0_CLR,
+		R_IRQ_READ0,
+		R_IRQ_MASK0_SET,
+		IO_FIELD(R_IRQ_MASK0_RD, par0_ready, 1U), /* tx (ready)*/
+		IO_FIELD(R_IRQ_MASK0_RD, par0_data, 1U), /* rx (data)*/
+		IO_FIELD(R_IRQ_MASK0_RD, par0_ecp_cmd, 1U), /* ecp_cmd */
+		IO_FIELD(R_IRQ_MASK0_RD, par0_peri, 1U), /* peri */
+		0
+	},
+	{
+		R_PAR1_CTRL_DATA,
+		R_PAR1_STATUS_DATA,
+		R_PAR1_CONFIG,
+		R_PAR1_DELAY,
+		/* DMA interrupt stuff */
+		4,
+		1U << 8, /* uses DMA 4 and 5 */
+		
+		R_DMA_CH4_CLR_INTR,
+		R_DMA_CH4_FIRST,
+		R_DMA_CH4_CMD,
+		R_DMA_CH5_CLR_INTR,
+		R_DMA_CH5_FIRST,
+		R_DMA_CH5_CMD,
+		R_DMA_CH5_STATUS,
+		R_DMA_CH5_HWSW,
+		/* Non DMA interrupt stuff */
+		IO_BITNR(R_VECT_MASK_RD, par1),
+		R_IRQ_MASK1_RD,
+		R_IRQ_MASK1_CLR,
+		R_IRQ_READ1,
+		R_IRQ_MASK1_SET,
+		IO_FIELD(R_IRQ_MASK1_RD, par1_ready, 1U), /* tx (ready)*/
+		IO_FIELD(R_IRQ_MASK1_RD, par1_data, 1U), /* rx (data)*/
+		IO_FIELD(R_IRQ_MASK1_RD, par1_ecp_cmd, 1U), /* ecp_cmd */
+		IO_FIELD(R_IRQ_MASK1_RD, par1_peri, 1U), /* peri */
+		1
+	}
+};
+
+
+#define NR_PORTS (sizeof(port_table)/sizeof(struct etrax100par_struct))
+
+static void
+parport_etrax_write_data(struct parport *p, unsigned char value)
+{
+	struct etrax100par_struct *info =
+		(struct etrax100par_struct *)p->private_data;
+
+	DPRINTK("* E100 PP %d: etrax_write_data %02X\n", p->portnum, value);
+	SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, data, value);
+	*info->reg_ctrl_data = info->reg_ctrl_data_shadow;
+}
+
+
+static unsigned char
+parport_etrax_read_data(struct parport *p)
+{
+	unsigned char ret;
+	struct etrax100par_struct *info =
+		(struct etrax100par_struct *)p->private_data;
+
+	ret = IO_EXTRACT(R_PAR0_STATUS_DATA, data, *info->reg_status_data);
+
+	DPRINTK("* E100 PP %d: etrax_read_data %02X\n", p->portnum, ret);
+	return ret;
+}
+
+
+static void
+parport_etrax_write_control(struct parport *p, unsigned char control)
+{
+	struct etrax100par_struct *info =
+		(struct etrax100par_struct *)p->private_data;
+
+	DPRINTK("* E100 PP %d: etrax_write_control %02x\n", p->portnum, control);
+  
+	SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, strb,
+	     (control & PARPORT_CONTROL_STROBE) > 0);
+	SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, autofd,
+	     (control & PARPORT_CONTROL_AUTOFD) > 0);
+	SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, init,
+	     (control & PARPORT_CONTROL_INIT) > 0);
+	SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, seli,
+	     (control & PARPORT_CONTROL_SELECT) > 0);
+
+	*info->reg_ctrl_data = info->reg_ctrl_data_shadow;
+}
+
+
+static unsigned char
+parport_etrax_read_control( struct parport *p)
+{
+	unsigned char ret = 0;
+	struct etrax100par_struct *info =
+		(struct etrax100par_struct *)p->private_data;
+
+	if (IO_EXTRACT(R_PAR0_CTRL_DATA, strb, info->reg_ctrl_data_shadow))
+		ret |= PARPORT_CONTROL_STROBE;
+	if (IO_EXTRACT(R_PAR0_CTRL_DATA, autofd, info->reg_ctrl_data_shadow))
+		ret |= PARPORT_CONTROL_AUTOFD;
+	if (IO_EXTRACT(R_PAR0_CTRL_DATA, init, info->reg_ctrl_data_shadow))
+		ret |= PARPORT_CONTROL_INIT;
+	if (IO_EXTRACT(R_PAR0_CTRL_DATA, seli, info->reg_ctrl_data_shadow))
+		ret |= PARPORT_CONTROL_SELECT;
+
+	DPRINTK("* E100 PP %d: etrax_read_control %02x\n", p->portnum, ret);
+	return ret;
+}
+
+
+static unsigned char
+parport_etrax_frob_control(struct parport *p, unsigned char mask,
+                           unsigned char val)
+{
+	unsigned char old;
+
+	DPRINTK("* E100 PP %d: frob_control mask %02x, value %02x\n",
+		p->portnum, mask, val);
+	old = parport_etrax_read_control(p);
+	parport_etrax_write_control(p, (old & ~mask) ^ val);
+	return old;
+}
+
+
+static unsigned char
+parport_etrax_read_status(struct parport *p)
+{
+	unsigned char ret = 0;
+	struct etrax100par_struct *info =
+		(struct etrax100par_struct *)p->private_data;
+
+	if (IO_EXTRACT(R_PAR0_STATUS_DATA, fault, *info->reg_status_data))
+		ret |= PARPORT_STATUS_ERROR;
+	if (IO_EXTRACT(R_PAR0_STATUS_DATA, sel, *info->reg_status_data))
+		ret |= PARPORT_STATUS_SELECT;
+	if (!IO_EXTRACT(R_PAR0_STATUS_DATA, perr, *info->reg_status_data))
+		ret |= PARPORT_STATUS_PAPEROUT;
+	if (IO_EXTRACT(R_PAR0_STATUS_DATA, ack, *info->reg_status_data))
+		ret |= PARPORT_STATUS_ACK;
+	if (!IO_EXTRACT(R_PAR0_STATUS_DATA, busy, *info->reg_status_data))
+		ret |= PARPORT_STATUS_BUSY;
+
+	DPRINTK("* E100 PP %d: status register %04x\n",
+		p->portnum, *info->reg_status_data);
+	DPRINTK("* E100 PP %d: read_status %02x\n", p->portnum, ret);
+	return ret;
+}
+
+
+static void
+parport_etrax_enable_irq(struct parport *p)
+{
+	struct etrax100par_struct *info =
+		(struct etrax100par_struct *)p->private_data;
+	*info->irq_mask_set = info->irq_mask_tx;
+	DPRINTK("* E100 PP %d: enable irq\n", p->portnum);
+}
+
+
+static void
+parport_etrax_disable_irq(struct parport *p)
+{
+	struct etrax100par_struct *info =
+		(struct etrax100par_struct *)p->private_data;
+	*info->irq_mask_clr = info->irq_mask_tx;
+	DPRINTK("* E100 PP %d: disable irq\n", p->portnum);
+}
+
+
+static void
+parport_etrax_data_forward(struct parport *p)
+{
+	struct etrax100par_struct *info =
+		(struct etrax100par_struct *)p->private_data;
+
+	DPRINTK("* E100 PP %d: forward mode\n", p->portnum);
+	SETS(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, oe, enable);
+	*info->reg_ctrl_data = info->reg_ctrl_data_shadow;
+}
+
+
+static void
+parport_etrax_data_reverse(struct parport *p)
+{
+	struct etrax100par_struct *info =
+		(struct etrax100par_struct *)p->private_data;
+
+	DPRINTK("* E100 PP %d: reverse mode\n", p->portnum);
+	SETS(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, oe, disable);
+	*info->reg_ctrl_data = info->reg_ctrl_data_shadow;
+}
+
+
+static void
+parport_etrax_init_state(struct pardevice *dev, struct parport_state *s)
+{
+	DPRINTK("* E100 PP: parport_etrax_init_state\n");
+}
+
+
+static void
+parport_etrax_save_state(struct parport *p, struct parport_state *s)
+{
+	DPRINTK("* E100 PP: parport_etrax_save_state\n");
+}
+
+
+static void
+parport_etrax_restore_state(struct parport *p, struct parport_state *s)
+{
+	DPRINTK("* E100 PP: parport_etrax_restore_state\n");
+}
+
+
+static void
+parport_etrax_inc_use_count(void)
+{
+	MOD_INC_USE_COUNT;
+}
+
+
+static void
+parport_etrax_dec_use_count(void)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+
+static struct
+parport_operations pp_etrax_ops = {
+	parport_etrax_write_data,
+	parport_etrax_read_data,
+
+	parport_etrax_write_control,
+	parport_etrax_read_control,
+	parport_etrax_frob_control,
+
+	parport_etrax_read_status,
+
+	parport_etrax_enable_irq,
+	parport_etrax_disable_irq,
+
+	parport_etrax_data_forward, 
+	parport_etrax_data_reverse, 
+
+	parport_etrax_init_state,
+	parport_etrax_save_state,
+	parport_etrax_restore_state,
+
+	parport_etrax_inc_use_count,
+	parport_etrax_dec_use_count,
+
+	parport_ieee1284_epp_write_data,
+	parport_ieee1284_epp_read_data,
+	parport_ieee1284_epp_write_addr,
+	parport_ieee1284_epp_read_addr,
+
+	parport_ieee1284_ecp_write_data,
+	parport_ieee1284_ecp_read_data,
+	parport_ieee1284_ecp_write_addr,
+
+	parport_ieee1284_write_compat,
+	parport_ieee1284_read_nibble,
+	parport_ieee1284_read_byte,
+};
+
+	
+static void 
+parport_etrax_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct etrax100par_struct *info = (struct etrax100par_struct *)
+		((struct parport *)dev_id)->private_data;
+	DPRINTK("* E100 PP %d: Interrupt received\n",
+		((struct parport *)dev_id)->portnum);
+	*info->irq_mask_clr = info->irq_mask_tx;
+	parport_generic_irq(irq, (struct parport *)dev_id, regs);
+}
+
+/* ----------- Initialisation code --------------------------------- */
+
+static void 
+parport_etrax_show_parallel_version(void)
+{
+	printk("ETRAX 100LX parallel port driver v1.0, (c) 2001 Axis Communications AB\n");
+}
+
+#ifdef CONFIG_ETRAX_PAR0_DMA
+#define PAR0_USE_DMA 1
+#else
+#define PAR0_USE_DMA 0
+#endif
+
+#ifdef CONFIG_ETRAX_PAR1_DMA
+#define PAR1_USE_DMA 1
+#else
+#define PAR1_USE_DMA 0
+#endif
+
+static void 
+parport_etrax_init_registers(void)
+{
+	struct etrax100par_struct *info;
+	int i;
+
+	/* The different times below will be (value*160 + 20) ns,    */
+	/* i.e. 20ns-4.98us. E.g. if setup is set to 00110 (0x6),    */
+	/* the setup time will be (6*160+20) = 980ns.                */
+
+	for (i = 0, info = port_table; i < 2; i++, info++) {
+#ifndef CONFIG_ETRAX_PARALLEL_PORT0
+		if (i == 0)
+			continue;
+#endif
+#ifndef CONFIG_ETRAX_PARALLEL_PORT1
+		if (i == 1)
+			continue;
+#endif
+		info->reg_config_shadow = 
+			IO_STATE(R_PAR0_CONFIG, iseli, inv)       |
+			IO_STATE(R_PAR0_CONFIG, iautofd, inv)     |
+			IO_STATE(R_PAR0_CONFIG, istrb, inv)       |
+			IO_STATE(R_PAR0_CONFIG, iinit, inv)       |
+			IO_STATE(R_PAR0_CONFIG, rle_in, disable)  |
+			IO_STATE(R_PAR0_CONFIG, rle_out, disable) |
+			IO_STATE(R_PAR0_CONFIG, enable, on)       |
+			IO_STATE(R_PAR0_CONFIG, force, off)       |
+			IO_STATE(R_PAR0_CONFIG, ign_ack, wait)    |
+			IO_STATE(R_PAR0_CONFIG, oe_ack, wait_oe)  |
+			IO_STATE(R_PAR0_CONFIG, mode, manual);
+
+		if ((i == 0 && PAR0_USE_DMA) || (i == 1 && PAR1_USE_DMA))
+			info->reg_config_shadow |=
+				IO_STATE(R_PAR0_CONFIG, dma, enable);
+		else
+			info->reg_config_shadow |=
+				IO_STATE(R_PAR0_CONFIG, dma, disable);
+
+		*info->reg_config = info->reg_config_shadow;
+
+		info->reg_ctrl_data_shadow = 
+			IO_STATE(R_PAR0_CTRL_DATA, peri_int, nop)    |
+			IO_STATE(R_PAR0_CTRL_DATA, oe, enable)       |
+			IO_STATE(R_PAR0_CTRL_DATA, seli, inactive)   |
+			IO_STATE(R_PAR0_CTRL_DATA, autofd, inactive) |
+			IO_STATE(R_PAR0_CTRL_DATA, strb, inactive)   |
+			IO_STATE(R_PAR0_CTRL_DATA, init, inactive)   |
+			IO_STATE(R_PAR0_CTRL_DATA, ecp_cmd, data)    |
+			IO_FIELD(R_PAR0_CTRL_DATA, data, 0);
+		*info->reg_ctrl_data = info->reg_ctrl_data_shadow;
+
+		/* Clear peri int without setting shadow */
+		*info->reg_ctrl_data = info->reg_ctrl_data_shadow |
+			IO_STATE(R_PAR0_CTRL_DATA, peri_int, ack);
+
+		info->reg_delay_shadow = 
+			IO_FIELD(R_PAR0_DELAY, setup, 5)  |
+			IO_FIELD(R_PAR0_DELAY, strobe, 5) |
+			IO_FIELD(R_PAR0_DELAY, hold, 5);
+		*info->reg_delay = info->reg_delay_shadow;
+	}
+
+#ifdef CONFIG_ETRAX_PARALLEL_PORT0
+#ifdef CONFIG_ETRAX_PAR0_DMA
+	RESET_DMA(2);
+	WAIT_DMA(2);
+#ifdef CONFIG_ETRAX_SERIAL_PORT2
+	printk(" Warning - DMA clash with ser2!\n");
+#endif /* SERIAL_PORT2 */
+#endif /* DMA */
+#endif /* PORT0 */
+
+#ifdef CONFIG_ETRAX_PARALLEL_PORT1
+#ifdef CONFIG_ETRAX_PAR1_DMA
+	RESET_DMA(4);
+	WAIT_DMA(4);
+#ifdef CONFIG_ETRAX_SERIAL_PORT3
+	printk(" Warning - DMA clash with ser3!\n");
+#endif /* SERIAL_PORT3 */
+#endif /* DMA */
+#endif /* PORT1 */
+} 
+
+
+int __init
+parport_etrax_init(void)
+{
+	struct parport *p;
+	int port_exists = 0;
+	int i;
+	struct etrax100par_struct *info;
+        const char *names[] = { "parallel 0 tx+rx", "parallel 1 tx+rx" };
+
+	parport_etrax_show_parallel_version();
+	parport_etrax_init_registers();
+
+        for (i = 0, info = port_table; i < NR_PORTS; i++, info++) {
+#ifndef CONFIG_ETRAX_PARALLEL_PORT0
+		if (i == 0)
+			continue;
+#endif
+#ifndef CONFIG_ETRAX_PARALLEL_PORT1
+		if (i == 1)
+			continue;
+#endif
+                p = parport_register_port((unsigned long)0, info->int_irq,
+                                          PARPORT_DMA_NONE, &pp_etrax_ops);
+                if (!p)
+			continue;
+
+                info->port = p;
+                p->private_data = info;
+                /* Axis FIXME: Set mode flags. */
+                /* p->modes = PARPORT_MODE_TRISTATE | PARPORT_MODE_SAFEININT; */
+
+	        if(request_irq(info->int_irq, parport_etrax_interrupt,
+                               SA_SHIRQ, names[i], p)) {
+	        	parport_unregister_port (p);
+                        continue;
+                }
+
+                printk(KERN_INFO "%s: ETRAX 100LX port %d using irq\n",
+                       p->name, i);
+                parport_proc_register(p);
+                parport_announce_port(p);
+                port_exists = 1;
+        }
+
+	return port_exists;
+}
+
+void __exit
+parport_etrax_exit(void)
+{
+	int i;
+	struct etrax100par_struct *info;
+
+        for (i = 0, info = port_table; i < NR_PORTS; i++, info++) {
+#ifndef CONFIG_ETRAX_PARALLEL_PORT0
+		if (i == 0)
+			continue;
+#endif
+#ifndef CONFIG_ETRAX_PARALLEL_PORT1
+		if (i == 1)
+			continue;
+#endif
+		if (info->int_irq != PARPORT_IRQ_NONE)
+			free_irq(info->int_irq, info->port);
+		parport_proc_unregister(info->port);
+		parport_unregister_port(info->port);
+        }
+}
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/serial.c linux/arch/cris/drivers/serial.c
--- v2.4.4/linux/arch/cris/drivers/serial.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/drivers/serial.c	Tue May  1 16:04:56 2001
@@ -1,4 +1,4 @@
-/* $Id: serial.c,v 1.10 2001/03/05 13:14:07 bjornw Exp $
+/* $Id: serial.c,v 1.12 2001/04/19 12:23:07 bjornw Exp $
  *
  * Serial port driver for the ETRAX 100LX chip
  *
@@ -7,6 +7,15 @@
  *      Many, many authors. Based once upon a time on serial.c for 16x50.
  *
  * $Log: serial.c,v $
+ * Revision 1.12  2001/04/19 12:23:07  bjornw
+ * CONFIG_RS485 -> CONFIG_ETRAX_RS485
+ *
+ * Revision 1.11  2001/04/05 14:29:48  markusl
+ * Updated according to review remarks i.e.
+ * -Use correct types in port structure to avoid compiler warnings
+ * -Try to use IO_* macros whenever possible
+ * -Open should never return -EBUSY
+ *
  * Revision 1.10  2001/03/05 13:14:07  bjornw
  * Another spelling fix
  *
@@ -190,7 +199,7 @@
  *
  */
 
-static char *serial_version = "$Revision: 1.10 $";
+static char *serial_version = "$Revision: 1.12 $";
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -299,6 +308,18 @@
 #define REG_BAUD 3
 #define REG_XOFF 4  /* this is a 32 bit register */
 
+/*
+ * General note regarding the use of IO_* macros in this file: 
+ *
+ * We will use the bits defined for DMA channel 6 when using various
+ * IO_* macros (e.g. IO_STATE, IO_MASK, IO_EXTRACT) and _assume_ they are
+ * the same for all channels (which of course they are).
+ *
+ * We will also use the bits defined for serial port 0 when writing commands
+ * to the different ports, as these bits too are the same for all ports.
+ */
+
+
 /* this is the data for the four serial ports in the etrax100 */
 /*  DMA2(ser2), DMA4(ser3), DMA6(ser0) or DMA8(ser1) */
 /* R_DMA_CHx_CLR_INTR, R_DMA_CHx_FIRST, R_DMA_CHx_CMD */
@@ -343,9 +364,9 @@
 
 
 /* RS-485 */
-#if defined(CONFIG_RS485)
-#if defined(CONFIG_RS485_ON_PA)
-static int rs485_pa_bit = CONFIG_RS485_ON_PA_BIT;
+#if defined(CONFIG_ETRAX_RS485)
+#if defined(CONFIG_ETRAX_RS485_ON_PA)
+static int rs485_pa_bit = CONFIG_ETRAX_RS485_ON_PA_BIT;
 #endif
 #endif
   
@@ -421,8 +442,8 @@
   }
 };
 
-#if defined(CONFIG_RS485) && defined(CONFIG_RS485_ON_PA)
-unsigned char rs485_pa_port = CONFIG_RS485_ON_PA_BIT;
+#if defined(CONFIG_ETRAX_RS485) && defined(CONFIG_ETRAX_RS485_ON_PA)
+unsigned char rs485_pa_port = CONFIG_ETRAX_RS485_ON_PA_BIT;
 #endif
 
 #define E100_RTS_MASK 0x20
@@ -668,7 +689,8 @@
 {
 #ifndef CONFIG_SVINTO_SIM
 	/* disable the receiver */
-	info->port[REG_REC_CTRL] = (info->rx_ctrl &= ~0x40);
+	info->port[REG_REC_CTRL] = info->rx_ctrl &=
+		~IO_MASK(R_SERIAL0_REC_CTRL, rec_enable);
 #endif
 }
 
@@ -677,7 +699,8 @@
 {
 #ifndef CONFIG_SVINTO_SIM
 	/* enable the receiver */
-	info->port[REG_REC_CTRL] = (info->rx_ctrl |= 0x40);
+	info->port[REG_REC_CTRL] = info->rx_ctrl |=
+		IO_MASK(R_SERIAL0_REC_CTRL, rec_enable);
 #endif
 }
 
@@ -747,14 +770,14 @@
 }
 #endif
 
-#if defined(CONFIG_RS485)
+#if defined(CONFIG_ETRAX_RS485)
 /* Enable RS-485 mode on selected port. This is UGLY. */
 static int
 e100_enable_rs485(struct tty_struct *tty,struct rs485_control *r)
 {
 	struct e100_serial * info = (struct e100_serial *)tty->driver_data;
 
-#if defined(CONFIG_RS485_ON_PA)	
+#if defined(CONFIG_ETRAX_RS485_ON_PA)	
 	*R_PORT_PA_DATA = port_pa_data_shadow |= (1 << rs485_pa_bit);
 #endif
 
@@ -766,7 +789,6 @@
 	return 0;
 }
 
-/* Enable RS-485 mode on selected port. This is UGLY. */
 static int
 e100_write_rs485(struct tty_struct *tty,struct rs485_write *r)
 {
@@ -782,7 +804,7 @@
 	 * the receiver before initiating a DMA transfer
 	 */
 	e100_rts(info, info->rs485.rts_on_send);
-#if defined(CONFIG_RS485_DISABLE_RECEIVER)
+#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
 	e100_disable_rx(info);
 	e100_disable_rxdma_irq(info);
 #endif
@@ -824,14 +846,16 @@
 	max_j = jiffies + (delay_ms * HZ)/1000 + 10;
 
 	while (jiffies < max_j ) {
-	  if (info->port[REG_STATUS] & 0x20) {
+	  if (info->port[REG_STATUS] &
+	      IO_STATE(R_SERIAL0_STATUS, tr_ready, ready)) {
 	    for( i=0 ; i<100; i++ ) {};
-	    if (info->port[REG_STATUS] & 0x20) {
+	    if (info->port[REG_STATUS] &
+		IO_STATE(R_SERIAL0_STATUS, tr_ready, ready)) {
 	      /* ~25 for loops per usec */
-	      stop_delay = 25 * (1000000 / info->baud);
+	      stop_delay = 1000000 / info->baud;
 	      if(cflags & CSTOPB) 
 		stop_delay *= 2;
-	      for( i=0 ; i<stop_delay; i++ ) {};
+	      udelay(stop_delay);
 	      break;
 	    }
 	  }
@@ -839,7 +863,7 @@
 
 	e100_rts(info, info->rs485.rts_after_sent);
 	
-#if defined(CONFIG_RS485_DISABLE_RECEIVER)
+#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
 	e100_enable_rx(info);
 	e100_enable_rxdma_irq(info);
 #endif
@@ -942,7 +966,9 @@
 	return;
 #endif
 	/* acknowledge both a dma_descr and dma_eop irq in R_DMAx_CLRINTR */
-	*info->oclrintradr = 3;
+	*info->oclrintradr =
+		IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
+		IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
 
 #ifdef SERIAL_DEBUG_INTR
 	if(info->line == SERIAL_DEBUG_LINE)
@@ -987,19 +1013,20 @@
 		/* our job here is done, don't schedule any new DMA transfer */
 		info->tr_running = 0;
 
-#if defined(CONFIG_RS485)
+#if defined(CONFIG_ETRAX_RS485)
 		/* Check if we should toggle RTS now */
 		if (info->rs485.enabled)
 		{
 			/* Make sure fifo is empty */
 			int in_fifo = 0 ;
 			do{
-				in_fifo = (*info->ostatusadr) & 0x007F ;
+				in_fifo = IO_EXTRACT(R_DMA_CH6_STATUS, avail,
+						    *info->ostatusadr);
 			}  while (in_fifo > 0) ;
 			/* Any way to really check transmitter empty? (TEMT) */
 			/* Control RTS to set to RX mode */
 			e100_rts(info, info->rs485.rts_after_sent); 
-#if defined(CONFIG_RS485_DISABLE_RECEIVER)
+#if defined(CONFIG_ETRAX_RS485_DISABLE_RECEIVER)
 			e100_enable_rx(info);
 			e100_enable_rxdma_irq(info);
 #endif
@@ -1060,7 +1087,9 @@
 
 	/* acknowledge both a dma_descr and dma_eop irq in R_DMAx_CLRINTR */
 
-	*info->iclrintradr = 3;
+	*info->iclrintradr =
+		IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
+		IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
 
 	if(!tty) /* something wrong... */
 		return;
@@ -1088,7 +1117,9 @@
 		/* read the status register so we can detect errors */
 		rstat = info->port[REG_STATUS];
 
-		if(rstat & 0xe) {
+		if(rstat & (IO_MASK(R_SERIAL0_STATUS, overrun) |
+			    IO_MASK(R_SERIAL0_STATUS, par_err) |
+			    IO_MASK(R_SERIAL0_STATUS, framing_err))) {
 			/* if we got an error, we must reset it by reading the
 			 * data_in field
 			 */
@@ -1148,7 +1179,7 @@
 	descr->status = 0;
 
 	*info->ifirstadr = virt_to_phys(descr);
-	*info->icmdadr = 1; /* start */
+	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, start);
 
 #ifdef SERIAL_HANDLE_EARLY_ERRORS
 	e100_enable_serial_data_irq(info);
@@ -1170,8 +1201,9 @@
 
 	/* reset the input dma channel to be sure it works */
 	
-	*info->icmdadr = 4;
-	while((*info->icmdadr & 7) == 4);
+	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
+	while(IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) ==
+	      IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
 
 	descr = &info->rec_descr;
 	
@@ -1186,7 +1218,8 @@
 	info->tty->flip.count = 0;
 
 	*info->ifirstadr = virt_to_phys(descr);
-	*info->icmdadr = 1; /* start */
+	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, start);
+	
 }
 
 
@@ -1293,7 +1326,7 @@
 static struct timer_list flush_timer;
 
 static void 
-timed_flush_handler(void)
+timed_flush_handler(unsigned long ptr)
 {
 	struct e100_serial *info;
 	int i;
@@ -1381,7 +1414,7 @@
 				PROCSTAT(early_errors_cnt[info->line]++);
 
 				/* restart the DMA */
-				*info->icmdadr = 3;
+				*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, restart);
 			} 
 			else { /* it was a valid byte, now let the dma do the rest */
 #ifdef SERIAL_DEBUG_INTR
@@ -1472,7 +1505,7 @@
 	if (info->flags & ASYNC_INITIALIZED) {
 		free_page(page);
 		restore_flags(flags);
-		return -EBUSY;
+		return 0;
 	}
 	
 	if (info->xmit.buf)
@@ -1518,14 +1551,22 @@
 	 * Reset the DMA channels and make sure their interrupts are cleared
 	 */
 	
-	*info->icmdadr = 4; /* reset command */
-	*info->ocmdadr = 4; /* reset command */
-	
-	while((*info->icmdadr & 7) == 4); /* wait until reset cycle is complete */
-	while((*info->ocmdadr & 7) == 4);
-	
-	*info->iclrintradr = 3; /* make sure the irqs are cleared */
-	*info->oclrintradr = 3;
+	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
+	*info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
+
+	/* wait until reset cycle is complete */
+	while(IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->icmdadr) ==
+	      IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
+
+	while(IO_EXTRACT(R_DMA_CH6_CMD, cmd, *info->ocmdadr) ==
+	      IO_STATE_VALUE(R_DMA_CH6_CMD, cmd, reset));
+	
+	*info->iclrintradr =
+		IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
+		IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
+	*info->oclrintradr =
+		IO_STATE(R_DMA_CH6_CLR_INTR, clr_descr, do) |
+		IO_STATE(R_DMA_CH6_CLR_INTR, clr_eop, do);
 	
 	if (info->tty)
 		clear_bit(TTY_IO_ERROR, &info->tty->flags);
@@ -1597,8 +1638,8 @@
 
 	/* reset both dma channels */
 
-	*info->icmdadr = 4;
-	*info->ocmdadr = 4;
+	*info->icmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
+	*info->ocmdadr = IO_STATE(R_DMA_CH6_CMD, cmd, reset);
 
 #endif /* CONFIG_SVINTO_SIM */
 
@@ -1658,42 +1699,51 @@
 #ifndef CONFIG_SVINTO_SIM
 	info->port[REG_BAUD] = cflag_to_etrax_baud(cflag);
 	/* start with default settings and then fill in changes */
-	
-	info->rx_ctrl &= ~(0x07); /* 8 bit, no/even parity */
-	info->tx_ctrl &= ~(0x37); /* 8 bit, no/even parity, 1 stop bit, no cts */
+
+	/* 8 bit, no/even parity */
+	info->rx_ctrl &= ~(IO_MASK(R_SERIAL0_REC_CTRL, rec_bitnr) |
+			   IO_MASK(R_SERIAL0_REC_CTRL, rec_par_en) |
+			   IO_MASK(R_SERIAL0_REC_CTRL, rec_par));
+
+	/* 8 bit, no/even parity, 1 stop bit, no cts */
+	info->tx_ctrl &= ~(IO_MASK(R_SERIAL0_TR_CTRL, tr_bitnr) |
+			   IO_MASK(R_SERIAL0_TR_CTRL, tr_par_en) |
+			   IO_MASK(R_SERIAL0_TR_CTRL, tr_par) |
+			   IO_MASK(R_SERIAL0_TR_CTRL, stop_bits) |
+			   IO_MASK(R_SERIAL0_TR_CTRL, auto_cts));
 	
 	if ((cflag & CSIZE) == CS7) {
 		/* set 7 bit mode */
-		info->tx_ctrl |= 0x01;
-		info->rx_ctrl |= 0x01;
+		info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_bitnr, tr_7bit);
+		info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_bitnr, rec_7bit);
 	}
 	
 	if (cflag & CSTOPB) {
 		/* set 2 stop bit mode */
-		info->tx_ctrl |= 0x10;
+		info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, stop_bits, two_bits);
 	}	  
 	
 	if (cflag & PARENB) {
 		/* enable parity */
-		info->tx_ctrl |= 0x02;
-		info->rx_ctrl |= 0x02;
+		info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par_en, enable);
+		info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par_en, enable);
 	}
 	
 	if (cflag & PARODD) {
 		/* set odd parity */
-		info->tx_ctrl |= 0x04;
-		info->rx_ctrl |= 0x04;
+		info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_par, odd);
+		info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_par, odd);
 	}
 	
 	if (cflag & CRTSCTS) {
 		/* enable automatic CTS handling */
-		info->tx_ctrl |= 0x20;
+		info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, auto_cts, active);
 	}
 	
 	/* make sure the tx and rx are enabled */
 	
-	info->tx_ctrl |= 0x40;
-	info->rx_ctrl |= 0x40;
+	info->tx_ctrl |= IO_STATE(R_SERIAL0_TR_CTRL, tr_enable, enable);
+	info->rx_ctrl |= IO_STATE(R_SERIAL0_REC_CTRL, rec_enable, enable);
 
 	/* actually write the control regs to the hardware */
 	
@@ -2330,7 +2380,7 @@
 				return -EFAULT;
 			return 0;
 
-#if defined(CONFIG_RS485)
+#if defined(CONFIG_ETRAX_RS485)
 		case TIOCSERSETRS485:
 			error = verify_area(VERIFY_WRITE, (void *) arg,
 					sizeof(struct rs485_control));
@@ -2488,10 +2538,10 @@
 
 	/* port closed */
 
-#if defined(CONFIG_RS485)
+#if defined(CONFIG_ETRAX_RS485)
 	if (info->rs485.enabled) {
 		info->rs485.enabled = 0;
-#if defined(CONFIG_RS485_ON_PA)
+#if defined(CONFIG_ETRAX_RS485_ON_PA)
 		*R_PORT_PA_DATA = port_pa_data_shadow &= ~(1 << rs485_pa_bit);
 #endif
 	}
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/serial.h linux/arch/cris/drivers/serial.h
--- v2.4.4/linux/arch/cris/drivers/serial.h	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/drivers/serial.h	Tue May  1 16:04:56 2001
@@ -25,26 +25,26 @@
 
 struct e100_serial {
 	int                   baud;
-	volatile unsigned char *	port; /* R_SERIALx_CTRL */
-	unsigned long	        irq;  /* bitnr in R_IRQ_MASK2 for dmaX_descr */
+	volatile u8 *port;             /* R_SERIALx_CTRL */
+	u32 irq;                       /* bitnr in R_IRQ_MASK2 for dmaX_descr */
 
-	volatile char *oclrintradr; /* adr to R_DMA_CHx_CLR_INTR, output */
-	volatile unsigned long *ofirstadr;   /* adr to R_DMA_CHx_FIRST, output */
-	volatile char *ocmdadr;     /* adr to R_DMA_CHx_CMD, output */
-	const volatile unsigned short *ostatusadr;  /* adr to R_DMA_CHx_STATUS, output */
-	volatile unsigned long  *ohwswadr;    /* adr to R_DMA_CHx_HWSW, output */
+	volatile u8 *oclrintradr;      /* adr to R_DMA_CHx_CLR_INTR, output */
+	volatile u32 *ofirstadr;       /* adr to R_DMA_CHx_FIRST, output */
+	volatile u8 *ocmdadr;          /* adr to R_DMA_CHx_CMD, output */
+	const volatile u8 *ostatusadr; /* adr to R_DMA_CHx_STATUS, output */
+	volatile u32 *ohwswadr;        /* adr to R_DMA_CHx_HWSW, output */
 
-	volatile char *iclrintradr; /* adr to R_DMA_CHx_CLR_INTR, input */
-	volatile unsigned long *ifirstadr;   /* adr to R_DMA_CHx_FIRST, input */
-	volatile char *icmdadr;     /* adr to R_DMA_CHx_CMD, input */
-	const volatile unsigned short *istatusadr;  /* adr to R_DMA_CHx_STATUS, input */
-	volatile unsigned long  *ihwswadr;    /* adr to R_DMA_CHx_HWSW, input */
+	volatile u8 *iclrintradr;      /* adr to R_DMA_CHx_CLR_INTR, input */
+	volatile u32 *ifirstadr;       /* adr to R_DMA_CHx_FIRST, input */
+	volatile u8 *icmdadr;          /* adr to R_DMA_CHx_CMD, input */
+	const volatile u8 *istatusadr; /* adr to R_DMA_CHx_STATUS, input */
+	volatile u32 *ihwswadr;        /* adr to R_DMA_CHx_HWSW, input */
 
 	int			flags; 		/* defined in tty.h */
 
-	unsigned char           rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */
-	unsigned char           tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */
-	unsigned char           iseteop; /* bit number for R_SET_EOP for the input dma */
+	u8           rx_ctrl; /* shadow for R_SERIALx_REC_CTRL */
+	u8           tx_ctrl; /* shadow for R_SERIALx_TR_CTRL */
+	u8           iseteop; /* bit number for R_SET_EOP for the input dma */
 /* end of fields defined in rs_table[] in .c-file */
 	unsigned char           fifo_didmagic; /* a fifo eop has been forced */
 
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/sync_serial.c linux/arch/cris/drivers/sync_serial.c
--- v2.4.4/linux/arch/cris/drivers/sync_serial.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/drivers/sync_serial.c	Tue May  1 16:04:56 2001
@@ -2,8 +2,9 @@
  * Simple synchronous serial port driver for ETRAX 100LX.
  *
  * Synchronous serial ports are used for continous streamed data like audio.
- * The deault setting for this driver is compatible with the STA 013 MP3 decoder
- * The driver can easily be tuned to fit other audio encoder/decoders and SPI
+ * The default setting for this driver is compatible with the STA 013 MP3
+ * decoder. The driver can easily be tuned to fit other audio encoder/decoders
+ * and SPI
  *
  * Copyright (c) 2001 Axis Communications AB
  * 
@@ -29,37 +30,43 @@
 #include <asm/sync_serial.h>
 
 /* The receiver is a bit tricky beacuse of the continous stream of data. */
-/*									 */
-/* Two DMA descriptors are linked together. Each DMA descriptor is	 */
-/* responsible for one half of a common buffer.				 */
-/*									 */
-/* ------------------------------					 */
-/* |   ----------   ----------	|					 */
-/* --> | Descr1 |-->| Descr2 |---					 */
-/*     ----------   ----------						 */
-/*	 |	       |						 */
-/*	 v	       v						 */
-/*	 -----------------------------					 */
-/*	 |	      BUFFER	     |					 */
-/*	 -----------------------------					 */
-/*	 |		|						 */
-/*	readp	      writep						 */
-/*									 */
+/*                                                                       */
+/* Two DMA descriptors are linked together. Each DMA descriptor is       */
+/* responsible for one half of a common buffer.                          */
+/*                                                                       */
+/* ------------------------------                                        */
+/* |   ----------   ----------	|                                        */
+/* --> | Descr1 |-->| Descr2 |---                                        */
+/*     ----------   ----------                                           */
+/*         |            |                                                */
+/*         v            v                                                */
+/*   -----------------------------                                       */
+/*   |        BUFFER             |                                       */
+/*   -----------------------------                                       */
+/*      |             |                                                  */
+/*    readp          writep                                              */
+/*                                                                       */
 /* If the application keeps up the pace readp will be right after writep.*/
-/* If the application can't keep the pace we have to throw away data.	 */ 
+/* If the application can't keep the pace we have to throw away data.    */ 
 /* The idea is that readp should be ready with the data pointed out by	 */
 /* Descr1 when the DMA has filled in Descr2. Otherwise we will discard	 */
 /* the rest of the data pointed out by Descr1 and set readp to the start */
-/* of Descr2								 */
+/* of Descr2                                                             */
 
 #define SYNC_SERIAL_MAJOR 125
 
-#define IN_BUFFER_SIZE 8192
+/* IN_BUFFER_SIZE should be a multiple of 6 to make sure that 24 bit */
+/* words can be handled */
+
+#define IN_BUFFER_SIZE 12288
 #define OUT_BUFFER_SIZE 4096
 
+#define DEFAULT_FRAME_RATE 0
+#define DEFAULT_WORD_RATE 7
+
 #define DEBUG(x) 
 
-/* Define some macros to access Etrax 100 registers */
+/* Define some macros to access ETRAX 100 registers */
 #define SETF(var, reg, field, val) var = (var & ~IO_MASK(##reg##, field)) | \
 					  IO_FIELD(##reg##, field, val)
 #define SETS(var, reg, field, val) var = (var & ~IO_MASK(##reg##, field)) | \
@@ -81,10 +88,8 @@
 	char data_avail_bit; /* In R_IRQ_MASK1_RD */
 	char transmitter_ready_bit; /* In R_IRQ_MASK1_RD */
 	char ready_irq_bit; /* In R_IRQ_MASK1_SET and R_IRQ_MASK1_CLR */
-	char input_dma_eop_bit;   /* In R_IRQ_MASK2_RD */
 	char input_dma_descr_bit; /* In R_IRQ_MASK2_RD */
 	char output_dma_bit; /* In R_IRQ_MASK2_RD */
-	char eop_bit; /* In R_SET_EOP */
 
 	int enabled;  /* 1 if port is enabled */
 	int use_dma;  /* 1 if port uses dma */
@@ -125,7 +130,6 @@
 static void tr_interrupt(int irq, void *dev_id, struct pt_regs * regs);
 static void rx_interrupt(int irq, void *dev_id, struct pt_regs * regs);
 static void manual_interrupt(int irq, void *dev_id, struct pt_regs * regs);
-static void flush_handler(void);
 
 /* The ports */
 static struct sync_port ports[]=
@@ -133,40 +137,36 @@
 	{
 		R_SYNC_SERIAL1_STATUS,  /* status */
 		R_SYNC_SERIAL1_CTRL,    /* ctrl_data */
-		R_DMA_CH8_FIRST,	    /* output_dma_first */
-		R_DMA_CH8_CMD,	    /* output_dma_cmd */
-		R_DMA_CH8_CLR_INTR,	    /* output_dma_clr_irq */
-		R_DMA_CH9_FIRST,	    /* input_dma_first */
-		R_DMA_CH9_CMD,	    /* input_dma_cmd */
-		R_DMA_CH9_CLR_INTR,	    /* input_dma_clr_irq */
+		R_DMA_CH8_FIRST,        /* output_dma_first */
+		R_DMA_CH8_CMD,          /* output_dma_cmd */
+		R_DMA_CH8_CLR_INTR,     /* output_dma_clr_irq */
+		R_DMA_CH9_FIRST,        /* input_dma_first */
+		R_DMA_CH9_CMD,          /* input_dma_cmd */
+		R_DMA_CH9_CLR_INTR,     /* input_dma_clr_irq */
 		R_SYNC_SERIAL1_TR_DATA, /* data_out */
 		R_SYNC_SERIAL1_REC_DATA,/* data in */
 		IO_BITNR(R_IRQ_MASK1_RD, ser1_data),   /* data_avail_bit */
 		IO_BITNR(R_IRQ_MASK1_RD, ser1_ready),  /* transmitter_ready_bit */
 		IO_BITNR(R_IRQ_MASK1_SET, ser1_ready), /* ready_irq_bit */
-		IO_BITNR(R_IRQ_MASK2_RD, dma9_eop),	   /* input_dma_eop_bit */
 		IO_BITNR(R_IRQ_MASK2_RD, dma9_descr),  /* input_dma_descr_bit */
-		IO_BITNR(R_IRQ_MASK2_RD, dma8_eop),	   /* output_dma_bit */
-		IO_BITNR(R_SET_EOP, ch9_eop)	   /* eop_bit */
+		IO_BITNR(R_IRQ_MASK2_RD, dma8_eop),    /* output_dma_bit */
 	},
 	{
 		R_SYNC_SERIAL3_STATUS,  /* status */
 		R_SYNC_SERIAL3_CTRL,    /* ctrl_data */
-		R_DMA_CH4_FIRST,	    /* output_dma_first */
-		R_DMA_CH4_CMD,	    /* output_dma_cmd */
-		R_DMA_CH4_CLR_INTR,	    /* output_dma_clr_irq */
-		R_DMA_CH5_FIRST,	    /* input_dma_first */
-		R_DMA_CH5_CMD,	    /* input_dma_cmd */
-		R_DMA_CH5_CLR_INTR,	    /* input_dma_clr_irq */
+		R_DMA_CH4_FIRST,        /* output_dma_first */
+		R_DMA_CH4_CMD,          /* output_dma_cmd */
+		R_DMA_CH4_CLR_INTR,     /* output_dma_clr_irq */
+		R_DMA_CH5_FIRST,        /* input_dma_first */
+		R_DMA_CH5_CMD,          /* input_dma_cmd */
+		R_DMA_CH5_CLR_INTR,     /* input_dma_clr_irq */
 		R_SYNC_SERIAL3_TR_DATA, /* data_out */
 		R_SYNC_SERIAL3_REC_DATA,/* data in */
 		IO_BITNR(R_IRQ_MASK1_RD, ser3_data),   /* data_avail_bit */
 		IO_BITNR(R_IRQ_MASK1_RD, ser3_ready),  /* transmitter_ready_bit */
 		IO_BITNR(R_IRQ_MASK1_SET, ser3_ready), /* ready_irq_bit */
-		IO_BITNR(R_IRQ_MASK2_RD, dma5_eop),	   /* input_dma_eop_bit */
-		IO_BITNR(R_IRQ_MASK2_RD, dma5_descr),  /* input_dma_eop_bit */
-		IO_BITNR(R_IRQ_MASK2_RD, dma4_eop),	   /* output_dma_bit */
-		IO_BITNR(R_SET_EOP, ch5_eop)	   /* eop_bit */
+		IO_BITNR(R_IRQ_MASK2_RD, dma5_descr),  /* input_dma_descr_bit */
+		IO_BITNR(R_IRQ_MASK2_RD, dma4_eop),    /* output_dma_bit */
 	}
 };
 
@@ -174,9 +174,6 @@
 static unsigned sync_serial_prescale_shadow = 0;
 static unsigned gen_config_ii_shadow = 0;
 
-/* Timer used to flush data from the DMA */
-static struct timer_list flush_timer;
-
 #define NUMBER_OF_PORTS (sizeof(ports)/sizeof(sync_port))
 
 static struct file_operations sync_serial_fops = {
@@ -213,24 +210,25 @@
 #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL0_DMA)
 	ports[0].use_dma = 1;
 	initialize_port(0);
-	if(request_irq(24, tr_interrupt, 0, "synchronous serial 1 dma tr", NULL))
+	if(request_irq(24, tr_interrupt, 0, "synchronous serial 1 dma tr", &ports[0]))
 		 panic("Can't allocate sync serial port 1 IRQ");
-	if(request_irq(25, rx_interrupt, 0, "synchronous serial 1 dma rx", NULL))
+	if(request_irq(25, rx_interrupt, 0, "synchronous serial 1 dma rx", &ports[0]))
 		panic("Can't allocate sync serial port 1 IRQ");
 	RESET_DMA(8); WAIT_DMA(8);
 	RESET_DMA(9); WAIT_DMA(9);
-	*R_DMA_CH8_CLR_INTR = 3;  /* Clear IRQ */
-	*R_DMA_CH9_CLR_INTR = 3;  /* Clear IRQ */
+	*R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) |
+	  IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do); 
+	*R_DMA_CH9_CLR_INTR = IO_STATE(R_DMA_CH9_CLR_INTR, clr_eop, do) |
+	  IO_STATE(R_DMA_CH9_CLR_INTR, clr_descr, do); 
 	*R_IRQ_MASK2_SET =
 	  IO_STATE(R_IRQ_MASK2_SET, dma8_eop, set) |
 	  IO_STATE(R_IRQ_MASK2_SET, dma8_descr, set) |
-          IO_STATE(R_IRQ_MASK2_SET, dma9_eop, set) | 
           IO_STATE(R_IRQ_MASK2_SET, dma9_descr, set);
 	start_dma_in(&ports[0]);
 #else
 	ports[0].use_dma = 0;
 	initialize_port(0);
-	if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", NULL))
+	if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", &ports[0]))
 		panic("Can't allocate sync serial manual irq");
 	*R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser1_data, set);	 
 #endif
@@ -243,18 +241,19 @@
 #if defined(CONFIG_ETRAX_SYNCHRONOUS_SERIAL1_DMA)
 	ports[1].use_dma = 1;
 	initialize_port(1);
-	if(request_irq(20, tr_interrupt, 0, "synchronous serial 3 dma tr", NULL))
+	if(request_irq(20, tr_interrupt, 0, "synchronous serial 3 dma tr", &ports[1]))
 		panic("Can't allocate sync serial port 1 IRQ");
-	if(request_irq(21, rx_interrupt, 0, "synchronous serial 3 dma rx", NULL))
+	if(request_irq(21, rx_interrupt, 0, "synchronous serial 3 dma rx", &ports[1]))
 		panic("Can't allocate sync serial port 1 IRQ");
 	RESET_DMA(4); WAIT_DMA(4);
 	RESET_DMA(5); WAIT_DMA(5);
-	*R_DMA_CH4_CLR_INTR = 3;  /* Clear IRQ */
-	*R_DMA_CH5_CLR_INTR = 3;  /* Clear IRQ */
+	*R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) |
+	  IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do); 
+	*R_DMA_CH5_CLR_INTR = IO_STATE(R_DMA_CH5_CLR_INTR, clr_eop, do) |
+	  IO_STATE(R_DMA_CH5_CLR_INTR, clr_descr, do); 
 	*R_IRQ_MASK2_SET =
 	  IO_STATE(R_IRQ_MASK2_SET, dma4_eop, set) |
 	  IO_STATE(R_IRQ_MASK2_SET, dma4_descr, set) |
-	  IO_STATE(R_IRQ_MASK2_SET, dma5_eop, set) | 
 	  IO_STATE(R_IRQ_MASK2_SET, dma5_descr, set);
 	start_dma_in(&ports[1]);
 #else
@@ -262,7 +261,7 @@
 	initialize_port(1);
 	if (port[0].use_dma) /* Port 0 uses dma, we must manual allocate IRQ */
 	{
-		if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", NULL))
+		if (request_irq(8, manual_interrupt, SA_SHIRQ, "synchronous serial manual irq", &ports[1]))
 			panic("Can't allocate sync serial manual irq");
 	}
 	*R_IRQ_MASK1_SET = IO_STATE(R_IRQ_MASK1_SET, ser3_data, set);	 
@@ -278,22 +277,14 @@
 	  IO_STATE(R_SYNC_SERIAL_PRESCALE, clk_sel_u3, codec) | 
 	  IO_STATE(R_SYNC_SERIAL_PRESCALE, word_stb_sel_u3, external) | 
 	  IO_STATE(R_SYNC_SERIAL_PRESCALE, prescaler, div4) | 
-	  IO_FIELD(R_SYNC_SERIAL_PRESCALE, frame_rate, 0) | 
-	  IO_FIELD(R_SYNC_SERIAL_PRESCALE, word_rate, 7) | 
+	  IO_FIELD(R_SYNC_SERIAL_PRESCALE, frame_rate, DEFAULT_FRAME_RATE) | 
+	  IO_FIELD(R_SYNC_SERIAL_PRESCALE, word_rate, DEFAULT_WORD_RATE) | 
 	  IO_STATE(R_SYNC_SERIAL_PRESCALE, warp_mode, normal));
 
 	/* Select synchronous ports */
 	*R_GEN_CONFIG_II = gen_config_ii_shadow;
 
-	/*Initialize DMA flush timer if dma is used */
-	if (ports[0].use_dma || ports[1].use_dma) 
-	{
-		init_timer(&flush_timer);
-		flush_timer.function = flush_handler;
-		mod_timer(&flush_timer, jiffies + 10);
-	}
-
-	printk("Etrax100LX synchronous serial port driver\n");
+	printk("ETRAX 100LX synchronous serial port driver\n");
 	return 0;
 }
 
@@ -321,9 +312,9 @@
 	  IO_STATE(R_SYNC_SERIAL1_CTRL, f_syncsize, word)    |
 	  IO_STATE(R_SYNC_SERIAL1_CTRL, f_sync, on)	     |
 	  IO_STATE(R_SYNC_SERIAL1_CTRL, clk_mode, normal)    |
-	  IO_STATE(R_SYNC_SERIAL1_CTRL, clk_halt, running)   |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, clk_halt, stopped)   |
 	  IO_STATE(R_SYNC_SERIAL1_CTRL, bitorder, msb)	     |
-	  IO_STATE(R_SYNC_SERIAL1_CTRL, tr_enable, enable)   |
+	  IO_STATE(R_SYNC_SERIAL1_CTRL, tr_enable, disable)  |
 	  IO_STATE(R_SYNC_SERIAL1_CTRL, wordsize, size8bit)  |
 	  IO_STATE(R_SYNC_SERIAL1_CTRL, buf_empty, lmt_8)    |
 	  IO_STATE(R_SYNC_SERIAL1_CTRL, buf_full, lmt_8)     |
@@ -365,27 +356,43 @@
 
 static int sync_serial_release(struct inode *inode, struct file *file)
 {
-	ports[MINOR(inode->i_rdev)].busy = 0;
+	int dev = MINOR(inode->i_rdev);
+	if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
+	{
+		DEBUG(printk("Invalid minor %d\n", dev));
+		return -ENODEV;
+	}
+	ports[dev].busy = 0;
 	return 0;
 }
 
 static int sync_serial_ioctl(struct inode *inode, struct file *file,
 		  unsigned int cmd, unsigned long arg)
 {
+	int return_val = 0;
 	int dev = MINOR(file->f_dentry->d_inode->i_rdev);
-	sync_port* port = &ports[dev];
+  sync_port* port;
+        
+	if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
+	{
+		DEBUG(printk("Invalid minor %d\n", dev));
+		return -1;
+	}
+        port = &ports[dev];
 
 	/* Disable port while changing config */
 	if (dev)
 	{
 		RESET_DMA(4); WAIT_DMA(4);
-		*R_DMA_CH4_CLR_INTR = 3;  
+		*R_DMA_CH4_CLR_INTR = IO_STATE(R_DMA_CH4_CLR_INTR, clr_eop, do) |
+                  IO_STATE(R_DMA_CH4_CLR_INTR, clr_descr, do); 
 		SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
 	}
 	else
 	{
 		RESET_DMA(8); WAIT_DMA(8);
-		*R_DMA_CH8_CLR_INTR = 3;  
+		*R_DMA_CH8_CLR_INTR = IO_STATE(R_DMA_CH8_CLR_INTR, clr_eop, do) |
+                  IO_STATE(R_DMA_CH8_CLR_INTR, clr_descr, do);  
 		SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
 	}
 	*R_GEN_CONFIG_II = gen_config_ii_shadow;
@@ -516,7 +523,7 @@
 			}
 			break;
 		default:
-			return -EINVAL;
+			return_val = -1;
 	}
 	/* Set config and enable port */
 	*port->ctrl_data = port->ctrl_data_shadow;
@@ -527,15 +534,23 @@
 		SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, sync);
 
 	*R_GEN_CONFIG_II = gen_config_ii_shadow;
-	return 0;
+	return return_val;
 }
 
 static ssize_t sync_serial_manual_write(struct file * file, const char * buf, 
                                         size_t count, loff_t *ppos)
 {
+	int dev = MINOR(file->f_dentry->d_inode->i_rdev);
 	DECLARE_WAITQUEUE(wait, current);
-	sync_port* port = &ports[MINOR(file->f_dentry->d_inode->i_rdev)];
+	sync_port* port;
 
+	if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
+	{
+		DEBUG(printk("Invalid minor %d\n", dev));
+		return -ENODEV;
+	}
+
+	port = &ports[dev];
 	copy_from_user(port->out_buffer, buf, count);
 	port->outp = port->out_buffer;
 	port->out_count = count;
@@ -547,17 +562,36 @@
 	schedule();
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&port->out_wait_q, &wait);
+	if (signal_pending(current))
+	{
+		return -EINTR;
+	}
 	return count;
 }
 
 static ssize_t sync_serial_write(struct file * file, const char * buf, 
                                  size_t count, loff_t *ppos)
 {
-	DECLARE_WAITQUEUE(wait, current);
-	sync_port *port = &ports[MINOR(file->f_dentry->d_inode->i_rdev)];
+	int dev = MINOR(file->f_dentry->d_inode->i_rdev);
+	DECLARE_WAITQUEUE(wait, current);	
+	sync_port *port;
+
+	if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
+	{
+		DEBUG(printk("Invalid minor %d\n", dev));
+		return -ENODEV;
+	}
+	port = &ports[dev];
 
 	DEBUG(printk("Write dev %d count %d\n", port->port_nbr, count));
 
+	count = count > OUT_BUFFER_SIZE ? OUT_BUFFER_SIZE : count;
+
+	/* Make sure transmitter is running */
+	SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running);
+	SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, tr_enable, enable);
+	*port->ctrl_data = port->ctrl_data_shadow;
+
 	if (!port->use_dma)
 	{
 		return sync_serial_manual_write(file, buf, count, ppos); 
@@ -570,26 +604,47 @@
 	schedule();
 	set_current_state(TASK_RUNNING);
 	remove_wait_queue(&port->out_wait_q, &wait);
+	if (signal_pending(current))
+	{
+		return -EINTR;
+	}
 	return count;
 }
 
 static ssize_t sync_serial_read(struct file * file, char * buf, 
 				size_t count, loff_t *ppos)
 {
+	int dev = MINOR(file->f_dentry->d_inode->i_rdev);
 	int avail;
-	sync_port *port = &ports[MINOR(file->f_dentry->d_inode->i_rdev)];
+	sync_port *port;
 	char* start; 
 	char* end;
 	unsigned long flags;	
 
-	DEBUG(printk("Read dev %d count\n"));
+	if (dev < 0 || dev >= NUMBER_OF_PORTS || !ports[dev].enabled)
+	{
+		DEBUG(printk("Invalid minor %d\n", dev));
+		return -ENODEV;
+	}
+	port = &ports[dev];
+
+	DEBUG(printk("Read dev %d count %d\n", dev, count));
+
+	/* Make sure receiver is running */
+	SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, clk_halt, running);
+	SETS(port->ctrl_data_shadow, R_SYNC_SERIAL1_CTRL, rec_enable, enable);
+	*port->ctrl_data = port->ctrl_data_shadow;
 
 	/* Calculate number of available bytes */
 	while (port->readp == port->writep) /* No data */
 	{
 		if (file->f_flags & O_NONBLOCK)
 			return -EAGAIN;
-			interruptible_sleep_on(&port->in_wait_q);
+		interruptible_sleep_on(&port->in_wait_q);
+		if (signal_pending(current))
+		{
+			return -EINTR;
+		}
 	}
 	
 	/* Save pointers to avoid that they are modified by interrupt */
@@ -673,12 +728,12 @@
 		return;
 	}
 	port->in_descr1.hw_len = 0;
-	port->in_descr1.ctrl = d_eop | d_int;
+	port->in_descr1.ctrl = d_int;
 	port->in_descr1.status = 0;
 	port->in_descr1.next = virt_to_phys(&port->in_descr2);
 	port->in_descr2.hw_len = 0;
 	port->in_descr2.next = virt_to_phys(&port->in_descr1);
-	port->in_descr2.ctrl = d_eop | d_int;
+	port->in_descr2.ctrl = d_int;
 	port->in_descr2.status = 0;
 
 	/* Find out which descriptor to start */
@@ -766,22 +821,6 @@
 			start_dma_in(port);
 			wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */
 		}
-		else if (ireg & (1 << port->input_dma_eop_bit)) /* EOP interrupt */
-		{
-			/* EOP interrupt means that DMA has not reached end of descriptor */
-			*port->input_dma_clr_irq = 
-			  IO_STATE(R_DMA_CH0_CLR_INTR, clr_eop, do) | 
-			  IO_STATE(R_DMA_CH0_CLR_INTR, clr_descr, do);
-
-			/* Find out the current descriptor */
-			if (port->writep >= port->in_buffer + IN_BUFFER_SIZE/2)
-				port->writep += port->in_descr2.hw_len;
-			else
-				port->writep += port->in_descr1.hw_len;
-
-			start_dma_in(port);
-			wake_up_interruptible(&port->in_wait_q); /* wake up the waiting process */
-		}
 	}
 }
 
@@ -853,21 +892,6 @@
 			}
 		}
 	}
-}
-
-static void flush_handler(void)
-{
-	int i;
-	
-	for (i = 0; i < NUMBER_OF_PORTS; i++)
-	{
-		if (ports[i].enabled)
-		{
-			*R_SET_EOP = 1 << ports[i].eop_bit;  
-		}
-	}
-	/* restart flush timer */
-	mod_timer(&flush_timer, jiffies + 10);
 }
 
 module_init(etrax_sync_serial_init);
diff -u --recursive --new-file v2.4.4/linux/arch/cris/drivers/usb-host.c linux/arch/cris/drivers/usb-host.c
--- v2.4.4/linux/arch/cris/drivers/usb-host.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/drivers/usb-host.c	Tue May  1 16:04:56 2001
@@ -623,7 +623,7 @@
 
 				traffic_ep->nep = tmp_ep->nep;
 				tmp_ep->nep = virt_to_phys(traffic_ep);
-				dbg_intr("One ep successfully inserted");
+				dbg_intr("One ep sucessfully inserted");
 			}
 			i++;
 		}
@@ -1804,7 +1804,7 @@
 						r_usb_ept_data);
 			
 			if (error_code == IO_STATE_VALUE(R_USB_EPT_DATA, error_code, no_error)) {
-				/* no_error means that this urb was successfully sent or that we have
+				/* no_error means that this urb was sucessfully sent or that we have
 				   some undefinde error*/
 				
 				if (IO_EXTRACT(R_USB_EPT_DATA, error_count_out, r_usb_ept_data) == 3 ||
@@ -1888,9 +1888,9 @@
 						/*
 						  This means that the endpoint has no error, is disabled
 						  and had inserted traffic,
-						  i.e. transfer successfully completed
+						  i.e. transfer sucessfully completed
 						*/
-						dbg_ctrl("Last SB for CTRL %d sent successfully", epid);
+						dbg_ctrl("Last SB for CTRL %d sent sucessfully", epid);
 						handle_control_transfer_attn(epid, 0);
 					}
 				}
@@ -1905,9 +1905,9 @@
 						/*
 						  This means that the endpoint has no error, is disabled
 						  and had inserted traffic,
-						  i.e. transfer successfully completed
+						  i.e. transfer sucessfully completed
 						*/
-						dbg_bulk("Last SB for BULK %d sent successfully", epid);
+						dbg_bulk("Last SB for BULK %d sent sucessfully", epid);
 						handle_bulk_transfer_attn(epid, 0);
 					}
 				}
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/Makefile linux/arch/cris/kernel/Makefile
--- v2.4.4/linux/arch/cris/kernel/Makefile	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/Makefile	Tue May  1 16:04:56 2001
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.3 2001/01/10 21:11:07 bjornw Exp $
+# $Id: Makefile,v 1.4 2001/04/17 13:58:39 orjanf Exp $
 #
 # Makefile for the linux kernel.
 #
@@ -18,7 +18,7 @@
            ptrace.o setup.o time.o sys_cris.o shadows.o \
 	   debugport.o semaphore.o
 
-obj-$(CONFIG_KGDB) += kgdb.o
+obj-$(CONFIG_ETRAX_KGDB) += kgdb.o
 
 clean:
 
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/debugport.c linux/arch/cris/kernel/debugport.c
--- v2.4.4/linux/arch/cris/kernel/debugport.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/debugport.c	Tue May  1 16:04:56 2001
@@ -12,6 +12,12 @@
  *    init_etrax_debug()
  *
  * $Log: debugport.c,v $
+ * Revision 1.6  2001/04/17 13:58:39  orjanf
+ * * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
+ *
+ * Revision 1.5  2001/03/26 14:22:05  bjornw
+ * Namechange of some config options
+ *
  * Revision 1.4  2000/10/06 12:37:26  bjornw
  * Use physical addresses when talking to DMA
  *
@@ -29,7 +35,7 @@
 
 /* Which serial-port is our debug port ? */
 
-#if defined(CONFIG_DEBUG_PORT0) || defined(CONFIG_DEBUG_PORT_NULL)
+#if defined(CONFIG_ETRAX_DEBUG_PORT0) || defined(CONFIG_ETRAX_DEBUG_PORT_NULL)
 #define DEBUG_PORT_IDX 0
 #define DEBUG_OCMD R_DMA_CH6_CMD
 #define DEBUG_FIRST R_DMA_CH6_FIRST
@@ -43,7 +49,7 @@
 #define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma6_descr, clr)
 #endif
 
-#ifdef CONFIG_DEBUG_PORT1
+#ifdef CONFIG_ETRAX_DEBUG_PORT1
 #define DEBUG_PORT_IDX 1
 #define DEBUG_OCMD R_DMA_CH8_CMD
 #define DEBUG_FIRST R_DMA_CH8_FIRST
@@ -57,7 +63,7 @@
 #define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma8_descr, clr)
 #endif
 
-#ifdef CONFIG_DEBUG_PORT2
+#ifdef CONFIG_ETRAX_DEBUG_PORT2
 #define DEBUG_PORT_IDX 2
 #define DEBUG_OCMD R_DMA_CH2_CMD
 #define DEBUG_FIRST R_DMA_CH2_FIRST
@@ -71,7 +77,7 @@
 #define DEBUG_DMA_IRQ_CLR IO_STATE(R_IRQ_MASK2_CLR, dma2_descr, clr)
 #endif
 
-#ifdef CONFIG_DEBUG_PORT3
+#ifdef CONFIG_ETRAX_DEBUG_PORT3
 #define DEBUG_PORT_IDX 3
 #define DEBUG_OCMD R_DMA_CH4_CMD
 #define DEBUG_FIRST R_DMA_CH4_FIRST
@@ -97,7 +103,7 @@
 	unsigned long flags; 
 	int in_progress;
 	
-#ifdef CONFIG_DEBUG_PORT_NULL
+#ifdef CONFIG_ETRAX_DEBUG_PORT_NULL
         /* no debug printout at all */
         return;
 #endif
@@ -111,7 +117,7 @@
 	save_flags(flags);
 	cli();
 
-#ifdef CONFIG_KGDB
+#ifdef CONFIG_ETRAX_KGDB
 	/* kgdb needs to output debug info using the gdb protocol */
 	putDebugString(buf, len);
 	restore_flags(flags);
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/entry.S linux/arch/cris/kernel/entry.S
--- v2.4.4/linux/arch/cris/kernel/entry.S	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/kernel/entry.S	Sun May 20 12:11:38 2001
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.15 2001/03/05 13:14:30 bjornw Exp $
+/* $Id: entry.S,v 1.22 2001/04/17 13:58:39 orjanf Exp $
  *
  *  linux/arch/cris/entry.S
  *
@@ -7,6 +7,40 @@
  *  Authors:	Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: entry.S,v $
+ *  Revision 1.22  2001/04/17 13:58:39  orjanf
+ *  * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
+ *
+ *  Revision 1.21  2001/04/17 11:33:29  orjanf
+ *  Updated according to review:
+ *  * Included asm/sv_addr_ag.h to get macro for internal register.
+ *  * Corrected comment regarding system call argument passing.
+ *  * Removed comment about instruction being in a delay slot.
+ *  * Added comment about SYMBOL_NAME macro.
+ *
+ *  Revision 1.20  2001/04/12 08:51:07  hp
+ *  - Add entry for sys_fcntl64.  In fact copy last piece from i386 including ...
+ *  - .rept to fill table to safe state with sys_ni_syscall.
+ *
+ *  Revision 1.19  2001/04/04 09:43:32  orjanf
+ *  * Moved do_sigtrap from traps.c to entry.S.
+ *  * LTASK_PID need not be global anymore.
+ *
+ *  Revision 1.18  2001/03/26 09:25:02  markusl
+ *  Updated after review, should now handle USB interrupts correctly.
+ *
+ *  Revision 1.17  2001/03/21 16:12:55  bjornw
+ *  * Always make room for the cpu status record in the frame, in order to
+ *    use the same framelength and layout for both mmu busfaults and normal
+ *    irqs. No need to check for the explicit CRIS_FRAME_FIXUP type anymore.
+ *  * Fixed bug with using addq for popping the stack in the epilogue - it
+ *    destroyed the flag register. Use instructions that don't affect the
+ *    flag register instead.
+ *  * Removed write to R_PORT_PA_DATA during spurious_interrupt
+ *
+ *  Revision 1.16  2001/03/20 19:43:02  bjornw
+ *  * Get rid of esp0 setting
+ *  * Give a 7th argument to a systemcall - the stackframe
+ *
  *  Revision 1.15  2001/03/05 13:14:30  bjornw
  *  Spelling fix
  *
@@ -78,9 +112,11 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/linkage.h>
 #include <linux/sys.h>
-			
+#include <asm/sv_addr_ag.h>
+	
 	;; functions exported from this file
 	
 	.globl _system_call
@@ -95,10 +131,11 @@
 	.globl _spurious_interrupt
 	.globl _hw_bp_trigs
 	.globl _mmu_bus_fault
-				
+	.globl _do_sigtrap
+	.globl _gdb_handle_breakpoint
+			
 	.globl _sys_call_table
 	
-	.globl LTASK_PID	
 	;; syscall error codes
 	
 LENOSYS = 38
@@ -115,11 +152,6 @@
 
 PT_TRACESYS_BIT	  = 1
 
-	;; Offset for esp0 into task_struct: current->thread.esp0.
-	;; FIXME: In need of padding somewhere, to get dword-alignment.
-
-THREAD_ESP0	  = 597
-	
 	;; some pt_regs offsets (from ptrace.h)
 	
 LORIG_R10	= 4
@@ -182,7 +214,7 @@
 	;; Since we can't have system calls inside interrupts, it should not matter
 	;; that we don't stack IRP.
 	;; 
-	;; In r1 we have the wanted syscall number. Arguments come in r10,r11,r12,r13,r0
+	;; In r9 we have the wanted syscall number. Arguments come in r10,r11,r12,r13,mof,srp
 	;;
 	;; This function looks on the _surface_ like spaghetti programming, but it's
 	;; really designed so that the fast-path does not force cache-loading of non-used
@@ -190,7 +222,7 @@
 
 _system_call:
 	;; stack-frame similar to the irq heads, which is reversed in ret_from_sys_call
-	push	brp		; this is normally push irp
+	move	brp,[sp=sp-16]	; instruction pointer and room for a fake SBFS frame
 	push	srp
 	push	dccr
 	push	mof
@@ -202,15 +234,11 @@
 	movs.w	-LENOSYS,r0
 	move.d	r0,[sp+LR10]	; put the default return value in r10 in the frame
 
-	;; Perform "current->thread.esp0 = sp".
-	;; This used to be a separate function; set_esp0(ssp).
-	movs.w -8192,r0		; THREAD_SIZE == 8192
-	and.d sp,r0
-
-	move.d sp,[r0+THREAD_ESP0]
-
 	;; check if this process is syscall-traced
 
+	movs.w	-8192,r0	; THREAD_SIZE == 8192
+	and.d	sp,r0
+	
 	move.d	[r0+LTASK_PTRACE],r0
 	btstq	PT_TRACESYS_BIT, r0
 	bmi	tracesys
@@ -222,6 +250,11 @@
 	bcc	_ret_from_sys_call
 	lslq	2,r9		;  multiply by 4, in the delay slot
 
+	;; as a bonus 7th parameter, we give the location on the stack
+	;; of the register structure itself. some syscalls need this.
+
+	push	sp
+	
 	;; the parameter carrying registers r10, r11, r12 and 13 are intact.
 	;; the fifth and sixth parameters (if any) was in mof and srp 
 	;; respectively, and we need to put them on the stack.
@@ -230,8 +263,8 @@
 	push	mof
 	
 	jsr	[r9+_sys_call_table]	; actually do the system call
-	addq	2*4,sp		; pop the mof and srp parameters
-	move.d	r10,[sp+LR10]	; save the return value
+	addq	3*4,sp			; pop the mof, srp and regs parameters
+	move.d	r10,[sp+LR10]		; save the return value
 
 	moveq	1,r9		; "parameter" to ret_from_sys_call to show it was a sys call
 	
@@ -274,31 +307,20 @@
 	pop	mof		; multiply overflow register 
 	pop	dccr		; condition codes
 	pop	srp		; subroutine return pointer
-	jmpu	[sp+]		; return by popping irp and jumping there
-	;; jmpu takes the U-flag into account to see if we return to
-	;; user-mode or kernel mode.
+	;; now we have a 4-word SBFS frame which we do not want to restore
+	;; using RBF since it was not stacked with SBFS. instead we would like to
+	;; just get the PC value to restart it with, and skip the rest of
+	;; the frame.
+	move	[sp=sp+16], p8	; pop the SBFS frame from the sp
+	jmpu	[sp-16]		; return through the irp field in the sbfs frame
 
 RBFexit:
-	cmpq	2, r10		; was it CRIS_FRAME_FIXUP ?
-	beq	2f
 	movem	[sp+],r13	; registers r0-r13, in delay slot
 	pop	mof		; multiply overflow register 
 	pop	dccr		; condition codes
 	pop	srp		; subroutine return pointer
 	rbf	[sp+]		; return by popping the CPU status
 
-2:	pop	mof		; multiply overflow register
-	pop	dccr		; condition codes
-	pop	srp		; subroutine return pointer
-	;; now we have a 4-word SBFS frame which we do not want to restore
-	;; using RBF since we have made a fixup. instead we would like to
-	;; just get the PC value to restart it with, and skip the rest of
-	;; the frame.
-	pop	irp		; fixup location will be here
-	reti			; return to IRP, taking U-flag into account
-	addq	12,sp		; Skip rest of SBFS frame.
-
-
 tracesys:
 	;; this first invocation of syscall_trace _requires_ that
 	;; LR10 in the frame contains -LENOSYS (as is set in the beginning
@@ -332,13 +354,19 @@
 	move	[sp+LMOF],      mof
 	move	[sp+LSRP],      srp
 
+	;; as a bonus 7th parameter, we give the location on the stack
+	;; of the register structure itself. some syscalls need this.
+
+	push	sp
+	
 	;; the fifth and sixth parameters needs to be put on the stack for
 	;; the system call to find them
 
 	push	srp
 	push	mof
+
 	jsr	r9		; actually call the system-call
-	addq	2*4,sp		; pop the r0 parameter
+	addq	3*4,sp		; pop the srp, mof and regs parameters
 
 1:	move.d	r10,[sp+LR10]	; save the return value
 
@@ -354,8 +382,7 @@
 	
 LTHREAD_KSP	= 0
 LTHREAD_USP	= 4
-LTHREAD_ESP0	= 8
-LTHREAD_DCCR	= 12
+LTHREAD_DCCR	= 8
 	
 	;; _resume performs the actual task-switching, by switching stack pointers
 	;; input arguments: r10 = prev, r11 = next, r12 = thread offset in task struct
@@ -468,8 +495,6 @@
 _IRQ1_interrupt:
 _spurious_interrupt:	
 	di
-	move.b	4,r0
-	move.b	r0,[0xb0000030]
 basse2:	ba	basse2
 	nop
 
@@ -479,7 +504,7 @@
 	
 _multiple_interrupt:
 	;; this prologue MUST match the one in irq.h and the struct in ptregs.h!!!
-	push	irp
+	move	irp,[sp=sp-16]	; instruction pointer and room for a fake SBFS frame
 	push	srp
 	push	dccr
 	push	mof
@@ -491,15 +516,15 @@
 	
 	move.d	_irq_shortcuts + 8,r1
 	moveq	2,r2		; first bit we care about is the timer0 irq
-	move.d	[0xb00000d8],r0	; read the irq bits that triggered the multiple irq
+	move.d	[R_VECT_MASK_RD],r0	; read the irq bits that triggered the multiple irq
 multloop:	
 	btst	r2,r0		; check for the irq given by bit r2
 	bmi	do_shortcut	; actually do the shortcut
 	nop
-	addq	1,r2		; next vector bit - remember this is in the delay slot!
+	addq	1,r2		; next vector bit
 	addq	4,r1		; next vector
-	cmpq	26,r2
-	bne	multloop	; process all irq's up to and including number 25
+	cmp.b	32,r2
+	bne	multloop	; process all irq's up to and including number 31
 	nop
 	
 	;; strange, we didn't get any set vector bits.. oh well, just return
@@ -513,6 +538,48 @@
 	nop
 	jump	[r1]		; jump to the irq handlers shortcut
 
+_do_sigtrap:
+	;; 
+	;; SIGTRAP the process that executed the break instruction.
+	;; Make a frame that Rexit in entry.S expects.
+	;;
+	move	brp,[sp=sp-16]		; Push BRP while faking a cpu status record.
+	push	srp			; Push subroutine return pointer.
+	push	dccr			; Push condition codes.
+	push	mof			; Push multiply overflow reg.
+	di				; Need to disable irq's at this point.
+	subq	14*4,sp			; Make room for r0-r13.
+	movem	r13,[sp]		; Push the r0-r13 registers.
+	push	r10			; Push orig_r10.
+	clear.d	[sp=sp-4]		; Frametype - this is a normal stackframe.
+
+	movs.w	-8192,r9		; THREAD_SIZE == 8192
+	and.d	sp,r9
+	move.d	[r9+LTASK_PID],r10	; current->pid as arg1.
+	moveq	5,r11			; SIGTRAP as arg2.
+	jsr	_sys_kill       
+	jump	_ret_from_intr		; Use the return routine for interrupts.
+
+_gdb_handle_breakpoint:	
+	push	dccr
+	push	r0
+#ifdef CONFIG_ETRAX_KGDB
+	move	dccr,r0			; U-flag not affected by previous insns. 
+	btstq	8,r0			; Test the U-flag.
+	bmi	_ugdb_handle_breakpoint	; Go to user mode debugging. 
+	nop				; Empty delay slot (cannot pop r0 here). 
+	pop	r0			; Restore r0.
+	ba	_kgdb_handle_breakpoint	; Go to kernel debugging. 
+	pop	dccr			; Restore dccr in delay slot.
+#endif
+	
+_ugdb_handle_breakpoint:	
+	move	brp,r0			; Use r0 temporarily for calculation.
+	subq	2,r0			; Set to address of previous instruction.
+	move	r0,brp
+	pop	r0			; Restore r0. 
+	ba	_do_sigtrap		; SIGTRAP the offending process. 
+	pop	dccr			; Restore dccr in delay slot.
 	
 	.data
 
@@ -521,8 +588,11 @@
 _hw_bp_trig_ptr:
 	.dword _hw_bp_trigs
 
-/* linux/linkage.h got it wrong for this compiler currently */
-	
+/* Because we compile this file with -traditional, we need to redefine
+   token-concatenation to the traditional trick, using an empty comment.
+   Normally (in other files, with ISO C as in gcc default) this is done
+   with the ## preprocessor operator.  */
+
 #undef SYMBOL_NAME
 #define SYMBOL_NAME(X) _/**/X
 		
@@ -748,6 +818,8 @@
 	.long SYMBOL_NAME(sys_mincore)
 	.long SYMBOL_NAME(sys_madvise)
 	.long SYMBOL_NAME(sys_getdents64)       /* 220 */
+	.long SYMBOL_NAME(sys_fcntl64)
+	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for TUX */
 
         /*
          * NOTE!! This doesn't have to be exact - we just have
@@ -756,9 +828,7 @@
          * been shrunk every time we add a new system call.
          */
 
-	;; TODO: this needs to actually generate sys_ni_syscall entires
-	;; since we now have removed the check for NULL entries in this
-	;; table in system_call!
-	
-	.space (NR_syscalls-220)*4
+	.rept NR_syscalls-221
+		.long SYMBOL_NAME(sys_ni_syscall)
+	.endr
 	
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/head.S linux/arch/cris/kernel/head.S
--- v2.4.4/linux/arch/cris/kernel/head.S	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/kernel/head.S	Tue May  1 16:04:56 2001
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.20 2001/02/23 12:47:56 bjornw Exp $
+/* $Id: head.S,v 1.29 2001/04/18 12:51:59 orjanf Exp $
  * 
  * Head of the kernel - alter with care
  *
@@ -7,6 +7,40 @@
  * Authors:	Bjorn Wesen (bjornw@axis.com)
  * 
  * $Log: head.S,v $
+ * Revision 1.29  2001/04/18 12:51:59  orjanf
+ * * Reverted review change regarding the use of bcs/bcc.
+ * * Removed non-working LED-clearing code.
+ *
+ * Revision 1.28  2001/04/17 13:58:39  orjanf
+ * * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
+ *
+ * Revision 1.27  2001/04/17 11:42:35  orjanf
+ * Changed according to review:
+ * * Added comment explaining memory map bug.
+ * * Changed bcs and bcc to blo and bhs, respectively.
+ * * Removed mentioning of Stallone and Olga boards.
+ *
+ * Revision 1.26  2001/04/06 12:31:07  jonashg
+ * Check for cramfs in flash before RAM instead of RAM before flash.
+ *
+ * Revision 1.25  2001/04/04 06:23:53  starvik
+ * Initialize DRAM if not already initialized
+ *
+ * Revision 1.24  2001/04/03 11:12:00  starvik
+ * Removed dram init (done by rescue or etrax100boot
+ * Corrected include
+ *
+ * Revision 1.23  2001/04/03 09:53:03  starvik
+ * Include hw_settings.S
+ *
+ * Revision 1.22  2001/03/26 14:23:26  bjornw
+ * Namechange of some config options
+ *
+ * Revision 1.21  2001/03/08 12:14:41  bjornw
+ * * Config name for ETRAX IDE was renamed
+ * * Removed G27 auto-setting when JULIETTE is chosen (need to make this
+ *   a new config option later)
+ *
  * Revision 1.20  2001/02/23 12:47:56  bjornw
  * MMU regs during LOW_MAP updated to reflect a newer reality
  *
@@ -76,7 +110,8 @@
 #include <asm/sv_addr_ag.h>
 
 #define CRAMFS_MAGIC 0x28cd3d45
-	
+#define RAM_INIT_MAGIC 0x56902387
+		
 	;; exported symbols
 		
 	.globl	_etrax_irv
@@ -92,9 +127,9 @@
 	;; since etrax actually starts at address 2 when booting from flash, we
 	;; put a nop (2 bytes) here first so we dont accidentally skip the di
 	;;
-	;; NOTICE! The register r9 is used as a parameter carrying register from
-	;; the decompressor (if the kernel was compressed). It should not be
-	;; used in the code below until it is read.
+	;; NOTICE! The registers r8 and r9 are used as a parameter carrying
+	;; information from the decompressor (if the kernel was compressed). 
+	;; They should not be used in the code below until it is read.
 	
 	nop	
 	di
@@ -109,6 +144,7 @@
 	;;
 	;; Due to a bug in Etrax-100 LX version 1 we need to map the memory
 	;; slightly different. We also let the simulator get this mapping for now.
+	;; (The bug is that you can't remap bit 31.)
 
 #ifdef CONFIG_CRIS_LOW_MAP
 	move.d	0x0004b098, r0	; kseg mappings, temporary map of 0xc0->0x40
@@ -161,8 +197,14 @@
 	
 inflash:
 	;; We need to initialze DRAM registers before we start using the DRAM
-#include "../lib/dram_init.S"	
 
+	cmp.d	RAM_INIT_MAGIC, r8	; Already initialized?
+	beq	dram_init_finished
+	nop
+	
+#include "../lib/dram_init.S"
+
+dram_init_finished:		
 	;; Copy text+data to DRAM
 	;; This is fragile - the calculation of r4 as the image size depends
 	;; on that the labels below actually are the first and last positions
@@ -218,7 +260,39 @@
 	moveq	0, r0
 	move.d	r0, [_romfs_length] ; default if there is no cramfs
 	
-	;; First check if there is a cramfs (magic value)
+	;; The kernel could have been unpacked to DRAM by the loader, but
+	;; the cramfs image could still be in the Flash directly after the
+	;; compressed kernel image. The loader passes the address of the
+	;; byte succeeding the last compressed byte in the flash in the
+	;; register r9 when starting the kernel. Check if r9 points to a
+	;; decent cramfs image!
+	;; (Notice that if this is not booted from the loader, r9 will be
+	;;  garbage but we do sanity checks on it, the chance that it points
+	;;  to a cramfs magic is small.. )
+	
+	cmp.d	0x0ffffff8, r9
+	bcc	no_romfs_in_flash	; r9 points outside the flash area
+	nop
+	move.d	[r9], r0	; cramfs_super.magic
+	cmp.d	CRAMFS_MAGIC, r0
+	bne	no_romfs_in_flash
+	nop
+	move.d	[r9+4], r0	; cramfs_super.length
+	move.d	r0, [_romfs_length]
+#ifdef CONFIG_CRIS_LOW_MAP
+	add.d   0x50000000, r9	; add flash start in virtual memory (cached)
+#else
+	add.d   0xf0000000, r9	; add flash start in virtual memory (cached)
+#endif
+	move.d	r9, [_romfs_start]
+
+	moveq	1, r0
+	move.d	r0, [_romfs_in_flash]
+	
+	jump	start_it	; enter code, cached this time
+
+no_romfs_in_flash:
+	;; Check if there is a cramfs (magic value).
 	;; Notice that we check for cramfs magic value - which is
 	;; the "rom fs" we'll possibly use in 2.4 if not JFFS (which does
 	;; not need this mechanism anyway)
@@ -226,7 +300,7 @@
 	move.d	__vmlinux_end, r0 ; the image will be after the vmlinux end address
 	move.d	[r0], r1	; cramfs assumes same endian on host/target
 	cmp.d	CRAMFS_MAGIC, r1; magic value in cramfs superblock
-	bne	no_romfs_in_ram
+	bne	1f
 	nop
 
 	;; Ok. What is its size ? 
@@ -263,40 +337,6 @@
 	move.d	r0, [_romfs_in_flash]
 
 	jump	start_it	; better skip the additional cramfs check below
-			
-no_romfs_in_ram:
-
-	;; We have still one other possibility at this point - the kernel
-	;; could have been unpacked to DRAM by the loader, but the cramfs
-	;; image was still in the Flash directly after the compressed kernel
-	;; image. The loader passes the address of the byte succeeding the
-	;; last compressed byte in the flash in the register r9 when starting
-	;; the kernel. Check if r9 points to a decent cramfs image!
-	;; (Notice that if this is not booted from the loader, r9 will be
-	;;  garbage but we do sanity checks on it, the chance that it points
-	;;  to a cramfs magic is small.. )
-	
-	cmp.d	0x0ffffff8, r9
-	bcc	1f		; r9 points outside the flash area
-	nop
-	move.d	[r9], r0	; cramfs_super.magic
-	cmp.d	CRAMFS_MAGIC, r0
-	bne	1f
-	nop
-	move.d	[r9+4], r0	; cramfs_super.length
-	move.d	r0, [_romfs_length]
-#ifdef CONFIG_CRIS_LOW_MAP
-	add.d   0x50000000, r9	; add flash start in virtual memory (cached)
-#else
-	add.d   0xf0000000, r9	; add flash start in virtual memory (cached)
-#endif
-	move.d	r9, [_romfs_start]
-
-	moveq	1, r0
-	move.d	r0, [_romfs_in_flash]
-1:	
-	
-	jump	start_it	; enter code, cached this time
 	
 start_it:
 	;; the kernel stack is overlayed with the task structure for each
@@ -368,10 +408,10 @@
 	;; Etrax product HW genconfig setup
 
 	moveq	0,r0
-#if !defined(CONFIG_KGDB) && !defined(CONFIG_DMA_MEMCPY)
+#if !defined(CONFIG_ETRAX_KGDB) && !defined(CONFIG_DMA_MEMCPY)
 	or.d	0x140000,r0	; DMA channels 6 and 7 to ser0, kgdb doesnt want DMA
 #endif
-#if !defined(CONFIG_KGDB) || !defined(CONFIG_DEBUG_PORT1)	
+#if !defined(CONFIG_ETRAX_KGDB) || !defined(CONFIG_ETRAX_DEBUG_PORT1)	
 	or.d	0xc00000,r0	; DMA channels 8 and 9 to ser1, kgdb doesnt want DMA
 #endif	
 #ifdef CONFIG_DMA_MEMCPY
@@ -389,7 +429,7 @@
 #if defined(CONFIG_ETRAX_PARALLEL_PORT1) || defined(CONFIG_ETRAX_ETHERNET_LPSLAVE)
 	or.w	0x80,r0	; parport 1 enabled using DMA 4/5
 #endif
-#ifdef CONFIG_BLK_DEV_ETRAXIDE
+#ifdef CONFIG_ETRAX_IDE
 	or.d	0x3c02,r0	; DMA channels 2 and 3 to ATA, ATA enabled
 #endif
 	
@@ -405,9 +445,6 @@
 	
 #ifdef CONFIG_JULIETTE
 	or.d	0x3c000,r0	; DMA channels 4 and 5 to EXTDMA0, for Juliette
-#ifndef CONFIG_BLK_DEV_ETRAXIDE
-	or.d	0x41,r0		; HACK for now! To make G27 connected for the RTC
-#endif
 #endif
 	move.d	r0,[_genconfig_shadow] ; init a shadow register of R_GEN_CONFIG
 
@@ -447,20 +484,20 @@
 	;; setup port PA and PB default initial directions and data
 	;; including their shadow registers
 		
-	move.b	DEF_R_PORT_PA_DIR,r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR,r0
 	move.b	r0,[_port_pa_dir_shadow]
 	move.b	r0,[R_PORT_PA_DIR]
-	move.b	DEF_R_PORT_PA_DATA,r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA,r0
 	move.b	r0,[_port_pa_data_shadow]
 	move.b	r0,[R_PORT_PA_DATA]
 	
-	move.b	DEF_R_PORT_PB_CONFIG,r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG,r0
 	move.b	r0,[_port_pb_config_shadow]
 	move.b	r0,[R_PORT_PB_CONFIG]
-	move.b	DEF_R_PORT_PB_DIR,r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR,r0
 	move.b	r0,[_port_pb_dir_shadow]
 	move.b	r0,[R_PORT_PB_DIR]
-	move.b	DEF_R_PORT_PB_DATA,r0
+	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA,r0
 	move.b	r0,[_port_pb_data_shadow]
 	move.b	r0,[R_PORT_PB_DATA]
 	move.d  0, r0
@@ -499,12 +536,6 @@
 	move.b	0x40,r0			; tr enable
 	move.b	r0,[R_SERIAL1_TR_CTRL]
 
-#ifdef CONFIG_ETRAX_90000000_LEDS
-	;; clear LED's on Stallone and Olga boards
-	moveq	-1,r0
-	move.d	r0,[_port_90000000_shadow]
-	move.d	r0,[0x90000000]
-#endif
 	
 #ifdef CONFIG_ETRAX_SERIAL_PORT3	
 	;; setup the serial port 3 at 115200 baud for debug purposes
@@ -544,3 +575,5 @@
 #else	
 _swapper_pg_dir = 0xc0002000
 #endif
+	
+#include "../lib/hw_settings.S"
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/irq.c linux/arch/cris/kernel/irq.c
--- v2.4.4/linux/arch/cris/kernel/irq.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/kernel/irq.c	Tue May  1 16:04:56 2001
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.11 2001/02/27 13:52:52 bjornw Exp $
+/* $Id: irq.c,v 1.14 2001/04/17 13:58:39 orjanf Exp $
  *
  *	linux/arch/cris/kernel/irq.c
  *
@@ -160,7 +160,7 @@
 BUILD_IRQ(23, 0x800000)
 BUILD_IRQ(24, 0x1000000)
 BUILD_IRQ(25, 0x2000000)
-/* IRQ 26-30 are resereved */	
+/* IRQ 26-30 are reserved */
 BUILD_IRQ(31, 0x80000000)
  
 /*
@@ -261,11 +261,11 @@
         irq_enter(cpu);
 	kstat.irqs[cpu][irq]++;
 
-	action = *(irq + irq_action);
+	action = irq_action[irq];
         if (action) {
                 if (!(action->flags & SA_INTERRUPT))
                         __sti();
-                action = *(irq + irq_action);
+                action = irq_action[irq];
                 do_random = 0;
                 do {
                         do_random |= action->flags;
@@ -396,7 +396,7 @@
 		save_flags(flags);
 		cli();
 		*p = action->next;
-		if (!irq[irq_action]) {
+		if (!irq_action[irq]) {
 			mask_irq(irq);
 			set_int_vector(irq, bad_interrupt[irq], 0);
 		}
@@ -419,8 +419,8 @@
 */
 
 void system_call(void);  /* from entry.S */
-void gdb_handle_breakpoint(void); /* from traps.c */
-void do_sigtrap(void); /* also from traps.c */
+void do_sigtrap(void); /* from entry.S */
+void gdb_handle_breakpoint(void); /* from entry.S */
 
 void init_IRQ(void)
 {
@@ -475,10 +475,10 @@
 
         /* setup a breakpoint handler for debugging used for both user and
            kernel mode debugging  (which is why it is not inside an ifdef
-           CONFIG_KGDB) */
+           CONFIG_ETRAX_KGDB) */
         set_break_vector(8, gdb_handle_breakpoint);
 
-#ifdef CONFIG_KGDB
+#ifdef CONFIG_ETRAX_KGDB
 	/* setup kgdb if its enabled, and break into the debugger */
 	kgdb_init();
 	breakpoint();
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/kgdb.c linux/arch/cris/kernel/kgdb.c
--- v2.4.4/linux/arch/cris/kernel/kgdb.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/kernel/kgdb.c	Tue May  1 16:04:56 2001
@@ -18,6 +18,9 @@
 *! Jul 21 1999  Bjorn Wesen     eLinux port
 *!
 *! $Log: kgdb.c,v $
+*! Revision 1.5  2001/04/17 13:58:39  orjanf
+*! * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
+*!
 *! Revision 1.4  2001/02/23 13:45:19  bjornw
 *! config.h check
 *!
@@ -49,7 +52,7 @@
 *!
 *!---------------------------------------------------------------------------
 *!
-*! $Id: kgdb.c,v 1.4 2001/02/23 13:45:19 bjornw Exp $
+*! $Id: kgdb.c,v 1.5 2001/04/17 13:58:39 orjanf Exp $
 *!
 *! (C) Copyright 1999, Axis Communications AB, LUND, SWEDEN
 *!
@@ -60,8 +63,8 @@
  *  kgdb usage notes:
  *  -----------------
  *
- * If you select CONFIG_KGDB in the configuration, the kernel will be built
- * with different gcc flags: "-g" is added to get debug infos, and
+ * If you select CONFIG_ETRAX_KGDB in the configuration, the kernel will be 
+ * built with different gcc flags: "-g" is added to get debug infos, and
  * "-fomit-frame-pointer" is omitted to make debugging easier. Since the
  * resulting kernel will be quite big (approx. > 7 MB), it will be stripped
  * before compresion. Such a kernel will behave just as usually, except if
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/process.c linux/arch/cris/kernel/process.c
--- v2.4.4/linux/arch/cris/kernel/process.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/kernel/process.c	Tue May  1 16:04:56 2001
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.12 2001/02/27 13:52:52 bjornw Exp $
+/* $Id: process.c,v 1.13 2001/03/20 19:44:06 bjornw Exp $
  * 
  *  linux/arch/cris/kernel/process.c
  *
@@ -7,6 +7,10 @@
  *
  *  Authors:   Bjorn Wesen (bjornw@axis.com)
  *
+ *  $Log: process.c,v $
+ *  Revision 1.13  2001/03/20 19:44:06  bjornw
+ *  Use the 7th syscall argument for regs instead of current_regs
+ *
  */
 
 /*
@@ -33,6 +37,8 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/io.h>
+#include <asm/processor.h>
+
 #include <linux/smp.h>
 
 //#define DEBUG
@@ -64,13 +70,6 @@
 
 static int hlt_counter=0;
 
-/* in a system call, set_esp0 is called to remember the stack frame, therefore
-   in the implementation of syscalls we can use that value to access the stack
-   frame and saved registers.
-*/
-
-#define currentregs ((struct pt_regs *)current->thread.esp0)
-
 void disable_hlt(void)
 {
 	hlt_counter++;
@@ -178,7 +177,7 @@
 	 * remember that the task_struct doubles as the kernel stack for the task
 	 */
 
-	childregs = ((struct pt_regs *) ((unsigned long)p + THREAD_SIZE)) - 1;
+	childregs = user_regs(p);
 
 	*childregs = *regs;  /* struct copy of pt_regs */
 
@@ -202,14 +201,11 @@
 
 	p->thread.ksp = (unsigned long) swstack;
 
-	/* esp0 keeps the pt_regs stacked structure pointer */
-
-	p->thread.esp0 = (unsigned long) childregs;
-
 #ifdef DEBUG
-	printk("kern_stack_page 0x%x, used stack %d, thread.usp 0x%x, usp 0x%x\n", 
-	       current->kernel_stack_page, usedstack, p->thread.usp, usp);
+	printk("copy_thread: new regs at 0x%p, as shown below:\n", childregs);
+	show_registers(childregs);
 #endif
+
 	return 0;
 }
 
@@ -240,33 +236,53 @@
 #endif 
 }
 
-asmlinkage int sys_fork(void)
+/* 
+ * Be aware of the "magic" 7th argument in the four system-calls below.
+ * They need the latest stackframe, which is put as the 7th argument by
+ * entry.S. The previous arguments are dummies or actually used, but need
+ * to be defined to reach the 7th argument.
+ *
+ * N.B.: Another method to get the stackframe is to use current_regs(). But
+ * it returns the latest stack-frame stacked when going from _user mode_ and
+ * some of these (at least sys_clone) are called from kernel-mode sometimes
+ * (for example during kernel_thread, above) and thus cannot use it. Thus,
+ * to be sure not to get any surprises, we use the method for the other calls
+ * as well.
+ */
+
+asmlinkage int sys_fork(long r10, long r11, long r12, long r13, long mof, long srp,
+			struct pt_regs *regs)
 {
-	return do_fork(SIGCHLD, rdusp(), currentregs, 0);
+	return do_fork(SIGCHLD, rdusp(), regs, 0);
 }
 
 /* if newusp is 0, we just grab the old usp */
 
-asmlinkage int sys_clone(unsigned long newusp, unsigned long flags)
+asmlinkage int sys_clone(unsigned long newusp, unsigned long flags,
+			 long r12, long r13, long mof, long srp,
+			 struct pt_regs *regs)
 {
 	if (!newusp)
 		newusp = rdusp();
-	return do_fork(flags, newusp, currentregs, 0);
+	return do_fork(flags, newusp, regs, 0);
 }
 
 /* vfork is a system call in i386 because of register-pressure - maybe
  * we can remove it and handle it in libc but we put it here until then.
  */
 
-asmlinkage int sys_vfork(void)
+asmlinkage int sys_vfork(long r10, long r11, long r12, long r13, long mof, long srp,
+			 struct pt_regs *regs)
 {
-        return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), currentregs, 0);
+        return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0);
 }
 
 /*
  * sys_execve() executes a new program.
  */
-asmlinkage int sys_execve(const char *fname, char **argv, char **envp)
+asmlinkage int sys_execve(const char *fname, char **argv, char **envp,
+			  long r13, long mof, long srp, 
+			  struct pt_regs *regs)
 {
 	int error;
 	char *filename;
@@ -276,7 +292,7 @@
 
 	if (IS_ERR(filename))
 	        goto out;
-	error = do_execve(filename, argv, envp, currentregs);
+	error = do_execve(filename, argv, envp, regs);
 	putname(filename);
  out:
 	return error;
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/ptrace.c linux/arch/cris/kernel/ptrace.c
--- v2.4.4/linux/arch/cris/kernel/ptrace.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/ptrace.c	Tue May  1 16:04:56 2001
@@ -3,11 +3,18 @@
  *
  * Parts taken from the m68k port.
  * 
- * Copyright (c) 2000 Axis Communications AB
+ * Copyright (c) 2000, 2001 Axis Communications AB
  *
  * Authors:   Bjorn Wesen
  *
  * $Log: ptrace.c,v $
+ * Revision 1.5  2001/03/26 14:24:28  orjanf
+ * * Changed loop condition.
+ * * Added comment documenting non-standard ptrace behaviour.
+ *
+ * Revision 1.4  2001/03/20 19:44:41  bjornw
+ * Use the user_regs macro instead of thread.esp0
+ *
  * Revision 1.3  2000/12/18 23:45:25  bjornw
  * Linux/CRIS first version
  *
@@ -49,8 +56,8 @@
 
 	if (regno == PT_USP)
 		return task->thread.usp;
-	else if (regno <= PT_MAX)
-		return ((unsigned long *)(task->thread.esp0))[regno];
+	else if (regno < PT_MAX)
+		return ((unsigned long *)user_regs(task))[regno];
 	else
 		return 0;
 }
@@ -65,12 +72,20 @@
 
 	if (regno == PT_USP)
 		task->thread.usp = data;
-	else if (regno <= PT_MAX)
-		((unsigned long *)(task->thread.esp0))[regno] = data;
+	else if (regno < PT_MAX)
+		((unsigned long *)user_regs(task))[regno] = data;
 	else
 		return -1;
 	return 0;
 }
+
+/* Note that this implementation of ptrace behaves differently from vanilla
+ * ptrace.  Contrary to what the man page says, in the PTRACE_PEEKTEXT,
+ * PTRACE_PEEKDATA, and PTRACE_PEEKUSER requests the data variable is not
+ * ignored.  Instead, the data variable is expected to point at a location
+ * (in user space) where the result of the ptrace call is written (instead of
+ * being returned).
+ */
 
 asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
 {
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/setup.c linux/arch/cris/kernel/setup.c
--- v2.4.4/linux/arch/cris/kernel/setup.c	Fri Apr 27 14:10:31 2001
+++ linux/arch/cris/kernel/setup.c	Tue May  1 16:04:56 2001
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.11 2001/03/02 15:52:03 bjornw Exp $
+/* $Id: setup.c,v 1.14 2001/04/03 12:54:12 starvik Exp $
  *
  *  linux/arch/cris/kernel/setup.c
  *
@@ -60,7 +60,7 @@
  * given by the macro __pa().
  *
  * In this DRAM, the kernel code and data is loaded, in the beginning.
- * It really starts at c00a0000 to make room for some special pages - 
+ * It really starts at c0004000 to make room for some special pages - 
  * the start address is text_start. The kernel data ends at _end. After
  * this the ROM filesystem is appended (if there is any).
  * 
@@ -77,11 +77,6 @@
 	unsigned long memory_start;
 	extern void console_print_etrax(const char *b);
 
-#if (defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH))
-	/* TODO: move this into flash_init I think */
-	flash_probe();
-#endif
-
  	/* register an initial console printing routine for printk's */
 
 	init_etrax_debug();
@@ -167,8 +162,9 @@
 
 	paging_init();
 
-	/* we dont use a command line yet, so just let it be an empty string */
-
+	/* we dont use a command line yet, so just let it be an empty string 
+	   to start with */
+        
 	*cmdline_p = command_line;
 	strcpy(command_line, "root=/dev/rom"); /* use the appended romdisk as root */
 
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/shadows.c linux/arch/cris/kernel/shadows.c
--- v2.4.4/linux/arch/cris/kernel/shadows.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/kernel/shadows.c	Tue May  1 16:04:56 2001
@@ -1,20 +1,36 @@
-/* $Id: shadows.c,v 1.1 2000/07/10 16:25:21 bjornw Exp $
+/* $Id: shadows.c,v 1.2 2001/03/15 14:25:16 bjornw Exp $
  * 
- * Various Etrax shadow registers. Defines for these are in include/asm-etrax100/io.h
+ * Various shadow registers. Defines for these are in include/asm-etrax100/io.h
  */
 
-#include <linux/config.h>
+/* Shadows for internal Etrax-registers */
+
+unsigned long genconfig_shadow;
+unsigned long port_g_data_shadow;
+unsigned char port_pa_dir_shadow;
+unsigned char port_pa_data_shadow;
+unsigned char port_pb_i2c_shadow;
+unsigned char port_pb_config_shadow;
+unsigned char port_pb_dir_shadow;
+unsigned char port_pb_data_shadow;
+unsigned long r_timer_ctrl_shadow;
+
+/* Shadows for external I/O port registers.
+ * These are only usable if there actually IS a latch connected
+ * to the corresponding external chip-select pin.
+ *
+ * A common usage is that CSP0 controls LED's and CSP4 video chips.
+ */
+
+unsigned long port_cse1_shadow;
+unsigned long port_csp0_shadow;
+unsigned long port_csp4_shadow;
+
+/* Corresponding addresses for the ports.
+ * These are initialized in arch/cris/mm/init.c using ioremap.
+ */
+
+volatile unsigned long *port_cse1_addr;
+volatile unsigned long *port_csp0_addr;
+volatile unsigned long *port_csp4_addr;
 
-unsigned long genconfig_shadow = 42;
-unsigned long port_g_data_shadow = 42;
-unsigned char port_pa_dir_shadow = 42;
-unsigned char port_pa_data_shadow = 42;
-unsigned char port_pb_i2c_shadow = 42;
-unsigned char port_pb_config_shadow = 42;
-unsigned char port_pb_dir_shadow = 42;
-unsigned char port_pb_data_shadow = 42;
-unsigned long r_timer_ctrl_shadow = 42;
-
-#ifdef CONFIG_ETRAX_90000000_LEDS
-unsigned long port_90000000_shadow = 42;
-#endif
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/signal.c linux/arch/cris/kernel/signal.c
--- v2.4.4/linux/arch/cris/kernel/signal.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/kernel/signal.c	Tue May  1 16:04:56 2001
@@ -36,6 +36,9 @@
 /* a syscall in Linux/CRIS is a break 13 instruction which is 2 bytes */
 /* manipulate regs so that upon return, it will be re-executed */
 
+/* We rely on that pc points to the instruction after "break 13", so the
+ * library must never do strange things like putting it in a delay slot.
+ */
 #define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->irp -= 2;
 
 int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs);
@@ -76,12 +79,14 @@
 }
 
 /*
- * Atomically swap in the new signal mask, and wait for a signal.
+ * Atomically swap in the new signal mask, and wait for a signal.  Define 
+ * dummy arguments to be able to reach the regs argument.  (Note that this
+ * arrangement relies on old_sigset_t occupying one register.)
  */
 int
-sys_sigsuspend(old_sigset_t mask)
+sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof, 
+               long srp, struct pt_regs *regs)
 {
-	struct pt_regs * regs = (struct pt_regs *)current_regs();
 	sigset_t saveset;
 
 	mask &= _BLOCKABLE;
@@ -100,10 +105,13 @@
 	}
 }
 
+/* Define dummy arguments to be able to reach the regs argument.  (Note that
+ * this arrangement relies on size_t occupying one register.)
+ */
 int
-sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
+sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, long r12, long r13, 
+                  long mof, long srp, struct pt_regs *regs)
 {
-	struct pt_regs * regs = (struct pt_regs *)current_regs();
 	sigset_t saveset, newset;
 
 	/* XXX: Don't preclude handling different sized sigset_t's.  */
@@ -225,9 +233,11 @@
 	return 1;
 }
 
-asmlinkage int sys_sigreturn(void)
+/* Define dummy arguments to be able to reach the regs argument.  */
+
+asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof, 
+                             long srp, struct pt_regs *regs)
 {
-	struct pt_regs *regs = (struct pt_regs *)current_regs();
 	struct sigframe *frame = (struct sigframe *)rdusp();
 	sigset_t set;
 
@@ -265,9 +275,11 @@
 	return 0;
 }	
 
-asmlinkage int sys_rt_sigreturn(void)
+/* Define dummy arguments to be able to reach the regs argument.  */
+
+asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13, 
+                                long mof, long srp, struct pt_regs *regs)
 {
-	struct pt_regs *regs = (struct pt_regs *)current_regs();
 	struct rt_sigframe *frame = (struct rt_sigframe *)rdusp();
 	sigset_t set;
 	stack_t st;
@@ -389,7 +401,6 @@
 		/* trampoline - the desired return ip is the retcode itself */
 		return_ip = (unsigned long)&frame->retcode;
 		/* This is movu.w __NR_sigreturn, r9; break 13; */
-		/* TODO: check byteorder */
 		err |= __put_user(0x9c5f,         (short *)(frame->retcode+0));
 		err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2));
 		err |= __put_user(0xe93d,         (short *)(frame->retcode+4));
@@ -535,7 +546,14 @@
  * Note that 'init' is a special process: it doesn't get signals it doesn't
  * want to handle. Thus you cannot kill init even with a SIGKILL even by
  * mistake.
+ *
+ * Also note that the regs structure given here as an argument, is the latest
+ * pushed pt_regs. It may or may not be the same as the first pushed registers
+ * when the initial usermode->kernelmode transition took place. Therefore
+ * we can use user_mode(regs) to see if we came directly from kernel or user
+ * mode below.
  */
+
 int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs)
 {
 	siginfo_t info;
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/sys_cris.c linux/arch/cris/kernel/sys_cris.c
--- v2.4.4/linux/arch/cris/kernel/sys_cris.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/kernel/sys_cris.c	Tue May  1 16:04:56 2001
@@ -1,6 +1,6 @@
-/* $Id: sys_cris.c,v 1.4 2001/01/31 14:55:58 perf Exp $
+/* $Id: sys_cris.c,v 1.7 2001/04/17 11:52:15 orjanf Exp $
  *
- * linux/arch/cris/kernel/sys_etrax.c
+ * linux/arch/cris/kernel/sys_cris.c
  *
  * This file contains various random system calls that
  * have a non-standard calling sequence on some platforms.
@@ -177,20 +177,13 @@
 	case MSGCTL:
 		return sys_msgctl (first, second, (struct msqid_ds *) ptr);
 
-	case SHMAT:
-		switch (version) {
-		default: {
-			ulong raddr;
-			ret = sys_shmat (first, (char *) ptr, second, &raddr);
-			if (ret)
-				return ret;
-			return put_user (raddr, (ulong *) third);
-		}
-		case 1:	/* iBCS2 emulator entry point */
-			if (!segment_eq(get_fs(), get_ds()))
-				return -EINVAL;
-			return sys_shmat (first, (char *) ptr, second, (ulong *) third);
-		}
+	case SHMAT: {
+                ulong raddr;
+                ret = sys_shmat (first, (char *) ptr, second, &raddr);
+                if (ret)
+                        return ret;
+                return put_user (raddr, (ulong *) third);
+        }
 	case SHMDT: 
 		return sys_shmdt ((char *)ptr);
 	case SHMGET:
diff -u --recursive --new-file v2.4.4/linux/arch/cris/kernel/traps.c linux/arch/cris/kernel/traps.c
--- v2.4.4/linux/arch/cris/kernel/traps.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/kernel/traps.c	Sun May 20 12:11:38 2001
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.8 2001/02/23 13:45:20 bjornw Exp $
+/* $Id: traps.c,v 1.11 2001/04/04 09:43:31 orjanf Exp $
  *
  *  linux/arch/cris/traps.c
  *
@@ -9,11 +9,9 @@
  *  Copyright (C) 2000,2001 Axis Communications AB
  *
  *  Authors:   Bjorn Wesen
- *             Orjan Friberg
  *
  */
 
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -45,8 +43,10 @@
         int i;
 	extern char _stext, _etext;
 
-        // debugging aid: "show_stack(NULL);" prints the
-        // back trace for this cpu.
+        /*
+         * debugging aid: "show_stack(NULL);" prints the
+         * back trace for this cpu.
+         */
 
         if(sp == NULL)
                 sp = (unsigned long*)rdsp();
@@ -107,8 +107,8 @@
 {
 	unsigned long usp = rdusp();
 
-	printk("IRP: %08lx SRP: %08lx CCR: %08lx USP: %08lx\n",
-	       regs->irp, regs->srp, regs->dccr, usp );
+	printk("IRP: %08lx SRP: %08lx CCR: %08lx USP: %08lx MOF: %08lx\n",
+	       regs->irp, regs->srp, regs->dccr, usp, regs->mof );
 	printk(" r0: %08lx  r1: %08lx  r2: %08lx  r3: %08lx\n",
 	       regs->r0, regs->r1, regs->r2, regs->r3);
 	printk(" r4: %08lx  r5: %08lx  r6: %08lx  r7: %08lx\n",
@@ -120,7 +120,7 @@
 	printk("Process %s (pid: %d, stackpage=%08lx)\n",
 	       current->comm, current->pid, (unsigned long)current);
 
-	// TODO, fix in_kernel detection
+	/* TODO, fix in_kernel detection */
 
 #if 0
 	/*
@@ -168,65 +168,5 @@
 void __init 
 trap_init(void)
 {
-
+  /* Nothing needs to be done */
 }
-
-/* Use static variables instead of the stack for temporary storage.  */
-static int saved_r0 = 0;
-static int saved_dccr = 0;
-
-asm ("
-  .global _gdb_handle_breakpoint
-  .global _do_sigtrap
-_gdb_handle_breakpoint:
-;;
-;; This handles a break instruction for entering a debug session.
-;;
-  move     dccr,[_saved_dccr]       ; Save dccr.
-  move.d   r0,[_saved_r0]           ; Save r0. "
-#ifdef CONFIG_KGDB
-" 
-  move     ccr,r0                   
-  btstq    8,r0                     ; Test the U-flag.
-  bmi      _ugdb_handle_breakpoint  ; Go to user mode debugging.
-  nop                               ; Delay slot.
-  move.d   [_saved_r0],r0           ; Restore r0.
-  move     [_saved_dccr],dccr       ; Restore dccr.
-  ba       _kgdb_handle_breakpoint  ; Go to kernel debugging.
-  nop                               ; Delay slot. "
-#endif
-" 
-_ugdb_handle_breakpoint:
-;;
-;; Yes, we could do a 'push brp' here and let gdb adjust the pc once it
-;; starts talking to the target again, but this way we avoid a 'P' packet.
-;;
-  move     brp,r0               ; Use r0 temporarily for calculation.
-  subq     2,r0                 ; Set to address of previous instruction.
-  move     r0,brp               ; Restore new brp.
-  move.d   [_saved_r0],r0       ; Restore r0.
-  move     [_saved_dccr],dccr   ; Restore dccr.
-
-_do_sigtrap:
-;; 
-;; SIGTRAP the process that executed the break instruction.
-;; Make a frame that Rexit in entry.S expects.
-;;
-  push     brp                  ; Push breakpoint return pointer.
-  push     srp                  ; Push subroutine return pointer.
-  push     dccr                 ; Push condition codes.
-  push     mof                  ; Push multiply overflow reg.
-  di                            ; Need to disable irq's at this point.
-  subq     14*4,sp              ; Make room for r0-r13.
-  movem    r13,[sp]             ; Push the r0-r13 registers.
-  push     r10                  ; Push orig_r10.
-  clear.d  [sp=sp-4]            ; Frametype - this is a normal stackframe.
-
-  movs.w   -8192,r9             ; THREAD_SIZE == 8192
-  and.d    sp,r9
-  move.d   [r9+LTASK_PID],r10   ; current->pid as arg1.
-  moveq    5,r11                ; SIGTRAP as arg2.
-  jsr      _sys_kill       
-
-  jump     _ret_from_intr       ; Use the return routine for interrupts.
-");
diff -u --recursive --new-file v2.4.4/linux/arch/cris/lib/dram_init.S linux/arch/cris/lib/dram_init.S
--- v2.4.4/linux/arch/cris/lib/dram_init.S	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/lib/dram_init.S	Tue May  1 16:04:56 2001
@@ -1,63 +1,97 @@
-	;; $Id: dram_init.S,v 1.2 2001/02/08 15:20:00 starvik Exp $
-	;; 
-	;; DRAM/SDRAM initialization - alter with care
-	;; This file is intended to be included from other assembler files
-	;;
-	;; Copyright (C) 2000 Axis Communications AB
-	;;
-	;; Authors:  Mikael Starvik (starvik@axis.com)	
-	;;           Bjorn Wesen (bjornw@axis.com)
-	;; 
-	;; $Log: dram_init.S,v $
-	;; Revision 1.2  2001/02/08 15:20:00  starvik
-	;; Corrected SDRAM initialization
-	;; Should now be included as inline
-	;;
-	;; Revision 1.1  2001/01/29 13:08:02  starvik
-	;; Initial version
-	;; This file should be included from all assembler files that needs to
-	;; initialize DRAM/SDRAM.
-	;;
-	;;
-	;;
+/* $Id: dram_init.S,v 1.7 2001/04/18 12:05:39 bjornw Exp $
+ * 
+ * DRAM/SDRAM initialization - alter with care
+ * This file is intended to be included from other assembler files
+ *
+ * Note: This file may not modify r9 because r9 is used to carry
+ *       information from the decompresser to the kernel
+ *
+ * Copyright (C) 2000, 2001 Axis Communications AB
+ *
+ * Authors:  Mikael Starvik (starvik@axis.com)	
+ * 
+ * $Log: dram_init.S,v $
+ * Revision 1.7  2001/04/18 12:05:39  bjornw
+ * Fixed comments, and explicitely include config.h to be sure its there
+ *
+ * Revision 1.6  2001/04/10 06:20:16  starvik
+ * Delay should be 200us, not 200ns
+ *
+ * Revision 1.5  2001/04/09 06:01:13  starvik
+ * Added support for 100 MHz SDRAMs
+ *
+ * Revision 1.4  2001/03/26 14:24:01  bjornw
+ * Namechange of some config options
+ *
+ * Revision 1.3  2001/03/23 08:29:41  starvik
+ * Corrected calculation of mrs_data
+ *
+ * Revision 1.2  2001/02/08 15:20:00  starvik
+ * Corrected SDRAM initialization
+ * Should now be included as inline
+ *
+ * Revision 1.1  2001/01/29 13:08:02  starvik
+ * Initial version
+ * This file should be included from all assembler files that needs to
+ * initialize DRAM/SDRAM.
+ *
+ */
+
+/* Just to be certain the config file is included, we include it here
+ * explicitely instead of depending on it being included in the file that
+ * uses this code.
+ */
 
 #include <linux/config.h>
 
+
 #ifndef CONFIG_SVINTO_SIM	
-	move.d   DEF_R_WAITSTATES, r0
+	move.d   CONFIG_ETRAX_DEF_R_WAITSTATES, r0
 	move.d   r0, [R_WAITSTATES]
 
-	move.d   DEF_R_BUS_CONFIG, r0
+	move.d   CONFIG_ETRAX_DEF_R_BUS_CONFIG, r0
 	move.d   r0, [R_BUS_CONFIG]
 	
-#ifndef CONFIG_SDRAM
-	move.d   DEF_R_DRAM_CONFIG, r0
+#ifndef CONFIG_ETRAX_SDRAM
+	move.d   CONFIG_ETRAX_DEF_R_DRAM_CONFIG, r0
 	move.d   r0, [R_DRAM_CONFIG]
 
-	move.d   DEF_R_DRAM_TIMING, r0
+	move.d   CONFIG_ETRAX_DEF_R_DRAM_TIMING, r0
 	move.d   r0, [R_DRAM_TIMING]
 #else	
 	; Refer to ETRAX 100LX Designers Reference for a description of SDRAM initialization
 	
 	; Bank configuration
-        move.d   DEF_R_SDRAM_CONFIG, r0
+	move.d   CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, r0
 	move.d   r0, [R_SDRAM_CONFIG]
 
 	; Calculate value of mrs_data 
-	; cas_delay = 2 && bus_width = 32 => 0x40
-	; cas_delay = 3 && bus_width = 32 => 0x60
-	; cas_delay = 2 && bus_width = 16 => 0x20
-	; cas_delay = 3 && bus_width = 16 => 0x30
+	; CAS latency = 2 && bus_width = 32 => 0x40
+	; CAS latency = 3 && bus_width = 32 => 0x60
+	; CAS latency = 2 && bus_width = 16 => 0x20
+	; CAS latency = 3 && bus_width = 16 => 0x30
 	
-	move.d   0x40, r2       ; Assume 32 bits and cas_delay = 2
-	move.d   DEF_R_SDRAM_TIMING, r1
-	and.d    0x0c, r1	; Get cas delay
-	cmp.d    0x08, r1	; cas_delay = 2?
-        beq      bw_check
+	move.d   0x40, r2       ; Assume 32 bits and CAS latency = 2
+	move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, r1
+	move.d   r1, r3
+ 	and.d    0x03, r1       ; Get CAS latency
+	and.d    0x1000, r3     ; 50 or 100 MHz?
+	beq      speed_50
+	nop
+speed_100:		
+	cmp.d    0x00, r1	; CAS latency = 2?
+	beq      bw_check
+	nop
+	or.d     0x20, r2	; CAS latency = 3 
+	ba       bw_check
+	nop
+speed_50:			
+	cmp.d    0x01, r1	; CAS latency = 2?
+	beq      bw_check
 	nop
-	or.d     0x20, r2       ; cas_delay = 3
+	or.d     0x20, r2       ; CAS latency = 3
 bw_check:
-	move.d   DEF_R_SDRAM_CONFIG, r1
+	move.d   CONFIG_ETRAX_DEF_R_SDRAM_CONFIG, r1
 	and.d    0x800000, r1	; DRAM width is bit 23
 	bne      set_timing
 	nop
@@ -65,14 +99,17 @@
 
 	; Set timing parameters. Starts master clock
 set_timing:
-	move.d   DEF_R_SDRAM_TIMING, r1
+	move.d   CONFIG_ETRAX_DEF_R_SDRAM_TIMING, r1
+	and.d    0x8000f9ff, r1 ; Make sure mrs data and command is 0 
 	or.d     0x80000000, r1	; Make sure sdram enable bit is set
+	move.d   r1, r5
+	or.d     0x0000c000, r1 ; ref = disable
 	lslq     16, r2		; mrs data starts at bit 16
 	or.d     r2, r1 
 	move.d   r1, [R_SDRAM_TIMING]	
 		
-	; Wait 200ns
-	move.d   10, r2
+	; Wait 200us
+	move.d   10000, r2
 sdram_loop:
 	bne      sdram_loop
 	subq     1, r2
@@ -83,10 +120,10 @@
 command_loop:
 	clear.d  r4
 	move.b   [r2+], r4
-	lslq     9, r4		; Command starts at bit 9
+	lslq     9, r4	; Command starts at bit 9
 	or.d     r1, r4
 	move.d   r4, [R_SDRAM_TIMING]
-	nop			; Wait five nop cycles between each command
+	nop		; Wait five nop cycles between each command
 	nop
 	nop
 	nop
@@ -94,6 +131,7 @@
 	cmp.d    r2, r3
 	bne      command_loop
 	nop
+	move.d   r5, [R_SDRAM_TIMING]
 	ba       sdram_commands_end
 	nop
 
diff -u --recursive --new-file v2.4.4/linux/arch/cris/lib/hw_settings.S linux/arch/cris/lib/hw_settings.S
--- v2.4.4/linux/arch/cris/lib/hw_settings.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/cris/lib/hw_settings.S	Sun May 20 12:11:38 2001
@@ -0,0 +1,61 @@
+	;; $Id: hw_settings.S,v 1.2 2001/04/03 11:11:09 starvik Exp $
+	;; 
+	;; This table is used by some tools to extract hardware parameters.
+	;; The table should be included in the kernel and the decompressor.
+	;; Don't forget to update the tools if you change this table.
+	;;
+	;; Copyright (C) 2001 Axis Communications AB
+	;;
+	;; Authors:  Mikael Starvik (starvik@axis.com)	
+
+	
+#define PA_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PA_DIR << 8) | \
+		(CONFIG_ETRAX_DEF_R_PORT_PA_DATA))
+#define PB_SET_VALUE ((CONFIG_ETRAX_DEF_R_PORT_PB_CONFIG << 16) | \
+		(CONFIG_ETRAX_DEF_R_PORT_PB_DIR << 8) | \
+		(CONFIG_ETRAX_DEF_R_PORT_PB_DATA))
+	
+	.ascii "HW_PARAM_MAGIC" ; Magic number
+	.dword 0xc0004000	; Kernel start address
+
+	; Debug port
+#ifdef CONFIG_ETRAX_DEBUG_PORT0
+	.dword 0		
+#elif defined(CONFIG_ETRAX_DEBUG_PORT1)
+	.dword 1
+#elif defined(CONFIG_ETRAX_DEBUG_PORT2)
+	.dword 2
+#elif defined(CONFIG_ETRAX_DEBUG_PORT3)
+	.dword 3
+#else
+	.dword 4 ; No debug
+#endif			
+
+	; SDRAM or EDO DRAM?
+#ifdef CONFIG_ETRAX_SDRAM
+	.dword 1
+#else
+	.dword 0
+#endif
+
+	; Register values 
+	.dword R_WAITSTATES
+	.dword CONFIG_ETRAX_DEF_R_WAITSTATES
+	.dword R_BUS_CONFIG
+	.dword CONFIG_ETRAX_DEF_R_BUS_CONFIG
+#ifdef CONFIG_ETRAX_SDRAM
+	.dword R_SDRAM_CONFIG
+	.dword CONFIG_ETRAX_DEF_R_SDRAM_CONFIG
+	.dword R_SDRAM_TIMING
+	.dword CONFIG_ETRAX_DEF_R_SDRAM_TIMING
+#else
+	.dword R_DRAM_CONFIG
+	.dword CONFIG_ETRAX_DEF_R_DRAM_CONFIG
+	.dword R_DRAM_TIMING
+	.dword CONFIG_ETRAX_DEF_R_DRAM_TIMING
+#endif
+	.dword R_PORT_PA_SET
+	.dword PA_SET_VALUE 
+	.dword R_PORT_PB_SET
+	.dword PB_SET_VALUE
+	.dword 0 ; No more register values
diff -u --recursive --new-file v2.4.4/linux/arch/cris/lib/memset.c linux/arch/cris/lib/memset.c
--- v2.4.4/linux/arch/cris/lib/memset.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/lib/memset.c	Tue May  1 16:04:56 2001
@@ -27,6 +27,8 @@
 /*#                                                                         */
 /*#-------------------------------------------------------------------------*/
 
+#include <linux/types.h>
+
 /* No, there's no macro saying 12*4, since it is "hard" to get it into
    the asm in a good way.  Thus better to expose the problem everywhere.
    */
@@ -39,7 +41,7 @@
 
 void *memset(void *pdst,
              int c,
-             unsigned int plen)
+             size_t plen)
 {
   /* Ok.  Now we want the parameters put in special registers.
      Make sure the compiler is able to make something useful of this. */
@@ -54,7 +56,12 @@
 
   /* Ugh.  This is fragile at best.  Check with newer GCC releases, if
      they compile cascaded "x |= x << 8" sanely! */
-  __asm__("movu.b %0,r13\n\tlslq 8,r13\n\tmove.b %0,r13\n\tmove.d r13,%0\n\tlslq 16,r13\n\tor.d r13,%0"
+  __asm__("movu.b %0,r13\n\t"
+          "lslq 8,r13\n\t"
+	  "move.b %0,r13\n\t"
+	  "move.d r13,%0\n\t"
+	  "lslq 16,r13\n\t"
+	  "or.d r13,%0"
           : "=r" (lc) : "0" (lc) : "r13");
 
   {
diff -u --recursive --new-file v2.4.4/linux/arch/cris/lib/string.c linux/arch/cris/lib/string.c
--- v2.4.4/linux/arch/cris/lib/string.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/lib/string.c	Tue May  1 16:04:56 2001
@@ -31,9 +31,11 @@
 /*#                                                                         */
 /*#-------------------------------------------------------------------------*/
 
+#include <linux/types.h>
+
 void *memcpy(void *pdst,
              const void *psrc,
-             unsigned int pn)
+             size_t pn)
 {
   /* Ok.  Now we want the parameters put in special registers.
      Make sure the compiler is able to make something useful of this.
diff -u --recursive --new-file v2.4.4/linux/arch/cris/mm/extable.c linux/arch/cris/mm/extable.c
--- v2.4.4/linux/arch/cris/mm/extable.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/mm/extable.c	Tue May  1 16:04:56 2001
@@ -37,8 +37,7 @@
 
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
-	ret = search_one_table(_start___ex_table, _stop___ex_table-1, addr);
-	if (ret) return ret;
+	return search_one_table(_start___ex_table, _stop___ex_table-1, addr);
 #else
 	/* The kernel is the last "module" -- no need to treat it special.  */
 	struct module *mp;
diff -u --recursive --new-file v2.4.4/linux/arch/cris/mm/fault.c linux/arch/cris/mm/fault.c
--- v2.4.4/linux/arch/cris/mm/fault.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/mm/fault.c	Tue May  1 16:04:56 2001
@@ -1,11 +1,20 @@
 /*
  *  linux/arch/cris/mm/fault.c
  *
- *  Copyright (C) 2000  Axis Communications AB
+ *  Copyright (C) 2000, 2001  Axis Communications AB
  *
  *  Authors:  Bjorn Wesen 
  * 
  *  $Log: fault.c,v $
+ *  Revision 1.12  2001/04/04 10:51:14  bjornw
+ *  mmap_sem is grabbed for reading
+ *
+ *  Revision 1.11  2001/03/23 07:36:07  starvik
+ *  Corrected according to review remarks
+ *
+ *  Revision 1.10  2001/03/21 16:10:11  bjornw
+ *  CRIS_FRAME_FIXUP not needed anymore, use FRAME_NORMAL
+ *
  *  Revision 1.9  2001/03/05 13:22:20  bjornw
  *  Spell-fix and fix in vmalloc_fault handling
  *
@@ -70,12 +79,12 @@
 
 	address = cause & PAGE_MASK; /* get faulting address */
 	
-	page_id = IO_EXTRACT(R_MMU_CAUSE,  page_id,   cause);
+	D(page_id = IO_EXTRACT(R_MMU_CAUSE,  page_id,   cause));
+	D(acc     = IO_EXTRACT(R_MMU_CAUSE,  acc_excp,  cause));
+	D(inv     = IO_EXTRACT(R_MMU_CAUSE,  inv_excp,  cause));  
+	D(index  =  IO_EXTRACT(R_TLB_SELECT, index,     select));
 	miss    = IO_EXTRACT(R_MMU_CAUSE,  miss_excp, cause);
 	we      = IO_EXTRACT(R_MMU_CAUSE,  we_excp,   cause);
-	acc     = IO_EXTRACT(R_MMU_CAUSE,  acc_excp,  cause);
-	inv     = IO_EXTRACT(R_MMU_CAUSE,  inv_excp,  cause);  
-	index  =  IO_EXTRACT(R_TLB_SELECT, index,     select);
 	
 	D(printk("bus_fault from IRP 0x%x: addr 0x%x, miss %d, inv %d, we %d, acc %d, "
 		 "idx %d pid %d\n",
@@ -304,23 +313,32 @@
 	/* Are we prepared to handle this kernel fault?
 	 *
 	 * (The kernel has valid exception-points in the source 
-	 *  when it accesses user-memory. When it fails in one
+	 *  when it acesses user-memory. When it fails in one
 	 *  of those points, we find it in a table and do a jump
 	 *  to some fixup code that loads an appropriate error
 	 *  code)
 	 */
 
         if ((fixup = search_exception_table(regs->irp)) != 0) {
+		/* Adjust the instruction pointer in the stackframe */
+
                 regs->irp = fixup;
-		regs->frametype = CRIS_FRAME_FIXUP;
+
+		/* We do not want to return by restoring the CPU-state
+		 * anymore, so switch frame-types (see ptrace.h)
+		 */
+
+		regs->frametype = CRIS_FRAME_NORMAL;
+
 		D(printk("doing fixup to 0x%x\n", fixup));
                 return;
         }
 
-/*
- * Oops. The kernel tried to access some bad page. We'll have to
- * terminate things with extreme prejudice.
- */
+	/*
+	 * Oops. The kernel tried to access some bad page. We'll have to
+	 * terminate things with extreme prejudice.
+	 */
+
 	if ((unsigned long) (address) < PAGE_SIZE)
 		printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
 	else
diff -u --recursive --new-file v2.4.4/linux/arch/cris/mm/init.c linux/arch/cris/mm/init.c
--- v2.4.4/linux/arch/cris/mm/init.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/mm/init.c	Tue May  1 16:04:56 2001
@@ -7,6 +7,22 @@
  *  Authors:  Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: init.c,v $
+ *  Revision 1.23  2001/04/04 14:35:40  bjornw
+ *  * Removed get_pte_slow and friends (2.4.3 change)
+ *  * Removed bad_pmd handling (2.4.3 change)
+ *
+ *  Revision 1.22  2001/04/04 13:38:04  matsfg
+ *  Moved ioremap to a separate function instead
+ *
+ *  Revision 1.21  2001/03/27 09:28:33  bjornw
+ *  ioremap used too early - lets try it in mem_init instead
+ *
+ *  Revision 1.20  2001/03/23 07:39:21  starvik
+ *  Corrected according to review remarks
+ *
+ *  Revision 1.19  2001/03/15 14:25:17  bjornw
+ *  More general shadow registers and ioremaped addresses for external I/O
+ *
  *  Revision 1.18  2001/02/23 12:46:44  bjornw
  *  * 0xc was not CSE1; 0x8 is, same as uncached flash, so we move the uncached
  *    flash during CRIS_LOW_MAP from 0xe to 0x8 so both the flash and the I/O
@@ -68,6 +84,7 @@
 #include <asm/pgtable.h>
 #include <asm/dma.h>
 #include <asm/svinto.h>
+#include <asm/io.h>
 
 static unsigned long totalram_pages;
 
@@ -79,128 +96,13 @@
 extern void show_net_buffers(void);
 extern void tlb_init(void);
 
-/*
- * empty_bad_page is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving a inode
- * unused etc..
- *
- * the main point is that when a page table error occurs, we want to get
- * out of the kernel safely before killing the process, so we need something
- * to feed the MMU with when the fault occurs even if we don't have any
- * real PTE's or page tables.
- *
- * empty_bad_page_table is the accompanying page-table: it is initialized
- * to point to empty_bad_page writable-shared entries.
- *
- * empty_zero_page is a special page that is used for zero-initialized
- * data and COW.
- */
 
-unsigned long empty_bad_page_table;
-unsigned long empty_bad_page;
 unsigned long empty_zero_page;
 
-pte_t * __bad_pagetable(void)
-{
-	/* somehow it is enough to just clear it and not fill it with
-	 * bad page PTE's...
-	 */
-	memset((void *)empty_bad_page_table, 0, PAGE_SIZE);
-
-	return (pte_t *) empty_bad_page_table;
-}
-
-pte_t __bad_page(void)
-{
-
-	/* clear the empty_bad_page page. this should perhaps be
-	 * a more simple inlined loop like it is on the other 
-	 * architectures.
-	 */
-
-	memset((void *)empty_bad_page, 0, PAGE_SIZE);
-
-	return pte_mkdirty(__mk_pte((void *)empty_bad_page, PAGE_SHARED));
-}
-
-static pte_t * get_bad_pte_table(void)
-{
-	pte_t *empty_bad_pte_table = (pte_t *)empty_bad_page_table;
-	pte_t v;
-	int i;
-
-	v = __bad_page();
-
-	for (i = 0; i < PAGE_SIZE/sizeof(pte_t); i++)
-		empty_bad_pte_table[i] = v;
-
-	return empty_bad_pte_table;
-}
-
-void __handle_bad_pmd(pmd_t *pmd)
-{
-	pmd_ERROR(*pmd);
-	pmd_set(pmd, get_bad_pte_table());
-}
-
-void __handle_bad_pmd_kernel(pmd_t *pmd)
-{
-	pmd_ERROR(*pmd);
-	pmd_set_kernel(pmd, get_bad_pte_table());
-}
-
-pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
-{
-        pte_t *pte;
-
-        pte = (pte_t *) __get_free_page(GFP_KERNEL);
-        if (pmd_none(*pmd)) {
-                if (pte) {
-                        clear_page(pte);
-			pmd_set_kernel(pmd, pte);
-                        return pte + offset;
-                }
-		pmd_set_kernel(pmd, get_bad_pte_table());
-                return NULL;
-        }
-        free_page((unsigned long)pte);
-        if (pmd_bad(*pmd)) {
-                __handle_bad_pmd_kernel(pmd);
-                return NULL;
-        }
-        return (pte_t *) pmd_page(*pmd) + offset;
-}
-
-pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
-{
-	pte_t *pte;
-
-        pte = (pte_t *) __get_free_page(GFP_KERNEL);
-        if (pmd_none(*pmd)) {
-                if (pte) {
-                        clear_page(pte);
-			pmd_set(pmd, pte);
-                        return pte + offset;
-                }
-		pmd_set(pmd, get_bad_pte_table());
-                return NULL;
-        }
-        free_page((unsigned long)pte);
-        if (pmd_bad(*pmd)) {
-                __handle_bad_pmd(pmd);
-                return NULL;
-        }
-        return (pte_t *) pmd_page(*pmd) + offset;
-}
-
-#ifndef CONFIG_NO_PGT_CACHE
-struct pgtable_cache_struct quicklists;
-
 /* trim the page-table cache if necessary */
 
-int do_check_pgt_cache(int low, int high)
+int 
+do_check_pgt_cache(int low, int high)
 {
         int freed = 0;
 
@@ -211,25 +113,20 @@
                                 freed++;
                         }
                         if(pmd_quicklist) {
-                                free_pmd_slow(get_pmd_fast());
+                                pmd_free_slow(pmd_alloc_one_fast(NULL, 0));
                                 freed++;
                         }
                         if(pte_quicklist) {
-                                free_pte_slow(get_pte_fast());
-                                 freed++;
+                                pte_free_slow(pte_alloc_one_fast(NULL, 0));
+				freed++;
                         }
                 } while(pgtable_cache_size > low);
         }
         return freed;
 }
-#else
-int do_check_pgt_cache(int low, int high)
-{
-        return 0;
-}
-#endif
 
-void show_mem(void)
+void 
+show_mem(void)
 {
 	int i,free = 0,total = 0,cached = 0, reserved = 0, nonshared = 0;
 	int shared = 0;
@@ -287,15 +184,51 @@
 
 	/* see README.mm for details on the KSEG setup */
 
-#ifdef CONFIG_CRIS_LOW_MAP
+#ifndef CONFIG_CRIS_LOW_MAP
+	/* This code is for the corrected Etrax-100 LX version 2... */
 
+	*R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, seg  ) | /* cached flash */
+			IO_STATE(R_MMU_KSEG, seg_e, seg  ) | /* uncached flash */
+			IO_STATE(R_MMU_KSEG, seg_d, page ) | /* vmalloc area */
+			IO_STATE(R_MMU_KSEG, seg_c, seg  ) | /* kernel area */
+			IO_STATE(R_MMU_KSEG, seg_b, seg  ) | /* kernel reg area */
+			IO_STATE(R_MMU_KSEG, seg_a, page ) | /* user area */
+			IO_STATE(R_MMU_KSEG, seg_9, page ) |
+			IO_STATE(R_MMU_KSEG, seg_8, page ) |
+			IO_STATE(R_MMU_KSEG, seg_7, page ) |
+			IO_STATE(R_MMU_KSEG, seg_6, page ) |
+			IO_STATE(R_MMU_KSEG, seg_5, page ) |
+			IO_STATE(R_MMU_KSEG, seg_4, page ) |
+			IO_STATE(R_MMU_KSEG, seg_3, page ) |
+			IO_STATE(R_MMU_KSEG, seg_2, page ) |
+			IO_STATE(R_MMU_KSEG, seg_1, page ) |
+			IO_STATE(R_MMU_KSEG, seg_0, page ) );
+
+	*R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_e, 0x8 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_c, 0x4 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_9, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_8, 0x0 ) );
+	
+	*R_MMU_KBASE_LO = ( IO_FIELD(R_MMU_KBASE_LO, base_7, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_6, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_5, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_4, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_3, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_2, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_1, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_LO, base_0, 0x0 ) );
+#else
 	/* Etrax-100 LX version 1 has a bug so that we cannot map anything
 	 * across the 0x80000000 boundary, so we need to shrink the user-virtual
 	 * area to 0x50000000 instead of 0xb0000000 and map things slightly
 	 * different. The unused areas are marked as paged so that we can catch
 	 * freak kernel accesses there.
 	 *
-	 * The Juliette chip is mapped at 0xa so we pass that segment straight
+	 * The ARTPEC chip is mapped at 0xa so we pass that segment straight
 	 * through. We cannot vremap it because the vmalloc area is below 0x8
 	 * and Juliette needs an uncached area above 0x8.
 	 *
@@ -308,7 +241,7 @@
 			IO_STATE(R_MMU_KSEG, seg_d, page ) | 
 			IO_STATE(R_MMU_KSEG, seg_c, page ) |   
 			IO_STATE(R_MMU_KSEG, seg_b, seg  ) |  /* kernel reg area */
-			IO_STATE(R_MMU_KSEG, seg_a, seg  ) |  /* Juliette etc. */
+			IO_STATE(R_MMU_KSEG, seg_a, seg  ) |  /* ARTPEC etc. */
 			IO_STATE(R_MMU_KSEG, seg_9, seg  ) |  /* LED's on some boards */
 			IO_STATE(R_MMU_KSEG, seg_8, seg  ) |  /* CSE0/1, flash and I/O */
 			IO_STATE(R_MMU_KSEG, seg_7, page ) |  /* kernel vmalloc area */
@@ -337,44 +270,7 @@
 			    IO_FIELD(R_MMU_KBASE_LO, base_2, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_LO, base_1, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_LO, base_0, 0x0 ) );
-#else
-	/* This code is for the hopefully corrected Etrax-100 LX version 2... */
-
-	*R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, seg  ) | /* cached flash */
-			IO_STATE(R_MMU_KSEG, seg_e, seg  ) | /* uncached flash */
-			IO_STATE(R_MMU_KSEG, seg_d, page ) | /* vmalloc area */
-			IO_STATE(R_MMU_KSEG, seg_c, seg  ) | /* kernel area */
-			IO_STATE(R_MMU_KSEG, seg_b, seg  ) | /* kernel reg area */
-			IO_STATE(R_MMU_KSEG, seg_a, page ) | /* user area */
-			IO_STATE(R_MMU_KSEG, seg_9, page ) |
-			IO_STATE(R_MMU_KSEG, seg_8, page ) |
-			IO_STATE(R_MMU_KSEG, seg_7, page ) |
-			IO_STATE(R_MMU_KSEG, seg_6, page ) |
-			IO_STATE(R_MMU_KSEG, seg_5, page ) |
-			IO_STATE(R_MMU_KSEG, seg_4, page ) |
-			IO_STATE(R_MMU_KSEG, seg_3, page ) |
-			IO_STATE(R_MMU_KSEG, seg_2, page ) |
-			IO_STATE(R_MMU_KSEG, seg_1, page ) |
-			IO_STATE(R_MMU_KSEG, seg_0, page ) );
-
-	*R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_HI, base_e, 0x8 ) |
-			    IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_HI, base_c, 0x4 ) |
-			    IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) |
-			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_HI, base_9, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_HI, base_8, 0x0 ) );
-	
-	*R_MMU_KBASE_LO = ( IO_FIELD(R_MMU_KBASE_LO, base_7, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_LO, base_6, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_LO, base_5, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_LO, base_4, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_LO, base_3, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_LO, base_2, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_LO, base_1, 0x0 ) |
-			    IO_FIELD(R_MMU_KBASE_LO, base_0, 0x0 ) );
-#endif	
+#endif
 
 	*R_MMU_CONTEXT = ( IO_FIELD(R_MMU_CONTEXT, page_id, 0 ) );
 	
@@ -393,8 +289,6 @@
 	 * to a couple of allocated pages
 	 */
 
-	empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
-	empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
 	empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
 	memset((void *)empty_zero_page, 0, PAGE_SIZE);
 
@@ -412,6 +306,7 @@
 	 */
 
 	free_area_init_node(0, 0, 0, zones_size, PAGE_OFFSET, 0);
+
 }
 
 extern unsigned long loops_per_jiffy; /* init/main.c */
@@ -462,7 +357,7 @@
 	       datasize >> 10,
 	       initsize >> 10
                );
-	
+
 	/* HACK alert - calculate a loops_per_usec for asm/delay.h here
 	 * since this is called just after calibrate_delay in init/main.c
 	 * but before places which use udelay. cannot be in time.c since
@@ -474,9 +369,52 @@
 	return;
 }
 
+/* Initialize remaps of some I/O-ports. This is designed to be callable
+ * multiple times from the drivers init-sections, because we don't know
+ * beforehand which driver will get initialized first.
+ */
+
+void 
+init_ioremap(void)
+{
+  
+	/* Give the external I/O-port addresses their values */
+
+        static int initialized = 0;
+  
+        if( !initialized ) {
+                initialized++;
+            
+#ifdef CONFIG_CRIS_LOW_MAP
+               /* Simply a linear map (see the KSEG map above in paging_init) */
+               port_cse1_addr = (volatile unsigned long *)(MEM_CSE1_START | 
+                                                           MEM_NON_CACHEABLE);
+               port_csp0_addr = (volatile unsigned long *)(MEM_CSP0_START |
+                                                           MEM_NON_CACHEABLE);
+               port_csp4_addr = (volatile unsigned long *)(MEM_CSP4_START |
+                                                           MEM_NON_CACHEABLE);
+#else
+               /* Note that nothing blows up just because we do this remapping 
+                * it's ok even if the ports are not used or connected 
+                * to anything (or connected to a non-I/O thing) */        
+               port_cse1_addr = (volatile unsigned long *)
+                 ioremap((unsigned long)(MEM_CSE1_START | 
+                                         MEM_NON_CACHEABLE), 16);
+               port_csp0_addr = (volatile unsigned long *)
+                 ioremap((unsigned long)(MEM_CSP0_START |
+                                         MEM_NON_CACHEABLE), 16);
+               port_csp4_addr = (volatile unsigned long *)
+                 ioremap((unsigned long)(MEM_CSP4_START |
+                                         MEM_NON_CACHEABLE), 16);
+#endif	
+        }
+}
+
+
 /* free the pages occupied by initialization code */
 
-void free_initmem(void)
+void 
+free_initmem(void)
 {
 #if 0
 	/* currently this is a bad idea since the cramfs image is catted onto
@@ -497,7 +435,8 @@
 #endif
 }
 
-void si_meminfo(struct sysinfo *val)
+void 
+si_meminfo(struct sysinfo *val)
 {
 	int i;
 
diff -u --recursive --new-file v2.4.4/linux/arch/cris/mm/ioremap.c linux/arch/cris/mm/ioremap.c
--- v2.4.4/linux/arch/cris/mm/ioremap.c	Fri Apr  6 10:42:55 2001
+++ linux/arch/cris/mm/ioremap.c	Tue May  1 16:04:56 2001
@@ -51,7 +51,7 @@
 	if (address >= end)
 		BUG();
 	do {
-		pte_t * pte = pte_alloc_kernel(pmd, address);
+		pte_t * pte = pte_alloc(&init_mm, pmd, address);
 		if (!pte)
 			return -ENOMEM;
 		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
@@ -64,6 +64,7 @@
 static int remap_area_pages(unsigned long address, unsigned long phys_addr,
 				 unsigned long size, unsigned long flags)
 {
+	int error;
 	pgd_t * dir;
 	unsigned long end = address + size;
 
@@ -72,19 +73,23 @@
 	flush_cache_all();
 	if (address >= end)
 		BUG();
+	spin_lock(&init_mm.page_table_lock);
 	do {
 		pmd_t *pmd;
-		pmd = pmd_alloc_kernel(dir, address);
+		pmd = pmd_alloc(&init_mm, dir, address);
+		error = -ENOMEM;
 		if (!pmd)
-			return -ENOMEM;
+			break;
 		if (remap_area_pmd(pmd, address, end - address,
-					 phys_addr + address, flags))
-			return -ENOMEM;
+				   phys_addr + address, flags))
+			break;
+		error = 0;
 		address = (address + PGDIR_SIZE) & PGDIR_MASK;
 		dir++;
 	} while (address && (address < end));
+	spin_unlock(&init_mm.page_table_lock);
 	flush_tlb_all();
-	return 0;
+	return error;
 }
 
 /*
diff -u --recursive --new-file v2.4.4/linux/arch/cris/mm/tlb.c linux/arch/cris/mm/tlb.c
--- v2.4.4/linux/arch/cris/mm/tlb.c	Thu Feb  8 16:32:44 2001
+++ linux/arch/cris/mm/tlb.c	Tue May  1 16:04:56 2001
@@ -288,7 +288,7 @@
 
 	/* clear the page_id map */
 
-	for(i = 0; i < 64; i++)
+	for(i = 0; i < NUM_PAGEID; i++)
 		page_id_map[i] = NULL;
 	
 	/* invalidate the entire TLB */
diff -u --recursive --new-file v2.4.4/linux/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
--- v2.4.4/linux/arch/i386/boot/setup.S	Wed Apr 11 18:50:25 2001
+++ linux/arch/i386/boot/setup.S	Tue May  1 16:04:56 2001
@@ -32,6 +32,16 @@
  *
  * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999.
  * <stiker@northlink.com>
+ *
+ * Fix to work around buggy BIOSes which dont use carry bit correctly
+ * and/or report extended memory in CX/DX for e801h memory size detection 
+ * call.  As a result the kernel got wrong figures.  The int15/e801h docs
+ * from Ralf Brown interrupt list seem to indicate AX/BX should be used
+ * anyway.  So to avoid breaking many machines (presumably there was a reason
+ * to orginally use CX/DX instead of AX/BX), we do a kludge to see
+ * if CX/DX have been changed in the e801 call and if so use AX/BX .
+ * Michael Miller, April 2001 <michaelm@mjmm.org>
+ *
  */
 
 #define __ASSEMBLY__
@@ -336,10 +346,24 @@
 # to write everything into the same place.)
 
 meme801:
+	stc					# fix to work around buggy
+	xorw	%cx,%cx				# BIOSes which dont clear/set
+	xorw	%dx,%dx				# carry on pass/error of
+						# e801h memory size call
+						# or merely pass cx,dx though
+						# without changing them.
 	movw	$0xe801, %ax
 	int	$0x15
 	jc	mem88
 
+	cmpw	$0x0, %cx			# Kludge to handle BIOSes
+	jne	e801usecxdx			# which report their extended
+	cmpw	$0x0, %dx			# memory in AX/BX rather than
+	jne	e801usecxdx			# CX/DX.  The spec I have read
+	movw	%ax, %cx			# seems to indicate AX/BX 
+	movw	%bx, %dx			# are more reasonable anyway...
+
+e801usecxdx:
 	andl	$0xffff, %edx			# clear sign extend
 	shll	$6, %edx			# and go from 64k to 1k chunks
 	movl	%edx, (0x1e0)			# store extended memory size
diff -u --recursive --new-file v2.4.4/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.4.4/linux/arch/i386/config.in	Fri Apr 20 18:26:15 2001
+++ linux/arch/i386/config.in	Wed May 16 10:06:07 2001
@@ -27,21 +27,21 @@
 mainmenu_option next_comment
 comment 'Processor type and features'
 choice 'Processor family' \
-	"386				CONFIG_M386 \
-	 486				CONFIG_M486 \
-	 586/K5/5x86/6x86/6x86MX	CONFIG_M586 \
-	 Pentium-Classic		CONFIG_M586TSC \
-	 Pentium-MMX			CONFIG_M586MMX \
-	 Pentium-Pro/Celeron/Pentium-II	CONFIG_M686 \
-	 Pentium-III			CONFIG_MPENTIUMIII \
-	 Pentium-4			CONFIG_MPENTIUM4 \
-	 K6/K6-II/K6-III		CONFIG_MK6 \
-	 Athlon/Duron/K7		CONFIG_MK7 \
-	 Crusoe				CONFIG_MCRUSOE \
-	 Winchip-C6			CONFIG_MWINCHIPC6 \
-	 Winchip-2			CONFIG_MWINCHIP2 \
-	 Winchip-2A/Winchip-3		CONFIG_MWINCHIP3D \
-	 CyrixIII/C3			CONFIG_MCYRIXIII" Pentium-Pro
+	"386					CONFIG_M386 \
+	 486					CONFIG_M486 \
+	 586/K5/5x86/6x86/6x86MX		CONFIG_M586 \
+	 Pentium-Classic			CONFIG_M586TSC \
+	 Pentium-MMX				CONFIG_M586MMX \
+	 Pentium-Pro/Celeron/Pentium-II		CONFIG_M686 \
+	 Pentium-III/Celeron-Coppermine		CONFIG_MPENTIUMIII \
+	 Pentium-4				CONFIG_MPENTIUM4 \
+	 K6/K6-II/K6-III			CONFIG_MK6 \
+	 Athlon/Duron/K7			CONFIG_MK7 \
+	 Crusoe					CONFIG_MCRUSOE \
+	 Winchip-C6				CONFIG_MWINCHIPC6 \
+	 Winchip-2				CONFIG_MWINCHIP2 \
+	 Winchip-2A/Winchip-3			CONFIG_MWINCHIP3D \
+	 CyrixIII/C3				CONFIG_MCYRIXIII" Pentium-Pro
 #
 # Define implied options from the CPU selection here
 #
diff -u --recursive --new-file v2.4.4/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.4.4/linux/arch/i386/defconfig	Fri Apr 27 14:41:16 2001
+++ linux/arch/i386/defconfig	Tue May 22 10:53:06 2001
@@ -382,6 +382,7 @@
 CONFIG_EEPRO100=y
 # CONFIG_EEPRO100_PM is not set
 # CONFIG_LNE390 is not set
+# CONFIG_FEALNX is not set
 # CONFIG_NATSEMI is not set
 # CONFIG_NE2K_PCI is not set
 # CONFIG_NE3210 is not set
@@ -441,7 +442,6 @@
 # CONFIG_PCMCIA_XIRTULIP is not set
 CONFIG_NET_PCMCIA_RADIO=y
 CONFIG_PCMCIA_RAYCS=y
-# CONFIG_PCMCIA_HERMES is not set
 # CONFIG_PCMCIA_NETWAVE is not set
 # CONFIG_PCMCIA_WAVELAN is not set
 # CONFIG_AIRONET4500_CS is not set
@@ -573,6 +573,7 @@
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
 # CONFIG_HPFS_FS is not set
@@ -676,6 +677,7 @@
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
 # CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_DPCM is not set
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
 
@@ -700,6 +702,7 @@
 #
 # CONFIG_USB_IBMCAM is not set
 # CONFIG_USB_OV511 is not set
+# CONFIG_USB_PWC is not set
 # CONFIG_USB_DSBR is not set
 # CONFIG_USB_DABUSB is not set
 
diff -u --recursive --new-file v2.4.4/linux/arch/i386/kernel/bluesmoke.c linux/arch/i386/kernel/bluesmoke.c
--- v2.4.4/linux/arch/i386/kernel/bluesmoke.c	Wed Apr 11 19:02:27 2001
+++ linux/arch/i386/kernel/bluesmoke.c	Mon May 21 12:34:50 2001
@@ -1,16 +1,18 @@
-/*
- *	Machine Check Handler For PII/PIII
- */
 
+#include <linux/init.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/processor.h> 
 #include <asm/msr.h>
 
+/*
+ *	Machine Check Handler For PII/PIII
+ */
+
 static int banks;
 
-void do_machine_check(struct pt_regs * regs, long error_code)
+static void intel_machine_check(struct pt_regs * regs, long error_code)
 {
 	int recover=1;
 	u32 alow, ahigh, high, low;
@@ -62,28 +64,101 @@
 	wrmsr(0x17a,mcgstl, mcgsth);
 }
 
+/*
+ *	Machine check handler for Pentium class Intel
+ */
+ 
+static void pentium_machine_check(struct pt_regs * regs, long error_code)
+{
+	u32 loaddr, hi, lotype;
+	rdmsr(0x0, loaddr, hi);
+	rdmsr(0x1, lotype, hi);
+	printk(KERN_EMERG "CPU#%d: Machine Check Exception:  0x%8X (type 0x%8X).\n", smp_processor_id(), loaddr, lotype);
+	if(lotype&(1<<5))
+		printk(KERN_EMERG "CPU#%d: Possible thermal failure (CPU on fire ?).\n", smp_processor_id());
+}
 
 /*
- *	This has to be run for each processor
+ *	Machine check handler for WinChip C6
+ */
+ 
+static void winchip_machine_check(struct pt_regs * regs, long error_code)
+{
+	printk(KERN_EMERG "CPU#%d: Machine Check Exception.\n", smp_processor_id());
+}
+
+/*
+ *	Handle unconfigured int18 (should never happen)
  */
+
+static void unexpected_machine_check(struct pt_regs * regs, long error_code)
+{	
+	printk(KERN_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", smp_processor_id());
+}
+
+/*
+ *	Call the installed machine check handler for this CPU setup.
+ */ 
  
-void mcheck_init(struct cpuinfo_x86 *c)
+static void (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;
+
+void do_machine_check(struct pt_regs * regs, long error_code)
+{
+	machine_check_vector(regs, error_code);
+}
+
+/*
+ *	Set up machine check reporting for Intel processors
+ */
+
+void __init intel_mcheck_init(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
 	int i;
 	static int done;
-
-	if( c->x86_vendor != X86_VENDOR_INTEL )
-		return;
 	
+	/*
+	 *	Check for MCE support
+	 */
+
 	if( !test_bit(X86_FEATURE_MCE, &c->x86_capability) )
+		return;	
+	
+	/*
+	 *	Pentium machine check
+	 */
+	
+	if(c->x86 == 5)
+	{
+		machine_check_vector = pentium_machine_check;
+		wmb();
+		/* Read registers before enabling */
+		rdmsr(0x0, l, h);
+		rdmsr(0x1, l, h);
+		if(done==0)
+			printk(KERN_INFO "Intel old style machine check architecture supported.\n");
+		/* Enable MCE */		
+		__asm__ __volatile__ (
+			"movl %%cr4, %%eax\n\t"
+			"orl $0x40, %%eax\n\t"
+			"movl %%eax, %%cr4\n\t" : : : "eax");
+		printk(KERN_INFO "Intel old style machine check reporting enabled on CPU#%d.\n", smp_processor_id());
 		return;
-		
+	}
+	
+
+	/*
+	 *	Check for PPro style MCA
+	 */
+	 		
 	if( !test_bit(X86_FEATURE_MCA, &c->x86_capability) )
 		return;
 		
 	/* Ok machine check is available */
 	
+	machine_check_vector = intel_machine_check;
+	wmb();
+	
 	if(done==0)
 		printk(KERN_INFO "Intel machine check architecture supported.\n");
 	rdmsr(0x179, l, h);
@@ -98,10 +173,56 @@
 	{
 		wrmsr(0x401+4*i, 0x0, 0x0); 
 	}
+	set_in_cr4(X86_CR4_MCE);
+	printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", smp_processor_id());
+	done=1;
+}
+
+/*
+ *	Set up machine check reporting on the Winchip C6 series
+ */
+ 
+static void winchip_mcheck_init(struct cpuinfo_x86 *c)
+{
+	u32 lo, hi;
+	/* Not supported on C3 */
+	if(c->x86 != 5)
+		return;
+	/* Winchip C6 */
+	machine_check_vector = winchip_machine_check;
+	wmb();
+	rdmsr(0x107, lo, hi);
+	lo|= (1<<2);	/* Enable EIERRINT (int 18 MCE) */
+	lo&= ~(1<<4);	/* Enable MCE */
+	wrmsr(0x107, lo, hi);
 	__asm__ __volatile__ (
 		"movl %%cr4, %%eax\n\t"
 		"orl $0x40, %%eax\n\t"
 		"movl %%eax, %%cr4\n\t" : : : "eax");
-	printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", smp_processor_id());
-	done=1;
+	printk(KERN_INFO "Winchip machine check reporting enabled on CPU#%d.\n", smp_processor_id());
+}
+
+
+/*
+ *	This has to be run for each processor
+ */
+
+void __init mcheck_init(struct cpuinfo_x86 *c)
+{
+	switch(c->x86_vendor)
+	{
+		case X86_VENDOR_AMD:
+			/*
+			 *	AMD K7 machine check is Intel like
+			 */
+			if(c->x86 == 6)
+				intel_mcheck_init(c);
+			break;
+		case X86_VENDOR_INTEL:
+			intel_mcheck_init(c);
+			break;
+		case X86_VENDOR_CENTAUR:
+			winchip_mcheck_init(c);
+			break;
+	}
 }
diff -u --recursive --new-file v2.4.4/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- v2.4.4/linux/arch/i386/kernel/i386_ksyms.c	Wed Apr 25 13:31:03 2001
+++ linux/arch/i386/kernel/i386_ksyms.c	Tue May 15 08:46:20 2001
@@ -112,6 +112,7 @@
 
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL(pcibios_penalize_isa_irq);
+EXPORT_SYMBOL(pci_mem_start);
 #endif
 
 #ifdef CONFIG_X86_USE_3DNOW
diff -u --recursive --new-file v2.4.4/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c
--- v2.4.4/linux/arch/i386/kernel/mtrr.c	Wed Apr 11 19:02:27 2001
+++ linux/arch/i386/kernel/mtrr.c	Tue May  1 16:04:56 2001
@@ -646,12 +646,32 @@
     unsigned long low;
 } centaur_mcr[8];
 
+static u8 centaur_mcr_reserved;
+static u8 centaur_mcr_type;		/* 0 for winchip, 1 for winchip2 */
+
+/*
+ *	Report boot time MCR setups 
+ */
+ 
+void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
+{
+	centaur_mcr[mcr].low = lo;
+	centaur_mcr[mcr].high = hi;
+}
+
 static void centaur_get_mcr (unsigned int reg, unsigned long *base,
 			     unsigned long *size, mtrr_type *type)
 {
     *base = centaur_mcr[reg].high >> PAGE_SHIFT;
     *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT;
     *type = MTRR_TYPE_WRCOMB;	/*  If it is there, it is write-combining  */
+    if(centaur_mcr_type==1 && ((centaur_mcr[reg].low&31)&2))
+    	*type = MTRR_TYPE_UNCACHABLE;
+    if(centaur_mcr_type==1 && (centaur_mcr[reg].low&31)==25)
+    	*type = MTRR_TYPE_WRBACK;
+    if(centaur_mcr_type==0 && (centaur_mcr[reg].low&31)==31)
+    	*type = MTRR_TYPE_WRBACK;
+    
 }   /*  End Function centaur_get_mcr  */
 
 static void (*get_mtrr) (unsigned int reg, unsigned long *base,
@@ -794,7 +814,15 @@
     else
     {
 	high = base << PAGE_SHIFT;
-	low = -size << PAGE_SHIFT | 0x1f; /* only support write-combining... */
+	if(centaur_mcr_type == 0)
+		low = -size << PAGE_SHIFT | 0x1f; /* only support write-combining... */
+	else
+	{
+		if(type == MTRR_TYPE_UNCACHABLE)
+			low = -size << PAGE_SHIFT | 0x02;	/* NC */
+		else
+			low = -size << PAGE_SHIFT | 0x09;	/* WWO,WC */
+	}
     }
     centaur_mcr[reg].high = high;
     centaur_mcr[reg].low = low;
@@ -1104,6 +1132,28 @@
     return -ENOSPC;
 }   /*  End Function generic_get_free_region  */
 
+static int centaur_get_free_region (unsigned long base, unsigned long size)
+/*  [SUMMARY] Get a free MTRR.
+    <base> The starting (base) address of the region.
+    <size> The size (in bytes) of the region.
+    [RETURNS] The index of the region on success, else -1 on error.
+*/
+{
+    int i, max;
+    mtrr_type ltype;
+    unsigned long lbase, lsize;
+
+    max = get_num_var_ranges ();
+    for (i = 0; i < max; ++i)
+    {
+    	if(centaur_mcr_reserved & (1<<i))
+    		continue;
+	(*get_mtrr) (i, &lbase, &lsize, &ltype);
+	if (lsize == 0) return i;
+    }
+    return -ENOSPC;
+}   /*  End Function generic_get_free_region  */
+
 static int cyrix_get_free_region (unsigned long base, unsigned long size)
 /*  [SUMMARY] Get a free ARR.
     <base> The starting (base) address of the region.
@@ -1164,9 +1214,9 @@
  *
  *	The available types are
  *
- *	%MTRR_TYPE_UNCACHEABLE	-	No caching
+ *	%MTRR_TYPE_UNCACHABLE	-	No caching
  *
- *	%MTRR_TYPE_WRITEBACK	-	Write data back in bursts whenever
+ *	%MTRR_TYPE_WRBACK	-	Write data back in bursts whenever
  *
  *	%MTRR_TYPE_WRCOMB	-	Write data back soon but allow bursts
  *
@@ -1229,9 +1279,13 @@
     case MTRR_IF_CENTAUR_MCR:
         if ( mtrr_if == MTRR_IF_CENTAUR_MCR )
 	{
-	    if (type != MTRR_TYPE_WRCOMB)
+	    /*
+	     *	FIXME: Winchip2 supports uncached
+	     */
+	    if (type != MTRR_TYPE_WRCOMB && (centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE))
 	    {
-		printk (KERN_WARNING "mtrr: only write-combining is supported\n");
+		printk (KERN_WARNING "mtrr: only write-combining%s supported\n",
+			centaur_mcr_type?" and uncacheable are":" is");
 		return -EINVAL;
 	    }
 	}
@@ -1348,9 +1402,9 @@
  *
  *	The available types are
  *
- *	%MTRR_TYPE_UNCACHEABLE	-	No caching
+ *	%MTRR_TYPE_UNCACHABLE	-	No caching
  *
- *	%MTRR_TYPE_WRITEBACK	-	Write data back in bursts whenever
+ *	%MTRR_TYPE_WRBACK	-	Write data back in bursts whenever
  *
  *	%MTRR_TYPE_WRCOMB	-	Write data back soon but allow bursts
  *
@@ -1947,23 +2001,64 @@
 {
     unsigned i;
     struct set_mtrr_context ctxt;
+    u32 lo, hi;
+    int wc2 = -1;
 
     set_mtrr_prepare (&ctxt);
     /* Unfortunately, MCR's are read-only, so there is no way to
      * find out what the bios might have done.
      */
-    /* Clear all MCR's.
+     
+    /*
+     *	Enable MCR key if we are using a winchip2
+     */
+     
+    if(boot_cpu_data.x86_model==4)
+    	wc2 = 0;
+    	
+    if(boot_cpu_data.x86_model==8 || boot_cpu_data.x86_model == 9)
+    {
+	    rdmsr(0x120, lo, hi);
+	    if(((lo>>17)&7)==1)		/* Type 1 Winchip2 MCR */
+	    {
+	    	lo&= ~0x1C0;		/* clear key */
+	    	lo|= 0x040;		/* set key to 1 */
+		wrmsr(0x120, lo, hi);	/* unlock MCR */
+		wc2 = 1;
+		centaur_mcr_type = 1;
+	    }
+    }    
+    /* Clear any unconfigured MCR's.
      * This way we are sure that the centaur_mcr array contains the actual
      * values. The disadvantage is that any BIOS tweaks are thus undone.
+     *
      */
     for (i = 0; i < 8; ++i)
     {
-        centaur_mcr[i].high = 0;
-	centaur_mcr[i].low = 0;
-	wrmsr (0x110 + i , 0, 0);
+    	if(centaur_mcr[i]. high == 0 && centaur_mcr[i].low == 0)
+    	{
+    		if(wc2 == 0 || ( wc2 == 1 && !(lo & (1<<(9+i)))))
+			wrmsr (0x110 + i , 0, 0);
+		else
+			/*
+			 *	If the BIOS set up an MCR we cannot see it
+			 *	but we don't wish to obliterate it
+			 */
+			centaur_mcr_reserved |= (1<<i);
+	}
+    }
+    /*  Throw the main write-combining switch... 
+        However if OOSTORE is enabled then people have already done far
+        cleverer things and we should behave. 
+     */
+
+    if(wc2 == 1)
+    {     
+	    lo |= 15;			/* Write combine enables */
+	    wrmsr(0x120, lo, hi);
     }
-    /*  Throw the main write-combining switch...  */
-    wrmsr (0x120, 0x01f0001f, 0);
+    else if(wc2 == 0)
+    	wrmsr(0x120, 0x01F0001F, 0);	/* Write only */
     set_mtrr_done (&ctxt);
 }   /*  End Function centaur_mcr_init  */
 
@@ -2036,6 +2131,7 @@
 	mtrr_if = MTRR_IF_CENTAUR_MCR;
 	get_mtrr = centaur_get_mcr;
 	set_mtrr_up = centaur_set_mcr_up;
+	get_free_region = centaur_get_free_region;
 	centaur_mcr_init();
 	size_or_mask  = 0xfff00000; /* 32 bits */
 	size_and_mask = 0;
diff -u --recursive --new-file v2.4.4/linux/arch/i386/kernel/pci-i386.c linux/arch/i386/kernel/pci-i386.c
--- v2.4.4/linux/arch/i386/kernel/pci-i386.c	Mon Aug  7 14:31:40 2000
+++ linux/arch/i386/kernel/pci-i386.c	Sat May 19 18:07:04 2001
@@ -350,3 +350,35 @@
 	printk("PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat);
 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
 }
+
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state, int write_combine)
+{
+	unsigned long prot;
+
+	/* I/O space cannot be accessed via normal processor loads and
+	 * stores on this platform.
+	 */
+	if (mmap_state == pci_mmap_io)
+		return -EINVAL;
+
+	/* Leave vm_pgoff as-is, the PCI space address is the physical
+	 * address on this platform.
+	 */
+	vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
+
+	prot = pgprot_val(vma->vm_page_prot);
+	if (boot_cpu_data.x86 > 3)
+		prot |= _PAGE_PCD | _PAGE_PWT;
+	vma->vm_page_prot = __pgprot(prot);
+
+	/* Write-combine setting is ignored, it is changed via the mtrr
+	 * interfaces on this platform.
+	 */
+	if (remap_page_range(vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
+			     vma->vm_end - vma->vm_start,
+			     vma->vm_page_prot))
+		return -EAGAIN;
+
+	return 0;
+}
diff -u --recursive --new-file v2.4.4/linux/arch/i386/kernel/pci-irq.c linux/arch/i386/kernel/pci-irq.c
--- v2.4.4/linux/arch/i386/kernel/pci-irq.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/i386/kernel/pci-irq.c	Wed May 16 10:25:39 2001
@@ -105,7 +105,7 @@
 		 *  known (ascending bus order) and therefore pci_scan_bus returns immediately.
 		 */
 		if (busmap[i] && pci_scan_bus(i, pci_root_bus->ops, NULL))
-			printk("PCI: Discovered primary peer bus %02x [IRQ]\n", i);
+			printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i);
 	pcibios_last_bus = -1;
 }
 
@@ -295,10 +295,10 @@
 		case 0x61:
 		case 0x6a:
 		case 0x7e:
-			printk("SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n");
+			printk(KERN_INFO "SiS pirq: advanced IDE/ACPI/DAQ mapping not yet implemented\n");
 			return 0;
 		default:			
-			printk("SiS router pirq escape (%d)\n", pirq);
+			printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
 			return 0;
 	}
 	return (x & 0x80) ? 0 : (x & 0x0f);
@@ -329,10 +329,10 @@
 		case 0x61:
 		case 0x6a:
 		case 0x7e:
-			printk("advanced SiS pirq mapping not yet implemented\n");
+			printk(KERN_INFO "advanced SiS pirq mapping not yet implemented\n");
 			return 0;
 		default:			
-			printk("SiS router pirq escape (%d)\n", pirq);
+			printk(KERN_INFO "SiS router pirq escape (%d)\n", pirq);
 			return 0;
 	}
 	pci_write_config_byte(router, reg, x);
@@ -351,7 +351,7 @@
 static int pirq_vlsi_get(struct pci_dev *router, struct pci_dev *dev, int pirq)
 {
 	if (pirq > 8) {
-		printk("VLSI router pirq escape (%d)\n", pirq);
+		printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
 		return 0;
 	}
 	return read_config_nybble(router, 0x74, pirq-1);
@@ -360,7 +360,7 @@
 static int pirq_vlsi_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq)
 {
 	if (pirq > 8) {
-		printk("VLSI router pirq escape (%d)\n", pirq);
+		printk(KERN_INFO "VLSI router pirq escape (%d)\n", pirq);
 		return 0;
 	}
 	write_config_nybble(router, 0x74, pirq-1, irq);
@@ -411,6 +411,7 @@
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX,   pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82820FW_0, pirq_piix_get, pirq_piix_set },
 
 	{ "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set },
 
@@ -439,13 +440,17 @@
 
 #ifdef CONFIG_PCI_BIOS
 	if (!rt->signature) {
-		printk("PCI: Using BIOS for IRQ routing\n");
+		printk(KERN_INFO "PCI: Using BIOS for IRQ routing\n");
 		pirq_router = &pirq_bios_router;
 		return;
 	}
 #endif
+
+	DBG("PCI: Attempting to find IRQ router for %04x:%04x\n",
+	    rt->rtr_vendor, rt->rtr_device);
+
 	/* fall back to default router if nothing else found */
-	pirq_router = pirq_routers + sizeof(pirq_routers) / sizeof(pirq_routers[0]) - 1;
+	pirq_router = &pirq_routers[ARRAY_SIZE(pirq_routers) - 1];
 
 	pirq_router_dev = pci_find_slot(rt->rtr_bus, rt->rtr_devfn);
 	if (!pirq_router_dev) {
@@ -464,7 +469,7 @@
 			pirq_router = r;
 		}
 	}
-	printk("PCI: Using IRQ router %s [%04x/%04x] at %s\n",
+	printk(KERN_INFO "PCI: Using IRQ router %s [%04x/%04x] at %s\n",
 		pirq_router->name,
 		pirq_router_dev->vendor,
 		pirq_router_dev->device,
@@ -568,7 +573,7 @@
 		} else
 			return 0;
 	}
-	printk("PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name);
+	printk(KERN_INFO "PCI: %s IRQ %d for device %s\n", msg, irq, dev->slot_name);
 
 	/* Update IRQ for all devices with the same pirq value */
 	pci_for_each_dev(dev2) {
@@ -582,13 +587,13 @@
 		if (info->irq[pin].link == pirq) {
 			/* We refuse to override the dev->irq information. Give a warning! */
 		    	if (dev2->irq && dev2->irq != irq) {
-		    		printk("IRQ routing conflict in pirq table for device %s\n", dev2->slot_name);
+		    		printk(KERN_INFO "IRQ routing conflict in pirq table for device %s\n", dev2->slot_name);
 		    		continue;
 		    	}
 			dev2->irq = irq;
 			pirq_penalty[irq]++;
 			if (dev != dev2)
-				printk("PCI: The same IRQ used for device %s\n", dev2->slot_name);
+				printk(KERN_INFO "PCI: The same IRQ used for device %s\n", dev2->slot_name);
 		}
 	}
 	return 1;
@@ -667,7 +672,7 @@
 				}
 #endif
 				if (irq >= 0) {
-					printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
+					printk(KERN_INFO "PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n",
 						dev->bus->number, PCI_SLOT(dev->devfn), pin, irq);
 					dev->irq = irq;
 				}
diff -u --recursive --new-file v2.4.4/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.4.4/linux/arch/i386/kernel/setup.c	Fri Apr 27 14:10:32 2001
+++ linux/arch/i386/kernel/setup.c	Tue May 22 10:23:16 2001
@@ -127,6 +127,9 @@
 unsigned int BIOS_revision;
 unsigned int mca_pentium_flag;
 
+/* For PCI or other memory-mapped resources */
+unsigned long pci_mem_start = 0x10000000;
+
 /*
  * Setup options
  */
@@ -1009,6 +1012,9 @@
 	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
 		request_resource(&ioport_resource, standard_io_resources+i);
 
+	/* Tell the PCI layer not to allocate too close to the RAM area.. */
+	pci_mem_start = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
+
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
 	conswitchp = &vga_con;
@@ -1657,7 +1663,7 @@
 
 	/* Unhide possibly hidden capability flags
 	   The mp6 iDragon family don't have MSRs.
-	   We switch on extra features with this cpuid wierdness: */
+	   We switch on extra features with this cpuid weirdness: */
 	__asm__ (
 		"movl $0x6363452a, %%eax\n\t"
 		"movl $0x3231206c, %%ecx\n\t"
@@ -2268,7 +2274,7 @@
 
 	/* Now the feature flags better reflect actual CPU features! */
 
-	printk(KERN_DEBUG "CPU: After generic, caps: %08x %08x %08x %08x\n",
+	printk(KERN_DEBUG "CPU:     After generic, caps: %08x %08x %08x %08x\n",
 	       c->x86_capability[0],
 	       c->x86_capability[1],
 	       c->x86_capability[2],
@@ -2286,7 +2292,7 @@
 			boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
 	}
 
-	printk(KERN_DEBUG "CPU: Common caps: %08x %08x %08x %08x\n",
+	printk(KERN_DEBUG "CPU:             Common caps: %08x %08x %08x %08x\n",
 	       boot_cpu_data.x86_capability[0],
 	       boot_cpu_data.x86_capability[1],
 	       boot_cpu_data.x86_capability[2],
diff -u --recursive --new-file v2.4.4/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- v2.4.4/linux/arch/i386/kernel/traps.c	Mon Mar 19 18:23:40 2001
+++ linux/arch/i386/kernel/traps.c	Mon May  7 14:15:21 2001
@@ -973,7 +973,7 @@
 	set_trap_gate(11,&segment_not_present);
 	set_trap_gate(12,&stack_segment);
 	set_trap_gate(13,&general_protection);
-	set_trap_gate(14,&page_fault);
+	set_intr_gate(14,&page_fault);
 	set_trap_gate(15,&spurious_interrupt_bug);
 	set_trap_gate(16,&coprocessor_error);
 	set_trap_gate(17,&alignment_check);
diff -u --recursive --new-file v2.4.4/linux/arch/i386/lib/mmx.c linux/arch/i386/lib/mmx.c
--- v2.4.4/linux/arch/i386/lib/mmx.c	Wed Apr 11 19:02:27 2001
+++ linux/arch/i386/lib/mmx.c	Tue May 22 10:23:16 2001
@@ -163,7 +163,7 @@
 		".previous"
 		: : "r" (from) );
 
-	for(i=0; i<4096/64; i++)
+	for(i=0; i<(4096-320)/64; i++)
 	{
 		__asm__ __volatile__ (
 		"1: prefetch 320(%0)\n"
@@ -195,6 +195,29 @@
 		from+=64;
 		to+=64;
 	}
+	for(i=(4096-320)/64; i<4096/64; i++)
+	{
+		__asm__ __volatile__ (
+		"2: movq (%0), %%mm0\n"
+		"   movntq %%mm0, (%1)\n"
+		"   movq 8(%0), %%mm1\n"
+		"   movntq %%mm1, 8(%1)\n"
+		"   movq 16(%0), %%mm2\n"
+		"   movntq %%mm2, 16(%1)\n"
+		"   movq 24(%0), %%mm3\n"
+		"   movntq %%mm3, 24(%1)\n"
+		"   movq 32(%0), %%mm4\n"
+		"   movntq %%mm4, 32(%1)\n"
+		"   movq 40(%0), %%mm5\n"
+		"   movntq %%mm5, 40(%1)\n"
+		"   movq 48(%0), %%mm6\n"
+		"   movntq %%mm6, 48(%1)\n"
+		"   movq 56(%0), %%mm7\n"
+		"   movntq %%mm7, 56(%1)\n"
+		: : "r" (from), "r" (to) : "memory");
+		from+=64;
+		to+=64;
+	}
 	/* since movntq is weakly-ordered, a "sfence" is needed to become
 	 * ordered again.
 	 */
@@ -213,13 +236,8 @@
 static void fast_clear_page(void *page)
 {
 	int i;
-	if (!(current->flags & PF_USEDFPU))
-		clts();
-	else
-	{
-		__asm__ __volatile__ ( " fnsave %0; fwait\n"::"m"(current->thread.i387));
-		current->flags &= ~PF_USEDFPU;
-	}
+	
+	kernel_fpu_begin();
 	
 	__asm__ __volatile__ (
 		"  pxor %%mm0, %%mm0\n" : :
@@ -247,19 +265,16 @@
 		: : "r" (page) : "memory");
 		page+=128;
 	}
-	stts();
+
+	kernel_fpu_end();
 }
 
 static void fast_copy_page(void *to, void *from)
 {
 	int i;
-	if (!(current->flags & PF_USEDFPU))
-		clts();
-	else
-	{
-		__asm__ __volatile__ ( " fnsave %0; fwait\n"::"m"(current->thread.i387));
-		current->flags &= ~PF_USEDFPU;
-	}
+	
+	
+	kernel_fpu_begin();
 
 	__asm__ __volatile__ (
 		"1: prefetch (%0)\n"
@@ -310,7 +325,7 @@
 		from+=64;
 		to+=64;
 	}
-	stts();
+	kernel_fpu_end();
 }
 
 
diff -u --recursive --new-file v2.4.4/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c
--- v2.4.4/linux/arch/i386/mm/fault.c	Mon Mar 19 12:35:09 2001
+++ linux/arch/i386/mm/fault.c	Tue May 15 00:16:51 2001
@@ -117,6 +117,10 @@
 	/* get the address */
 	__asm__("movl %%cr2,%0":"=r" (address));
 
+	/* It's safe to allow irq's after cr2 has been saved */
+	if (regs->eflags & X86_EFLAGS_IF)
+		local_irq_enable();
+
 	tsk = current;
 
 	/*
@@ -127,8 +131,12 @@
 	 * be in an interrupt or a critical region, and should
 	 * only copy the information from the master page table,
 	 * nothing more.
+	 *
+	 * This verifies that the fault happens in kernel space
+	 * (error_code & 4) == 0, and that the fault was not a
+	 * protection error (error_code & 1) == 0.
 	 */
-	if (address >= TASK_SIZE)
+	if (address >= TASK_SIZE && !(error_code & 5))
 		goto vmalloc_fault;
 
 	mm = tsk->mm;
@@ -224,7 +232,6 @@
 bad_area:
 	up_read(&mm->mmap_sem);
 
-bad_area_nosemaphore:
 	/* User mode accesses just cause a SIGSEGV */
 	if (error_code & 4) {
 		tsk->thread.cr2 = address;
@@ -322,27 +329,32 @@
 		/*
 		 * Synchronize this task's top level page-table
 		 * with the 'reference' page table.
+		 *
+		 * Do _not_ use "tsk" here. We might be inside
+		 * an interrupt in the middle of a task switch..
 		 */
 		int offset = __pgd_offset(address);
 		pgd_t *pgd, *pgd_k;
 		pmd_t *pmd, *pmd_k;
+		pte_t *pte_k;
 
-		pgd = tsk->active_mm->pgd + offset;
+		asm("movl %%cr3,%0":"=r" (pgd));
+		pgd = offset + (pgd_t *)__va(pgd);
 		pgd_k = init_mm.pgd + offset;
 
-		if (!pgd_present(*pgd)) {
-			if (!pgd_present(*pgd_k))
-				goto bad_area_nosemaphore;
-			set_pgd(pgd, *pgd_k);
-			return;
-		}
-
+		if (!pgd_present(*pgd_k))
+			goto no_context;
+		set_pgd(pgd, *pgd_k);
+		
 		pmd = pmd_offset(pgd, address);
 		pmd_k = pmd_offset(pgd_k, address);
-
-		if (pmd_present(*pmd) || !pmd_present(*pmd_k))
-			goto bad_area_nosemaphore;
+		if (!pmd_present(*pmd_k))
+			goto no_context;
 		set_pmd(pmd, *pmd_k);
+
+		pte_k = pte_offset(pmd_k, address);
+		if (!pte_present(*pte_k))
+			goto no_context;
 		return;
 	}
 }
diff -u --recursive --new-file v2.4.4/linux/arch/m68k/config.in linux/arch/m68k/config.in
--- v2.4.4/linux/arch/m68k/config.in	Tue Apr 17 17:19:25 2001
+++ linux/arch/m68k/config.in	Mon May 21 18:12:09 2001
@@ -192,7 +192,7 @@
       int  'Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40
    fi
    dep_tristate '  SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
-   if [ "$CONFIG_BLK_DEV_ST" != "n" ]; then
+   if [ "$CONFIG_CHR_DEV_ST" != "n" ]; then
       int  'Maximum number of SCSI tapes that can be loaded as modules' CONFIG_ST_EXTRA_DEVS 2
    fi
    dep_tristate '  SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
diff -u --recursive --new-file v2.4.4/linux/arch/m68k/lib/semaphore.S linux/arch/m68k/lib/semaphore.S
--- v2.4.4/linux/arch/m68k/lib/semaphore.S	Wed Jan 26 12:44:20 2000
+++ linux/arch/m68k/lib/semaphore.S	Sat May 19 17:43:05 2001
@@ -51,49 +51,3 @@
 	moveml (%sp)+,%a0/%d0/%d1
 	rts
 
-ENTRY(__down_read_failed)
-	moveml %a0/%d0/%d1,-(%sp)
-	jcc 3f
-1:	movel %a1,-(%sp)
-	jbsr SYMBOL_NAME(down_read_failed_biased)
-	movel (%sp)+,%a1
-2:	moveml (%sp)+,%a0/%d0/%d1
-	rts
-
-3:	movel %a1,-(%sp)
-	jbsr SYMBOL_NAME(down_read_failed)
-	movel (%sp)+,%a1
-	subql #1,%a1@
-	jpl 2b
-	jcc 3b
-	jra 1b
-
-ENTRY(__down_write_failed)
-	moveml %a0/%d0/%d1,-(%sp)
-	jcc 3f
-1:	movel %a1,-(%sp)
-	jbsr SYMBOL_NAME(down_write_failed_biased)
-	movel (%sp)+,%a1
-2:	moveml (%sp)+,%a0/%d0/%d1
-	rts
-
-3:	movel %a1,-(%sp)
-	jbsr SYMBOL_NAME(down_write_failed)
-	movel (%sp)+,%a1
-	subl #RW_LOCK_BIAS,%a1@
-	jpl 2b
-	jcc 3b
-	jra 1b
-
-ENTRY(__rwsem_wake)
-	moveml %a0/%d0/%d1,-(%sp)
-	jeq 1f
-	movel %a1,-(%sp)
-	jbsr SYMBOL_NAME(rwsem_wake_readers)
-	jra 2f
-1:	movel %a1,-(%sp)
-	jbsr rwsem_wake_writer
-2:	movel (%sp)+,%a1
-	moveml (%sp)+,%a0/%d0/%d1
-	rts
-
diff -u --recursive --new-file v2.4.4/linux/arch/m68k/mm/memory.c linux/arch/m68k/mm/memory.c
--- v2.4.4/linux/arch/m68k/mm/memory.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/m68k/mm/memory.c	Sat May 19 17:43:05 2001
@@ -246,6 +246,10 @@
 		voff -= m68k_memory[i].size;
 	} while (++i < m68k_num_memory);
 
+	/* As a special case allow `__pa(high_memory)'.  */
+	if (voff == 0)
+		return m68k_memory[i-1].addr + m68k_memory[i-1].size;
+
 	return mm_vtop_fallback(vaddr);
 }
 #endif
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/8260_io/Makefile linux/arch/ppc/8260_io/Makefile
--- v2.4.4/linux/arch/ppc/8260_io/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/ppc/8260_io/Makefile	Mon May 21 17:04:46 2001
@@ -1,3 +1,5 @@
+# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:19 cort
+#
 #
 # Makefile for the linux MPC8xx ppc-specific parts of comm processor
 #
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/8260_io/commproc.c linux/arch/ppc/8260_io/commproc.c
--- v2.4.4/linux/arch/ppc/8260_io/commproc.c	Sun Sep 17 09:48:05 2000
+++ linux/arch/ppc/8260_io/commproc.c	Mon May 21 17:04:46 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.commproc.c 1.5 05/17/01 18:14:19 cort
+ */
 
 /*
  * General Purpose functions for the global management of the
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/8260_io/enet.c linux/arch/ppc/8260_io/enet.c
--- v2.4.4/linux/arch/ppc/8260_io/enet.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/ppc/8260_io/enet.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.enet.c 1.6 05/17/01 18:14:19 cort
+ */
+/*
  * Ethernet driver for Motorola MPC8260.
  * Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
  * Copyright (c) 2000 MontaVista Software Inc. (source@mvista.com)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/8260_io/fcc_enet.c linux/arch/ppc/8260_io/fcc_enet.c
--- v2.4.4/linux/arch/ppc/8260_io/fcc_enet.c	Fri Feb 16 16:02:34 2001
+++ linux/arch/ppc/8260_io/fcc_enet.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.fcc_enet.c 1.7 05/17/01 18:14:20 cort
+ */
+/*
  * Fast Ethernet Controller (FCC) driver for Motorola MPC8260.
  * Copyright (c) 2000 MontaVista Software, Inc.   Dan Malek (dmalek@jlc.net)
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/8260_io/uart.c linux/arch/ppc/8260_io/uart.c
--- v2.4.4/linux/arch/ppc/8260_io/uart.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/ppc/8260_io/uart.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.uart.c 1.6 05/17/01 18:14:20 cort
+ */
+/*
  *  UART driver for MPC8260 CPM SCC or SMC
  *  Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
  *  Copyright (c) 2000 MontaVista Software, Inc. (source@mvista.com)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/8xx_io/Config.in linux/arch/ppc/8xx_io/Config.in
--- v2.4.4/linux/arch/ppc/8xx_io/Config.in	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/8xx_io/Config.in	Wed May 16 09:57:20 2001
@@ -18,12 +18,12 @@
   fi
   bool 'Use Big CPM Ethernet Buffers' CONFIG_ENET_BIG_BUFFERS
 fi
-bool 'Use SMC2 for UART' CONFIG_8xxSMC2
-if [ "$CONFIG_8xxSMC2" = "y" ]; then
-  bool 'Use Alternate SMC2 I/O (823/850)' CONFIG_8xx_ALTSMC2
-  bool 'Use SMC2 for Console' CONFIG_8xx_CONS_SMC2
+bool 'Use SMC2 for UART' CONFIG_SMC2_UART
+if [ "$CONFIG_SMC2_UART" = "y" ]; then
+  bool 'Use Alternate SMC2 I/O (823/850)' CONFIG_ALTSMC2
+  bool 'Use SMC2 for Console' CONFIG_CONS_SMC2
 fi
-bool 'Enable SCC2 and SCC3 for UART' CONFIG_8xxSCC
+bool 'Enable SCC2 and SCC3 for UART' CONFIG_USE_SCC_IO
 
 # This doesn't really belong here, but it is convenient to ask
 # 8xx specific questions.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/8xx_io/Makefile linux/arch/ppc/8xx_io/Makefile
--- v2.4.4/linux/arch/ppc/8xx_io/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/ppc/8xx_io/Makefile	Mon May 21 17:04:46 2001
@@ -1,3 +1,5 @@
+# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:20 cort
+#
 #
 # Makefile for the linux MPC8xx ppc-specific parts of comm processor
 #
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/8xx_io/commproc.c linux/arch/ppc/8xx_io/commproc.c
--- v2.4.4/linux/arch/ppc/8xx_io/commproc.c	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/8xx_io/commproc.c	Mon May 21 17:04:46 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.commproc.c 1.8 05/18/01 07:54:04 patch
+ */
 
 /*
  * General Purpose functions for the global management of the
@@ -218,7 +221,7 @@
  * The internal baud rate clock is the system clock divided by 16.
  * This assumes the baudrate is 16x oversampled by the uart.
  */
-#define BRG_INT_CLK		(((bd_t *)__res)->bi_intfreq * 1000000)
+#define BRG_INT_CLK		(((bd_t *)__res)->bi_intfreq)
 #define BRG_UART_CLK		(BRG_INT_CLK/16)
 #define BRG_UART_CLK_DIV16	(BRG_UART_CLK/16)
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/8xx_io/commproc.h linux/arch/ppc/8xx_io/commproc.h
--- v2.4.4/linux/arch/ppc/8xx_io/commproc.h	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/8xx_io/commproc.h	Mon May 21 17:04:46 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.commproc.h 1.8 05/17/01 18:14:20 cort
+ */
 
 /*
  * MPC8xx Communication Processor Module.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/8xx_io/enet.c linux/arch/ppc/8xx_io/enet.c
--- v2.4.4/linux/arch/ppc/8xx_io/enet.c	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/8xx_io/enet.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.enet.c 1.10 05/17/01 18:14:20 cort
+ */
+/*
  * Ethernet driver for Motorola MPC8xx.
  * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/8xx_io/fec.c linux/arch/ppc/8xx_io/fec.c
--- v2.4.4/linux/arch/ppc/8xx_io/fec.c	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/8xx_io/fec.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.fec.c 1.12 05/18/01 07:54:04 patch
+ */
+/*
  * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx.
  * Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
  *
@@ -1686,10 +1689,7 @@
 	/* Set MII speed to 2.5 MHz
 	*/
 	fecp->fec_mii_speed = fep->phy_speed =
-		(
-		  ( ((bd->bi_intfreq * 1000000) + 500000) / 2500000 / 2 )
-		  & 0x3F
-		) << 1;
+		(( (bd->bi_intfreq + 500000) / 2500000 / 2 ) & 0x3F ) << 1;
 #else
 	fecp->fec_mii_speed = 0;	/* turn off MDIO */
 #endif	/* CONFIG_USE_MDIO */
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/8xx_io/uart.c linux/arch/ppc/8xx_io/uart.c
--- v2.4.4/linux/arch/ppc/8xx_io/uart.c	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/8xx_io/uart.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.uart.c 1.10 05/17/01 18:14:20 cort
+ */
+/*
  *  UART driver for MPC860 CPM SCC or SMC
  *  Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
  *
@@ -55,17 +58,17 @@
 */
 # ifndef CONFIG_SERIAL_CONSOLE_PORT
 #  ifdef CONFIG_SCC3_ENET
-#   ifdef CONFIG_8xx_CONS_SMC2
+#   ifdef CONFIG_CONS_SMC2
 #    define CONFIG_SERIAL_CONSOLE_PORT	0	/* Console on SMC2 is 1st port */
 #   else
 #    error "Can't use SMC1 for console with Ethernet on SCC3"
 #   endif
 #  else	/* ! CONFIG_SCC3_ENET */
-#   ifdef CONFIG_8xx_CONS_SMC2			/* Console on SMC2 */
+#   ifdef CONFIG_CONS_SMC2			/* Console on SMC2 */
 #    define CONFIG_SERIAL_CONSOLE_PORT	1
 #   else					/* Console on SMC1 */
 #    define CONFIG_SERIAL_CONSOLE_PORT	0
-#   endif /* CONFIG_8xx_CONS_SMC2 */
+#   endif /* CONFIG_CONS_SMC2 */
 #  endif  /* CONFIG_SCC3_ENET */
 # endif	  /* CONFIG_SERIAL_CONSOLE_PORT */
 #endif	  /* CONFIG_SERIAL_CONSOLE */
@@ -134,15 +137,15 @@
   	{ 0,     0, PROFF_SMC1, CPMVEC_SMC1,   0,    0 },    /* SMC1 ttyS0 */
 #endif
 #if !defined(CONFIG_USB_MPC8xx) && !defined(CONFIG_USB_CLIENT_MPC8xx)
-# ifdef CONFIG_8xxSMC2
+# ifdef CONFIG_SMC2_UART
   	{ 0,     0, PROFF_SMC2, CPMVEC_SMC2,   0,    1 },    /* SMC2 ttyS1 */
 # endif
-# ifdef CONFIG_8xxSCC
+# ifdef CONFIG_USE_SCC_IO
   	{ 0,     0, PROFF_SCC2, CPMVEC_SCC2,   0,    (NUM_IS_SCC | 1) },    /* SCC2 ttyS2 */
   	{ 0,     0, PROFF_SCC3, CPMVEC_SCC3,   0,    (NUM_IS_SCC | 2) },    /* SCC3 ttyS3 */
 # endif
   #else /* CONFIG_USB_xxx */
-# ifdef CONFIG_8xxSCC
+# ifdef CONFIG_USE_SCC_IO
   	{ 0,     0, PROFF_SCC3, CPMVEC_SCC3,   0,    (NUM_IS_SCC | 2) },    /* SCC3 ttyS3 */
 # endif
 #endif	/* CONFIG_USB_xxx */
@@ -2533,7 +2536,7 @@
 
 	/* Configure SCC2, SCC3, and SCC4 instead of port A parallel I/O.
 	 */
-#ifdef CONFIG_8xxSCC
+#ifdef CONFIG_USE_SCC_IO
 #ifndef CONFIG_MBX
 	/* The "standard" configuration through the 860.
 	*/
@@ -2747,7 +2750,7 @@
 				 * parallel I/O.  On 823/850 these are on
 				 * port A for SMC2.
 				 */
-#ifndef CONFIG_8xx_ALTSMC2
+#ifndef CONFIG_ALTSMC2
 				iobits = 0xc0 << (idx * 4);
 				cp->cp_pbpar |= iobits;
 				cp->cp_pbdir &= ~iobits;
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/Makefile linux/arch/ppc/Makefile
--- v2.4.4/linux/arch/ppc/Makefile	Mon Jan 22 15:41:14 2001
+++ linux/arch/ppc/Makefile	Mon May 21 17:04:46 2001
@@ -1,3 +1,5 @@
+# BK Id: SCCS/s.Makefile 1.13 05/21/01 00:48:24 cort
+#
 # This file is included by the global makefile so that you can add your own
 # architecture-specific flags and dependencies. Remember to do have actions
 # for "archclean" and "archdep" for cleaning up and making dependencies for
@@ -31,7 +33,7 @@
 endif
 
 ifdef CONFIG_8xx
-CFLAGS := $(CFLAGS) -mcpu=860 -I../8xx_io
+CFLAGS := $(CFLAGS) -mcpu=860
 endif
 
 ifdef CONFIG_PPC64BRIDGE
@@ -141,45 +143,9 @@
 	@$(MAKECHRPBOOT) $@
 endif
 
-.PHONY: clean_config
-clean_config:
+%_config: arch/ppc/configs/%_defconfig
 	rm -f .config arch/ppc/defconfig
-
-pmac_config: clean_config
-	cp -f arch/ppc/configs/pmac_defconfig arch/ppc/defconfig
-
-prep_config: clean_config
-	cp -f arch/ppc/configs/prep_defconfig arch/ppc/defconfig
-
-chrp_config: clean_config
-	cp -f arch/ppc/configs/chrp_defconfig arch/ppc/defconfig
-
-common_config: clean_config
-	cp -f arch/ppc/configs/common_defconfig arch/ppc/defconfig
-
-mbx_config: clean_config
-	cp -f arch/ppc/configs/mbx_defconfig arch/ppc/defconfig
-
-apus_config: clean_config
-	cp -f arch/ppc/configs/apus_defconfig arch/ppc/defconfig
-
-oak_config: clean_config
-	cp -f arch/ppc/configs/oak_defconfig arch/ppc/defconfig
-
-walnut_config: clean_config
-	cp -f arch/ppc/configs/walnut_defconfig arch/ppc/defconfig
-
-rpxlite_config: clean_config
-	cp -f arch/ppc/configs/rpxlite_defconfig arch/ppc/defconfig
-
-rpxcllf_config: clean_config
-	cp -f arch/ppc/configs/rpxcllf_defconfig arch/ppc/defconfig
-
-bseip_config: clean_config
-	cp -f arch/ppc/configs/bseip_defconfig arch/ppc/defconfig
-
-est8260_config: clean_config
-	cp -f arch/ppc/configs/est8260_defconfig arch/ppc/defconfig
+	cp -f arch/ppc/configs/$(@:config=defconfig) arch/ppc/defconfig
 
 archclean:
 	rm -f arch/ppc/kernel/{mk_defs,ppc_defs.h,find_name,checks}
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/amiga/Makefile linux/arch/ppc/amiga/Makefile
--- v2.4.4/linux/arch/ppc/amiga/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/ppc/amiga/Makefile	Mon May 21 17:04:46 2001
@@ -1,3 +1,5 @@
+# BK Id: SCCS/s.Makefile 1.5 05/21/01 00:48:24 cort
+#
 #
 # Makefile for Linux arch/m68k/amiga source directory
 #
@@ -14,6 +16,6 @@
 obj-y		:= config.o amiints.o cia.o time.o bootinfo.o amisound.o \
 			chipram.o amiga_ksyms.o
 
-obj-$(CONFIG_AMIGA_PCMCIA) += pcmia.o
+obj-$(CONFIG_AMIGA_PCMCIA) += pcmcia.o
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/amiga/amiga_ksyms.c linux/arch/ppc/amiga/amiga_ksyms.c
--- v2.4.4/linux/arch/ppc/amiga/amiga_ksyms.c	Tue Aug  4 16:06:36 1998
+++ linux/arch/ppc/amiga/amiga_ksyms.c	Mon May 21 17:04:46 2001
@@ -1 +1,4 @@
+/*
+ * BK Id: SCCS/s.amiga_ksyms.c 1.5 05/17/01 18:14:20 cort
+ */
 #include "../../m68k/amiga/amiga_ksyms.c"
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/amiga/amiints.c linux/arch/ppc/amiga/amiints.c
--- v2.4.4/linux/arch/ppc/amiga/amiints.c	Fri Feb 16 16:02:34 2001
+++ linux/arch/ppc/amiga/amiints.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.amiints.c 1.8 05/21/01 00:48:24 cort
+ */
+/*
  * linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -255,9 +258,10 @@
 		return;
 	}
 
-	if (irq >= IRQ_AMIGA_AUTO)
+	if (irq >= IRQ_AMIGA_AUTO) {
 		sys_free_irq(irq - IRQ_AMIGA_AUTO, dev_id);
-
+		return;
+	}
 	if (irq >= IRQ_AMIGA_CIAA) {
 		cia_free_irq(irq, dev_id);
 		return;
@@ -295,7 +299,10 @@
 		return;
 	}
 
-	if (--ami_ablecount[irq])
+	ami_ablecount[irq]--;
+	if (ami_ablecount[irq]<0)
+		ami_ablecount[irq]=0;
+	else if (ami_ablecount[irq])
 		return;
 
 	/* No action for auto-vector interrupts */
@@ -347,64 +354,16 @@
 	ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp);
 }
 
-void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server)
+void amiga_do_irq_list(int irq, struct pt_regs *fp)
 {
-	irq_node_t *node, *slow_nodes;
-	unsigned short intena;
-	unsigned long flags;
+	irq_node_t *node;
 
 	kstat.irqs[0][SYS_IRQS + irq]++;
-	if (server->count++)
-		server->reentrance = 1;
-
-	intena = ami_intena_vals[irq];
-	custom.intreq = intena;
 
-	/* serve first fast handlers - there can only be one of these */
-	node = ami_irq_list[irq];
-
-	/*
-	 * Timer interrupts show up like this
-	 */
-	if (!node) {
-		server->count--;
-		return;
-	}
+	custom.intreq = ami_intena_vals[irq];
 
-	if (node && (node->flags & SA_INTERRUPT)) {
-		save_flags(flags);
-		cli();
+	for (node = ami_irq_list[irq]; node; node = node->next)
 		node->handler(irq, node->dev_id, fp);
-		restore_flags(flags);
-
-		server->count--;
-		return;
-	}
-
-	/*
-	 * Disable the interrupt source in question and reenable all
-	 * other interrupts. No interrupt handler should ever touch
-	 * the intena flags directly!
-	 */
-	custom.intena = intena;
-	save_flags(flags);
-	sti();
-
-	slow_nodes = node;
-	for (;;) {
-		for (; node; node = node->next)
-			node->handler(irq, node->dev_id, fp);
-
-		if (!server->reentrance) {
-			server->count--;
-			restore_flags(flags);
-			custom.intena = IF_SETCLR | intena;
-			return;
-		}
-
-		server->reentrance = 0;
-		node = slow_nodes;
-	}
 }
 
 /*
@@ -437,7 +396,6 @@
 static void ami_int3(int irq, void *dev_id, struct pt_regs *fp)
 {
 	unsigned short ints = custom.intreqr & custom.intenar;
-	static struct irq_server server = {0, 0};
 
 	/* if a blitter interrupt */
 	if (ints & IF_BLIT) {
@@ -453,7 +411,7 @@
 
 	/* if a vertical blank interrupt */
 	if (ints & IF_VERTB)
-		amiga_do_irq_list(IRQ_AMIGA_VERTB, fp, &server);
+		amiga_do_irq_list(IRQ_AMIGA_VERTB, fp);
 }
 
 static void ami_int4(int irq, void *dev_id, struct pt_regs *fp)
@@ -512,7 +470,7 @@
    and executes them in a loop. Having ami_badint at the end of the chain
    is a bad idea. */
 void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
-	NULL, ami_int1, NULL, NULL /* FB expects to replace ami_int3*/,
+	NULL, ami_int1, NULL, ami_int3,
 	ami_int4, ami_int5, NULL, ami_int7
 };
 #else
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/amiga/amisound.c linux/arch/ppc/amiga/amisound.c
--- v2.4.4/linux/arch/ppc/amiga/amisound.c	Tue Aug  4 16:06:36 1998
+++ linux/arch/ppc/amiga/amisound.c	Mon May 21 17:04:46 2001
@@ -1 +1,4 @@
+/*
+ * BK Id: SCCS/s.amisound.c 1.5 05/17/01 18:14:20 cort
+ */
 #include "../../m68k/amiga/amisound.c"
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/amiga/bootinfo.c linux/arch/ppc/amiga/bootinfo.c
--- v2.4.4/linux/arch/ppc/amiga/bootinfo.c	Thu Oct  7 10:17:08 1999
+++ linux/arch/ppc/amiga/bootinfo.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.bootinfo.c 1.5 05/17/01 18:14:20 cort
+ */
+/*
  *  linux/arch/ppc/amiga/bootinfo.c
  *
  *  Extracted from arch/m68k/kernel/setup.c.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/amiga/chipram.c linux/arch/ppc/amiga/chipram.c
--- v2.4.4/linux/arch/ppc/amiga/chipram.c	Tue Jul 11 11:18:53 2000
+++ linux/arch/ppc/amiga/chipram.c	Mon May 21 17:04:46 2001
@@ -1,183 +1,4 @@
 /*
-**  linux/amiga/chipram.c
-**
-**      Modified 03-May-94 by Geert Uytterhoeven <geert@linux-m68k.org>
-**          - 64-bit aligned allocations for full AGA compatibility
-*/
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/zorro.h>
-#include <asm/amigahw.h>
-
-struct chip_desc {
-	unsigned first   :  1;
-	unsigned last    :  1;
-	unsigned alloced :  1;
-	unsigned length  : 24;
-	long pad;					/* We suppose this makes this struct 64 bits long!! */
-};
-
-#define DP(ptr) ((struct chip_desc *)(ptr))
-
-u_long amiga_chip_size;
-static unsigned long chipavail;
-
-static struct resource chipram = { "Chip RAM", 0 };
-
-unsigned long amiga_chip_avail( void )
-{
-#ifdef DEBUG
-	printk("chip_avail : %ld bytes\n",chipavail);
-#endif
-	return chipavail;
-}
-
-
-void __init amiga_chip_init (void)
-{
-  struct chip_desc *dp;
-
-  if (!AMIGAHW_PRESENT(CHIP_RAM))
-    return;
-
-#ifndef CONFIG_APUS_FAST_EXCEPT
-  /*
-   * Remove the first 4 pages where PPC exception handlers will
-   * be located.
-   */
-  amiga_chip_size -= 0x4000;
-#endif
-  chipram.end = amiga_chip_size-1;
-  request_resource(&iomem_resource, &chipram);
-
-  /* initialize start boundary */
-
-  dp = DP(chipaddr);
-  dp->first = 1;
-
-  dp->alloced = 0;
-  dp->length = amiga_chip_size - 2*sizeof(*dp);
-
-  /* initialize end boundary */
-  dp = DP(chipaddr + amiga_chip_size) - 1;
-  dp->last = 1;
-  
-  dp->alloced = 0;
-  dp->length = amiga_chip_size - 2*sizeof(*dp);
-  chipavail = dp->length;  /*MILAN*/
-
-#ifdef DEBUG
-  printk ("chipram end boundary is %p, length is %d\n", dp,
-	  dp->length);
-#endif
-}
-
-void *amiga_chip_alloc(long size, const char *name)
-{
-	/* last chunk */
-	struct chip_desc *dp;
-	void *ptr;
-
-	/* round off */
-	size = (size + 7) & ~7;
-
-#ifdef DEBUG
-   printk("amiga_chip_alloc: allocate %ld bytes\n", size);
-#endif
-
-	/*
-	 * get pointer to descriptor for last chunk by 
-	 * going backwards from end chunk
-	 */
-	dp = DP(chipaddr + amiga_chip_size) - 1;
-	dp = DP((unsigned long)dp - dp->length) - 1;
-	
-	while ((dp->alloced || dp->length < size)
-	       && !dp->first)
-		dp = DP ((unsigned long)dp - dp[-1].length) - 2;
-
-	if (dp->alloced || dp->length < size) {
-		printk ("no chipmem available for %ld allocation\n", size);
-		return NULL;
-	}
-
-	if (dp->length < (size + 2*sizeof(*dp))) {
-		/* length too small to split; allocate the whole thing */
-		dp->alloced = 1;
-		ptr = (void *)(dp+1);
-		dp = DP((unsigned long)ptr + dp->length);
-		dp->alloced = 1;
-#ifdef DEBUG
-		printk ("amiga_chip_alloc: no split\n");
-#endif
-	} else {
-		/* split the extent; use the end part */
-		long newsize = dp->length - (2*sizeof(*dp) + size);
-
-#ifdef DEBUG
-		printk ("amiga_chip_alloc: splitting %d to %ld\n", dp->length,
-			newsize);
-#endif
-		dp->length = newsize;
-		dp = DP((unsigned long)(dp+1) + newsize);
-		dp->first = dp->last = 0;
-		dp->alloced = 0;
-		dp->length = newsize;
-		dp++;
-		dp->first = dp->last = 0;
-		dp->alloced = 1;
-		dp->length = size;
-		ptr = (void *)(dp+1);
-		dp = DP((unsigned long)ptr + size);
-		dp->alloced = 1;
-		dp->length = size;
-	}
-
-#ifdef DEBUG
-	printk ("amiga_chip_alloc: returning %p\n", ptr);
-#endif
-
-	if ((unsigned long)ptr & 7)
-		panic("amiga_chip_alloc: alignment violation\n");
-
-    chipavail -= size + (2*sizeof(*dp)); /*MILAN*/
-
-    if (!request_mem_region(ZTWO_PADDR(ptr), size, name))
-	printk(KERN_WARNING "amiga_chip_alloc: region of size %ld at 0x%08lx "
-	       "is busy\n", size, ZTWO_PADDR(ptr));
-
-    return ptr;
-}
-
-void amiga_chip_free (void *ptr)
-{
-	struct chip_desc *sdp = DP(ptr) - 1, *dp2;
-	struct chip_desc *edp = DP((unsigned long)ptr + sdp->length);
-
-    chipavail += sdp->length + (2* sizeof(sdp)); /*MILAN*/
-#ifdef DEBUG
-   printk("chip_free: free %ld bytes at %p\n",sdp->length,ptr);
-#endif
-	/* deallocate the chunk */
-	sdp->alloced = edp->alloced = 0;
-	release_mem_region(ZTWO_PADDR(ptr), sdp->length);
-
-	/* check if we should merge with the previous chunk */
-	if (!sdp->first && !sdp[-1].alloced) {
-		dp2 = DP((unsigned long)sdp - sdp[-1].length) - 2;
-		dp2->length += sdp->length + 2*sizeof(*sdp);
-		edp->length = dp2->length;
-		sdp = dp2;
-	}
-
-	/* check if we should merge with the following chunk */
-	if (!edp->last && !edp[1].alloced) {
-		dp2 = DP((unsigned long)edp + edp[1].length) + 2;
-		dp2->length += edp->length + 2*sizeof(*sdp);
-		sdp->length = dp2->length;
-		edp = dp2;
-	}
-}
+ * BK Id: SCCS/s.chipram.c 1.7 05/21/01 00:49:49 cort
+ */
+#include "../../m68k/amiga/chipram.c"
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/amiga/cia.c linux/arch/ppc/amiga/cia.c
--- v2.4.4/linux/arch/ppc/amiga/cia.c	Wed Feb  9 19:43:47 2000
+++ linux/arch/ppc/amiga/cia.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.cia.c 1.7 05/21/01 00:48:24 cort
+ */
+/*
  *  linux/arch/m68k/amiga/cia.c - CIA support
  *
  *  Copyright (C) 1996 Roman Zippel
@@ -27,18 +30,17 @@
 	u_short int_mask;
 	int handler_irq, cia_irq, server_irq;
 	char *name;
-	struct irq_server server;
 	irq_handler_t irq_list[CIA_IRQS];
 } ciaa_base = {
 	&ciaa, 0, 0, IF_PORTS,
 	IRQ_AMIGA_AUTO_2, IRQ_AMIGA_CIAA,
 	IRQ_AMIGA_PORTS,
-	"CIAA handler", {0, 0}
+	"CIAA handler"
 }, ciab_base = {
 	&ciab, 0, 0, IF_EXTER,
 	IRQ_AMIGA_AUTO_6, IRQ_AMIGA_CIAB,
 	IRQ_AMIGA_EXTER,
-	"CIAB handler", {0, 0}
+	"CIAB handler"
 };
 
 #define CIA_SET_BASE_ADJUST_IRQ(base, irq)	\
@@ -197,7 +199,7 @@
 		}
 		ints >>= 1;
 	}
-	amiga_do_irq_list(base->server_irq, fp, &base->server);
+	amiga_do_irq_list(base->server_irq, fp);
 }
 
 void __init cia_init_IRQ(struct ciabase *base)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/amiga/config.c linux/arch/ppc/amiga/config.c
--- v2.4.4/linux/arch/ppc/amiga/config.c	Mon Nov 27 17:57:34 2000
+++ linux/arch/ppc/amiga/config.c	Mon May 21 17:04:46 2001
@@ -1,12 +1,8 @@
+/*
+ * BK Id: SCCS/s.config.c 1.7 05/21/01 00:48:24 cort
+ */
 #define m68k_debug_device debug_device
 
-#include <linux/init.h>
-
-/* machine dependent "kbd-reset" setup function */
-void (*mach_kbd_reset_setup) (char *, int) __initdata = 0;
-
-#include <asm/io.h>
-
 /*
  *  linux/arch/m68k/amiga/config.c
  *
@@ -28,6 +24,10 @@
 #include <linux/kd.h>
 #include <linux/tty.h>
 #include <linux/console.h>
+#include <linux/init.h>
+#ifdef CONFIG_ZORRO
+#include <linux/zorro.h>
+#endif
 
 #include <asm/bootinfo.h>
 #include <asm/setup.h>
@@ -36,10 +36,12 @@
 #include <asm/amigahw.h>
 #include <asm/amigaints.h>
 #include <asm/irq.h>
+#include <asm/keyboard.h>
 #include <asm/machdep.h>
-#include <linux/zorro.h>
+#include <asm/io.h>
 
 unsigned long powerup_PCI_present;
+unsigned long powerup_BPPCPLUS_present;
 unsigned long amiga_model;
 unsigned long amiga_eclock;
 unsigned long amiga_masterclock;
@@ -121,7 +123,7 @@
 };
 
 #ifdef CONFIG_MAGIC_SYSRQ
-static char amiga_sysrq_xlate[128] =
+char amiga_sysrq_xlate[128] =
 	"\0001234567890-=\\\000\000"					/* 0x00 - 0x0f */
 	"qwertyuiop[]\000123"							/* 0x10 - 0x1f */
 	"asdfghjkl;'\000\000456"						/* 0x20 - 0x2f */
@@ -139,16 +141,18 @@
      *  Motherboard Resources present in all Amiga models
      */
 
-static struct resource mb_res[] = {
-    { "Ranger Memory", 0x00c00000, 0x00c7ffff },
-    { "CIA B", 0x00bfd000, 0x00bfdfff },
-    { "CIA A", 0x00bfe000, 0x00bfefff },
-    { "Custom I/O", 0x00dff000, 0x00dfffff },
-    { "Kickstart ROM", 0x00f80000, 0x00ffffff }
+static struct {
+    struct resource _ciab, _ciaa, _custom, _kickstart;
+} mb_resources = {
+//    { "Ranger Memory", 0x00c00000, 0x00c7ffff },
+    _ciab:	{ "CIA B", 0x00bfd000, 0x00bfdfff },
+    _ciaa:	{ "CIA A", 0x00bfe000, 0x00bfefff },
+    _custom:	{ "Custom I/O", 0x00dff000, 0x00dfffff },
+    _kickstart:	{ "Kickstart ROM", 0x00f80000, 0x00ffffff }
 };
 
 static struct resource rtc_resource = {
-    "A2000 RTC", 0x00dc0000, 0x00dcffff
+    NULL, 0x00dc0000, 0x00dcffff
 };
 
 static struct resource ram_resource[NUM_MEMINFO];
@@ -194,6 +198,7 @@
 	    break;
 
 	case BI_AMIGA_AUTOCON:
+#ifdef CONFIG_ZORRO
 	    if (zorro_num_autocon < ZORRO_NUM_AUTO) {
 		const struct ConfigDev *cd = (struct ConfigDev *)data;
 		struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++];
@@ -204,12 +209,21 @@
 		dev->resource.end = dev->resource.start+cd->cd_BoardSize-1;
 	    } else
 		printk("amiga_parse_bootinfo: too many AutoConfig devices\n");
+#endif /* CONFIG_ZORRO */
 	    break;
 
 	case BI_AMIGA_SERPER:
 	    /* serial port period: ignored here */
 	    break;
 
+	case BI_AMIGA_PUP_BRIDGE:
+	    powerup_PCI_present = *(const unsigned short *)data;
+	    break;
+
+	case BI_AMIGA_BPPC_SCSI:
+	    powerup_BPPCPLUS_present = *(const unsigned short *)data;
+	    break;
+
 	default:
 	    unknown = 1;
     }
@@ -392,11 +406,8 @@
 
   /* Some APUS boxes may have PCI memory, but ... */
   iomem_resource.name = "Memory";
-  request_resource(&iomem_resource, &ranger_resource);
-  request_resource(&iomem_resource, &ciab_resource);
-  request_resource(&iomem_resource, &ciaa_resource);
-  request_resource(&iomem_resource, &custom_chips_resource);
-  request_resource(&iomem_resource, &kickstart_resource);
+  for (i = 0; i < 4; i++)
+    request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]);
 
   mach_sched_init      = amiga_sched_init;
   mach_keyb_init       = amiga_keyb_init;
@@ -415,11 +426,12 @@
   mach_gettimeoffset   = amiga_gettimeoffset;
   if (AMIGAHW_PRESENT(A3000_CLK)){
     mach_gettod  = a3000_gettod;
-    rtc_resource.name[1] = '3';
+    rtc_resource.name = "A3000 RTC";
     request_resource(&iomem_resource, &rtc_resource);
   }
   else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */
     mach_gettod  = a2000_gettod;
+    rtc_resource.name = "A2000 RTC";
     request_resource(&iomem_resource, &rtc_resource);
   }
 
@@ -439,14 +451,10 @@
   mach_floppy_setup    = amiga_floppy_setup;
 #endif
   mach_reset           = amiga_reset;
+#ifdef CONFIG_DUMMY_CONSOLE
   conswitchp           = &dummy_con;
-  kd_mksound           = amiga_mksound;
-#ifdef CONFIG_MAGIC_SYSRQ
-  mach_sysrq_key = 0x5f;	     /* HELP */
-  mach_sysrq_shift_state = 0x03; /* SHIFT+ALTGR */
-  mach_sysrq_shift_mask = 0xff;  /* all modifiers except CapsLock */
-  mach_sysrq_xlate = amiga_sysrq_xlate;
 #endif
+  kd_mksound           = amiga_mksound;
 #ifdef CONFIG_HEARTBEAT
   mach_heartbeat = amiga_heartbeat;
 #endif
@@ -500,11 +508,14 @@
 static unsigned short jiffy_ticks;
 
 static void __init amiga_sched_init(void (*timer_routine)(int, void *,
-					struct pt_regs *))
+							  struct pt_regs *))
 {
+	static struct resource sched_res = {
+	    "timer", 0x00bfd400, 0x00bfd5ff,
+	};
 	jiffy_ticks = (amiga_eclock+HZ/2)/HZ;
 
-	if (!request_mem_region(CIAB_PHYSADDR+0x400, 0x200, "timer"))
+	if (request_resource(&mb_resources._ciab, &sched_res))
 	    printk("Cannot allocate ciab.ta{lo,hi}\n");
 	ciab.cra &= 0xC0;   /* turn off timer A, continuous mode, from Eclk */
 	ciab.talo = jiffy_ticks % 256;
@@ -612,6 +623,8 @@
 			t->wday = tod->weekday;
 			t->mon  = tod->month1  * 10 + tod->month2 - 1;
 			t->year = tod->year1   * 10 + tod->year2;
+			if (t->year <= 69)
+				t->year += 100;
 		} else {
 			tod->second1 = t->sec / 10;
 			tod->second2 = t->sec % 10;
@@ -625,6 +638,8 @@
 				tod->weekday = t->wday;
 			tod->month1  = (t->mon + 1) / 10;
 			tod->month2  = (t->mon + 1) % 10;
+			if (t->year >= 100)
+				t->year -= 100;
 			tod->year1   = t->year / 10;
 			tod->year2   = t->year % 10;
 		}
@@ -646,6 +661,8 @@
 			t->wday = tod->weekday;
 			t->mon  = tod->month1      * 10 + tod->month2 - 1;
 			t->year = tod->year1       * 10 + tod->year2;
+			if (t->year <= 69)
+				t->year += 100;
 
 			if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){
 				if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
@@ -672,6 +689,8 @@
 				tod->weekday = t->wday;
 			tod->month1  = (t->mon + 1) / 10;
 			tod->month2  = (t->mon + 1) % 10;
+			if (t->year >= 100)
+				t->year -= 100;
 			tod->year1   = t->year / 10;
 			tod->year2   = t->year % 10;
 		}
@@ -796,7 +815,9 @@
 
 static void amiga_savekmsg_init(void)
 {
-    savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM, "Debug");
+    static struct resource debug_res = { "Debug" };
+
+    savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res);
     savekmsg->magic1 = SAVEKMSG_MAGIC1;
     savekmsg->magic2 = SAVEKMSG_MAGIC2;
     savekmsg->magicptr = virt_to_phys(savekmsg);
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/amiga/ints.c linux/arch/ppc/amiga/ints.c
--- v2.4.4/linux/arch/ppc/amiga/ints.c	Fri Nov 12 04:29:47 1999
+++ linux/arch/ppc/amiga/ints.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.ints.c 1.5 05/17/01 18:14:20 cort
+ */
+/*
  *  linux/arch/ppc/amiga/ints.c
  *
  *  Linux/m68k general interrupt handling code from arch/m68k/kernel/ints.c
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/amiga/pcmcia.c linux/arch/ppc/amiga/pcmcia.c
--- v2.4.4/linux/arch/ppc/amiga/pcmcia.c	Thu Oct  7 10:17:08 1999
+++ linux/arch/ppc/amiga/pcmcia.c	Mon May 21 17:04:46 2001
@@ -1 +1,4 @@
+/*
+ * BK Id: SCCS/s.pcmcia.c 1.5 05/17/01 18:14:20 cort
+ */
 #include "../../m68k/amiga/pcmcia.c"
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/amiga/time.c linux/arch/ppc/amiga/time.c
--- v2.4.4/linux/arch/ppc/amiga/time.c	Mon Sep 11 08:39:48 2000
+++ linux/arch/ppc/amiga/time.c	Mon May 21 17:04:46 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.time.c 1.5 05/17/01 18:14:20 cort
+ */
 #include <linux/config.h> /* CONFIG_HEARTBEAT */
 #include <linux/errno.h>
 #include <linux/sched.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/boot/Makefile linux/arch/ppc/boot/Makefile
--- v2.4.4/linux/arch/ppc/boot/Makefile	Mon Jan 22 15:41:14 2001
+++ linux/arch/ppc/boot/Makefile	Wed May 16 09:57:20 2001
@@ -31,6 +31,12 @@
 TFTPIMAGE=/tftpboot/zImage.prep$(MSIZE)
 endif
 
+ifeq ($(CONFIG_SMP),y)
+TFTPSIMAGE=/tftpboot/sImage.smp
+else
+TFTPSIMAGE=/tftpboot/sImage
+endif
+
 ifeq ($(CONFIG_PPC64BRIDGE),y)
 MSIZE=.64
 else
@@ -70,8 +76,24 @@
 		--add-section=image=../coffboot/vmlinux.gz \
 		zvmlinux.initrd.tmp $@
 	rm zvmlinux.initrd.tmp
+ifdef CONFIG_GEMINI
+	$(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)
+	$(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.initrd.tmp svmlinux.initrd.tmp
+	./mksimage svmlinux.initrd.tmp ../coffboot/vmlinux.gz ramdisk.image.gz \
+	-o svmlinux.initrd > sImage.map
+	$(CC) $(CFLAGS) -DINITRD_OFFSET=`sh sioffset initrd` \
+			-DINITRD_SIZE=`sh sisize initrd` \
+			-DZIMAGE_OFFSET=`sh sioffset zimage` \
+			-DZIMAGE_SIZE=`sh sisize zimage` \
+			-c -o misc.o misc.c
+	$(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)
+	$(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.initrd.tmp svmlinux.initrd.tmp
+	./mksimage svmlinux.initrd.tmp ../coffboot/vmlinux.gz ramdisk.image.gz \
+	-o svmlinux.initrd > /dev/null
+	rm svmlinux.initrd.tmp zvmlinux.initrd.tmp sImage.map
+endif
 
-zImage: zvmlinux mkprep
+zImage: zvmlinux mkprep sImage mksimage
 ifdef CONFIG_ALL_PPC
 	./mkprep -pbp zvmlinux zImage
 endif
@@ -80,12 +102,17 @@
 	gzip $(GZIP_FLAGS) vmapus
 endif
 
+sImage: ../../../vmlinux
+ifdef CONFIG_GEMINI
+	$(OBJCOPY) -I elf32-powerpc -O binary ../../../vmlinux sImage
+endif
+
 zImage.initrd: zvmlinux.initrd mkprep
 ifdef CONFIG_ALL_PPC
 	./mkprep -pbp zvmlinux.initrd zImage.initrd
 endif
 
-zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz
+zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz mksimage
 #
 # build the boot loader image and then compute the offset into it
 # for the kernel image
@@ -105,6 +132,19 @@
 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \
 		zvmlinux.tmp $@
 	rm zvmlinux.tmp
+ifdef CONFIG_GEMINI
+	$(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)
+	$(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.tmp svmlinux.tmp
+	./mksimage svmlinux.tmp ../coffboot/vmlinux.gz -o svmlinux > sImage.map
+	$(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
+		-DZIMAGE_OFFSET=`sh sioffset zimage` \
+		-DZIMAGE_SIZE=`sh sisize zimage` \
+		-c -o misc.o misc.c
+	$(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS)
+	$(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.tmp svmlinux.tmp
+	./mksimage svmlinux.tmp ../coffboot/vmlinux.gz -o svmlinux > /dev/null
+	rm svmlinux.tmp sImage.map zvmlinux.tmp
+endif
 
 floppy: $(TOPDIR)/vmlinux zImage
 	dd if=zImage of=/dev/fd0H1440 bs=64b
@@ -112,16 +152,22 @@
 mkprep : mkprep.c
 	$(HOSTCC) -o mkprep mkprep.c
 
+mksimage: mksimage.c
+	$(HOSTCC) -o mksimage mksimage.c
+
 znetboot : zImage
 ifdef CONFIG_ALL_PPC
 	cp zImage $(TFTPIMAGE)
 endif
+ifdef CONFIG_GEMINI
+	cp sImage $(TFTPSIMAGE)
+endif
 
 znetboot.initrd : zImage.initrd
 	cp zImage.initrd $(TFTPIMAGE)
 
 clean:
-	rm -f vmlinux* zvmlinux* mkprep zImage*
+	rm -f vmlinux* zvmlinux* mkprep zImage* sImage* mksimage
 
 fastdep:
 	$(TOPDIR)/scripts/mkdep *.[Sch] > .depend
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/boot/mksimage.c linux/arch/ppc/boot/mksimage.c
--- v2.4.4/linux/arch/ppc/boot/mksimage.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/boot/mksimage.c	Wed May 16 09:57:20 2001
@@ -0,0 +1,124 @@
+/*
+ *
+ *
+ *
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+#define SIZE 1024
+#define BLOCK_ALIGN(x)  (((x)+SIZE-1)&(~(SIZE-1)))
+
+static void
+die(const char *fmt, ...)
+{
+	va_list args;
+	va_start(args, fmt);
+	vfprintf(stderr, fmt, args);
+	fputc('\n', stderr);
+	exit(1);
+}
+
+static void
+usage(void)
+{
+	printf("Usage: mkbinimg <bootstrap> <kernel> <ramdisk> -o <binary>\n");
+	exit(1);
+}
+
+static int
+copy_blocks(int ifd, int ofd, unsigned long *offset, unsigned long *size)
+{
+	off_t cur;
+	int amt;
+	unsigned long len = 0;
+	char buffer[SIZE];
+
+	cur = lseek(ofd, 0, SEEK_CUR);
+
+	if (cur % SIZE) {
+		cur = BLOCK_ALIGN(cur);
+		cur = lseek(ofd, cur, SEEK_SET);
+	}
+
+	*offset = (unsigned long) cur;
+	while((amt = read(ifd, buffer, SIZE)) > 0) {
+		write(ofd, buffer, amt);
+		len += amt;
+	}
+	*size = len;
+	return 0;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+	char *kernel, *loader, *rdimage = NULL;
+	unsigned long ld_off, kern_off, rd_off;
+	unsigned long ld_size, kern_size, rd_size;
+	int fd, ofd, len;
+	char buffer[500];
+
+	if (argc < 5 && !strcmp(argv[argc-2], "-o"))
+		usage();
+
+	if (argc > 5)
+		rdimage = argv[3];
+
+	kernel = argv[2];
+	loader = argv[1];
+
+	ofd = open(argv[argc-1], (O_RDWR|O_CREAT), 0755);
+	if (ofd < 0) {
+		die("can't open %s: %s", argv[5], strerror(errno));
+	}
+
+	ld_off = kern_off = rd_off = 0;
+	ld_size = kern_size = rd_size = 0;
+	memset(buffer, 0, 500);
+	len = 0;
+
+	fd = open(loader, O_RDONLY);
+	if (fd < 0) 
+		die("can't open loader: %s", strerror(errno));
+
+	copy_blocks(fd, ofd, &ld_off, &ld_size);
+	len = sprintf(buffer, "bootloader: %x %x\n", ld_off, ld_size);
+	close(fd);
+
+	fd = open(kernel, O_RDONLY);
+	if (fd < 0)
+		die("can't open kernel: %s", strerror(errno));
+
+	copy_blocks(fd, ofd, &kern_off, &kern_size);
+	len += sprintf(buffer+len, "zimage: %x %x\n", kern_off, kern_size);
+	close(fd);
+	
+	if (rdimage) {
+		fd = open(rdimage, O_RDONLY);
+		if (fd < 0)
+			die("can't get ramdisk: %s", strerror(errno));
+		
+		copy_blocks(fd, ofd, &rd_off, &rd_size);
+		close(fd);
+	}
+
+	len += sprintf(buffer+len, "initrd: %x %x", rd_off, rd_size);
+
+	close(ofd);
+
+	printf("%s\n", buffer);
+
+	return 0;
+}
+
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/boot/sioffset linux/arch/ppc/boot/sioffset
--- v2.4.4/linux/arch/ppc/boot/sioffset	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/boot/sioffset	Wed May 16 09:57:20 2001
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+OFFSET=`grep $1 sImage.map | awk '{print $2}'`
+echo "0x"$OFFSET
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/boot/sisize linux/arch/ppc/boot/sisize
--- v2.4.4/linux/arch/ppc/boot/sisize	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/boot/sisize	Wed May 16 09:57:20 2001
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+OFFSET=`grep $1 sImage.map | awk '{print $3}'`
+echo "0x"$OFFSET
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/chrpboot/crt0.S linux/arch/ppc/chrpboot/crt0.S
--- v2.4.4/linux/arch/ppc/chrpboot/crt0.S	Mon Jan 12 15:18:13 1998
+++ linux/arch/ppc/chrpboot/crt0.S	Wed May 16 18:05:34 2001
@@ -15,6 +15,8 @@
 1:	dcbf	0,9
 	icbi	0,9
 	addi	9,9,0x20
-	cmplwi	0,9,8
+	cmplw	0,9,8
 	blt	1b
+	sync
+	isync
 	b	start
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/coffboot/chrpmain.c linux/arch/ppc/coffboot/chrpmain.c
--- v2.4.4/linux/arch/ppc/coffboot/chrpmain.c	Sun Sep 17 09:48:06 2000
+++ linux/arch/ppc/coffboot/chrpmain.c	Wed May 16 09:57:20 2001
@@ -14,6 +14,8 @@
 
 extern void *finddevice(const char *);
 extern int getprop(void *, const char *, void *, int);
+extern void *claim(unsigned int, unsigned int, unsigned int);
+extern void release(void *ptr, unsigned int len);
 void make_bi_recs(unsigned long);
 void gunzip(void *, int, unsigned char *, int *);
 void stop_imac_ethernet(void);
@@ -78,6 +80,7 @@
 	printf("done %u bytes\n", len);
 	printf("%u bytes of heap consumed, max in use %u\n",
 	       avail_high - begin_avail, heap_max);
+	release(begin_avail, SCRATCH_SIZE);
     } else {
 	memmove(dst, im, len);
     }
@@ -98,8 +101,13 @@
 void make_bi_recs(unsigned long addr)
 {
 	struct bi_record *rec;
-	rec = (struct bi_record *)_ALIGN((unsigned long)addr+(1<<20)-1,(1<<20));
-	    
+
+	/* leave a 1MB gap then align to the next 1MB boundary */
+	addr = _ALIGN(addr+ (1<<20) - 1, (1<<20));
+	if (addr >= PROG_START + PROG_SIZE)
+		claim(addr, 0x1000, 0);
+
+	rec = (struct bi_record *)addr;
 	rec->tag = BI_FIRST;
 	rec->size = sizeof(struct bi_record);
 	rec = (struct bi_record *)((unsigned long)rec + rec->size);
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/coffboot/start.c linux/arch/ppc/coffboot/start.c
--- v2.4.4/linux/arch/ppc/coffboot/start.c	Thu Dec  2 14:37:34 1999
+++ linux/arch/ppc/coffboot/start.c	Wed May 16 09:57:20 2001
@@ -172,6 +172,25 @@
     return args.ret;
 }
 
+void
+release(void *virt, unsigned int size)
+{
+    struct prom_args {
+	char *service;
+	int nargs;
+	int nret;
+	void *virt;
+	unsigned int size;
+    } args;
+
+    args.service = "release";
+    args.nargs = 2;
+    args.nret = 0;
+    args.virt = virt;
+    args.size = size;
+    (*prom)(&args);
+}
+
 int
 getprop(void *phandle, const char *name, void *buf, int buflen)
 {
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v2.4.4/linux/arch/ppc/config.in	Tue Apr 17 17:19:25 2001
+++ linux/arch/ppc/config.in	Tue May 22 10:23:16 2001
@@ -1,10 +1,11 @@
-# $Id: config.in,v 1.106 1999/09/14 19:21:18 cort Exp $
+# BK Id: SCCS/s.config.in 1.24 05/21/01 00:48:24 cort
+#
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
 define_bool CONFIG_UID16 n
-define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
-define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
 
 mainmenu_name "Linux/PowerPC Kernel Configuration"
 
@@ -84,6 +85,7 @@
 if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ]; then
   choice 'Machine Type'		\
 	"PowerMac/PReP/MTX/CHRP	CONFIG_ALL_PPC	\
+	 Gemini         CONFIG_GEMINI           \
 	 APUS		CONFIG_APUS"		PowerMac/PReP/MTX/CHRP
 fi
 
@@ -104,10 +106,6 @@
   bool 'AltiVec Support' CONFIG_ALTIVEC
 fi
 
-if [ "$CONFIG_ALL_PPC" != "y" ];then
-  define_bool CONFIG_MACH_SPECIFIC y
-fi
-
 if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then
   bool 'Math emulation' CONFIG_MATH_EMULATION
 fi
@@ -118,7 +116,6 @@
 comment 'General setup'
 
 bool 'High memory support (experimental)' CONFIG_HIGHMEM
-bool 'Mac-on-Linux support' CONFIG_MOL
 
 define_bool CONFIG_ISA n
 define_bool CONFIG_EISA n
@@ -127,15 +124,19 @@
 # Yes MCA RS/6000s exist but Linux-PPC does not currently support any
 define_bool CONFIG_MCA n
 
-if [ "$CONFIG_APUS" = "y" -o "$CONFIG_4xx" = "y" -o \
-     "$CONFIG_8260" = "y" ]; then
+if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8260" = "y" ]; then
   define_bool CONFIG_PCI n
 else
   if [ "$CONFIG_8xx" = "y" ]; then
      bool 'QSpan PCI' CONFIG_PCI_QSPAN
      define_bool CONFIG_PCI $CONFIG_PCI_QSPAN
   else
-     define_bool CONFIG_PCI y
+     if [ "$CONFIG_APUS" = "y" ]; then
+       bool 'PCI for Permedia2' CONFIG_PCI_PERMEDIA
+       define_bool CONFIG_PCI $CONFIG_PCI_PERMEDIA
+     else
+       define_bool CONFIG_PCI y
+     fi
   fi
 fi
 
@@ -165,7 +166,11 @@
 source drivers/parport/Config.in
 
 if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then
-  tristate 'Support for /dev/rtc' CONFIG_PPC_RTC
+  if [ "$CONFIG_APUS" != "y" ]; then
+    tristate 'Support for /dev/rtc' CONFIG_PPC_RTC
+  else
+    bool 'Generic /dev/rtc emulation' CONFIG_GEN_RTC
+  fi
 fi
 
 if [ "$CONFIG_ALL_PPC" = "y" ]; then
@@ -186,12 +191,26 @@
   define_bool CONFIG_AMIGAMOUSE y
   define_bool CONFIG_ABSTRACT_CONSOLE y
   define_bool CONFIG_FB y
+  define_bool CONFIG_MOUSE y
+  define_bool CONFIG_BUSMOUSE y
+  define_bool CONFIG_APUS_FAST_EXCEPT y
+
+  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+    bool 'Amiga 1200/600 PCMCIA support' CONFIG_AMIGA_PCMCIA
+  fi
+
   tristate 'Amiga builtin serial support' CONFIG_AMIGA_BUILTIN_SERIAL
-  tristate 'Parallel printer support' CONFIG_M68K_PRINTER
   tristate 'GVP IO-Extender support' CONFIG_GVPIOEXT
   dep_tristate 'GVP IO-Extender parallel printer support' CONFIG_GVPIOEXT_LP $CONFIG_GVPIOEXT
   dep_tristate 'GVP IO-Extender PLIP support' CONFIG_GVPIOEXT_PLIP $CONFIG_GVPIOEXT
   tristate 'Multiface Card III serial support' CONFIG_MULTIFACE_III_TTY
+  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232
+  fi
+  if [ "$CONFIG_AMIGA_PCMCIA" = "y" ]; then
+    tristate 'Hisoft Whippet PCMCIA serial support' CONFIG_WHIPPET_SERIAL
+    tristate 'PCMCIA NE2000 support' CONFIG_APNE
+  fi
   if [ "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o "$CONFIG_GVPIOEXT" = "y" -o \
        "$CONFIG_MULTIFACE_III_TTY" = "y" ]; then
     bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/IVMS8_defconfig linux/arch/ppc/configs/IVMS8_defconfig
--- v2.4.4/linux/arch/ppc/configs/IVMS8_defconfig	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/configs/IVMS8_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -23,7 +25,6 @@
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
 CONFIG_8xx=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_RPXLITE is not set
@@ -40,9 +41,9 @@
 # CONFIG_SM850 is not set
 # CONFIG_MBX is not set
 # CONFIG_WINCEPT is not set
+# CONFIG_PPC601_SYNC_FIX is not set
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 CONFIG_MATH_EMULATION=y
 CONFIG_SASH=y
 CONFIG_SASH_PATH="/bin/sash"
@@ -50,8 +51,12 @@
 #
 # General setup
 #
+# CONFIG_HIGHMEM is not set
 # CONFIG_ISA is not set
+# CONFIG_EISA is not set
 # CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+# CONFIG_PCI_QSPAN is not set
 # CONFIG_PCI is not set
 CONFIG_NET=y
 CONFIG_SYSCTL=y
@@ -87,17 +92,23 @@
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
 # CONFIG_BLK_DEV_MD is not set
 # CONFIG_MD_LINEAR is not set
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
 
 #
 # Networking options
@@ -116,10 +127,8 @@
 CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
-# CONFIG_IP_ROUTER is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
-# CONFIG_IP_ALIAS is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
@@ -136,6 +145,7 @@
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
 # CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_FASTROUTE is not set
@@ -184,11 +194,10 @@
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
-CONFIG_BLK_DEV_MPC8xx_IDE=y
 # CONFIG_IDE_CHIPSETS is not set
 # CONFIG_IDEDMA_AUTO is not set
 # CONFIG_DMA_NONPCI is not set
-CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_IDE_MODES is not set
 
 #
 # SCSI support
@@ -207,6 +216,7 @@
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
 # CONFIG_ETHERTAP is not set
 # CONFIG_NET_SB1000 is not set
 
@@ -232,8 +242,9 @@
 #
 # Ethernet (1000 Mbit)
 #
-# CONFIG_YELLOWFIN is not set
 # CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -288,6 +299,15 @@
 # CONFIG_FB is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+
+#
+# Macintosh device drivers
+#
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -312,6 +332,10 @@
 # Joysticks
 #
 # CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -321,12 +345,6 @@
 # CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_FLASH is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -335,8 +353,13 @@
 # Ftape, the floppy tape device driver
 #
 # CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
 # CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
 
 #
 # File systems
@@ -344,6 +367,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -356,6 +381,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
@@ -398,8 +424,6 @@
 # CONFIG_NCPFS_NFS_NS is not set
 # CONFIG_NCPFS_OS2_NS is not set
 # CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 
@@ -416,6 +440,7 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
@@ -430,14 +455,15 @@
 CONFIG_FEC_ENET=y
 CONFIG_USE_MDIO=y
 CONFIG_ENET_BIG_BUFFERS=y
-# CONFIG_8xxSMC2 is not set
-# CONFIG_8xxSCC is not set
+# CONFIG_SMC2_UART is not set
+# CONFIG_USE_SCC_IO is not set
 
 #
 # Generic MPC8xx Options
 #
 CONFIG_8xx_COPYBACK=y
 # CONFIG_8xx_CPU6 is not set
+CONFIG_BLK_DEV_MPC8xx_IDE=y
 
 #
 # USB support
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/SM850_defconfig linux/arch/ppc/configs/SM850_defconfig
--- v2.4.4/linux/arch/ppc/configs/SM850_defconfig	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/configs/SM850_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -23,7 +25,6 @@
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
 CONFIG_8xx=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_RPXLITE is not set
@@ -36,13 +37,14 @@
 # CONFIG_FPS850L is not set
 # CONFIG_TQM860 is not set
 # CONFIG_SPD823TS is not set
+# CONFIG_IVMS8 is not set
 CONFIG_SM850=y
 # CONFIG_MBX is not set
 # CONFIG_WINCEPT is not set
 CONFIG_TQM8xxL=y
+# CONFIG_PPC601_SYNC_FIX is not set
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 CONFIG_MATH_EMULATION=y
 CONFIG_SASH=y
 CONFIG_SASH_PATH="/bin/sash"
@@ -50,8 +52,12 @@
 #
 # General setup
 #
+# CONFIG_HIGHMEM is not set
 # CONFIG_ISA is not set
+# CONFIG_EISA is not set
 # CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+# CONFIG_PCI_QSPAN is not set
 # CONFIG_PCI is not set
 CONFIG_NET=y
 CONFIG_SYSCTL=y
@@ -87,17 +93,23 @@
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
 # CONFIG_BLK_DEV_MD is not set
 # CONFIG_MD_LINEAR is not set
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
 
 #
 # Networking options
@@ -116,10 +128,8 @@
 CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
-# CONFIG_IP_ROUTER is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
-# CONFIG_IP_ALIAS is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
@@ -136,6 +146,7 @@
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
 # CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_FASTROUTE is not set
@@ -170,6 +181,7 @@
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
 # CONFIG_ETHERTAP is not set
 # CONFIG_NET_SB1000 is not set
 
@@ -195,8 +207,9 @@
 #
 # Ethernet (1000 Mbit)
 #
-# CONFIG_YELLOWFIN is not set
 # CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -251,6 +264,15 @@
 # CONFIG_FB is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+
+#
+# Macintosh device drivers
+#
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -275,6 +297,10 @@
 # Joysticks
 #
 # CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -284,13 +310,6 @@
 # CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-CONFIG_FLASH=y
-CONFIG_AMD_FLASH=y
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -299,8 +318,13 @@
 # Ftape, the floppy tape device driver
 #
 # CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
 # CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
 
 #
 # File systems
@@ -308,6 +332,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -320,6 +346,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
@@ -362,8 +389,6 @@
 # CONFIG_NCPFS_NFS_NS is not set
 # CONFIG_NCPFS_OS2_NS is not set
 # CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 
@@ -380,6 +405,7 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
@@ -396,10 +422,10 @@
 CONFIG_SCC3_ENET=y
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
-CONFIG_8xxSMC2=y
-CONFIG_8xx_ALTSMC2=y
-CONFIG_8xx_CONS_SMC2=y
-# CONFIG_8xxSCC is not set
+CONFIG_SMC2_UART=y
+CONFIG_ALTSMC2=y
+CONFIG_CONS_SMC2=y
+# CONFIG_USE_SCC_IO is not set
 
 #
 # Generic MPC8xx Options
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/SPD823TS_defconfig linux/arch/ppc/configs/SPD823TS_defconfig
--- v2.4.4/linux/arch/ppc/configs/SPD823TS_defconfig	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/configs/SPD823TS_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -23,7 +25,6 @@
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
 CONFIG_8xx=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_RPXLITE is not set
@@ -36,11 +37,13 @@
 # CONFIG_FPS850L is not set
 # CONFIG_TQM860 is not set
 CONFIG_SPD823TS=y
+# CONFIG_IVMS8 is not set
+# CONFIG_SM850 is not set
 # CONFIG_MBX is not set
 # CONFIG_WINCEPT is not set
+# CONFIG_PPC601_SYNC_FIX is not set
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 CONFIG_MATH_EMULATION=y
 CONFIG_SASH=y
 CONFIG_SASH_PATH="/bin/sash"
@@ -48,8 +51,12 @@
 #
 # General setup
 #
+# CONFIG_HIGHMEM is not set
 # CONFIG_ISA is not set
+# CONFIG_EISA is not set
 # CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+# CONFIG_PCI_QSPAN is not set
 # CONFIG_PCI is not set
 CONFIG_NET=y
 CONFIG_SYSCTL=y
@@ -85,17 +92,23 @@
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
 # CONFIG_BLK_DEV_MD is not set
 # CONFIG_MD_LINEAR is not set
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
 
 #
 # Networking options
@@ -114,10 +127,8 @@
 CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
-# CONFIG_IP_ROUTER is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
-# CONFIG_IP_ALIAS is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
@@ -134,6 +145,7 @@
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
 # CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_FASTROUTE is not set
@@ -168,6 +180,7 @@
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
 # CONFIG_ETHERTAP is not set
 # CONFIG_NET_SB1000 is not set
 
@@ -193,8 +206,9 @@
 #
 # Ethernet (1000 Mbit)
 #
-# CONFIG_YELLOWFIN is not set
 # CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -249,6 +263,15 @@
 # CONFIG_FB is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+
+#
+# Macintosh device drivers
+#
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -273,6 +296,10 @@
 # Joysticks
 #
 # CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -282,12 +309,6 @@
 # CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-# CONFIG_FLASH is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -296,8 +317,13 @@
 # Ftape, the floppy tape device driver
 #
 # CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
 # CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
 
 #
 # File systems
@@ -305,6 +331,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -317,6 +345,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
@@ -359,8 +388,6 @@
 # CONFIG_NCPFS_NFS_NS is not set
 # CONFIG_NCPFS_OS2_NS is not set
 # CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 
@@ -377,6 +404,7 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
@@ -390,12 +418,13 @@
 CONFIG_SCC_ENET=y
 # CONFIG_SCC1_ENET is not set
 CONFIG_SCC2_ENET=y
+# CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
-CONFIG_8xxSMC2=y
-CONFIG_8xx_ALTSMC2=y
-# CONFIG_8xx_CONS_SMC2 is not set
-# CONFIG_8xxSCC is not set
+CONFIG_SMC2_UART=y
+CONFIG_ALTSMC2=y
+# CONFIG_CONS_SMC2 is not set
+# CONFIG_USE_SCC_IO is not set
 
 #
 # Generic MPC8xx Options
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/TQM823L_defconfig linux/arch/ppc/configs/TQM823L_defconfig
--- v2.4.4/linux/arch/ppc/configs/TQM823L_defconfig	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/configs/TQM823L_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -23,7 +25,6 @@
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
 CONFIG_8xx=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_RPXLITE is not set
@@ -36,12 +37,14 @@
 # CONFIG_FPS850L is not set
 # CONFIG_TQM860 is not set
 # CONFIG_SPD823TS is not set
+# CONFIG_IVMS8 is not set
+# CONFIG_SM850 is not set
 # CONFIG_MBX is not set
 # CONFIG_WINCEPT is not set
 CONFIG_TQM8xxL=y
+# CONFIG_PPC601_SYNC_FIX is not set
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 CONFIG_MATH_EMULATION=y
 CONFIG_SASH=y
 CONFIG_SASH_PATH="/bin/sash"
@@ -49,8 +52,12 @@
 #
 # General setup
 #
+# CONFIG_HIGHMEM is not set
 # CONFIG_ISA is not set
+# CONFIG_EISA is not set
 # CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+# CONFIG_PCI_QSPAN is not set
 # CONFIG_PCI is not set
 CONFIG_NET=y
 CONFIG_SYSCTL=y
@@ -86,17 +93,23 @@
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
 # CONFIG_BLK_DEV_MD is not set
 # CONFIG_MD_LINEAR is not set
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
 
 #
 # Networking options
@@ -115,10 +128,8 @@
 CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
-# CONFIG_IP_ROUTER is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
-# CONFIG_IP_ALIAS is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
@@ -135,6 +146,7 @@
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
 # CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_FASTROUTE is not set
@@ -169,6 +181,7 @@
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
 # CONFIG_ETHERTAP is not set
 # CONFIG_NET_SB1000 is not set
 
@@ -194,8 +207,9 @@
 #
 # Ethernet (1000 Mbit)
 #
-# CONFIG_YELLOWFIN is not set
 # CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -250,6 +264,15 @@
 # CONFIG_FB is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+
+#
+# Macintosh device drivers
+#
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -274,6 +297,10 @@
 # Joysticks
 #
 # CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -283,13 +310,6 @@
 # CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-CONFIG_FLASH=y
-CONFIG_AMD_FLASH=y
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -298,8 +318,13 @@
 # Ftape, the floppy tape device driver
 #
 # CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
 # CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
 
 #
 # File systems
@@ -307,6 +332,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -319,6 +346,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
@@ -361,8 +389,6 @@
 # CONFIG_NCPFS_NFS_NS is not set
 # CONFIG_NCPFS_OS2_NS is not set
 # CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 
@@ -379,6 +405,7 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
@@ -395,10 +422,10 @@
 # CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
-CONFIG_8xxSMC2=y
-CONFIG_8xx_ALTSMC2=y
-# CONFIG_8xx_CONS_SMC2 is not set
-# CONFIG_8xxSCC is not set
+CONFIG_SMC2_UART=y
+CONFIG_ALTSMC2=y
+# CONFIG_CONS_SMC2 is not set
+# CONFIG_USE_SCC_IO is not set
 
 #
 # Generic MPC8xx Options
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/TQM850L_defconfig linux/arch/ppc/configs/TQM850L_defconfig
--- v2.4.4/linux/arch/ppc/configs/TQM850L_defconfig	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/configs/TQM850L_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -23,7 +25,6 @@
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
 CONFIG_8xx=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_RPXLITE is not set
@@ -36,12 +37,14 @@
 # CONFIG_FPS850L is not set
 # CONFIG_TQM860 is not set
 # CONFIG_SPD823TS is not set
+# CONFIG_IVMS8 is not set
+# CONFIG_SM850 is not set
 # CONFIG_MBX is not set
 # CONFIG_WINCEPT is not set
 CONFIG_TQM8xxL=y
+# CONFIG_PPC601_SYNC_FIX is not set
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 CONFIG_MATH_EMULATION=y
 CONFIG_SASH=y
 CONFIG_SASH_PATH="/bin/sash"
@@ -49,8 +52,12 @@
 #
 # General setup
 #
+# CONFIG_HIGHMEM is not set
 # CONFIG_ISA is not set
+# CONFIG_EISA is not set
 # CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+# CONFIG_PCI_QSPAN is not set
 # CONFIG_PCI is not set
 CONFIG_NET=y
 CONFIG_SYSCTL=y
@@ -86,17 +93,23 @@
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
 # CONFIG_BLK_DEV_MD is not set
 # CONFIG_MD_LINEAR is not set
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
 
 #
 # Networking options
@@ -115,10 +128,8 @@
 CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
-# CONFIG_IP_ROUTER is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
-# CONFIG_IP_ALIAS is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
@@ -135,6 +146,7 @@
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
 # CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_FASTROUTE is not set
@@ -169,6 +181,7 @@
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
 # CONFIG_ETHERTAP is not set
 # CONFIG_NET_SB1000 is not set
 
@@ -194,8 +207,9 @@
 #
 # Ethernet (1000 Mbit)
 #
-# CONFIG_YELLOWFIN is not set
 # CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -250,6 +264,15 @@
 # CONFIG_FB is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+
+#
+# Macintosh device drivers
+#
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -274,6 +297,10 @@
 # Joysticks
 #
 # CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -283,13 +310,6 @@
 # CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-CONFIG_FLASH=y
-CONFIG_AMD_FLASH=y
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -298,8 +318,13 @@
 # Ftape, the floppy tape device driver
 #
 # CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
 # CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
 
 #
 # File systems
@@ -307,6 +332,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -319,6 +346,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
@@ -361,8 +389,6 @@
 # CONFIG_NCPFS_NFS_NS is not set
 # CONFIG_NCPFS_OS2_NS is not set
 # CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 
@@ -379,6 +405,7 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
@@ -395,10 +422,10 @@
 # CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
-CONFIG_8xxSMC2=y
-CONFIG_8xx_ALTSMC2=y
-# CONFIG_8xx_CONS_SMC2 is not set
-# CONFIG_8xxSCC is not set
+CONFIG_SMC2_UART=y
+CONFIG_ALTSMC2=y
+# CONFIG_CONS_SMC2 is not set
+# CONFIG_USE_SCC_IO is not set
 
 #
 # Generic MPC8xx Options
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/TQM860L_defconfig linux/arch/ppc/configs/TQM860L_defconfig
--- v2.4.4/linux/arch/ppc/configs/TQM860L_defconfig	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/configs/TQM860L_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -23,7 +25,6 @@
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
 CONFIG_8xx=y
 CONFIG_SERIAL_CONSOLE=y
 # CONFIG_RPXLITE is not set
@@ -36,12 +37,14 @@
 # CONFIG_FPS850L is not set
 # CONFIG_TQM860 is not set
 # CONFIG_SPD823TS is not set
+# CONFIG_IVMS8 is not set
+# CONFIG_SM850 is not set
 # CONFIG_MBX is not set
 # CONFIG_WINCEPT is not set
 CONFIG_TQM8xxL=y
+# CONFIG_PPC601_SYNC_FIX is not set
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 CONFIG_MATH_EMULATION=y
 CONFIG_SASH=y
 CONFIG_SASH_PATH="/bin/sash"
@@ -49,8 +52,12 @@
 #
 # General setup
 #
+# CONFIG_HIGHMEM is not set
 # CONFIG_ISA is not set
+# CONFIG_EISA is not set
 # CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+# CONFIG_PCI_QSPAN is not set
 # CONFIG_PCI is not set
 CONFIG_NET=y
 CONFIG_SYSCTL=y
@@ -86,17 +93,23 @@
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
 # CONFIG_BLK_DEV_MD is not set
 # CONFIG_MD_LINEAR is not set
 # CONFIG_MD_RAID0 is not set
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
 
 #
 # Networking options
@@ -115,10 +128,8 @@
 CONFIG_IP_PNP=y
 # CONFIG_IP_PNP_BOOTP is not set
 # CONFIG_IP_PNP_RARP is not set
-# CONFIG_IP_ROUTER is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
-# CONFIG_IP_ALIAS is not set
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 # CONFIG_IPV6 is not set
@@ -135,6 +146,7 @@
 # CONFIG_X25 is not set
 # CONFIG_LAPB is not set
 # CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_NET_FASTROUTE is not set
@@ -169,6 +181,7 @@
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
 # CONFIG_ETHERTAP is not set
 # CONFIG_NET_SB1000 is not set
 
@@ -194,8 +207,9 @@
 #
 # Ethernet (1000 Mbit)
 #
-# CONFIG_YELLOWFIN is not set
 # CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -250,6 +264,15 @@
 # CONFIG_FB is not set
 
 #
+# Input core support
+#
+# CONFIG_INPUT is not set
+
+#
+# Macintosh device drivers
+#
+
+#
 # Character devices
 #
 # CONFIG_VT is not set
@@ -274,6 +297,10 @@
 # Joysticks
 #
 # CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -283,13 +310,6 @@
 # CONFIG_INTEL_RNG is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
-CONFIG_FLASH=y
-CONFIG_AMD_FLASH=y
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -298,8 +318,13 @@
 # Ftape, the floppy tape device driver
 #
 # CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
 # CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
 
 #
 # File systems
@@ -307,6 +332,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -319,6 +346,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
@@ -361,8 +389,6 @@
 # CONFIG_NCPFS_NFS_NS is not set
 # CONFIG_NCPFS_OS2_NS is not set
 # CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_MOUNT_SUBDIR is not set
-# CONFIG_NCPFS_NDS_DOMAINS is not set
 # CONFIG_NCPFS_NLS is not set
 # CONFIG_NCPFS_EXTRAS is not set
 
@@ -379,6 +405,7 @@
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_ULTRIX_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
 # CONFIG_NLS is not set
 
 #
@@ -395,10 +422,10 @@
 # CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
-CONFIG_8xxSMC2=y
-# CONFIG_8xx_ALTSMC2 is not set
-# CONFIG_8xx_CONS_SMC2 is not set
-# CONFIG_8xxSCC is not set
+CONFIG_SMC2_UART=y
+# CONFIG_ALTSMC2 is not set
+# CONFIG_CONS_SMC2 is not set
+# CONFIG_USE_SCC_IO is not set
 
 #
 # Generic MPC8xx Options
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/apus_defconfig linux/arch/ppc/configs/apus_defconfig
--- v2.4.4/linux/arch/ppc/configs/apus_defconfig	Mon Jan 22 15:41:14 2001
+++ linux/arch/ppc/configs/apus_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -11,7 +13,9 @@
 #
 # Loadable module support
 #
-# CONFIG_MODULES is not set
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
 
 #
 # Platform support
@@ -24,22 +28,21 @@
 # CONFIG_8xx is not set
 # CONFIG_8260 is not set
 # CONFIG_ALL_PPC is not set
+# CONFIG_GEMINI is not set
 CONFIG_APUS=y
-CONFIG_PPC601_SYNC_FIX=y
+# CONFIG_PPC601_SYNC_FIX is not set
 # CONFIG_SMP is not set
 # CONFIG_ALTIVEC is not set
-CONFIG_MACH_SPECIFIC=y
 
 #
 # General setup
 #
 # CONFIG_HIGHMEM is not set
-# CONFIG_MOL is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
 # CONFIG_MCA is not set
-# CONFIG_PCI is not set
+CONFIG_PCI=y
 CONFIG_NET=y
 CONFIG_SYSCTL=y
 CONFIG_SYSVIPC=y
@@ -47,32 +50,42 @@
 CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
 CONFIG_KERNEL_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
+CONFIG_BINFMT_MISC=m
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
 # CONFIG_PCMCIA is not set
 
 #
 # Parallel port support
 #
-# CONFIG_PARPORT is not set
-CONFIG_PPC_RTC=y
+CONFIG_PARPORT=m
+# CONFIG_PARPORT_PC is not set
+CONFIG_PARPORT_AMIGA=m
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_1284 is not set
+CONFIG_GEN_RTC=y
 CONFIG_FB_CONSOLE=y
 CONFIG_AMIGA=y
 CONFIG_ZORRO=y
 CONFIG_AMIGAMOUSE=y
 CONFIG_ABSTRACT_CONSOLE=y
 CONFIG_FB=y
+CONFIG_MOUSE=y
+CONFIG_BUSMOUSE=y
+CONFIG_APUS_FAST_EXCEPT=y
+CONFIG_AMIGA_PCMCIA=y
 CONFIG_AMIGA_BUILTIN_SERIAL=y
-# CONFIG_M68K_PRINTER is not set
 CONFIG_GVPIOEXT=y
-# CONFIG_GVPIOEXT_LP is not set
-CONFIG_GVPIOEXT_PLIP=y
+CONFIG_GVPIOEXT_LP=m
+CONFIG_GVPIOEXT_PLIP=m
 CONFIG_MULTIFACE_III_TTY=y
-# CONFIG_SERIAL_CONSOLE is not set
+CONFIG_A2232=y
+CONFIG_WHIPPET_SERIAL=y
+CONFIG_APNE=y
+CONFIG_SERIAL_CONSOLE=y
 CONFIG_HEARTBEAT=y
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZORRO_NAMES=y
@@ -93,14 +106,14 @@
 #
 # CONFIG_BLK_DEV_FD is not set
 CONFIG_AMIGA_FLOPPY=y
-CONFIG_AMIGA_Z2RAM=y
+CONFIG_AMIGA_Z2RAM=m
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
@@ -108,22 +121,25 @@
 #
 # Multi-device support (RAID and LVM)
 #
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID5=m
+CONFIG_BLK_DEV_LVM=m
 
 #
 # Networking options
 #
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
+CONFIG_PACKET=m
+CONFIG_PACKET_MMAP=y
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+CONFIG_NETLINK_DEV=m
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_FILTER=y
 CONFIG_UNIX=y
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
@@ -132,9 +148,42 @@
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
+CONFIG_SYN_COOKIES=y
+
+#
+#   IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=m
+CONFIG_IP_NF_FTP=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_LIMIT=m
+CONFIG_IP_NF_MATCH_MAC=m
+CONFIG_IP_NF_MATCH_MARK=m
+CONFIG_IP_NF_MATCH_MULTIPORT=m
+CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
+CONFIG_IP_NF_MATCH_STATE=m
+CONFIG_IP_NF_MATCH_UNCLEAN=m
+CONFIG_IP_NF_MATCH_OWNER=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_MIRROR=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_NAT_FTP=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_TCPMSS=m
+CONFIG_IP_NF_COMPAT_IPCHAINS=m
+CONFIG_IP_NF_NAT_NEEDED=y
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
 # CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
+CONFIG_KHTTPD=m
 # CONFIG_ATM is not set
 
 #
@@ -186,9 +235,9 @@
 # CONFIG_BLK_DEV_TIVO is not set
 # CONFIG_BLK_DEV_IDECS is not set
 CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
+CONFIG_BLK_DEV_IDETAPE=m
+CONFIG_BLK_DEV_IDEFLOPPY=y
+CONFIG_BLK_DEV_IDESCSI=m
 
 #
 # IDE chipset support/bugfixes
@@ -196,6 +245,9 @@
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_CMD640_ENHANCED is not set
 # CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
 CONFIG_BLK_DEV_GAYLE=y
 CONFIG_BLK_DEV_IDEDOUBLER=y
 CONFIG_BLK_DEV_BUDDHA=y
@@ -214,35 +266,38 @@
 #
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_SR_EXTRA_DEVS=2
-# CONFIG_CHR_DEV_SG is not set
+CONFIG_SR_EXTRA_DEVS=4
+CONFIG_CHR_DEV_SG=m
 
 #
 # Some SCSI devices (e.g. CD jukebox) support multiple LUNs
 #
 # CONFIG_SCSI_DEBUG_QUEUES is not set
 # CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
 
 #
 # SCSI low-level drivers
 #
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AHA152X is not set
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
 # CONFIG_SCSI_MEGARAID is not set
 # CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
 # CONFIG_SCSI_DMX3191D is not set
 # CONFIG_SCSI_DTC3280 is not set
 # CONFIG_SCSI_EATA is not set
@@ -253,20 +308,47 @@
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX is not set
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
 # CONFIG_SCSI_PCI2220I is not set
 # CONFIG_SCSI_PSI240I is not set
 # CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_SIM710 is not set
 # CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_MESH is not set
 # CONFIG_SCSI_MAC53C94 is not set
+CONFIG_A3000_SCSI=y
+CONFIG_A4000T_SCSI=y
+CONFIG_A2091_SCSI=y
+CONFIG_GVP11_SCSI=y
+CONFIG_CYBERSTORM_SCSI=y
+CONFIG_CYBERSTORMII_SCSI=y
+CONFIG_BLZ2060_SCSI=y
+CONFIG_BLZ1230_SCSI=y
+CONFIG_FASTLANE_SCSI=y
+CONFIG_A4091_SCSI=y
+CONFIG_WARPENGINE_SCSI=y
+CONFIG_BLZ603EPLUS_SCSI=y
+CONFIG_OKTAGON_SCSI=y
+CONFIG_CYBERSTORMIII_SCSI=y
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
 
 #
 # Network device support
@@ -277,10 +359,11 @@
 # ARCnet devices
 #
 # CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
+CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
+CONFIG_TUN=m
+# CONFIG_ETHERTAP is not set
 # CONFIG_NET_SB1000 is not set
 
 #
@@ -290,9 +373,10 @@
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 CONFIG_ARIADNE=y
-# CONFIG_NE2K_ZORRO is not set
+CONFIG_NE2K_ZORRO=y
 CONFIG_A2065=y
 CONFIG_HYDRA=y
 # CONFIG_NET_VENDOR_3COM is not set
@@ -301,6 +385,7 @@
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_AT1700 is not set
 # CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
 # CONFIG_NET_ISA is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_NET_POCKET is not set
@@ -314,17 +399,19 @@
 # CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
+CONFIG_PLIP=m
 CONFIG_PPP=y
 CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
 CONFIG_PPP_ASYNC=y
 CONFIG_PPP_SYNC_TTY=y
 CONFIG_PPP_DEFLATE=y
 CONFIG_PPP_BSDCOMP=y
-# CONFIG_PPPOE is not set
+CONFIG_PPPOE=y
 CONFIG_SLIP=y
 CONFIG_SLIP_COMPRESSED=y
 CONFIG_SLIP_SMART=y
-# CONFIG_SLIP_MODE_SLIP6 is not set
+CONFIG_SLIP_MODE_SLIP6=y
 
 #
 # Wireless LAN (non-hamradio)
@@ -374,10 +461,13 @@
 #
 CONFIG_FB=y
 CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
 CONFIG_FB_CLGEN=y
 CONFIG_FB_PM2=y
+# CONFIG_FB_PM2_FIFO_DISCONNECT is not set
+# CONFIG_FB_PM2_PCI is not set
 CONFIG_FB_PM2_CVPPC=y
-# CONFIG_FB_CYBER2000 is not set
+CONFIG_FB_CYBER2000=y
 CONFIG_FB_AMIGA=y
 CONFIG_FB_AMIGA_OCS=y
 CONFIG_FB_AMIGA_ECS=y
@@ -385,7 +475,7 @@
 CONFIG_FB_CYBER=y
 CONFIG_FB_VIRGE=y
 CONFIG_FB_RETINAZ3=y
-# CONFIG_FB_FM2 is not set
+CONFIG_FB_FM2=y
 # CONFIG_FB_OF is not set
 # CONFIG_FB_CONTROL is not set
 # CONFIG_FB_PLATINUM is not set
@@ -394,25 +484,50 @@
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_S3TRIO is not set
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_E1355 is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_SIS is not set
 # CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_MFB=y
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
 CONFIG_FBCON_CFB8=y
 CONFIG_FBCON_CFB16=y
 CONFIG_FBCON_CFB24=y
 CONFIG_FBCON_CFB32=y
 CONFIG_FBCON_AFB=y
 CONFIG_FBCON_ILBM=y
-CONFIG_FBCON_FONTWIDTH8_ONLY=y
-# CONFIG_FBCON_FONTS is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+CONFIG_FBCON_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_8x16=y
+CONFIG_FONT_SUN8x16=y
+CONFIG_FONT_SUN12x22=y
+CONFIG_FONT_6x11=y
 CONFIG_FONT_PEARL_8x8=y
+CONFIG_FONT_ACORN_8x8=y
 
 #
 # Input core support
 #
-# CONFIG_INPUT is not set
+CONFIG_INPUT=m
+CONFIG_INPUT_KEYBDEV=m
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+CONFIG_INPUT_JOYDEV=m
+CONFIG_INPUT_EVDEV=m
 
 #
 # Macintosh device drivers
@@ -423,11 +538,14 @@
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
 
 #
 # I2C support
@@ -437,8 +555,14 @@
 #
 # Mice
 #
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
+CONFIG_BUSMOUSE=y
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_LOGIBUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+CONFIG_MOUSE=y
+# CONFIG_PSMOUSE is not set
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
 
 #
 # Joysticks
@@ -477,8 +601,10 @@
 # File systems
 #
 # CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS_FS=m
+CONFIG_AUTOFS4_FS=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 CONFIG_AFFS_FS=y
@@ -490,10 +616,11 @@
 CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_RAMFS is not set
+CONFIG_CRAMFS=y
+CONFIG_TMPFS=y
+CONFIG_RAMFS=m
 CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
+CONFIG_JOLIET=y
 CONFIG_MINIX_FS=y
 # CONFIG_NTFS_FS is not set
 # CONFIG_NTFS_RW is not set
@@ -502,10 +629,10 @@
 # CONFIG_DEVFS_FS is not set
 # CONFIG_DEVFS_MOUNT is not set
 # CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
+CONFIG_DEVPTS_FS=y
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_ROMFS_FS=y
 CONFIG_EXT2_FS=y
 # CONFIG_SYSV_FS is not set
 # CONFIG_SYSV_FS_WRITE is not set
@@ -517,15 +644,17 @@
 #
 # Network File Systems
 #
-# CONFIG_CODA_FS is not set
+CONFIG_CODA_FS=m
 CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
+CONFIG_NFS_V3=y
 # CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
-# CONFIG_SMB_FS is not set
+CONFIG_LOCKD_V4=y
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_NCPFS_PACKET_SIGNING is not set
 # CONFIG_NCPFS_IOCTL_LOCKING is not set
@@ -539,53 +668,116 @@
 #
 # Partition Types
 #
-# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
 CONFIG_AMIGA_PARTITION=y
-# CONFIG_SMB_NLS is not set
+CONFIG_ATARI_PARTITION=y
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+# CONFIG_MINIX_SUBPARTITION is not set
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+CONFIG_SMB_NLS=y
 CONFIG_NLS=y
 
 #
 # Native Language Support
 #
 CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_ISO8859_9 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_UTF8 is not set
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_NLS_UTF8=m
 
 #
 # Sound
 #
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+CONFIG_DMASOUND_PAULA=m
+CONFIG_DMASOUND=m
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_MAESTRO3 is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_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=m
+CONFIG_SOUND_TRACEINIT=y
+CONFIG_SOUND_DMAP=y
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+CONFIG_SOUND_VMIDI=m
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_YMFPCI_LEGACY is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_TVMIXER is not set
 
 #
 # USB support
@@ -595,6 +787,6 @@
 #
 # Kernel hacking
 #
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_KGDB is not set
 # CONFIG_XMON is not set
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/bseip_defconfig linux/arch/ppc/configs/bseip_defconfig
--- v2.4.4/linux/arch/ppc/configs/bseip_defconfig	Mon Jan 22 15:41:14 2001
+++ linux/arch/ppc/configs/bseip_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -26,22 +28,26 @@
 # CONFIG_RPXLITE is not set
 # CONFIG_RPXCLASSIC is not set
 CONFIG_BSEIP=y
-# CONFIG_TQM8xxL is not set
+# CONFIG_TQM823L is not set
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
 # CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
 # CONFIG_TQM860 is not set
+# CONFIG_SPD823TS is not set
+# CONFIG_IVMS8 is not set
+# CONFIG_SM850 is not set
 # CONFIG_MBX is not set
 # CONFIG_WINCEPT is not set
 CONFIG_PPC601_SYNC_FIX=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 CONFIG_MATH_EMULATION=y
 
 #
 # General setup
 #
 # CONFIG_HIGHMEM is not set
-# CONFIG_MOL is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
@@ -100,7 +106,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -184,6 +189,7 @@
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -323,6 +329,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -335,6 +343,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
@@ -407,11 +416,13 @@
 CONFIG_SCC_ENET=y
 # CONFIG_SCC1_ENET is not set
 CONFIG_SCC2_ENET=y
+# CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 # CONFIG_ENET_BIG_BUFFERS is not set
-CONFIG_8xxSMC2=y
-# CONFIG_8xx_ALTSMC2 is not set
-# CONFIG_8xxSCC is not set
+CONFIG_SMC2_UART=y
+# CONFIG_ALTSMC2 is not set
+# CONFIG_CONS_SMC2 is not set
+# CONFIG_USE_SCC_IO is not set
 
 #
 # Generic MPC8xx Options
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/common_defconfig linux/arch/ppc/configs/common_defconfig
--- v2.4.4/linux/arch/ppc/configs/common_defconfig	Sun Mar  4 14:30:18 2001
+++ linux/arch/ppc/configs/common_defconfig	Wed May 16 09:57:20 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -26,6 +28,7 @@
 # CONFIG_8xx is not set
 # CONFIG_8260 is not set
 CONFIG_ALL_PPC=y
+# CONFIG_GEMINI is not set
 # CONFIG_APUS is not set
 CONFIG_PPC601_SYNC_FIX=y
 # CONFIG_SMP is not set
@@ -35,7 +38,6 @@
 # General setup
 #
 # CONFIG_HIGHMEM is not set
-CONFIG_MOL=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
@@ -105,7 +107,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -141,6 +142,7 @@
 CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
 CONFIG_IP_NF_MATCH_STATE=m
 CONFIG_IP_NF_MATCH_UNCLEAN=m
 CONFIG_IP_NF_MATCH_OWNER=m
@@ -151,8 +153,10 @@
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_NAT_FTP=m
 # CONFIG_IP_NF_MANGLE is not set
 # CONFIG_IP_NF_TARGET_LOG is not set
+CONFIG_IP_NF_TARGET_TCPMSS=m
 CONFIG_IP_NF_COMPAT_IPCHAINS=m
 CONFIG_IP_NF_NAT_NEEDED=y
 # CONFIG_IP_NF_COMPAT_IPFWADM is not set
@@ -296,6 +300,8 @@
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
 CONFIG_SCSI_AIC7XXX=m
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
+CONFIG_AIC7XXX_RESET_DELAY=5000
 CONFIG_SCSI_AIC7XXX_OLD=m
 # CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT is not set
 CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8
@@ -376,8 +382,10 @@
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_MACE=y
+# CONFIG_MACE_AAUI_PORT is not set
 CONFIG_BMAC=y
 CONFIG_GMAC=y
+# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -404,7 +412,9 @@
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139TOO is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -425,6 +435,7 @@
 # CONFIG_HIPPI is not set
 CONFIG_PPP=y
 CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
 CONFIG_PPP_ASYNC=y
 # CONFIG_PPP_SYNC_TTY is not set
 CONFIG_PPP_DEFLATE=y
@@ -492,6 +503,7 @@
 CONFIG_FB_IMSTT=y
 # CONFIG_FB_S3TRIO is not set
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_E1355 is not set
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
@@ -544,6 +556,7 @@
 CONFIG_INPUT_ADBHID=y
 CONFIG_MAC_ADBKEYCODES=y
 CONFIG_MAC_EMUMOUSEBTN=y
+CONFIG_MAC_HID=y
 
 #
 # Character devices
@@ -612,6 +625,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -624,6 +639,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
@@ -680,6 +696,7 @@
 CONFIG_MAC_PARTITION=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
 # CONFIG_SGI_PARTITION is not set
@@ -707,11 +724,13 @@
 # CONFIG_NLS_CODEPAGE_865 is not set
 # CONFIG_NLS_CODEPAGE_866 is not set
 # CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
 # CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_949 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_1251 is not set
 CONFIG_NLS_ISO8859_1=m
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
@@ -719,11 +738,12 @@
 # CONFIG_NLS_ISO8859_5 is not set
 # CONFIG_NLS_ISO8859_6 is not set
 # CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 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
 
 #
@@ -740,6 +760,8 @@
 # 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_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
@@ -814,7 +836,6 @@
 # USB Serial Converter support
 #
 CONFIG_USB_SERIAL=m
-# CONFIG_USB_SERIAL_DEBUG is not set
 # CONFIG_USB_SERIAL_GENERIC is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
@@ -822,6 +843,7 @@
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
 CONFIG_USB_SERIAL_VISOR=m
+# CONFIG_USB_SERIAL_EDGEPORT is not set
 # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
 # CONFIG_USB_SERIAL_KEYSPAN is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/est8260_defconfig linux/arch/ppc/configs/est8260_defconfig
--- v2.4.4/linux/arch/ppc/configs/est8260_defconfig	Mon Jan 22 15:41:14 2001
+++ linux/arch/ppc/configs/est8260_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -28,13 +30,11 @@
 CONFIG_PPC601_SYNC_FIX=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 
 #
 # General setup
 #
 # CONFIG_HIGHMEM is not set
-# CONFIG_MOL is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
@@ -93,7 +93,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -177,6 +176,7 @@
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -317,6 +317,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -329,6 +331,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/gemini_defconfig linux/arch/ppc/configs/gemini_defconfig
--- v2.4.4/linux/arch/ppc/configs/gemini_defconfig	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/configs/gemini_defconfig	Mon May 21 17:04:46 2001
@@ -0,0 +1,509 @@
+#
+# Automatically generated make config: don't edit
+#
+# CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_6xx=y
+# CONFIG_4xx is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
+# CONFIG_8xx is not set
+# CONFIG_8260 is not set
+# CONFIG_ALL_PPC is not set
+CONFIG_GEMINI=y
+# CONFIG_APUS is not set
+# CONFIG_PPC601_SYNC_FIX is not set
+# CONFIG_SMP is not set
+CONFIG_ALTIVEC=y
+
+#
+# General setup
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_ISA is not set
+# CONFIG_EISA is not set
+# CONFIG_SBUS is not set
+# CONFIG_MCA is not set
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+# CONFIG_PPC_RTC is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_BLK_DEV_LVM is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES 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_COMPAT_IPCHAINS is not set
+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_NET_DIVERT is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_SD_EXTRA_DEVS=40
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 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_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+CONFIG_SCSI_SYM53C8XX=y
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
+CONFIG_SCSI_NCR53C8XX_SYNC=20
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
+# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
+# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_MESH is not set
+# CONFIG_SCSI_MAC53C94 is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_GMAC is not set
+CONFIG_NCR885E=y
+# CONFIG_OAKNET is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Input core support
+#
+# CONFIG_INPUT is not set
+
+#
+# Macintosh device drivers
+#
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_ROOT_NFS is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+CONFIG_SOLARIS_X86_PARTITION=y
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_SMB_NLS is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_KGDB is not set
+CONFIG_XMON=y
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/ibmchrp_defconfig linux/arch/ppc/configs/ibmchrp_defconfig
--- v2.4.4/linux/arch/ppc/configs/ibmchrp_defconfig	Mon Jan 22 15:41:14 2001
+++ linux/arch/ppc/configs/ibmchrp_defconfig	Wed May 16 09:57:20 2001
@@ -1,7 +1,9 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -23,8 +25,8 @@
 # CONFIG_4xx is not set
 # CONFIG_POWER3 is not set
 # CONFIG_POWER4 is not set
-# CONFIG_8260 is not set
 # CONFIG_8xx is not set
+# CONFIG_8260 is not set
 CONFIG_ALL_PPC=y
 # CONFIG_GEMINI is not set
 # CONFIG_APUS is not set
@@ -36,7 +38,6 @@
 # General setup
 #
 CONFIG_HIGHMEM=y
-# CONFIG_MOL is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
@@ -101,7 +102,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -137,6 +137,7 @@
 CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
 CONFIG_IP_NF_MATCH_STATE=m
 CONFIG_IP_NF_MATCH_UNCLEAN=m
 CONFIG_IP_NF_MATCH_OWNER=m
@@ -147,14 +148,20 @@
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_NAT_FTP=m
 # CONFIG_IP_NF_MANGLE is not set
 # CONFIG_IP_NF_TARGET_LOG is not set
+CONFIG_IP_NF_TARGET_TCPMSS=m
 CONFIG_IP_NF_COMPAT_IPCHAINS=m
 CONFIG_IP_NF_NAT_NEEDED=y
 # CONFIG_IP_NF_COMPAT_IPFWADM is not set
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+
+#
+#  
+#
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_DECNET is not set
@@ -184,6 +191,10 @@
 # SCSI support
 #
 CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
 CONFIG_CHR_DEV_ST=y
@@ -192,6 +203,10 @@
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_SR_EXTRA_DEVS=2
 CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
 # CONFIG_SCSI_DEBUG_QUEUES is not set
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
@@ -207,6 +222,7 @@
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
@@ -306,7 +322,9 @@
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139TOO is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -337,11 +355,9 @@
 # Token Ring devices
 #
 CONFIG_TR=y
-# CONFIG_IBMTR is not set
 CONFIG_IBMOL=y
 # CONFIG_IBMLS is not set
 # CONFIG_TMS380TR is not set
-# CONFIG_SMCTR is not set
 # CONFIG_NET_FC is not set
 # CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
@@ -393,6 +409,7 @@
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_S3TRIO is not set
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_E1355 is not set
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
@@ -439,6 +456,7 @@
 # CONFIG_MAC_FLOPPY is not set
 # CONFIG_MAC_SERIAL is not set
 # CONFIG_ADB is not set
+CONFIG_MAC_HID=y
 
 #
 # Character devices
@@ -473,6 +491,10 @@
 # Joysticks
 #
 # CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -504,6 +526,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -516,6 +540,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
@@ -572,6 +597,7 @@
 CONFIG_MAC_PARTITION=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
 # CONFIG_SGI_PARTITION is not set
@@ -599,11 +625,13 @@
 # CONFIG_NLS_CODEPAGE_865 is not set
 # CONFIG_NLS_CODEPAGE_866 is not set
 # CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
 # CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_949 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_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
@@ -611,11 +639,12 @@
 # CONFIG_NLS_ISO8859_5 is not set
 # CONFIG_NLS_ISO8859_6 is not set
 # CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 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
 
 #
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/mbx_defconfig linux/arch/ppc/configs/mbx_defconfig
--- v2.4.4/linux/arch/ppc/configs/mbx_defconfig	Mon Jan 22 15:41:14 2001
+++ linux/arch/ppc/configs/mbx_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -26,22 +28,26 @@
 # CONFIG_RPXLITE is not set
 # CONFIG_RPXCLASSIC is not set
 # CONFIG_BSEIP is not set
-# CONFIG_TQM8xxL is not set
+# CONFIG_TQM823L is not set
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
 # CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
 # CONFIG_TQM860 is not set
+# CONFIG_SPD823TS is not set
+# CONFIG_IVMS8 is not set
+# CONFIG_SM850 is not set
 CONFIG_MBX=y
 # CONFIG_WINCEPT is not set
 CONFIG_PPC601_SYNC_FIX=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 CONFIG_MATH_EMULATION=y
 
 #
 # General setup
 #
 # CONFIG_HIGHMEM is not set
-# CONFIG_MOL is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
@@ -99,7 +105,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -178,6 +183,7 @@
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -316,6 +322,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -328,6 +336,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
@@ -399,11 +408,14 @@
 #
 CONFIG_SCC_ENET=y
 CONFIG_SCC1_ENET=y
+# CONFIG_SCC2_ENET is not set
+# CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 CONFIG_ENET_BIG_BUFFERS=y
-CONFIG_8xxSMC2=y
-# CONFIG_8xx_ALTSMC2 is not set
-CONFIG_8xxSCC=y
+CONFIG_SMC2_UART=y
+# CONFIG_ALTSMC2 is not set
+# CONFIG_CONS_SMC2 is not set
+CONFIG_USE_SCC_IO=y
 
 #
 # Generic MPC8xx Options
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/oak_defconfig linux/arch/ppc/configs/oak_defconfig
--- v2.4.4/linux/arch/ppc/configs/oak_defconfig	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/configs/oak_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -28,14 +30,12 @@
 # CONFIG_WALNUT is not set
 CONFIG_PPC601_SYNC_FIX=y
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 # CONFIG_MATH_EMULATION is not set
 
 #
 # General setup
 #
 # CONFIG_HIGHMEM is not set
-# CONFIG_MOL is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
@@ -93,7 +93,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -173,6 +172,7 @@
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
 CONFIG_OAKNET=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -312,6 +312,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -324,6 +326,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/power3_defconfig linux/arch/ppc/configs/power3_defconfig
--- v2.4.4/linux/arch/ppc/configs/power3_defconfig	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/configs/power3_defconfig	Wed May 16 09:57:20 2001
@@ -1,7 +1,9 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -27,12 +29,12 @@
 CONFIG_PPC64BRIDGE=y
 CONFIG_ALL_PPC=y
 CONFIG_SMP=y
+# CONFIG_IRQ_ALL_CPUS is not set
 
 #
 # General setup
 #
 CONFIG_HIGHMEM=y
-# CONFIG_MOL is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
@@ -105,10 +107,7 @@
 CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 CONFIG_MD_RAID5=y
-# CONFIG_MD_BOOT is not set
-# CONFIG_AUTODETECT_RAID is not set
 CONFIG_BLK_DEV_LVM=y
-CONFIG_LVM_PROC_FS=y
 
 #
 # Networking options
@@ -133,6 +132,10 @@
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+
+#
+#  
+#
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
 # CONFIG_DECNET is not set
@@ -162,6 +165,10 @@
 # SCSI support
 #
 CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
 CONFIG_CHR_DEV_ST=y
@@ -170,6 +177,10 @@
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_SR_EXTRA_DEVS=2
 CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
 # CONFIG_SCSI_DEBUG_QUEUES is not set
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
@@ -185,6 +196,7 @@
 # CONFIG_SCSI_AHA1542 is not set
 # CONFIG_SCSI_AHA1740 is not set
 # CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
@@ -259,6 +271,7 @@
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -285,7 +298,9 @@
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139TOO is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -317,11 +332,9 @@
 # Token Ring devices
 #
 CONFIG_TR=y
-# CONFIG_IBMTR is not set
 CONFIG_IBMOL=y
 # CONFIG_IBMLS is not set
 # CONFIG_TMS380TR is not set
-# CONFIG_SMCTR is not set
 # CONFIG_NET_FC is not set
 # CONFIG_RCPCI is not set
 # CONFIG_SHAPER is not set
@@ -373,6 +386,7 @@
 # CONFIG_FB_IMSTT is not set
 # CONFIG_FB_S3TRIO is not set
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_E1355 is not set
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
@@ -421,6 +435,7 @@
 # CONFIG_MAC_FLOPPY is not set
 # CONFIG_MAC_SERIAL is not set
 # CONFIG_ADB is not set
+CONFIG_MAC_HID=y
 
 #
 # Character devices
@@ -462,6 +477,10 @@
 # Joysticks
 #
 # CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
 # CONFIG_QIC02_TAPE is not set
 
 #
@@ -507,6 +526,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
@@ -579,11 +599,13 @@
 # CONFIG_NLS_CODEPAGE_865 is not set
 # CONFIG_NLS_CODEPAGE_866 is not set
 # CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
 # CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_949 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_1251 is not set
 CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
@@ -591,11 +613,12 @@
 # CONFIG_NLS_ISO8859_5 is not set
 # CONFIG_NLS_ISO8859_6 is not set
 # CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 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
 
 #
@@ -611,6 +634,8 @@
 # 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_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
@@ -626,7 +651,6 @@
 CONFIG_SOUND_CS4232=m
 # CONFIG_SOUND_SSCAPE is not set
 # CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_ICH is not set
 # CONFIG_SOUND_VMIDI is not set
 # CONFIG_SOUND_TRIX is not set
 CONFIG_SOUND_MSS=m
@@ -643,8 +667,8 @@
 # CONFIG_SOUND_YM3812 is not set
 # CONFIG_SOUND_OPL3SA1 is not set
 # CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_YMPCI is not set
 # CONFIG_SOUND_YMFPCI is not set
+# CONFIG_SOUND_YMFPCI_LEGACY is not set
 # CONFIG_SOUND_UART6850 is not set
 # CONFIG_SOUND_AEDSP16 is not set
 CONFIG_SOUND_TVMIXER=y
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/rpxcllf_defconfig linux/arch/ppc/configs/rpxcllf_defconfig
--- v2.4.4/linux/arch/ppc/configs/rpxcllf_defconfig	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/configs/rpxcllf_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -26,22 +28,26 @@
 # CONFIG_RPXLITE is not set
 CONFIG_RPXCLASSIC=y
 # CONFIG_BSEIP is not set
-# CONFIG_TQM8xxL is not set
+# CONFIG_TQM823L is not set
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
 # CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
 # CONFIG_TQM860 is not set
+# CONFIG_SPD823TS is not set
+# CONFIG_IVMS8 is not set
+# CONFIG_SM850 is not set
 # CONFIG_MBX is not set
 # CONFIG_WINCEPT is not set
 CONFIG_PPC601_SYNC_FIX=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 CONFIG_MATH_EMULATION=y
 
 #
 # General setup
 #
 # CONFIG_HIGHMEM is not set
-# CONFIG_MOL is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
@@ -100,7 +106,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -184,6 +189,7 @@
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -323,6 +329,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -335,6 +343,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
@@ -406,11 +415,15 @@
 #
 CONFIG_SCC_ENET=y
 CONFIG_SCC1_ENET=y
+# CONFIG_SCC2_ENET is not set
+# CONFIG_SCC3_ENET is not set
 CONFIG_FEC_ENET=y
+# CONFIG_USE_MDIO is not set
 CONFIG_ENET_BIG_BUFFERS=y
-CONFIG_8xxSMC2=y
-# CONFIG_8xx_ALTSMC2 is not set
-CONFIG_8xxSCC=y
+CONFIG_SMC2_UART=y
+# CONFIG_ALTSMC2 is not set
+# CONFIG_CONS_SMC2 is not set
+CONFIG_USE_SCC_IO=y
 
 #
 # Generic MPC8xx Options
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/rpxlite_defconfig linux/arch/ppc/configs/rpxlite_defconfig
--- v2.4.4/linux/arch/ppc/configs/rpxlite_defconfig	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/configs/rpxlite_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -26,22 +28,26 @@
 CONFIG_RPXLITE=y
 # CONFIG_RPXCLASSIC is not set
 # CONFIG_BSEIP is not set
-# CONFIG_TQM8xxL is not set
+# CONFIG_TQM823L is not set
+# CONFIG_TQM850L is not set
+# CONFIG_TQM855L is not set
 # CONFIG_TQM860L is not set
+# CONFIG_FPS850L is not set
 # CONFIG_TQM860 is not set
+# CONFIG_SPD823TS is not set
+# CONFIG_IVMS8 is not set
+# CONFIG_SM850 is not set
 # CONFIG_MBX is not set
 # CONFIG_WINCEPT is not set
 CONFIG_PPC601_SYNC_FIX=y
 # CONFIG_ALL_PPC is not set
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 CONFIG_MATH_EMULATION=y
 
 #
 # General setup
 #
 # CONFIG_HIGHMEM is not set
-# CONFIG_MOL is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
@@ -100,7 +106,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -184,6 +189,7 @@
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -323,6 +329,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -335,6 +343,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
@@ -407,10 +416,11 @@
 CONFIG_SCC_ENET=y
 # CONFIG_SCC1_ENET is not set
 CONFIG_SCC2_ENET=y
+# CONFIG_SCC3_ENET is not set
 # CONFIG_FEC_ENET is not set
 # CONFIG_ENET_BIG_BUFFERS is not set
-# CONFIG_8xxSMC2 is not set
-# CONFIG_8xxSCC is not set
+# CONFIG_SMC2_UART is not set
+# CONFIG_USE_SCC_IO is not set
 
 #
 # Generic MPC8xx Options
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/configs/walnut_defconfig linux/arch/ppc/configs/walnut_defconfig
--- v2.4.4/linux/arch/ppc/configs/walnut_defconfig	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/configs/walnut_defconfig	Mon May 21 17:04:46 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -28,14 +30,12 @@
 CONFIG_WALNUT=y
 CONFIG_PPC601_SYNC_FIX=y
 # CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
 # CONFIG_MATH_EMULATION is not set
 
 #
 # General setup
 #
 # CONFIG_HIGHMEM is not set
-# CONFIG_MOL is not set
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
@@ -93,7 +93,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -173,6 +172,7 @@
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
+# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -315,6 +315,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -327,6 +329,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 # CONFIG_ISO9660_FS is not set
 # CONFIG_JOLIET is not set
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/defconfig linux/arch/ppc/defconfig
--- v2.4.4/linux/arch/ppc/defconfig	Sun Mar  4 14:30:18 2001
+++ linux/arch/ppc/defconfig	Wed May 16 09:57:20 2001
@@ -2,6 +2,8 @@
 # Automatically generated make config: don't edit
 #
 # CONFIG_UID16 is not set
+# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 
 #
 # Code maturity level options
@@ -26,6 +28,7 @@
 # CONFIG_8xx is not set
 # CONFIG_8260 is not set
 CONFIG_ALL_PPC=y
+# CONFIG_GEMINI is not set
 # CONFIG_APUS is not set
 CONFIG_PPC601_SYNC_FIX=y
 # CONFIG_SMP is not set
@@ -35,7 +38,6 @@
 # General setup
 #
 # CONFIG_HIGHMEM is not set
-CONFIG_MOL=y
 # CONFIG_ISA is not set
 # CONFIG_EISA is not set
 # CONFIG_SBUS is not set
@@ -105,7 +107,6 @@
 # CONFIG_MD_RAID1 is not set
 # CONFIG_MD_RAID5 is not set
 # CONFIG_BLK_DEV_LVM is not set
-# CONFIG_LVM_PROC_FS is not set
 
 #
 # Networking options
@@ -141,6 +142,7 @@
 CONFIG_IP_NF_MATCH_MARK=m
 CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
+CONFIG_IP_NF_MATCH_TCPMSS=m
 CONFIG_IP_NF_MATCH_STATE=m
 CONFIG_IP_NF_MATCH_UNCLEAN=m
 CONFIG_IP_NF_MATCH_OWNER=m
@@ -151,8 +153,10 @@
 CONFIG_IP_NF_NAT_NEEDED=y
 CONFIG_IP_NF_TARGET_MASQUERADE=m
 CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_NAT_FTP=m
 # CONFIG_IP_NF_MANGLE is not set
 # CONFIG_IP_NF_TARGET_LOG is not set
+CONFIG_IP_NF_TARGET_TCPMSS=m
 CONFIG_IP_NF_COMPAT_IPCHAINS=m
 CONFIG_IP_NF_NAT_NEEDED=y
 # CONFIG_IP_NF_COMPAT_IPFWADM is not set
@@ -297,7 +301,7 @@
 # CONFIG_SCSI_AHA1740 is not set
 CONFIG_SCSI_AIC7XXX=y
 CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
-CONFIG_AIC7XXX_RESET_DELAY=15000
+CONFIG_AIC7XXX_RESET_DELAY_MS=15000
 # CONFIG_SCSI_AIC7XXX_OLD is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
@@ -375,8 +379,10 @@
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_MACE=y
+# CONFIG_MACE_AAUI_PORT is not set
 CONFIG_BMAC=y
 CONFIG_GMAC=y
+# CONFIG_NCR885E is not set
 # CONFIG_OAKNET is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -403,7 +409,9 @@
 # CONFIG_NE3210 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_8139TOO is not set
-# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO_PIO is not set
+# CONFIG_8139TOO_TUNE_TWISTER is not set
+# CONFIG_8139TOO_8129 is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -424,6 +432,7 @@
 # CONFIG_HIPPI is not set
 CONFIG_PPP=y
 CONFIG_PPP_MULTILINK=y
+# CONFIG_PPP_FILTER is not set
 CONFIG_PPP_ASYNC=y
 # CONFIG_PPP_SYNC_TTY is not set
 CONFIG_PPP_DEFLATE=y
@@ -491,6 +500,7 @@
 CONFIG_FB_IMSTT=y
 # CONFIG_FB_S3TRIO is not set
 # CONFIG_FB_VGA16 is not set
+# CONFIG_FB_E1355 is not set
 CONFIG_FB_MATROX=y
 CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
@@ -543,6 +553,7 @@
 CONFIG_INPUT_ADBHID=y
 CONFIG_MAC_ADBKEYCODES=y
 CONFIG_MAC_EMUMOUSEBTN=y
+CONFIG_MAC_HID=y
 
 #
 # Character devices
@@ -611,6 +622,8 @@
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_REISERFS_CHECK is not set
 # CONFIG_ADFS_FS is not set
 # CONFIG_ADFS_FS_RW is not set
 # CONFIG_AFFS_FS is not set
@@ -623,6 +636,7 @@
 # CONFIG_EFS_FS is not set
 # CONFIG_JFFS_FS is not set
 # CONFIG_CRAMFS is not set
+CONFIG_TMPFS=y
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
@@ -679,6 +693,7 @@
 CONFIG_MAC_PARTITION=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
 # CONFIG_SOLARIS_X86_PARTITION is not set
 # CONFIG_UNIXWARE_DISKLABEL is not set
 # CONFIG_SGI_PARTITION is not set
@@ -706,11 +721,13 @@
 # CONFIG_NLS_CODEPAGE_865 is not set
 # CONFIG_NLS_CODEPAGE_866 is not set
 # CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
 # CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_949 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_1251 is not set
 CONFIG_NLS_ISO8859_1=m
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
@@ -718,11 +735,12 @@
 # CONFIG_NLS_ISO8859_5 is not set
 # CONFIG_NLS_ISO8859_6 is not set
 # CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 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
 
 #
@@ -739,6 +757,8 @@
 # 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_SONICVIBES is not set
 # CONFIG_SOUND_TRIDENT is not set
 # CONFIG_SOUND_MSNDCLAS is not set
@@ -813,7 +833,6 @@
 # USB Serial Converter support
 #
 CONFIG_USB_SERIAL=m
-# CONFIG_USB_SERIAL_DEBUG is not set
 # CONFIG_USB_SERIAL_GENERIC is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
@@ -821,6 +840,7 @@
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
 CONFIG_USB_SERIAL_VISOR=m
+# CONFIG_USB_SERIAL_EDGEPORT is not set
 # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
 # CONFIG_USB_SERIAL_KEYSPAN is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile
--- v2.4.4/linux/arch/ppc/kernel/Makefile	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/kernel/Makefile	Mon May 21 17:04:46 2001
@@ -1,3 +1,5 @@
+# BK Id: SCCS/s.Makefile 1.17 05/21/01 00:48:24 cort
+#
 #
 # Makefile for the linux kernel.
 #
@@ -7,12 +9,10 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
+USE_STANDARD_AS_RULE	:= true
+
 ifdef CONFIG_PPC64BRIDGE
-.S.o:
-	$(CC) $(CFLAGS) -D__ASSEMBLY__ -mppc64bridge -c $< -o $*.o
-else
-.S.o:
-	$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $*.o
+EXTRA_AFLAGS		:= -Wa,-mppc64bridge
 endif
 
 ifeq ($(CONFIG_4xx),y)
@@ -31,7 +31,7 @@
 
 export-objs			:= ppc_ksyms.o prep_setup.o 
 
-obj-$(CONFIG_PPC)		:= entry.o traps.o irq.o idle.o time.o misc.o \
+obj-y				:= entry.o traps.o irq.o idle.o time.o misc.o \
 					process.o signal.o bitops.o ptrace.o \
 					ppc_htab.o semaphore.o syscalls.o  \
 					align.o setup.o
@@ -53,18 +53,25 @@
 obj-$(CONFIG_8xx)		+= m8xx_setup.o ppc8xx_pic.o
 ifeq ($(CONFIG_8xx),y)
 obj-$(CONFIG_PCI)		+= qspan_pci.c
+ifndef CONFIG_MATH_EMULATION
+obj-y				+= softemu8xx.o
+endif
 else
-obj-$(CONFIG_PPC)		+= hashtable.o
+obj-y				+= hashtable.o
 endif
-obj-$(CONFIG_MATH_EMULATION)	+= softemu8xx.o
 obj-$(CONFIG_MBX)		+= i8259.o
 obj-$(CONFIG_APUS)		+= apus_setup.o
+ifeq ($(CONFIG_APUS),y)
+obj-$(CONFIG_PCI)		+= apus_pci.o
+endif
 obj-$(CONFIG_ALL_PPC)		+= pmac_pic.o pmac_setup.o pmac_time.o prom.o \
 					feature.o pmac_pci.o chrp_setup.o \
 					chrp_time.o chrp_pci.o 	open_pic.o \
 					indirect_pci.o i8259.o prep_pci.o \
 					prep_time.o prep_nvram.o prep_setup.o
 obj-$(CONFIG_PMAC_BACKLIGHT)	+= pmac_backlight.o
+obj-$(CONFIG_GEMINI)		+= gemini_prom.o gemini_pci.o gemini_setup.o \
+					open_pic.o
 obj-$(CONFIG_8260)		+= m8260_setup.o ppc8260_pic.o
 
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/align.c linux/arch/ppc/kernel/align.c
--- v2.4.4/linux/arch/ppc/kernel/align.c	Mon Jun 19 17:59:36 2000
+++ linux/arch/ppc/kernel/align.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.align.c 1.5 05/17/01 18:14:21 cort
+ */
+/*
  * align.c - handle alignment exceptions for the Power PC.
  *
  * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/apus_pci.c linux/arch/ppc/kernel/apus_pci.c
--- v2.4.4/linux/arch/ppc/kernel/apus_pci.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/apus_pci.c	Mon May 21 17:04:46 2001
@@ -0,0 +1,189 @@
+/*
+ * BK Id: SCCS/s.apus_pci.c 1.3 05/17/01 18:14:21 cort
+ */
+/*
+ * Copyright (C) Michel Dänzer <michdaen@iiic.ethz.ch>
+ *
+ * APUS PCI routines.
+ *
+ * Currently, only B/CVisionPPC cards (Permedia2) are supported.
+ *
+ * Thanks to Geert Uytterhoeven for the idea:
+ * Read values from given config space(s) for the first devices, -1 otherwise
+ *
+ */
+
+#include <linux/config.h>
+#ifdef CONFIG_AMIGA
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+
+#include <asm/init.h>
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+#include <asm/machdep.h>
+
+#include "apus_pci.h"
+
+
+/* These definitions are mostly adapted from pm2fb.c */
+
+#undef APUS_PCI_MASTER_DEBUG
+#ifdef APUS_PCI_MASTER_DEBUG
+#define DPRINTK(a,b...)	printk(KERN_DEBUG "apus_pci: %s: " a, __FUNCTION__ , ## b)
+#else
+#define DPRINTK(a,b...)
+#endif 
+
+/*
+ * The _DEFINITIVE_ memory mapping/unmapping functions.
+ * This is due to the fact that they're changing soooo often...
+ */
+#define DEFW()		wmb()
+#define DEFR()		rmb()
+#define DEFRW()		mb()
+
+#define DEVNO(d)	((d)>>3)
+#define FNNO(d)		((d)&7)
+
+
+extern unsigned long powerup_PCI_present;
+
+static struct pci_controller *apus_hose;
+
+
+__apus
+void *pci_io_base(unsigned int bus)
+{
+	return 0;
+}
+
+
+#define cfg_read(val, addr, type, op)	*val = op((type)(addr))
+#define cfg_write(val, addr, type, op)	op((val), (type *)(addr)); DEFW()
+#define cfg_read_bad	*val = ~0;
+#define cfg_write_bad	;
+#define cfg_read_val(val)	*val
+#define cfg_write_val(val)	val
+
+#define APUS_PCI_OP(rw, size, type, op, mask)					\
+__apus int									\
+apus_pcibios_##rw##_config_##size(struct pci_dev *dev, int offset, type val)	\
+{										\
+	int fnno = FNNO(dev->devfn);						\
+	int devno = DEVNO(dev->devfn);						\
+										\
+	if (dev->bus->number > 0 || devno != 1) {				\
+		cfg_##rw##_bad;							\
+		return PCIBIOS_DEVICE_NOT_FOUND;				\
+	}									\
+	/* base address + function offset + offset ^ endianness conversion */	\
+	cfg_##rw(val, apus_hose->cfg_data + (fnno<<5) + (offset ^ mask),	\
+		 type, op);							\
+										\
+	DPRINTK(#op " b: 0x%x, d: 0x%x, f: 0x%x, o: 0x%x, v: 0x%x\n",		\
+		dev->bus->number, dev->devfn>>3, dev->devfn&7,			\
+		offset, cfg_##rw##_val(val));					\
+	return PCIBIOS_SUCCESSFUL;						\
+}
+
+APUS_PCI_OP(read, byte, u8 *, readb, 3)
+APUS_PCI_OP(read, word, u16 *, readw, 2)
+APUS_PCI_OP(read, dword, u32 *, readl, 0)
+APUS_PCI_OP(write, byte, u8, writeb, 3)
+APUS_PCI_OP(write, word, u16, writew, 2)
+APUS_PCI_OP(write, dword, u32, writel, 0)
+
+
+static struct pci_ops apus_pci_ops = {
+	apus_pcibios_read_config_byte,
+	apus_pcibios_read_config_word,
+	apus_pcibios_read_config_dword,
+	apus_pcibios_write_config_byte,
+	apus_pcibios_write_config_word,
+	apus_pcibios_write_config_dword
+};
+
+static struct resource pci_mem = { "B/CVisionPPC PCI mem", CVPPC_FB_APERTURE_ONE, CVPPC_PCI_CONFIG, IORESOURCE_MEM };
+
+void __init
+apus_pcibios_fixup(void)
+{
+/*	struct pci_dev *dev = pci_find_slot(0, 1<<3);
+	unsigned int reg, val, offset;*/
+
+	/* FIXME: interrupt? */
+	/*dev->interrupt = xxx;*/
+
+        request_resource(&iomem_resource, &pci_mem);
+    	printk("%s: PCI mem resource requested\n", __FUNCTION__);
+}
+
+static void __init apus_pcibios_fixup_bus(struct pci_bus *bus)
+{
+        bus->resource[1] = &pci_mem;
+}
+
+
+/* 
+ * This is from pm2fb.c again
+ * 
+ * Check if PCI (B/CVisionPPC) is available, initialize it and set up
+ * the pcibios_* pointers
+ */
+
+
+void __init
+apus_setup_pci_ptrs(void)
+{
+	if (!powerup_PCI_present) {
+		DPRINTK("no PCI bridge detected\n");
+		return;
+	}
+	DPRINTK("Phase5 B/CVisionPPC PCI bridge detected.\n");
+
+	apus_hose = pcibios_alloc_controller();
+	if (!apus_hose) {
+		printk("apus_pci: Can't allocate PCI controller structure\n");
+		return;
+	}
+
+	if (!(apus_hose->cfg_data = ioremap(CVPPC_PCI_CONFIG, 256))) {
+		printk("apus_pci: unable to map PCI config region\n");
+		return;
+	}
+
+	if (!(apus_hose->cfg_addr = ioremap(CSPPC_PCI_BRIDGE, 256))) {
+		printk("apus_pci: unable to map PCI bridge\n");
+		return;
+	}
+
+	writel(CSPPCF_BRIDGE_BIG_ENDIAN, apus_hose->cfg_addr + CSPPC_BRIDGE_ENDIAN);
+	DEFW();
+
+	writel(CVPPC_REGS_REGION,  apus_hose->cfg_data+ PCI_BASE_ADDRESS_0);
+	DEFW();
+	writel(CVPPC_FB_APERTURE_ONE, apus_hose->cfg_data + PCI_BASE_ADDRESS_1);
+	DEFW();
+	writel(CVPPC_FB_APERTURE_TWO, apus_hose->cfg_data + PCI_BASE_ADDRESS_2);
+	DEFW();
+	writel(CVPPC_ROM_ADDRESS, apus_hose->cfg_data + PCI_ROM_ADDRESS);
+	DEFW();
+
+	writel(0xef000000 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+		PCI_COMMAND_MASTER, apus_hose->cfg_data + PCI_COMMAND);
+	DEFW();
+
+	apus_hose->first_busno = 0;
+	apus_hose->last_busno = 0;
+	apus_hose->ops = &apus_pci_ops;
+	ppc_md.pcibios_fixup = apus_pcibios_fixup;
+	ppc_md.pcibios_fixup_bus = apus_pcibios_fixup_bus;
+
+	return;
+}
+
+#endif /* CONFIG_AMIGA */
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/apus_pci.h linux/arch/ppc/kernel/apus_pci.h
--- v2.4.4/linux/arch/ppc/kernel/apus_pci.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/apus_pci.h	Mon May 21 17:04:46 2001
@@ -0,0 +1,40 @@
+/*
+ * BK Id: SCCS/s.apus_pci.h 1.4 05/17/01 18:14:21 cort
+ */
+/*
+ * Phase5 CybervisionPPC (TVP4020) definitions for the Permedia2 framebuffer
+ * driver.
+ *
+ * Copyright (c) 1998-1999 Ilario Nardinocchi (nardinoc@CS.UniBO.IT)
+ * --------------------------------------------------------------------------
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef APUS_PCI_H
+#define APUS_PCI_H
+
+
+#include "pci.h"
+
+
+#define CSPPC_PCI_BRIDGE		0xfffe0000
+#define CSPPC_BRIDGE_ENDIAN		0x0000
+#define CSPPC_BRIDGE_INT		0x0010
+
+#define	CVPPC_PCI_CONFIG		0xfffc0000
+#define CVPPC_ROM_ADDRESS		0xe2000001
+#define CVPPC_REGS_REGION		0xef000000
+#define CVPPC_FB_APERTURE_ONE		0xe0000000
+#define CVPPC_FB_APERTURE_TWO		0xe1000000
+#define CVPPC_FB_SIZE			0x00800000
+
+/* CVPPC_BRIDGE_ENDIAN */
+#define CSPPCF_BRIDGE_BIG_ENDIAN	0x02
+
+/* CVPPC_BRIDGE_INT */
+#define CSPPCF_BRIDGE_ACTIVE_INT2	0x01
+
+
+#endif	/* APUS_PCI_H */
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/apus_setup.c linux/arch/ppc/kernel/apus_setup.c
--- v2.4.4/linux/arch/ppc/kernel/apus_setup.c	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/apus_setup.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.apus_setup.c 1.11 05/17/01 18:14:21 cort
+ */
+/*
  *  linux/arch/ppc/kernel/apus_setup.c
  *
  *  Copyright (C) 1998, 1999  Jesper Skov
@@ -1017,6 +1020,59 @@
 	0
 };
 
+#define HARDWARE_MAPPED_SIZE (512*1024)
+unsigned long __init apus_find_end_of_memory(void)
+{
+	int shadow = 0;
+	unsigned long total;
+
+	/* The memory size reported by ADOS excludes the 512KB
+	   reserved for PPC exception registers and possibly 512KB
+	   containing a shadow of the ADOS ROM. */
+	{
+		unsigned long size = memory[0].size;
+
+		/* If 2MB aligned, size was probably user
+                   specified. We can't tell anything about shadowing
+                   in this case so skip shadow assignment. */
+		if (0 != (size & 0x1fffff)){
+			/* Align to 512KB to ensure correct handling
+			   of both memfile and system specified
+			   sizes. */
+			size = ((size+0x0007ffff) & 0xfff80000);
+			/* If memory is 1MB aligned, assume
+                           shadowing. */
+			shadow = !(size & 0x80000);
+		}
+
+		/* Add the chunk that ADOS does not see. by aligning
+                   the size to the nearest 2MB limit upwards.  */
+		memory[0].size = ((size+0x001fffff) & 0xffe00000);
+	}
+
+	total = memory[0].size;
+
+	/* Remove the memory chunks that are controlled by special
+           Phase5 hardware. */
+
+	/* Remove the upper 512KB if it contains a shadow of
+	   the ADOS ROM. FIXME: It might be possible to
+	   disable this shadow HW. Check the booter
+	   (ppc_boot.c) */
+	if (shadow)
+		total -= HARDWARE_MAPPED_SIZE;
+
+	/* Remove the upper 512KB where the PPC exception
+	   vectors are mapped. */
+	total -= HARDWARE_MAPPED_SIZE;
+
+	/* Linux/APUS only handles one block of memory -- the one on
+	   the PowerUP board. Other system memory is horrible slow in
+	   comparison. The user can use other memory for swapping
+	   using the z2ram device. */
+	ram_phys_base = memory[0].addr;
+	return total;
+}
 
 __init
 void apus_init_IRQ(void)
@@ -1037,10 +1093,6 @@
 
 	amiga_init_IRQ();
 
-	int_control.int_sti = __no_use_sti;
-	int_control.int_cli = __no_use_cli;
-	int_control.int_save_flags = __no_use_save_flags;
-	int_control.int_restore_flags = __no_use_restore_flags;
 }
 
 __init
@@ -1072,7 +1124,10 @@
 	ppc_md.irq_cannonicalize = apus_irq_cannonicalize;
 	ppc_md.init_IRQ       = apus_init_IRQ;
 	ppc_md.get_irq        = apus_get_irq;
-	ppc_md.post_irq       = apus_post_irq;
+	
+#error Should use the ->end() member of irq_desc[x]. -- Cort
+	/*ppc_md.post_irq       = apus_post_irq;*/
+	
 #ifdef CONFIG_HEARTBEAT
 	ppc_md.heartbeat      = apus_heartbeat;
 	ppc_md.heartbeat_count = 1;
@@ -1091,6 +1146,8 @@
 	ppc_md.set_rtc_time   = apus_set_rtc_time;
 	ppc_md.get_rtc_time   = apus_get_rtc_time;
 	ppc_md.calibrate_decr = apus_calibrate_decr;
+
+	ppc_md.find_end_of_memory = apus_find_end_of_memory;
 
 	ppc_md.nvram_read_val = NULL;
 	ppc_md.nvram_write_val = NULL;
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/bitops.c linux/arch/ppc/kernel/bitops.c
--- v2.4.4/linux/arch/ppc/kernel/bitops.c	Thu Jul 13 09:42:50 2000
+++ linux/arch/ppc/kernel/bitops.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.bitops.c 1.7 05/17/01 18:14:21 cort
+ */
+/*
  * Copyright (C) 1996 Paul Mackerras.
  */
 
@@ -16,10 +19,10 @@
 	unsigned long mask = 1 << (nr & 0x1f);
 	unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
 	
-	__asm__ __volatile__(SMP_WMB "\
-1:	lwarx	%0,0,%3
-	or	%0,%0,%2
-	stwcx.	%0,0,%3
+	__asm__ __volatile__(SMP_WMB "\n\
+1:	lwarx	%0,0,%3 \n\
+	or	%0,%0,%2 \n\
+	stwcx.	%0,0,%3 \n\
 	bne	1b"
 	SMP_MB
 	: "=&r" (old), "=m" (*p)
@@ -33,10 +36,10 @@
 	unsigned long mask = 1 << (nr & 0x1f);
 	unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
 
-	__asm__ __volatile__(SMP_WMB "\
-1:	lwarx	%0,0,%3
-	andc	%0,%0,%2
-	stwcx.	%0,0,%3
+	__asm__ __volatile__(SMP_WMB "\n\
+1:	lwarx	%0,0,%3 \n\
+	andc	%0,%0,%2 \n\
+	stwcx.	%0,0,%3 \n\
 	bne	1b"
 	SMP_MB
 	: "=&r" (old), "=m" (*p)
@@ -50,10 +53,10 @@
 	unsigned long mask = 1 << (nr & 0x1f);
 	unsigned long *p = ((unsigned long *)addr) + (nr >> 5);
 
-	__asm__ __volatile__(SMP_WMB "\
-1:	lwarx	%0,0,%3
-	xor	%0,%0,%2
-	stwcx.	%0,0,%3
+	__asm__ __volatile__(SMP_WMB "\n\
+1:	lwarx	%0,0,%3 \n\
+	xor	%0,%0,%2 \n\
+	stwcx.	%0,0,%3 \n\
 	bne	1b"
 	SMP_MB
 	: "=&r" (old), "=m" (*p)
@@ -67,10 +70,10 @@
 	unsigned int mask = 1 << (nr & 0x1f);
 	volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
 
-	__asm__ __volatile__(SMP_WMB "\
-1:	lwarx	%0,0,%4
-	or	%1,%0,%3
-	stwcx.	%1,0,%4
+	__asm__ __volatile__(SMP_WMB "\n\
+1:	lwarx	%0,0,%4 \n\
+	or	%1,%0,%3 \n\
+	stwcx.	%1,0,%4 \n\
 	bne	1b"
 	SMP_MB
 	: "=&r" (old), "=&r" (t), "=m" (*p)
@@ -86,10 +89,10 @@
 	unsigned int mask = 1 << (nr & 0x1f);
 	volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
 
-	__asm__ __volatile__(SMP_WMB "\
-1:	lwarx	%0,0,%4
-	andc	%1,%0,%3
-	stwcx.	%1,0,%4
+	__asm__ __volatile__(SMP_WMB "\n\
+1:	lwarx	%0,0,%4 \n\
+	andc	%1,%0,%3 \n\
+	stwcx.	%1,0,%4 \n\
 	bne	1b"
 	SMP_MB
 	: "=&r" (old), "=&r" (t), "=m" (*p)
@@ -105,10 +108,10 @@
 	unsigned int mask = 1 << (nr & 0x1f);
 	volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5);
 
-	__asm__ __volatile__(SMP_WMB "\
-1:	lwarx	%0,0,%4
-	xor	%1,%0,%3
-	stwcx.	%1,0,%4
+	__asm__ __volatile__(SMP_WMB "\n\
+1:	lwarx	%0,0,%4 \n\
+	xor	%1,%0,%3 \n\
+	stwcx.	%1,0,%4 \n\
 	bne	1b"
 	SMP_MB
 	: "=&r" (old), "=&r" (t), "=m" (*p)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/checks.c linux/arch/ppc/kernel/checks.c
--- v2.4.4/linux/arch/ppc/kernel/checks.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/ppc/kernel/checks.c	Mon May 21 17:04:46 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.checks.c 1.6 05/17/01 18:14:21 cort
+ */
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/chrp_pci.c linux/arch/ppc/kernel/chrp_pci.c
--- v2.4.4/linux/arch/ppc/kernel/chrp_pci.c	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/kernel/chrp_pci.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.chrp_pci.c 1.16 05/17/01 18:14:21 cort
+ */
+/*
  * CHRP pci routines.
  */
 
@@ -264,6 +267,7 @@
 	}
 }
 
+#if 0
 static struct {
     /* parent is iomem */
     struct resource ram, pci_mem, isa_mem, pci_io, pci_cfg, rom_exp, flash;
@@ -297,62 +301,7 @@
 {
     	bus->resource[1] = &gg2_resources.pci_mem;
 }
-
-/* this is used by the pmac_pci code too... - paulus */
-void process_bridge_ranges(struct pci_controller *hose,
-			   struct device_node *dev, int primary)
-{
-	unsigned int *ranges;
-	int rlen = 0;
-	int memno = 0;
-	struct resource *res;
-
-	hose->io_base_phys = 0;
-	ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
-	while ((rlen -= 6 * sizeof(unsigned int)) >= 0) {
-		res = NULL;
-		switch (ranges[0] >> 24) {
-		case 1:		/* I/O space */
-			if (ranges[2] != 0)
-				break;
-			hose->io_base_phys = ranges[3];
-			hose->io_base_virt = ioremap(ranges[3], ranges[5]);
-			if (primary)
-				isa_io_base = (unsigned long) hose->io_base_virt;
-			res = &hose->io_resource;
-			res->flags = IORESOURCE_IO;
-			res->start = ranges[2];
-			break;
-		case 2:		/* memory space */
-			memno = 0;
-			if (ranges[1] == 0 && ranges[2] == 0
-			    && ranges[5] <= (16 << 20)) {
-				/* 1st 16MB, i.e. ISA memory area */
-				if (primary)
-					isa_mem_base = ranges[3];
-				memno = 1;
-			}
-			while (memno < 3 && hose->mem_resources[memno].flags)
-				++memno;
-			if (memno == 0)
-				hose->pci_mem_offset = ranges[3] - ranges[2];
-			if (memno < 3) {
-				res = &hose->mem_resources[memno];
-				res->flags = IORESOURCE_MEM;
-				res->start = ranges[3];
-			}
-			break;
-		}
-		if (res != NULL) {
-			res->name = dev->full_name;
-			res->end = res->start + ranges[5] - 1;
-			res->parent = NULL;
-			res->sibling = NULL;
-			res->child = NULL;
-		}
-		ranges += 6;
-	}
-}
+#endif /* 0 */
 
 /* this is largely modeled and stolen after the pmac_pci code -- tgall
  */
@@ -366,8 +315,10 @@
 	volatile unsigned char *cfg;
 	unsigned int *dma;
 #ifdef CONFIG_POWER3
-	unsigned long *opprop = (unsigned long *)
-		get_property(find_path_device("/"), "platform-open-pic", NULL);
+	struct device_node *root = find_path_device("/");
+	unsigned int *opprop = (unsigned int *)
+		get_property(root, "platform-open-pic", NULL);
+	int i;
 #endif
 
 	for(; dev != NULL; dev = dev->next, ++index) {
@@ -405,10 +356,11 @@
        		hose->cfg_addr = (volatile unsigned int *) cfg;
        		hose->cfg_data = cfg + 0x10;
 
-		process_bridge_ranges(hose, dev, index == 0);
+		pci_process_bridge_OF_ranges(hose, dev, index == 0);
 
 #ifdef CONFIG_POWER3
-                openpic_setup_ISU(index, opprop[index+1]);
+		i = prom_n_addr_cells(root) * (index + 2) - 1;
+                openpic_setup_ISU(index, opprop[i]);
 #endif /* CONFIG_POWER3 */
 
 		/* check the first bridge for a property that we can
@@ -442,7 +394,7 @@
 void __init
 chrp_find_bridges(void)
 {
-	struct device_node *py;
+	struct device_node *py, *dev;
 	char *model, *name;
 	struct pci_controller* hose;
 
@@ -453,7 +405,7 @@
 #else /* CONFIG_POWER4 */
 	model = get_property(find_path_device("/"), "model", NULL);
         if (!strncmp("MOT", model, 3)) {
-		struct pci_controller* hose;
+		struct pci_controller *hose;
 
 		hose = pcibios_alloc_controller();
 		if (!hose)
@@ -463,8 +415,9 @@
         	/* Check that please. This must be the root of the OF
         	 * PCI tree (the root host bridge
         	 */
-               	hose->arch_data = find_devices("pci");
+               	hose->arch_data = dev = find_devices("pci");
                 setup_grackle(hose, 0x20000);
+		pci_process_bridge_OF_ranges(hose, dev, 1);
 		return;
         }
 
@@ -485,25 +438,22 @@
 	/* Check that please. This must be the root of the OF
 	 * PCI tree (the root host bridge
 	 */
-	hose->arch_data = find_devices("pci");
+	hose->arch_data = dev = find_devices("pci");
 	name = get_property(find_path_device("/"), "name", NULL);
 	if (!strncmp("IBM,7043-150", name, 12) ||
 	    !strncmp("IBM,7046-155", name, 12) ||
 	    !strncmp("IBM,7046-B50", name, 12) ) {
 		setup_grackle(hose, 0x01000000);
-		isa_mem_base = 0x80000000;
+		pci_process_bridge_OF_ranges(hose, dev, 1);
 		return;
 	}
 
 	/* LongTrail */
 	hose->ops = &gg2_pci_ops;
 	pci_dram_offset = 0;
-	isa_mem_base = 0xf7000000;
-	hose->io_base_phys = (unsigned long) 0xf8000000;
-	hose->io_base_virt = ioremap(hose->io_base_phys, 0x10000);
-	isa_io_base = (unsigned long) hose->io_base_virt;
-	ppc_md.pcibios_fixup = gg2_pcibios_fixup;
-	ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus;
+	pci_process_bridge_OF_ranges(hose, find_devices("pci"), 1);
+//	ppc_md.pcibios_fixup = gg2_pcibios_fixup;
+//	ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus;
 #endif /* CONFIG_POWER4 */
 }
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/chrp_setup.c linux/arch/ppc/kernel/chrp_setup.c
--- v2.4.4/linux/arch/ppc/kernel/chrp_setup.c	Fri Apr 27 14:10:32 2001
+++ linux/arch/ppc/kernel/chrp_setup.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.chrp_setup.c 1.17 05/17/01 18:14:21 cort
+ */
+/*
  *  linux/arch/ppc/kernel/setup.c
  *
  *  Copyright (C) 1995  Linus Torvalds
@@ -67,6 +70,7 @@
 void rtas_indicator_progress(char *, unsigned short);
 void bootx_text_progress(char *, unsigned short);
 
+extern unsigned long pmac_find_end_of_memory(void);
 extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
 extern int pckbd_getkeycode(unsigned int scancode);
 extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
@@ -194,37 +198,36 @@
 				     u8 type)
 {
 	u8 level0, type0, active;
-	struct device_node *root;
-	
-	root = find_path_device("/");
-	if (root &&
-	    !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13 ) )
-	{
-		/* select logical device */
-		sio_write(device, 0x07);
-		active = sio_read(0x30);
-		level0 = sio_read(0x70);
-		type0 = sio_read(0x71);
-		printk("sio: %s irq level %d, type %d, %sactive: ", name, level0, type0,
-		       !active ? "in" : "");
-		if (level0 == level && type0 == type && active)
-			printk("OK\n");
-		else {
-			printk("remapping to level %d, type %d, active\n", level, type);
-			sio_write(0x01, 0x30);
-			sio_write(level, 0x70);
-			sio_write(type, 0x71);
-		}
-	}
 
+	/* select logical device */
+	sio_write(device, 0x07);
+	active = sio_read(0x30);
+	level0 = sio_read(0x70);
+	type0 = sio_read(0x71);
+	printk("sio: %s irq level %d, type %d, %sactive: ", name, level0,
+	       type0, !active ? "in" : "");
+	if (level0 == level && type0 == type && active)
+		printk("OK\n");
+	else {
+		printk("remapping to level %d, type %d, active\n", level,
+		       type);
+		sio_write(0x01, 0x30);
+		sio_write(level, 0x70);
+		sio_write(type, 0x71);
+	}
 }
 
 static void __init sio_init(void)
 {
-	/* logical device 0 (KBC/Keyboard) */
-	sio_fixup_irq("keyboard", 0, 1, 2);
-	/* select logical device 1 (KBC/Mouse) */
-	sio_fixup_irq("mouse", 1, 12, 2);
+	struct device_node *root;
+
+	if ((root = find_path_device("/")) &&
+	    !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13)) {
+		/* logical device 0 (KBC/Keyboard) */
+		sio_fixup_irq("keyboard", 0, 1, 2);
+		/* select logical device 1 (KBC/Mouse) */
+		sio_fixup_irq("mouse", 1, 12, 2);
+	}
 }
 
 
@@ -263,16 +266,19 @@
 
 #ifndef CONFIG_POWER4
 	/* Some IBM machines don't have the hydra -- Cort */
-	if ( !OpenPIC_Addr )
-	{
+	if (!OpenPIC_Addr) {
+		struct device_node *root;
 		unsigned long *opprop;
+		int n;
 
-		opprop = (unsigned long *)get_property(find_path_device("/"),
-						"platform-open-pic", NULL);
+		root = find_path_device("/");
+		opprop = (unsigned long *) get_property
+			(root, "platform-open-pic", NULL);
+		n = prom_n_addr_cells(root);
 		if (opprop != 0) {
 			printk("OpenPIC addrs: %lx %lx %lx\n",
-			       opprop[0], opprop[1], opprop[2]);
-			OpenPIC_Addr = ioremap(opprop[0], 0x40000);
+			       opprop[n-1], opprop[2*n-1], opprop[3*n-1]);
+			OpenPIC_Addr = ioremap(opprop[n-1], 0x40000);
 		}
 	}
 #endif
@@ -281,6 +287,10 @@
 	 *  Fix the Super I/O configuration
 	 */
 	sio_init();
+
+	/*
+	 *  Setup the console operations
+	 */
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
 #endif
@@ -356,7 +366,7 @@
 {
 	struct device_node *np;
 	int i;
-	unsigned long *addrp;
+	unsigned int *addrp;
 	unsigned char* chrp_int_ack_special = 0;
 	unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
 	int nmi_irq = -1;
@@ -365,11 +375,12 @@
 #endif
 
 	if (!(np = find_devices("pci"))
-	    || !(addrp = (unsigned long *)
+	    || !(addrp = (unsigned int *)
 		 get_property(np, "8259-interrupt-acknowledge", NULL)))
 		printk("Cannot find pci to get ack address\n");
 	else
-		chrp_int_ack_special = (unsigned char *)ioremap(*addrp, 1);
+		chrp_int_ack_special = (unsigned char *)
+			ioremap(addrp[prom_n_addr_cells(np)-1], 1);
 	/* hydra still sets OpenPIC_InitSenses to a static set of values */
 	if (OpenPIC_InitSenses == NULL) {
 		prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS);
@@ -553,11 +564,9 @@
 #ifndef CONFIG_POWER4
 	ppc_md.init_IRQ       = chrp_init_IRQ;
 	ppc_md.get_irq        = openpic_get_irq;
-	ppc_md.post_irq	      = NULL;
 #else
 	ppc_md.init_IRQ	      = xics_init_IRQ;
 	ppc_md.get_irq	      = xics_get_irq;
-	ppc_md.post_irq	      = NULL;
 #endif /* CONFIG_POWER4 */
 
 	ppc_md.init           = chrp_init2;
@@ -570,6 +579,8 @@
 	ppc_md.set_rtc_time   = chrp_set_rtc_time;
 	ppc_md.get_rtc_time   = chrp_get_rtc_time;
 	ppc_md.calibrate_decr = chrp_calibrate_decr;
+
+	ppc_md.find_end_of_memory = pmac_find_end_of_memory;
 
 #ifdef CONFIG_VT
 	/* these are adjusted in chrp_init2 if we have an ADB keyboard */
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/chrp_time.c linux/arch/ppc/kernel/chrp_time.c
--- v2.4.4/linux/arch/ppc/kernel/chrp_time.c	Sun Sep 17 09:48:06 2000
+++ linux/arch/ppc/kernel/chrp_time.c	Mon May 21 17:04:46 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.chrp_time.c 1.7 05/17/01 18:14:21 cort
+ */
+/*
  *  linux/arch/i386/kernel/time.c
  *
  *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
@@ -29,6 +32,8 @@
 #include <asm/init.h>
 #include <asm/time.h>
 
+extern spinlock_t rtc_lock;
+
 static int nvram_as1 = NVRAM_AS1;
 static int nvram_as0 = NVRAM_AS0;
 static int nvram_data = NVRAM_DATA;
@@ -74,6 +79,7 @@
 	unsigned char save_control, save_freq_select;
 	struct rtc_time tm;
 
+	spin_lock(&rtc_lock);
 	to_tm(nowtime, &tm);
 
 	save_control = chrp_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */
@@ -112,6 +118,7 @@
 
 	if ( (time_state == TIME_ERROR) || (time_state == TIME_BAD) )
 		time_state = TIME_OK;
+	spin_unlock(&rtc_lock);
 	return 0;
 }
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/entry.S linux/arch/ppc/kernel/entry.S
--- v2.4.4/linux/arch/ppc/kernel/entry.S	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/entry.S	Mon May 21 17:04:46 2001
@@ -1,8 +1,7 @@
 /*
- *  arch/ppc/kernel/entry.S
- *
- *  $Id: entry.S,v 1.4 1999/09/14 05:18:14 dmalek Exp $
- *
+ * BK Id: SCCS/s.entry.S 1.12 05/21/01 11:49:59 paulus
+ */
+/*
  *  PowerPC version 
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *  Rewritten by Cort Dougan (cort@fsmlabs.com) for PReP
@@ -30,7 +29,6 @@
 #include <linux/errno.h>
 #include <linux/sys.h>
 #include <linux/config.h>
-#include "mol.h"
 
 #undef SHOW_SYSCALLS
 #undef SHOW_SYSCALLS_TASK
@@ -315,21 +313,12 @@
 	lwz	r5,_MSR(r1)
 	andi.	r5,r5,MSR_EE
 	beq	2f
-	.globl	lost_irq_ret
-lost_irq_ret:
-3:	lis	r4,ppc_n_lost_interrupts@ha
-	lwz	r4,ppc_n_lost_interrupts@l(r4)
-	cmpi	0,r4,0
-	beq+	1f
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	do_IRQ
-	b	3b
-1:	lis	r4,irq_stat@ha		/* &softirq_active for cpu 0 */
+	lis	r4,irq_stat@ha		/* &softirq_active for cpu 0 */
 	addi	r4,r4,irq_stat@l
 #ifdef CONFIG_SMP
 	/* get processor # */
 	lwz	r3,PROCESSOR(r2)
-	slwi	r3,r3,5
+	slwi	r3,r3,LG_CACHE_LINE_SIZE
 	add	r4,r4,r3
 #endif /* CONFIG_SMP */
 	lwz	r5,0(r4)		/* softirq_active */
@@ -351,7 +340,6 @@
 	beq+	do_signal_ret
 	li	r3,0
 	addi	r4,r1,STACK_FRAME_OVERHEAD
-	MOL_HOOK_MMU(8,r8)
 	bl	do_signal
 	.globl	do_signal_ret
 do_signal_ret:
@@ -373,7 +361,9 @@
 	rlwinm	r0,r0,0,17,15	/* clear MSR_EE in r0 */
 	SYNC			/* Some chip revs have problems here... */
 	mtmsr	r0		/* Update machine state */
-	
+
+	stwcx.	r0,0,r1		/* to clear the reservation */
+
 	/* if returning to user mode, set new sprg2 and save kernel SP */
 	lwz	r0,_MSR(r1)
 	andi.	r0,r0,MSR_PR
@@ -391,7 +381,6 @@
 	stw	r0,THREAD+KSP(r2)	/* save kernel stack pointer */
 	tophys(r8,r1)
 	CLR_TOP32(r8)
-	MOL_HOOK_MMU(9, r4)		/* mod. r0,r2-r7, lr, ctr */
 	mtspr	SPRG2,r8		/* phys exception stack pointer */	
 1:
 	lwz	r3,_CTR(r1)
@@ -412,29 +401,6 @@
 	lwz	r1,GPR1(r1)
 	SYNC
 	RFI
-
-/*
- * Fake an interrupt from kernel mode.
- * This is used when enable_irq loses an interrupt.
- * We only fill in the stack frame minimally.
- */
-_GLOBAL(fake_interrupt)
-	mflr	r0
-	stw	r0,4(r1)
-	stwu	r1,-INT_FRAME_SIZE(r1)
-	stw	r0,_NIP(r1)
-	stw	r0,_LINK(r1)
-	mfmsr	r3
-	stw	r3,_MSR(r1)
-	li	r0,0x0fac
-	stw	r0,TRAP(r1)
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	li	r4,1
-	bl	do_IRQ
-	addi	r1,r1,INT_FRAME_SIZE
-	lwz	r0,4(r1)
-	mtlr	r0
-	blr
 
 
 /*
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/error_log.c linux/arch/ppc/kernel/error_log.c
--- v2.4.4/linux/arch/ppc/kernel/error_log.c	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/error_log.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.error_log.c 1.6 05/17/01 18:14:21 cort
+ */
+/*
  *  arch/ppc/kernel/error_log.c
  *  
  *  Copyright (c) 2000 Tilmann Bitterberg
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/error_log.h linux/arch/ppc/kernel/error_log.h
--- v2.4.4/linux/arch/ppc/kernel/error_log.h	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/error_log.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.error_log.h 1.5 05/17/01 18:14:21 cort
+ */
 #ifndef __ERROR_LOG_H__
 #define __ERROR_LOG_H__
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/feature.c linux/arch/ppc/kernel/feature.c
--- v2.4.4/linux/arch/ppc/kernel/feature.c	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/feature.c	Mon May 21 17:04:47 2001
@@ -1,18 +1,17 @@
 /*
+ * BK Id: SCCS/s.feature.c 1.10 05/17/01 18:14:21 cort
+ */
+/*
  *  arch/ppc/kernel/feature.c
  *
  *  Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au)
- *                     Ben. Herrenschmidt (bh40@calva.net)
+ *                     Ben. Herrenschmidt (benh@kernel.crashing.org)
  *
  *  This program is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU General Public License
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
  *
- *  BenH: Changed implementation to work on multiple registers
- * 	  polarity is also taken into account. Removed delay (now
- * 	  responsibility of the caller). Added spinlocks.
- *
  */
 #include <linux/config.h>
 #include <linux/types.h>
@@ -29,11 +28,12 @@
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/feature.h>
+#include <asm/dbdma.h>
+#include <asm/machdep.h>
 
 #undef DEBUG_FEATURE
 
 #define MAX_FEATURE_CONTROLLERS		2
-#define MAX_FEATURE_OFFSET		0x100
 #define FREG(c,r)			(&(((c)->reg)[(r)>>2]))
 
 /* Keylargo reg. access. */
@@ -56,9 +56,7 @@
 	unsigned int	mask;		/* bit mask */
 } fbit;
 
-/* I don't have an OHare machine to test with, so I left those as they
- * were. Someone with such a machine chould check out what OF says and
- * try too see if they match the heathrow ones and should be changed too
+/* Those features concern for OHare-based PowerBooks (2400, 3400, 3500)
  */
 static fbit feature_bits_ohare_pbook[] = {
 	{0x38,0,0},			/* FEATURE_null */
@@ -159,11 +157,12 @@
 
 /*
  * Those bits are from a 1999 G3 PowerBook, with a paddington chip.
- * Mostly the same as the heathrow.
+ * Mostly the same as the heathrow. They are used on both PowerBooks
+ * and desktop machines using the paddington chip
  */
 static fbit feature_bits_paddington[] = {
 	{0x38,0,0},			/* FEATURE_null */
-	{0x38,0,0},			/* FEATURE_Serial_reset */
+	{0x38,0,PADD_RESET_SCC},	/* FEATURE_Serial_reset */
 	{0x38,0,HRW_SCC_ENABLE},	/* FEATURE_Serial_enable */
 	{0x38,0,HRW_SCCA_IO},		/* FEATURE_Serial_IO_A */
 	{0x38,0,HRW_SCCB_IO},		/* FEATURE_Serial_IO_B */
@@ -192,6 +191,7 @@
 };
 
 /* Those bits are for Core99 machines (iBook,G4,iMacSL/DV,Pismo,...).
+ * Note: Different sets may be needed for iBook, especially for sound
  */
 static fbit feature_bits_keylargo[] = {
 	{0x38,0,0},			/* FEATURE_null */
@@ -201,13 +201,13 @@
 	{0x38,0,KL0_SCC_B_INTF_ENABLE},	/* FEATURE_Serial_IO_B */
 	{0x38,0,0},			/* FEATURE_SWIM3_enable */
 	{0x38,0,0},			/* FEATURE_MESH_enable */
-	{0x3c,0,0},			/* FEATURE_IDE0_enable */
+	{0x3c,0,KL1_EIDE0_ENABLE},	/* FEATURE_IDE0_enable */
  	{0x3c,1,KL1_EIDE0_RESET_N},	/* FEATURE_IDE0_reset */
 	{0x38,0,0},			/* FEATURE_IOBUS_enable */
-	{0x34,1,0x00000200},		/* FEATURE_Mediabay_reset */
-	{0x34,1,0x00000400},		/* FEATURE_Mediabay_power */
+	{0x34,1,KL_MBCR_MB0_DEV_RESET},	/* FEATURE_Mediabay_reset */
+	{0x34,1,KL_MBCR_MB0_DEV_POWER},	/* FEATURE_Mediabay_power */
 	{0x38,0,0},			/* FEATURE_Mediabay_PCI_enable */
-	{0x3c,0,0x0},			/* FEATURE_IDE1_enable */
+	{0x3c,0,KL1_EIDE1_ENABLE},	/* FEATURE_IDE1_enable */
 	{0x3c,1,KL1_EIDE1_RESET_N},	/* FEATURE_IDE1_reset */
 	{0x38,0,0},			/* FEATURE_Mediabay_floppy_enable */
 	{0x38,0,0},			/* FEATURE_BMac_reset */
@@ -216,10 +216,10 @@
 	{0x38,0,0},			/* FEATURE_Slow_SCC_PCLK */
 	{0x38,0,0},			/* FEATURE_Sound_Power */
 	{0x38,0,0},			/* FEATURE_Sound_CLK_Enable */
-	{0x38,0,0},			/* FEATURE_IDE2_enable */
+	{0x3c,0,KL1_UIDE_ENABLE},	/* FEATURE_IDE2_enable */
 	{0x3c,1,KL1_UIDE_RESET_N},	/* FEATURE_IDE2_reset */
-	{0x34,0,KL_MBCR_MBDEV_ENABLE},	/* FEATURE_Mediabay_IDE_switch */
-	{0x34,0,0x00000100},		/* FEATURE_Mediabay_content */
+	{0x34,0,KL_MBCR_MB0_DEV_ENABLE},/* FEATURE_Mediabay_IDE_switch */
+	{0x34,0,KL_MBCR_MB0_ENABLE},	/* FEATURE_Mediabay_content */
 	{0x40,1,KL2_AIRPORT_RESET_N},	/* FEATURE_Airport_reset */
 };
 
@@ -238,6 +238,8 @@
 static struct feature_controller*
 feature_lookup_controller(struct device_node *device);
 
+static void uninorth_init(void);
+static void keylargo_init(void);
 #ifdef CONFIG_PMAC_PBOOK
 static void heathrow_prepare_for_sleep(struct feature_controller* ctrler);
 static void heathrow_wakeup(struct feature_controller* ctrler);
@@ -245,32 +247,80 @@
 static void core99_wake_up(struct feature_controller* ctrler);
 #endif /* CONFIG_PMAC_PBOOK */
 
-static void keylargo_init(void);
-static void uninorth_init(void);
-
 /* static variables */
 static struct feature_controller	controllers[MAX_FEATURE_CONTROLLERS];
 static int				controller_count = 0;
 
 /* Core99 stuffs */
-static volatile u32*			uninorth_base = NULL;
-static volatile u32*			keylargo_base = NULL;
+/*static*/ volatile u32*		uninorth_base;
+static volatile u32*			keylargo_base;
+static struct feature_controller*	keylargo;
 static int				uninorth_rev;
 static int				keylargo_rev;
+static u32				board_features;
+static u8				airport_pwr_regs[5];
+static int				airport_pwr_state;
+static struct device_node*		airport_dev;
+
+#define FTR_NEED_OPENPIC_TWEAK		0x00000001
+#define FTR_CAN_NAP			0x00000002
+#define FTR_HAS_FW_POWER		0x00000004
+#define FTR_CAN_SLEEP			0x00000008
+
+static struct board_features_t {
+	char*	compatible;
+	u32	features;
+} board_features_datas[] __init = 
+{
+  {	"AAPL,PowerMac G3",	0				}, /* Beige G3 */
+  {	"iMac,1",		0				}, /* First iMac (gossamer) */
+  {	"PowerMac1,1",		0				}, /* B&W G3 / Yikes */
+  {	"PowerMac1,2",		0				}, /* B&W G3 / Yikes */
+  {	"PowerMac2,1",		FTR_CAN_SLEEP			}, /* r128 based iMac */
+  {	"PowerMac2,2",		FTR_HAS_FW_POWER|FTR_CAN_SLEEP	}, /* Summer 2000 iMac */
+  {	"PowerMac4,1",		FTR_CAN_SLEEP			}, /* iMac "Flower Power" */
+  {	"PowerMac3,1",		FTR_NEED_OPENPIC_TWEAK		}, /* Sawtooth (G4) */
+  {	"PowerMac3,2",		0				}, /* G4/Dual G4 */
+  {	"PowerMac3,3",		FTR_NEED_OPENPIC_TWEAK		}, /* G4/Dual G4 */
+  {	"PowerMac5,1",		0				}, /* Cube */
+  {	"AAPL,3400/2400",	FTR_CAN_SLEEP			}, /* 2400/3400 PowerBook */
+  {	"AAPL,3500",		FTR_CAN_SLEEP			}, /* 3500 PowerBook (G3) */
+  {	"AAPL,PowerBook1998",	FTR_CAN_SLEEP			}, /* Wallstreet PowerBook */
+  {	"PowerBook1,1",		FTR_CAN_SLEEP			}, /* 101 (Lombard) PowerBook */
+  {	"PowerBook2,1",		FTR_CAN_SLEEP 			}, /* iBook */
+  {	"PowerBook2,2",		FTR_CAN_SLEEP /*| FTR_CAN_NAP*/	}, /* iBook FireWire */
+  {	"PowerBook3,1",		FTR_CAN_SLEEP|FTR_CAN_NAP|	   /* PowerBook 2000 (Pismo) */
+  				FTR_HAS_FW_POWER		}, 
+  {	"PowerBook3,2",		FTR_CAN_NAP|FTR_CAN_SLEEP	}, /* PowerBook Titanium */
+  {	"PowerBook4,1",		FTR_CAN_NAP|FTR_CAN_SLEEP	}, /* New polycarbonate iBook */
+  {	NULL, 0 }
+};
+
+extern unsigned long powersave_nap;
 
-/*
- * WARNING ! This function is called early in setup_arch, neither the IO base
- * nor the udelay calibration have been done yet
- */
 void
 feature_init(void)
 {
 	struct device_node *np;
 	u32 *rev;
-	
+	int i;
+
 	if (_machine != _MACH_Pmac)
 		return;
 
+	/* Figure out motherboard type & options */
+	for(i=0;board_features_datas[i].compatible;i++) {
+		if (machine_is_compatible(board_features_datas[i].compatible)) {
+			board_features = board_features_datas[i].features;
+			break;
+		}
+	}
+
+	/* Set default value of powersave_nap on machines that support it */
+	if (board_features & FTR_CAN_NAP)
+		powersave_nap = 1;
+		
+	/* Track those poor mac-io's */
 	np = find_devices("mac-io");
 	while (np != NULL) {
 		/* KeyLargo contains several (5 ?) FCR registers in mac-io,
@@ -280,13 +330,25 @@
 			struct feature_controller* ctrler =
 				feature_add_controller(np, feature_bits_keylargo);
 			if (ctrler) {
+				keylargo = ctrler;
 				keylargo_base = ctrler->reg;
 				rev = (u32 *)get_property(ctrler->device, "revision-id", NULL);
 				if (rev)
 					keylargo_rev = *rev;
+				
+				rev = (u32 *)get_property(ctrler->device, "device-id", NULL);
+				if (rev && (*rev) == 0x0025)
+					keylargo_rev |= KL_PANGEA_REV;
 			}
 		} else if (device_is_compatible(np, "paddington")) {
 			feature_add_controller(np, feature_bits_paddington);
+			/* We disable the modem power bit on Yikes as it can
+			 * do bad things (it's the nvram power)
+			 */
+			if (machine_is_compatible("PowerMac1,1") ||
+				machine_is_compatible("PowerMac1,2")) {
+				feature_bits_paddington[FEATURE_Modem_power].mask = 0;
+			}
 		} else if (machine_is_compatible("AAPL,PowerBook1998")) {
 			feature_add_controller(np, feature_bits_wallstreet);
 		} else {
@@ -311,11 +373,12 @@
 		}
 	}
 
-	/* Handle core99 Uni-N */
+	/* Locate core99 Uni-N */
 	np = find_devices("uni-n");
 	if (np && np->n_addrs > 0) {
 		uninorth_base = ioremap(np->addrs[0].address, 0x1000);
 		uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
+		printk("Uninorth at 0x%08x\n", np->addrs[0].address);
 	}
 	if (uninorth_base && keylargo_base)
 		printk("Uni-N revision: %d, KeyLargo revision: %d\n",
@@ -360,8 +423,12 @@
 		return NULL;
 	}
 
+	/* We remap the entire mac-io here. Normally, this will just
+	 * give us back our already existing BAT mapping
+	 */
 	controller->reg		= (volatile u32 *)ioremap(
-		controller_device->addrs[0].address, MAX_FEATURE_OFFSET);
+		controller_device->addrs[0].address,
+		controller_device->addrs[0].size);
 
 	if (bits == NULL) {
 		printk(KERN_INFO "Twiddling the magic ohare bits\n");
@@ -495,6 +562,12 @@
 	return bit->polarity ? (value == 0) : (value == bit->mask);
 }
 
+int
+feature_can_sleep(void)
+{
+	return ((board_features & FTR_CAN_SLEEP) != 0);	
+}
+
 /*
  * Core99 functions
  * 
@@ -506,53 +579,220 @@
 void
 feature_set_gmac_power(struct device_node* device, int power)
 {
-	if (!uninorth_base)
+	unsigned long flags;
+	
+	if (!uninorth_base || !keylargo)
 		return;
+		
+	/* TODO: Handle save/restore of PCI config space here
+	 */
+
+	spin_lock_irqsave(&keylargo->lock, flags);
 	if (power)
 		UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
 	else
 		UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
+	spin_unlock_irqrestore(&keylargo->lock, flags);
 	udelay(20);
 }
 
 void
-feature_set_gmac_phy_reset(struct device_node* device, int reset)
+feature_gmac_phy_reset(struct device_node* device)
 {
-	if (!keylargo_base)
+	unsigned long flags;
+	
+	if (!keylargo_base || !keylargo)
 		return;
-	out_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET), reset);
+		
+	spin_lock_irqsave(&keylargo->lock, flags);
+	out_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET),
+		KEYLARGO_GPIO_OUTPUT_ENABLE);
 	(void)in_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET));
+	spin_unlock_irqrestore(&keylargo->lock, flags);
+	mdelay(10);
+	spin_lock_irqsave(&keylargo->lock, flags);
+	out_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET),
+		KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
+	(void)in_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET));
+	spin_unlock_irqrestore(&keylargo->lock, flags);
+	mdelay(10);
 }
 
 /* Pass the node of the correct controller, please */
 void
 feature_set_usb_power(struct device_node* device, int power)
 {
+	char* prop;
+	int number;
+	u32 reg;
+	
+	unsigned long flags;
+	
+	if (!keylargo_base || !keylargo)
+		return;
+		
+	prop = (char *)get_property(device, "AAPL,clock-id", NULL);
+	if (!prop)
+		return;
+	if (strncmp(prop, "usb0u048", strlen("usb0u048")) == 0)
+		number = 0;
+	else if (strncmp(prop, "usb1u148", strlen("usb1u148")) == 0)
+		number = 2;
+	else
+		return;
+
+	spin_lock_irqsave(&keylargo->lock, flags);
+	if (power) {
+		/* Turn ON */
+			
+		if (number == 0) {
+			KL_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
+			mdelay(1);
+			KL_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
+		} else {
+			KL_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
+			mdelay(1);
+			KL_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
+		}
+		reg = KL_IN(KEYLARGO_FCR4);
+		reg &=	~(KL4_SET_PORT_ENABLE(number) | KL4_SET_PORT_RESUME(number) |
+			KL4_SET_PORT_CONNECT(number) | KL4_SET_PORT_DISCONNECT(number));
+		reg &=	~(KL4_SET_PORT_ENABLE(number+1) | KL4_SET_PORT_RESUME(number+1) |
+			KL4_SET_PORT_CONNECT(number+1) | KL4_SET_PORT_DISCONNECT(number+1));
+		KL_OUT(KEYLARGO_FCR4, reg);
+		(void)KL_IN(KEYLARGO_FCR4);
+		udelay(10);
+	} else {
+		/* Turn OFF */
+		
+		reg = KL_IN(KEYLARGO_FCR4);
+		reg |=	KL4_SET_PORT_ENABLE(number) | KL4_SET_PORT_RESUME(number) |
+			KL4_SET_PORT_CONNECT(number) | KL4_SET_PORT_DISCONNECT(number);
+		reg |=	KL4_SET_PORT_ENABLE(number+1) | KL4_SET_PORT_RESUME(number+1) |
+			KL4_SET_PORT_CONNECT(number+1) | KL4_SET_PORT_DISCONNECT(number+1);
+		KL_OUT(KEYLARGO_FCR4, reg);
+		(void)KL_IN(KEYLARGO_FCR4);
+		udelay(1);
+		if (number == 0) {
+			KL_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
+			(void)KL_IN(KEYLARGO_FCR0);
+			udelay(1);
+			KL_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
+			(void)KL_IN(KEYLARGO_FCR0);
+		} else {
+			KL_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
+			(void)KL_IN(KEYLARGO_FCR0);
+			udelay(1);
+			KL_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
+			(void)KL_IN(KEYLARGO_FCR0);
+		}
+		udelay(1);
+	}
+	spin_unlock_irqrestore(&keylargo->lock, flags);
 }
 
-/* Not yet implemented */
 void 
 feature_set_firewire_power(struct device_node* device, int power)
 {
+	unsigned long flags;
+
+	/* TODO: Handle save/restore of PCI config space here
+	 */
+		
 	if (!uninorth_base)
 		return;
+	spin_lock_irqsave(&keylargo->lock, flags);
 	if (power)
 		UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
 	else
 		UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
 	udelay(20);
+	spin_unlock_irqrestore(&keylargo->lock, flags);
+}
+
+/* Warning: will kill the PHY.. */
+void 
+feature_set_firewire_cable_power(struct device_node* device, int power)
+{
+	unsigned long flags;
+	u8 gpioValue = power ? 0 : 4;
+	
+	if (!keylargo_base || !(board_features & FTR_HAS_FW_POWER))
+		return;
+	spin_lock_irqsave(&keylargo->lock, flags);
+	out_8((volatile u8 *)KL_FCR(KL_GPIO_FW_CABLE_POWER), gpioValue);
+	(void)in_8((volatile u8 *)KL_FCR(KL_GPIO_FW_CABLE_POWER));
+	spin_unlock_irqrestore(&keylargo->lock, flags);		
 }
 
 #ifdef CONFIG_SMP
 void
-feature_core99_kick_cpu1(void)
+feature_core99_kick_cpu(int cpu_nr)
 {
-	out_8((volatile u8 *)KL_FCR(KL_GPIO_KICK_CPU1), KL_GPIO_KICK_CPU1_UP);
+#if 1 /* New way */
+	const int reset_lines[] = {	KL_GPIO_RESET_CPU0,
+					KL_GPIO_RESET_CPU1,
+					KL_GPIO_RESET_CPU2,
+					KL_GPIO_RESET_CPU3 };
+	volatile u8* reset_io;
+
+	if (!keylargo_base || cpu_nr > 3)
+		return;
+	reset_io = (volatile u8*)KL_FCR(reset_lines[cpu_nr]);
+	out_8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
+	udelay(1);
+	out_8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
+#else
+	out_8((volatile u8 *)KL_FCR(KL_GPIO_EXTINT_CPU1), KL_GPIO_EXTINT_CPU1_ASSERT);
 	udelay(1);
-	out_8((volatile u8 *)KL_FCR(KL_GPIO_KICK_CPU1), KL_GPIO_KICK_CPU1_DOWN);
+	out_8((volatile u8 *)KL_FCR(KL_GPIO_EXTINT_CPU1), KL_GPIO_EXTINT_CPU1_RELEASE);
+#endif	
 }
 #endif /* CONFIG_SMP */
 
+void
+feature_set_airport_power(struct device_node* device, int power)
+{
+	if (!keylargo_base || !airport_dev || airport_dev != device)
+		return;
+	if (airport_pwr_state == power)
+		return;
+	if (power) {
+		/* Some if this is from Darwin code, some is from tracing of
+		 * MacOS driver with Macsbug. Some real bit definitions would
+		 * really help here...
+		 */
+		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_0), airport_pwr_regs[0]);
+		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_1), airport_pwr_regs[1]);
+		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_2), airport_pwr_regs[2]);
+		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_3), airport_pwr_regs[3]);
+		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4), airport_pwr_regs[4]);
+		udelay(20);
+		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4), 5);
+		udelay(20);
+		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4), 4);
+		mdelay(20);
+		KL_BIC(KEYLARGO_FCR2, KL2_AIRPORT_RESET_N);
+		udelay(10);
+		out_8((volatile u8*)KL_FCR(0x1a3e0), 0x41);
+		udelay(10);
+		KL_BIS(KEYLARGO_FCR2, KL2_AIRPORT_RESET_N);
+		udelay(10);
+	} else {
+		airport_pwr_regs[0] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_0));
+		airport_pwr_regs[1] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_1));
+		airport_pwr_regs[2] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_2));
+		airport_pwr_regs[3] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_3));
+		airport_pwr_regs[4] = in_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4));
+		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_0), 0);
+		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_1), 0);
+		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_2), 0);
+		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_3), 0);
+		out_8((volatile u8*)KL_FCR(KL_GPIO_AIRPORT_4), 0);
+	}
+	airport_pwr_state = power;	
+}
+
 /* Initialize the Core99 UniNorth host bridge and memory controller
  */
 static void
@@ -563,51 +803,106 @@
 	
 	/* Set the arbitrer QAck delay according to what Apple does
 	 */
-	actrl = in_be32(UN_REG(UNI_N_ARB_CTRL)) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;
-	actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : UNI_N_ARB_CTRL_QACK_DELAY)
-		<< UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;
-	UN_OUT(UNI_N_ARB_CTRL, actrl);
+	if (uninorth_rev < 0x10) {
+		actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;
+		actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 :
+			UNI_N_ARB_CTRL_QACK_DELAY) << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;
+		UN_OUT(UNI_N_ARB_CTRL, actrl);
+	}
 	
-	/* 
-	 * Turns OFF the gmac clock. The gmac driver will turn
-	 * it back ON when the interface is enabled. This save
-	 * power on portables.
-	 * 
-	 * Note: We could also try to turn OFF the PHY. Since this
-	 * has to be done by both the gmac driver and this code,
-	 * I'll probably end-up moving some of this out of the
-	 * modular gmac driver into a non-modular stub containing
-	 * some basic PHY management and power management stuffs
+	/* Enable GMAC for now for PCI probing. It will be disabled
+	 * later on after PCI probe
 	 */
 	gmac = find_devices("ethernet");
-
 	while(gmac) {
 		if (device_is_compatible(gmac, "gmac"))
 			break;
 		gmac = gmac->next;
 	}
 	if (gmac)
-		feature_set_gmac_power(gmac, 0);
+		feature_set_gmac_power(gmac, 1);
 
-	/* Kludge (enable FW before PCI probe) */
+	/* Enable FW before PCI probe. Will be disabled later on
+	 */
 	fw = find_devices("firewire");
 	if (fw && device_is_compatible(fw, "pci106b,18"))
 		feature_set_firewire_power(fw, 1);
 }
 
-/* Initialize the Core99 KeyLargo ASIC. Currently, we just make sure
- * OpenPIC is enabled
+/* Initialize the Core99 KeyLargo ASIC. 
  */
 static void
 keylargo_init(void)
 {
+	struct device_node* np;
+	
 	KL_BIS(KEYLARGO_FCR2, KL2_MPIC_ENABLE);
+
+	/* Lookup for an airport card, and disable it if found
+	 * to save power (will be re-enabled by driver if used)
+	 */
+	np = find_devices("radio");
+	if (np && np->parent == keylargo->device)
+		airport_dev = np;
+
+	if (airport_dev) {
+		airport_pwr_state = 1;
+		feature_set_airport_power(airport_dev, 0);
+	}
+	
 }
 
 #ifdef CONFIG_PMAC_PBOOK
+void
+feature_prepare_for_sleep(void)
+{
+	/* We assume gatwick is second */
+	struct feature_controller* ctrler = &controllers[0];
+
+	if (controller_count > 1 &&
+		device_is_compatible(ctrler->device, "gatwick"))
+		ctrler = &controllers[1];
+
+	if (ctrler->bits == feature_bits_heathrow ||
+		ctrler->bits == feature_bits_paddington) {
+		heathrow_prepare_for_sleep(ctrler);
+		return;
+	}
+	if (ctrler->bits == feature_bits_keylargo) {
+		core99_prepare_for_sleep(ctrler);
+		return;
+	}
+}
+
+
+void
+feature_wake_up(void)
+{
+	struct feature_controller* ctrler = &controllers[0];
+
+	if (controller_count > 1 &&
+		device_is_compatible(ctrler->device, "gatwick"))
+		ctrler = &controllers[1];
+	
+	if (ctrler->bits == feature_bits_heathrow ||
+		ctrler->bits == feature_bits_paddington) {
+		heathrow_wakeup(ctrler);
+		return;
+	}
+	if (ctrler->bits == feature_bits_keylargo) {
+		core99_wake_up(ctrler);
+		return;
+	}
+}
 
 static u32 save_fcr[5];
 static u32 save_mbcr;
+static u32 save_gpio_levels[2];
+static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT];
+static u8 save_gpio_normal[KEYLARGO_GPIO_CNT];
+static u32 save_unin_clock_ctl;
+static struct dbdma_regs save_dbdma[13];
+
 
 static void
 heathrow_prepare_for_sleep(struct feature_controller* ctrler)
@@ -631,60 +926,226 @@
 }
 
 static void
-core99_prepare_for_sleep(struct feature_controller* ctrler)
+turn_off_keylargo(void)
 {
-	/* Not yet implemented */
+	u32 temp;
+
+	/* For now, suspending the USB ref cause the machine to die on
+	 * wakeup -- BenH
+	 */
+#if 0
+	mdelay(1);
+	KL_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND);
+	(void)KL_IN(KEYLARGO_FCR0);
+	mdelay(1500);
+#endif
+
+	KL_BIC(KEYLARGO_FCR0,	KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
+				KL0_SCC_CELL_ENABLE |
+		      		KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE |
+		      		KL0_IRDA_CLK19_ENABLE);
+
+	(void)KL_IN(KEYLARGO_FCR0); udelay(10);
+	KL_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_ENABLE);
+	(void)KL_IN(KEYLARGO_MBCR); udelay(10);
+
+	KL_BIC(KEYLARGO_FCR1,
+		KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
+		KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
+		KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
+		KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
+		KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
+		KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N |
+		KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N |
+		KL1_UIDE_ENABLE);
+	(void)KL_IN(KEYLARGO_FCR1); udelay(10);
+
+	KL_BIS(KEYLARGO_FCR2, KL2_MODEM_POWER_N);
+ 	udelay(10);
+ 	KL_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE);
+ 	udelay(10);
+	temp = KL_IN(KEYLARGO_FCR3);
+	if (keylargo_rev >= 2)
+		temp |= (KL3_SHUTDOWN_PLL2X | KL3_SHUTDOWN_PLL_TOTAL);
+		
+	temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
+		KL3_SHUTDOWN_PLLKW35 | KL3_SHUTDOWN_PLLKW12;
+	temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE
+		| KL3_CLK31_ENABLE | KL3_TIMER_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE
+		| KL3_I2S0_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE);
+	KL_OUT(KEYLARGO_FCR3, temp);
+	(void)KL_IN(KEYLARGO_FCR3); udelay(10);
 }
 
 static void
-core99_wake_up(struct feature_controller* ctrler)
+turn_off_pangea(void)
 {
-	/* Not yet implemented */
+	u32 temp;
+
+	KL_BIC(KEYLARGO_FCR0,	KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
+				KL0_SCC_CELL_ENABLE |
+				KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
+
+	(void)KL_IN(KEYLARGO_FCR0); udelay(10);
+	KL_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_ENABLE);
+	(void)KL_IN(KEYLARGO_MBCR); udelay(10);
+
+	KL_BIC(KEYLARGO_FCR1,
+		KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
+		KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
+		KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
+		KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
+		KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
+		KL1_UIDE_ENABLE);
+	(void)KL_IN(KEYLARGO_FCR1); udelay(10);
+
+	KL_BIS(KEYLARGO_FCR2, KL2_MODEM_POWER_N);
+ 	udelay(10);
+	temp = KL_IN(KEYLARGO_FCR3);
+	temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
+		KL3_SHUTDOWN_PLLKW35;
+	temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE
+		| KL3_CLK31_ENABLE | KL3_TIMER_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE
+		| KL3_I2S0_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE);
+	KL_OUT(KEYLARGO_FCR3, temp);
+	(void)KL_IN(KEYLARGO_FCR3); udelay(10);
 }
 
-void
-feature_prepare_for_sleep(void)
+static void
+core99_prepare_for_sleep(struct feature_controller* ctrler)
 {
-	/* We assume gatwick is second */
-	struct feature_controller* ctrler = &controllers[0];
+	int i;
+	u8* base8;
+	
+	/*
+	 * Save various bits of KeyLargo
+	 */
 
-	if (!ctrler)
-		return;
-	if (controller_count > 1 &&
-		device_is_compatible(ctrler->device, "gatwick"))
-		ctrler = &controllers[1];
+	/* We power off the wireless slot in case it was not done
+	 * by the driver. We don't power it on automatically however
+	 */
+	feature_set_airport_power(airport_dev, 0);
 
-	if (ctrler->bits == feature_bits_heathrow ||
-		ctrler->bits == feature_bits_paddington) {
-		heathrow_prepare_for_sleep(ctrler);
-		return;
+	/* We power off the FW cable. Should be done by the driver... */
+	feature_set_firewire_cable_power(NULL, 0);
+	 
+	/* Save the state of the various GPIOs */
+	save_gpio_levels[0] = KL_IN(KEYLARGO_GPIO_LEVELS0);
+	save_gpio_levels[1] = KL_IN(KEYLARGO_GPIO_LEVELS1);
+	base8 = (u8 *)KL_FCR(KEYLARGO_GPIO_EXTINT_0);
+	for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
+		save_gpio_extint[i] = in_8(base8+i);
+	base8 = (u8 *)KL_FCR(KEYLARGO_GPIO_0);
+	for (i=0; i<KEYLARGO_GPIO_CNT; i++)
+		save_gpio_normal[i] = in_8(base8+i);
+
+	/* Save the FCRs */
+	save_mbcr = KL_IN(KEYLARGO_MBCR);
+	save_fcr[0] = KL_IN(KEYLARGO_FCR0);
+	save_fcr[1] = KL_IN(KEYLARGO_FCR1);
+	save_fcr[2] = KL_IN(KEYLARGO_FCR2);
+	save_fcr[3] = KL_IN(KEYLARGO_FCR3);
+	save_fcr[4] = KL_IN(KEYLARGO_FCR4);
+
+	/* Save state & config of DBDMA channels */
+	for (i=0; i<13; i++) {
+		volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*)
+			(keylargo_base + ((0x8000+i*0x100)>>2));
+		save_dbdma[i].cmdptr_hi = in_le32(&chan->cmdptr_hi);
+		save_dbdma[i].cmdptr = in_le32(&chan->cmdptr);
+		save_dbdma[i].intr_sel = in_le32(&chan->intr_sel);
+		save_dbdma[i].br_sel = in_le32(&chan->br_sel);
+		save_dbdma[i].wait_sel = in_le32(&chan->wait_sel);
 	}
-	if (ctrler->bits == feature_bits_keylargo) {
-		core99_prepare_for_sleep(ctrler);
-		return;
+
+	/*
+	 * Turn off as much as we can
+	 */
+	if (keylargo_rev & KL_PANGEA_REV)
+		turn_off_pangea();
+	else
+		turn_off_keylargo();
+	
+	/* 
+	 * Put the host bridge to sleep
+	 */
+
+	save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL);
+	UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl &
+		~(UNI_N_CLOCK_CNTL_GMAC|UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
+	udelay(100);
+	UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
+	UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP);
+
+	/*
+	 * FIXME: A bit of black magic with OpenPIC (don't ask me why)
+	 */
+	if (board_features & FTR_NEED_OPENPIC_TWEAK) {
+		KL_BIS(0x506e0, 0x00400000);
+		KL_BIS(0x506e0, 0x80000000);
 	}
 }
 
-void
-feature_wake_up(void)
+static void
+core99_wake_up(struct feature_controller* ctrler)
 {
-	struct feature_controller* ctrler = &controllers[0];
+	int i;
+	u8* base8;
 
-	if (!ctrler)
-		return;
-	if (controller_count > 1 &&
-		device_is_compatible(ctrler->device, "gatwick"))
-		ctrler = &controllers[1];
+	/*
+	 * Wakeup the host bridge
+	 */
+	UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
+	udelay(10);
+	UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
+	udelay(10);
 	
-	if (ctrler->bits == feature_bits_heathrow ||
-		ctrler->bits == feature_bits_paddington) {
-		heathrow_wakeup(ctrler);
-		return;
+	/*
+	 * Restore KeyLargo
+	 */
+	 
+	KL_OUT(KEYLARGO_MBCR, save_mbcr);
+	(void)KL_IN(KEYLARGO_MBCR); udelay(10);
+	KL_OUT(KEYLARGO_FCR0, save_fcr[0]);
+	(void)KL_IN(KEYLARGO_FCR0); udelay(10);
+	KL_OUT(KEYLARGO_FCR1, save_fcr[1]);
+	(void)KL_IN(KEYLARGO_FCR1); udelay(10);
+	KL_OUT(KEYLARGO_FCR2, save_fcr[2]);
+	(void)KL_IN(KEYLARGO_FCR2); udelay(10);
+	KL_OUT(KEYLARGO_FCR3, save_fcr[3]);
+	(void)KL_IN(KEYLARGO_FCR3); udelay(10);
+	KL_OUT(KEYLARGO_FCR4, save_fcr[4]);
+	(void)KL_IN(KEYLARGO_FCR4); udelay(10);
+
+	for (i=0; i<13; i++) {
+		volatile struct dbdma_regs* chan = (volatile struct dbdma_regs*)
+			(keylargo_base + ((0x8000+i*0x100)>>2));
+		out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16);
+		while (in_le32(&chan->status) & ACTIVE)
+			mb();
+		out_le32(&chan->cmdptr_hi, save_dbdma[i].cmdptr_hi);
+		out_le32(&chan->cmdptr, save_dbdma[i].cmdptr);
+		out_le32(&chan->intr_sel, save_dbdma[i].intr_sel);
+		out_le32(&chan->br_sel, save_dbdma[i].br_sel);
+		out_le32(&chan->wait_sel, save_dbdma[i].wait_sel);
 	}
-	if (ctrler->bits == feature_bits_keylargo) {
-		core99_wake_up(ctrler);
-		return;
+
+	KL_OUT(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]);
+	KL_OUT(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]);
+	base8 = (u8 *)KL_FCR(KEYLARGO_GPIO_EXTINT_0);
+	for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
+		out_8(base8+i, save_gpio_extint[i]);
+	base8 = (u8 *)KL_FCR(KEYLARGO_GPIO_0);
+	for (i=0; i<KEYLARGO_GPIO_CNT; i++)
+		out_8(base8+i, save_gpio_normal[i]);
+
+	/* FIXME more black magic with OpenPIC ... */
+	if (board_features & FTR_NEED_OPENPIC_TWEAK) {
+		KL_BIC(0x506e0, 0x00400000);
+		KL_BIC(0x506e0, 0x80000000);
 	}
-}
 
+	UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
+	udelay(100);
+}
 #endif /* CONFIG_PMAC_PBOOK */
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/find_name.c linux/arch/ppc/kernel/find_name.c
--- v2.4.4/linux/arch/ppc/kernel/find_name.c	Wed Sep 30 10:14:17 1998
+++ linux/arch/ppc/kernel/find_name.c	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.find_name.c 1.5 05/17/01 18:14:21 cort
+ */
 #include <stdio.h>
 #include <asm/page.h>
 #include <sys/mman.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/galaxy_pci.c linux/arch/ppc/kernel/galaxy_pci.c
--- v2.4.4/linux/arch/ppc/kernel/galaxy_pci.c	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/galaxy_pci.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.galaxy_pci.c 1.7 05/17/01 18:14:21 cort
+ */
+/*
  *
  *    Copyright (c) 2000 Grant Erickson <grant@borg.umn.edu>
  *    All rights reserved.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/gemini_pci.c linux/arch/ppc/kernel/gemini_pci.c
--- v2.4.4/linux/arch/ppc/kernel/gemini_pci.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/gemini_pci.c	Mon May 21 17:04:47 2001
@@ -0,0 +1,124 @@
+/*
+ * BK Id: SCCS/s.gemini_pci.c 1.5 05/17/01 18:14:21 cort
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/malloc.h>
+
+#include <asm/machdep.h>
+#include <asm/gemini.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pci-bridge.h>
+
+#include "pci.h"
+
+#define pci_config_addr(bus,dev,offset) \
+        (0x80000000 | (bus<<16) | (dev<<8) | offset)
+
+
+int
+gemini_pcibios_read_config_byte(struct pci_dev *dev, int offset, u8 *val)
+{
+	unsigned long reg;
+	reg = grackle_read(pci_config_addr(dev->bus->number, dev->devfn,
+					   (offset & ~(0x3))));
+	*val = ((reg >> ((offset & 0x3) << 3)) & 0xff);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int
+gemini_pcibios_read_config_word(struct pci_dev *dev, int offset, u16 *val)
+{
+	unsigned long reg;
+	reg = grackle_read(pci_config_addr(dev->bus->number, dev->devfn,
+					   (offset & ~(0x3))));
+	*val = ((reg >> ((offset & 0x3) << 3)) & 0xffff);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int
+gemini_pcibios_read_config_dword(struct pci_dev *dev, int offset, u32 *val)
+{
+	*val = grackle_read(pci_config_addr(dev->bus->number, dev->devfn,
+					    (offset & ~(0x3))));
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int
+gemini_pcibios_write_config_byte(struct pci_dev *dev, int offset, u8 val)
+{
+	unsigned long reg;
+	int shifts = offset & 0x3;
+	unsigned int addr = pci_config_addr(dev->bus->number, dev->devfn,
+					    (offset & ~(0x3)));
+
+	reg = grackle_read(addr);
+	reg = (reg & ~(0xff << (shifts << 3))) | (val << (shifts << 3));
+	grackle_write(addr, reg );
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int
+gemini_pcibios_write_config_word(struct pci_dev *dev, int offset, u16 val)
+{
+	unsigned long reg;
+	int shifts = offset & 0x3;
+	unsigned int addr = pci_config_addr(dev->bus->number, dev->devfn,
+					    (offset & ~(0x3)));
+
+	reg = grackle_read(addr);
+	reg = (reg & ~(0xffff << (shifts << 3))) | (val << (shifts << 3));
+	grackle_write(addr, reg );
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int
+gemini_pcibios_write_config_dword(struct pci_dev *dev, int offset, u32 val)
+{
+	grackle_write(pci_config_addr(dev->bus->number, dev->devfn,
+				      (offset & ~(0x3))), val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops gemini_pci_ops =
+{
+	gemini_pcibios_read_config_byte,
+	gemini_pcibios_read_config_word,
+	gemini_pcibios_read_config_dword,
+	gemini_pcibios_write_config_byte,
+	gemini_pcibios_write_config_word,
+	gemini_pcibios_write_config_dword
+};
+
+void __init gemini_pcibios_fixup(void)
+{
+	int i;
+	struct pci_dev *dev;
+	
+	pci_for_each_dev(dev) {
+		for(i = 0; i < 6; i++) {
+			if (dev->resource[i].flags & IORESOURCE_IO) {
+				dev->resource[i].start |= (0xfe << 24);
+				dev->resource[i].end |= (0xfe << 24);
+			}
+		}
+	}
+}
+
+
+/* The "bootloader" for Synergy boards does none of this for us, so we need to
+   lay it all out ourselves... --Dan */
+void __init gemini_find_bridges(void)
+{
+	struct pci_controller* hose;
+	
+	ppc_md.pcibios_fixup = gemini_pcibios_fixup;
+
+	hose = pcibios_alloc_controller();
+	if (!hose)
+		return;
+	hose->ops = &gemini_pci_ops;
+}
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/gemini_prom.S linux/arch/ppc/kernel/gemini_prom.S
--- v2.4.4/linux/arch/ppc/kernel/gemini_prom.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/gemini_prom.S	Mon May 21 17:04:47 2001
@@ -0,0 +1,99 @@
+/*
+ * BK Id: SCCS/s.gemini_prom.S 1.5 05/17/01 18:14:21 cort
+ */
+/*
+ *  arch/ppc/kernel/gemini_prom.S
+ *
+ *  Not really prom support code (yet), but sort of anti-prom code.  The current
+ *  bootloader does a number of things it shouldn't and doesn't do things that it
+ *  should.  The stuff in here is mainly a hodge-podge collection of setup code
+ *  to get the board up and running.
+ *    ---Dan
+ */
+
+#include "ppc_asm.tmpl"
+#include "ppc_defs.h"
+#include <linux/config.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/gemini.h>
+
+#define HID0_ABE (1<<3)
+
+/*
+ *  On 750's the MMU is on when Linux is booted, so we need to clear out the
+ *  bootloader's BAT settings, make sure we're in supervisor state (gotcha!),
+ *  and turn off the MMU.
+ *
+ */
+
+_GLOBAL(gemini_prom_init)
+#ifdef CONFIG_SMP
+	/* Since the MMU's on, get stuff in rom space that we'll need */
+	lis	r4,GEMINI_CPUSTAT@h
+	ori	r4,r4,GEMINI_CPUSTAT@l
+	lbz	r5,0(r4)
+	andi.	r5,r5,3
+	mr	r24,r5		/* cpu # used later on */
+#endif
+	mfmsr	r4
+	li	r3,MSR_PR	/* ensure supervisor! */
+	ori	r3,r3,MSR_IR|MSR_DR
+	andc	r4,r4,r3
+	mtmsr	r4
+	isync
+#if 0
+	/* zero out the bats now that the MMU is off */
+prom_no_mmu:	
+	li	r3,0
+        mtspr   IBAT0U,r3
+        mtspr   IBAT0L,r3
+        mtspr   IBAT1U,r3
+        mtspr   IBAT1L,r3
+        mtspr   IBAT2U,r3
+        mtspr   IBAT2L,r3
+        mtspr   IBAT3U,r3
+        mtspr   IBAT3L,r3
+
+        mtspr   DBAT0U,r3
+        mtspr   DBAT0L,r3
+        mtspr   DBAT1U,r3
+        mtspr   DBAT1L,r3
+        mtspr   DBAT2U,r3
+	mtspr   DBAT2L,r3
+        mtspr   DBAT3U,r3
+        mtspr   DBAT3L,r3
+#endif
+
+	/* the bootloader (as far as I'm currently aware) doesn't mess with page
+	   tables, but since we're already here, might as well zap these, too */
+	li	r4,0
+	mtspr	SDR1,r4
+
+	li	r4,16
+	mtctr	r4
+	li	r3,0
+	li	r4,0
+3:	mtsrin	r3,r4
+	addi	r3,r3,1
+	bdnz	3b
+
+#ifdef CONFIG_SMP
+	/* The 750 book (and Mot/IBM support) says that this will "assist" snooping
+	   when in SMP.  Not sure yet whether this should stay or leave... */
+	mfspr	r4,HID0
+	ori	r4,r4,HID0_ABE
+	mtspr	HID0,r4
+	sync
+#endif /* CONFIG_SMP */
+	blr
+
+/*  apparently, SMon doesn't pay attention to HID0[SRST].  Disable the MMU and
+    branch to 0xfff00100 */
+_GLOBAL(_gemini_reboot)
+	lis	r5,GEMINI_BOOT_INIT@h
+	ori	r5,r5,GEMINI_BOOT_INIT@l
+	li	r6,MSR_IP
+	mtspr	SRR0,r5
+	mtspr	SRR1,r6
+	rfi
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/gemini_setup.c linux/arch/ppc/kernel/gemini_setup.c
--- v2.4.4/linux/arch/ppc/kernel/gemini_setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/gemini_setup.c	Mon May 21 17:04:47 2001
@@ -0,0 +1,540 @@
+/*
+ * BK Id: SCCS/s.gemini_setup.c 1.7 05/17/01 18:14:21 cort
+ */
+/*
+ *  linux/arch/ppc/kernel/setup.c
+ *
+ *  Copyright (C) 1995 Linus Torvalds
+ *  Adapted from 'alpha' version by Gary Thomas
+ *  Modified by Cort Dougan (cort@cs.nmt.edu)
+ *  Synergy Microsystems board support by Dan Cox (dan@synergymicro.com)
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h> 
+#include <linux/reboot.h>
+#include <linux/pci.h>
+#include <linux/time.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/blk.h>
+#include <linux/console.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/dma.h>
+#include <asm/io.h>
+#include <asm/m48t35.h>
+#include <asm/gemini.h>
+#include <asm/time.h>
+
+#include "local_irq.h"
+#include "open_pic.h"
+
+void gemini_find_bridges(void);
+static int gemini_get_clock_speed(void);
+extern void gemini_pcibios_fixup(void);
+
+static char *gemini_board_families[] = {
+  "VGM", "VSS", "KGM", "VGR", "VCM", "VCS", "KCM", "VCR"
+};
+static int gemini_board_count = sizeof(gemini_board_families) /
+                                 sizeof(gemini_board_families[0]);
+
+static unsigned int cpu_7xx[16] = {
+	0, 15, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0
+};
+static unsigned int cpu_6xx[16] = {
+	0, 0, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 0, 12, 7, 0
+};
+
+int chrp_get_irq(struct pt_regs *);
+void chrp_post_irq(struct pt_regs* regs, int);
+
+static inline unsigned long _get_HID1(void)
+{
+	unsigned long val;
+
+	__asm__ __volatile__("mfspr %0,1009" : "=r" (val));
+	return val;
+}
+
+/*
+ * prom_init is the Gemini version of prom.c:prom_init.  We only need
+ * the BSS clearing code, so I copied that out of prom.c.  This is a
+ * lot simpler than hacking prom.c so it will build with Gemini. -VAL
+ */
+
+#define PTRRELOC(x)	((typeof(x))((unsigned long)(x) + offset))
+
+unsigned long
+prom_init(void)
+{
+	unsigned long offset = reloc_offset();
+	unsigned long phys;
+	extern char __bss_start, _end;
+
+	/* First zero the BSS -- use memset, some arches don't have
+	 * caches on yet */
+	memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start);
+
+ 	/* Default */
+ 	phys = offset + KERNELBASE;
+
+	gemini_prom_init();
+
+	return phys;
+}
+
+int
+gemini_get_cpuinfo(char *buffer)
+{
+	int len;
+	unsigned char reg, rev;
+	char *family;
+	unsigned int type;
+
+	reg = readb(GEMINI_FEAT);
+	family = gemini_board_families[((reg>>4) & 0xf)];
+	if (((reg>>4) & 0xf) > gemini_board_count)
+		printk(KERN_ERR "cpuinfo(): unable to determine board family\n");
+
+	reg = readb(GEMINI_BREV);
+	type = (reg>>4) & 0xf;
+	rev = reg & 0xf;
+
+	reg = readb(GEMINI_BECO);
+
+	len = sprintf( buffer, "machine\t\t: Gemini %s%d, rev %c, eco %d\n", 
+		       family, type, (rev + 'A'), (reg & 0xf));
+
+	len = sprintf(buffer, "board\t\t: Gemini %s", family);
+	if (type > 9)
+		len += sprintf(buffer+len, "%c", (type - 10) + 'A');
+	else
+		len += sprintf(buffer+len, "%d", type);
+
+	len += sprintf(buffer+len, ", rev %c, eco %d\n",
+		       (rev + 'A'), (reg & 0xf));
+
+	len += sprintf(buffer+len, "clock\t\t: %dMhz\n", 
+		       gemini_get_clock_speed());
+
+	return len;
+}
+
+static u_char gemini_openpic_initsenses[] = {
+	1,
+	1,
+	1,
+	1,
+	0,
+	0,
+	1, /* remainder are level-triggered */
+};
+
+#define GEMINI_MPIC_ADDR (0xfcfc0000)
+#define GEMINI_MPIC_PCI_CFG (0x80005800)
+
+void __init gemini_openpic_init(void)
+{
+
+	OpenPIC_Addr = (volatile struct OpenPIC *)
+		grackle_read(GEMINI_MPIC_PCI_CFG + 0x10);
+	OpenPIC_InitSenses = gemini_openpic_initsenses;
+	OpenPIC_NumInitSenses = sizeof( gemini_openpic_initsenses );
+
+	ioremap( GEMINI_MPIC_ADDR, OPENPIC_SIZE);
+}
+
+
+extern unsigned long loops_per_jiffy;
+extern int root_mountflags;
+extern char cmd_line[];
+
+void
+gemini_heartbeat(void)
+{
+	static unsigned long led = GEMINI_LEDBASE+(4*8);
+	static char direction = 8;
+	*(char *)led = 0;
+	if ( (led + direction) > (GEMINI_LEDBASE+(7*8)) ||
+	     (led + direction) < (GEMINI_LEDBASE+(4*8)) )
+		direction *= -1;
+	led += direction;
+	*(char *)led = 0xff;
+	ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
+}
+
+void __init gemini_setup_arch(void)
+{
+	extern char cmd_line[];
+
+
+	loops_per_jiffy = 50000000/HZ;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	/* bootable off CDROM */
+	if (initrd_start)
+		ROOT_DEV = MKDEV(SCSI_CDROM_MAJOR, 0);
+	else
+#endif
+		ROOT_DEV = to_kdev_t(0x0801);
+
+	/* nothing but serial consoles... */
+	sprintf(cmd_line, "%s console=ttyS0", cmd_line);
+
+	printk("Boot arguments: %s\n", cmd_line);
+
+	ppc_md.heartbeat = gemini_heartbeat;
+	ppc_md.heartbeat_reset = HZ/8;
+	ppc_md.heartbeat_count = 1;
+	
+	/* Lookup PCI hosts */
+	gemini_find_bridges();
+	/* take special pains to map the MPIC, since it isn't mapped yet */
+	gemini_openpic_init();
+	/* start the L2 */
+	gemini_init_l2();
+}
+
+
+int
+gemini_get_clock_speed(void)
+{
+	unsigned long hid1, pvr = _get_PVR();
+	int clock;
+
+	hid1 = (_get_HID1() >> 28) & 0xf;
+	if (PVR_VER(pvr) == 8 ||
+	    PVR_VER(pvr) == 12)
+		hid1 = cpu_7xx[hid1];
+	else
+		hid1 = cpu_6xx[hid1];
+
+	switch((readb(GEMINI_BSTAT) & 0xc) >> 2) {
+
+	case 0:
+	default:
+		clock = (hid1*100)/3;
+		break;
+  
+	case 1:
+		clock = (hid1*125)/3;
+		break;
+  
+	case 2:
+		clock = (hid1*50);
+		break;
+	}
+
+	return clock;
+}
+
+void __init gemini_init_l2(void)
+{
+        unsigned char reg, brev, fam, creg;
+        unsigned long cache;
+        unsigned long pvr = _get_PVR();
+
+        reg = readb(GEMINI_L2CFG);
+        brev = readb(GEMINI_BREV);
+        fam = readb(GEMINI_FEAT);
+
+        switch(PVR_VER(pvr)) {
+
+        case 8:
+                if (reg & 0xc0)
+                        cache = (((reg >> 6) & 0x3) << 28);
+                else
+                        cache = 0x3 << 28;
+
+#ifdef CONFIG_SMP
+                /* Pre-3.0 processor revs had snooping errata.  Leave
+                   their L2's disabled with SMP. -- Dan */
+                if (PVR_CFG(pvr) < 3) {
+                        printk("Pre-3.0 750; L2 left disabled!\n");
+                        return;
+                }
+#endif /* CONFIG_SMP */
+
+                /* Special case: VGM5-B's came before L2 ratios were set on
+                   the board.  Processor speed shouldn't be too high, so
+                   set L2 ratio to 1:1.5.  */
+                if ((brev == 0x51) && ((fam & 0xa0) >> 4) == 0)
+                        reg |= 1;
+
+                /* determine best cache ratio based upon what the board
+                   tells us (which sometimes _may_ not be true) and
+                   the processor speed. */
+                else {
+                        if (gemini_get_clock_speed() > 250)
+                                reg = 2;
+                }
+                break;
+        case 12:
+	{
+		static unsigned long l2_size_val = 0;
+		
+		if (!l2_size_val)
+			l2_size_val = _get_L2CR();
+		cache = l2_size_val;
+                break;
+	}
+        case 4:
+        case 9:
+                creg = readb(GEMINI_CPUSTAT);
+                if (((creg & 0xc) >> 2) != 1)
+                        printk("Dual-604 boards don't support the use of L2\n");
+                else
+                        writeb(1, GEMINI_L2CFG);
+                return;
+        default:
+                printk("Unknown processor; L2 left disabled\n");
+                return;
+        }
+
+        cache |= ((1<<reg) << 25);
+        cache |= (L2CR_L2RAM_MASK|L2CR_L2CTL|L2CR_L2DO);
+        _set_L2CR(0);
+        _set_L2CR(cache | L2CR_L2E);
+
+}
+
+void
+gemini_restart(char *cmd)
+{
+	__cli();
+	/* make a clean restart, not via the MPIC */
+	_gemini_reboot();
+	for(;;);
+}
+
+void
+gemini_power_off(void)
+{
+	for(;;);
+}
+
+void
+gemini_halt(void)
+{
+	gemini_restart(NULL);
+}
+
+void __init gemini_init_IRQ(void)
+{
+	/* gemini has no 8259 */
+	openpic_init(1, 0, 0, -1);
+}
+
+#define gemini_rtc_read(x)       (readb(GEMINI_RTC+(x)))
+#define gemini_rtc_write(val,x)  (writeb((val),(GEMINI_RTC+(x))))
+
+/* ensure that the RTC is up and running */
+long __init gemini_time_init(void)
+{
+	unsigned char reg;
+
+	reg = gemini_rtc_read(M48T35_RTC_CONTROL);
+
+	if ( reg & M48T35_RTC_STOPPED ) {
+		printk(KERN_INFO "M48T35 real-time-clock was stopped. Now starting...\n");
+		gemini_rtc_write((reg & ~(M48T35_RTC_STOPPED)), M48T35_RTC_CONTROL);
+		gemini_rtc_write((reg | M48T35_RTC_SET), M48T35_RTC_CONTROL);
+	}
+	return 0;
+}
+
+#undef DEBUG_RTC
+
+unsigned long
+gemini_get_rtc_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+	unsigned char reg;
+
+	reg = gemini_rtc_read(M48T35_RTC_CONTROL);
+	gemini_rtc_write((reg|M48T35_RTC_READ), M48T35_RTC_CONTROL);
+#ifdef DEBUG_RTC
+	printk("get rtc: reg = %x\n", reg);
+#endif
+  
+	do {
+		sec = gemini_rtc_read(M48T35_RTC_SECONDS);
+		min = gemini_rtc_read(M48T35_RTC_MINUTES);
+		hour = gemini_rtc_read(M48T35_RTC_HOURS);
+		day = gemini_rtc_read(M48T35_RTC_DOM);
+		mon = gemini_rtc_read(M48T35_RTC_MONTH);
+		year = gemini_rtc_read(M48T35_RTC_YEAR);
+	} while( sec != gemini_rtc_read(M48T35_RTC_SECONDS));
+#ifdef DEBUG_RTC
+	printk("get rtc: sec=%x, min=%x, hour=%x, day=%x, mon=%x, year=%x\n", 
+	       sec, min, hour, day, mon, year);
+#endif
+
+	gemini_rtc_write(reg, M48T35_RTC_CONTROL);
+
+	BCD_TO_BIN(sec);
+	BCD_TO_BIN(min);
+	BCD_TO_BIN(hour);
+	BCD_TO_BIN(day);
+	BCD_TO_BIN(mon);
+	BCD_TO_BIN(year);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+#ifdef DEBUG_RTC
+	printk("get rtc: sec=%x, min=%x, hour=%x, day=%x, mon=%x, year=%x\n", 
+	       sec, min, hour, day, mon, year);
+#endif
+
+	return mktime( year, mon, day, hour, min, sec );
+}
+
+
+int
+gemini_set_rtc_time( unsigned long now )
+{
+	unsigned char reg;
+	struct rtc_time tm;
+
+	to_tm( now, &tm );
+
+	reg = gemini_rtc_read(M48T35_RTC_CONTROL);
+#if DEBUG_RTC
+	printk("set rtc: reg = %x\n", reg);
+#endif
+  
+	gemini_rtc_write((reg|M48T35_RTC_SET), M48T35_RTC_CONTROL);
+#if DEBUG_RTC
+	printk("set rtc: tm vals - sec=%x, min=%x, hour=%x, mon=%x, mday=%x, year=%x\n",
+	       tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mon, tm.tm_mday, tm.tm_year);
+#endif
+  
+	tm.tm_year -= 1900;
+	BIN_TO_BCD(tm.tm_sec);
+	BIN_TO_BCD(tm.tm_min);
+	BIN_TO_BCD(tm.tm_hour);
+	BIN_TO_BCD(tm.tm_mon);
+	BIN_TO_BCD(tm.tm_mday);
+	BIN_TO_BCD(tm.tm_year);
+#ifdef DEBUG_RTC
+	printk("set rtc: tm vals - sec=%x, min=%x, hour=%x, mon=%x, mday=%x, year=%x\n",
+	       tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mon, tm.tm_mday, tm.tm_year);
+#endif
+
+	gemini_rtc_write(tm.tm_sec, M48T35_RTC_SECONDS);
+	gemini_rtc_write(tm.tm_min, M48T35_RTC_MINUTES);
+	gemini_rtc_write(tm.tm_hour, M48T35_RTC_HOURS);
+	gemini_rtc_write(tm.tm_mday, M48T35_RTC_DOM);
+	gemini_rtc_write(tm.tm_mon, M48T35_RTC_MONTH);
+	gemini_rtc_write(tm.tm_year, M48T35_RTC_YEAR);
+
+	/* done writing */
+	gemini_rtc_write(reg, M48T35_RTC_CONTROL);
+
+	if ((time_state == TIME_ERROR) || (time_state == TIME_BAD))
+		time_state = TIME_OK;
+  
+	return 0;
+}
+
+/*  use the RTC to determine the decrementer count */
+void __init gemini_calibrate_decr(void)
+{
+	int freq, divisor;
+	unsigned char reg;
+
+	/* determine processor bus speed */
+	reg = readb(GEMINI_BSTAT);
+
+	switch(((reg & 0x0c)>>2)&0x3) {
+	case 0:
+	default:
+		freq = 66667;
+		break;
+	case 1:
+		freq = 83000;
+		break;
+	case 2:
+		freq = 100000;
+		break;
+	}
+
+	freq *= 1000;
+	divisor = 4;
+	tb_ticks_per_jiffy = freq / HZ / divisor;
+	tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);
+}
+
+unsigned long __init gemini_find_end_of_memory(void)
+{
+	unsigned long total;
+	unsigned char reg;
+
+	reg = readb(GEMINI_MEMCFG);
+	total = ((1<<((reg & 0x7) - 1)) *
+		 (8<<((reg >> 3) & 0x7)));
+	total *= (1024*1024);
+	return total;
+}
+
+void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5,
+			unsigned long r6, unsigned long r7)
+{
+	int i;
+	int chrp_get_irq( struct pt_regs * );
+
+	for(i = 0; i < GEMINI_LEDS; i++)
+		gemini_led_off(i);
+ 
+	ISA_DMA_THRESHOLD = 0;
+	DMA_MODE_READ = 0;
+	DMA_MODE_WRITE = 0;
+
+#ifdef CONFIG_BLK_DEV_INITRD
+	if ( r4 )
+	{
+		initrd_start = r4 + KERNELBASE;
+		initrd_end = r5 + KERNELBASE;
+	}
+#endif
+
+	ppc_md.setup_arch = gemini_setup_arch;
+	ppc_md.setup_residual = NULL;
+	ppc_md.get_cpuinfo = gemini_get_cpuinfo;
+	ppc_md.irq_cannonicalize = NULL;
+	ppc_md.init_IRQ = gemini_init_IRQ;
+	ppc_md.get_irq = openpic_get_irq;
+	ppc_md.init = NULL;
+
+	ppc_md.restart = gemini_restart;
+	ppc_md.power_off = gemini_power_off;
+	ppc_md.halt = gemini_halt;
+
+	ppc_md.time_init = gemini_time_init;
+	ppc_md.set_rtc_time = gemini_set_rtc_time;
+	ppc_md.get_rtc_time = gemini_get_rtc_time;
+	ppc_md.calibrate_decr = gemini_calibrate_decr;
+
+	ppc_md.find_end_of_memory = gemini_find_end_of_memory;
+
+	/* no keyboard/mouse/video stuff yet.. */
+	ppc_md.kbd_setkeycode = NULL;
+	ppc_md.kbd_getkeycode = NULL;
+	ppc_md.kbd_translate = NULL;
+	ppc_md.kbd_unexpected_up = NULL;
+	ppc_md.kbd_leds = NULL;
+	ppc_md.kbd_init_hw = NULL;
+#ifdef CONFIG_MAGIC_SYSRQ
+	ppc_md.ppc_kbd_sysrq_xlate = NULL;
+#endif
+	ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup;
+}
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/hashtable.S linux/arch/ppc/kernel/hashtable.S
--- v2.4.4/linux/arch/ppc/kernel/hashtable.S	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/hashtable.S	Mon May 21 17:04:47 2001
@@ -1,8 +1,9 @@
 /*
+ * BK Id: SCCS/s.hashtable.S 1.11 05/17/01 18:14:21 cort
+ */
+/*
  *  arch/ppc/kernel/hashtable.S
  *
- *  $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $
- *
  *  PowerPC version 
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
@@ -27,7 +28,6 @@
 #include <asm/processor.h>
 #include <asm/page.h>
 #include <linux/config.h>
-#include "mol.h"
 
 /*
  * Load a PTE into the hash table, if possible.
@@ -609,11 +609,6 @@
  * flush_hash_page(unsigned context, unsigned long va)
  */
 _GLOBAL(flush_hash_page)
-#ifdef CONFIG_MOL
-	mflr    r10
-	MOL_HOOK_MMU(10, r6)
-	mtlr    r10
-#endif
 	lis	r6,Hash@ha
 	lwz	r6,Hash@l(r6)		/* hash table base */
 	cmpwi	0,r6,0			/* hash table in use? */
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
--- v2.4.4/linux/arch/ppc/kernel/head.S	Sat Mar  3 10:52:13 2001
+++ linux/arch/ppc/kernel/head.S	Mon May 21 17:04:47 2001
@@ -1,8 +1,7 @@
 /*
- *  arch/ppc/kernel/head.S
- *
- *  $Id: head.S,v 1.154 1999/10/12 00:33:31 cort Exp $
- *
+ * BK Id: SCCS/s.head.S 1.18 05/21/01 11:49:59 paulus
+ */
+/*
  *  PowerPC version 
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
@@ -31,24 +30,11 @@
 #include <asm/page.h>
 #include <linux/config.h>
 #include <asm/mmu.h>
-#include "mol.h"
 
 #ifdef CONFIG_APUS
 #include <asm/amigappc.h>
 #endif
 
-#ifndef CONFIG_PPC64BRIDGE
-CACHELINE_BYTES = 32
-LG_CACHELINE_BYTES = 5
-CACHELINE_MASK = 0x1f
-CACHELINE_WORDS = 8
-#else
-CACHELINE_BYTES = 128
-LG_CACHELINE_BYTES = 7
-CACHELINE_MASK = 0x7f
-CACHELINE_WORDS = 32
-#endif /* CONFIG_PPC64BRIDGE */
-
 #ifdef CONFIG_PPC64BRIDGE
 #define LOAD_BAT(n, reg, RA, RB)	\
 	ld	RA,(n*32)+0(reg);	\
@@ -161,6 +147,7 @@
 	bl	fix_mem_constants
 #endif /* CONFIG_APUS */
 
+#ifndef CONFIG_GEMINI
 /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
  * the physical address we are running at, returned by prom_init()
  */
@@ -168,6 +155,7 @@
 __after_mmu_off:
 	bl	clear_bats
 	bl	flush_tlbs
+#endif
 
 #ifndef CONFIG_POWER4
 	/* POWER4 doesn't have BATs */
@@ -294,21 +282,14 @@
 	.long	hdlr;				\
 	.long	ret_from_except
 
-#define STD_MOL_EXCEPTION(n, label, hdlr, hook)	\
-	. = n;					\
-label:						\
-	EXCEPTION_PROLOG;			\
-	MOL_HOOK(hook); 			\
-	addi	r3,r1,STACK_FRAME_OVERHEAD;	\
-	li	r20,MSR_KERNEL;			\
-	bl	transfer_to_handler; 		\
-i##n:						\
-	.long	hdlr;				\
-	.long	ret_from_except
-
 /* System reset */
-#ifdef CONFIG_SMP /* MVME/MTX start the secondary here */
+#ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */
+#ifdef CONFIG_GEMINI
+	. = 0x100
+	b	__secondary_start_gemini
+#else /* CONFIG_GEMINI */
 	STD_EXCEPTION(0x100, Reset, __secondary_start_psurge)
+#endif /* CONFIG_GEMINI */
 #else
 	STD_EXCEPTION(0x100, Reset, UnknownException)
 #endif
@@ -325,7 +306,6 @@
 DataAccess:
 	EXCEPTION_PROLOG
 #endif /* CONFIG_PPC64BRIDGE */
-	MOL_HOOK(0)
 	mfspr	r20,DSISR
 	andis.	r0,r20,0xa470		/* weird error? */
 	bne	1f			/* if not, try to put a PTE */
@@ -369,7 +349,6 @@
 InstructionAccess:
 	EXCEPTION_PROLOG
 #endif /* CONFIG_PPC64BRIDGE */
-	MOL_HOOK(1)
 	andis.	r0,r23,0x4000		/* no pte found? */
 	beq	1f			/* if so, try to put a PTE */
 	mr	r3,r22			/* into the hash table */
@@ -436,7 +415,6 @@
 	. = 0x700
 ProgramCheck:
 	EXCEPTION_PROLOG
-	MOL_HOOK(2)
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	li	r20,MSR_KERNEL
 	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */
@@ -449,7 +427,6 @@
 	. = 0x800
 FPUnavailable:
 	EXCEPTION_PROLOG
-	MOL_HOOK_RESTORE(3)
 	bne	load_up_fpu		/* if from user, just load it up */
 	li	r20,MSR_KERNEL
 	bl	transfer_to_handler	/* if from kernel, take a trap */
@@ -460,7 +437,6 @@
 	. = 0x900
 Decrementer:
 	EXCEPTION_PROLOG
-	MOL_HOOK(4)	
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	li	r20,MSR_KERNEL
 	bl	transfer_to_handler
@@ -484,7 +460,7 @@
 	.long	ret_from_except
 
 /* Single step - not used on 601 */
-	STD_MOL_EXCEPTION(0xd00, SingleStep, SingleStepException, 5)
+	STD_EXCEPTION(0xd00, SingleStep, SingleStepException)
 	STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
 
 /*
@@ -514,7 +490,6 @@
  */
 	. = 0x1000
 InstructionTLBMiss:
-	MOL_HOOK_TLBMISS( 14 )
 /*
  * r0:	stored ctr
  * r1:	linux style pte ( later becomes ppc hardware pte )
@@ -586,7 +561,6 @@
  */
 	. = 0x1100
 DataLoadTLBMiss:
-	MOL_HOOK_TLBMISS( 15 )
 /*
  * r0:	stored ctr
  * r1:	linux style pte ( later becomes ppc hardware pte )
@@ -657,7 +631,6 @@
  */
 	. = 0x1200
 DataStoreTLBMiss:
-	MOL_HOOK_TLBMISS( 16 )
 /*
  * r0:	stored ctr
  * r1:	linux style pte ( later becomes ppc hardware pte )
@@ -704,7 +677,7 @@
 	mtcrf	0x80,r3
 	rfi
 
-	STD_MOL_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, 11)
+	STD_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint)
 	STD_EXCEPTION(0x1400, SMI, SMIException)
 	STD_EXCEPTION(0x1500, Trap_15, UnknownException)
 	STD_EXCEPTION(0x1600, Trap_16, UnknownException)
@@ -717,7 +690,7 @@
 	STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
 	STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
 	STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
-	STD_MOL_EXCEPTION(0x2000, RunMode, RunModeException, 5)
+	STD_EXCEPTION(0x2000, RunMode, RunModeException)
 	STD_EXCEPTION(0x2100, Trap_21, UnknownException)
 	STD_EXCEPTION(0x2200, Trap_22, UnknownException)
 	STD_EXCEPTION(0x2300, Trap_23, UnknownException)
@@ -739,7 +712,6 @@
 #ifdef CONFIG_ALTIVEC
 AltiVecUnavailable:
 	EXCEPTION_PROLOG
-	MOL_HOOK_RESTORE(12)
 	bne	load_up_altivec		/* if from user, just load it up */
 	li	r20,MSR_KERNEL
 	bl	transfer_to_handler	/* if from kernel, take a trap */
@@ -792,8 +764,6 @@
 	mflr	r23
 	andi.	r24,r23,0x3f00		/* get vector offset */
 	stw	r24,TRAP(r21)
-	li	r22,RESULT
-	stwcx.	r22,r22,r21		/* to clear the reservation */
 	li	r22,0
 	stw	r22,RESULT(r21)
 	mtspr	SPRG2,r22		/* r1 is now kernel sp */
@@ -805,7 +775,6 @@
 	lwz	r24,0(r23)		/* virtual address of handler */
 	lwz	r23,4(r23)		/* where to go when done */
 	FIX_SRR1(r20,r22)
-	MOL_HOOK(6)
 	mtspr	SRR0,r24
 	mtspr	SRR1,r20
 	mtlr	r23
@@ -1016,11 +985,6 @@
 
 	.globl	giveup_altivec
 giveup_altivec:
-#ifdef CONFIG_MOL
-	mflr	r4
-	MOL_HOOK_MMU(13, r5)
-	mtlr	r4
-#endif
 	mfmsr	r5
 	oris	r5,r5,MSR_VEC@h
 	SYNC
@@ -1057,11 +1021,6 @@
  */
 	.globl	giveup_fpu
 giveup_fpu:
-#ifdef CONFIG_MOL
-	mflr	r4
-	MOL_HOOK_MMU(7, r5)
-	mtlr	r4
-#endif		
 	mfmsr	r5
 	ori	r5,r5,MSR_FP
 	SYNC
@@ -1116,7 +1075,7 @@
 copy_and_flush:
 	addi	r5,r5,-4
 	addi	r6,r6,-4
-4:	li	r0,CACHELINE_WORDS
+4:	li	r0,CACHE_LINE_SIZE/4
 	mtctr	r0
 3:	addi	r6,r6,4			/* copy a cache line */
 	lwzx	r0,r6,r4
@@ -1127,6 +1086,7 @@
 	icbi	r6,r3			/* flush the icache line */
 	cmplw	0,r6,r5
 	blt	4b
+	sync				/* additional sync needed on g4 */
 	isync
 	addi	r5,r5,4
 	addi	r6,r6,4
@@ -1165,6 +1125,7 @@
 	icbi	r0,r14			 /* flush the icache line */
 	cmpw	r12,r13
 	bne     1b
+	sync				/* additional sync needed on g4 */
 	isync
 
 /*
@@ -1199,6 +1160,7 @@
 	cmpw	r12,r13
 	bne     1b
 
+	sync				/* additional sync needed on g4 */
 	isync				/* No speculative loading until now */
 	blr
 	
@@ -1266,6 +1228,20 @@
 #endif /* CONFIG_APUS */
 
 #ifdef CONFIG_SMP
+#ifdef CONFIG_GEMINI
+	.globl	__secondary_start_gemini
+__secondary_start_gemini:
+        mfspr   r4,HID0
+        ori     r4,r4,HID0_ICFI
+        li      r3,0
+        ori     r3,r3,HID0_ICE
+        andc    r4,r4,r3
+        mtspr   HID0,r4
+        sync
+        bl      prom_init
+        b       __secondary_start
+#endif /* CONFIG_GEMINI */
+	
 	.globl	__secondary_start_psurge
 __secondary_start_psurge:
 	li	r24,1			/* cpu # */
@@ -1536,6 +1512,7 @@
  *  -- Cort 
  */
 clear_bats:
+#if !defined(CONFIG_GEMINI)
 	li	r20,0
 	mfspr	r9,PVR
 	rlwinm	r9,r9,16,16,31		/* r9 = 1 for 601, 4 for 604 */
@@ -1559,8 +1536,10 @@
 	mtspr	IBAT2L,r20
 	mtspr	IBAT3U,r20
 	mtspr	IBAT3L,r20
+#endif /* !defined(CONFIG_GEMINI) */
 	blr
 
+#ifndef CONFIG_GEMINI
 flush_tlbs:
 	lis	r20, 0x40
 1:	addic.	r20, r20, -0x1000
@@ -1579,6 +1558,7 @@
 	mtspr	SRR1,r3
 	sync
 	RFI
+#endif
 
 #ifndef CONFIG_POWER4	
 /*
@@ -1688,17 +1668,6 @@
 2:
 	mtlr	r4
 	blr
-#endif
-
-#ifdef CONFIG_MOL
-/*
- * Mac-on-linux hook_table. Don't put this in the data section -
- * the base address must be within the first 32KB of RAM.
- */
-	.globl mol_interface
-mol_interface:
-	.long   MOL_INTERFACE_VERSION
-	.fill	24,4,0		/* space for 24 hooks */
 #endif
 
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/head_4xx.S linux/arch/ppc/kernel/head_4xx.S
--- v2.4.4/linux/arch/ppc/kernel/head_4xx.S	Wed Feb  9 19:43:47 2000
+++ linux/arch/ppc/kernel/head_4xx.S	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.head_4xx.S 1.6 05/21/01 11:50:00 paulus
+ */
+/*
  *    Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
  *      Initial PowerPC version.
  *    Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
@@ -387,8 +390,6 @@
 	mflr	r23
 	andi.	r24,r23,0x3f00		# Get vector offset
 	stw	r24,TRAP(r21)
-	li	r22,RESULT
-	stwcx.	r22,r22,r21		# Clear the reservation
 	li	r22,0
 	stw	r22,RESULT(r21)
 	mtspr	SPRN_SPRG2,r22		# r1 is now the kernel stack pointer
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/head_8xx.S linux/arch/ppc/kernel/head_8xx.S
--- v2.4.4/linux/arch/ppc/kernel/head_8xx.S	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/head_8xx.S	Mon May 21 17:04:47 2001
@@ -1,8 +1,9 @@
 /*
+ * BK Id: SCCS/s.head_8xx.S 1.11 05/21/01 11:50:00 paulus
+ */
+/*
  *  arch/ppc/kernel/except_8xx.S
  *
- *  $Id: head_8xx.S,v 1.4 1999/09/18 18:43:19 dmalek Exp $
- *
  *  PowerPC version 
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
@@ -30,13 +31,6 @@
 #include <asm/mmu.h>
 #include <asm/cache.h>
 #include <asm/pgtable.h>
-	
-/* XXX need definitions here for 16 byte cachelines on some/all 8xx
-   -- paulus */
-CACHELINE_BYTES = 32
-LG_CACHELINE_BYTES = 5
-CACHELINE_MASK = 0x1f
-CACHELINE_WORDS = 8
 
 	.text
 	.globl	_stext
@@ -685,8 +679,6 @@
 	mflr	r23
 	andi.	r24,r23,0x3f00		/* get vector offset */
 	stw	r24,TRAP(r21)
-	li	r22,RESULT
-	stwcx.	r22,r22,r21		/* to clear the reservation */
 	li	r22,0
 	stw	r22,RESULT(r21)
 	mtspr	SPRG2,r22		/* r1 is now kernel sp */
@@ -757,7 +749,7 @@
 copy_and_flush:
 	addi	r5,r5,-4
 	addi	r6,r6,-4
-4:	li	r0,CACHELINE_WORDS
+4:	li	r0,CACHE_LINE_SIZE/4
 	mtctr	r0
 3:	addi	r6,r6,4			/* copy a cache line */
 	lwzx	r0,r6,r4
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/i8259.c linux/arch/ppc/kernel/i8259.c
--- v2.4.4/linux/arch/ppc/kernel/i8259.c	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/i8259.c	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.i8259.c 1.7 05/17/01 18:14:21 cort
+ */
 
 #include <linux/stddef.h>
 #include <linux/init.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/i8259.h linux/arch/ppc/kernel/i8259.h
--- v2.4.4/linux/arch/ppc/kernel/i8259.h	Tue May 11 08:24:32 1999
+++ linux/arch/ppc/kernel/i8259.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.i8259.h 1.5 05/17/01 18:14:21 cort
+ */
 
 #ifndef _PPC_KERNEL_i8259_H
 #define _PPC_KERNEL_i8259_H
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/idle.c linux/arch/ppc/kernel/idle.c
--- v2.4.4/linux/arch/ppc/kernel/idle.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/ppc/kernel/idle.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,7 @@
 /*
- * $Id: idle.c,v 1.68 1999/10/15 18:16:03 cort Exp $
- *
+ * BK Id: SCCS/s.idle.c 1.11 05/17/01 18:14:21 cort
+ */
+/*
  * Idle daemon for PowerPC.  Idle daemon will handle any action
  * that needs to be taken when the system becomes idle.
  *
@@ -56,6 +57,7 @@
 	case 7:			/* 603ev */
 	case 8:			/* 750 */
 	case 12:		/* 7400 */
+	case 0x800c:		/* 7410 */
 		do_power_save = 1;
 	}
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/indirect_pci.c linux/arch/ppc/kernel/indirect_pci.c
--- v2.4.4/linux/arch/ppc/kernel/indirect_pci.c	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/indirect_pci.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.indirect_pci.c 1.7 05/17/01 18:14:21 cort
+ */
+/*
  * Support for indirect PCI bridges.
  *
  * Copyright (C) 1998 Gabriel Paubert.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- v2.4.4/linux/arch/ppc/kernel/irq.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/irq.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,7 @@
 /*
- * $Id: irq.c,v 1.113 1999/09/17 17:22:56 cort Exp $
- *
+ * BK Id: SCCS/s.irq.c 1.23 05/17/01 18:14:21 cort
+ */
+/*
  *  arch/ppc/kernel/irq.c
  *
  *  Derived from arch/i386/kernel/irq.c
@@ -176,9 +177,19 @@
 	return 0;
 }
 
-/* This could be promoted to a real free_irq() ... */
-static int
-do_free_irq(int irq, void* dev_id)
+#if (defined(CONFIG_8xx) || defined(CONFIG_8260))
+/* Name change so we can catch standard drivers that potentially mess up
+ * the internal interrupt controller on 8xx and 8260.  Just bear with me,
+ * I don't like this either and I am searching a better solution.  For
+ * now, this is what I need. -- Dan
+ */
+#define request_irq	request_8xxirq
+#elif defined(CONFIG_APUS)
+#define request_irq	request_sysirq
+#define free_irq	sys_free_irq
+#endif
+
+void free_irq(unsigned int irq, void* dev_id)
 {
 	irq_desc_t *desc;
 	struct irqaction **p;
@@ -209,27 +220,15 @@
 				barrier();
 #endif
 			irq_kfree(action);
-			return 0;
+			return;
 		}
 		printk("Trying to free free IRQ%d\n",irq);
 		spin_unlock_irqrestore(&desc->lock,flags);
 		break;
 	}
-	return -ENOENT;
+	return;
 }
 
-#if (defined(CONFIG_8xx) || defined(CONFIG_8260))
-/* Name change so we can catch standard drivers that potentially mess up
- * the internal interrupt controller on 8xx and 8260.  Just bear with me,
- * I don't like this either and I am searching a better solution.  For
- * now, this is what I need. -- Dan
- */
-#define request_irq	request_8xxirq
-#elif defined(CONFIG_APUS)
-#define request_irq	request_sysirq
-#define free_irq	sys_free_irq
-#endif
-
 int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
 	unsigned long irqflags, const char * devname, void *dev_id)
 {
@@ -239,8 +238,17 @@
 	if (irq >= NR_IRQS)
 		return -EINVAL;
 	if (!handler)
-		/* We could implement really free_irq() instead of that... */
-		return do_free_irq(irq, dev_id);
+	{
+		/*
+		 * free_irq() used to be implemented as a call to
+		 * request_irq() with handler being NULL.  Now we have
+		 * a real free_irq() but need to allow the old behavior
+		 * for old code that hasn't caught up yet.
+		 *  -- Cort <cort@fsmlabs.com>
+		 */
+		free_irq(irq, dev_id);
+		return 0;
+	}
 	
 	action = (struct irqaction *)
 		irq_kmalloc(sizeof(struct irqaction), GFP_KERNEL);
@@ -266,11 +274,6 @@
 	return 0;
 }
 
-void free_irq(unsigned int irq, void *dev_id)
-{
-	request_irq(irq, NULL, 0, NULL, dev_id);
-}
-
 /*
  * Generic enable/disable code: this just calls
  * down into the PIC-specific version for the actual
@@ -524,7 +527,7 @@
 	spin_unlock(&desc->lock);
 }
 
-int do_IRQ(struct pt_regs *regs, int isfake)
+int do_IRQ(struct pt_regs *regs)
 {
 	int cpu = smp_processor_id();
 	int irq;
@@ -546,10 +549,7 @@
 		goto out;
 	}
 	ppc_irq_dispatch_handler( regs, irq );
-	if (ppc_md.post_irq)
-		ppc_md.post_irq( regs, irq );
-
- out:	
+out:	
         hardirq_exit( cpu );
 	return 1; /* lets ret_from_int know we can do checks */
 }
@@ -851,15 +851,18 @@
 }
 #endif /* CONFIG_SMP */
 
-static struct proc_dir_entry * root_irq_dir;
-static struct proc_dir_entry * irq_dir [NR_IRQS];
-static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+static struct proc_dir_entry *root_irq_dir;
+static struct proc_dir_entry *irq_dir[NR_IRQS];
+static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
 
 #ifdef CONFIG_IRQ_ALL_CPUS
-unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0xffffffff};
-#else  /* CONFIG_IRQ_ALL_CPUS */
-unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0x00000000};
-#endif /* CONFIG_IRQ_ALL_CPUS */
+#define DEFAULT_CPU_AFFINITY 0xffffffff
+#else
+#define DEFAULT_CPU_AFFINITY 0x00000001
+#endif
+
+unsigned int irq_affinity [NR_IRQS] =
+	{ [0 ... NR_IRQS-1] = DEFAULT_CPU_AFFINITY };
 
 #define HEX_DIGITS 8
 
@@ -919,16 +922,18 @@
 
 	err = parse_hex_value(buffer, count, &new_value);
 
-/* Why is this disabled ? --BenH */
-#if 0/*CONFIG_SMP*/
 	/*
 	 * Do not allow disabling IRQs completely - it's a too easy
 	 * way to make the system unusable accidentally :-) At least
 	 * one online CPU still has to be targeted.
+	 *
+	 * We assume a 1-1 logical<->physical cpu mapping here.  If
+	 * we assume that the cpu indices in /proc/irq/../smp_affinity
+	 * are actually logical cpu #'s then we have no problem.
+	 *  -- Cort <cort@fsmlabs.com>
 	 */
 	if (!(new_value & cpu_online_map))
 		return -EINVAL;
-#endif
 
 	irq_affinity[irq] = new_value;
 	irq_desc[irq].handler->set_affinity(irq, new_value);
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/local_irq.h linux/arch/ppc/kernel/local_irq.h
--- v2.4.4/linux/arch/ppc/kernel/local_irq.h	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/local_irq.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.local_irq.h 1.7 05/17/01 18:14:21 cort
+ */
 
 #ifndef _PPC_KERNEL_LOCAL_IRQ_H
 #define _PPC_KERNEL_LOCAL_IRQ_H
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/m8260_setup.c linux/arch/ppc/kernel/m8260_setup.c
--- v2.4.4/linux/arch/ppc/kernel/m8260_setup.c	Fri Apr 27 14:10:32 2001
+++ linux/arch/ppc/kernel/m8260_setup.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,7 @@
 /*
- * $Id: m8xx_setup.c,v 1.4 1999/09/18 18:40:36 dmalek Exp $
- *
+ * BK Id: SCCS/s.m8260_setup.c 1.15 05/17/01 18:14:21 cort
+ */
+/*
  *  linux/arch/ppc/kernel/setup.c
  *
  *  Copyright (C) 1995  Linus Torvalds
@@ -119,7 +120,7 @@
 	return(0);
 }
 
-unsigned long __init
+unsigned long
 m8260_get_rtc_time(void)
 {
 
@@ -206,6 +207,18 @@
 
 }
 
+/*
+ * Same hack as 8xx
+ */
+unsigned long __init m8260_find_end_of_memory(void)
+{
+	bd_t	*binfo;
+	extern unsigned char __res[];
+	
+	binfo = (bd_t *)__res;
+
+	return binfo->bi_memsize;
+}
 
 void __init
 m8260_init(unsigned long r3, unsigned long r4, unsigned long r5,
@@ -248,18 +261,8 @@
 	ppc_md.get_rtc_time   = m8260_get_rtc_time;
 	ppc_md.calibrate_decr = m8260_calibrate_decr;
 
-#if 0
-	ppc_md.kbd_setkeycode    = pckbd_setkeycode;
-	ppc_md.kbd_getkeycode    = pckbd_getkeycode;
-	ppc_md.kbd_pretranslate  = pckbd_pretranslate;
-	ppc_md.kbd_translate     = pckbd_translate;
-	ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
-	ppc_md.kbd_leds          = pckbd_leds;
-	ppc_md.kbd_init_hw       = pckbd_init_hw;
-#ifdef CONFIG_MAGIC_SYSRQ
-	ppc_md.kbd_sysrq_xlate	 = pckbd_sysrq_xlate;
-#endif
-#else
+	ppc_md.find_end_of_memory = m8260_find_end_of_memory;
+
 	ppc_md.kbd_setkeycode    = NULL;
 	ppc_md.kbd_getkeycode    = NULL;
 	ppc_md.kbd_translate     = NULL;
@@ -268,7 +271,6 @@
 	ppc_md.kbd_init_hw       = NULL;
 #ifdef CONFIG_MAGIC_SYSRQ
 	ppc_md.kbd_sysrq_xlate	 = NULL;
-#endif
 #endif
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/m8xx_setup.c linux/arch/ppc/kernel/m8xx_setup.c
--- v2.4.4/linux/arch/ppc/kernel/m8xx_setup.c	Fri Apr 27 14:10:32 2001
+++ linux/arch/ppc/kernel/m8xx_setup.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,7 @@
 /*
- * $Id: m8xx_setup.c,v 1.4 1999/09/18 18:40:36 dmalek Exp $
- *
+ * BK Id: SCCS/s.m8xx_setup.c 1.17 05/18/01 07:54:04 patch
+ */
+/*
  *  linux/arch/ppc/kernel/setup.c
  *
  *  Copyright (C) 1995  Linus Torvalds
@@ -107,11 +108,17 @@
 ide_pio_timings_t ide_pio_clocks[6];
 
 /* Make clock cycles and always round up */
-#define PCMCIA_MK_CLKS( t, T ) (( (t) * (T) + 999U ) / 1000U )
+#define PCMCIA_MK_CLKS( t, T ) (( (t) * ((T)/1000000) + 999U ) / 1000U )
 
 #endif	/* CONFIG_BLK_DEV_MPC8xx_IDE */
 #endif	/* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */
 
+#ifdef CONFIG_BLK_DEV_RAM
+extern int rd_doload;		/* 1 = load ramdisk, 0 = don't load */
+extern int rd_prompt;		/* 1 = prompt for ramdisk, 0 = don't prompt */
+extern int rd_image_start;	/* starting block # of image */
+#endif
+
 extern char saved_command_line[256];
 
 extern unsigned long find_available_memory(void);
@@ -200,7 +207,7 @@
 	/* Processor frequency is MHz.
 	 * The value 'fp' is the number of decrementer ticks per second.
 	 */
-	fp = (binfo->bi_intfreq * 1000000) / 16;
+	fp = binfo->bi_intfreq / 16;
 	freq = fp*60;	/* try to make freq/1e6 an integer */
         divisor = 60;
         printk("Decrementer Frequency = %d/%d\n", freq, divisor);
@@ -308,10 +315,10 @@
 
 	bp = (bd_t *)__res;
 			
-	len += sprintf(len+buffer,"clock\t\t: %ldMHz\n"
-		       "bus clock\t: %ldMHz\n",
-		       bp->bi_intfreq /*/ 1000000*/,
-		       bp->bi_busfreq /*/ 1000000*/);
+	len += sprintf(len+buffer,"clock\t\t: %dMHz\n"
+		       "bus clock\t: %dMHz\n",
+		       bp->bi_intfreq / 1000000,
+		       bp->bi_busfreq / 1000000);
 
 	return len;
 }
@@ -358,7 +365,7 @@
 #ifdef CONFIG_BLK_DEV_MPC8xx_IDE
 	ide_insw(port, buf, ns);
 #else
-	ide_insw(port+_IO_BASE, buf, ns);
+	_insw_ns((unsigned short *)(port+_IO_BASE), buf, ns);
 #endif
 }
 
@@ -368,7 +375,7 @@
 #ifdef CONFIG_BLK_DEV_MPC8xx_IDE
 	ide_outsw(port, buf, ns);
 #else
-	ide_outsw(port+_IO_BASE, buf, ns);
+	_outsw_ns((unsigned short *)(port+_IO_BASE), buf, ns);
 #endif
 }
 
@@ -381,7 +388,7 @@
 	
 	return (ioport_dsc[base].irq);
 #else
-        return 14;
+        return 9;
 #endif
 }
 
@@ -398,11 +405,7 @@
 		       const char *device,
 		       void *dev_id)
 {
-#ifdef CONFIG_BLK_DEV_MPC8xx_IDE
 	return request_8xxirq(irq, handler, flags, device, dev_id);
-#else
-	return request_irq(irq, handler, flags, device, dev_id);
-#endif
 }
 
 /* We can use an external IDE controller
@@ -413,16 +416,14 @@
 void m8xx_ide_init_hwif_ports(hw_regs_t *hw,
 	ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
 {
-	ide_ioreg_t *p = hw->io_ports;
 	int i;
 #ifdef CONFIG_BLK_DEV_MPC8xx_IDE
+	ide_ioreg_t *p = hw->io_ports;
 	volatile pcmconf8xx_t	*pcmp;
 
 	static unsigned long pcmcia_base = 0;
-#else
-	ide_ioreg_t port = data_port;	/* ??? XXX ??? XXX */
-#endif
 	unsigned long base;
+#endif
 
 #ifdef CONFIG_BLK_DEV_MPC8xx_IDE
 	*p = 0;
@@ -500,12 +501,15 @@
 	
 	/* Just a regular IDE drive on some I/O port.
 	*/
-	i = 8;
-	while (i--)
-		*p++ = port++;
-	*p++ = base + 0x206;
-	if (irq != NULL)
-		*irq = 0;
+	if (data_port == 0)
+		return;
+
+	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; ++i)
+		hw->io_ports[i] = data_port + i - IDE_DATA_OFFSET;
+
+	hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+        return;
+
 #endif	/* CONFIG_BLK_DEV_MPC8xx_IDE */
 }
 #endif	/* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */
@@ -523,7 +527,6 @@
 #define PCMCIA_SL(t) ((t==32) ? 0 : ((t & 0x1F)<<7)) /* Strobe Length	*/
 #endif
 
-
 /* Calculate PIO timings */
 static void
 m8xx_ide_tuneproc(ide_drive_t *drive, byte pio)
@@ -581,9 +584,27 @@
 
 #endif	/* CONFIG_BLK_DEV_MPC8xx_IDE */
 #endif	/* CONFIG_BLK_DEV_IDE || CONFIG_BLK_DEV_IDE_MODULE */
-
 /* -------------------------------------------------------------------- */
 
+/*
+ * This is a big hack right now, but it may turn into something real
+ * someday.
+ *
+ * For the 8xx boards (at this time anyway), there is nothing to initialize
+ * associated the PROM.  Rather than include all of the prom.c
+ * functions in the image just to get prom_init, all we really need right
+ * now is the initialization of the physical memory region.
+ */
+unsigned long __init m8xx_find_end_of_memory(void)
+{
+	bd_t	*binfo;
+	extern unsigned char __res[];
+	
+	binfo = (bd_t *)__res;
+
+	return binfo->bi_memsize;
+}
+
 void __init
 m8xx_init(unsigned long r3, unsigned long r4, unsigned long r5,
 	 unsigned long r6, unsigned long r7)
@@ -629,18 +650,8 @@
 	ppc_md.get_rtc_time   = m8xx_get_rtc_time;
 	ppc_md.calibrate_decr = m8xx_calibrate_decr;
 
-#if 0
-	ppc_md.kbd_setkeycode    = pckbd_setkeycode;
-	ppc_md.kbd_getkeycode    = pckbd_getkeycode;
-	ppc_md.kbd_pretranslate  = pckbd_pretranslate;
-	ppc_md.kbd_translate     = pckbd_translate;
-	ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
-	ppc_md.kbd_leds          = pckbd_leds;
-	ppc_md.kbd_init_hw       = pckbd_init_hw;
-#ifdef CONFIG_MAGIC_SYSRQ
-	ppc_md.kbd_sysrq_xlate	 = pckbd_sysrq_xlate;
-#endif
-#else
+	ppc_md.find_end_of_memory = m8xx_find_end_of_memory;
+
 	ppc_md.kbd_setkeycode    = NULL;
 	ppc_md.kbd_getkeycode    = NULL;
 	ppc_md.kbd_translate     = NULL;
@@ -648,8 +659,7 @@
 	ppc_md.kbd_leds          = NULL;
 	ppc_md.kbd_init_hw       = NULL;
 #ifdef CONFIG_MAGIC_SYSRQ
-	ppc_md.kbd_sysrq_xlate	 = NULL;
-#endif
+	ppc_md.ppc_kbd_sysrq_xlate	 = NULL;
 #endif
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
--- v2.4.4/linux/arch/ppc/kernel/misc.S	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/misc.S	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.misc.S 1.16 05/17/01 18:14:21 cort
+ */
+/*
  * This file contains miscellaneous low-level functions.
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
@@ -21,20 +24,6 @@
 #include <asm/cache.h>
 #include "ppc_asm.h"
 
-#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
-#define CACHE_LINE_SIZE		16
-#define LG_CACHE_LINE_SIZE	4
-#define MAX_COPY_PREFETCH	1
-#elif !defined(CONFIG_PPC64BRIDGE)
-#define CACHE_LINE_SIZE		32
-#define LG_CACHE_LINE_SIZE	5
-#define MAX_COPY_PREFETCH	4
-#else
-#define CACHE_LINE_SIZE		128
-#define LG_CACHE_LINE_SIZE	7
-#define MAX_COPY_PREFETCH	1
-#endif /* CONFIG_4xx || CONFIG_8xx */
-
 	.text
 
 	.align	5
@@ -60,14 +49,37 @@
 	mtlr	r0
 	blr
 
-/* void __no_use_save_flags(unsigned long *flags) */
-_GLOBAL(__no_use_save_flags)
+/* void __save_flags_ptr(unsigned long *flags) */
+_GLOBAL(__save_flags_ptr)
 	mfmsr	r4
 	stw	r4,0(r3)
 	blr
+	/* 
+	 * Need these nops here for taking over save/restore to
+	 * handle lost intrs
+	 * -- Cort
+	 */
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+_GLOBAL(__save_flags_ptr_end)
 
-/* void __no_use_restore_flags(unsigned long flags) */	
-_GLOBAL(__no_use_restore_flags)
+/* void __restore_flags(unsigned long flags) */	
+_GLOBAL(__restore_flags)
 /*
  * Just set/clear the MSR_EE bit through restore/flags but do not
  * change anything else.  This is needed by the RT system and makes
@@ -82,66 +94,95 @@
 	 /* Check if things are setup the way we want _already_. */
 	cmpw	0,r3,r4
 	beqlr
-	/* are we enabling interrupts? */
-	rlwinm.	r0,r3,0,16,16
-	beq	1f
-	/* if so, check if there are any lost interrupts */
-	lis	r7,ppc_n_lost_interrupts@ha
-	lwz	r7,ppc_n_lost_interrupts@l(r7)
-	cmpi	0,r7,0		/* lost interrupts to process first? */
-	bne-	do_lost_interrupts
 1:	SYNC
 	mtmsr	r3
 	SYNC
 	blr
-	
-_GLOBAL(__no_use_cli)
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+_GLOBAL(__restore_flags_end)
+
+_GLOBAL(__cli)
 	mfmsr	r0		/* Get current interrupt state */
 	rlwinm	r3,r0,16+1,32-1,31	/* Extract old value of 'EE' */
 	rlwinm	r0,r0,0,17,15	/* clear MSR_EE in r0 */
 	SYNC			/* Some chip revs have problems here... */
 	mtmsr	r0		/* Update machine state */
 	blr			/* Done */
+	/* 
+	 * Need these nops here for taking over save/restore to
+	 * handle lost intrs
+	 * -- Cort
+	 */
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+_GLOBAL(__cli_end)
 
-_GLOBAL(__no_use_sti)
-	lis	r4,ppc_n_lost_interrupts@ha
-	lwz	r4,ppc_n_lost_interrupts@l(r4)
+_GLOBAL(__sti)
 	mfmsr	r3		/* Get current state */
 	ori	r3,r3,MSR_EE	/* Turn on 'EE' bit */
-	cmpi	0,r4,0		/* lost interrupts to process first? */
-	bne-	do_lost_interrupts
 	SYNC			/* Some chip revs have problems here... */
 	mtmsr	r3		/* Update machine state */
 	blr
-
-/*
- * We were about to enable interrupts but we have to simulate
- * some interrupts that were lost by enable_irq first.
- */
-_GLOBAL(do_lost_interrupts)
-	stwu	r1,-16(r1)
-	mflr	r0
-	stw	r0,20(r1)
-	stw	r3,8(r1)
-1:	bl	fake_interrupt
-	lis	r4,ppc_n_lost_interrupts@ha
-	lwz	r4,ppc_n_lost_interrupts@l(r4)
-	cmpi	0,r4,0
-	bne-	1b
-	lwz	r3,8(r1)
-	SYNC
-	mtmsr	r3
-	lwz	r0,20(r1)
-	mtlr	r0
-	addi	r1,r1,16
-	blr
+	/* 
+	 * Need these nops here for taking over save/restore to
+	 * handle lost intrs
+	 * -- Cort
+	 */
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+_GLOBAL(__sti_end)
 
 
 /*
  * complement mask on the msr then "or" some values on.
  *     _nmask_and_or_msr(nmask, value_to_or)
  */
-	_GLOBAL(_nmask_and_or_msr)
+_GLOBAL(_nmask_and_or_msr)
 	mfmsr	r0		/* Get current msr */
 	andc	r0,r0,r3	/* And off the bits set in r3 (first parm) */
 	or	r0,r0,r4		/* Or on the bits in r4 (second parm) */
@@ -267,6 +308,7 @@
 2:	icbi	0,r6
 	addi	r6,r6,CACHE_LINE_SIZE
 	bdnz	2b
+	sync				/* additional sync needed on g4 */
 	isync
 	blr
 
@@ -1283,7 +1325,7 @@
 	.long sys_vfork
 	.long sys_getrlimit	/* 190 */
 	.long sys_ni_syscall		/* 191 */	/* Unused */
-	.long sys_ni_syscall		/* 192 - reserved - mmap2 */
+	.long sys_mmap2			/* 192 */
 	.long sys_truncate64		/* 193 */
 	.long sys_ftruncate64		/* 194 */
 	.long sys_stat64		/* 195 */
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/mk_defs.c linux/arch/ppc/kernel/mk_defs.c
--- v2.4.4/linux/arch/ppc/kernel/mk_defs.c	Mon Jun 19 17:59:36 2000
+++ linux/arch/ppc/kernel/mk_defs.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.mk_defs.c 1.5 05/17/01 18:14:21 cort
+ */
+/*
  * This program is used to generate definitions needed by
  * assembly language modules.
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/mol.h linux/arch/ppc/kernel/mol.h
--- v2.4.4/linux/arch/ppc/kernel/mol.h	Sun Sep 17 09:48:07 2000
+++ linux/arch/ppc/kernel/mol.h	Wed Dec 31 16:00:00 1969
@@ -1,68 +0,0 @@
-/* 
- *   arch/ppc/kernel/mol.h
- *   
- *	<mol.h>
- *	
- *	Mac-on-Linux hook macros
- *	<http://www.maconlinux.org>
- *   
- *   Copyright (C) 2000 Samuel Rydh (samuel@ibrium.se)
- *   
- *   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
- *   
- */
-
-#ifndef _PPC_KERNEL_MOL
-#define _PPC_KERNEL_MOL
-
-#include <linux/config.h>
-
-#ifdef CONFIG_MOL
-#define MOL_INTERFACE_VERSION		3
-
-#define MOL_HOOK(hook_num)					\
-	lwz	r0,(mol_interface + 4 * hook_num + 4)@l(0); 	\
-	cmpwi	cr1,r0,0; 					\
-	beq+	cr1,777f; 					\
-	mtctr	r0; 						\
-	bctrl; 							\
-777:	lwz	r0,GPR0(r21)
-
-#define MOL_HOOK_RESTORE(hook_num)				\
-	mfcr	r2;						\
-	MOL_HOOK(hook_num);					\
-	mtcrf	0x80,r2;					\
-	lwz	r2,_CTR(r21);					\
-	mtctr	r2;						\
-	lwz	r2,GPR2(r21)
-
-#define MOL_HOOK_MMU(hook_num, scr)				\
-	lis	scr,(mol_interface + 4 * hook_num + 4)@ha;	\
-	lwz	scr,(mol_interface + 4 * hook_num + 4)@l(scr);	\
-	cmpwi	cr1,scr,0;					\
-	beq+	cr1,778f;					\
-	mtctr	scr;						\
-	bctrl;							\
-778:
-
-#define MOL_HOOK_TLBMISS(hook_num)				\
-	lwz	r0,(mol_interface + 4 * hook_num + 4)@l(0);	\
-	cmpwi	r0,0;						\
-	beq+	779f;						\
-	mflr	r3;						\
-	mtlr	r0;						\
-	blrl;							\
-	mtlr	r3;						\
-779:
-
-#else
-#define MOL_HOOK(num)
-#define MOL_HOOK_RESTORE(num)
-#define MOL_HOOK_MMU(num, scr)
-#define MOL_HOOK_TLBMISS(num)
-#endif
-
-
-#endif   /* _PPC_KERNEL_MOL */
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/oak_setup.c linux/arch/ppc/kernel/oak_setup.c
--- v2.4.4/linux/arch/ppc/kernel/oak_setup.c	Sun Sep 17 09:48:07 2000
+++ linux/arch/ppc/kernel/oak_setup.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.oak_setup.c 1.5 05/17/01 18:14:21 cort
+ */
+/*
  *
  *    Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/oak_setup.h linux/arch/ppc/kernel/oak_setup.h
--- v2.4.4/linux/arch/ppc/kernel/oak_setup.h	Wed Feb  9 19:43:47 2000
+++ linux/arch/ppc/kernel/oak_setup.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.oak_setup.h 1.5 05/17/01 18:14:21 cort
+ */
+/*
  *
  *    Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/open_pic.c linux/arch/ppc/kernel/open_pic.c
--- v2.4.4/linux/arch/ppc/kernel/open_pic.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/open_pic.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.open_pic.c 1.20 05/17/01 18:14:21 cort
+ */
+/*
  *  arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling
  *
  *  Copyright (C) 1997 Geert Uytterhoeven
@@ -775,11 +778,17 @@
 int
 openpic_get_irq(struct pt_regs *regs)
 {
+/*
+ * Clean up needed. -VAL
+ */
+#ifndef CONFIG_GEMINI
 	extern int i8259_irq(int cpu);
-
+#endif
 	int irq = openpic_irq();
 
 	/* Management of the cascade should be moved out of here */
+
+	/* Yep - because openpic !=> i8259, for one thing. -VAL */
         if (open_pic_irq_offset && irq == open_pic_irq_offset)
         {
                 /*
@@ -787,8 +796,10 @@
                  */
 		if ( chrp_int_ack_special )
 			irq = *chrp_int_ack_special;
+#ifndef CONFIG_GEMINI
 		else
 			irq = i8259_irq( smp_processor_id() );
+#endif
 		openpic_eoi();
         }
 	if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset) {
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/open_pic.h linux/arch/ppc/kernel/open_pic.h
--- v2.4.4/linux/arch/ppc/kernel/open_pic.h	Wed Jan 24 15:28:36 2001
+++ linux/arch/ppc/kernel/open_pic.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.open_pic.h 1.8 05/17/01 18:14:21 cort
+ */
+/*
  *  arch/ppc/kernel/open_pic.h -- OpenPIC Interrupt Handling
  *
  *  Copyright (C) 1997 Geert Uytterhoeven
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/open_pic_defs.h linux/arch/ppc/kernel/open_pic_defs.h
--- v2.4.4/linux/arch/ppc/kernel/open_pic_defs.h	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/open_pic_defs.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.open_pic_defs.h 1.7 05/17/01 18:14:21 cort
+ */
+/*
  *  linux/openpic.h -- OpenPIC definitions
  *
  *  Copyright (C) 1997 Geert Uytterhoeven
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/pci-dma.c linux/arch/ppc/kernel/pci-dma.c
--- v2.4.4/linux/arch/ppc/kernel/pci-dma.c	Mon Feb 14 15:34:21 2000
+++ linux/arch/ppc/kernel/pci-dma.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.pci-dma.c 1.5 05/17/01 18:14:21 cort
+ */
+/*
  * Copyright (C) 2000   Ani Joshi <ajoshi@unixbox.com>
  *
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/pci.c linux/arch/ppc/kernel/pci.c
--- v2.4.4/linux/arch/ppc/kernel/pci.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/pci.c	Mon May 21 17:04:47 2001
@@ -1,5 +1,7 @@
 /*
- * $Id: pci.c,v 1.64 1999/09/17 18:01:53 cort Exp $
+ * BK Id: SCCS/s.pci.c 1.21 05/21/01 01:31:30 cort
+ */
+/*
  * Common pmac/prep/chrp pci routines. -- Cort
  */
 
@@ -385,6 +387,8 @@
 	return 0;
 }
 
+static int next_controller_index;
+
 struct pci_controller * __init
 pcibios_alloc_controller(void)
 {
@@ -396,9 +400,15 @@
 	*hose_tail = hose;
 	hose_tail = &hose->next;
 
+	hose->index = next_controller_index++;
+
 	return hose;
 }
 
+#ifdef CONFIG_ALL_PPC
+/*
+ * Functions below are used on OpenFirmware machines.
+ */
 static void
 make_one_node_map(struct device_node* node, u8 pci_bus)
 {
@@ -579,6 +589,95 @@
 }
 
 void __init
+pci_process_bridge_OF_ranges(struct pci_controller *hose,
+			   struct device_node *dev, int primary)
+{
+	unsigned int *ranges, *prev;
+	int rlen = 0;
+	int memno = 0;
+	struct resource *res;
+	int np, na = prom_n_addr_cells(dev);
+	np = na + 5;
+
+	/* First we try to merge ranges to fix a problem with some pmacs
+	 * that can have more than 3 ranges, fortunately using contiguous
+	 * addresses -- BenH
+	 */
+	ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
+	prev = NULL;
+	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
+		if (prev) {
+			if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
+				(prev[2] + prev[na+4]) == ranges[2] &&
+				(prev[na+2] + prev[na+4]) == ranges[na+2]) {
+				prev[na+4] += ranges[na+4];
+				ranges[0] = 0;
+				ranges += np;
+				continue;
+			}
+		}
+		prev = ranges;
+		ranges += np;
+	}
+
+	/*
+	 * The ranges property is laid out as an array of elements,
+	 * each of which comprises:
+	 *   cells 0 - 2:	a PCI address
+	 *   cells 3 or 3+4:	a CPU physical address
+	 *			(size depending on dev->n_addr_cells)
+	 *   cells 4+5 or 5+6:	the size of the range
+	 */
+	rlen = 0;
+	hose->io_base_phys = 0;
+	ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
+	while ((rlen -= np * sizeof(unsigned int)) >= 0) {
+		res = NULL;
+		switch (ranges[0] >> 24) {
+		case 1:		/* I/O space */
+			if (ranges[2] != 0)
+				break;
+			hose->io_base_phys = ranges[na+2];
+			hose->io_base_virt = ioremap(ranges[na+2], ranges[na+4]);
+			if (primary)
+				isa_io_base = (unsigned long) hose->io_base_virt;
+			res = &hose->io_resource;
+			res->flags = IORESOURCE_IO;
+			res->start = ranges[2];
+			break;
+		case 2:		/* memory space */
+			memno = 0;
+			if (ranges[1] == 0 && ranges[2] == 0
+			    && ranges[na+4] <= (16 << 20)) {
+				/* 1st 16MB, i.e. ISA memory area */
+				if (primary)
+					isa_mem_base = ranges[na+2];
+				memno = 1;
+			}
+			while (memno < 3 && hose->mem_resources[memno].flags)
+				++memno;
+			if (memno == 0)
+				hose->pci_mem_offset = ranges[na+2] - ranges[2];
+			if (memno < 3) {
+				res = &hose->mem_resources[memno];
+				res->flags = IORESOURCE_MEM;
+				res->start = ranges[na+2];
+			}
+			break;
+		}
+		if (res != NULL) {
+			res->name = dev->full_name;
+			res->end = res->start + ranges[na+4] - 1;
+			res->parent = NULL;
+			res->sibling = NULL;
+			res->child = NULL;
+		}
+		ranges += np;
+	}
+}
+#endif /* CONFIG_ALL_PPC */
+
+void __init
 pcibios_init(void)
 {
 	struct pci_controller *hose;
@@ -632,9 +731,6 @@
 	/* OF fails to initialize IDE controllers on macs
 	 * (and maybe other machines)
 	 * 
-	 * This late fixup is done here since I want it to happen after
-	 * resource assignement, and there's no "late-init" arch hook
-	 * 
 	 * Ideally, this should be moved to the IDE layer, but we need
 	 * to check specifically with Andre Hedrick how to do it cleanly
 	 * since the common IDE code seem to care about the fact that the
@@ -651,6 +747,9 @@
 		}
 	}
 #endif /* CONFIG_BLK_DEV_IDE */
+
+	if (ppc_md.pcibios_after_init)
+		ppc_md.pcibios_after_init();
 }
 
 int __init
@@ -802,6 +901,143 @@
 	/* We may want to do something with IOs here... */
 	return res->start;
 #endif	
+}
+
+/*
+ * Return the index of the PCI controller for device pdev.
+ */
+int pci_controller_num(struct pci_dev *dev)
+{
+	struct pci_controller *hose = (struct pci_controller *) dev->sysdata;
+
+	return hose->index;
+}
+
+/*
+ * Platform support for /proc/bus/pci/X/Y mmap()s,
+ * modelled on the sparc64 implementation by Dave Miller.
+ *  -- paulus.
+ */
+
+/*
+ * Adjust vm_pgoff of VMA such that it is the physical page offset
+ * corresponding to the 32-bit pci bus offset for DEV requested by the user.
+ *
+ * Basically, the user finds the base address for his device which he wishes
+ * to mmap.  They read the 32-bit value from the config space base register,
+ * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
+ * offset parameter of mmap on /proc/bus/pci/XXX for that device.
+ *
+ * Returns negative error code on failure, zero on success.
+ */
+static __inline__ int
+__pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma,
+		       enum pci_mmap_state mmap_state)
+{
+	struct pci_controller *hose = (struct pci_controller *) dev->sysdata;
+	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+	unsigned long io_offset = 0;
+	int i, res_bit;
+
+	if (hose == 0)
+		return -EINVAL;		/* should never happen */
+
+	/* If memory, add on the PCI bridge address offset */
+	if (mmap_state == pci_mmap_mem) {
+		offset += hose->pci_mem_offset;
+		res_bit = IORESOURCE_MEM;
+	} else {
+		io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
+		offset += io_offset;
+		res_bit = IORESOURCE_IO;
+	}
+
+	/*
+	 * Check that the offset requested corresponds to one of the
+	 * resources of the device.
+	 */
+	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+		struct resource *rp = &dev->resource[i];
+		int flags = rp->flags;
+
+		/* treat ROM as memory (should be already) */
+		if (i == PCI_ROM_RESOURCE)
+			flags |= IORESOURCE_MEM;
+
+		/* Active and same type? */
+		if ((flags & res_bit) == 0)
+			continue;
+
+		/* In the range of this resource? */
+		if (offset < (rp->start & PAGE_MASK) || offset > rp->end)
+			continue;
+
+		/* found it! construct the final physical address */
+		if (mmap_state == pci_mmap_io)
+			offset += hose->io_base_phys - io_offset;
+
+		vma->vm_pgoff = offset >> PAGE_SHIFT;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+/*
+ * Set vm_flags of VMA, as appropriate for this architecture, for a pci device
+ * mapping.
+ */
+static __inline__ void
+__pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma,
+		     enum pci_mmap_state mmap_state)
+{
+	vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO;
+}
+
+/*
+ * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
+ * device mapping.
+ */
+static __inline__ void
+__pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma,
+		      enum pci_mmap_state mmap_state, int write_combine)
+{
+	int prot = pgprot_val(vma->vm_page_prot);
+
+	/* XXX would be nice to have a way to ask for write-through */
+	prot |= _PAGE_NO_CACHE;
+	if (!write_combine)
+		prot |= _PAGE_GUARDED;
+	vma->vm_page_prot = __pgprot(prot);
+}
+
+/*
+ * Perform the actual remap of the pages for a PCI device mapping, as
+ * appropriate for this architecture.  The region in the process to map
+ * is described by vm_start and vm_end members of VMA, the base physical
+ * address is found in vm_pgoff.
+ * The pci device structure is provided so that architectures may make mapping
+ * decisions on a per-device or per-bus basis.
+ *
+ * Returns a negative error code on failure, zero on success.
+ */
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state,
+			int write_combine)
+{
+	int ret;
+
+	ret = __pci_mmap_make_offset(dev, vma, mmap_state);
+	if (ret < 0)
+		return ret;
+
+	__pci_mmap_set_flags(dev, vma, mmap_state);
+	__pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine);
+
+	ret = remap_page_range(vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
+			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
+
+	return ret;
 }
 
 /* Obsolete functions. Should be removed once the symbios driver
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/pci.h linux/arch/ppc/kernel/pci.h
--- v2.4.4/linux/arch/ppc/kernel/pci.h	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/pci.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.pci.h 1.7 05/17/01 18:14:21 cort
+ */
 
 #ifndef __PPC_KERNEL_PCI_H__
 #define __PPC_KERNEL_PCI_H__
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/pmac_backlight.c linux/arch/ppc/kernel/pmac_backlight.c
--- v2.4.4/linux/arch/ppc/kernel/pmac_backlight.c	Sun Sep 17 09:48:07 2000
+++ linux/arch/ppc/kernel/pmac_backlight.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.pmac_backlight.c 1.5 05/17/01 18:14:21 cort
+ */
+/*
  * Miscellaneous procedures for dealing with the PowerMac hardware.
  * Contains support for the backlight.
  * 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/pmac_nvram.c linux/arch/ppc/kernel/pmac_nvram.c
--- v2.4.4/linux/arch/ppc/kernel/pmac_nvram.c	Sun Sep 17 09:48:07 2000
+++ linux/arch/ppc/kernel/pmac_nvram.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.pmac_nvram.c 1.5 05/17/01 18:14:21 cort
+ */
+/*
  * Miscellaneous procedures for dealing with the PowerMac hardware.
  */
 #include <linux/config.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/pmac_pci.c linux/arch/ppc/kernel/pmac_pci.c
--- v2.4.4/linux/arch/ppc/kernel/pmac_pci.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/pmac_pci.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.pmac_pci.c 1.14 05/17/01 18:14:21 cort
+ */
+/*
  * Support for PCI bridges found on Power Macintoshes.
  * At present the "bandit" and "chaos" bridges are supported.
  * Fortunately you access configuration space in the same
@@ -24,13 +27,12 @@
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <asm/machdep.h>
+#include <asm/feature.h>
 
 #include "pci.h"
 
 #undef DEBUG
 
-extern void process_bridge_ranges(struct pci_controller *hose,
-				  struct device_node *dev, int primary);
 static void add_bridges(struct device_node *dev);
 
 /* XXX Could be per-controller, but I don't think we risk anything by
@@ -382,17 +384,6 @@
 	hose->ops = &macrisc_pci_ops;
 	hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
 	hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
-#if 0 /* done in process_bridge_ranges now - paulus */
-	hose->io_base_phys = addr->address;
-	/* is 0x10000 enough for io space ? */
-	hose->io_base_virt = (void *)ioremap(addr->address, 0x10000);
-
-	/* XXX This is the bridge with the PCI expansion bus. We route
-	 * legacy IOs to it.
-	 */
-	if (addr->address == 0xf2000000)
-		isa_io_base = (unsigned long)hose->io_base_virt;
-#endif
 	/* We "know" that the bridge at f2000000 has the PCI slots. */
 	return addr->address == 0xf2000000;
 }
@@ -405,10 +396,6 @@
 		ioremap(addr->address + 0x800000, 0x1000);
 	hose->cfg_data = (volatile unsigned char *)
 		ioremap(addr->address + 0xc00000, 0x1000);
-#if 0 /* done in process_bridge_ranges now - paulus */
-	hose->io_base_phys = addr->address;
-	hose->io_base_virt = (void *) ioremap(addr->address, 0x10000);
-#endif
 	init_bandit(hose);
 }
 
@@ -421,23 +408,12 @@
 		ioremap(addr->address + 0x800000, 0x1000);
 	hose->cfg_data = (volatile unsigned char *)
 		ioremap(addr->address + 0xc00000, 0x1000);
-#if 0 /* done in process_bridge_ranges now - paulus */
-	hose->io_base_phys = addr->address;
-	hose->io_base_virt = (void *) ioremap(addr->address, 0x10000);
-#endif
 }
 
 void __init
 setup_grackle(struct pci_controller *hose, unsigned io_space_size)
 {
 	setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
-#if 0 /* done in process_bridge_ranges now - paulus */
-	hose->io_base_phys = 0xfe000000;
-	hose->io_base_virt = (void *) ioremap(0xfe000000, io_space_size);
-	pci_dram_offset = 0;
-	isa_mem_base = 0xfd000000;
-	isa_io_base = (unsigned long) hose->io_base_virt;
-#endif
 	if (machine_is_compatible("AAPL,PowerBook1998"))
 		grackle_set_loop_snoop(hose, 1);
 #if 0	/* Disabled for now, HW problems ??? */
@@ -505,7 +481,7 @@
 		
 		/* Interpret the "ranges" property */
 		/* This also maps the I/O region and sets isa_io/mem_base */
-		process_bridge_ranges(hose, dev, primary);
+		pci_process_bridge_OF_ranges(hose, dev, primary);
 
 		/* Fixup "bus-range" OF property */
 		fixup_bus_range(dev);
@@ -557,19 +533,56 @@
 	pcibios_fixup_OF_interrupts();
 }
 
-/* We don't want to enable USB controllers absent from the OF tree
- * (iBook second controller)
- */
 int
 pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
 {
+	struct device_node* node;
+
+	node = pci_device_to_OF_node(dev);
+
+	/* We don't want to enable USB controllers absent from the OF tree
+	 * (iBook second controller)
+	 */
 	if (dev->vendor == PCI_VENDOR_ID_APPLE
-	    && dev->device == PCI_DEVICE_ID_APPLE_KL_USB) {
-		struct device_node* node;
-		node = pci_device_to_OF_node(dev);
-		if (!node)
-			return -EINVAL;
+	    && dev->device == PCI_DEVICE_ID_APPLE_KL_USB && !node)
+		return -EINVAL;
+		
+	/* Firewire was disabled after PCI probe, the driver is claiming it,
+	 * so we must re-enable it now, at least until the driver can do it
+	 * itself.
+	 */
+	if (node && !strcmp(node->name, "firewire") && 
+	    device_is_compatible(node, "pci106b,18")) {
+		feature_set_firewire_cable_power(node, 1);
+		feature_set_firewire_power(node, 1);
 	}
+	
 	return 0;
+}
+
+/* We power down some devices after they have been probed. They'll
+ * be powered back on later on
+ */
+void
+pmac_pcibios_after_init(void)
+{
+	struct device_node* nd;
+
+	nd = find_devices("firewire");
+	while (nd) {
+		if (nd->parent && device_is_compatible(nd, "pci106b,18")
+		    && device_is_compatible(nd->parent, "uni-north")) {
+			feature_set_firewire_power(nd, 0);
+			feature_set_firewire_cable_power(nd, 0);
+		}
+		nd = nd->next;
+	}
+	nd = find_devices("ethernet");
+	while (nd) {
+		if (nd->parent && device_is_compatible(nd, "gmac")
+		    && device_is_compatible(nd->parent, "uni-north"))
+			feature_set_gmac_power(nd, 0);
+		nd = nd->next;
+	}
 }
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/pmac_pic.c linux/arch/ppc/kernel/pmac_pic.c
--- v2.4.4/linux/arch/ppc/kernel/pmac_pic.c	Fri Feb 16 16:02:34 2001
+++ linux/arch/ppc/kernel/pmac_pic.c	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.pmac_pic.c 1.14 05/17/01 18:14:21 cort
+ */
 #include <linux/config.h>
 #include <linux/stddef.h>
 #include <linux/init.h>
@@ -10,6 +13,7 @@
 #include <asm/smp.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
+#include <asm/time.h>
 
 #include "pmac_pic.h"
 #include "open_pic.h"
@@ -44,10 +48,12 @@
  * since it can lose interrupts (see pmac_set_irq_mask).
  * -- Cort
  */
-void __pmac __no_use_set_lost(unsigned long irq_nr)
+void __pmac __set_lost(unsigned long irq_nr)
 {
-	if (!test_and_set_bit(irq_nr, ppc_lost_interrupts))
+	if (!test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
 		atomic_inc(&ppc_n_lost_interrupts);
+		set_dec(1);
+	}
 }
 
 static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr)
@@ -373,7 +379,6 @@
 		irqctrler = NULL;
 	}
 
-	int_control.int_set_lost = __no_use_set_lost;
 	/*
 	 * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,
 	 * 1998 G3 Series PowerBooks have 128, 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/pmac_pic.h linux/arch/ppc/kernel/pmac_pic.h
--- v2.4.4/linux/arch/ppc/kernel/pmac_pic.h	Thu Oct  7 10:17:08 1999
+++ linux/arch/ppc/kernel/pmac_pic.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.pmac_pic.h 1.5 05/17/01 18:14:21 cort
+ */
 #ifndef _PPC_KERNEL_PMAC_PIC_H
 #define _PPC_KERNEL_PMAC_PIC_H
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c
--- v2.4.4/linux/arch/ppc/kernel/pmac_setup.c	Tue Mar  6 19:28:35 2001
+++ linux/arch/ppc/kernel/pmac_setup.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.pmac_setup.c 1.21 05/17/01 18:14:21 cort
+ */
+/*
  *  linux/arch/ppc/kernel/setup.c
  *
  *  PowerPC version 
@@ -66,6 +69,7 @@
 #include <asm/time.h>
 #include "local_irq.h"
 #include "pmac_pic.h"
+#include "../mm/mem_pieces.h"
 
 #undef SHOW_GATWICK_IRQS
 
@@ -102,6 +106,9 @@
 extern void pmac_nvram_update(void);
 
 extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial);
+extern void pmac_pcibios_after_init(void);
+
+struct device_node *memory_node;
 
 unsigned char drive_info;
 
@@ -470,7 +477,7 @@
 	char *p;
 
 	/* Do nothing if the root has been set already. */
-	if ((goodness < current_root_goodness) &&
+	if ((goodness <= current_root_goodness) &&
 		(ROOT_DEV != to_kdev_t(DEFAULT_ROOT_DEVICE)))
 		return;
 	p = strstr(saved_command_line, "root=");
@@ -635,6 +642,88 @@
 #endif
 #endif
 
+/*
+ * Read in a property describing some pieces of memory.
+ */
+
+static void __init get_mem_prop(char *name, struct mem_pieces *mp)
+{
+	struct reg_property *rp;
+	int i, s;
+	unsigned int *ip;
+	int nac = prom_n_addr_cells(memory_node);
+	int nsc = prom_n_size_cells(memory_node);
+
+	ip = (unsigned int *) get_property(memory_node, name, &s);
+	if (ip == NULL) {
+		printk(KERN_ERR "error: couldn't get %s property on /memory\n",
+		       name);
+		abort();
+	}
+	s /= (nsc + nac) * 4;
+	rp = mp->regions;
+	for (i = 0; i < s; ++i, ip += nac+nsc) {
+		if (nac >= 2 && ip[nac-2] != 0)
+			continue;
+		rp->address = ip[nac-1];
+		if (nsc >= 2 && ip[nac+nsc-2] != 0)
+			rp->size = ~0U;
+		else
+			rp->size = ip[nac+nsc-1];
+		++rp;
+	}
+	mp->n_regions = rp - mp->regions;
+
+	/* Make sure the pieces are sorted. */
+	mem_pieces_sort(mp);
+	mem_pieces_coalesce(mp);
+}
+
+/*
+ * On systems with Open Firmware, collect information about
+ * physical RAM and which pieces are already in use.
+ * At this point, we have (at least) the first 8MB mapped with a BAT.
+ * Our text, data, bss use something over 1MB, starting at 0.
+ * Open Firmware may be using 1MB at the 4MB point.
+ */
+unsigned long __init pmac_find_end_of_memory(void)
+{
+	unsigned long a, total;
+	struct mem_pieces phys_mem;
+
+	memory_node = find_devices("memory");
+	if (memory_node == NULL) {
+		printk(KERN_ERR "can't find memory node\n");
+		abort();
+	}
+
+	/*
+	 * Find out where physical memory is, and check that it
+	 * starts at 0 and is contiguous.  It seems that RAM is
+	 * always physically contiguous on Power Macintoshes.
+	 *
+	 * Supporting discontiguous physical memory isn't hard,
+	 * it just makes the virtual <-> physical mapping functions
+	 * more complicated (or else you end up wasting space
+	 * in mem_map).
+	 */
+	get_mem_prop("reg", &phys_mem);
+	if (phys_mem.n_regions == 0)
+		panic("No RAM??");
+	a = phys_mem.regions[0].address;
+	if (a != 0)
+		panic("RAM doesn't start at physical address 0");
+	total = phys_mem.regions[0].size;
+
+	if (phys_mem.n_regions > 1) {
+		printk("RAM starting at 0x%x is not contiguous\n",
+		       phys_mem.regions[1].address);
+		printk("Using RAM from 0 to 0x%lx\n", total-1);
+	}
+
+	return total;
+}
+
 void __init
 pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
 	  unsigned long r6, unsigned long r7)
@@ -656,6 +745,7 @@
 	
 	ppc_md.pcibios_fixup  = pmac_pcibios_fixup;
 	ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook;
+	ppc_md.pcibios_after_init = pmac_pcibios_after_init;
 
 	ppc_md.restart        = pmac_restart;
 	ppc_md.power_off      = pmac_power_off;
@@ -665,6 +755,8 @@
 	ppc_md.set_rtc_time   = pmac_set_rtc_time;
 	ppc_md.get_rtc_time   = pmac_get_rtc_time;
 	ppc_md.calibrate_decr = pmac_calibrate_decr;
+
+	ppc_md.find_end_of_memory = pmac_find_end_of_memory;
 
 #ifdef CONFIG_VT
 #ifdef CONFIG_INPUT
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/pmac_time.c linux/arch/ppc/kernel/pmac_time.c
--- v2.4.4/linux/arch/ppc/kernel/pmac_time.c	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/pmac_time.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.pmac_time.c 1.8 05/17/01 18:14:21 cort
+ */
+/*
  * Support for periodic interrupts (100 per second) and for getting
  * the current time from the RTC on Power Macintoshes.
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/ppc-stub.c linux/arch/ppc/kernel/ppc-stub.c
--- v2.4.4/linux/arch/ppc/kernel/ppc-stub.c	Sun Oct  1 20:35:15 2000
+++ linux/arch/ppc/kernel/ppc-stub.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
-/* $Id: ppc-stub.c,v 1.6 1999/08/12 22:18:11 cort Exp $
+/*
+ * BK Id: SCCS/s.ppc-stub.c 1.6 05/17/01 18:14:21 cort
+ */
+/*
  * ppc-stub.c:  KGDB support for the Linux kernel.
  *
  * adapted from arch/sparc/kernel/sparc-stub.c for the PowerPC
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/ppc4xx_pic.c linux/arch/ppc/kernel/ppc4xx_pic.c
--- v2.4.4/linux/arch/ppc/kernel/ppc4xx_pic.c	Tue Jan 11 21:49:26 2000
+++ linux/arch/ppc/kernel/ppc4xx_pic.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.ppc4xx_pic.c 1.5 05/17/01 18:14:21 cort
+ */
+/*
  *
  *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/ppc4xx_pic.h linux/arch/ppc/kernel/ppc4xx_pic.h
--- v2.4.4/linux/arch/ppc/kernel/ppc4xx_pic.h	Mon Jan 10 18:25:32 2000
+++ linux/arch/ppc/kernel/ppc4xx_pic.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.ppc4xx_pic.h 1.5 05/17/01 18:14:21 cort
+ */
+/*
  *
  *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/ppc8260_pic.c linux/arch/ppc/kernel/ppc8260_pic.c
--- v2.4.4/linux/arch/ppc/kernel/ppc8260_pic.c	Sat Nov 11 18:14:38 2000
+++ linux/arch/ppc/kernel/ppc8260_pic.c	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.ppc8260_pic.c 1.5 05/17/01 18:14:21 cort
+ */
 
 #include <linux/stddef.h>
 #include <linux/init.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/ppc8260_pic.h linux/arch/ppc/kernel/ppc8260_pic.h
--- v2.4.4/linux/arch/ppc/kernel/ppc8260_pic.h	Tue May  2 13:05:40 2000
+++ linux/arch/ppc/kernel/ppc8260_pic.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.ppc8260_pic.h 1.7 05/17/01 18:14:21 cort
+ */
 
 #ifndef _PPC_KERNEL_PPC8260_H
 #define _PPC_KERNEL_PPC8260_H
@@ -8,8 +11,7 @@
 
 void m8260_pic_init(void);
 void m8260_do_IRQ(struct pt_regs *regs,
-                 int            cpu,
-                 int            isfake);
+                 int            cpu);
 int m8260_get_irq(struct pt_regs *regs);
 
 #endif /* _PPC_KERNEL_PPC8260_H */
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/ppc8xx_pic.c linux/arch/ppc/kernel/ppc8xx_pic.c
--- v2.4.4/linux/arch/ppc/kernel/ppc8xx_pic.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/ppc8xx_pic.c	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.ppc8xx_pic.c 1.10 05/17/01 18:14:21 cort
+ */
 #include <linux/config.h>
 #include <linux/stddef.h>
 #include <linux/init.h>
@@ -67,8 +70,7 @@
 #if 0
 void
 m8xx_do_IRQ(struct pt_regs *regs,
-	   int            cpu,
-           int            isfake)
+	   int            cpu)
 {
 	int irq;
         unsigned long bits = 0;
@@ -158,13 +160,15 @@
 	 */
 	switch (irq) {
 #ifdef	IDE0_INTERRUPT
-	case IDE0_INTERRUPT:		/* fall through */
+		case IDE0_INTERRUPT:	/* IDE0 */
+			return (request_8xxirq(irq, handler, irqflags, devname,
+						dev_id));
 #endif
 #ifdef	IDE1_INTERRUPT
-	case IDE1_INTERRUPT:		/* fall through */
+		case IDE1_INTERRUPT:	/* IDE1 */
+			return (request_8xxirq(irq, handler, irqflags, devname,
+						dev_id));
 #endif
-		return (request_8xxirq(irq, handler, irqflags, devname, dev_id));
-	
 	default:			/* unknown IRQ -> panic */
 		panic("request_irq");
 	}
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/ppc8xx_pic.h linux/arch/ppc/kernel/ppc8xx_pic.h
--- v2.4.4/linux/arch/ppc/kernel/ppc8xx_pic.h	Fri Nov 12 04:29:47 1999
+++ linux/arch/ppc/kernel/ppc8xx_pic.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.ppc8xx_pic.h 1.7 05/17/01 18:14:21 cort
+ */
 #ifndef _PPC_KERNEL_PPC8xx_H
 #define _PPC_KERNEL_PPC8xx_H
 
@@ -8,8 +11,7 @@
 
 void m8xx_pic_init(void);
 void m8xx_do_IRQ(struct pt_regs *regs,
-                 int            cpu,
-                 int            isfake);
+                 int            cpu);
 int m8xx_get_irq(struct pt_regs *regs);
 
 #ifdef CONFIG_MBX
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/ppc_asm.h linux/arch/ppc/kernel/ppc_asm.h
--- v2.4.4/linux/arch/ppc/kernel/ppc_asm.h	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/ppc_asm.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.ppc_asm.h 1.10 05/17/01 18:14:21 cort
+ */
+/*
  * arch/ppc/kernel/ppc_asm.h
  *
  * Definitions used by various bits of low-level assembly code on PowerPC.
@@ -130,3 +133,22 @@
 #define MTMSRD(r)	mtmsr	r
 #define CLR_TOP32(r)
 #endif /* CONFIG_PPC64BRIDGE */
+
+/*
+ * Defines for cache-line size etc.
+ */
+#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
+#define CACHE_LINE_SIZE		16
+#define LG_CACHE_LINE_SIZE	4
+#define MAX_COPY_PREFETCH	1
+
+#elif !defined(CONFIG_PPC64BRIDGE)
+#define CACHE_LINE_SIZE		32
+#define LG_CACHE_LINE_SIZE	5
+#define MAX_COPY_PREFETCH	4
+
+#else
+#define CACHE_LINE_SIZE		128
+#define LG_CACHE_LINE_SIZE	7
+#define MAX_COPY_PREFETCH	1
+#endif /* CONFIG_4xx || CONFIG_8xx */
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/ppc_htab.c linux/arch/ppc/kernel/ppc_htab.c
--- v2.4.4/linux/arch/ppc/kernel/ppc_htab.c	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/ppc_htab.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,7 @@
 /*
- * $Id: ppc_htab.c,v 1.29 1999/09/10 05:05:50 paulus Exp $
- *
+ * BK Id: SCCS/s.ppc_htab.c 1.8 05/17/01 18:14:21 cort
+ */
+/*
  * PowerPC hash table management proc entry.  Will show information
  * about the current hash table and will allow changes to it.
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c
--- v2.4.4/linux/arch/ppc/kernel/ppc_ksyms.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/ppc_ksyms.c	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.ppc_ksyms.c 1.31 05/18/01 08:18:10 patch
+ */
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/threads.h>
@@ -55,12 +58,11 @@
 
 extern void transfer_to_handler(void);
 extern void syscall_trace(void);
-extern void do_IRQ(struct pt_regs *regs, int isfake);
+extern void do_IRQ(struct pt_regs *regs);
 extern void MachineCheckException(struct pt_regs *regs);
 extern void AlignmentException(struct pt_regs *regs);
 extern void ProgramCheckException(struct pt_regs *regs);
 extern void SingleStepException(struct pt_regs *regs);
-extern void do_lost_interrupts(unsigned long);
 extern int do_signal(sigset_t *, struct pt_regs *);
 extern int pmac_newworld;
 extern int sys_sigreturn(struct pt_regs *regs);
@@ -83,7 +85,6 @@
 EXPORT_SYMBOL(sys_sigreturn);
 EXPORT_SYMBOL(ppc_n_lost_interrupts);
 EXPORT_SYMBOL(ppc_lost_interrupts);
-EXPORT_SYMBOL(do_lost_interrupts);
 EXPORT_SYMBOL(enable_irq);
 EXPORT_SYMBOL(disable_irq);
 EXPORT_SYMBOL(disable_irq_nosync);
@@ -92,20 +93,13 @@
 EXPORT_SYMBOL(kernel_flag);
 #endif /* CONFIG_SMP */
 
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
-EXPORT_SYMBOL_NOVERS(isa_io_base);
-EXPORT_SYMBOL_NOVERS(isa_mem_base);
-EXPORT_SYMBOL_NOVERS(pci_dram_offset);
-#endif
 EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
 EXPORT_SYMBOL_NOVERS(DMA_MODE_READ);
 EXPORT_SYMBOL(DMA_MODE_WRITE);
-#ifndef CONFIG_8xx
 #if defined(CONFIG_ALL_PPC)
 EXPORT_SYMBOL(_prep_type);
 EXPORT_SYMBOL(ucSystemType);
 #endif
-#endif
 
 #if !__INLINE_BITOPS
 EXPORT_SYMBOL(set_bit);
@@ -175,6 +169,9 @@
 #endif
 
 #ifdef CONFIG_PCI
+EXPORT_SYMBOL_NOVERS(isa_io_base);
+EXPORT_SYMBOL_NOVERS(isa_mem_base);
+EXPORT_SYMBOL_NOVERS(pci_dram_offset);
 EXPORT_SYMBOL(pci_alloc_consistent);
 EXPORT_SYMBOL(pci_free_consistent);
 #endif /* CONFIG_PCI */
@@ -216,9 +213,6 @@
 EXPORT_SYMBOL(synchronize_irq);
 #endif
 
-#ifndef CONFIG_MACH_SPECIFIC
-EXPORT_SYMBOL(_machine);
-#endif
 EXPORT_SYMBOL(ppc_md);
 
 #ifdef CONFIG_ADB
@@ -249,10 +243,9 @@
 EXPORT_SYMBOL(set_backlight_enable);
 EXPORT_SYMBOL(register_backlight_controller);
 #endif /* CONFIG_PMAC_BACKLIGHT */
-#ifndef CONFIG_MACH_SPECIFIC
-EXPORT_SYMBOL_NOVERS(have_of);
-#endif /* CONFIG_MACH_SPECIFIC */
 #if defined(CONFIG_ALL_PPC)
+EXPORT_SYMBOL(_machine);
+EXPORT_SYMBOL_NOVERS(have_of);
 EXPORT_SYMBOL_NOVERS(sys_ctrler);
 EXPORT_SYMBOL(find_devices);
 EXPORT_SYMBOL(find_type_devices);
@@ -277,9 +270,11 @@
 EXPORT_SYMBOL(feature_clear);
 EXPORT_SYMBOL(feature_test);
 EXPORT_SYMBOL(feature_set_gmac_power);
-EXPORT_SYMBOL(feature_set_gmac_phy_reset);
+EXPORT_SYMBOL(feature_gmac_phy_reset);
 EXPORT_SYMBOL(feature_set_usb_power);
 EXPORT_SYMBOL(feature_set_firewire_power);
+EXPORT_SYMBOL(feature_set_firewire_cable_power);
+EXPORT_SYMBOL(feature_set_airport_power);
 #endif /* defined(CONFIG_ALL_PPC) */
 #if defined(CONFIG_BOOTX_TEXT)
 EXPORT_SYMBOL(bootx_update_display);
@@ -314,7 +309,14 @@
 #endif
 
 EXPORT_SYMBOL(__delay);
-EXPORT_SYMBOL(int_control);
+EXPORT_SYMBOL(__sti);
+EXPORT_SYMBOL(__sti_end);
+EXPORT_SYMBOL(__cli);
+EXPORT_SYMBOL(__cli_end);
+EXPORT_SYMBOL(__save_flags_ptr);
+EXPORT_SYMBOL(__save_flags_ptr_end);
+EXPORT_SYMBOL(__restore_flags);
+EXPORT_SYMBOL(__restore_flags_end);
 EXPORT_SYMBOL(timer_interrupt_intercept);
 EXPORT_SYMBOL(timer_interrupt);
 EXPORT_SYMBOL(do_IRQ_intercept);
@@ -331,9 +333,6 @@
 EXPORT_SYMBOL(__up);
 EXPORT_SYMBOL(__down);
 EXPORT_SYMBOL(__down_interruptible);
-EXPORT_SYMBOL(__down_trylock);
-EXPORT_SYMBOL(down_read_failed);
-EXPORT_SYMBOL(down_write_failed);
 
 #if defined(CONFIG_KGDB) || defined(CONFIG_XMON)
 extern void (*debugger)(struct pt_regs *regs);
@@ -362,6 +361,8 @@
 EXPORT_SYMBOL(next_mmu_context);
 EXPORT_SYMBOL(set_context);
 EXPORT_SYMBOL(mmu_context_overflow);
+EXPORT_SYMBOL(flush_hash_page); /* For MOL */
+EXPORT_SYMBOL(handle_mm_fault); /* For MOL */
 EXPORT_SYMBOL_NOVERS(disarm_decr);
 #if !defined(CONFIG_8xx) && !defined(CONFIG_4xx)
 extern long *intercept_table;
@@ -369,17 +370,3 @@
 #endif
 extern long *ret_from_intercept;
 EXPORT_SYMBOL(ret_from_intercept);
-
-#ifdef CONFIG_MOL
-extern ulong mol_interface[];
-extern PTE *Hash;
-extern unsigned long Hash_mask;
-extern void (*ret_from_except)(void);
-extern struct task_struct *last_task_used_altivec;
-EXPORT_SYMBOL_NOVERS(mol_interface);
-EXPORT_SYMBOL(Hash);
-EXPORT_SYMBOL(Hash_mask);
-EXPORT_SYMBOL(handle_mm_fault);
-EXPORT_SYMBOL(last_task_used_math);
-EXPORT_SYMBOL(ret_from_except);
-#endif /* CONFIG_MOL */
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/prep_nvram.c linux/arch/ppc/kernel/prep_nvram.c
--- v2.4.4/linux/arch/ppc/kernel/prep_nvram.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/ppc/kernel/prep_nvram.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.prep_nvram.c 1.9 05/17/01 18:14:22 cort
+ */
+/*
  *  linux/arch/ppc/kernel/prep_nvram.c
  *
  *  Copyright (C) 1998  Corey Minyard
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/prep_pci.c linux/arch/ppc/kernel/prep_pci.c
--- v2.4.4/linux/arch/ppc/kernel/prep_pci.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/prep_pci.c	Mon May 21 17:04:47 2001
@@ -1,5 +1,7 @@
 /*
- * $Id: prep_pci.c,v 1.40 1999/09/17 17:23:05 cort Exp $
+ * BK Id: SCCS/s.prep_pci.c 1.18 05/17/01 18:14:22 cort
+ */
+/*
  * PReP pci functions.
  * Originally by Gary Thomas
  * rewritten and updated by Cort Dougan (cort@cs.nmt.edu)
@@ -437,8 +439,8 @@
 
 static char ibm8xx_pci_IRQ_routes[] __prepdata = {
         0,      /* Line 0 - unused */
-        13,     /* Line 1 */
-        10,     /* Line 2 */
+        15,     /* Line 1 */
+        15,     /* Line 2 */
         15,     /* Line 3 */
         15,     /* Line 4 */
 };
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c
--- v2.4.4/linux/arch/ppc/kernel/prep_setup.c	Fri Apr 27 14:10:32 2001
+++ linux/arch/ppc/kernel/prep_setup.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.prep_setup.c 1.20 05/21/01 09:19:50 trini
+ */
+/*
  *  linux/arch/ppc/kernel/setup.c
  *
  *  Copyright (C) 1995  Linus Torvalds
@@ -103,6 +106,17 @@
 extern int probingmem;
 extern unsigned long loops_per_jiffy;
 
+#ifdef CONFIG_BLK_DEV_RAM
+extern int rd_doload;		/* 1 = load ramdisk, 0 = don't load */
+extern int rd_prompt;		/* 1 = prompt for ramdisk, 0 = don't prompt */
+extern int rd_image_start;	/* starting block # of image */
+#endif
+
+#ifdef CONFIG_SOUND_MODULE
+EXPORT_SYMBOL(ppc_cs4232_dma);
+EXPORT_SYMBOL(ppc_cs4232_dma2);
+#endif
+
 int __prep
 prep_get_cpuinfo(char *buffer)
 {
@@ -246,7 +260,16 @@
 	case _PREP_Motorola:
 		/* Enable L2.  Assume we don't need to flush -- Cort*/
 		*(unsigned char *)(0x8000081c) |= 3;
-		ROOT_DEV = to_kdev_t(0x0802); /* sda2 */
+#ifdef CONFIG_BLK_DEV_INITRD
+		if (initrd_start)
+			ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
+		else
+#endif
+#ifdef CONFIG_ROOT_NFS
+			ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs */
+#else
+			ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */
+#endif
 		break;
 	}
 
@@ -313,6 +336,8 @@
 	vgacon_remap_base = 0xf0000000;
 	/*vgacon_remap_base = ioremap(0xc0000000, 0xba000);*/
         conswitchp = &vga_con;
+#elif defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;
 #endif
 }
 
@@ -504,8 +529,8 @@
 	__cli();
 
 	__asm__ __volatile__("\n\
-	mtspr   26, %1  /* SRR0 */
-	mtspr   27, %0  /* SRR1 */
+	mtspr   26, %1  /* SRR0 */	\n\
+	mtspr   27, %0  /* SRR1 */	\n\
 	rfi"
 	:
 	: "r" (defaultmsr), "r" (jumpaddr));
@@ -575,7 +600,7 @@
 
 #if 0
 void __prep
-prep_do_IRQ(struct pt_regs *regs, int cpu, int isfake)
+prep_do_IRQ(struct pt_regs *regs, int cpu)
 {
         int irq;
 
@@ -691,6 +716,35 @@
 }
 #endif
 
+/*
+ * This finds the amount of physical ram and does necessary
+ * setup for prep.  This is pretty architecture specific so
+ * this will likely stay separate from the pmac.
+ * -- Cort
+ */
+unsigned long __init prep_find_end_of_memory(void)
+{
+	unsigned long total;
+#ifdef CONFIG_PREP_RESIDUAL	
+	total = res->TotalMemory;
+#else
+	total = 0;
+#endif	
+
+	if (total == 0 )
+	{
+		/*
+		 * I need a way to probe the amount of memory if the residual
+		 * data doesn't contain it. -- Cort
+		 */
+		printk("Ramsize from residual data was 0 -- Probing for value\n");
+		total = 0x02000000;
+		printk("Ramsize default to be %ldM\n", total>>20);
+	}
+
+	return (total);
+}
+
 unsigned long *MotSave_SmpIar;
 unsigned char *MotSave_CpusState[2];
 
@@ -730,6 +784,14 @@
 	}
 #endif
 
+#ifdef CONFIG_BLK_DEV_INITRD
+	if ( r4 )
+	{
+		initrd_start = r4 + KERNELBASE;
+		initrd_end = r5 + KERNELBASE;
+	}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 	/* Copy cmd_line parameters */
 	if ( r6)
 	{
@@ -750,7 +812,8 @@
 	{
 		if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) )
 			_prep_type = _PREP_IBM;
-		_prep_type = _PREP_Motorola;
+		else
+			_prep_type = _PREP_Motorola;
 	}
 	else /* assume motorola if no residual (netboot?) */
 #endif	  
@@ -784,6 +847,8 @@
 		ppc_md.time_init      = mk48t59_init;
 	}
 
+	ppc_md.find_end_of_memory = prep_find_end_of_memory;
+
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
         ppc_ide_md.insw = prep_ide_insw;
         ppc_ide_md.outsw = prep_ide_outsw;
@@ -810,8 +875,3 @@
 #endif
 #endif
 }
-
-#ifdef CONFIG_SOUND_MODULE
-EXPORT_SYMBOL(ppc_cs4232_dma);
-EXPORT_SYMBOL(ppc_cs4232_dma2);
-#endif
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/prep_time.c linux/arch/ppc/kernel/prep_time.c
--- v2.4.4/linux/arch/ppc/kernel/prep_time.c	Sun Sep 17 09:48:07 2000
+++ linux/arch/ppc/kernel/prep_time.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.prep_time.c 1.7 05/17/01 18:14:22 cort
+ */
+/*
  *  linux/arch/i386/kernel/time.c
  *
  *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
@@ -30,6 +33,8 @@
 
 #include <asm/time.h>
 
+extern spinlock_t rtc_lock;
+
 /*
  * The motorola uses the m48t18 rtc (includes DS1643) whose registers
  * are at a higher end of nvram (1ff8-1fff) than the ibm mc146818
@@ -55,6 +60,7 @@
 	unsigned char save_control, save_freq_select;
 	struct rtc_time tm;
 
+	spin_lock(&rtc_lock);
 	to_tm(nowtime, &tm);
 
 	/* tell the clock it's being set */
@@ -92,6 +98,7 @@
 	 */
 	CMOS_WRITE(save_control,     RTC_CONTROL);
 	CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+	spin_unlock(&rtc_lock);
 
 	return 0;
 }
@@ -149,7 +156,7 @@
 	unsigned char save_control;
 	struct rtc_time tm;
 
-
+	spin_lock(&rtc_lock);
 	to_tm(nowtime, &tm);
 
 	/* tell the clock it's being written */
@@ -175,6 +182,7 @@
 	
 	/* Turn off the write bit. */
 	ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control);
+	spin_unlock(&rtc_lock);
 
 	return 0;
 }
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/proc_rtas.c linux/arch/ppc/kernel/proc_rtas.c
--- v2.4.4/linux/arch/ppc/kernel/proc_rtas.c	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/kernel/proc_rtas.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.proc_rtas.c 1.5 05/17/01 18:14:22 cort
+ */
+/*
  *   arch/ppc/kernel/proc_rtas.c
  *   Copyright (C) 2000 Tilmann Bitterberg
  *   (tilmann@bitterberg.de)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- v2.4.4/linux/arch/ppc/kernel/process.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/ppc/kernel/process.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,7 @@
 /*
- * $Id: process.c,v 1.97 1999/09/14 19:07:42 cort Exp $
- *
+ * BK Id: SCCS/s.process.c 1.15 05/17/01 18:14:22 cort
+ */
+/*
  *  linux/arch/ppc/kernel/process.c
  *
  *  Derived from "arch/i386/kernel/process.c"
@@ -378,45 +379,6 @@
 }
 
 /*
- * XXX ld.so expects the auxiliary table to start on
- * a 16-byte boundary, so we have to find it and
- * move it up. :-(
- */
-static inline void shove_aux_table(unsigned long sp)
-{
-	int argc;
-	char *p;
-	unsigned long e;
-	unsigned long aux_start, offset;
-
-	if (__get_user(argc, (int *)sp))
-		return;
-	sp += sizeof(int) + (argc + 1) * sizeof(char *);
-	/* skip over the environment pointers */
-	do {
-		if (__get_user(p, (char **)sp))
-			return;
-		sp += sizeof(char *);
-	} while (p != NULL);
-	aux_start = sp;
-	/* skip to the end of the auxiliary table */
-	do {
-		if (__get_user(e, (unsigned long *)sp))
-			return;
-		sp += 2 * sizeof(unsigned long);
-	} while (e != AT_NULL);
-	offset = ((aux_start + 15) & ~15) - aux_start;
-	if (offset != 0) {
-		do {
-			sp -= sizeof(unsigned long);
-			if (__get_user(e, (unsigned long *)sp)
-			    || __put_user(e, (unsigned long *)(sp + offset)))
-				return;
-		} while (sp > aux_start);
-	}
-}
-
-/*
  * Set up a thread for executing a new program
  */
 void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
@@ -425,7 +387,6 @@
 	regs->nip = nip;
 	regs->gpr[1] = sp;
 	regs->msr = MSR_USER;
-	shove_aux_table(sp);
 	if (last_task_used_math == current)
 		last_task_used_math = 0;
 	if (last_task_used_altivec == current)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
--- v2.4.4/linux/arch/ppc/kernel/prom.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/prom.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,7 @@
 /*
- * $Id: prom.c,v 1.79 1999/10/08 01:56:32 paulus Exp $
- *
+ * BK Id: SCCS/s.prom.c 1.17 05/17/01 18:14:22 cort
+ */
+/*
  * Procedures for interfacing to the Open Firmware PROM on
  * Power Macintosh computers.
  *
@@ -757,14 +758,9 @@
 		setup_disp_fake_bi(RELOC(prom_disp_node));
 #endif
 
-	/* If pmac, then use quiesce call. We can't rely on prom_version
-	 * since some old iMacs appear to have an incorrect /openprom/model
-	 * entry in the device tree
-	 */
-	if (!chrp) {
-		prom_print(RELOC("Calling quiesce ...\n"));
-		call_prom(RELOC("quiesce"), 0, 0);
-	}
+	/* Use quiesce call to get OF to shut down any devices it's using */
+	prom_print(RELOC("Calling quiesce ...\n"));
+	call_prom(RELOC("quiesce"), 0, 0);
 
 #ifdef CONFIG_BOOTX_TEXT
 	if (!chrp && RELOC(disp_bi)) {
@@ -839,7 +835,7 @@
 	    __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
 	    prom_drawhex(flags);
 	}
-	if (pvr == 8 || pvr == 12) {
+	if (pvr == 8 || pvr == 12 || pvr == 0x800c) {
 	    prom_drawstring(RELOC("\nICTC             : 0x"));
 	    __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
 	    prom_drawhex(flags);
@@ -986,9 +982,11 @@
 			prom_print(RELOC("... failed\n"));
 		} else {
 			prom_print(RELOC("... ok\n"));
-
-			/* Setup a useable color table when the appropriate
-			 * method is available. Should update this to set-colors */
+			/*
+			 * Setup a usable color table when the appropriate
+			 * method is available.
+			 * Should update this to use set-colors.
+			 */
 			for (i = 0; i < 32; i++)
 				if (prom_set_color(ih, i, RELOC(default_colors)[i*3],
 						   RELOC(default_colors)[i*3+1],
@@ -1267,7 +1265,10 @@
 
 	np->name = get_property(np, "name", 0);
 	np->type = get_property(np, "device_type", 0);
-
+#if 0
+	np->n_addr_cells = naddrc;
+	np->n_size_cells = nsizec;
+#endif
 	/* get the device addresses and interrupts */
 	if (ifunc != NULL) {
 		mem_start = ifunc(np, mem_start, naddrc, nsizec);
@@ -1283,6 +1284,16 @@
 	ip = (int *) get_property(np, "#size-cells", 0);
 	if (ip != NULL)
 		nsizec = *ip;
+#if 0
+	if (np->parent == NULL) {
+		/*
+		 * Set the n_addr/size_cells on the root to its
+		 * own values, rather than 0.
+		 */
+		np->n_addr_cells = naddrc;
+		np->n_size_cells = nsizec;
+	}
+#endif	
 
 	/* the f50 sets the name to 'display' and 'compatible' to what we
 	 * expect for the name -- Cort
@@ -1497,6 +1508,34 @@
 	}
 }
 
+int
+prom_n_addr_cells(struct device_node* np)
+{
+	int* ip;
+	do {
+		if (np->parent)
+			np = np->parent;
+		ip = (int *) get_property(np, "#address-cells", 0);
+		if (ip != NULL)
+			return *ip;
+	} while(np->parent);
+	return 0;
+}
+
+int
+prom_n_size_cells(struct device_node* np)
+{
+	int* ip;
+	do {
+		if (np->parent)
+			np = np->parent;
+		ip = (int *) get_property(np, "#size-cells", 0);
+		if (ip != NULL)
+			return *ip;
+	} while(np->parent);
+	return 0;
+}
+
 __init
 static unsigned long
 interpret_pci_props(struct device_node *np, unsigned long mem_start,
@@ -1566,6 +1605,8 @@
 	}
 
 	ip = (int *) get_property(np, "AAPL,interrupts", &l);
+	if (ip == 0 && np->parent)
+		ip = (int *) get_property(np->parent, "AAPL,interrupts", &l);
 	if (ip == 0)
 		ip = (int *) get_property(np, "interrupts", &l);
 	if (ip != 0) {
@@ -1761,7 +1802,7 @@
 		i = 0;
 		adr = (struct address_range *) mem_start;
 		while ((l -= rpsize) >= 0) {
-			adr[i].space = 0;
+			adr[i].space = (naddrc >= 2? rp[naddrc-2]: 0);
 			adr[i].address = rp[naddrc - 1];
 			adr[i].size = rp[naddrc + nsizec - 1];
 			++i;
@@ -1978,12 +2019,13 @@
 {
 	struct property *pp;
 
-	for (pp = np->properties; pp != 0; pp = pp->next)
-		if (strcmp(pp->name, name) == 0) {
+	for (pp = np->properties; pp != 0; pp = pp->next) {
+		if (name && strcmp(pp->name, name) == 0) {
 			if (lenp != 0)
 				*lenp = pp->length;
 			return pp->value;
 		}
+	}
 	return 0;
 }
 
@@ -2161,9 +2203,10 @@
 {
 	if (disp_bi == 0)
 		return;
-	/* check it's the same frame buffer (within 16MB) */
-	if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xff000000)
+	/* check it's the same frame buffer (within 64MB) */
+	if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xfc000000) {
 		return;
+	}
 
 	disp_bi->dispDeviceBase = (__u8 *) phys;
 	disp_bi->dispDeviceRect[0] = 0;
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/ptrace.c linux/arch/ppc/kernel/ptrace.c
--- v2.4.4/linux/arch/ppc/kernel/ptrace.c	Mon Jun 19 17:59:36 2000
+++ linux/arch/ppc/kernel/ptrace.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.ptrace.c 1.5 05/17/01 18:14:22 cort
+ */
+/*
  *  linux/arch/ppc/kernel/ptrace.c
  *
  *  PowerPC version
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/qspan_pci.c linux/arch/ppc/kernel/qspan_pci.c
--- v2.4.4/linux/arch/ppc/kernel/qspan_pci.c	Tue May  2 13:05:40 2000
+++ linux/arch/ppc/kernel/qspan_pci.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.qspan_pci.c 1.5 05/17/01 18:14:22 cort
+ */
+/*
  * QSpan pci routines.
  * Most 8xx boards use the QSpan PCI bridge.  The config address register
  * is located 0x500 from the base of the bridge control/status registers.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/residual.c linux/arch/ppc/kernel/residual.c
--- v2.4.4/linux/arch/ppc/kernel/residual.c	Fri Feb  9 11:29:44 2001
+++ linux/arch/ppc/kernel/residual.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,7 @@
 /*
- * $Id: residual.c,v 1.17 1999/09/27 18:40:23 cort Exp $
- *
+ * BK Id: SCCS/s.residual.c 1.7 05/17/01 18:14:22 cort
+ */
+/*
  * Code to deal with the PReP residual data.
  *
  * Written by: Cort Dougan (cort@cs.nmt.edu)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/semaphore.c linux/arch/ppc/kernel/semaphore.c
--- v2.4.4/linux/arch/ppc/kernel/semaphore.c	Tue Apr 17 17:19:25 2001
+++ linux/arch/ppc/kernel/semaphore.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,7 @@
 /*
- * $Id: semaphore.c,v 1.1 1999/08/31 15:11:44 cort Exp $
- *
+ * BK Id: SCCS/s.semaphore.c 1.12 05/17/01 18:14:22 cort
+ */
+/*
  * PowerPC-specific semaphore code.
  *
  * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu>
@@ -9,131 +10,122 @@
  * 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.
+ *
+ * April 2001 - Reworked by Paul Mackerras <paulus@samba.org>
+ * to eliminate the SMP races in the old version between the updates
+ * of `count' and `waking'.  Now we use negative `count' values to
+ * indicate that some process(es) are waiting for the semaphore.
  */
 
 #include <linux/sched.h>
-
+#include <asm/atomic.h>
 #include <asm/semaphore.h>
-#include <asm/semaphore-helper.h>
 
 /*
- * Semaphores are implemented using a two-way counter:
- * The "count" variable is decremented for each process
- * that tries to sleep, while the "waking" variable is
- * incremented when the "up()" code goes to wake up waiting
- * processes.
- *
- * Notably, the inline "up()" and "down()" functions can
- * efficiently test if they need to do any extra work (up
- * needs to do something only if count was negative before
- * the increment operation.
- *
- * waking_non_zero() (from asm/semaphore.h) must execute
- * atomically.
+ * Atomically update sem->count.
+ * This does the equivalent of the following:
  *
- * When __up() is called, the count was negative before
- * incrementing it, and we need to wake up somebody.
- *
- * This routine adds one to the count of processes that need to
- * wake up and exit.  ALL waiting processes actually wake up but
- * only the one that gets to the "waking" field first will gate
- * through and acquire the semaphore.  The others will go back
- * to sleep.
- *
- * Note that these functions are only called when there is
- * contention on the lock, and as such all this is the
- * "non-critical" part of the whole semaphore business. The
- * critical part is the inline stuff in <asm/semaphore.h>
- * where we want to avoid any extra jumps and calls.
+ *	old_count = sem->count;
+ *	tmp = MAX(old_count, 0) + incr;
+ *	sem->count = tmp;
+ *	return old_count;
  */
+static inline int __sem_update_count(struct semaphore *sem, int incr)
+{
+	int old_count, tmp;
+
+	__asm__ __volatile__("\n"
+"1:	lwarx	%0,0,%3\n"
+"	srawi	%1,%0,31\n"
+"	andc	%1,%0,%1\n"
+"	add	%1,%1,%4\n"
+"	stwcx.	%1,0,%3\n"
+"	bne	1b"
+	: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
+	: "r" (&sem->count), "r" (incr), "m" (sem->count)
+	: "cc");
+
+	return old_count;
+}
+
 void __up(struct semaphore *sem)
 {
-	wake_one_more(sem);
+	/*
+	 * Note that we incremented count in up() before we came here,
+	 * but that was ineffective since the result was <= 0, and
+	 * any negative value of count is equivalent to 0.
+	 * This ends up setting count to 1, unless count is now > 0
+	 * (i.e. because some other cpu has called up() in the meantime),
+	 * in which case we just increment count.
+	 */
+	__sem_update_count(sem, 1);
 	wake_up(&sem->wait);
 }
 
 /*
- * Perform the "down" function.  Return zero for semaphore acquired,
- * return negative for signalled out of the function.
- *
- * If called from __down, the return is ignored and the wait loop is
- * not interruptible.  This means that a task waiting on a semaphore
- * using "down()" cannot be killed until someone does an "up()" on
- * the semaphore.
- *
- * If called from __down_interruptible, the return value gets checked
- * upon return.  If the return value is negative then the task continues
- * with the negative value in the return register (it can be tested by
- * the caller).
- *
- * Either form may be used in conjunction with "up()".
- *
+ * Note that when we come in to __down or __down_interruptible,
+ * we have already decremented count, but that decrement was
+ * ineffective since the result was < 0, and any negative value
+ * of count is equivalent to 0.
+ * Thus it is only when we decrement count from some value > 0
+ * that we have actually got the semaphore.
  */
+void __down(struct semaphore *sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
 
-#define DOWN_VAR				\
-	struct task_struct *tsk = current;	\
-	wait_queue_t wait;			\
-	init_waitqueue_entry(&wait, tsk);
-
-#define DOWN_HEAD(task_state)						\
-									\
-									\
-	tsk->state = (task_state);					\
-	add_wait_queue(&sem->wait, &wait);				\
-									\
-	/*								\
-	 * Ok, we're set up.  sem->count is known to be less than zero	\
-	 * so we must wait.						\
-	 *								\
-	 * We can let go the lock for purposes of waiting.		\
-	 * We re-acquire it after awaking so as to protect		\
-	 * all semaphore operations.					\
-	 *								\
-	 * If "up()" is called before we call waking_non_zero() then	\
-	 * we will catch it right away.  If it is called later then	\
-	 * we will have to go through a wakeup cycle to catch it.	\
-	 *								\
-	 * Multiple waiters contend for the semaphore lock to see	\
-	 * who gets to gate through and who has to wait some more.	\
-	 */								\
-	for (;;) {
-
-#define DOWN_TAIL(task_state)			\
-		tsk->state = (task_state);	\
-	}					\
-	tsk->state = TASK_RUNNING;		\
+	tsk->state = TASK_UNINTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+	smp_wmb();
+
+	/*
+	 * Try to get the semaphore.  If the count is > 0, then we've
+	 * got the semaphore; we decrement count and exit the loop.
+	 * If the count is 0 or negative, we set it to -1, indicating
+	 * that we are asleep, and then sleep.
+	 */
+	while (__sem_update_count(sem, -1) <= 0) {
+		schedule();
+		tsk->state = TASK_UNINTERRUPTIBLE;
+	}
 	remove_wait_queue(&sem->wait, &wait);
+	tsk->state = TASK_RUNNING;
 
-void __down(struct semaphore * sem)
-{
-	DOWN_VAR
-	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
-	if (waking_non_zero(sem))
-		break;
-	schedule();
-	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+	/*
+	 * If there are any more sleepers, wake one of them up so
+	 * that it can either get the semaphore, or set count to -1
+	 * indicating that there are still processes sleeping.
+	 */
+	wake_up(&sem->wait);
 }
 
 int __down_interruptible(struct semaphore * sem)
 {
-	int ret = 0;
-	DOWN_VAR
-	DOWN_HEAD(TASK_INTERRUPTIBLE)
-
-	ret = waking_non_zero_interruptible(sem, tsk);
-	if (ret)
-	{
-		if (ret == 1)
-			/* ret != 0 only if we get interrupted -arca */
-			ret = 0;
-		break;
+	int retval = 0;
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	tsk->state = TASK_INTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+	smp_wmb();
+
+	while (__sem_update_count(sem, -1) <= 0) {
+		if (signal_pending(current)) {
+			/*
+			 * A signal is pending - give up trying.
+			 * Set sem->count to 0 if it is negative,
+			 * since we are no longer sleeping.
+			 */
+			__sem_update_count(sem, 0);
+			retval = -EINTR;
+			break;
+		}
+		schedule();
+		tsk->state = TASK_INTERRUPTIBLE;
 	}
-	schedule();
-	DOWN_TAIL(TASK_INTERRUPTIBLE)
-	return ret;
-}
-
-int __down_trylock(struct semaphore * sem)
-{
-	return waking_non_zero_trylock(sem);
+	tsk->state = TASK_RUNNING;
+	remove_wait_queue(&sem->wait, &wait);
+	wake_up(&sem->wait);
+	return retval;
 }
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- v2.4.4/linux/arch/ppc/kernel/setup.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/setup.c	Mon May 21 17:04:47 2001
@@ -1,5 +1,7 @@
 /*
- * $Id: setup.c,v 1.160 1999/10/08 01:56:38 paulus Exp $
+ * BK Id: SCCS/s.setup.c 1.23 05/21/01 16:08:53 cort
+ */
+/*
  * Common prep/pmac/chrp boot and setup code.
  */
 
@@ -73,6 +75,12 @@
                       unsigned long r6,
                       unsigned long r7);
 
+extern void gemini_init(unsigned long r3,
+                      unsigned long r4,
+                      unsigned long r5,
+                      unsigned long r6,
+                      unsigned long r7);
+
 #ifdef CONFIG_XMON
 extern void xmon_map_scc(void);
 #endif
@@ -80,23 +88,16 @@
 extern boot_infos_t *boot_infos;
 char saved_command_line[256];
 unsigned char aux_device_present;
-struct int_control_struct int_control =
-{
-	__no_use_cli,
-	__no_use_sti,
-	__no_use_restore_flags,
-	__no_use_save_flags
-};
 struct ide_machdep_calls ppc_ide_md;
 int parse_bootinfo(void);
 
 unsigned long ISA_DMA_THRESHOLD;
 unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
 
-#ifndef CONFIG_MACH_SPECIFIC
+#ifdef CONFIG_ALL_PPC
 int _machine = 0;
 int have_of = 0;
-#endif /* CONFIG_MACH_SPECIFIC */
+#endif /* CONFIG_ALL_PPC */
 
 #ifdef CONFIG_MAGIC_SYSRQ
 unsigned long SYSRQ_KEY;
@@ -412,7 +413,7 @@
 	return len;
 }
 
-#ifndef CONFIG_MACH_SPECIFIC
+#ifdef CONFIG_ALL_PPC
 void __init
 intuit_machine_type(void)
 {
@@ -434,7 +435,7 @@
 		}
 	}
 }
-#endif /* CONFIG_MACH_SPECIFIC */
+#endif /* CONFIG_ALL_PPC */
 
 /*
  * Find out what kind of machine we're on and save any data we need
@@ -448,36 +449,26 @@
 
 	if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100);
 	
-#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_8260)
-#ifndef CONFIG_MACH_SPECIFIC
+#ifdef CONFIG_ALL_PPC
 	/* if we didn't get any bootinfo telling us what we are... */
 	if ( _machine == 0 )
 	{
-		/* boot loader will tell us if we're APUS */
-		if ( r3 == 0x61707573 )
-		{
-			_machine = _MACH_apus;
-			r3 = 0;
-		}
 		/* prep boot loader tells us if we're prep or not */
-		else if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
+		if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
 		{
 			_machine = _MACH_prep;
 		} else
 			have_of = 1;
 	}
-#endif /* CONFIG_MACH_SPECIFIC */
 
 	if ( have_of )
 	{
 		/* prom_init has already been called from __start */
 		if (boot_infos)
 			relocate_nodes();
-#ifndef CONFIG_MACH_SPECIFIC
 		/* we need to set _machine before calling finish_device_tree */
 		if (_machine == 0)
 			intuit_machine_type();
-#endif /* CONFIG_MACH_SPECIFIC */
 		finish_device_tree();
 		/*
 		 * If we were booted via quik, r3 points to the physical
@@ -495,7 +486,7 @@
 				sizeof(cmd_line));
 		} else if (boot_infos != 0) {
 			/* booted by BootX - check for ramdisk */
-			if (boot_infos->kernelParamsOffset != 0)
+ 			if (boot_infos->kernelParamsOffset != 0)
 				strncpy(cmd_line, (char *) boot_infos
 					+ boot_infos->kernelParamsOffset,
 					sizeof(cmd_line));
@@ -526,13 +517,17 @@
 			chosen = find_devices("chosen");
 			if (chosen != NULL) {
 				p = get_property(chosen, "bootargs", NULL);
-				if (p != NULL)
+				if (p != NULL) {
+					cmd_line[0] = 0;
 					strncpy(cmd_line, p, sizeof(cmd_line));
+				}
 			}
 		}
 		cmd_line[sizeof(cmd_line) - 1] = 0;
 	}
+#endif /* CONFIG_ALL_PPC */
 
+#if defined(CONFIG_ALL_PPC)
 	switch (_machine)
 	{
 	case _MACH_Pmac:
@@ -544,22 +539,14 @@
 	case _MACH_chrp:
                 chrp_init(r3, r4, r5, r6, r7);
 		break;
-#ifdef CONFIG_APUS
-	case _MACH_apus:
-                apus_init(r3, r4, r5, r6, r7);
-		break;
-#endif
 	default:
 		printk("Unknown machine type in identify_machine!\n");
 	}
-
-	/* Check for nobats option (used in mapin_ram). */
-	if (strstr(cmd_line, "nobats")) {
-		extern int __map_without_bats;
-		__map_without_bats = 1;
-	}
-#else
-#if defined(CONFIG_4xx)
+#elif defined(CONFIG_APUS)
+	apus_init(r3, r4, r5, r6, r7);
+#elif defined(CONFIG_GEMINI)
+	gemini_init(r3, r4, r5, r6, r7);
+#elif defined(CONFIG_4xx)
 	oak_init(r3, r4, r5, r6, r7);
 #elif defined(CONFIG_8xx)
         m8xx_init(r3, r4, r5, r6, r7);
@@ -567,8 +554,15 @@
         m8260_init(r3, r4, r5, r6, r7);
 #else
 #error "No board type has been defined for identify_machine()!"
-#endif /* CONFIG_4xx */
-#endif /* !CONFIG_4xx && !CONFIG_8xx */
+#endif
+
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_8260)
+	/* Check for nobats option (used in mapin_ram). */
+	if (strstr(cmd_line, "nobats")) {
+		extern int __map_without_bats;
+		__map_without_bats = 1;
+	}
+#endif /* !CONFIG_4xx && !CONFIG_8xx && !CONFIG_8260 */
 
 	/* Look for mem= option on command line */
 	if (strstr(cmd_line, "mem=")) {
@@ -639,12 +633,12 @@
 			initrd_end = data[0] + rec->size;
 			break;
 #endif /* CONFIG_BLK_DEV_INITRD */
-#ifndef CONFIG_MACH_SPECIFIC
+#ifdef CONFIG_ALL_PPC
 		case BI_MACHTYPE:
 			_machine = data[0];
 			have_of = data[1];
 			break;
-#endif /* CONFIG_MACH_SPECIFIC */
+#endif /* CONFIG_ALL_PPC */
 		}
 	}
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/signal.c linux/arch/ppc/kernel/signal.c
--- v2.4.4/linux/arch/ppc/kernel/signal.c	Wed Jan 24 15:21:19 2001
+++ linux/arch/ppc/kernel/signal.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.signal.c 1.7 05/17/01 18:14:22 cort
+ */
+/*
  *  linux/arch/ppc/kernel/signal.c
  *
  *  PowerPC version 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/sleep.S linux/arch/ppc/kernel/sleep.S
--- v2.4.4/linux/arch/ppc/kernel/sleep.S	Wed Feb  9 19:43:47 2000
+++ linux/arch/ppc/kernel/sleep.S	Mon May 21 17:04:47 2001
@@ -1,6 +1,9 @@
 /*
+ * BK Id: SCCS/s.sleep.S 1.7 05/17/01 18:14:22 cort
+ */
+/*
  * This file contains sleep low-level functions for PowerBook G3.
- *    Copyright (C) 1999 Benjamin Herrenschmidt (bh40@calva.net)
+ *    Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org)
  *    and Paul Mackerras (paulus@cs.anu.edu.au).
  *
  * This program is free software; you can redistribute it and/or
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
--- v2.4.4/linux/arch/ppc/kernel/smp.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/smp.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.smp.c 1.23 05/17/01 18:14:22 cort
+ */
+/*
  * Smp support for ppc.
  *
  * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great
@@ -40,6 +43,7 @@
 #include <asm/residual.h>
 #include <asm/feature.h>
 #include <asm/time.h>
+#include <asm/gemini.h>
 
 #include "open_pic.h"
 int smp_threads_ready;
@@ -55,7 +59,7 @@
 unsigned int prof_counter[NR_CPUS];
 cycles_t cacheflush_time;
 static int max_cpus __initdata = NR_CPUS;
-
+unsigned long cpu_online_map;
 int smp_hw_index[NR_CPUS];
 
 /* all cpu mappings are 1-1 -- Cort */
@@ -452,32 +456,48 @@
 static void
 smp_core99_kick_cpu(int nr)
 {
-	unsigned long save_int;
+	unsigned long save_vector, new_vector;
 	unsigned long flags;
+#if 1 /* New way... */
+	volatile unsigned long *vector
+		 = ((volatile unsigned long *)(KERNELBASE+0x100));
+	if (nr < 1 || nr > 3)
+		return;
+#else
 	volatile unsigned long *vector
 		 = ((volatile unsigned long *)(KERNELBASE+0x500));
-
 	if (nr != 1)
 		return;
+#endif
 	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346);
 
 	local_irq_save(flags);
 	local_irq_disable();
 	
-	/* Save EE vector */
-	save_int = *vector;
+	/* Save reset vector */
+	save_vector = *vector;
 	
-	/* Setup fake EE vector that does	  
+	/* Setup fake reset vector that does	  
 	 *   b __secondary_start_psurge - KERNELBASE
-	 */   
-	*vector = 0x48000002 +
-		((unsigned long)__secondary_start_psurge - KERNELBASE);
+	 */  
+	switch(nr) {
+		case 1:
+			new_vector = (unsigned long)__secondary_start_psurge;
+			break;
+		case 2:
+			new_vector = (unsigned long)__secondary_start_psurge2;
+			break;
+		case 3:
+			new_vector = (unsigned long)__secondary_start_psurge3;
+			break;
+	}
+	*vector = 0x48000002 + new_vector - KERNELBASE;
 	
 	/* flush data cache and inval instruction cache */
 	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
 	
 	/* Put some life in our friend */
-	feature_core99_kick_cpu1();
+	feature_core99_kick_cpu(nr);
 	
 	/* FIXME: We wait a bit for the CPU to take the exception, I should
 	 * instead wait for the entry code to set something for me. Well,
@@ -487,11 +507,11 @@
 	mdelay(1);
 	
 	/* Restore our exception vector */
-	*vector = save_int;
+	*vector = save_vector;
 	flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
 	
 	local_irq_restore(flags);
-	if (ppc_md.progress) ppc_md.progress("smp_core99_probe done", 0x347);
+	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
 }
 
 static void
@@ -628,6 +648,43 @@
 		do_openpic_setup_cpu();
 }
 
+#ifdef CONFIG_GEMINI	
+static int
+smp_gemini_probe(void)
+{
+	int i, nr;
+
+        nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK) >> 2;
+	if (nr == 0)
+		nr = 4;
+
+	if (nr > 1) {
+		openpic_request_IPIs();
+		for (i = 1; i < nr; ++i)
+			smp_hw_index[i] = i;
+	}
+
+	return nr;
+}
+
+static void
+smp_gemini_kick_cpu(int nr)
+{
+	openpic_init_processor( 1<<i );
+	openpic_init_processor( 0 );
+}
+
+static void
+smp_gemini_setup_cpu(void)
+{
+	if (OpenPIC_Addr)
+		do_openpic_setup_cpu();
+	if (cpu_nr > 0)
+		gemini_init_l2();
+}
+#endif /* CONFIG_GEMINI */
+
+
 static struct smp_ops_t {
 	void  (*message_pass)(int target, int msg, unsigned long data, int wait);
 	int   (*probe)(void);
@@ -685,6 +742,16 @@
 	smp_prep_setup_cpu,
 };
 
+#ifdef CONFIG_GEMINI	
+/* Gemini */
+static struct smp_ops_t gemini_smp_ops = {
+	smp_openpic_message_pass,
+	smp_gemini_probe,
+	smp_gemini_kick_cpu,
+	smp_gemini_setup_cpu,
+};
+#endif /* CONFIG_GEMINI	*/
+
 /* 
  * Common functions
  */
@@ -925,6 +992,11 @@
 	case _MACH_prep:
 		smp_ops = &prep_smp_ops;
 		break;
+#ifdef CONFIG_GEMINI		
+	case _MACH_gemini:
+		smp_ops = &gemini_smp_ops;
+		break;
+#endif /* CONFIG_GEMINI	*/
 	default:
 		printk("SMP not supported on this machine.\n");
 		return;
@@ -946,6 +1018,19 @@
 		/* create a process for the processor */
 		/* we don't care about the values in regs since we'll
 		   never reschedule the forked task. */
+		/* We DO care about one bit in the pt_regs we
+		   pass to do_fork.  That is the MSR_FP bit in 
+		   regs.msr.  If that bit is on, then do_fork
+		   (via copy_thread) will call giveup_fpu.
+		   giveup_fpu will get a pointer to our (current's)
+		   last register savearea via current->thread.regs 
+		   and using that pointer will turn off the MSR_FP,
+		   MSR_FE0 and MSR_FE1 bits.  At this point, this 
+		   pointer is pointing to some arbitrary point within
+		   our stack. */
+
+		memset(&regs, 0, sizeof(struct pt_regs));
+		
 		if (do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0) < 0)
 			panic("failed fork for CPU %d", i);
 		p = init_task.prev_task;
@@ -1114,8 +1199,18 @@
 
 	init_idle();
 
+	/*
+	 * This cpu is now "online".  Only set them online
+	 * before they enter the loop below since write access
+	 * to the below variable is _not_ guaranteed to be
+	 * atomic.
+	 *   -- Cort <cort@fsmlabs.com>
+	 */
+	cpu_online_map |= 1UL << smp_processor_id();
+	
 	while(!smp_commenced)
 		barrier();
+
 	/* see smp_commence for more info */
 	if (!smp_tb_synchronized && smp_num_cpus == 2) {
 		smp_software_tb_sync(cpu);
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/softemu8xx.c linux/arch/ppc/kernel/softemu8xx.c
--- v2.4.4/linux/arch/ppc/kernel/softemu8xx.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/softemu8xx.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.softemu8xx.c 1.8 05/17/01 18:14:22 cort
+ */
+/*
  * Software emulation of some PPC instructions for the 8xx core.
  *
  * Copyright (C) 1998 Dan Malek (dmalek@jlc.net)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/syscalls.c linux/arch/ppc/kernel/syscalls.c
--- v2.4.4/linux/arch/ppc/kernel/syscalls.c	Mon Mar 19 12:35:09 2001
+++ linux/arch/ppc/kernel/syscalls.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.syscalls.c 1.8 05/17/01 18:14:22 cort
+ */
+/*
  * linux/arch/ppc/kernel/sys_ppc.c
  *
  *  PowerPC version 
@@ -185,9 +188,10 @@
 	return error;
 }
 
-unsigned long sys_mmap(unsigned long addr, size_t len,
-		       unsigned long prot, unsigned long flags,
-		       unsigned long fd, off_t offset)
+static inline unsigned long
+do_mmap2(unsigned long addr, size_t len,
+	 unsigned long prot, unsigned long flags,
+	 unsigned long fd, unsigned long pgoff)
 {
 	struct file * file = NULL;
 	int ret = -EBADF;
@@ -199,12 +203,33 @@
 	}
 	
 	down_write(&current->mm->mmap_sem);
-	ret = do_mmap(file, addr, len, prot, flags, offset);
+	ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
 	up_write(&current->mm->mmap_sem);
 	if (file)
 		fput(file);
 out:
 	return ret;
+}
+
+unsigned long sys_mmap2(unsigned long addr, size_t len,
+			unsigned long prot, unsigned long flags,
+			unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+unsigned long sys_mmap(unsigned long addr, size_t len,
+		       unsigned long prot, unsigned long flags,
+		       unsigned long fd, off_t offset)
+{
+	int err = -EINVAL;
+
+	if (offset & ~PAGE_MASK)
+		goto out;
+
+	err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+out:
+	return err;
 }
 
 extern int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/time.c linux/arch/ppc/kernel/time.c
--- v2.4.4/linux/arch/ppc/kernel/time.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/time.c	Mon May 21 17:04:47 2001
@@ -1,5 +1,7 @@
 /*
- * $Id: time.c,v 1.57 1999/10/21 03:08:16 cort Exp $
+ * BK Id: SCCS/s.time.c 1.15 05/17/01 18:14:22 cort
+ */
+/*
  * Common time routines among all ppc machines.
  *
  * Written by Cort Dougan (cort@cs.nmt.edu) to merge
@@ -50,6 +52,7 @@
 #include <linux/param.h>
 #include <linux/string.h>
 #include <linux/mm.h>
+#include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/timex.h>
 #include <linux/kernel_stat.h>
@@ -91,6 +94,10 @@
 
 static long time_offset;
 
+spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
+
+EXPORT_SYMBOL(rtc_lock);
+
 /* Timer interrupt helper function */
 static inline int tb_delta(unsigned *jiffy_stamp) {
 	int delta;
@@ -144,14 +151,20 @@
 	int next_dec;
 	unsigned long cpu = smp_processor_id();
 	unsigned jiffy_stamp = last_jiffy_stamp(cpu);
+	extern void do_IRQ(struct pt_regs *);
+
+	if (atomic_read(&ppc_n_lost_interrupts) != 0)
+		do_IRQ(regs);
 
 	hardirq_enter(cpu);
 	
-	if (!user_mode(regs))
-		ppc_do_profile(instruction_pointer(regs));
-	do { 
+	while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0) {
 		jiffy_stamp += tb_ticks_per_jiffy;
-	  	if (smp_processor_id()) continue;
+		if (!user_mode(regs))
+			ppc_do_profile(instruction_pointer(regs));
+	  	if (smp_processor_id())
+			continue;
+
 		/* We are in an interrupt, no need to save/restore flags */
 		write_lock(&xtime_lock);
 		tb_last_stamp = jiffy_stamp;
@@ -184,7 +197,7 @@
 				last_rtc_update += 60;
 		}
 		write_unlock(&xtime_lock);
-	} while((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0);
+	}
 	if ( !disarm_decr[smp_processor_id()] )
 		set_dec(next_dec);
 	last_jiffy_stamp(cpu) = jiffy_stamp;
@@ -337,6 +350,8 @@
         	tz.tz_dsttime = 0;
         	do_sys_settimeofday(NULL, &tz);
         }
+
+       do_get_fast_time = do_gettimeofday;
 }
 
 #define TICK_SIZE tick
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- v2.4.4/linux/arch/ppc/kernel/traps.c	Sat Mar  3 10:52:14 2001
+++ linux/arch/ppc/kernel/traps.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.traps.c 1.11 05/17/01 18:14:22 cort
+ */
+/*
  *  linux/arch/ppc/kernel/traps.c
  *
  *  Copyright (C) 1995-1996  Gary Thomas (gdt@linuxppc.org)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/walnut_setup.c linux/arch/ppc/kernel/walnut_setup.c
--- v2.4.4/linux/arch/ppc/kernel/walnut_setup.c	Sun Sep 17 09:48:07 2000
+++ linux/arch/ppc/kernel/walnut_setup.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.walnut_setup.c 1.5 05/17/01 18:14:22 cort
+ */
+/*
  *
  *    Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/walnut_setup.h linux/arch/ppc/kernel/walnut_setup.h
--- v2.4.4/linux/arch/ppc/kernel/walnut_setup.h	Thu Feb 10 12:37:51 2000
+++ linux/arch/ppc/kernel/walnut_setup.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.walnut_setup.h 1.5 05/17/01 18:14:22 cort
+ */
+/*
  *
  *    Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/xics.c linux/arch/ppc/kernel/xics.c
--- v2.4.4/linux/arch/ppc/kernel/xics.c	Sun Sep 17 09:48:07 2000
+++ linux/arch/ppc/kernel/xics.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.xics.c 1.5 05/17/01 18:14:22 cort
+ */
+/*
  * arch/ppc/kernel/xics.c
  *
  * Copyright 2000 IBM Corporation.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/kernel/xics.h linux/arch/ppc/kernel/xics.h
--- v2.4.4/linux/arch/ppc/kernel/xics.h	Mon Jun 19 17:59:36 2000
+++ linux/arch/ppc/kernel/xics.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.xics.h 1.5 05/17/01 18:14:22 cort
+ */
+/*
  * arch/ppc/kernel/xics.h
  *
  * Copyright 2000 IBM Corporation.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/lib/Makefile linux/arch/ppc/lib/Makefile
--- v2.4.4/linux/arch/ppc/lib/Makefile	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/lib/Makefile	Mon May 21 17:04:47 2001
@@ -1,9 +1,10 @@
+# BK Id: SCCS/s.Makefile 1.7 05/17/01 18:14:22 cort
+#
 #
 # Makefile for ppc-specific library files..
 #
 
-.S.o:
-	$(CC) $(AFLAGS) -c $< -o $*.o
+USE_STANDARD_AS_RULE	:= true
 
 O_TARGET		:= lib.o
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/lib/checksum.S linux/arch/ppc/lib/checksum.S
--- v2.4.4/linux/arch/ppc/lib/checksum.S	Thu Dec  2 14:37:34 1999
+++ linux/arch/ppc/lib/checksum.S	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.checksum.S 1.5 05/17/01 18:14:22 cort
+ */
+/*
  * This file contains assembly-language implementations
  * of IP-style 1's complement checksum routines.
  *	
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/lib/locks.c linux/arch/ppc/lib/locks.c
--- v2.4.4/linux/arch/ppc/lib/locks.c	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/lib/locks.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,7 @@
 /*
- * $Id: locks.c,v 1.25 1999/09/10 10:40:13 davem Exp $
- *
+ * BK Id: SCCS/s.locks.c 1.8 05/17/01 18:14:22 cort
+ */
+/*
  * Locks for smp ppc 
  * 
  * Written by Cort Dougan (cort@cs.nmt.edu)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/lib/strcase.c linux/arch/ppc/lib/strcase.c
--- v2.4.4/linux/arch/ppc/lib/strcase.c	Thu Apr 29 12:39:01 1999
+++ linux/arch/ppc/lib/strcase.c	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.strcase.c 1.5 05/17/01 18:14:22 cort
+ */
 #include <linux/ctype.h>
 
 int strcasecmp(const char *s1, const char *s2)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/lib/string.S linux/arch/ppc/lib/string.S
--- v2.4.4/linux/arch/ppc/lib/string.S	Tue Sep 19 08:31:53 2000
+++ linux/arch/ppc/lib/string.S	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.string.S 1.5 05/17/01 18:14:22 cort
+ */
+/*
  * String handling functions for PowerPC.
  *
  * Copyright (C) 1996 Paul Mackerras.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/Makefile linux/arch/ppc/math-emu/Makefile
--- v2.4.4/linux/arch/ppc/math-emu/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/ppc/math-emu/Makefile	Mon May 21 17:04:47 2001
@@ -1,3 +1,5 @@
+# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:22 cort
+#
 #
 #
 #
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/double.h linux/arch/ppc/math-emu/double.h
--- v2.4.4/linux/arch/ppc/math-emu/double.h	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/double.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.double.h 1.5 05/17/01 18:14:22 cort
+ */
+/*
  * Definitions for IEEE Double Precision
  */
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fabs.c linux/arch/ppc/math-emu/fabs.c
--- v2.4.4/linux/arch/ppc/math-emu/fabs.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fabs.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fabs.c,v 1.1 1999/08/23 18:59:21 cort Exp $
+/*
+ * BK Id: SCCS/s.fabs.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fadd.c linux/arch/ppc/math-emu/fadd.c
--- v2.4.4/linux/arch/ppc/math-emu/fadd.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fadd.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fadd.c,v 1.1 1999/08/23 18:59:22 cort Exp $
+/*
+ * BK Id: SCCS/s.fadd.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fadds.c linux/arch/ppc/math-emu/fadds.c
--- v2.4.4/linux/arch/ppc/math-emu/fadds.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fadds.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fadds.c,v 1.1 1999/08/23 18:59:25 cort Exp $
+/*
+ * BK Id: SCCS/s.fadds.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fcmpo.c linux/arch/ppc/math-emu/fcmpo.c
--- v2.4.4/linux/arch/ppc/math-emu/fcmpo.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fcmpo.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fcmpo.c,v 1.1 1999/08/23 18:59:26 cort Exp $
+/*
+ * BK Id: SCCS/s.fcmpo.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fcmpu.c linux/arch/ppc/math-emu/fcmpu.c
--- v2.4.4/linux/arch/ppc/math-emu/fcmpu.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fcmpu.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fcmpu.c,v 1.1 1999/08/23 18:59:28 cort Exp $
+/*
+ * BK Id: SCCS/s.fcmpu.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fctiw.c linux/arch/ppc/math-emu/fctiw.c
--- v2.4.4/linux/arch/ppc/math-emu/fctiw.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fctiw.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fctiw.c,v 1.1 1999/08/23 18:59:30 cort Exp $
+/*
+ * BK Id: SCCS/s.fctiw.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fctiwz.c linux/arch/ppc/math-emu/fctiwz.c
--- v2.4.4/linux/arch/ppc/math-emu/fctiwz.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fctiwz.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fctiwz.c,v 1.1 1999/08/23 18:59:31 cort Exp $
+/*
+ * BK Id: SCCS/s.fctiwz.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fdiv.c linux/arch/ppc/math-emu/fdiv.c
--- v2.4.4/linux/arch/ppc/math-emu/fdiv.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fdiv.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fdiv.c,v 1.1 1999/08/23 18:59:33 cort Exp $
+/*
+ * BK Id: SCCS/s.fdiv.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fdivs.c linux/arch/ppc/math-emu/fdivs.c
--- v2.4.4/linux/arch/ppc/math-emu/fdivs.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fdivs.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fdivs.c,v 1.1 1999/08/23 18:59:35 cort Exp $
+/*
+ * BK Id: SCCS/s.fdivs.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fmadd.c linux/arch/ppc/math-emu/fmadd.c
--- v2.4.4/linux/arch/ppc/math-emu/fmadd.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fmadd.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fmadd.c,v 1.1 1999/08/23 18:59:36 cort Exp $
+/*
+ * BK Id: SCCS/s.fmadd.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fmadds.c linux/arch/ppc/math-emu/fmadds.c
--- v2.4.4/linux/arch/ppc/math-emu/fmadds.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fmadds.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fmadds.c,v 1.1 1999/08/23 18:59:38 cort Exp $
+/*
+ * BK Id: SCCS/s.fmadds.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fmr.c linux/arch/ppc/math-emu/fmr.c
--- v2.4.4/linux/arch/ppc/math-emu/fmr.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fmr.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fmr.c,v 1.1 1999/08/23 18:59:40 cort Exp $
+/*
+ * BK Id: SCCS/s.fmr.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fmsub.c linux/arch/ppc/math-emu/fmsub.c
--- v2.4.4/linux/arch/ppc/math-emu/fmsub.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fmsub.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fmsub.c,v 1.1 1999/08/23 18:59:41 cort Exp $
+/*
+ * BK Id: SCCS/s.fmsub.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fmsubs.c linux/arch/ppc/math-emu/fmsubs.c
--- v2.4.4/linux/arch/ppc/math-emu/fmsubs.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fmsubs.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fmsubs.c,v 1.1 1999/08/23 18:59:42 cort Exp $
+/*
+ * BK Id: SCCS/s.fmsubs.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fmul.c linux/arch/ppc/math-emu/fmul.c
--- v2.4.4/linux/arch/ppc/math-emu/fmul.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fmul.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fmul.c,v 1.1 1999/08/23 18:59:44 cort Exp $
+/*
+ * BK Id: SCCS/s.fmul.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fmuls.c linux/arch/ppc/math-emu/fmuls.c
--- v2.4.4/linux/arch/ppc/math-emu/fmuls.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fmuls.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fmuls.c,v 1.1 1999/08/23 18:59:45 cort Exp $
+/*
+ * BK Id: SCCS/s.fmuls.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fnabs.c linux/arch/ppc/math-emu/fnabs.c
--- v2.4.4/linux/arch/ppc/math-emu/fnabs.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fnabs.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fnabs.c,v 1.1 1999/08/23 18:59:47 cort Exp $
+/*
+ * BK Id: SCCS/s.fnabs.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fneg.c linux/arch/ppc/math-emu/fneg.c
--- v2.4.4/linux/arch/ppc/math-emu/fneg.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fneg.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fneg.c,v 1.1 1999/08/23 18:59:48 cort Exp $
+/*
+ * BK Id: SCCS/s.fneg.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fnmadd.c linux/arch/ppc/math-emu/fnmadd.c
--- v2.4.4/linux/arch/ppc/math-emu/fnmadd.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fnmadd.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fnmadd.c,v 1.1 1999/08/23 18:59:50 cort Exp $
+/*
+ * BK Id: SCCS/s.fnmadd.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fnmadds.c linux/arch/ppc/math-emu/fnmadds.c
--- v2.4.4/linux/arch/ppc/math-emu/fnmadds.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fnmadds.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fnmadds.c,v 1.1 1999/08/23 18:59:51 cort Exp $
+/*
+ * BK Id: SCCS/s.fnmadds.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fnmsub.c linux/arch/ppc/math-emu/fnmsub.c
--- v2.4.4/linux/arch/ppc/math-emu/fnmsub.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fnmsub.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fnmsub.c,v 1.1 1999/08/23 18:59:53 cort Exp $
+/*
+ * BK Id: SCCS/s.fnmsub.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fnmsubs.c linux/arch/ppc/math-emu/fnmsubs.c
--- v2.4.4/linux/arch/ppc/math-emu/fnmsubs.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fnmsubs.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fnmsubs.c,v 1.1 1999/08/23 18:59:54 cort Exp $
+/*
+ * BK Id: SCCS/s.fnmsubs.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fres.c linux/arch/ppc/math-emu/fres.c
--- v2.4.4/linux/arch/ppc/math-emu/fres.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fres.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fres.c,v 1.1 1999/08/23 18:59:56 cort Exp $
+/*
+ * BK Id: SCCS/s.fres.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/frsp.c linux/arch/ppc/math-emu/frsp.c
--- v2.4.4/linux/arch/ppc/math-emu/frsp.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/frsp.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: frsp.c,v 1.1 1999/08/23 18:59:57 cort Exp $
+/*
+ * BK Id: SCCS/s.frsp.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/frsqrte.c linux/arch/ppc/math-emu/frsqrte.c
--- v2.4.4/linux/arch/ppc/math-emu/frsqrte.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/frsqrte.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: frsqrte.c,v 1.1 1999/08/23 18:59:58 cort Exp $
+/*
+ * BK Id: SCCS/s.frsqrte.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fsel.c linux/arch/ppc/math-emu/fsel.c
--- v2.4.4/linux/arch/ppc/math-emu/fsel.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fsel.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fsel.c,v 1.1 1999/08/23 18:59:59 cort Exp $
+/*
+ * BK Id: SCCS/s.fsel.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fsqrt.c linux/arch/ppc/math-emu/fsqrt.c
--- v2.4.4/linux/arch/ppc/math-emu/fsqrt.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fsqrt.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fsqrt.c,v 1.1 1999/08/23 19:00:01 cort Exp $
+/*
+ * BK Id: SCCS/s.fsqrt.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fsqrts.c linux/arch/ppc/math-emu/fsqrts.c
--- v2.4.4/linux/arch/ppc/math-emu/fsqrts.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fsqrts.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fsqrts.c,v 1.1 1999/08/23 19:00:03 cort Exp $
+/*
+ * BK Id: SCCS/s.fsqrts.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fsub.c linux/arch/ppc/math-emu/fsub.c
--- v2.4.4/linux/arch/ppc/math-emu/fsub.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fsub.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fsub.c,v 1.1 1999/08/23 19:00:05 cort Exp $
+/*
+ * BK Id: SCCS/s.fsub.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/fsubs.c linux/arch/ppc/math-emu/fsubs.c
--- v2.4.4/linux/arch/ppc/math-emu/fsubs.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/fsubs.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: fsubs.c,v 1.1 1999/08/23 19:00:07 cort Exp $
+/*
+ * BK Id: SCCS/s.fsubs.c 1.6 05/17/01 18:14:22 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/lfd.c linux/arch/ppc/math-emu/lfd.c
--- v2.4.4/linux/arch/ppc/math-emu/lfd.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/lfd.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: lfd.c,v 1.1 1999/08/23 19:00:08 cort Exp $
+/*
+ * BK Id: SCCS/s.lfd.c 1.6 05/17/01 18:14:23 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/lfs.c linux/arch/ppc/math-emu/lfs.c
--- v2.4.4/linux/arch/ppc/math-emu/lfs.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/lfs.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: lfs.c,v 1.1 1999/08/23 19:00:10 cort Exp $
+/*
+ * BK Id: SCCS/s.lfs.c 1.6 05/17/01 18:14:23 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/math.c linux/arch/ppc/math-emu/math.c
--- v2.4.4/linux/arch/ppc/math-emu/math.c	Mon Mar 27 22:30:30 2000
+++ linux/arch/ppc/math-emu/math.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
-/* $Id: math.c,v 1.1 1999/08/23 19:00:11 cort Exp $
+/*
+ * BK Id: SCCS/s.math.c 1.6 05/17/01 18:14:23 cort
+ */
+/*
  * arch/ppc/math-emu/math.c
  *
  * Copyright (C) 1999  Eddie C. Dost  (ecd@atecom.com)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/mcrfs.c linux/arch/ppc/math-emu/mcrfs.c
--- v2.4.4/linux/arch/ppc/math-emu/mcrfs.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/mcrfs.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: mcrfs.c,v 1.1 1999/08/23 19:00:13 cort Exp $
+/*
+ * BK Id: SCCS/s.mcrfs.c 1.6 05/17/01 18:14:23 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/mffs.c linux/arch/ppc/math-emu/mffs.c
--- v2.4.4/linux/arch/ppc/math-emu/mffs.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/mffs.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: mffs.c,v 1.1 1999/08/23 19:00:14 cort Exp $
+/*
+ * BK Id: SCCS/s.mffs.c 1.6 05/17/01 18:14:23 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/mtfsb0.c linux/arch/ppc/math-emu/mtfsb0.c
--- v2.4.4/linux/arch/ppc/math-emu/mtfsb0.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/mtfsb0.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: mtfsb0.c,v 1.1 1999/08/23 19:00:16 cort Exp $
+/*
+ * BK Id: SCCS/s.mtfsb0.c 1.6 05/17/01 18:14:23 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/mtfsb1.c linux/arch/ppc/math-emu/mtfsb1.c
--- v2.4.4/linux/arch/ppc/math-emu/mtfsb1.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/mtfsb1.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: mtfsb1.c,v 1.1 1999/08/23 19:00:17 cort Exp $
+/*
+ * BK Id: SCCS/s.mtfsb1.c 1.6 05/17/01 18:14:23 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/mtfsf.c linux/arch/ppc/math-emu/mtfsf.c
--- v2.4.4/linux/arch/ppc/math-emu/mtfsf.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/mtfsf.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: mtfsf.c,v 1.1 1999/08/23 19:00:19 cort Exp $
+/*
+ * BK Id: SCCS/s.mtfsf.c 1.6 05/17/01 18:14:23 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/mtfsfi.c linux/arch/ppc/math-emu/mtfsfi.c
--- v2.4.4/linux/arch/ppc/math-emu/mtfsfi.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/mtfsfi.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: mtfsfi.c,v 1.1 1999/08/23 19:00:20 cort Exp $
+/*
+ * BK Id: SCCS/s.mtfsfi.c 1.6 05/17/01 18:14:23 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/op-1.h linux/arch/ppc/math-emu/op-1.h
--- v2.4.4/linux/arch/ppc/math-emu/op-1.h	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/op-1.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.op-1.h 1.5 05/17/01 18:14:23 cort
+ */
+/*
  * Basic one-word fraction declaration and manipulation.
  */
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/op-2.h linux/arch/ppc/math-emu/op-2.h
--- v2.4.4/linux/arch/ppc/math-emu/op-2.h	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/op-2.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.op-2.h 1.5 05/17/01 18:14:23 cort
+ */
+/*
  * Basic two-word fraction declaration and manipulation.
  */
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/op-4.h linux/arch/ppc/math-emu/op-4.h
--- v2.4.4/linux/arch/ppc/math-emu/op-4.h	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/op-4.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.op-4.h 1.5 05/17/01 18:14:23 cort
+ */
+/*
  * Basic four-word fraction declaration and manipulation.
  *
  * When adding quadword support for 32 bit machines, we need
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/op-common.h linux/arch/ppc/math-emu/op-common.h
--- v2.4.4/linux/arch/ppc/math-emu/op-common.h	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/op-common.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.op-common.h 1.5 05/17/01 18:14:23 cort
+ */
 
 #define _FP_DECL(wc, X)			\
   _FP_I_TYPE X##_c, X##_s, X##_e;	\
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/sfp-machine.h linux/arch/ppc/math-emu/sfp-machine.h
--- v2.4.4/linux/arch/ppc/math-emu/sfp-machine.h	Mon Mar 27 22:30:29 2000
+++ linux/arch/ppc/math-emu/sfp-machine.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.sfp-machine.h 1.5 05/17/01 18:14:23 cort
+ */
 /* Machine-dependent software floating-point definitions.  PPC version.
    Copyright (C) 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/single.h linux/arch/ppc/math-emu/single.h
--- v2.4.4/linux/arch/ppc/math-emu/single.h	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/single.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.single.h 1.5 05/17/01 18:14:23 cort
+ */
+/*
  * Definitions for IEEE Single Precision
  */
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/soft-fp.h linux/arch/ppc/math-emu/soft-fp.h
--- v2.4.4/linux/arch/ppc/math-emu/soft-fp.h	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/soft-fp.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.soft-fp.h 1.5 05/17/01 18:14:23 cort
+ */
 #ifndef SOFT_FP_H
 #define SOFT_FP_H
 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/stfd.c linux/arch/ppc/math-emu/stfd.c
--- v2.4.4/linux/arch/ppc/math-emu/stfd.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/stfd.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: stfd.c,v 1.1 1999/08/23 19:00:33 cort Exp $
+/*
+ * BK Id: SCCS/s.stfd.c 1.6 05/17/01 18:14:23 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/stfiwx.c linux/arch/ppc/math-emu/stfiwx.c
--- v2.4.4/linux/arch/ppc/math-emu/stfiwx.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/stfiwx.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: stfiwx.c,v 1.1 1999/08/23 19:00:34 cort Exp $
+/*
+ * BK Id: SCCS/s.stfiwx.c 1.6 05/17/01 18:14:23 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/stfs.c linux/arch/ppc/math-emu/stfs.c
--- v2.4.4/linux/arch/ppc/math-emu/stfs.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/stfs.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,6 @@
-/* $Id: stfs.c,v 1.1 1999/08/23 19:00:35 cort Exp $
+/*
+ * BK Id: SCCS/s.stfs.c 1.6 05/17/01 18:14:23 cort
  */
-
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/types.c linux/arch/ppc/math-emu/types.c
--- v2.4.4/linux/arch/ppc/math-emu/types.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/types.c	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.types.c 1.5 05/17/01 18:14:23 cort
+ */
 
 #include "soft-fp.h"
 #include "double.h"
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/math-emu/udivmodti4.c linux/arch/ppc/math-emu/udivmodti4.c
--- v2.4.4/linux/arch/ppc/math-emu/udivmodti4.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/math-emu/udivmodti4.c	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.udivmodti4.c 1.5 05/17/01 18:14:23 cort
+ */
 /* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny.  */
 
 #include "soft-fp.h"
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/mbxboot/offset linux/arch/ppc/mbxboot/offset
--- v2.4.4/linux/arch/ppc/mbxboot/offset	Fri Mar 19 10:50:03 1999
+++ linux/arch/ppc/mbxboot/offset	Wed Dec 31 16:00:00 1969
@@ -1,4 +0,0 @@
-#!/bin/bash
-
-OFFSET=`$1 -h $2  | grep $3 | grep -v zvmlinux| awk '{print $6}'`
-echo "0x"$OFFSET
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/mbxboot/size linux/arch/ppc/mbxboot/size
--- v2.4.4/linux/arch/ppc/mbxboot/size	Fri Mar 19 10:50:03 1999
+++ linux/arch/ppc/mbxboot/size	Wed Dec 31 16:00:00 1969
@@ -1,4 +0,0 @@
-#!/bin/bash
-
-OFFSET=`$1 -h $2  | grep $3 | grep -v zvmlinux | awk '{print $3}'`
-echo "0x"$OFFSET
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/mm/4xx_tlb.c linux/arch/ppc/mm/4xx_tlb.c
--- v2.4.4/linux/arch/ppc/mm/4xx_tlb.c	Wed Feb  9 19:43:47 2000
+++ linux/arch/ppc/mm/4xx_tlb.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.4xx_tlb.c 1.5 05/17/01 18:14:23 cort
+ */
+/*
  *
  *    Copyright (c) 1998-1999 TiVo, Inc.
  *      Original implementation.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/mm/4xx_tlb.h linux/arch/ppc/mm/4xx_tlb.h
--- v2.4.4/linux/arch/ppc/mm/4xx_tlb.h	Mon Jan 10 18:25:32 2000
+++ linux/arch/ppc/mm/4xx_tlb.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.4xx_tlb.h 1.5 05/17/01 18:14:23 cort
+ */
+/*
  *
  *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
  *
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/mm/Makefile linux/arch/ppc/mm/Makefile
--- v2.4.4/linux/arch/ppc/mm/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/ppc/mm/Makefile	Mon May 21 17:04:47 2001
@@ -1,3 +1,5 @@
+# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:23 cort
+#
 #
 # Makefile for the linux ppc-specific parts of the memory manager.
 #
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/mm/extable.c linux/arch/ppc/mm/extable.c
--- v2.4.4/linux/arch/ppc/mm/extable.c	Tue Sep 19 08:31:53 2000
+++ linux/arch/ppc/mm/extable.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.extable.c 1.5 05/17/01 18:14:23 cort
+ */
+/*
  * linux/arch/ppc/mm/extable.c
  *
  * from linux/arch/i386/mm/extable.c
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/mm/fault.c linux/arch/ppc/mm/fault.c
--- v2.4.4/linux/arch/ppc/mm/fault.c	Mon Mar 19 12:35:09 2001
+++ linux/arch/ppc/mm/fault.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.fault.c 1.10 05/17/01 18:14:23 cort
+ */
+/*
  *  arch/ppc/mm/fault.c
  *
  *  PowerPC version 
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v2.4.4/linux/arch/ppc/mm/init.c	Mon Mar 26 15:29:44 2001
+++ linux/arch/ppc/mm/init.c	Mon May 21 17:04:47 2001
@@ -1,6 +1,7 @@
 /*
- *  $Id: init.c,v 1.195 1999/10/15 16:39:39 cort Exp $
- *
+ * BK Id: SCCS/s.init.c 1.22 05/17/01 18:14:23 cort
+ */
+/*
  *  PowerPC version 
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
@@ -46,7 +47,6 @@
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
 #include <asm/mmu.h>
-#include <asm/residual.h>
 #include <asm/uaccess.h>
 #ifdef CONFIG_8xx
 #include <asm/8xx_immap.h>
@@ -61,6 +61,7 @@
 #include <asm/machdep.h>
 #include <asm/setup.h>
 #include <asm/amigahw.h>
+#include <asm/gemini.h>
 
 #include "mem_pieces.h"
 
@@ -93,7 +94,6 @@
 extern char __pmac_begin, __pmac_end;
 extern char __apus_begin, __apus_end;
 extern char __openfirmware_begin, __openfirmware_end;
-struct device_node *memory_node;
 unsigned long ioremap_base;
 unsigned long ioremap_bot;
 unsigned long avail_start;
@@ -111,19 +111,6 @@
 
 void MMU_init(void);
 void *early_get_page(void);
-unsigned long prep_find_end_of_memory(void);
-unsigned long pmac_find_end_of_memory(void);
-unsigned long apus_find_end_of_memory(void);
-extern unsigned long find_end_of_memory(void);
-#ifdef CONFIG_8xx
-unsigned long m8xx_find_end_of_memory(void);
-#endif /* CONFIG_8xx */
-#ifdef CONFIG_4xx
-unsigned long oak_find_end_of_memory(void);
-#endif
-#ifdef CONFIG_8260
-unsigned long m8260_find_end_of_memory(void);
-#endif /* CONFIG_8260 */
 static void mapin_ram(void);
 int map_page(unsigned long va, unsigned long pa, int flags);
 void set_phys_avail(unsigned long total_ram);
@@ -436,11 +423,9 @@
 	 * Should check if it is a candidate for a BAT mapping
 	 */
 
-	spin_lock(&init_mm.page_table_lock);
 	err = 0;
 	for (i = 0; i < size && err == 0; i += PAGE_SIZE)
 		err = map_page(v+i, p+i, flags);
-	spin_unlock(&init_mm.page_table_lock);
 	if (err) {
 		if (mem_init_done)
 			vfree((void *)v);
@@ -487,17 +472,21 @@
 {
 	pmd_t *pd;
 	pte_t *pg;
+	int err = -ENOMEM;
 
+	spin_lock(&init_mm.page_table_lock);
 	/* Use upper 10 bits of VA to index the first level map */
 	pd = pmd_offset(pgd_offset_k(va), va);
 	/* Use middle 10 bits of VA to index the second-level map */
 	pg = pte_alloc(&init_mm, pd, va);
-	if (pg == 0)
-		return -ENOMEM;
-	set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags)));
-	if (mem_init_done)
-		flush_hash_page(0, va);
-	return 0;
+	if (pg != 0) {
+		err = 0;
+		set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags)));
+		if (mem_init_done)
+			flush_hash_page(0, va);
+	}
+	spin_unlock(&init_mm.page_table_lock);
+	return err;
 }
 
 #ifndef CONFIG_8xx
@@ -668,33 +657,6 @@
 }
 
 #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
-static void get_mem_prop(char *, struct mem_pieces *);
-
-#if defined(CONFIG_ALL_PPC)
-/*
- * Read in a property describing some pieces of memory.
- */
-
-static void __init get_mem_prop(char *name, struct mem_pieces *mp)
-{
-	struct reg_property *rp;
-	int s;
-
-	rp = (struct reg_property *) get_property(memory_node, name, &s);
-	if (rp == NULL) {
-		printk(KERN_ERR "error: couldn't get %s property on /memory\n",
-		       name);
-		abort();
-	}
-	mp->n_regions = s / sizeof(mp->regions[0]);
-	memcpy(mp->regions, rp, s);
-
-	/* Make sure the pieces are sorted. */
-	mem_pieces_sort(mp);
-	mem_pieces_coalesce(mp);
-}
-#endif /* CONFIG_ALL_PPC */
-
 /*
  * Set up one of the I/D BAT (block address translation) register pairs.
  * The parameters are not checked; in particular size must be a power
@@ -877,14 +839,13 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
-
 	for (; start < end; start += PAGE_SIZE) {
 		ClearPageReserved(virt_to_page(start));
 		set_page_count(virt_to_page(start), 1);
 		free_page(start);
 		totalram_pages++;
 	}
+	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
 }
 #endif
 
@@ -904,27 +865,28 @@
 	/*
 	 * The Zone Protection Register (ZPR) defines how protection will
 	 * be applied to every page which is a member of a given zone. At
-	 * present, we utilize only two of the 4xx's zones. The first, zone
-	 * 0, is set at '00b and only allows access in supervisor-mode based
-	 * on the EX and WR bits. No user-mode access is allowed. The second,
-	 * zone 1, is set at '10b and in supervisor-mode allows access
-	 * without regard to the EX and WR bits. In user-mode, access is
-	 * allowed based on the EX and WR bits.
+	 * present, we utilize only two of the 4xx's zones.
+	 * The zone index bits (of ZSEL) in the PTE are used for software
+	 * indicators, except the LSB.  For user access, zone 15 is used,
+	 * for kernel access, zone 14 is used.  We set all but zone 15
+	 * to zero, allowing only kernel access as indicated in the PTE.
+	 * For zone 15, we set a 10 binary (I guess a 01 would work too)
+	 * to allow user access as indicated in the PTE.  This also allows
+	 * kernel access as indicated in the PTE.
 	 */
 
-        mtspr(SPRN_ZPR, 0x2aaaaaaa);
-
-	/* Hardwire any TLB entries necessary here. */
+        mtspr(SPRN_ZPR, 0x00000002);
 
-	PPC4xx_tlb_pin(KERNELBASE, 0, TLB_PAGESZ(PAGESZ_16M), 1);
+	flush_instruction_cache();
 
 	/*
 	 * Find the top of physical memory and map all of it in starting
 	 * at KERNELBASE.
 	 */
 
-        total_memory = total_lowmem = oak_find_end_of_memory();
-	end_of_DRAM = __va(total_memory);
+        total_memory = total_lowmem = ppc_md.find_end_of_memory();
+	end_of_DRAM = __va(total_lowmem);
+	set_phys_avail(total_lowmem);
         mapin_ram();
 
 	/*
@@ -943,70 +905,13 @@
         mtspr(SPRN_ICCR, 0x80000000);	/* 128 MB of instr. space at 0x0. */
 }
 
-#elif defined(CONFIG_8xx)
+#else /* !CONFIG_4xx */
 void __init MMU_init(void)
 {
 	if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111);
 
-	total_memory = total_lowmem = m8xx_find_end_of_memory();
-#ifdef CONFIG_HIGHMEM
-	if (total_lowmem > MAX_LOW_MEM) {
-		total_lowmem = MAX_LOW_MEM;
-		mem_pieces_remove(&phys_avail, total_lowmem,
-				  total_memory - total_lowmem, 0);
-	}
-#endif /* CONFIG_HIGHMEM */
-	end_of_DRAM = __va(total_lowmem);
-	set_phys_avail(total_lowmem);
-
-        /* Map in all of RAM starting at KERNELBASE */
-        mapin_ram();
-
-        /* Now map in some of the I/O space that is generically needed
-         * or shared with multiple devices.
-         * All of this fits into the same 4Mbyte region, so it only
-         * requires one page table page.
-         */
-        ioremap(IMAP_ADDR, IMAP_SIZE);
-#ifdef CONFIG_MBX
-        ioremap(NVRAM_ADDR, NVRAM_SIZE);
-        ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE);
-        ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE);
-
-	/* Map some of the PCI/ISA I/O space to get the IDE interface.
-	*/
-        ioremap(PCI_ISA_IO_ADDR, 0x4000);
-        ioremap(PCI_IDE_ADDR, 0x4000);
-#endif
-#ifdef CONFIG_RPXLITE
-	ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE);
-	ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE);
-#endif
-#ifdef CONFIG_RPXCLASSIC
-        ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE);
-	ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE);
-#endif
-	if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211);
-}
-
-#else /* not 4xx or 8xx */
-void __init MMU_init(void)
-{
-	if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111);
+	total_memory = ppc_md.find_end_of_memory();
 
-	if (have_of)
-		total_memory = pmac_find_end_of_memory();
-#ifdef CONFIG_APUS
-	else if (_machine == _MACH_apus )
-		total_memory = apus_find_end_of_memory();
-#endif
-#if defined(CONFIG_8260)
-	else
-		total_memory = m8260_find_end_of_memory();
-#else
-	else /* prep */
-		total_memory = prep_find_end_of_memory();
-#endif
 	if (__max_memory && total_memory > __max_memory)
 		total_memory = __max_memory;
 	total_lowmem = total_memory;
@@ -1019,6 +924,7 @@
 	end_of_DRAM = __va(total_lowmem);
 	set_phys_avail(total_lowmem);
 
+#if !defined(CONFIG_8xx)
 	if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300);
         hash_init();
 #ifndef CONFIG_PPC64BRIDGE
@@ -1026,16 +932,49 @@
 #endif
 	
 	ioremap_base = 0xf8000000;
+#endif /* CONFIG_8xx */
 
 	if ( ppc_md.progress ) ppc_md.progress("MMU:mapin", 0x301);
 	/* Map in all of RAM starting at KERNELBASE */
 	mapin_ram();
 
-#ifdef CONFIG_POWER4
+#if defined(CONFIG_POWER4)
 	ioremap_base = ioremap_bot = 0xfffff000;
 	isa_io_base = (unsigned long) ioremap(0xffd00000, 0x200000) + 0x100000;
 
-#else /* CONFIG_POWER4 */
+#elif defined(CONFIG_8xx)
+        /* Now map in some of the I/O space that is generically needed
+         * or shared with multiple devices.
+         * All of this fits into the same 4Mbyte region, so it only
+         * requires one page table page.
+         */
+        ioremap(IMAP_ADDR, IMAP_SIZE);
+#ifdef CONFIG_MBX
+        ioremap(NVRAM_ADDR, NVRAM_SIZE);
+        ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE);
+        ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE);
+
+	/* Map some of the PCI/ISA I/O space to get the IDE interface.
+	*/
+        ioremap(PCI_ISA_IO_ADDR, 0x4000);
+        ioremap(PCI_IDE_ADDR, 0x4000);
+#endif
+#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
+	ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE);
+#if !defined(CONFIG_PCI)
+	ioremap(_IO_BASE,_IO_BASE_SIZE);
+#endif
+#endif
+#ifdef CONFIG_HTDMSOUND
+	ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE);
+#endif
+#ifdef CONFIG_FADS
+	ioremap(BCSR_ADDR, BCSR_SIZE);
+#endif
+#ifdef CONFIG_PCI
+        ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE);
+#endif
+#else /* !CONFIG_POWER4 && !CONFIG_8xx */
 	/*
 	 * Setup the bat mappings we're going to load that cover
 	 * the io areas.  RAM was mapped by mapin_ram().
@@ -1069,6 +1008,10 @@
 		/* Map chip and ZorroII memory */
 		setbat(1, zTwoBase,   0x00000000, 0x01000000, IO_PAGE);
 		break;
+	case _MACH_gemini:
+		setbat(0, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE);
+		setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE);
+		break;
 	case _MACH_8260:
 		/* Map the IMMR, plus anything else we can cover
 		 * in that upper space according to the memory controller
@@ -1081,7 +1024,7 @@
 		break;
 	}
 	ioremap_bot = ioremap_base;
-#endif /* CONFIG_POWER4 */
+#endif /* CONFIG_POWER4 || CONFIG_8xx */
 
 	if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211);
 #ifdef CONFIG_BOOTX_TEXT
@@ -1257,155 +1200,6 @@
 }
 
 #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
-#if defined(CONFIG_ALL_PPC)
-/*
- * On systems with Open Firmware, collect information about
- * physical RAM and which pieces are already in use.
- * At this point, we have (at least) the first 8MB mapped with a BAT.
- * Our text, data, bss use something over 1MB, starting at 0.
- * Open Firmware may be using 1MB at the 4MB point.
- */
-unsigned long __init pmac_find_end_of_memory(void)
-{
-	unsigned long a, total;
-	struct mem_pieces phys_mem;
-
-	memory_node = find_devices("memory");
-	if (memory_node == NULL) {
-		printk(KERN_ERR "can't find memory node\n");
-		abort();
-	}
-
-	/*
-	 * Find out where physical memory is, and check that it
-	 * starts at 0 and is contiguous.  It seems that RAM is
-	 * always physically contiguous on Power Macintoshes.
-	 *
-	 * Supporting discontiguous physical memory isn't hard,
-	 * it just makes the virtual <-> physical mapping functions
-	 * more complicated (or else you end up wasting space
-	 * in mem_map).
-	 */
-	get_mem_prop("reg", &phys_mem);
-	if (phys_mem.n_regions == 0)
-		panic("No RAM??");
-	a = phys_mem.regions[0].address;
-	if (a != 0)
-		panic("RAM doesn't start at physical address 0");
-	total = phys_mem.regions[0].size;
-
-	if (phys_mem.n_regions > 1) {
-		printk("RAM starting at 0x%x is not contiguous\n",
-		       phys_mem.regions[1].address);
-		printk("Using RAM from 0 to 0x%lx\n", total-1);
-	}
-
-	return total;
-}
-#endif /* CONFIG_ALL_PPC */
-
-#if defined(CONFIG_ALL_PPC)
-/*
- * This finds the amount of physical ram and does necessary
- * setup for prep.  This is pretty architecture specific so
- * this will likely stay separate from the pmac.
- * -- Cort
- */
-unsigned long __init prep_find_end_of_memory(void)
-{
-	unsigned long total;
-#ifdef CONFIG_PREP_RESIDUAL
-	total = res->TotalMemory;
-#else
-	total = 0;
-#endif
-
-	if (total == 0 )
-	{
-		/*
-		 * I need a way to probe the amount of memory if the residual
-		 * data doesn't contain it. -- Cort
-		 */
-		printk("Ramsize from residual data was 0 -- Probing for value\n");
-		total = 0x02000000;
-		printk("Ramsize default to be %ldM\n", total>>20);
-	}
-
-	return (total);
-}
-#endif /* defined(CONFIG_ALL_PPC) */
-
-#ifdef CONFIG_8260
-/*
- * Same hack as 8xx.
- */
-unsigned long __init m8260_find_end_of_memory(void)
-{
-	bd_t	*binfo;
-	extern unsigned char __res[];
-	
-	binfo = (bd_t *)__res;
-
-	return binfo->bi_memsize;
-}
-#endif /* CONFIG_8260 */
-
-#ifdef CONFIG_APUS
-#define HARDWARE_MAPPED_SIZE (512*1024)
-unsigned long __init apus_find_end_of_memory(void)
-{
-	int shadow = 0;
-	unsigned long total;
-
-	/* The memory size reported by ADOS excludes the 512KB
-	   reserved for PPC exception registers and possibly 512KB
-	   containing a shadow of the ADOS ROM. */
-	{
-		unsigned long size = memory[0].size;
-
-		/* If 2MB aligned, size was probably user
-                   specified. We can't tell anything about shadowing
-                   in this case so skip shadow assignment. */
-		if (0 != (size & 0x1fffff)){
-			/* Align to 512KB to ensure correct handling
-			   of both memfile and system specified
-			   sizes. */
-			size = ((size+0x0007ffff) & 0xfff80000);
-			/* If memory is 1MB aligned, assume
-                           shadowing. */
-			shadow = !(size & 0x80000);
-		}
-
-		/* Add the chunk that ADOS does not see. by aligning
-                   the size to the nearest 2MB limit upwards.  */
-		memory[0].size = ((size+0x001fffff) & 0xffe00000);
-	}
-
-	total = memory[0].size;
-
-	/* Remove the memory chunks that are controlled by special
-           Phase5 hardware. */
-
-	/* Remove the upper 512KB if it contains a shadow of
-	   the ADOS ROM. FIXME: It might be possible to
-	   disable this shadow HW. Check the booter
-	   (ppc_boot.c) */
-	if (shadow)
-		total -= HARDWARE_MAPPED_SIZE;
-
-	/* Remove the upper 512KB where the PPC exception
-	   vectors are mapped. */
-	total -= HARDWARE_MAPPED_SIZE;
-
-	/* Linux/APUS only handles one block of memory -- the one on
-	   the PowerUP board. Other system memory is horrible slow in
-	   comparison. The user can use other memory for swapping
-	   using the z2ram device. */
-	ram_phys_base = memory[0].addr;
-	return total;
-}
-#endif /* CONFIG_APUS */
-
 /*
  * Initialize the hash table and patch the instructions in head.S.
  */
@@ -1514,43 +1308,7 @@
 	}
 	if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205);
 }
-#elif defined(CONFIG_8xx)
-/*
- * This is a big hack right now, but it may turn into something real
- * someday.
- *
- * For the 8xx boards (at this time anyway), there is nothing to initialize
- * associated the PROM.  Rather than include all of the prom.c
- * functions in the image just to get prom_init, all we really need right
- * now is the initialization of the physical memory region.
- */
-unsigned long __init m8xx_find_end_of_memory(void)
-{
-	bd_t	*binfo;
-	extern unsigned char __res[];
-	
-	binfo = (bd_t *)__res;
-
-	return binfo->bi_memsize;
-}
 #endif /* !CONFIG_4xx && !CONFIG_8xx */
-
-#ifdef CONFIG_OAK
-/*
- * Return the virtual address representing the top of physical RAM
- * on the Oak board.
- */
-unsigned long __init
-oak_find_end_of_memory(void)
-{
-	extern unsigned char __res[];
-
-	unsigned long *ret;
-	bd_t *bip = (bd_t *)__res;
-	
-	return bip->bi_memsize;
-}
-#endif
 
 /*
  * Set phys_avail to the amount of physical memory,
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/mm/mem_pieces.c linux/arch/ppc/mm/mem_pieces.c
--- v2.4.4/linux/arch/ppc/mm/mem_pieces.c	Mon Jun 19 17:59:37 2000
+++ linux/arch/ppc/mm/mem_pieces.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.mem_pieces.c 1.5 05/17/01 18:14:23 cort
+ */
+/*
  *    Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
  *      Changes to accomodate Power Macintoshes.
  *    Cort Dougan <cort@cs.nmt.edu>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/mm/mem_pieces.h linux/arch/ppc/mm/mem_pieces.h
--- v2.4.4/linux/arch/ppc/mm/mem_pieces.h	Mon Jun 19 17:59:37 2000
+++ linux/arch/ppc/mm/mem_pieces.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.mem_pieces.h 1.5 05/17/01 18:14:23 cort
+ */
+/*
  *    Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
  *      Changes to accomodate Power Macintoshes.
  *    Cort Dougan <cort@cs.nmt.edu>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/treeboot/crt0.S linux/arch/ppc/treeboot/crt0.S
--- v2.4.4/linux/arch/ppc/treeboot/crt0.S	Mon Jan 10 18:25:32 2000
+++ linux/arch/ppc/treeboot/crt0.S	Wed Dec 31 16:00:00 1969
@@ -1,70 +0,0 @@
-/*
- *    Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au>
- *      Initial Power Macintosh COFF version.
- *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
- *      Modifications for IBM PowerPC 400-class processor evaluation
- *      boards.
- *
- *    Module name: crt0.S
- *
- *    Description:
- *      Boot loader execution entry point. Clears out .bss section as per
- *      ANSI C requirements. Invalidates and flushes the caches over the
- *      range covered by the boot loader's .text section. Sets up a stack
- *      below the .text section entry point.
- *
- *    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.
- *
- */
-
-#include "../kernel/ppc_asm.tmpl"
-
-	.text
-
-	.globl	_start
-_start:	
-        ## Clear out the BSS as per ANSI C requirements
-
-        lis     r7,_end@ha		# 
-        addi    r7,r7,_end@l		# r7 = &_end
-        lis     r8,__bss_start@ha	# 
-        addi    r8,r8,__bss_start@l	# r8 = &_bss_start
-
-	## Determine how large an area, in number of words, to clear
-	
-        subf    r7,r8,r7		# r7 = &_end - &_bss_start + 1 
-        addi    r7,r7,3			# r7 += 3
-        srwi.   r7,r7,2			# r7 = size in words.
-        beq     2f			# If the size is zero, do not bother
-        addi    r8,r8,-4		# r8 -= 4
-        mtctr   r7			# SPRN_CTR = number of words to clear
-        li      r0,0			# r0 = 0
-1:      stwu    r0,4(r8)		# Clear out a word
-        bdnz    1b			# If we are not done yet, keep clearing
-	
-	## Flush and invalidate the caches for the range in memory covering
-	## the .text section of the boot loader
-	
-2:	lis	r9,_start@h		# r9 = &_start
-	lis	r8,_etext@ha		# 
-	addi	r8,r8,_etext@l		# r8 = &_etext
-3:	dcbf	r0,r9			# Flush the data cache
-	icbi	r0,r9			# Invalidate the instruction cache
-	addi	r9,r9,0x10		# Increment by one cache line
-	cmplwi	cr0,r9,r8		# Are we at the end yet?
-	blt	3b			# No, keep flushing and invalidating
-
-	## Set up the stack
-
-	lis	r9,_start@h		# r9 = &_start (text section entry)
-	addi	r9,r9,_start@l
-	subi	r1,r9,64		# Start the stack 64 bytes below _start
-	clrrwi	r1,r1,4			# Make sure it is aligned on 16 bytes.
-	li	r0,0
-	stwu	r0,-16(r1)
-	mtlr	r9
-	
-	b	start			# All done, start the real work.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/Makefile linux/arch/ppc/xmon/Makefile
--- v2.4.4/linux/arch/ppc/xmon/Makefile	Fri Dec 29 14:07:20 2000
+++ linux/arch/ppc/xmon/Makefile	Mon May 21 17:04:47 2001
@@ -1,3 +1,5 @@
+# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:23 cort
+#
 # Makefile for xmon
 
 O_TARGET	:= x.o
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/adb.c linux/arch/ppc/xmon/adb.c
--- v2.4.4/linux/arch/ppc/xmon/adb.c	Sat May 22 13:03:00 1999
+++ linux/arch/ppc/xmon/adb.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.adb.c 1.5 05/17/01 18:14:23 cort
+ */
+/*
  * Copyright (C) 1996 Paul Mackerras.
  */
 #include "nonstdio.h"
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/ansidecl.h linux/arch/ppc/xmon/ansidecl.h
--- v2.4.4/linux/arch/ppc/xmon/ansidecl.h	Sat May 22 13:03:00 1999
+++ linux/arch/ppc/xmon/ansidecl.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.ansidecl.h 1.5 05/17/01 18:14:23 cort
+ */
 /* ANSI and traditional C compatability macros
    Copyright 1991, 1992 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/nonstdio.h linux/arch/ppc/xmon/nonstdio.h
--- v2.4.4/linux/arch/ppc/xmon/nonstdio.h	Sat May 22 13:03:00 1999
+++ linux/arch/ppc/xmon/nonstdio.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.nonstdio.h 1.5 05/17/01 18:14:23 cort
+ */
 typedef int	FILE;
 extern FILE *xmon_stdin, *xmon_stdout;
 #define EOF	(-1)
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/ppc-dis.c linux/arch/ppc/xmon/ppc-dis.c
--- v2.4.4/linux/arch/ppc/xmon/ppc-dis.c	Sat May 22 13:03:00 1999
+++ linux/arch/ppc/xmon/ppc-dis.c	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.ppc-dis.c 1.5 05/17/01 18:14:23 cort
+ */
 /* ppc-dis.c -- Disassemble PowerPC instructions
    Copyright 1994 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/ppc-opc.c linux/arch/ppc/xmon/ppc-opc.c
--- v2.4.4/linux/arch/ppc/xmon/ppc-opc.c	Sat Nov 27 15:41:59 1999
+++ linux/arch/ppc/xmon/ppc-opc.c	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.ppc-opc.c 1.5 05/17/01 18:14:23 cort
+ */
 /* ppc-opc.c -- PowerPC opcode list
    Copyright 1994 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/ppc.h linux/arch/ppc/xmon/ppc.h
--- v2.4.4/linux/arch/ppc/xmon/ppc.h	Sat May 22 13:03:00 1999
+++ linux/arch/ppc/xmon/ppc.h	Mon May 21 17:04:47 2001
@@ -1,3 +1,6 @@
+/*
+ * BK Id: SCCS/s.ppc.h 1.5 05/17/01 18:14:23 cort
+ */
 /* ppc.h -- Header file for PowerPC opcode table
    Copyright 1994 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Cygnus Support
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/privinst.h linux/arch/ppc/xmon/privinst.h
--- v2.4.4/linux/arch/ppc/xmon/privinst.h	Wed May  3 01:47:57 2000
+++ linux/arch/ppc/xmon/privinst.h	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.privinst.h 1.5 05/17/01 18:14:23 cort
+ */
+/*
  * Copyright (C) 1996 Paul Mackerras.
  */
 #include <linux/config.h>
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/setjmp.c linux/arch/ppc/xmon/setjmp.c
--- v2.4.4/linux/arch/ppc/xmon/setjmp.c	Sat May 22 13:03:00 1999
+++ linux/arch/ppc/xmon/setjmp.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.setjmp.c 1.5 05/17/01 18:14:23 cort
+ */
+/*
  * Copyright (C) 1996 Paul Mackerras.
  *
  * NB this file must be compiled with -O2.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/start.c linux/arch/ppc/xmon/start.c
--- v2.4.4/linux/arch/ppc/xmon/start.c	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/xmon/start.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.start.c 1.12 05/21/01 21:39:13 paulus
+ */
+/*
  * Copyright (C) 1996 Paul Mackerras.
  */
 #include <linux/config.h>
@@ -28,7 +31,7 @@
 
 static int console;
 static int use_screen;
-static int via_modem = 1;
+static int via_modem;
 static int xmon_use_sccb;
 static struct device_node *macio_node;
 
@@ -61,27 +64,37 @@
 		struct device_node *np;
 		unsigned long addr;
 #ifdef CONFIG_BOOTX_TEXT
-		extern boot_infos_t *disp_bi;
+		if (!machine_is_compatible("iMac")) {
+			extern boot_infos_t *disp_bi;
 
-		/* see if there is a keyboard in the device tree
-		   with a parent of type "adb" */
-		for (np = find_devices("keyboard"); np; np = np->next)
-			if (np->parent && np->parent->type
-			    && strcmp(np->parent->type, "adb") == 0)
-				break;
+			/* see if there is a keyboard in the device tree
+			   with a parent of type "adb" */
+			for (np = find_devices("keyboard"); np; np = np->next)
+				if (np->parent && np->parent->type
+				    && strcmp(np->parent->type, "adb") == 0)
+					break;
 
-		/* needs to be hacked if xmon_printk is to be used
- 		   from within find_via_pmu() */
+			/* needs to be hacked if xmon_printk is to be used
+			   from within find_via_pmu() */
 #ifdef CONFIG_ADB_PMU
-		if (np != NULL && disp_bi && find_via_pmu())
-			use_screen = 1;
+			if (np != NULL && disp_bi && find_via_pmu())
+				use_screen = 1;
 #endif
 #ifdef CONFIG_ADB_CUDA
-		if (np != NULL && disp_bi && find_via_cuda())
-			use_screen = 1;
+			if (np != NULL && disp_bi && find_via_cuda())
+				use_screen = 1;
 #endif
+		}
+		prom_drawstring("xmon uses ");
 		if (use_screen)
-			prom_drawstring("xmon uses screen and keyboard\n");
+			prom_drawstring("screen and keyboard\n");
+		else {
+			if (via_modem)
+				prom_drawstring("modem on ");
+			prom_drawstring(xmon_use_sccb? "printer": "modem");
+			prom_drawstring(" port\n");
+		}
+
 #endif /* CONFIG_BOOTX_TEXT */
 
 #ifdef CHRP_ESCC
@@ -100,6 +113,15 @@
 		base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
 		sccc = base + (addr & ~PAGE_MASK);
 		sccd = sccc + 0x10;
+	}
+	else if ( _machine & _MACH_gemini )
+	{
+		/* should already be mapped by the kernel boot */
+		sccc = (volatile unsigned char *) 0xffeffb0d;
+		sccd = (volatile unsigned char *) 0xffeffb08;
+		TXRDY = 0x20;
+		RXRDY = 1;
+		console = 1;
 	}
 	else
 	{
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/start_8xx.c linux/arch/ppc/xmon/start_8xx.c
--- v2.4.4/linux/arch/ppc/xmon/start_8xx.c	Wed May  3 01:47:57 2000
+++ linux/arch/ppc/xmon/start_8xx.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.start_8xx.c 1.7 05/17/01 18:14:23 cort
+ */
+/*
  * Copyright (C) 1996 Paul Mackerras.
  * Copyright (C) 2000 Dan Malek.
  * Quick hack of Paul's code to make XMON work on 8xx processors.  Lots
@@ -15,7 +18,7 @@
 #include <asm/processor.h>
 #include <asm/8xx_immap.h>
 #include <asm/mpc8xx.h>
-#include "commproc.h"
+#include "../8xx_io/commproc.h"
 
 extern void xmon_printf(const char *fmt, ...);
 extern int xmon_8xx_write(char *str, int nb);
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/subr_prf.c linux/arch/ppc/xmon/subr_prf.c
--- v2.4.4/linux/arch/ppc/xmon/subr_prf.c	Tue Aug 31 11:36:43 1999
+++ linux/arch/ppc/xmon/subr_prf.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.subr_prf.c 1.5 05/17/01 18:14:23 cort
+ */
+/*
  * Written by Cort Dougan to replace the version originally used
  * by Paul Mackerras, which came from NetBSD and thus had copyright
  * conflicts with Linux.
diff -u --recursive --new-file v2.4.4/linux/arch/ppc/xmon/xmon.c linux/arch/ppc/xmon/xmon.c
--- v2.4.4/linux/arch/ppc/xmon/xmon.c	Mon Jan 22 15:41:15 2001
+++ linux/arch/ppc/xmon/xmon.c	Mon May 21 17:04:47 2001
@@ -1,4 +1,7 @@
 /*
+ * BK Id: SCCS/s.xmon.c 1.9 05/17/01 18:14:24 cort
+ */
+/*
  * Routines providing a simple monitor for use on the PowerMac.
  *
  * Copyright (C) 1996 Paul Mackerras.
@@ -208,10 +211,11 @@
 xmon_irq(int irq, void *d, struct pt_regs *regs)
 {
 	unsigned long flags;
-	save_flags(flags);cli();
+	__save_flags(flags);
+	__cli();
 	printf("Keyboard interrupt\n");
 	xmon(regs);
-	restore_flags(flags);
+	__restore_flags(flags);
 }
 
 int
@@ -657,7 +661,7 @@
 	unsigned stack[2];
 	struct pt_regs regs;
 	extern char ret_from_intercept, ret_from_syscall_1, ret_from_syscall_2;
-	extern char lost_irq_ret, do_bottom_half_ret, do_signal_ret;
+	extern char do_bottom_half_ret, do_signal_ret;
 	extern char ret_from_except;
 
 	printf("backtrace:\n");
@@ -676,7 +680,6 @@
 		    || stack[1] == (unsigned) &ret_from_except
 		    || stack[1] == (unsigned) &ret_from_syscall_1
 		    || stack[1] == (unsigned) &ret_from_syscall_2
-		    || stack[1] == (unsigned) &lost_irq_ret
 		    || stack[1] == (unsigned) &do_bottom_half_ret
 		    || stack[1] == (unsigned) &do_signal_ret) {
 			if (mread(sp+16, &regs, sizeof(regs)) != sizeof(regs))
diff -u --recursive --new-file v2.4.4/linux/arch/sh/kernel/hd64465_gpio.c linux/arch/sh/kernel/hd64465_gpio.c
--- v2.4.4/linux/arch/sh/kernel/hd64465_gpio.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/hd64465_gpio.c	Sun May 20 12:11:38 2001
@@ -6,7 +6,6 @@
  * GPIO pin support for HD64465 companion chip.
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
diff -u --recursive --new-file v2.4.4/linux/arch/sh/kernel/io_cat68701.c linux/arch/sh/kernel/io_cat68701.c
--- v2.4.4/linux/arch/sh/kernel/io_cat68701.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/io_cat68701.c	Sun May 20 12:11:38 2001
@@ -14,6 +14,7 @@
 
 #include <asm/io.h>
 #include <asm/machvec.h>
+#include <linux/config.h>
 #include <linux/module.h>
 
 #define SH3_PCMCIA_BUG_WORKAROUND 1
diff -u --recursive --new-file v2.4.4/linux/arch/sh/kernel/io_dc.c linux/arch/sh/kernel/io_dc.c
--- v2.4.4/linux/arch/sh/kernel/io_dc.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/io_dc.c	Sun May 20 12:11:38 2001
@@ -3,7 +3,6 @@
  *	I/O routines for SEGA Dreamcast
  */
 
-#include <linux/config.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
 
diff -u --recursive --new-file v2.4.4/linux/arch/sh/kernel/io_ec3104.c linux/arch/sh/kernel/io_ec3104.c
--- v2.4.4/linux/arch/sh/kernel/io_ec3104.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/io_ec3104.c	Sun May 20 12:11:38 2001
@@ -14,8 +14,6 @@
  * (prumpf@tux.org).
  */
 
-
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <asm/io.h>
diff -u --recursive --new-file v2.4.4/linux/arch/sh/kernel/irq_intc2.c linux/arch/sh/kernel/irq_intc2.c
--- v2.4.4/linux/arch/sh/kernel/irq_intc2.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/irq_intc2.c	Sun May 20 12:11:38 2001
@@ -12,7 +12,6 @@
  * Hitachi 7751 and the STM ST40 STB1.
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/irq.h>
diff -u --recursive --new-file v2.4.4/linux/arch/sh/kernel/mach_dc.c linux/arch/sh/kernel/mach_dc.c
--- v2.4.4/linux/arch/sh/kernel/mach_dc.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/mach_dc.c	Sun May 20 12:11:38 2001
@@ -3,6 +3,7 @@
  *	SEGA Dreamcast machine vector
  */
 
+#include <linux/config.h>
 #include <linux/init.h>
 
 #include <asm/machvec.h>
diff -u --recursive --new-file v2.4.4/linux/arch/sh/kernel/setup_dc.c linux/arch/sh/kernel/setup_dc.c
--- v2.4.4/linux/arch/sh/kernel/setup_dc.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/setup_dc.c	Sun May 20 12:11:38 2001
@@ -3,7 +3,6 @@
  *	SEGA Dreamcast support
  */
 
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/param.h>
diff -u --recursive --new-file v2.4.4/linux/arch/sh/kernel/setup_ec3104.c linux/arch/sh/kernel/setup_ec3104.c
--- v2.4.4/linux/arch/sh/kernel/setup_ec3104.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/kernel/setup_ec3104.c	Sun May 20 12:11:38 2001
@@ -14,7 +14,6 @@
  * (prumpf@tux.org).
  */
 
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/param.h>
diff -u --recursive --new-file v2.4.4/linux/arch/sh/mm/cache.c linux/arch/sh/mm/cache.c
--- v2.4.4/linux/arch/sh/mm/cache.c	Wed Apr 11 21:24:52 2001
+++ linux/arch/sh/mm/cache.c	Sun May 20 12:11:38 2001
@@ -6,6 +6,7 @@
  *
  */
 
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
diff -u --recursive --new-file v2.4.4/linux/arch/sparc/config.in linux/arch/sparc/config.in
--- v2.4.4/linux/arch/sparc/config.in	Thu Apr 19 08:38:48 2001
+++ linux/arch/sparc/config.in	Mon May 21 18:12:09 2001
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.109 2001/04/18 21:06:05 davem Exp $
+# $Id: config.in,v 1.110 2001/05/20 05:14:46 davem Exp $
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
@@ -162,9 +162,7 @@
 
    dep_tristate '  SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
 
-   if [ "$CONFIG_BLK_DEV_ST" != "n" ]; then
-      int  'Maximum number of SCSI tapes that can be loaded as modules' CONFIG_ST_EXTRA_DEVS 2
-   fi
+   dep_tristate '  SCSI OnStream SC-x0 tape support' CONFIG_CHR_DEV_OSST $CONFIG_SCSI
 
    dep_tristate '  SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
 
diff -u --recursive --new-file v2.4.4/linux/arch/sparc/defconfig linux/arch/sparc/defconfig
--- v2.4.4/linux/arch/sparc/defconfig	Sun Mar 25 18:14:21 2001
+++ linux/arch/sparc/defconfig	Wed May 16 10:31:27 2001
@@ -148,7 +148,6 @@
 # CONFIG_INET_ECN is not set
 # CONFIG_SYN_COOKIES is not set
 CONFIG_IPV6=m
-# CONFIG_IPV6_EUI64 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
 
diff -u --recursive --new-file v2.4.4/linux/arch/sparc/kernel/head.S linux/arch/sparc/kernel/head.S
--- v2.4.4/linux/arch/sparc/kernel/head.S	Thu Apr 26 22:17:26 2001
+++ linux/arch/sparc/kernel/head.S	Tue May  1 20:59:24 2001
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.103 2000/05/09 17:40:13 davem Exp $
+/* $Id: head.S,v 1.104 2001/04/27 07:02:41 davem Exp $
  * head.S: The initial boot code for the Sparc port of Linux.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
diff -u --recursive --new-file v2.4.4/linux/arch/sparc/kernel/irq.c linux/arch/sparc/kernel/irq.c
--- v2.4.4/linux/arch/sparc/kernel/irq.c	Thu Apr 26 22:17:26 2001
+++ linux/arch/sparc/kernel/irq.c	Tue May  1 20:59:24 2001
@@ -1,4 +1,4 @@
-/*  $Id: irq.c,v 1.111 2001/04/14 21:13:46 davem Exp $
+/*  $Id: irq.c,v 1.112 2001/04/27 07:02:42 davem Exp $
  *  arch/sparc/kernel/irq.c:  Interrupt request handling routines. On the
  *                            Sparc the IRQ's are basically 'cast in stone'
  *                            and you are supposed to probe the prom's device
diff -u --recursive --new-file v2.4.4/linux/arch/sparc/kernel/sys_sunos.c linux/arch/sparc/kernel/sys_sunos.c
--- v2.4.4/linux/arch/sparc/kernel/sys_sunos.c	Thu Apr 26 22:17:26 2001
+++ linux/arch/sparc/kernel/sys_sunos.c	Tue May  1 20:59:24 2001
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos.c,v 1.133 2001/03/24 09:36:10 davem Exp $
+/* $Id: sys_sunos.c,v 1.134 2001/04/27 07:02:42 davem Exp $
  * sys_sunos.c: SunOS specific syscall compatibility support.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
diff -u --recursive --new-file v2.4.4/linux/arch/sparc/prom/console.c linux/arch/sparc/prom/console.c
--- v2.4.4/linux/arch/sparc/prom/console.c	Thu Apr 26 22:17:26 2001
+++ linux/arch/sparc/prom/console.c	Tue May  1 20:59:24 2001
@@ -1,4 +1,4 @@
-/* $Id: console.c,v 1.23 2000/08/26 02:38:03 anton Exp $
+/* $Id: console.c,v 1.24 2001/04/27 07:02:42 davem Exp $
  * console.c: Routines that deal with sending and receiving IO
  *            to/from the current console device using the PROM.
  *
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/config.in linux/arch/sparc64/config.in
--- v2.4.4/linux/arch/sparc64/config.in	Thu Apr 19 08:38:48 2001
+++ linux/arch/sparc64/config.in	Sun May 20 11:32:07 2001
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.141 2001/04/19 01:52:04 davem Exp $
+# $Id: config.in,v 1.143 2001/05/20 05:14:46 davem Exp $
 # For a description of the syntax of this configuration file,
 # see the Configure script.
 #
@@ -146,9 +146,7 @@
 
    dep_tristate '  SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
 
-   if [ "$CONFIG_BLK_DEV_ST" != "n" ]; then
-      int  'Maximum number of SCSI tapes that can be loaded as modules' CONFIG_ST_EXTRA_DEVS 2
-   fi
+   dep_tristate '  SCSI OnStream SC-x0 tape support' CONFIG_CHR_DEV_OSST $CONFIG_SCSI
 
    dep_tristate '  SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
 
@@ -337,6 +335,15 @@
 source drivers/input/Config.in
 
 source fs/Config.in
+
+mainmenu_option next_comment
+comment 'Sound'
+
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+   source drivers/sound/Config.in
+fi
+endmenu
 
 source drivers/usb/Config.in
 
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.4.4/linux/arch/sparc64/defconfig	Thu Apr 26 22:17:25 2001
+++ linux/arch/sparc64/defconfig	Sun May 20 11:32:07 2001
@@ -178,7 +178,6 @@
 CONFIG_INET_ECN=y
 # CONFIG_SYN_COOKIES is not set
 CONFIG_IPV6=m
-# CONFIG_IPV6_EUI64 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
 
@@ -291,7 +290,7 @@
 CONFIG_BLK_DEV_SD=y
 CONFIG_SD_EXTRA_DEVS=40
 CONFIG_CHR_DEV_ST=y
-CONFIG_ST_EXTRA_DEVS=2
+CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_SR_EXTRA_DEVS=2
@@ -311,7 +310,8 @@
 CONFIG_SCSI_QLOGICPTI=m
 CONFIG_SCSI_AIC7XXX=m
 CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
-CONFIG_AIC7XXX_RESET_DELAY=5000
+CONFIG_AIC7XXX_RESET_DELAY_MS=5000
+# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
 CONFIG_SCSI_AIC7XXX_OLD=m
 CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT=y
 CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8
@@ -547,6 +547,28 @@
 # CONFIG_NLS_UTF8 is not set
 
 #
+# Sound
+#
+CONFIG_SOUND=m
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+CONFIG_SOUND_ES1371=m
+# 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_SONICVIBES is not set
+CONFIG_SOUND_TRIDENT=m
+# 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
+
+#
 # USB support
 #
 CONFIG_USB=y
@@ -561,8 +583,7 @@
 #
 # USB Controllers
 #
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
+CONFIG_USB_UHCI=y
 CONFIG_USB_OHCI=y
 
 #
@@ -573,6 +594,7 @@
 CONFIG_USB_STORAGE=m
 # CONFIG_USB_STORAGE_DEBUG is not set
 CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_DPCM=y
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=m
 
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/Makefile linux/arch/sparc64/kernel/Makefile
--- v2.4.4/linux/arch/sparc64/kernel/Makefile	Thu Apr 12 12:10:25 2001
+++ linux/arch/sparc64/kernel/Makefile	Wed May 16 10:31:27 2001
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.66 2001/04/03 12:29:38 davem Exp $
+# $Id: Makefile,v 1.67 2001/05/11 04:31:55 davem Exp $
 # Makefile for the linux kernel.
 #
 # Note! Dependencies are done automagically by 'make dep', which also
@@ -26,7 +26,7 @@
 		   unaligned.o central.o pci.o starfire.o semaphore.o \
 		   power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o
 
-obj-$(CONFIG_PCI)	 += ebus.o pci_common.o pci_iommu.o \
+obj-$(CONFIG_PCI)	 += ebus.o isa.o pci_common.o pci_iommu.o \
 			    pci_psycho.o pci_sabre.o pci_schizo.o
 obj-$(CONFIG_SMP)	 += smp.o trampoline.o
 obj-$(CONFIG_SPARC32_COMPAT) += sys32.o sys_sparc32.o signal32.o ioctl32.o
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/devices.c linux/arch/sparc64/kernel/devices.c
--- v2.4.4/linux/arch/sparc64/kernel/devices.c	Thu Apr 26 22:17:25 2001
+++ linux/arch/sparc64/kernel/devices.c	Sun May 20 12:11:38 2001
@@ -4,6 +4,7 @@
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/threads.h>
 #include <linux/init.h>
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/ioctl32.c linux/arch/sparc64/kernel/ioctl32.c
--- v2.4.4/linux/arch/sparc64/kernel/ioctl32.c	Thu Apr 12 12:10:25 2001
+++ linux/arch/sparc64/kernel/ioctl32.c	Wed May 16 10:31:27 2001
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.111 2001/03/27 07:28:43 davem Exp $
+/* $Id: ioctl32.c,v 1.115 2001/05/12 06:41:58 davem Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997-2000  Jakub Jelinek  (jakub@redhat.com)
@@ -49,6 +49,7 @@
 #include <linux/blk.h>
 #include <linux/elevator.h>
 #include <linux/rtc.h>
+#include <linux/pci.h>
 #if defined(CONFIG_BLK_DEV_LVM) || defined(CONFIG_BLK_DEV_LVM_MODULE)
 /* Ugh. This header really is not clean */
 #define min min
@@ -514,10 +515,19 @@
 			}
 		}
 		if (!err) {
-			if (i <= ifc32.ifc_len)
+			if (ifc32.ifcbuf == 0) {
+				/* Translate from 64-bit structure multiple to
+				 * a 32-bit one.
+				 */
+				i = ifc.ifc_len;
+				i = ((i / sizeof(struct ifreq)) * sizeof(struct ifreq32));
 				ifc32.ifc_len = i;
-			else
-				ifc32.ifc_len = i - sizeof (struct ifreq32);
+			} else {
+				if (i <= ifc32.ifc_len)
+					ifc32.ifc_len = i;
+				else
+					ifc32.ifc_len = i - sizeof (struct ifreq32);
+			}
 			if (copy_to_user((struct ifconf32 *)arg, &ifc32, sizeof(struct ifconf32)))
 				err = -EFAULT;
 		}
@@ -3369,11 +3379,6 @@
 COMPATIBLE_IOCTL(SIOCSARP)
 COMPATIBLE_IOCTL(SIOCGARP)
 COMPATIBLE_IOCTL(SIOCDARP)
-#if 0 /* XXX No longer exist in new routing code. XXX */
-COMPATIBLE_IOCTL(OLD_SIOCSARP)
-COMPATIBLE_IOCTL(OLD_SIOCGARP)
-COMPATIBLE_IOCTL(OLD_SIOCDARP)
-#endif
 COMPATIBLE_IOCTL(SIOCSRARP)
 COMPATIBLE_IOCTL(SIOCGRARP)
 COMPATIBLE_IOCTL(SIOCDRARP)
@@ -3714,6 +3719,13 @@
 COMPATIBLE_IOCTL(WIOCSTART)
 COMPATIBLE_IOCTL(WIOCSTOP)
 COMPATIBLE_IOCTL(WIOCGSTAT)
+/* Misc. */
+COMPATIBLE_IOCTL(0x41545900)		/* ATYIO_CLKR */
+COMPATIBLE_IOCTL(0x41545901)		/* ATYIO_CLKW */
+COMPATIBLE_IOCTL(PCIIOC_CONTROLLER)
+COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_IO)
+COMPATIBLE_IOCTL(PCIIOC_MMAP_IS_MEM)
+COMPATIBLE_IOCTL(PCIIOC_WRITE_COMBINE)
 /* And these ioctls need translation */
 HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32)
 HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf)
@@ -3991,8 +4003,9 @@
 	} else {
 		static int count = 0;
 		if (++count <= 20)
-			printk("sys32_ioctl: Unknown cmd fd(%d) "
+			printk("sys32_ioctl(%s:%d): Unknown cmd fd(%d) "
 			       "cmd(%08x) arg(%08x)\n",
+			       current->comm, current->pid,
 			       (int)fd, (unsigned int)cmd, (unsigned int)arg);
 		error = -EINVAL;
 	}
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/isa.c linux/arch/sparc64/kernel/isa.c
--- v2.4.4/linux/arch/sparc64/kernel/isa.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/sparc64/kernel/isa.c	Wed May 16 10:31:27 2001
@@ -0,0 +1,269 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <asm/oplib.h>
+#include <asm/isa.h>
+
+struct isa_bridge *isa_chain;
+
+static void __init fatal_err(const char *reason)
+{
+	prom_printf("ISA: fatal error, %s.\n", reason);
+}
+
+static void __init report_dev(struct isa_device *isa_dev, int child)
+{
+	if (child)
+		printk(" (%s)", isa_dev->prom_name);
+	else
+		printk(" [%s", isa_dev->prom_name);
+}
+
+static void __init isa_dev_get_resource(struct isa_device *isa_dev)
+{
+	struct linux_prom_registers regs[PROMREG_MAX];
+	unsigned long base, len;
+	int prop_len;
+
+	prop_len = prom_getproperty(isa_dev->prom_node, "reg",
+				    (char *) regs, sizeof(regs));
+
+	if (prop_len <= 0)
+		return;
+
+	/* Only the first one is interesting. */
+	len = regs[0].reg_size;
+	base = (((unsigned long)regs[0].which_io << 32) |
+		(unsigned long)regs[0].phys_addr);
+	base += isa_dev->bus->parent->io_space.start;
+
+	isa_dev->resource.start = base;
+	isa_dev->resource.end   = (base + len - 1UL);
+	isa_dev->resource.flags = IORESOURCE_IO;
+	isa_dev->resource.name  = isa_dev->prom_name;
+
+	request_resource(&isa_dev->bus->parent->io_space,
+			 &isa_dev->resource);
+}
+
+/* I can't believe they didn't put a real INO in the isa device
+ * interrupts property.  The whole point of the OBP properties
+ * is to shield the kernel from IRQ routing details.
+ *
+ * The P1275 standard for ISA devices seems to also have been
+ * totally ignored.
+ */
+static struct {
+	int	obp_irq;
+	int	pci_ino;
+} grover_irq_table[] = {
+	{ 1, 0x00 },	/* dma, unknown ino at this point */
+	{ 2, 0x27 },	/* floppy */
+	{ 3, 0x22 },	/* parallel */
+	{ 4, 0x2b },	/* serial */
+	{ 5, 0x25 },	/* acpi power management */
+
+	{ 0, 0x00 }	/* end of table */
+};
+
+static void __init isa_dev_get_irq(struct isa_device *isa_dev)
+{
+	int irq_prop;
+
+	irq_prop = prom_getintdefault(isa_dev->prom_node,
+				      "interrupts", -1);
+	if (irq_prop <= 0) {
+		isa_dev->irq = 0;
+	} else {
+		int i;
+
+		for (i = 0; grover_irq_table[i].obp_irq != 0; i++) {
+			if (grover_irq_table[i].obp_irq == irq_prop) {
+				struct pci_controller_info *pcic;
+				struct pci_pbm_info *pbm;
+				int ino = grover_irq_table[i].pci_ino;
+
+				if (ino == 0) {
+					isa_dev->irq = 0;
+				} else {
+					pbm = isa_dev->bus->parent;
+					pcic = pbm->parent;
+					isa_dev->irq = pcic->irq_build(pbm, NULL, ino);
+				}
+			}
+		}
+	}
+}
+
+static void __init isa_fill_children(struct isa_device *parent_isa_dev)
+{
+	int node = prom_getchild(parent_isa_dev->prom_node);
+
+	if (node == 0)
+		return;
+
+	printk(" ->");
+	while (node != 0) {
+		struct isa_device *isa_dev;
+		int prop_len;
+
+		isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
+		if (!isa_dev) {
+			fatal_err("cannot allocate child isa_dev");
+			prom_halt();
+		}
+
+		memset(isa_dev, 0, sizeof(*isa_dev));
+
+		/* Link it in to parent. */
+		isa_dev->next = parent_isa_dev->child;
+		parent_isa_dev->child = isa_dev;
+
+		isa_dev->bus = parent_isa_dev->bus;
+		isa_dev->prom_node = node;
+		prop_len = prom_getproperty(node, "name",
+					    (char *) isa_dev->prom_name,
+					    sizeof(isa_dev->prom_name));
+		if (prop_len <= 0) {
+			fatal_err("cannot get child isa_dev OBP node name");
+			prom_halt();
+		}
+
+		prop_len = prom_getproperty(node, "compatible",
+					    (char *) isa_dev->compatible,
+					    sizeof(isa_dev->compatible));
+
+		/* Not having this is OK. */
+		if (prop_len <= 0)
+			isa_dev->compatible[0] = '\0';
+
+		isa_dev_get_resource(isa_dev);
+		isa_dev_get_irq(isa_dev);
+
+		report_dev(isa_dev, 1);
+
+		node = prom_getsibling(node);
+	}
+}
+
+static void __init isa_fill_devices(struct isa_bridge *isa_br)
+{
+	int node = prom_getchild(isa_br->prom_node);
+
+	while (node != 0) {
+		struct isa_device *isa_dev;
+		int prop_len;
+
+		isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
+		if (!isa_dev) {
+			fatal_err("cannot allocate isa_dev");
+			prom_halt();
+		}
+
+		memset(isa_dev, 0, sizeof(*isa_dev));
+
+		/* Link it in. */
+		isa_dev->next = NULL;
+		if (isa_br->devices == NULL) {
+			isa_br->devices = isa_dev;
+		} else {
+			struct isa_device *tmp = isa_br->devices;
+
+			while (tmp->next)
+				tmp = tmp->next;
+
+			tmp->next = isa_dev;
+		}
+
+		isa_dev->bus = isa_br;
+		isa_dev->prom_node = node;
+		prop_len = prom_getproperty(node, "name",
+					    (char *) isa_dev->prom_name,
+					    sizeof(isa_dev->prom_name));
+		if (prop_len <= 0) {
+			fatal_err("cannot get isa_dev OBP node name");
+			prom_halt();
+		}
+
+		prop_len = prom_getproperty(node, "compatible",
+					    (char *) isa_dev->compatible,
+					    sizeof(isa_dev->compatible));
+
+		/* Not having this is OK. */
+		if (prop_len <= 0)
+			isa_dev->compatible[0] = '\0';
+
+		isa_dev_get_resource(isa_dev);
+		isa_dev_get_irq(isa_dev);
+
+		report_dev(isa_dev, 0);
+
+		isa_fill_children(isa_dev);
+
+		printk("]");
+
+		node = prom_getsibling(node);
+	}
+}
+
+void __init isa_init(void)
+{
+	struct pci_dev *pdev;
+	unsigned short vendor, device;
+	int index = 0;
+
+	vendor = PCI_VENDOR_ID_AL;
+	device = PCI_DEVICE_ID_AL_M1533;
+
+	pdev = NULL;
+	while ((pdev = pci_find_device(vendor, device, pdev)) != NULL) {
+		struct pcidev_cookie *pdev_cookie;
+		struct pci_pbm_info *pbm;
+		struct isa_bridge *isa_br;
+		int prop_len;
+
+		pdev_cookie = pdev->sysdata;
+		if (!pdev_cookie) {
+			printk("ISA: Warning, ISA bridge ignored due to "
+			       "lack of OBP data.\n");
+			continue;
+		}
+		pbm = pdev_cookie->pbm;
+
+		isa_br = kmalloc(sizeof(*isa_br), GFP_KERNEL);
+		if (!isa_br) {
+			fatal_err("cannot allocate isa_bridge");
+			prom_halt();
+		}
+
+		memset(isa_br, 0, sizeof(*isa_br));
+
+		/* Link it in. */
+		isa_br->next = isa_chain;
+		isa_chain = isa_br;
+
+		isa_br->parent = pbm;
+		isa_br->self = pdev;
+		isa_br->index = index++;
+		isa_br->prom_node = pdev_cookie->prom_node;
+		strncpy(isa_br->prom_name, pdev_cookie->prom_name,
+			sizeof(isa_br->prom_name));
+
+		prop_len = prom_getproperty(isa_br->prom_node,
+					    "ranges",
+					    (char *) isa_br->isa_ranges,
+					    sizeof(isa_br->isa_ranges));
+		if (prop_len <= 0)
+			isa_br->num_isa_ranges = 0;
+		else
+			isa_br->num_isa_ranges =
+				(prop_len / sizeof(struct linux_prom_isa_ranges));
+
+		printk("isa%d:", isa_br->index);
+
+		isa_fill_devices(isa_br);
+
+		printk("\n");
+	}
+}
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/pci.c linux/arch/sparc64/kernel/pci.c
--- v2.4.4/linux/arch/sparc64/kernel/pci.c	Thu Apr 12 12:10:25 2001
+++ linux/arch/sparc64/kernel/pci.c	Wed May 16 10:31:27 2001
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.24 2001/03/28 10:56:34 davem Exp $
+/* $Id: pci.c,v 1.29 2001/05/15 08:54:30 davem Exp $
  * pci.c: UltraSparc PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com)
@@ -19,6 +19,7 @@
 #include <asm/pbm.h>
 #include <asm/irq.h>
 #include <asm/ebus.h>
+#include <asm/isa.h>
 
 unsigned long pci_memspace_mask = 0xffffffffUL;
 
@@ -77,13 +78,13 @@
 volatile int pci_poke_faulted;
 
 /* Probe for all PCI controllers in the system. */
-extern void sabre_init(int);
-extern void psycho_init(int);
-extern void schizo_init(int);
+extern void sabre_init(int, char *);
+extern void psycho_init(int, char *);
+extern void schizo_init(int, char *);
 
 static struct {
 	char *model_name;
-	void (*init)(int);
+	void (*init)(int, char *);
 } pci_controller_table[] = {
 	{ "SUNW,sabre", sabre_init },
 	{ "pci108e,a000", sabre_init },
@@ -104,7 +105,7 @@
 		if (!strncmp(model_name,
 			     pci_controller_table[i].model_name,
 			     namelen)) {
-			pci_controller_table[i].init(node);
+			pci_controller_table[i].init(node, model_name);
 			return;
 		}
 	}
@@ -187,6 +188,7 @@
 	if (pci_device_reorder)
 		pci_reorder_devs();
 
+	isa_init();
 	ebus_init();
 }
 
@@ -232,6 +234,149 @@
 		return NULL;
 	}
 	return str;
+}
+
+/* Platform support for /proc/bus/pci/X/Y mmap()s. */
+
+/* Adjust vm_pgoff of VMA such that it is the physical page offset corresponding
+ * to the 32-bit pci bus offset for DEV requested by the user.
+ *
+ * Basically, the user finds the base address for his device which he wishes
+ * to mmap.  They read the 32-bit value from the config space base register,
+ * add whatever PAGE_SIZE multiple offset they wish, and feed this into the
+ * offset parameter of mmap on /proc/bus/pci/XXX for that device.
+ *
+ * Returns negative error code on failure, zero on success.
+ */
+static __inline__ int __pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma,
+					     enum pci_mmap_state mmap_state)
+{
+	unsigned long user_offset = vma->vm_pgoff << PAGE_SHIFT;
+	unsigned long user32 = user_offset & 0xffffffffUL;
+	unsigned long largest_base, this_base, addr32;
+	int i;
+
+	/* Figure out which base address this is for. */
+	largest_base = 0UL;
+	for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
+		struct resource *rp = &dev->resource[i];
+
+		/* Active? */
+		if (!rp->flags)
+			continue;
+
+		/* Same type? */
+		if (i == PCI_ROM_RESOURCE) {
+			if (mmap_state != pci_mmap_mem)
+				continue;
+		} else {
+			if ((mmap_state == pci_mmap_io &&
+			     (rp->flags & IORESOURCE_IO) == 0) ||
+			    (mmap_state == pci_mmap_mem &&
+			     (rp->flags & IORESOURCE_MEM) == 0))
+				continue;
+		}
+
+		this_base = rp->start;
+
+		addr32 = (this_base & PAGE_MASK) & 0xffffffffUL;
+
+		if (mmap_state == pci_mmap_io)
+			addr32 &= 0xffffff;
+
+		if (addr32 <= user32 && this_base > largest_base)
+			largest_base = this_base;
+	}
+
+	if (largest_base == 0UL)
+		return -EINVAL;
+
+	/* Now construct the final physical address. */
+	if (mmap_state == pci_mmap_io)
+		vma->vm_pgoff = (((largest_base & ~0xffffffUL) | user32) >> PAGE_SHIFT);
+	else
+		vma->vm_pgoff = (((largest_base & ~0xffffffffUL) | user32) >> PAGE_SHIFT);
+
+	return 0;
+}
+
+/* Set vm_flags of VMA, as appropriate for this architecture, for a pci device
+ * mapping.
+ */
+static __inline__ void __pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma,
+					    enum pci_mmap_state mmap_state)
+{
+	vma->vm_flags |= (VM_SHM | VM_LOCKED);
+}
+
+/* Set vm_page_prot of VMA, as appropriate for this architecture, for a pci
+ * device mapping.
+ */
+static __inline__ void __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma,
+					     enum pci_mmap_state mmap_state)
+{
+	/* Our io_remap_page_range takes care of this, do nothing. */
+}
+
+extern int io_remap_page_range(unsigned long from, unsigned long offset,
+			       unsigned long size, pgprot_t prot, int space);
+
+/* Perform the actual remap of the pages for a PCI device mapping, as appropriate
+ * for this architecture.  The region in the process to map is described by vm_start
+ * and vm_end members of VMA, the base physical address is found in vm_pgoff.
+ * The pci device structure is provided so that architectures may make mapping
+ * decisions on a per-device or per-bus basis.
+ *
+ * Returns a negative error code on failure, zero on success.
+ */
+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
+			enum pci_mmap_state mmap_state,
+			int write_combine)
+{
+	int ret;
+
+	ret = __pci_mmap_make_offset(dev, vma, mmap_state);
+	if (ret < 0)
+		return ret;
+
+	__pci_mmap_set_flags(dev, vma, mmap_state);
+	__pci_mmap_set_pgprot(dev, vma, mmap_state);
+
+	ret = io_remap_page_range(vma->vm_start,
+				  (vma->vm_pgoff << PAGE_SHIFT |
+				   (write_combine ? 0x1UL : 0x0UL)),
+				  vma->vm_end - vma->vm_start, vma->vm_page_prot, 0);
+	if (ret)
+		return ret;
+
+	vma->vm_flags |= VM_IO;
+	return 0;
+}
+
+/* Return the index of the PCI controller for device PDEV. */
+
+int pci_controller_num(struct pci_dev *pdev)
+{
+	struct pcidev_cookie *cookie = pdev->sysdata;
+	int ret;
+
+	if (cookie != NULL) {
+		struct pci_pbm_info *pbm = cookie->pbm;
+		if (pbm == NULL || pbm->parent == NULL) {
+			ret = -ENXIO;
+		} else {
+			struct pci_controller_info *p = pbm->parent;
+
+			ret = p->index;
+			if (p->pbms_same_domain == 0)
+				ret = ((ret << 1) +
+				       ((pbm == &pbm->parent->pbm_B) ? 1 : 0));
+		}
+	} else {
+		ret = -ENXIO;
+	}
+
+	return ret;
 }
 
 #endif /* !(CONFIG_PCI) */
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/pci_common.c linux/arch/sparc64/kernel/pci_common.c
--- v2.4.4/linux/arch/sparc64/kernel/pci_common.c	Tue Mar  6 22:44:16 2001
+++ linux/arch/sparc64/kernel/pci_common.c	Sat May 19 18:13:15 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_common.c,v 1.14 2001/02/28 03:28:55 davem Exp $
+/* $Id: pci_common.c,v 1.18 2001/05/18 23:06:35 davem Exp $
  * pci_common.c: PCI controller common support.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -10,6 +10,29 @@
 
 #include <asm/pbm.h>
 
+/* Fix self device of BUS and hook it into BUS->self.
+ * The pci_scan_bus does not do this for the host bridge.
+ */
+void __init pci_fixup_host_bridge_self(struct pci_bus *pbus)
+{
+	struct list_head *walk = &pbus->devices;
+
+	walk = walk->next;
+	while (walk != &pbus->devices) {
+		struct pci_dev *pdev = pci_dev_b(walk);
+
+		if (pdev->class >> 8 == PCI_CLASS_BRIDGE_HOST) {
+			pbus->self = pdev;
+			return;
+		}
+
+		walk = walk->next;
+	}
+
+	prom_printf("PCI: Critical error, cannot find host bridge PDEV.\n");
+	prom_halt();
+}
+
 /* Find the OBP PROM device tree node for a PCI device.
  * Return zero if not found.
  */
@@ -29,7 +52,10 @@
 	 */
 	if ((pdev->bus->number == pbm->pci_bus->number) && (pdev->devfn == 0) &&
 	    (pdev->vendor == PCI_VENDOR_ID_SUN) &&
-	    (pdev->device == PCI_DEVICE_ID_SUN_PBM)) {
+	    (pdev->device == PCI_DEVICE_ID_SUN_PBM ||
+	     pdev->device == PCI_DEVICE_ID_SUN_SCHIZO ||
+	     pdev->device == PCI_DEVICE_ID_SUN_SABRE ||
+	     pdev->device == PCI_DEVICE_ID_SUN_HUMMINGBIRD)) {
 		*nregs = 0;
 		return bus_prom_node;
 	}
@@ -474,15 +500,21 @@
 
 static int __init pci_intmap_match(struct pci_dev *pdev, unsigned int *interrupt)
 {
+	struct linux_prom_pci_intmap bridge_local_intmap[PROM_PCIIMAP_MAX], *intmap;
+	struct linux_prom_pci_intmask bridge_local_intmask, *intmask;
 	struct pcidev_cookie *dev_pcp = pdev->sysdata;
 	struct pci_pbm_info *pbm = dev_pcp->pbm;
 	struct linux_prom_pci_registers *pregs = dev_pcp->prom_regs;
 	unsigned int hi, mid, lo, irq;
-	int i;
+	int i, num_intmap;
 
 	if (pbm->num_pbm_intmap == 0)
 		return 0;
 
+	intmap = &pbm->pbm_intmap[0];
+	intmask = &pbm->pbm_intmask;
+	num_intmap = pbm->num_pbm_intmap;
+
 	/* If we are underneath a PCI bridge, use PROM register
 	 * property of the parent bridge which is closest to
 	 * the PBM.
@@ -490,7 +522,7 @@
 	if (pdev->bus->number != pbm->pci_first_busno) {
 		struct pcidev_cookie *bus_pcp;
 		struct pci_dev *pwalk;
-		int offset;
+		int offset, plen;
 
 		pwalk = pdev->bus->self;
 		while (pwalk->bus &&
@@ -498,6 +530,27 @@
 			pwalk = pwalk->bus->self;
 
 		bus_pcp = pwalk->sysdata;
+
+		/* But if the PCI bridge has it's own interrupt map
+		 * and mask properties, use that and the device regs.
+		 */
+		plen = prom_getproperty(bus_pcp->prom_node, "interrupt-map",
+					(char *) &bridge_local_intmap[0],
+					sizeof(bridge_local_intmap));
+		if (plen != -1) {
+			intmap = &bridge_local_intmap[0];
+			num_intmap = plen / sizeof(struct linux_prom_pci_intmap);
+			plen = prom_getproperty(bus_pcp->prom_node, "interrupt-map-mask",
+						(char *) &bridge_local_intmask,
+						sizeof(bridge_local_intmask));
+			if (plen == -1) {
+				prom_printf("pbm_intmap_match: Bridge has intmap but "
+					    "no intmask.\n");
+				prom_halt();
+			}
+			goto check_intmap;
+		}
+
 		pregs = bus_pcp->prom_regs;
 
 		offset = prom_getint(dev_pcp->prom_node,
@@ -518,17 +571,18 @@
 		}
 	}
 
-	hi   = pregs->phys_hi & pbm->pbm_intmask.phys_hi;
-	mid  = pregs->phys_mid & pbm->pbm_intmask.phys_mid;
-	lo   = pregs->phys_lo & pbm->pbm_intmask.phys_lo;
-	irq  = *interrupt & pbm->pbm_intmask.interrupt;
-
-	for (i = 0; i < pbm->num_pbm_intmap; i++) {
-		if (pbm->pbm_intmap[i].phys_hi  == hi	&&
-		    pbm->pbm_intmap[i].phys_mid == mid	&&
-		    pbm->pbm_intmap[i].phys_lo  == lo	&&
-		    pbm->pbm_intmap[i].interrupt == irq) {
-			*interrupt = pbm->pbm_intmap[i].cinterrupt;
+check_intmap:
+	hi   = pregs->phys_hi & intmask->phys_hi;
+	mid  = pregs->phys_mid & intmask->phys_mid;
+	lo   = pregs->phys_lo & intmask->phys_lo;
+	irq  = *interrupt & intmask->interrupt;
+
+	for (i = 0; i < num_intmap; i++) {
+		if (intmap[i].phys_hi  == hi	&&
+		    intmap[i].phys_mid == mid	&&
+		    intmap[i].phys_lo  == lo	&&
+		    intmap[i].interrupt == irq) {
+			*interrupt = intmap[i].cinterrupt;
 			return 1;
 		}
 	}
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/pci_impl.h linux/arch/sparc64/kernel/pci_impl.h
--- v2.4.4/linux/arch/sparc64/kernel/pci_impl.h	Thu Apr 12 12:10:25 2001
+++ linux/arch/sparc64/kernel/pci_impl.h	Wed May 16 10:31:27 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_impl.h,v 1.7 2001/03/28 10:56:34 davem Exp $
+/* $Id: pci_impl.h,v 1.8 2001/05/15 08:54:30 davem Exp $
  * pci_impl.h: Helper definitions for PCI controller support.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -19,6 +19,7 @@
 extern int pci_num_controllers;
 
 /* PCI bus scanning and fixup support. */
+extern void pci_fixup_host_bridge_self(struct pci_bus *pbus);
 extern void pci_fill_in_pbm_cookies(struct pci_bus *pbus,
 				    struct pci_pbm_info *pbm,
 				    int prom_node);
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/pci_psycho.c linux/arch/sparc64/kernel/pci_psycho.c
--- v2.4.4/linux/arch/sparc64/kernel/pci_psycho.c	Thu Apr 19 08:38:49 2001
+++ linux/arch/sparc64/kernel/pci_psycho.c	Wed May 16 10:31:27 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_psycho.c,v 1.22 2001/04/17 01:19:23 davem Exp $
+/* $Id: pci_psycho.c,v 1.24 2001/05/15 08:54:30 davem Exp $
  * pci_psycho.c: PSYCHO/U2P specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -1235,9 +1235,23 @@
 static void __init pbm_scan_bus(struct pci_controller_info *p,
 				struct pci_pbm_info *pbm)
 {
+	struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
+
+	if (!cookie) {
+		prom_printf("PSYCHO: Critical allocation failure.\n");
+		prom_halt();
+	}
+
+	/* All we care about is the PBM. */
+	memset(cookie, 0, sizeof(*cookie));
+	cookie->pbm = pbm;
+
 	pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno,
 				    p->pci_ops,
 				    pbm);
+	pci_fixup_host_bridge_self(pbm->pci_bus);
+	pbm->pci_bus->self->sysdata = cookie;
+
 	pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
 	pci_record_assignments(pbm, pbm->pci_bus);
 	pci_assign_unassigned(pbm, pbm->pci_bus);
@@ -1521,7 +1535,7 @@
 
 #define PSYCHO_CONFIGSPACE	0x001000000UL
 
-void __init psycho_init(int node)
+void __init psycho_init(int node, char *model_name)
 {
 	struct linux_prom64_registers pr_regs[3];
 	struct pci_controller_info *p;
@@ -1564,6 +1578,7 @@
 
 	p->portid = upa_portid;
 	p->index = pci_num_controllers++;
+	p->pbms_same_domain = 0;
 	p->scan_bus = psycho_scan_bus;
 	p->irq_build = psycho_irq_build;
 	p->base_address_update = psycho_base_address_update;
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/pci_sabre.c linux/arch/sparc64/kernel/pci_sabre.c
--- v2.4.4/linux/arch/sparc64/kernel/pci_sabre.c	Thu Apr 26 22:17:25 2001
+++ linux/arch/sparc64/kernel/pci_sabre.c	Wed May 16 10:31:27 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_sabre.c,v 1.27 2001/04/24 05:14:12 davem Exp $
+/* $Id: pci_sabre.c,v 1.32 2001/05/15 11:10:01 davem Exp $
  * pci_sabre.c: Sabre specific PCI controller support.
  *
  * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -215,7 +215,7 @@
 	 ((unsigned long)(DEVFN) << 8)  |	\
 	 ((unsigned long)(REG)))
 
-static int apb_present;
+static int hummingbird_p;
 
 static void *sabre_pci_config_mkaddr(struct pci_pbm_info *pbm,
 				     unsigned char bus,
@@ -231,7 +231,7 @@
 
 static int sabre_out_of_range(unsigned char devfn)
 {
-	if (!apb_present)
+	if (hummingbird_p)
 		return 0;
 
 	return (((PCI_SLOT(devfn) == 0) && (PCI_FUNC(devfn) > 0)) ||
@@ -243,7 +243,7 @@
 				unsigned char bus,
 				unsigned char devfn)
 {
-	if (!apb_present)
+	if (hummingbird_p)
 		return 0;
 
 	return ((pbm->parent == 0) ||
@@ -1112,11 +1112,28 @@
 	}
 }
 
+static struct pcidev_cookie *alloc_bridge_cookie(struct pci_pbm_info *pbm)
+{
+	struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
+
+	if (!cookie) {
+		prom_printf("SABRE: Critical allocation failure.\n");
+		prom_halt();
+	}
+
+	/* All we care about is the PBM. */
+	memset(cookie, 0, sizeof(*cookie));
+	cookie->pbm = pbm;
+
+	return cookie;
+}
+
 static void __init sabre_scan_bus(struct pci_controller_info *p)
 {
 	static int once = 0;
 	struct pci_bus *sabre_bus;
 	struct pci_pbm_info *pbm;
+	struct pcidev_cookie *cookie;
 	struct list_head *walk;
 	int sabres_scanned;
 
@@ -1142,10 +1159,15 @@
 	}
 	once++;
 
+	cookie = alloc_bridge_cookie(&p->pbm_A);
+
 	/* The pci_bus2pbm table has already been setup in sabre_init. */
 	sabre_bus = pci_scan_bus(p->pci_first_busno,
 				 p->pci_ops,
 				 &p->pbm_A);
+	pci_fixup_host_bridge_self(sabre_bus);
+	sabre_bus->self->sysdata = cookie;
+
 	apb_init(p, sabre_bus);
 
 	sabres_scanned = 0;
@@ -1161,6 +1183,9 @@
 		} else
 			continue;
 
+		cookie = alloc_bridge_cookie(pbm);
+		pbus->self->sysdata = cookie;
+
 		sabres_scanned++;
 
 		pbus->sysdata = pbm;
@@ -1444,6 +1469,11 @@
 			memset(&pbm->pbm_intmask, 0, sizeof(pbm->pbm_intmask));
 		}
 
+
+		sprintf(pbm->name, "SABRE%d PBM%c", p->index,
+			(pbm == &p->pbm_A ? 'A' : 'B'));
+		pbm->io_space.name = pbm->mem_space.name = pbm->name;
+
 		/* Hack up top-level resources. */
 		pbm->io_space.start = p->controller_regs + SABRE_IOSPACE;
 		pbm->io_space.end   = pbm->io_space.start + (1UL << 16) - 1UL;
@@ -1461,12 +1491,10 @@
 			prom_printf("Cannot register Hummingbird's MEM space.\n");
 			prom_halt();
 		}
-	} else {
-		apb_present = 1;
 	}
 }
 
-void __init sabre_init(int pnode)
+void __init sabre_init(int pnode, char *model_name)
 {
 	struct linux_prom64_registers pr_regs[2];
 	struct pci_controller_info *p;
@@ -1478,6 +1506,18 @@
 	u32 upa_portid, dma_mask;
 	int bus;
 
+	hummingbird_p = 0;
+	if (!strcmp(model_name, "pci108e,a001"))
+		hummingbird_p = 1;
+	else if (!strcmp(model_name, "SUNW,sabre")) {
+		char compat[64];
+
+		if (prom_getproperty(pnode, "compatible",
+				     compat, sizeof(compat)) > 0 &&
+		    !strcmp(compat, "pci108e,a001"))
+			hummingbird_p = 1;
+	}
+
 	p = kmalloc(sizeof(*p), GFP_ATOMIC);
 	if (!p) {
 		prom_printf("SABRE: Error, kmalloc(pci_controller_info) failed.\n");
@@ -1502,6 +1542,7 @@
 
 	p->portid = upa_portid;
 	p->index = pci_num_controllers++;
+	p->pbms_same_domain = 1;
 	p->scan_bus = sabre_scan_bus;
 	p->irq_build = sabre_irq_build;
 	p->base_address_update = sabre_base_address_update;
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/pci_schizo.c linux/arch/sparc64/kernel/pci_schizo.c
--- v2.4.4/linux/arch/sparc64/kernel/pci_schizo.c	Thu Apr 19 08:38:49 2001
+++ linux/arch/sparc64/kernel/pci_schizo.c	Wed May 16 10:31:27 2001
@@ -1,4 +1,4 @@
-/* $Id: pci_schizo.c,v 1.14 2001/04/17 01:19:23 davem Exp $
+/* $Id: pci_schizo.c,v 1.16 2001/05/15 08:54:30 davem Exp $
  * pci_schizo.c: SCHIZO specific PCI controller support.
  *
  * Copyright (C) 2001 David S. Miller (davem@redhat.com)
@@ -1328,9 +1328,23 @@
 static void __init pbm_scan_bus(struct pci_controller_info *p,
 				struct pci_pbm_info *pbm)
 {
+	struct pcidev_cookie *cookie = kmalloc(sizeof(*cookie), GFP_KERNEL);
+
+	if (!cookie) {
+		prom_printf("SCHIZO: Critical allocation failure.\n");
+		prom_halt();
+	}
+
+	/* All we care about is the PBM. */
+	memset(cookie, 0, sizeof(*cookie));
+	cookie->pbm = pbm;
+
 	pbm->pci_bus = pci_scan_bus(pbm->pci_first_busno,
 				    p->pci_ops,
 				    pbm);
+	pci_fixup_host_bridge_self(pbm->pci_bus);
+	pbm->pci_bus->self->sysdata = cookie;
+
 	pci_fill_in_pbm_cookies(pbm->pci_bus, pbm, pbm->prom_node);
 	pci_record_assignments(pbm, pbm->pci_bus);
 	pci_assign_unassigned(pbm, pbm->pci_bus);
@@ -1709,7 +1723,7 @@
 	schizo_write(pbm_b_base + 0x2000UL, tmp);
 }
 
-void __init schizo_init(int node)
+void __init schizo_init(int node, char *model_name)
 {
 	struct linux_prom64_registers pr_regs[3];
 	struct pci_controller_info *p;
@@ -1761,6 +1775,7 @@
 
 	p->portid = portid;
 	p->index = pci_num_controllers++;
+	p->pbms_same_domain = 0;
 	p->scan_bus = schizo_scan_bus;
 	p->irq_build = schizo_irq_build;
 	p->base_address_update = schizo_base_address_update;
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/semaphore.c linux/arch/sparc64/kernel/semaphore.c
--- v2.4.4/linux/arch/sparc64/kernel/semaphore.c	Tue Apr 17 17:19:30 2001
+++ linux/arch/sparc64/kernel/semaphore.c	Sun May 20 11:32:07 2001
@@ -1,128 +1,88 @@
-/* $Id: semaphore.c,v 1.6 2001/04/14 01:12:02 davem Exp $
- *  Generic semaphore code. Buyer beware. Do your own
- * specific changes in <asm/semaphore-helper.h>
+/* $Id: semaphore.c,v 1.8 2001/05/18 08:01:35 davem Exp $
+ * semaphore.c: Sparc64 semaphore implementation.
+ *
+ * This is basically the PPC semaphore scheme ported to use
+ * the sparc64 atomic instructions, so see the PPC code for
+ * credits.
  */
 
 #include <linux/sched.h>
-#include <asm/semaphore-helper.h>
 
 /*
- * Semaphores are implemented using a two-way counter:
- * The "count" variable is decremented for each process
- * that tries to sleep, while the "waking" variable is
- * incremented when the "up()" code goes to wake up waiting
- * processes.
- *
- * Notably, the inline "up()" and "down()" functions can
- * efficiently test if they need to do any extra work (up
- * needs to do something only if count was negative before
- * the increment operation.
- *
- * waking_non_zero() (from asm/semaphore.h) must execute
- * atomically.
- *
- * When __up() is called, the count was negative before
- * incrementing it, and we need to wake up somebody.
+ * Atomically update sem->count.
+ * This does the equivalent of the following:
  *
- * This routine adds one to the count of processes that need to
- * wake up and exit.  ALL waiting processes actually wake up but
- * only the one that gets to the "waking" field first will gate
- * through and acquire the semaphore.  The others will go back
- * to sleep.
- *
- * Note that these functions are only called when there is
- * contention on the lock, and as such all this is the
- * "non-critical" part of the whole semaphore business. The
- * critical part is the inline stuff in <asm/semaphore.h>
- * where we want to avoid any extra jumps and calls.
+ *	old_count = sem->count;
+ *	tmp = MAX(old_count, 0) + incr;
+ *	sem->count = tmp;
+ *	return old_count;
  */
+static __inline__ int __sem_update_count(struct semaphore *sem, int incr)
+{
+	int old_count, tmp;
+
+	__asm__ __volatile__("\n"
+"	! __sem_update_count old_count(%0) tmp(%1) incr(%4) &sem->count(%3)\n"
+"1:	ldsw	[%3], %0\n"
+"	mov	%0, %1\n"
+"	cmp	%0, 0\n"
+"	movl	%%icc, 0, %1\n"
+"	add	%1, %4, %1\n"
+"	cas	[%3], %0, %1\n"
+"	cmp	%0, %1\n"
+"	bne,pn	%%icc, 1b\n"
+"	 nop\n"
+	: "=&r" (old_count), "=&r" (tmp), "=m" (sem->count)
+	: "r" (&sem->count), "r" (incr), "m" (sem->count)
+	: "cc");
+
+	return old_count;
+}
+
 void __up(struct semaphore *sem)
 {
-	wake_one_more(sem);
+	__sem_update_count(sem, 1);
 	wake_up(&sem->wait);
 }
 
-/*
- * Perform the "down" function.  Return zero for semaphore acquired,
- * return negative for signalled out of the function.
- *
- * If called from __down, the return is ignored and the wait loop is
- * not interruptible.  This means that a task waiting on a semaphore
- * using "down()" cannot be killed until someone does an "up()" on
- * the semaphore.
- *
- * If called from __down_interruptible, the return value gets checked
- * upon return.  If the return value is negative then the task continues
- * with the negative value in the return register (it can be tested by
- * the caller).
- *
- * Either form may be used in conjunction with "up()".
- *
- */
-
-#define DOWN_VAR				\
-	struct task_struct *tsk = current;	\
+void __down(struct semaphore * sem)
+{
+	struct task_struct *tsk = current;
 	DECLARE_WAITQUEUE(wait, tsk);
 
-#define DOWN_HEAD(task_state)						\
-									\
-									\
-	tsk->state = (task_state);					\
-	add_wait_queue(&sem->wait, &wait);				\
-									\
-	/*								\
-	 * Ok, we're set up.  sem->count is known to be less than zero	\
-	 * so we must wait.						\
-	 *								\
-	 * We can let go the lock for purposes of waiting.		\
-	 * We re-acquire it after awaking so as to protect		\
-	 * all semaphore operations.					\
-	 *								\
-	 * If "up()" is called before we call waking_non_zero() then	\
-	 * we will catch it right away.  If it is called later then	\
-	 * we will have to go through a wakeup cycle to catch it.	\
-	 *								\
-	 * Multiple waiters contend for the semaphore lock to see	\
-	 * who gets to gate through and who has to wait some more.	\
-	 */								\
-	for (;;) {
-
-#define DOWN_TAIL(task_state)			\
-		tsk->state = (task_state);	\
-	}					\
-	tsk->state = TASK_RUNNING;		\
+	tsk->state = TASK_UNINTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	while (__sem_update_count(sem, -1) <= 0) {
+		schedule();
+		tsk->state = TASK_UNINTERRUPTIBLE;
+	}
 	remove_wait_queue(&sem->wait, &wait);
+	tsk->state = TASK_RUNNING;
 
-void __down(struct semaphore * sem)
-{
-	DOWN_VAR
-	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
-	if (waking_non_zero(sem))
-		break;
-	schedule();
-	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+	wake_up(&sem->wait);
 }
 
 int __down_interruptible(struct semaphore * sem)
 {
-	int ret = 0;
-	DOWN_VAR
-	DOWN_HEAD(TASK_INTERRUPTIBLE)
-
-	ret = waking_non_zero_interruptible(sem, tsk);
-	if (ret)
-	{
-		if (ret == 1)
-			/* ret != 0 only if we get interrupted -arca */
-			ret = 0;
-		break;
-	}
-	schedule();
-	DOWN_TAIL(TASK_INTERRUPTIBLE)
-	return ret;
-}
+	int retval = 0;
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
 
-int __down_trylock(struct semaphore * sem)
-{
-	return waking_non_zero_trylock(sem);
+	tsk->state = TASK_INTERRUPTIBLE;
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	while (__sem_update_count(sem, -1) <= 0) {
+		if (signal_pending(current)) {
+			__sem_update_count(sem, 0);
+			retval = -EINTR;
+			break;
+		}
+		schedule();
+		tsk->state = TASK_INTERRUPTIBLE;
+	}
+	tsk->state = TASK_RUNNING;
+	remove_wait_queue(&sem->wait, &wait);
+	wake_up(&sem->wait);
+	return retval;
 }
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/sparc64_ksyms.c linux/arch/sparc64/kernel/sparc64_ksyms.c
--- v2.4.4/linux/arch/sparc64/kernel/sparc64_ksyms.c	Fri Apr 13 20:15:55 2001
+++ linux/arch/sparc64/kernel/sparc64_ksyms.c	Sun May 20 11:32:07 2001
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.105 2001/04/14 01:12:02 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.107 2001/05/18 08:01:35 davem Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -47,6 +47,7 @@
 #endif
 #ifdef CONFIG_PCI
 #include <asm/ebus.h>
+#include <asm/isa.h>
 #endif
 #include <asm/a.out.h>
 
@@ -156,7 +157,6 @@
 /* semaphores */
 EXPORT_SYMBOL(__down);
 EXPORT_SYMBOL(__down_interruptible);
-EXPORT_SYMBOL(__down_trylock);
 EXPORT_SYMBOL(__up);
 
 /* Atomic counter implementation. */
@@ -199,6 +199,7 @@
 #endif
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL(ebus_chain);
+EXPORT_SYMBOL(isa_chain);
 EXPORT_SYMBOL(pci_memspace_mask);
 EXPORT_SYMBOL(empty_zero_page);
 EXPORT_SYMBOL(outsb);
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/kernel/sys_sunos32.c linux/arch/sparc64/kernel/sys_sunos32.c
--- v2.4.4/linux/arch/sparc64/kernel/sys_sunos32.c	Thu Apr 26 22:17:26 2001
+++ linux/arch/sparc64/kernel/sys_sunos32.c	Tue May  1 20:59:24 2001
@@ -1,4 +1,4 @@
-/* $Id: sys_sunos32.c,v 1.59 2001/03/24 09:36:11 davem Exp $
+/* $Id: sys_sunos32.c,v 1.60 2001/04/27 07:02:42 davem Exp $
  * sys_sunos32.c: SunOS binary compatability layer on sparc64.
  *
  * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
diff -u --recursive --new-file v2.4.4/linux/arch/sparc64/mm/init.c linux/arch/sparc64/mm/init.c
--- v2.4.4/linux/arch/sparc64/mm/init.c	Thu Apr 26 22:17:25 2001
+++ linux/arch/sparc64/mm/init.c	Wed May 16 10:20:11 2001
@@ -1,4 +1,4 @@
-/*  $Id: init.c,v 1.175 2001/04/24 01:09:12 davem Exp $
+/*  $Id: init.c,v 1.176 2001/05/16 15:07:11 davem Exp $
  *  arch/sparc64/mm/init.c
  *
  *  Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -1139,8 +1139,16 @@
 	unsigned long second_alias_page = 0;
 	unsigned long pt, flags, end_pfn, pages_avail;
 	unsigned long shift = alias_base - ((unsigned long)&empty_zero_page);
+	unsigned long real_end;
 
 	set_bit(0, mmu_context_bmap);
+
+	real_end = (unsigned long)&_end;
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (sparc_ramdisk_image)
+		real_end = (PAGE_ALIGN(real_end) + PAGE_ALIGN(sparc_ramdisk_size));
+#endif
+
 	/* We assume physical memory starts at some 4mb multiple,
 	 * if this were not true we wouldn't boot up to this point
 	 * anyways.
@@ -1161,7 +1169,7 @@
 		: "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt),
 		  "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" (61 << 3)
 		: "memory");
-		if (((unsigned long)&_end) >= KERNBASE + 0x340000) {
+		if (real_end >= KERNBASE + 0x340000) {
 			second_alias_page = alias_base + 0x400000;
 			__asm__ __volatile__(
 		"	stxa	%1, [%0] %3\n"
@@ -1189,7 +1197,7 @@
 		: "r" (TLB_TAG_ACCESS), "r" (alias_base), "r" (pt),
 		  "i" (ASI_DMMU), "i" (ASI_DTLB_DATA_ACCESS), "r" ((0<<16) | (13<<3))
 		: "memory");
-		if (((unsigned long)&_end) >= KERNBASE + 0x340000) {
+		if (real_end >= KERNBASE + 0x340000) {
 			second_alias_page = alias_base + 0x400000;
 			__asm__ __volatile__(
 		"	stxa	%1, [%0] %3\n"
diff -u --recursive --new-file v2.4.4/linux/drivers/Makefile linux/drivers/Makefile
--- v2.4.4/linux/drivers/Makefile	Fri Dec 29 14:07:21 2000
+++ linux/drivers/Makefile	Wed May 16 10:27:02 2001
@@ -9,7 +9,7 @@
 mod-subdirs :=	dio mtd sbus video macintosh usb input telephony sgi i2o ide \
 		scsi md ieee1394 pnp isdn atm fc4 net/hamradio i2c acpi
 
-subdir-y :=	block char net parport sound misc media cdrom
+subdir-y :=	parport char block net sound misc media cdrom
 subdir-m :=	$(subdir-y)
 
 
diff -u --recursive --new-file v2.4.4/linux/drivers/acorn/block/mfmhd.c linux/drivers/acorn/block/mfmhd.c
--- v2.4.4/linux/drivers/acorn/block/mfmhd.c	Thu Oct 26 23:35:47 2000
+++ linux/drivers/acorn/block/mfmhd.c	Sat Apr 28 11:27:53 2001
@@ -1485,14 +1485,7 @@
 
 	for (i = maxp - 1; i >= 0; i--) {
 		int minor = start + i;
-		kdev_t devi = MKDEV(MAJOR_NR, minor);
-		struct super_block *sb = get_super(devi);
-
-		sync_dev (devi);
-		if (sb)
-			invalidate_inodes (sb);
-		invalidate_buffers (devi);
-
+		invalidate_device (MKDEV(MAJOR_NR, minor), 1);
 		mfm_gendisk.part[minor].start_sect = 0;
 		mfm_gendisk.part[minor].nr_sects = 0;
 	}
diff -u --recursive --new-file v2.4.4/linux/drivers/acpi/driver.c linux/drivers/acpi/driver.c
--- v2.4.4/linux/drivers/acpi/driver.c	Fri Feb  9 11:45:58 2001
+++ linux/drivers/acpi/driver.c	Tue May 22 09:38:51 2001
@@ -311,8 +311,10 @@
 		size = buf.length - file->f_pos;
 		if (size > *len)
 			size = *len;
-		if (copy_to_user(buffer, data, size))
+		if (copy_to_user(buffer, data, size)) {
+			kfree(buf.pointer);
 			return -EFAULT;
+		}
 	}
 
 	kfree(buf.pointer);
diff -u --recursive --new-file v2.4.4/linux/drivers/atm/eni.c linux/drivers/atm/eni.c
--- v2.4.4/linux/drivers/atm/eni.c	Thu Jul  6 21:37:24 2000
+++ linux/drivers/atm/eni.c	Wed May 16 10:22:50 2001
@@ -1796,6 +1796,7 @@
 		return -EAGAIN;
 	}
 	/* @@@ should release IRQ on error */
+	pci_set_master(eni_dev->pci_dev);
 	if ((error = pci_write_config_word(eni_dev->pci_dev,PCI_COMMAND,
 	    PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
 	    (eni_dev->asic ? PCI_COMMAND_PARITY | PCI_COMMAND_SERR : 0)))) {
diff -u --recursive --new-file v2.4.4/linux/drivers/block/DAC960.c linux/drivers/block/DAC960.c
--- v2.4.4/linux/drivers/block/DAC960.c	Tue Feb 20 21:26:22 2001
+++ linux/drivers/block/DAC960.c	Sat Apr 28 11:27:53 2001
@@ -5134,16 +5134,12 @@
 						      PartitionNumber);
 	  int MinorNumber = DAC960_MinorNumber(LogicalDriveNumber,
 					       PartitionNumber);
-	  SuperBlock_T *SuperBlock = get_super(Device);
 	  if (Controller->GenericDiskInfo.part[MinorNumber].nr_sects == 0)
 	    continue;
 	  /*
 	    Flush all changes and invalidate buffered state.
 	  */
-	  sync_dev(Device);
-	  if (SuperBlock != NULL)
-	    invalidate_inodes(SuperBlock);
-	  invalidate_buffers(Device);
+	  invalidate_device(Device, 1);
 	  /*
 	    Clear existing partition sizes.
 	  */
diff -u --recursive --new-file v2.4.4/linux/drivers/block/acsi.c linux/drivers/block/acsi.c
--- v2.4.4/linux/drivers/block/acsi.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/block/acsi.c	Sat Apr 28 11:27:53 2001
@@ -1886,13 +1886,7 @@
 
 	for( i = max_p - 1; i >= 0 ; i-- ) {
 		if (gdev->part[start + i].nr_sects != 0) {
-			kdev_t devp = MKDEV(MAJOR_NR, start + i);
-			struct super_block *sb = get_super(devp);
-
-			fsync_dev(devp);
-			if (sb)
-				invalidate_inodes(sb);
-			invalidate_buffers(devp);
+			invalidate_device(MKDEV(MAJOR_NR, start + i), 1);
 			gdev->part[start + i].nr_sects = 0;
 		}
 		gdev->part[start+i].start_sect = 0;
diff -u --recursive --new-file v2.4.4/linux/drivers/block/acsi_slm.c linux/drivers/block/acsi_slm.c
--- v2.4.4/linux/drivers/block/acsi_slm.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/block/acsi_slm.c	Tue May 22 10:23:16 2001
@@ -378,19 +378,22 @@
 	
 	length = slm_getstats( (char *)page, MINOR(node->i_rdev) );
 	if (length < 0) {
-		free_page( page );
-		return( length );
+		count = length;
+		goto out;
 	}
 	if (file->f_pos >= length) {
-		free_page( page );
-		return( 0 );
+		count = 0;
+		goto out;
 	}
 	if (count + file->f_pos > length)
 		count = length - file->f_pos;
 	end = count + file->f_pos;
-	copy_to_user( buf, (char *)page + file->f_pos, count );
-	free_page( page );
+	if (copy_to_user(buf, (char *)page + file->f_pos, count)) {
+		count = -EFAULT;
+		goto out;
+	}
 	file->f_pos = end;
+out:	free_page( page );
 	return( count );
 }
 
@@ -648,7 +651,8 @@
 	if (filled + n > BufferSize)
 		n = BufferSize - filled;
 
-	copy_from_user( BufferP, buf, n );
+	if (copy_from_user(BufferP, buf, n))
+		return -EFAULT;
 	BufferP += n;
 	filled += n;
 
@@ -725,8 +729,9 @@
 			if (put_user(stat,
     	    	    	    	     (long *)&((struct SLM_status *)arg)->stat))
     	    	    	    	return -EFAULT;
-			copy_to_user( ((struct SLM_status *)arg)->str, str,
-						 strlen(str) + 1 );
+			if (copy_to_user( ((struct SLM_status *)arg)->str, str,
+						 strlen(str) + 1))
+				return -EFAULT;
 		}
 		return( stat );
 	  }
@@ -734,10 +739,6 @@
 	  case SLMIOGPSIZE: {	/* get paper size */
 		int w, h;
 		
-		err = verify_area( VERIFY_WRITE, (long *)arg,
-						   sizeof(struct SLM_paper_size) );
-		if (err) return( err );
-
 		if ((err = slm_get_pagesize( device, &w, &h ))) return( err );
 		
     	    	if (put_user(w, (long *)&((struct SLM_paper_size *)arg)->width))
diff -u --recursive --new-file v2.4.4/linux/drivers/block/amiflop.c linux/drivers/block/amiflop.c
--- v2.4.4/linux/drivers/block/amiflop.c	Sun Oct  1 20:35:15 2000
+++ linux/drivers/block/amiflop.c	Sat Apr 28 11:27:53 2001
@@ -1540,10 +1540,7 @@
 		break;
 	case FDFMTEND:
 		floppy_off(drive);
-		sb = get_super(inode->i_rdev);
-		if (sb)
-			invalidate_inodes(sb);
-		invalidate_buffers(inode->i_rdev);
+		invalidate_device(inode->i_rdev, 0);
 		break;
 	case FDGETPRM:
 		memset((void *)&getprm, 0, sizeof (getprm));
diff -u --recursive --new-file v2.4.4/linux/drivers/block/blkpg.c linux/drivers/block/blkpg.c
--- v2.4.4/linux/drivers/block/blkpg.c	Thu Oct 26 23:35:47 2000
+++ linux/drivers/block/blkpg.c	Sun May 20 11:34:05 2001
@@ -157,8 +157,7 @@
 
 	/* partition in use? Incomplete check for now. */
 	devp = MKDEV(MAJOR(dev), minor);
-	if (get_super(devp) ||		/* mounted? */
-	    is_swap_partition(devp))
+	if (is_mounted(devp) || is_swap_partition(devp))
 		return -EBUSY;
 
 	/* all seems OK */
diff -u --recursive --new-file v2.4.4/linux/drivers/block/cciss.c linux/drivers/block/cciss.c
--- v2.4.4/linux/drivers/block/cciss.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/block/cciss.c	Tue May 22 10:23:16 2001
@@ -44,8 +44,8 @@
 #include <linux/genhd.h>
 
 #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "Compaq CISS Driver (v 2.4.2)"
-#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,2)
+#define DRIVER_NAME "Compaq CISS Driver (v 2.4.5)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,5)
 
 /* Embedded module documentation macros - see modules.h */
 MODULE_AUTHOR("Charles M. White III - Compaq Computer Corporation");
@@ -55,6 +55,17 @@
 #include "cciss.h"
 #include <linux/cciss_ioctl.h>
 
+/* define the PCI info for the cards we can control */
+const struct pci_device_id cciss_pci_device_id[] = {
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISS,
+			0x0E11, 0x4070, 0, 0, 0},
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB,
+                        0x0E11, 0x4080, 0, 0, 0},
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSB,
+                        0x0E11, 0x4082, 0, 0, 0},
+};
+MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
+
 #define NR_PRODUCTS (sizeof(products)/sizeof(struct board_type))
 
 /*  board_id = Subsystem Device ID & Vendor ID
@@ -73,7 +84,9 @@
 #define READ_AHEAD 	 128
 #define NR_CMDS		 128 /* #commands that can be outstanding */
 #define MAX_CTLR 8
-static int nr_ctlr; 
+
+#define CCISS_DMA_MASK	0xFFFFFFFF	/* 32 bit DMA */
+
 static ctlr_info_t *hba[MAX_CTLR];
 
 static struct proc_dir_entry *proc_cciss;
@@ -125,10 +138,10 @@
 
         ctlr = h->ctlr;
         size = sprintf(buffer, "%s:  Compaq %s Controller\n"
-                "       Board ID: %08lx\n"
+                "       Board ID: 0x%08lx\n"
 		"       Firmware Version: %c%c%c%c\n"
-                "       Memory Address: %08lx\n"
-                "       IRQ: 0x%x\n"
+                "       Memory Address: 0x%08lx\n"
+                "       IRQ: %d\n"
                 "       Logical drives: %d\n"
                 "       Current Q depth: %d\n"
 		"       Current # commands on controller %d\n"
@@ -172,7 +185,7 @@
 static void __init cciss_procinit(int i)
 {
         if (proc_cciss == NULL) {
-                proc_cciss = proc_mkdir("driver/cciss", NULL);
+                proc_cciss = proc_mkdir("cciss", proc_root_driver);
                 if (!proc_cciss) 
 			return;
         }
@@ -186,29 +199,32 @@
  * For operations that cannot sleep, a command block is allocated at init, 
  * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track
  * which ones are free or in use.  For operations that can wait for kmalloc 
- * to possible sleep, this routine can be called with a NULL pointer. 
- * cmd_free() MUST be called with a NULL pointer if cmd_alloc was. 
+ * to possible sleep, this routine can be called with get_from_pool set to 0. 
+ * cmd_free() MUST be called with a got_from_pool set to 0 if cmd_alloc was. 
  */ 
-static CommandList_struct * cmd_alloc(ctlr_info_t *h)
+static CommandList_struct * cmd_alloc(ctlr_info_t *h, int get_from_pool)
 {
 	CommandList_struct *c;
 	int i; 
 	u64bit temp64;
+	dma_addr_t cmd_dma_handle, err_dma_handle;
 
-	if (h == NULL)
+	if (!get_from_pool)
 	{
-		c = (CommandList_struct *)kmalloc(sizeof(CommandList_struct), 
-			GFP_KERNEL);
+		c = (CommandList_struct *) pci_alloc_consistent(
+			h->pdev, sizeof(CommandList_struct), &cmd_dma_handle); 
         	if(c==NULL)
                  	return NULL;
 		memset(c, 0, sizeof(CommandList_struct));
 
-		c->err_info = (ErrorInfo_struct *)kmalloc(
-					sizeof(ErrorInfo_struct), GFP_KERNEL);
+		c->err_info = (ErrorInfo_struct *)pci_alloc_consistent(
+					h->pdev, sizeof(ErrorInfo_struct), 
+					&err_dma_handle);
 	
 		if (c->err_info == NULL)
 		{
-			kfree(c);
+			pci_free_consistent(h->pdev, 
+				sizeof(CommandList_struct), c, cmd_dma_handle);
 			return NULL;
 		}
 		memset(c->err_info, 0, sizeof(ErrorInfo_struct));
@@ -223,18 +239,23 @@
 		printk(KERN_DEBUG "cciss: using command buffer %d\n", i);
 #endif
                 c = h->cmd_pool + i;
-		memset(c, 0, sizeof(CommandList_struct));			
+		memset(c, 0, sizeof(CommandList_struct));
+		cmd_dma_handle = h->cmd_pool_dhandle 
+					+ i*sizeof(CommandList_struct);
 		c->err_info = h->errinfo_pool + i;
 		memset(c->err_info, 0, sizeof(ErrorInfo_struct));
+		err_dma_handle = h->errinfo_pool_dhandle 
+					+ i*sizeof(ErrorInfo_struct);
                 h->nr_allocs++;
         }
 
-
-	temp64.val = (__u64) virt_to_bus(c->err_info);
+	c->busaddr = (__u32) cmd_dma_handle;
+	temp64.val = (__u64) err_dma_handle;	
 	c->ErrDesc.Addr.lower = temp64.val32.lower;
 	c->ErrDesc.Addr.upper = temp64.val32.upper;
 	c->ErrDesc.Len = sizeof(ErrorInfo_struct);
-       	c->busaddr = virt_to_bus(c);
+	
+	c->ctlr = h->ctlr;
         return c;
 
 
@@ -243,14 +264,19 @@
 /* 
  * Frees a command block that was previously allocated with cmd_alloc(). 
  */
-static void cmd_free(ctlr_info_t *h, CommandList_struct *c)
+static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool)
 {
 	int i;
+	u64bit temp64;
 
-	if( h == NULL)
+	if( !got_from_pool)
 	{ 
-		kfree(c->err_info);
-		kfree(c);	
+		temp64.val32.lower = c->ErrDesc.Addr.lower;
+		temp64.val32.upper = c->ErrDesc.Addr.upper;
+		pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct), 
+			c->err_info, (dma_addr_t) temp64.val);
+		pci_free_consistent(h->pdev, sizeof(CommandList_struct), 
+			c, (dma_addr_t) c->busaddr);
 	} else 
 	{
 		i = c - h->cmd_pool;
@@ -390,8 +416,8 @@
 		cciss_pci_info_struct pciinfo;
 
 		if (!arg) return -EINVAL;
-		pciinfo.bus = hba[ctlr]->pci_bus;
-		pciinfo.dev_fn = hba[ctlr]->pci_dev_fn;
+		pciinfo.bus = hba[ctlr]->pdev->bus->number;
+		pciinfo.dev_fn = hba[ctlr]->pdev->devfn;
 		pciinfo.board_id = hba[ctlr]->board_id;
 		if (copy_to_user((void *) arg, &pciinfo,  sizeof( cciss_pci_info_struct )))
 			return  -EFAULT;
@@ -583,13 +609,10 @@
 		if (iocommand.Request.Type.Direction == XFER_WRITE)
 		{
 			/* Copy the data into the buffer we created */ 
-			if (copy_from_user(buff, iocommand.buf,
-						iocommand.buf_size)) {
-				kfree(buff);
+			if (copy_from_user(buff, iocommand.buf, iocommand.buf_size))
 				return -EFAULT;
-			}
 		}
-		if ((c = cmd_alloc(NULL)) == NULL)
+		if ((c = cmd_alloc(h , 0)) == NULL)
 		{
 			kfree(buff);
 			return -ENOMEM;
@@ -615,8 +638,10 @@
 	
 		// Fill in the scatter gather information
 		if (iocommand.buf_size > 0 ) 
-		{	
-			temp64.val = (__u64) virt_to_bus(buff);
+		{
+			temp64.val = pci_map_single( h->pdev, buff,
+                                        iocommand.buf_size, 
+                                PCI_DMA_BIDIRECTIONAL);	
 			c->SG[0].Addr.lower = temp64.val32.lower;
 			c->SG[0].Addr.upper = temp64.val32.upper;
 			c->SG[0].Len = iocommand.buf_size;
@@ -633,12 +658,18 @@
 		while(c->cmd_type != CMD_IOCTL_DONE)
 			schedule_timeout(1);
 
+		/* unlock the buffers from DMA */
+		temp64.val32.lower = c->SG[0].Addr.lower;
+                temp64.val32.upper = c->SG[0].Addr.upper;
+                pci_unmap_single( h->pdev, (dma_addr_t) temp64.val,
+                	iocommand.buf_size, PCI_DMA_BIDIRECTIONAL);
+
 		/* Copy the error information out */ 
 		iocommand.error_info = *(c->err_info);
 		if ( copy_to_user((void *) arg, &iocommand, sizeof( IOCTL_Command_struct) ) )
 		{
-			cmd_free(NULL, c);
 			kfree(buff);
+			cmd_free(h, c, 0);
 			return( -EFAULT);	
 		} 	
 
@@ -647,13 +678,12 @@
                         /* Copy the data out of the buffer we created */
                         if (copy_to_user(iocommand.buf, buff, iocommand.buf_size))
 			{
-			             cmd_free(NULL, c);
-			             kfree(buff);
-				     return -EFAULT;	
+                        	kfree(buff);
+				cmd_free(h, c, 0);
 			}
                 }
-		cmd_free(NULL, c);
                 kfree(buff);
+		cmd_free(h, c, 0);
                 return(0);
 	} 
 
@@ -691,13 +721,9 @@
         max_p = gdev->max_p;
         start = target << gdev->minor_shift;
 
-        for(i=max_p; i>=0; i--) {
+        for(i=max_p-1; i>=0; i--) {
                 int minor = start+i;
-                kdev_t devi = MKDEV(MAJOR_NR + ctlr, minor);
-                struct super_block *sb = get_super(devi);
-                sync_dev(devi);
-                if (sb) invalidate_inodes(sb);
-                invalidate_buffers(devi);
+                invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1);
                 gdev->part[minor].start_sect = 0;
                 gdev->part[minor].nr_sects = 0;
 
@@ -820,9 +846,9 @@
 	int i;
 	unsigned long complete;
 	ctlr_info_t *info_p= hba[ctlr];
-	u64bit temp64;
+	u64bit buff_dma_handle;
 
-	c = cmd_alloc(info_p);
+	c = cmd_alloc(info_p, 1);
 	if (c == NULL)
 	{
 		printk(KERN_WARNING "cciss: unable to get memory");
@@ -903,15 +929,16 @@
 			printk(KERN_WARNING
 				"cciss:  Unknown Command 0x%c sent attempted\n",
 				  cmd);
-			cmd_free(info_p, c);
+			cmd_free(info_p, c, 1);
 			return(IO_ERROR);
 	};
 	// Fill in the scatter gather information
 	if (size > 0 ) 
 	{
-		temp64.val = (__u64) virt_to_bus(buff);
-		c->SG[0].Addr.lower = temp64.val32.lower;
-		c->SG[0].Addr.upper = temp64.val32.upper;
+		buff_dma_handle.val = (__u64) pci_map_single( info_p->pdev, 
+			buff, size, PCI_DMA_BIDIRECTIONAL);
+		c->SG[0].Addr.lower = buff_dma_handle.val32.lower;
+		c->SG[0].Addr.upper = buff_dma_handle.val32.upper;
 		c->SG[0].Len = size;
 		c->SG[0].Ext = 0;  // we are not chaining
 	}
@@ -947,6 +974,9 @@
 	printk(KERN_DEBUG "cciss: command completed\n");
 #endif /* CCISS_DEBUG */
 
+	/* unlock the data buffer from DMA */
+	pci_unmap_single(info_p->pdev, (dma_addr_t) buff_dma_handle.val,
+                                size, PCI_DMA_BIDIRECTIONAL);
 	if (complete != 1) {
 		if ( (complete & CISS_ERROR_BIT)
 		     && (complete & ~CISS_ERROR_BIT) == c->busaddr)
@@ -974,7 +1004,7 @@
 				  c->err_info->MoreErrInfo.Invalid_Cmd.offense_size,
 				  c->err_info->MoreErrInfo.Invalid_Cmd.offense_num,
 				  c->err_info->MoreErrInfo.Invalid_Cmd.offense_value);
-				cmd_free(info_p,c);
+				cmd_free(info_p,c, 1);
 				return(IO_ERROR);
 			}
 		}
@@ -982,7 +1012,7 @@
                         printk( KERN_WARNING "cciss cciss%d: SendCmd "
                       "Invalid command list address returned! (%lx)\n",
                                 ctlr, complete);
-                        cmd_free(info_p, c);
+                        cmd_free(info_p, c, 1);
                         return (IO_ERROR);
                 }
         } else {
@@ -990,10 +1020,10 @@
                         "cciss cciss%d: SendCmd Timeout out, "
                         "No command list address returned!\n",
                         ctlr);
-                cmd_free(info_p, c);
+                cmd_free(info_p, c, 1);
                 return (IO_ERROR);
         }
-	cmd_free(info_p, c);
+	cmd_free(info_p, c, 1);
         return (IO_OK);
 } 
 /*
@@ -1084,9 +1114,22 @@
 static inline void complete_command( CommandList_struct *cmd, int timeout)
 {
 	int status = 1;
-	
+	int i;
+	u64bit temp64;
+		
 	if (timeout)
 		status = 0; 
+	/* unmap the DMA mapping for all the scatter gather elements */
+	for(i=0; i<cmd->Header.SGList; i++)
+	{
+		temp64.val32.lower = cmd->SG[i].Addr.lower;
+		temp64.val32.upper = cmd->SG[i].Addr.upper;
+		pci_unmap_single(hba[cmd->ctlr]->pdev,
+			temp64.val, cmd->SG[i].Len, 
+			(cmd->Request.Type.Direction == XFER_READ) ? 
+				PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+	}
+
 	if(cmd->err_info->CommandStatus != 0) 
 	{ /* an error has occurred */ 
 		switch(cmd->err_info->CommandStatus)
@@ -1221,7 +1264,12 @@
 	struct list_head *queue_head = &q->queue_head;
 	struct request *creq;
 	u64bit temp64;
+	struct my_sg tmp_sg[MAXSGENTRIES];
+	int i;
 
+    // Loop till the queue is empty if or it is plugged
+    while (1)
+    {
 	if (q->plugged || list_empty(queue_head)) {
                 start_io(h);
                 return;
@@ -1231,7 +1279,7 @@
 	if (creq->nr_segments > MAXSGENTRIES)
                 BUG();
 
-        if ((h->ctlr != MAJOR(creq->rq_dev)-MAJOR_NR) || (h->ctlr > nr_ctlr))
+        if (h->ctlr != MAJOR(creq->rq_dev)-MAJOR_NR )
         {
                 printk(KERN_WARNING "doreq cmd for %d, %x at %p\n",
                                 h->ctlr, creq->rq_dev, creq);
@@ -1241,7 +1289,7 @@
                 return;
         }
 
-	if (( c = cmd_alloc(h)) == NULL)
+	if (( c = cmd_alloc(h, 1)) == NULL)
 	{
 		start_io(h);
 		return;
@@ -1277,22 +1325,32 @@
 		sect += bh->b_size/512;
 		if (bh->b_data == lastdataend)
 		{  // tack it on to the last segment 
-			c->SG[seg-1].Len +=bh->b_size;
+			tmp_sg[seg-1].len +=bh->b_size;
 			lastdataend += bh->b_size;
 		} else
 		{
 			if (seg == MAXSGENTRIES)
 				BUG();
-			c->SG[seg].Len = bh->b_size;
-			temp64.val = (__u64) virt_to_bus(bh->b_data);
-			c->SG[seg].Addr.lower = temp64.val32.lower;
-			c->SG[seg].Addr.upper = temp64.val32.upper;
-			c->SG[0].Ext = 0;  // we are not chaining
+			tmp_sg[seg].len = bh->b_size;
+			tmp_sg[seg].start_addr = bh->b_data;
 			lastdataend = bh->b_data + bh->b_size;
 			seg++;
 		}
 		bh = bh->b_reqnext;
 	}
+	/* get the DMA records for the setup */ 
+	for (i=0; i<seg; i++)
+	{
+		c->SG[i].Len = tmp_sg[i].len;
+		temp64.val = (__u64) pci_map_single( h->pdev,
+			tmp_sg[i].start_addr,
+			tmp_sg[i].len,
+			(c->Request.Type.Direction == XFER_READ) ? 
+                                PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+		c->SG[i].Addr.lower = temp64.val32.lower;
+                c->SG[i].Addr.upper = temp64.val32.upper;
+                c->SG[i].Ext = 0;  // we are not chaining
+	}
 	/* track how many SG entries we are using */ 
 	if( seg > h->maxSG)
 		h->maxSG = seg; 
@@ -1329,7 +1387,7 @@
 	h->Qdepth++;
 	if(h->Qdepth > h->maxQsinceinit)
 		h->maxQsinceinit = h->Qdepth; 
-	start_io(h);
+   }  // while loop
 }
 
 static void do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs)
@@ -1373,7 +1431,7 @@
 				removeQ(&h->cmpQ, c);
 				if (c->cmd_type == CMD_RWREQ) {
 					complete_command(c, 0);
-					cmd_free(h, c);
+					cmd_free(h, c, 1);
 				} else if (c->cmd_type == CMD_IOCTL_PEND) {
 					c->cmd_type = CMD_IOCTL_DONE;
 				}
@@ -1427,20 +1485,18 @@
 }
 #endif /* CCISS_DEBUG */ 
 
-static int cciss_pci_init(ctlr_info_t *c, unchar bus, unchar device_fn)
+static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
 {
 	ushort vendor_id, device_id, command;
 	unchar cache_line_size, latency_timer;
 	unchar irq, revision;
 	uint addr[6];
 	__u32 board_id;
-	struct pci_dev *pdev;
 	int cfg_offset;
 	int cfg_base_addr;
 	int cfg_base_addr_index;
 	int i;
 
-	pdev = pci_find_slot(bus, device_fn);
 	vendor_id = pdev->vendor;
 	device_id = pdev->device;
 	irq = pdev->irq;
@@ -1449,7 +1505,15 @@
 		addr[i] = pdev->resource[i].start;
 
 	if (pci_enable_device(pdev))
+	{
+		printk(KERN_ERR "cciss: Unable to Enable PCI device\n");
 		return( -1);
+	}
+	if (pci_set_dma_mask(pdev, CCISS_DMA_MASK ) != 0)
+	{
+		printk(KERN_ERR "cciss:  Unable to set DMA mask\n");
+		return(-1);
+	}
 	
 	(void) pci_read_config_word(pdev, PCI_COMMAND,&command);
 	(void) pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
@@ -1566,59 +1630,6 @@
 	return 0;
 
 }
-/* 
- * Scans PCI space for any controllers that this driver can control. 
- */
-static int cciss_pci_detect(void)
-{
-
-	int index;
-	unchar bus=0, dev_fn=0;
-
-	#define CCISS_BOARD_TYPES 2
-	static int cciss_device_id[CCISS_BOARD_TYPES] = { 
-		PCI_DEVICE_ID_COMPAQ_CISS, PCI_DEVICE_ID_COMPAQ_CISSB};
-	int brdtype;
-
-	/* search for all PCI board types that could be for this driver */
-	for(brdtype=0; brdtype<CCISS_BOARD_TYPES; brdtype++)
-	{
-		for(index=0; ; index++) {
-			if (pcibios_find_device(PCI_VENDOR_ID_COMPAQ,
-			 	cciss_device_id[brdtype], 
-					index, &bus, &dev_fn))
-				break;
-			printk(KERN_DEBUG "cciss: Device %x has been found at %x %x\n",
-				cciss_device_id[brdtype], bus, dev_fn);
-			if (index == 1000000) break;
-			if (nr_ctlr == 8) {
-				printk(KERN_WARNING "cciss: This driver"
-				" supports a maximum of 8 controllers.\n");
-				break;
-			}
-			hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
-			if(hba[nr_ctlr]==NULL)
-			{
-				printk(KERN_ERR "cciss: out of memory.\n");
-				continue;
-			}
-			memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
-			if (cciss_pci_init(hba[nr_ctlr], bus, dev_fn) != 0)
-			{
-				kfree(hba[nr_ctlr]);
-				continue;
-			}
-			sprintf(hba[nr_ctlr]->devname, "cciss%d", nr_ctlr);
-			hba[nr_ctlr]->ctlr = nr_ctlr;
-			hba[nr_ctlr]->pci_bus = bus;
-			hba[nr_ctlr]->pci_dev_fn = dev_fn;
-			nr_ctlr++;
-
-		}
-	}
-	return nr_ctlr;
-
-}
 
 /* 
  * Gets information about the local volumes attached to the controller. 
@@ -1797,166 +1808,265 @@
 	kfree(size_buff);
 }	
 
+/* Function to find the first free pointer into our hba[] array */
+/* Returns -1 if no free entries are left.  */
+static int alloc_cciss_hba(void)
+{
+	int i;
+	for(i=0; i< MAX_CTLR; i++)
+	{
+		if (hba[i] == NULL)
+		{
+			hba[i] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
+			if(hba[i]==NULL)
+			{
+				printk(KERN_ERR "cciss: out of memory.\n");
+				return (-1);
+			}
+			return (i);
+		}
+	}
+	printk(KERN_WARNING "cciss: This driver supports a maximum"
+		" of 8 controllers.\n");
+	return(-1);
+}
+
+static void free_hba(int i)
+{
+	kfree(hba[i]);
+	hba[i]=NULL;
+}
+
 /*
  *  This is it.  Find all the controllers and register them.  I really hate
  *  stealing all these major device numbers.
  *  returns the number of block devices registered.
  */
-int __init cciss_init(void)
+static int __init cciss_init_one(struct pci_dev *pdev,
+	const struct pci_device_id *ent)
 {
-	int num_cntlrs_reg = 0;
-	int i,j;
 	request_queue_t *q;
+	int i;
+	int j;
 
-	/* detect controllers */
-	cciss_pci_detect();
-
-	if (nr_ctlr == 0)
-		return(num_cntlrs_reg);
-
-	printk(KERN_INFO DRIVER_NAME "\n");
-	printk(KERN_INFO "Found %d controller(s)\n", nr_ctlr);
-	for(i=0;i<nr_ctlr;i++)
+	printk(KERN_DEBUG "cciss: Device 0x%x has been found at"
+			" bus %d dev %d func %d\n",
+		pdev->device, pdev->bus->number, PCI_SLOT(pdev->devfn),
+			PCI_FUNC(pdev->devfn));
+	i = alloc_cciss_hba();
+	if( i < 0 ) 
+		return (-1);
+	memset(hba[i], 0, sizeof(ctlr_info_t));
+	if (cciss_pci_init(hba[i], pdev) != 0)
+	{
+		free_hba(i);
+		return (-1);
+	}
+	sprintf(hba[i]->devname, "cciss%d", i);
+	hba[i]->ctlr = i;
+	hba[i]->pdev = pdev;
+			
+	if( register_blkdev(MAJOR_NR+i, hba[i]->devname, &cciss_fops))
 	{
-		if( register_blkdev(MAJOR_NR+i, hba[i]->devname, &cciss_fops))
-		{
-			printk(KERN_ERR "cciss:  Unable to get major number "
-				"%d for %s\n", MAJOR_NR+i, hba[i]->devname);
-			continue;
-		}
-		/* make sure the board interrupts are off */
-		hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
-		if( request_irq(hba[i]->intr, do_cciss_intr, SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i]))
-		{
-			printk(KERN_ERR "ciss: Unable to get irq %d for %s\n",
-				hba[i]->intr, hba[i]->devname);
-			unregister_blkdev( MAJOR_NR+i, hba[i]->devname);
-			continue;
-		}
-		num_cntlrs_reg++;
-		hba[i]->cmd_pool_bits = (__u32*)kmalloc(
-                                ((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL);
-		hba[i]->cmd_pool = (CommandList_struct *)kmalloc(
-                                NR_CMDS * sizeof(CommandList_struct), 
-					GFP_KERNEL);
-		hba[i]->errinfo_pool = (ErrorInfo_struct *)kmalloc(
-                                NR_CMDS * sizeof( ErrorInfo_struct), 
-					GFP_KERNEL);
-		if((hba[i]->cmd_pool_bits == NULL) 
-			|| (hba[i]->cmd_pool == NULL)
-			|| (hba[i]->errinfo_pool == NULL))
-                {
-                        nr_ctlr = i;
-			kfree(hba[i]->cmd_pool_bits);
-			kfree(hba[i]->cmd_pool);
-			kfree(hba[i]->errinfo_pool);
-                        free_irq(hba[i]->intr, hba[i]);
-                        unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
-                        num_cntlrs_reg--;
-                        printk( KERN_ERR "cciss: out of memory");
-			return(num_cntlrs_reg);
-		}
-
-		/* command and error info recs zeroed out before 
+		printk(KERN_ERR "cciss:  Unable to get major number "
+			"%d for %s\n", MAJOR_NR+i, hba[i]->devname);
+		free_hba(i);
+		return(-1);
+	}
+	/* make sure the board interrupts are off */
+	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
+	if( request_irq(hba[i]->intr, do_cciss_intr, 
+		SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i]))
+	{
+		printk(KERN_ERR "ciss: Unable to get irq %d for %s\n",
+			hba[i]->intr, hba[i]->devname);
+		unregister_blkdev( MAJOR_NR+i, hba[i]->devname);
+		free_hba(i);
+		return(-1);
+	}
+	hba[i]->cmd_pool_bits = (__u32*)kmalloc(
+        	((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL);
+	hba[i]->cmd_pool = (CommandList_struct *)pci_alloc_consistent(
+		hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), 
+		&(hba[i]->cmd_pool_dhandle));
+	hba[i]->errinfo_pool = (ErrorInfo_struct *)pci_alloc_consistent(
+		hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct), 
+		&(hba[i]->errinfo_pool_dhandle));
+	if((hba[i]->cmd_pool_bits == NULL) 
+		|| (hba[i]->cmd_pool == NULL)
+		|| (hba[i]->errinfo_pool == NULL))
+        {
+		if(hba[i]->cmd_pool_bits)
+                	kfree(hba[i]->cmd_pool_bits);
+                if(hba[i]->cmd_pool)
+                	pci_free_consistent(hba[i]->pdev,  
+				NR_CMDS * sizeof(CommandList_struct), 
+				hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);	
+		if(hba[i]->errinfo_pool)
+			pci_free_consistent(hba[i]->pdev,
+				NR_CMDS * sizeof( ErrorInfo_struct),
+				hba[i]->errinfo_pool, 
+				hba[i]->errinfo_pool_dhandle);
+                free_irq(hba[i]->intr, hba[i]);
+                unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+		free_hba(i);
+                printk( KERN_ERR "cciss: out of memory");
+		return(-1);
+	}
+
+	/* Initialize the pdev driver private data. 
+		have it point to hba[i].  */
+	pdev->driver_data = hba[i];
+	/* command and error info recs zeroed out before 
 			they are used */
-                memset(hba[i]->cmd_pool_bits, 0, 
-			((NR_CMDS+31)/32)*sizeof(__u32));
+        memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32));
 
 #ifdef CCISS_DEBUG	
-		printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n",i);
+	printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n",i);
 #endif /* CCISS_DEBUG */
 
-		cciss_getgeometry(i);
+	cciss_getgeometry(i);
 
-		/* Turn the interrupts on so we can service requests */
-		hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
+	/* Turn the interrupts on so we can service requests */
+	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON);
 
-		cciss_procinit(i);
+	cciss_procinit(i);
 
-		q = BLK_DEFAULT_QUEUE(MAJOR_NR + i);
-                q->queuedata = hba[i];
-                blk_init_queue(q, do_cciss_request);
-                blk_queue_headactive(q, 0);		
-
-		/* fill in the other Kernel structs */
-		blksize_size[MAJOR_NR+i] = hba[i]->blocksizes;
-                hardsect_size[MAJOR_NR+i] = hba[i]->hardsizes;
-                read_ahead[MAJOR_NR+i] = READ_AHEAD;
-
-		/* Set the pointers to queue functions */ 
-		q->back_merge_fn = cpq_back_merge_fn;
-                q->front_merge_fn = cpq_front_merge_fn;
-                q->merge_requests_fn = cpq_merge_requests_fn;
-
-
-		/* Fill in the gendisk data */ 	
-		hba[i]->gendisk.major = MAJOR_NR + i;
-		hba[i]->gendisk.major_name = "cciss";
-		hba[i]->gendisk.minor_shift = NWD_SHIFT;
-		hba[i]->gendisk.max_p = MAX_PART;
-		hba[i]->gendisk.part = hba[i]->hd;
-		hba[i]->gendisk.sizes = hba[i]->sizes;
-		hba[i]->gendisk.nr_real = hba[i]->num_luns;
-
-		/* Get on the disk list */ 
-		hba[i]->gendisk.next = gendisk_head;
-		gendisk_head = &(hba[i]->gendisk); 
-
-		cciss_geninit(i);
-		for(j=0; j<NWD; j++)
-			register_disk(&(hba[i]->gendisk),
-				MKDEV(MAJOR_NR+i, j <<4), 
-				MAX_PART, &cciss_fops, 
-				hba[i]->drv[j].nr_blocks);
-	}
-	return(nr_ctlr);
-}
+	q = BLK_DEFAULT_QUEUE(MAJOR_NR + i);
+        q->queuedata = hba[i];
+        blk_init_queue(q, do_cciss_request);
+        blk_queue_headactive(q, 0);		
 
-EXPORT_NO_SYMBOLS;
+	/* fill in the other Kernel structs */
+	blksize_size[MAJOR_NR+i] = hba[i]->blocksizes;
+        hardsect_size[MAJOR_NR+i] = hba[i]->hardsizes;
+        read_ahead[MAJOR_NR+i] = READ_AHEAD;
 
-/* This is a bit of a hack... */
-static int __init init_cciss_module(void)
-{
+	/* Set the pointers to queue functions */ 
+	q->back_merge_fn = cpq_back_merge_fn;
+        q->front_merge_fn = cpq_front_merge_fn;
+        q->merge_requests_fn = cpq_merge_requests_fn;
 
-	if (cciss_init() == 0) /* all the block dev numbers already used */
-		return -EIO;	  /* or no controllers were found */
-	return 0;
+
+	/* Fill in the gendisk data */ 	
+	hba[i]->gendisk.major = MAJOR_NR + i;
+	hba[i]->gendisk.major_name = "cciss";
+	hba[i]->gendisk.minor_shift = NWD_SHIFT;
+	hba[i]->gendisk.max_p = MAX_PART;
+	hba[i]->gendisk.part = hba[i]->hd;
+	hba[i]->gendisk.sizes = hba[i]->sizes;
+	hba[i]->gendisk.nr_real = hba[i]->num_luns;
+
+	/* Get on the disk list */ 
+	hba[i]->gendisk.next = gendisk_head;
+	gendisk_head = &(hba[i]->gendisk); 
+
+	cciss_geninit(i);
+	for(j=0; j<NWD; j++)
+		register_disk(&(hba[i]->gendisk),
+			MKDEV(MAJOR_NR+i, j <<4), 
+			MAX_PART, &cciss_fops, 
+			hba[i]->drv[j].nr_blocks);
+
+	return(1);
 }
 
-static void __exit cleanup_cciss_module(void)
+static void __devexit cciss_remove_one (struct pci_dev *pdev)
 {
+	ctlr_info_t *tmp_ptr;
 	int i;
 	struct gendisk *g;
 
-	for(i=0; i<nr_ctlr; i++)
+	if (pdev->driver_data == NULL)
+	{
+		printk( KERN_ERR "cciss: Unable to remove device \n");
+		return;
+	}
+	tmp_ptr = (ctlr_info_t *) pdev->driver_data;
+	i = tmp_ptr->ctlr;
+	if (hba[i] == NULL) 
 	{
-		/* Turn board interrupts off */ 
-		hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
-		free_irq(hba[i]->intr, hba[i]);
-		iounmap((void*)hba[i]->vaddr);
-		unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
-		remove_proc_entry(hba[i]->devname, proc_cciss);	
+		printk(KERN_ERR "cciss: device appears to "
+			"already be removed \n");
+		return;
+	}
+	/* Turn board interrupts off */
+	hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
+	free_irq(hba[i]->intr, hba[i]);
+	pdev->driver_data = NULL;
+	iounmap((void*)hba[i]->vaddr);
+	unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+	remove_proc_entry(hba[i]->devname, proc_cciss);	
+	
 
-		/* remove it from the disk list */ 
-		if (gendisk_head == &(hba[i]->gendisk))
-		{
-			gendisk_head = hba[i]->gendisk.next;
-		} else 
+	/* remove it from the disk list */
+	if (gendisk_head == &(hba[i]->gendisk))
+	{
+		gendisk_head = hba[i]->gendisk.next;
+	} else
+	{
+		for(g=gendisk_head; g ; g=g->next)
 		{
-			for(g=gendisk_head; g ; g=g->next)
+			if(g->next == &(hba[i]->gendisk))
 			{
-				if(g->next == &(hba[i]->gendisk))
-				{
-					g->next = hba[i]->gendisk.next;
-				}
+				g->next = hba[i]->gendisk.next;
 			}
 		}
-		remove_proc_entry("driver/cciss", &proc_root);
-		kfree(hba[i]->cmd_pool);
-		kfree(hba[i]->errinfo_pool);
-                kfree(hba[i]->cmd_pool_bits);
-		kfree(hba[i]);
 	}
+	pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), 
+		hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
+	pci_free_consistent(hba[i]->pdev, NR_CMDS * sizeof( ErrorInfo_struct),
+		hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle);
+	kfree(hba[i]->cmd_pool_bits);
+	free_hba(i);
+}	
+
+static struct pci_driver cciss_pci_driver = {
+	 name:   "cciss",
+	probe:  cciss_init_one,
+	remove:  cciss_remove_one,
+	id_table:  cciss_pci_device_id, /* id_table */
+};
+
+/*
+*  This is it.  Register the PCI driver information for the cards we control
+*  the OS will call our registered routines when it finds one of our cards. 
+*/
+int __init cciss_init(void)
+{
+
+	printk(KERN_INFO DRIVER_NAME "\n");
+	/* Register for out PCI devices */
+	if (pci_register_driver(&cciss_pci_driver) > 0 )
+		return 0;
+	else 
+		return -ENODEV;
+
+ }
+
+EXPORT_NO_SYMBOLS;
+static int __init init_cciss_module(void)
+{
+
+	return ( cciss_init());
+}
+
+static void __exit cleanup_cciss_module(void)
+{
+	int i;
+
+	pci_unregister_driver(&cciss_pci_driver);
+	/* double check that all controller entrys have been removed */
+	for (i=0; i< MAX_CTLR; i++) 
+	{
+		if (hba[i] != NULL)
+		{
+			printk(KERN_WARNING "cciss: had to remove"
+					" controller %d\n", i);
+			cciss_remove_one(hba[i]->pdev);
+		}
+	}
+	remove_proc_entry("cciss", proc_root_driver);
 }
 
 module_init(init_cciss_module);
diff -u --recursive --new-file v2.4.4/linux/drivers/block/cciss.h linux/drivers/block/cciss.h
--- v2.4.4/linux/drivers/block/cciss.h	Fri Apr 13 20:26:07 2001
+++ linux/drivers/block/cciss.h	Tue May 22 10:23:16 2001
@@ -15,6 +15,11 @@
 
 #define MAJOR_NR COMPAQ_CISS_MAJOR 
 
+struct my_sg {
+	int len;
+	char *start_addr;
+};
+
 struct ctlr_info;
 typedef struct ctlr_info ctlr_info_t;
 
@@ -42,8 +47,7 @@
 	char	devname[8];
 	char    *product_name;
 	char	firm_ver[4]; // Firmware version 
-	unchar  pci_bus;
-        unchar  pci_dev_fn;
+	struct pci_dev *pdev;
 	__u32	board_id;
 	ulong   vaddr;
 	__u32	paddr;	
@@ -70,7 +74,9 @@
 
 	//* pointers to command and error info pool */ 
 	CommandList_struct 	*cmd_pool;
+	dma_addr_t		cmd_pool_dhandle; 
 	ErrorInfo_struct 	*errinfo_pool;
+	dma_addr_t		errinfo_pool_dhandle; 
         __u32   		*cmd_pool_bits;
 	int			nr_allocs;
 	int			nr_frees; 
diff -u --recursive --new-file v2.4.4/linux/drivers/block/cciss_cmd.h linux/drivers/block/cciss_cmd.h
--- v2.4.4/linux/drivers/block/cciss_cmd.h	Fri Apr 13 20:26:07 2001
+++ linux/drivers/block/cciss_cmd.h	Tue May 22 10:23:16 2001
@@ -125,20 +125,20 @@
 //Command List Structure
 typedef union _SCSI3Addr_struct {
    struct {
+    BYTE Dev;
     BYTE Bus:6;
     BYTE Mode:2;        // b00
-    BYTE Dev;
   } PeripDev;
    struct {
+    BYTE DevLSB;
     BYTE DevMSB:6;
     BYTE Mode:2;        // b01
-    BYTE DevLSB;
   } LogDev;
    struct {
-    BYTE Targ:6;
-    BYTE Mode:2;        // b10
     BYTE Dev:5;
     BYTE Bus:3;
+    BYTE Targ:6;
+    BYTE Mode:2;        // b10
   } LogUnit;
 } SCSI3Addr_struct;
 
@@ -224,6 +224,7 @@
 	/* information associated with the command */ 
   __u32			   busaddr; /* physical address of this record */
   ErrorInfo_struct * 	   err_info; /* pointer to the allocated mem */ 
+  int			   ctlr;
   int			   cmd_type; 
   struct _CommandList_struct *prev;
   struct _CommandList_struct *next;
diff -u --recursive --new-file v2.4.4/linux/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
--- v2.4.4/linux/drivers/block/cpqarray.c	Tue Feb 13 14:13:43 2001
+++ linux/drivers/block/cpqarray.c	Tue May 22 10:23:16 2001
@@ -44,8 +44,8 @@
 
 #define SMART2_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
 
-#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.2)"
-#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,2)
+#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.4)"
+#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,4)
 
 /* Embedded module documentation macros - see modules.h */
 /* Original author Chris Frantz - Compaq Computer Corporation */
@@ -68,6 +68,8 @@
 #define MAX_CTLR	8
 #define CTLR_SHIFT	8
 
+#define CPQARRAY_DMA_MASK	0xFFFFFFFF	/* 32 bit DMA */
+
 static int nr_ctlr;
 static ctlr_info_t *hba[MAX_CTLR];
 
@@ -123,8 +125,8 @@
 static void getgeometry(int ctlr);
 static void start_fwbk(int ctlr);
 
-static cmdlist_t * cmd_alloc(ctlr_info_t *h);
-static void cmd_free(ctlr_info_t *h, cmdlist_t *c);
+static cmdlist_t * cmd_alloc(ctlr_info_t *h, int get_from_pool);
+static void cmd_free(ctlr_info_t *h, cmdlist_t *c, int got_from_pool);
 
 static int sendcmd(
 	__u8	cmd,
@@ -204,7 +206,7 @@
 static void __init ida_procinit(int i)
 {
 	if (proc_array == NULL) {
-		proc_array = proc_mkdir("driver/array", NULL);
+		proc_array = proc_mkdir("array", proc_root_driver);
 		if (!proc_array) return;
 	}
 
@@ -228,12 +230,12 @@
 
 	ctlr = h->ctlr;
 	size = sprintf(buffer, "%s:  Compaq %s Controller\n"
-		"       Board ID: %08lx\n"
+		"       Board ID: 0x%08lx\n"
 		"       Firmware Revision: %c%c%c%c\n"
-		"       Controller Sig: %08lx\n"
-		"       Memory Address: %08lx\n"
-		"       I/O Port: %04x\n"
-		"       IRQ: %x\n"
+		"       Controller Sig: 0x%08lx\n"
+		"       Memory Address: 0x%08lx\n"
+		"       I/O Port: 0x%04x\n"
+		"       IRQ: %d\n"
 		"       Logical drives: %d\n"
 		"       Physical drives: %d\n\n"
 		"       Current Q depth: %d\n"
@@ -314,7 +316,7 @@
 	int i;
 	struct gendisk *g;
 
-	remove_proc_entry("driver/array", NULL);
+	remove_proc_entry("array", proc_root_driver);
 
 	for(i=0; i<nr_ctlr; i++) {
 		hba[i]->access.set_intr_mask(hba[i], 0);
@@ -324,7 +326,9 @@
 		del_timer(&hba[i]->timer);
 		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i));
 		remove_proc_entry(hba[i]->devname, proc_array);
-		kfree(hba[i]->cmd_pool);
+		pci_free_consistent(hba[i]->pci_dev, 
+			NR_CMDS * sizeof(cmdlist_t), (hba[i]->cmd_pool), 
+			hba[i]->cmd_pool_dhandle);
 		kfree(hba[i]->cmd_pool_bits);
 
 		if (gendisk_head == &ida_gendisk[i]) {
@@ -474,8 +478,9 @@
 			continue;
 		}
 		num_cntlrs_reg++;
-		hba[i]->cmd_pool = (cmdlist_t *)kmalloc(
-				NR_CMDS * sizeof(cmdlist_t), GFP_KERNEL);
+		hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent(
+				hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), 
+				&(hba[i]->cmd_pool_dhandle));
 		hba[i]->cmd_pool_bits = (__u32*)kmalloc(
 				((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL);
 		
@@ -485,7 +490,10 @@
 			if(hba[i]->cmd_pool_bits)
 				kfree(hba[i]->cmd_pool_bits);
 			if(hba[i]->cmd_pool)
-				kfree(hba[i]->cmd_pool);
+				pci_free_consistent(hba[i]->pci_dev, 
+					NR_CMDS * sizeof(cmdlist_t), 
+					hba[i]->cmd_pool, 
+					hba[i]->cmd_pool_dhandle);
 			free_irq(hba[i]->intr, hba[i]);
 			unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
 			num_cntlrs_reg--;
@@ -580,9 +588,11 @@
 		pdev = pci_find_device(ida_vendor_id[brdtype],
 				       ida_device_id[brdtype], NULL);
 		while (pdev) {
-			printk(KERN_DEBUG "cpqarray: Device %x has been found at %x %x\n",
+			printk(KERN_DEBUG "cpqarray: Device 0x%x has"
+				" been found at bus %d dev %d func %d\n",
 				ida_vendor_id[brdtype],
-				pdev->bus->number, pdev->devfn);
+				pdev->bus->number, PCI_SLOT(pdev->devfn),
+				PCI_FUNC(pdev->devfn));
 			if (nr_ctlr == 8) {
 				printk(KERN_WARNING "cpqarray: This driver"
 				" supports a maximum of 8 controllers.\n");
@@ -647,7 +657,15 @@
 		addr[i] = pci_resource_start(pdev, i);
 
 	if (pci_enable_device(pdev))
+	{
+		printk(KERN_ERR "cpqarray: Unable to Enable PCI device\n");
+		return -1;
+	}
+	if (pci_set_dma_mask(pdev, CPQARRAY_DMA_MASK) != 0)
+	{
+		printk(KERN_ERR "cpqarray: Unable to set DMA mask\n");
 		return -1;
+	}
 
 	pci_read_config_word(pdev, PCI_COMMAND, &command);
 	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
@@ -905,7 +923,12 @@
 	struct list_head * queue_head = &q->queue_head;
 	struct buffer_head *bh;
 	struct request *creq;
+	struct my_sg tmp_sg[SG_MAX];
+	int i;
 
+// Loop till the queue is empty if or it is plugged 
+   while (1)
+{
 	if (q->plugged || list_empty(queue_head)) {
 		start_io(h);
 		return;
@@ -925,7 +948,7 @@
                 return;
 	}
 
-	if ((c = cmd_alloc(h)) == NULL)
+	if ((c = cmd_alloc(h,1)) == NULL)
 	{
                 start_io(h);
                 return;
@@ -951,18 +974,28 @@
 	while(bh) {
 		sect += bh->b_size/512;
 		if (bh->b_data == lastdataend) {
-			c->req.sg[seg-1].size += bh->b_size;
+			tmp_sg[seg-1].size += bh->b_size;
 			lastdataend += bh->b_size;
 		} else {
 			if (seg == SG_MAX)
 				BUG();
-			c->req.sg[seg].size = bh->b_size;
-			c->req.sg[seg].addr = (__u32)virt_to_bus(bh->b_data);
+			tmp_sg[seg].size = bh->b_size;
+			tmp_sg[seg].start_addr = bh->b_data;
 			lastdataend = bh->b_data + bh->b_size;
 			seg++;
 		}
 		bh = bh->b_reqnext;
 	}
+	/* Now do all the DMA Mappings */
+	for( i=0; i < seg; i++)
+	{
+		c->req.sg[i].size = tmp_sg[i].size;
+		c->req.sg[i].addr = (__u32) pci_map_single(
+                		h->pci_dev, tmp_sg[i].start_addr, 
+				tmp_sg[i].size,
+                                (creq->cmd == READ) ? 
+					PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+	}
 DBGPX(	printk("Submitting %d sectors in %d segments\n", sect, seg); );
 	c->req.hdr.sg_cnt = seg;
 	c->req.hdr.blk_cnt = sect;
@@ -993,8 +1026,7 @@
 	h->Qdepth++;
 	if (h->Qdepth > h->maxQsinceinit) 
 		h->maxQsinceinit = h->Qdepth;
-
-	start_io(h);
+   } // while loop
 }
 
 /* 
@@ -1043,6 +1075,7 @@
 static inline void complete_command(cmdlist_t *cmd, int timeout)
 {
 	int ok=1;
+	int i;
 
 	if (cmd->req.hdr.rcode & RCODE_NONFATAL &&
 	   (hba[cmd->ctlr]->misc_tflags & MISC_NONFATAL_WARN) == 0) {
@@ -1063,6 +1096,13 @@
 		ok = 0;	
 	}
 	if (timeout) ok = 0;
+	/* unmap the DMA mapping for all the scatter gather elements */
+        for(i=0; i<cmd->req.hdr.sg_cnt; i++)
+        {
+                pci_unmap_single(hba[cmd->ctlr]->pci_dev,
+                        cmd->req.sg[i].addr, cmd->req.sg[i].size,
+                        (cmd->req.hdr.cmd == IDA_READ) ? PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+        }
 	complete_buffers(cmd->bh, ok);
 }
 
@@ -1110,7 +1150,7 @@
 				removeQ(&h->cmpQ, c);
 				if (c->type == CMD_RWREQ) {
 					complete_command(c, 0);
-					cmd_free(h, c);
+					cmd_free(h, c, 1);
 				} else if (c->type == CMD_IOCTL_PEND) {
 					c->type = CMD_IOCTL_DONE;
 				}
@@ -1243,7 +1283,7 @@
 	unsigned long flags;
 	int error;
 
-	if ((c = cmd_alloc(NULL)) == NULL)
+	if ((c = cmd_alloc(h, 0)) == NULL)
 		return -ENOMEM;
 	c->ctlr = ctlr;
 	c->hdr.unit = (io->unit & UNITVALID) ? (io->unit & ~UNITVALID) : dsk;
@@ -1262,13 +1302,16 @@
 		if (!p) 
 		{ 
 			error = -ENOMEM; 
-			cmd_free(NULL, c); 
+			cmd_free(h, c, 0); 
 			return(error);
 		}
 		copy_from_user(p, (void*)io->sg[0].addr, io->sg[0].size);
-		c->req.hdr.blk = virt_to_bus(&(io->c));
+		c->req.hdr.blk = pci_map_single(h->pci_dev, &(io->c), 
+				sizeof(ida_ioctl_t), 
+				PCI_DMA_BIDIRECTIONAL);
 		c->req.sg[0].size = io->sg[0].size;
-		c->req.sg[0].addr = virt_to_bus(p);
+		c->req.sg[0].addr = pci_map_single(h->pci_dev, p, 
+			c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL);
 		c->req.hdr.sg_cnt = 1;
 		break;
 	case IDA_READ:
@@ -1276,12 +1319,13 @@
 		if (!p) 
 		{ 
                         error = -ENOMEM; 
-                        cmd_free(NULL, c);
+                        cmd_free(h, c, 0);
                         return(error);
                 }
 
 		c->req.sg[0].size = io->sg[0].size;
-		c->req.sg[0].addr = virt_to_bus(p);
+		c->req.sg[0].addr = pci_map_single(h->pci_dev, p, 
+			c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL); 
 		c->req.hdr.sg_cnt = 1;
 		break;
 	case IDA_WRITE:
@@ -1291,20 +1335,22 @@
 		if (!p) 
  		{ 
                         error = -ENOMEM; 
-                        cmd_free(NULL, c);
+                        cmd_free(h, c, 0);
                         return(error);
                 }
 		copy_from_user(p, (void*)io->sg[0].addr, io->sg[0].size);
 		c->req.sg[0].size = io->sg[0].size;
-		c->req.sg[0].addr = virt_to_bus(p);
+		c->req.sg[0].addr = pci_map_single(h->pci_dev, p, 
+			c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL); 
 		c->req.hdr.sg_cnt = 1;
 		break;
 	default:
 		c->req.sg[0].size = sizeof(io->c);
-		c->req.sg[0].addr = virt_to_bus(&io->c);
+		c->req.sg[0].addr = pci_map_single(h->pci_dev,&io->c, 
+			c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL);
 		c->req.hdr.sg_cnt = 1;
 	}
-
+	
 	/* Put the request on the tail of the request queue */
 	spin_lock_irqsave(&io_request_lock, flags);
 	addQ(&h->reqQ, c);
@@ -1316,9 +1362,15 @@
 	while(c->type != CMD_IOCTL_DONE)
 		schedule();
 
+	/* Unmap the DMA  */
+	pci_unmap_single(h->pci_dev, c->req.sg[0].addr, c->req.sg[0].size, 
+		PCI_DMA_BIDIRECTIONAL);
 	/* Post submit processing */
 	switch(io->cmd) {
 	case PASSTHRU_A:
+		pci_unmap_single(h->pci_dev, c->req.hdr.blk,
+                                sizeof(ida_ioctl_t),
+                                PCI_DMA_BIDIRECTIONAL);
 	case IDA_READ:
 	case DIAG_PASS_THRU:
 		copy_to_user((void*)io->sg[0].addr, p, io->sg[0].size);
@@ -1332,7 +1384,7 @@
 	}
 
 	io->rcode = c->req.hdr.rcode;
-	cmd_free(NULL, c);
+	cmd_free(h, c, 0);
 	return(0);
 }
 
@@ -1342,13 +1394,15 @@
  * critical (and can wait for kmalloc and possibly sleep) can pass in NULL
  * as the first argument to get a new command.
  */
-static cmdlist_t * cmd_alloc(ctlr_info_t *h)
+static cmdlist_t * cmd_alloc(ctlr_info_t *h, int get_from_pool)
 {
 	cmdlist_t * c;
 	int i;
+	dma_addr_t cmd_dhandle;
 
-	if (h == NULL) {
-		c = (cmdlist_t*)kmalloc(sizeof(cmdlist_t), GFP_KERNEL);
+	if (!get_from_pool) {
+		c = (cmdlist_t*)pci_alloc_consistent(h->pci_dev, 
+			sizeof(cmdlist_t), &cmd_dhandle);
 		if(c==NULL)
 			return NULL;
 	} else {
@@ -1358,20 +1412,22 @@
 				return NULL;
 		} while(test_and_set_bit(i%32, h->cmd_pool_bits+(i/32)) != 0);
 		c = h->cmd_pool + i;
+		cmd_dhandle = h->cmd_pool_dhandle + i*sizeof(cmdlist_t);
 		h->nr_allocs++;
 	}
 
 	memset(c, 0, sizeof(cmdlist_t));
-	c->busaddr = virt_to_bus(c);
+	c->busaddr = cmd_dhandle; 
 	return c;
 }
 
-static void cmd_free(ctlr_info_t *h, cmdlist_t *c)
+static void cmd_free(ctlr_info_t *h, cmdlist_t *c, int got_from_pool)
 {
 	int i;
 
-	if (h == NULL) {
-		kfree(c);
+	if (!got_from_pool) {
+		pci_free_consistent(h->pci_dev, sizeof(cmdlist_t), c,
+			c->busaddr);
 	} else {
 		i = c - h->cmd_pool;
 		clear_bit(i%32, h->cmd_pool_bits+(i/32));
@@ -1400,7 +1456,7 @@
 	unsigned long i;
 	ctlr_info_t *info_p = hba[ctlr];
 
-	c = cmd_alloc(info_p);
+	c = cmd_alloc(info_p, 1);
 	if(!c)
 		return IO_ERROR;
 	c->ctlr = ctlr;
@@ -1424,7 +1480,8 @@
 	c->req.hdr.blk = blk;
 	c->req.hdr.blk_cnt = blkcnt;
 	c->req.hdr.cmd = (unsigned char) cmd;
-	c->req.sg[0].addr = (__u32) virt_to_bus(buff);
+	c->req.sg[0].addr = (__u32) pci_map_single(info_p->pci_dev, 
+		buff, c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL);
 	/*
 	 * Disable interrupt
 	 */
@@ -1447,13 +1504,16 @@
 	 */
 	info_p->access.submit_command(info_p, c);
 	complete = pollcomplete(ctlr);
+	
+	pci_unmap_single(info_p->pci_dev, (dma_addr_t) c->req.sg[0].addr, 
+		c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL);
 	if (complete != 1) {
 		if (complete != c->busaddr) {
 			printk( KERN_WARNING
 			"cpqarray ida%d: idaSendPciCmd "
 		      "Invalid command list address returned! (%08lx)\n",
 				ctlr, (unsigned long)complete);
-			cmd_free(info_p, c);
+			cmd_free(info_p, c, 1);
 			return (IO_ERROR);
 		}
 	} else {
@@ -1461,7 +1521,7 @@
 			"cpqarray ida%d: idaSendPciCmd Timeout out, "
 			"No command list address returned!\n",
 			ctlr);
-		cmd_free(info_p, c);
+		cmd_free(info_p, c, 1);
 		return (IO_ERROR);
 	}
 
@@ -1473,11 +1533,11 @@
 				"cmd: 0x%x, return code = 0x%x\n",
 				ctlr, c->req.hdr.cmd, c->req.hdr.rcode);
 
-			cmd_free(info_p, c);
+			cmd_free(info_p, c, 1);
 			return (IO_ERROR);
 		}
 	}
-	cmd_free(info_p, c);
+	cmd_free(info_p, c, 1);
 	return (IO_OK);
 }
 
@@ -1574,13 +1634,9 @@
 	max_p = gdev->max_p;
 	start = target << gdev->minor_shift;
 
-	for(i=max_p; i>=0; i--) {
+	for(i=max_p-1; i>=0; i--) {
 		int minor = start+i;
-		kdev_t devi = MKDEV(MAJOR_NR + ctlr, minor);
-		struct super_block *sb = get_super(devi);
-		sync_dev(devi);
-		if (sb) invalidate_inodes(sb);
-		invalidate_buffers(devi);
+		invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1);
 		gdev->part[minor].start_sect = 0;	
 		gdev->part[minor].nr_sects = 0;	
 
diff -u --recursive --new-file v2.4.4/linux/drivers/block/cpqarray.h linux/drivers/block/cpqarray.h
--- v2.4.4/linux/drivers/block/cpqarray.h	Fri Feb  9 11:30:22 2001
+++ linux/drivers/block/cpqarray.h	Tue May 22 10:23:16 2001
@@ -56,6 +56,11 @@
 
 #ifdef __KERNEL__
 
+struct my_sg {
+	int size;
+	char *start_addr;
+};
+
 struct ctlr_info;
 typedef struct ctlr_info ctlr_info_t;
 
@@ -104,6 +109,7 @@
 	cmdlist_t *reqQ;
 	cmdlist_t *cmpQ;
 	cmdlist_t *cmd_pool;
+	dma_addr_t cmd_pool_dhandle;
 	__u32	*cmd_pool_bits;
 
 	unsigned int Qdepth;
diff -u --recursive --new-file v2.4.4/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v2.4.4/linux/drivers/block/genhd.c	Sun Sep 17 23:16:35 2000
+++ linux/drivers/block/genhd.c	Wed May 16 14:01:32 2001
@@ -17,8 +17,6 @@
 #include <linux/blk.h>
 #include <linux/init.h>
 
-extern int parport_init(void);
-extern int chr_dev_init(void);
 extern int blk_dev_init(void);
 #ifdef CONFIG_BLK_DEV_DAC960
 extern void DAC960_Initialize(void);
@@ -31,12 +29,8 @@
 extern int cpqarray_init(void);
 extern void ieee1394_init(void);
 
-void __init device_init(void)
+int __init device_init(void)
 {
-#ifdef CONFIG_PARPORT
-	parport_init();
-#endif
-	chr_dev_init();
 	blk_dev_init();
 	sti();
 #ifdef CONFIG_I2O
@@ -64,4 +58,7 @@
 #ifdef CONFIG_VT
 	console_map_init();
 #endif
+	return 0;
 }
+
+__initcall(device_init);
diff -u --recursive --new-file v2.4.4/linux/drivers/block/nbd.c linux/drivers/block/nbd.c
--- v2.4.4/linux/drivers/block/nbd.c	Wed Apr 11 19:02:30 2001
+++ linux/drivers/block/nbd.c	Tue May  1 14:20:25 2001
@@ -5,7 +5,8 @@
  * deadlocks sometimes - you can not swap over TCP in general.
  * 
  * Copyright 1997-2000 Pavel Machek <pavel@ucw.cz>
- * 
+ * Parts copyright 2001 Steven Whitehouse <steve@chygwyn.com>
+ *
  * (part of code stolen from loop.c)
  *
  * 97-3-25 compiled 0-th version, not yet tested it 
@@ -20,6 +21,9 @@
  * 99-1-11 Attempt to make 64-bit-clean on 32-bit machines <ankry@mif.pg.gda.pl>
  * 01-2-27 Fix to store proper blockcount for kernel (calculated using
  *   BLOCK_SIZE_BITS, not device blocksize) <aga@permonline.ru>
+ * 01-3-11 Make nbd work with new Linux block layer code. It now supports
+ *   plugging like all the other block devices. Also added in MSG_MORE to
+ *   reduce number of partial TCP segments sent. <steve@chygwyn.com>
  *
  * possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall
  * why not: would need verify_area and friends, would share yet another 
diff -u --recursive --new-file v2.4.4/linux/drivers/block/paride/pd.c linux/drivers/block/paride/pd.c
--- v2.4.4/linux/drivers/block/paride/pd.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/block/paride/pd.c	Sat Apr 28 11:27:53 2001
@@ -589,9 +589,6 @@
 
 {       int p, unit, minor;
         long flags;
-        kdev_t devp;
-
-	struct super_block *sb;
 
         unit = DEVICE_NR(dev);
         if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV;
@@ -607,13 +604,7 @@
 
         for (p=(PD_PARTNS-1);p>=0;p--) {
 		minor = p + unit*PD_PARTNS;
-                devp = MKDEV(MAJOR_NR, minor);
-                fsync_dev(devp);
-
-                sb = get_super(devp);
-                if (sb) invalidate_inodes(sb);
-
-                invalidate_buffers(devp);
+                invalidate_device(MKDEV(MAJOR_NR, minor), 1);
                 pd_hd[minor].start_sect = 0;
                 pd_hd[minor].nr_sects = 0;
         }
diff -u --recursive --new-file v2.4.4/linux/drivers/block/ps2esdi.c linux/drivers/block/ps2esdi.c
--- v2.4.4/linux/drivers/block/ps2esdi.c	Wed Apr 18 11:49:13 2001
+++ linux/drivers/block/ps2esdi.c	Tue May  1 16:05:00 2001
@@ -56,7 +56,7 @@
 #include <asm/uaccess.h>
 
 #define PS2ESDI_IRQ 14
-#define MAX_HD 1
+#define MAX_HD 2
 #define MAX_RETRIES 5
 #define MAX_16BIT 65536
 #define ESDI_TIMEOUT   0xf000
@@ -105,14 +105,14 @@
 
 static void ps2esdi_get_device_cfg(void);
 
-void ps2esdi_reset_timer(unsigned long unused);
+static void ps2esdi_reset_timer(unsigned long unused);
 
-u_int dma_arb_level;		/* DMA arbitration level */
+static u_int dma_arb_level;		/* DMA arbitration level */
 
 static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
 static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_wait_open);
 
-int no_int_yet;
+static int no_int_yet;
 static int access_count[MAX_HD];
 static char ps2esdi_valid[MAX_HD];
 static int ps2esdi_sizes[MAX_HD << 6];
@@ -123,26 +123,26 @@
 static struct timer_list esdi_timer = { function: ps2esdi_reset_timer };
 static int reset_status;
 static int ps2esdi_slot = -1;
-int tp720esdi = 0;		/* Is it Integrated ESDI of ThinkPad-720? */
-int intg_esdi = 0;              /* If integrated adapter */
+static int tp720esdi = 0;	/* Is it Integrated ESDI of ThinkPad-720? */
+static int intg_esdi = 0;       /* If integrated adapter */
 struct ps2esdi_i_struct {
 	unsigned int head, sect, cyl, wpcom, lzone, ctl;
 };
 
 #if 0
 #if 0				/* try both - I don't know which one is better... UB */
-struct ps2esdi_i_struct ps2esdi_info[] =
+static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
 {
 	{4, 48, 1553, 0, 0, 0},
 	{0, 0, 0, 0, 0, 0}};
 #else
-struct ps2esdi_i_struct ps2esdi_info[] =
+static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
 {
 	{64, 32, 161, 0, 0, 0},
 	{0, 0, 0, 0, 0, 0}};
 #endif
 #endif
-struct ps2esdi_i_struct ps2esdi_info[] =
+static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
 {
 	{0, 0, 0, 0, 0, 0},
 	{0, 0, 0, 0, 0, 0}};
@@ -191,9 +191,9 @@
 
 #ifdef MODULE
 
-int cyl[2] = {-1,-1};
-int head[2] = {-1, -1};
-int sect[2] = {-1, -1};
+static int cyl[MAX_HD] = {-1,-1};
+static int head[MAX_HD] = {-1, -1};
+static int sect[MAX_HD] = {-1, -1};
 
 MODULE_PARM(tp720esdi, "i");
 MODULE_PARM(cyl, "i");
@@ -203,7 +203,7 @@
 int init_module(void) {
 	int drive;
 
-	for(drive = 0; drive <= 1; drive++) {
+	for(drive = 0; drive < MAX_HD; drive++) {
 	        struct ps2_esdi_i_struct *info = &ps2esdi_info[drive];
 
         	if (cyl[drive] != -1) {
@@ -1145,15 +1145,9 @@
 	for (partition = ps2esdi_gendisk.max_p - 1;
 	     partition >= 0; partition--) {
 		int minor = (start | partition);
-		kdev_t devp = MKDEV(MAJOR_NR, minor);
-		struct super_block * sb = get_super(devp);
-		
-		sync_dev(devp);
-		if (sb)
-			invalidate_inodes(sb);
-		invalidate_buffers(devp);
-		ps2esdi_gendisk.part[start + partition].start_sect = 0;
-		ps2esdi_gendisk.part[start + partition].nr_sects = 0;
+		invalidate_device(MKDEV(MAJOR_NR, minor), 1);
+		ps2esdi_gendisk.part[minor].start_sect = 0;
+		ps2esdi_gendisk.part[minor].nr_sects = 0;
 	}
 
 	grok_partitions(&ps2esdi_gendisk, target, 1<<6, 
@@ -1165,7 +1159,7 @@
 	return (0);
 }
 
-void ps2esdi_reset_timer(unsigned long unused)
+static void ps2esdi_reset_timer(unsigned long unused)
 {
 
 	int status;
diff -u --recursive --new-file v2.4.4/linux/drivers/block/smart1,2.h linux/drivers/block/smart1,2.h
--- v2.4.4/linux/drivers/block/smart1,2.h	Fri Jun 23 21:04:36 2000
+++ linux/drivers/block/smart1,2.h	Tue May  1 16:05:00 2001
@@ -45,7 +45,7 @@
 }
 
 /*  
- *  This card is the oposite of the other cards.  
+ *  This card is the opposite of the other cards.  
  *   0 turns interrupts on... 
  *   0x08 turns them off... 
  */
diff -u --recursive --new-file v2.4.4/linux/drivers/block/swim3.c linux/drivers/block/swim3.c
--- v2.4.4/linux/drivers/block/swim3.c	Tue Sep 19 08:31:53 2000
+++ linux/drivers/block/swim3.c	Tue May 22 10:23:16 2001
@@ -851,7 +851,7 @@
 				   sizeof(struct floppy_struct));
 		return err;
 	}
-	return -ENOIOCTLCMD;
+	return -ENOTTY;
 }
 
 static int floppy_open(struct inode *inode, struct file *filp)
diff -u --recursive --new-file v2.4.4/linux/drivers/block/swim_iop.c linux/drivers/block/swim_iop.c
--- v2.4.4/linux/drivers/block/swim_iop.c	Wed Feb 16 10:56:45 2000
+++ linux/drivers/block/swim_iop.c	Sat May 19 17:43:05 2001
@@ -363,7 +363,7 @@
 				   sizeof(struct floppy_struct));
 		return err;
 	}
-	return -ENOIOCTLCMD;
+	return -ENOTTY;
 }
 
 static int floppy_open(struct inode *inode, struct file *filp)
diff -u --recursive --new-file v2.4.4/linux/drivers/block/xd.c linux/drivers/block/xd.c
--- v2.4.4/linux/drivers/block/xd.c	Fri Feb 16 16:02:35 2001
+++ linux/drivers/block/xd.c	Sat Apr 28 11:27:53 2001
@@ -401,13 +401,7 @@
 
 	for (partition = xd_gendisk.max_p - 1; partition >= 0; partition--) {
 		int minor = (start | partition);
-		kdev_t devp = MKDEV(MAJOR_NR, minor);
-		struct super_block * sb = get_super(devp);
-		
-		sync_dev(devp);
-		if (sb)
-			invalidate_inodes(sb);
-		invalidate_buffers(devp);
+		invalidate_device(MKDEV(MAJOR_NR, minor), 1);
 		xd_gendisk.part[minor].start_sect = 0;
 		xd_gendisk.part[minor].nr_sects = 0;
 	};
@@ -1163,16 +1157,6 @@
 	int partition,dev,start;
 
 	devfs_unregister_blkdev(MAJOR_NR, "xd");
-	for (dev = 0; dev < xd_drives; dev++) {
-		start = dev << xd_gendisk.minor_shift; 
-		for (partition = xd_gendisk.max_p - 1; partition >= 0; partition--) {
-			int minor = (start | partition);
-			kdev_t devp = MKDEV(MAJOR_NR, minor);
-			start = dev << xd_gendisk.minor_shift; 
-			sync_dev(devp);
-			invalidate_buffers(devp);
-		}
-	}
 	xd_done();
 	devfs_unregister (devfs_handle);
 	if (xd_drives) {
diff -u --recursive --new-file v2.4.4/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c
--- v2.4.4/linux/drivers/cdrom/cdrom.c	Thu Mar 29 11:56:07 2001
+++ linux/drivers/cdrom/cdrom.c	Fri May  4 15:09:23 2001
@@ -2626,7 +2626,8 @@
 
 static void cdrom_sysctl_unregister(void)
 {
-	unregister_sysctl_table(cdrom_sysctl_header);
+	if (cdrom_sysctl_header)
+		unregister_sysctl_table(cdrom_sysctl_header);
 }
 
 #endif /* CONFIG_SYSCTL */
diff -u --recursive --new-file v2.4.4/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.4.4/linux/drivers/char/Makefile	Thu Apr 26 14:11:29 2001
+++ linux/drivers/char/Makefile	Wed May 16 10:27:02 2001
@@ -16,7 +16,7 @@
 
 O_TARGET := char.o
 
-obj-y	 += tty_io.o n_tty.o tty_ioctl.o mem.o raw.o pty.o misc.o random.o
+obj-y	 += mem.o tty_io.o n_tty.o tty_ioctl.o raw.o pty.o misc.o random.o
 
 # All of the (potential) objects that export symbols.
 # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
diff -u --recursive --new-file v2.4.4/linux/drivers/char/acquirewdt.c linux/drivers/char/acquirewdt.c
--- v2.4.4/linux/drivers/char/acquirewdt.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/char/acquirewdt.c	Sat May 19 17:43:05 2001
@@ -110,7 +110,7 @@
 	  break;
 
 	default:
-	  return -ENOIOCTLCMD;
+	  return -ENOTTY;
 	}
 	return 0;
 }
diff -u --recursive --new-file v2.4.4/linux/drivers/char/advantechwdt.c linux/drivers/char/advantechwdt.c
--- v2.4.4/linux/drivers/char/advantechwdt.c	Tue Mar  6 19:44:34 2001
+++ linux/drivers/char/advantechwdt.c	Sat May 19 17:43:05 2001
@@ -120,7 +120,7 @@
 	  break;
 
 	default:
-	  return -ENOIOCTLCMD;
+	  return -ENOTTY;
 	}
 	return 0;
 }
diff -u --recursive --new-file v2.4.4/linux/drivers/char/agp/agpgart_fe.c linux/drivers/char/agp/agpgart_fe.c
--- v2.4.4/linux/drivers/char/agp/agpgart_fe.c	Wed Apr 11 19:02:30 2001
+++ linux/drivers/char/agp/agpgart_fe.c	Tue May 15 01:29:34 2001
@@ -852,6 +852,9 @@
 	if (copy_from_user(&reserve, (void *) arg, sizeof(agp_region))) {
 		return -EFAULT;
 	}
+	if ((unsigned) reserve.seg_count >= ~0U/sizeof(agp_segment))
+		return -EFAULT;
+
 	client = agp_find_client_by_pid(reserve.pid);
 
 	if (reserve.seg_count == 0) {
diff -u --recursive --new-file v2.4.4/linux/drivers/char/drm/ffb_drv.c linux/drivers/char/drm/ffb_drv.c
--- v2.4.4/linux/drivers/char/drm/ffb_drv.c	Fri Apr 13 20:15:55 2001
+++ linux/drivers/char/drm/ffb_drv.c	Sun May 20 12:11:38 2001
@@ -6,7 +6,6 @@
 
 #include "drmP.h"
 
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/smp_lock.h>
 #include <asm/shmparam.h>
diff -u --recursive --new-file v2.4.4/linux/drivers/char/drm/fops.c linux/drivers/char/drm/fops.c
--- v2.4.4/linux/drivers/char/drm/fops.c	Tue Aug 29 14:09:15 2000
+++ linux/drivers/char/drm/fops.c	Tue May 22 10:23:16 2001
@@ -47,7 +47,10 @@
 	DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
 
 	priv		    = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
+	if(priv == NULL)
+		return -ENOMEM;
 	memset(priv, 0, sizeof(*priv));
+
 	filp->private_data  = priv;
 	priv->uid	    = current->euid;
 	priv->pid	    = current->pid;
diff -u --recursive --new-file v2.4.4/linux/drivers/char/epca.c linux/drivers/char/epca.c
--- v2.4.4/linux/drivers/char/epca.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/char/epca.c	Tue May 22 10:23:16 2001
@@ -876,6 +876,9 @@
 
 		/* First we read the data in from the file system into a temp buffer */
 
+		memoff(ch);
+		restore_flags(flags);
+
 		if (bytesAvailable) 
 		{ /* Begin bytesAvailable */
 
@@ -916,8 +919,6 @@
 			post_fep_init.
 		--------------------------------------------------------------------- */
 		buf = ch->tmp_buf;
-		memoff(ch);
-		restore_flags(flags);
 
 	} /* End from_user */
 
diff -u --recursive --new-file v2.4.4/linux/drivers/char/i810-tco.c linux/drivers/char/i810-tco.c
--- v2.4.4/linux/drivers/char/i810-tco.c	Fri Dec 29 14:35:47 2000
+++ linux/drivers/char/i810-tco.c	Tue May 22 10:23:16 2001
@@ -213,7 +213,7 @@
 	};
 	switch (cmd) {
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 	case WDIOC_GETSUPPORT:
 		if (copy_to_user
 		    ((struct watchdog_info *) arg, &ident, sizeof (ident)))
diff -u --recursive --new-file v2.4.4/linux/drivers/char/machzwd.c linux/drivers/char/machzwd.c
--- v2.4.4/linux/drivers/char/machzwd.c	Thu Apr 12 12:16:35 2001
+++ linux/drivers/char/machzwd.c	Tue May 22 10:23:16 2001
@@ -357,7 +357,7 @@
 			break;
 
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 	}
 
 	return 0;
diff -u --recursive --new-file v2.4.4/linux/drivers/char/mem.c linux/drivers/char/mem.c
--- v2.4.4/linux/drivers/char/mem.c	Fri Apr 27 14:23:25 2001
+++ linux/drivers/char/mem.c	Sat May 19 18:11:36 2001
@@ -29,9 +29,6 @@
 #ifdef CONFIG_I2C
 extern int i2c_init_all(void);
 #endif
-#ifdef CONFIG_VIDEO_DEV
-extern int videodev_init(void);
-#endif
 #ifdef CONFIG_FB
 extern void fbmem_init(void);
 #endif
@@ -648,8 +645,7 @@
 #if defined(CONFIG_ADB)
 	adbdev_init();
 #endif
-#ifdef CONFIG_VIDEO_DEV
-	videodev_init();
-#endif
 	return 0;
 }
+
+__initcall(chr_dev_init);
diff -u --recursive --new-file v2.4.4/linux/drivers/char/mixcomwd.c linux/drivers/char/mixcomwd.c
--- v2.4.4/linux/drivers/char/mixcomwd.c	Sun Dec  3 17:45:21 2000
+++ linux/drivers/char/mixcomwd.c	Tue May 22 10:23:16 2001
@@ -165,7 +165,7 @@
 			mixcomwd_ping();
 			break;
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 	}
 	return 0;
 }
diff -u --recursive --new-file v2.4.4/linux/drivers/char/moxa.c linux/drivers/char/moxa.c
--- v2.4.4/linux/drivers/char/moxa.c	Wed Dec  6 12:06:18 2000
+++ linux/drivers/char/moxa.c	Tue May 22 10:23:16 2001
@@ -698,21 +698,32 @@
 	struct moxa_str *ch;
 	int len, port;
 	unsigned long flags;
-	unsigned char *temp;
 
 	ch = (struct moxa_str *) tty->driver_data;
 	if (ch == NULL)
 		return (0);
 	port = ch->port;
 	save_flags(flags);
-	cli();
 	if (from_user) {
-		copy_from_user(moxaXmitBuff, buf, count);
-		temp = moxaXmitBuff;
-	} else
-		temp = (unsigned char *) buf;
-	len = MoxaPortWriteData(port, temp, count);
-	restore_flags(flags);
+		if (count > PAGE_SIZE)
+			count = PAGE_SIZE;
+		down(&moxaBuffSem);
+		if (copy_from_user(moxaXmitBuff, buf, count)) {
+			len = -EFAULT;
+		} else {
+			cli();
+			len = MoxaPortWriteData(port, moxaXmitBuff, count);
+			restore_flags(flags);
+		}
+		up(&moxaBuffSem);
+		if (len < 0)
+			return len;
+	} else {
+		cli();
+		len = MoxaPortWriteData(port, (unsigned char *) buf, count);
+		restore_flags(flags);
+	}
+
 	/*********************************************
 	if ( !(ch->statusflags & LOWWAIT) &&
 	     ((len != count) || (MoxaPortTxFree(port) <= 100)) )
diff -u --recursive --new-file v2.4.4/linux/drivers/char/mxser.c linux/drivers/char/mxser.c
--- v2.4.4/linux/drivers/char/mxser.c	Fri Mar  2 11:12:07 2001
+++ linux/drivers/char/mxser.c	Wed May 16 10:31:27 2001
@@ -27,10 +27,11 @@
  *
  *      Copyright (C) 1999,2000  Moxa Technologies Co., LTD.
  *
- *      for             : LINUX 2.0.X, 2.2.X
- *      date            : 1999/07/22
- *      version         : 1.1 
+ *      for             : LINUX 2.0.X, 2.2.X, 2.4.X
+ *      date            : 2001/05/01
+ *      version         : 1.2 
  *      
+ *    Fixes for C104H/PCI by Tim Hockin <thockin@sun.com>
  */
 
 #include <linux/config.h>
@@ -61,7 +62,7 @@
 #include <asm/bitops.h>
 #include <asm/uaccess.h>
 
-#define		MXSER_VERSION			"1.1kern"
+#define		MXSER_VERSION			"1.2"
 
 #define		MXSERMAJOR	 	174
 #define		MXSERCUMAJOR		175
@@ -120,7 +121,7 @@
 #define CI104J_ASIC_ID  5
 
 enum {
-	MXSER_BOARD_C168_ISA = 1,
+	MXSER_BOARD_C168_ISA = 0,
 	MXSER_BOARD_C104_ISA,
 	MXSER_BOARD_CI104J,
 	MXSER_BOARD_C168_PCI,
@@ -434,7 +435,7 @@
 			     "mxser", info);
 	if (retval) {
 		restore_flags(flags);
-		printk("Board %d: %s", board, mxser_brdname[hwconf->board_type - 1]);
+		printk("Board %d: %s", board, mxser_brdname[hwconf->board_type]);
 		printk("  Request irq fail,IRQ (%d) may be conflit with another device.\n", info->irq);
 		return (retval);
 	}
@@ -455,7 +456,7 @@
 	unsigned int ioaddress;
 
 	hwconf->board_type = board_type;
-	hwconf->ports = mxser_numports[board_type - 1];
+	hwconf->ports = mxser_numports[board_type];
 	ioaddress = pci_resource_start (pdev, 2);
 	for (i = 0; i < hwconf->ports; i++)
 		hwconf->ioaddr[i] = ioaddress + 8 * i;
@@ -544,7 +545,7 @@
 
 		if (retval != 0)
 			printk("Found MOXA %s board (CAP=0x%x)\n",
-			       mxser_brdname[hwconf.board_type - 1],
+			       mxser_brdname[hwconf.board_type],
 			       ioaddr[b]);
 
 		if (retval <= 0) {
@@ -579,7 +580,7 @@
 
 		if (retval != 0)
 			printk("Found MOXA %s board (CAP=0x%x)\n",
-			       mxser_brdname[hwconf.board_type - 1],
+			       mxser_brdname[hwconf.board_type],
 			       ioaddr[b]);
 
 		if (retval <= 0) {
@@ -612,21 +613,15 @@
 
 		n = sizeof(mxser_pcibrds) / sizeof(mxser_pciinfo);
 		index = 0;
-		b = 0;
-		while (b < n) {
+		for (b = 0; b < n; b++) {
 			pdev = pci_find_device(mxser_pcibrds[b].vendor_id,
 					       mxser_pcibrds[b].device_id, pdev);
-			if (!pdev)
-			{
-				b++;
-				continue;
-			}
-			if (pci_enable_device(pdev))
+			if (!pdev || pci_enable_device(pdev))
 				continue;
 			hwconf.pdev = pdev;
 			printk("Found MOXA %s board(BusNo=%d,DevNo=%d)\n",
-				mxser_brdname[mxser_pcibrds[b].board_type - 1],
-				pdev->bus->number, PCI_SLOT(pdev->devfn >> 3));
+				mxser_brdname[mxser_pcibrds[b].board_type],
+				pdev->bus->number, PCI_SLOT(pdev->devfn));
 			if (m >= MXSER_BOARDS) {
 				printk("Too many Smartio family boards found (maximum %d),board not configured\n", MXSER_BOARDS);
 			} else {
@@ -892,29 +887,56 @@
 	if (from_user)
 		down(&mxvar_tmp_buf_sem);
 	save_flags(flags);
-	while (1) {
-		cli();
-		c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-				   SERIAL_XMIT_SIZE - info->xmit_head));
-		if (c <= 0)
-			break;
+	if (from_user) {
+		down(&mxvar_tmp_buf_sem);
+		while (1) {
+			c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+					   SERIAL_XMIT_SIZE - info->xmit_head));
+			if (c <= 0)
+				break;
 
-		if (from_user) {
-			copy_from_user(mxvar_tmp_buf, buf, c);
+			c -= copy_from_user(mxvar_tmp_buf, buf, c);
+			if (!c) {
+				if (!total)
+					total = -EFAULT;
+				break;
+			}
+
+			cli();
 			c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-				    SERIAL_XMIT_SIZE - info->xmit_head));
+				       SERIAL_XMIT_SIZE - info->xmit_head));
 			memcpy(info->xmit_buf + info->xmit_head, mxvar_tmp_buf, c);
-		} else
+			info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
+			info->xmit_cnt += c;
+			restore_flags(flags);
+
+			buf += c;
+			count -= c;
+			total += c;
+		}
+		up(&mxvar_tmp_buf_sem);
+	} else {
+		while (1) {
+			cli();
+			c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+					   SERIAL_XMIT_SIZE - info->xmit_head));
+			if (c <= 0) {
+				restore_flags(flags);
+				break;
+			}
+
 			memcpy(info->xmit_buf + info->xmit_head, buf, c);
-		info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
-		info->xmit_cnt += c;
-		restore_flags(flags);
-		buf += c;
-		count -= c;
-		total += c;
+			info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE - 1);
+			info->xmit_cnt += c;
+			restore_flags(flags);
+
+			buf += c;
+			count -= c;
+			total += c;
+		}
 	}
-	if (from_user)
-		up(&mxvar_tmp_buf_sem);
+
+	cli();
 	if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
 	    !(info->IER & UART_IER_THRI)) {
 		info->IER |= UART_IER_THRI;
@@ -1352,7 +1374,7 @@
 		return;
 	if (port == 0)
 		return;
-	max = mxser_numports[mxsercfg[i].board_type - 1];
+	max = mxser_numports[mxsercfg[i].board_type];
 
 	while (1) {
 		irqbits = inb(port->vector) & port->vectormask;
diff -u --recursive --new-file v2.4.4/linux/drivers/char/pc110pad.c linux/drivers/char/pc110pad.c
--- v2.4.4/linux/drivers/char/pc110pad.c	Sun Feb  4 10:05:29 2001
+++ linux/drivers/char/pc110pad.c	Tue May 22 10:23:16 2001
@@ -766,7 +766,7 @@
 		current_params.tap_interval	= new.tap_interval;
 		return 0;
 	}
-	return -ENOIOCTLCMD;
+	return -ENOTTY;
 }
 
 
diff -u --recursive --new-file v2.4.4/linux/drivers/char/pcwd.c linux/drivers/char/pcwd.c
--- v2.4.4/linux/drivers/char/pcwd.c	Fri Apr  6 10:42:55 2001
+++ linux/drivers/char/pcwd.c	Tue May 22 10:23:16 2001
@@ -247,7 +247,7 @@
 
 	switch(cmd) {
 	default:
-		return -ENOIOCTLCMD;
+		return -ENOTTY;
 
 	case WDIOC_GETSUPPORT:
 		i = copy_to_user((void*)arg, &ident, sizeof(ident));
diff -u --recursive --new-file v2.4.4/linux/drivers/char/pcxx.c linux/drivers/char/pcxx.c
--- v2.4.4/linux/drivers/char/pcxx.c	Fri Feb 16 16:02:35 2001
+++ linux/drivers/char/pcxx.c	Tue May 22 10:23:16 2001
@@ -685,7 +685,6 @@
 	int total, remain, size, stlen;
 	unsigned int head, tail;
 	unsigned long flags;
-
 	/* printk("Entering pcxe_write()\n"); */
 
 	if ((ch=chan(tty))==NULL)
@@ -696,6 +695,7 @@
 
 	if (from_user) {
 
+		down(&ch->tmp_buf_sem);
 		save_flags(flags);
 		cli();
 		globalwinon(ch);
@@ -703,19 +703,21 @@
 		/* It seems to be necessary to make sure that the value is stable here somehow
 		   This is a rather odd pice of code here. */
 		do
-		{ tail = bc->tout;
+		{
+			tail = bc->tout;
 		} while (tail != bc->tout);
 		
 		tail &= (size - 1);
 		stlen = (head >= tail) ? (size - (head - tail) - 1) : (tail - head - 1);
 		count = MIN(stlen, count);
+		memoff(ch);
+		restore_flags(flags);
+
 		if (count)
 			if (copy_from_user(ch->tmp_buf, buf, count))
 				count = 0;
 
 		buf = ch->tmp_buf;
-		memoff(ch);
-		restore_flags(flags);
 	}
 
 	/*
@@ -763,6 +765,9 @@
 	}
 	memoff(ch);
 	restore_flags(flags);
+	
+	if(from_user)
+		up(&ch->tmp_buf_sem);
 
 	return(total);
 }
@@ -1587,6 +1592,7 @@
 			ch->txbufsize = bc->tmax + 1;
 			ch->rxbufsize = bc->rmax + 1;
 			ch->tmp_buf = kmalloc(ch->txbufsize,GFP_KERNEL);
+			init_MUTEX(&ch->tmp_buf_sem);
 
 			if (!ch->tmp_buf) {
 				printk(KERN_ERR "Unable to allocate memory for temp buffers\n");
diff -u --recursive --new-file v2.4.4/linux/drivers/char/pcxx.h linux/drivers/char/pcxx.h
--- v2.4.4/linux/drivers/char/pcxx.h	Tue Aug 22 15:21:54 2000
+++ linux/drivers/char/pcxx.h	Tue May 22 10:23:16 2001
@@ -120,6 +120,7 @@
 	unchar						*txptr;
 	unchar						*rxptr;
 	unchar						*tmp_buf;		/* Temp buffer */
+	struct semaphore				tmp_buf_sem;
 							/* ---- Termios data ---- */
 	ulong						c_iflag;
 	ulong						c_cflag;
diff -u --recursive --new-file v2.4.4/linux/drivers/char/ppdev.c linux/drivers/char/ppdev.c
--- v2.4.4/linux/drivers/char/ppdev.c	Mon Oct 16 12:58:51 2000
+++ linux/drivers/char/ppdev.c	Sat May 19 18:07:04 2001
@@ -35,17 +35,25 @@
  *   WCTLONIRQ	on interrupt, set control lines
  *   CLRIRQ	clear (and return) interrupt count
  *   SETTIME	sets device timeout (struct timeval)
- *   GETTIME    gets device timeout (struct timeval)
+ *   GETTIME	gets device timeout (struct timeval)
+ *   GETMODES	gets hardware supported modes (unsigned int)
+ *   GETMODE	gets the current IEEE1284 mode
+ *   GETPHASE   gets the current IEEE1284 phase
+ *   GETFLAGS   gets current (user-visible) flags
+ *   SETFLAGS   sets current (user-visible) flags
  * read/write	read or write in current IEEE 1284 protocol
  * select	wait for interrupt (in readfds)
  *
  * Changes:
- * Added SETTIME/GETTIME ioctl, Fred Barnes 1999.
+ * Added SETTIME/GETTIME ioctl, Fred Barnes, 1999.
  *
  * Arnaldo Carvalho de Melo <acme@conectiva.com.br> 2000/08/25
  * - On error, copy_from_user and copy_to_user do not return -EFAULT,
  *   They return the positive number of bytes *not* copied due to address
  *   space errors.
+ *
+ * Added GETMODES/GETMODE/GETPHASE ioctls, Fred Barnes <frmb2@ukc.ac.uk>, 03/01/2001.
+ * Added GETFLAGS/SETFLAGS ioctls, Fred Barnes, 04/2001
  */
 
 #include <linux/module.h>
@@ -84,7 +92,7 @@
 
 /* Other constants */
 #define PP_INTERRUPT_TIMEOUT (10 * HZ) /* 10s */
-#define PP_BUFFER_SIZE 256
+#define PP_BUFFER_SIZE 1024
 #define PARDEVICE_MAX 8
 
 /* ROUND_UP macro from fs/select.c */
@@ -109,6 +117,8 @@
 	char * kbuffer;
 	ssize_t bytes_read = 0;
 	ssize_t got = 0;
+	struct parport *pport;
+	int mode;
 
 	if (!(pp->flags & PP_CLAIMED)) {
 		/* Don't have the port claimed */
@@ -118,18 +128,40 @@
 	}
 
 	kbuffer = kmalloc (min (count, PP_BUFFER_SIZE), GFP_KERNEL);
-	if (!kbuffer)
+	if (!kbuffer) {
 		return -ENOMEM;
+	}
+	pport = pp->pdev->port;
+	mode = pport->ieee1284.mode & ~(IEEE1284_DEVICEID | IEEE1284_ADDR);
 
 	while (bytes_read < count) {
 		ssize_t need = min(count - bytes_read, PP_BUFFER_SIZE);
 
-		got = parport_read (pp->pdev->port, kbuffer, need);
+		if (mode == IEEE1284_MODE_EPP) {
+			/* various specials for EPP mode */
+			int flags = 0;
+			size_t (*fn)(struct parport *, void *, size_t, int);
+
+			if (pp->flags & PP_W91284PIC) {
+				flags |= PARPORT_W91284PIC;
+			}
+			if (pp->flags & PP_FASTREAD) {
+				flags |= PARPORT_EPP_FAST;
+			}
+			if (pport->ieee1284.mode & IEEE1284_ADDR) {
+				fn = pport->ops->epp_read_addr;
+			} else {
+				fn = pport->ops->epp_read_data;
+			}
+			got = (*fn)(pport, kbuffer, need, flags);
+		} else {
+			got = parport_read (pport, kbuffer, need);
+		}
 
 		if (got <= 0) {
-			if (!bytes_read)
+			if (!bytes_read) {
 				bytes_read = got;
-
+			}
 			break;
 		}
 
@@ -141,13 +173,15 @@
 		bytes_read += got;
 
 		if (signal_pending (current)) {
-			if (!bytes_read)
+			if (!bytes_read) {
 				bytes_read = -EINTR;
+			}
 			break;
 		}
 
-		if (current->need_resched)
+		if (current->need_resched) {
 			schedule ();
+		}
 	}
 
 	kfree (kbuffer);
@@ -163,6 +197,8 @@
 	char * kbuffer;
 	ssize_t bytes_written = 0;
 	ssize_t wrote;
+	int mode;
+	struct parport *pport;
 
 	if (!(pp->flags & PP_CLAIMED)) {
 		/* Don't have the port claimed */
@@ -172,8 +208,11 @@
 	}
 
 	kbuffer = kmalloc (min (count, PP_BUFFER_SIZE), GFP_KERNEL);
-	if (!kbuffer)
+	if (!kbuffer) {
 		return -ENOMEM;
+	}
+	pport = pp->pdev->port;
+	mode = pport->ieee1284.mode & ~(IEEE1284_DEVICEID | IEEE1284_ADDR);
 
 	while (bytes_written < count) {
 		ssize_t n = min(count - bytes_written, PP_BUFFER_SIZE);
@@ -183,24 +222,38 @@
 			break;
 		}
 
-		wrote = parport_write (pp->pdev->port, kbuffer, n);
+		if ((pp->flags & PP_FASTWRITE) && (mode == IEEE1284_MODE_EPP)) {
+			/* do a fast EPP write */
+			if (pport->ieee1284.mode & IEEE1284_ADDR) {
+				wrote = pport->ops->epp_write_addr (pport,
+					kbuffer, n, PARPORT_EPP_FAST);
+			} else {
+				wrote = pport->ops->epp_write_data (pport,
+					kbuffer, n, PARPORT_EPP_FAST);
+			}
+		} else {
+			wrote = parport_write (pp->pdev->port, kbuffer, n);
+		}
 
 		if (wrote <= 0) {
-			if (!bytes_written)
+			if (!bytes_written) {
 				bytes_written = wrote;
+			}
 			break;
 		}
 
 		bytes_written += wrote;
 
 		if (signal_pending (current)) {
-			if (!bytes_written)
+			if (!bytes_written) {
 				bytes_written = -EINTR;
+			}
 			break;
 		}
 
-		if (current->need_resched)
+		if (current->need_resched) {
 			schedule ();
+		}
 	}
 
 	kfree (kbuffer);
@@ -276,7 +329,9 @@
 	struct parport * port;
 
 	/* First handle the cases that don't take arguments. */
-	if (cmd == PPCLAIM) {
+	switch (cmd) {
+	case PPCLAIM:
+	    {
 		struct ieee1284_info *info;
 
 		if (pp->flags & PP_CLAIMED) {
@@ -288,8 +343,9 @@
 		/* Deferred device registration. */
 		if (!pp->pdev) {
 			int err = register_device (minor, pp);
-			if (err)
+			if (err) {
 				return err;
+			}
 		}
 
 		parport_claim_or_block (pp->pdev);
@@ -307,9 +363,8 @@
 		info->phase = pp->state.phase;
 
 		return 0;
-	}
-
-	if (cmd == PPEXCL) {
+	    }
+	case PPEXCL:
 		if (pp->pdev) {
 			printk (KERN_DEBUG CHRDEV "%x: too late for PPEXCL; "
 				"already registered\n", minor);
@@ -324,9 +379,8 @@
 		 * when we finally do the registration. */
 		pp->flags |= PP_EXCL;
 		return 0;
-	}
-
-	if (cmd == PPSETMODE) {
+	case PPSETMODE:
+	    {
 		int mode;
 		if (copy_from_user (&mode, (int *) arg, sizeof (mode)))
 			return -EFAULT;
@@ -340,20 +394,82 @@
 		}
 
 		return 0;
-	}
+	    }
+	case PPGETMODE:
+	    {
+		int mode;
 
-	if (cmd == PPSETPHASE) {
+		if (pp->flags & PP_CLAIMED) {
+			mode = pp->pdev->port->ieee1284.mode;
+		} else {
+			mode = pp->state.mode;
+		}
+		if (copy_to_user ((int *)arg, &mode, sizeof (mode))) {
+			return -EFAULT;
+		}
+		return 0;
+	    }
+	case PPSETPHASE:
+	    {
 		int phase;
-		if (copy_from_user (&phase, (int *) arg, sizeof (phase)))
+		if (copy_from_user (&phase, (int *) arg, sizeof (phase))) {
 			return -EFAULT;
+		}
 		/* FIXME: validate phase */
 		pp->state.phase = phase;
 
-		if (pp->flags & PP_CLAIMED)
+		if (pp->flags & PP_CLAIMED) {
 			pp->pdev->port->ieee1284.phase = phase;
+		}
 
 		return 0;
-	}
+	    }
+	case PPGETPHASE:
+	    {
+		int phase;
+
+		if (pp->flags & PP_CLAIMED) {
+			phase = pp->pdev->port->ieee1284.phase;
+		} else {
+			phase = pp->state.phase;
+		}
+		if (copy_to_user ((int *)arg, &phase, sizeof (phase))) {
+			return -EFAULT;
+		}
+		return 0;
+	    }
+	case PPGETMODES:
+	    {
+		unsigned int modes;
+
+		modes = pp->pdev->port->modes;
+		if (copy_to_user ((unsigned int *)arg, &modes, sizeof (port->modes))) {
+			return -EFAULT;
+		}
+		return 0;
+	    }
+	case PPSETFLAGS:
+	    {
+		int uflags;
+
+		if (copy_from_user (&uflags, (int *)arg, sizeof (uflags))) {
+			return -EFAULT;
+		}
+		pp->flags &= ~PP_FLAGMASK;
+		pp->flags |= (uflags & PP_FLAGMASK);
+		return 0;
+	    }
+	case PPGETFLAGS:
+	    {
+		int uflags;
+
+		uflags = pp->flags & PP_FLAGMASK;
+		if (copy_to_user ((int *)arg, &uflags, sizeof (uflags))) {
+			return -EFAULT;
+		}
+		return 0;
+	    }
+	}	/* end switch() */
 
 	/* Everything else requires the port to be claimed, so check
 	 * that now. */
@@ -537,13 +653,28 @@
 {
 	unsigned int minor = MINOR (inode->i_rdev);
 	struct pp_struct *pp = file->private_data;
+	int compat_negot;
 
 	lock_kernel();
-	if (pp->pdev && pp->pdev->port->ieee1284.mode != IEEE1284_MODE_COMPAT) {
-		if (!(pp->flags & PP_CLAIMED)) {
-			parport_claim_or_block (pp->pdev);
-			pp->flags |= PP_CLAIMED;
-		}
+	compat_negot = 0;
+	if (!(pp->flags & PP_CLAIMED) && pp->pdev &&
+	    (pp->state.mode != IEEE1284_MODE_COMPAT)) {
+	    	struct ieee1284_info *info;
+
+		/* parport released, but not in compatability mode */
+		parport_claim_or_block (pp->pdev);
+		pp->flags |= PP_CLAIMED;
+		info = &pp->pdev->port->ieee1284;
+		pp->saved_state.mode = info->mode;
+		pp->saved_state.phase = info->phase;
+		info->mode = pp->state.mode;
+		info->phase = pp->state.phase;
+		compat_negot = 1;
+	} else if ((pp->flags & PP_CLAIMED) && pp->pdev &&
+	    (pp->pdev->port->ieee1284.mode != IEEE1284_MODE_COMPAT)) {
+		compat_negot = 2;
+	}
+	if (compat_negot) {
 		parport_negotiate (pp->pdev->port, IEEE1284_MODE_COMPAT);
 		printk (KERN_DEBUG CHRDEV
 			"%x: negotiated back to compatibility mode because "
@@ -551,9 +682,18 @@
 	}
 
 	if (pp->flags & PP_CLAIMED) {
+		struct ieee1284_info *info;
+
+		info = &pp->pdev->port->ieee1284;
+		pp->state.mode = info->mode;
+		pp->state.phase = info->phase;
+		info->mode = pp->saved_state.mode;
+		info->phase = pp->saved_state.phase;
 		parport_release (pp->pdev);
-		printk (KERN_DEBUG CHRDEV "%x: released pardevice because "
-			"user-space forgot\n", minor);
+		if (compat_negot != 1) {
+			printk (KERN_DEBUG CHRDEV "%x: released pardevice "
+				"because user-space forgot\n", minor);
+		}
 	}
 
 	if (pp->pdev) {
diff -u --recursive --new-file v2.4.4/linux/drivers/char/random.c linux/drivers/char/random.c
--- v2.4.4/linux/drivers/char/random.c	Fri Feb 16 16:02:36 2001
+++ linux/drivers/char/random.c	Tue May  1 16:05:00 2001
@@ -610,7 +610,7 @@
 static void batch_entropy_process(void *private_);
 
 /* note: the size must be a power of 2 */
-static int batch_entropy_init(int size, struct entropy_store *r)
+static int __init batch_entropy_init(int size, struct entropy_store *r)
 {
 	batch_entropy_pool = kmalloc(2*size*sizeof(__u32), GFP_KERNEL);
 	if (!batch_entropy_pool)
diff -u --recursive --new-file v2.4.4/linux/drivers/char/raw.c linux/drivers/char/raw.c
--- v2.4.4/linux/drivers/char/raw.c	Fri Apr 27 14:23:25 2001
+++ linux/drivers/char/raw.c	Sun May 20 11:34:05 2001
@@ -131,7 +131,7 @@
 	 */
 	
 	sector_size = 512;
-	if (get_super(rdev) != NULL) {
+	if (is_mounted(rdev)) {
 		if (blksize_size[MAJOR(rdev)])
 			sector_size = blksize_size[MAJOR(rdev)][MINOR(rdev)];
 	} else {
diff -u --recursive --new-file v2.4.4/linux/drivers/char/riscom8.c linux/drivers/char/riscom8.c
--- v2.4.4/linux/drivers/char/riscom8.c	Thu Jan  4 12:50:12 2001
+++ linux/drivers/char/riscom8.c	Wed May 16 10:31:27 2001
@@ -1217,33 +1217,58 @@
 	if (!tty || !port->xmit_buf || !tmp_buf)
 		return 0;
 
-	if (from_user)
+	save_flags(flags);
+	if (from_user) {
 		down(&tmp_buf_sem);
+		while (1) {
+			cli();		
+			c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
+					   SERIAL_XMIT_SIZE - port->xmit_head));
+			if (c <= 0)
+				break;
 
-	save_flags(flags);
-	while (1) {
-		cli();		
-		c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
-				   SERIAL_XMIT_SIZE - port->xmit_head));
-		if (c <= 0)
-			break;
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!total)
+					total = -EFAULT;
+				break;
+			}
 
-		if (from_user) {
-			copy_from_user(tmp_buf, buf, c);
+			cli();
 			c = MIN(c, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
 				       SERIAL_XMIT_SIZE - port->xmit_head));
 			memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c);
-		} else
+			port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+			port->xmit_cnt += c;
+			restore_flags(flags);
+
+			buf += c;
+			count -= c;
+			total += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		while (1) {
+			cli();		
+			c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
+					   SERIAL_XMIT_SIZE - port->xmit_head));
+			if (c <= 0) {
+				restore_flags(flags);
+				break;
+			}
+
 			memcpy(port->xmit_buf + port->xmit_head, buf, c);
-		port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
-		port->xmit_cnt += c;
-		restore_flags(flags);
-		buf += c;
-		count -= c;
-		total += c;
+			port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+			port->xmit_cnt += c;
+			restore_flags(flags);
+
+			buf += c;
+			count -= c;
+			total += c;
+		}
 	}
-	if (from_user)
-		up(&tmp_buf_sem);
+
+	cli();
 	if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
 	    !(port->IER & IER_TXRDY)) {
 		port->IER |= IER_TXRDY;
@@ -1251,6 +1276,7 @@
 		rc_out(bp, CD180_IER, port->IER);
 	}
 	restore_flags(flags);
+
 	return total;
 }
 
diff -u --recursive --new-file v2.4.4/linux/drivers/char/sbc60xxwdt.c linux/drivers/char/sbc60xxwdt.c
--- v2.4.4/linux/drivers/char/sbc60xxwdt.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/char/sbc60xxwdt.c	Tue May 22 10:23:16 2001
@@ -16,6 +16,7 @@
  *
  *           12/4 - 2000      [Initial revision]
  *           25/4 - 2000      Added /dev/watchdog support
+ *           09/5 - 2001      [smj@oro.net] fixed fop_write to "return 1" on success
  *
  *
  *  Theory of operation:
@@ -178,6 +179,7 @@
 
 		/* Well, anyhow someone wrote to us, we should return that favour */
 		next_heartbeat = jiffies + WDT_HEARTBEAT;
+		return 1;
 	}
 	return 0;
 }
@@ -241,7 +243,7 @@
 	switch(cmd)
 	{
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
 			return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
 		case WDIOC_KEEPALIVE:
diff -u --recursive --new-file v2.4.4/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v2.4.4/linux/drivers/char/serial.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/char/serial.c	Sun May 20 12:11:38 2001
@@ -565,9 +565,12 @@
 
 	icount = &info->state->icount;
 	do {
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+			tty->flip.tqueue.routine((void *) tty);
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+				return;		// if TTY_DONT_FLIP is set
+		}
 		ch = serial_inp(info, UART_RX);
-		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-			goto ignore_char;
 		*tty->flip.char_buf_ptr = ch;
 		icount->rx++;
 		
@@ -657,7 +660,9 @@
 			tty->flip.flag_buf_ptr++;
 			tty->flip.char_buf_ptr++;
 		}
+#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 	ignore_char:
+#endif
 		*status = serial_inp(info, UART_LSR);
 	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
 #if (LINUX_VERSION_CODE > 131394) /* 2.1.66 */
diff -u --recursive --new-file v2.4.4/linux/drivers/char/serial167.c linux/drivers/char/serial167.c
--- v2.4.4/linux/drivers/char/serial167.c	Mon Nov 27 17:11:26 2000
+++ linux/drivers/char/serial167.c	Wed May 16 10:31:27 2001
@@ -1247,36 +1247,54 @@
         return 0;
     }
 
-    while (1) {
-        save_flags(flags); cli();		
-	c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-			   SERIAL_XMIT_SIZE - info->xmit_head));
-	if (c <= 0){
-	    restore_flags(flags);
-	    break;
-	}
-
-	if (from_user) {
+    if (from_user) {
 	    down(&tmp_buf_sem);
-	    if (copy_from_user(tmp_buf, buf, c)) {
-	    	up(&tmp_buf_sem);
-	        restore_flags(flags);
-		return 0;
+	    while (1) {
+		    c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				       SERIAL_XMIT_SIZE - info->xmit_head));
+		    if (c <= 0)
+			    break;
+
+		    c -= copy_from_user(tmp_buf, buf, c);
+		    if (!c) {
+			    if (!total)
+				    total = -EFAULT;
+			    break;
+		    }
+
+		    cli();
+		    c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				   SERIAL_XMIT_SIZE - info->xmit_head));
+		    memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
+		    info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+		    info->xmit_cnt += c;
+		    restore_flags(flags);
+
+		    buf += c;
+		    count -= c;
+		    total += c;
 	    }
-	    c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
-		       SERIAL_XMIT_SIZE - info->xmit_head));
-	    memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
 	    up(&tmp_buf_sem);
-	} else
-	    memcpy(info->xmit_buf + info->xmit_head, buf, c);
-	info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
-	info->xmit_cnt += c;
-	restore_flags(flags);
-	buf += c;
-	count -= c;
-	total += c;
-    }
+    } else {
+	    while (1) {
+		    cli();
+		    c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
+				       SERIAL_XMIT_SIZE - info->xmit_head));
+		    if (c <= 0) {
+			    restore_flags(flags);
+			    break;
+		    }
+
+		    memcpy(info->xmit_buf + info->xmit_head, buf, c);
+		    info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+		    info->xmit_cnt += c;
+		    restore_flags(flags);
 
+		    buf += c;
+		    count -= c;
+		    total += c;
+	    }
+    }
 
     if (info->xmit_cnt
     && !tty->stopped
diff -u --recursive --new-file v2.4.4/linux/drivers/char/softdog.c linux/drivers/char/softdog.c
--- v2.4.4/linux/drivers/char/softdog.c	Tue Feb 13 14:13:43 2001
+++ linux/drivers/char/softdog.c	Sat May 19 17:43:05 2001
@@ -132,7 +132,7 @@
 	};
 	switch (cmd) {
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
 			if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
 				return -EFAULT;
diff -u --recursive --new-file v2.4.4/linux/drivers/char/specialix.c linux/drivers/char/specialix.c
--- v2.4.4/linux/drivers/char/specialix.c	Wed Dec  6 12:06:18 2000
+++ linux/drivers/char/specialix.c	Wed May 16 10:31:27 2001
@@ -1611,33 +1611,56 @@
 	if (!tty || !port->xmit_buf || !tmp_buf)
 		return 0;
 
-	if (from_user)
+	save_flags(flags);
+	if (from_user) {
 		down(&tmp_buf_sem);
+		while (1) {
+			c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
+					   SERIAL_XMIT_SIZE - port->xmit_head));
+			if (c <= 0)
+				break;
 
-	save_flags(flags);
-	while (1) {
-		cli();		
-		c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
-		                   SERIAL_XMIT_SIZE - port->xmit_head));
-		if (c <= 0)
-			break;
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!total)
+					total = -EFAULT;
+				break;
+			}
 
-		if (from_user) {
-			copy_from_user(tmp_buf, buf, c);
+			cli();
 			c = MIN(c, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
-			               SERIAL_XMIT_SIZE - port->xmit_head));
+				       SERIAL_XMIT_SIZE - port->xmit_head));
 			memcpy(port->xmit_buf + port->xmit_head, tmp_buf, c);
-		} else
+			port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+			port->xmit_cnt += c;
+			restore_flags(flags);
+
+			buf += c;
+			count -= c;
+			total += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		while (1) {
+			cli();
+			c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1,
+					   SERIAL_XMIT_SIZE - port->xmit_head));
+			if (c <= 0) {
+				restore_flags(flags);
+				break;
+			}
 			memcpy(port->xmit_buf + port->xmit_head, buf, c);
-		port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
-		port->xmit_cnt += c;
-		restore_flags(flags);
-		buf += c;
-		count -= c;
-		total += c;
+			port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
+			port->xmit_cnt += c;
+			restore_flags(flags);
+
+			buf += c;
+			count -= c;
+			total += c;
+		}
 	}
-	if (from_user)
-		up(&tmp_buf_sem);
+
+	cli();
 	if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped &&
 	    !(port->IER & IER_TXRDY)) {
 		port->IER |= IER_TXRDY;
diff -u --recursive --new-file v2.4.4/linux/drivers/char/synclink.c linux/drivers/char/synclink.c
--- v2.4.4/linux/drivers/char/synclink.c	Wed Apr 18 14:40:06 2001
+++ linux/drivers/char/synclink.c	Tue May  1 16:05:00 2001
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/char/synclink.c
  *
- * $Id: synclink.c,v 3.2 2000/11/06 22:34:38 paul Exp $
+ * $Id: synclink.c,v 3.8 2001/03/30 17:30:38 ez Exp $
  *
  * Device driver for Microgate SyncLink ISA and PCI
  * high speed multiprotocol serial adapters.
@@ -107,8 +107,12 @@
 #endif
 
 #ifdef CONFIG_SYNCLINK_SYNCPPP
+#if LINUX_VERSION_CODE < VERSION(2,4,3) 
+#include "../net/wan/syncppp.h"
+#else
 #include <net/syncppp.h>
 #endif
+#endif
 
 #include <asm/segment.h>
 #define GET_USER(error,value,addr) error = get_user(value,addr)
@@ -176,6 +180,14 @@
 	int	cts_down;
 };
 
+/* transmit holding buffer definitions*/
+#define MAX_TX_HOLDING_BUFFERS 5
+struct tx_holding_buffer {
+	int	buffer_size;
+	unsigned char *	buffer;
+};
+
+
 /*
  * Device instance data structure
  */
@@ -241,11 +253,21 @@
 	DMABUFFERENTRY *rx_buffer_list;	/* list of receive buffer entries */
 	unsigned int current_rx_buffer;
 
+	int num_tx_dma_buffers;		/* number of tx dma frames required */
+ 	int tx_dma_buffers_used;
 	unsigned int tx_buffer_count;	/* count of total allocated Tx buffers */
 	DMABUFFERENTRY *tx_buffer_list;	/* list of transmit buffer entries */
+	int start_tx_dma_buffer;	/* tx dma buffer to start tx dma operation */
+	int current_tx_buffer;          /* next tx dma buffer to be loaded */
 	
 	unsigned char *intermediate_rxbuffer;
 
+	int num_tx_holding_buffers;	/* number of tx holding buffer allocated */
+	int get_tx_holding_index;  	/* next tx holding buffer for adapter to load */
+	int put_tx_holding_index;  	/* next tx holding buffer to store user request */
+	int tx_holding_count;		/* number of tx holding buffers waiting */
+	struct tx_holding_buffer tx_holding_buffers[MAX_TX_HOLDING_BUFFERS];
+
 	int rx_enabled;
 	int rx_overflow;
 
@@ -685,6 +707,8 @@
 #define usc_TCmd(a,b) usc_OutReg((a), TCSR, (u16)((a)->tcsr_value + (b)))
 #define usc_RCmd(a,b) usc_OutReg((a), RCSR, (b))
 
+#define usc_SetTransmitSyncChars(a,s0,s1) usc_OutReg((a), TSR, (u16)(((u16)s0<<8)|(u16)s1))
+
 void usc_process_rxoverrun_sync( struct mgsl_struct *info );
 void usc_start_receiver( struct mgsl_struct *info );
 void usc_stop_receiver( struct mgsl_struct *info );
@@ -775,7 +799,10 @@
  */
 void mgsl_free_rx_frame_buffers( struct mgsl_struct *info, unsigned int StartIndex, unsigned int EndIndex );
 int  mgsl_get_rx_frame( struct mgsl_struct *info );
+int  mgsl_get_raw_rx_frame( struct mgsl_struct *info );
 void mgsl_reset_rx_dma_buffers( struct mgsl_struct *info );
+void mgsl_reset_tx_dma_buffers( struct mgsl_struct *info );
+int num_free_tx_dma_buffers(struct mgsl_struct *info);
 void mgsl_load_tx_dma_buffer( struct mgsl_struct *info, const char *Buffer, unsigned int BufferSize);
 void mgsl_load_pci_memory(char* TargetPtr, const char* SourcePtr, unsigned short count);
 
@@ -790,6 +817,10 @@
 void mgsl_free_buffer_list_memory(struct mgsl_struct *info);
 int mgsl_alloc_intermediate_rxbuffer_memory(struct mgsl_struct *info);
 void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info);
+int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info);
+void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info);
+int load_next_tx_holding_buffer(struct mgsl_struct *info);
+int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, unsigned int BufferSize);
 
 /*
  * Bottom half interrupt handlers
@@ -810,6 +841,7 @@
 void mgsl_isr_io_pin( struct mgsl_struct *info );
 void mgsl_isr_misc( struct mgsl_struct *info );
 void mgsl_isr_receive_dma( struct mgsl_struct *info );
+void mgsl_isr_transmit_dma( struct mgsl_struct *info );
 
 typedef void (*isr_dispatch_func)(struct mgsl_struct *);
 
@@ -874,6 +906,8 @@
 static int debug_level = 0;
 static int maxframe[MAX_TOTAL_DEVICES] = {0,};
 static int dosyncppp[MAX_TOTAL_DEVICES] = {0,};
+static int txdmabufs[MAX_TOTAL_DEVICES] = {0,};
+static int txholdbufs[MAX_TOTAL_DEVICES] = {0,};
 	
 MODULE_PARM(break_on_load,"i");
 MODULE_PARM(ttymajor,"i");
@@ -884,9 +918,11 @@
 MODULE_PARM(debug_level,"i");
 MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
 MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
+MODULE_PARM(txdmabufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
+MODULE_PARM(txholdbufs,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
 
 static char *driver_name = "SyncLink serial driver";
-static char *driver_version = "3.2";
+static char *driver_version = "3.8";
 
 static int __init synclink_init_one (struct pci_dev *dev,
 				     const struct pci_device_id *ent);
@@ -1096,11 +1132,14 @@
 
 void mgsl_bh_receive(struct mgsl_struct *info)
 {
+	int (*get_rx_frame)(struct mgsl_struct *info) =
+		(info->params.mode == MGSL_MODE_HDLC ? mgsl_get_rx_frame : mgsl_get_raw_rx_frame);
+
 	if ( debug_level >= DEBUG_LEVEL_BH )
 		printk( "%s(%d):mgsl_bh_receive(%s)\n",
 			__FILE__,__LINE__,info->device_name);
 	
-	while( mgsl_get_rx_frame(info) );
+	while( (get_rx_frame)(info) );
 }
 
 void mgsl_bh_transmit(struct mgsl_struct *info)
@@ -1318,11 +1357,6 @@
 #endif
 			} else
 				info->input_signal_events.dcd_down++;
-#ifdef CONFIG_HARD_PPS
-			if ((info->flags & ASYNC_HARDPPS_CD) &&
-			    (status & MISCSTATUS_DCD_LATCHED))
-				hardpps();
-#endif
 		}
 		if (status & MISCSTATUS_CTS_LATCHED)
 		{
@@ -1609,6 +1643,58 @@
 
 }	/* end of mgsl_isr_receive_dma() */
 
+/* mgsl_isr_transmit_dma()
+ *
+ *	This function services a transmit DMA channel interrupt.
+ *
+ *	For this driver there is one source of transmit DMA interrupts
+ *	as identified in the Transmit DMA Mode Register (TDMR):
+ *
+ *     	BIT2  EOB       End of Buffer. This interrupt occurs when a
+ *     			transmit DMA buffer has been emptied.
+ *
+ *     	The driver maintains enough transmit DMA buffers to hold at least
+ *     	one max frame size transmit frame. When operating in a buffered
+ *     	transmit mode, there may be enough transmit DMA buffers to hold at
+ *     	least two or more max frame size frames. On an EOB condition,
+ *     	determine if there are any queued transmit buffers and copy into
+ *     	transmit DMA buffers if we have room.
+ *
+ * Arguments:		info		pointer to device instance data
+ * Return Value:	None
+ */
+void mgsl_isr_transmit_dma( struct mgsl_struct *info )
+{
+	u16 status;
+
+	/* clear interrupt pending and IUS bit for Tx DMA IRQ */
+	usc_OutDmaReg(info, CDIR, BIT8+BIT0 );
+
+	/* Read the transmit DMA status to identify interrupt type. */
+	/* This also clears the status bits. */
+
+	status = usc_InDmaReg( info, TDMR );
+
+	if ( debug_level >= DEBUG_LEVEL_ISR )
+		printk("%s(%d):mgsl_isr_transmit_dma(%s) status=%04X\n",
+			__FILE__,__LINE__,info->device_name,status);
+
+	if ( status & BIT2 ) {
+		--info->tx_dma_buffers_used;
+
+		/* if there are transmit frames queued,
+		 *  try to load the next one
+		 */
+		if ( load_next_tx_holding_buffer(info) ) {
+			/* if call returns non-zero value, we have
+			 * at least one free tx holding buffer
+			 */
+			info->pending_bh |= BH_TRANSMIT;
+		}
+	}
+
+}	/* end of mgsl_isr_transmit_dma() */
+
 /* mgsl_interrupt()
  * 
  * 	Interrupt service routine entry point.
@@ -1652,6 +1738,8 @@
 		/* Dispatch interrupt vector */
 		if ( UscVector )
 			(*UscIsrTable[UscVector])(info);
+		else if ( (DmaVector&(BIT10|BIT9)) == BIT10)
+			mgsl_isr_transmit_dma(info);
 		else
 			mgsl_isr_receive_dma(info);
 
@@ -1818,7 +1906,9 @@
 	usc_stop_transmitter(info);
 	info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
 	
-	if (info->params.mode == MGSL_MODE_HDLC || info->netcount)
+	if (info->params.mode == MGSL_MODE_HDLC ||
+	    info->params.mode == MGSL_MODE_RAW ||
+	    info->netcount)
 		usc_set_sync_mode(info);
 	else
 		usc_set_async_mode(info);
@@ -1970,8 +2060,7 @@
 
 	spin_lock_irqsave(&info->irq_spinlock,flags);
 	
-	if ( (info->params.mode != MGSL_MODE_HDLC) || 
-	     !info->tx_active ) {
+	if ( (info->params.mode == MGSL_MODE_ASYNC ) || !info->tx_active ) {
 	
 		if (info->xmit_cnt < SERIAL_XMIT_SIZE - 1) {
 			info->xmit_buf[info->xmit_head++] = ch;
@@ -2015,8 +2104,8 @@
 	spin_lock_irqsave(&info->irq_spinlock,flags);
 	
 	if (!info->tx_active) {
-		if ( (info->params.mode == MGSL_MODE_HDLC) &&
-			info->xmit_cnt ) {
+		if ( (info->params.mode == MGSL_MODE_HDLC ||
+			info->params.mode == MGSL_MODE_RAW) && info->xmit_cnt ) {
 			/* operating in synchronous (frame oriented) mode */
 			/* copy data from circular xmit_buf to */
 			/* transmit DMA buffer. */
@@ -2060,11 +2149,51 @@
 	if (!tty || !info->xmit_buf || !tmp_buf)
 		goto cleanup;
 
-	if ( info->params.mode == MGSL_MODE_HDLC ) {
+	if ( info->params.mode == MGSL_MODE_HDLC ||
+			info->params.mode == MGSL_MODE_RAW ) {
+		/* operating in synchronous (frame oriented) mode */
 		/* operating in synchronous (frame oriented) mode */
-
 		if (info->tx_active) {
-			ret = 0; goto cleanup; 
+
+			if ( info->params.mode == MGSL_MODE_HDLC ) {
+				ret = 0;
+				goto cleanup;
+			}
+			/* transmitter is actively sending data -
+			 * if we have multiple transmit dma and
+			 * holding buffers, attempt to queue this
+			 * frame for transmission at a later time.
+			 */
+			if (info->tx_holding_count >= info->num_tx_holding_buffers ) {
+				/* no tx holding buffers available */
+				ret = 0;
+				goto cleanup;
+			}
+
+			/* queue transmit frame request */
+			ret = count;
+			if (from_user) {
+				down(&tmp_buf_sem);
+				COPY_FROM_USER(err,tmp_buf, buf, count);
+				if (err) {
+					if ( debug_level >= DEBUG_LEVEL_INFO )
+						printk( "%s(%d):mgsl_write(%s) sync user buf copy failed\n",
+							__FILE__,__LINE__,info->device_name);
+					ret = -EFAULT;
+				} else
+					save_tx_buffer_request(info,tmp_buf,count);
+				up(&tmp_buf_sem);
+			}
+			else
+				save_tx_buffer_request(info,buf,count);
+
+			/* if we have sufficient tx dma buffers,
+			 * load the next buffered tx request
+			 */
+			spin_lock_irqsave(&info->irq_spinlock,flags);
+			load_next_tx_holding_buffer(info);
+			spin_unlock_irqrestore(&info->irq_spinlock,flags);
+			goto cleanup;
 		}
 	
 		/* if operating in HDLC LoopMode and the adapter  */
@@ -2200,7 +2329,8 @@
 		printk("%s(%d):mgsl_write_room(%s)=%d\n",
 			 __FILE__,__LINE__, info->device_name,ret );
 			 
-	if ( info->params.mode == MGSL_MODE_HDLC ) {
+	if ( info->params.mode == MGSL_MODE_HDLC ||
+		info->params.mode == MGSL_MODE_RAW ) {
 		/* operating in synchronous (frame oriented) mode */
 		if ( info->tx_active )
 			return 0;
@@ -2234,10 +2364,11 @@
 		printk("%s(%d):mgsl_chars_in_buffer(%s)=%d\n",
 			 __FILE__,__LINE__, info->device_name,info->xmit_cnt );
 			 
-	if ( info->params.mode == MGSL_MODE_HDLC ) {
+	if ( info->params.mode == MGSL_MODE_HDLC ||
+		info->params.mode == MGSL_MODE_RAW ) {
 		/* operating in synchronous (frame oriented) mode */
 		if ( info->tx_active )
-			return info->tx_buffer_list[0].rcc;
+			return info->max_frame_size;
 		else
 			return 0;
 	}
@@ -2627,11 +2758,11 @@
  	unsigned long flags;
 	int s;
 	int rc=0;
-	u16 regval;
 	struct mgsl_icount cprev, cnow;
-	int events = 0;
+	int events;
 	int mask;
-	struct	_input_signal_events signal_events_prev, signal_events_now;
+	struct	_input_signal_events oldsigs, newsigs;
+	DECLARE_WAITQUEUE(wait, current);
 
 	COPY_FROM_USER(rc,&mask, mask_ptr, sizeof(int));
 	if (rc) {
@@ -2644,114 +2775,99 @@
 
 	spin_lock_irqsave(&info->irq_spinlock,flags);
 
+	/* return immediately if state matches requested events */
 	usc_get_serial_signals(info);
 	s = info->serial_signals;
+	events = mask &
+		( ((s & SerialSignal_DSR) ? MgslEvent_DsrActive:MgslEvent_DsrInactive) +
+ 		  ((s & SerialSignal_DCD) ? MgslEvent_DcdActive:MgslEvent_DcdInactive) +
+		  ((s & SerialSignal_CTS) ? MgslEvent_CtsActive:MgslEvent_CtsInactive) +
+		  ((s & SerialSignal_RI)  ? MgslEvent_RiActive :MgslEvent_RiInactive) );
+	if (events) {
+		spin_unlock_irqrestore(&info->irq_spinlock,flags);
+		goto exit;
+	}
 
-	/* note the counters on entry */
+	/* save current irq counts */
 	cprev = info->icount;
-	signal_events_prev = info->input_signal_events;
+	oldsigs = info->input_signal_events;
 	
-	if (mask & MgslEvent_ExitHuntMode) {
-		/* enable exit hunt mode IRQ */
-		regval = usc_InReg(info,RICR);
-		if (!(regval & RXSTATUS_EXITED_HUNT))
-			usc_OutReg(info, RICR, regval | RXSTATUS_EXITED_HUNT);
+	/* enable hunt and idle irqs if needed */
+	if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) {
+		u16 oldreg = usc_InReg(info,RICR);
+		u16 newreg = oldreg +
+			 (mask & MgslEvent_ExitHuntMode ? RXSTATUS_EXITED_HUNT:0) +
+			 (mask & MgslEvent_IdleReceived ? RXSTATUS_IDLE_RECEIVED:0);
+		if (oldreg != newreg)
+			usc_OutReg(info, RICR, newreg);
 	}
 	
-	if (mask & MgslEvent_IdleReceived) {
-		/* enable idle mode received IRQ */
-		regval = usc_InReg(info,RICR);
-		if (!(regval & RXSTATUS_IDLE_RECEIVED))
-			usc_OutReg(info, RICR, regval | RXSTATUS_IDLE_RECEIVED);
-	}
+	set_current_state(TASK_INTERRUPTIBLE);
+	add_wait_queue(&info->event_wait_q, &wait);
 	
 	spin_unlock_irqrestore(&info->irq_spinlock,flags);
 	
-	/* Determine if any user requested events for input signals is currently TRUE */
-	
-	events |= (mask & ((s & SerialSignal_DSR) ?
-			MgslEvent_DsrActive:MgslEvent_DsrInactive));
-
-	events |= (mask & ((s & SerialSignal_DCD) ?
-			MgslEvent_DcdActive:MgslEvent_DcdInactive));
-		
-	events |= (mask & ((s & SerialSignal_CTS) ?
-			MgslEvent_CtsActive:MgslEvent_CtsInactive));
-		
-	events |= (mask & ((s & SerialSignal_RI) ?
-			MgslEvent_RiActive:MgslEvent_RiInactive));
-	
 
-	while(!events) {
-		/* sleep until event occurs */
-		interruptible_sleep_on(&info->event_wait_q);
-		
-		/* see if a signal woke us */
+	for(;;) {
+		schedule();
 		if (signal_pending(current)) {
 			rc = -ERESTARTSYS;
 			break;
 		}
 			
+		/* get current irq counts */
 		spin_lock_irqsave(&info->irq_spinlock,flags);
-
-		/* get icount and serial signal states */
 		cnow = info->icount;
-		signal_events_now = info->input_signal_events;
+		newsigs = info->input_signal_events;
+		set_current_state(TASK_INTERRUPTIBLE);
 		spin_unlock_irqrestore(&info->irq_spinlock,flags);
 
-		if (signal_events_now.dsr_up != signal_events_prev.dsr_up && 
-				mask & MgslEvent_DsrActive )
-			events |= MgslEvent_DsrActive;
-		
-		if (signal_events_now.dsr_down != signal_events_prev.dsr_down && 
-				mask & MgslEvent_DsrInactive )
-			events |= MgslEvent_DsrInactive;
-
-		if (signal_events_now.dcd_up != signal_events_prev.dcd_up &&
-				mask & MgslEvent_DcdActive )
-			events |= MgslEvent_DcdActive;
-		
-		if (signal_events_now.dcd_down != signal_events_prev.dcd_down &&
-				mask & MgslEvent_DcdInactive )
-			events |= MgslEvent_DcdInactive;
-		
-		if (signal_events_now.cts_up != signal_events_prev.cts_up &&
-				mask & MgslEvent_CtsActive )
-			events |= MgslEvent_CtsActive;
-		
-		if (signal_events_now.cts_down != signal_events_prev.cts_down &&
-				mask & MgslEvent_CtsInactive )
-			events |= MgslEvent_CtsInactive;
-		
-		if (signal_events_now.ri_up != signal_events_prev.ri_up &&
-				mask & MgslEvent_RiActive )
-			events |= MgslEvent_RiActive;
-		
-		if (signal_events_now.ri_down != signal_events_prev.ri_down &&
-				mask & MgslEvent_RiInactive )
-			events |= MgslEvent_RiInactive;
-		
-		if (cnow.exithunt != cprev.exithunt)
-			events |= (mask & MgslEvent_ExitHuntMode);
+		/* if no change, wait aborted for some reason */
+		if (newsigs.dsr_up   == oldsigs.dsr_up   &&
+		    newsigs.dsr_down == oldsigs.dsr_down &&
+		    newsigs.dcd_up   == oldsigs.dcd_up   &&
+		    newsigs.dcd_down == oldsigs.dcd_down &&
+		    newsigs.cts_up   == oldsigs.cts_up   &&
+		    newsigs.cts_down == oldsigs.cts_down &&
+		    newsigs.ri_up    == oldsigs.ri_up    &&
+		    newsigs.ri_down  == oldsigs.ri_down  &&
+		    cnow.exithunt    == cprev.exithunt   &&
+		    cnow.rxidle      == cprev.rxidle) {
+			rc = -EIO;
+			break;
+		}
 
-		if (cnow.rxidle != cprev.rxidle)
-			events |= (mask & MgslEvent_IdleReceived);
+		events = mask &
+			( (newsigs.dsr_up   != oldsigs.dsr_up   ? MgslEvent_DsrActive:0)   +
+			(newsigs.dsr_down != oldsigs.dsr_down ? MgslEvent_DsrInactive:0) +
+			(newsigs.dcd_up   != oldsigs.dcd_up   ? MgslEvent_DcdActive:0)   +
+			(newsigs.dcd_down != oldsigs.dcd_down ? MgslEvent_DcdInactive:0) +
+			(newsigs.cts_up   != oldsigs.cts_up   ? MgslEvent_CtsActive:0)   +
+			(newsigs.cts_down != oldsigs.cts_down ? MgslEvent_CtsInactive:0) +
+			(newsigs.ri_up    != oldsigs.ri_up    ? MgslEvent_RiActive:0)    +
+			(newsigs.ri_down  != oldsigs.ri_down  ? MgslEvent_RiInactive:0)  +
+			(cnow.exithunt    != cprev.exithunt   ? MgslEvent_ExitHuntMode:0) +
+			  (cnow.rxidle      != cprev.rxidle     ? MgslEvent_IdleReceived:0) );
+		if (events)
+			break;
 		
 		cprev = cnow;
-		signal_events_prev = signal_events_now;
+		oldsigs = newsigs;
 	}
 	
+	remove_wait_queue(&info->event_wait_q, &wait);
+	set_current_state(TASK_RUNNING);
+
 	if (mask & (MgslEvent_ExitHuntMode + MgslEvent_IdleReceived)) {
 		spin_lock_irqsave(&info->irq_spinlock,flags);
 		if (!waitqueue_active(&info->event_wait_q)) {
 			/* disable enable exit hunt mode/idle rcvd IRQs */
-			regval = usc_InReg(info,RICR);
-			usc_OutReg(info, RICR, regval & 
+			usc_OutReg(info, RICR, usc_InReg(info,RICR) &
 				~(RXSTATUS_EXITED_HUNT + RXSTATUS_IDLE_RECEIVED));
 		}
 		spin_unlock_irqrestore(&info->irq_spinlock,flags);
 	}
-
+exit:
 	if ( rc == 0 )
 		PUT_USER(rc, events, mask_ptr);
 		
@@ -2759,6 +2875,56 @@
 	
 }	/* end of mgsl_wait_event() */
 
+static int modem_input_wait(struct mgsl_struct *info,int arg)
+{
+ 	unsigned long flags;
+	int rc;
+	struct mgsl_icount cprev, cnow;
+	DECLARE_WAITQUEUE(wait, current);
+
+	/* save current irq counts */
+	spin_lock_irqsave(&info->irq_spinlock,flags);
+	cprev = info->icount;
+	add_wait_queue(&info->status_event_wait_q, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	spin_unlock_irqrestore(&info->irq_spinlock,flags);
+
+	for(;;) {
+		schedule();
+		if (signal_pending(current)) {
+			rc = -ERESTARTSYS;
+			break;
+		}
+
+		/* get new irq counts */
+		spin_lock_irqsave(&info->irq_spinlock,flags);
+		cnow = info->icount;
+		set_current_state(TASK_INTERRUPTIBLE);
+		spin_unlock_irqrestore(&info->irq_spinlock,flags);
+
+		/* if no change, wait aborted for some reason */
+		if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+		    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
+			rc = -EIO;
+			break;
+		}
+
+		/* check for change in caller specified modem input */
+		if ((arg & TIOCM_RNG && cnow.rng != cprev.rng) ||
+		    (arg & TIOCM_DSR && cnow.dsr != cprev.dsr) ||
+		    (arg & TIOCM_CD  && cnow.dcd != cprev.dcd) ||
+		    (arg & TIOCM_CTS && cnow.cts != cprev.cts)) {
+			rc = 0;
+			break;
+		}
+
+		cprev = cnow;
+	}
+	remove_wait_queue(&info->status_event_wait_q, &wait);
+	set_current_state(TASK_RUNNING);
+	return rc;
+}
+
 /* get_modem_info()
  * 
  * 	Read the state of the serial control and
@@ -2926,7 +3092,7 @@
 int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg)
 {
 	int error;
-	struct mgsl_icount cprev, cnow;	/* kernel counter temps */
+	struct mgsl_icount cnow;	/* kernel counter temps */
 	struct serial_icounter_struct *p_cuser;	/* user space */
 	unsigned long flags;
 	
@@ -2961,37 +3127,12 @@
 			while(MOD_IN_USE)
 				MOD_DEC_USE_COUNT;
 			return 0;
-		/*
-		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
-		 * - mask passed in arg for lines of interest
- 		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
-		 * Caller should use TIOCGICOUNT to see which one it was
+
+		/* Wait for modem input (DCD,RI,DSR,CTS) change
+		 * as specified by mask in arg (TIOCM_RNG/DSR/CD/CTS)
 		 */
 		case TIOCMIWAIT:
-			spin_lock_irqsave(&info->irq_spinlock,flags);
-			/* note the counters on entry */
-			cprev = info->icount;
-			spin_unlock_irqrestore(&info->irq_spinlock,flags);
-			while (1) {
-				interruptible_sleep_on(&info->status_event_wait_q);
-				/* see if a signal did it */
-				if (signal_pending(current))
-					return -ERESTARTSYS;
-				save_flags(flags); cli();
-				cnow = info->icount; /* atomic copy */
-				restore_flags(flags);
-				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
-				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
-					return -EIO; /* no change => error */
-				if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
-				     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
-				     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
-				     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
-					return 0;
-				}
-				cprev = cnow;
-			}
-			/* NOTREACHED */
+			return modem_input_wait(info,(int)arg);
 
 		/* 
 		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
@@ -3243,7 +3384,8 @@
 	if (timeout)
 		char_time = MIN(char_time, timeout);
 		
-	if ( info->params.mode == MGSL_MODE_HDLC ) {
+	if ( info->params.mode == MGSL_MODE_HDLC ||
+		info->params.mode == MGSL_MODE_RAW ) {
 		while (info->tx_active) {
 			set_current_state(TASK_INTERRUPTIBLE);
 			schedule_timeout(char_time);
@@ -3601,7 +3743,8 @@
 	if (info->serial_signals & SerialSignal_RI)
 		strcat(stat_buf, "|RI");
 
-	if (info->params.mode == MGSL_MODE_HDLC) {
+	if (info->params.mode == MGSL_MODE_HDLC ||
+	    info->params.mode == MGSL_MODE_RAW ) {
 		ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d",
 			      info->icount.txok, info->icount.rxok);
 		if (info->icount.txunder)
@@ -3742,15 +3885,15 @@
 		 *
 		 * This leaves 62 4K pages.
 		 *
-		 * The next N pages are used for a transmit frame. We
-		 * reserve enough 4K page blocks to hold the configured
-		 * MaxFrameSize
+		 * The next N pages are used for transmit frame(s). We
+		 * reserve enough 4K page blocks to hold the required
+		 * number of transmit dma buffers (num_tx_dma_buffers),
+		 * each of MaxFrameSize size.
 		 *
 		 * Of the remaining pages (62-N), determine how many can
 		 * be used to receive full MaxFrameSize inbound frames
 		 */
-		
-		info->tx_buffer_count = BuffersPerFrame;
+		info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame;
 		info->rx_buffer_count = 62 - info->tx_buffer_count;
 	} else {
 		/* Calculate the number of PAGE_SIZE buffers needed for */
@@ -3763,7 +3906,7 @@
 		/* End of List condition if all receive buffers are used when */
 		/* using linked list DMA buffers. */
 
-		info->tx_buffer_count = BuffersPerFrame;
+		info->tx_buffer_count = info->num_tx_dma_buffers * BuffersPerFrame;
 		info->rx_buffer_count = (BuffersPerFrame * MAXRXFRAMES) + 6;
 		
 		/* 
@@ -3783,12 +3926,14 @@
 	if ( mgsl_alloc_buffer_list_memory( info ) < 0 ||
 		  mgsl_alloc_frame_memory(info, info->rx_buffer_list, info->rx_buffer_count) < 0 || 
 		  mgsl_alloc_frame_memory(info, info->tx_buffer_list, info->tx_buffer_count) < 0 || 
-		  mgsl_alloc_intermediate_rxbuffer_memory(info) < 0 ) {
+		  mgsl_alloc_intermediate_rxbuffer_memory(info) < 0  ||
+		  mgsl_alloc_intermediate_txbuffer_memory(info) < 0 ) {
 		printk("%s(%d):Can't allocate DMA buffer memory\n",__FILE__,__LINE__);
 		return -ENOMEM;
 	}
 	
 	mgsl_reset_rx_dma_buffers( info );
+  	mgsl_reset_tx_dma_buffers( info );
 
 	return 0;
 
@@ -4044,6 +4189,149 @@
 
 }	/* end of mgsl_free_intermediate_rxbuffer_memory() */
 
+/*
+ * mgsl_alloc_intermediate_txbuffer_memory()
+ *
+ * 	Allocate intermdiate transmit buffer(s) large enough to hold max_frame_size.
+ * 	This buffer is used to load transmit frames into the adapter's dma transfer
+ * 	buffers when there is sufficient space.
+ *
+ * Arguments:
+ *
+ *	info		pointer to device instance data
+ *
+ * Return Value:	0 if success, otherwise -ENOMEM
+ */
+int mgsl_alloc_intermediate_txbuffer_memory(struct mgsl_struct *info)
+{
+	int i;
+
+	if ( debug_level >= DEBUG_LEVEL_INFO )
+		printk("%s %s(%d)  allocating %d tx holding buffers\n",
+				info->device_name, __FILE__,__LINE__,info->num_tx_holding_buffers);
+
+	memset(info->tx_holding_buffers,0,sizeof(info->tx_holding_buffers));
+
+	for ( i=0; i<info->num_tx_holding_buffers; ++i) {
+		info->tx_holding_buffers[i].buffer =
+			kmalloc(info->max_frame_size, GFP_KERNEL);
+		if ( info->tx_holding_buffers[i].buffer == NULL )
+			return -ENOMEM;
+	}
+
+	return 0;
+
+}	/* end of mgsl_alloc_intermediate_txbuffer_memory() */
+
+/*
+ * mgsl_free_intermediate_txbuffer_memory()
+ *
+ *
+ * Arguments:
+ *
+ *	info		pointer to device instance data
+ *
+ * Return Value:	None
+ */
+void mgsl_free_intermediate_txbuffer_memory(struct mgsl_struct *info)
+{
+	int i;
+
+	for ( i=0; i<info->num_tx_holding_buffers; ++i ) {
+		if ( info->tx_holding_buffers[i].buffer ) {
+				kfree(info->tx_holding_buffers[i].buffer);
+				info->tx_holding_buffers[i].buffer=NULL;
+		}
+	}
+
+	info->get_tx_holding_index = 0;
+	info->put_tx_holding_index = 0;
+	info->tx_holding_count = 0;
+
+}	/* end of mgsl_free_intermediate_txbuffer_memory() */
+
+
+/*
+ * load_next_tx_holding_buffer()
+ *
+ * attempts to load the next buffered tx request into the
+ * tx dma buffers
+ *
+ * Arguments:
+ *
+ *	info		pointer to device instance data
+ *
+ * Return Value:	1 if next buffered tx request loaded
+ * 			into adapter's tx dma buffer,
+ * 			0 otherwise
+ */
+int load_next_tx_holding_buffer(struct mgsl_struct *info)
+{
+	int ret = 0;
+
+	if ( info->tx_holding_count ) {
+		/* determine if we have enough tx dma buffers
+		 * to accomodate the next tx frame
+		 */
+		struct tx_holding_buffer *ptx =
+			&info->tx_holding_buffers[info->get_tx_holding_index];
+		int num_free = num_free_tx_dma_buffers(info);
+		int num_needed = ptx->buffer_size / DMABUFFERSIZE;
+		if ( ptx->buffer_size % DMABUFFERSIZE )
+			++num_needed;
+
+		if (num_needed <= num_free) {
+			info->xmit_cnt = ptx->buffer_size;
+			mgsl_load_tx_dma_buffer(info,ptx->buffer,ptx->buffer_size);
+
+			--info->tx_holding_count;
+			if ( ++info->get_tx_holding_index >= info->num_tx_holding_buffers)
+				info->get_tx_holding_index=0;
+
+			/* restart transmit timer */
+			del_timer(&info->tx_timer);
+			info->tx_timer.expires = jiffies + jiffies_from_ms(5000);
+			add_timer(&info->tx_timer);
+
+			ret = 1;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * save_tx_buffer_request()
+ *
+ * attempt to store transmit frame request for later transmission
+ *
+ * Arguments:
+ *
+ *	info		pointer to device instance data
+ * 	Buffer		pointer to buffer containing frame to load
+ * 	BufferSize	size in bytes of frame in Buffer
+ *
+ * Return Value:	1 if able to store, 0 otherwise
+ */
+int save_tx_buffer_request(struct mgsl_struct *info,const char *Buffer, unsigned int BufferSize)
+{
+	struct tx_holding_buffer *ptx;
+
+	if ( info->tx_holding_count >= info->num_tx_holding_buffers ) {
+		return 0;	        /* all buffers in use */
+	}
+
+	ptx = &info->tx_holding_buffers[info->put_tx_holding_index];
+	ptx->buffer_size = BufferSize;
+	memcpy( ptx->buffer, Buffer, BufferSize);
+
+	++info->tx_holding_count;
+	if ( ++info->put_tx_holding_index >= info->num_tx_holding_buffers)
+		info->put_tx_holding_index=0;
+
+	return 1;
+}
+
 int mgsl_claim_resources(struct mgsl_struct *info)
 {
 	if (request_region(info->io_base,info->io_addr_size,"synclink") == NULL) {
@@ -4120,7 +4408,7 @@
 	return 0;
 errout:
 	mgsl_release_resources(info);
-	return ENODEV;
+	return -ENODEV;
 
 }	/* end of mgsl_claim_resources() */
 
@@ -4141,6 +4429,7 @@
 	}
 	mgsl_free_dma_buffers(info);
 	mgsl_free_intermediate_rxbuffer_memory(info);
+     	mgsl_free_intermediate_txbuffer_memory(info);
 	
 	if ( info->io_addr_requested ) {
 		release_region(info->io_base,info->io_addr_size);
@@ -4187,6 +4476,20 @@
 		if (maxframe[info->line])
 			info->max_frame_size = maxframe[info->line];
 		info->dosyncppp = dosyncppp[info->line];
+
+		if (txdmabufs[info->line]) {
+			info->num_tx_dma_buffers = txdmabufs[info->line];
+			if (info->num_tx_dma_buffers < 1)
+				info->num_tx_dma_buffers = 1;
+		}
+
+		if (txholdbufs[info->line]) {
+			info->num_tx_holding_buffers = txholdbufs[info->line];
+			if (info->num_tx_holding_buffers < 1)
+				info->num_tx_holding_buffers = 1;
+			else if (info->num_tx_holding_buffers > MAX_TX_HOLDING_BUFFERS)
+				info->num_tx_holding_buffers = MAX_TX_HOLDING_BUFFERS;
+		}
 	}
 
 	mgsl_device_count++;
@@ -4255,6 +4558,8 @@
 		spin_lock_init(&info->netlock);
 		memcpy(&info->params,&default_params,sizeof(MGSL_PARAMS));
 		info->idle_mode = HDLC_TXIDLE_FLAGS;		
+		info->num_tx_dma_buffers = 1;
+		info->num_tx_holding_buffers = 0;
 	}
 	
 	return info;
@@ -4432,6 +4737,7 @@
 	unsigned long flags;
 	int rc;
 	struct mgsl_struct *info;
+	struct mgsl_struct *tmp;
 
 	printk("Unloading %s: version %s\n", driver_name, driver_version);
 	save_flags(flags);
@@ -4451,7 +4757,9 @@
 			mgsl_sppp_delete(info);
 #endif
 		mgsl_release_resources(info);
+		tmp = info;
 		info = info->next_device;
+		kfree(tmp);
 	}
 	
 	if (tmp_buf) {
@@ -4691,6 +4999,27 @@
 		 *
 		 * 0000 0110 0000 0110 = 0x0606
 		 */
+		if (info->params.mode == MGSL_MODE_RAW) {
+			RegValue = 0x0001;		/* Set Receive mode = external sync */
+
+			usc_OutReg( info, IOCR,		/* Set IOCR DCD is RxSync Detect Input */
+				(unsigned short)((usc_InReg(info, IOCR) & ~(BIT13|BIT12)) | BIT12));
+
+			/*
+			 * TxSubMode:
+			 * 	CMR <15>		0	Don't send CRC on Tx Underrun
+			 * 	CMR <14>		x	undefined
+			 * 	CMR <13>		0	Send preamble before openning sync
+			 * 	CMR <12>		0	Send 8-bit syncs, 1=send Syncs per TxLength
+			 *
+			 * TxMode:
+			 * 	CMR <11-8)	0100	MonoSync
+			 *
+			 * 	0x00 0100 xxxx xxxx  04xx
+			 */
+			RegValue |= 0x0400;
+		}
+		else {
 
 		RegValue = 0x0606;
 
@@ -4700,12 +5029,14 @@
 			RegValue |= BIT15;
 		else if ( info->params.flags & HDLC_FLAG_UNDERRUN_CRC )
 			RegValue |= BIT15 + BIT14;
+		}
 
 		if ( info->params.preamble != HDLC_PREAMBLE_PATTERN_NONE )
 			RegValue |= BIT13;
 	}
 
-	if ( info->params.flags & HDLC_FLAG_SHARE_ZERO )
+	if ( info->params.mode == MGSL_MODE_HDLC &&
+		(info->params.flags & HDLC_FLAG_SHARE_ZERO) )
 		RegValue |= BIT12;
 
 	if ( info->params.addr_filter != 0xff )
@@ -4745,15 +5076,13 @@
 	case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: RegValue |= BIT15 + BIT14 + BIT13; break;
 	}
 
-	if ( info->params.crc_type == HDLC_CRC_16_CCITT )
+	if ( (info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_16_CCITT )
 		RegValue |= BIT9;
-	else if ( info->params.crc_type == HDLC_CRC_32_CCITT )
+	else if ( (info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_32_CCITT )
 		RegValue |= ( BIT12 | BIT10 | BIT9 );
 
 	usc_OutReg( info, RMR, RegValue );
 
-
- 
 	/* Set the Receive count Limit Register (RCLR) to 0xffff. */
 	/* When an opening flag of an SDLC frame is recognized the */
 	/* Receive Character count (RCC) is loaded with the value in */
@@ -4822,9 +5151,9 @@
 	case HDLC_ENCODING_DIFF_BIPHASE_LEVEL: RegValue |= BIT15 + BIT14 + BIT13; break;
 	}
 
-	if ( info->params.crc_type == HDLC_CRC_16_CCITT )
+	if ( (info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_16_CCITT )
 		RegValue |= BIT9 + BIT8;
-	else if ( info->params.crc_type == HDLC_CRC_32_CCITT )
+	else if ( (info->params.crc_type & HDLC_CRC_MASK) == HDLC_CRC_32_CCITT )
 		RegValue |= ( BIT12 | BIT10 | BIT9 | BIT8);
 
 	usc_OutReg( info, TMR, RegValue );
@@ -5495,7 +5824,8 @@
 	usc_OutReg( info, CCSR, (u16)(usc_InReg(info,CCSR) | BIT13) );
 	usc_RTCmd( info, RTCmd_PurgeRxFifo );
 
-	if ( info->params.mode == MGSL_MODE_HDLC ) {
+	if ( info->params.mode == MGSL_MODE_HDLC ||
+		info->params.mode == MGSL_MODE_RAW ) {
 		/* DMA mode Transfers */
 		/* Program the DMA controller. */
 		/* Enable the DMA controller end of buffer interrupt. */
@@ -5585,8 +5915,14 @@
 			/* Transmit DMA buffer is loaded, so program USC */
 			/* to send the frame contained in the buffers.	 */
 
+			FrameSize = info->tx_buffer_list[info->start_tx_dma_buffer].rcc;
 
-			FrameSize = info->tx_buffer_list[0].rcc;
+			/* if operating in Raw sync mode, reset the rcc component
+			 * of the tx dma buffer entry, otherwise, the serial controller
+			 * will send a closing sync char after this count.
+			 */
+	    		if ( info->params.mode == MGSL_MODE_RAW )
+				info->tx_buffer_list[info->start_tx_dma_buffer].rcc = 0;
 
 			/* Program the Transmit Character Length Register (TCLR) */
 			/* and clear FIFO (TCC is loaded with TCLR on FIFO clear) */
@@ -5595,7 +5931,7 @@
 			usc_RTCmd( info, RTCmd_PurgeTxFifo );
 
 			/* Program the address of the 1st DMA Buffer Entry in linked list */
-			phys_addr = info->tx_buffer_list[0].phys_entry;
+			phys_addr = info->tx_buffer_list[info->start_tx_dma_buffer].phys_entry;
 			usc_OutDmaReg( info, NTARL, (u16)phys_addr );
 			usc_OutDmaReg( info, NTARU, (u16)(phys_addr >> 16) );
 
@@ -5603,6 +5939,19 @@
 			usc_ClearIrqPendingBits( info, TRANSMIT_STATUS );
 			usc_EnableInterrupts( info, TRANSMIT_STATUS );
 
+			if ( info->params.mode == MGSL_MODE_RAW &&
+					info->num_tx_dma_buffers > 1 ) {
+			   /* When running external sync mode, attempt to 'stream' transmit  */
+			   /* by filling tx dma buffers as they become available. To do this */
+			   /* we need to enable Tx DMA EOB Status interrupts :               */
+			   /*                                                                */
+			   /* 1. Arm End of Buffer (EOB) Transmit DMA Interrupt (BIT2 of TDIAR) */
+			   /* 2. Enable Transmit DMA Interrupts (BIT0 of DICR) */
+
+			   usc_OutDmaReg( info, TDIAR, BIT2|BIT3 );
+			   usc_OutDmaReg( info, DICR, (u16)(usc_InDmaReg(info,DICR) | BIT0) );
+			}
+
 			/* Initialize Transmit DMA Channel */
 			usc_DmaCmd( info, DmaCmd_InitTxChannel );
 			
@@ -6026,6 +6375,9 @@
 void usc_loopback_frame( struct mgsl_struct *info )
 {
 	int i;
+	unsigned long oldmode = info->params.mode;
+
+	info->params.mode = MGSL_MODE_HDLC;
 	
 	usc_DisableMasterIrqBit( info );
 
@@ -6079,6 +6431,8 @@
 
 	usc_EnableMasterIrqBit(info);
 
+	info->params.mode = oldmode;
+
 }	/* end of usc_loopback_frame() */
 
 /* usc_set_sync_mode()	Programs the USC for SDLC communications.
@@ -6130,6 +6484,38 @@
 	info->tcsr_value += usc_idle_mode;
 	usc_OutReg(info, TCSR, info->tcsr_value);
 
+	/*
+	 * if SyncLink WAN adapter is running in external sync mode, the
+	 * transmitter has been set to Monosync in order to try to mimic
+	 * a true raw outbound bit stream. Monosync still sends an open/close
+	 * sync char at the start/end of a frame. Try to match those sync
+	 * patterns to the idle mode set here
+	 */
+	if ( info->params.mode == MGSL_MODE_RAW ) {
+		unsigned char syncpat = 0;
+		switch( info->idle_mode ) {
+		case HDLC_TXIDLE_FLAGS:
+			syncpat = 0x7e;
+			break;
+		case HDLC_TXIDLE_ALT_ZEROS_ONES:
+			syncpat = 0x55;
+			break;
+		case HDLC_TXIDLE_ZEROS:
+		case HDLC_TXIDLE_SPACE:
+			syncpat = 0x00;
+			break;
+		case HDLC_TXIDLE_ONES:
+		case HDLC_TXIDLE_MARK:
+			syncpat = 0xff;
+			break;
+		case HDLC_TXIDLE_ALT_MARK_SPACE:
+			syncpat = 0xaa;
+			break;
+		}
+
+		usc_SetTransmitSyncChars(info,syncpat,syncpat);
+	}
+
 }	/* end of usc_set_txidle() */
 
 /* usc_get_serial_signals()
@@ -6307,6 +6693,48 @@
  */
 
 /*
+ * mgsl_reset_tx_dma_buffers()
+ *
+ * 	Set the count for all transmit buffers to 0 to indicate the
+ * 	buffer is available for use and set the current buffer to the
+ * 	first buffer. This effectively makes all buffers free and
+ * 	discards any data in buffers.
+ *
+ * Arguments:		info	pointer to device instance data
+ * Return Value:	None
+ */
+void mgsl_reset_tx_dma_buffers( struct mgsl_struct *info )
+{
+	unsigned int i;
+
+	for ( i = 0; i < info->tx_buffer_count; i++ ) {
+		*((unsigned long *)&(info->tx_buffer_list[i].count)) = 0;
+	}
+
+	info->current_tx_buffer = 0;
+	info->start_tx_dma_buffer = 0;
+	info->tx_dma_buffers_used = 0;
+
+	info->get_tx_holding_index = 0;
+	info->put_tx_holding_index = 0;
+	info->tx_holding_count = 0;
+
+}	/* end of mgsl_reset_tx_dma_buffers() */
+
+/*
+ * num_free_tx_dma_buffers()
+ *
+ * 	returns the number of free tx dma buffers available
+ *
+ * Arguments:		info	pointer to device instance data
+ * Return Value:	number of free tx dma buffers
+ */
+int num_free_tx_dma_buffers(struct mgsl_struct *info)
+{
+	return info->tx_buffer_count - info->tx_dma_buffers_used;
+}
+
+/*
  * mgsl_reset_rx_dma_buffers()
  * 
  * 	Set the count for all receive buffers to DMABUFFERSIZE
@@ -6392,10 +6820,11 @@
 	unsigned int StartIndex, EndIndex;	/* index of 1st and last buffers of Rx frame */
 	unsigned short status;
 	DMABUFFERENTRY *pBufEntry;
-	unsigned int framesize;
+	unsigned int framesize = 0;
 	int ReturnCode = 0;
 	unsigned long flags;
 	struct tty_struct *tty = info->tty;
+	int return_frame = 0;
 	
 	/*
 	 * current_rx_buffer points to the 1st buffer of the next available
@@ -6451,14 +6880,20 @@
 			info->icount.rxabort++;
 		else if ( status & RXSTATUS_OVERRUN )
 			info->icount.rxover++;
-		else 
+		else {
 			info->icount.rxcrc++;
+			if ( info->params.crc_type & HDLC_CRC_RETURN_EX )
+				return_frame = 1;
+		}
 		framesize = 0;
 #ifdef CONFIG_SYNCLINK_SYNCPPP
 		info->netstats.rx_errors++;
 		info->netstats.rx_frame_errors++;
 #endif
-	} else {
+	} else
+		return_frame = 1;
+
+	if ( return_frame ) {
 		/* receive frame has no errors, get frame size.
 		 * The frame size is the starting value of the RCC (which was
 		 * set to 0xffff) minus the ending value of the RCC (decremented
@@ -6483,7 +6918,9 @@
 			MIN(framesize,DMABUFFERSIZE),0);	
 		
 	if (framesize) {
-		if (framesize > info->max_frame_size)
+		if ( ( (info->params.crc_type & HDLC_CRC_RETURN_EX) &&
+				((framesize+1) > info->max_frame_size) ) ||
+			(framesize > info->max_frame_size) )
 			info->icount.rxlong++;
 		else {
 			/* copy dma buffer(s) to contiguous intermediate buffer */
@@ -6491,6 +6928,7 @@
 			int index = StartIndex;
 			unsigned char *ptmp = info->intermediate_rxbuffer;
 
+			if ( !(status & RXSTATUS_CRC_ERROR))
 			info->icount.rxok++;
 			
 			while(copy_count) {
@@ -6509,6 +6947,18 @@
 					index = 0;
 			}
 
+			if ( info->params.crc_type & HDLC_CRC_RETURN_EX ) {
+				++framesize;
+				*ptmp = (status & RXSTATUS_CRC_ERROR ?
+						RX_CRC_ERROR :
+						RX_OK);
+
+				if ( debug_level >= DEBUG_LEVEL_DATA )
+					printk("%s(%d):mgsl_get_rx_frame(%s) rx frame status=%d\n",
+						__FILE__,__LINE__,info->device_name,
+						*ptmp);
+			}
+
 #ifdef CONFIG_SYNCLINK_SYNCPPP
 			if (info->netcount) {
 				/* pass frame to syncppp device */
@@ -6518,6 +6968,7 @@
 #endif
 			{
 				/* Call the line discipline receive callback directly. */
+				if ( tty && tty->ldisc.receive_buf )
 				tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize);
 			}
 		}
@@ -6547,6 +6998,180 @@
 
 }	/* end of mgsl_get_rx_frame() */
 
+/* mgsl_get_raw_rx_frame()
+ *
+ *     	This function attempts to return a received frame from the
+ *	receive DMA buffers when running in external loop mode. In this mode,
+ *	we will return at most one DMABUFFERSIZE frame to the application.
+ *	The USC receiver is triggering off of DCD going active to start a new
+ *	frame, and DCD going inactive to terminate the frame (similar to
+ *	processing a closing flag character).
+ *
+ *	In this routine, we will return DMABUFFERSIZE "chunks" at a time.
+ *	If DCD goes inactive, the last Rx DMA Buffer will have a non-zero
+ * 	status field and the RCC field will indicate the length of the
+ *	entire received frame. We take this RCC field and get the modulus
+ *	of RCC and DMABUFFERSIZE to determine if number of bytes in the
+ *	last Rx DMA buffer and return that last portion of the frame.
+ *
+ * Arguments:	 	info	pointer to device extension
+ * Return Value:	1 if frame returned, otherwise 0
+ */
+int mgsl_get_raw_rx_frame(struct mgsl_struct *info)
+{
+	unsigned int CurrentIndex, NextIndex;
+	unsigned short status;
+	DMABUFFERENTRY *pBufEntry;
+	unsigned int framesize = 0;
+	int ReturnCode = 0;
+	unsigned long flags;
+	struct tty_struct *tty = info->tty;
+
+	/*
+ 	 * current_rx_buffer points to the 1st buffer of the next available
+	 * receive frame. The status field is set by the 16C32 after
+	 * completing a receive frame. If the status field of this buffer
+	 * is zero, either the USC is still filling this buffer or this
+	 * is one of a series of buffers making up a received frame.
+	 *
+	 * If the count field of this buffer is zero, the USC is either
+	 * using this buffer or has used this buffer. Look at the count
+	 * field of the next buffer. If that next buffer's count is
+	 * non-zero, the USC is still actively using the current buffer.
+	 * Otherwise, if the next buffer's count field is zero, the
+	 * current buffer is complete and the USC is using the next
+	 * buffer.
+	 */
+	CurrentIndex = NextIndex = info->current_rx_buffer;
+	++NextIndex;
+	if ( NextIndex == info->rx_buffer_count )
+		NextIndex = 0;
+
+	if ( info->rx_buffer_list[CurrentIndex].status != 0 ||
+		(info->rx_buffer_list[CurrentIndex].count == 0 &&
+			info->rx_buffer_list[NextIndex].count == 0)) {
+		/*
+	 	 * Either the status field of this dma buffer is non-zero
+		 * (indicating the last buffer of a receive frame) or the next
+	 	 * buffer is marked as in use -- implying this buffer is complete
+		 * and an intermediate buffer for this received frame.
+	 	 */
+
+		status = info->rx_buffer_list[CurrentIndex].status;
+
+		if ( status & (RXSTATUS_SHORT_FRAME + RXSTATUS_OVERRUN +
+				RXSTATUS_CRC_ERROR + RXSTATUS_ABORT) ) {
+			if ( status & RXSTATUS_SHORT_FRAME )
+				info->icount.rxshort++;
+			else if ( status & RXSTATUS_ABORT )
+				info->icount.rxabort++;
+			else if ( status & RXSTATUS_OVERRUN )
+				info->icount.rxover++;
+			else
+				info->icount.rxcrc++;
+			framesize = 0;
+		} else {
+			/*
+			 * A receive frame is available, get frame size and status.
+			 *
+			 * The frame size is the starting value of the RCC (which was
+			 * set to 0xffff) minus the ending value of the RCC (decremented
+			 * once for each receive character) minus 2 or 4 for the 16-bit
+			 * or 32-bit CRC.
+			 *
+			 * If the status field is zero, this is an intermediate buffer.
+			 * It's size is 4K.
+			 *
+			 * If the DMA Buffer Entry's Status field is non-zero, the
+			 * receive operation completed normally (ie: DCD dropped). The
+			 * RCC field is valid and holds the received frame size.
+			 * It is possible that the RCC field will be zero on a DMA buffer
+			 * entry with a non-zero status. This can occur if the total
+			 * frame size (number of bytes between the time DCD goes active
+			 * to the time DCD goes inactive) exceeds 65535 bytes. In this
+			 * case the 16C32 has underrun on the RCC count and appears to
+			 * stop updating this counter to let us know the actual received
+			 * frame size. If this happens (non-zero status and zero RCC),
+			 * simply return the entire RxDMA Buffer
+			 */
+			if ( status ) {
+				/*
+				 * In the event that the final RxDMA Buffer is
+				 * terminated with a non-zero status and the RCC
+				 * field is zero, we interpret this as the RCC
+				 * having underflowed (received frame > 65535 bytes).
+				 *
+				 * Signal the event to the user by passing back
+				 * a status of RxStatus_CrcError returning the full
+				 * buffer and let the app figure out what data is
+				 * actually valid
+				 */
+				if ( info->rx_buffer_list[CurrentIndex].rcc )
+					framesize = RCLRVALUE - info->rx_buffer_list[CurrentIndex].rcc;
+				else
+					framesize = DMABUFFERSIZE;
+			}
+			else
+				framesize = DMABUFFERSIZE;
+		}
+
+		if ( framesize > DMABUFFERSIZE ) {
+			/*
+			 * if running in raw sync mode, ISR handler for
+			 * End Of Buffer events terminates all buffers at 4K.
+			 * If this frame size is said to be >4K, get the
+			 * actual number of bytes of the frame in this buffer.
+			 */
+			framesize = framesize % DMABUFFERSIZE;
+		}
+
+
+		if ( debug_level >= DEBUG_LEVEL_BH )
+			printk("%s(%d):mgsl_get_raw_rx_frame(%s) status=%04X size=%d\n",
+				__FILE__,__LINE__,info->device_name,status,framesize);
+
+		if ( debug_level >= DEBUG_LEVEL_DATA )
+			mgsl_trace_block(info,info->rx_buffer_list[CurrentIndex].virt_addr,
+				MIN(framesize,DMABUFFERSIZE),0);
+
+		if (framesize) {
+			/* copy dma buffer(s) to contiguous intermediate buffer */
+			/* NOTE: we never copy more than DMABUFFERSIZE bytes	*/
+
+			pBufEntry = &(info->rx_buffer_list[CurrentIndex]);
+			memcpy( info->intermediate_rxbuffer, pBufEntry->virt_addr, framesize);
+			info->icount.rxok++;
+
+			/* Call the line discipline receive callback directly. */
+			if ( tty && tty->ldisc.receive_buf )
+				tty->ldisc.receive_buf(tty, info->intermediate_rxbuffer, info->flag_buf, framesize);
+		}
+
+		/* Free the buffers used by this frame. */
+		mgsl_free_rx_frame_buffers( info, CurrentIndex, CurrentIndex );
+
+		ReturnCode = 1;
+	}
+
+
+	if ( info->rx_enabled && info->rx_overflow ) {
+		/* The receiver needs to restarted because of
+		 * a receive overflow (buffer or FIFO). If the
+		 * receive buffers are now empty, then restart receiver.
+		 */
+
+		if ( !info->rx_buffer_list[CurrentIndex].status &&
+			info->rx_buffer_list[CurrentIndex].count ) {
+			spin_lock_irqsave(&info->irq_spinlock,flags);
+			usc_start_receiver(info);
+			spin_unlock_irqrestore(&info->irq_spinlock,flags);
+		}
+	}
+
+	return ReturnCode;
+
+}	/* end of mgsl_get_raw_rx_frame() */
+
 /* mgsl_load_tx_dma_buffer()
  * 
  * 	Load the transmit DMA buffer with the specified data.
@@ -6576,12 +7201,19 @@
 	 	info->cmr_value |= BIT13;			  
 	}
 		
+	/* begin loading the frame in the next available tx dma
+	 * buffer, remember it's starting location for setting
+	 * up tx dma operation
+	 */
+	i = info->current_tx_buffer;
+	info->start_tx_dma_buffer = i;
+
 	/* Setup the status and RCC (Frame Size) fields of the 1st */
 	/* buffer entry in the transmit DMA buffer list. */
 
-	info->tx_buffer_list[0].status = info->cmr_value & 0xf000;
-	info->tx_buffer_list[0].rcc    = BufferSize;
-	info->tx_buffer_list[0].count  = BufferSize;
+	info->tx_buffer_list[i].status = info->cmr_value & 0xf000;
+	info->tx_buffer_list[i].rcc    = BufferSize;
+	info->tx_buffer_list[i].count  = BufferSize;
 
 	/* Copy frame data from 1st source buffer to the DMA buffers. */
 	/* The frame data may span multiple DMA buffers. */
@@ -6590,6 +7222,9 @@
 		/* Get a pointer to next DMA buffer entry. */
 		pBufEntry = &info->tx_buffer_list[i++];
 			
+		if ( i == info->tx_buffer_count )
+			i=0;
+
 		/* Calculate the number of bytes that can be copied from */
 		/* the source buffer to this DMA buffer. */
 		if ( BufferSize > DMABUFFERSIZE )
@@ -6609,8 +7244,13 @@
 		/* Advance source pointer and reduce remaining data count. */
 		Buffer += Copycount;
 		BufferSize -= Copycount;
+
+		++info->tx_dma_buffers_used;
 	}
 
+	/* remember next available tx dma buffer */
+	info->current_tx_buffer = i;
+
 }	/* end of mgsl_load_tx_dma_buffer() */
 
 /*
@@ -6741,7 +7381,7 @@
 	unsigned int i;
 	char *TmpPtr;
 	BOOLEAN rc = TRUE;
-	unsigned short status;
+	unsigned short status=0;
 	unsigned long EndTime;
 	unsigned long flags;
 	MGSL_PARAMS tmp_params;
@@ -6998,7 +7638,7 @@
 		status = info->rx_buffer_list[0].status;
 
 		if ( status & (BIT8 + BIT3 + BIT1) ) {
-			/* receive error has occurred */
+			/* receive error has occured */
 			rc = FALSE;
 		} else {
 			if ( memcmp( info->tx_buffer_list[0].virt_addr ,
@@ -7219,7 +7859,9 @@
 	if ( debug_level >= DEBUG_LEVEL_INFO )
 		printk( "%s(%d):mgsl_tx_timeout(%s)\n",
 			__FILE__,__LINE__,info->device_name);
-	if(info->tx_active && info->params.mode == MGSL_MODE_HDLC) {
+	if(info->tx_active &&
+	   (info->params.mode == MGSL_MODE_HDLC ||
+	    info->params.mode == MGSL_MODE_RAW) ) {
 		info->icount.txtimeout++;
 	}
 	spin_lock_irqsave(&info->irq_spinlock,flags);
diff -u --recursive --new-file v2.4.4/linux/drivers/char/wdt.c linux/drivers/char/wdt.c
--- v2.4.4/linux/drivers/char/wdt.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/char/wdt.c	Sat May 19 17:43:05 2001
@@ -311,7 +311,7 @@
 	switch(cmd)
 	{
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
 			return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
 
diff -u --recursive --new-file v2.4.4/linux/drivers/char/wdt285.c linux/drivers/char/wdt285.c
--- v2.4.4/linux/drivers/char/wdt285.c	Mon Oct 16 12:58:51 2000
+++ linux/drivers/char/wdt285.c	Sat May 19 17:43:05 2001
@@ -136,7 +136,7 @@
 	switch(cmd)
 	{
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
 			i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct watchdog_info));
 			if (i)
diff -u --recursive --new-file v2.4.4/linux/drivers/char/wdt_pci.c linux/drivers/char/wdt_pci.c
--- v2.4.4/linux/drivers/char/wdt_pci.c	Fri Feb  9 11:30:22 2001
+++ linux/drivers/char/wdt_pci.c	Sat May 19 17:43:05 2001
@@ -327,7 +327,7 @@
 	switch(cmd)
 	{
 		default:
-			return -ENOIOCTLCMD;
+			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
 			return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident))?-EFAULT:0;
 
diff -u --recursive --new-file v2.4.4/linux/drivers/i2o/i2o_block.c linux/drivers/i2o/i2o_block.c
--- v2.4.4/linux/drivers/i2o/i2o_block.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/i2o/i2o_block.c	Tue May  1 16:12:51 2001
@@ -28,14 +28,16 @@
  *    		Support for larger I/Os through merge* functions 
  *       	(taken from DAC960 driver)
  *	Boji T Kannanthanam:
- *		Reduced the timeout during RAID 5 creation. 
- *		This is to prevent race condition when a RAID volume
- *		is created and immediately deleted.
+ *		Set the I2O Block devices to be detected in increasing 
+ *		order of TIDs during boot.
+ *		Search and set the I2O block device that we boot off from  as
+ *		the first device to be claimed (as /dev/i2o/hda)
+ *		Properly attach/detach I2O gendisk structure from the system
+ *		gendisk list. The I2O block devices now appear in 
+ * 		/proc/partitions.
  *
  *	To do:
  *		Serial number scanning to find duplicates for FC multipathing
- *		Remove the random timeout in the code needed for RAID 5
- *			volume creation.
  */
 
 #include <linux/major.h>
@@ -86,7 +88,8 @@
 #define I2OB_EVENT_MASK		(I2O_EVT_IND_BSA_VOLUME_LOAD |	\
 				 I2O_EVT_IND_BSA_VOLUME_UNLOAD | \
 				 I2O_EVT_IND_BSA_VOLUME_UNLOAD_REQ | \
-				 I2O_EVT_IND_BSA_CAPACITY_CHANGE)
+				 I2O_EVT_IND_BSA_CAPACITY_CHANGE | \
+				 I2O_EVT_IND_BSA_SCSI_SMART )
 
 
 /*
@@ -135,6 +138,8 @@
 	request_queue_t *req_queue;
 	int max_segments;
 	int done_flag;
+	int constipated;
+	int depth;
 };
 
 /*
@@ -164,7 +169,9 @@
 	struct i2ob_request *i2ob_qhead;
 	request_queue_t req_queue;
 };
-static struct i2ob_iop_queue *i2ob_queues[MAX_I2O_CONTROLLERS] = {NULL};
+static struct i2ob_iop_queue *i2ob_queues[MAX_I2O_CONTROLLERS];
+static struct i2ob_request *i2ob_backlog[MAX_I2O_CONTROLLERS];
+static struct i2ob_request *i2ob_backlog_tail[MAX_I2O_CONTROLLERS];
 
 /*
  *	Each I2O disk is one of these.
@@ -179,10 +186,10 @@
  * Mutex and spin lock for event handling synchronization
  * evt_msg contains the last event.
  */
-DECLARE_MUTEX(i2ob_evt_sem);
+static DECLARE_MUTEX_LOCKED(i2ob_evt_sem);
+static DECLARE_MUTEX_LOCKED(i2ob_thread_dead);
 static spinlock_t i2ob_evt_lock = SPIN_LOCK_UNLOCKED;
-static unsigned int evt_msg[MSG_FRAME_SIZE>>2];
-DECLARE_WAIT_QUEUE_HEAD(i2ob_evt_wait);
+static u32 evt_msg[MSG_FRAME_SIZE>>2];
 
 static struct timer_list i2ob_timer;
 static int i2ob_timer_started = 0;
@@ -195,6 +202,7 @@
 static int i2ob_install_device(struct i2o_controller *, struct i2o_device *, int);
 static void i2ob_end_request(struct request *);
 static void i2ob_request(request_queue_t *);
+static int i2ob_backlog_request(struct i2o_controller *, struct i2ob_device *);
 static int i2ob_init_iop(unsigned int);
 static request_queue_t* i2ob_get_queue(kdev_t);
 static int i2ob_query_device(struct i2ob_device *, int, int, void*, int);
@@ -203,6 +211,7 @@
 
 static int evt_pid = 0;
 static int evt_running = 0;
+static int scan_unit = 0;
 
 /*
  * I2O OSM registration structure...keeps getting bigger and bigger :)
@@ -255,7 +264,12 @@
 	__raw_writel(i2ob_context|(unit<<8), msg+8);
 	__raw_writel(ireq->num, msg+12);
 	__raw_writel(req->nr_sectors << 9, msg+20);
-	
+
+	/* 
+	 * Mask out partitions from now on
+	 */
+	unit &= 0xF0;
+		
 	/* This can be optimised later - just want to be sure its right for
 	   starters */
 	offset = ((u64)(req->sector+base)) << 9;
@@ -266,8 +280,6 @@
 	if(req->cmd == READ)
 	{
 		__raw_writel(I2O_CMD_BLOCK_READ<<24|HOST_TID<<12|tid, msg+4);
-		/* We don't yet do cache/readahead and other magic */
-		__raw_writel(1<<16, msg+16);
 		while(bh!=NULL)
 		{
 			if(bh->b_data == last) {
@@ -293,16 +305,20 @@
 			count -= bh->b_size;
 			bh = bh->b_reqnext;
 		}
+		/*
+		 *	Heuristic for now since the block layer doesnt give
+		 *	us enough info. If its a big write assume sequential
+		 *	readahead on controller. If its small then don't read
+		 *	ahead but do use the controller cache.
+		 */
+		if(size >= 8192)
+			__raw_writel((8<<24)|(1<<16)|8, msg+16);
+		else
+			__raw_writel((8<<24)|(1<<16)|4, msg+16);
 	}
 	else if(req->cmd == WRITE)
 	{
 		__raw_writel(I2O_CMD_BLOCK_WRITE<<24|HOST_TID<<12|tid, msg+4);
-		/* 
-		 * Allow replies to come back once data is cached in the controller
-		 * This allows us to handle writes quickly thus giving more of the
-		 * queue to reads.
-		 */
-		__raw_writel(0x00000010, msg+16);
 		while(bh!=NULL)
 		{
 			if(bh->b_data == last) {
@@ -328,13 +344,32 @@
 			count -= bh->b_size;
 			bh = bh->b_reqnext;
 		}
+
+		if(c->battery)
+		{
+			
+			if(size>16384)
+				__raw_writel(4, msg+16);
+			else
+				/* 
+				 * Allow replies to come back once data is cached in the controller
+				 * This allows us to handle writes quickly thus giving more of the
+				 * queue to reads.
+				 */
+				__raw_writel(16, msg+16);
+		}
+		else
+		{
+			/* Large write, don't cache */
+			if(size>8192)
+				__raw_writel(4, msg+16);
+			else
+			/* write through */
+				__raw_writel(8, msg+16);
+		}
 	}
 	__raw_writel(I2O_MESSAGE_SIZE(mptr-msg)>>2 | SGL_OFFSET_8, msg);
 	
-	if(req->current_nr_sectors > i2ob_max_sectors[unit])
-		printk("Gathered sectors %ld.\n", 
-			req->current_nr_sectors);
-			
 	if(count != 0)
 	{
 		printk(KERN_ERR "Request count botched by %d.\n", count);
@@ -434,7 +469,32 @@
 	return 1;
 }
 
+static int i2ob_flush(struct i2o_controller *c, struct i2ob_device *d, int unit)
+{
+	unsigned long msg;
+	u32 m = i2ob_get(d);
+	
+	if(m == 0xFFFFFFFF)
+		return -1;
+		
+	msg = c->mem_offset + m;
 
+	/*
+	 *	Ask the controller to write the cache back. This sorts out
+	 *	the supertrak firmware flaw and also does roughly the right
+	 *	thing for other cases too.
+	 */
+	 	
+	__raw_writel(FIVE_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
+	__raw_writel(I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|d->tid, msg+4);
+	__raw_writel(i2ob_context|(unit<<8), msg+8);
+	__raw_writel(0, msg+12);
+	__raw_writel(60<<16, msg+16);
+	
+	i2o_post_message(c,m);
+	return 0;
+}
+			
 /*
  *	OSM reply handler. This gets all the message replies
  */
@@ -447,7 +507,7 @@
 	u32 *m = (u32 *)msg;
 	u8 unit = (m[2]>>8)&0xF0;	/* low 4 bits are partition */
 	struct i2ob_device *dev = &i2ob_dev[(unit&0xF0)];
-
+	
 	/*
 	 * FAILed message
 	 */
@@ -482,9 +542,20 @@
 	if(msg->function == I2O_CMD_UTIL_EVT_REGISTER)
 	{
 		spin_lock(&i2ob_evt_lock);
-		memcpy(&evt_msg, m, msg->size);
+		memcpy(evt_msg, msg, (m[0]>>16)<<2);
 		spin_unlock(&i2ob_evt_lock);
-		wake_up_interruptible(&i2ob_evt_wait);
+		up(&i2ob_evt_sem);
+		return;
+	}
+
+	if(msg->function == I2O_CMD_BLOCK_CFLUSH)
+	{
+		spin_lock_irqsave(&io_request_lock, flags);
+		dev->constipated=0;
+		DEBUG(("unconstipated\n"));
+		if(i2ob_backlog_request(c, dev)==0)
+			i2ob_request(dev->req_queue);
+		spin_unlock_irqrestore(&io_request_lock, flags);
 		return;
 	}
 
@@ -517,6 +588,7 @@
 
 	if(st!=0)
 	{
+		int err;
 		char *bsa_errors[] = 
 		{ 
 			"Success", 
@@ -535,12 +607,78 @@
 			"Volume has changed, waiting for acknowledgement"
 		};
 				
+		err = m[4]&0xFFFF;
+		
+		/*
+		 *	Device not ready means two things. One is that the
+		 *	the thing went offline (but not a removal media)
+		 *
+		 *	The second is that you have a SuperTrak 100 and the
+		 *	firmware got constipated. Unlike standard i2o card
+		 *	setups the supertrak returns an error rather than
+		 *	blocking for the timeout in these cases.
+		 */
+		 
+		
+		spin_lock_irqsave(&io_request_lock, flags);
+		if(err==4)
+		{
+			/*
+			 *	Time to uncork stuff
+			 */
+			
+			if(!dev->constipated)
+			{
+				dev->constipated = 1;
+				DEBUG(("constipated\n"));
+				/* Now pull the chain */
+				if(i2ob_flush(c, dev, unit)<0)
+				{
+					DEBUG(("i2ob: Unable to queue flush. Retrying I/O immediately.\n"));
+					dev->constipated=0;
+				}
+				DEBUG(("flushing\n"));
+			}
+			
+			/*
+			 *	Recycle the request
+			 */
+			 
+//			i2ob_unhook_request(ireq, c->unit);
+			
+			/*
+			 *	Place it on the recycle queue
+			 */
+			 
+			ireq->next = NULL;
+			if(i2ob_backlog_tail[c->unit]!=NULL)
+				i2ob_backlog_tail[c->unit]->next = ireq;
+			else
+				i2ob_backlog[c->unit] = ireq;			
+			i2ob_backlog_tail[c->unit] = ireq;
+			
+			atomic_dec(&i2ob_queues[c->unit]->queue_depth);
+
+			/*
+			 *	If the constipator flush failed we want to
+			 *	poke the queue again. 
+			 */
+			 
+			i2ob_request(dev->req_queue);
+			spin_unlock_irqrestore(&io_request_lock, flags);
+			
+			/*
+			 *	and out
+			 */
+			 
+			return;	
+		}
+		spin_unlock_irqrestore(&io_request_lock, flags);
 		printk(KERN_ERR "\n/dev/%s error: %s", dev->i2odev->dev_name, 
 			bsa_errors[m[4]&0XFFFF]);
 		if(m[4]&0x00FF0000)
 			printk(" - DDM attempted %d retries", (m[4]>>16)&0x00FF );
-		printk("\n");
-
+		printk(".\n");
 		ireq->req->errors++;	
 	}
 	else
@@ -559,7 +697,9 @@
 	/*
 	 *	We may be able to do more I/O
 	 */
-	i2ob_request(dev->req_queue);
+
+	if(i2ob_backlog_request(c, dev)==0)
+		i2ob_request(dev->req_queue);
 
 	spin_unlock_irqrestore(&io_request_lock, flags);
 }
@@ -575,6 +715,14 @@
 	unsigned int flags;
 	int unit;
 	int i;
+	//The only event that has data is the SCSI_SMART event.
+	struct i2o_reply {
+		u32 header[4];
+		u32 evt_indicator;
+		u8 ASC;
+		u8 ASCQ;
+		u8 data[16];
+		} *evt_local;
 
 	lock_kernel();
 	daemonize();
@@ -585,15 +733,13 @@
 
 	while(1)
 	{
-#warning "RACE"
-		interruptible_sleep_on(&i2ob_evt_wait);
- 		if(signal_pending(current)) {
+		if(down_interruptible(&i2ob_evt_sem))
+		{
 			evt_running = 0;
-			return 0;
+			printk("exiting...");
+			break;
 		}
 
-		printk(KERN_INFO "Doing something in i2o_block event thread\n");
-		
 		/*
 		 * Keep another CPU/interrupt from overwriting the 
 		 * message while we're reading it
@@ -602,10 +748,12 @@
 		 * None of the BSA we care about events have EventData
 		 */
 		spin_lock_irqsave(&i2ob_evt_lock, flags);
-		unit = evt_msg[3];
-		evt = evt_msg[4];
+		evt_local = (struct i2o_reply *)evt_msg;
 		spin_unlock_irqrestore(&i2ob_evt_lock, flags);
 
+		unit = evt_local->header[3];
+		evt = evt_local->evt_indicator;
+
 		switch(evt)
 		{
 			/*
@@ -675,18 +823,43 @@
 				break;
 			}
 
+			/* 
+			 * We got a SCSI SMART event, we just log the relevant
+			 * information and let the user decide what they want
+			 * to do with the information.
+			 */
+			case I2O_EVT_IND_BSA_SCSI_SMART:
+			{
+				char buf[16];
+				printk(KERN_INFO "I2O Block: %s received a SCSI SMART Event\n",i2ob_dev[unit].i2odev->dev_name);
+				evt_local->data[16]='\0';
+				sprintf(buf,"%s",&evt_local->data[0]);
+				printk(KERN_INFO "      Disk Serial#:%s\n",buf);
+				printk(KERN_INFO "      ASC 0x%02x \n",evt_local->ASC);
+				printk(KERN_INFO "      ASCQ 0x%02x \n",evt_local->ASCQ);
+				break;
+			}
+		
+			/*
+			 *	Non event
+			 */
+			 
+			case 0:
+				break;
+				
 			/*
 			 * An event we didn't ask for.  Call the card manufacturer
 			 * and tell them to fix their firmware :)
 			 */
 			default:
-				printk(KERN_INFO "%s: Received event we didn't register for\n"
-					KERN_INFO "   Call I2O card manufacturer\n", 
-					i2ob_dev[unit].i2odev->dev_name);
+				printk(KERN_INFO "%s: Received event %d we didn't register for\n"
+					KERN_INFO "   Blame the I2O card manufacturer 8)\n", 
+					i2ob_dev[unit].i2odev->dev_name, evt);
 				break;
 		}
 	};
 
+	up_and_exit(&i2ob_thread_dead,0);
 	return 0;
 }
 
@@ -724,6 +897,34 @@
 	spin_unlock_irqrestore(&io_request_lock,flags);
 }
 
+static int i2ob_backlog_request(struct i2o_controller *c, struct i2ob_device *dev)
+{
+	u32 m;
+	struct i2ob_request *ireq;
+	
+	while((ireq=i2ob_backlog[c->unit])!=NULL)
+	{
+		int unit;
+
+		if(atomic_read(&i2ob_queues[c->unit]->queue_depth) > dev->depth/4)
+			break;
+
+		m = i2ob_get(dev);
+		if(m == 0xFFFFFFFF)
+			break;
+
+		i2ob_backlog[c->unit] = ireq->next;
+		if(i2ob_backlog[c->unit] == NULL)
+			i2ob_backlog_tail[c->unit] = NULL;
+			
+		unit = MINOR(ireq->req->rq_dev);
+		i2ob_send(m, dev, ireq, i2ob[unit].start_sect, unit);
+	}
+	if(i2ob_backlog[c->unit])
+		return 1;
+	return 0;
+}
+
 /*
  *	The I2O block driver is listed as one of those that pulls the
  *	front entry off the queue before processing it. This is important
@@ -731,6 +932,7 @@
  *	on us. We must unlink CURRENT in this routine before we return, if
  *	we use it.
  */
+
 static void i2ob_request(request_queue_t *q)
 {
 	struct request *req;
@@ -738,9 +940,8 @@
 	int unit;
 	struct i2ob_device *dev;
 	u32 m;
-
-	// printk(KERN_INFO "i2ob_request() called with queue %p\n", q);
-
+	
+	
 	while (!list_empty(&q->queue_head)) {
 		/*
 		 *	On an IRQ completion if there is an inactive
@@ -760,9 +961,16 @@
 		 *	generic IOP commit control. Certainly its not right 
 		 *	its global!  
 		 */
-		if(atomic_read(&i2ob_queues[dev->unit]->queue_depth)>=MAX_I2OB_DEPTH)
+		if(atomic_read(&i2ob_queues[dev->unit]->queue_depth) >= dev->depth)
 			break;
+		
+		/*
+		 *	Is the channel constipated ?
+		 */
 
+		if(i2ob_backlog[dev->unit]!=NULL)
+			break;
+			
 		/* Get a message */
 		m = i2ob_get(dev);
 
@@ -773,7 +981,7 @@
 			 */
 			if (!i2ob_timer_started)
 			{
-				printk(KERN_ERR "i2ob: starting timer\n");
+				DEBUG((KERN_ERR "i2ob: starting timer\n"));
 
 				/*
 				 * Set the timer_started flag to insure
@@ -795,6 +1003,7 @@
 				 */
 				 
 				add_timer(&i2ob_timer);
+				return;
 			}
 		}
 
@@ -804,7 +1013,7 @@
 		req->errors = 0;
 		blkdev_dequeue_request(req);	
 		req->sem = NULL;
-
+		
 		ireq = i2ob_queues[dev->unit]->i2ob_qhead;
 		i2ob_queues[dev->unit]->i2ob_qhead = ireq->next;
 		ireq->req = req;
@@ -892,13 +1101,7 @@
 	for( i = 15; i>=0 ; i--)
 	{
 		int m = minor+i;
-		kdev_t d = MKDEV(MAJOR_NR, m);
-		struct super_block *sb = get_super(d);
-		
-		sync_dev(d);
-		if(sb)
-			invalidate_inodes(sb);
-		invalidate_buffers(d);
+		invalidate_device(MKDEV(MAJOR_NR, m), 1);
 		i2ob_gendisk.part[m].start_sect = 0;
 		i2ob_gendisk.part[m].nr_sects = 0;
 	}
@@ -1009,7 +1212,8 @@
 		msg[2] = i2ob_context|0x40000000;
 		msg[3] = (u32)query_done;
 		msg[4] = 60<<16;
-		i2o_post_wait(dev->controller, msg, 20, 2);
+		DEBUG("Flushing...");
+		i2o_post_wait(dev->controller, msg, 20, 60);
 
 		/*
 		 *	Unlock the media
@@ -1019,14 +1223,18 @@
 		msg[2] = i2ob_context|0x40000000;
 		msg[3] = (u32)query_done;
 		msg[4] = -1;
+		DEBUG("Unlocking...");
 		i2o_post_wait(dev->controller, msg, 20, 2);
+		DEBUG("Unlocked.\n");
 	
 		/*
  		 * Now unclaim the device.
 		 */
+
 		if (i2o_release_device(dev->i2odev, &i2o_block_handler))
 			printk(KERN_ERR "i2ob_release: controller rejected unclaim.\n");
-
+		
+		DEBUG("Unclaim\n");
 	}
 	MOD_DEC_USE_COUNT;
 	return 0;
@@ -1055,12 +1263,14 @@
 	{ 
 		u32 msg[6];
 		
+		DEBUG("Claim ");
 		if(i2o_claim_device(dev->i2odev, &i2o_block_handler))
 		{
 			dev->refcnt--;
 			printk(KERN_INFO "I2O Block: Could not open device\n");
 			return -EBUSY;
 		}
+		DEBUG("Claimed ");
 		
 		/*
 		 *	Mount the media if needed. Note that we don't use
@@ -1072,6 +1282,7 @@
 		msg[1] = I2O_CMD_BLOCK_MMOUNT<<24|HOST_TID<<12|dev->tid;
 		msg[4] = -1;
 		msg[5] = 0;
+		DEBUG("Mount ");
 		i2o_post_wait(dev->controller, msg, 24, 2);
 
 		/*
@@ -1080,7 +1291,9 @@
 		msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
 		msg[1] = I2O_CMD_BLOCK_MLOCK<<24|HOST_TID<<12|dev->tid;
 		msg[4] = -1;
+		DEBUG("Lock ");
 		i2o_post_wait(dev->controller, msg, 20, 2);
+		DEBUG("Ready.\n");
 	}		
 	MOD_INC_USE_COUNT;
 	return 0;
@@ -1132,7 +1345,8 @@
 	i2ob_query_device(dev, 0x0000, 5, &flags, 4);
 	i2ob_query_device(dev, 0x0000, 6, &status, 4);
 	i2ob_sizes[unit] = (int)(size>>10);
-	i2ob_hardsizes[unit] = blocksize;
+	for(i=unit; i <= unit+15 ; i++)
+		i2ob_hardsizes[i] = blocksize;
 	i2ob_gendisk.part[unit].nr_sects = size>>9;
 	i2ob[unit].nr_sects = (int)(size>>9);
 
@@ -1143,20 +1357,33 @@
 	/*
 	 * Max number of Scatter-Gather Elements
 	 */	
-	i2ob_dev[unit].max_segments = 
-		(d->controller->status_block->inbound_frame_size - 8)/2;
 
-	printk(KERN_INFO "Max Segments set to %d\n", 
-				i2ob_dev[unit].max_segments);
-	printk(KERN_INFO "Byte limit is %d.\n", limit);
-	
 	for(i=unit;i<=unit+15;i++)
 	{
-		i2ob_max_sectors[i]=MAX_SECTORS;
-		i2ob_dev[i].max_segments = 
-			(d->controller->status_block->inbound_frame_size - 8)/2;
+		if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy)
+		{
+			i2ob_max_sectors[i] = 32;
+			i2ob_dev[i].max_segments = 8;
+			i2ob_dev[i].depth = 4;
+		}
+		else if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.short_req)
+		{
+			i2ob_max_sectors[i] = 8;
+			i2ob_dev[i].max_segments = 8;
+		}
+		else
+		{
+			/* MAX_SECTORS was used but 255 is a dumb number for
+			   striped RAID */
+			i2ob_max_sectors[i]=256;
+			i2ob_dev[i].max_segments = (d->controller->status_block->inbound_frame_size - 8)/2;
+		}
 	}
 
+	printk(KERN_INFO "Max segments set to %d\n", 
+				i2ob_dev[unit].max_segments);
+	printk(KERN_INFO "Byte limit is %d.\n", limit);
+
 	i2ob_query_device(dev, 0x0000, 0, &type, 1);
 	
 	sprintf(d->dev_name, "%s%c", i2ob_gendisk.major_name, 'a' + (unit>>4));
@@ -1190,6 +1417,7 @@
 			printk(", %dMb cache", cachesize>>10);
 		else
 			printk(", %dKb cache", cachesize);
+		
 	}
 	printk(".\n");
 	printk(KERN_INFO "%s: Maximum sectors/read set to %d.\n", 
@@ -1277,53 +1505,94 @@
 /*
  * Probe the I2O subsytem for block class devices
  */
-static void i2ob_probe(void)
+static void i2ob_scan(int bios)
 {
 	int i;
-	int unit = 0;
 	int warned = 0;
+
+	struct i2o_device *d, *b=NULL;
+	struct i2o_controller *c;
+	struct i2ob_device *dev;
 		
 	for(i=0; i< MAX_I2O_CONTROLLERS; i++)
 	{
-		struct i2o_controller *c=i2o_find_controller(i);
-		struct i2o_device *d;
+		c=i2o_find_controller(i);
 	
 		if(c==NULL)
 			continue;
 
-		for(d=c->devices;d!=NULL;d=d->next)
-		{
+	/*
+	 *    The device list connected to the I2O Controller is doubly linked
+	 * Here we traverse the end of the list , and start claiming devices
+	 * from that end. This assures that within an I2O controller atleast
+	 * the newly created volumes get claimed after the older ones, thus
+	 * mapping to same major/minor (and hence device file name) after 
+	 * every reboot.
+	 * The exception being: 
+	 * 1. If there was a TID reuse.
+	 * 2. There was more than one I2O controller. 
+	 */
+
+	if(!bios)
+	{
+		for (d=c->devices;d!=NULL;d=d->next)
+		if(d->next == NULL)
+			b = d;
+	}
+	else
+		b = c->devices;
+
+	while(b != NULL)
+	{
+		d=b;
+		if(bios)
+			b = b->next;
+		else
+			b = b->prev;
+
 			if(d->lct_data.class_id!=I2O_CLASS_RANDOM_BLOCK_STORAGE)
 				continue;
 
 			if(d->lct_data.user_tid != 0xFFF)
 				continue;
 
+			if(bios)
+			{
+				if(d->lct_data.bios_info != 0x80)
+					continue;
+				printk(KERN_INFO "Claiming as Boot device: Controller %d, TID %d\n", c->unit, d->lct_data.tid);
+			}
+			else
+			{
+				if(d->lct_data.bios_info == 0x80)
+					continue; /*Already claimed on pass 1 */
+			}
+
 			if(i2o_claim_device(d, &i2o_block_handler))
 			{
 				printk(KERN_WARNING "i2o_block: Controller %d, TID %d\n", c->unit,
 					d->lct_data.tid);
-				printk(KERN_WARNING "\tDevice refused claim! Skipping installation\n");
+				printk(KERN_WARNING "\t%sevice refused claim! Skipping installation\n", bios?"Boot d":"D");
 				continue;
 			}
 
-			if(unit<MAX_I2OB<<4)
+			if(scan_unit<MAX_I2OB<<4)
 			{
  				/*
 				 * Get the device and fill in the
 				 * Tid and controller.
 				 */
-				struct i2ob_device *dev=&i2ob_dev[unit];
+				dev=&i2ob_dev[scan_unit];
 				dev->i2odev = d; 
 				dev->controller = c;
 				dev->unit = c->unit;
 				dev->tid = d->lct_data.tid;
 
-				if(i2ob_install_device(c,d,unit))
+				if(i2ob_install_device(c,d,scan_unit))
 					printk(KERN_WARNING "Could not install I2O block device\n");
 				else
 				{
-					unit+=16;
+					scan_unit+=16;
 					i2ob_dev_count++;
 
 					/* We want to know when device goes away */
@@ -1333,7 +1602,7 @@
 			else
 			{
 				if(!warned++)
-					printk(KERN_WARNING "i2o_block: too many device, registering only %d.\n", unit>>4);
+					printk(KERN_WARNING "i2o_block: too many device, registering only %d.\n", scan_unit>>4);
 			}
 			i2o_release_device(d, &i2o_block_handler);
 		}
@@ -1341,6 +1610,31 @@
 	}
 }
 
+static void i2ob_probe(void)
+{
+	/*
+	 *      Some overhead/redundancy involved here, while trying to
+	 *      claim the first boot volume encountered as /dev/i2o/hda
+	 *      everytime. All the i2o_controllers are searched and the
+	 *      first i2o block device marked as bootable is claimed
+	 *      If an I2O block device was booted off , the bios sets
+	 *      its bios_info field to 0x80, this what we search for.
+	 *      Assuming that the bootable volume is /dev/i2o/hda
+	 *      everytime will prevent any kernel panic while mounting
+	 *      root partition
+	 */
+
+	printk(KERN_INFO "i2o_block: Checking for Boot device...\n");
+	i2ob_scan(1);
+
+	/*
+	 *      Now the remainder.
+	 */
+	printk(KERN_INFO "i2o_block: Checking for I2O Block devices...\n");
+	i2ob_scan(0);
+}
+
+
 /*
  * New device notification handler.  Called whenever a new
  * I2O block storage device is added to the system.
@@ -1369,14 +1663,6 @@
 			break;
 	}
 
-	/*
-	 * Creating a RAID 5 volume takes a little while and the UTIL_CLAIM
-	 * will fail if we don't give the card enough time to do it's magic, 
-	 * so we just sleep for a little while and let it do it's thing
-	 */
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(3*HZ);
-
 	if(i2o_claim_device(d, &i2o_block_handler))
 	{
 		printk(KERN_INFO 
@@ -1435,6 +1721,7 @@
 	if(unit >= MAX_I2OB<<4)
 	{
 		printk(KERN_ERR "i2ob_del_device called, but not in dev table!\n");
+		spin_unlock_irqrestore(&io_request_lock, flags);
 		return;
 	}
 
@@ -1492,8 +1779,6 @@
 	i2ob_media_change_flag[unit] = 1;
 
 	i2ob_dev_count--;	
-
-	return;
 }
 
 /*
@@ -1540,8 +1825,11 @@
 			msg[2] = i2ob_context|0x40000000;
 			msg[3] = (u32)query_done;
 			msg[4] = 60<<16;
-			i2o_post_wait(dev->controller, msg, 20, 2);
+			
+			DEBUG("Flushing...");
+			i2o_post_wait(dev->controller, msg, 20, 60);
 
+			DEBUG("Unlocking...");
 			/*
 			 *	Unlock the media
 			 */
@@ -1551,20 +1839,21 @@
 			msg[3] = (u32)query_done;
 			msg[4] = -1;
 			i2o_post_wait(dev->controller, msg, 20, 2);
+			
+			DEBUG("Unlocked.\n");
 		}
 	}	
 }
 
 static struct block_device_operations i2ob_fops =
 {
-   open:       i2ob_open,
-   release:    i2ob_release,
-   ioctl:         i2ob_ioctl,
-   check_media_change:  i2ob_media_change,
-   revalidate:    i2ob_revalidate,
+	open:			i2ob_open,
+	release:		i2ob_release,
+	ioctl:			i2ob_ioctl,
+	check_media_change:	i2ob_media_change,
+	revalidate:		i2ob_revalidate,
 };
 
-
 static struct gendisk i2ob_gendisk = 
 {
 	MAJOR_NR,
@@ -1573,9 +1862,10 @@
 	1<<4,
 	i2ob,
 	i2ob_sizes,
-	0,
+	MAX_I2OB,
+	NULL,
 	NULL,
-	NULL
+	&i2ob_fops,
 };
 
 
@@ -1593,7 +1883,7 @@
 	int i;
 
 	printk(KERN_INFO "I2O Block Storage OSM v0.9\n");
-	printk(KERN_INFO "   (c) Copyright 1999, 2000 Red Hat Software.\n");
+	printk(KERN_INFO "   (c) Copyright 1999-2001 Red Hat Software.\n");
 	
 	/*
 	 *	Register the block device interfaces
@@ -1629,6 +1919,7 @@
 		i2ob_dev[i].tid = 0;
 		i2ob_dev[i].head = NULL;
 		i2ob_dev[i].tail = NULL;
+		i2ob_dev[i].depth = MAX_I2OB_DEPTH;
 		i2ob_blksizes[i] = 1024;
 		i2ob_max_sectors[i] = 2;
 	}
@@ -1683,7 +1974,13 @@
 		register_disk(&i2ob_gendisk, MKDEV(MAJOR_NR,i<<4), 1<<4,
 			&i2ob_fops, 0);
 	i2ob_probe();
-	
+
+	/*
+	 *	Adding i2ob_gendisk into the gendisk list.
+	 */	
+	i2ob_gendisk.next = gendisk_head;
+	gendisk_head = &i2ob_gendisk;
+
 	return 0;
 }
 
@@ -1695,9 +1992,20 @@
 
 void cleanup_module(void)
 {
-	struct gendisk **gdp;
+	struct gendisk *gdp;
 	int i;
 	
+	if(evt_running) {
+		printk(KERN_INFO "Killing I2O block threads...");
+		i = kill_proc(evt_pid, SIGTERM, 1);
+		if(!i) {
+			printk("waiting...");
+		}
+		/* Be sure it died */
+		down(&i2ob_thread_dead);
+		printk("done.\n");
+	}
+
 	/*
 	 * Unregister for updates from any devices..otherwise we still
 	 * get them and the core jumps to random memory :O
@@ -1713,6 +2021,18 @@
 	}
 	
 	/*
+	 *	We may get further callbacks for ourself. The i2o_core
+	 *	code handles this case reasonably sanely. The problem here
+	 *	is we shouldn't get them .. but a couple of cards feel 
+	 *	obliged to tell us stuff we dont care about.
+	 *
+	 *	This isnt ideal at all but will do for now.
+	 */
+	 
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(HZ);
+	
+	/*
 	 *	Flush the OSM
 	 */
 
@@ -1729,28 +2049,20 @@
 	 */
 	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
 
-	if(evt_running) {
-		i = kill_proc(evt_pid, SIGTERM, 1);
-		if(!i) {
-			int count = 5 * 100;
-			while(evt_running && --count) {
-				current->state = TASK_INTERRUPTIBLE;
-				schedule_timeout(1);
-			}
-	
-			if(!count)
-				printk(KERN_ERR "Giving up on i2oblock thread...\n");	
-		}
-	}
-
-
 	/*
 	 *	Why isnt register/unregister gendisk in the kernel ???
 	 */
 
-	for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-		if (*gdp == &i2ob_gendisk)
-			break;
-
+	if (gendisk_head == &i2ob_gendisk) {
+		gendisk_head = i2ob_gendisk.next;
+		}
+	else {
+		for (gdp = gendisk_head; gdp; gdp = gdp->next)
+			if (gdp->next == &i2ob_gendisk)
+			{
+				gdp->next = i2ob_gendisk.next;
+				break;
+			}
+	}
 }
 #endif
diff -u --recursive --new-file v2.4.4/linux/drivers/i2o/i2o_config.c linux/drivers/i2o/i2o_config.c
--- v2.4.4/linux/drivers/i2o/i2o_config.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/i2o/i2o_config.c	Tue May  1 16:10:37 2001
@@ -42,7 +42,6 @@
 
 static int i2o_cfg_context = -1;
 static void *page_buf;
-static void *i2o_buffer;
 static spinlock_t i2o_config_lock = SPIN_LOCK_UNLOCKED;
 struct wait_queue *i2o_wait_queue;
 
@@ -499,6 +498,7 @@
 	if(!res)
 	{
 		i2o_unlock_controller(c);
+		kfree(query);
 		return -ENOMEM;
 	}
 
@@ -517,16 +517,25 @@
 		msg[7] = 0xD4000000|(kcmd.qlen);
 		msg[8] = virt_to_bus(query);
 	}
-
-	token = i2o_post_wait(c, msg, 9*4, 10);
-	if(token)
+	/*
+	Wait for a considerable time till the Controller 
+	does its job before timing out. The controller might
+	take more time to process this request if there are
+	many devices connected to it.
+	*/
+	token = i2o_post_wait_mem(c, msg, 9*4, 400, query, res);
+	if(token < 0)
 	{
 		printk(KERN_DEBUG "token = %#10x\n", token);
 		i2o_unlock_controller(c);
-		kfree(res);
-		if(kcmd.qlen) kfree(query);
+		
+		if(token != -ETIMEDOUT)
+		{
+			kfree(res);
+			if(kcmd.qlen) kfree(query);
+		}
 
-		return -ETIMEDOUT;
+		return token;
 	}
 	i2o_unlock_controller(c);
 
@@ -595,17 +604,18 @@
 	msg[8]= virt_to_bus(buffer);
 
 //	printk("i2o_config: swdl frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
-	status = i2o_post_wait(c, msg, sizeof(msg), 60);
+	status = i2o_post_wait_mem(c, msg, sizeof(msg), 60, buffer, NULL);
 
 	i2o_unlock_controller(c);
-	kfree(buffer);
+	if(status != -ETIMEDOUT)
+		kfree(buffer);
 	
 	if (status != I2O_POST_WAIT_OK)
 	{
 		// it fails if you try and send frags out of order
 		// and for some yet unknown reasons too
 		printk(KERN_INFO "i2o_config: swdl failed, DetailedStatus = %d\n", status);
-		return -ETIMEDOUT;
+		return status;
 	}
 
 	return 0;
@@ -660,14 +670,15 @@
 	msg[8]= virt_to_bus(buffer);
 	
 //	printk("i2o_config: swul frag %d/%d (size %d)\n", curfrag, maxfrag, fragsize);
-	status = i2o_post_wait(c, msg, sizeof(msg), 60);
+	status = i2o_post_wait_mem(c, msg, sizeof(msg), 60, buffer, NULL);
 	i2o_unlock_controller(c);
 	
 	if (status != I2O_POST_WAIT_OK)
 	{
-		kfree(buffer);
+		if(status != -ETIMEDOUT)
+			kfree(buffer);
 		printk(KERN_INFO "i2o_config: swul failed, DetailedStatus = %d\n", status);
-		return -ETIMEDOUT;
+		return status;
 	}
 	
 	__copy_to_user(kxfer.buf, buffer, fragsize);
@@ -787,13 +798,6 @@
 	struct i2o_evt_get kget;
 	unsigned int flags;
 
-	// access_ok doesn't check for NULL?!?!
-	if(!arg)
-		return -EFAULT;
-	
-	if(!access_ok(VERIFY_WRITE, uget,  sizeof(struct i2o_evt_get)))
-		return -EFAULT;
-
 	for(p = open_files; p; p = p->next)
 		if(p->q_id == id)
 			break;
@@ -812,8 +816,8 @@
 	kget.lost = p->q_lost;
 	spin_unlock_irqrestore(&i2o_config_lock, flags);
 
-	__copy_to_user(uget, &kget, sizeof(struct i2o_evt_get));
-
+	if(copy_to_user(uget, &kget, sizeof(struct i2o_evt_get)))
+		return -EFAULT;
 	return 0;
 }
 
@@ -958,8 +962,6 @@
 		kfree(page_buf);
 	if(i2o_cfg_context != -1)
 		i2o_remove_handler(&cfg_handler);
-	if(i2o_buffer)
-		kfree(i2o_buffer);
 }
  
 EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.4/linux/drivers/i2o/i2o_core.c linux/drivers/i2o/i2o_core.c
--- v2.4.4/linux/drivers/i2o/i2o_core.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/i2o/i2o_core.c	Tue May  1 16:10:37 2001
@@ -1,5 +1,5 @@
-/* 
- * Core I2O structure managment 
+/*
+ * Core I2O structure management 
  * 
  * (C) Copyright 1999   Red Hat Software 
  *
@@ -49,7 +49,7 @@
 
 #include "i2o_lan.h"
 
-// #define DRIVERDEBUG
+//#define DRIVERDEBUG
 
 #ifdef DRIVERDEBUG
 #define dprintk(s, args...) printk(s, ## args)
@@ -147,10 +147,12 @@
  */ 
 struct i2o_post_wait_data
 {
-	int status;
-	u32 id;
-	wait_queue_head_t *wq;
-	struct i2o_post_wait_data *next;
+	int *status;		/* Pointer to status block on caller stack */
+	int *complete;		/* Pointer to completion flag on caller stack */
+	u32 id;			/* Unique identifier */
+	wait_queue_head_t *wq;	/* Wake up for caller (NULL for dead) */
+	struct i2o_post_wait_data *next;	/* Chain */
+	void *mem[2];		/* Memory blocks to recover on failure path */
 };
 static struct i2o_post_wait_data *post_wait_queue = NULL;
 static u32 post_wait_id = 0;	// Unique ID for each post_wait
@@ -169,10 +171,10 @@
 	I2O_CLASS_EXECUTIVE
 };
 
-
 /*
- * Used when queing a reply to be handled later
+ * Used when queueing a reply to be handled later
  */
+ 
 struct reply_info
 {
 	struct i2o_controller *iop;
@@ -199,10 +201,12 @@
 static spinlock_t i2o_evt_lock = SPIN_LOCK_UNLOCKED;
 
 /*
- * Semaphore used to syncrhonize event handling thread with 
+ * Semaphore used to synchronize event handling thread with 
  * interrupt handler.
  */
-DECLARE_MUTEX(evt_sem);
+ 
+static DECLARE_MUTEX(evt_sem);
+static DECLARE_MUTEX_LOCKED(evt_dead);
 DECLARE_WAIT_QUEUE_HEAD(evt_wait);
 
 static struct notifier_block i2o_reboot_notifier =
@@ -212,6 +216,12 @@
         0
 };
 
+/*
+ *	Config options
+ */
+
+static int verbose = 0;
+MODULE_PARM(verbose, "i");
 
 /*
  * I2O Core reply handler
@@ -252,7 +262,7 @@
 	if(msg[2]&0x80000000)	// Post wait message
 	{
 		if (msg[4] >> 24)
-			status = -(msg[4] & 0xFFFF);
+			status = (msg[4] & 0xFFFF);
 		else
 			status = I2O_POST_WAIT_OK;
 	
@@ -369,6 +379,9 @@
 	d->controller=c;
 	d->owner=NULL;
 	d->next=c->devices;
+	d->prev=NULL;
+	if (c->devices != NULL)
+		c->devices->prev=d;
 	c->devices=d;
 	*d->dev_name = 0;
 
@@ -696,7 +709,7 @@
 {
 	down(&i2o_configuration_lock);
 	if (d->owner) {
-		printk(KERN_INFO "Device claim called, but dev allready owned by %s!",
+		printk(KERN_INFO "Device claim called, but dev already owned by %s!",
 		       h->name);
 		up(&i2o_configuration_lock);
 		return -EBUSY;
@@ -721,37 +734,59 @@
  *	Drop a claim by an OSM on a given I2O device. The handler is cleared
  *	and 0 is returned on success.
  *
+ *	AC - some devices seem to want to refuse an unclaim until they have
+ *	finished internal processing. It makes sense since you don't want a
+ *	new device to go reconfiguring the entire system until you are done.
+ *	Thus we are prepared to wait briefly.
  */
 
 int i2o_release_device(struct i2o_device *d, struct i2o_handler *h)
 {
 	int err = 0;
+	int tries;
 
 	down(&i2o_configuration_lock);
 	if (d->owner != h) {
-		printk(KERN_INFO "Claim release called, but not owned by %s!",
+		printk(KERN_INFO "Claim release called, but not owned by %s!\n",
 		       h->name);
 		up(&i2o_configuration_lock);
 		return -ENOENT;
 	}	
 
-	d->owner = NULL;
-
-	if(i2o_issue_claim(I2O_CMD_UTIL_RELEASE, d->controller, d->lct_data.tid, 
-			   I2O_CLAIM_PRIMARY))
+	for(tries=0;tries<10;tries++)
 	{
-		err = -ENXIO;
-		d->owner = h;
-	}
+		d->owner = NULL;
 
+		/*
+		 *	If the controller takes a nonblocking approach to
+		 *	releases we have to sleep/poll for a few times.
+		 */
+		 
+		if((err=i2o_issue_claim(I2O_CMD_UTIL_RELEASE, d->controller, d->lct_data.tid, I2O_CLAIM_PRIMARY)) )
+		{
+			err = -ENXIO;
+			current->state = TASK_UNINTERRUPTIBLE;
+			schedule_timeout(HZ);
+		}
+		else
+		{
+			err=0;
+			break;
+		}
+	}
 	up(&i2o_configuration_lock);
 	return err;
 }
 
-/*
- * Called by OSMs to let the core know that they want to be
- * notified if the given device is deleted from the system.
+/**
+ * 	i2o_device_notify_on	-	Enable deletion notifiers
+ *	@d: device for notification
+ *	@h: handler to install
+ *
+ *	Called by OSMs to let the core know that they want to be
+ *	notified if the given device is deleted from the system.
  */
+
 int i2o_device_notify_on(struct i2o_device *d, struct i2o_handler *h)
 {
 	int i;
@@ -773,7 +808,11 @@
 	return 0;
 }
 
-/*
+/**
+ * 	i2o_device_notify_off	-	Remove deletion notifiers
+ *	@d: device for notification
+ *	@h: handler to remove
+ *
  * Called by OSMs to let the core know that they no longer
  * are interested in the fate of the given device.
  */
@@ -794,9 +833,18 @@
 	return -ENOENT;
 }
 
-/*
- * Event registration API
+/**
+ *	i2o_event_register	-	register interest in an event
+ * 	@c: Controller to register interest with
+ *	@tid: I2O task id
+ *	@init_context: initiator context to use with this notifier
+ *	@tr_context: transaction context to use with this notifier
+ *	@evt_mask: mask of events
+ *
+ *	Create and posts an event registration message to the task. No reply
+ *	is waited for, or expected. Errors in posting will be reported.
  */
+ 
 int i2o_event_register(struct i2o_controller *c, u32 tid, 
 		u32 init_context, u32 tr_context, u32 evt_mask)
 {
@@ -814,11 +862,13 @@
 }
 
 /*
- * Event ack API
+ * 	i2o_event_ack	-	acknowledge an event
+ *	@c: controller 
+ *	@msg: pointer to the UTIL_EVENT_REGISTER reply we received
  *
- * We just take a pointer to the original UTIL_EVENT_REGISTER reply
- * message and change the function code since that's what spec
- * describes an EventAck message looking like.
+ *	We just take a pointer to the original UTIL_EVENT_REGISTER reply
+ *	message and change the function code since that's what spec
+ *	describes an EventAck message looking like.
  */
  
 int i2o_event_ack(struct i2o_controller *c, u32 *msg)
@@ -850,12 +900,12 @@
 
 	while(1)
 	{
-		down_interruptible(&evt_sem);
-		if(signal_pending(current))
+		if(down_interruptible(&evt_sem))
 		{
 			dprintk(KERN_INFO "I2O event thread dead\n");
+			printk("exiting...");
 			evt_running = 0;
-			return 0;	
+			up_and_exit(&evt_dead, 0);
 		}
 
 		/* 
@@ -922,6 +972,10 @@
 					kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
 				int i;
 
+				if (d == NULL) {
+					printk(KERN_EMERG "i2oevtd: out of memory\n");
+					break;
+				}
 				memcpy(&d->lct_data, &msg[5], sizeof(i2o_lct_entry));
 	
 				d->next = NULL;
@@ -974,7 +1028,11 @@
 				printk(KERN_WARNING "%s: Warning notification received!"
 					"Check configuration for errors!\n", c->name);
 				break;
-	
+				
+			case I2O_EVT_IND_EVT_MASK_MODIFIED:
+				/* Well I guess that was us hey .. */
+				break;
+					
 			default:
 				printk(KERN_WARNING "%s: No handler for event (0x%08x)\n", c->name, msg[4]);
 				break;
@@ -1124,12 +1182,6 @@
 		m=(struct i2o_message *)bus_to_virt(mv);
 		msg=(u32*)m;
 
-		/*
-		 *	Temporary Debugging
-		 */
-		if(m->function==0x15)
-			printk(KERN_ERR "%s: UTFR!\n", c->name);
-
 		i=i2o_handlers[m->initiator_context&(MAX_I2O_MODULES-1)];
 		if(i && i->reply)
 			i->reply(i,c,m);
@@ -1219,9 +1271,9 @@
 
 
 /**
- *	i2o_wait_message
+ *	i2o_wait_message	-	obtain an i2o message from the IOP
  *	@c: controller
- *	@why: explanation
+ *	@why: explanation 
  *
  *	This function waits up to 5 seconds for a message slot to be
  *	available. If no message is available it prints an error message
@@ -1266,9 +1318,11 @@
 	char str[22];
 	int ret;
 	int unit = d->lct_data.tid;
-	
-	printk(KERN_INFO "Target ID %d.\n", unit);
 
+	if(verbose==0)
+		return;
+		
+	printk(KERN_INFO "Target ID %d.\n", unit);
 	if((ret=i2o_query_scalar(c, unit, 0xF100, 3, buf, 16))>=0)
 	{
 		buf[16]=0;
@@ -1279,13 +1333,11 @@
 		buf[16]=0;
 		printk(KERN_INFO "     Device: %s\n", buf);
 	}
-#if 0
 	if(i2o_query_scalar(c, unit, 0xF100, 5, buf, 16)>=0)
 	{
 		buf[16]=0;
 		printk(KERN_INFO "     Description: %s\n", buf);
 	}
-#endif	
 	if((ret=i2o_query_scalar(c, unit, 0xF100, 6, buf, 8))>=0)
 	{
 		buf[8]=0;
@@ -1581,7 +1633,7 @@
 
 
 /**
- *	i2o_reset_controller
+ *	i2o_reset_controller	-	reset an IOP
  *	@c: controller to reset
  *
  *	Reset the IOP into INIT state and wait until IOP gets into RESET state.
@@ -1601,7 +1653,10 @@
 	/* Quiesce all IOPs first */
 
 	for (iop = i2o_controller_chain; iop; iop = iop->next)
-		i2o_quiesce_controller(iop);
+	{
+		if(iop->type != I2O_TYPE_PCI || !iop->bus.pci.dpt)
+			i2o_quiesce_controller(iop);
+	}
 
 	m=i2o_wait_message(c, "AdapterReset");
 	if(m==0xFFFFFFFF)	
@@ -1628,19 +1683,19 @@
 
 	/* Wait for a reply */
 	time=jiffies;
-	while(status[0]==0)
+	while(*status==0)
 	{
 		if((jiffies-time)>=20*HZ)
 		{
 			printk(KERN_ERR "IOP reset timeout.\n");
-			kfree(status);
+			// Better to leak this for safety: kfree(status);
 			return -ETIMEDOUT;
 		}
 		schedule();
 		barrier();
 	}
 
-	if (status[0]==I2O_CMD_IN_PROGRESS)
+	if (*status==I2O_CMD_IN_PROGRESS)
 	{ 
 		/* 
 		 * Once the reset is sent, the IOP goes into the INIT state 
@@ -1799,7 +1854,7 @@
 	u32 msg[6];
 	int ret, size = sizeof(i2o_hrt);
 
-	/* Read first just the header to figure out the real size */
+	/* First read just the header to figure out the real size */
 
 	do  {
 		if (c->hrt == NULL) {
@@ -1816,7 +1871,18 @@
 		msg[4]= (0xD0000000 | size);	/* Simple transaction */
 		msg[5]= virt_to_bus(c->hrt);	/* Dump it here */
 
-		if ((ret = i2o_post_wait(c, msg, sizeof(msg), 20))) {
+		ret = i2o_post_wait_mem(c, msg, sizeof(msg), 20, c->hrt, NULL);
+		
+		if(ret == -ETIMEDOUT)
+		{
+			/* The HRT block we used is in limbo somewhere. When the iop wakes up
+			   we will recover it */
+			c->hrt = NULL;
+			return ret;
+		}
+		
+		if(ret<0)
+		{
 			printk(KERN_ERR "%s: Unable to get HRT (status=%#x)\n",
 				c->name, -ret);	
 			return ret;
@@ -1845,14 +1911,15 @@
 static int i2o_systab_send(struct i2o_controller *iop)
 {
 	u32 msg[12];
-	u32 privmem[2];
-	u32 privio[2];
 	int ret;
+	u32 *privbuf = kmalloc(16, GFP_KERNEL);
+	if(privbuf == NULL)
+		return -ENOMEM;
 
-	privmem[0] = iop->status_block->current_mem_base;
-	privmem[1] = iop->status_block->current_mem_size;
-	privio[0] = iop->status_block->current_io_base;
-	privio[1] = iop->status_block->current_io_size;
+	privbuf[0] = iop->status_block->current_mem_base;
+	privbuf[1] = iop->status_block->current_mem_size;
+	privbuf[2] = iop->status_block->current_io_base;
+	privbuf[3] = iop->status_block->current_io_size;
 
 	msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6;
 	msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID;
@@ -1864,20 +1931,33 @@
  	 * Provide three SGL-elements:
  	 * System table (SysTab), Private memory space declaration and 
  	 * Private i/o space declaration  
+ 	 *
+ 	 * FIXME: provide these for controllers needing them
  	 */
 	msg[6] = 0x54000000 | sys_tbl_len;
 	msg[7] = virt_to_bus(sys_tbl);
 	msg[8] = 0x54000000 | 0;
-	msg[9] = virt_to_bus(privmem);
+	msg[9] = virt_to_bus(privbuf);
 	msg[10] = 0xD4000000 | 0;
-	msg[11] = virt_to_bus(privio);
+	msg[11] = virt_to_bus(privbuf+8);
 
-	if ((ret=i2o_post_wait(iop, msg, sizeof(msg), 120)))
-		printk(KERN_INFO "%s: Unable to set SysTab (status=%#x).\n", 
+	ret=i2o_post_wait_mem(iop, msg, sizeof(msg), 120, privbuf, NULL);
+	
+	if(ret==-ETIMEDOUT)
+	{
+		printk(KERN_ERR "%s: SysTab setup timed out.\n", iop->name);
+	}
+	else if(ret<0)
+	{
+		printk(KERN_ERR "%s: Unable to set SysTab (status=%#x).\n", 
 			iop->name, -ret);
+		kfree(privbuf);
+	}
 	else
+	{
 		dprintk(KERN_INFO "%s: SysTab set.\n", iop->name);
-
+		kfree(privbuf);
+	}
 	i2o_status_get(iop); // Entered READY state
 
 	return ret;	
@@ -2162,7 +2242,16 @@
 		msg[6] = 0xD0000000|size;
 		msg[7] = virt_to_bus(c->lct);
 
-		if ((ret=i2o_post_wait(c, msg, sizeof(msg), 120))) {
+		ret=i2o_post_wait_mem(c, msg, sizeof(msg), 120, c->lct, NULL);
+		
+		if(ret == -ETIMEDOUT)
+		{
+			c->lct = NULL;
+			return ret;
+		}
+		
+		if(ret<0)
+		{
 			printk(KERN_ERR "%s: LCT Get failed (status=%#x.\n", 
 				c->name, -ret);	
 			return ret;
@@ -2206,8 +2295,11 @@
 /*
  *	Bring a controller online into OPERATIONAL state. 
  */
+ 
 int i2o_online_controller(struct i2o_controller *iop)
 {
+	u32 v;
+	
 	if (i2o_systab_send(iop) < 0)
 		return -1;
 
@@ -2223,6 +2315,15 @@
 	if (i2o_lct_get(iop) < 0)
 		return -1;
 
+	/* Check battery status */
+	 
+	iop->battery = 0;
+	if(i2o_query_scalar(iop, ADAPTER_TID, 0x0000, 4, &v, 4)>=0)
+	{
+		if(v&16)
+			iop->battery = 1;
+	}
+
 	return 0;
 }
 
@@ -2346,83 +2447,134 @@
 	return 0;
 }
 
-/*
- * This core API allows an OSM to post a message and then be told whether
- * or not the system received a successful reply.  It is useful when
- * the OSM does not want to know the exact 3
+/**
+ * 	i2o_post_wait_mem	-	I2O query/reply with DMA buffers
+ *	@c: controller
+ *	@msg: message to send
+ *	@len: length of message
+ *	@timeout: time in seconds to wait
+ *	@mem1: attached memory buffer 1
+ *	@mem2: attached memory buffer 2
+ *
+ * 	This core API allows an OSM to post a message and then be told whether
+ *	or not the system received a successful reply. 
+ *
+ *	If the message times out then the value '-ETIMEDOUT' is returned. This
+ *	is a special case. In this situation the message may (should) complete
+ *	at an indefinite time in the future. When it completes it will use the
+ *	memory buffers attached to the request. If -ETIMEDOUT is returned then
+ *	the memory buffers must not be freed. Instead the event completion will
+ *	free them for you. In all other cases the buffers are your problem.
+ *
+ *	Pass NULL for unneeded buffers.
  */
-int i2o_post_wait(struct i2o_controller *c, u32 *msg, int len, int timeout)
+ 
+int i2o_post_wait_mem(struct i2o_controller *c, u32 *msg, int len, int timeout, void *mem1, void *mem2)
 {
 	DECLARE_WAIT_QUEUE_HEAD(wq_i2o_post);
-	int status = 0;
+	int complete = 0;
+	int status;
 	int flags = 0;
-	struct i2o_post_wait_data *p1, *p2;
 	struct i2o_post_wait_data *wait_data =
 		kmalloc(sizeof(struct i2o_post_wait_data), GFP_KERNEL);
 
 	if(!wait_data)
 		return -ENOMEM;
 
+	/*
+	 *	Create a new notification object
+	 */
+	wait_data->status = &status;
+	wait_data->complete = &complete;
+	wait_data->mem[0] = mem1;
+	wait_data->mem[1] = mem2;
 	/* 
-	 * The spin locking is needed to keep anyone from playing 
-	 * with the queue pointers and id while we do the same
+	 *	Queue the event with its unique id
 	 */
 	spin_lock_irqsave(&post_wait_lock, flags);
+
 	wait_data->next = post_wait_queue;
 	post_wait_queue = wait_data;
 	wait_data->id = (++post_wait_id) & 0x7fff;
-	spin_unlock_irqrestore(&post_wait_lock, flags);
-
 	wait_data->wq = &wq_i2o_post;
-	wait_data->status = -ETIMEDOUT;
 
+	spin_unlock_irqrestore(&post_wait_lock, flags);
+
+	/*
+	 *	Fill in the message id
+	 */
+	 
 	msg[2] = 0x80000000|(u32)core_context|((u32)wait_data->id<<16);
 	
+	/*
+	 *	Post the message to the controller. At some point later it 
+	 *	will return. If we time out before it returns then
+	 *	complete will be zero.  From the point post_this returns
+	 *	the wait_data may have been deleted.
+	 */
 	if ((status = i2o_post_this(c, msg, len))==0) {
-		interruptible_sleep_on_timeout(&wq_i2o_post, HZ * timeout);
-		status = wait_data->status;
+		sleep_on_timeout(&wq_i2o_post, HZ * timeout);
 	}  
-
-#ifdef DRIVERDEBUG
-	if(status == -ETIMEDOUT)
-		printk(KERN_INFO "%s: POST WAIT TIMEOUT\n",c->name);
-#endif
-
-	/* 
-	 * Remove the entry from the queue.
-	 * Since i2o_post_wait() may have been called again by
-	 * a different thread while we were waiting for this 
-	 * instance to complete, we're not guaranteed that 
-	 * this entry is at the head of the queue anymore, so 
-	 * we need to search for it, find it, and delete it.
-	 */
-	p2 = NULL;
+	else
+		return -EIO;
+		
+	if(signal_pending(current))
+		status = -EINTR;
+		
 	spin_lock_irqsave(&post_wait_lock, flags);
-	for(p1 = post_wait_queue; p1; p2 = p1, p1 = p1->next) {
-		if(p1 == wait_data) {
-			if(p2)
-				p2->next = p1->next;
-			else
-				post_wait_queue = p1->next;
-
-			break;
+	barrier();	/* Be sure we see complete as it is locked */
+	if(!complete)
+	{
+		/* 
+		 *	Mark the entry dead. We cannot remove it. This is important.
+		 *	When it does terminate (which it must do if the controller hasnt
+		 *	died..) then it will otherwise scribble on stuff.
+		 *	!complete lets us safely check if the entry is still
+		 *	allocated and thus we can write into it
+		 */
+		wait_data->wq = NULL;
+		status = -ETIMEDOUT;
+	}
+	else
+	{
+		/* Debugging check - remove me soon */
+		if(status == -ETIMEDOUT)
+		{
+			printk("TIMEDOUT BUG!\n");
+			status = -EIO;
 		}
 	}
+	/* And the wait_data is not leaked either! */	 
 	spin_unlock_irqrestore(&post_wait_lock, flags);
-	
-	kfree(wait_data);
-
 	return status;
 }
 
+/**
+ * 	i2o_post_wait		-	I2O query/reply
+ *	@c: controller
+ *	@msg: message to send
+ *	@len: length of message
+ *	@timeout: time in seconds to wait
+ *
+ * 	This core API allows an OSM to post a message and then be told whether
+ *	or not the system received a successful reply. 
+ */
+ 
+int i2o_post_wait(struct i2o_controller *c, u32 *msg, int len, int timeout)
+{
+	return i2o_post_wait_mem(c, msg, len, timeout, NULL, NULL);
+}
+
 /*
  * i2o_post_wait is completed and we want to wake up the 
  * sleeping proccess. Called by core's reply handler.
  */
+
 static void i2o_post_wait_complete(u32 context, int status)
 {
-	struct i2o_post_wait_data *p1 = NULL;
-
+	struct i2o_post_wait_data **p1, *q;
+	unsigned long flags;
+	
 	/* 
 	 * We need to search through the post_wait 
 	 * queue to see if the given message is still
@@ -2435,18 +2587,49 @@
 	 * Lock needed to keep anyone from moving queue pointers 
 	 * around while we're looking through them.
 	 */
-	spin_lock(&post_wait_lock);
-	for(p1 = post_wait_queue; p1; p1 = p1->next) {
-		if(p1->id == ((context >> 16) & 0x7fff)) {
-			p1->status = status;
-			wake_up_interruptible(p1->wq);
+
+	spin_lock_irqsave(&post_wait_lock, flags);
+
+	for(p1 = &post_wait_queue; *p1!=NULL; p1 = &((*p1)->next)) 
+	{
+		q = (*p1);
+		if(q->id == ((context >> 16) & 0x7fff)) {
+			/*
+			 *	Delete it 
+			 */
+			 
+			*p1 = q->next;
+			
+			/*
+			 *	Live or dead ?
+			 */
+			 
+			if(q->wq)
+			{
+				/* Live entry - wakeup and set status */
+				*q->status = status;
+				*q->complete = 1;
+				wake_up(q->wq);
+			}
+			else
+			{
+				/*
+				 *	Free resources. Caller is dead
+				 */
+				if(q->mem[0])
+					kfree(q->mem[0]);
+				if(q->mem[1])
+					kfree(q->mem[1]);
+				printk(KERN_WARNING "i2o_post_wait event completed after timeout.\n");
+			}
+			kfree(q);
 			spin_unlock(&post_wait_lock);
 			return;
 		}
 	}
 	spin_unlock(&post_wait_lock);
 
-	printk(KERN_DEBUG "i2o_post_wait reply after timeout!\n");
+	printk(KERN_DEBUG "i2o_post_wait: Bogus reply!\n");
 }
 
 /*	Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
@@ -2461,25 +2644,52 @@
                 void *oplist, int oplen, void *reslist, int reslen)
 {
 	u32 msg[9]; 
-	u8 *res = (u8 *)reslist;
 	u32 *res32 = (u32*)reslist;
 	u32 *restmp = (u32*)reslist;
 	int len = 0;
 	int i = 0;
 	int wait_status;
-
+	u32 *opmem, *resmem;
+	
+	/* Get DMAable memory */
+	opmem = kmalloc(oplen, GFP_KERNEL);
+	if(opmem == NULL)
+		return -ENOMEM;
+	memcpy(opmem, oplist, oplen);
+	
+	resmem = kmalloc(reslen, GFP_KERNEL);
+	if(resmem == NULL)
+	{
+		kfree(opmem);
+		return -ENOMEM;
+	}
+	
 	msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;
 	msg[1] = cmd << 24 | HOST_TID << 12 | tid; 
 	msg[3] = 0;
 	msg[4] = 0;
 	msg[5] = 0x54000000 | oplen;	/* OperationList */
-	msg[6] = virt_to_bus(oplist);
+	msg[6] = virt_to_bus(opmem);
 	msg[7] = 0xD0000000 | reslen;	/* ResultList */
-	msg[8] = virt_to_bus(reslist);
+	msg[8] = virt_to_bus(resmem);
 
-	if((wait_status = i2o_post_wait(iop, msg, sizeof(msg), 10)))
-		return wait_status; 	/* -DetailedStatus */
+	wait_status = i2o_post_wait_mem(iop, msg, sizeof(msg), 10, opmem, resmem);
+	
+	/*
+	 *	This only looks like a memory leak - don't "fix" it.	
+	 */
+	if(wait_status == -ETIMEDOUT)
+		return wait_status;
 
+	/* Query failed */
+	if(wait_status != 0)
+	{
+		kfree(resmem);
+		kfree(opmem);
+		return wait_status;
+	}
+	
+	memcpy(reslist, resmem, reslen);
 	/*
 	 * Calculate number of bytes of Result LIST
 	 * We need to loop through each Result BLOCK and grab the length
@@ -2500,13 +2710,13 @@
 			 *	If this is the only request,than we return an error
 			 */
 			if((res32[0]&0x0000FFFF) == 1)
-				return -((res[1] >> 16) & 0xFF); /* -BlockStatus */
+			{
+				return -((res32[1] >> 16) & 0xFF); /* -BlockStatus */
+			}
 		}
-
 		len += restmp[0] & 0x0000FFFF;	/* Length of res BLOCK */
 		restmp += restmp[0] & 0x0000FFFF;	/* Skip to next BLOCK */
 	}
-
 	return (len << 2);  /* bytes used by result list */
 }
 
@@ -2526,10 +2736,10 @@
 	size = i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, iop, tid, 
 		opblk, sizeof(opblk), resblk, sizeof(resblk));
 		
-	if (size < 0)
-		return size;	
-
 	memcpy(buf, resblk+8, buflen);  /* cut off header */
+	
+	if(size>buflen)
+		return buflen;
 	return size;
 }
 
@@ -2570,6 +2780,8 @@
 				opblk, 12+buflen, resblk, sizeof(resblk));
 
 	kfree(opblk);
+	if(size>buflen)
+		return buflen;
 	return size;
 }
 
@@ -2614,6 +2826,8 @@
 				opblk, 10+ibuflen, resblk, reslen);
 
 	kfree(opblk);
+	if(size>reslen)
+		return reslen;
 	return size;
 }
 
@@ -2662,6 +2876,8 @@
 				opblk, 10+buflen, resblk, sizeof(resblk));
 
 	kfree(opblk);
+	if(size>buflen)
+		return buflen;
 	return size;
 }
 
@@ -3113,8 +3329,6 @@
 }
 
 
-#ifdef MODULE
-
 EXPORT_SYMBOL(i2o_controller_chain);
 EXPORT_SYMBOL(i2o_num_controllers);
 EXPORT_SYMBOL(i2o_find_controller);
@@ -3131,6 +3345,7 @@
 
 EXPORT_SYMBOL(i2o_post_this);
 EXPORT_SYMBOL(i2o_post_wait);
+EXPORT_SYMBOL(i2o_post_wait_mem);
 
 EXPORT_SYMBOL(i2o_query_scalar);
 EXPORT_SYMBOL(i2o_set_scalar);
@@ -3147,6 +3362,8 @@
 
 EXPORT_SYMBOL(i2o_get_class_name);
 
+#ifdef MODULE
+
 MODULE_AUTHOR("Red Hat Software");
 MODULE_DESCRIPTION("I2O Core");
 
@@ -3206,17 +3423,13 @@
 	 * If this is shutdown time, the thread has already been killed
 	 */
 	if(evt_running) {
+		printk("Terminating i2o threads...");
 		stat = kill_proc(evt_pid, SIGTERM, 1);
 		if(!stat) {
-			int count = 10 * 100;
-			while(evt_running && count--) {
-				current->state = TASK_INTERRUPTIBLE;
-				schedule_timeout(1);
-			}
-	
-			if(!count)
-				printk(KERN_ERR "i2o: Event thread still running!\n");
+			printk("waiting...");
+			down(&evt_dead);
 		}
+		printk("done.\n");
 	}
 
 #ifdef CONFIG_I2O_PCI_MODULE
diff -u --recursive --new-file v2.4.4/linux/drivers/i2o/i2o_lan.c linux/drivers/i2o/i2o_lan.c
--- v2.4.4/linux/drivers/i2o/i2o_lan.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/i2o/i2o_lan.c	Sun May 20 12:11:38 2001
@@ -938,7 +938,7 @@
 	spin_unlock_irq(&priv->tx_lock);
 	return 0;
 }
-#endif CONFIG_NET_FC
+#endif /* CONFIG_NET_FC */
 
 /*
  * i2o_lan_packet_send(): Send a packet as is, including the MAC header.
diff -u --recursive --new-file v2.4.4/linux/drivers/i2o/i2o_pci.c linux/drivers/i2o/i2o_pci.c
--- v2.4.4/linux/drivers/i2o/i2o_pci.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/i2o/i2o_pci.c	Tue May  1 16:11:29 2001
@@ -160,6 +160,10 @@
 
 	c->bus.pci.irq = -1;
 
+	c->bus.pci.queue_buggy = 0;
+	c->bus.pci.dpt = 0;
+	c->bus.pci.short_req = 0;
+
 	c->irq_mask = (volatile u32 *)(mem+0x34);
 	c->post_port = (volatile u32 *)(mem+0x40);
 	c->reply_port = (volatile u32 *)(mem+0x44);
@@ -175,6 +179,30 @@
 	
 	c->type = I2O_TYPE_PCI;
 
+	/*
+	 *	Cards that fall apart if you hit them with large I/O
+	 *	loads...
+	 */
+	 
+	if(dev->vendor == PCI_VENDOR_ID_NCR && dev->device == 0x0630)
+	{
+		c->bus.pci.short_req=1;
+		printk(KERN_INFO "I2O: Symbios FC920 workarounds activated.\n");
+	}
+	if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE)
+	{
+		c->bus.pci.queue_buggy=1;
+		printk(KERN_INFO "I2O: Promise workarounds activated.\n");
+	}
+
+	/*
+	 *	Cards that go bananas if you quiesce them before you reset
+	 *	them
+	 */
+	 
+	if(dev->vendor == PCI_VENDOR_ID_DPT)
+		c->bus.pci.dpt=1;
+	
 	/* 
 	 * Enable Write Combining MTRR for IOP's memory region
 	 */
@@ -186,13 +214,12 @@
 * since the region contains the Messaging unit which shouldn't be cached.
 */
 	c->bus.pci.mtrr_reg1 = -1;
-	if(dev->vendor == PCI_VENDOR_ID_INTEL)
+	if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT)
 	{
-	printk(KERN_INFO "I2O: MTRR workaround for Intel i960 processor\n"); 
-	c->bus.pci.mtrr_reg1 =
-		mtrr_add(c->mem_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
-	if(c->bus.pci.mtrr_reg1< 0)
-		printk(KERN_INFO "i2o_pci: Error in setting MTRR_TYPE_UNCACHABLE\n");
+		printk(KERN_INFO "I2O: MTRR workaround for Intel i960 processor\n"); 
+		c->bus.pci.mtrr_reg1 =	mtrr_add(c->mem_phys, 65536, MTRR_TYPE_UNCACHABLE, 1);
+		if(c->bus.pci.mtrr_reg1< 0)
+			printk(KERN_INFO "i2o_pci: Error in setting MTRR_TYPE_UNCACHABLE\n");
 	}
 
 #endif
diff -u --recursive --new-file v2.4.4/linux/drivers/i2o/i2o_proc.c linux/drivers/i2o/i2o_proc.c
--- v2.4.4/linux/drivers/i2o/i2o_proc.c	Fri Nov 17 16:51:47 2000
+++ linux/drivers/i2o/i2o_proc.c	Tue May  1 16:09:53 2001
@@ -2356,7 +2356,7 @@
 	len += sprintf(buf+len, "Packet orphan limit           : %d\n", work32[2]);
 
 	len += sprintf(buf+len, "Tx modes : 0x%08x\n", work32[3]);
-	len += sprintf(buf+len, "    [%s] HW CRC supression\n",
+	len += sprintf(buf+len, "    [%s] HW CRC suppression\n",
 			(work32[3]&0x00000004) ? "+" : "-");
 	len += sprintf(buf+len, "    [%s] HW IPv4 checksum\n",
 			(work32[3]&0x00000100) ? "+" : "-");
@@ -2368,7 +2368,7 @@
 			(work32[3]&0x00000800) ? "+" : "-");
 	len += sprintf(buf+len, "    [%s] HW ICMP checksum\n",
 			(work32[3]&0x00001000) ? "+" : "-");
-	len += sprintf(buf+len, "    [%s] Loopback supression enable\n",
+	len += sprintf(buf+len, "    [%s] Loopback suppression enable\n",
 			(work32[3]&0x00002000) ? "+" : "-");
 
 	len += sprintf(buf+len, "Rx modes : 0x%08x\n", work32[4]);
diff -u --recursive --new-file v2.4.4/linux/drivers/i2o/i2o_scsi.c linux/drivers/i2o/i2o_scsi.c
--- v2.4.4/linux/drivers/i2o/i2o_scsi.c	Mon Oct 30 14:44:29 2000
+++ linux/drivers/i2o/i2o_scsi.c	Tue May  1 16:09:53 2001
@@ -262,7 +262,7 @@
 	
 	if(st)
 	{
-		/* An error has occured */
+		/* An error has occurred */
 
 		dprintk((KERN_DEBUG "SCSI error %08X", m[4]));
 			
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/alim15x3.c linux/drivers/ide/alim15x3.c
--- v2.4.4/linux/drivers/ide/alim15x3.c	Fri Apr 27 14:15:01 2001
+++ linux/drivers/ide/alim15x3.c	Sat May 19 17:43:06 2001
@@ -233,8 +233,8 @@
 }
 #endif  /* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
 
-static byte m5229_revision	= 0;
-static byte chip_is_1543c_e	= 0;
+static byte m5229_revision;
+static byte chip_is_1543c_e;
 
 byte ali_proc = 0;
 static struct pci_dev *isa_dev;
@@ -689,7 +689,8 @@
 		 * M1543C or newer for DMAing
 		 */
 		hwif->dmaproc = &ali15x3_dmaproc;
-		hwif->autodma = 1;
+		if (!noautodma)
+			hwif->autodma = 1;
 	}
 }
 
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/amd7409.c linux/drivers/ide/amd7409.c
--- v2.4.4/linux/drivers/ide/amd7409.c	Tue Nov  7 11:02:24 2000
+++ linux/drivers/ide/amd7409.c	Sat May 19 17:43:06 2001
@@ -455,7 +455,8 @@
 
 	if (hwif->dma_base) {
 		hwif->dmaproc = &amd7409_dmaproc;
-		hwif->autodma = 1;
+		if (!noautodma)
+			hwif->autodma = 1;
 	} else {
 		hwif->autodma = 0;
 		hwif->drives[0].autotune = 1;
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/cy82c693.c linux/drivers/ide/cy82c693.c
--- v2.4.4/linux/drivers/ide/cy82c693.c	Tue Jun 20 07:52:36 2000
+++ linux/drivers/ide/cy82c693.c	Sat May 19 17:43:06 2001
@@ -442,7 +442,8 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_base) {
 		hwif->dmaproc = &cy82c693_dmaproc;
-		hwif->autodma = 1;
+		if (!noautodma)
+			hwif->autodma = 1;
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 }
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/hd.c linux/drivers/ide/hd.c
--- v2.4.4/linux/drivers/ide/hd.c	Fri Feb 16 16:02:36 2001
+++ linux/drivers/ide/hd.c	Sat Apr 28 11:27:53 2001
@@ -892,13 +892,7 @@
 
 	for (i=max_p - 1; i >=0 ; i--) {
 		int minor = start + i;
-		kdev_t devi = MKDEV(MAJOR_NR, minor);
-		struct super_block *sb = get_super(devi); 
-
-		sync_dev(devi);
-		if (sb)
-			invalidate_inodes(sb);
-		invalidate_buffers(devi);
+		invalidate_device(MKDEV(MAJOR_NR, minor), 1);
 		gdev->part[minor].start_sect = 0;
 		gdev->part[minor].nr_sects = 0;
 	}
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/hpt34x.c linux/drivers/ide/hpt34x.c
--- v2.4.4/linux/drivers/ide/hpt34x.c	Tue Jun 20 07:52:36 2000
+++ linux/drivers/ide/hpt34x.c	Sat May 19 17:43:06 2001
@@ -419,7 +419,11 @@
 		unsigned short pcicmd = 0;
 
 		pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd);
-		hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0;
+		if (!noautodma)
+			hwif->autodma = (pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0;
+		else
+			hwif->autodma = 0;
+
 		hwif->dmaproc = &hpt34x_dmaproc;
 	} else {
 		hwif->drives[0].autotune = 1;
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/hpt366.c linux/drivers/ide/hpt366.c
--- v2.4.4/linux/drivers/ide/hpt366.c	Sat Jan 27 08:45:58 2001
+++ linux/drivers/ide/hpt366.c	Sat May 19 17:43:06 2001
@@ -223,8 +223,8 @@
 byte hpt366_proc = 0;
 
 extern char *ide_xfer_verbose (byte xfer_rate);
-byte hpt363_shared_irq = 0;
-byte hpt363_shared_pin = 0;
+byte hpt363_shared_irq;
+byte hpt363_shared_pin;
 
 static unsigned int pci_rev_check_hpt3xx (struct pci_dev *dev)
 {
@@ -706,7 +706,10 @@
 		} else {
 			hwif->dmaproc = &hpt366_dmaproc;
 		}
-		hwif->autodma = 1;
+		if (!noautodma)
+			hwif->autodma = 1;
+		else
+			hwif->autodma = 0;
 	} else {
 		hwif->autodma = 0;
 		hwif->drives[0].autotune = 1;
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/ide-pci.c linux/drivers/ide/ide-pci.c
--- v2.4.4/linux/drivers/ide/ide-pci.c	Thu Apr 19 22:57:06 2001
+++ linux/drivers/ide/ide-pci.c	Sun May 20 11:32:11 2001
@@ -581,7 +581,7 @@
 		if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20265))
 		{
 			printk(KERN_INFO "ide: Found promise 20265 in RAID mode.\n");
-			if(dev->bus->self->vendor == PCI_VENDOR_ID_INTEL &&
+			if(dev->bus->self && dev->bus->self->vendor == PCI_VENDOR_ID_INTEL &&
 				dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960)
 			{
 				printk(KERN_INFO "ide: Skipping Promise PDC20265 attached to I2O RAID controller.\n");
@@ -708,7 +708,8 @@
 				/*
  	 			 * Set up BM-DMA capability (PnP BIOS should have done this)
  	 			 */
-				hwif->autodma = 0;	/* default DMA off if we had to configure it here */
+		    		if (!IDE_PCI_DEVID_EQ(d->devid, DEVID_CS5530))
+					hwif->autodma = 0;	/* default DMA off if we had to configure it here */
 				(void) pci_write_config_word(dev, PCI_COMMAND, pcicmd | PCI_COMMAND_MASTER);
 				if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) || !(pcicmd & PCI_COMMAND_MASTER)) {
 					printk("%s: %s error updating PCICMD\n", hwif->name, d->name);
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/ide-pnp.c linux/drivers/ide/ide-pnp.c
--- v2.4.4/linux/drivers/ide/ide-pnp.c	Wed May 24 18:38:26 2000
+++ linux/drivers/ide/ide-pnp.c	Tue May  1 16:06:23 2001
@@ -49,7 +49,7 @@
 
 /* ISA PnP device table entry */
 struct pnp_dev_t {
-	unsigned int vendor, device;
+	unsigned short card_vendor, card_device, vendor, device;
 	int (*init_fn)(struct pci_dev *dev, int enable);
 };
 
@@ -81,8 +81,9 @@
 
 /* Add your devices here :)) */
 struct pnp_dev_t idepnp_devices[] __initdata = {
-	/* Generic ESDI/IDE/ATA compatible hard disk controller
 */
-	{	ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0600),
+  	/* Generic ESDI/IDE/ATA compatible hard disk controller */
+	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+		ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0600),
 		pnpide_generic_init },
 	{	0 }
 };
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/ide.c linux/drivers/ide/ide.c
--- v2.4.4/linux/drivers/ide/ide.c	Wed Apr 11 19:06:12 2001
+++ linux/drivers/ide/ide.c	Tue May  1 16:05:00 2001
@@ -179,6 +179,8 @@
 static int	ide_lock;
 #endif /* __mc68000__ || CONFIG_APUS */
 
+int noautodma = 0;
+
 /*
  * ide_modules keeps track of the available IDE chipset/probe/driver modules.
  */
@@ -1762,11 +1764,7 @@
 	for (p = 0; p < (1<<PARTN_BITS); ++p) {
 		if (drive->part[p].nr_sects > 0) {
 			kdev_t devp = MKDEV(major, minor+p);
-			struct super_block * sb = get_super(devp);
-			fsync_dev          (devp);
-			if (sb)
-				invalidate_inodes(sb);
-			invalidate_buffers (devp);
+			invalidate_device(devp, 1);
 			set_blocksize(devp, 1024);
 		}
 		drive->part[p].start_sect = 0;
@@ -1983,9 +1981,7 @@
 		for (p = 0; p < (1<<PARTN_BITS); ++p) {
 			if (drive->part[p].nr_sects > 0) {
 				kdev_t devp = MKDEV(hwif->major, minor+p);
-				struct super_block * sb = get_super(devp);
-				if (sb) invalidate_inodes(sb);
-				invalidate_buffers (devp);
+				invalidate_device(devp, 0);
 			}
 		}
 #ifdef CONFIG_PROC_FS
@@ -2893,6 +2889,12 @@
 		return 1;
 	}
 #endif /* CONFIG_BLK_DEV_IDEDOUBLER */
+
+	if (!strcmp(s, "ide=nodma")) {
+		printk("IDE: Prevented DMA\n");
+		noautodma = 1;
+		return 1;
+	}
 
 #ifdef CONFIG_BLK_DEV_IDEPCI
 	if (!strcmp(s, "ide=reverse")) {
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/opti621.c linux/drivers/ide/opti621.c
--- v2.4.4/linux/drivers/ide/opti621.c	Tue Nov  7 11:02:24 2000
+++ linux/drivers/ide/opti621.c	Tue May  1 16:05:00 2001
@@ -118,7 +118,7 @@
 /* Uncommnent for disable read prefetch.
  * There is some readprefetch capatibility in hdparm,
  * but when I type hdparm -P 1 /dev/hda, I got errors
- * and till reset drive is inacessible.
+ * and till reset drive is inaccessible.
  * This (hw) read prefetch is safe on my drive.
  */
 
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/osb4.c linux/drivers/ide/osb4.c
--- v2.4.4/linux/drivers/ide/osb4.c	Sun Feb  4 10:05:30 2001
+++ linux/drivers/ide/osb4.c	Tue May  1 16:05:00 2001
@@ -402,10 +402,16 @@
 #ifdef DEBUG
 	printk("%s: reg64 == 0x%08x\n", name, reg64);
 #endif
-	reg64 &= ~0x0000A000;
-#ifdef CONFIG_SMP
-	reg64 |= 0x00008000;
-#endif
+
+//	reg64 &= ~0x0000A000;
+//#ifdef CONFIG_SMP
+//	reg64 |= 0x00008000;
+//#endif
+	/* Assume the APIC was set up properly by the BIOS for now . If it
+	   wasnt we need to do a fix up _way_ earlier. Bits 15,10,3 control
+	   APIC enable, routing and decode */
+	   
+	reg64 &= ~0x00002000;	
 	pci_write_config_dword(isa_dev, 0x64, reg64);
 
 	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40);
@@ -441,7 +447,8 @@
 #else /* CONFIG_BLK_DEV_IDEDMA */
 
 	if (hwif->dma_base) {
-		hwif->autodma = 1;
+		if (!noautodma)
+			hwif->autodma = 1;
 		hwif->dmaproc = &osb4_dmaproc;
 	} else {
 		hwif->autodma = 0;
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/pdc202xx.c linux/drivers/ide/pdc202xx.c
--- v2.4.4/linux/drivers/ide/pdc202xx.c	Thu Apr 19 22:57:06 2001
+++ linux/drivers/ide/pdc202xx.c	Tue May  1 16:05:00 2001
@@ -101,13 +101,6 @@
 	return(pdc202xx_dma_verbose(drive_pci));
 }
 
-char *pdc202xx_interrupt_verbose (u8 sc1d)
-{
-	char *p = NULL;
-	p += sprintf(p,"0x%02x        ", sc1d);
-	return (char *)p;
-}
-
 static char * pdc202xx_info (char *buf, struct pci_dev *dev)
 {
 	char *p = buf;
@@ -862,7 +855,8 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA
 	if (hwif->dma_base) {
 		hwif->dmaproc = &pdc202xx_dmaproc;
-		hwif->autodma = 1;
+		if (!noautodma)
+			hwif->autodma = 1;
 	} else {
 		hwif->drives[0].autotune = 1;
 		hwif->drives[1].autotune = 1;
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/rz1000.c linux/drivers/ide/rz1000.c
--- v2.4.4/linux/drivers/ide/rz1000.c	Thu Apr 13 22:54:26 2000
+++ linux/drivers/ide/rz1000.c	Tue May  1 16:05:00 2001
@@ -94,4 +94,4 @@
 		init_rz1000 (dev, "RZ1001");
 }
 
-#endif CONFIG_BLK_DEV_IDEPCI
+#endif /* CONFIG_BLK_DEV_IDEPCI */
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/sis5513.c linux/drivers/ide/sis5513.c
--- v2.4.4/linux/drivers/ide/sis5513.c	Tue Jan  2 16:58:45 2001
+++ linux/drivers/ide/sis5513.c	Sat May 19 17:43:06 2001
@@ -629,7 +629,8 @@
 			case PCI_DEVICE_ID_SI_5600:
 			case PCI_DEVICE_ID_SI_5597:
 			case PCI_DEVICE_ID_SI_5591:
-				hwif->autodma = 1;
+				if (!noautodma)
+					hwif->autodma = 1;
 				hwif->dmaproc = &sis5513_dmaproc;
 				break;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
diff -u --recursive --new-file v2.4.4/linux/drivers/ide/slc90e66.c linux/drivers/ide/slc90e66.c
--- v2.4.4/linux/drivers/ide/slc90e66.c	Tue Mar  6 19:44:34 2001
+++ linux/drivers/ide/slc90e66.c	Sat May 19 17:43:06 2001
@@ -372,10 +372,10 @@
 	if (!hwif->dma_base)
 		return;
 
-#ifndef CONFIG_BLK_DEV_IDEDMA
 	hwif->autodma = 0;
-#else /* CONFIG_BLK_DEV_IDEDMA */
-	hwif->autodma = 1;
+#ifdef CONFIG_BLK_DEV_IDEDMA 
+	if (!noautodma)
+		hwif->autodma = 1;
 	hwif->dmaproc = &slc90e66_dmaproc;
 	hwif->speedproc = &slc90e66_tune_chipset;
 #endif /* !CONFIG_BLK_DEV_IDEDMA */
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/avmcard.h linux/drivers/isdn/avmb1/avmcard.h
--- v2.4.4/linux/drivers/isdn/avmb1/avmcard.h	Thu Apr 19 22:30:16 2001
+++ linux/drivers/isdn/avmb1/avmcard.h	Sat May 19 17:54:14 2001
@@ -1,60 +1,8 @@
 /*
- * $Id: avmcard.h,v 1.8.6.1 2001/04/20 02:41:59 keil Exp $
+ * $Id: avmcard.h,v 1.8.6.3 2001/05/17 21:15:33 kai Exp $
  *
  * Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
  *
- * $Log: avmcard.h,v $
- * Revision 1.8.6.1  2001/04/20 02:41:59  keil
- * changes from mainstream
- *
- * Revision 1.8  2000/10/10 17:44:19  kai
- * changes from/for 2.2.18
- *
- * Revision 1.7  2000/01/25 14:33:38  calle
- * - Added Support AVM B1 PCI V4.0 (tested with prototype)
- *   - splitted up t1pci.c into b1dma.c for common function with b1pciv4
- *   - support for revision register
- *
- * Revision 1.6  1999/11/05 16:38:01  calle
- * Cleanups before kernel 2.4:
- * - Changed all messages to use card->name or driver->name instead of
- *   constant string.
- * - Moved some data from struct avmcard into new struct avmctrl_info.
- *   Changed all lowlevel capi driver to match the new structur.
- *
- * Revision 1.5  1999/09/07 09:02:53  calle
- * SETDATA removed. Now inside the kernel the datapart of DATA_B3_REQ and
- * DATA_B3_IND is always directly after the CAPI message. The "Data" member
- * ist never used inside the kernel.
- *
- * Revision 1.4  1999/08/04 10:10:08  calle
- * Bugfix: corrected /proc functions, added structure for new AVM cards.
- *
- * Revision 1.3  1999/07/23 08:41:47  calle
- * prepared for new AVM cards.
- *
- * Revision 1.2  1999/07/05 15:09:45  calle
- * - renamed "appl_release" to "appl_released".
- * - version und profile data now cleared on controller reset
- * - extended /proc interface, to allow driver and controller specific
- *   informations to include by driver hackers.
- *
- * Revision 1.1  1999/07/01 15:26:22  calle
- * complete new version (I love it):
- * + new hardware independed "capi_driver" interface that will make it easy to:
- *   - support other controllers with CAPI-2.0 (i.e. USB Controller)
- *   - write a CAPI-2.0 for the passive cards
- *   - support serial link CAPI-2.0 boxes.
- * + wrote "capi_driver" for all supported cards.
- * + "capi_driver" (supported cards) now have to be configured with
- *   make menuconfig, in the past all supported cards where included
- *   at once.
- * + new and better informations in /proc/capi/
- * + new ioctl to switch trace of capi messages per controller
- *   using "avmcapictrl trace [contr] on|off|...."
- * + complete testcircle with all supported cards and also the
- *   PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
- *
  */
 
 #ifndef _AVMCARD_H_
@@ -62,7 +10,6 @@
 
 #define	AVMB1_PORTLEN		0x1f
 #define AVM_MAXVERSION		8
-#define AVM_NAPPS		30
 #define AVM_NCCI_PER_CHANNEL	4
 
 /*
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/b1.c linux/drivers/isdn/avmb1/b1.c
--- v2.4.4/linux/drivers/isdn/avmb1/b1.c	Thu Apr 19 22:30:16 2001
+++ linux/drivers/isdn/avmb1/b1.c	Sat May 19 17:54:14 2001
@@ -120,6 +120,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/capi.h>
+#include <linux/kernelcapi.h>
 #include <asm/io.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
@@ -129,7 +130,7 @@
 #include "capicmd.h"
 #include "capiutil.h"
 
-static char *revision = "$Revision: 1.20.6.4 $";
+static char *revision = "$Revision: 1.20.6.6 $";
 
 /* ------------------------------------------------------------- */
 
@@ -374,7 +375,7 @@
 	cli();
 	b1_setinterrupt(port, card->irq, card->cardtype);
 	b1_put_byte(port, SEND_INIT);
-	b1_put_word(port, AVM_NAPPS);
+	b1_put_word(port, CAPI_MAXAPPL);
 	b1_put_word(port, AVM_NCCI_PER_CHANNEL*2);
 	b1_put_word(port, ctrl->cnr - 1);
 	restore_flags(flags);
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/b1dma.c linux/drivers/isdn/avmb1/b1dma.c
--- v2.4.4/linux/drivers/isdn/avmb1/b1dma.c	Thu Apr 19 22:30:16 2001
+++ linux/drivers/isdn/avmb1/b1dma.c	Sat May 19 17:54:14 2001
@@ -65,6 +65,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/capi.h>
+#include <linux/kernelcapi.h>
 #include <asm/io.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
@@ -74,7 +75,7 @@
 #include "capicmd.h"
 #include "capiutil.h"
 
-static char *revision = "$Revision: 1.11.6.4 $";
+static char *revision = "$Revision: 1.11.6.6 $";
 
 /* ------------------------------------------------------------- */
 
@@ -731,7 +732,7 @@
 	_put_byte(&p, 0);
 	_put_byte(&p, 0);
 	_put_byte(&p, SEND_INIT);
-	_put_word(&p, AVM_NAPPS);
+	_put_word(&p, CAPI_MAXAPPL);
 	_put_word(&p, AVM_NCCI_PER_CHANNEL*30);
 	_put_word(&p, card->cardnr - 1);
 	skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/b1isa.c linux/drivers/isdn/avmb1/b1isa.c
--- v2.4.4/linux/drivers/isdn/avmb1/b1isa.c	Sun Mar 25 18:20:44 2001
+++ linux/drivers/isdn/avmb1/b1isa.c	Sat May 19 17:54:14 2001
@@ -95,7 +95,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.10.6.4 $";
+static char *revision = "$Revision: 1.10.6.5 $";
 
 /* ------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/b1pci.c linux/drivers/isdn/avmb1/b1pci.c
--- v2.4.4/linux/drivers/isdn/avmb1/b1pci.c	Thu Apr 19 22:30:16 2001
+++ linux/drivers/isdn/avmb1/b1pci.c	Sat May 19 17:54:14 2001
@@ -125,7 +125,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.29.6.3 $";
+static char *revision = "$Revision: 1.29.6.4 $";
 
 /* ------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/b1pcmcia.c linux/drivers/isdn/avmb1/b1pcmcia.c
--- v2.4.4/linux/drivers/isdn/avmb1/b1pcmcia.c	Sun Mar 25 18:20:44 2001
+++ linux/drivers/isdn/avmb1/b1pcmcia.c	Sat May 19 17:54:14 2001
@@ -102,7 +102,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.12.6.3 $";
+static char *revision = "$Revision: 1.12.6.4 $";
 
 /* ------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/c4.c linux/drivers/isdn/avmb1/c4.c
--- v2.4.4/linux/drivers/isdn/avmb1/c4.c	Thu Apr 19 22:30:16 2001
+++ linux/drivers/isdn/avmb1/c4.c	Sat May 19 17:54:14 2001
@@ -112,6 +112,7 @@
 #include <linux/ioport.h>
 #include <linux/pci.h>
 #include <linux/capi.h>
+#include <linux/kernelcapi.h>
 #include <linux/init.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -121,7 +122,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.20.6.6 $";
+static char *revision = "$Revision: 1.20.6.8 $";
 
 #undef CONFIG_C4_DEBUG
 #undef CONFIG_C4_POLLDEBUG
@@ -851,7 +852,7 @@
 	_put_byte(&p, 0);
 	_put_byte(&p, 0);
 	_put_byte(&p, SEND_INIT);
-	_put_word(&p, AVM_NAPPS);
+	_put_word(&p, CAPI_MAXAPPL);
 	_put_word(&p, AVM_NCCI_PER_CHANNEL*30);
 	_put_word(&p, card->cardnr - 1);
 	skb_put(skb, (__u8 *)p - (__u8 *)skb->data);
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/capi.c linux/drivers/isdn/avmb1/capi.c
--- v2.4.4/linux/drivers/isdn/avmb1/capi.c	Wed Apr 18 11:49:13 2001
+++ linux/drivers/isdn/avmb1/capi.c	Sat May 19 17:54:14 2001
@@ -1,238 +1,10 @@
 /*
- * $Id: capi.c,v 1.44.6.9 2001/04/08 17:51:42 kai Exp $
+ * $Id: capi.c,v 1.44.6.11 2001/05/17 20:41:51 kai Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
  * Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de)
  *
- * $Log: capi.c,v $
- * Revision 1.44.6.9  2001/04/08 17:51:42  kai
- * merge various fixes from HEAD (found by the CHECKER project)
- *
- * Revision 1.44.6.8  2001/03/21 08:52:21  kai
- * merge from main branch: fix buffer for revision string (calle)
- *
- * Revision 1.44.6.7  2001/03/15 15:11:24  kai
- * *** empty log message ***
- *
- * Revision 1.44.6.6  2001/03/13 16:17:07  kai
- * spelling fixes from 2.4.3-pre
- *
- * Revision 1.44.6.5  2001/02/13 11:43:29  kai
- * more compatility changes for 2.2.19
- *
- * Revision 1.44.6.4  2001/02/10 14:41:20  kai
- * Changes from kernel tree
- *
- * Revision 1.44.6.3  2000/12/17 22:45:08  kai
- * That's hopefully it for test13-4
- *
- * Revision 1.44.6.2  2000/12/14 23:04:12  kai
- * Makefile changes and the like for 2.4.0-test13-pre1
- * No compatiblity code for older kernels yet, but note the branch
- *
- * Revision 1.45  2000/12/02 19:47:29  kai
- * Change the Makefiles to new style.
- * There may be problems there that I missed, so this shouldn't go into
- * an offical kernel any time soon.
- * However, if I didn't commit it, we wouldn't find the bugs...
- *
- * Revision 1.44  2000/11/25 17:00:59  kai
- * compatibility cleanup - final part for the time being
- *
- * Revision 1.43  2000/11/23 20:45:14  kai
- * fixed module_init/exit stuff
- * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
- *
- * Revision 1.42  2000/11/19 17:03:55  kai
- * compatibility cleanup - part 5
- *
- * Revision 1.41  2000/11/01 14:05:02  calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.40  2000/10/24 15:15:04  calle
- * Workaround: pppd calls restoretty before reseting the ldisc and
- *   ldisc "ppp_sync" didn't support this. So we call n_tty_ioctl
- *   in the driver ioctl function. (remember: driver ioctl function is
- *   only called if ldisc ioctl function did not handle the call)
- *
- * Revision 1.39  2000/07/24 13:42:50  calle
- * - lock_kernel/unlock_kernel for _release functions. (from 2.4)
- *
- * Revision 1.38  2000/07/24 08:49:09  calle
- * - Bugfix: capiminor_del_all_ack completely wrong :-(
- *
- * Revision 1.37  2000/07/20 10:22:27  calle
- * - Made procfs function cleaner and removed variable "begin".
- *
- * Revision 1.36  2000/06/29 13:59:35  calle
- * - call to devfs_register was wrong
- *
- * Revision 1.35  2000/06/19 15:11:24  keil
- * avoid use of freed structs
- * changes from 2.4.0-ac21
- *
- * Revision 1.34  2000/06/18 16:09:54  keil
- * more changes for 2.4
- *
- * Revision 1.33  2000/05/18 16:35:43  calle
- * Uaaahh. Bad memory leak fixed.
- *
- * Revision 1.32  2000/04/21 12:38:42  calle
- * Bugfix: error in proc_ functions, begin-off => off-begin
- *
- * Revision 1.31  2000/04/03 13:29:24  calle
- * make Tim Waugh happy (module unload races in 2.3.99-pre3).
- * no real problem there, but now it is much cleaner ...
- *
- * Revision 1.30  2000/03/19 12:31:36  calle
- * PPP over CAPI raw driver disabled for now, ppp_generic has been changed.
- *
- * Revision 1.29  2000/03/13 17:48:13  calle
- * removed unused variable.
- *
- * Revision 1.28  2000/03/08 17:06:33  calle
- * - changes for devfs and 2.3.49
- * - capifs now configurable (no need with devfs)
- * - New Middleware ioctl CAPI_NCCI_GETUNIT
- * - Middleware again tested with 2.2.14 and 2.3.49 (with and without devfs)
- *
- * Revision 1.27  2000/03/06 18:00:23  calle
- * - Middleware extention now working with 2.3.49 (capifs).
- * - Fixed typos in debug section of capi.c
- * - Bugfix: Makefile corrected for b1pcmcia.c
- *
- * Revision 1.26  2000/03/03 16:48:38  calle
- * - Added CAPI2.0 Middleware support (CONFIG_ISDN_CAPI)
- *   It is now possible to create a connection with a CAPI2.0 applikation
- *   and than to handle the data connection from /dev/capi/ (capifs) and also
- *   using async or sync PPP on this connection.
- *   The two major device number 190 and 191 are not confirmed yet,
- *   but I want to save the code in cvs, before I go on.
- *
- * Revision 1.25  2000/03/03 16:37:11  kai
- * incorporated some cosmetic changes from the official kernel tree back
- * into CVS
- *
- * Revision 1.24  2000/03/03 15:50:42  calle
- * - kernel CAPI:
- *   - Changed parameter "param" in capi_signal from __u32 to void *.
- *   - rewrote notifier handling in kcapi.c
- *   - new notifier NCCI_UP and NCCI_DOWN
- * - User CAPI:
- *   - /dev/capi20 is now a cloning device.
- *   - middleware extentions prepared.
- * - capidrv.c
- *   - locking of list operations and module count updates.
- *
- * Revision 1.23  2000/02/26 01:00:53  keil
- * changes from 2.3.47
- *
- * Revision 1.22  1999/11/13 21:27:16  keil
- * remove KERNELVERSION
- *
- * Revision 1.21  1999/09/10 17:24:18  calle
- * Changes for proposed standard for CAPI2.0:
- * - AK148 "Linux Exention"
- *
- * Revision 1.20  1999/09/07 09:02:53  calle
- * SETDATA removed. Now inside the kernel the datapart of DATA_B3_REQ and
- * DATA_B3_IND is always directly after the CAPI message. The "Data" member
- * ist never used inside the kernel.
- *
- * Revision 1.19  1999/07/09 15:05:42  keil
- * compat.h is now isdn_compat.h
- *
- * Revision 1.18  1999/07/06 07:42:01  calle
- * - changes in /proc interface
- * - check and changed calls to [dev_]kfree_skb and [dev_]alloc_skb.
- *
- * Revision 1.17  1999/07/01 15:26:30  calle
- * complete new version (I love it):
- * + new hardware independed "capi_driver" interface that will make it easy to:
- *   - support other controllers with CAPI-2.0 (i.e. USB Controller)
- *   - write a CAPI-2.0 for the passive cards
- *   - support serial link CAPI-2.0 boxes.
- * + wrote "capi_driver" for all supported cards.
- * + "capi_driver" (supported cards) now have to be configured with
- *   make menuconfig, in the past all supported cards where included
- *   at once.
- * + new and better informations in /proc/capi/
- * + new ioctl to switch trace of capi messages per controller
- *   using "avmcapictrl trace [contr] on|off|...."
- * + complete testcircle with all supported cards and also the
- *   PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
- *
- * Revision 1.16  1999/07/01 08:22:57  keil
- * compatibility macros now in <linux/isdn_compat.h>
- *
- * Revision 1.15  1999/06/21 15:24:11  calle
- * extend information in /proc.
- *
- * Revision 1.14  1999/06/10 16:51:03  calle
- * Bugfix: open/release of control device was not handled correct.
- *
- * Revision 1.13  1998/08/28 04:32:25  calle
- * Added patch send by Michael.Mueller4@post.rwth-aachen.de, to get AVM B1
- * driver running with 2.1.118.
- *
- * Revision 1.12  1998/05/26 22:39:34  he
- * sync'ed with 2.1.102 where appropriate (CAPABILITY changes)
- * concap typo
- * cleared dev.tbusy in isdn_net BCONN status callback
- *
- * Revision 1.11  1998/03/09 17:46:37  he
- * merged in 2.1.89 changes
- *
- * Revision 1.10  1998/02/13 07:09:13  calle
- * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
- *
- * Revision 1.9  1998/01/31 11:14:44  calle
- * merged changes to 2.0 tree, prepare 2.1.82 to work.
- *
- * Revision 1.8  1997/11/04 06:12:08  calle
- * capi.c: new read/write in file_ops since 2.1.60
- * capidrv.c: prepared isdnlog interface for d2-trace in newer firmware.
- * capiutil.c: needs config.h (CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON)
- * compat.h: added #define LinuxVersionCode
- *
- * Revision 1.7  1997/10/11 10:29:34  calle
- * llseek() parameters changed in 2.1.56.
- *
- * Revision 1.6  1997/10/01 09:21:15  fritz
- * Removed old compatibility stuff for 2.0.X kernels.
- * From now on, this code is for 2.1.X ONLY!
- * Old stuff is still in the separate branch.
- *
- * Revision 1.5  1997/08/21 23:11:55  fritz
- * Added changes for kernels >= 2.1.45
- *
- * Revision 1.4  1997/05/27 15:17:50  fritz
- * Added changes for recent 2.1.x kernels:
- *   changed return type of isdn_close
- *   queue_task_* -> queue_task
- *   clear/set_bit -> test_and_... where apropriate.
- *   changed type of hard_header_cache parameter.
- *
- * Revision 1.3  1997/05/18 09:24:14  calle
- * added verbose disconnect reason reporting to avmb1.
- * some fixes in capi20 interface.
- * changed info messages for B1-PCI
- *
- * Revision 1.2  1997/03/05 21:17:59  fritz
- * Added capi_poll for compiling under 2.1.27
- *
- * Revision 1.1  1997/03/04 21:50:29  calle
- * Frirst version in isdn4linux
- *
- * Revision 2.2  1997/02/12 09:31:39  calle
- * new version
- *
- * Revision 1.1  1997/01/31 10:32:20  calle
- * Initial revision
- *
  */
 
 #include <linux/config.h>
@@ -271,7 +43,7 @@
 #include "capifs.h"
 #endif
 
-static char *revision = "$Revision: 1.44.6.9 $";
+static char *revision = "$Revision: 1.44.6.11 $";
 
 MODULE_AUTHOR("Carsten Paeth (calle@calle.in-berlin.de)");
 
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/capidev.h linux/drivers/isdn/avmb1/capidev.h
--- v2.4.4/linux/drivers/isdn/avmb1/capidev.h	Mon Nov 27 16:53:43 2000
+++ linux/drivers/isdn/avmb1/capidev.h	Sat May 19 17:54:14 2001
@@ -1,55 +1,9 @@
 /*
- * $Id: capidev.h,v 1.6 2000/11/25 17:00:59 kai Exp $
+ * $Id: capidev.h,v 1.6.6.1 2001/05/17 20:41:51 kai Exp $
  *
  * CAPI 2.0 Interface for Linux
  *
  * (c) Copyright 1996 by Carsten Paeth (calle@calle.in-berlin.de)
- *
- * $Log: capidev.h,v $
- * Revision 1.6  2000/11/25 17:00:59  kai
- * compatibility cleanup - final part for the time being
- *
- * Revision 1.5  2000/03/03 15:50:42  calle
- * - kernel CAPI:
- *   - Changed parameter "param" in capi_signal from __u32 to void *.
- *   - rewrote notifier handling in kcapi.c
- *   - new notifier NCCI_UP and NCCI_DOWN
- * - User CAPI:
- *   - /dev/capi20 is now a cloning device.
- *   - middleware extentions prepared.
- * - capidrv.c
- *   - locking of list operations and module count updates.
- *
- * Revision 1.4  1999/07/01 15:26:32  calle
- * complete new version (I love it):
- * + new hardware independed "capi_driver" interface that will make it easy to:
- *   - support other controllers with CAPI-2.0 (i.e. USB Controller)
- *   - write a CAPI-2.0 for the passive cards
- *   - support serial link CAPI-2.0 boxes.
- * + wrote "capi_driver" for all supported cards.
- * + "capi_driver" (supported cards) now have to be configured with
- *   make menuconfig, in the past all supported cards where included
- *   at once.
- * + new and better informations in /proc/capi/
- * + new ioctl to switch trace of capi messages per controller
- *   using "avmcapictrl trace [contr] on|off|...."
- * + complete testcircle with all supported cards and also the
- *   PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
- *
- * Revision 1.3  1999/07/01 08:22:58  keil
- * compatibility macros now in <linux/isdn_compat.h>
- *
- * Revision 1.2  1999/06/21 15:24:13  calle
- * extend information in /proc.
- *
- * Revision 1.1  1997/03/04 21:50:30  calle
- * Frirst version in isdn4linux
- *
- * Revision 2.2  1997/02/12 09:31:39  calle
- * new version
- *
- * Revision 1.1  1997/01/31 10:32:20  calle
- * Initial revision
  *
  */
 
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/capidrv.c linux/drivers/isdn/avmb1/capidrv.c
--- v2.4.4/linux/drivers/isdn/avmb1/capidrv.c	Wed Apr 18 11:49:13 2001
+++ linux/drivers/isdn/avmb1/capidrv.c	Sat May 19 17:54:14 2001
@@ -1,211 +1,10 @@
 /*
- * $Id: capidrv.c,v 1.39.6.5 2001/04/08 17:51:42 kai Exp $
+ * $Id: capidrv.c,v 1.39.6.6 2001/05/17 20:41:51 kai Exp $
  *
  * ISDN4Linux Driver, using capi20 interface (kernelcapi)
  *
  * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
  *
- * $Log: capidrv.c,v $
- * Revision 1.39.6.5  2001/04/08 17:51:42  kai
- * merge various fixes from HEAD (found by the CHECKER project)
- *
- * Revision 1.39.6.4  2001/03/21 08:52:21  kai
- * merge from main branch: fix buffer for revision string (calle)
- *
- * Revision 1.39.6.3  2001/03/13 16:17:07  kai
- * spelling fixes from 2.4.3-pre
- *
- * Revision 1.39.6.2  2001/02/13 11:43:29  kai
- * more compatility changes for 2.2.19
- *
- * Revision 1.39.6.1  2001/02/10 14:41:20  kai
- * Changes from kernel tree
- *
- * Revision 1.39  2000/11/23 20:45:14  kai
- * fixed module_init/exit stuff
- * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
- *
- * Revision 1.38  2000/11/14 08:43:07  calle
- * Bugfix for v110. Connectparamters where setup for sync ...
- *
- * Revision 1.37  2000/11/01 14:05:02  calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.36  2000/06/26 15:13:41  keil
- * features should be or'ed
- *
- * Revision 1.35  2000/06/19 15:11:25  keil
- * avoid use of freed structs
- * changes from 2.4.0-ac21
- *
- * Revision 1.34  2000/06/19 13:13:55  calle
- * Added Modemsupport!
- *
- * Revision 1.33  2000/05/06 00:52:36  kai
- * merged changes from kernel tree
- * fixed timer and net_device->name breakage
- *
- * Revision 1.32  2000/04/07 15:19:58  calle
- * remove warnings
- *
- * Revision 1.31  2000/04/06 15:01:25  calle
- * Bugfix: crash in capidrv.c when reseting a capi controller.
- * - changed code order on remove of controller.
- * - using tq_schedule for notifier in kcapi.c.
- * - now using spin_lock_irqsave() and spin_unlock_irqrestore().
- * strange: sometimes even MP hang on unload of isdn.o ...
- *
- * Revision 1.30  2000/03/03 15:50:42  calle
- * - kernel CAPI:
- *   - Changed parameter "param" in capi_signal from __u32 to void *.
- *   - rewrote notifier handling in kcapi.c
- *   - new notifier NCCI_UP and NCCI_DOWN
- * - User CAPI:
- *   - /dev/capi20 is now a cloning device.
- *   - middleware extentions prepared.
- * - capidrv.c
- *   - locking of list operations and module count updates.
- *
- * Revision 1.29  1999/12/06 17:13:06  calle
- * Added controller watchdog.
- *
- * Revision 1.28  1999/11/05 16:22:37  calle
- * Bugfix: Missing break in switch on ISDN_CMD_HANGUP.
- *
- * Revision 1.27  1999/09/16 15:13:04  calle
- * forgot to change paramter type of contr for lower_callback ...
- *
- * Revision 1.26  1999/08/06 07:41:16  calle
- * Added the "vbox patch". if (si1 == 1) si2 = 0;
- *
- * Revision 1.25  1999/08/04 10:10:11  calle
- * Bugfix: corrected /proc functions, added structure for new AVM cards.
- *
- * Revision 1.24  1999/07/20 06:48:02  calle
- * Bugfix: firmware version check for D2 trace was too restrictiv.
- *
- * Revision 1.23  1999/07/09 15:05:44  keil
- * compat.h is now isdn_compat.h
- *
- * Revision 1.22  1999/07/06 07:24:14  calle
- * Bugfix: call to kfree_skb in capidrv_signal was too early,
- *         thanks to Lars Heete <hel@admin.de>.
- *
- * Revision 1.21  1999/07/01 15:26:34  calle
- * complete new version (I love it):
- * + new hardware independed "capi_driver" interface that will make it easy to:
- *   - support other controllers with CAPI-2.0 (i.e. USB Controller)
- *   - write a CAPI-2.0 for the passive cards
- *   - support serial link CAPI-2.0 boxes.
- * + wrote "capi_driver" for all supported cards.
- * + "capi_driver" (supported cards) now have to be configured with
- *   make menuconfig, in the past all supported cards where included
- *   at once.
- * + new and better informations in /proc/capi/
- * + new ioctl to switch trace of capi messages per controller
- *   using "avmcapictrl trace [contr] on|off|...."
- * + complete testcircle with all supported cards and also the
- *   PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
- *
- * Revision 1.20  1999/07/01 08:22:59  keil
- * compatibility macros now in <linux/isdn_compat.h>
- *
- * Revision 1.19  1999/06/29 16:16:54  calle
- * Let ISDN_CMD_UNLOAD work with open isdn devices without crash again.
- * Also right unlocking (ISDN_CMD_UNLOCK) is done now.
- * isdnlog should check returncode of read(2) calls.
- *
- * Revision 1.18  1999/06/21 15:24:15  calle
- * extend information in /proc.
- *
- * Revision 1.17  1999/06/10 16:53:55  calle
- * Removing of module b1pci will now remove card from lower level.
- *
- * Revision 1.16  1999/05/31 11:50:33  calle
- * Bugfix: In if_sendbuf, skb_push'ed DATA_B3 header was not skb_pull'ed
- *         on failure, result in data block with DATA_B3 header transmitted
- *
- * Revision 1.15  1999/05/25 21:26:16  calle
- * Include CAPI-Channelallocation (leased lines) from the 2.0 tree.
- *
- * Revision 1.14  1999/05/22 07:55:06  calle
- * Added *V110* to AVM B1 driver.
- *
- * Revision 1.13  1998/06/26 15:12:55  fritz
- * Added handling of STAT_ICALL with incomplete CPN.
- * Added AT&L for ttyI emulator.
- * Added more locking stuff in tty_write.
- *
- * Revision 1.12  1998/03/29 16:06:03  calle
- * changes from 2.0 tree merged.
- *
- * Revision 1.3.2.10  1998/03/20 14:38:24  calle
- * capidrv: prepared state machines for suspend/resume/hold
- * capidrv: fix bug in state machine if B1/T1 is out of nccis
- * b1capi: changed some errno returns.
- * b1capi: detect if you try to add same T1 to different io address.
- * b1capi: change number of nccis depending on number of channels.
- * b1lli: cosmetics
- *
- * Revision 1.3.2.9  1998/03/20 09:01:12  calle
- * Changes capi_register handling to get full support for 30 bchannels.
- *
- * Revision 1.3.2.8  1998/03/18 17:51:28  calle
- * added controller number to error messages
- *
- * Revision 1.3.2.7  1998/02/27 15:40:47  calle
- * T1 running with slow link. bugfix in capi_release.
- *
- * Revision 1.11  1998/02/13 07:09:15  calle
- * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
- *
- * Revision 1.10  1998/02/02 19:52:23  calle
- * Fixed vbox (audio) acceptb.
- *
- * Revision 1.9  1998/01/31 11:14:45  calle
- * merged changes to 2.0 tree, prepare 2.1.82 to work.
- *
- * Revision 1.8  1997/11/04 06:12:09  calle
- * capi.c: new read/write in file_ops since 2.1.60
- * capidrv.c: prepared isdnlog interface for d2-trace in newer firmware.
- * capiutil.c: needs config.h (CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON)
- * compat.h: added #define LinuxVersionCode
- *
- * Revision 1.7  1997/10/11 10:36:34  calle
- * Added isdnlog support. patch to isdnlog needed.
- *
- * Revision 1.6  1997/10/11 10:25:55  calle
- * New interface for lowlevel drivers. BSENT with nr. of bytes sent,
- * allow sending without ACK.
- *
- * Revision 1.5  1997/10/01 09:21:16  fritz
- * Removed old compatibility stuff for 2.0.X kernels.
- * From now on, this code is for 2.1.X ONLY!
- * Old stuff is still in the separate branch.
- *
- * Revision 1.4  1997/07/13 12:22:43  calle
- * bug fix for more than one controller in connect_req.
- * debugoutput now with contrnr.
- *
- * Revision 1.3  1997/05/18 09:24:15  calle
- * added verbose disconnect reason reporting to avmb1.
- * some fixes in capi20 interface.
- * changed info messages for B1-PCI
- *
- * Revision 1.2  1997/03/05 21:19:59  fritz
- * Removed include of config.h (mkdep stated this is unneded).
- *
- * Revision 1.1  1997/03/04 21:50:31  calle
- * Frirst version in isdn4linux
- *
- * Revision 2.2  1997/02/12 09:31:39  calle
- * new version
- *
- * Revision 1.1  1997/01/31 10:32:20  calle
- * Initial revision
- *
  */
 
 #include <linux/module.h>
@@ -234,7 +33,7 @@
 #include "capicmd.h"
 #include "capidrv.h"
 
-static char *revision = "$Revision: 1.39.6.5 $";
+static char *revision = "$Revision: 1.39.6.6 $";
 static int debugmode = 0;
 
 MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/capidrv.h linux/drivers/isdn/avmb1/capidrv.h
--- v2.4.4/linux/drivers/isdn/avmb1/capidrv.h	Sun May 23 10:03:41 1999
+++ linux/drivers/isdn/avmb1/capidrv.h	Sat May 19 17:54:14 2001
@@ -1,30 +1,9 @@
 /*
- * $Id: capidrv.h,v 1.2 1998/03/29 16:06:06 calle Exp $
+ * $Id: capidrv.h,v 1.2.8.1 2001/05/17 20:41:51 kai Exp $
  *
  * ISDN4Linux Driver, using capi20 interface (kernelcapi)
  *
  * Copyright 1997 by Carsten Paeth (calle@calle.in-berlin.de)
- *
- * $Log: capidrv.h,v $
- * Revision 1.2  1998/03/29 16:06:06  calle
- * changes from 2.0 tree merged.
- *
- * Revision 1.1.2.1  1998/03/20 14:38:28  calle
- * capidrv: prepared state machines for suspend/resume/hold
- * capidrv: fix bug in state machine if B1/T1 is out of nccis
- * b1capi: changed some errno returns.
- * b1capi: detect if you try to add same T1 to different io address.
- * b1capi: change number of nccis depending on number of channels.
- * b1lli: cosmetics
- *
- * Revision 1.1  1997/03/04 21:50:33  calle
- * Frirst version in isdn4linux
- *
- * Revision 2.2  1997/02/12 09:31:39  calle
- * new version
- *
- * Revision 1.1  1997/01/31 10:32:20  calle
- * Initial revision
  *
  */
 #ifndef __CAPIDRV_H__
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/capifs.c linux/drivers/isdn/avmb1/capifs.c
--- v2.4.4/linux/drivers/isdn/avmb1/capifs.c	Sun Mar 25 18:20:44 2001
+++ linux/drivers/isdn/avmb1/capifs.c	Tue May 22 09:31:25 2001
@@ -105,7 +105,7 @@
 
 MODULE_AUTHOR("Carsten Paeth <calle@calle.de>");
 
-static char *revision = "$Revision: 1.14.6.5 $";
+static char *revision = "$Revision: 1.14.6.6 $";
 
 struct capifs_ncci {
 	struct inode *inode;
@@ -290,19 +290,9 @@
 #endif
 }
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,51)
-static int capifs_statfs(struct super_block *sb, struct statfs *buf, int bufsiz);
-static void capifs_write_inode(struct inode *inode) { };
-#else
 static int capifs_statfs(struct super_block *sb, struct statfs *buf);
-#endif
-static void capifs_read_inode(struct inode *inode);
 
 static struct super_operations capifs_sops = {
-	read_inode:	capifs_read_inode,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,51)
-	write_inode:	capifs_write_inode,
-#endif
 	put_super:	capifs_put_super,
 	statfs:		capifs_statfs,
 };
@@ -411,7 +401,14 @@
 	/*
 	 * Get the root inode and dentry, but defer checking for errors.
 	 */
-	root_inode = iget(s, 1); /* inode 1 == root directory */
+	root_inode = capifs_new_inode(s);
+	if (root_inode) {
+		root_inode->i_ino = 1;
+		root_inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
+		root_inode->i_op = &capifs_root_inode_operations;
+		root_inode->i_fop = &capifs_root_operations;
+		root_inode->i_nlink = 2;
+	} 
 	root = d_alloc_root(root_inode);
 
 	/*
@@ -494,33 +491,16 @@
 }
 #endif
 
-static void capifs_read_inode(struct inode *inode)
+static struct inode *capifs_new_inode(struct super_block *sb);
 {
-	ino_t ino = inode->i_ino;
-	struct capifs_sb_info *sbi = SBI(inode->i_sb);
-
-	inode->i_mode = 0;
-	inode->i_nlink = 0;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-	inode->i_blocks = 0;
-	inode->i_blksize = 1024;
-	inode->i_uid = inode->i_gid = 0;
-
-	if ( ino == 1 ) {
-		inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
-		inode->i_op = &capifs_root_inode_operations;
-		inode->i_fop = &capifs_root_operations;
-		inode->i_nlink = 2;
-		return;
-	} 
-
-	ino -= 2;
-	if ( ino >= sbi->max_ncci )
-		return;		/* Bogus */
-	
-	init_special_inode(inode, S_IFCHR, 0);
-
-	return;
+	inode = new_inode(sb);
+	if (inode) {
+		inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+		inode->i_blocks = 0;
+		inode->i_blksize = 1024;
+		inode->i_uid = inode->i_gid = 0;
+	}
+	return inode;
 }
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,51)
@@ -553,14 +533,16 @@
 				break;
 			}
 		}
+		if ( ino >= sbi->max_ncci )
+			continue;
 
-		if ((np->inode = iget(sb, ino+2)) != 0) {
+		if ((np->inode = capifs_new_inode(sb)) != NULL) {
 			struct inode *inode = np->inode;
 			inode->i_uid = sbi->setuid ? sbi->uid : current->fsuid;
 			inode->i_gid = sbi->setgid ? sbi->gid : current->fsgid;
-			inode->i_mode = sbi->mode | S_IFCHR;
-			inode->i_rdev = np->kdev;
-			inode->i_nlink++;
+			inode->i_nlink = 1;
+			inode->i_ino = ino + 2;
+			init_special_inode(inode, sbi->mode|S_IFCHR, np->kdev);
 		}
 	}
 }
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/capiutil.c linux/drivers/isdn/avmb1/capiutil.c
--- v2.4.4/linux/drivers/isdn/avmb1/capiutil.c	Sun Mar 25 18:20:44 2001
+++ linux/drivers/isdn/avmb1/capiutil.c	Sat May 19 17:54:14 2001
@@ -1,93 +1,10 @@
 /*
- * $Id: capiutil.c,v 1.13.6.2 2001/03/15 15:11:24 kai Exp $
+ * $Id: capiutil.c,v 1.13.6.3 2001/05/17 20:41:51 kai Exp $
  *
  * CAPI 2.0 convert capi message to capi message struct
  *
  * From CAPI 2.0 Development Kit AVM 1995 (msg.c)
  * Rewritten for Linux 1996 by Carsten Paeth (calle@calle.in-berlin.de)
- *
- * $Log: capiutil.c,v $
- * Revision 1.13.6.2  2001/03/15 15:11:24  kai
- * *** empty log message ***
- *
- * Revision 1.13.6.1  2001/02/13 11:43:29  kai
- * more compatility changes for 2.2.19
- *
- * Revision 1.13  2000/11/23 20:45:14  kai
- * fixed module_init/exit stuff
- * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
- *
- * Revision 1.12  2000/11/01 14:05:02  calle
- * - use module_init/module_exit from linux/init.h.
- * - all static struct variables are initialized with "membername:" now.
- * - avm_cs.c, let it work with newer pcmcia-cs.
- *
- * Revision 1.11  2000/03/03 15:50:42  calle
- * - kernel CAPI:
- *   - Changed parameter "param" in capi_signal from __u32 to void *.
- *   - rewrote notifier handling in kcapi.c
- *   - new notifier NCCI_UP and NCCI_DOWN
- * - User CAPI:
- *   - /dev/capi20 is now a cloning device.
- *   - middleware extentions prepared.
- * - capidrv.c
- *   - locking of list operations and module count updates.
- *
- * Revision 1.10  1999/08/31 11:19:54  paul
- * various spelling corrections (new checksums may be needed, Karsten!)
- *
- * Revision 1.9  1999/07/09 15:05:46  keil
- * compat.h is now isdn_compat.h
- *
- * Revision 1.8  1999/07/01 15:26:37  calle
- * complete new version (I love it):
- * + new hardware independed "capi_driver" interface that will make it easy to:
- *   - support other controllers with CAPI-2.0 (i.e. USB Controller)
- *   - write a CAPI-2.0 for the passive cards
- *   - support serial link CAPI-2.0 boxes.
- * + wrote "capi_driver" for all supported cards.
- * + "capi_driver" (supported cards) now have to be configured with
- *   make menuconfig, in the past all supported cards where included
- *   at once.
- * + new and better informations in /proc/capi/
- * + new ioctl to switch trace of capi messages per controller
- *   using "avmcapictrl trace [contr] on|off|...."
- * + complete testcircle with all supported cards and also the
- *   PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
- *
- * Revision 1.7  1999/07/01 08:23:01  keil
- * compatibility macros now in <linux/isdn_compat.h>
- *
- * Revision 1.6  1997/11/04 06:12:12  calle
- * capi.c: new read/write in file_ops since 2.1.60
- * capidrv.c: prepared isdnlog interface for d2-trace in newer firmware.
- * capiutil.c: needs config.h (CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON)
- * compat.h: added #define LinuxVersionCode
- *
- * Revision 1.5  1997/10/01 09:21:19  fritz
- * Removed old compatibility stuff for 2.0.X kernels.
- * From now on, this code is for 2.1.X ONLY!
- * Old stuff is still in the separate branch.
- *
- * Revision 1.4  1997/08/10 07:43:55  calle
- * forgot to export symbol capi_info2str for 2.1.x
- *
- * Revision 1.3  1997/05/18 09:24:18  calle
- * added verbose disconnect reason reporting to avmb1.
- * some fixes in capi20 interface.
- * changed info messages for B1-PCI
- *
- * Revision 1.2  1997/03/05 21:22:13  fritz
- * Fix: Symbols have to be exported unconditionally.
- *
- * Revision 1.1  1997/03/04 21:50:34  calle
- * Frirst version in isdn4linux
- *
- * Revision 2.2  1997/02/12 09:31:39  calle
- * new version
- *
- * Revision 1.1  1997/01/31 10:32:20  calle
- * Initial revision
  *
  */
 #include <linux/module.h>
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/kcapi.c linux/drivers/isdn/avmb1/kcapi.c
--- v2.4.4/linux/drivers/isdn/avmb1/kcapi.c	Sun Mar 25 18:20:44 2001
+++ linux/drivers/isdn/avmb1/kcapi.c	Sat May 19 17:54:14 2001
@@ -148,7 +148,7 @@
 #include <linux/b1lli.h>
 #endif
 
-static char *revision = "$Revision: 1.21.6.5 $";
+static char *revision = "$Revision: 1.21.6.6 $";
 
 /* ------------------------------------------------------------- */
 
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/t1isa.c linux/drivers/isdn/avmb1/t1isa.c
--- v2.4.4/linux/drivers/isdn/avmb1/t1isa.c	Sun Mar 25 18:20:44 2001
+++ linux/drivers/isdn/avmb1/t1isa.c	Sat May 19 17:54:14 2001
@@ -109,6 +109,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/capi.h>
+#include <linux/kernelcapi.h>
 #include <linux/init.h>
 #include <asm/io.h>
 #include "capicmd.h"
@@ -116,7 +117,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.16.6.4 $";
+static char *revision = "$Revision: 1.16.6.6 $";
 
 /* ------------------------------------------------------------- */
 
@@ -410,7 +411,7 @@
 	cli();
 	b1_setinterrupt(port, card->irq, card->cardtype);
 	b1_put_byte(port, SEND_INIT);
-	b1_put_word(port, AVM_NAPPS);
+	b1_put_word(port, CAPI_MAXAPPL);
 	b1_put_word(port, AVM_NCCI_PER_CHANNEL*30);
 	b1_put_word(port, ctrl->cnr - 1);
 	restore_flags(flags);
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/avmb1/t1pci.c linux/drivers/isdn/avmb1/t1pci.c
--- v2.4.4/linux/drivers/isdn/avmb1/t1pci.c	Wed Apr 18 11:49:13 2001
+++ linux/drivers/isdn/avmb1/t1pci.c	Sat May 19 17:54:14 2001
@@ -94,7 +94,7 @@
 #include "capilli.h"
 #include "avmcard.h"
 
-static char *revision = "$Revision: 1.13.6.3 $";
+static char *revision = "$Revision: 1.13.6.5 $";
 
 #undef CONFIG_T1PCI_DEBUG
 #undef CONFIG_T1PCI_POLLDEBUG
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/eicon/bri.c linux/drivers/isdn/eicon/bri.c
--- v2.4.4/linux/drivers/isdn/eicon/bri.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/bri.c	Sat May 19 17:43:06 2001
@@ -21,8 +21,7 @@
  *
  */
 
-#include <sys/types.h>
-
+#include "eicon.h"
 #include "sys.h"
 #include "idi.h"
 #include "divas.h"
@@ -33,9 +32,6 @@
 #include "adapter.h"
 #include "uxio.h"
 
-#define PCI_COMMAND	0x04
-#define PCI_STATUS	0x06
-#define PCI_LATENCY	0x0D
 #define PCI_BADDR0	0x10
 #define PCI_BADDR1	0x14
 #define PCI_BADDR2	0x18
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/eicon/common.c linux/drivers/isdn/eicon/common.c
--- v2.4.4/linux/drivers/isdn/eicon/common.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/common.c	Sat May 19 17:43:06 2001
@@ -22,6 +22,7 @@
  */
 
 
+#include "eicon.h"
 #include "sys.h"
 #include "idi.h"
 #include "constant.h"
@@ -30,19 +31,14 @@
 #include "pr_pc.h"
 
 #include "uxio.h"
-#include <sys/types.h>
-
-#define MAX_ADDR_LEN
 
 #define DIVAS_LOAD_CMD		0x02
 #define DIVAS_START_CMD		0x03
 #define DIVAS_IRQ_RESET		0xC18
 #define DIVAS_IRQ_RESET_VAL	0xFE
 
-#define	PCI_COMMAND	0x04
-#define	PCI_STATUS	0x06
-#define	PCI_LATENCY	0x0D
-#define PCI_INTERRUPT	0x3C
+#define	PCI_LATENCY	PCI_LATENCY_TIMER
+#define PCI_INTERRUPT	PCI_INTERRUPT_LINE
 
 #define TEST_INT_DIVAS		0x11
 #define TEST_INT_DIVAS_BRI	0x12
@@ -93,7 +89,7 @@
         }
 
         if (tablelength > 0)
-          bcopy((caddr_t)DIDD_Table, (caddr_t)table, tablelength);
+          bcopy((void *)DIDD_Table, (void *)table, tablelength);
 
 	return;
 }
@@ -103,7 +99,7 @@
         if (tablelength > sizeof(DIDD_Table))
           tablelength = sizeof(DIDD_Table);
 
-	bcopy((caddr_t)table, (caddr_t)DIDD_Table, tablelength);
+	bcopy((void *)table, (void *)DIDD_Table, tablelength);
 
 	return;
 }
@@ -573,7 +569,7 @@
 
 		b = card->cfg.irq;
 
-		UxPciConfigWrite(card->hw, sizeof(b), PCI_INTERRUPT, &b);
+		UxPciConfigWrite(card->hw, sizeof(b), PCI_INTERRUPT_LINE, &b);
 
 		if (card_info->card_type != DIA_CARD_TYPE_DIVA_SERVER_Q)
 		{
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/eicon/eicon.h linux/drivers/isdn/eicon/eicon.h
--- v2.4.4/linux/drivers/isdn/eicon/eicon.h	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/eicon.h	Sat May 19 17:54:14 2001
@@ -1,4 +1,4 @@
-/* $Id: eicon.h,v 1.23.6.2 2001/02/13 11:43:30 kai Exp $
+/* $Id: eicon.h,v 1.23.6.3 2001/05/17 21:15:33 kai Exp $
  *
  * ISDN low-level module for Eicon active ISDN-Cards.
  *
@@ -147,9 +147,11 @@
 #include <linux/wait.h>
 #include <linux/delay.h>
 #include <linux/ctype.h>
+#include <linux/pci.h>
 
 #include <linux/isdn.h>
 #include <linux/isdnif.h>
+
 
 typedef struct {
   __u16 length __attribute__ ((packed)); /* length of data/parameter field */
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/eicon/kprintf.c linux/drivers/isdn/eicon/kprintf.c
--- v2.4.4/linux/drivers/isdn/eicon/kprintf.c	Fri Mar  2 11:12:08 2001
+++ linux/drivers/isdn/eicon/kprintf.c	Sat May 19 17:43:06 2001
@@ -27,13 +27,11 @@
  */
 
 
+#include "eicon.h"
 #include "sys.h"
 #include <stdarg.h>
 #undef MAX
 #undef MIN
-
-#include <sys/types.h>
-#include <sys/param.h>
 
 #include "divas.h"
 #include "divalog.h"
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/hysdn/boardergo.c linux/drivers/isdn/hysdn/boardergo.c
--- v2.4.4/linux/drivers/isdn/hysdn/boardergo.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/hysdn/boardergo.c	Sat May 19 17:54:14 2001
@@ -1,4 +1,4 @@
-/* $Id: boardergo.c,v 1.5.6.3 2001/03/13 16:17:09 kai Exp $
+/* $Id: boardergo.c,v 1.5.6.4 2001/04/20 02:42:00 keil Exp $
 
  * Linux driver for HYSDN cards, specific routines for ergo type boards.
  *
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/hysdn/hycapi.c linux/drivers/isdn/hysdn/hycapi.c
--- v2.4.4/linux/drivers/isdn/hysdn/hycapi.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/hysdn/hycapi.c	Sat May 19 17:54:14 2001
@@ -1,4 +1,4 @@
-/* $Id: hycapi.c,v 1.8.6.1 2001/02/16 16:43:30 kai Exp $
+/* $Id: hycapi.c,v 1.8.6.2 2001/04/20 02:42:00 keil Exp $
  *
  * Linux driver for HYSDN cards, CAPI2.0-Interface.
  * written by Ulrich Albrecht (u.albrecht@hypercope.de) for Hypercope GmbH
@@ -41,7 +41,7 @@
 #include "hysdn_defs.h"
 #include <linux/kernelcapi.h>
 
-static char hycapi_revision[]="$Revision: 1.11 $";
+static char hycapi_revision[]="$Revision: 1.8.6.2 $";
 
 unsigned int hycapi_enable = 0xffffffff; 
 MODULE_PARM(hycapi_enable, "i");
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/hysdn/hysdn_defs.h linux/drivers/isdn/hysdn/hysdn_defs.h
--- v2.4.4/linux/drivers/isdn/hysdn/hysdn_defs.h	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/hysdn/hysdn_defs.h	Sat May 19 17:54:14 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_defs.h,v 1.5.6.1 2000/11/28 12:02:47 kai Exp $
+/* $Id: hysdn_defs.h,v 1.5.6.2 2001/04/20 02:42:00 keil Exp $
 
  * Linux driver for HYSDN cards, global definitions and exported vars and functions.
  * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/hysdn/hysdn_net.c linux/drivers/isdn/hysdn/hysdn_net.c
--- v2.4.4/linux/drivers/isdn/hysdn/hysdn_net.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/hysdn/hysdn_net.c	Sat May 19 17:54:14 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_net.c,v 1.8.6.1 2001/02/16 16:43:30 kai Exp $
+/* $Id: hysdn_net.c,v 1.8.6.2 2001/04/20 02:42:00 keil Exp $
 
  * Linux driver for HYSDN cards, net (ethernet type) handling routines.
  *
@@ -41,7 +41,7 @@
 MODULE_PARM(hynet_enable, "i");
 
 /* store the actual version for log reporting */
-char *hysdn_net_revision = "$Revision: 1.10 $";
+char *hysdn_net_revision = "$Revision: 1.8.6.2 $";
 
 #define MAX_SKB_BUFFERS 20	/* number of buffers for keeping TX-data */
 
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/hysdn/hysdn_procconf.c linux/drivers/isdn/hysdn/hysdn_procconf.c
--- v2.4.4/linux/drivers/isdn/hysdn/hysdn_procconf.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/hysdn/hysdn_procconf.c	Sat May 19 17:54:14 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_procconf.c,v 1.8.6.1 2001/03/13 16:17:09 kai Exp $
+/* $Id: hysdn_procconf.c,v 1.8.6.2 2001/04/20 02:42:00 keil Exp $
 
  * Linux driver for HYSDN cards, /proc/net filesystem dir and conf functions.
  * written by Werner Cornelius (werner@titro.de) for Hypercope GmbH
@@ -31,7 +31,7 @@
 
 #include "hysdn_defs.h"
 
-static char *hysdn_procconf_revision = "$Revision: 1.8.6.1 $";
+static char *hysdn_procconf_revision = "$Revision: 1.8.6.2 $";
 
 #define INFO_OUT_LEN 80		/* length of info line including lf */
 
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/hysdn/hysdn_sched.c linux/drivers/isdn/hysdn/hysdn_sched.c
--- v2.4.4/linux/drivers/isdn/hysdn/hysdn_sched.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/hysdn/hysdn_sched.c	Sat May 19 17:54:14 2001
@@ -1,4 +1,4 @@
-/* $Id: hysdn_sched.c,v 1.5.6.1 2001/03/13 16:17:09 kai Exp $
+/* $Id: hysdn_sched.c,v 1.5.6.2 2001/04/20 02:42:00 keil Exp $
 
  * Linux driver for HYSDN cards, scheduler routines for handling exchange card <-> pc.
  *
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/isdn_common.c linux/drivers/isdn/isdn_common.c
--- v2.4.4/linux/drivers/isdn/isdn_common.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/isdn_common.c	Sat May 19 17:54:14 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_common.c,v 1.114.6.10 2001/04/08 19:14:00 kai Exp $
+/* $Id: isdn_common.c,v 1.114.6.11 2001/04/20 02:41:58 keil Exp $
 
  * Linux ISDN subsystem, common used functions (linklevel).
  *
@@ -51,7 +51,7 @@
 
 isdn_dev *dev;
 
-static char *isdn_revision = "$Revision: 1.114.6.10 $";
+static char *isdn_revision = "$Revision: 1.114.6.11 $";
 
 extern char *isdn_net_revision;
 extern char *isdn_tty_revision;
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/isdn_net.c linux/drivers/isdn/isdn_net.c
--- v2.4.4/linux/drivers/isdn/isdn_net.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/isdn_net.c	Sat May 19 17:54:14 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.c,v 1.140.6.3 2001/02/07 11:31:30 kai Exp $
+/* $Id: isdn_net.c,v 1.140.6.4 2001/04/20 02:41:58 keil Exp $
 
  * Linux ISDN subsystem, network interfaces and related functions (linklevel).
  *
@@ -190,7 +190,7 @@
 static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
 static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp);
 
-char *isdn_net_revision = "$Revision: 1.144 $";
+char *isdn_net_revision = "$Revision: 1.140.6.4 $";
 
  /*
   * Code for raw-networking over ISDN
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/isdn_net.h linux/drivers/isdn/isdn_net.h
--- v2.4.4/linux/drivers/isdn/isdn_net.h	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/isdn_net.h	Sat May 19 17:54:14 2001
@@ -1,4 +1,4 @@
-/* $Id: isdn_net.h,v 1.19 2000/06/21 09:54:29 keil Exp $
+/* $Id: isdn_net.h,v 1.19.6.1 2001/04/20 02:41:58 keil Exp $
 
  * header for Linux ISDN subsystem, network related functions (linklevel).
  *
diff -u --recursive --new-file v2.4.4/linux/drivers/isdn/isdn_ppp.c linux/drivers/isdn/isdn_ppp.c
--- v2.4.4/linux/drivers/isdn/isdn_ppp.c	Wed Apr 18 11:49:14 2001
+++ linux/drivers/isdn/isdn_ppp.c	Tue May 22 10:23:16 2001
@@ -819,7 +819,7 @@
 		      kmalloc(sizeof(struct ippp_struct), GFP_KERNEL))) {
 			printk(KERN_WARNING "isdn_ppp_init: Could not alloc ippp_table\n");
 			for (j = 0; j < i; j++)
-				kfree(ippp_table[i]);
+				kfree(ippp_table[j]);
 			return -1;
 		}
 		memset((char *) ippp_table[i], 0, sizeof(struct ippp_struct));
diff -u --recursive --new-file v2.4.4/linux/drivers/macintosh/via-cuda.c linux/drivers/macintosh/via-cuda.c
--- v2.4.4/linux/drivers/macintosh/via-cuda.c	Sun Sep 17 09:48:05 2000
+++ linux/drivers/macintosh/via-cuda.c	Tue May  1 16:05:00 2001
@@ -170,7 +170,7 @@
     }
 
     /* Clear and enable interrupts, but only on PPC. On 68K it's done  */
-    /* for us by the the main VIA driver in arch/m68k/mac/via.c        */
+    /* for us by the main VIA driver in arch/m68k/mac/via.c        */
 
 #ifndef CONFIG_MAC
     via[IFR] = 0x7f; eieio();	/* clear interrupts by writing 1s */
diff -u --recursive --new-file v2.4.4/linux/drivers/md/md.c linux/drivers/md/md.c
--- v2.4.4/linux/drivers/md/md.c	Fri Apr  6 10:42:55 2001
+++ linux/drivers/md/md.c	Sun May 20 11:34:05 2001
@@ -1097,7 +1097,7 @@
 	}
 	memset(rdev, 0, sizeof(*rdev));
 
-	if (get_super(newdev)) {
+	if (is_mounted(newdev)) {
 		printk("md: can not import %s, has active inodes!\n",
 			partition_name(newdev));
 		err = -EBUSY;
@@ -1735,7 +1735,7 @@
  	}
  
  	/* this shouldn't be needed as above would have fired */
-	if (!ro && get_super(dev)) {
+	if (!ro && is_mounted(dev)) {
 		printk (STILL_MOUNTED, mdidx(mddev));
 		OUT(-EBUSY);
 	}
@@ -2464,7 +2464,7 @@
 	int ret;
 
 	fsync_dev(mddev_to_kdev(mddev));
-	ret = md_error(mddev_to_kdev(mddev), dev);
+	ret = md_error(mddev, dev);
 	return ret;
 }
 
@@ -2938,13 +2938,11 @@
 }
 
 
-int md_error (kdev_t dev, kdev_t rdev)
+int md_error (mddev_t *mddev, kdev_t rdev)
 {
-	mddev_t *mddev;
 	mdk_rdev_t * rrdev;
 	int rc;
 
-	mddev = kdev_to_mddev(dev);
 /*	printk("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",MAJOR(dev),MINOR(dev),MAJOR(rdev),MINOR(rdev), __builtin_return_address(0),__builtin_return_address(1),__builtin_return_address(2),__builtin_return_address(3));
  */
 	if (!mddev) {
@@ -2999,7 +2997,7 @@
 	int sz = 0;
 	unsigned long max_blocks, resync, res, dt, db, rt;
 
-	resync = mddev->curr_resync - atomic_read(&mddev->recovery_active);
+	resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active))/2;
 	max_blocks = mddev->sb->size;
 
 	/*
@@ -3044,7 +3042,7 @@
 	 */
 	dt = ((jiffies - mddev->resync_mark) / HZ);
 	if (!dt) dt++;
-	db = resync - mddev->resync_mark_cnt;
+	db = resync - (mddev->resync_mark_cnt/2);
 	rt = (dt * ((max_blocks-resync) / (db/100+1)))/100;
 	
 	sz += sprintf(page + sz, " finish=%lu.%lumin", rt / 60, (rt % 60)/6);
@@ -3219,7 +3217,7 @@
 
 void md_done_sync(mddev_t *mddev, int blocks, int ok)
 {
-	/* another "blocks" (1K) blocks have been synced */
+	/* another "blocks" (512byte) blocks have been synced */
 	atomic_sub(blocks, &mddev->recovery_active);
 	wake_up(&mddev->recovery_wait);
 	if (!ok) {
@@ -3232,7 +3230,7 @@
 int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
 {
 	mddev_t *mddev2;
-	unsigned int max_blocks, currspeed,
+	unsigned int max_sectors, currspeed,
 		j, window, err, serialize;
 	kdev_t read_disk = mddev_to_kdev(mddev);
 	unsigned long mark[SYNC_MARKS];
@@ -3269,7 +3267,7 @@
 
 	mddev->curr_resync = 1;
 
-	max_blocks = mddev->sb->size;
+	max_sectors = mddev->sb->size<<1;
 
 	printk(KERN_INFO "md: syncing RAID array md%d\n", mdidx(mddev));
 	printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed: %d KB/sec/disc.\n",
@@ -3293,23 +3291,23 @@
 	/*
 	 * Tune reconstruction:
 	 */
-	window = MAX_READAHEAD*(PAGE_SIZE/1024);
-	printk(KERN_INFO "md: using %dk window, over a total of %d blocks.\n",window,max_blocks);
+	window = MAX_READAHEAD*(PAGE_SIZE/512);
+	printk(KERN_INFO "md: using %dk window, over a total of %d blocks.\n",window/2,max_sectors/2);
 
 	atomic_set(&mddev->recovery_active, 0);
 	init_waitqueue_head(&mddev->recovery_wait);
 	last_check = 0;
-	for (j = 0; j < max_blocks;) {
-		int blocks;
+	for (j = 0; j < max_sectors;) {
+		int sectors;
 
-		blocks = mddev->pers->sync_request(mddev, j);
+		sectors = mddev->pers->sync_request(mddev, j);
 
-		if (blocks < 0) {
-			err = blocks;
+		if (sectors < 0) {
+			err = sectors;
 			goto out;
 		}
-		atomic_add(blocks, &mddev->recovery_active);
-		j += blocks;
+		atomic_add(sectors, &mddev->recovery_active);
+		j += sectors;
 		mddev->curr_resync = j;
 
 		if (last_check + window > j)
@@ -3327,7 +3325,7 @@
 			mark_cnt[next] = j - atomic_read(&mddev->recovery_active);
 			last_mark = next;
 		}
-			
+
 
 		if (md_signal_pending(current)) {
 			/*
@@ -3352,7 +3350,7 @@
 		if (md_need_resched(current))
 			schedule();
 
-		currspeed = (j-mddev->resync_mark_cnt)/((jiffies-mddev->resync_mark)/HZ +1) +1;
+		currspeed = (j-mddev->resync_mark_cnt)/2/((jiffies-mddev->resync_mark)/HZ +1) +1;
 
 		if (currspeed > sysctl_speed_limit_min) {
 			current->nice = 19;
diff -u --recursive --new-file v2.4.4/linux/drivers/md/raid1.c linux/drivers/md/raid1.c
--- v2.4.4/linux/drivers/md/raid1.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/md/raid1.c	Sat May 19 12:50:04 2001
@@ -388,7 +388,7 @@
 	 * this branch is our 'one mirror IO has finished' event handler:
 	 */
 	if (!uptodate)
-		md_error (mddev_to_kdev(r1_bh->mddev), bh->b_dev);
+		md_error (r1_bh->mddev, bh->b_dev);
 	else
 		/*
 		 * Set R1BH_Uptodate in our master buffer_head, so that
@@ -832,6 +832,7 @@
 	struct mirror_info *tmp, *sdisk, *fdisk, *rdisk, *adisk;
 	mdp_super_t *sb = mddev->sb;
 	mdp_disk_t *failed_desc, *spare_desc, *added_desc;
+	mdk_rdev_t *spare_rdev, *failed_rdev;
 
 	print_raid1_conf(conf);
 	md_spin_lock_irq(&conf->device_lock);
@@ -989,6 +990,16 @@
 		/*
 		 * do the switch finally
 		 */
+		spare_rdev = find_rdev_nr(mddev, spare_desc->number);
+		failed_rdev = find_rdev_nr(mddev, failed_desc->number);
+
+		/* There must be a spare_rdev, but there may not be a
+		 * failed_rdev.  That slot might be empty...
+		 */
+		spare_rdev->desc_nr = failed_desc->number;
+		if (failed_rdev)
+			failed_rdev->desc_nr = spare_desc->number;
+		
 		xchg_values(*spare_desc, *failed_desc);
 		xchg_values(*fdisk, *sdisk);
 
@@ -1187,7 +1198,7 @@
 				raid1_map (mddev, &bh->b_dev, bh->b_size >> 9);
 				if (bh->b_dev == dev) {
 					printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr);
-					md_done_sync(mddev, bh->b_size>>10, 0);
+					md_done_sync(mddev, bh->b_size>>9, 0);
 				} else {
 					printk (REDIRECT_SECTOR,
 						partition_name(bh->b_dev), bh->b_blocknr);
@@ -1294,7 +1305,7 @@
  * issue suitable write requests
  */
 
-static int raid1_sync_request (mddev_t *mddev, unsigned long block_nr)
+static int raid1_sync_request (mddev_t *mddev, unsigned long sector_nr)
 {
 	raid1_conf_t *conf = mddev_to_conf(mddev);
 	struct mirror_info *mirror;
@@ -1304,7 +1315,7 @@
 	int disk;
 
 	spin_lock_irq(&conf->segment_lock);
-	if (!block_nr) {
+	if (!sector_nr) {
 		/* initialize ...*/
 		int buffs;
 		conf->start_active = 0;
@@ -1324,9 +1335,9 @@
 		if (conf->cnt_ready || conf->cnt_active)
 			MD_BUG();
 	}
-	while ((block_nr<<1) >= conf->start_pending) {
+	while (sector_nr >= conf->start_pending) {
 		PRINTK("wait .. sect=%lu start_active=%d ready=%d pending=%d future=%d, cnt_done=%d active=%d ready=%d pending=%d future=%d\n",
-			block_nr<<1, conf->start_active, conf->start_ready, conf->start_pending, conf->start_future,
+			sector_nr, conf->start_active, conf->start_ready, conf->start_pending, conf->start_future,
 			conf->cnt_done, conf->cnt_active, conf->cnt_ready, conf->cnt_pending, conf->cnt_future);
 		wait_event_lock_irq(conf->wait_done,
 					!conf->cnt_active,
@@ -1372,10 +1383,10 @@
 	r1_bh->cmd = SPECIAL;
 	bh = &r1_bh->bh_req;
 
-	bh->b_blocknr = block_nr;
-	bsize = 1024;
+	bh->b_blocknr = sector_nr;
+	bsize = 512;
 	while (!(bh->b_blocknr & 1) && bsize < PAGE_SIZE
-			&& (bh->b_blocknr+2)*(bsize>>10) < mddev->sb->size) {
+			&& (bh->b_blocknr+2)*(bsize>>9) < (mddev->sb->size *2)) {
 		bh->b_blocknr >>= 1;
 		bsize <<= 1;
 	}
@@ -1392,13 +1403,13 @@
 		BUG();
 	bh->b_end_io = end_sync_read;
 	bh->b_private = r1_bh;
-	bh->b_rsector = block_nr<<1;
+	bh->b_rsector = sector_nr;
 	init_waitqueue_head(&bh->b_wait);
 
 	generic_make_request(READ, bh);
 	md_sync_acct(bh->b_dev, bh->b_size/512);
 
-	return (bsize >> 10);
+	return (bsize >> 9);
 
 nomem:
 	raid1_shrink_buffers(conf);
@@ -1415,7 +1426,7 @@
 	 * We don't do much here, just schedule handling by raid1d
 	 */
 	if (!uptodate)
-		md_error (mddev_to_kdev(r1_bh->mddev), bh->b_dev);
+		md_error (r1_bh->mddev, bh->b_dev);
 	else
 		set_bit(R1BH_Uptodate, &r1_bh->state);
 	raid1_reschedule_retry(r1_bh);
@@ -1426,78 +1437,15 @@
  	struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_private);
 	
 	if (!uptodate)
- 		md_error (mddev_to_kdev(r1_bh->mddev), bh->b_dev);
+ 		md_error (r1_bh->mddev, bh->b_dev);
 	if (atomic_dec_and_test(&r1_bh->remaining)) {
 		mddev_t *mddev = r1_bh->mddev;
  		unsigned long sect = bh->b_blocknr * (bh->b_size>>9);
 		int size = bh->b_size;
 		raid1_free_buf(r1_bh);
 		sync_request_done(sect, mddev_to_conf(mddev));
-		md_done_sync(mddev,size>>10, uptodate);
-	}
-}
-
-/*
- * This will catch the scenario in which one of the mirrors was
- * mounted as a normal device rather than as a part of a raid set.
- *
- * check_consistency is very personality-dependent, eg. RAID5 cannot
- * do this check, it uses another method.
- */
-static int __check_consistency (mddev_t *mddev, int row)
-{
-	raid1_conf_t *conf = mddev_to_conf(mddev);
-	int disks = MD_SB_DISKS;
-	kdev_t dev;
-	struct buffer_head *bh = NULL;
-	int i, rc = 0;
-	char *buffer = NULL;
-
-	for (i = 0; i < disks; i++) {
-		printk("(checking disk %d)\n",i);
-		if (!conf->mirrors[i].operational)
-			continue;
-		printk("(really checking disk %d)\n",i);
-		dev = conf->mirrors[i].dev;
-		set_blocksize(dev, 4096);
-		if ((bh = bread(dev, row / 4, 4096)) == NULL)
-			break;
-		if (!buffer) {
-			buffer = (char *) __get_free_page(GFP_KERNEL);
-			if (!buffer)
-				break;
-			memcpy(buffer, bh->b_data, 4096);
-		} else if (memcmp(buffer, bh->b_data, 4096)) {
-			rc = 1;
-			break;
-		}
-		bforget(bh);
-		fsync_dev(dev);
-		invalidate_buffers(dev);
-		bh = NULL;
-	}
-	if (buffer)
-		free_page((unsigned long) buffer);
-	if (bh) {
-		dev = bh->b_dev;
-		bforget(bh);
-		fsync_dev(dev);
-		invalidate_buffers(dev);
+		md_done_sync(mddev,size>>9, uptodate);
 	}
-	return rc;
-}
-
-static int check_consistency (mddev_t *mddev)
-{
-	if (__check_consistency(mddev, 0))
-/*
- * we do not do this currently, as it's perfectly possible to
- * have an inconsistent array when it's freshly created. Only
- * newly written data has to be consistent.
- */
-		return 0;
-
-	return 0;
 }
 
 #define INVALID_LEVEL KERN_WARNING \
@@ -1530,9 +1478,6 @@
 #define NONE_OPERATIONAL KERN_ERR \
 "raid1: no operational mirrors for md%d\n"
 
-#define RUNNING_CKRAID KERN_ERR \
-"raid1: detected mirror differences -- running resync\n"
-
 #define ARRAY_IS_ACTIVE KERN_INFO \
 "raid1: raid set md%d active with %d out of %d mirrors\n"
 
@@ -1714,17 +1659,6 @@
 		start_recovery = 1;
 	}
 
-	if (!start_recovery && (sb->state & (1 << MD_SB_CLEAN))) {
-		/*
-		 * we do sanity checks even if the device says
-		 * it's clean ...
-		 */
-		if (check_consistency(mddev)) {
-			printk(RUNNING_CKRAID);
-			sb->state &= ~(1 << MD_SB_CLEAN);
-		}
-	}
-
 	{
 		const char * name = "raid1d";
 
@@ -1794,7 +1728,6 @@
 #undef OPERATIONAL
 #undef SPARE
 #undef NONE_OPERATIONAL
-#undef RUNNING_CKRAID
 #undef ARRAY_IS_ACTIVE
 
 static int raid1_stop_resync (mddev_t *mddev)
diff -u --recursive --new-file v2.4.4/linux/drivers/md/raid5.c linux/drivers/md/raid5.c
--- v2.4.4/linux/drivers/md/raid5.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/md/raid5.c	Sat May 19 12:50:04 2001
@@ -156,9 +156,9 @@
 			return 1;
 		memset(bh, 0, sizeof (struct buffer_head));
 		init_waitqueue_head(&bh->b_wait);
-		page = alloc_page(priority);
-		bh->b_data = page_address(page);
-		if (!bh->b_data) {
+		if ((page = alloc_page(priority)))
+			bh->b_data = page_address(page);
+		else {
 			kfree(bh);
 			return 1;
 		}
@@ -412,7 +412,7 @@
 			spin_lock_irqsave(&conf->device_lock, flags);
 		}
 	} else {
-		md_error(mddev_to_kdev(conf->mddev), bh->b_dev);
+		md_error(conf->mddev, bh->b_dev);
 		clear_bit(BH_Uptodate, &bh->b_state);
 	}
 	clear_bit(BH_Lock, &bh->b_state);
@@ -440,7 +440,7 @@
 
 	md_spin_lock_irqsave(&conf->device_lock, flags);
 	if (!uptodate)
-		md_error(mddev_to_kdev(conf->mddev), bh->b_dev);
+		md_error(conf->mddev, bh->b_dev);
 	clear_bit(BH_Lock, &bh->b_state);
 	set_bit(STRIPE_HANDLE, &sh->state);
 	__release_stripe(conf, sh);
@@ -886,7 +886,7 @@
 			}
 		}
 		if (syncing) {
-			md_done_sync(conf->mddev, (sh->size>>10) - sh->sync_redone,0);
+			md_done_sync(conf->mddev, (sh->size>>9) - sh->sync_redone,0);
 			clear_bit(STRIPE_SYNCING, &sh->state);
 			syncing = 0;
 		}			
@@ -1059,7 +1059,7 @@
 		}
 	}
 	if (syncing && locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) {
-		md_done_sync(conf->mddev, (sh->size>>10) - sh->sync_redone,1);
+		md_done_sync(conf->mddev, (sh->size>>9) - sh->sync_redone,1);
 		clear_bit(STRIPE_SYNCING, &sh->state);
 	}
 	
@@ -1153,13 +1153,13 @@
 	return correct_size;
 }
 
-static int raid5_sync_request (mddev_t *mddev, unsigned long block_nr)
+static int raid5_sync_request (mddev_t *mddev, unsigned long sector_nr)
 {
 	raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
 	struct stripe_head *sh;
 	int sectors_per_chunk = conf->chunk_size >> 9;
-	unsigned long stripe = (block_nr<<1)/sectors_per_chunk;
-	int chunk_offset = (block_nr<<1) % sectors_per_chunk;
+	unsigned long stripe = sector_nr/sectors_per_chunk;
+	int chunk_offset = sector_nr % sectors_per_chunk;
 	int dd_idx, pd_idx;
 	unsigned long first_sector;
 	int raid_disks = conf->raid_disks;
@@ -1167,9 +1167,9 @@
 	int redone = 0;
 	int bufsize;
 
-	sh = get_active_stripe(conf, block_nr<<1, 0, 0);
+	sh = get_active_stripe(conf, sector_nr, 0, 0);
 	bufsize = sh->size;
-	redone = block_nr-(sh->sector>>1);
+	redone = sector_nr - sh->sector;
 	first_sector = raid5_compute_sector(stripe*data_disks*sectors_per_chunk
 		+ chunk_offset, raid_disks, data_disks, &dd_idx, &pd_idx, conf);
 	sh->pd_idx = pd_idx;
@@ -1182,7 +1182,7 @@
 	handle_stripe(sh);
 	release_stripe(sh);
 
-	return (bufsize>>10)-redone;
+	return (bufsize>>9)-redone;
 }
 
 /*
@@ -1256,76 +1256,6 @@
 	printk("raid5: resync finished.\n");
 }
 
-static int __check_consistency (mddev_t *mddev, int row)
-{
-	raid5_conf_t *conf = mddev->private;
-	kdev_t dev;
-	struct buffer_head *bh[MD_SB_DISKS], *tmp = NULL;
-	int i, ret = 0, nr = 0, count;
-	struct buffer_head *bh_ptr[MAX_XOR_BLOCKS];
-
-	if (conf->working_disks != conf->raid_disks)
-		goto out;
-	tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
-	tmp->b_size = 4096;
-	tmp->b_page = alloc_page(GFP_KERNEL);
-	tmp->b_data = page_address(tmp->b_page);
-	if (!tmp->b_data)
-		goto out;
-	md_clear_page(tmp->b_data);
-	memset(bh, 0, MD_SB_DISKS * sizeof(struct buffer_head *));
-	for (i = 0; i < conf->raid_disks; i++) {
-		dev = conf->disks[i].dev;
-		set_blocksize(dev, 4096);
-		bh[i] = bread(dev, row / 4, 4096);
-		if (!bh[i])
-			break;
-		nr++;
-	}
-	if (nr == conf->raid_disks) {
-		bh_ptr[0] = tmp;
-		count = 1;
-		for (i = 1; i < nr; i++) {
-			bh_ptr[count++] = bh[i];
-			if (count == MAX_XOR_BLOCKS) {
-				xor_block(count, &bh_ptr[0]);
-				count = 1;
-			}
-		}
-		if (count != 1) {
-			xor_block(count, &bh_ptr[0]);
-		}
-		if (memcmp(tmp->b_data, bh[0]->b_data, 4096))
-			ret = 1;
-	}
-	for (i = 0; i < conf->raid_disks; i++) {
-		dev = conf->disks[i].dev;
-		if (bh[i]) {
-			bforget(bh[i]);
-			bh[i] = NULL;
-		}
-		fsync_dev(dev);
-		invalidate_buffers(dev);
-	}
-	free_page((unsigned long) tmp->b_data);
-out:
-	if (tmp)
-		kfree(tmp);
-	return ret;
-}
-
-static int check_consistency (mddev_t *mddev)
-{
-	if (__check_consistency(mddev, 0))
-/*
- * We are not checking this currently, as it's legitimate to have
- * an inconsistent array, at creation time.
- */
-		return 0;
-
-	return 0;
-}
-
 static int raid5_run (mddev_t *mddev)
 {
 	raid5_conf_t *conf;
@@ -1485,12 +1415,6 @@
 		start_recovery = 1;
 	}
 
-	if (!start_recovery && (sb->state & (1 << MD_SB_CLEAN)) &&
-			check_consistency(mddev)) {
-		printk(KERN_ERR "raid5: detected raid-5 superblock xor inconsistency -- running resync\n");
-		sb->state &= ~(1 << MD_SB_CLEAN);
-	}
-
 	{
 		const char * name = "raid5d";
 
@@ -1704,6 +1628,7 @@
 	struct disk_info *tmp, *sdisk, *fdisk, *rdisk, *adisk;
 	mdp_super_t *sb = mddev->sb;
 	mdp_disk_t *failed_desc, *spare_desc, *added_desc;
+	mdk_rdev_t *spare_rdev, *failed_rdev;
 
 	print_raid5_conf(conf);
 	md_spin_lock_irq(&conf->device_lock);
@@ -1875,6 +1800,16 @@
 		/*
 		 * do the switch finally
 		 */
+		spare_rdev = find_rdev_nr(mddev, spare_desc->number);
+		failed_rdev = find_rdev_nr(mddev, failed_desc->number);
+
+		/* There must be a spare_rdev, but there may not be a
+		 * failed_rdev.  That slot might be empty...
+		 */
+		spare_rdev->desc_nr = failed_desc->number;
+		if (failed_rdev)
+			failed_rdev->desc_nr = spare_desc->number;
+		
 		xchg_values(*spare_desc, *failed_desc);
 		xchg_values(*fdisk, *sdisk);
 
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-aimslab.c linux/drivers/media/radio/radio-aimslab.c
--- v2.4.4/linux/drivers/media/radio/radio-aimslab.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/radio/radio-aimslab.c	Sat May 19 17:43:06 2001
@@ -42,6 +42,7 @@
 #endif
 
 static int io = CONFIG_RADIO_RTRACK_PORT; 
+static int radio_nr = -1;
 static int users = 0;
 static struct semaphore lock;
 
@@ -345,7 +346,7 @@
 
 	rtrack_radio.priv=&rtrack_unit;
 	
-	if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO)==-1)
+	if(video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr)==-1)
 	{
 		release_region(io, 2);
 		return -EINVAL;
@@ -371,6 +372,7 @@
 MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
+MODULE_PARM(radio_nr, "i");
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-aztech.c linux/drivers/media/radio/radio-aztech.c
--- v2.4.4/linux/drivers/media/radio/radio-aztech.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/radio/radio-aztech.c	Sat May 19 17:43:06 2001
@@ -40,6 +40,7 @@
 #endif
 
 static int io = CONFIG_RADIO_AZTECH_PORT; 
+static int radio_nr = -1;
 static int radio_wait_time = 1000;
 static int users = 0;
 static struct semaphore lock;
@@ -297,7 +298,7 @@
 	init_MUTEX(&lock);
 	aztech_radio.priv=&aztech_unit;
 	
-	if(video_register_device(&aztech_radio, VFL_TYPE_RADIO)==-1)
+	if(video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr)==-1)
 	{
 		release_region(io,2);
 		return -EINVAL;
@@ -312,6 +313,7 @@
 MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
 MODULE_DESCRIPTION("A driver for the Aztech radio card.");
 MODULE_PARM(io, "i");
+MODULE_PARM(radio_nr, "i");
 MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
 
 EXPORT_NO_SYMBOLS;
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-cadet.c linux/drivers/media/radio/radio-cadet.c
--- v2.4.4/linux/drivers/media/radio/radio-cadet.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/radio/radio-cadet.c	Sat May 19 17:43:06 2001
@@ -35,6 +35,7 @@
 #define RDS_BUFFER 256
 
 static int io=-1;		/* default to isapnp activation */
+static int radio_nr = -1;
 static int users=0;
 static int curtuner=0;
 static int tunestat=0;
@@ -616,7 +617,7 @@
 	}
 	if (!request_region(io,2,"cadet"))
 		return -EBUSY;
-	if(video_register_device(&cadet_radio,VFL_TYPE_RADIO)==-1) {
+	if(video_register_device(&cadet_radio,VFL_TYPE_RADIO,radio_nr)==-1) {
 		release_region(io,2);
 		return -EINVAL;
 	}
@@ -630,6 +631,7 @@
 MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
+MODULE_PARM(radio_nr, "i");
 
 static struct isapnp_device_id id_table[] __devinitdata = {
 	{ 	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-gemtek.c linux/drivers/media/radio/radio-gemtek.c
--- v2.4.4/linux/drivers/media/radio/radio-gemtek.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/radio/radio-gemtek.c	Sat May 19 17:43:06 2001
@@ -30,6 +30,7 @@
 #endif
 
 static int io = CONFIG_RADIO_GEMTEK_PORT; 
+static int radio_nr = -1;
 static int users = 0;
 static spinlock_t lock;
 
@@ -272,7 +273,7 @@
 
 	gemtek_radio.priv=&gemtek_unit;
 	
-	if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO)==-1)
+	if(video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr)==-1)
 	{
 		release_region(io, 4);
 		return -EINVAL;
@@ -295,6 +296,7 @@
 MODULE_DESCRIPTION("A driver for the GemTek Radio Card");
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the GemTek card (0x20c, 0x30c, 0x24c or 0x34c (0x20c or 0x248 have been reported to work for the combined sound/radiocard)).");
+MODULE_PARM(radio_nr, "i");
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-maestro.c linux/drivers/media/radio/radio-maestro.c
--- v2.4.4/linux/drivers/media/radio/radio-maestro.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/radio/radio-maestro.c	Sat May 19 17:43:06 2001
@@ -61,6 +61,8 @@
 
 #define BITS2FREQ(x)	((x) * FREQ_STEP - FREQ_IF)
 
+static int radio_nr = -1;
+MODULE_PARM(radio_nr, "i");
 
 
 static int radio_open(struct video_device *, int);
@@ -359,7 +361,7 @@
 	init_MUTEX(&radio_unit.lock);
 	
 	if(radio_power_on(&radio_unit)) {
-		if(video_register_device(&maestro_radio, VFL_TYPE_RADIO)==-1) {
+		if(video_register_device(&maestro_radio, VFL_TYPE_RADIO, radio_nr)==-1) {
 			printk("radio-maestro: can't register device!");
 			return 0;
 		}
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-maxiradio.c linux/drivers/media/radio/radio-maxiradio.c
--- v2.4.4/linux/drivers/media/radio/radio-maxiradio.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/radio/radio-maxiradio.c	Sat May 19 17:43:06 2001
@@ -56,6 +56,9 @@
 /* TEA5757 pin mappings */
 const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ;
 
+static int radio_nr = -1;
+MODULE_PARM(radio_nr, "i");
+
 
 #define FREQ_LO		 50*16000
 #define FREQ_HI		150*16000
@@ -331,7 +334,7 @@
 	init_MUTEX(&radio_unit.lock);
 	maxiradio_radio.priv = &radio_unit;
 
-	if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO)==-1) {
+	if(video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr)==-1) {
 	        printk("radio-maxiradio: can't register device!");
 	        goto err_out_free_region;
 	}
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-miropcm20.c linux/drivers/media/radio/radio-miropcm20.c
--- v2.4.4/linux/drivers/media/radio/radio-miropcm20.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/media/radio/radio-miropcm20.c	Sat May 19 17:43:06 2001
@@ -30,6 +30,8 @@
 #include "../../sound/aci.h"
 
 static int users = 0;
+static int radio_nr = -1;
+MODULE_PARM(radio_nr, "i");
 
 struct pcm20_device
 {
@@ -258,7 +260,7 @@
 
 static int __init pcm20_init(void)
 {
-	if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO)==-1)
+	if(video_register_device(&pcm20_radio, VFL_TYPE_RADIO, radio_nr)==-1)
 		return -EINVAL;
 		
 	if(attach_aci_rds()<0) {
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-rtrack2.c linux/drivers/media/radio/radio-rtrack2.c
--- v2.4.4/linux/drivers/media/radio/radio-rtrack2.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/radio/radio-rtrack2.c	Sat May 19 17:43:06 2001
@@ -23,6 +23,7 @@
 #endif
 
 static int io = CONFIG_RADIO_RTRACK2_PORT; 
+static int radio_nr = -1;
 static int users = 0;
 static spinlock_t lock;
 
@@ -238,7 +239,7 @@
 	rtrack2_radio.priv=&rtrack2_unit;
 
 	spin_lock_init(&lock);	
-	if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO)==-1)
+	if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr)==-1)
 	{
 		release_region(io, 4);
 		return -EINVAL;
@@ -257,6 +258,7 @@
 MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
+MODULE_PARM(radio_nr, "i");
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-sf16fmi.c linux/drivers/media/radio/radio-sf16fmi.c
--- v2.4.4/linux/drivers/media/radio/radio-sf16fmi.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/radio/radio-sf16fmi.c	Sat May 19 17:43:06 2001
@@ -37,6 +37,7 @@
 #endif
 
 static int io = CONFIG_RADIO_SF16FMI_PORT; 
+static int radio_nr = -1;
 static int users = 0;
 static struct semaphore lock;
 
@@ -304,7 +305,7 @@
 	
 	init_MUTEX(&lock);
 	
-	if(video_register_device(&fmi_radio, VFL_TYPE_RADIO)==-1)
+	if(video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr)==-1)
 	{
 		release_region(io, 2);
 		return -EINVAL;
@@ -321,6 +322,7 @@
 MODULE_DESCRIPTION("A driver for the SF16MI radio.");
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
+MODULE_PARM(radio_nr, "i");
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-terratec.c linux/drivers/media/radio/radio-terratec.c
--- v2.4.4/linux/drivers/media/radio/radio-terratec.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/radio/radio-terratec.c	Sat May 19 17:43:06 2001
@@ -50,6 +50,7 @@
 /*******************************************************************/
 
 static int io = CONFIG_RADIO_TERRATEC_PORT; 
+static int radio_nr = -1;
 static int users = 0;
 static spinlock_t lock;
 
@@ -318,7 +319,7 @@
 	
 	spin_lock_init(&lock);
 	
-	if(video_register_device(&terratec_radio, VFL_TYPE_RADIO)==-1)
+	if(video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr)==-1)
 	{
 		release_region(io,2);
 		return -EINVAL;
@@ -339,6 +340,7 @@
 MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
+MODULE_PARM(radio_nr, "i");
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-trust.c linux/drivers/media/radio/radio-trust.c
--- v2.4.4/linux/drivers/media/radio/radio-trust.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/radio/radio-trust.c	Sat May 19 17:43:06 2001
@@ -31,6 +31,7 @@
 #endif
 
 static int io = CONFIG_RADIO_TRUST_PORT; 
+static int radio_nr = -1;
 static int ioval = 0xf;
 static int users = 0;
 static __u16 curvol;
@@ -303,7 +304,7 @@
 		printk(KERN_ERR "trust: port 0x%x already in use\n", io);
 		return -EBUSY;
 	}
-	if(video_register_device(&trust_radio, VFL_TYPE_RADIO)==-1)
+	if(video_register_device(&trust_radio, VFL_TYPE_RADIO, radio_nr)==-1)
 	{
 		release_region(io, 2);
 		return -EINVAL;
@@ -332,6 +333,7 @@
 MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
+MODULE_PARM(radio_nr, "i");
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-typhoon.c linux/drivers/media/radio/radio-typhoon.c
--- v2.4.4/linux/drivers/media/radio/radio-typhoon.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/radio/radio-typhoon.c	Sat May 19 17:43:06 2001
@@ -321,10 +321,12 @@
 MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
 MODULE_PARM(mutefreq, "i");
 MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
+MODULE_PARM(radio_nr, "i");
 
 EXPORT_NO_SYMBOLS;
 
 static int io = -1;
+static int radio_nr = -1;
 
 #ifdef MODULE
 static unsigned long mutefreq = 0;
@@ -356,7 +358,7 @@
 	}
 
 	typhoon_radio.priv = &typhoon_unit;
-	if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO) == -1)
+	if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO, radio_nr) == -1)
 	{
 		release_region(io, 8);
 		return -EINVAL;
diff -u --recursive --new-file v2.4.4/linux/drivers/media/radio/radio-zoltrix.c linux/drivers/media/radio/radio-zoltrix.c
--- v2.4.4/linux/drivers/media/radio/radio-zoltrix.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/radio/radio-zoltrix.c	Sat May 19 17:43:06 2001
@@ -39,6 +39,7 @@
 #endif
 
 static int io = CONFIG_RADIO_ZOLTRIX_PORT;
+static int radio_nr = -1;
 static int users = 0;
 
 struct zol_device {
@@ -365,7 +366,7 @@
 		return -EBUSY;
 	}
 
-	if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO) == -1)
+	if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) == -1)
 	{
 		release_region(io, 2);
 		return -EINVAL;
@@ -394,6 +395,7 @@
 MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
 MODULE_PARM(io, "i");
 MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
+MODULE_PARM(radio_nr, "i");
 
 EXPORT_NO_SYMBOLS;
 
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/adv7175.c linux/drivers/media/video/adv7175.c
--- v2.4.4/linux/drivers/media/video/adv7175.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/media/video/adv7175.c	Sat May 19 17:43:06 2001
@@ -0,0 +1,478 @@
+#define DEBUGLEVEL 0
+/* 
+    adv7175 - adv7175a video encoder driver version 0.0.3
+
+    Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+
+    Copyright (C) 1999 Wolfgang Scherr <scherr@net4you.net>
+    Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
+       - some corrections for Pinnacle Systems Inc. DC10plus card.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/malloc.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/signal.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <linux/sched.h>
+#include <asm/segment.h>
+#include <linux/types.h>
+#include <linux/wrapper.h>
+
+#include <linux/videodev.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+
+#include <linux/i2c-old.h>
+
+#include <linux/video_encoder.h>
+
+#if (DEBUGLEVEL > 0)
+#define DEBUG(x...)  x		/* Debug driver */
+#else
+#define DEBUG(x...)
+#endif
+
+/* ----------------------------------------------------------------------- */
+
+struct adv7175 {
+	struct i2c_bus *bus;
+	int addr;
+	unsigned char reg[128];
+
+	int norm;
+	int input;
+	int enable;
+	int bright;
+	int contrast;
+	int hue;
+	int sat;
+};
+
+#define   I2C_ADV7175        0xd4
+#define   I2C_ADV7176        0x54
+
+static char adv7175_name[] = "adv7175";
+static char adv7176_name[] = "adv7176";
+static char unknown_name[] = "UNKNOWN";
+
+#if (DEBUGLEVEL > 0)
+static char *inputs[] = { "pass_through", "play_back", "color_bar" };
+static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };
+#endif
+
+#define I2C_DELAY   10
+
+/* ----------------------------------------------------------------------- */
+
+static int adv7175_write(struct adv7175 *dev, unsigned char subaddr, unsigned char data)
+{
+	int ack;
+
+	LOCK_I2C_BUS(dev->bus);
+
+	i2c_start(dev->bus);
+	i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
+	i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
+	ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
+	dev->reg[subaddr] = data;
+	i2c_stop(dev->bus);
+	UNLOCK_I2C_BUS(dev->bus);
+	return ack;
+}
+
+static unsigned char adv7175_read(struct adv7175 *dev, unsigned char subaddr)
+{
+	unsigned char data;
+
+	LOCK_I2C_BUS(dev->bus);
+
+	i2c_start(dev->bus);
+	i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
+	i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
+	i2c_sendbyte(dev->bus, dev->addr + 1, I2C_DELAY);
+	data = i2c_readbyte(dev->bus, 1);
+	dev->reg[subaddr] = data;
+	i2c_stop(dev->bus);
+	UNLOCK_I2C_BUS(dev->bus);
+	return data;
+}
+
+static int adv7175_write_block(struct adv7175 *dev,
+			       unsigned const char *data, unsigned int len)
+{
+	int ack = 0;
+	unsigned subaddr;
+
+	while (len > 1) {
+		LOCK_I2C_BUS(dev->bus);
+		i2c_start(dev->bus);
+		i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
+		ack = i2c_sendbyte(dev->bus, (subaddr = *data++), I2C_DELAY);
+		ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
+		len -= 2;
+		while (len > 1 && *data == ++subaddr) {
+			data++;
+			ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
+			len -= 2;
+		}
+		i2c_stop(dev->bus);
+		UNLOCK_I2C_BUS(dev->bus);
+	}
+	return ack;
+}
+
+/* ----------------------------------------------------------------------- */
+// Output filter:  S-Video  Composite
+
+#define MR050       0x11	//0x09
+#define MR060       0x14	//0x0c
+
+//---------------------------------------------------------------------------
+
+#define TR0MODE     0x46
+#define TR0RST	    0x80
+
+#define TR1CAPT	    0x80
+#define TR1PLAY	    0x00
+
+static const unsigned char init_common[] = {
+
+	0x00, MR050,		/* MR0, PAL enabled */
+	0x01, 0x00,		/* MR1 */
+	0x02, 0x0c,		/* subc. freq. */
+	0x03, 0x8c,		/* subc. freq. */
+	0x04, 0x79,		/* subc. freq. */
+	0x05, 0x26,		/* subc. freq. */
+	0x06, 0x40,		/* subc. phase */
+
+	0x07, TR0MODE,		/* TR0, 16bit */
+	0x08, 0x21,		/*  */
+	0x09, 0x00,		/*  */
+	0x0a, 0x00,		/*  */
+	0x0b, 0x00,		/*  */
+	0x0c, TR1CAPT,		/* TR1 */
+	0x0d, 0x4f,		/* MR2 */
+	0x0e, 0x00,		/*  */
+	0x0f, 0x00,		/*  */
+	0x10, 0x00,		/*  */
+	0x11, 0x00,		/*  */
+	0x12, 0x00,		/* MR3 */
+	0x24, 0x00,		/*  */
+};
+
+static const unsigned char init_pal[] = {
+	0x00, MR050,		/* MR0, PAL enabled */
+	0x01, 0x00,		/* MR1 */
+	0x02, 0x0c,		/* subc. freq. */
+	0x03, 0x8c,		/* subc. freq. */
+	0x04, 0x79,		/* subc. freq. */
+	0x05, 0x26,		/* subc. freq. */
+	0x06, 0x40,		/* subc. phase */
+};
+
+static const unsigned char init_ntsc[] = {
+	0x00, MR060,		/* MR0, NTSC enabled */
+	0x01, 0x00,		/* MR1 */
+	0x02, 0x55,		/* subc. freq. */
+	0x03, 0x55,		/* subc. freq. */
+	0x04, 0x55,		/* subc. freq. */
+	0x05, 0x25,		/* subc. freq. */
+	0x06, 0x1a,		/* subc. phase */
+};
+
+static int adv7175_attach(struct i2c_device *device)
+{
+	int i;
+	struct adv7175 *encoder;
+	char *dname;
+
+	MOD_INC_USE_COUNT;
+
+	device->data = encoder = kmalloc(sizeof(struct adv7175), GFP_KERNEL);
+	if (encoder == NULL) {
+		MOD_DEC_USE_COUNT;
+		return -ENOMEM;
+	}
+
+
+	memset(encoder, 0, sizeof(struct adv7175));
+	if ((device->addr == I2C_ADV7175) || (device->addr == (I2C_ADV7175 + 2))) {
+		dname = adv7175_name;
+	} else if ((device->addr == I2C_ADV7176) || (device->addr == (I2C_ADV7176 + 2))) {
+		dname = adv7176_name;
+	} else {
+		// We should never get here!!!
+		dname = unknown_name;
+	}
+	strcpy(device->name, dname);
+	encoder->bus = device->bus;
+	encoder->addr = device->addr;
+	encoder->norm = VIDEO_MODE_PAL;
+	encoder->input = 0;
+	encoder->enable = 1;
+
+	i = adv7175_write_block(encoder, init_common, sizeof(init_common));
+	if (i >= 0) {
+		i = adv7175_write(encoder, 0x07, TR0MODE | TR0RST);
+		i = adv7175_write(encoder, 0x07, TR0MODE);
+		i = adv7175_read(encoder, 0x12);
+		printk(KERN_INFO "%s_attach: %s rev. %d at 0x%02x\n",
+		       device->name, dname, i & 1, device->addr);
+	}
+	if (i < 0) {
+		printk(KERN_ERR "%s_attach: init error %d\n", device->name,
+		       i);
+	}
+
+	return 0;
+}
+
+
+static int adv7175_detach(struct i2c_device *device)
+{
+	kfree(device->data);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static int adv7175_command(struct i2c_device *device, unsigned int cmd,
+			   void *arg)
+{
+	struct adv7175 *encoder = device->data;
+
+	switch (cmd) {
+
+	case ENCODER_GET_CAPABILITIES:
+		{
+			struct video_encoder_capability *cap = arg;
+
+			cap->flags = VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC
+			    // | VIDEO_ENCODER_SECAM
+			    // | VIDEO_ENCODER_CCIR
+			    ;
+			cap->inputs = 2;
+			cap->outputs = 1;
+		}
+		break;
+
+	case ENCODER_SET_NORM:
+		{
+			int iarg = *(int *) arg;
+
+			if (encoder->norm != iarg) {
+				switch (iarg) {
+
+				case VIDEO_MODE_NTSC:
+					adv7175_write_block(encoder,
+							    init_ntsc,
+							    sizeof
+							    (init_ntsc));
+					if (encoder->input == 0)
+						adv7175_write(encoder, 0x0d, 0x4f);	// Enable genlock
+					adv7175_write(encoder, 0x07,
+						      TR0MODE | TR0RST);
+					adv7175_write(encoder, 0x07,
+						      TR0MODE);
+					break;
+
+				case VIDEO_MODE_PAL:
+					adv7175_write_block(encoder,
+							    init_pal,
+							    sizeof
+							    (init_pal));
+					if (encoder->input == 0)
+						adv7175_write(encoder, 0x0d, 0x4f);	// Enable genlock
+					adv7175_write(encoder, 0x07,
+						      TR0MODE | TR0RST);
+					adv7175_write(encoder, 0x07,
+						      TR0MODE);
+					break;
+
+				case VIDEO_MODE_SECAM:	// WARNING! ADV7176 does not support SECAM.
+					// This is an attempt to convert SECAM->PAL (typically
+					// it does not work due to genlock: when decoder
+					// is in SECAM and encoder in in PAL the subcarrier
+					// can not be syncronized with horizontal frequency)
+					adv7175_write_block(encoder,
+							    init_pal,
+							    sizeof
+							    (init_pal));
+					if (encoder->input == 0)
+						adv7175_write(encoder, 0x0d, 0x49);	// Disable genlock
+					adv7175_write(encoder, 0x07,
+						      TR0MODE | TR0RST);
+					adv7175_write(encoder, 0x07,
+						      TR0MODE);
+					break;
+				default:
+					printk(KERN_ERR
+					       "%s: illegal norm: %d\n",
+					       device->name, iarg);
+					return -EINVAL;
+
+				}
+				DEBUG(printk
+				      (KERN_INFO "%s: switched to %s\n",
+				       device->name, norms[iarg]));
+				encoder->norm = iarg;
+			}
+		}
+		break;
+
+	case ENCODER_SET_INPUT:
+		{
+			int iarg = *(int *) arg;
+
+			/* RJ: *iarg = 0: input is from SAA7110
+			   *iarg = 1: input is from ZR36060
+			   *iarg = 2: color bar */
+
+			if (encoder->input != iarg) {
+				switch (iarg) {
+
+				case 0:
+					adv7175_write(encoder, 0x01, 0x00);
+					adv7175_write(encoder, 0x0c, TR1CAPT);	/* TR1 */
+					if (encoder->norm ==
+					    VIDEO_MODE_SECAM)
+						adv7175_write(encoder, 0x0d, 0x49);	// Disable genlock
+					else
+						adv7175_write(encoder, 0x0d, 0x4f);	// Enable genlock
+					adv7175_write(encoder, 0x07,
+						      TR0MODE | TR0RST);
+					adv7175_write(encoder, 0x07,
+						      TR0MODE);
+					//udelay(10);
+					break;
+
+				case 1:
+					adv7175_write(encoder, 0x01, 0x00);
+					adv7175_write(encoder, 0x0c, TR1PLAY);	/* TR1 */
+					adv7175_write(encoder, 0x0d, 0x49);
+					adv7175_write(encoder, 0x07,
+						      TR0MODE | TR0RST);
+					adv7175_write(encoder, 0x07,
+						      TR0MODE);
+					//udelay(10);
+					break;
+
+				case 2:
+					adv7175_write(encoder, 0x01, 0x80);
+					adv7175_write(encoder, 0x0d, 0x49);
+					adv7175_write(encoder, 0x07,
+						      TR0MODE | TR0RST);
+					adv7175_write(encoder, 0x07,
+						      TR0MODE);
+					//udelay(10);
+					break;
+
+				default:
+					printk(KERN_ERR
+					       "%s: illegal input: %d\n",
+					       device->name, iarg);
+					return -EINVAL;
+
+				}
+				DEBUG(printk
+				      (KERN_INFO "%s: switched to %s\n",
+				       device->name, inputs[iarg]));
+				encoder->input = iarg;
+			}
+		}
+		break;
+
+	case ENCODER_SET_OUTPUT:
+		{
+			int *iarg = arg;
+
+			/* not much choice of outputs */
+			if (*iarg != 0) {
+				return -EINVAL;
+			}
+		}
+		break;
+
+	case ENCODER_ENABLE_OUTPUT:
+		{
+			int *iarg = arg;
+
+			encoder->enable = !!*iarg;
+			adv7175_write(encoder, 0x61,
+				      (encoder->
+				       reg[0x61] & 0xbf) | (encoder->
+							    enable ? 0x00 :
+							    0x40));
+		}
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_driver i2c_driver_adv7175 = {
+	"adv7175",		/* name */
+	I2C_DRIVERID_VIDEOENCODER,	/* ID */
+	I2C_ADV7175, I2C_ADV7175 + 3,
+
+	adv7175_attach,
+	adv7175_detach,
+	adv7175_command
+};
+
+static struct i2c_driver i2c_driver_adv7176 = {
+	"adv7175",		/* name */
+	I2C_DRIVERID_VIDEOENCODER,	/* ID */
+	I2C_ADV7176, I2C_ADV7176 + 3,
+
+	adv7175_attach,
+	adv7175_detach,
+	adv7175_command
+};
+
+EXPORT_NO_SYMBOLS;
+
+static int adv7175_init(void)
+{
+	int res_adv7175 = 0, res_adv7176 = 0;
+	res_adv7175 = i2c_register_driver(&i2c_driver_adv7175);
+	res_adv7176 = i2c_register_driver(&i2c_driver_adv7176);
+	return (res_adv7175 | res_adv7176);	// Any idea how to make it better?
+}
+
+static void adv7175_exit(void)
+{
+	i2c_unregister_driver(&i2c_driver_adv7176);
+	i2c_unregister_driver(&i2c_driver_adv7175);
+}
+
+module_init(adv7175_init);
+module_exit(adv7175_exit);
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/bt819.c linux/drivers/media/video/bt819.c
--- v2.4.4/linux/drivers/media/video/bt819.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/media/video/bt819.c	Sat May 19 17:43:06 2001
@@ -0,0 +1,496 @@
+/* 
+    bt819 - BT819A VideoStream Decoder (Rockwell Part)
+
+    Copyright (C) 1999 Mike Bernson <mike@mlb.org>
+    Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+
+    Modifications for LML33/DC10plus unified driver
+    Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
+    
+    This code was modify/ported from the saa7111 driver written
+    by Dave Perks.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+
+#include <linux/videodev.h>
+
+#include <linux/i2c-old.h>
+#include <linux/video_decoder.h>
+
+#define DEBUG(x)       x	/* Debug driver */
+
+/* ----------------------------------------------------------------------- */
+
+struct bt819 {
+	struct i2c_bus *bus;
+	int addr;
+	unsigned char reg[32];
+
+	int initialized;
+	int norm;
+	int input;
+	int enable;
+	int bright;
+	int contrast;
+	int hue;
+	int sat;
+};
+
+struct timing {
+	int hactive;
+	int hdelay;
+	int vactive;
+	int vdelay;
+	int hscale;
+	int vscale;
+};
+
+struct timing timing_data[] = {
+	{864 - 24, 2, 623, 1, 0x0504, 0x0000},
+	{858 - 24, 2, 523, 1, 0x00f8, 0x0000},
+//      { 858-68, 64, 523, 1, 0x00f8, 0x0000 },
+};
+
+#define   I2C_BT819        0x8a
+
+#define   I2C_DELAY   10
+
+/* ----------------------------------------------------------------------- */
+
+static int bt819_write(struct bt819 *dev, unsigned char subaddr,
+		       unsigned char data)
+{
+	int ack;
+
+	LOCK_I2C_BUS(dev->bus);
+	i2c_start(dev->bus);
+	i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
+	i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
+	ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
+	dev->reg[subaddr] = data;
+	i2c_stop(dev->bus);
+	UNLOCK_I2C_BUS(dev->bus);
+	return ack;
+}
+
+static int bt819_setbit(struct bt819 *dev, int subaddr, int bit, int data)
+{
+	return bt819_write(dev, subaddr, (dev->reg[subaddr] & ~(1 << bit)) | (data ? (1 << bit) : 0));
+}
+
+static int bt819_write_block(struct bt819 *dev, unsigned const char *data,
+			     unsigned int len)
+{
+	int ack;
+	unsigned subaddr;
+
+	ack = 0;
+	while (len > 1) {
+		LOCK_I2C_BUS(dev->bus);
+		i2c_start(dev->bus);
+		i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
+		ack = i2c_sendbyte(dev->bus, (subaddr = *data++), I2C_DELAY);
+		ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++),
+				 I2C_DELAY);
+		len -= 2;
+		while (len > 1 && *data == ++subaddr) {
+			data++;
+			ack =
+			    i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
+			len -= 2;
+		}
+		i2c_stop(dev->bus);
+		UNLOCK_I2C_BUS(dev->bus);
+	}
+	return ack;
+}
+
+static int bt819_read(struct bt819 *dev, unsigned char subaddr)
+{
+	int data;
+
+	LOCK_I2C_BUS(dev->bus);
+	i2c_start(dev->bus);
+	i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
+	i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
+	i2c_start(dev->bus);
+	i2c_sendbyte(dev->bus, dev->addr | 1, I2C_DELAY);
+	data = i2c_readbyte(dev->bus, 1);
+	i2c_stop(dev->bus);
+	UNLOCK_I2C_BUS(dev->bus);
+	return data;
+}
+
+static int bt819_init(struct i2c_device *device)
+{
+	struct bt819 *decoder;
+
+	static unsigned char init[] = {
+		//0x1f, 0x00,     /* Reset */
+		0x01, 0x59,	/* 0x01 input format */
+		0x02, 0x00,	/* 0x02 temporal decimation */
+		0x03, 0x12,	/* 0x03 Cropping msb */
+		0x04, 0x16,	/* 0x04 Vertical Delay, lsb */
+		0x05, 0xe0,	/* 0x05 Vertical Active lsb */
+		0x06, 0x80,	/* 0x06 Horizontal Delay lsb */
+		0x07, 0xd0,	/* 0x07 Horizontal Active lsb */
+		0x08, 0x00,	/* 0x08 Horizontal Scaling msb */
+		0x09, 0xf8,	/* 0x09 Horizontal Scaling lsb */
+		0x0a, 0x00,	/* 0x0a Brightness control */
+		0x0b, 0x30,	/* 0x0b Miscellaneous control */
+		0x0c, 0xd8,	/* 0x0c Luma Gain lsb */
+		0x0d, 0xfe,	/* 0x0d Chroma Gain (U) lsb */
+		0x0e, 0xb4,	/* 0x0e Chroma Gain (V) msb */
+		0x0f, 0x00,	/* 0x0f Hue control */
+		0x12, 0x04,	/* 0x12 Output Format */
+		0x13, 0x20,	/* 0x13 Vertial Scaling msb 0x60, */
+		0x14, 0x00,	/* 0x14 Vertial Scaling lsb */
+		0x16, 0x04,	/* 0x16 Video Timing Polarity 0x02, */
+		0x18, 0x68,	/* 0x18 AGC Delay */
+		0x19, 0x5d,	/* 0x19 Burst Gate Delay */
+		0x1a, 0x80,	/* 0x1a ADC Interface */
+	};
+
+	struct timing *timing;
+
+	decoder = device->data;
+	timing = &timing_data[decoder->norm];
+
+	init[3 * 2 - 1] = (((timing->vdelay >> 8) & 0x03) << 6) |
+	    (((timing->vactive >> 8) & 0x03) << 4) |
+	    (((timing->hdelay >> 8) & 0x03) << 2) |
+	    ((timing->hactive >> 8) & 0x03);
+	init[4 * 2 - 1] = timing->vdelay & 0xff;
+	init[5 * 2 - 1] = timing->vactive & 0xff;
+	init[6 * 2 - 1] = timing->hdelay & 0xff;
+	init[7 * 2 - 1] = timing->hactive & 0xff;
+	init[8 * 2 - 1] = timing->hscale >> 8;
+	init[9 * 2 - 1] = timing->hscale & 0xff;
+
+	bt819_write(decoder, 0x1f, 0x00);
+	mdelay(1);
+	return bt819_write_block(decoder, init, sizeof(init));
+
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int bt819_attach(struct i2c_device *device)
+{
+	int i;
+	struct bt819 *decoder;
+
+	MOD_INC_USE_COUNT;
+
+	device->data = decoder = kmalloc(sizeof(struct bt819), GFP_KERNEL);
+	if (decoder == NULL) {
+		MOD_DEC_USE_COUNT;
+		return -ENOMEM;
+	}
+
+	memset(decoder, 0, sizeof(struct bt819));
+	strcpy(device->name, "bt819");
+	decoder->bus = device->bus;
+	decoder->addr = device->addr;
+	decoder->norm = VIDEO_MODE_NTSC;
+	decoder->input = 0;
+	decoder->enable = 1;
+	decoder->bright = 32768;
+	decoder->contrast = 32768;
+	decoder->hue = 32768;
+	decoder->sat = 32768;
+	decoder->initialized = 0;
+
+	i = bt819_init(device);
+	if (i < 0) {
+		printk(KERN_ERR "%s: bt819_attach: init status %d\n",
+		       decoder->bus->name, i);
+	} else {
+		printk(KERN_INFO "%s: bt819_attach: chip version %x\n",
+		       decoder->bus->name, bt819_read(decoder,
+						      0x17) & 0x0f);
+	}
+	return 0;
+}
+
+static int bt819_detach(struct i2c_device *device)
+{
+	kfree(device->data);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static int bt819_command(struct i2c_device *device, unsigned int cmd, void *arg)
+{
+	int temp;
+
+	struct bt819 *decoder = device->data;
+	//return 0;
+
+	if (!decoder->initialized) {	// First call to bt819_init could be
+		bt819_init(device);	// without #FRST = 0
+		decoder->initialized = 1;
+	}
+
+	switch (cmd) {
+
+	case DECODER_GET_CAPABILITIES:
+		{
+			struct video_decoder_capability *cap = arg;
+
+			cap->flags
+			    = VIDEO_DECODER_PAL
+			    | VIDEO_DECODER_NTSC | VIDEO_DECODER_CCIR;
+			cap->inputs = 8;
+			cap->outputs = 1;
+		}
+		break;
+
+	case DECODER_GET_STATUS:
+		{
+			int *iarg = arg;
+			int status;
+			int res;
+
+			status = bt819_read(decoder, 0x00);
+			res = 0;
+			if ((status & 0x80)) {
+				res |= DECODER_STATUS_GOOD;
+			}
+			switch (decoder->norm) {
+			case VIDEO_MODE_NTSC:
+				res |= DECODER_STATUS_NTSC;
+				break;
+			case VIDEO_MODE_PAL:
+				res |= DECODER_STATUS_PAL;
+				break;
+			default:
+			case VIDEO_MODE_AUTO:
+				if ((status & 0x10)) {
+					res |= DECODER_STATUS_PAL;
+				} else {
+					res |= DECODER_STATUS_NTSC;
+				}
+				break;
+			}
+			res |= DECODER_STATUS_COLOR;
+			*iarg = res;
+
+			DEBUG(printk(KERN_INFO "%s-bt819: get status %x\n",
+				     decoder->bus->name, *iarg));
+		}
+		break;
+
+	case DECODER_SET_NORM:
+		{
+			int *iarg = arg;
+			struct timing *timing;
+
+			DEBUG(printk(KERN_INFO "%s-bt819: set norm %x\n",
+				     decoder->bus->name, *iarg));
+
+			if (*iarg == VIDEO_MODE_NTSC) {
+				bt819_setbit(decoder, 0x01, 0, 1);
+				bt819_setbit(decoder, 0x01, 1, 0);
+				bt819_write(decoder, 0x18, 0x68);
+				bt819_write(decoder, 0x19, 0x5d);
+				//bt819_setbit(decoder, 0x1a,  5, 1);
+				timing = &timing_data[VIDEO_MODE_NTSC];
+			} else {
+				bt819_setbit(decoder, 0x01, 0, 1);
+				bt819_setbit(decoder, 0x01, 1, 1);
+				bt819_write(decoder, 0x18, 0x7f);
+				bt819_write(decoder, 0x19, 0x72);
+				//bt819_setbit(decoder, 0x1a,  5, 0);
+				timing = &timing_data[VIDEO_MODE_PAL];
+			}
+
+			bt819_write(decoder, 0x03,
+				    (((timing->vdelay >> 8) & 0x03) << 6) |
+				    (((timing->
+				       vactive >> 8) & 0x03) << 4) |
+				    (((timing->
+				       hdelay >> 8) & 0x03) << 2) |
+				    ((timing->hactive >> 8) & 0x03));
+			bt819_write(decoder, 0x04, timing->vdelay & 0xff);
+			bt819_write(decoder, 0x05, timing->vactive & 0xff);
+			bt819_write(decoder, 0x06, timing->hdelay & 0xff);
+			bt819_write(decoder, 0x07, timing->hactive & 0xff);
+			bt819_write(decoder, 0x08, timing->hscale >> 8);
+			bt819_write(decoder, 0x09, timing->hscale & 0xff);
+			decoder->norm = *iarg;
+		}
+		break;
+
+	case DECODER_SET_INPUT:
+		{
+			int *iarg = arg;
+
+			DEBUG(printk(KERN_INFO "%s-bt819: set input %x\n",
+				     decoder->bus->name, *iarg));
+
+			if (*iarg < 0 || *iarg > 7) {
+				return -EINVAL;
+			}
+
+			if (decoder->input != *iarg) {
+				decoder->input = *iarg;
+				/* select mode */
+				if (decoder->input == 0) {
+					bt819_setbit(decoder, 0x0b, 6, 0);
+					bt819_setbit(decoder, 0x1a, 1, 1);
+				} else {
+					bt819_setbit(decoder, 0x0b, 6, 1);
+					bt819_setbit(decoder, 0x1a, 1, 0);
+				}
+			}
+		}
+		break;
+
+	case DECODER_SET_OUTPUT:
+		{
+			int *iarg = arg;
+
+			DEBUG(printk(KERN_INFO "%s-bt819: set output %x\n",
+				     decoder->bus->name, *iarg));
+
+			/* not much choice of outputs */
+			if (*iarg != 0) {
+				return -EINVAL;
+			}
+		}
+		break;
+
+	case DECODER_ENABLE_OUTPUT:
+		{
+			int *iarg = arg;
+			int enable = (*iarg != 0);
+
+			DEBUG(printk
+			      (KERN_INFO "%s-bt819: enable output %x\n",
+			       decoder->bus->name, *iarg));
+
+			if (decoder->enable != enable) {
+				decoder->enable = enable;
+
+				if (decoder->enable) {
+					bt819_setbit(decoder, 0x16, 7, 0);
+				} else {
+					bt819_setbit(decoder, 0x16, 7, 1);
+				}
+			}
+		}
+		break;
+
+	case DECODER_SET_PICTURE:
+		{
+			struct video_picture *pic = arg;
+
+			DEBUG(printk
+			      (KERN_INFO
+			       "%s-bt819: set picture brightness %d contrast %d colour %d\n",
+			       decoder->bus->name, pic->brightness,
+			       pic->contrast, pic->colour));
+
+
+			if (decoder->bright != pic->brightness) {
+				/* We want -128 to 127 we get 0-65535 */
+				decoder->bright = pic->brightness;
+				bt819_write(decoder, 0x0a,
+					    (decoder->bright >> 8) - 128);
+			}
+
+			if (decoder->contrast != pic->contrast) {
+				/* We want 0 to 511 we get 0-65535 */
+				decoder->contrast = pic->contrast;
+				bt819_write(decoder, 0x0c,
+					    (decoder->
+					     contrast >> 7) & 0xff);
+				bt819_setbit(decoder, 0x0b, 2,
+					     ((decoder->
+					       contrast >> 15) & 0x01));
+			}
+
+			if (decoder->sat != pic->colour) {
+				/* We want 0 to 511 we get 0-65535 */
+				decoder->sat = pic->colour;
+				bt819_write(decoder, 0x0d,
+					    (decoder->sat >> 7) & 0xff);
+				bt819_setbit(decoder, 0x0b, 1,
+					     ((decoder->
+					       sat >> 15) & 0x01));
+
+				temp = (decoder->sat * 201) / 237;
+				bt819_write(decoder, 0x0e,
+					    (temp >> 7) & 0xff);
+				bt819_setbit(decoder, 0x0b, 0,
+					     (temp >> 15) & 0x01);
+			}
+
+			if (decoder->hue != pic->hue) {
+				/* We want -128 to 127 we get 0-65535 */
+				decoder->hue = pic->hue;
+				bt819_write(decoder, 0x0f,
+					    128 - (decoder->hue >> 8));
+			}
+		}
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_driver i2c_driver_bt819 = {
+	"bt819",		/* name */
+	I2C_DRIVERID_VIDEODECODER,	/* ID */
+	I2C_BT819, I2C_BT819 + 1,
+
+	bt819_attach,
+	bt819_detach,
+	bt819_command
+};
+
+EXPORT_NO_SYMBOLS;
+
+static int bt819_setup(void)
+{
+	return i2c_register_driver(&i2c_driver_bt819);
+}
+
+static void bt819_exit(void)
+{
+	i2c_unregister_driver(&i2c_driver_bt819);
+}
+
+module_init(bt819_setup);
+module_exit(bt819_exit);
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/bt856.c linux/drivers/media/video/bt856.c
--- v2.4.4/linux/drivers/media/video/bt856.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/media/video/bt856.c	Sat May 19 17:43:06 2001
@@ -0,0 +1,303 @@
+/* 
+    bt856 - BT856A Digital Video Encoder (Rockwell Part)
+
+    Copyright (C) 1999 Mike Bernson <mike@mlb.org>
+    Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+
+    Modifications for LML33/DC10plus unified driver
+    Copyright (C) 2000 Serguei Miridonov <mirsev@cicese.mx>
+    
+    This code was modify/ported from the saa7111 driver written
+    by Dave Perks.
+
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/malloc.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/signal.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <linux/sched.h>
+#include <asm/segment.h>
+#include <linux/types.h>
+#include <linux/wrapper.h>
+
+#include <linux/videodev.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+
+#include <linux/i2c-old.h>
+#include <linux/video_encoder.h>
+
+#define DEBUG(x)   x		/* Debug driver */
+
+/* ----------------------------------------------------------------------- */
+
+struct bt856 {
+	struct i2c_bus *bus;
+	int addr;
+	unsigned char reg[128];
+
+	int norm;
+	int enable;
+	int bright;
+	int contrast;
+	int hue;
+	int sat;
+};
+
+#define   I2C_BT856        0x88
+
+#define I2C_DELAY   10
+
+/* ----------------------------------------------------------------------- */
+
+static int bt856_write(struct bt856 *dev, unsigned char subaddr,
+		       unsigned char data)
+{
+	int ack;
+
+	LOCK_I2C_BUS(dev->bus);
+
+	i2c_start(dev->bus);
+	i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
+	i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
+	ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
+	dev->reg[subaddr] = data;
+	i2c_stop(dev->bus);
+	UNLOCK_I2C_BUS(dev->bus);
+	return ack;
+}
+
+static int bt856_setbit(struct bt856 *dev, int subaddr, int bit, int data)
+{
+	return bt856_write(dev, subaddr,(dev->reg[subaddr] & ~(1 << bit)) | (data ? (1 << bit) : 0));
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int bt856_attach(struct i2c_device *device)
+{
+	struct bt856 *encoder;
+
+	/* This chip is not on the buz card but at the same address saa7185 */
+	//if (memcmp(device->bus->name, "buz", 3) == 0 || memcmp(device->bus->name, "zr36057", 6) == 0)
+	//   return 1;
+
+	MOD_INC_USE_COUNT;
+	device->data = encoder = kmalloc(sizeof(struct bt856), GFP_KERNEL);
+
+	if (encoder == NULL) {
+		MOD_DEC_USE_COUNT;
+		return -ENOMEM;
+	}
+
+
+	memset(encoder, 0, sizeof(struct bt856));
+	strcpy(device->name, "bt856");
+	encoder->bus = device->bus;
+	encoder->addr = device->addr;
+	encoder->norm = VIDEO_MODE_NTSC;
+	encoder->enable = 1;
+
+	DEBUG(printk(KERN_INFO "%s-bt856: attach\n", encoder->bus->name));
+
+	bt856_write(encoder, 0xdc, 0x18);
+	bt856_write(encoder, 0xda, 0);
+	bt856_write(encoder, 0xde, 0);
+
+	bt856_setbit(encoder, 0xdc, 3, 1);
+	//bt856_setbit(encoder, 0xdc, 6, 0);
+	bt856_setbit(encoder, 0xdc, 4, 1);
+
+	switch (encoder->norm) {
+
+	case VIDEO_MODE_NTSC:
+		bt856_setbit(encoder, 0xdc, 2, 0);
+		break;
+
+	case VIDEO_MODE_PAL:
+		bt856_setbit(encoder, 0xdc, 2, 1);
+		break;
+	}
+
+	bt856_setbit(encoder, 0xdc, 1, 1);
+	bt856_setbit(encoder, 0xde, 4, 0);
+	bt856_setbit(encoder, 0xde, 3, 1);
+	return 0;
+}
+
+
+static int bt856_detach(struct i2c_device *device)
+{
+	kfree(device->data);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static int bt856_command(struct i2c_device *device, unsigned int cmd,
+			 void *arg)
+{
+	struct bt856 *encoder = device->data;
+
+	switch (cmd) {
+
+	case ENCODER_GET_CAPABILITIES:
+		{
+			struct video_encoder_capability *cap = arg;
+
+			DEBUG(printk
+			      (KERN_INFO "%s-bt856: get capabilities\n",
+			       encoder->bus->name));
+
+			cap->flags
+			    = VIDEO_ENCODER_PAL
+			    | VIDEO_ENCODER_NTSC | VIDEO_ENCODER_CCIR;
+			cap->inputs = 2;
+			cap->outputs = 1;
+		}
+		break;
+
+	case ENCODER_SET_NORM:
+		{
+			int *iarg = arg;
+
+			DEBUG(printk(KERN_INFO "%s-bt856: set norm %d\n",
+				     encoder->bus->name, *iarg));
+
+			switch (*iarg) {
+
+			case VIDEO_MODE_NTSC:
+				bt856_setbit(encoder, 0xdc, 2, 0);
+				break;
+
+			case VIDEO_MODE_PAL:
+				bt856_setbit(encoder, 0xdc, 2, 1);
+				bt856_setbit(encoder, 0xda, 0, 0);
+				//bt856_setbit(encoder, 0xda, 0, 1);
+				break;
+
+			default:
+				return -EINVAL;
+
+			}
+			encoder->norm = *iarg;
+		}
+		break;
+
+	case ENCODER_SET_INPUT:
+		{
+			int *iarg = arg;
+
+			DEBUG(printk(KERN_INFO "%s-bt856: set input %d\n",
+				     encoder->bus->name, *iarg));
+
+			/*     We only have video bus.
+			   *iarg = 0: input is from bt819
+			   *iarg = 1: input is from ZR36060 */
+
+			switch (*iarg) {
+
+			case 0:
+				bt856_setbit(encoder, 0xde, 4, 0);
+				bt856_setbit(encoder, 0xde, 3, 1);
+				bt856_setbit(encoder, 0xdc, 3, 1);
+				bt856_setbit(encoder, 0xdc, 6, 0);
+				break;
+			case 1:
+				bt856_setbit(encoder, 0xde, 4, 0);
+				bt856_setbit(encoder, 0xde, 3, 1);
+				bt856_setbit(encoder, 0xdc, 3, 1);
+				bt856_setbit(encoder, 0xdc, 6, 1);
+				break;
+			case 2:	// Color bar
+				bt856_setbit(encoder, 0xdc, 3, 0);
+				bt856_setbit(encoder, 0xde, 4, 1);
+				break;
+			default:
+				return -EINVAL;
+
+			}
+		}
+		break;
+
+	case ENCODER_SET_OUTPUT:
+		{
+			int *iarg = arg;
+
+			DEBUG(printk(KERN_INFO "%s-bt856: set output %d\n",
+				     encoder->bus->name, *iarg));
+
+			/* not much choice of outputs */
+			if (*iarg != 0) {
+				return -EINVAL;
+			}
+		}
+		break;
+
+	case ENCODER_ENABLE_OUTPUT:
+		{
+			int *iarg = arg;
+
+			encoder->enable = !!*iarg;
+
+			DEBUG(printk
+			      (KERN_INFO "%s-bt856: enable output %d\n",
+			       encoder->bus->name, encoder->enable));
+		}
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct i2c_driver i2c_driver_bt856 = {
+	"bt856",		/* name */
+	I2C_DRIVERID_VIDEOENCODER,	/* ID */
+	I2C_BT856, I2C_BT856 + 1,
+	bt856_attach,
+	bt856_detach,
+	bt856_command
+};
+
+EXPORT_NO_SYMBOLS;
+
+static int bt856_init(void)
+{
+	return i2c_register_driver(&i2c_driver_bt856);
+}
+
+static void bt856_exit(void)
+{
+	i2c_unregister_driver(&i2c_driver_bt856);
+}
+
+module_init(bt856_init);
+module_exit(bt856_exit);
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/bttv-driver.c linux/drivers/media/video/bttv-driver.c
--- v2.4.4/linux/drivers/media/video/bttv-driver.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/video/bttv-driver.c	Sat May 19 17:43:06 2001
@@ -69,6 +69,9 @@
 static unsigned int gbuffers = 2;
 static unsigned int gbufsize = BTTV_MAX_FBUF;
 static unsigned int combfilter = 0;
+static int video_nr = -1;
+static int radio_nr = -1;
+static int vbi_nr = -1;
 unsigned int bttv_debug = 0;
 unsigned int bttv_verbose = 1;
 unsigned int bttv_gpio = 0;
@@ -94,6 +97,10 @@
 MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
 MODULE_PARM(combfilter,"i");
 
+MODULE_PARM(video_nr,"i");
+MODULE_PARM(radio_nr,"i");
+MODULE_PARM(vbi_nr,"i");
+
 MODULE_DESCRIPTION("bttv - v4l driver module for bt848/878 based cards");
 MODULE_AUTHOR("Ralph  Metzler & Marcus Metzler & Gerd Knorr");
 
@@ -2435,16 +2442,16 @@
 {
 	audio(btv, AUDIO_MUTE, 1);
         
-	if(video_register_device(&btv->video_dev,VFL_TYPE_GRABBER)<0)
+	if(video_register_device(&btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
 		return -1;
-	if(video_register_device(&btv->vbi_dev,VFL_TYPE_VBI)<0) 
+	if(video_register_device(&btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0) 
         {
 	        video_unregister_device(&btv->video_dev);
 		return -1;
 	}
 	if (btv->has_radio)
 	{
-		if(video_register_device(&btv->radio_dev, VFL_TYPE_RADIO)<0) 
+		if(video_register_device(&btv->radio_dev, VFL_TYPE_RADIO, radio_nr)<0) 
                 {
 		        video_unregister_device(&btv->vbi_dev);
 		        video_unregister_device(&btv->video_dev);
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/bw-qcam.c linux/drivers/media/video/bw-qcam.c
--- v2.4.4/linux/drivers/media/video/bw-qcam.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/video/bw-qcam.c	Sat May 19 17:43:06 2001
@@ -83,10 +83,12 @@
 
 static unsigned int maxpoll=250;   /* Maximum busy-loop count for qcam I/O */
 static unsigned int yieldlines=4;  /* Yield after this many during capture */
+static int video_nr = -1;
 
 #if LINUX_VERSION_CODE >= 0x020117
 MODULE_PARM(maxpoll,"i");
 MODULE_PARM(yieldlines,"i");   
+MODULE_PARM(video_nr,"i");
 #endif
 
 extern __inline__ int read_lpstatus(struct qcam_device *q)
@@ -962,7 +964,7 @@
 	
 	printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
 	
-	if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER)==-1)
+	if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
 	{
 		parport_unregister_device(qcam->pdev);
 		kfree(qcam);
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/c-qcam.c linux/drivers/media/video/c-qcam.c
--- v2.4.4/linux/drivers/media/video/c-qcam.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/video/c-qcam.c	Sat May 19 17:43:06 2001
@@ -69,6 +69,7 @@
 static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
 static int probe = 2;
 static int force_rgb = 0;
+static int video_nr = -1;
 
 static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i)
 {
@@ -815,7 +816,7 @@
 
 	parport_release(qcam->pdev);
 	
-	if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER)==-1)
+	if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
 	{
 		printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
 		       qcam->pport->name);
@@ -881,6 +882,7 @@
 MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "i");
 MODULE_PARM(probe, "i");
 MODULE_PARM(force_rgb, "i");
+MODULE_PARM(video_nr,"i");
 
 module_init(cqcam_init);
 module_exit(cqcam_cleanup);
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/cpia.c linux/drivers/media/video/cpia.c
--- v2.4.4/linux/drivers/media/video/cpia.c	Fri Apr  6 10:42:55 2001
+++ linux/drivers/media/video/cpia.c	Sat May 19 17:43:06 2001
@@ -52,7 +52,10 @@
 extern int cpia_usb_init(void);
 #endif
 
+static int video_nr = -1;
+
 #ifdef MODULE
+MODULE_PARM(video_nr,"i");
 MODULE_AUTHOR("Scott J. Bertin <sbertin@mindspring.com> & Peter Pregler <Peter_Pregler@email.com> & Johannes Erdfelt <jerdfelt@valinux.com>");
 MODULE_DESCRIPTION("V4L-driver for Vision CPiA based cameras");
 MODULE_SUPPORTED_DEVICE("video");
@@ -540,6 +543,8 @@
 static int cpia_write_proc(struct file *file, const char *buffer,
                            unsigned long count, void *data)
 {
+	return -EINVAL;
+#if 0
 	struct cam_data *cam = data;
 	struct cam_params new_params;
 	int retval, find_colon;
@@ -1250,6 +1255,7 @@
 	up(&cam->param_lock);
 	
 	return retval;
+#endif
 }
 
 static void create_proc_cpia_cam(struct cam_data *cam)
@@ -3180,7 +3186,7 @@
 	camera->lowlevel_data = lowlevel;
 	
 	/* register v4l device */
-	if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER) == -1) {
+	if (video_register_device(&camera->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
 		kfree(camera);
 		unlock_kernel();
 		printk(KERN_DEBUG "video_register_device failed\n");
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/planb.c linux/drivers/media/video/planb.c
--- v2.4.4/linux/drivers/media/video/planb.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/video/planb.c	Sat May 19 17:43:06 2001
@@ -69,9 +69,11 @@
 static volatile struct planb_registers *planb_regs;
 
 static int def_norm = PLANB_DEF_NORM;	/* default norm */
+static int video_nr = -1;
 
 MODULE_PARM(def_norm, "i");
 MODULE_PARM_DESC(def_norm, "Default startup norm (0=PAL, 1=NTSC, 2=SECAM)");
+MODULE_PARM(video_nr,"i");
 
 /* ------------------ PlanB Exported Functions ------------------ */
 static long planb_write(struct video_device *, const char *, unsigned long, int);
@@ -2168,7 +2170,7 @@
 	pb->intr_mask = PLANB_FRM_IRQ;
 	enable_irq(pb->irq);
 
-	if(video_register_device(&pb->video_dev, VFL_TYPE_GRABBER)<0)
+	if(video_register_device(&pb->video_dev, VFL_TYPE_GRABBER, video_nr)<0)
 		return -1;
 
 	return 0;
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/pms.c linux/drivers/media/video/pms.c
--- v2.4.4/linux/drivers/media/video/pms.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/video/pms.c	Sat May 19 17:43:06 2001
@@ -64,6 +64,7 @@
 static int io_port		=	0x250;
 static int data_port		=	0x251;
 static int mem_base		=	0xC8000;
+static int video_nr             =       -1;
 
 	
 
@@ -1040,11 +1041,12 @@
 	pms_device.width=320;
 	pms_swsense(75);
 	pms_resolution(320,240);
-	return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER);
+	return video_register_device((struct video_device *)&pms_device, VFL_TYPE_GRABBER, video_nr);
 }
 
 MODULE_PARM(io_port,"i");
 MODULE_PARM(mem_base,"i");
+MODULE_PARM(video_nr,"i");
 
 static void __exit shutdown_mediavision(void)
 {
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/saa5249.c linux/drivers/media/video/saa5249.c
--- v2.4.4/linux/drivers/media/video/saa5249.c	Fri Nov 17 17:56:51 2000
+++ linux/drivers/media/video/saa5249.c	Sat May 19 17:43:06 2001
@@ -205,7 +205,7 @@
 	 *	Register it
 	 */
 
-	if((err=video_register_device(vd, VFL_TYPE_VTX))<0)
+	if((err=video_register_device(vd, VFL_TYPE_VTX,-1))<0)
 	{
 		kfree(t);
 		kfree(vd);
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/saa7110.c linux/drivers/media/video/saa7110.c
--- v2.4.4/linux/drivers/media/video/saa7110.c	Wed Dec 29 17:08:55 1999
+++ linux/drivers/media/video/saa7110.c	Sat May 19 17:43:06 2001
@@ -19,6 +19,7 @@
 */
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/types.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
@@ -398,7 +399,7 @@
 
 /* ----------------------------------------------------------------------- */
 
-struct i2c_driver i2c_driver_saa7110 =
+static struct i2c_driver i2c_driver_saa7110 =
 {
 	"saa7110",			/* name */
 
@@ -412,18 +413,16 @@
 
 EXPORT_NO_SYMBOLS;
 
-#ifdef MODULE
-int init_module(void)
-#else
-int saa7110_init(void)
-#endif
+static int saa7110_init(void)
 {
 	return i2c_register_driver(&i2c_driver_saa7110);
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+static void saa7110_exit(void)
 {
 	i2c_unregister_driver(&i2c_driver_saa7110);
 }
-#endif
+
+
+module_init(saa7110_init);
+module_exit(saa7110_exit);
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/saa7111.c linux/drivers/media/video/saa7111.c
--- v2.4.4/linux/drivers/media/video/saa7111.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/media/video/saa7111.c	Sat May 19 17:43:06 2001
@@ -1,46 +1,41 @@
 /* 
-   saa7111 - Philips SAA7111A video decoder driver version 0.0.3
+    saa7111 - Philips SAA7111A video decoder driver version 0.0.3
 
-   Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+    Copyright (C) 1998 Dave Perks <dperks@ibm.net>
 
-   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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+    Slight changes for video timing and attachment output by
+    Wolfgang Scherr <scherr@net4you.net>
+    
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
-#include <linux/slab.h>
+#include <linux/malloc.h>
 #include <linux/mm.h>
-#include <linux/pci.h>
-#include <linux/signal.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
 #include <linux/sched.h>
-#include <asm/segment.h>
-#include <linux/types.h>
-#include <linux/wrapper.h>
 
 #include <linux/videodev.h>
 #include <linux/version.h>
-#include <asm/uaccess.h>
-
 #include <linux/i2c-old.h>
+
 #include <linux/video_decoder.h>
 
 #define DEBUG(x)		/* Debug driver */
@@ -67,7 +62,8 @@
 
 /* ----------------------------------------------------------------------- */
 
-static int saa7111_write(struct saa7111 *dev, unsigned char subaddr, unsigned char data)
+static int saa7111_write(struct saa7111 *dev, unsigned char subaddr,
+			 unsigned char data)
 {
 	int ack;
 
@@ -82,9 +78,10 @@
 	return ack;
 }
 
-static int saa7111_write_block(struct saa7111 *dev, unsigned const char *data, unsigned int len)
+static int saa7111_write_block(struct saa7111 *dev,
+	       unsigned const char *data, unsigned int len)
 {
-	int ack = 0;
+	int ack = -1;
 	unsigned subaddr;
 
 	while (len > 1) {
@@ -96,7 +93,10 @@
 		len -= 2;
 		while (len > 1 && *data == ++subaddr) {
 			data++;
-			ack = i2c_sendbyte(dev->bus, (dev->reg[subaddr] = *data++), I2C_DELAY);
+			ack =
+			    i2c_sendbyte(dev->bus,
+					 (dev->reg[subaddr] =
+					  *data++), I2C_DELAY);
 			len -= 2;
 		}
 		i2c_stop(dev->bus);
@@ -128,20 +128,19 @@
 	int i;
 	struct saa7111 *decoder;
 
-	static const unsigned char init[] =
-	{
+	static const unsigned char init[] = {
 		0x00, 0x00,	/* 00 - ID byte */
 		0x01, 0x00,	/* 01 - reserved */
 
-	/*front end */
+		/*front end */
 		0x02, 0xd0,	/* 02 - FUSE=3, GUDL=2, MODE=0 */
 		0x03, 0x23,	/* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
 		0x04, 0x00,	/* 04 - GAI1=256 */
 		0x05, 0x00,	/* 05 - GAI2=256 */
 
-	/* decoder */
-		0x06, 0xf6,	/* 06 - HSB at  13(50Hz) /  17(60Hz) pixels after end of last line */
-		0x07, 0xdd,	/* 07 - HSS at 113(50Hz) / 117(60Hz) pixels after end of last line */
+		/* decoder */
+		0x06, 0xf3,	/* 06 - HSB at  13(50Hz) /  17(60Hz) pixels after end of last line */
+		0x07, 0x13,	/* 07 - HSS at 113(50Hz) / 117(60Hz) pixels after end of last line */
 		0x08, 0xc8,	/* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1, HPLL=0, VNOI=0 */
 		0x09, 0x01,	/* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0, UPTCV=0, APER=1 */
 		0x0a, 0x80,	/* 0a - BRIG=128 */
@@ -160,11 +159,14 @@
 		0x17, 0x00,	/* 17 - VBI */
 	};
 
+	MOD_INC_USE_COUNT;
+
 	device->data = decoder = kmalloc(sizeof(struct saa7111), GFP_KERNEL);
-	if (decoder == NULL) {
+	if (decoder == NULL)
+	{
+		MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
-	MOD_INC_USE_COUNT;
 
 	memset(decoder, 0, sizeof(struct saa7111));
 	strcpy(device->name, "saa7111");
@@ -180,9 +182,11 @@
 
 	i = saa7111_write_block(decoder, init, sizeof(init));
 	if (i < 0) {
-		printk(KERN_ERR "%s_attach: init status %d\n", device->name, i);
+		printk(KERN_ERR "%s_attach: init status %d\n",
+		       device->name, i);
 	} else {
-		printk(KERN_INFO "%s_attach: chip version %x\n", device->name, saa7111_read(decoder, 0x00));
+		printk(KERN_INFO "%s_attach: chip version %x\n",
+		       device->name, saa7111_read(decoder, 0x00) >> 4);
 	}
 	return 0;
 }
@@ -195,7 +199,8 @@
 	return 0;
 }
 
-static int saa7111_command(struct i2c_device *device, unsigned int cmd, void *arg)
+static int saa7111_command(struct i2c_device *device, unsigned int cmd,
+			   void *arg)
 {
 	struct saa7111 *decoder = device->data;
 
@@ -209,9 +214,12 @@
 			for (i = 0; i < 32; i += 16) {
 				int j;
 
-				printk("KERN_DEBUG %s: %03x", device->name, i);
+				printk("KERN_DEBUG %s: %03x", device->name,
+				       i);
 				for (j = 0; j < 16; ++j) {
-					printk(" %02x", saa7111_read(decoder, i + j));
+					printk(" %02x",
+					       saa7111_read(decoder,
+							    i + j));
 				}
 				printk("\n");
 			}
@@ -226,8 +234,7 @@
 			cap->flags
 			    = VIDEO_DECODER_PAL
 			    | VIDEO_DECODER_NTSC
-			    | VIDEO_DECODER_AUTO
-			    | VIDEO_DECODER_CCIR;
+			    | VIDEO_DECODER_AUTO | VIDEO_DECODER_CCIR;
 			cap->inputs = 8;
 			cap->outputs = 1;
 		}
@@ -274,15 +281,21 @@
 			switch (*iarg) {
 
 			case VIDEO_MODE_NTSC:
-				saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0x3f) | 0x40);
+				saa7111_write(decoder, 0x08,
+					      (decoder->
+					       reg[0x08] & 0x3f) | 0x40);
 				break;
 
 			case VIDEO_MODE_PAL:
-				saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0x3f) | 0x00);
+				saa7111_write(decoder, 0x08,
+					      (decoder->
+					       reg[0x08] & 0x3f) | 0x00);
 				break;
 
 			case VIDEO_MODE_AUTO:
-				saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0x3f) | 0x80);
+				saa7111_write(decoder, 0x08,
+					      (decoder->
+					       reg[0x08] & 0x3f) | 0x80);
 				break;
 
 			default:
@@ -300,12 +313,20 @@
 			if (*iarg < 0 || *iarg > 7) {
 				return -EINVAL;
 			}
+
 			if (decoder->input != *iarg) {
 				decoder->input = *iarg;
 				/* select mode */
-				saa7111_write(decoder, 0x02, (decoder->reg[0x02] & 0xf8) | decoder->input);
+				saa7111_write(decoder, 0x02,
+					      (decoder->
+					       reg[0x02] & 0xf8) |
+					      decoder->input);
 				/* bypass chrominance trap for modes 4..7 */
-				saa7111_write(decoder, 0x09, (decoder->reg[0x09] & 0x7f) | ((decoder->input > 3) ? 0x80 : 0));
+				saa7111_write(decoder, 0x09,
+					      (decoder->
+					       reg[0x09] & 0x7f) |
+					      ((decoder->input >
+						3) ? 0x80 : 0));
 			}
 		}
 		break;
@@ -330,19 +351,34 @@
 				decoder->enable = enable;
 
 // RJ: If output should be disabled (for playing videos), we also need a open PLL.
-				//     The input is set to 0 (where no input source is connected), although this
-				//     is not necessary.
-				//
-				//     If output should be enabled, we have to reverse the above.
+//     The input is set to 0 (where no input source is connected), although this
+//     is not necessary.
+//
+//     If output should be enabled, we have to reverse the above.
 
 				if (decoder->enable) {
-					saa7111_write(decoder, 0x02, (decoder->reg[0x02] & 0xf8) | decoder->input);
-					saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0xfb));
-					saa7111_write(decoder, 0x11, (decoder->reg[0x11] & 0xf3) | 0x0c);
+					saa7111_write(decoder, 0x02,
+						      (decoder->
+						       reg[0x02] & 0xf8) |
+						      decoder->input);
+					saa7111_write(decoder, 0x08,
+						      (decoder->
+						       reg[0x08] & 0xfb));
+					saa7111_write(decoder, 0x11,
+						      (decoder->
+						       reg[0x11] & 0xf3) |
+						      0x0c);
 				} else {
-					saa7111_write(decoder, 0x02, (decoder->reg[0x02] & 0xf8));
-					saa7111_write(decoder, 0x08, (decoder->reg[0x08] & 0xfb) | 0x04);
-					saa7111_write(decoder, 0x11, (decoder->reg[0x11] & 0xf3));
+					saa7111_write(decoder, 0x02,
+						      (decoder->
+						       reg[0x02] & 0xf8));
+					saa7111_write(decoder, 0x08,
+						      (decoder->
+						       reg[0x08] & 0xfb) |
+						      0x04);
+					saa7111_write(decoder, 0x11,
+						      (decoder->
+						       reg[0x11] & 0xf3));
 				}
 			}
 		}
@@ -355,22 +391,26 @@
 			if (decoder->bright != pic->brightness) {
 				/* We want 0 to 255 we get 0-65535 */
 				decoder->bright = pic->brightness;
-				saa7111_write(decoder, 0x0a, decoder->bright >> 8);
+				saa7111_write(decoder, 0x0a,
+					      decoder->bright >> 8);
 			}
 			if (decoder->contrast != pic->contrast) {
 				/* We want 0 to 127 we get 0-65535 */
 				decoder->contrast = pic->contrast;
-				saa7111_write(decoder, 0x0b, decoder->contrast >> 9);
+				saa7111_write(decoder, 0x0b,
+					      decoder->contrast >> 9);
 			}
 			if (decoder->sat != pic->colour) {
 				/* We want 0 to 127 we get 0-65535 */
 				decoder->sat = pic->colour;
-				saa7111_write(decoder, 0x0c, decoder->sat >> 9);
+				saa7111_write(decoder, 0x0c,
+					      decoder->sat >> 9);
 			}
 			if (decoder->hue != pic->hue) {
 				/* We want -128 to 127 we get 0-65535 */
 				decoder->hue = pic->hue;
-				saa7111_write(decoder, 0x0d, (decoder->hue - 32768) >> 8);
+				saa7111_write(decoder, 0x0d,
+					      (decoder->hue - 32768) >> 8);
 			}
 		}
 		break;
@@ -384,8 +424,7 @@
 
 /* ----------------------------------------------------------------------- */
 
-struct i2c_driver i2c_driver_saa7111 =
-{
+static struct i2c_driver i2c_driver_saa7111 = {
 	"saa7111",		/* name */
 	I2C_DRIVERID_VIDEODECODER,	/* ID */
 	I2C_SAA7111, I2C_SAA7111 + 1,
@@ -397,22 +436,15 @@
 
 EXPORT_NO_SYMBOLS;
 
-#ifdef MODULE
-int init_module(void)
-#else
-int saa7111_init(void)
-#endif
+static int saa7111_init(void)
 {
 	return i2c_register_driver(&i2c_driver_saa7111);
 }
 
-
-
-#ifdef MODULE
-
-void cleanup_module(void)
+static void saa7111_exit(void)
 {
 	i2c_unregister_driver(&i2c_driver_saa7111);
 }
 
-#endif
+module_init(saa7111_init);
+module_exit(saa7111_exit);
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/saa7185.c linux/drivers/media/video/saa7185.c
--- v2.4.4/linux/drivers/media/video/saa7185.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/media/video/saa7185.c	Sat May 19 17:43:06 2001
@@ -1,30 +1,34 @@
 /* 
-   saa7185 - Philips SAA7185B video encoder driver version 0.0.3
+    saa7185 - Philips SAA7185B video encoder driver version 0.0.3
 
-   Copyright (C) 1998 Dave Perks <dperks@ibm.net>
+    Copyright (C) 1998 Dave Perks <dperks@ibm.net>
 
-   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., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+    Slight changes for video timing and attachment output by
+    Wolfgang Scherr <scherr@net4you.net>
+    
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
 #include <linux/major.h>
-#include <linux/slab.h>
+#include <linux/malloc.h>
 #include <linux/mm.h>
 #include <linux/pci.h>
 #include <linux/signal.h>
@@ -41,9 +45,10 @@
 #include <asm/uaccess.h>
 
 #include <linux/i2c-old.h>
+
 #include <linux/video_encoder.h>
 
-#define DEBUG(x)   x		/* Debug driver */
+#define DEBUG(x)		/* Debug driver */
 
 /* ----------------------------------------------------------------------- */
 
@@ -66,13 +71,31 @@
 
 /* ----------------------------------------------------------------------- */
 
-static int saa7185_write(struct saa7185 *dev, unsigned char subaddr, unsigned char data)
+static int saa7185_read(struct saa7185 *dev)
 {
 	int ack;
 
 	LOCK_I2C_BUS(dev->bus);
 
 	i2c_start(dev->bus);
+	i2c_sendbyte(dev->bus, dev->addr | 1, I2C_DELAY);
+	ack = i2c_readbyte(dev->bus, 1);
+	i2c_stop(dev->bus);
+	UNLOCK_I2C_BUS(dev->bus);
+	return ack;
+}
+
+static int saa7185_write(struct saa7185 *dev, unsigned char subaddr,
+			 unsigned char data)
+{
+	int ack;
+
+	DEBUG(printk
+	      (KERN_DEBUG "SAA7185: %02x set to %02x\n", subaddr, data);
+	    )
+	    LOCK_I2C_BUS(dev->bus);
+
+	i2c_start(dev->bus);
 	i2c_sendbyte(dev->bus, dev->addr, I2C_DELAY);
 	i2c_sendbyte(dev->bus, subaddr, I2C_DELAY);
 	ack = i2c_sendbyte(dev->bus, data, I2C_DELAY);
@@ -82,9 +105,10 @@
 	return ack;
 }
 
-static int saa7185_write_block(struct saa7185 *dev, unsigned const char *data, unsigned int len)
+static int saa7185_write_block(struct saa7185 *dev,
+			       unsigned const char *data, unsigned int len)
 {
-	int ack = 0;
+	int ack = -1;
 	unsigned subaddr;
 
 	while (len > 1) {
@@ -107,8 +131,7 @@
 
 /* ----------------------------------------------------------------------- */
 
-static const unsigned char init_common[] =
-{
+static const unsigned char init_common[] = {
 	0x3a, 0x0f,		/* CBENB=0, V656=0, VY2C=1, YUV2C=1, MY2C=1, MUV2C=1 */
 
 	0x42, 0x6b,		/* OVLY0=107 */
@@ -155,7 +178,7 @@
 	0x6c, 0x20,		/* SRCV1=0, TRCV2=1, ORCV1=0, PRCV1=0, CBLF=0, ORCV2=0, PRCV2=0 */
 	0x6d, 0x00,		/* SRCM1=0, CCEN=0 */
 
-	0x6e, 0x0e,		/* HTRIG=0x00e, approx. centered, at least for PAL */
+	0x6e, 0x0e,		/* HTRIG=0x005, approx. centered, at least for PAL */
 	0x6f, 0x00,		/* HTRIG upper bits */
 	0x70, 0x20,		/* PHRES=0, SBLN=1, VTRIG=0 */
 
@@ -182,8 +205,7 @@
 	0x7d, 0x20,		/* LAL=244, FAL=22 */
 };
 
-static const unsigned char init_pal[] =
-{
+static const unsigned char init_pal[] = {
 	0x61, 0x1e,		/* FISE=0, PAL=1, SCBW=1, RTCE=1, YGS=1, INPI=0, DOWN=0 */
 	0x62, 0xc8,		/* DECTYP=1, BSTA=72 */
 	0x63, 0xcb,		/* FSC0 */
@@ -192,8 +214,7 @@
 	0x66, 0x2a,		/* FSC3 */
 };
 
-static const unsigned char init_ntsc[] =
-{
+static const unsigned char init_ntsc[] = {
 	0x61, 0x1d,		/* FISE=1, PAL=0, SCBW=1, RTCE=1, YGS=1, INPI=0, DOWN=0 */
 	0x62, 0xe6,		/* DECTYP=1, BSTA=102 */
 	0x63, 0x1f,		/* FSC0 */
@@ -207,11 +228,14 @@
 	int i;
 	struct saa7185 *encoder;
 
+	MOD_INC_USE_COUNT;
+	
 	device->data = encoder = kmalloc(sizeof(struct saa7185), GFP_KERNEL);
 	if (encoder == NULL) {
+		MOD_DEC_USE_COUNT;
 		return -ENOMEM;
 	}
-	MOD_INC_USE_COUNT;
+
 
 	memset(encoder, 0, sizeof(struct saa7185));
 	strcpy(device->name, "saa7185");
@@ -222,23 +246,33 @@
 
 	i = saa7185_write_block(encoder, init_common, sizeof(init_common));
 	if (i >= 0) {
-		i = saa7185_write_block(encoder, init_ntsc, sizeof(init_ntsc));
+		i = saa7185_write_block(encoder, init_ntsc,
+					sizeof(init_ntsc));
 	}
 	if (i < 0) {
-		printk(KERN_ERR "%s_attach: init error %d\n", device->name, i);
+		printk(KERN_ERR "%s_attach: init error %d\n", device->name,
+		       i);
+	} else {
+		printk(KERN_INFO "%s_attach: chip version %d\n",
+		       device->name, saa7185_read(encoder) >> 5);
 	}
+
 	return 0;
 }
 
 
 static int saa7185_detach(struct i2c_device *device)
 {
-	kfree(device->data);
+	struct saa7185 *encoder = device->data;
+	saa7185_write(encoder, 0x61, (encoder->reg[0x61]) | 0x40);	/* SW: output off is active */
+	//saa7185_write(encoder, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */
+	kfree(encoder);
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
-static int saa7185_command(struct i2c_device *device, unsigned int cmd, void *arg)
+static int saa7185_command(struct i2c_device *device, unsigned int cmd,
+			   void *arg)
 {
 	struct saa7185 *encoder = device->data;
 
@@ -251,8 +285,7 @@
 			cap->flags
 			    = VIDEO_ENCODER_PAL
 			    | VIDEO_ENCODER_NTSC
-			    | VIDEO_ENCODER_SECAM
-			    | VIDEO_ENCODER_CCIR;
+			    | VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR;
 			cap->inputs = 1;
 			cap->outputs = 1;
 		}
@@ -265,11 +298,13 @@
 			switch (*iarg) {
 
 			case VIDEO_MODE_NTSC:
-				saa7185_write_block(encoder, init_ntsc, sizeof(init_ntsc));
+				saa7185_write_block(encoder, init_ntsc,
+						    sizeof(init_ntsc));
 				break;
 
 			case VIDEO_MODE_PAL:
-				saa7185_write_block(encoder, init_pal, sizeof(init_pal));
+				saa7185_write_block(encoder, init_pal,
+						    sizeof(init_pal));
 				break;
 
 			case VIDEO_MODE_SECAM:
@@ -285,12 +320,6 @@
 		{
 			int *iarg = arg;
 
-#if 0
-			/* not much choice of inputs */
-			if (*iarg != 0) {
-				return -EINVAL;
-			}
-#else
 			/* RJ: *iarg = 0: input is from SA7111
 			   *iarg = 1: input is from ZR36060 */
 
@@ -298,19 +327,25 @@
 
 			case 0:
 				/* Switch RTCE to 1 */
-				saa7185_write(encoder, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
+				saa7185_write(encoder, 0x61,
+					      (encoder->
+					       reg[0x61] & 0xf7) | 0x08);
+				saa7185_write(encoder, 0x6e, 0x01);
 				break;
 
 			case 1:
 				/* Switch RTCE to 0 */
-				saa7185_write(encoder, 0x61, (encoder->reg[0x61] & 0xf7) | 0x00);
+				saa7185_write(encoder, 0x61,
+					      (encoder->
+					       reg[0x61] & 0xf7) | 0x00);
+				/* SW: a slight sync problem... */
+				saa7185_write(encoder, 0x6e, 0x00);
 				break;
 
 			default:
 				return -EINVAL;
 
 			}
-#endif
 		}
 		break;
 
@@ -330,7 +365,11 @@
 			int *iarg = arg;
 
 			encoder->enable = !!*iarg;
-			saa7185_write(encoder, 0x61, (encoder->reg[0x61] & 0xbf) | (encoder->enable ? 0x00 : 0x40));
+			saa7185_write(encoder, 0x61,
+				      (encoder->
+				       reg[0x61] & 0xbf) | (encoder->
+							    enable ? 0x00 :
+							    0x40));
 		}
 		break;
 
@@ -343,8 +382,7 @@
 
 /* ----------------------------------------------------------------------- */
 
-struct i2c_driver i2c_driver_saa7185 =
-{
+static struct i2c_driver i2c_driver_saa7185 = {
 	"saa7185",		/* name */
 	I2C_DRIVERID_VIDEOENCODER,	/* ID */
 	I2C_SAA7185, I2C_SAA7185 + 1,
@@ -356,22 +394,15 @@
 
 EXPORT_NO_SYMBOLS;
 
-#ifdef MODULE
-int init_module(void)
-#else
-int saa7185_init(void)
-#endif
+static int saa7185_init(void)
 {
 	return i2c_register_driver(&i2c_driver_saa7185);
 }
 
-
-
-#ifdef MODULE
-
-void cleanup_module(void)
+static void saa7185_exit(void)
 {
 	i2c_unregister_driver(&i2c_driver_saa7185);
 }
 
-#endif
+module_init(saa7185_init);
+module_exit(saa7185_exit);
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/stradis.c linux/drivers/media/video/stradis.c
--- v2.4.4/linux/drivers/media/video/stradis.c	Thu Apr 19 09:34:05 2001
+++ linux/drivers/media/video/stradis.c	Sat May 19 17:43:06 2001
@@ -63,6 +63,9 @@
 
 static int saa_num = 0;		/* number of SAA7146s in use */
 
+static int video_nr = -1;
+MODULE_PARM(video_nr,"i");
+
 #define nDebNormal	0x00480000
 #define nDebNoInc	0x00480000
 #define nDebVideo	0xd0480000
@@ -2073,7 +2076,7 @@
 		return result;
 	}
 	pci_set_master(dev);
-	if (video_register_device(&saa->video_dev, VFL_TYPE_GRABBER) < 0) {
+	if (video_register_device(&saa->video_dev, VFL_TYPE_GRABBER, video_nr) < 0) {
 		iounmap(saa->saa7146_mem);
 		return -1;
 	}
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/tda9875.c linux/drivers/media/video/tda9875.c
--- v2.4.4/linux/drivers/media/video/tda9875.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/media/video/tda9875.c	Sat May 19 17:43:06 2001
@@ -80,8 +80,8 @@
 #define TDA9875_DACOS       0x13  /*DAC i/o select (ADC) 0b0000100*/
 #define TDA9875_LOSR        0x16  /*Line output select regirter 0b0100 0001*/
 
-#define TDA9875_CH1V        0x0c  /*Chanel 1 volume (mute)*/
-#define TDA9875_CH2V        0x0d  /*Chanel 2 volume (mute)*/
+#define TDA9875_CH1V        0x0c  /*Channel 1 volume (mute)*/
+#define TDA9875_CH2V        0x0d  /*Channel 2 volume (mute)*/
 #define TDA9875_SC1         0x14  /*SCART 1 in (mono)*/
 #define TDA9875_SC2         0x15  /*SCART 2 in (mono)*/
 
@@ -182,8 +182,8 @@
 	tda9875_write(client, TDA9875_SC1, 0x00 );    /* SCART 1 (SC1)*/
 	tda9875_write(client, TDA9875_SC2, 0x01 );    /* SCART 2 (sc2)*/
         
-	tda9875_write(client, TDA9875_CH1V, 0x10 );  /* Chanel volume 1 mute*/
-	tda9875_write(client, TDA9875_CH2V, 0x10 );  /* Chanel volume 2 mute */
+	tda9875_write(client, TDA9875_CH1V, 0x10 );  /* Channel volume 1 mute*/
+	tda9875_write(client, TDA9875_CH2V, 0x10 );  /* Channel volume 2 mute */
 	tda9875_write(client, TDA9875_DACOS, 0x02 ); /* sig DAC i/o(in:nicam)*/
 	tda9875_write(client, TDA9875_ADCIS, 0x6f ); /* sig ADC input(in:mono)*/
 	tda9875_write(client, TDA9875_LOSR, 0x00 );  /* line out (in:mono)*/
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/tvaudio.c linux/drivers/media/video/tvaudio.c
--- v2.4.4/linux/drivers/media/video/tvaudio.c	Mon Feb 19 14:43:36 2001
+++ linux/drivers/media/video/tvaudio.c	Tue May  1 16:05:00 2001
@@ -124,7 +124,7 @@
 
 
 /* ---------------------------------------------------------------------- */
-/* i2c adresses                                                           */
+/* i2c addresses                                                           */
 
 static unsigned short normal_i2c[] = {
 	I2C_TDA8425   >> 1,
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/videodev.c linux/drivers/media/video/videodev.c
--- v2.4.4/linux/drivers/media/video/videodev.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/video/videodev.c	Sat May 19 18:13:15 2001
@@ -30,6 +30,7 @@
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
+#include <asm/semaphore.h>
 
 #include <linux/kmod.h>
 
@@ -394,7 +395,7 @@
 		if (vfd == d->vdev) {
 			remove_proc_entry(d->name, video_dev_proc_entry);
 			list_del (&d->proc_list);
-			kfree (d);
+			kfree(d);
 			break;
 		}
 	}
@@ -406,9 +407,10 @@
 
 /**
  *	video_register_device - register video4linux devices
- *	@vfd: video device structure we want to register
+ *	@vfd:  video device structure we want to register
  *	@type: type of device to register
- *	FIXME: needs a semaphore on 2.3.x
+ *	@nr:   which device number (0 == /dev/video0, 1 == /dev/video1, ...
+ *             -1 == first free)
  *	
  *	The registration code assigns minor numbers based on the type
  *	requested. -ENFILE is returned in all the device slots for this
@@ -427,14 +429,17 @@
  *
  *	%VFL_TYPE_RADIO - A radio card	
  */
- 
-int video_register_device(struct video_device *vfd, int type)
+
+static DECLARE_MUTEX(videodev_register_lock);
+
+int video_register_device(struct video_device *vfd, int type, int nr)
 {
 	int i=0;
 	int base;
 	int err;
 	int end;
 	char *name_base;
+	char name[16];
 	
 	switch(type)
 	{
@@ -461,49 +466,58 @@
 		default:
 			return -1;
 	}
-	
-	for(i=base;i<end;i++)
-	{
-		if(video_device[i]==NULL)
-		{
-			char name[16];
 
-			video_device[i]=vfd;
-			vfd->minor=i;
-			/* The init call may sleep so we book the slot out
-			   then call */
-			MOD_INC_USE_COUNT;
-			if(vfd->initialize)
-			{
-				err=vfd->initialize(vfd);
-				if(err<0)
-				{
-					video_device[i]=NULL;
-					MOD_DEC_USE_COUNT;
-					return err;
-				}
-			}
-			sprintf (name, "v4l/%s%d", name_base, i - base);
-			/*
-			 *	Start the device root only. Anything else
-			 *	has serious privacy issues.
-			 */
-			vfd->devfs_handle =
-			    devfs_register (NULL, name, DEVFS_FL_DEFAULT,
-					    VIDEO_MAJOR, vfd->minor,
-					    S_IFCHR | S_IRUSR | S_IWUSR,
-					    &video_fops, NULL);
-
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
-			sprintf (name, "%s%d", name_base, i - base);
-			videodev_proc_create_dev (vfd, name);
-#endif
-			
-
-			return 0;
+	/* pick a minor number */
+	down(&videodev_register_lock);
+	if (-1 == nr) {
+		/* use first free */
+		for(i=base;i<end;i++)
+			if (NULL == video_device[i])
+				break;
+		if (i == end) {
+			up(&videodev_register_lock);
+			return -ENFILE;
+		}
+	} else {
+		/* use the one the driver asked for */
+		i = base+nr;
+		if (NULL != video_device[i]) {
+			up(&videodev_register_lock);
+			return -ENFILE;
+		}
+	}
+	video_device[i]=vfd;
+	vfd->minor=i;
+	up(&videodev_register_lock);
+
+	/* The init call may sleep so we book the slot out
+	   then call */
+	MOD_INC_USE_COUNT;
+	if(vfd->initialize) {
+		err=vfd->initialize(vfd);
+		if(err<0) {
+			video_device[i]=NULL;
+			MOD_DEC_USE_COUNT;
+			return err;
 		}
 	}
-	return -ENFILE;
+	sprintf (name, "v4l/%s%d", name_base, i - base);
+	/*
+	 *	Start the device root only. Anything else
+	 *	has serious privacy issues.
+	 */
+	vfd->devfs_handle =
+		devfs_register (NULL, name, DEVFS_FL_DEFAULT,
+				VIDEO_MAJOR, vfd->minor,
+				S_IFCHR | S_IRUSR | S_IWUSR,
+				&video_fops,
+				NULL);
+	
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
+	sprintf (name, "%s%d", name_base, i - base);
+	videodev_proc_create_dev (vfd, name);
+#endif
+	return 0;
 }
 
 /**
@@ -546,7 +560,7 @@
  *	Initialise video for linux
  */
  
-int __init videodev_init(void)
+static int __init videodev_init(void)
 {
 	struct video_init *vfli = video_init_list;
 	
@@ -573,25 +587,28 @@
 	return 0;
 }
 
-#ifdef MODULE		
-int init_module(void)
-{
-	return videodev_init();
-}
-
-void cleanup_module(void)
+static void __exit videodev_exit(void)
 {
+#ifdef MODULE		
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
 	videodev_proc_destroy ();
 #endif
+#endif
 	
 	devfs_unregister_chrdev(VIDEO_MAJOR, "video_capture");
 }
 
-#endif
+module_init(videodev_init)
+module_exit(videodev_exit)
 
 EXPORT_SYMBOL(video_register_device);
 EXPORT_SYMBOL(video_unregister_device);
 
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("Device registrar for Video4Linux drivers");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/w9966.c linux/drivers/media/video/w9966.c
--- v2.4.4/linux/drivers/media/video/w9966.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/media/video/w9966.c	Sat May 19 17:43:06 2001
@@ -0,0 +1,996 @@
+/*
+	Winbond w9966cf Webcam parport driver.
+
+	Version 0.32
+
+	Copyright (C) 2001 Jakob Kemi <jakob.kemi@post.utfors.se>
+
+	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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+	Supported devices:
+	*Lifeview FlyCam Supra (using the Philips saa7111a chip)
+
+	Does any other model using the w9966 interface chip exist ?
+
+	Todo:
+	
+	*Add a working EPP mode, since DMA ECP read isn't implemented
+	in the parport drivers. (That's why it's so sloow)
+
+	*Add support for other ccd-control chips than the saa7111
+	please send me feedback on what kind of chips you have.
+
+	*Add proper probing. I don't know what's wrong with the IEEE1284
+	parport drivers but (IEEE1284_MODE_NIBBLE|IEEE1284_DEVICE_ID)
+	and nibble read seems to be broken for some peripherals.
+
+	*Add probing for onboard SRAM, port directions etc. (if possible)
+
+	*Add support for the hardware compressed modes (maybe using v4l2)
+
+	*Fix better support for the capture window (no skewed images, v4l
+	interface to capt. window)
+
+	*Probably some bugs that I don't know of
+
+	Please support me by sending feedback!
+	
+	Changes:
+	
+	Alan Cox:	Removed RGB mode for kernel merge, added THIS_MODULE
+			and owner support for newer module locks
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/videodev.h>
+#include <linux/parport.h>
+
+//#define DEBUG				// Undef me for production
+
+#ifdef DEBUG
+#define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: "__FUNCTION__ "(): "x, ##a)
+#else
+#define DPRINTF(x...)
+#endif
+
+/*
+ *	Defines, simple typedefs etc.
+ */
+
+#define W9966_DRIVERNAME	"W9966CF Webcam"
+#define W9966_MAXCAMS		4	// Maximum number of cameras
+#define W9966_RBUFFER		2048	// Read buffer (must be an even number)
+#define W9966_SRAMSIZE		131072	// 128kb
+#define W9966_SRAMID		0x02	// check w9966cf.pdf
+
+// Empirically determined window limits
+#define W9966_WND_MIN_X		16
+#define W9966_WND_MIN_Y		14
+#define W9966_WND_MAX_X		705
+#define W9966_WND_MAX_Y		253
+#define W9966_WND_MAX_W		(W9966_WND_MAX_X - W9966_WND_MIN_X)
+#define W9966_WND_MAX_H		(W9966_WND_MAX_Y - W9966_WND_MIN_Y)
+
+// Keep track of our current state
+#define W9966_STATE_PDEV	0x01
+#define W9966_STATE_CLAIMED	0x02
+#define W9966_STATE_VDEV	0x04
+
+#define W9966_I2C_W_ID		0x48
+#define W9966_I2C_R_ID		0x49
+#define W9966_I2C_R_DATA	0x08
+#define W9966_I2C_R_CLOCK	0x04
+#define W9966_I2C_W_DATA	0x02
+#define W9966_I2C_W_CLOCK	0x01
+
+struct w9966_dev {
+	unsigned char dev_state;
+	unsigned char i2c_state;
+	unsigned short ppmode;
+	struct parport* pport;
+	struct pardevice* pdev;
+	struct video_device vdev;
+	unsigned short width;
+	unsigned short height;
+	unsigned char brightness;
+	signed char contrast;
+	signed char color;
+	signed char hue;
+};
+
+/*
+ *	Module specific properties
+ */
+
+MODULE_AUTHOR("Jakob Kemi <jakob.kemi@post.utfors.se>");
+MODULE_DESCRIPTION("Winbond w9966cf WebCam driver (0.32)");
+
+#ifdef MODULE
+static const char* pardev[] = {[0 ... W9966_MAXCAMS] = ""};
+#else
+static const char* pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"};
+#endif
+MODULE_PARM(pardev, "1-" __MODULE_STRING(W9966_MAXCAMS) "s");
+MODULE_PARM_DESC(pardev, "pardev: where to search for\n\
+\teach camera. 'aggressive' means brute-force search.\n\
+\tEg: >pardev=parport3,aggressive,parport2,parport1< would assign
+\tcam 1 to parport3 and search every parport for cam 2 etc...");
+
+static int parmode = 0;
+MODULE_PARM(parmode, "i");
+MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp");
+
+static int video_nr = -1;
+MODULE_PARM(video_nr, "i");
+
+/*
+ *	Private data
+ */
+
+static struct w9966_dev w9966_cams[W9966_MAXCAMS];
+
+/*
+ *	Private function declares
+ */
+
+static inline void w9966_setState(struct w9966_dev* cam, int mask, int val);
+static inline int  w9966_getState(struct w9966_dev* cam, int mask, int val);
+static inline void w9966_pdev_claim(struct w9966_dev *vdev);
+static inline void w9966_pdev_release(struct w9966_dev *vdev);
+
+static int w9966_rReg(struct w9966_dev* cam, int reg);
+static int w9966_wReg(struct w9966_dev* cam, int reg, int data);
+static int w9966_rReg_i2c(struct w9966_dev* cam, int reg);
+static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data);
+static int w9966_findlen(int near, int size, int maxlen);
+static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor);
+static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h);
+
+static int  w9966_init(struct w9966_dev* cam, struct parport* port);
+static void w9966_term(struct w9966_dev* cam);
+
+static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state);
+static inline int  w9966_i2c_setscl(struct w9966_dev* cam, int state);
+static inline int  w9966_i2c_getsda(struct w9966_dev* cam);
+static inline int  w9966_i2c_getscl(struct w9966_dev* cam);
+static int w9966_i2c_wbyte(struct w9966_dev* cam, int data);
+static int w9966_i2c_rbyte(struct w9966_dev* cam);
+
+static int  w9966_v4l_open(struct video_device *vdev, int mode);
+static void w9966_v4l_close(struct video_device *vdev);
+static int  w9966_v4l_ioctl(struct video_device *vdev, unsigned int cmd, void *arg);
+static long w9966_v4l_read(struct video_device *vdev, char *buf, unsigned long count, int noblock);
+
+/*
+ *	Private function defines
+ */
+
+
+// Set camera phase flags, so we know what to uninit when terminating 
+static inline void w9966_setState(struct w9966_dev* cam, int mask, int val)
+{
+	cam->dev_state = (cam->dev_state & ~mask) ^ val;
+}
+
+// Get camera phase flags
+static inline int w9966_getState(struct w9966_dev* cam, int mask, int val)
+{
+	return ((cam->dev_state & mask) == val);
+}
+
+// Claim parport for ourself
+static inline void w9966_pdev_claim(struct w9966_dev* cam)
+{
+	if (w9966_getState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED))
+		return;
+	parport_claim_or_block(cam->pdev);
+	w9966_setState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED);
+}
+
+// Release parport for others to use
+static inline void w9966_pdev_release(struct w9966_dev* cam)
+{
+	if (w9966_getState(cam, W9966_STATE_CLAIMED, 0))
+		return;
+	parport_release(cam->pdev);
+	w9966_setState(cam, W9966_STATE_CLAIMED, 0);
+}
+ 
+// Read register from W9966 interface-chip
+// Expects a claimed pdev
+// -1 on error, else register data (byte)
+static int w9966_rReg(struct w9966_dev* cam, int reg)
+{
+	// ECP, read, regtransfer, REG, REG, REG, REG, REG
+	const unsigned char addr = 0x80 | (reg & 0x1f);
+	unsigned char val;
+	
+	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
+		return -1;
+	if (parport_write(cam->pport, &addr, 1) != 1)
+		return -1;
+	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
+		return -1;
+	if (parport_read(cam->pport, &val, 1) != 1)
+		return -1;
+
+	return val;
+}
+
+// Write register to W9966 interface-chip
+// Expects a claimed pdev
+// -1 on error
+static int w9966_wReg(struct w9966_dev* cam, int reg, int data)
+{
+	// ECP, write, regtransfer, REG, REG, REG, REG, REG
+	const unsigned char addr = 0xc0 | (reg & 0x1f);
+	const unsigned char val = data;
+	
+	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
+		return -1;
+	if (parport_write(cam->pport, &addr, 1) != 1)
+		return -1;
+	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
+		return -1;
+	if (parport_write(cam->pport, &val, 1) != 1)
+		return -1;
+
+	return 0;
+}
+
+// Initialize camera device. Setup all internal flags, set a
+// default video mode, setup ccd-chip, register v4l device etc..
+// Also used for 'probing' of hardware.
+// -1 on error
+static int w9966_init(struct w9966_dev* cam, struct parport* port)
+{
+	if (cam->dev_state != 0)
+		return -1;
+	
+	cam->pport = port;
+	cam->brightness = 128;
+	cam->contrast = 64;
+	cam->color = 64;
+	cam->hue = 0;
+
+// Select requested transfer mode
+	switch(parmode)
+	{
+	default:	// Auto-detect (priority: hw-ecp, hw-epp, sw-ecp)
+	case 0:
+		if (port->modes & PARPORT_MODE_ECP)
+			cam->ppmode = IEEE1284_MODE_ECP;
+		else if (port->modes & PARPORT_MODE_EPP)
+			cam->ppmode = IEEE1284_MODE_EPP;
+		else
+			cam->ppmode = IEEE1284_MODE_ECP;
+		break;	
+	case 1:		// hw- or sw-ecp
+		cam->ppmode = IEEE1284_MODE_ECP;
+		break;
+	case 2:		// hw- or sw-epp
+		cam->ppmode = IEEE1284_MODE_EPP;
+	break;
+	}
+	
+// Tell the parport driver that we exists
+	cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL);
+	if (cam->pdev == NULL) {
+		DPRINTF("parport_register_device() failed\n");
+		return -1;
+	}
+	w9966_setState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);
+
+	w9966_pdev_claim(cam);
+	
+// Setup a default capture mode
+	if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
+		DPRINTF("w9966_setup() failed.\n");
+		return -1;
+	}
+
+	w9966_pdev_release(cam);
+
+// Fill in the video_device struct and register us to v4l
+	memset(&cam->vdev, 0, sizeof(struct video_device));
+	strcpy(cam->vdev.name, W9966_DRIVERNAME);
+	cam->vdev.type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
+	cam->vdev.hardware = VID_HARDWARE_W9966;
+	cam->vdev.open = &w9966_v4l_open;
+	cam->vdev.close = &w9966_v4l_close;
+	cam->vdev.read = &w9966_v4l_read;
+	cam->vdev.ioctl = &w9966_v4l_ioctl;
+	cam->vdev.priv = (void*)cam;
+	cam->vdev.owner = THIS_MODULE;
+
+	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) == -1)		 
+		return -1;
+	
+	w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
+	
+	// All ok
+	printk(
+		"w9966cf: Found and initialized a webcam on %s.\n",
+		cam->pport->name
+	);
+	return 0;
+}
+
+
+// Terminate everything gracefully
+static void w9966_term(struct w9966_dev* cam)
+{
+// Unregister from v4l
+	if (w9966_getState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) {
+		video_unregister_device(&cam->vdev);
+		w9966_setState(cam, W9966_STATE_VDEV, 0);
+	}
+
+// Terminate from IEEE1284 mode and release pdev block
+	if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
+		w9966_pdev_claim(cam);
+		parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
+		w9966_pdev_release(cam);
+	}
+
+// Unregister from parport
+	if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
+		parport_unregister_device(cam->pdev);
+		w9966_setState(cam, W9966_STATE_PDEV, 0);
+	}
+}
+
+
+// Find a good length for capture window (used both for W and H)
+// A bit ugly but pretty functional. The capture length
+// have to match the downscale
+static int w9966_findlen(int near, int size, int maxlen)
+{
+	int bestlen = size;
+	int besterr = abs(near - bestlen);
+	int len;
+
+	for(len = size+1;len < maxlen;len++)
+	{
+		int err;
+		if ( ((64*size) %len) != 0)
+			continue;
+
+		err = abs(near - len);
+
+		// Only continue as long as we keep getting better values
+		if (err > besterr)
+			break;
+		
+		besterr = err;
+		bestlen = len;
+	}
+
+	return bestlen;
+}
+
+// Modify capture window (if necessary) 
+// and calculate downscaling
+// Return -1 on error
+static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor)
+{
+	int maxlen = max - min;
+	int len = *end - *beg + 1;
+	int newlen = w9966_findlen(len, size, maxlen);
+	int err = newlen - len; 
+
+	// Check for bad format
+	if (newlen > maxlen || newlen < size)
+		return -1;
+
+	// Set factor (6 bit fixed)
+	*factor = (64*size) / newlen;
+	if (*factor == 64)
+		*factor = 0x00;	// downscale is disabled
+	else
+		*factor |= 0x80; // set downscale-enable bit
+
+	// Modify old beginning and end
+	*beg -= err / 2;
+	*end += err - (err / 2);
+
+	// Move window if outside borders
+	if (*beg < min) {
+		*end += min - *beg;
+		*beg += min - *beg;
+	}
+	if (*end > max) {
+		*beg -= *end - max;
+		*end -= *end - max;
+	}
+
+	return 0;
+}
+
+// Setup the cameras capture window etc.
+// Expects a claimed pdev
+// return -1 on error
+static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h)
+{
+	unsigned int i;
+	unsigned int enh_s, enh_e;
+	unsigned char scale_x, scale_y;
+	unsigned char regs[0x1c];
+	unsigned char saa7111_regs[] = {
+		0x21, 0x00, 0xd8, 0x23, 0x00, 0x80, 0x80, 0x00,
+		0x88, 0x10, 0x80, 0x40, 0x40, 0x00, 0x01, 0x00,
+		0x48, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x71, 0xe7, 0x00, 0x00, 0xc0
+	};
+	
+	
+	if (w*h*2 > W9966_SRAMSIZE)
+	{
+		DPRINTF("capture window exceeds SRAM size!.\n");
+		w = 200; h = 160;	// Pick default values
+	}
+
+	w &= ~0x1;
+	if (w < 2) w = 2;
+	if (h < 1) h = 1;
+	if (w > W9966_WND_MAX_W) w = W9966_WND_MAX_W;
+	if (h > W9966_WND_MAX_H) h = W9966_WND_MAX_H;
+
+	cam->width = w;
+	cam->height = h;
+
+	enh_s = 0;	
+	enh_e = w*h*2;
+	
+// Modify capture window if necessary and calculate downscaling
+	if (
+		w9966_calcscale(w, W9966_WND_MIN_X, W9966_WND_MAX_X, &x1, &x2, &scale_x) != 0 ||
+		w9966_calcscale(h, W9966_WND_MIN_Y, W9966_WND_MAX_Y, &y1, &y2, &scale_y) != 0
+	) return -1;
+
+	DPRINTF(
+		"%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
+		w, h, x1, x2, y1, y2, scale_x&~0x80, scale_y&~0x80
+	);
+	
+// Setup registers
+	regs[0x00] = 0x00;			// Set normal operation
+	regs[0x01] = 0x18;			// Capture mode
+	regs[0x02] = scale_y;			// V-scaling
+	regs[0x03] = scale_x;			// H-scaling
+	
+	// Capture window	
+	regs[0x04] = (x1 & 0x0ff);		// X-start (8 low bits)
+	regs[0x05] = (x1 & 0x300)>>8;		// X-start (2 high bits)
+	regs[0x06] = (y1 & 0x0ff);		// Y-start (8 low bits)
+	regs[0x07] = (y1 & 0x300)>>8;		// Y-start (2 high bits)
+	regs[0x08] = (x2 & 0x0ff);		// X-end (8 low bits)
+	regs[0x09] = (x2 & 0x300)>>8;		// X-end (2 high bits)
+	regs[0x0a] = (y2 & 0x0ff);		// Y-end (8 low bits)
+
+	regs[0x0c] = W9966_SRAMID;		// SRAM-banks (1x 128kb)
+	
+	// Enhancement layer
+	regs[0x0d] = (enh_s& 0x000ff);		// Enh. start (0-7)
+	regs[0x0e] = (enh_s& 0x0ff00)>>8;	// Enh. start (8-15)
+	regs[0x0f] = (enh_s& 0x70000)>>16;	// Enh. start (16-17/18??)
+	regs[0x10] = (enh_e& 0x000ff);		// Enh. end (0-7)
+	regs[0x11] = (enh_e& 0x0ff00)>>8;	// Enh. end (8-15)
+	regs[0x12] = (enh_e& 0x70000)>>16;	// Enh. end (16-17/18??)
+
+	// Misc
+	regs[0x13] = 0x40;			// VEE control (raw 4:2:2)
+	regs[0x17] = 0x00;			// ???
+	regs[0x18] = cam->i2c_state = 0x00;	// Serial bus
+	regs[0x19] = 0xff;			// I/O port direction control
+	regs[0x1a] = 0xff;			// I/O port data register
+	regs[0x1b] = 0x10;			// ???
+	
+	// SAA7111 chip settings
+	saa7111_regs[0x0a] = cam->brightness;
+	saa7111_regs[0x0b] = cam->contrast;
+	saa7111_regs[0x0c] = cam->color;
+	saa7111_regs[0x0d] = cam->hue;
+
+// Reset (ECP-fifo & serial-bus)
+	if (w9966_wReg(cam, 0x00, 0x03) == -1)
+		return -1;
+
+// Write regs to w9966cf chip
+	for (i = 0; i < 0x1c; i++)
+		if (w9966_wReg(cam, i, regs[i]) == -1)
+			return -1;
+
+// Write regs to saa7111 chip
+	for (i = 0; i < 0x20; i++)
+		if (w9966_wReg_i2c(cam, i, saa7111_regs[i]) == -1)
+			return -1;
+
+	return 0;
+}
+
+/*
+ *	Ugly and primitive i2c protocol functions
+ */
+
+// Sets the data line on the i2c bus.
+// Expects a claimed pdev.
+static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state)
+{
+	if (state)
+		cam->i2c_state |= W9966_I2C_W_DATA;
+	else
+		cam->i2c_state &= ~W9966_I2C_W_DATA;
+	
+	w9966_wReg(cam, 0x18, cam->i2c_state);
+	udelay(5);
+}
+
+// Sets the clock line on the i2c bus.
+// Expects a claimed pdev. -1 on error
+static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state)
+{
+	int timeout;
+	if (state)
+		cam->i2c_state |= W9966_I2C_W_CLOCK;
+	else
+		cam->i2c_state &= ~W9966_I2C_W_CLOCK;
+
+	w9966_wReg(cam, 0x18, cam->i2c_state);
+	udelay(5);
+	
+	// we go to high, we also expect the peripheral to ack.
+	if (state) {
+		timeout = jiffies + 100;
+		while (!w9966_i2c_getscl(cam)) {
+			if (jiffies > timeout)
+				return -1;
+		}
+	}
+	return 0;
+}
+
+// Get peripheral data line
+// Expects a claimed pdev.
+static inline int w9966_i2c_getsda(struct w9966_dev* cam)
+{
+	const unsigned char state = w9966_rReg(cam, 0x18);
+	return ((state & W9966_I2C_R_DATA) > 0);
+}
+
+// Get peripheral clock line
+// Expects a claimed pdev.
+static inline int w9966_i2c_getscl(struct w9966_dev* cam)
+{
+	const unsigned char state = w9966_rReg(cam, 0x18);
+	return ((state & W9966_I2C_R_CLOCK) > 0);
+}
+
+// Write a byte with ack to the i2c bus.
+// Expects a claimed pdev. -1 on error
+static int w9966_i2c_wbyte(struct w9966_dev* cam, int data)
+{
+	int i;
+	for (i = 7; i >= 0; i--)
+	{
+		w9966_i2c_setsda(cam, (data >> i) & 0x01);
+
+		if (w9966_i2c_setscl(cam, 1) == -1)
+			return -1;			
+		w9966_i2c_setscl(cam, 0);
+	}
+
+	w9966_i2c_setsda(cam, 1);
+	
+	if (w9966_i2c_setscl(cam, 1) == -1)
+		return -1;
+	w9966_i2c_setscl(cam, 0);
+	
+	return 0;
+}
+
+// Read a data byte with ack from the i2c-bus
+// Expects a claimed pdev. -1 on error
+static int w9966_i2c_rbyte(struct w9966_dev* cam)
+{
+	unsigned char data = 0x00;
+	int i;	
+	
+	w9966_i2c_setsda(cam, 1);
+
+	for (i = 0; i < 8; i++)
+	{
+		if (w9966_i2c_setscl(cam, 1) == -1)
+			return -1;
+		data = data << 1;
+		if (w9966_i2c_getsda(cam))
+			data |= 0x01;
+		
+		w9966_i2c_setscl(cam, 0);
+	}
+	return data;
+}
+
+// Read a register from the i2c device.
+// Expects claimed pdev. -1 on error
+static int w9966_rReg_i2c(struct w9966_dev* cam, int reg)
+{
+	int data;
+
+	w9966_i2c_setsda(cam, 0);
+	w9966_i2c_setscl(cam, 0);
+
+	if (
+		w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
+		w9966_i2c_wbyte(cam, reg) == -1
+	)
+		return -1;
+
+	w9966_i2c_setsda(cam, 1);
+	if (w9966_i2c_setscl(cam, 1) == -1)
+		return -1;
+	w9966_i2c_setsda(cam, 0);
+	w9966_i2c_setscl(cam, 0);
+
+	if (
+		w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1 ||
+		(data = w9966_i2c_rbyte(cam)) == -1
+	)
+		return -1;
+
+	w9966_i2c_setsda(cam, 0);
+	
+	if (w9966_i2c_setscl(cam, 1) == -1)
+		return -1;
+	w9966_i2c_setsda(cam, 1);
+	
+	return data;
+}
+
+// Write a register to the i2c device.
+// Expects claimed pdev. -1 on error
+static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data)
+{
+	w9966_i2c_setsda(cam, 0);
+	w9966_i2c_setscl(cam, 0);
+
+	if (
+		w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
+		w9966_i2c_wbyte(cam, reg) == -1 ||
+		w9966_i2c_wbyte(cam, data) == -1
+	)
+		return -1;
+
+	w9966_i2c_setsda(cam, 0);
+	if (w9966_i2c_setscl(cam, 1) == -1)
+		return -1;
+		
+	w9966_i2c_setsda(cam, 1);
+
+	return 0;
+}
+
+/*
+ *	Video4linux interfacing
+ */
+
+static int w9966_v4l_open(struct video_device *vdev, int flags)
+{
+	return 0;
+}
+
+static void w9966_v4l_close(struct video_device *vdev)
+{
+}
+
+static int w9966_v4l_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
+{
+	struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;
+	
+	switch(cmd)
+	{
+	case VIDIOCGCAP:
+	{
+		struct video_capability vcap = {
+			W9966_DRIVERNAME,	// name
+			VID_TYPE_CAPTURE | VID_TYPE_SCALES,	// type
+			1, 0,			// vid, aud channels
+			W9966_WND_MAX_W,	// max w
+			W9966_WND_MAX_H,	// max h
+			2, 1			// min w, min h
+		};
+
+		if(copy_to_user(arg, &vcap, sizeof(vcap)) != 0)
+			return -EFAULT;
+
+		return 0;
+	}
+	case VIDIOCGCHAN:
+	{
+		struct video_channel vch;
+		if(copy_from_user(&vch, arg, sizeof(vch)) != 0)
+			return -EFAULT;
+
+		if(vch.channel != 0)	// We only support one channel (#0)
+			return -EINVAL;
+
+		strcpy(vch.name, "CCD-input");
+		vch.flags = 0;		// We have no tuner or audio
+		vch.tuners = 0;
+		vch.type = VIDEO_TYPE_CAMERA;
+		vch.norm = 0;		// ???
+		
+		if(copy_to_user(arg, &vch, sizeof(vch)) != 0)
+			return -EFAULT;
+		
+		return 0;
+	}
+	case VIDIOCSCHAN:
+	{
+		struct video_channel vch;
+		if(copy_from_user(&vch, arg, sizeof(vch) ) != 0)
+			return -EFAULT;
+		
+		if(vch.channel != 0)
+			return -EINVAL;
+		
+		return 0;
+	}
+	case VIDIOCGTUNER:
+	{
+		struct video_tuner vtune;
+		if(copy_from_user(&vtune, arg, sizeof(vtune)) != 0)
+			return -EFAULT;
+		
+		if(vtune.tuner != 0);
+			return -EINVAL;
+		
+		strcpy(vtune.name, "Foo-tuner");
+		vtune.rangelow = 0;
+		vtune.rangehigh = 0;
+		vtune.flags = VIDEO_TUNER_NORM;
+		vtune.mode = VIDEO_MODE_AUTO;
+		vtune.signal = 0xffff;
+		
+		if(copy_to_user(arg, &vtune, sizeof(vtune)) != 0)
+			return -EFAULT;
+		
+		return 0;
+	}
+	case VIDIOCSTUNER:
+	{
+		struct video_tuner vtune;
+		if (copy_from_user(&vtune, arg, sizeof(vtune)) != 0)
+			return -EFAULT;
+		
+		if (vtune.tuner != 0)
+			return -EINVAL;
+		
+		if (vtune.mode != VIDEO_MODE_AUTO)
+			return -EINVAL;
+		
+		return 0;
+	}
+	case VIDIOCGPICT:
+	{
+		struct video_picture vpic = {
+			cam->brightness << 8,	// brightness
+			(cam->hue + 128) << 8,	// hue
+			cam->color << 9,	// color
+			cam->contrast << 9,	// contrast
+			0x8000,			// whiteness
+			16, VIDEO_PALETTE_YUV422// bpp, palette format
+		};
+
+		if(copy_to_user(arg, &vpic, sizeof(vpic)) != 0)
+			return -EFAULT;
+
+		return 0;
+	}
+	case VIDIOCSPICT:
+	{
+		struct video_picture vpic;
+		if(copy_from_user(&vpic, arg, sizeof(vpic)) != 0)
+			return -EFAULT;
+		
+		if (vpic.depth != 16 || vpic.palette != VIDEO_PALETTE_YUV422)
+			return -EINVAL;
+			
+		cam->brightness = vpic.brightness >> 8;
+		cam->hue = (vpic.hue >> 8) - 128;
+		cam->color = vpic.colour >> 9;
+		cam->contrast = vpic.contrast >> 9;
+
+		w9966_pdev_claim(cam);
+		
+		if (
+			w9966_wReg_i2c(cam, 0x0a, cam->brightness) == -1 ||
+			w9966_wReg_i2c(cam, 0x0b, cam->contrast) == -1 ||
+			w9966_wReg_i2c(cam, 0x0c, cam->color) == -1 ||
+			w9966_wReg_i2c(cam, 0x0d, cam->hue) == -1
+		) {
+			w9966_pdev_release(cam);
+			return -EFAULT;
+		}
+		
+		w9966_pdev_release(cam);
+		return 0;
+	}
+	case VIDIOCSWIN:
+	{
+		int ret;
+		struct video_window vwin;
+		
+		if (copy_from_user(&vwin, arg, sizeof(vwin)) != 0)
+			return -EFAULT;		
+		if (vwin.flags != 0)
+			return -EINVAL;
+		if (vwin.clipcount != 0)
+			return -EINVAL;
+		if (vwin.width < 2 || vwin.width > W9966_WND_MAX_W)
+			return -EINVAL;		
+		if (vwin.height < 1 || vwin.height > W9966_WND_MAX_H)
+			return -EINVAL;
+
+		// Update camera regs
+		w9966_pdev_claim(cam);
+		ret = w9966_setup(cam, 0, 0, 1023, 1023, vwin.width, vwin.height);
+		w9966_pdev_release(cam);
+		
+		if (ret != 0) {
+			DPRINTF("VIDIOCSWIN: w9966_setup() failed.\n");
+			return -EFAULT;
+		}
+		
+		return 0;
+	}
+	case VIDIOCGWIN:
+	{
+		struct video_window vwin;
+		memset(&vwin, 0, sizeof(vwin));
+		
+		vwin.width = cam->width;
+		vwin.height = cam->height;
+		
+		if(copy_to_user(arg, &vwin, sizeof(vwin)) != 0)
+			return -EFAULT;
+		
+		return 0;
+	}
+	// Unimplemented
+	case VIDIOCCAPTURE:	
+	case VIDIOCGFBUF:
+	case VIDIOCSFBUF:
+	case VIDIOCKEY:
+	case VIDIOCGFREQ:
+	case VIDIOCSFREQ:
+	case VIDIOCGAUDIO:
+	case VIDIOCSAUDIO:
+		return -EINVAL;
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+// Capture data
+static long w9966_v4l_read(struct video_device *vdev, char *buf, unsigned long count,  int noblock)
+{
+	struct w9966_dev *cam = (struct w9966_dev *)vdev->priv;
+	unsigned char addr = 0xa0;	// ECP, read, CCD-transfer, 00000
+	unsigned char* dest = (unsigned char*)buf;
+	unsigned long dleft = count;
+	
+	// Why would anyone want more than this??
+	if (count > cam->width * cam->height * 2)
+		return -EINVAL;
+	
+	w9966_pdev_claim(cam);
+	w9966_wReg(cam, 0x00, 0x02);	// Reset ECP-FIFO buffer
+	w9966_wReg(cam, 0x00, 0x00);	// Return to normal operation
+	w9966_wReg(cam, 0x01, 0x98);	// Enable capture
+
+	// write special capture-addr and negotiate into data transfer	
+	if (
+		(parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0	)||
+		(parport_write(cam->pport, &addr, 1) != 1						)||
+		(parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0	)
+	) {
+		w9966_pdev_release(cam);
+		return -EFAULT;
+	}
+	
+	while(dleft > 0)
+	{
+		unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
+		unsigned char tbuf[W9966_RBUFFER];
+	
+		if (parport_read(cam->pport, tbuf, tsize) < tsize) {
+			w9966_pdev_release(cam);
+			return -EFAULT;
+		}
+		if (copy_to_user(dest, tbuf, tsize) != 0) {
+			w9966_pdev_release(cam);
+			return -EFAULT;
+		}
+		dest += tsize;
+		dleft -= tsize;
+	}
+	
+	w9966_wReg(cam, 0x01, 0x18);	// Disable capture
+	w9966_pdev_release(cam);
+
+	return count;
+}
+
+
+// Called once for every parport on init
+static void w9966_attach(struct parport *port)
+{
+	int i;
+	
+	for (i = 0; i < W9966_MAXCAMS; i++)
+	{
+		if (w9966_cams[i].dev_state != 0)	// Cam is already assigned
+			continue;
+		if (
+			strcmp(pardev[i], "aggressive") == 0 ||
+			strcmp(pardev[i], port->name) == 0
+		) {
+			if (w9966_init(&w9966_cams[i], port) != 0)
+			w9966_term(&w9966_cams[i]);
+			break;	// return
+		}
+	}
+}
+
+// Called once for every parport on termination
+static void w9966_detach(struct parport *port)
+{
+	int i;
+	for (i = 0; i < W9966_MAXCAMS; i++)
+	if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port)
+		w9966_term(&w9966_cams[i]);
+}
+
+
+static struct parport_driver w9966_ppd = {
+	W9966_DRIVERNAME,
+	w9966_attach,
+	w9966_detach,
+	NULL
+};
+
+// Module entry point
+static int __init w9966_mod_init(void)
+{
+	int i;
+	for (i = 0; i < W9966_MAXCAMS; i++)
+		w9966_cams[i].dev_state = 0;
+
+	return parport_register_driver(&w9966_ppd);
+}
+
+// Module cleanup
+static void __exit w9966_mod_term(void)
+{
+	parport_unregister_driver(&w9966_ppd);
+}
+
+module_init(w9966_mod_init);
+module_exit(w9966_mod_term);
diff -u --recursive --new-file v2.4.4/linux/drivers/media/video/zr36120.c linux/drivers/media/video/zr36120.c
--- v2.4.4/linux/drivers/media/video/zr36120.c	Fri Mar  2 11:12:10 2001
+++ linux/drivers/media/video/zr36120.c	Mon May 21 17:06:00 2001
@@ -57,11 +57,15 @@
 
 static unsigned int triton1=0;			/* triton1 chipset? */
 static unsigned int cardtype[ZORAN_MAX]={ [ 0 ... ZORAN_MAX-1 ] = CARDTYPE };
+static int video_nr = -1;
+static int vbi_nr = -1;
 
 MODULE_AUTHOR("Pauline Middelink <middelin@polyware.nl>");
 MODULE_DESCRIPTION("Zoran ZR36120 based framegrabber");
 MODULE_PARM(triton1,"i");
 MODULE_PARM(cardtype,"1-" __MODULE_STRING(ZORAN_MAX) "i");
+MODULE_PARM(video_nr,"i");
+MODULE_PARM(vbi_nr,"i");
 
 static int zoran_cards;
 static struct zoran zorans[ZORAN_MAX];
@@ -1194,8 +1198,10 @@
 		vcp = vmalloc(sizeof(struct video_clip)*(vw.clipcount+4));
 		if (vcp==NULL)
 			return -ENOMEM;
-		if (vw.clipcount && copy_from_user(vcp,vw.clips,sizeof(struct video_clip)*vw.clipcount))
+		if (vw.clipcount && copy_from_user(vcp,vw.clips,sizeof(struct video_clip)*vw.clipcount)) {
+			vfree(vcp);
 			return -EFAULT;
+		}
 
 		on = ztv->running;
 		if (on)
@@ -1990,13 +1996,13 @@
 	ztv->video_dev = zr36120_template;
 	strcpy(ztv->video_dev.name, ztv->i2c.name);
 	ztv->video_dev.priv = ztv;
-	if (video_register_device(&ztv->video_dev, VFL_TYPE_GRABBER) < 0)
+	if (video_register_device(&ztv->video_dev, VFL_TYPE_GRABBER, video_nr) < 0)
 		return -1;
 
 	ztv->vbi_dev = vbi_template;
 	strcpy(ztv->vbi_dev.name, ztv->i2c.name);
 	ztv->vbi_dev.priv = ztv;
-	if (video_register_device(&ztv->vbi_dev, VFL_TYPE_VBI) < 0) {
+	if (video_register_device(&ztv->vbi_dev, VFL_TYPE_VBI, vbi_nr) < 0) {
 		video_unregister_device(&ztv->video_dev);
 		return -1;
 	}
diff -u --recursive --new-file v2.4.4/linux/drivers/mtd/ftl.c linux/drivers/mtd/ftl.c
--- v2.4.4/linux/drivers/mtd/ftl.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/ftl.c	Sat Apr 28 11:27:54 2001
@@ -915,9 +915,6 @@
 
 static release_t ftl_close(struct inode *inode, struct file *file)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-    struct super_block *sb = get_super(inode->i_rdev);
-#endif
     int minor = MINOR(inode->i_rdev);
     partition_t *part = myparts[minor >> 4];
     int i;
@@ -925,11 +922,7 @@
     DEBUG(0, "ftl_cs: ftl_close(%d)\n", minor);
 
     /* Flush all writes */
-    fsync_dev(inode->i_rdev);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-    if (sb) invalidate_inodes(sb);
-#endif
-    invalidate_buffers(inode->i_rdev);
+    invalidate_device(inode->i_rdev, 1);
 
     /* Wait for any pending erase operations to complete */
     if (part->mtd->sync)
diff -u --recursive --new-file v2.4.4/linux/drivers/mtd/mtdblock.c linux/drivers/mtd/mtdblock.c
--- v2.4.4/linux/drivers/mtd/mtdblock.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/mtdblock.c	Sat Apr 28 11:27:54 2001
@@ -355,19 +355,12 @@
 {
 	int dev;
 	struct mtdblk_dev *mtdblk;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-	struct super_block * sb = get_super(inode->i_rdev);
-#endif
    	DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
 
 	if (inode == NULL)
 		release_return(-ENODEV);
    
-	fsync_dev(inode->i_rdev);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-	if (sb) invalidate_inodes(sb);
-#endif
-	invalidate_buffers(inode->i_rdev);
+	invalidate_device(inode->i_rdev, 1);
 
 	dev = MINOR(inode->i_rdev);
 	mtdblk = mtdblks[dev];
diff -u --recursive --new-file v2.4.4/linux/drivers/mtd/mtdchar.c linux/drivers/mtd/mtdchar.c
--- v2.4.4/linux/drivers/mtd/mtdchar.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/mtdchar.c	Mon May 21 17:06:29 2001
@@ -310,8 +310,10 @@
 		if (!databuf)
 			return -ENOMEM;
 		
-		if (copy_from_user(databuf, buf.ptr, buf.length))
+		if (copy_from_user(databuf, buf.ptr, buf.length)) {
+			kfree(databuf);
 			return -EFAULT;
+		}
 
 		ret = (mtd->write_oob)(mtd, buf.start, buf.length, &retlen, databuf);
 
diff -u --recursive --new-file v2.4.4/linux/drivers/mtd/nftl.c linux/drivers/mtd/nftl.c
--- v2.4.4/linux/drivers/mtd/nftl.c	Fri Feb  9 11:30:23 2001
+++ linux/drivers/mtd/nftl.c	Sat Apr 28 11:27:54 2001
@@ -997,17 +997,13 @@
 
 static int nftl_release(struct inode *inode, struct file *fp)
 {
-	struct super_block *sb = get_super(inode->i_rdev);
 	struct NFTLrecord *thisNFTL;
 
 	thisNFTL = NFTLs[MINOR(inode->i_rdev) / 16];
 
 	DEBUG(MTD_DEBUG_LEVEL2, "NFTL_release\n");
 
-	fsync_dev(inode->i_rdev);
-	if (sb)
-		invalidate_inodes(sb);
-	invalidate_buffers(inode->i_rdev);
+	invalidate_device(inode->i_rdev, 1);
 
 	if (thisNFTL->mtd->sync)
 		thisNFTL->mtd->sync(thisNFTL->mtd);
diff -u --recursive --new-file v2.4.4/linux/drivers/net/8139too.c linux/drivers/net/8139too.c
--- v2.4.4/linux/drivers/net/8139too.c	Thu Apr 19 09:32:48 2001
+++ linux/drivers/net/8139too.c	Mon May  7 14:13:19 2001
@@ -149,7 +149,7 @@
 #include <asm/io.h>
 
 
-#define RTL8139_VERSION "0.9.16"
+#define RTL8139_VERSION "0.9.17"
 #define MODNAME "8139too"
 #define RTL8139_DRIVER_NAME   MODNAME " Fast Ethernet driver " RTL8139_VERSION
 #define PFX MODNAME ": "
@@ -728,7 +728,7 @@
 	struct rtl8139_private *tp;
 	u8 tmp8;
 	int rc;
-	unsigned int i, have_pci_pm = 1;
+	unsigned int i;
 	u32 pio_start, pio_end, pio_flags, pio_len;
 	unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
 	u32 tmp;
@@ -770,10 +770,6 @@
 	DPRINTK("PIO region size == 0x%02X\n", pio_len);
 	DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
 
-	/* ugly hueristic, but it's a chicken-and-egg problem */
-	if (pio_len < RTL8139B_IO_SIZE)
-		have_pci_pm = 0;
-	
 #ifdef USE_IO_OPS
 	/* make sure PCI base addr 0 is PIO */
 	if (!(pio_flags & IORESOURCE_IO)) {
@@ -824,30 +820,7 @@
 #endif /* USE_IO_OPS */
 
 	/* Bring old chips out of low-power mode. */
-	if (have_pci_pm) {
-		u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
-		if ((rtl_chip_info[tp->chipset].flags & HasLWake) &&
-		    (tmp8 & LWAKE))
-			new_tmp8 &= ~LWAKE;
-		new_tmp8 |= Cfg1_PM_Enable;
-		if (new_tmp8 != tmp8) {
-			RTL_W8 (Cfg9346, Cfg9346_Unlock);
-			RTL_W8 (Config1, tmp8);
-			RTL_W8 (Cfg9346, Cfg9346_Lock);
-		}
-		if (rtl_chip_info[tp->chipset].flags & HasLWake) {
-			tmp8 = RTL_R8 (Config4);
-			if (tmp8 & LWPTN)
-				RTL_W8 (Config4, tmp8 & ~LWPTN);
-		}
-	} else {
-		RTL_W8 (HltClk, 'R');
-		tmp8 = RTL_R8 (Config1);
-		tmp8 &= ~(SLEEP | PWRDN);
-		RTL_W8 (Config1, tmp8);
-	}
-
-	rtl8139_chip_reset (ioaddr);
+	RTL_W8 (HltClk, 'R');
 
 	/* check for missing/broken hardware */
 	if (RTL_R32 (TxConfig) == 0xFFFFFFFF) {
@@ -877,6 +850,32 @@
 		tp->chipset,
 		rtl_chip_info[tp->chipset].name);
 
+	if (tp->chipset >= CH_8139B) {
+		u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
+		DPRINTK("PCI PM wakeup\n");
+		if ((rtl_chip_info[tp->chipset].flags & HasLWake) &&
+		    (tmp8 & LWAKE))
+			new_tmp8 &= ~LWAKE;
+		new_tmp8 |= Cfg1_PM_Enable;
+		if (new_tmp8 != tmp8) {
+			RTL_W8 (Cfg9346, Cfg9346_Unlock);
+			RTL_W8 (Config1, tmp8);
+			RTL_W8 (Cfg9346, Cfg9346_Lock);
+		}
+		if (rtl_chip_info[tp->chipset].flags & HasLWake) {
+			tmp8 = RTL_R8 (Config4);
+			if (tmp8 & LWPTN)
+				RTL_W8 (Config4, tmp8 & ~LWPTN);
+		}
+	} else {
+		DPRINTK("Old chip wakeup\n");
+		tmp8 = RTL_R8 (Config1);
+		tmp8 &= ~(SLEEP | PWRDN);
+		RTL_W8 (Config1, tmp8);
+	}
+
+	rtl8139_chip_reset (ioaddr);
+
 	DPRINTK ("EXIT, returning 0\n");
 	*dev_out = dev;
 	return 0;
@@ -1358,11 +1357,16 @@
 		else if ((mii_reg5 & 0x0100) == 0x0100
 				 || (mii_reg5 & 0x00C0) == 0x0040)
 			tp->full_duplex = 1;
-		printk(KERN_INFO"%s: Setting %s%s-duplex based on"
+		if (mii_reg5) {
+			printk(KERN_INFO"%s: Setting %s%s-duplex based on"
 			   " auto-negotiated partner ability %4.4x.\n", dev->name,
 			   mii_reg5 == 0 ? "" :
 			   (mii_reg5 & 0x0180) ? "100mbps " : "10mbps ",
 			   tp->full_duplex ? "full" : "half", mii_reg5);
+		} else {
+			printk(KERN_INFO"%s: media is unconnected, link down, or incompatible connection\n",
+			       dev->name);
+		}
 	}
 
 	if (tp->chipset >= CH_8139B) {
@@ -1542,11 +1546,18 @@
 		    || (mii_reg5 & 0x01C0) == 0x0040;
 		if (tp->full_duplex != duplex) {
 			tp->full_duplex = duplex;
-			printk (KERN_INFO
-				"%s: Setting %s-duplex based on MII #%d link"
-				" partner ability of %4.4x.\n", dev->name,
-				tp->full_duplex ? "full" : "half",
-				tp->phys[0], mii_reg5);
+
+			if (mii_reg5) {
+				printk (KERN_INFO
+					"%s: Setting %s-duplex based on MII #%d link"
+					" partner ability of %4.4x.\n",
+					dev->name,
+					tp->full_duplex ? "full" : "half",
+					tp->phys[0], mii_reg5);
+			} else {
+				printk(KERN_INFO"%s: media is unconnected, link down, or incompatible connection\n",
+				       dev->name);
+			}
 #if 0
 			RTL_W8 (Cfg9346, Cfg9346_Unlock);
 			RTL_W8 (Config1, tp->full_duplex ? 0x60 : 0x20);
diff -u --recursive --new-file v2.4.4/linux/drivers/net/8390.c linux/drivers/net/8390.c
--- v2.4.4/linux/drivers/net/8390.c	Thu Apr 19 09:34:52 2001
+++ linux/drivers/net/8390.c	Wed May 16 10:25:38 2001
@@ -453,6 +453,8 @@
 	{
 		if (!netif_running(dev)) {
 			printk(KERN_WARNING "%s: interrupt from stopped card\n", dev->name);
+			/* rmk - acknowledge the interrupts */
+			outb_p(interrupts, e8390_base + EN0_ISR);
 			interrupts = 0;
 			break;
 		}
diff -u --recursive --new-file v2.4.4/linux/drivers/net/Config.in linux/drivers/net/Config.in
--- v2.4.4/linux/drivers/net/Config.in	Sun Apr 22 15:43:21 2001
+++ linux/drivers/net/Config.in	Sat May 19 17:55:11 2001
@@ -35,6 +35,9 @@
    fi
    if [ "$CONFIG_PPC" = "y" ]; then
       tristate '  MACE (Power Mac ethernet) support' CONFIG_MACE
+      if [ "$CONFIG_MACE" != "n" ]; then
+        bool '    Use AAUI port instead of TP by default' CONFIG_MACE_AAUI_PORT
+      fi
       tristate '  BMAC (G3 ethernet) support' CONFIG_BMAC
       tristate '  GMAC (G4/iBook ethernet) support' CONFIG_GMAC
       tristate '  Symbios 53c885 (Synergy ethernet) support' CONFIG_NCR885E
@@ -143,10 +146,11 @@
          tristate '    Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5
          tristate '    Digi Intl. RightSwitch SE-X support' CONFIG_DGRS
       fi
-      dep_tristate '    DM9102 PCI Fast Ethernet Adapter support (EXPERIMENTAL)' CONFIG_DM9102 $CONFIG_PCI $CONFIG_EXPERIMENTAL
+      dep_tristate '    Davicom DM910x/DM980x support' CONFIG_DM9102 $CONFIG_PCI
       dep_tristate '    EtherExpressPro/100 support' CONFIG_EEPRO100 $CONFIG_PCI
       dep_mbool '      Enable Power Management (EXPERIMENTAL)' CONFIG_EEPRO100_PM $CONFIG_EEPRO100 $CONFIG_EXPERIMENTAL
       dep_tristate '    Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390 $CONFIG_EISA $CONFIG_EXPERIMENTAL
+      dep_tristate '    Myson MTD-8xx PCI Ethernet support' CONFIG_FEALNX $CONFIG_PCI
       dep_tristate '    National Semiconductor DP8381x series PCI Ethernet support' CONFIG_NATSEMI $CONFIG_PCI
       dep_tristate '    PCI NE2000 and clones support (see help)' CONFIG_NE2K_PCI $CONFIG_PCI
       dep_tristate '    Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210 $CONFIG_EISA $CONFIG_EXPERIMENTAL
@@ -261,6 +265,9 @@
       dep_bool '     Aironet 4500/4800 I365 broken support (EXPERIMENTAL)' CONFIG_AIRONET4500_I365 $CONFIG_EXPERIMENTAL
    fi
    dep_tristate '   Aironet 4500/4800 PROC interface ' CONFIG_AIRONET4500_PROC $CONFIG_AIRONET4500 m
+
+# New directory for Wireless LAN devices - cards above will move there
+   source drivers/net/wireless/Config.in
 fi
 
 endmenu
diff -u --recursive --new-file v2.4.4/linux/drivers/net/Makefile linux/drivers/net/Makefile
--- v2.4.4/linux/drivers/net/Makefile	Thu Apr 19 22:46:05 2001
+++ linux/drivers/net/Makefile	Wed May 16 10:25:38 2001
@@ -8,7 +8,7 @@
 obj-n           :=
 obj-            :=
 
-mod-subdirs     := appletalk arcnet fc irda tokenring pcmcia wan
+mod-subdirs     := appletalk arcnet fc irda tokenring pcmcia wireless wan
 
 O_TARGET := net.o
 
@@ -30,6 +30,7 @@
 endif
 
 subdir-$(CONFIG_NET_PCMCIA) += pcmcia
+subdir-$(CONFIG_NET_RADIO) += wireless
 subdir-$(CONFIG_TULIP) += tulip
 subdir-$(CONFIG_IRDA) += irda
 subdir-$(CONFIG_TR) += tokenring
@@ -75,6 +76,7 @@
 obj-$(CONFIG_ACENIC) += acenic.o
 obj-$(CONFIG_NATSEMI) += natsemi.o
 obj-$(CONFIG_STNIC) += stnic.o 8390.o
+obj-$(CONFIG_FEALNX) += fealnx.o
 
 ifeq ($(CONFIG_SK98LIN),y)
 obj-y += sk98lin/sk98lin.o
diff -u --recursive --new-file v2.4.4/linux/drivers/net/acenic.h linux/drivers/net/acenic.h
--- v2.4.4/linux/drivers/net/acenic.h	Thu Apr 12 12:11:39 2001
+++ linux/drivers/net/acenic.h	Sun May 20 12:11:38 2001
@@ -1,6 +1,7 @@
 #ifndef _ACENIC_H_
 #define _ACENIC_H_
 
+#include <linux/config.h>
 
 /*
  * Generate TX index update each time, when TX ring is closed.
diff -u --recursive --new-file v2.4.4/linux/drivers/net/acenic_firmware.h linux/drivers/net/acenic_firmware.h
--- v2.4.4/linux/drivers/net/acenic_firmware.h	Tue Mar  6 19:28:33 2001
+++ linux/drivers/net/acenic_firmware.h	Tue May  1 22:03:44 2001
@@ -17,7 +17,7 @@
 #define tigonFwSbssLen 0x38
 #define tigonFwBssAddr 0x00015dd0
 #define tigonFwBssLen 0x2080
-#ifndef CONFIG_ACENIC_OMIT_TIGON_I
+#ifdef CONFIG_ACENIC_OMIT_TIGON_I
 #define tigonFwText 0
 #define tigonFwData 0
 #define tigonFwRodata 0
diff -u --recursive --new-file v2.4.4/linux/drivers/net/appletalk/cops.c linux/drivers/net/appletalk/cops.c
--- v2.4.4/linux/drivers/net/appletalk/cops.c	Wed Apr 18 14:40:05 2001
+++ linux/drivers/net/appletalk/cops.c	Wed May 16 10:31:27 2001
@@ -1,7 +1,7 @@
 /*      cops.c: LocalTalk driver for Linux.
  *
  *	Authors:
- *      - Jay Schulist <jschlst@turbolinux.com>
+ *      - Jay Schulist <jschlst@samba.org>
  *
  *	With more than a little help from;
  *	- Alan Cox <Alan.Cox@linux.org> 
@@ -34,7 +34,7 @@
  */
 
 static const char *version =
-"cops.c:v0.04 6/7/98 Jay Schulist <jschlst@turbolinux.com>\n";
+"cops.c:v0.04 6/7/98 Jay Schulist <jschlst@samba.org>\n";
 /*
  *  Sources:
  *      COPS Localtalk SDK. This provides almost all of the information
diff -u --recursive --new-file v2.4.4/linux/drivers/net/appletalk/cops.h linux/drivers/net/appletalk/cops.h
--- v2.4.4/linux/drivers/net/appletalk/cops.h	Fri Mar  3 12:54:44 2000
+++ linux/drivers/net/appletalk/cops.h	Wed May 16 10:31:27 2001
@@ -1,7 +1,7 @@
 /*      cops.h: LocalTalk driver for Linux.
  *
  *      Authors:
- *      - Jay Schulist <jschlst@turbolinux.com>
+ *      - Jay Schulist <jschlst@samba.org>
  */
 
 #ifndef __LINUX_COPSLTALK_H
diff -u --recursive --new-file v2.4.4/linux/drivers/net/appletalk/cops_ffdrv.h linux/drivers/net/appletalk/cops_ffdrv.h
--- v2.4.4/linux/drivers/net/appletalk/cops_ffdrv.h	Mon Dec 11 13:00:20 2000
+++ linux/drivers/net/appletalk/cops_ffdrv.h	Wed May 16 10:31:27 2001
@@ -21,7 +21,7 @@
 /*      cops_ffdrv.h: LocalTalk driver firmware dump for Linux.
  *
  *      Authors:
- *      - Jay Schulist <jschlst@turbolinux.com>
+ *      - Jay Schulist <jschlst@samba.org>
  */
 
 #include <linux/config.h>
diff -u --recursive --new-file v2.4.4/linux/drivers/net/appletalk/cops_ltdrv.h linux/drivers/net/appletalk/cops_ltdrv.h
--- v2.4.4/linux/drivers/net/appletalk/cops_ltdrv.h	Mon Dec 11 13:00:20 2000
+++ linux/drivers/net/appletalk/cops_ltdrv.h	Wed May 16 10:31:27 2001
@@ -20,7 +20,7 @@
 /*      cops_ltdrv.h: LocalTalk driver firmware dump for Linux.
  *
  *      Authors:
- *      - Jay Schulist <jschlst@turbolinux.com>
+ *      - Jay Schulist <jschlst@samba.org>
  */
  
 #include <linux/config.h>
diff -u --recursive --new-file v2.4.4/linux/drivers/net/appletalk/ipddp.c linux/drivers/net/appletalk/ipddp.c
--- v2.4.4/linux/drivers/net/appletalk/ipddp.c	Fri Apr 13 20:26:07 2001
+++ linux/drivers/net/appletalk/ipddp.c	Wed May 16 10:31:27 2001
@@ -4,7 +4,7 @@
  *
  *	Authors:
  *      - DDP-IP Encap by: Bradford W. Johnson <johns393@maroon.tc.umn.edu>
- *	- DDP-IP Decap by: Jay Schulist <jschlst@turbolinux.com>
+ *	- DDP-IP Decap by: Jay Schulist <jschlst@samba.org>
  *
  *	Derived from:
  *	- Almost all code already existed in net/appletalk/ddp.c I just
@@ -14,7 +14,7 @@
  *        Written 1993-94 by Donald Becker.
  *	- dummy.c: A dummy net driver. By Nick Holloway.
  *	- MacGate: A user space Daemon for Appletalk-IP Decap for
- *	  Linux by Jay Schulist <jschlst@turbolinux.com>
+ *	  Linux by Jay Schulist <jschlst@samba.org>
  *
  *      Copyright 1993 United States Government as represented by the
  *      Director, National Security Agency.
@@ -69,7 +69,7 @@
 		printk("%s: Appletalk-IP Encap. mode by Bradford W. Johnson <johns393@maroon.tc.umn.edu>\n", 
 			dev->name);
 	if(ipddp_mode == IPDDP_DECAP)
-		printk("%s: Appletalk-IP Decap. mode by Jay Schulist <jschlst@turbolinux.com>\n", 
+		printk("%s: Appletalk-IP Decap. mode by Jay Schulist <jschlst@samba.org>\n", 
 			dev->name);
 
 	/* Fill in the device structure with ethernet-generic values. */
diff -u --recursive --new-file v2.4.4/linux/drivers/net/bmac.c linux/drivers/net/bmac.c
--- v2.4.4/linux/drivers/net/bmac.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/bmac.c	Wed May 16 09:58:36 2001
@@ -76,9 +76,6 @@
 	struct net_device_stats stats;
 	struct timer_list tx_timeout;
 	int timeout_active;
-	int reset_and_enabled;
-	int rx_allocated;
-	int tx_allocated;
 	unsigned short hash_use_count[64];
 	unsigned short hash_table_mask[4];
 	struct net_device *next_bmac;
@@ -126,6 +123,7 @@
 };
 
 static struct net_device *bmac_devs;
+static unsigned char *bmac_emergency_rxbuf;
 
 #ifdef CONFIG_PMAC_PBOOK
 static int bmac_sleep_notify(struct pmu_sleep_notifier *self, int when);
@@ -151,9 +149,9 @@
 static int bmac_transmit_packet(struct sk_buff *skb, struct net_device *dev);
 static struct net_device_stats *bmac_stats(struct net_device *dev);
 static void bmac_set_multicast(struct net_device *dev);
-static int bmac_reset_and_enable(struct net_device *dev, int enable);
+static void bmac_reset_and_enable(struct net_device *dev);
 static void bmac_start_chip(struct net_device *dev);
-static int bmac_init_chip(struct net_device *dev);
+static void bmac_init_chip(struct net_device *dev);
 static void bmac_init_registers(struct net_device *dev);
 static void bmac_reset_chip(struct net_device *dev);
 static int bmac_set_address(struct net_device *dev, void *addr);
@@ -185,17 +183,6 @@
 }
 
 static void
-dbdma_stop(volatile struct dbdma_regs *dmap)
-{
-	dbdma_st32((volatile unsigned long *)&dmap->control,
-		   DBDMA_CLEAR(RUN) | DBDMA_SET(FLUSH));
-	eieio();
-
-	while (dbdma_ld32((volatile unsigned long *)&dmap->status) & (ACTIVE|FLUSH))
-		eieio();
-}
-
-static void
 dbdma_continue(volatile struct dbdma_regs *dmap)
 {
 	dbdma_st32((volatile unsigned long *)&dmap->control,
@@ -467,12 +454,11 @@
 	}
 }
 
-static int
+static void
 bmac_init_chip(struct net_device *dev)
 {
 	bmac_init_phy(dev);
 	bmac_init_registers(dev);
-	return 1;
 }
 
 #ifdef CONFIG_PMAC_PBOOK
@@ -503,7 +489,7 @@
 		break;
 	case PBOOK_WAKE:
 		/* see if this is enough */
-		bmac_reset_and_enable(bmac_devs, 1);
+		bmac_reset_and_enable(bmac_devs);
 		enable_irq(bmac_devs->irq);
 		enable_irq(bp->tx_dma_intr);
 		enable_irq(bp->rx_dma_intr);
@@ -569,9 +555,12 @@
 }
 
 static void
-bmac_construct_rxbuff(unsigned char *addr, volatile struct dbdma_cmd *cp)
+bmac_construct_rxbuff(struct sk_buff *skb, volatile struct dbdma_cmd *cp)
 {
-	dbdma_setcmd(cp, (INPUT_LAST | INTR_ALWAYS), RX_BUFLEN, virt_to_bus(addr), 0);
+	unsigned char *addr = skb? skb->data: bmac_emergency_rxbuf;
+
+	dbdma_setcmd(cp, (INPUT_LAST | INTR_ALWAYS), RX_BUFLEN,
+		     virt_to_bus(addr), 0);
 }
 
 /* Bit-reverse one byte of an ethernet hardware address. */
@@ -586,7 +575,7 @@
 }
 
 
-static int
+static void
 bmac_init_tx_ring(struct bmac_data *bp)
 {
 	volatile struct dbdma_regs *td = bp->tx_dma;
@@ -605,9 +594,6 @@
 	dbdma_reset(td);
 	out_le32(&td->wait_sel, 0x00200020);
 	out_le32(&td->cmdptr, virt_to_bus(bp->tx_cmds));
-
-	return 1;
-
 }
 
 static int
@@ -615,22 +601,20 @@
 {
 	volatile struct dbdma_regs *rd = bp->rx_dma;
 	int i;
+	struct sk_buff *skb;
 
 	/* initialize list of sk_buffs for receiving and set up recv dma */
-	if (!bp->rx_allocated) {
-		for (i = 0; i < N_RX_RING; i++) {
-			bp->rx_bufs[i] = dev_alloc_skb(RX_BUFLEN+2);
-			if (bp->rx_bufs[i] == NULL)
-				return 0;
-			skb_reserve(bp->rx_bufs[i], 2);
+	memset((char *)bp->rx_cmds, 0,
+	       (N_RX_RING + 1) * sizeof(struct dbdma_cmd));
+	for (i = 0; i < N_RX_RING; i++) {
+		if ((skb = bp->rx_bufs[i]) == NULL) {
+			bp->rx_bufs[i] = skb = dev_alloc_skb(RX_BUFLEN+2);
+			if (skb != NULL)
+				skb_reserve(skb, 2);
 		}
-		bp->rx_allocated = 1;
+		bmac_construct_rxbuff(skb, &bp->rx_cmds[i]);
 	}
 
-	memset((char *)bp->rx_cmds, 0, (N_RX_RING+1) * sizeof(struct dbdma_cmd));
-	for (i = 0; i < N_RX_RING; i++)
-		bmac_construct_rxbuff(bp->rx_bufs[i]->data, &bp->rx_cmds[i]);
-
 	bp->rx_empty = 0;
 	bp->rx_fill = i;
 
@@ -706,27 +690,36 @@
 		cp = &bp->rx_cmds[i];
 		stat = ld_le16(&cp->xfer_status);
 		residual = ld_le16(&cp->res_count);
-		if ((stat & ACTIVE) == 0) break;
+		if ((stat & ACTIVE) == 0)
+			break;
 		nb = RX_BUFLEN - residual - 2;
 		if (nb < (ETHERMINPACKET - ETHERCRC)) {
 			skb = NULL;
 			bp->stats.rx_length_errors++;
 			bp->stats.rx_errors++;
-		} else skb =  bp->rx_bufs[i];
+		} else {
+			skb = bp->rx_bufs[i];
+			bp->rx_bufs[i] = NULL;
+		}
 		if (skb != NULL) {
 			nb -= ETHERCRC;
 			skb_put(skb, nb);
 			skb->dev = dev;
 			skb->protocol = eth_type_trans(skb, dev);
 			netif_rx(skb);
-			bp->rx_bufs[i] = dev_alloc_skb(RX_BUFLEN+2);
-			skb_reserve(bp->rx_bufs[i], 2);
-			bmac_construct_rxbuff(bp->rx_bufs[i]->data, &bp->rx_cmds[i]);
+			dev->last_rx = jiffies;
 			++bp->stats.rx_packets;
 			bp->stats.rx_bytes += nb;
 		} else {
 			++bp->stats.rx_dropped;
 		}
+		dev->last_rx = jiffies;
+		if ((skb = bp->rx_bufs[i]) == NULL) {
+			bp->rx_bufs[i] = skb = dev_alloc_skb(RX_BUFLEN+2);
+			if (skb != NULL)
+				skb_reserve(bp->rx_bufs[i], 2);
+		}
+		bmac_construct_rxbuff(skb, &bp->rx_cmds[i]);
 		st_le16(&cp->res_count, 0);
 		st_le16(&cp->xfer_status, 0);
 		last = i;
@@ -772,7 +765,13 @@
 		if (txintcount < 10) {
 			XXDEBUG(("bmac_txdma_xfer_stat=%#0x\n", stat));
 		}
-		if (!(stat & ACTIVE)) break;
+		if (!(stat & ACTIVE)) {
+			/*
+			 * status field might not have been filled by DBDMA
+			 */
+			if (cp == bus_to_virt(in_le32(&bp->tx_dma->cmdptr)))
+				break;
+		}
 
 		if (bp->tx_bufs[bp->tx_empty]) {
 			++bp->stats.tx_packets;
@@ -1215,7 +1214,7 @@
 		}
 }
 
-static int bmac_reset_and_enable(struct net_device *dev, int enable)
+static void bmac_reset_and_enable(struct net_device *dev)
 {
 	struct bmac_data *bp = dev->priv;
 	unsigned long flags;
@@ -1223,22 +1222,19 @@
 	unsigned char *data;
 
 	save_flags(flags); cli();
-	bp->reset_and_enabled = 0;
 	bmac_reset_chip(dev);
-	if (enable) {
-		if (!bmac_init_tx_ring(bp) || !bmac_init_rx_ring(bp))
-			return 0;
-		if (!bmac_init_chip(dev))
-			return 0;
-		bmac_start_chip(dev);
-		bmwrite(dev, INTDISABLE, EnableNormal);
-		bp->reset_and_enabled = 1;
-
-		/*
-		 * It seems that the bmac can't receive until it's transmitted
-		 * a packet.  So we give it a dummy packet to transmit.
-		 */
-		skb = dev_alloc_skb(ETHERMINPACKET);
+	bmac_init_tx_ring(bp);
+	bmac_init_rx_ring(bp);
+	bmac_init_chip(dev);
+	bmac_start_chip(dev);
+	bmwrite(dev, INTDISABLE, EnableNormal);
+
+	/*
+	 * It seems that the bmac can't receive until it's transmitted
+	 * a packet.  So we give it a dummy packet to transmit.
+	 */
+	skb = dev_alloc_skb(ETHERMINPACKET);
+	if (skb != NULL) {
 		data = skb_put(skb, ETHERMINPACKET);
 		memset(data, 0, ETHERMINPACKET);
 		memcpy(data, dev->dev_addr, 6);
@@ -1246,13 +1242,14 @@
 		bmac_transmit_packet(skb, dev);
 	}
 	restore_flags(flags);
-	return 1;
 }
 
 static int __init bmac_probe(void)
 {
 	struct device_node *bmac;
 
+	MOD_INC_USE_COUNT;
+
 	for (bmac = find_devices("bmac"); bmac != 0; bmac = bmac->next)
 		bmac_probe1(bmac, 0);
 	for (bmac = find_compatible_devices("network", "bmac+"); bmac != 0;
@@ -1265,7 +1262,10 @@
 		pmu_register_sleep_notifier(&bmac_sleep_notifier);
 #endif
 	}
-	return 0;
+
+	MOD_DEC_USE_COUNT;
+
+	return bmac_devs? 0: -ENODEV;
 }
 
 static void __init bmac_probe1(struct device_node *bmac, int is_bmac_plus)
@@ -1290,6 +1290,14 @@
 		}
 	}
 
+	if (bmac_emergency_rxbuf == NULL) {
+		bmac_emergency_rxbuf = kmalloc(RX_BUFLEN, GFP_KERNEL);
+		if (bmac_emergency_rxbuf == NULL) {
+			printk(KERN_ERR "BMAC: can't allocate emergency RX buffer\n");
+			return;
+		}
+	}
+
 	dev = init_etherdev(NULL, PRIV_BYTES);
 	if (!dev) {
 		printk(KERN_ERR "init_etherdev failed, out of memory for BMAC %s\n",
@@ -1390,9 +1398,7 @@
 {
 	/* XXDEBUG(("bmac: enter open\n")); */
 	/* reset the chip */
-	if (!bmac_reset_and_enable(dev, 1))
-		return -ENOMEM;
-
+	bmac_reset_and_enable(dev);
 	dev->flags |= IFF_RUNNING;
 	return 0;
 }
@@ -1428,7 +1434,6 @@
 			bp->rx_bufs[i] = NULL;
 		}
 	}
-	bp->rx_allocated = 0;
 	XXDEBUG(("bmac: free tx bufs\n"));
 	for (i = 0; i<N_TX_RING; i++) {
 		if (bp->tx_bufs[i] != NULL) {
@@ -1436,7 +1441,6 @@
 			bp->tx_bufs[i] = NULL;
 		}
 	}
-	bp->reset_and_enabled = 0;
 	XXDEBUG(("bmac: all bufs freed\n"));
 
 	return 0;
@@ -1607,6 +1611,11 @@
 {
 	struct bmac_data *bp;
 	struct net_device *dev;
+
+	if (bmac_emergency_rxbuf != NULL) {
+		kfree(bmac_emergency_rxbuf);
+		bmac_emergency_rxbuf = NULL;
+	}
 
 	if (bmac_devs == 0)
 		return;
diff -u --recursive --new-file v2.4.4/linux/drivers/net/dmfe.c linux/drivers/net/dmfe.c
--- v2.4.4/linux/drivers/net/dmfe.c	Wed Apr 25 16:14:08 2001
+++ linux/drivers/net/dmfe.c	Sat May 19 18:05:23 2001
@@ -1,82 +1,56 @@
 /*
-   dmfe.c: Version 1.30 06/11/2000
+    dmfe.c: Version 1.36p1 2001-05-12 for Linux kernel 2.4.x
 
-   A Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver for Linux. 
-   Copyright (C) 1997  Sten Wang
-   (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
+    A Davicom DM9102/DM9102A/DM9102A+DM9801/DM9102A+DM9802 NIC fast
+    ethernet driver for Linux.
+    Copyright (C) 1997  Sten Wang
 
-   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 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.
+    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.
 
+    DAVICOM Web-Site: www.davicom.com.tw
 
-   Compiler command:
-   "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall 
-   -Wstrict-prototypes -O6 -c dmfe.c"
-   OR
-   "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net -Wall 
-   -Wstrict-prototypes -O6 -c dmfe.c"
+    Author: Sten Wang, 886-3-5798797-8517, E-mail: sten_wang@davicom.com.tw
+    Maintainer: Tobias Ringstrom <tori@unhappy.mine.nu>
 
-   The following steps teach you how to active DM9102 board:
-   1. Used the upper compiler command to compile dmfe.c
-   2. insert dmfe module into kernel
-   "insmod dmfe"        ;;Auto Detection Mode
-   "insmod dmfe mode=0" ;;Force 10M Half Duplex
-   "insmod dmfe mode=1" ;;Force 100M Half Duplex
-   "insmod dmfe mode=4" ;;Force 10M Full Duplex
-   "insmod dmfe mode=5" ;;Force 100M Full Duplex
-   3. config a dm9102 network interface
-   "ifconfig eth0 172.22.3.18"
-   4. active the IP routing table
-   "route add -net 172.22.3.0 eth0"
-   5. Well done. Your DM9102 adapter actived now.
+    (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
 
-   Author: Sten Wang, 886-3-5798797-8517, E-mail: sten_wang@davicom.com.tw
+    Marcelo Tosatti <marcelo@conectiva.com.br> :
+    Made it compile in 2.3 (device to net_device)
 
-   Date:   10/28,1998
+    Alan Cox <alan@redhat.com> :
+    Cleaned up for kernel merge.
+    Removed the back compatibility support
+    Reformatted, fixing spelling etc as I went
+    Removed IRQ 0-15 assumption
 
-   (C)Copyright 1997-1998 DAVICOM Semiconductor, Inc. All Rights Reserved.
+    Jeff Garzik <jgarzik@mandrakesoft.com> :
+    Updated to use new PCI driver API.
+    Resource usage cleanups.
+    Report driver version to user.
 
-   Marcelo Tosatti <marcelo@conectiva.com.br> : 
-   Made it compile in 2.3 (device to net_device)
-   
-   Alan Cox <alan@redhat.com> :
-   Cleaned up for kernel merge.
-   Removed the back compatibility support
-   Reformatted, fixing spelling etc as I went
-   Removed IRQ 0-15 assumption
+    Tobias Ringstrom <tori@unhappy.mine.nu> :
+    Cleaned up and added SMP safety.  Thanks go to Jeff Garzik,
+	Andrew Morton and Frank Davis for the SMP safety fixes.
 
-   Jeff Garzik <jgarzik@mandrakesoft.com> :
-   Updated to use new PCI driver API.
-   Resource usage cleanups.
-   Report driver version to user.
+    TODO
 
-   Tobias Ringstr÷m <zajbot@goteborg.utfors.se> :
-   Added additional proper locking
-   Rewrote the transmit code to actually use the ring buffer,
-   and to generate a lot fewer interrupts.
+    Implement pci_driver::suspend() and pci_driver::resume()
+    power management methods.
 
-   Frank Davis <fdavis112@juno.com>
-   Added SMP-safe locking mechanisms in addition to Andrew Morton's work
+    Check and fix on 64bit and big endian boxes.
 
-   TODO
+    Test and make sure PCI latency is now correct for all cases.
+*/
 
-   Implement pci_driver::suspend() and pci_driver::resume()
-   power management methods.
-
-   Check and fix on 64bit and big endian boxes.
-
-   Test and make sure PCI latency is now correct for all cases.
-
- */
-
-#define DMFE_VERSION "1.30p3 (April 17, 2001)"
+#define DMFE_VERSION "1.36p1 (May 12, 2001)"
 
 #include <linux/module.h>
 
@@ -87,7 +61,7 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-#include <linux/slab.h>
+#include <linux/malloc.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -103,54 +77,58 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 
-static char version[] __initdata =
-KERN_INFO "Davicom DM91xx net driver, version " DMFE_VERSION "\n";
-
-
 
 /* Board/System/Debug information/definition ---------------- */
-#define PCI_DM9132_ID   0x91321282	/* Davicom DM9132 ID */
-#define PCI_DM9102_ID   0x91021282	/* Davicom DM9102 ID */
-#define PCI_DM9100_ID   0x91001282	/* Davicom DM9100 ID */
+#define PCI_DM9132_ID   0x91321282      /* Davicom DM9132 ID */
+#define PCI_DM9102_ID   0x91021282      /* Davicom DM9102 ID */
+#define PCI_DM9100_ID   0x91001282      /* Davicom DM9100 ID */
+#define PCI_DM9009_ID   0x90091282      /* Davicom DM9009 ID */
 
 #define DMFE_SUCC       0
 #define DM9102_IO_SIZE  0x80
 #define DM9102A_IO_SIZE 0x100
-#define TX_FREE_DESC_CNT 0xc	/* Tx packet count */
-#define TX_MAX_SEND_CNT 0x1	/* Maximum tx packet per time */
-#define TX_DESC_CNT     0x10	/* Allocated Tx descriptors */
-#define RX_DESC_CNT     0x10	/* Allocated Rx descriptors */
-#define TX_IRQ_THR      12
-#define DESC_ALL_CNT    TX_DESC_CNT+RX_DESC_CNT
+#define TX_MAX_SEND_CNT 0x1             /* Maximum tx packet per time */
+#define TX_DESC_CNT     0x10            /* Allocated Tx descriptors */
+#define RX_DESC_CNT     0x20            /* Allocated Rx descriptors */
+#define TX_FREE_DESC_CNT (TX_DESC_CNT - 2)	/* Max TX packet count */
+#define TX_WAKE_DESC_CNT (TX_DESC_CNT - 3)	/* TX wakeup count */
+#define DESC_ALL_CNT    (TX_DESC_CNT + RX_DESC_CNT)
 #define TX_BUF_ALLOC    0x600
 #define RX_ALLOC_SIZE   0x620
 #define DM910X_RESET    1
-#define CR6_DEFAULT     0x00280000	/* SF, HD */
-#define CR7_DEFAULT     0x1a2cd
-#define CR15_DEFAULT    0x06	/* TxJabber RxWatchdog */
-#define TDES0_ERR_MASK  0x4302	/* TXJT, LC, EC, FUE */
+#define CR0_DEFAULT     0x00E00000      /* TX & RX burst mode */
+#define CR6_DEFAULT     0x00080000      /* HD */
+#define CR7_DEFAULT     0x180c1
+#define CR15_DEFAULT    0x06            /* TxJabber RxWatchdog */
+#define TDES0_ERR_MASK  0x4302          /* TXJT, LC, EC, FUE */
 #define MAX_PACKET_SIZE 1514
 #define DMFE_MAX_MULTICAST 14
-#define RX_MAX_TRAFFIC  0x14000
+#define RX_COPY_SIZE	100
 #define MAX_CHECK_PACKET 0x8000
+#define DM9801_NOISE_FLOOR 8
+#define DM9802_NOISE_FLOOR 5
 
 #define DMFE_10MHF      0
 #define DMFE_100MHF     1
 #define DMFE_10MFD      4
 #define DMFE_100MFD     5
 #define DMFE_AUTO       8
+#define DMFE_1M_HPNA    0x10
+
+#define DMFE_TXTH_72	0x400000	/* TX TH 72 byte */
+#define DMFE_TXTH_96	0x404000	/* TX TH 96 byte */
+#define DMFE_TXTH_128	0x0000		/* TX TH 128 byte */
+#define DMFE_TXTH_256	0x4000		/* TX TH 256 byte */
+#define DMFE_TXTH_512	0x8000		/* TX TH 512 byte */
+#define DMFE_TXTH_1K	0xC000		/* TX TH 1K  byte */
+
+#define DMFE_TIMER_WUT  (jiffies + HZ * 1)/* timer wakeup time : 1 second */
+#define DMFE_TX_TIMEOUT (HZ * 1.5)	/* tx packet time-out time 1.5 s" */
+#define DMFE_TX_KICK 	(HZ * 0.5)	/* tx packet Kick-out time 0.5 s" */
 
-#define DMFE_TIMER_WUT  (HZ)	/* timer wakeup time : 1 second */
-#define DMFE_TX_TIMEOUT ((HZ*3)/2)	/* tx packet time-out time 1.5 s" */
+#define DMFE_DBUG(dbug_now, msg, vaule) if (dmfe_debug || dbug_now) printk(KERN_ERR "<DMFE>: %s %x\n", msg, vaule)
 
-#define DMFE_DBUG(dbug_now, msg, value)	\
-	if (dmfe_debug || dbug_now)	\
-		printk("DBUG: %s %x\n", msg, value)
-
-#define SHOW_MEDIA_TYPE(mode) \
- 	printk(KERN_WARNING "dmfe: Change Speed to %sMhz %s duplex\n",	\
-	       mode & 1 ? "100" : "10",					\
-	       mode & 4 ? "full":"half");
+#define SHOW_MEDIA_TYPE(mode) printk(KERN_ERR "<DMFE>: Change Speed to %sMhz %s duplex\n",mode & 1 ?"100":"10", mode & 4 ? "full":"half");
 
 
 /* CR9 definition: SROM/MII */
@@ -164,20 +142,17 @@
 #define PHY_DATA_0      0x00000
 #define MDCLKH          0x10000
 
-#define SROM_CLK_WRITE(data, ioaddr) \
-	outl(data | CR9_SROM_READ | CR9_SRCS , ioaddr);			\
-	udelay(5);							\
-	outl(data | CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, ioaddr);	\
-	udelay(5);							\
-	outl(data | CR9_SROM_READ | CR9_SRCS , ioaddr);			\
-	udelay(5);
+#define PHY_POWER_DOWN	0x800
 
-#define __CHK_IO_SIZE(pci_id, dev_rev) \
-	( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x02000030) ) ? \
-		DM9102A_IO_SIZE : DM9102_IO_SIZE
-#define CHK_IO_SIZE(pci_dev, dev_rev) \
-	__CHK_IO_SIZE(((pci_dev)->device << 16) | (pci_dev)->vendor, dev_rev)
+#define SROM_V41_CODE   0x14
 
+#define SROM_CLK_WRITE(data, ioaddr) outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);udelay(5);outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK,ioaddr);udelay(5);outl(data|CR9_SROM_READ|CR9_SRCS,ioaddr);udelay(5);
+
+#define __CHK_IO_SIZE(pci_id, dev_rev) ( ((pci_id)==PCI_DM9132_ID) || ((dev_rev) >= 0x02000030) ) ? DM9102A_IO_SIZE: DM9102_IO_SIZE
+#define CHK_IO_SIZE(pci_dev, dev_rev) __CHK_IO_SIZE(((pci_dev)->device << 16) | (pci_dev)->vendor, dev_rev)
+
+/* Sten Check */
+#define DEVICE net_device
 
 /* Structure/enum declaration ------------------------------- */
 struct tx_desc {
@@ -197,19 +172,26 @@
 };
 
 struct dmfe_board_info {
-	u32 chip_id;		/* Chip vendor/Device ID */
-	u32 chip_revision;	/* Chip revision */
-	struct net_device *next_dev;	/* next device */
-	spinlock_t lock; /* Spinlock */
-	struct pci_dev *net_dev;	/* PCI device */
+	u32 chip_id;			/* Chip vendor/Device ID */
+	u32 chip_revision;		/* Chip revision */
+	struct DEVICE *next_dev;	/* next device */
+	struct pci_dev * net_dev;	/* PCI device */
+	spinlock_t lock;
 
-	unsigned long ioaddr;		/* I/O base address */
+	u32 ioaddr;			/* I/O base address */
 	u32 cr0_data;
 	u32 cr5_data;
 	u32 cr6_data;
 	u32 cr7_data;
 	u32 cr15_data;
-	
+
+	/* pointer for memory physical address */
+	dma_addr_t buf_pool_dma_ptr;	/* Tx buffer pool memory */
+	dma_addr_t buf_pool_dma_start;	/* Tx buffer pool align dword */
+	dma_addr_t desc_pool_dma_ptr;	/* descriptor pool memory */
+	dma_addr_t first_tx_desc_dma;
+	dma_addr_t first_rx_desc_dma;
+
 	/* descriptor pointer */
 	unsigned char *buf_pool_ptr;	/* Tx buffer pool memory */
 	unsigned char *buf_pool_start;	/* Tx buffer pool align dword */
@@ -220,52 +202,82 @@
 	struct rx_desc *first_rx_desc;
 	struct rx_desc *rx_insert_ptr;
 	struct rx_desc *rx_ready_ptr;	/* packet come pointer */
-	int tx_int_pkt_num;	/* number of packets to transmit until
-				 * a transmit interrupt is requested */
-	u32 tx_live_cnt;	/* number of used/live tx slots */
-	u32 rx_avail_cnt;	/* available rx descriptor count */
-	u32 interval_rx_cnt;	/* rx packet count a callback time */
-
-	u16 phy_id2;		/* Phyxcer ID2 */
-
-	u8 media_mode;		/* user specify media mode */
-	u8 op_mode;		/* real work media mode */
+	u32 tx_packet_cnt;		/* transmitted packet count */
+	u32 tx_queue_cnt;		/* wait to send packet count */
+	u32 rx_avail_cnt;		/* available rx descriptor count */
+	u32 interval_rx_cnt;		/* rx packet count a callback time */
+
+	u16 HPNA_command;		/* For HPNA register 16 */
+	u16 HPNA_timer;			/* For HPNA remote device check */
+	u16 dbug_cnt;
+	u16 NIC_capability;		/* NIC media capability */
+	u16 PHY_reg4;			/* Saved Phyxcer register 4 value */
+
+	u8 HPNA_present;		/* 0:none, 1:DM9801, 2:DM9802 */
+	u8 chip_type;			/* Keep DM9102A chip type */
+	u8 media_mode;			/* user specify media mode */
+	u8 op_mode;			/* real work media mode */
 	u8 phy_addr;
-	u8 link_failed;		/* Ever link failed */
-	u8 wait_reset;		/* Hardware failed, need to reset */
-	u8 in_reset_state;	/* Now driver in reset routine */
-	u8 rx_error_cnt;	/* recieved abnormal case count */
-	u8 dm910x_chk_mode;	/* Operating mode check */
+	u8 link_failed;			/* Ever link failed */
+	u8 wait_reset;			/* Hardware failed, need to reset */
+	u8 dm910x_chk_mode;		/* Operating mode check */
+	u8 first_in_callback;		/* Flag to record state */
 	struct timer_list timer;
-	struct net_device_stats stats;	/* statistic counter */
+
+	/* System defined statistic counter */
+	struct net_device_stats stats;
+
+	/* Driver defined statistic counter */
+	unsigned long tx_fifo_underrun;
+	unsigned long tx_loss_carrier;
+	unsigned long tx_no_carrier;
+	unsigned long tx_late_collision;
+	unsigned long tx_excessive_collision;
+	unsigned long tx_jabber_timeout;
+	unsigned long reset_count;
+	unsigned long reset_cr8;
+	unsigned long reset_fatal;
+	unsigned long reset_TXtimeout;
+
+	/* NIC SROM data */
 	unsigned char srom[128];
 };
 
 enum dmfe_offsets {
-	DCR0 = 0, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20, DCR5 = 0x28,
-	DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48, DCR10 = 0x50, DCR11 = 0x58,
-	DCR12 = 0x60, DCR13 = 0x68, DCR14 = 0x70, DCR15 = 0x78
+	DCR0 = 0x00, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20,
+	DCR5 = 0x28, DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48,
+	DCR10 = 0x50, DCR11 = 0x58, DCR12 = 0x60, DCR13 = 0x68, DCR14 = 0x70,
+	DCR15 = 0x78
 };
 
 enum dmfe_CR6_bits {
-	CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80, CR6_FDM = 0x200,
-	CR6_TXSC = 0x2000, CR6_STI = 0x100000, CR6_SFT = 0x200000, CR6_RXA = 0x40000000,
-	CR6_NO_PURGE = 0x20000000
+	CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80,
+	CR6_FDM = 0x200, CR6_TXSC = 0x2000, CR6_STI = 0x100000,
+	CR6_SFT = 0x200000, CR6_RXA = 0x40000000, CR6_NO_PURGE = 0x20000000
 };
 
 /* Global variable declaration ----------------------------- */
-static int dmfe_debug;
-static unsigned char dmfe_media_mode = 8;
-static u32 dmfe_cr6_user_set;
+static int __devinitdata printed_version;
+static char version[] __devinitdata =
+	KERN_INFO "Davicom DM9xxx net driver, version " DMFE_VERSION "\n";
+
+static int dmfe_debug = 0;
+static unsigned char dmfe_media_mode = DMFE_AUTO;
+static u32 dmfe_cr6_user_set = 0;
 
 /* For module input parameter */
-static int debug;
-static u32 cr6set;
+static int debug = 0;
+static u32 cr6set = 0;
 static unsigned char mode = 8;
 static u8 chkmode = 1;
+static u8 HPNA_mode = 0;	/* Default: Low Power/High Speed */
+static u8 HPNA_rx_cmd = 0;	/* Default: Disable Rx remote command */
+static u8 HPNA_tx_cmd = 0;	/* Default: Don't issue remote command */
+static u8 HPNA_NoiseFloor = 0;	/* Default: HPNA NoiseFloor */
+static u8 SF_mode = 0;		/* Special Function: 1:VLAN, 2:RX Flow Control
+				   4: TX pause packet */
 
-static unsigned long CrcTable[256] =
-{
+unsigned long CrcTable[256] = {
 	0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,
 	0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,
 	0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,
@@ -333,83 +345,73 @@
 };
 
 /* function declaration ------------------------------------- */
-static int dmfe_open(struct net_device *);
-static int dmfe_start_xmit(struct sk_buff *, struct net_device *);
-static int dmfe_stop(struct net_device *);
-static struct net_device_stats *dmfe_get_stats(struct net_device *);
-static void dmfe_set_filter_mode(struct net_device *);
-static int dmfe_do_ioctl(struct net_device *, struct ifreq *, int);
-static u16 read_srom_word(long, int);
-static void dmfe_interrupt(int, void *, struct pt_regs *);
+static int dmfe_open(struct DEVICE *);
+static int dmfe_start_xmit(struct sk_buff *, struct DEVICE *);
+static int dmfe_stop(struct DEVICE *);
+static struct net_device_stats * dmfe_get_stats(struct DEVICE *);
+static void dmfe_set_filter_mode(struct DEVICE *);
+static int dmfe_do_ioctl(struct DEVICE *, struct ifreq *, int);
+static u16 read_srom_word(long ,int);
+static void dmfe_interrupt(int , void *, struct pt_regs *);
 static void dmfe_descriptor_init(struct dmfe_board_info *, u32);
 static void allocated_rx_buffer(struct dmfe_board_info *);
 static void update_cr6(u32, u32);
-static void send_filter_frame(struct net_device *, int);
-static void dm9132_id_table(struct net_device *, int);
+static void send_filter_frame(struct DEVICE * ,int);
+static void dm9132_id_table(struct DEVICE * ,int);
 static u16 phy_read(u32, u8, u8, u32);
 static void phy_write(u32, u8, u8, u16, u32);
 static void phy_write_1bit(u32, u32);
 static u16 phy_read_1bit(u32);
-static void dmfe_sense_speed(struct dmfe_board_info *);
+static u8 dmfe_sense_speed(struct dmfe_board_info *);
 static void dmfe_process_mode(struct dmfe_board_info *);
 static void dmfe_timer(unsigned long);
-static void dmfe_rx_packet(struct net_device *, struct dmfe_board_info *);
+static void dmfe_rx_packet(struct DEVICE *, struct dmfe_board_info *);
+static void dmfe_free_tx_pkt(struct DEVICE *, struct dmfe_board_info *);
 static void dmfe_reused_skb(struct dmfe_board_info *, struct sk_buff *);
-static void dmfe_dynamic_reset(struct net_device *);
+static void dmfe_dynamic_reset(struct DEVICE *);
 static void dmfe_free_rxbuffer(struct dmfe_board_info *);
-static void dmfe_init_dm910x(struct net_device *);
+static void dmfe_init_dm910x(struct DEVICE *);
 static unsigned long cal_CRC(unsigned char *, unsigned int, u8);
+static void dmfe_parse_srom(struct dmfe_board_info *);
+static void dmfe_program_DM9801(struct dmfe_board_info *, int);
+static void dmfe_program_DM9802(struct dmfe_board_info *);
+static void dmfe_HPNA_remote_cmd_chk(struct dmfe_board_info * );
+static void dmfe_set_phyxcer(struct dmfe_board_info *);
 
-/* DM910X network board routine ---------------------------- */
+/* DM910X network baord routine ---------------------------- */
 
 /*
- *	Search DM910X board, allocate space and register it
+ *	Search DM910X board ,allocate space and register it
  */
- 
 
-static int __init dmfe_init_one (struct pci_dev *pdev,
-				 const struct pci_device_id *ent)
+static int __devinit dmfe_init_one (struct pci_dev *pdev,
+				    const struct pci_device_id *ent)
 {
 	unsigned long pci_iobase;
 	u8 pci_irqline;
-	struct dmfe_board_info *db;	/* Point a board information structure */
+	struct dmfe_board_info *db;	/* board information structure */
 	int i;
 	struct net_device *dev;
-	u32 dev_rev;
-	u16 pci_command;
+	u32 dev_rev, pci_pmr;
 
-/* when built into the kernel, we only print version if device is found */
-#ifndef MODULE
-	static int printed_version;
 	if (!printed_version++)
 		printk(version);
-#endif
 
-	DMFE_DBUG(0, "dmfe_probe()", 0);
+	DMFE_DBUG(0, "dmfe_init_one()", 0);
 
 	/* Enable Master/IO access, Disable memory access */
 	i = pci_enable_device(pdev);
-	if (i) return i;
-
+	if (i)
+		return i;
 	pci_set_master(pdev);
-	pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
-	pci_command &= ~PCI_COMMAND_MEMORY;
-	pci_write_config_word(pdev, PCI_COMMAND, pci_command);
 
 	pci_iobase = pci_resource_start(pdev, 0);
 	pci_irqline = pdev->irq;
 
-	/* Interrupt check */
-	if (pci_irqline == 0) {
-		printk(KERN_ERR "dmfe(%s): Interrupt wrong : IRQ=%d\n",
-		       pdev->slot_name, pci_irqline);
-		goto err_out;
-	}
-
 	/* iobase check */
-	if (pci_iobase == 0 || pci_resource_len(pdev, 0) == 0) {
-		printk(KERN_ERR "dmfe(%s): I/O base is zero\n", pdev->slot_name);
-		goto err_out;
+	if (pci_iobase == 0) {
+		printk(KERN_ERR "<DMFE>: I/O base is zero\n");
+		return -ENODEV;
 	}
 
 #if 0	/* pci_{enable_device,set_master} sets minimum latency for us now */
@@ -427,15 +429,36 @@
 	/* Init network device */
 	dev = alloc_etherdev(sizeof(*db));
 	if (dev == NULL)
-		goto err_out;
+		return -ENOMEM;
 	SET_MODULE_OWNER(dev);
 
-	if (pci_request_regions(pdev, "dmfe"))
-		goto err_out_netdev;
+	/* IO range check */
+	if (pci_resource_len (pdev, 0) < (CHK_IO_SIZE(pdev, dev_rev)) ) {
+		printk(KERN_ERR "<DMFE>: Allocated I/O size too small\n");
+		goto err_out;
+	}
 
+	if (!request_region(pci_iobase,
+			    pci_resource_len (pdev, 0),
+			    dev->name)) {
+		printk(KERN_ERR "<DMFE>: I/O conflict : IO=%lx Range=%x\n",
+		       pci_iobase, CHK_IO_SIZE(pdev, dev_rev));
+		goto err_out;
+	}
+
+	/* Init system & device */
 	db = dev->priv;
-	pci_set_drvdata(pdev, dev);
-	spin_lock_init(&db->lock);
+
+	/* Allocated Tx/Rx descriptor memory */
+	db->desc_pool_ptr = pci_alloc_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, &db->desc_pool_dma_ptr);
+	db->buf_pool_ptr = pci_alloc_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4, &db->buf_pool_dma_ptr);
+
+	db->first_tx_desc = (struct tx_desc *)db->desc_pool_ptr;
+	db->first_tx_desc_dma = db->desc_pool_dma_ptr;
+	db->buf_pool_start = db->buf_pool_ptr;
+	db->buf_pool_dma_start = db->buf_pool_dma_ptr;
+
+	pdev->driver_data = dev;
 
 	db->chip_id = ent->driver_data;
 	db->ioaddr = pci_iobase;
@@ -445,12 +468,21 @@
 
 	dev->base_addr = pci_iobase;
 	dev->irq = pci_irqline;
+	pci_set_drvdata(pdev, dev);
 	dev->open = &dmfe_open;
 	dev->hard_start_xmit = &dmfe_start_xmit;
 	dev->stop = &dmfe_stop;
 	dev->get_stats = &dmfe_get_stats;
 	dev->set_multicast_list = &dmfe_set_filter_mode;
 	dev->do_ioctl = &dmfe_do_ioctl;
+	spin_lock_init(&db->lock);
+
+	pci_read_config_dword(pdev, 0x50, &pci_pmr);
+	pci_pmr &= 0x70000;
+	if ( (pci_pmr == 0x10000) && (dev_rev == 0x02000031) )
+		db->chip_type = 1;	/* DM9102A E3 */
+	else
+		db->chip_type = 0;
 
 	/* read 64 word srom data */
 	for (i = 0; i < 64; i++)
@@ -460,9 +492,8 @@
 	for (i = 0; i < 6; i++)
 		dev->dev_addr[i] = db->srom[20 + i];
 
-	i = register_netdev(dev);
-	if (i)
-		goto err_out_res;
+	i = register_netdev (dev);
+	if (i) goto err_out;
 
 	printk(KERN_INFO "%s: Davicom DM%04lx at 0x%lx,",
 	       dev->name,
@@ -474,11 +505,9 @@
 
 	return 0;
 
-err_out_res:
-	pci_release_regions(pdev);
-err_out_netdev:
-	kfree(dev);
 err_out:
+	pci_set_drvdata(pdev, NULL);
+	kfree(dev);
 	return -ENODEV;
 }
 
@@ -486,17 +515,22 @@
 static void __exit dmfe_remove_one (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
-	struct dmfe_board_info *db;
+	struct dmfe_board_info *db = dev->priv;
 
 	DMFE_DBUG(0, "dmfe_remove_one()", 0);
-	
-	db = dev->priv;
-
-	unregister_netdev(dev);
-	pci_release_regions(pdev);
-	kfree(dev);	/* free board information */
 
-	pci_set_drvdata(pdev, NULL);
+ 	if (dev) {
+		pci_free_consistent(db->net_dev, sizeof(struct tx_desc) *
+					DESC_ALL_CNT + 0x20, db->desc_pool_ptr,
+ 					db->desc_pool_dma_ptr);
+		pci_free_consistent(db->net_dev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
+					db->buf_pool_ptr, db->buf_pool_dma_ptr);
+		unregister_netdev(dev);
+		release_region(dev->base_addr,
+				CHK_IO_SIZE(pdev, db->chip_revision));
+		kfree(dev);	/* free board information */
+		pci_set_drvdata(pdev, NULL);
+	}
 
 	DMFE_DBUG(0, "dmfe_remove_one() exit", 0);
 }
@@ -506,107 +540,103 @@
  *	Open the interface.
  *	The interface is opened whenever "ifconfig" actives it.
  */
- 
-static int dmfe_open(struct net_device *dev)
+
+static int dmfe_open(struct DEVICE *dev)
 {
 	int ret;
 	struct dmfe_board_info *db = dev->priv;
 
 	DMFE_DBUG(0, "dmfe_open", 0);
 
-	ret = request_irq(dev->irq, &dmfe_interrupt, SA_SHIRQ, dev->name, dev);
+	ret =  request_irq(dev->irq, &dmfe_interrupt, SA_SHIRQ, dev->name, dev);
 	if (ret)
 		return ret;
 
-	/* Allocated Tx/Rx descriptor memory */
-	db->desc_pool_ptr = kmalloc(sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20, GFP_KERNEL | GFP_DMA);
-	if (db->desc_pool_ptr == NULL)
-		return -ENOMEM;
-	if ((u32) db->desc_pool_ptr & 0x1f)
-		db->first_tx_desc = (struct tx_desc *) (((u32) db->desc_pool_ptr & ~0x1f) + 0x20);
-	else
-		db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr;
-
-	/* Allocated Tx buffer memory */
-	db->buf_pool_ptr = kmalloc(TX_BUF_ALLOC * TX_DESC_CNT + 4, GFP_KERNEL | GFP_DMA);
-	if (db->buf_pool_ptr == NULL) {
-		kfree(db->desc_pool_ptr);
-		return -ENOMEM;
-	}
-	if ((u32) db->buf_pool_ptr & 0x3)
-		db->buf_pool_start = (char *) (((u32) db->buf_pool_ptr & ~0x3) + 0x4);
-	else
-		db->buf_pool_start = db->buf_pool_ptr;
-
 	/* system variable init */
 	db->cr6_data = CR6_DEFAULT | dmfe_cr6_user_set;
-	db->tx_int_pkt_num = TX_IRQ_THR;
-	db->tx_live_cnt = 0;
+	db->tx_packet_cnt = 0;
+	db->tx_queue_cnt = 0;
 	db->rx_avail_cnt = 0;
-	db->link_failed = 0;
+	db->link_failed = 1;
 	db->wait_reset = 0;
-	db->in_reset_state = 0;
-	db->rx_error_cnt = 0;
 
-	if (!chkmode || (db->chip_id == PCI_DM9132_ID) || (db->chip_revision >= 0x02000030)) {
-		//db->cr6_data &= ~CR6_SFT;         /* Used Tx threshold */
-		//db->cr6_data |= CR6_NO_PURGE;     /* No purge if rx unavailable */
-		db->cr0_data = 0xc00000;	/* TX/RX desc burst mode */
-		db->dm910x_chk_mode = 4;	/* Enter the normal mode */
-	} else {
+	db->first_in_callback = 0;
+	db->NIC_capability = 0xf;	/* All capability*/
+	db->PHY_reg4 = 0x1e0;
+
+	/* CR6 operation mode decision */
+	if ( !chkmode || (db->chip_id == PCI_DM9132_ID) ||
+		(db->chip_revision >= 0x02000030) ) {
+    		db->cr6_data |= DMFE_TXTH_256;
+		db->cr0_data = CR0_DEFAULT;
+		db->dm910x_chk_mode=4;		/* Enter the normal mode */
+ 	} else {
+		db->cr6_data |= CR6_SFT;	/* Store & Forward mode */
 		db->cr0_data = 0;
 		db->dm910x_chk_mode = 1;	/* Enter the check mode */
 	}
 
-	/* Initialize DM910X board */
+	/* Initilize DM910X board */
 	dmfe_init_dm910x(dev);
 
+	/* Active System Interface */
+	netif_wake_queue(dev);
+
 	/* set and active a timer process */
 	init_timer(&db->timer);
-	db->timer.expires = jiffies + DMFE_TIMER_WUT;
-	db->timer.data = (unsigned long) dev;
+	db->timer.expires = DMFE_TIMER_WUT + HZ * 2;
+	db->timer.data = (unsigned long)dev;
 	db->timer.function = &dmfe_timer;
 	add_timer(&db->timer);
-	
-	netif_wake_queue(dev);
 
 	return 0;
 }
 
-/* Initialize DM910X board
-   Reset DM910X board
-   Initialize TX/Rx descriptor chain structure
-   Send the set-up frame
-   Enable Tx/Rx machine
+
+/*	Initilize DM910X board
+ *	Reset DM910X board
+ *	Initilize TX/Rx descriptor chain structure
+ *	Send the set-up frame
+ *	Enable Tx/Rx machine
  */
-static void dmfe_init_dm910x(struct net_device *dev)
+
+static void dmfe_init_dm910x(struct DEVICE *dev)
 {
 	struct dmfe_board_info *db = dev->priv;
 	u32 ioaddr = db->ioaddr;
-	
+
 	DMFE_DBUG(0, "dmfe_init_dm910x()", 0);
 
-	/* Reset DM910x board : need 32 PCI clock to complete */
+	/* Reset DM910x MAC controller */
 	outl(DM910X_RESET, ioaddr + DCR0);	/* RESET MAC */
-	udelay(5);
+	udelay(100);
 	outl(db->cr0_data, ioaddr + DCR0);
-
-	outl(0x180, ioaddr + DCR12);	/* Let bit 7 output port */
-	outl(0x80, ioaddr + DCR12);	/* RESET DM9102 phyxcer */
-	outl(0x0, ioaddr + DCR12);	/* Clear RESET signal */
+	udelay(5);
 
 	/* Phy addr : DM910(A)2/DM9132/9801, phy address = 1 */
 	db->phy_addr = 1;
 
-	/* Media Mode Check */
+	/* Parser SROM and media mode */
+	dmfe_parse_srom(db);
 	db->media_mode = dmfe_media_mode;
-	if (db->media_mode & DMFE_AUTO)
-		dmfe_sense_speed(db);
-	else
-		db->op_mode = db->media_mode;
-	dmfe_process_mode(db);
 
-	/* Initialize Transmit/Receive decriptor and CR3/4 */
+	/* RESET Phyxcer Chip by GPR port bit 7 */
+	outl(0x180, ioaddr + DCR12);		/* Let bit 7 output port */
+	if (db->chip_id == PCI_DM9009_ID) {
+		outl(0x80, ioaddr + DCR12);	/* Issue RESET signal */
+		mdelay(300);			/* Delay 300 ms */
+	}
+	outl(0x0, ioaddr + DCR12);	/* Clear RESET signal */
+
+	/* Process Phyxcer Media Mode */
+	if ( !(db->media_mode & 0x10) )	/* Force 1M mode */
+		dmfe_set_phyxcer(db);
+
+	/* Media Mode Process */
+	if ( !(db->media_mode & DMFE_AUTO) )
+		db->op_mode = db->media_mode; 	/* Force Mode */
+
+	/* Initiliaze Transmit/Receive decriptor and CR3/4 */
 	dmfe_descriptor_init(db, ioaddr);
 
 	/* Init CR6 to program DM910x operation */
@@ -618,182 +648,184 @@
 	else
 		send_filter_frame(dev, dev->mc_count);	/* DM9102/DM9102A */
 
-	/* Init CR5/CR7, interrupt active bit */
-	outl(0xffffffff, ioaddr + DCR5);	/* clear all CR5 status */
+	/* Init CR7, interrupt active bit */
 	db->cr7_data = CR7_DEFAULT;
 	outl(db->cr7_data, ioaddr + DCR7);
 
 	/* Init CR15, Tx jabber and Rx watchdog timer */
-	db->cr15_data = CR15_DEFAULT;
 	outl(db->cr15_data, ioaddr + DCR15);
 
 	/* Enable DM910X Tx/Rx function */
-	db->cr6_data |= CR6_RXSC | CR6_TXSC;
+	db->cr6_data |= CR6_RXSC | CR6_TXSC | 0x40000;
 	update_cr6(db->cr6_data, ioaddr);
-
 }
 
 
 /*
-   Hardware start transmission.
-   Send a packet to media from the upper layer.
+ *	Hardware start transmission.
+ *	Send a packet to media from the upper layer.
  */
-static int dmfe_start_xmit(struct sk_buff *skb, struct net_device *dev)
+
+static int dmfe_start_xmit(struct sk_buff *skb, struct DEVICE *dev)
 {
 	struct dmfe_board_info *db = dev->priv;
 	struct tx_desc *txptr;
 	unsigned long flags;
 
 	DMFE_DBUG(0, "dmfe_start_xmit", 0);
+
+	/* Resource flag check */
+	netif_stop_queue(dev);
+
+	/* Too large packet check */
+	if (skb->len > MAX_PACKET_SIZE) {
+		printk(KERN_ERR "<DMFE>: big packet = %d\n", (u16)skb->len);
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
 	spin_lock_irqsave(&db->lock, flags);
-	
-	/* transmit this packet */
-	txptr = db->tx_insert_ptr;
-	memcpy((char *) txptr->tx_buf_ptr, (char *) skb->data, skb->len);
-	if (--db->tx_int_pkt_num < 0)
-	{
-		txptr->tdes1 = 0xe1000000 | skb->len;
-		db->tx_int_pkt_num = TX_IRQ_THR;
+
+	/* No Tx resource check, it never happen nromally */
+	if (db->tx_queue_cnt >= TX_FREE_DESC_CNT) {
+		spin_unlock_irqrestore(&db->lock, flags);
+		printk(KERN_ERR "<DMFE>: No Tx resource %d\n", db->tx_queue_cnt);
+		return 1;
 	}
-	else
-		txptr->tdes1 = 0x61000000 | skb->len;
 
-	/* Transmit Packet Process */
-	txptr->tdes0 = 0x80000000;	/* set owner bit to DM910X */
-	outl(0x1, dev->base_addr + DCR1);	/* Issue Tx polling command */
-	dev->trans_start = jiffies;     /* saved the time stamp */
+	/* Disable NIC interrupt */
+	outl(0, dev->base_addr + DCR7);
 
-	/* Point to next transmit free descriptor */
-	txptr = (struct tx_desc *)txptr->next_tx_desc;
+	/* transmit this packet */
+	txptr = db->tx_insert_ptr;
+	memcpy( (char *) txptr->tx_buf_ptr, (char *) skb->data, skb->len);
+	txptr->tdes1 = cpu_to_le32(0xe1000000 | skb->len);
 
-	if (txptr->tdes0 & 0x80000000)
-		netif_stop_queue(dev);
+	/* Point to next transmit free descriptor */
+	db->tx_insert_ptr = (struct tx_desc *) txptr->next_tx_desc;
 
-	db->tx_insert_ptr = txptr;
-	db->tx_live_cnt++;
+	/* Transmit Packet Process */
+	if ( (!db->tx_queue_cnt) && (db->tx_packet_cnt < TX_MAX_SEND_CNT) ) {
+		txptr->tdes0 = cpu_to_le32(0x80000000);	/* Set owner bit */
+		db->tx_packet_cnt++;			/* Ready to send */
+		outl(0x1, dev->base_addr + DCR1);	/* Issue Tx polling */
+		dev->trans_start = jiffies;		/* saved time stamp */
+	} else {
+		db->tx_queue_cnt++;			/* queue TX packet */
+		outl(0x1, dev->base_addr + DCR1);	/* Issue Tx polling */
+	}
 
-	spin_unlock_irqrestore(&db->lock, flags);
+	/* Tx resource check */
+	if ( db->tx_queue_cnt < TX_FREE_DESC_CNT )
+		netif_wake_queue(dev);
 
 	/* free this SKB */
 	dev_kfree_skb(skb);
 
+	/* Restore CR7 to enable interrupt */
+	spin_unlock_irqrestore(&db->lock, flags);
+	outl(db->cr7_data, dev->base_addr + DCR7);
+
 	return 0;
 }
 
+
 /*
  *	Stop the interface.
  *	The interface is stopped when it is brought.
  */
 
-static int dmfe_stop(struct net_device *dev)
+static int dmfe_stop(struct DEVICE *dev)
 {
 	struct dmfe_board_info *db = dev->priv;
 	u32 ioaddr = dev->base_addr;
 
 	DMFE_DBUG(0, "dmfe_stop", 0);
 
+	/* disable system */
 	netif_stop_queue(dev);
 
+	/* deleted timer */
+	del_timer_sync(&db->timer);
+
 	/* Reset & stop DM910X board */
 	outl(DM910X_RESET, ioaddr + DCR0);
 	udelay(5);
+	phy_write(db->ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);
 
-	/* deleted timer */
-	del_timer_sync(&db->timer);
-	
 	/* free interrupt */
 	free_irq(dev->irq, dev);
 
 	/* free allocated rx buffer */
 	dmfe_free_rxbuffer(db);
 
-	/* free all descriptor memory and buffer memory */
-	kfree(db->desc_pool_ptr);
-	kfree(db->buf_pool_ptr);
+#if 0
+	/* show statistic counter */
+	printk("<DMFE>: FU:%lx EC:%lx LC:%lx NC:%lx LOC:%lx TXJT:%lx RESET:%lx RCR8:%lx FAL:%lx TT:%lx\n",
+		db->tx_fifo_underrun, db->tx_excessive_collision,
+		db->tx_late_collision, db->tx_no_carrier, db->tx_loss_carrier,
+		db->tx_jabber_timeout, db->reset_count, db->reset_cr8,
+		db->reset_fatal, db->reset_TXtimeout);
+#endif
 
 	return 0;
 }
 
+
 /*
-   DM9102 interrupt handler
-   receive the packet to upper layer, free the transmitted packet
+ *	DM9102 insterrupt handler
+ *	receive the packet to upper layer, free the transmitted packet
  */
 
 static void dmfe_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
-	struct net_device *dev = dev_id;
-	struct tx_desc *txptr;
-	struct dmfe_board_info *db;
-	u32 ioaddr;
+	struct DEVICE *dev = dev_id;
+	struct dmfe_board_info *db = (struct dmfe_board_info *) dev->priv;
+	u32 ioaddr = dev->base_addr;
 	unsigned long flags;
 
+	DMFE_DBUG(0, "dmfe_interrupt()", 0);
+
 	if (!dev) {
-		DMFE_DBUG(1, "dmfe_interrupt() without device arg", 0);
+		DMFE_DBUG(1, "dmfe_interrupt() without DEVICE arg", 0);
 		return;
 	}
-	/* A real interrupt coming */
-	db = (struct dmfe_board_info *) dev->priv;
-	ioaddr = dev->base_addr;
-
-	DMFE_DBUG(0, "dmfe_interrupt()", 0);
 
 	spin_lock_irqsave(&db->lock, flags);
 
-	/* Disable all interrupt in CR7 to solve the interrupt edge problem */
-	outl(0, ioaddr + DCR7);
-
 	/* Got DM910X status */
 	db->cr5_data = inl(ioaddr + DCR5);
 	outl(db->cr5_data, ioaddr + DCR5);
-	/* printk("CR5=%x\n", db->cr5_data); */
+	if ( !(db->cr5_data & 0xc1) ) {
+		spin_unlock_irqrestore(&db->lock, flags);
+		return;
+	}
+
+	/* Disable all interrupt in CR7 to solve the interrupt edge problem */
+	outl(0, ioaddr + DCR7);
 
 	/* Check system status */
 	if (db->cr5_data & 0x2000) {
-		/* A system bus error occurred */
-		DMFE_DBUG(1, "A system bus error occurred. CR5=", db->cr5_data);
-		netif_stop_queue(dev);
-		db->wait_reset = 1;		/* Need to RESET */
-		outl(0, ioaddr + DCR7);		/* disable all interrupt */
+		/* system bus error happen */
+		DMFE_DBUG(1, "System bus error happen. CR5=", db->cr5_data);
+		db->reset_fatal++;
+		db->wait_reset = 1;	/* Need to RESET */
 		spin_unlock_irqrestore(&db->lock, flags);
 		return;
 	}
 
-	/* Free the transmitted descriptor */
-	txptr = db->tx_remove_ptr;
-	while (db->tx_live_cnt > 0 && (txptr->tdes0 & 0x80000000) == 0)
-	{
-		/* printk("tdes0=%x\n", txptr->tdes0); */
-		db->stats.tx_packets++;
-		
-		if ((txptr->tdes0 & TDES0_ERR_MASK) && (txptr->tdes0 != 0x7fffffff)) {
-			/* printk("tdes0=%x\n", txptr->tdes0); */
-			db->stats.tx_errors++;
-		}
-		/* Transmit statistic counter */
-		if (txptr->tdes0 != 0x7fffffff) {
- 			/* printk("tdes0=%x\n", txptr->tdes0); */
- 			db->stats.collisions += (txptr->tdes0 >> 3) & 0xf;
-			db->stats.tx_bytes += txptr->tdes1 & 0x7ff;
-			if (txptr->tdes0 & TDES0_ERR_MASK)
-				db->stats.tx_errors++;
-		}
-		txptr = (struct tx_desc *) txptr->next_tx_desc;
-		db->tx_live_cnt--;
-	}
-	/* Update TX remove pointer to next */
-	db->tx_remove_ptr = (struct tx_desc *) txptr;
-
-	if ((db->tx_insert_ptr->tdes0 & 0x80000000) == 0)
-		netif_wake_queue(dev);
-
-	/* Received the coming packet */
-	if (db->rx_avail_cnt)
+	 /* Received the coming packet */
+	if ( (db->cr5_data & 0x40) && db->rx_avail_cnt )
 		dmfe_rx_packet(dev, db);
 
 	/* reallocated rx descriptor buffer */
-	if (db->rx_avail_cnt < RX_DESC_CNT)
+	if (db->rx_avail_cnt<RX_DESC_CNT)
 		allocated_rx_buffer(db);
 
+	/* Free the transmitted descriptor */
+	if ( db->cr5_data & 0x01)
+		dmfe_free_tx_pkt(dev, db);
+
 	/* Mode Check */
 	if (db->dm910x_chk_mode & 0x2) {
 		db->dm910x_chk_mode = 0x4;
@@ -802,19 +834,85 @@
 	}
 
 	/* Restore CR7 to enable interrupt mask */
-	if (db->interval_rx_cnt > RX_MAX_TRAFFIC)
-		db->cr7_data = 0x1a28d;
-	else
-		db->cr7_data = 0x1a2cd;
 	outl(db->cr7_data, ioaddr + DCR7);
 
 	spin_unlock_irqrestore(&db->lock, flags);
 }
 
+
 /*
-   Receive the come packet and pass to upper layer
+ *	Free TX resource after TX complete
  */
-static void dmfe_rx_packet(struct net_device *dev, struct dmfe_board_info *db)
+
+static void dmfe_free_tx_pkt(struct DEVICE *dev, struct dmfe_board_info * db)
+{
+	struct tx_desc *txptr;
+	u32 ioaddr = dev->base_addr;
+
+	txptr = db->tx_remove_ptr;
+	while(db->tx_packet_cnt) {
+		/* printk("<DMFE>: tdes0=%x\n", txptr->tdes0); */
+		if (txptr->tdes0 & 0x80000000)
+			break;
+
+		/* A packet sent completed */
+		db->tx_packet_cnt--;
+		db->stats.tx_packets++;
+
+		/* Transmit statistic counter */
+		if ( txptr->tdes0 != 0x7fffffff ) {
+			/* printk("<DMFE>: tdes0=%x\n", txptr->tdes0); */
+			db->stats.collisions += (txptr->tdes0 >> 3) & 0xf;
+			db->stats.tx_bytes += txptr->tdes1 & 0x7ff;
+			if (txptr->tdes0 & TDES0_ERR_MASK) {
+				db->stats.tx_errors++;
+
+				if (txptr->tdes0 & 0x0002) {	/* UnderRun */
+					db->tx_fifo_underrun++;
+					if ( !(db->cr6_data & CR6_SFT) ) {
+						db->cr6_data = db->cr6_data | CR6_SFT;
+						update_cr6(db->cr6_data, db->ioaddr);
+					}
+				}
+				if (txptr->tdes0 & 0x0100)
+					db->tx_excessive_collision++;
+				if (txptr->tdes0 & 0x0200)
+					db->tx_late_collision++;
+				if (txptr->tdes0 & 0x0400)
+					db->tx_no_carrier++;
+				if (txptr->tdes0 & 0x0800)
+					db->tx_loss_carrier++;
+				if (txptr->tdes0 & 0x4000)
+					db->tx_jabber_timeout++;
+			}
+		}
+
+    		txptr = (struct tx_desc *) txptr->next_tx_desc;
+	}/* End of while */
+
+	/* Update TX remove pointer to next */
+	db->tx_remove_ptr = (struct tx_desc *) txptr;
+
+	/* Send the Tx packet in queue */
+	if ( (db->tx_packet_cnt < TX_MAX_SEND_CNT) && db->tx_queue_cnt ) {
+		txptr->tdes0 = cpu_to_le32(0x80000000);	/* Set owner bit */
+		db->tx_packet_cnt++;			/* Ready to send */
+		db->tx_queue_cnt--;
+		outl(0x1, ioaddr + DCR1);		/* Issue Tx polling */
+		dev->trans_start = jiffies;		/* saved time stamp */
+	}
+
+	/* Resource available check */
+	if ( db->tx_queue_cnt < TX_WAKE_DESC_CNT )
+		netif_wake_queue(dev);	/* Active upper layer, send again */
+}
+
+
+/*
+ *	Receive the come packet and pass to upper layer
+ */
+
+static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db)
 {
 	struct rx_desc *rxptr;
 	struct sk_buff *skb;
@@ -822,26 +920,26 @@
 
 	rxptr = db->rx_ready_ptr;
 
-	while (db->rx_avail_cnt) {
+	while(db->rx_avail_cnt) {
 		if (rxptr->rdes0 & 0x80000000)	/* packet owner check */
 			break;
 
 		db->rx_avail_cnt--;
 		db->interval_rx_cnt++;
 
-		if ((rxptr->rdes0 & 0x300) != 0x300) {
+		if ( (rxptr->rdes0 & 0x300) != 0x300) {
 			/* A packet without First/Last flag */
 			/* reused this SKB */
 			DMFE_DBUG(0, "Reused SK buffer, rdes0", rxptr->rdes0);
 			dmfe_reused_skb(db, (struct sk_buff *) rxptr->rx_skb_ptr);
-			/* db->rx_error_cnt++; */
 		} else {
 			/* A packet with First/Last flag */
-			rxlen = ((rxptr->rdes0 >> 16) & 0x3fff) - 4;	/* skip CRC */
+			rxlen = ( (rxptr->rdes0 >> 16) & 0x3fff) - 4;
 
-			if (rxptr->rdes0 & 0x8000) {	/* error summary bit check */
+			/* error summary bit check */
+			if (rxptr->rdes0 & 0x8000) {
 				/* This is a error packet */
-				/* printk("rdes0 error : %x \n", rxptr->rdes0); */
+				//printk("<DMFE>: rdes0: %lx\n", rxptr->rdes0);
 				db->stats.rx_errors++;
 				if (rxptr->rdes0 & 1)
 					db->stats.rx_fifo_errors++;
@@ -850,21 +948,36 @@
 				if (rxptr->rdes0 & 0x80)
 					db->stats.rx_length_errors++;
 			}
-			if (!(rxptr->rdes0 & 0x8000) ||
-			    ((db->cr6_data & CR6_PM) && (rxlen > 6))) {
+
+			if ( !(rxptr->rdes0 & 0x8000) ||
+				((db->cr6_data & CR6_PM) && (rxlen>6)) ) {
 				skb = (struct sk_buff *) rxptr->rx_skb_ptr;
 
 				/* Received Packet CRC check need or not */
-				if ((db->dm910x_chk_mode & 1) && (cal_CRC(skb->tail, rxlen, 1) != (*(unsigned long *) (skb->tail + rxlen)))) {
+				if ( (db->dm910x_chk_mode & 1) &&
+					(cal_CRC(skb->tail, rxlen, 1) !=
+					(*(unsigned long *) (skb->tail+rxlen) )
+					) ) {
 					/* Found a error received packet */
 					dmfe_reused_skb(db, (struct sk_buff *) rxptr->rx_skb_ptr);
 					db->dm910x_chk_mode = 3;
 				} else {
-					/* A good packet coming, send to upper layer */
-					skb->dev = dev;
-					skb_put(skb, rxlen);
+					/* Good packet, send to upper layer */
+					/* Shorst packet used new SKB */
+					if ( (rxlen < RX_COPY_SIZE) &&
+						( (skb = dev_alloc_skb(rxlen + 2) )
+						!= NULL) ) {
+						/* size less than COPY_SIZE, allocated a rxlen SKB */
+						skb->dev = dev;
+						skb_reserve(skb, 2); /* 16byte align */
+						memcpy(skb_put(skb, rxlen), ((struct sk_buff *) rxptr->rx_skb_ptr)->tail, rxlen);
+						dmfe_reused_skb(db, (struct sk_buff *) rxptr->rx_skb_ptr);
+					} else {
+						skb->dev = dev;
+						skb_put(skb, rxlen);
+					}
 					skb->protocol = eth_type_trans(skb, dev);
-					netif_rx(skb);	/* Send to upper layer */
+					netif_rx(skb);
 					dev->last_rx = jiffies;
 					db->stats.rx_packets++;
 					db->stats.rx_bytes += rxlen;
@@ -880,24 +993,27 @@
 	}
 
 	db->rx_ready_ptr = rxptr;
-
 }
 
+
 /*
-   Get statistics from driver.
+ *	Get statistics from driver.
  */
-static struct net_device_stats *dmfe_get_stats(struct net_device *dev)
+
+static struct net_device_stats * dmfe_get_stats(struct DEVICE *dev)
 {
-	struct dmfe_board_info *db = (struct dmfe_board_info *) dev->priv;
+	struct dmfe_board_info *db = (struct dmfe_board_info *)dev->priv;
 
 	DMFE_DBUG(0, "dmfe_get_stats", 0);
 	return &db->stats;
 }
 
+
 /*
-   Set DM910X multicast address
+ * Set DM910X multicast address
  */
-static void dmfe_set_filter_mode(struct net_device *dev)
+
+static void dmfe_set_filter_mode(struct DEVICE * dev)
 {
 	struct dmfe_board_info *db = dev->priv;
 	unsigned long flags;
@@ -912,6 +1028,7 @@
 		spin_unlock_irqrestore(&db->lock, flags);
 		return;
 	}
+
 	if (dev->flags & IFF_ALLMULTI || dev->mc_count > DMFE_MAX_MULTICAST) {
 		DMFE_DBUG(0, "Pass all multicast address", dev->mc_count);
 		db->cr6_data &= ~(CR6_PM | CR6_PBF);
@@ -919,83 +1036,97 @@
 		spin_unlock_irqrestore(&db->lock, flags);
 		return;
 	}
+
 	DMFE_DBUG(0, "Set multicast address", dev->mc_count);
 	if (db->chip_id == PCI_DM9132_ID)
 		dm9132_id_table(dev, dev->mc_count);	/* DM9132 */
 	else
-		send_filter_frame(dev, dev->mc_count);	/* DM9102/DM9102A */
+		send_filter_frame(dev, dev->mc_count); 	/* DM9102/DM9102A */
 	spin_unlock_irqrestore(&db->lock, flags);
 }
 
-/*
-   Process the upper socket ioctl command
- */
 
-/* 
- * The following function just returns 0. Shouldn't it do more? 
+/*
+ *	Process the upper socket ioctl command
  */
 
-static int dmfe_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int dmfe_do_ioctl(struct DEVICE *dev, struct ifreq *ifr, int cmd)
 {
 	DMFE_DBUG(0, "dmfe_do_ioctl()", 0);
 	return 0;
 }
 
+
 /*
-   A periodic timer routine
-   Dynamic media sense, allocated Rx buffer...
+ *	A periodic timer routine
+ *	Dynamic media sense, allocated Rx buffer...
  */
+
 static void dmfe_timer(unsigned long data)
 {
 	u32 tmp_cr8;
 	unsigned char tmp_cr12;
-	struct net_device *dev = (struct net_device *) data;
+	struct DEVICE *dev = (struct DEVICE *) data;
 	struct dmfe_board_info *db = (struct dmfe_board_info *) dev->priv;
-	unsigned long flags;
+ 	unsigned long flags;
 
 	DMFE_DBUG(0, "dmfe_timer()", 0);
 	spin_lock_irqsave(&db->lock, flags);
 
-	/* Do reset now */
-	if (db->in_reset_state) {
-		spin_unlock_irqrestore(&db->lock, flags);
-		return;
+	/* Media mode process when Link OK before enter this route */
+	if (db->first_in_callback == 0) {
+		db->first_in_callback = 1;
+		if (db->chip_type && (db->chip_id==PCI_DM9102_ID)) {
+			db->cr6_data &= ~0x40000;
+			update_cr6(db->cr6_data, db->ioaddr);
+			phy_write(db->ioaddr, db->phy_addr, 0, 0x1000, db->chip_id);
+			db->cr6_data |= 0x40000;
+			update_cr6(db->cr6_data, db->ioaddr);
+			db->timer.expires = DMFE_TIMER_WUT + HZ * 2;
+			add_timer(&db->timer);
+			spin_unlock_irqrestore(&db->lock, flags);
+			return;
+		}
 	}
 
+
 	/* Operating Mode Check */
-	if ((db->dm910x_chk_mode & 0x1) && (db->stats.rx_packets > MAX_CHECK_PACKET)) {
+	if ( (db->dm910x_chk_mode & 0x1) &&
+		(db->stats.rx_packets > MAX_CHECK_PACKET) )
 		db->dm910x_chk_mode = 0x4;
-	}
+
 	/* Dynamic reset DM910X : system error or transmit time-out */
 	tmp_cr8 = inl(db->ioaddr + DCR8);
-	if ((db->interval_rx_cnt == 0) && (tmp_cr8)) {
+	if ( (db->interval_rx_cnt==0) && (tmp_cr8) ) {
+		db->reset_cr8++;
 		db->wait_reset = 1;
-		/* printk("CR8 %x, Interval Rx %x\n", tmp_cr8, db->interval_rx_cnt); */
 	}
-	/* Receiving Traffic check */
-	if (db->interval_rx_cnt > RX_MAX_TRAFFIC)
-		db->cr7_data = 0x1a28d;
-	else
-		db->cr7_data = 0x1a2cd;
-	outl(db->cr7_data, db->ioaddr + DCR7);
-
 	db->interval_rx_cnt = 0;
 
-	if (db->wait_reset ||
-	    (db->tx_live_cnt > 0 &&
-	     ((jiffies - dev->trans_start) > DMFE_TX_TIMEOUT)) ||
-	    (db->rx_error_cnt > 3)) {
-		/*
-		   printk("wait_reset %x, tx cnt %x, rx err %x, time %x\n", db->wait_reset, db->tx_packet_cnt, db->rx_error_cnt, jiffies-dev->trans_start);
-		 */
-		DMFE_DBUG(0, "Warn!! Warn!! Tx/Rx monitor step1", 0);
+	/* TX polling kick monitor */
+	if ( db->tx_packet_cnt &&
+		((jiffies - dev->trans_start) > DMFE_TX_KICK) ) {
+		outl(0x1, dev->base_addr + DCR1);   /* Tx polling again */
+
+		/* TX Timeout */
+		if ( (jiffies - dev->trans_start) > DMFE_TX_TIMEOUT ) {
+			db->reset_TXtimeout++;
+			db->wait_reset = 1;
+			printk(KERN_WARNING "%s: Tx timeout - resetting\n",
+			       dev->name);
+		}
+	}
+
+	if (db->wait_reset) {
+		DMFE_DBUG(0, "Dynamic Reset device", db->tx_packet_cnt);
+		db->reset_count++;
 		dmfe_dynamic_reset(dev);
-		db->timer.expires = jiffies + DMFE_TIMER_WUT;
+		db->first_in_callback = 0;
+		db->timer.expires = DMFE_TIMER_WUT;
 		add_timer(&db->timer);
 		spin_unlock_irqrestore(&db->lock, flags);
 		return;
 	}
-	db->rx_error_cnt = 0;	/* Clear previos counter */
 
 	/* Link status check, Dynamic media type change */
 	if (db->chip_id == PCI_DM9132_ID)
@@ -1003,138 +1134,150 @@
 	else
 		tmp_cr12 = inb(db->ioaddr + DCR12);	/* DM9102/DM9102A */
 
-	if (((db->chip_id == PCI_DM9102_ID) && (db->chip_revision == 0x02000030)) ||
-	    ((db->chip_id == PCI_DM9132_ID) && (db->chip_revision == 0x02000010))) {
+	if ( ((db->chip_id == PCI_DM9102_ID) &&
+		(db->chip_revision == 0x02000030)) ||
+		((db->chip_id == PCI_DM9132_ID) &&
+		(db->chip_revision == 0x02000010)) ) {
 		/* DM9102A Chip */
 		if (tmp_cr12 & 2)
 			tmp_cr12 = 0x0;		/* Link failed */
 		else
-			tmp_cr12 = 0x3;		/* Link OK */
+			tmp_cr12 = 0x3;	/* Link OK */
 	}
-	if (!(tmp_cr12 & 0x3) && !db->link_failed) {
+
+	if ( !(tmp_cr12 & 0x3) && !db->link_failed ) {
 		/* Link Failed */
 		DMFE_DBUG(0, "Link Failed", tmp_cr12);
 		db->link_failed = 1;
-		phy_write(db->ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);	/* reset Phy */
-
-		/* 10/100M link failed, used 1M Home-Net */
-		db->cr6_data |= 0x00040000;	/* CR6 bit18 = 1, select Home-Net */
-		db->cr6_data &= ~0x00000200;	/* CR6 bit9 =0, half duplex mode */
-		update_cr6(db->cr6_data, db->ioaddr);
-
-		/* For DM9801 : PHY ID1 0181h, PHY ID2 B900h */
-		db->phy_id2 = phy_read(db->ioaddr, db->phy_addr, 3, db->chip_id);
-		if (db->phy_id2 == 0xb900)
-			phy_write(db->ioaddr, db->phy_addr, 25, 0x7e08, db->chip_id);
-	} else if ((tmp_cr12 & 0x3) && db->link_failed) {
-		DMFE_DBUG(0, "Link link OK", tmp_cr12);
-		db->link_failed = 0;
 
-		/* CR6 bit18=0, select 10/100M */
-		db->cr6_data &= ~0x00040000;
-		update_cr6(db->cr6_data, db->ioaddr);
+		/* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */
+		/* AUTO or force 1M Homerun/Longrun don't need */
+		if ( !(db->media_mode & 0x38) )
+			phy_write(db->ioaddr, db->phy_addr, 0, 0x1000, db->chip_id);
+
+		/* AUTO mode, if INT phyxcer link failed, select EXT device */
+		if (db->media_mode & DMFE_AUTO) {
+			/* 10/100M link failed, used 1M Home-Net */
+			db->cr6_data|=0x00040000;	/* bit18=1, MII */
+			db->cr6_data&=~0x00000200;	/* bit9=0, HD mode */
+			update_cr6(db->cr6_data, db->ioaddr);
+		}
+	} else
+		if ((tmp_cr12 & 0x3) && db->link_failed) {
+			DMFE_DBUG(0, "Link link OK", tmp_cr12);
+			db->link_failed = 0;
+
+			/* Auto Sense Speed */
+			if ( (db->media_mode & DMFE_AUTO) &&
+				dmfe_sense_speed(db) )
+				db->link_failed = 1;
+			dmfe_process_mode(db);
+			/* SHOW_MEDIA_TYPE(db->op_mode); */
+		}
 
-		/* Auto Sense Speed */
-		if (db->media_mode & DMFE_AUTO)
-			dmfe_sense_speed(db);
-		dmfe_process_mode(db);
-		update_cr6(db->cr6_data, db->ioaddr);
-		/* SHOW_MEDIA_TYPE(db->op_mode); */
+	/* HPNA remote command check */
+	if (db->HPNA_command & 0xf00) {
+		db->HPNA_timer--;
+		if (!db->HPNA_timer)
+			dmfe_HPNA_remote_cmd_chk(db);
 	}
-	/* reallocated rx descriptor buffer */
-	if (db->rx_avail_cnt < RX_DESC_CNT)
-		allocated_rx_buffer(db);
 
 	/* Timer active again */
-	db->timer.expires = jiffies + DMFE_TIMER_WUT;
+	db->timer.expires = DMFE_TIMER_WUT;
 	add_timer(&db->timer);
 	spin_unlock_irqrestore(&db->lock, flags);
 }
 
+
 /*
-   Dynamic reset the DM910X board
-   Stop DM910X board
-   Free Tx/Rx allocated memory
-   Reset DM910X board
-   Re-initialize DM910X board
+ *	Dynamic reset the DM910X board
+ *	Stop DM910X board
+ *	Free Tx/Rx allocated memory
+ *	Reset DM910X board
+ *	Re-initilize DM910X board
  */
-static void dmfe_dynamic_reset(struct net_device *dev)
+
+static void dmfe_dynamic_reset(struct DEVICE *dev)
 {
 	struct dmfe_board_info *db = dev->priv;
 
 	DMFE_DBUG(0, "dmfe_dynamic_reset()", 0);
 
-	/* Enter dynamic reset route */
-	db->in_reset_state = 1;
+	/* Sopt MAC controller */
+	db->cr6_data &= ~(CR6_RXSC | CR6_TXSC);	/* Disable Tx/Rx */
+	update_cr6(db->cr6_data, dev->base_addr);
+	outl(0, dev->base_addr + DCR7);		/* Disable Interrupt */
+	outl(inl(dev->base_addr + DCR5), dev->base_addr + DCR5);
 
 	/* Disable upper layer interface */
 	netif_stop_queue(dev);
-	
-	db->cr6_data &= ~(CR6_RXSC | CR6_TXSC);		/* Disable Tx/Rx */
-	update_cr6(db->cr6_data, dev->base_addr);
 
 	/* Free Rx Allocate buffer */
 	dmfe_free_rxbuffer(db);
 
 	/* system variable init */
-	db->tx_int_pkt_num = TX_IRQ_THR;
-	db->tx_live_cnt = 0;
+	db->tx_packet_cnt = 0;
+	db->tx_queue_cnt = 0;
 	db->rx_avail_cnt = 0;
-	db->link_failed = 0;
+	db->link_failed = 1;
 	db->wait_reset = 0;
-	db->rx_error_cnt = 0;
 
-	/* Re-initialize DM910X board */
+	/* Re-initilize DM910X board */
 	dmfe_init_dm910x(dev);
 
-	/* Leave dynamic reser route */
-	db->in_reset_state = 0;
-
 	/* Restart upper layer interface */
 	netif_wake_queue(dev);
 }
 
+
 /*
-   free all allocated rx buffer 
+ *	free all allocated rx buffer
  */
-static void dmfe_free_rxbuffer(struct dmfe_board_info *db)
+
+static void dmfe_free_rxbuffer(struct dmfe_board_info * db)
 {
 	DMFE_DBUG(0, "dmfe_free_rxbuffer()", 0);
 
 	/* free allocated rx buffer */
 	while (db->rx_avail_cnt) {
-		dev_kfree_skb((void *) (db->rx_ready_ptr->rx_skb_ptr));
+		dev_kfree_skb( (void *) (db->rx_ready_ptr->rx_skb_ptr) );
 		db->rx_ready_ptr = (struct rx_desc *) db->rx_ready_ptr->next_rx_desc;
 		db->rx_avail_cnt--;
 	}
 }
 
+
 /*
-   Reused the SK buffer
+ *	Reused the SK buffer
  */
-static void dmfe_reused_skb(struct dmfe_board_info *db, struct sk_buff *skb)
+
+static void dmfe_reused_skb(struct dmfe_board_info *db, struct sk_buff * skb)
 {
 	struct rx_desc *rxptr = db->rx_insert_ptr;
 
 	if (!(rxptr->rdes0 & 0x80000000)) {
 		rxptr->rx_skb_ptr = (u32) skb;
-		rxptr->rdes2 = virt_to_bus(skb->tail);
-		rxptr->rdes0 = 0x80000000;
+		rxptr->rdes2 = cpu_to_le32( pci_map_single(db->net_dev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
+		rxptr->rdes0 = cpu_to_le32(0x80000000);
 		db->rx_avail_cnt++;
 		db->rx_insert_ptr = (struct rx_desc *) rxptr->next_rx_desc;
 	} else
 		DMFE_DBUG(0, "SK Buffer reused method error", db->rx_avail_cnt);
 }
 
+
 /*
-   Initialize transmit/Receive descriptor 
-   Using Chain structure, and allocated Tx/Rx buffer
+ *	Initialize transmit/Receive descriptor
+ *	Using Chain structure, and allocated Tx/Rx buffer
  */
+
 static void dmfe_descriptor_init(struct dmfe_board_info *db, u32 ioaddr)
 {
 	struct tx_desc *tmp_tx;
 	struct rx_desc *tmp_rx;
 	unsigned char *tmp_buf;
+	dma_addr_t tmp_tx_dma, tmp_rx_dma;
+	dma_addr_t tmp_buf_dma;
 	int i;
 
 	DMFE_DBUG(0, "dmfe_descriptor_init()", 0);
@@ -1142,67 +1285,77 @@
 	/* tx descriptor start pointer */
 	db->tx_insert_ptr = db->first_tx_desc;
 	db->tx_remove_ptr = db->first_tx_desc;
-	outl(virt_to_bus(db->first_tx_desc), ioaddr + DCR4);	/* Init CR4 */
+	outl(db->first_tx_desc_dma, ioaddr + DCR4);     /* TX DESC address */
 
 	/* rx descriptor start pointer */
-	db->first_rx_desc = (struct rx_desc *)
-	    ((u32) db->first_tx_desc + sizeof(struct rx_desc) * TX_DESC_CNT);
+	db->first_rx_desc = (struct rx_desc *) ( (u32) db->first_tx_desc + sizeof(struct rx_desc) * TX_DESC_CNT );
+	db->first_rx_desc_dma = ( db->first_tx_desc_dma + sizeof(struct rx_desc) * TX_DESC_CNT);
 	db->rx_insert_ptr = db->first_rx_desc;
 	db->rx_ready_ptr = db->first_rx_desc;
-	outl(virt_to_bus(db->first_rx_desc), ioaddr + DCR3);	/* Init CR3 */
+	outl(db->first_rx_desc_dma, ioaddr + DCR3);	/* RX DESC address */
 
 	/* Init Transmit chain */
 	tmp_buf = db->buf_pool_start;
+	tmp_buf_dma = db->buf_pool_dma_start;
+	tmp_tx_dma = db->first_tx_desc_dma;
 	for (tmp_tx = db->first_tx_desc, i = 0; i < TX_DESC_CNT; i++, tmp_tx++) {
 		tmp_tx->tx_buf_ptr = (u32) tmp_buf;
-		tmp_tx->tdes0 = 0;
-		tmp_tx->tdes1 = 0x81000000;	/* IC, chain */
-		tmp_tx->tdes2 = (u32) virt_to_bus(tmp_buf);
-		tmp_tx->tdes3 = (u32) virt_to_bus(tmp_tx) + sizeof(struct tx_desc);
+		tmp_tx->tdes0 = cpu_to_le32(0);
+		tmp_tx->tdes1 = cpu_to_le32(0x81000000);	/* IC, chain */
+		tmp_tx->tdes2 = cpu_to_le32(tmp_buf_dma);
+		tmp_tx_dma += sizeof(struct tx_desc);
+		tmp_tx->tdes3 = cpu_to_le32(tmp_tx_dma);
 		tmp_tx->next_tx_desc = (u32) ((u32) tmp_tx + sizeof(struct tx_desc));
 		tmp_buf = (unsigned char *) ((u32) tmp_buf + TX_BUF_ALLOC);
+		tmp_buf_dma = tmp_buf_dma + TX_BUF_ALLOC;
 	}
-	(--tmp_tx)->tdes3 = (u32) virt_to_bus(db->first_tx_desc);
+	(--tmp_tx)->tdes3 = cpu_to_le32(db->first_tx_desc_dma);
 	tmp_tx->next_tx_desc = (u32) db->first_tx_desc;
 
-	/* Init Receive descriptor chain */
+	 /* Init Receive descriptor chain */
+	tmp_rx_dma=db->first_rx_desc_dma;
 	for (tmp_rx = db->first_rx_desc, i = 0; i < RX_DESC_CNT; i++, tmp_rx++) {
-		tmp_rx->rdes0 = 0;
-		tmp_rx->rdes1 = 0x01000600;
-		tmp_rx->rdes3 = (u32) virt_to_bus(tmp_rx) + sizeof(struct rx_desc);
+		tmp_rx->rdes0 = cpu_to_le32(0);
+		tmp_rx->rdes1 = cpu_to_le32(0x01000600);
+		tmp_rx_dma += sizeof(struct rx_desc);
+		tmp_rx->rdes3 = cpu_to_le32(tmp_rx_dma);
 		tmp_rx->next_rx_desc = (u32) ((u32) tmp_rx + sizeof(struct rx_desc));
 	}
-	(--tmp_rx)->rdes3 = (u32) virt_to_bus(db->first_rx_desc);
+	(--tmp_rx)->rdes3 = cpu_to_le32(db->first_rx_desc_dma);
 	tmp_rx->next_rx_desc = (u32) db->first_rx_desc;
 
 	/* pre-allocated Rx buffer */
 	allocated_rx_buffer(db);
 }
 
+
 /*
-   Update CR6 value
-   Firstly stop DM910X , then written value and start
+ *	Update CR6 vaule
+ *	Firstly stop DM910X , then written value and start
  */
+
 static void update_cr6(u32 cr6_data, u32 ioaddr)
 {
 	u32 cr6_tmp;
 
-	cr6_tmp = cr6_data & ~0x2002;	/* stop Tx/Rx */
+	cr6_tmp = cr6_data & ~0x2002;           /* stop Tx/Rx */
 	outl(cr6_tmp, ioaddr + DCR6);
 	udelay(5);
 	outl(cr6_data, ioaddr + DCR6);
-	cr6_tmp = inl(ioaddr + DCR6);
-	/* printk("CR6 update %x ", cr6_tmp); */
+	udelay(5);
 }
 
-/* Send a setup frame for DM9132
-   This setup frame initialize DM910X address filter mode
- */
-static void dm9132_id_table(struct net_device *dev, int mc_cnt)
+
+/*
+ *	Send a setup frame for DM9132
+ *	This setup frame initilize DM910X addres filter mode
+*/
+
+static void dm9132_id_table(struct DEVICE *dev, int mc_cnt)
 {
 	struct dev_mc_list *mcptr;
-	u16 *addrptr;
-	u32 ioaddr = dev->base_addr + 0xc0;	/* ID Table */
+	u16 * addrptr;
+	u32 ioaddr = dev->base_addr+0xc0;		/* ID Table */
 	u32 hash_val;
 	u16 i, hash_table[4];
 
@@ -1226,26 +1379,28 @@
 
 	/* the multicast address in Hash Table : 64 bits */
 	for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
-		hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f;
+		hash_val = cal_CRC( (char *) mcptr->dmi_addr, 6, 0) & 0x3f;
 		hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
 	}
 
 	/* Write the hash table to MAC MD table */
-	for (i = 0; i < 4; i++, ioaddr += 4) {
+	for (i = 0; i < 4; i++, ioaddr += 4)
 		outw(hash_table[i], ioaddr);
-	}
 }
 
-/* Send a setup frame for DM9102/DM9102A
-   This setup frame initialize DM910X address filter mode
+
+/*
+ *	Send a setup frame for DM9102/DM9102A
+ *	This setup frame initilize DM910X addres filter mode
  */
-static void send_filter_frame(struct net_device *dev, int mc_cnt)
+
+static void send_filter_frame(struct DEVICE *dev, int mc_cnt)
 {
 	struct dmfe_board_info *db = dev->priv;
 	struct dev_mc_list *mcptr;
 	struct tx_desc *txptr;
-	u16 *addrptr;
-	u32 *suptr;
+	u16 * addrptr;
+	u32 * suptr;
 	int i;
 
 	DMFE_DBUG(0, "send_filter_frame()", 0);
@@ -1253,12 +1408,6 @@
 	txptr = db->tx_insert_ptr;
 	suptr = (u32 *) txptr->tx_buf_ptr;
 
-	if (txptr->tdes0 & 0x80000000) {
-		printk(KERN_WARNING "%s: Too busy to send filter frame\n",
-		       dev->name);
-		return;
-	}
-
 	/* Node address */
 	addrptr = (u16 *) dev->dev_addr;
 	*suptr++ = addrptr[0];
@@ -1278,26 +1427,35 @@
 		*suptr++ = addrptr[2];
 	}
 
-	for (i=0; i < 14; i++) 
+	for (; i<14; i++) {
 		*suptr++ = 0xffff;
 		*suptr++ = 0xffff;
 		*suptr++ = 0xffff;
-	
+	}
+
 	/* prepare the setup frame */
 	db->tx_insert_ptr = (struct tx_desc *) txptr->next_tx_desc;
-	db->tx_live_cnt++;
-	txptr->tdes1 = 0x890000c0;
-	/* Send the setup packet */
-	txptr->tdes0 = 0x80000000;
-	update_cr6(db->cr6_data | 0x2000, dev->base_addr);
-	outl(0x1, dev->base_addr + DCR1);	/* Issue Tx polling command */
-	update_cr6(db->cr6_data, dev->base_addr);
+	txptr->tdes1 = cpu_to_le32(0x890000c0);
+
+	/* Resource Check and Send the setup packet */
+	if (!db->tx_packet_cnt) {
+		/* Resource Empty */
+		db->tx_packet_cnt++;
+		txptr->tdes0 = cpu_to_le32(0x80000000);
+		update_cr6(db->cr6_data | 0x2000, dev->base_addr);
+		outl(0x1, dev->base_addr + DCR1);	/* Issue Tx polling */
+		update_cr6(db->cr6_data, dev->base_addr);
+		dev->trans_start = jiffies;
+	} else
+		db->tx_queue_cnt++;	/* Put in TX queue */
 }
 
+
 /*
  *	Allocate rx buffer,
- *	Allocate as many Rx buffers as possible.
+ *	As possible as allocated maxiumn Rx buffer
  */
+
 static void allocated_rx_buffer(struct dmfe_board_info *db)
 {
 	struct rx_desc *rxptr;
@@ -1305,12 +1463,12 @@
 
 	rxptr = db->rx_insert_ptr;
 
-	while (db->rx_avail_cnt < RX_DESC_CNT) {
-		if ((skb = alloc_skb(RX_ALLOC_SIZE, GFP_ATOMIC)) == NULL)
+	while(db->rx_avail_cnt < RX_DESC_CNT) {
+		if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL )
 			break;
 		rxptr->rx_skb_ptr = (u32) skb;
-		rxptr->rdes2 = virt_to_bus(skb->tail);
-		rxptr->rdes0 = 0x80000000;
+		rxptr->rdes2 = cpu_to_le32( pci_map_single(db->net_dev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) );
+		rxptr->rdes0 = cpu_to_le32(0x80000000);
 		rxptr = (struct rx_desc *) rxptr->next_rx_desc;
 		db->rx_avail_cnt++;
 	}
@@ -1318,9 +1476,11 @@
 	db->rx_insert_ptr = rxptr;
 }
 
+
 /*
-   Read one word data from the serial ROM
+ *	Read one word data from the serial ROM
  */
+
 static u16 read_srom_word(long ioaddr, int offset)
 {
 	int i;
@@ -1355,113 +1515,150 @@
 	return srom_data;
 }
 
+
 /*
  *	Auto sense the media mode
  */
- 
-static void dmfe_sense_speed(struct dmfe_board_info *db)
+
+static u8 dmfe_sense_speed(struct dmfe_board_info * db)
 {
-	int i;
-	u16 phy_mode = 0;
+	u8 ErrFlag = 0;
+	u16 phy_mode;
 
-	for (i = 1000; i; i--) {
-		udelay(5);
-		phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
-		if ((phy_mode & 0x24) == 0x24)
-			break;
-	}
+	/* CR6 bit18=0, select 10/100M */
+	update_cr6( (db->cr6_data & ~0x40000), db->ioaddr);
+
+	phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
+	phy_mode = phy_read(db->ioaddr, db->phy_addr, 1, db->chip_id);
 
-	if (i) {
+	if ( (phy_mode & 0x24) == 0x24 ) {
 		if (db->chip_id == PCI_DM9132_ID)	/* DM9132 */
 			phy_mode = phy_read(db->ioaddr, db->phy_addr, 7, db->chip_id) & 0xf000;
-		else		/* DM9102/DM9102A */
+		else 				/* DM9102/DM9102A */
 			phy_mode = phy_read(db->ioaddr, db->phy_addr, 17, db->chip_id) & 0xf000;
-		/* printk("Phy_mode %x ",phy_mode); */
+		/* printk("<DMFE>: Phy_mode %x ",phy_mode); */
 		switch (phy_mode) {
-		case 0x1000:
-			db->op_mode = DMFE_10MHF;
-			break;
-		case 0x2000:
-			db->op_mode = DMFE_10MFD;
-			break;
-		case 0x4000:
-			db->op_mode = DMFE_100MHF;
-			break;
-		case 0x8000:
-			db->op_mode = DMFE_100MFD;
-			break;
-		default:
-			db->op_mode = DMFE_10MHF;
-			DMFE_DBUG(0, "Media Type error, phy reg17", phy_mode);
+		case 0x1000: db->op_mode = DMFE_10MHF; break;
+		case 0x2000: db->op_mode = DMFE_10MFD; break;
+		case 0x4000: db->op_mode = DMFE_100MHF; break;
+		case 0x8000: db->op_mode = DMFE_100MFD; break;
+		default: db->op_mode = DMFE_10MHF;
+			ErrFlag = 1;
 			break;
 		}
 	} else {
 		db->op_mode = DMFE_10MHF;
 		DMFE_DBUG(0, "Link Failed :", phy_mode);
+		ErrFlag = 1;
+	}
+
+	return ErrFlag;
+}
+
+
+/*
+ *	Set 10/100 phyxcer capability
+ *	AUTO mode : phyxcer register4 is NIC capability
+ *	Force mode: phyxcer register4 is the force media
+ */
+
+static void dmfe_set_phyxcer(struct dmfe_board_info *db)
+{
+	u16 phy_reg;
+
+	/* Select 10/100M phyxcer */
+	db->cr6_data &= ~0x40000;
+	update_cr6(db->cr6_data, db->ioaddr);
+
+	/* DM9009 Chip: Phyxcer reg18 bit12=0 */
+	if (db->chip_id == PCI_DM9009_ID) {
+		phy_reg = phy_read(db->ioaddr, db->phy_addr, 18, db->chip_id) & ~0x1000;
+		phy_write(db->ioaddr, db->phy_addr, 18, phy_reg, db->chip_id);
+	}
+
+	/* Phyxcer capability setting */
+	phy_reg = phy_read(db->ioaddr, db->phy_addr, 4, db->chip_id) & ~0x01e0;
+
+	if (db->media_mode & DMFE_AUTO) {
+		/* AUTO Mode */
+		phy_reg |= db->PHY_reg4;
+	} else {
+		/* Force Mode */
+		switch(db->media_mode) {
+		case DMFE_10MHF: phy_reg |= 0x20; break;
+		case DMFE_10MFD: phy_reg |= 0x40; break;
+		case DMFE_100MHF: phy_reg |= 0x80; break;
+		case DMFE_100MFD: phy_reg |= 0x100; break;
+		}
+		if (db->chip_id == PCI_DM9009_ID) phy_reg &= 0x61;
 	}
+
+  	/* Write new capability to Phyxcer Reg4 */
+	if ( !(phy_reg & 0x01e0)) {
+		phy_reg|=db->PHY_reg4;
+		db->media_mode|=DMFE_AUTO;
+	}
+	phy_write(db->ioaddr, db->phy_addr, 4, phy_reg, db->chip_id);
+
+ 	/* Restart Auto-Negotiation */
+	if ( db->chip_type && (db->chip_id == PCI_DM9102_ID) )
+		phy_write(db->ioaddr, db->phy_addr, 0, 0x1800, db->chip_id);
+	if ( !db->chip_type )
+		phy_write(db->ioaddr, db->phy_addr, 0, 0x1200, db->chip_id);
 }
 
+
 /*
-   Process op-mode
-   AUTO mode : PHY controller in Auto-negotiation Mode
-   Force mode: PHY controller in force mode with HUB
-   N-way force capability with SWITCH
+ *	Process op-mode
+ *	AUTO mode : PHY controller in Auto-negotiation Mode
+ *	Force mode: PHY controller in force mode with HUB
+ *			N-way force capability with SWITCH
  */
+
 static void dmfe_process_mode(struct dmfe_board_info *db)
 {
 	u16 phy_reg;
 
 	/* Full Duplex Mode Check */
-	db->cr6_data &= ~CR6_FDM;	/* Clear Full Duplex Bit */
 	if (db->op_mode & 0x4)
-		db->cr6_data |= CR6_FDM;
+		db->cr6_data |= CR6_FDM;	/* Set Full Duplex Bit */
+	else
+		db->cr6_data &= ~CR6_FDM;	/* Clear Full Duplex Bit */
 
-	if (!(db->media_mode & DMFE_AUTO)) {	/* Force Mode Check */
-		/* User force the media type */
-		phy_reg = phy_read(db->ioaddr, db->phy_addr, 5, db->chip_id);
-		/* printk("Nway phy_reg5 %x ",phy_reg); */
-		if (phy_reg & 0x1) {
-			/* parter own the N-Way capability */
-			phy_reg = phy_read(db->ioaddr, db->phy_addr, 4, db->chip_id) & ~0x1e0;
-			switch (db->op_mode) {
-			case DMFE_10MHF:
-				phy_reg |= 0x20;
-				break;
-			case DMFE_10MFD:
-				phy_reg |= 0x40;
-				break;
-			case DMFE_100MHF:
-				phy_reg |= 0x80;
-				break;
-			case DMFE_100MFD:
-				phy_reg |= 0x100;
-				break;
-			}
-			phy_write(db->ioaddr, db->phy_addr, 4, phy_reg, db->chip_id);
-		} else {
-			/* parter without the N-Way capability */
-			switch (db->op_mode) {
-			case DMFE_10MHF:
-				phy_reg = 0x0;
-				break;
-			case DMFE_10MFD:
-				phy_reg = 0x100;
-				break;
-			case DMFE_100MHF:
-				phy_reg = 0x2000;
-				break;
-			case DMFE_100MFD:
-				phy_reg = 0x2100;
-				break;
+	/* Transciver Selection */
+	if (db->op_mode & 0x10)		/* 1M HomePNA */
+		db->cr6_data |= 0x40000;/* External MII select */
+	else
+		db->cr6_data &= ~0x40000;/* Internal 10/100 transciver */
+
+	update_cr6(db->cr6_data, db->ioaddr);
+
+	/* 10/100M phyxcer force mode need */
+	if ( !(db->media_mode & 0x18)) {
+		/* Forece Mode */
+		phy_reg = phy_read(db->ioaddr, db->phy_addr, 6, db->chip_id);
+		if ( !(phy_reg & 0x1) ) {
+			/* parter without N-Way capability */
+			phy_reg = 0x0;
+			switch(db->op_mode) {
+			case DMFE_10MHF: phy_reg = 0x0; break;
+			case DMFE_10MFD: phy_reg = 0x100; break;
+			case DMFE_100MHF: phy_reg = 0x2000; break;
+			case DMFE_100MFD: phy_reg = 0x2100; break;
 			}
 			phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id);
+       			if ( db->chip_type && (db->chip_id == PCI_DM9102_ID) )
+				mdelay(20);
+			phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id);
 		}
 	}
 }
 
+
 /*
-   Write a word to Phy register
+ *	Write a word to Phy register
  */
+
 static void phy_write(u32 iobase, u8 phy_addr, u8 offset, u16 phy_data, u32 chip_id)
 {
 	u16 i;
@@ -1486,11 +1683,11 @@
 		phy_write_1bit(ioaddr, PHY_DATA_0);
 		phy_write_1bit(ioaddr, PHY_DATA_1);
 
-		/* Send Phy address */
+		/* Send Phy addres */
 		for (i = 0x10; i > 0; i = i >> 1)
 			phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0);
 
-		/* Send register address */
+		/* Send register addres */
 		for (i = 0x10; i > 0; i = i >> 1)
 			phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0);
 
@@ -1499,14 +1696,16 @@
 		phy_write_1bit(ioaddr, PHY_DATA_0);
 
 		/* Write a word data to PHY controller */
-		for (i = 0x8000; i > 0; i >>= 1)
+		for ( i = 0x8000; i > 0; i >>= 1)
 			phy_write_1bit(ioaddr, phy_data & i ? PHY_DATA_1 : PHY_DATA_0);
 	}
 }
 
+
 /*
-   Read a word data from phy register
+ *	Read a word data from phy register
  */
+
 static u16 phy_read(u32 iobase, u8 phy_addr, u8 offset, u32 chip_id)
 {
 	int i;
@@ -1519,8 +1718,8 @@
 		phy_data = inw(ioaddr);
 	} else {
 		/* DM9102/DM9102A Chip */
-
 		ioaddr = iobase + DCR9;
+
 		/* Send 33 synchronization clock to Phy controller */
 		for (i = 0; i < 35; i++)
 			phy_write_1bit(ioaddr, PHY_DATA_1);
@@ -1533,11 +1732,11 @@
 		phy_write_1bit(ioaddr, PHY_DATA_1);
 		phy_write_1bit(ioaddr, PHY_DATA_0);
 
-		/* Send Phy address */
+		/* Send Phy addres */
 		for (i = 0x10; i > 0; i = i >> 1)
 			phy_write_1bit(ioaddr, phy_addr & i ? PHY_DATA_1 : PHY_DATA_0);
 
-		/* Send register address */
+		/* Send register addres */
 		for (i = 0x10; i > 0; i = i >> 1)
 			phy_write_1bit(ioaddr, offset & i ? PHY_DATA_1 : PHY_DATA_0);
 
@@ -1554,41 +1753,47 @@
 	return phy_data;
 }
 
+
 /*
-   Write one bit data to Phy Controller
+ *	Write one bit data to Phy Controller
  */
+
 static void phy_write_1bit(u32 ioaddr, u32 phy_data)
 {
-	outl(phy_data, ioaddr);	/* MII Clock Low */
+	outl(phy_data, ioaddr);			/* MII Clock Low */
 	udelay(1);
 	outl(phy_data | MDCLKH, ioaddr);	/* MII Clock High */
 	udelay(1);
-	outl(phy_data, ioaddr);	/* MII Clock Low */
+	outl(phy_data, ioaddr);			/* MII Clock Low */
 	udelay(1);
 }
 
+
 /*
-   Read one bit phy data from PHY controller
+ *	Read one bit phy data from PHY controller
  */
+
 static u16 phy_read_1bit(u32 ioaddr)
 {
 	u16 phy_data;
 
 	outl(0x50000, ioaddr);
 	udelay(1);
-	phy_data = (inl(ioaddr) >> 19) & 0x1;
+	phy_data = ( inl(ioaddr) >> 19 ) & 0x1;
 	outl(0x40000, ioaddr);
 	udelay(1);
 
 	return phy_data;
 }
 
+
 /*
-   Calculate the CRC valude of the Rx packet
-   flag = 1 : return the reverse CRC (for the received packet CRC)
-   0 : return the normal CRC (for Hash Table index)
+ *	Calculate the CRC valude of the Rx packet
+ *	flag = 	1 : return the reverse CRC (for the received packet CRC)
+ *		0 : return the normal CRC (for Hash Table index)
  */
-unsigned long cal_CRC(unsigned char *Data, unsigned int Len, u8 flag)
+
+unsigned long cal_CRC(unsigned char * Data, unsigned int Len, u8 flag)
 {
 	unsigned long Crc = 0xffffffff;
 
@@ -1603,10 +1808,190 @@
 }
 
 
-static struct pci_device_id dmfe_pci_tbl[] __initdata = {
+/*
+ *	Parser SROM and media mode
+ */
+
+static void dmfe_parse_srom(struct dmfe_board_info * db)
+{
+	char * srom = db->srom;
+	int dmfe_mode, tmp_reg;
+
+	DMFE_DBUG(0, "dmfe_parse_srom() ", 0);
+
+	/* Init CR15 */
+	db->cr15_data = CR15_DEFAULT;
+
+	/* Check SROM Version */
+	if ( ( (int) srom[18] & 0xff) == SROM_V41_CODE) {
+		/* SROM V4.01 */
+		/* Get NIC support media mode */
+		db->NIC_capability = *(u16 *) (&srom[34]);
+		db->PHY_reg4 = 0;
+		for (tmp_reg = 1; tmp_reg < 0x10; tmp_reg <<= 1) {
+			switch( db->NIC_capability & tmp_reg ) {
+			case 0x1: db->PHY_reg4 |= 0x0020; break;
+			case 0x2: db->PHY_reg4 |= 0x0040; break;
+			case 0x4: db->PHY_reg4 |= 0x0080; break;
+			case 0x8: db->PHY_reg4 |= 0x0100; break;
+			}
+		}
+
+		/* Media Mode Force or not check */
+		dmfe_mode = *( (int *) &srom[34]) & *( (int *) &srom[36] );
+		switch(dmfe_mode) {
+		case 0x4: dmfe_media_mode = DMFE_100MHF; break;	/* 100MHF */
+		case 0x2: dmfe_media_mode = DMFE_10MFD; break;	/* 10MFD */
+		case 0x8: dmfe_media_mode = DMFE_100MFD; break;	/* 100MFD */
+		case 0x100:
+		case 0x200: dmfe_media_mode = DMFE_1M_HPNA; break;/* HomePNA */
+		}
+
+		/* Special Function setting */
+		/* VLAN function */
+		if ( (SF_mode & 0x1) || (srom[43] & 0x80) )
+			db->cr15_data |= 0x40;
+
+		/* Flow Control */
+		if ( (SF_mode & 0x2) || (srom[40] & 0x1) )
+			db->cr15_data |= 0x400;
+
+		/* TX pause packet */
+		if ( (SF_mode & 0x4) || (srom[40] & 0xe) )
+			db->cr15_data |= 0x9800;
+	}
+
+	/* Parse HPNA parameter */
+	db->HPNA_command = 1;
+
+	/* Accept remote command or not */
+	if (HPNA_rx_cmd == 0)
+		db->HPNA_command |= 0x8000;
+
+	 /* Issue remote command & operation mode */
+	if (HPNA_tx_cmd == 1)
+		switch(HPNA_mode) {	/* Issue Remote Command */
+		case 0: db->HPNA_command |= 0x0904; break;
+		case 1: db->HPNA_command |= 0x0a00; break;
+		case 2: db->HPNA_command |= 0x0506; break;
+		case 3: db->HPNA_command |= 0x0602; break;
+		}
+	else
+		switch(HPNA_mode) {	/* Don't Issue */
+		case 0: db->HPNA_command |= 0x0004; break;
+		case 1: db->HPNA_command |= 0x0000; break;
+		case 2: db->HPNA_command |= 0x0006; break;
+		case 3: db->HPNA_command |= 0x0002; break;
+		}
+
+	/* Check DM9801 or DM9802 present or not */
+	db->HPNA_present = 0;
+	update_cr6(db->cr6_data|0x40000, db->ioaddr);
+	tmp_reg = phy_read(db->ioaddr, db->phy_addr, 3, db->chip_id);
+	if ( ( tmp_reg & 0xfff0 ) == 0xb900 ) {
+		/* DM9801 or DM9802 present */
+		db->HPNA_timer = 8;
+		if ( phy_read(db->ioaddr, db->phy_addr, 31, db->chip_id) == 0x4404) {
+			/* DM9801 HomeRun */
+			db->HPNA_present = 1;
+			dmfe_program_DM9801(db, tmp_reg);
+		} else {
+			/* DM9802 LongRun */
+			db->HPNA_present = 2;
+			dmfe_program_DM9802(db);
+		}
+	}
+
+}
+
+
+/*
+ *	Init HomeRun DM9801
+ */
+
+static void dmfe_program_DM9801(struct dmfe_board_info * db, int HPNA_rev)
+{
+	uint reg17, reg25;
+
+	if ( !HPNA_NoiseFloor ) HPNA_NoiseFloor = DM9801_NOISE_FLOOR;
+	switch(HPNA_rev) {
+	case 0xb900: /* DM9801 E3 */
+		db->HPNA_command |= 0x1000;
+		reg25 = phy_read(db->ioaddr, db->phy_addr, 24, db->chip_id);
+		reg25 = ( (reg25 + HPNA_NoiseFloor) & 0xff) | 0xf000;
+		reg17 = phy_read(db->ioaddr, db->phy_addr, 17, db->chip_id);
+		break;
+	case 0xb901: /* DM9801 E4 */
+		reg25 = phy_read(db->ioaddr, db->phy_addr, 25, db->chip_id);
+		reg25 = (reg25 & 0xff00) + HPNA_NoiseFloor;
+		reg17 = phy_read(db->ioaddr, db->phy_addr, 17, db->chip_id);
+		reg17 = (reg17 & 0xfff0) + HPNA_NoiseFloor + 3;
+		break;
+	case 0xb902: /* DM9801 E5 */
+	case 0xb903: /* DM9801 E6 */
+	default:
+		db->HPNA_command |= 0x1000;
+		reg25 = phy_read(db->ioaddr, db->phy_addr, 25, db->chip_id);
+		reg25 = (reg25 & 0xff00) + HPNA_NoiseFloor - 5;
+		reg17 = phy_read(db->ioaddr, db->phy_addr, 17, db->chip_id);
+		reg17 = (reg17 & 0xfff0) + HPNA_NoiseFloor;
+		break;
+	}
+	phy_write(db->ioaddr, db->phy_addr, 16, db->HPNA_command, db->chip_id);
+	phy_write(db->ioaddr, db->phy_addr, 17, reg17, db->chip_id);
+	phy_write(db->ioaddr, db->phy_addr, 25, reg25, db->chip_id);
+}
+
+
+/*
+ *	Init HomeRun DM9802
+ */
+
+static void dmfe_program_DM9802(struct dmfe_board_info * db)
+{
+	uint phy_reg;
+
+	if ( !HPNA_NoiseFloor ) HPNA_NoiseFloor = DM9802_NOISE_FLOOR;
+	phy_write(db->ioaddr, db->phy_addr, 16, db->HPNA_command, db->chip_id);
+	phy_reg = phy_read(db->ioaddr, db->phy_addr, 25, db->chip_id);
+	phy_reg = ( phy_reg & 0xff00) + HPNA_NoiseFloor;
+	phy_write(db->ioaddr, db->phy_addr, 25, phy_reg, db->chip_id);
+}
+
+
+/*
+ *	Check remote HPNA power and speed status. If not correct,
+ *	issue command again.
+*/
+
+static void dmfe_HPNA_remote_cmd_chk(struct dmfe_board_info * db)
+{
+	uint phy_reg;
+
+	/* Got remote device status */
+	phy_reg = phy_read(db->ioaddr, db->phy_addr, 17, db->chip_id) & 0x60;
+	switch(phy_reg) {
+	case 0x00: phy_reg = 0x0a00;break; /* LP/LS */
+	case 0x20: phy_reg = 0x0900;break; /* LP/HS */
+	case 0x40: phy_reg = 0x0600;break; /* HP/LS */
+	case 0x60: phy_reg = 0x0500;break; /* HP/HS */
+	}
+
+	/* Check remote device status match our setting ot not */
+	if ( phy_reg != (db->HPNA_command & 0x0f00) ) {
+		phy_write(db->ioaddr, db->phy_addr, 16, db->HPNA_command, db->chip_id);
+		db->HPNA_timer=8;
+	} else
+		db->HPNA_timer=600;	/* Match, every 10 minutes, check */
+}
+
+
+
+static struct pci_device_id dmfe_pci_tbl[] __devinitdata = {
 	{ 0x1282, 0x9132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_DM9132_ID },
 	{ 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_DM9102_ID },
 	{ 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_DM9100_ID },
+	{ 0x1282, 0x9009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, PCI_DM9009_ID },
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci, dmfe_pci_tbl);
@@ -1624,20 +2009,23 @@
 MODULE_PARM(mode, "i");
 MODULE_PARM(cr6set, "i");
 MODULE_PARM(chkmode, "i");
+MODULE_PARM(HPNA_mode, "i");
+MODULE_PARM(HPNA_rx_cmd, "i");
+MODULE_PARM(HPNA_tx_cmd, "i");
+MODULE_PARM(HPNA_NoiseFloor, "i");
+MODULE_PARM(SF_mode, "i");
 
-/*	Description: 
+/*	Description:
  *	when user used insmod to add module, system invoked init_module()
- *	to initialize and register.
+ *	to initilize and register.
  */
- 
+
 static int __init dmfe_init_module(void)
 {
 	int rc;
-	
-/* when a module, this is printed whether or not devices are found in probe */
-#ifdef MODULE
+
 	printk(version);
-#endif
+	printed_version = 1;
 
 	DMFE_DBUG(0, "init_module() ", debug);
 
@@ -1646,18 +2034,27 @@
 	if (cr6set)
 		dmfe_cr6_user_set = cr6set;
 
-	switch (mode) {
-	case 0:
-	case 1:
-	case 4:
-	case 5:
+ 	switch(mode) {
+   	case DMFE_10MHF:
+	case DMFE_100MHF:
+	case DMFE_10MFD:
+	case DMFE_100MFD:
+	case DMFE_1M_HPNA:
 		dmfe_media_mode = mode;
 		break;
-	default:
-		dmfe_media_mode = 8;
+	default:dmfe_media_mode = DMFE_AUTO;
 		break;
 	}
 
+	if (HPNA_mode > 4)
+		HPNA_mode = 0;		/* Default: LP/HS */
+	if (HPNA_rx_cmd > 1)
+		HPNA_rx_cmd = 0;	/* Default: Ignored remote cmd */
+	if (HPNA_tx_cmd > 1)
+		HPNA_tx_cmd = 0;	/* Default: Don't issue remote cmd */
+	if (HPNA_NoiseFloor > 15)
+		HPNA_NoiseFloor = 0;
+
 	rc = pci_module_init(&dmfe_driver);
 	if (rc < 0)
 		return rc;
@@ -1665,14 +2062,16 @@
 	return 0;
 }
 
+
 /*
- *	Description: 
+ *	Description:
  *	when user used rmmod to delete module, system invoked clean_module()
  *	to un-register all registered services.
  */
- 
+
 static void __exit dmfe_cleanup_module(void)
 {
+	DMFE_DBUG(0, "dmfe_clean_module() ", debug);
 	pci_unregister_driver(&dmfe_driver);
 }
 
diff -u --recursive --new-file v2.4.4/linux/drivers/net/epic100.c linux/drivers/net/epic100.c
--- v2.4.4/linux/drivers/net/epic100.c	Fri Apr 20 11:54:23 2001
+++ linux/drivers/net/epic100.c	Sat May 19 18:02:45 2001
@@ -41,8 +41,19 @@
 	* Merge becker version 1.11
 	* Move pci_enable_device before any PCI BAR len checks
 
+	LK1.1.7:
+	* { fill me in }
+
+	LK1.1.8:
+	* ethtool support (jgarzik)
+
 */
 
+#define DRV_NAME	"epic100"
+#define DRV_VERSION	"1.11+LK1.1.8"
+#define DRV_RELDATE	"May 18, 2001"
+
+
 /* The user-configurable values.
    These may be modified when a driver module is loaded.*/
 
@@ -104,16 +115,18 @@
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
+#include <linux/ethtool.h>
 #include <asm/bitops.h>
 #include <asm/io.h>
+#include <asm/uaccess.h>
 
 /* These identify the driver base version and may not be removed. */
 static char version[] __devinitdata =
-"epic100.c:v1.11 1/7/2001 Written by Donald Becker <becker@scyld.com>\n";
+DRV_NAME ".c:v1.11 1/7/2001 Written by Donald Becker <becker@scyld.com>\n";
 static char version2[] __devinitdata =
 "  http://www.scyld.com/network/epic100.html\n";
 static char version3[] __devinitdata =
-"  (unofficial 2.4.x kernel port, version 1.1.7, April 17, 2001)\n";
+"  (unofficial 2.4.x kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("SMC 83c170 EPIC series Ethernet driver");
@@ -326,7 +339,7 @@
 static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int epic_rx(struct net_device *dev);
 static void epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int epic_close(struct net_device *dev);
 static struct net_device_stats *epic_get_stats(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
@@ -375,7 +388,7 @@
 	}
 	SET_MODULE_OWNER(dev);
 
-	if (pci_request_regions(pdev, "epic100"))
+	if (pci_request_regions(pdev, DRV_NAME))
 		goto err_out_free_netdev;
 
 #ifdef USE_IO_OPS
@@ -384,7 +397,7 @@
 	ioaddr = pci_resource_start (pdev, 1);
 	ioaddr = (long) ioremap (ioaddr, pci_resource_len (pdev, 1));
 	if (!ioaddr) {
-		printk (KERN_ERR "epic100 %d: ioremap failed\n", card_idx);
+		printk (KERN_ERR DRV_NAME " %d: ioremap failed\n", card_idx);
 		goto err_out_free_res;
 	}
 #endif
@@ -435,7 +448,7 @@
 		((u16 *)dev->dev_addr)[i] = le16_to_cpu(inw(ioaddr + LAN0 + i*4));
 
 	if (debug > 2) {
-		printk(KERN_DEBUG "epic100(%s): EEPROM contents\n",
+		printk(KERN_DEBUG DRV_NAME "(%s): EEPROM contents\n",
 		       pdev->slot_name);
 		for (i = 0; i < 64; i++)
 			printk(" %4.4x%s", read_eeprom(ioaddr, i),
@@ -455,7 +468,7 @@
 			int mii_status = mdio_read(dev, phy, 1);
 			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
 				ep->phys[phy_idx++] = phy;
-				printk(KERN_INFO "epic100(%s): MII transceiver #%d control "
+				printk(KERN_INFO DRV_NAME "(%s): MII transceiver #%d control "
 					   "%4.4x status %4.4x.\n",
 					   pdev->slot_name, phy, mdio_read(dev, phy, 0), mii_status);
 			}
@@ -464,11 +477,11 @@
 		if (phy_idx != 0) {
 			phy = ep->phys[0];
 			ep->advertising = mdio_read(dev, phy, 4);
-			printk(KERN_INFO "epic100(%s): Autonegotiation advertising %4.4x link "
+			printk(KERN_INFO DRV_NAME "(%s): Autonegotiation advertising %4.4x link "
 				   "partner %4.4x.\n",
 				   pdev->slot_name, ep->advertising, mdio_read(dev, phy, 5));
 		} else if ( ! (ep->chip_flags & NO_MII)) {
-			printk(KERN_WARNING "epic100(%s): ***WARNING***: No MII transceiver found!\n",
+			printk(KERN_WARNING DRV_NAME "(%s): ***WARNING***: No MII transceiver found!\n",
 			       pdev->slot_name);
 			/* Use the known PHY address of the EPII. */
 			ep->phys[0] = 3;
@@ -483,7 +496,7 @@
 	/* The lower four bits are the media type. */
 	if (duplex) {
 		ep->duplex_lock = ep->full_duplex = 1;
-		printk(KERN_INFO "epic100(%s):  Forced full duplex operation requested.\n",
+		printk(KERN_INFO DRV_NAME "(%s):  Forced full duplex operation requested.\n",
 		       pdev->slot_name);
 	}
 	dev->if_port = ep->default_port = option;
@@ -496,7 +509,7 @@
 	dev->stop = &epic_close;
 	dev->get_stats = &epic_get_stats;
 	dev->set_multicast_list = &set_rx_mode;
-	dev->do_ioctl = &mii_ioctl;
+	dev->do_ioctl = &netdev_ioctl;
 	dev->watchdog_timeo = TX_TIMEOUT;
 	dev->tx_timeout = &epic_tx_timeout;
 
@@ -1331,13 +1344,39 @@
 	return;
 }
 
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	struct epic_private *np = dev->priv;
+	u32 ethcmd;
+		
+	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+		return -EFAULT;
+
+        switch (ethcmd) {
+        case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		strcpy(info.driver, DRV_NAME);
+		strcpy(info.version, DRV_VERSION);
+		strcpy(info.bus_info, np->pci_dev->slot_name);
+		if (copy_to_user(useraddr, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+
+        }
+	
+	return -EOPNOTSUPP;
+}
+
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct epic_private *ep = dev->priv;
 	long ioaddr = dev->base_addr;
 	u16 *data = (u16 *)&rq->ifr_data;
 
 	switch(cmd) {
+	case SIOCETHTOOL:
+		return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
 	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
 		data[0] = ep->phys[0] & 0x1f;
 		/* Fall Through */
@@ -1432,7 +1471,7 @@
 
 
 static struct pci_driver epic_driver = {
-	name:		"epic100",
+	name:		DRV_NAME,
 	id_table:	epic_pci_tbl,
 	probe:		epic_init_one,
 	remove:		epic_remove_one,
diff -u --recursive --new-file v2.4.4/linux/drivers/net/eql.c linux/drivers/net/eql.c
--- v2.4.4/linux/drivers/net/eql.c	Wed Apr 18 14:40:06 2001
+++ linux/drivers/net/eql.c	Mon May 14 23:55:12 2001
@@ -422,6 +422,8 @@
 				slave_t *s = eql_new_slave ();
 				equalizer_t *eql = 
 					(equalizer_t *) master_dev->priv;
+				if (!s)
+					return -ENOMEM;
 				s->dev = slave_dev;
 				s->priority = srq.priority;
 				s->priority_bps = srq.priority;
diff -u --recursive --new-file v2.4.4/linux/drivers/net/fealnx.c linux/drivers/net/fealnx.c
--- v2.4.4/linux/drivers/net/fealnx.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/fealnx.c	Wed May 16 10:25:38 2001
@@ -0,0 +1,1777 @@
+/*
+	Written 1998-2000 by Donald Becker.
+
+	This software may be used and distributed according to the terms of
+	the GNU General Public License (GPL), incorporated herein by reference.
+	Drivers based on or derived from this code fall under the GPL and must
+	retain the authorship, copyright and license notice.  This file is not
+	a complete program and may only be used when the entire operating
+	system is licensed under the GPL.
+
+	The author may be reached as becker@scyld.com, or C/O
+	Scyld Computing Corporation
+	410 Severn Ave., Suite 210
+	Annapolis MD 21403
+
+	Support information and updates available at
+	http://www.scyld.com/network/pci-skeleton.html
+*/
+
+static int debug = 0;		/* 1-> print debug message */
+static int max_interrupt_work = 20;
+
+/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast). */
+static int multicast_filter_limit = 32;
+
+/* Set the copy breakpoint for the copy-only-tiny-frames scheme. */
+/* Setting to > 1518 effectively disables this feature.          */
+static int rx_copybreak = 0;
+
+/* Used to pass the media type, etc.                            */
+/* Both 'options[]' and 'full_duplex[]' should exist for driver */
+/* interoperability.                                            */
+/* The media type is usually passed in 'options[]'.             */
+#define MAX_UNITS 8		/* More are supported, limit only on options */
+static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+
+/* Operational parameters that are set at compile time.                 */
+/* Keep the ring sizes a power of two for compile efficiency.           */
+/* The compiler will convert <unsigned>'%'<2^N> into a bit mask.        */
+/* Making the Tx ring too large decreases the effectiveness of channel  */
+/* bonding and packet priority.                                         */
+/* There are no ill effects from too-large receive rings.               */
+// 88-12-9 modify,
+// #define TX_RING_SIZE    16
+// #define RX_RING_SIZE    32
+#define TX_RING_SIZE    6
+#define RX_RING_SIZE    12
+
+/* Operational parameters that usually are not changed. */
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT      (2*HZ)
+
+#define PKT_BUF_SZ      1536	/* Size of each temporary Rx buffer. */
+
+
+/* Include files, designed to support most kernel versions 2.0.0 and later. */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <asm/processor.h>	/* Processor type for cache alignment. */
+#include <asm/bitops.h>
+#include <asm/io.h>
+
+/* These identify the driver base version and may not be removed. */
+static char version[] __devinitdata =
+KERN_INFO "fealnx.c:v2.50 1/17/2001\n";
+
+
+/* This driver was written to use PCI memory space, however some x86 systems
+   work only with I/O space accesses. */
+#ifndef __alpha__
+#define USE_IO_OPS
+#endif
+
+#ifdef USE_IO_OPS
+#undef readb
+#undef readw
+#undef readl
+#undef writeb
+#undef writew
+#undef writel
+#define readb inb
+#define readw inw
+#define readl inl
+#define writeb outb
+#define writew outw
+#define writel outl
+#endif
+
+/* Kernel compatibility defines, some common to David Hinds' PCMCIA package. */
+/* This is only in the support-all-kernels source code. */
+
+#define RUN_AT(x) (jiffies + (x))
+
+MODULE_AUTHOR("Myson or whoever");
+MODULE_DESCRIPTION("Myson MTD-8xx 100/10M Ethernet PCI Adapter Driver");
+MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(min_pci_latency, "i");
+MODULE_PARM(debug, "i");
+MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(multicast_filter_limit, "i");
+MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+
+#define MIN_REGION_SIZE 136
+
+enum pci_flags_bit {
+	PCI_USES_IO = 1,
+	PCI_USES_MEM = 2,
+	PCI_USES_MASTER = 4,
+	PCI_ADDR0 = 0x10 << 0,
+	PCI_ADDR1 = 0x10 << 1,
+	PCI_ADDR2 = 0x10 << 2,
+	PCI_ADDR3 = 0x10 << 3,
+};
+
+/* A chip capabilities table, matching the entries in pci_tbl[] above. */
+enum chip_capability_flags {
+	HAS_MII_XCVR,
+	HAS_CHIP_XCVR,
+};
+
+/* 89/6/13 add, */
+/* for different PHY */
+enum phy_type_flags {
+	MysonPHY = 1,
+	AhdocPHY = 2,
+	SeeqPHY = 3,
+	MarvellPHY = 4,
+	Myson981 = 5,
+	LevelOnePHY = 6,
+	OtherPHY = 10,
+};
+
+struct chip_info {
+	char *chip_name;
+	int io_size;
+	int flags;
+};
+
+static struct chip_info skel_netdrv_tbl[] = {
+	{"100/10M Ethernet PCI Adapter", 136, HAS_MII_XCVR},
+	{"100/10M Ethernet PCI Adapter", 136, HAS_CHIP_XCVR},
+	{"1000/100/10M Ethernet PCI Adapter", 136, HAS_MII_XCVR},
+};
+
+/* Offsets to the Command and Status Registers. */
+enum fealnx_offsets {
+	PAR0 = 0x0,		/* physical address 0-3 */
+	PAR1 = 0x04,		/* physical address 4-5 */
+	MAR0 = 0x08,		/* multicast address 0-3 */
+	MAR1 = 0x0C,		/* multicast address 4-7 */
+	FAR0 = 0x10,		/* flow-control address 0-3 */
+	FAR1 = 0x14,		/* flow-control address 4-5 */
+	TCRRCR = 0x18,		/* receive & transmit configuration */
+	BCR = 0x1C,		/* bus command */
+	TXPDR = 0x20,		/* transmit polling demand */
+	RXPDR = 0x24,		/* receive polling demand */
+	RXCWP = 0x28,		/* receive current word pointer */
+	TXLBA = 0x2C,		/* transmit list base address */
+	RXLBA = 0x30,		/* receive list base address */
+	ISR = 0x34,		/* interrupt status */
+	IMR = 0x38,		/* interrupt mask */
+	FTH = 0x3C,		/* flow control high/low threshold */
+	MANAGEMENT = 0x40,	/* bootrom/eeprom and mii management */
+	TALLY = 0x44,		/* tally counters for crc and mpa */
+	TSR = 0x48,		/* tally counter for transmit status */
+	BMCRSR = 0x4c,		/* basic mode control and status */
+	PHYIDENTIFIER = 0x50,	/* phy identifier */
+	ANARANLPAR = 0x54,	/* auto-negotiation advertisement and link
+				   partner ability */
+	ANEROCR = 0x58,		/* auto-negotiation expansion and pci conf. */
+	BPREMRPSR = 0x5c,	/* bypass & receive error mask and phy status */
+};
+
+/* Bits in the interrupt status/enable registers. */
+/* The bits in the Intr Status/Enable registers, mostly interrupt sources. */
+enum intr_status_bits {
+	RFCON = 0x00020000,	/* receive flow control xon packet */
+	RFCOFF = 0x00010000,	/* receive flow control xoff packet */
+	LSCStatus = 0x00008000,	/* link status change */
+	ANCStatus = 0x00004000,	/* autonegotiation completed */
+	FBE = 0x00002000,	/* fatal bus error */
+	FBEMask = 0x00001800,	/* mask bit12-11 */
+	ParityErr = 0x00000000,	/* parity error */
+	TargetErr = 0x00001000,	/* target abort */
+	MasterErr = 0x00000800,	/* master error */
+	TUNF = 0x00000400,	/* transmit underflow */
+	ROVF = 0x00000200,	/* receive overflow */
+	ETI = 0x00000100,	/* transmit early int */
+	ERI = 0x00000080,	/* receive early int */
+	CNTOVF = 0x00000040,	/* counter overflow */
+	RBU = 0x00000020,	/* receive buffer unavailable */
+	TBU = 0x00000010,	/* transmit buffer unavilable */
+	TI = 0x00000008,	/* transmit interrupt */
+	RI = 0x00000004,	/* receive interrupt */
+	RxErr = 0x00000002,	/* receive error */
+};
+
+/* Bits in the NetworkConfig register. */
+enum rx_mode_bits {
+	RxModeMask = 0xe0,
+	PROM = 0x80,		/* promiscuous mode */
+	AB = 0x40,		/* accept broadcast */
+	AM = 0x20,		/* accept mutlicast */
+	ARP = 0x08,		/* receive runt pkt */
+	ALP = 0x04,		/* receive long pkt */
+	SEP = 0x02,		/* receive error pkt */
+};
+
+/* The Tulip Rx and Tx buffer descriptors. */
+struct fealnx_desc {
+	s32 status;
+	s32 control;
+	u32 buffer;
+	u32 next_desc;
+	struct fealnx_desc *next_desc_logical;
+	struct sk_buff *skbuff;
+	u32 reserved1;
+	u32 reserved2;
+};
+
+/* Bits in network_desc.status */
+enum rx_desc_status_bits {
+	RXOWN = 0x80000000,	/* own bit */
+	FLNGMASK = 0x0fff0000,	/* frame length */
+	FLNGShift = 16,
+	MARSTATUS = 0x00004000,	/* multicast address received */
+	BARSTATUS = 0x00002000,	/* broadcast address received */
+	PHYSTATUS = 0x00001000,	/* physical address received */
+	RXFSD = 0x00000800,	/* first descriptor */
+	RXLSD = 0x00000400,	/* last descriptor */
+	ErrorSummary = 0x80,	/* error summary */
+	RUNT = 0x40,		/* runt packet received */
+	LONG = 0x20,		/* long packet received */
+	FAE = 0x10,		/* frame align error */
+	CRC = 0x08,		/* crc error */
+	RXER = 0x04,		/* receive error */
+};
+
+enum rx_desc_control_bits {
+	RXIC = 0x00800000,	/* interrupt control */
+	RBSShift = 0,
+};
+
+enum tx_desc_status_bits {
+	TXOWN = 0x80000000,	/* own bit */
+	JABTO = 0x00004000,	/* jabber timeout */
+	CSL = 0x00002000,	/* carrier sense lost */
+	LC = 0x00001000,	/* late collision */
+	EC = 0x00000800,	/* excessive collision */
+	UDF = 0x00000400,	/* fifo underflow */
+	DFR = 0x00000200,	/* deferred */
+	HF = 0x00000100,	/* heartbeat fail */
+	NCRMask = 0x000000ff,	/* collision retry count */
+	NCRShift = 0,
+};
+
+enum tx_desc_control_bits {
+	TXIC = 0x80000000,	/* interrupt control */
+	ETIControl = 0x40000000,	/* early transmit interrupt */
+	TXLD = 0x20000000,	/* last descriptor */
+	TXFD = 0x10000000,	/* first descriptor */
+	CRCEnable = 0x08000000,	/* crc control */
+	PADEnable = 0x04000000,	/* padding control */
+	RetryTxLC = 0x02000000,	/* retry late collision */
+	PKTSMask = 0x3ff800,	/* packet size bit21-11 */
+	PKTSShift = 11,
+	TBSMask = 0x000007ff,	/* transmit buffer bit 10-0 */
+	TBSShift = 0,
+};
+
+/* BootROM/EEPROM/MII Management Register */
+#define MASK_MIIR_MII_READ       0x00000000
+#define MASK_MIIR_MII_WRITE      0x00000008
+#define MASK_MIIR_MII_MDO        0x00000004
+#define MASK_MIIR_MII_MDI        0x00000002
+#define MASK_MIIR_MII_MDC        0x00000001
+
+/* ST+OP+PHYAD+REGAD+TA */
+#define OP_READ             0x6000	/* ST:01+OP:10+PHYAD+REGAD+TA:Z0 */
+#define OP_WRITE            0x5002	/* ST:01+OP:01+PHYAD+REGAD+TA:10 */
+
+/* ------------------------------------------------------------------------- */
+/*      Constants for Myson PHY                                              */
+/* ------------------------------------------------------------------------- */
+#define MysonPHYID      0xd0000302
+/* 89-7-27 add, (begin) */
+#define MysonPHYID0     0x0302
+#define StatusRegister  18
+#define SPEED100        0x0400	// bit10
+#define FULLMODE        0x0800	// bit11
+/* 89-7-27 add, (end) */
+
+/* ------------------------------------------------------------------------- */
+/*      Constants for Seeq 80225 PHY                                         */
+/* ------------------------------------------------------------------------- */
+#define SeeqPHYID0      0x0016
+
+#define MIIRegister18   18
+#define SPD_DET_100     0x80
+#define DPLX_DET_FULL   0x40
+
+/* ------------------------------------------------------------------------- */
+/*      Constants for Ahdoc 101 PHY                                          */
+/* ------------------------------------------------------------------------- */
+#define AhdocPHYID0     0x0022
+
+#define DiagnosticReg   18
+#define DPLX_FULL       0x0800
+#define Speed_100       0x0400
+
+/* 89/6/13 add, */
+/* -------------------------------------------------------------------------- */
+/*      Constants                                                             */
+/* -------------------------------------------------------------------------- */
+#define MarvellPHYID0           0x0141
+#define LevelOnePHYID0		0x0013
+
+#define MII1000BaseTControlReg  9
+#define MII1000BaseTStatusReg   10
+#define SpecificReg		17
+
+/* for 1000BaseT Control Register */
+#define PHYAbletoPerform1000FullDuplex  0x0200
+#define PHYAbletoPerform1000HalfDuplex  0x0100
+#define PHY1000AbilityMask              0x300
+
+// for phy specific status register, marvell phy.
+#define SpeedMask       0x0c000
+#define Speed_1000M     0x08000
+#define Speed_100M      0x4000
+#define Speed_10M       0
+#define Full_Duplex     0x2000
+
+// 89/12/29 add, for phy specific status register, levelone phy, (begin)
+#define LXT1000_100M    0x08000
+#define LXT1000_1000M   0x0c000
+#define LXT1000_Full    0x200
+// 89/12/29 add, for phy specific status register, levelone phy, (end)
+
+/* for 3-in-1 case */
+#define PS10            0x00080000
+#define FD              0x00100000
+#define PS1000          0x00010000
+#define LinkIsUp2	0x00040000
+
+/* for PHY */
+#define LinkIsUp        0x0004
+
+
+struct netdev_private {
+	/* Descriptor rings first for alignment. */
+	struct fealnx_desc rx_ring[RX_RING_SIZE];
+	struct fealnx_desc tx_ring[TX_RING_SIZE];
+
+	struct net_device_stats stats;
+
+	/* Media monitoring timer. */
+	struct timer_list timer;
+
+	/* Frequently used values: keep some adjacent for cache effect. */
+	int flags;
+	struct pci_dev *pci_dev;
+	unsigned long crvalue;
+	unsigned long bcrvalue;
+	unsigned long imrvalue;
+	struct fealnx_desc *cur_rx;
+	struct fealnx_desc *lack_rxbuf;
+	int really_rx_count;
+	struct fealnx_desc *cur_tx;
+	struct fealnx_desc *cur_tx_copy;
+	int really_tx_count;
+	int free_tx_count;
+	unsigned int rx_buf_sz;	/* Based on MTU+slack. */
+
+	/* These values are keep track of the transceiver/media in use. */
+	unsigned int linkok;
+	unsigned int line_speed;
+	unsigned int duplexmode;
+	unsigned int full_duplex:1;	/* Full-duplex operation requested. */
+	unsigned int duplex_lock:1;
+	unsigned int medialock:1;	/* Do not sense media. */
+	unsigned int default_port:4;	/* Last dev->if_port value. */
+	unsigned int PHYType;
+
+	/* MII transceiver section. */
+	int mii_cnt;		/* MII device addresses. */
+	unsigned char phys[2];	/* MII device addresses. */
+};
+
+
+static unsigned int mdio_read(struct net_device *dev, int phy_id, int location);
+static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
+static int netdev_open(struct net_device *dev);
+static void getlinktype(struct net_device *dev);
+static void getlinkstatus(struct net_device *dev);
+static void netdev_timer(unsigned long data);
+static void tx_timeout(struct net_device *dev);
+static void init_ring(struct net_device *dev);
+static int start_tx(struct sk_buff *skb, struct net_device *dev);
+static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static int netdev_rx(struct net_device *dev);
+static inline unsigned ether_crc(int length, unsigned char *data);
+static void set_rx_mode(struct net_device *dev);
+static struct net_device_stats *get_stats(struct net_device *dev);
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int netdev_close(struct net_device *dev);
+
+
+void stop_nic_tx(long ioaddr, long crvalue)
+{
+	writel(crvalue & (~0x40000), ioaddr + TCRRCR);
+
+	/* wait for tx stop */
+	{
+		int i = 0, delay = 0x1000;
+
+		while ((!(readl(ioaddr + TCRRCR) & 0x04000000)) && (i < delay)) {
+			++i;
+		}
+	}
+}
+
+
+void stop_nic_rx(long ioaddr, long crvalue)
+{
+	writel(crvalue & (~0x1), ioaddr + TCRRCR);
+
+	/* wait for rx stop */
+	{
+		int i = 0, delay = 0x1000;
+
+		while ((!(readl(ioaddr + TCRRCR) & 0x00008000)) && (i < delay)) {
+			++i;
+		}
+	}
+}
+
+
+
+static int __devinit fealnx_init_one(struct pci_dev *pdev,
+				     const struct pci_device_id *ent)
+{
+	struct netdev_private *np;
+	int i, option, err, irq;
+	static int card_idx = -1;
+	char boardname[12];
+	long ioaddr;
+	unsigned int chip_id = ent->driver_data;
+	struct net_device *dev;
+	
+/* when built into the kernel, we only print version if device is found */
+#ifndef MODULE
+	static int printed_version;
+	if (!printed_version++)
+		printk (version);
+#endif
+	
+	card_idx++;
+	sprintf(boardname, "fealnx%d", card_idx);
+	
+	option = card_idx < MAX_UNITS ? options[card_idx] : 0;
+
+	i = pci_enable_device(pdev);
+	if (i) return i;
+	pci_set_master(pdev);
+	
+#ifdef USE_IO_OPS
+	ioaddr = pci_resource_len(pdev, 0);
+#else
+	ioaddr = pci_resource_len(pdev, 1);
+#endif
+	if (ioaddr < MIN_REGION_SIZE) {
+		printk(KERN_ERR "%s: region size %ld too small, aborting\n",
+		       boardname, ioaddr);
+		return -ENODEV;
+	}
+
+	i = pci_request_regions(pdev, boardname);
+	if (i) return i;
+	
+	irq = pdev->irq;
+
+#ifdef USE_IO_OPS
+	ioaddr = pci_resource_start(pdev, 0);
+#else
+	ioaddr = (long) ioremap(pci_resource_start(pdev, 1),
+				pci_resource_len(pdev, 1));
+	if (!ioaddr) {
+		err = -ENOMEM;
+		goto err_out_res;
+	}
+#endif
+	
+	dev = alloc_etherdev(sizeof(struct netdev_private));
+	if (!dev) {
+		err = -ENOMEM;
+		goto err_out_unmap;
+	}
+	SET_MODULE_OWNER(dev);
+
+	/* read ethernet id */
+	for (i = 0; i < 6; ++i)
+		dev->dev_addr[i] = readb(ioaddr + PAR0 + i);
+
+	/* Reset the chip to erase previous misconfiguration. */
+	writel(0x00000001, ioaddr + BCR);
+
+	dev->base_addr = ioaddr;
+	dev->irq = irq;
+
+	/* Make certain the descriptor lists are aligned. */
+	np = dev->priv;
+	np->pci_dev = pdev;
+	np->flags = skel_netdrv_tbl[chip_id].flags;
+	pci_set_drvdata(pdev, dev);
+
+	/* find the connected MII xcvrs */
+	if (np->flags == HAS_MII_XCVR) {
+		int phy, phy_idx = 0;
+
+		for (phy = 1; phy < 32 && phy_idx < 4; phy++) {
+			int mii_status = mdio_read(dev, phy, 1);
+
+			if (mii_status != 0xffff && mii_status != 0x0000) {
+				np->phys[phy_idx++] = phy;
+				printk(KERN_INFO
+				       "%s: MII PHY found at address %d, status "
+				       "0x%4.4x.\n", dev->name, phy, mii_status);
+				/* get phy type */
+				{
+					unsigned int data;
+
+					data = mdio_read(dev, np->phys[0], 2);
+					if (data == SeeqPHYID0)
+						np->PHYType = SeeqPHY;
+					else if (data == AhdocPHYID0)
+						np->PHYType = AhdocPHY;
+					else if (data == MarvellPHYID0)
+						np->PHYType = MarvellPHY;
+					else if (data == MysonPHYID0)
+						np->PHYType = Myson981;
+					else if (data == LevelOnePHYID0)
+						np->PHYType = LevelOnePHY;
+					else
+						np->PHYType = OtherPHY;
+				}
+			}
+		}
+
+		np->mii_cnt = phy_idx;
+		if (phy_idx == 0) {
+			printk(KERN_WARNING "%s: MII PHY not found -- this device may "
+			       "not operate correctly.\n", dev->name);
+		}
+	} else {
+		np->phys[0] = 32;
+/* 89/6/23 add, (begin) */
+		/* get phy type */
+		if (readl(dev->base_addr + PHYIDENTIFIER) == MysonPHYID)
+			np->PHYType = MysonPHY;
+		else
+			np->PHYType = OtherPHY;
+	}
+
+	if (dev->mem_start)
+		option = dev->mem_start;
+
+	/* The lower four bits are the media type. */
+	if (option > 0) {
+		if (option & 0x200)
+			np->full_duplex = 1;
+		np->default_port = option & 15;
+
+		if (np->default_port)
+			np->medialock = 1;
+	}
+
+	if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
+		np->full_duplex = full_duplex[card_idx];
+
+	if (np->full_duplex) {
+		printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name);
+/* 89/6/13 add, (begin) */
+//      if (np->PHYType==MarvellPHY)
+		if ((np->PHYType == MarvellPHY) || (np->PHYType == LevelOnePHY)) {
+			unsigned int data;
+
+			data = mdio_read(dev, np->phys[0], 9);
+			data = (data & 0xfcff) | 0x0200;
+			mdio_write(dev, np->phys[0], 9, data);
+		}
+/* 89/6/13 add, (end) */
+		if (np->flags == HAS_MII_XCVR)
+			mdio_write(dev, np->phys[0], 4, 0x141);
+		else
+			writel(0x141, dev->base_addr + ANARANLPAR);
+		np->duplex_lock = 1;
+	}
+
+	/* The chip-specific entries in the device structure. */
+	dev->open = &netdev_open;
+	dev->hard_start_xmit = &start_tx;
+	dev->stop = &netdev_close;
+	dev->get_stats = &get_stats;
+	dev->set_multicast_list = &set_rx_mode;
+	dev->do_ioctl = &mii_ioctl;
+	dev->tx_timeout = tx_timeout;
+	dev->watchdog_timeo = TX_TIMEOUT;
+	
+	err = register_netdev(dev);
+	if (err)
+		goto err_out_free;
+
+	printk(KERN_INFO "%s: %s at 0x%lx, ",
+	       dev->name, skel_netdrv_tbl[chip_id].chip_name, ioaddr);
+	for (i = 0; i < 5; i++)
+		printk("%2.2x:", dev->dev_addr[i]);
+	printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
+
+	return 0;
+
+err_out_free:
+	kfree(dev);
+err_out_unmap:
+#ifndef USE_IO_OPS
+	iounmap((void *)ioaddr);
+err_out_res:
+#endif
+	pci_release_regions(pdev);
+	return err;
+}
+
+static void __devexit fealnx_remove_one(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	if (dev) {
+		unregister_netdev(dev);
+#ifndef USE_IO_OPS
+		iounmap((void *)dev->base_addr);
+#endif
+		kfree(dev);
+		pci_release_regions(pdev);
+		pci_set_drvdata(pdev, NULL);
+	} else
+		printk(KERN_ERR "fealnx: remove for unknown device\n");
+}
+
+unsigned int m80x_read_tick(void)
+/* function: Reads the Timer tick count register which decrements by 2 from  */
+/*           65536 to 0 every 1/36.414 of a second. Each 2 decrements of the *//*           count represents 838 nsec's.                                    */
+/* input   : none.                                                           */
+/* output  : none.                                                           */
+{
+	unsigned char tmp;
+	int value;
+
+	writeb((char) 0x06, 0x43);	// Command 8254 to latch T0's count
+
+	// now read the count.
+	tmp = (unsigned char) readb(0x40);
+	value = ((int) tmp) << 8;
+	tmp = (unsigned char) readb(0x40);
+	value |= (((int) tmp) & 0xff);
+	return (value);
+}
+
+
+void m80x_delay(unsigned int interval)
+/* function: to wait for a specified time.                                   */
+/* input   : interval ... the specified time.                                */
+/* output  : none.                                                           */
+{
+	unsigned int interval1, interval2, i = 0;
+
+	interval1 = m80x_read_tick();	// get initial value
+	do {
+		interval2 = m80x_read_tick();
+		if (interval1 < interval2)
+			interval1 = interval2;
+		++i;
+	} while (((interval1 - interval2) < (ushort) interval) && (i < 65535));
+}
+
+
+static ulong m80x_send_cmd_to_phy(long miiport, int opcode, int phyad, int regad)
+{
+	ulong miir;
+	int i;
+	unsigned int mask, data;
+
+	/* enable MII output */
+	miir = (ulong) readl(miiport);
+	miir &= 0xfffffff0;
+
+	miir |= MASK_MIIR_MII_WRITE + MASK_MIIR_MII_MDO;
+
+	/* send 32 1's preamble */
+	for (i = 0; i < 32; i++) {
+		/* low MDC; MDO is already high (miir) */
+		miir &= ~MASK_MIIR_MII_MDC;
+		writel(miir, miiport);
+
+		/* high MDC */
+		miir |= MASK_MIIR_MII_MDC;
+		writel(miir, miiport);
+	}
+
+	/* calculate ST+OP+PHYAD+REGAD+TA */
+	data = opcode | (phyad << 7) | (regad << 2);
+
+	/* sent out */
+	mask = 0x8000;
+	while (mask) {
+		/* low MDC, prepare MDO */
+		miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO);
+		if (mask & data)
+			miir |= MASK_MIIR_MII_MDO;
+
+		writel(miir, miiport);
+		/* high MDC */
+		miir |= MASK_MIIR_MII_MDC;
+		writel(miir, miiport);
+		m80x_delay(30);
+
+		/* next */
+		mask >>= 1;
+		if (mask == 0x2 && opcode == OP_READ)
+			miir &= ~MASK_MIIR_MII_WRITE;
+	}
+	return miir;
+}
+
+
+static unsigned int mdio_read(struct net_device *dev, int phyad, int regad)
+{
+	long miiport = dev->base_addr + MANAGEMENT;
+	ulong miir;
+	unsigned int mask, data;
+
+	miir = m80x_send_cmd_to_phy(miiport, OP_READ, phyad, regad);
+
+	/* read data */
+	mask = 0x8000;
+	data = 0;
+	while (mask) {
+		/* low MDC */
+		miir &= ~MASK_MIIR_MII_MDC;
+		writel(miir, miiport);
+
+		/* read MDI */
+		miir = readl(miiport);
+		if (miir & MASK_MIIR_MII_MDI)
+			data |= mask;
+
+		/* high MDC, and wait */
+		miir |= MASK_MIIR_MII_MDC;
+		writel(miir, miiport);
+		m80x_delay((int) 30);
+
+		/* next */
+		mask >>= 1;
+	}
+
+	/* low MDC */
+	miir &= ~MASK_MIIR_MII_MDC;
+	writel(miir, miiport);
+
+	return data;
+}
+
+
+static void mdio_write(struct net_device *dev, int phyad, int regad, int data)
+{
+	long miiport = dev->base_addr + MANAGEMENT;
+	ulong miir;
+	unsigned int mask;
+
+	miir = m80x_send_cmd_to_phy(miiport, OP_WRITE, phyad, regad);
+
+	/* write data */
+	mask = 0x8000;
+	while (mask) {
+		/* low MDC, prepare MDO */
+		miir &= ~(MASK_MIIR_MII_MDC + MASK_MIIR_MII_MDO);
+		if (mask & data)
+			miir |= MASK_MIIR_MII_MDO;
+		writel(miir, miiport);
+
+		/* high MDC */
+		miir |= MASK_MIIR_MII_MDC;
+		writel(miir, miiport);
+
+		/* next */
+		mask >>= 1;
+	}
+
+	/* low MDC */
+	miir &= ~MASK_MIIR_MII_MDC;
+	writel(miir, miiport);
+
+	return;
+}
+
+
+static int netdev_open(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
+
+	writel(0x00000001, ioaddr + BCR);	/* Reset */
+
+	if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev))
+		return -EAGAIN;
+
+	init_ring(dev);
+
+	writel(virt_to_bus(np->rx_ring), ioaddr + RXLBA);
+	writel(virt_to_bus(np->tx_ring), ioaddr + TXLBA);
+
+	/* Initialize other registers. */
+	/* Configure the PCI bus bursts and FIFO thresholds.
+	   486: Set 8 longword burst.
+	   586: no burst limit.
+	   Burst length 5:3
+	   0 0 0   1
+	   0 0 1   4
+	   0 1 0   8
+	   0 1 1   16
+	   1 0 0   32
+	   1 0 1   64
+	   1 1 0   128
+	   1 1 1   256
+	   Wait the specified 50 PCI cycles after a reset by initializing
+	   Tx and Rx queues and the address filter list. */
+#if defined(__powerpc__)
+// 89/9/1 modify, 
+//   np->bcrvalue=0x04 | 0x0x38;  /* big-endian, 256 burst length */
+	np->bcrvalue = 0x04 | 0x0 x10;	/* big-endian, tx 8 burst length */
+	a np->cralue = 0xe00;	/* rx 128 burst length */
+#elif defined(__alpha__)
+// 89/9/1 modify, 
+//   np->bcrvalue=0x38;           /* little-endian, 256 burst length */
+	np->bcrvalue = 0x10;	/* little-endian, 8 burst length */
+	np->cralue = 0xe00;	/* rx 128 burst length */
+#elif defined(__i386__)
+#if defined(MODULE)
+// 89/9/1 modify, 
+//   np->bcrvalue=0x38;           /* little-endian, 256 burst length */
+	np->bcrvalue = 0x10;	/* little-endian, 8 burst length */
+	np->crvalue = 0xe00;	/* rx 128 burst length */
+#else
+	/* When not a module we can work around broken '486 PCI boards. */
+#define x86 boot_cpu_data.x86
+// 89/9/1 modify, 
+//   np->bcrvalue=(x86 <= 4 ? 0x10 : 0x38);
+	np->bcrvalue = 0x10;
+	np->crvalue = (x86 <= 4 ? 0xa00 : 0xe00);
+	if (x86 <= 4)
+		printk(KERN_INFO "%s: This is a 386/486 PCI system, setting burst "
+		       "length to %x.\n", dev->name, (x86 <= 4 ? 0x10 : 0x38));
+#endif
+#else
+// 89/9/1 modify,
+//   np->bcrvalue=0x38;
+	np->bcrvalue = 0x10;
+	np->cralue = 0xe00;	/* rx 128 burst length */
+#warning Processor architecture undefined!
+#endif
+// 89/12/29 add,
+// 90/1/16 modify,
+//   np->imrvalue=FBE|TUNF|CNTOVF|RBU|TI|RI;
+	np->imrvalue = TUNF | CNTOVF | RBU | TI | RI;
+	if (np->pci_dev->device == 0x891) {
+		np->bcrvalue |= 0x200;	/* set PROG bit */
+		np->crvalue |= 0x02000000;	/* set enhanced bit */
+		np->imrvalue |= ETI;
+	}
+	writel(np->bcrvalue, ioaddr + BCR);
+
+	if (dev->if_port == 0)
+		dev->if_port = np->default_port;
+
+	writel(0, dev->base_addr + RXPDR);
+// 89/9/1 modify,
+//   np->crvalue = 0x00e40001;    /* tx store and forward, tx/rx enable */
+	np->crvalue |= 0x00e40001;	/* tx store and forward, tx/rx enable */
+	np->full_duplex = np->duplex_lock;
+	getlinkstatus(dev);
+	if (np->linkok)
+		getlinktype(dev);
+	set_rx_mode(dev);
+
+	netif_start_queue(dev);
+
+	/* Clear and Enable interrupts by setting the interrupt mask. */
+	writel(FBE | TUNF | CNTOVF | RBU | TI | RI, ioaddr + ISR);
+	writel(np->imrvalue, ioaddr + IMR);
+
+	if (debug)
+		printk(KERN_DEBUG "%s: Done netdev_open().\n", dev->name);
+
+	/* Set the timer to check for link beat. */
+	init_timer(&np->timer);
+	np->timer.expires = RUN_AT(3 * HZ);
+	np->timer.data = (unsigned long) dev;
+	np->timer.function = &netdev_timer;
+
+	/* timer handler */
+	add_timer(&np->timer);
+
+	return 0;
+}
+
+
+static void getlinkstatus(struct net_device *dev)
+/* function: Routine will read MII Status Register to get link status.       */
+/* input   : dev... pointer to the adapter block.                            */
+/* output  : none.                                                           */
+{
+	struct netdev_private *np = dev->priv;
+	unsigned int i, DelayTime = 0x1000;
+
+	np->linkok = 0;
+
+	if (np->PHYType == MysonPHY) {
+		for (i = 0; i < DelayTime; ++i) {
+			if (readl(dev->base_addr + BMCRSR) & LinkIsUp2) {
+				np->linkok = 1;
+				return;
+			}
+			// delay
+			m80x_delay(100);
+		}
+	} else {
+		for (i = 0; i < DelayTime; ++i) {
+			if (mdio_read(dev, np->phys[0], 1) & 0x4) {
+				np->linkok = 1;
+				return;
+			}
+			// delay
+			m80x_delay(100);
+		}
+	}
+}
+
+
+static void getlinktype(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+
+	if (np->PHYType == MysonPHY) {	/* 3-in-1 case */
+		if (readl(dev->base_addr + TCRRCR) & FD)
+			np->duplexmode = 2;	/* full duplex */
+		else
+			np->duplexmode = 1;	/* half duplex */
+		if (readl(dev->base_addr + TCRRCR) & PS10)
+			np->line_speed = 1;	/* 10M */
+		else
+			np->line_speed = 2;	/* 100M */
+	} else {
+		if (np->PHYType == SeeqPHY) {	/* this PHY is SEEQ 80225 */
+			unsigned int data;
+
+			data = mdio_read(dev, np->phys[0], MIIRegister18);
+			if (data & SPD_DET_100)
+				np->line_speed = 2;	/* 100M */
+			else
+				np->line_speed = 1;	/* 10M */
+			if (data & DPLX_DET_FULL)
+				np->duplexmode = 2;	/* full duplex mode */
+			else
+				np->duplexmode = 1;	/* half duplex mode */
+		} else if (np->PHYType == AhdocPHY) {
+			unsigned int data;
+
+			data = mdio_read(dev, np->phys[0], DiagnosticReg);
+			if (data & Speed_100)
+				np->line_speed = 2;	/* 100M */
+			else
+				np->line_speed = 1;	/* 10M */
+			if (data & DPLX_FULL)
+				np->duplexmode = 2;	/* full duplex mode */
+			else
+				np->duplexmode = 1;	/* half duplex mode */
+		}
+/* 89/6/13 add, (begin) */
+		else if (np->PHYType == MarvellPHY) {
+			unsigned int data;
+
+			data = mdio_read(dev, np->phys[0], SpecificReg);
+			if (data & Full_Duplex)
+				np->duplexmode = 2;	/* full duplex mode */
+			else
+				np->duplexmode = 1;	/* half duplex mode */
+			data &= SpeedMask;
+			if (data == Speed_1000M)
+				np->line_speed = 3;	/* 1000M */
+			else if (data == Speed_100M)
+				np->line_speed = 2;	/* 100M */
+			else
+				np->line_speed = 1;	/* 10M */
+		}
+/* 89/6/13 add, (end) */
+/* 89/7/27 add, (begin) */
+		else if (np->PHYType == Myson981) {
+			unsigned int data;
+
+			data = mdio_read(dev, np->phys[0], StatusRegister);
+
+			if (data & SPEED100)
+				np->line_speed = 2;
+			else
+				np->line_speed = 1;
+
+			if (data & FULLMODE)
+				np->duplexmode = 2;
+			else
+				np->duplexmode = 1;
+		}
+/* 89/7/27 add, (end) */
+/* 89/12/29 add */
+		else if (np->PHYType == LevelOnePHY) {
+			unsigned int data;
+
+			data = mdio_read(dev, np->phys[0], SpecificReg);
+			if (data & LXT1000_Full)
+				np->duplexmode = 2;	/* full duplex mode */
+			else
+				np->duplexmode = 1;	/* half duplex mode */
+			data &= SpeedMask;
+			if (data == LXT1000_1000M)
+				np->line_speed = 3;	/* 1000M */
+			else if (data == LXT1000_100M)
+				np->line_speed = 2;	/* 100M */
+			else
+				np->line_speed = 1;	/* 10M */
+		}
+		// chage crvalue
+		// np->crvalue&=(~PS10)&(~FD);
+		np->crvalue &= (~PS10) & (~FD) & (~PS1000);
+		if (np->line_speed == 1)
+			np->crvalue |= PS10;
+		else if (np->line_speed == 3)
+			np->crvalue |= PS1000;
+		if (np->duplexmode == 2)
+			np->crvalue |= FD;
+	}
+}
+
+
+static void allocate_rx_buffers(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+
+	/*  allocate skb for rx buffers */
+	while (np->really_rx_count != RX_RING_SIZE) {
+		struct sk_buff *skb;
+
+		skb = dev_alloc_skb(np->rx_buf_sz);
+		np->lack_rxbuf->skbuff = skb;
+
+		if (skb == NULL)
+			break;	/* Better luck next round. */
+
+		skb->dev = dev;	/* Mark as being used by this device. */
+		np->lack_rxbuf->buffer = virt_to_bus(skb->tail);
+		np->lack_rxbuf = np->lack_rxbuf->next_desc_logical;
+		++np->really_rx_count;
+	}
+}
+
+
+static void netdev_timer(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *) data;
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
+	int next_tick = 10 * HZ;
+	int old_crvalue = np->crvalue;
+	unsigned int old_linkok = np->linkok;
+
+	if (debug)
+		printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x "
+		       "config %8.8x.\n", dev->name, readl(ioaddr + ISR),
+		       readl(ioaddr + TCRRCR));
+
+	if (np->flags == HAS_MII_XCVR) {
+		getlinkstatus(dev);
+		if ((old_linkok == 0) && (np->linkok == 1)) {	/* we need to detect the media type again */
+			getlinktype(dev);
+			if (np->crvalue != old_crvalue) {
+				stop_nic_tx(ioaddr, np->crvalue);
+				stop_nic_rx(ioaddr, np->crvalue & (~0x40000));
+				writel(np->crvalue, ioaddr + TCRRCR);
+			}
+		}
+	}
+
+	allocate_rx_buffers(dev);
+
+	np->timer.expires = RUN_AT(next_tick);
+	add_timer(&np->timer);
+}
+
+
+static void tx_timeout(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
+
+	printk(KERN_WARNING "%s: Transmit timed out, status %8.8x,"
+	       " resetting...\n", dev->name, readl(ioaddr + ISR));
+
+#ifndef __alpha__
+	{
+		int i;
+
+		printk(KERN_DEBUG "  Rx ring %8.8x: ", (int) np->rx_ring);
+		for (i = 0; i < RX_RING_SIZE; i++)
+			printk(" %8.8x", (unsigned int) np->rx_ring[i].status);
+		printk("\n" KERN_DEBUG "  Tx ring %8.8x: ", (int) np->tx_ring);
+		for (i = 0; i < TX_RING_SIZE; i++)
+			printk(" %4.4x", np->tx_ring[i].status);
+		printk("\n");
+	}
+#endif
+
+	/* Perhaps we should reinitialize the hardware here.  Just trigger a
+	   Tx demand for now. */
+	writel(0, dev->base_addr + TXPDR);
+	dev->if_port = 0;
+
+	/* Stop and restart the chip's Tx processes . */
+	dev->trans_start = jiffies;
+	np->stats.tx_errors++;
+
+	return;
+}
+
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void init_ring(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+	int i;
+
+	/* initialize rx variables */
+	np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
+	np->cur_rx = &np->rx_ring[0];
+	np->lack_rxbuf = NULL;
+	np->really_rx_count = 0;
+
+	/* initial rx descriptors. */
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		np->rx_ring[i].status = 0;
+		np->rx_ring[i].control = np->rx_buf_sz << RBSShift;
+		np->rx_ring[i].next_desc = virt_to_bus(&np->rx_ring[i + 1]);
+		np->rx_ring[i].next_desc_logical = &np->rx_ring[i + 1];
+		np->rx_ring[i].skbuff = NULL;
+	}
+
+	/* for the last rx descriptor */
+	np->rx_ring[i - 1].next_desc = virt_to_bus(&np->rx_ring[0]);
+	np->rx_ring[i - 1].next_desc_logical = &np->rx_ring[0];
+
+	/* allocate skb for rx buffers */
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
+
+		if (skb == NULL) {
+			np->lack_rxbuf = &np->rx_ring[i];
+			break;
+		}
+
+		++np->really_rx_count;
+		np->rx_ring[i].skbuff = skb;
+		skb->dev = dev;	/* Mark as being used by this device. */
+		np->rx_ring[i].buffer = virt_to_bus(skb->tail);
+		np->rx_ring[i].status = RXOWN;
+		np->rx_ring[i].control |= RXIC;
+	}
+
+	/* initialize tx variables */
+	np->cur_tx = &np->tx_ring[0];
+	np->cur_tx_copy = &np->tx_ring[0];
+	np->really_tx_count = 0;
+	np->free_tx_count = TX_RING_SIZE;
+
+	for (i = 0; i < TX_RING_SIZE; i++) {
+		np->tx_ring[i].status = 0;
+		np->tx_ring[i].next_desc = virt_to_bus(&np->tx_ring[i + 1]);
+		np->tx_ring[i].next_desc_logical = &np->tx_ring[i + 1];
+		np->tx_ring[i].skbuff = NULL;
+	}
+
+	/* for the last tx descriptor */
+	np->tx_ring[i - 1].next_desc = virt_to_bus(&np->tx_ring[0]);
+	np->tx_ring[i - 1].next_desc_logical = &np->tx_ring[0];
+
+	return;
+}
+
+
+static int start_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+
+	np->cur_tx_copy->skbuff = skb;
+	np->cur_tx_copy->buffer = virt_to_bus(skb->data);
+
+#define one_buffer
+#define BPT 1022
+#if defined(one_buffer)
+	np->cur_tx_copy->control = TXIC | TXLD | TXFD | CRCEnable | PADEnable;
+	np->cur_tx_copy->control |= (skb->len << PKTSShift);	/* pkt size */
+	np->cur_tx_copy->control |= (skb->len << TBSShift);	/* buffer size */
+// 89/12/29 add,
+	if (np->pci_dev->device == 0x891)
+		np->cur_tx_copy->control |= ETIControl | RetryTxLC;
+	np->cur_tx_copy->status = TXOWN;
+	np->cur_tx_copy = np->cur_tx_copy->next_desc_logical;
+	--np->free_tx_count;
+#elif defined(two_buffer)
+	if (skb->len > BPT) {
+		struct fealnx_desc *next;
+
+		/* for the first descriptor */
+		np->cur_tx_copy->control = TXIC | TXFD | CRCEnable | PADEnable;
+		np->cur_tx_copy->control |= (skb->len << PKTSShift);	/* pkt size */
+		np->cur_tx_copy->control |= (BPT << TBSShift);	/* buffer size */
+
+		/* for the last descriptor */
+		next = (struct fealnx *) np->cur_tx_copy.next_desc_logical;
+		next->skbuff = skb;
+		next->control = TXIC | TXLD | CRCEnable | PADEnable;
+		next->control |= (skb->len << PKTSShift);	/* pkt size */
+		next->control |= ((skb->len - BPT) << TBSShift);	/* buf size */
+// 89/12/29 add,
+		if (np->pci_dev->device == 0x891)
+			np->cur_tx_copy->control |= ETIControl | RetryTxLC;
+		next->buffer = virt_to_bus(skb->data) + BPT;
+
+		next->status = TXOWN;
+		np->cur_tx_copy->status = TXOWN;
+
+		np->cur_tx_copy = next->next_desc_logical;
+		np->free_tx_count -= 2;
+	} else {
+		np->cur_tx_copy->control = TXIC | TXLD | TXFD | CRCEnable | PADEnable;
+		np->cur_tx_copy->control |= (skb->len << PKTSShift);	/* pkt size */
+		np->cur_tx_copy->control |= (skb->len << TBSShift);	/* buffer size */
+// 89/12/29 add,
+		if (np->pci_dev->device == 0x891)
+			np->cur_tx_copy->control |= ETIControl | RetryTxLC;
+		np->cur_tx_copy->status = TXOWN;
+		np->cur_tx_copy = np->cur_tx_copy->next_desc_logical;
+		--np->free_tx_count;
+	}
+#endif
+
+	if (np->free_tx_count < 2)
+		netif_stop_queue(dev);
+	++np->really_tx_count;
+	writel(0, dev->base_addr + TXPDR);
+	dev->trans_start = jiffies;
+
+	return 0;
+}
+
+
+void free_one_rx_descriptor(struct netdev_private *np)
+{
+	if (np->really_rx_count == RX_RING_SIZE)
+		np->cur_rx->status = RXOWN;
+	else {
+		np->lack_rxbuf->skbuff = np->cur_rx->skbuff;
+		np->lack_rxbuf->buffer = np->cur_rx->buffer;
+		np->lack_rxbuf->status = RXOWN;
+		++np->really_rx_count;
+		np->lack_rxbuf = np->lack_rxbuf->next_desc_logical;
+	}
+	np->cur_rx = np->cur_rx->next_desc_logical;
+}
+
+
+void reset_rx_descriptors(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+
+	stop_nic_rx(dev->base_addr, np->crvalue);
+
+	while (!(np->cur_rx->status & RXOWN))
+		free_one_rx_descriptor(np);
+
+	allocate_rx_buffers(dev);
+
+	writel(virt_to_bus(np->cur_rx), dev->base_addr + RXLBA);
+	writel(np->crvalue, dev->base_addr + TCRRCR);
+}
+
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+   after the Tx thread. */
+static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+{
+	struct net_device *dev = (struct net_device *) dev_instance;
+	struct netdev_private *np = dev->priv;
+	long ioaddr, boguscnt = max_interrupt_work;
+	unsigned int num_tx = 0;
+
+	writel(0, dev->base_addr + IMR);
+
+	ioaddr = dev->base_addr;
+	np = (struct netdev_private *) dev->priv;
+
+	do {
+		u32 intr_status = readl(ioaddr + ISR);
+
+		/* Acknowledge all of the current interrupt sources ASAP. */
+		writel(intr_status, ioaddr + ISR);
+
+		if (debug)
+			printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n", dev->name,
+			       intr_status);
+
+		if (!(intr_status & np->imrvalue))
+			break;
+
+// 90/1/16 delete,
+//
+//      if (intr_status & FBE)
+//      {   /* fatal error */
+//          stop_nic_tx(ioaddr, 0);
+//          stop_nic_rx(ioaddr, 0);
+//          break;
+//      };
+
+		if (intr_status & TUNF)
+			writel(0, ioaddr + TXPDR);
+
+		if (intr_status & CNTOVF) {
+			/* missed pkts */
+			np->stats.rx_missed_errors += readl(ioaddr + TALLY) & 0x7fff;
+
+			/* crc error */
+			np->stats.rx_crc_errors +=
+			    (readl(ioaddr + TALLY) & 0x7fff0000) >> 16;
+		}
+
+		if (intr_status & (RI | RBU)) {
+			if (intr_status & RI)
+				netdev_rx(dev);
+			else
+				reset_rx_descriptors(dev);
+		}
+
+		while (np->really_tx_count) {
+			long tx_status = np->cur_tx->status;
+			long tx_control = np->cur_tx->control;
+
+			if (!(tx_control & TXLD)) {	/* this pkt is combined by two tx descriptors */
+				struct fealnx_desc *next;
+
+				next = np->cur_tx->next_desc_logical;
+				tx_status = next->status;
+				tx_control = next->control;
+			}
+
+			if (tx_status & TXOWN)
+				break;
+
+			if (!(np->crvalue & 0x02000000)) {
+				if (tx_status & (CSL | LC | EC | UDF | HF)) {
+					np->stats.tx_errors++;
+					if (tx_status & EC)
+						np->stats.tx_aborted_errors++;
+					if (tx_status & CSL)
+						np->stats.tx_carrier_errors++;
+					if (tx_status & LC)
+						np->stats.tx_window_errors++;
+					if (tx_status & UDF)
+						np->stats.tx_fifo_errors++;
+					if ((tx_status & HF) && np->full_duplex == 0)
+						np->stats.tx_heartbeat_errors++;
+
+#ifdef ETHER_STATS
+					if (tx_status & EC)
+						np->stats.collisions16++;
+#endif
+				} else {
+#ifdef ETHER_STATS
+					if (tx_status & DFR)
+						np->stats.tx_deferred++;
+#endif
+
+					np->stats.tx_bytes +=
+					    ((tx_control & PKTSMask) >> PKTSShift);
+
+					np->stats.collisions +=
+					    ((tx_status & NCRMask) >> NCRShift);
+					np->stats.tx_packets++;
+				}
+			} else {
+				np->stats.tx_bytes +=
+				    ((tx_control & PKTSMask) >> PKTSShift);
+				np->stats.tx_packets++;
+			}
+
+			/* Free the original skb. */
+			dev_kfree_skb_irq(np->cur_tx->skbuff);
+			np->cur_tx->skbuff = NULL;
+			--np->really_tx_count;
+			if (np->cur_tx->control & TXLD) {
+				np->cur_tx = np->cur_tx->next_desc_logical;
+				++np->free_tx_count;
+			} else {
+				np->cur_tx = np->cur_tx->next_desc_logical;
+				np->cur_tx = np->cur_tx->next_desc_logical;
+				np->free_tx_count += 2;
+			}
+			num_tx++;
+		}		/* end of for loop */
+		
+		if (num_tx && np->free_tx_count >= 2)
+			netif_wake_queue(dev);
+
+		/* read transmit status for enhanced mode only */
+		if (np->crvalue & 0x02000000) {
+			long data;
+
+			data = readl(ioaddr + TSR);
+			np->stats.tx_errors += (data & 0xff000000) >> 24;
+			np->stats.tx_aborted_errors += (data & 0xff000000) >> 24;
+			np->stats.tx_window_errors += (data & 0x00ff0000) >> 16;
+#ifdef ETHER_STATS
+			np->stats.collisions16 += (data & 0xff000000) >> 24;
+#endif
+			np->stats.collisions += (data & 0x0000ffff);
+		}
+
+		if (--boguscnt < 0) {
+			printk(KERN_WARNING "%s: Too much work at interrupt, "
+			       "status=0x%4.4x.\n", dev->name, intr_status);
+			break;
+		}
+	} while (1);
+
+	/* read the tally counters */
+	/* missed pkts */
+	np->stats.rx_missed_errors += readl(ioaddr + TALLY) & 0x7fff;
+
+	/* crc error */
+	np->stats.rx_crc_errors += (readl(ioaddr + TALLY) & 0x7fff0000) >> 16;
+
+	if (debug)
+		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
+		       dev->name, readl(ioaddr + ISR));
+
+	writel(np->imrvalue, ioaddr + IMR);
+
+	return;
+}
+
+
+/* This routine is logically part of the interrupt handler, but seperated
+   for clarity and better register allocation. */
+static int netdev_rx(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+
+	/* If EOP is set on the next entry, it's a new packet. Send it up. */
+	while (!(np->cur_rx->status & RXOWN)) {
+		s32 rx_status = np->cur_rx->status;
+
+		if (np->really_rx_count == 0)
+			break;
+
+		if (debug)
+			printk(KERN_DEBUG "  netdev_rx() status was %8.8x.\n", rx_status);
+
+		if ((!((rx_status & RXFSD) && (rx_status & RXLSD)))
+		    || (rx_status & ErrorSummary)) {
+			if (rx_status & ErrorSummary) {	/* there was a fatal error */
+				if (debug)
+					printk(KERN_DEBUG
+					       "%s: Receive error, Rx status %8.8x.\n",
+					       dev->name, rx_status);
+
+				np->stats.rx_errors++;	/* end of a packet. */
+				if (rx_status & (LONG | RUNT))
+					np->stats.rx_length_errors++;
+				if (rx_status & RXER)
+					np->stats.rx_frame_errors++;
+				if (rx_status & CRC)
+					np->stats.rx_crc_errors++;
+			} else {
+				int need_to_reset = 0;
+				int desno = 0;
+
+				if (rx_status & RXFSD) {	/* this pkt is too long, over one rx buffer */
+					struct fealnx_desc *cur;
+
+					/* check this packet is received completely? */
+					cur = np->cur_rx;
+					while (desno <= np->really_rx_count) {
+						++desno;
+						if ((!(cur->status & RXOWN))
+						    && (cur->status & RXLSD))
+							break;
+						/* goto next rx descriptor */
+						cur = cur->next_desc_logical;
+					}
+					if (desno > np->really_rx_count)
+						need_to_reset = 1;
+				} else	/* RXLSD did not find, something error */
+					need_to_reset = 1;
+
+				if (need_to_reset == 0) {
+					int i;
+
+					np->stats.rx_length_errors++;
+
+					/* free all rx descriptors related this long pkt */
+					for (i = 0; i < desno; ++i)
+						free_one_rx_descriptor(np);
+					continue;
+				} else {	/* something error, need to reset this chip */
+					reset_rx_descriptors(dev);
+				}
+				break;	/* exit the while loop */
+			}
+		} else {	/* this received pkt is ok */
+
+			struct sk_buff *skb;
+			/* Omit the four octet CRC from the length. */
+			short pkt_len = ((rx_status & FLNGMASK) >> FLNGShift) - 4;
+
+#ifndef final_version
+			if (debug)
+				printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d"
+				       " status %x.\n", pkt_len, rx_status);
+#endif
+
+			/* Check if the packet is long enough to accept without copying
+			   to a minimally-sized skbuff. */
+			if (pkt_len < rx_copybreak &&
+			    (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+				skb->dev = dev;
+				skb_reserve(skb, 2);	/* 16 byte align the IP header */
+				/* Call copy + cksum if available. */
+
+#if ! defined(__alpha__)
+				eth_copy_and_sum(skb, bus_to_virt(np->cur_rx->buffer),
+						 pkt_len, 0);
+				skb_put(skb, pkt_len);
+#else
+				memcpy(skb_put(skb, pkt_len),
+				       bus_to_virt(np->cur_rx->buffer), pkt_len);
+#endif
+			} else {
+				skb_put(skb = np->cur_rx->skbuff, pkt_len);
+				np->cur_rx->skbuff = NULL;
+				if (np->really_rx_count == RX_RING_SIZE)
+					np->lack_rxbuf = np->cur_rx;
+				--np->really_rx_count;
+			}
+			skb->protocol = eth_type_trans(skb, dev);
+			netif_rx(skb);
+			dev->last_rx = jiffies;
+			np->stats.rx_packets++;
+			np->stats.rx_bytes += pkt_len;
+		}
+
+		if (np->cur_rx->skbuff == NULL) {
+			struct sk_buff *skb;
+
+			skb = dev_alloc_skb(np->rx_buf_sz);
+
+			if (skb != NULL) {
+				skb->dev = dev;	/* Mark as being used by this device. */
+				np->cur_rx->buffer = virt_to_bus(skb->tail);
+				np->cur_rx->skbuff = skb;
+				++np->really_rx_count;
+			}
+		}
+
+		if (np->cur_rx->skbuff != NULL)
+			free_one_rx_descriptor(np);
+	}			/* end of while loop */
+
+	/*  allocate skb for rx buffers */
+	allocate_rx_buffers(dev);
+
+	return 0;
+}
+
+
+static struct net_device_stats *get_stats(struct net_device *dev)
+{
+	long ioaddr = dev->base_addr;
+	struct netdev_private *np = dev->priv;
+
+	/* The chip only need report frame silently dropped. */
+	if (netif_running(dev)) {
+		np->stats.rx_missed_errors += readl(ioaddr + TALLY) & 0x7fff;
+		np->stats.rx_crc_errors += (readl(ioaddr + TALLY) & 0x7fff0000) >> 16;
+	}
+
+	return &np->stats;
+}
+
+
+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc(int length, unsigned char *data)
+{
+	int crc = -1;
+
+	while (--length >= 0) {
+		unsigned char current_octet = *data++;
+		int bit;
+
+		for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
+			crc = (crc << 1) ^
+			    ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
+		}
+	}
+
+	return crc;
+}
+
+
+static void set_rx_mode(struct net_device *dev)
+{
+	struct netdev_private *np = dev->priv;
+	long ioaddr = dev->base_addr;
+	u32 mc_filter[2];	/* Multicast hash filter */
+	u32 rx_mode;
+
+	if (dev->flags & IFF_PROMISC) {	/* Set promiscuous. */
+		/* Unconditionally log net taps. */
+		printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+		memset(mc_filter, 0xff, sizeof(mc_filter));
+		rx_mode = PROM | AB | AM;
+	} else if ((dev->mc_count > multicast_filter_limit)
+		   || (dev->flags & IFF_ALLMULTI)) {
+		/* Too many to match, or accept all multicasts. */
+		memset(mc_filter, 0xff, sizeof(mc_filter));
+		rx_mode = AB | AM;
+	} else {
+		struct dev_mc_list *mclist;
+		int i;
+
+		memset(mc_filter, 0, sizeof(mc_filter));
+		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+		     i++, mclist = mclist->next) {
+			set_bit((ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26) ^ 0x3F,
+				mc_filter);
+		}
+		rx_mode = AB | AM;
+	}
+
+	stop_nic_tx(ioaddr, np->crvalue);
+	stop_nic_rx(ioaddr, np->crvalue & (~0x40000));
+
+	writel(mc_filter[0], ioaddr + MAR0);
+	writel(mc_filter[1], ioaddr + MAR1);
+	np->crvalue &= ~RxModeMask;
+	np->crvalue |= rx_mode;
+	writel(np->crvalue, ioaddr + TCRRCR);
+}
+
+
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	u16 *data = (u16 *) & rq->ifr_data;
+
+	switch (cmd) {
+	case SIOCDEVPRIVATE:	/* Get the address of the PHY in use. */
+		data[0] = ((struct netdev_private *) dev->priv)->phys[0] & 0x1f;
+		/* Fall Through */
+	case SIOCDEVPRIVATE + 1:	/* Read the specified MII register. */
+		data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);
+		return 0;
+	case SIOCDEVPRIVATE + 2:	/* Write the specified MII register */
+		if (!suser())
+			return -EPERM;
+		mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+		return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+
+static int netdev_close(struct net_device *dev)
+{
+	long ioaddr = dev->base_addr;
+	struct netdev_private *np = dev->priv;
+	int i;
+
+	netif_stop_queue(dev);
+
+	/* Disable interrupts by clearing the interrupt mask. */
+	writel(0x0000, ioaddr + IMR);
+
+	/* Stop the chip's Tx and Rx processes. */
+	stop_nic_tx(ioaddr, 0);
+	stop_nic_rx(ioaddr, 0);
+
+	del_timer_sync(&np->timer);
+
+	free_irq(dev->irq, dev);
+
+	/* Free all the skbuffs in the Rx queue. */
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		np->rx_ring[i].status = 0;
+		if (np->rx_ring[i].skbuff)
+			dev_kfree_skb(np->rx_ring[i].skbuff);
+		np->rx_ring[i].skbuff = NULL;
+	}
+
+	for (i = 0; i < TX_RING_SIZE; i++) {
+		if (np->tx_ring[i].skbuff)
+			dev_kfree_skb(np->tx_ring[i].skbuff);
+		np->tx_ring[i].skbuff = NULL;
+	}
+
+	return 0;
+}
+
+static struct pci_device_id fealnx_pci_tbl[] = __devinitdata {
+	{0x1516, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+	{0x1516, 0x0803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
+	{0x1516, 0x0891, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
+	{} /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, fealnx_pci_tbl);
+
+
+static struct pci_driver fealnx_driver = {
+	name:		"fealnx",
+	id_table:	fealnx_pci_tbl,
+	probe:		fealnx_init_one,
+	remove:		fealnx_remove_one,
+};
+
+static int __init fealnx_init(void)
+{
+/* when a module, this is printed whether or not devices are found in probe */
+#ifdef MODULE
+	printk (version);
+#endif
+
+	return pci_module_init(&fealnx_driver);
+}
+
+static void __exit fealnx_exit(void)
+{
+	pci_unregister_driver(&fealnx_driver);
+}
+
+module_init(fealnx_init);
+module_exit(fealnx_exit);
diff -u --recursive --new-file v2.4.4/linux/drivers/net/gmac.c linux/drivers/net/gmac.c
--- v2.4.4/linux/drivers/net/gmac.c	Tue Feb 13 13:15:05 2001
+++ linux/drivers/net/gmac.c	Wed May 16 09:58:36 2001
@@ -9,7 +9,7 @@
  * Changes:
  * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/06/2000
  * - check init_etherdev return in gmac_probe1
- * BenH <bh40@calva.net> - 03/09/2000
+ * BenH <benh@kernel.crashing.org> - 03/09/2000
  * - Add support for new PHYs
  * - Add some PowerBook sleep code
  * 
@@ -47,10 +47,11 @@
 #define DEBUG_PHY
 
 /* Driver version 1.3, kernel 2.4.x */
-#define GMAC_VERSION	"v1.3k4"
+#define GMAC_VERSION	"v1.4k4"
 
-static unsigned char dummy_buf[RX_BUF_ALLOC_SIZE + RX_OFFSET + GMAC_BUFFER_ALIGN];
-static struct net_device *gmacs = NULL;
+#define DUMMY_BUF_LEN	RX_BUF_ALLOC_SIZE + RX_OFFSET + GMAC_BUFFER_ALIGN
+static unsigned char *dummy_buf;
+static struct net_device *gmacs;
 
 /* Prototypes */
 static int mii_read(struct gmac *gm, int phy, int r);
@@ -62,6 +63,7 @@
 static void mii_setup_phy(struct gmac *gm);
 static int mii_do_reset_phy(struct gmac *gm, int phy_addr);
 static void mii_init_BCM5400(struct gmac *gm);
+static void mii_init_BCM5401(struct gmac *gm);
 
 static void gmac_set_power(struct gmac *gm, int power_up);
 static int gmac_powerup_and_reset(struct net_device *dev);
@@ -211,10 +213,12 @@
 		int		link_100 = 0;
 		int		gigabit = 0;
 #ifdef DEBUG_PHY
-		printk("Link state change, phy_status: 0x%04x\n", phy_status);
+		printk("%s: Link state change, phy_status: 0x%04x\n",
+			gm->dev->name, phy_status);
 #endif
 		gm->phy_status = phy_status;
 
+		/* Should we enable that in generic mode ? */
 		lpar_ability = mii_read(gm, gm->phy_addr, MII_ANLPA);
 		if (lpar_ability & MII_ANLPA_PAUS)
 			GM_BIS(GM_MAC_CTRL_CONFIG, GM_MAC_CTRL_CONF_SND_PAUSE_EN);
@@ -249,6 +253,9 @@
 #endif
 		    	full_duplex = ((stat2 & MII_LXT971_STATUS2_FULLDUPLEX) != 0);
 		    	link_100 = ((stat2 & MII_LXT971_STATUS2_SPEED) != 0);
+		    } else {
+		    	full_duplex = (lpar_ability & MII_ANLPA_FDAM) != 0;
+		    	link_100 = (lpar_ability & MII_ANLPA_100M) != 0;
 		    }
 #ifdef DEBUG_PHY
 		    printk("    full_duplex: %d, speed: %s\n", full_duplex,
@@ -274,6 +281,144 @@
 	}
 }
 
+/* Power management: stop PHY chip for suspend mode
+ */
+static void
+gmac_suspend(struct gmac* gm)
+{
+	int data, timeout;
+	unsigned long flags;
+	
+	gm->sleeping = 1;
+	netif_stop_queue(gm->dev);
+
+
+	spin_lock_irqsave(&gm->lock, flags);
+	if (gm->opened) {
+		disable_irq(gm->dev->irq);
+		/* Stop polling PHY */
+		mii_poll_stop(gm);
+	}
+	/* Mask out all chips interrupts */
+	GM_OUT(GM_IRQ_MASK, 0xffffffff);
+	spin_unlock_irqrestore(&gm->lock, flags);
+	
+	if (gm->opened) {
+		int i;
+		/* Empty Tx ring of any remaining gremlins */
+		gmac_tx_cleanup(gm->dev, 1);
+	
+		/* Empty Rx ring of any remaining gremlins */
+		for (i = 0; i < NRX; ++i) {
+			if (gm->rx_buff[i] != 0) {
+				dev_kfree_skb_irq(gm->rx_buff[i]);
+				gm->rx_buff[i] = 0;
+			}
+		}
+	}
+
+	/* Clear interrupts on 5201 */
+	if (gm->phy_type == PHY_B5201)
+		mii_write(gm, gm->phy_addr, MII_BCM5201_INTERRUPT, 0);
+		
+	/* Drive MDIO high */
+	GM_OUT(GM_MIF_CFG, 0);
+	
+	/* Unchanged, don't ask me why */
+	data = mii_read(gm, gm->phy_addr, MII_ANLPA);
+	mii_write(gm, gm->phy_addr, MII_ANLPA, data);
+	
+	/* Put MDIO in sane state */
+	GM_OUT(GM_MIF_CFG, GM_MIF_CFGBB);
+	GM_OUT(GM_MIF_BB_CLOCK, 0);
+	GM_OUT(GM_MIF_BB_DATA, 0);
+	GM_OUT(GM_MIF_BB_OUT_ENABLE, 0);
+	
+	/* Stop everything */
+	GM_OUT(GM_MAC_RX_CONFIG, 0);
+	GM_OUT(GM_MAC_TX_CONFIG, 0);
+	GM_OUT(GM_MAC_XIF_CONFIG, 0);
+	GM_OUT(GM_TX_CONF, 0);
+	GM_OUT(GM_RX_CONF, 0);
+	
+	/* Set reset state */
+	GM_OUT(GM_RESET, GM_RESET_TX | GM_RESET_RX);
+	for (timeout = 100; timeout > 0; --timeout) {
+		mdelay(10);
+		if ((GM_IN(GM_RESET) & (GM_RESET_TX | GM_RESET_RX)) == 0)
+			break;
+	}
+	GM_OUT(GM_MAC_TX_RESET, GM_MAC_TX_RESET_NOW);
+	GM_OUT(GM_MAC_RX_RESET, GM_MAC_RX_RESET_NOW);
+
+	/* Superisolate PHY */
+	if (gm->phy_type == PHY_B5201)
+		mii_write(gm, gm->phy_addr, MII_BCM5201_MULTIPHY,
+			MII_BCM5201_MULTIPHY_SUPERISOLATE);
+
+	/* Unclock chip */
+	gmac_set_power(gm, 0);
+}
+
+static void
+gmac_resume(struct gmac *gm)
+{
+	int data;
+
+	if (gmac_powerup_and_reset(gm->dev)) {
+		printk(KERN_ERR "%s: Couldn't revive gmac ethernet !\n", gm->dev->name);
+		return;
+	}
+
+	gm->sleeping = 0;
+	
+	if (gm->opened) {
+		/* Create fresh rings */
+		gmac_init_rings(gm, 1);
+		/* re-initialize the MAC */
+		gmac_mac_init(gm, gm->dev->dev_addr);	
+		/* re-initialize the multicast tables & promisc mode if any */
+		gmac_set_multicast(gm->dev);
+	}
+
+	/* Early enable Tx and Rx so that we are clocked */
+	GM_BIS(GM_TX_CONF, GM_TX_CONF_DMA_EN);
+	mdelay(20);
+	GM_BIS(GM_RX_CONF, GM_RX_CONF_DMA_EN);
+	mdelay(20);
+	GM_BIS(GM_MAC_TX_CONFIG, GM_MAC_TX_CONF_ENABLE);
+	mdelay(20);
+	GM_BIS(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_ENABLE);
+	mdelay(20);
+	if (gm->phy_type == PHY_B5201) {
+		data = mii_read(gm, gm->phy_addr, MII_BCM5201_MULTIPHY);
+		mii_write(gm, gm->phy_addr, MII_BCM5201_MULTIPHY,
+			data & ~MII_BCM5201_MULTIPHY_SUPERISOLATE);
+	}
+	mdelay(1);
+
+	if (gm->opened) {
+		/* restart polling PHY */
+		mii_interrupt(gm);
+		/* restart DMA operations */
+		gmac_start_dma(gm);
+		netif_start_queue(gm->dev);
+		enable_irq(gm->dev->irq);
+	} else {
+		/* Driver not opened, just leave things off. Note that
+		 * we could be smart and superisolate the PHY when the
+		 * driver is closed, but I won't do that unless I have
+		 * a better understanding of some electrical issues with
+		 * this PHY chip --BenH
+		 */
+		GM_OUT(GM_MAC_RX_CONFIG, 0);
+		GM_OUT(GM_MAC_TX_CONFIG, 0);
+		GM_OUT(GM_MAC_XIF_CONFIG, 0);
+		GM_OUT(GM_TX_CONF, 0);
+		GM_OUT(GM_RX_CONF, 0);
+	}
+}
+
 static int
 mii_do_reset_phy(struct gmac *gm, int phy_addr)
 {
@@ -326,6 +471,40 @@
 	mii_write(gm, gm->phy_addr, MII_BCM5400_AUXCONTROL, data);
 }
 
+static void
+mii_init_BCM5401(struct gmac *gm)
+{
+	int data;
+	int rev;
+
+	rev = mii_read(gm, gm->phy_addr, MII_ID1) & 0x000f;
+	if (rev == 0 || rev == 3) {
+		/* A bit of black magic from Apple */
+		mii_write(gm, gm->phy_addr, 0x18, 0x0c20);
+		mii_write(gm, gm->phy_addr, 0x17, 0x0012);
+		mii_write(gm, gm->phy_addr, 0x15, 0x1804);
+		mii_write(gm, gm->phy_addr, 0x17, 0x0013);
+		mii_write(gm, gm->phy_addr, 0x15, 0x1204);
+		mii_write(gm, gm->phy_addr, 0x17, 0x8006);
+		mii_write(gm, gm->phy_addr, 0x15, 0x0132);
+		mii_write(gm, gm->phy_addr, 0x17, 0x8006);
+		mii_write(gm, gm->phy_addr, 0x15, 0x0232);
+		mii_write(gm, gm->phy_addr, 0x17, 0x201f);
+		mii_write(gm, gm->phy_addr, 0x15, 0x0a20);
+	}
+	
+	data = mii_read(gm, gm->phy_addr, MII_BCM5400_GB_CONTROL);
+	data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
+	mii_write(gm, gm->phy_addr, MII_BCM5400_GB_CONTROL, data);
+
+	mdelay(10);
+	mii_do_reset_phy(gm, 0x1f);
+	
+	data = mii_read(gm, 0x1f, MII_BCM5201_MULTIPHY);
+	data |= MII_BCM5201_MULTIPHY_SERIALMODE;
+	mii_write(gm, 0x1f, MII_BCM5201_MULTIPHY, data);
+}
+
 static int
 mii_lookup_and_reset(struct gmac *gm)
 {
@@ -335,10 +514,7 @@
 	gm->phy_type = PHY_UNKNOWN;
 
 	/* Hard reset the PHY */
-	feature_set_gmac_phy_reset(gm->of_node, KL_GPIO_ETH_PHY_RESET_ASSERT);
-	mdelay(10);
-	feature_set_gmac_phy_reset(gm->of_node, KL_GPIO_ETH_PHY_RESET_RELEASE);
-	mdelay(10);
+	feature_gmac_phy_reset(gm->of_node);
 	
 	/* Find the PHY */
 	for(i=0; i<=31; i++) {
@@ -367,14 +543,22 @@
 		printk(KERN_ERR "%s Found Broadcom BCM5400 PHY (Gigabit)\n",
 			gm->dev->name);
 		mii_init_BCM5400(gm);		
+	} else if ((gm->phy_id & MII_BCM5401_MASK) == MII_BCM5401_ID) {
+		gm->phy_type = PHY_B5401;
+		printk(KERN_ERR "%s Found Broadcom BCM5401 PHY (Gigabit)\n",
+			gm->dev->name);
+		mii_init_BCM5401(gm);		
 	} else if ((gm->phy_id & MII_BCM5201_MASK) == MII_BCM5201_ID) {
 		gm->phy_type = PHY_B5201;
 		printk(KERN_INFO "%s Found Broadcom BCM5201 PHY\n", gm->dev->name);
+	} else if ((gm->phy_id & MII_BCM5221_MASK) == MII_BCM5221_ID) {
+		gm->phy_type = PHY_B5201; /* Same as 5201 for now */
+		printk(KERN_INFO "%s Found Broadcom BCM5221 PHY\n", gm->dev->name);
 	} else if ((gm->phy_id & MII_LXT971_MASK) == MII_LXT971_ID) {
 		gm->phy_type = PHY_LXT971;
 		printk(KERN_INFO "%s Found LevelOne LX971 PHY\n", gm->dev->name);
 	} else {
-		printk(KERN_ERR "%s: Warning ! Unknown PHY ID 0x%08x !\n",
+		printk(KERN_ERR "%s: Warning ! Unknown PHY ID 0x%08x, using generic mode...\n",
 			gm->dev->name, gm->phy_id);
 	}
 
@@ -448,8 +632,6 @@
 	    			PCI_CACHE_LINE_SIZE, 8);
 		}
 	} else {
-		/* FIXME: Add PHY power down */
-		gm->phy_type = 0;
 		feature_set_gmac_power(gm->of_node, 0);
 	}
 }
@@ -472,11 +654,14 @@
 		if ((GM_IN(GM_RESET) & (GM_RESET_TX | GM_RESET_RX)) == 0) {
 			/* Mask out all chips interrupts */
 			GM_OUT(GM_IRQ_MASK, 0xffffffff);
+			GM_OUT(GM_MAC_TX_RESET, GM_MAC_TX_RESET_NOW);
+			GM_OUT(GM_MAC_RX_RESET, GM_MAC_RX_RESET_NOW);
 			return 0;
 		}
 	}
 	printk(KERN_ERR "%s reset failed!\n", dev->name);
 	gmac_set_power(gm, 0);
+	gm->phy_type = 0;
 	return -1;
 }
 
@@ -747,7 +932,9 @@
 	int multicast_hash = 0;
 	int multicast_all = 0;
 	int promisc = 0;
-	
+
+	if (gm->sleeping)
+		return;
 
 	/* Lock out others. */
 	netif_stop_queue(dev);
@@ -881,6 +1068,7 @@
 	
 	/* Shut down chip */
 	gmac_set_power(gm, 0);
+	gm->phy_type = 0;
 
 	/* Empty rings of any remaining gremlins */
 	for (i = 0; i < NRX; ++i) {
@@ -904,7 +1092,6 @@
 gmac_sleep_notify(struct pmu_sleep_notifier *self, int when)
 {
 	struct gmac *gm;
-	int i;
 	
 	/* XXX should handle more than one */
 	if (gmacs == NULL)
@@ -920,38 +1107,10 @@
 	case PBOOK_SLEEP_REJECT:
 		break;
 	case PBOOK_SLEEP_NOW:
-		disable_irq(gm->dev->irq);
-		netif_stop_queue(gm->dev);
-		gmac_stop_dma(gm);
-		mii_poll_stop(gm);
-		gmac_set_power(gm, 0);
-		for (i = 0; i < NRX; ++i) {
-			if (gm->rx_buff[i] != 0) {
-				dev_kfree_skb(gm->rx_buff[i]);
-				gm->rx_buff[i] = 0;
-			}
-		}
-		for (i = 0; i < NTX; ++i) {
-			if (gm->tx_buff[i] != 0) {
-				dev_kfree_skb(gm->tx_buff[i]);
-				gm->tx_buff[i] = 0;
-			}
-		}
+		gmac_suspend(gm);
 		break;
 	case PBOOK_WAKE:
-		/* see if this is enough */
-		gmac_powerup_and_reset(gm->dev);
-		gm->full_duplex = 0;
-		gm->phy_status = 0;
-		mii_lookup_and_reset(gm);
-		mii_setup_phy(gm);
-		gmac_init_rings(gm, 0);
-		gmac_mac_init(gm, gm->dev->dev_addr);
-		gmac_set_multicast(gm->dev);
-		mii_interrupt(gm);
-		gmac_start_dma(gm);
-		netif_start_queue(gm->dev);
-		enable_irq(gm->dev->irq);
+		gmac_resume(gm);
 		break;
 	}
 	return PBOOK_SLEEP_OK;
@@ -967,7 +1126,10 @@
 	struct gmac *gm = (struct gmac *) dev->priv;
 	int i, timeout;
 	unsigned long flags;
-		
+
+	if (gm->sleeping)
+		return;
+
 	printk (KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
 
 	spin_lock_irqsave(&gm->lock, flags);
@@ -990,6 +1152,8 @@
 		if ((GM_IN(GM_RESET) & (GM_RESET_TX | GM_RESET_RX)) == 0) {
 			/* Mask out all chips interrupts */
 			GM_OUT(GM_IRQ_MASK, 0xffffffff);
+			GM_OUT(GM_MAC_TX_RESET, GM_MAC_TX_RESET_NOW);
+			GM_OUT(GM_MAC_RX_RESET, GM_MAC_RX_RESET_NOW);
 			break;
 		}
 	}
@@ -1022,6 +1186,9 @@
 	unsigned long flags;
 	int i;
 
+	if (gm->sleeping)
+		return 1;
+		
 	spin_lock_irqsave(&gm->lock, flags);
 
 	i = gm->next_tx;
@@ -1274,7 +1441,7 @@
 	struct gmac *gm = (struct gmac *) dev->priv;
 	struct net_device_stats *stats = &gm->stats;
 
-	if (gm && gm->opened) {
+	if (gm && gm->opened && !gm->sleeping) {
 		stats->rx_crc_errors += GM_IN(GM_MAC_RX_CRC_ERR_CTR);
 		GM_OUT(GM_MAC_RX_CRC_ERR_CTR, 0);
 
@@ -1315,10 +1482,14 @@
 	     gmac = gmac->next)
 		gmac_probe1(gmac);
 
+#ifdef CONFIG_PMAC_PBOOK
+	if (gmacs)
+		pmu_register_sleep_notifier(&gmac_sleep_notifier);
+#endif
 
 	MOD_DEC_USE_COUNT;
 
-	return 0;
+	return gmacs? 0: -ENODEV;
 }
 
 static void
@@ -1343,6 +1514,14 @@
 		return;
 	}
 
+	if (dummy_buf == NULL) {
+		dummy_buf = kmalloc(DUMMY_BUF_LEN, GFP_KERNEL);
+		if (dummy_buf == NULL) {
+			printk(KERN_ERR "GMAC: failed to allocated dummy buffer\n");
+			return;
+		}
+	}
+
 	tx_descpage = get_free_page(GFP_KERNEL);
 	if (tx_descpage == 0) {
 		printk(KERN_ERR "GMAC: can't get a page for tx descriptors\n");
@@ -1351,17 +1530,13 @@
 	rx_descpage = get_free_page(GFP_KERNEL);
 	if (rx_descpage == 0) {
 		printk(KERN_ERR "GMAC: can't get a page for rx descriptors\n");
-		free_page(tx_descpage);
-		return;
+		goto out_txdesc;
 	}
 
 	dev = init_etherdev(NULL, sizeof(struct gmac));
-
 	if (!dev) {
 		printk(KERN_ERR "GMAC: init_etherdev failed, out of memory\n");
-		free_page(tx_descpage);
-		free_page(rx_descpage);
-		return;
+		goto out_rxdesc;
 	}
 	SET_MODULE_OWNER(dev);
 
@@ -1369,6 +1544,10 @@
 	dev->base_addr = gmac->addrs[0].address;
 	gm->regs = (volatile unsigned int *)
 		ioremap(gmac->addrs[0].address, 0x10000);
+	if (!gm->regs) {
+		printk(KERN_ERR "GMAC: unable to map I/O registers\n");
+		goto out_unreg;
+	}
 	dev->irq = gmac->intrs[0].line;
 	gm->dev = dev;
 	gm->of_node = gmac;
@@ -1394,6 +1573,7 @@
 
 	gm->phy_addr = 0;
 	gm->opened = 0;
+	gm->sleeping = 0;
 
 	dev->open = gmac_open;
 	dev->stop = gmac_close;
@@ -1404,13 +1584,18 @@
 	dev->watchdog_timeo = 5*HZ;
 
 	ether_setup(dev);
-	
+
 	gm->next_gmac = gmacs;
 	gmacs = dev;
+	return;
 
-#ifdef CONFIG_PMAC_PBOOK
-	pmu_register_sleep_notifier(&gmac_sleep_notifier);
-#endif
+out_unreg:
+	unregister_netdev(dev);
+	kfree(dev);
+out_rxdesc:
+	free_page(rx_descpage);
+out_txdesc:
+	free_page(tx_descpage);
 }
 
 MODULE_AUTHOR("Paul Mackerras/Ben Herrenschmidt");
@@ -1421,16 +1606,25 @@
 	struct gmac *gm;
 	struct net_device *dev;
 
+#ifdef CONFIG_PMAC_PBOOK
+	if (gmacs)
+		pmu_unregister_sleep_notifier(&gmac_sleep_notifier);
+#endif
+
 	while ((dev = gmacs) != NULL) {
 		gm = (struct gmac *) dev->priv;
 		unregister_netdev(dev);
+		iounmap((void *) gm->regs);
 		free_page(gm->tx_desc_page);
 		free_page(gm->rx_desc_page);
 		gmacs = gm->next_gmac;
 		kfree(dev);
 	}
+	if (dummy_buf != NULL) {
+		kfree(dummy_buf);
+		dummy_buf = NULL;
+	}
 }
 
 module_init(gmac_probe);
 module_exit(gmac_cleanup_module);
-
diff -u --recursive --new-file v2.4.4/linux/drivers/net/gmac.h linux/drivers/net/gmac.h
--- v2.4.4/linux/drivers/net/gmac.h	Sun Sep 17 09:48:05 2000
+++ linux/drivers/net/gmac.h	Wed May 16 09:58:36 2001
@@ -722,6 +722,13 @@
 #define MII_ANLPA_CSMA 0x0001      /* CSMA-CD Capable */
 #define MII_ANLPA_PAUS 0x0400 
 
+/* Generic PHYs
+ * 
+ * These GENERIC values assumes that the PHY devices follow 802.3u and
+ * allow parallel detection to set the link partner ability register.
+ * Detection of 100Base-TX [H/F Duplex] and 100Base-T4 is supported.
+ */
+
 /*
  * Model-specific PHY registers
  *
@@ -731,6 +738,7 @@
 
 /* Supported PHYs (phy_type field ) */
 #define PHY_B5400	0x5400
+#define PHY_B5401	0x5401
 #define PHY_B5201	0x5201
 #define PHY_LXT971	0x0971
 #define PHY_UNKNOWN	0
@@ -741,11 +749,21 @@
 #define MII_BCM5201_REV                         0x01
 #define MII_BCM5201_ID                          ((MII_BCM5201_OUI << 10) | (MII_BCM5201_MODEL << 4))
 #define MII_BCM5201_MASK                        0xfffffff0
+#define MII_BCM5221_OUI                         0x001018
+#define MII_BCM5221_MODEL                       0x1e
+#define MII_BCM5221_REV                         0x00
+#define MII_BCM5221_ID                          ((MII_BCM5221_OUI << 10) | (MII_BCM5221_MODEL << 4))
+#define MII_BCM5221_MASK                        0xfffffff0
 #define MII_BCM5400_OUI                         0x000818
 #define MII_BCM5400_MODEL                       0x04
 #define MII_BCM5400_REV                         0x01
 #define MII_BCM5400_ID                          ((MII_BCM5400_OUI << 10) | (MII_BCM5400_MODEL << 4))
 #define MII_BCM5400_MASK                        0xfffffff0
+#define MII_BCM5401_OUI                         0x000818
+#define MII_BCM5401_MODEL                       0x05
+#define MII_BCM5401_REV                         0x01
+#define MII_BCM5401_ID                          ((MII_BCM5401_OUI << 10) | (MII_BCM5401_MODEL << 4))
+#define MII_BCM5401_MASK                        0xfffffff0
 #define MII_LXT971_OUI                          0x0004de
 #define MII_LXT971_MODEL                        0x0e
 #define MII_LXT971_REV                          0x00
@@ -791,7 +809,6 @@
 #define MII_LXT971_STATUS2_AUTONEG_COMPLETE	0x0080
 
 
-
 	/*
 	 * DMA descriptors
 	 */
@@ -877,6 +894,7 @@
 	u8				pci_devfn;
 	spinlock_t			lock;
 	int				opened;
+	int				sleeping;
 	struct net_device		*next_gmac;
 };
 
diff -u --recursive --new-file v2.4.4/linux/drivers/net/hamachi.c linux/drivers/net/hamachi.c
--- v2.4.4/linux/drivers/net/hamachi.c	Fri Apr 20 11:54:23 2001
+++ linux/drivers/net/hamachi.c	Sat May 19 18:02:45 2001
@@ -23,10 +23,21 @@
 	or
 	http://www.parl.clemson.edu/~keithu/hamachi.html
 
-	For best viewing, set your tabs to 3.
+
+
+	Linux kernel changelog:
+
+	LK1.0.1:
+	- fix lack of pci_dev<->dev association
+	- ethtool support (jgarzik)
 
 */
 
+#define DRV_NAME	"hamachi"
+#define DRV_VERSION	"1.01+LK1.0.1"
+#define DRV_RELDATE	"5/18/2001"
+
+
 /* A few user-configurable values. */
 
 static int debug = 1;		/* 1 normal messages, 0 quiet .. 7 verbose.  */
@@ -116,7 +127,7 @@
 #define RX_RING_SIZE	512
 
 /*
- * Enable mii_ioctl.  Added interrupt coalescing parameter adjustment.
+ * Enable netdev_ioctl.  Added interrupt coalescing parameter adjustment.
  * 2/19/99 Pete Wyckoff <wyckoff@ca.sandia.gov>
  */
 
@@ -152,7 +163,9 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
+#include <linux/ethtool.h>
 
+#include <asm/uaccess.h>
 #include <asm/processor.h>	/* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
@@ -166,7 +179,7 @@
 #include <linux/delay.h>
 
 static char version[] __initdata =
-KERN_INFO "hamachi.c:v1.01 5/16/2000  Written by Donald Becker\n"
+KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "  Written by Donald Becker\n"
 KERN_INFO "   Some modifications by Eric kasten <kasten@nscl.msu.edu>\n"
 KERN_INFO "   Further modifications by Keith Underwood <keithu@parl.clemson.edu>\n";
 
@@ -502,7 +515,7 @@
 	unsigned char phys[MII_CNT];		/* MII device addresses, only first one used. */
 	u_int32_t rx_int_var, tx_int_var;	/* interrupt control variables */
 	u_int32_t option;							/* Hold on to a copy of the options */
-	u_int8_t pad[16];							/* Used for 32-byte alignment */
+	struct pci_dev *pci_dev;
 };
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>, Eric Kasten <kasten@nscl.msu.edu>, Keith Underwood <keithu@parl.clemson.edu>");
@@ -527,7 +540,7 @@
 static int mdio_read(long ioaddr, int phy_id, int location);
 static void mdio_write(long ioaddr, int phy_id, int location, int value);
 static int hamachi_open(struct net_device *dev);
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void hamachi_timer(unsigned long data);
 static void hamachi_tx_timeout(struct net_device *dev);
 static void hamachi_init_ring(struct net_device *dev);
@@ -569,7 +582,7 @@
 
 	pci_set_master(pdev);
 
-	i = pci_request_regions(pdev, "hamachi");
+	i = pci_request_regions(pdev, DRV_NAME);
 	if (i) return i;
 
 	irq = pdev->irq;
@@ -633,8 +646,10 @@
 
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
+	pci_set_drvdata(pdev, dev);
 
 	hmp->chip_id = chip_id;
+	hmp->pci_dev = pdev;
 
 	/* The lower four bits are the media type. */
 	if (option > 0) {
@@ -676,7 +691,7 @@
 	dev->stop = &hamachi_close;
 	dev->get_stats = &hamachi_get_stats;
 	dev->set_multicast_list = &set_rx_mode;
-	dev->do_ioctl = &mii_ioctl;
+	dev->do_ioctl = &netdev_ioctl;
 	dev->tx_timeout = &hamachi_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 	if (mtu)
@@ -687,6 +702,7 @@
 		kfree(dev);
 		iounmap((char *)ioaddr);
 		pci_release_regions(pdev);
+		pci_set_drvdata(pdev, NULL);
 		return i;
 	}
 
@@ -1815,12 +1831,38 @@
 	}
 }
 
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+{
+	struct hamachi_private *np = dev->priv;
+	u32 ethcmd;
+		
+	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+		return -EFAULT;
+
+        switch (ethcmd) {
+        case ETHTOOL_GDRVINFO: {
+		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
+		strcpy(info.driver, DRV_NAME);
+		strcpy(info.version, DRV_VERSION);
+		strcpy(info.bus_info, np->pci_dev->slot_name);
+		if (copy_to_user(useraddr, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+
+        }
+	
+	return -EOPNOTSUPP;
+}
+
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	long ioaddr = dev->base_addr;
 	u16 *data = (u16 *)&rq->ifr_data;
 
 	switch(cmd) {
+	case SIOCETHTOOL:
+		return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
 	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
 		data[0] = ((struct hamachi_private *)dev->priv)->phys[0] & 0x1f;
 		/* Fall Through */
@@ -1878,7 +1920,7 @@
 MODULE_DEVICE_TABLE(pci, hamachi_pci_tbl);
 
 static struct pci_driver hamachi_driver = {
-	name:		"hamachi",
+	name:		DRV_NAME,
 	id_table:	hamachi_pci_tbl,
 	probe:		hamachi_init_one,
 	remove:		hamachi_remove_one,
diff -u --recursive --new-file v2.4.4/linux/drivers/net/hp100.h linux/drivers/net/hp100.h
--- v2.4.4/linux/drivers/net/hp100.h	Wed May 20 18:55:04 1998
+++ linux/drivers/net/hp100.h	Wed May 16 10:25:38 2001
@@ -38,10 +38,10 @@
 #define HP100_REG_HW_ID		0x00	/* R:  (16) Unique card ID           */
 #define HP100_REG_TRACE		0x00	/* W:  (16) Used for debug output    */
 #define HP100_REG_PAGING	0x02	/* R:  (16),15:4 Card ID             */
-                                        /* W:  (16),3:0 Switch pages         */
+					/* W:  (16),3:0 Switch pages         */
 #define HP100_REG_OPTION_LSW	0x04	/* RW: (16) Select card functions    */
 #define HP100_REG_OPTION_MSW	0x06	/* RW: (16) Select card functions    */
-                                        
+
 /*  Page 0 - Performance  */
 
 #define HP100_REG_IRQ_STATUS	0x08	/* RW: (16) Which ints are pending   */
@@ -53,27 +53,27 @@
 #define HP100_REG_DATA32	0x10	/* RW: (32) I/O mode data port       */
 #define HP100_REG_DATA16	0x12	/* RW: WORDs must be read from here  */
 #define HP100_REG_TX_MEM_FREE	0x14	/* RD: (32) Amount of free Tx mem    */
-#define HP100_REG_TX_PDA_L      0x14    /* W: (32) BM: Ptr to PDL, Low Pri  */
-#define HP100_REG_TX_PDA_H      0x1c    /* W: (32) BM: Ptr to PDL, High Pri */
+#define HP100_REG_TX_PDA_L      0x14	/* W: (32) BM: Ptr to PDL, Low Pri  */
+#define HP100_REG_TX_PDA_H      0x1c	/* W: (32) BM: Ptr to PDL, High Pri */
 #define HP100_REG_RX_PKT_CNT	0x18	/* RD: (8) Rx count of pkts on card  */
 #define HP100_REG_TX_PKT_CNT	0x19	/* RD: (8) Tx count of pkts on card  */
-#define HP100_REG_RX_PDL        0x1a    /* R: (8) BM: # rx pdl not executed */
-#define HP100_REG_TX_PDL        0x1b    /* R: (8) BM: # tx pdl not executed */
-#define HP100_REG_RX_PDA        0x18    /* W: (32) BM: Up to 31 addresses */
-                                        /*             which point to a PDL */
-#define HP100_REG_SL_EARLY      0x1c    /*    (32) Enhanced Slave Early Rx */
-#define HP100_REG_STAT_DROPPED  0x20    /* R (12) Dropped Packet Counter */
-#define HP100_REG_STAT_ERRORED  0x22    /* R (8) Errored Packet Counter */
-#define HP100_REG_STAT_ABORT    0x23    /* R (8) Abort Counter/OW Coll. Flag */
-#define HP100_REG_RX_RING       0x24    /* W (32) Slave: RX Ring Pointers */
-#define HP100_REG_32_FRAGMENT_LEN 0x28  /* W (13) Slave: Fragment Length Reg */
-#define HP100_REG_32_OFFSET     0x2c    /* W (16) Slave: Offset Register */
+#define HP100_REG_RX_PDL        0x1a	/* R: (8) BM: # rx pdl not executed */
+#define HP100_REG_TX_PDL        0x1b	/* R: (8) BM: # tx pdl not executed */
+#define HP100_REG_RX_PDA        0x18	/* W: (32) BM: Up to 31 addresses */
+					/*             which point to a PDL */
+#define HP100_REG_SL_EARLY      0x1c	/*    (32) Enhanced Slave Early Rx */
+#define HP100_REG_STAT_DROPPED  0x20	/* R (12) Dropped Packet Counter */
+#define HP100_REG_STAT_ERRORED  0x22	/* R (8) Errored Packet Counter */
+#define HP100_REG_STAT_ABORT    0x23	/* R (8) Abort Counter/OW Coll. Flag */
+#define HP100_REG_RX_RING       0x24	/* W (32) Slave: RX Ring Pointers */
+#define HP100_REG_32_FRAGMENT_LEN 0x28	/* W (13) Slave: Fragment Length Reg */
+#define HP100_REG_32_OFFSET     0x2c	/* W (16) Slave: Offset Register */
 
 /*  Page 1 - MAC Address/Hash Table  */
 
-#define HP100_REG_MAC_ADDR	0x08	/* RW: (8) Cards MAC address	     */
+#define HP100_REG_MAC_ADDR	0x08	/* RW: (8) Cards MAC address         */
 #define HP100_REG_HASH_BYTE0	0x10	/* RW: (8) Cards multicast filter    */
-                                        
+
 /*  Page 2 - Hardware Mapping  */
 
 #define HP100_REG_MEM_MAP_LSW	0x08	/* RW: (16) LSW of cards mem addr    */
@@ -84,44 +84,44 @@
 #define HP100_REG_BM		0x0f	/* RW: (8) Controls BM functions     */
 
 /* New on Page 2 for ETR chips: */
-#define HP100_REG_MODECTRL1     0x10    /* RW: (8) Mode Control 1 */
-#define HP100_REG_MODECTRL2     0x11    /* RW: (8) Mode Control 2 */
-#define HP100_REG_PCICTRL1      0x12    /* RW: (8) PCI Cfg 1 */
-#define HP100_REG_PCICTRL2      0x13    /* RW: (8) PCI Cfg 2 */
-#define HP100_REG_PCIBUSMLAT    0x15    /* RW: (8) PCI Bus Master Latency */
-#define HP100_REG_EARLYTXCFG    0x16    /* RW: (16) Early TX Cfg/Cntrl Reg */
-#define HP100_REG_EARLYRXCFG    0x18    /* RW: (8) Early RX Cfg/Cntrl Reg */
-#define HP100_REG_ISAPNPCFG1    0x1a    /* RW: (8) ISA PnP Cfg/Cntrl Reg 1 */
-#define HP100_REG_ISAPNPCFG2    0x1b    /* RW: (8) ISA PnP Cfg/Cntrl Reg 2 */
-                                        
+#define HP100_REG_MODECTRL1     0x10	/* RW: (8) Mode Control 1 */
+#define HP100_REG_MODECTRL2     0x11	/* RW: (8) Mode Control 2 */
+#define HP100_REG_PCICTRL1      0x12	/* RW: (8) PCI Cfg 1 */
+#define HP100_REG_PCICTRL2      0x13	/* RW: (8) PCI Cfg 2 */
+#define HP100_REG_PCIBUSMLAT    0x15	/* RW: (8) PCI Bus Master Latency */
+#define HP100_REG_EARLYTXCFG    0x16	/* RW: (16) Early TX Cfg/Cntrl Reg */
+#define HP100_REG_EARLYRXCFG    0x18	/* RW: (8) Early RX Cfg/Cntrl Reg */
+#define HP100_REG_ISAPNPCFG1    0x1a	/* RW: (8) ISA PnP Cfg/Cntrl Reg 1 */
+#define HP100_REG_ISAPNPCFG2    0x1b	/* RW: (8) ISA PnP Cfg/Cntrl Reg 2 */
+
 /*  Page 3 - EEPROM/Boot ROM  */
 
 #define HP100_REG_EEPROM_CTRL	0x08	/* RW: (16) Used to load EEPROM      */
 #define HP100_REG_BOOTROM_CTRL  0x0a
-                                        
+
 /*  Page 4 - LAN Configuration  (MAC_CTRL) */
 
 #define HP100_REG_10_LAN_CFG_1	0x08	/* RW: (8) Set 10M XCVR functions   */
-#define HP100_REG_10_LAN_CFG_2  0x09    /* RW: (8)     10M XCVR functions   */
+#define HP100_REG_10_LAN_CFG_2  0x09	/* RW: (8)     10M XCVR functions   */
 #define HP100_REG_VG_LAN_CFG_1	0x0a	/* RW: (8) Set 100M XCVR functions  */
-#define HP100_REG_VG_LAN_CFG_2  0x0b    /* RW: (8) 100M LAN Training cfgregs */
+#define HP100_REG_VG_LAN_CFG_2  0x0b	/* RW: (8) 100M LAN Training cfgregs */
 #define HP100_REG_MAC_CFG_1	0x0c	/* RW: (8) Types of pkts to accept   */
 #define HP100_REG_MAC_CFG_2	0x0d	/* RW: (8) Misc MAC functions        */
-#define HP100_REG_MAC_CFG_3     0x0e    /* RW: (8) Misc MAC functions */
-#define HP100_REG_MAC_CFG_4     0x0f    /* R:  (8) Misc MAC states */
-#define HP100_REG_DROPPED	0x10	/* R:  (16),11:0 Pkts cant fit in mem*/
+#define HP100_REG_MAC_CFG_3     0x0e	/* RW: (8) Misc MAC functions */
+#define HP100_REG_MAC_CFG_4     0x0f	/* R:  (8) Misc MAC states */
+#define HP100_REG_DROPPED	0x10	/* R:  (16),11:0 Pkts cant fit in mem */
 #define HP100_REG_CRC		0x12	/* R:  (8) Pkts with CRC             */
 #define HP100_REG_ABORT		0x13	/* R:  (8) Aborted Tx pkts           */
-#define HP100_REG_TRAIN_REQUEST 0x14    /* RW: (16) Endnode MAC register.*/
-#define HP100_REG_TRAIN_ALLOW   0x16    /* R:  (16) Hub allowed register */
-                    
+#define HP100_REG_TRAIN_REQUEST 0x14	/* RW: (16) Endnode MAC register. */
+#define HP100_REG_TRAIN_ALLOW   0x16	/* R:  (16) Hub allowed register */
+
 /*  Page 5 - MMU  */
 
 #define HP100_REG_RX_MEM_STOP	0x0c	/* RW: (16) End of Rx ring addr      */
 #define HP100_REG_TX_MEM_STOP	0x0e	/* RW: (16) End of Tx ring addr      */
-#define HP100_REG_PDL_MEM_STOP  0x10    /* Not used by 802.12 devices */
-#define HP100_REG_ECB_MEM_STOP  0x14    /* I've no idea what this is */
-          
+#define HP100_REG_PDL_MEM_STOP  0x10	/* Not used by 802.12 devices */
+#define HP100_REG_ECB_MEM_STOP  0x14	/* I've no idea what this is */
+
 /*  Page 6 - Card ID/Physical LAN Address  */
 
 #define HP100_REG_BOARD_ID	0x08	/* R:  (8) EISA/ISA card ID          */
@@ -129,7 +129,7 @@
 #define HP100_REG_SOFT_MODEL	0x0d	/* R:  (8) Config program defined    */
 #define HP100_REG_LAN_ADDR	0x10	/* R:  (8) MAC addr of card          */
 #define HP100_REG_LAN_ADDR_CHCK 0x16	/* R:  (8) Added to addr to get FFh  */
-                                        
+
 /*  Page 7 - MMU Current Pointers  */
 
 #define HP100_REG_PTR_RXSTART	0x08	/* R:  (16) Current begin of Rx ring */
@@ -146,7 +146,7 @@
 /* 
  * Hardware ID Register I (Always available, HW_ID, Offset 0x00)
  */
-#define HP100_HW_ID_CASCADE     0x4850  /* Identifies Cascade Chip */
+#define HP100_HW_ID_CASCADE     0x4850	/* Identifies Cascade Chip */
 
 /* 
  * Hardware ID Register 2 & Paging Register
@@ -154,12 +154,12 @@
  * Bits 15:4 are for the Chip ID 
  */
 #define HP100_CHIPID_MASK        0xFFF0
-#define HP100_CHIPID_SHASTA      0address sdres  0x16    /* T:- (16) Hrb allowed 0	Maintaac (jgarzialloddress
D_SHASTA )     0
 #tefine DM916{
-		/*a what (16) Oddress
D_SHASTA )     0
 #tcatðƒ…êwn0
 /1ialloddre/*a wnp->t