diff -u --recursive --new-file v2.3.29/linux/CREDITS linux/CREDITS
--- v2.3.29/linux/CREDITS	Thu Nov 18 20:25:37 1999
+++ linux/CREDITS	Fri Dec  3 10:55:09 1999
@@ -156,12 +156,9 @@
 S: USA
 
 N: James Banks
-E: james.banks@caldera.com
+E: james@sovereign.org
 D: TLAN network driver
-S: Caldera, Inc.
-S: 633 South 550 East
-S: Provo, Utah 84606
-S: USA
+D: Logitech Busmouse driver
 
 N: Krzysztof G. Baranowski
 E: kgb@manjak.knm.org.pl
@@ -439,11 +436,11 @@
 D: Initial Mac68K port
 D: Video4Linux design, bw-qcam and PMS driver ports.
 D: 2.1.x modular sound
-S: c/o I2IT Limited
-S: The Innovation Centre
-S: Singleton Park
-S: Swansea, SA2 8PP
-S: Wales, United Kingdom
+S: c/o Red Hat UK Ltd
+S: Alexandra House
+S: Alexandra Terrace
+S: Guildford, GU1 3DA
+S: United Kingdom
 
 N: Laurence Culhane
 E: loz@holmes.demon.co.uk
@@ -1468,8 +1465,10 @@
 S: Australia
 
 N: Pauline Middelink
-E: middelin@polyware.iaf.nl
+E: middelin@polyware.nl
 D: General low-level bug fixes, /proc fixes, identd support
+D: Author of IP masquerading
+D: Zoran ZR36120 Video For Linux driver
 S: Boterkorfhoek 34
 S: 7546 JA  Enschede
 S: Netherlands
diff -u --recursive --new-file v2.3.29/linux/Documentation/00-INDEX linux/Documentation/00-INDEX
--- v2.3.29/linux/Documentation/00-INDEX	Tue Nov 23 22:42:20 1999
+++ linux/Documentation/00-INDEX	Sat Nov 27 15:27:48 1999
@@ -69,12 +69,12 @@
 	- directory with info on the Linux ISDN support, and supported cards.
 java.txt
 	- info on the in-kernel binary support for Java(tm)
-joystick.txt
-	- info on using joystick devices (and driver) with Linux.
 joystick-api.txt
 	- API specification for applications that will be using the joystick.
 joystick-parport.txt 
 	- info on how to hook joysticks/gamepads to the parallel port.
+joystick.txt
+	- info on using joystick devices (and driver) with Linux.
 kbuild/
 	- directory with info about the kernel build process
 kernel-docs.txt
@@ -127,8 +127,6 @@
 	- info and sample code for using with the PC Watchdog reset card.
 powerpc/
 	- directory with info on using Linux with the PowerPC.
-proc.txt
-	- detailed info on Linux's /proc filesystem.
 proc_usb_info.txt
 	- info on /proc/bus/usb direcory generated for USB devices
 ramdisk.txt
@@ -177,5 +175,4 @@
 	- how to auto-reboot Linux if it has "fallen and can't get up". ;-)
 xterm-linux.xpm
 	- XPM image of penguin logo (see logo.txt) sitting on an xterm.
-
 
diff -u --recursive --new-file v2.3.29/linux/Documentation/BUG-HUNTING linux/Documentation/BUG-HUNTING
--- v2.3.29/linux/Documentation/BUG-HUNTING	Thu Apr 11 23:49:28 1996
+++ linux/Documentation/BUG-HUNTING	Sat Nov 27 15:46:24 1999
@@ -85,8 +85,8 @@
 If you get it down to a routine, you'll probably get a fix in 24 hours.
 
 My apologies to Linus and the other kernel hackers for describing this
-brute force approach, it's hardly what a kernel hack would do.  However,
-it does work and it lets non-hackers help bug fix.  And it is cool
+brute force approach, it's hardly what a kernel hacker would do.  However,
+it does work and it lets non-hackers help fix bugs.  And it is cool
 because Linux snapshots will let you do this - something that you can't
-do with vender supplied releases.
+do with vendor supplied releases.
 
diff -u --recursive --new-file v2.3.29/linux/Documentation/Changes linux/Documentation/Changes
--- v2.3.29/linux/Documentation/Changes	Tue Nov 23 22:42:20 1999
+++ linux/Documentation/Changes	Sat Nov 27 15:46:24 1999
@@ -43,7 +43,7 @@
 encountered a bug!  If you're unsure what version you're currently
 running, the suggested command should tell you.
 
-- Kernel modutils	 2.3.6                   ; insmod -V
+- Kernel modutils	 2.3.7                   ; insmod -V
 - Gnu C 		 2.7.2.3                 ; gcc --version
 - Binutils		 2.9.1.0.7               ; ld -v
 - Linux libc5 C Library	 5.4.46                  ; ls -l /lib/libc*
@@ -576,8 +576,8 @@
 Modules utilities
 =================
 
-The 2.3.6 release:
-ftp://ftp.ocs.com.au/pub/modutils/v2.3/modutils-2.3.6.tar.gz
+The 2.3.7 release:
+ftp://ftp.ocs.com.au/pub/modutils/v2.3/modutils-2.3.7.tar.gz
 
 Procps utilities
 ================
diff -u --recursive --new-file v2.3.29/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.3.29/linux/Documentation/Configure.help	Tue Nov 23 22:42:20 1999
+++ linux/Documentation/Configure.help	Sat Nov 27 15:27:48 1999
@@ -12447,6 +12447,18 @@
   whenever you want). If you want to compile it as a module, say M
   here and read Documentation/modules.txt.
 
+ZR36120/36125 Video for Linux
+CONFIG_VIDEO_ZR36120
+  Support for ZR36120/ZR36125 based frame grabber/overlay boards.
+  This includes the Victor II, WaveWatcher, Video Wonder, Maxi-TV,
+  and Buster boards. Please read the material in
+  Documentation/video4linux/zr36120.txt for more information.
+
+  This driver is also available as a module called zr36120.o ( = code
+  which can be inserted in and removed from the running kernel
+  whenever you want). If you want to compile it as a module, say M
+  here and read Documentation/modules.txt.
+
 SAA5249 Teletext processor
 CONFIG_VIDEO_SAA5249
   Support for I2C bus based teletext using the SAA5249 chip. At the
diff -u --recursive --new-file v2.3.29/linux/Documentation/filesystems/00-INDEX linux/Documentation/filesystems/00-INDEX
--- v2.3.29/linux/Documentation/filesystems/00-INDEX	Mon Nov  1 13:56:26 1999
+++ linux/Documentation/filesystems/00-INDEX	Sat Nov 27 15:27:48 1999
@@ -18,6 +18,8 @@
 	- info on Novell Netware(tm) filesystem using NCP protocol.
 ntfs.txt
 	- info and mount options for the NTFS filesystem (Windows NT).
+proc.txt
+	- info on Linux's /proc filesystem.
 romfs.txt
 	- Description of the ROMFS filesystem.
 smbfs.txt
diff -u --recursive --new-file v2.3.29/linux/Documentation/filesystems/vfs.txt linux/Documentation/filesystems/vfs.txt
--- v2.3.29/linux/Documentation/filesystems/vfs.txt	Tue Apr 27 09:24:34 1999
+++ linux/Documentation/filesystems/vfs.txt	Fri Dec  3 10:55:09 1999
@@ -4,7 +4,7 @@
 
 		Richard Gooch <rgooch@atnf.csiro.au>
 
-			      23-APR-1999
+			      5-JUL-1999
 
 
 Conventions used in this document                                     <section>
@@ -41,10 +41,11 @@
 Opening a File                                                     <subsection>
 --------------
 
-The VFS implements the open(2) system call. The pathname argument is
-used by the VFS to search through the directory entry cache (dentry
-cache or "dcache"). This provides a very fast lookup mechanism to
-translate a pathname (filename) into a specific dentry.
+The VFS implements the open(2), stat(2), chmod(2) and similar system
+calls. The pathname argument is used by the VFS to search through the
+directory entry cache (dentry cache or "dcache"). This provides a very
+fast lookup mechanism to translate a pathname (filename) into a
+specific dentry.
 
 An individual dentry usually has a pointer to an inode. Inodes are the
 things that live on disc drives, and can be regular files (you know:
@@ -53,7 +54,8 @@
 only for performance. Inodes live on disc and are copied into memory
 when required. Later any changes are written back to disc. The inode
 that lives in RAM is a VFS inode, and it is this which the dentry
-points to.
+points to. A single inode can be pointed to by multiple dentries
+(think about hardlinks).
 
 The dcache is meant to be a view into your entire filespace. Unlike
 Linus, most of us losers can't fit enough dentries into RAM to cover
@@ -76,10 +78,10 @@
 Opening a file requires another operation: allocation of a file
 structure (this is the kernel-side implementation of file
 descriptors). The freshly allocated file structure is initialised with
-a pointer to the dentry and a set of file operation member
-functions. These are taken from the inode data. The open() file method
-is then called so the specific filesystem implementation can do it's
-work. You can see that this is another switch performed by the VFS.
+a pointer to the dentry and a set of file operation member functions.
+These are taken from the inode data. The open() file method is then
+called so the specific filesystem implementation can do it's work. You
+can see that this is another switch performed by the VFS.
 
 The file structure is placed into the file descriptor table for the
 process.
@@ -92,6 +94,14 @@
 For as long as the file is open, it keeps the dentry "open" (in use),
 which in turn means that the VFS inode is still in use.
 
+All VFS system calls (i.e. open(2), stat(2), read(2), write(2),
+chmod(2) and so on) are called from a process context. You should
+assume that these calls are made without any kernel locks being
+held. This means that the processes may be executing the same piece of
+filesystem or driver code at the same time, on different
+processors. You should ensure that access to shared resources is
+protected by appropriate locks.
+
 Registering and Mounting a Filesystem                              <subsection>
 -------------------------------------
 
@@ -249,8 +259,11 @@
 	int (*revalidate) (struct dentry *);
 };
 
+Again, all methods are called without any locks being held, unless
+otherwise noted.
+
   default_file_ops: this is a pointer to a "struct file_operations"
-	which describes how to manipulate open files
+	which describes how to open and then manipulate open files
 
   create: called by the open(2) and creat(2) system calls. Only
 	required if you want to support regular files. The dentry you
@@ -270,7 +283,7 @@
 	If you wish to overload the dentry methods then you should
 	initialise the "d_dop" field in the dentry; this is a pointer
 	to a struct "dentry_operations".
-	This method is called with the directory semaphore held
+	This method is called with the directory inode semaphore held
 
   link: called by the link(2) system call. Only required if you want
 	to support hard links. You will probably need to call
@@ -327,17 +340,20 @@
 	int (*lock) (struct file *, int, struct file_lock *);
 };
 
+Again, all methods are called without any locks being held, unless
+otherwise noted.
+
   llseek: called when the VFS needs to move the file position index
 
-  read: called by the read(2) system call
+  read: called by read(2) and related system calls
 
-  write: called by the write(2) system call
+  write: called by write(2) and related system calls
 
   readdir: called when the VFS needs to read the directory contents
 
   poll: called by the VFS when a process wants to check if there is
 	activity on this file and (optionally) go to sleep until there
-	is activity
+	is activity. Called by the select(2) and poll(2) system calls
 
   ioctl: called by the ioctl(2) system call
 
@@ -380,7 +396,9 @@
 This describes how a filesystem can overload the standard dentry
 operations. Dentries and the dcache are the domain of the VFS and the
 individual filesystem implementations. Device drivers have no business
-here. As of kernel 2.1.99, the following members are defined:
+here. These methods may be set to NULL, as they are either optional or
+the VFS uses a default. As of kernel 2.1.99, the following members are
+defined:
 
 struct dentry_operations {
 	int (*d_revalidate)(struct dentry *);
@@ -391,7 +409,10 @@
 	void (*d_iput)(struct dentry *, struct inode *);
 };
 
-  d_revalidate: called when the VFS needs to revalidate a dentry
+  d_revalidate: called when the VFS needs to revalidate a dentry. This
+	is called whenever a name lookup finds a dentry in the
+	dcache. Most filesystems leave this as NULL, because all their
+	dentries in the dcache are valid
 
   d_hash: called when the VFS adds a dentry to the hash table
 
@@ -401,7 +422,7 @@
 	deleted. This means no-one is using the dentry, however it is
 	still valid and in the dcache
 
-  d_release: called when a dentry is deallocated
+  d_release: called when a dentry is really deallocated
 
   d_iput: called when a dentry looses its inode (just prior to its
 	being deallocated). The default when this is NULL is that the
diff -u --recursive --new-file v2.3.29/linux/Documentation/networking/00-INDEX linux/Documentation/networking/00-INDEX
--- v2.3.29/linux/Documentation/networking/00-INDEX	Thu Aug  5 14:34:01 1999
+++ linux/Documentation/networking/00-INDEX	Sat Nov 27 15:27:48 1999
@@ -58,8 +58,6 @@
 	- info and "insmod" parameters for all network driver modules.
 policy-routing.txt
 	- IP policy-based routing
-ppp.txt
-	- info on what software you should use to run PPP.
 pt.txt
 	- the Gracilis Packetwin AX.25 device driver
 routing.txt
diff -u --recursive --new-file v2.3.29/linux/Documentation/networking/tlan.txt linux/Documentation/networking/tlan.txt
--- v2.3.29/linux/Documentation/networking/tlan.txt	Fri Jul 24 11:15:05 1998
+++ linux/Documentation/networking/tlan.txt	Fri Dec  3 10:55:09 1999
@@ -1,15 +1,26 @@
-TLAN driver for Linux, version 1.0
-README
 
-Well, I'm back.  The TLAN driver seems pretty stable, so I'm
-declaring this cycle of development finished, and calling the
-driver 1.0.  I will, of course continue to work on improving
-the driver, and work towards a 2.0 release.
 
+I haven't had any time to do anything for a long time, and this isn't
+likely to change.  So there's a driver here for anyone looking to
+carry forward a project :)
+
+For those who are looking for help, I can't.  I haven't looked at
+a kernel since the early 2.0 series, so I won't know what's going on.
+Your best chance at help would be joining the TLAN mailing list and
+posting your question there.
+
+You can join by sending "subscribe tlan" in the body of an email to
+majordomo@vuser.vu.union.edu.
+
+Thanks to those who have (and who will ;) put work in to keep the TLAN
+driver working as the kernel moves on.
 
 James
 james@sovereign.org
 
+
+TLAN driver for Linux, version 1.0
+README
 
 
 I.  Supported Devices.
diff -u --recursive --new-file v2.3.29/linux/Documentation/pci.txt linux/Documentation/pci.txt
--- v2.3.29/linux/Documentation/pci.txt	Sun Nov  7 16:37:33 1999
+++ linux/Documentation/pci.txt	Sat Nov 27 15:27:48 1999
@@ -4,7 +4,7 @@
 
 		"What should you avoid when writing PCI drivers"
 
-	  by Martin Mares <mj@atrey.karlin.mff.cuni.cz> on 03-Nov-1999
+		  by Martin Mares <mj@suse.cz> on 21-Nov-1999
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -74,6 +74,12 @@
 have been remapped by the kernel.
 
    See Documentation/IO-mapping.txt for how to access device memory.
+
+   You still need to call request_region() for I/O regions and request_mem_region()
+for memory regions to make sure nobody else is using the same device.
+
+   All interrupt handlers should be registered with SA_SHIRQ and use the devid
+to map IRQs to devices (remember that all PCI interrupts are shared).
 
 5. Other interesting functions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff -u --recursive --new-file v2.3.29/linux/Documentation/sound/CMI8338 linux/Documentation/sound/CMI8338
--- v2.3.29/linux/Documentation/sound/CMI8338	Wed May 26 09:36:36 1999
+++ linux/Documentation/sound/CMI8338	Sat Nov 27 15:27:48 1999
@@ -1,5 +1,22 @@
 Audio driver for CM8338/CM8738 chips by Chen-Li Tien
 
+
+HARDWARE SUPPORTED
+================================================================================
+C-Media CMI8338
+C-Media CMI8738
+On-board C-Media chips
+
+
+WHAT'S NEW
+================================================================================
+
+  1. Support modem interface for 8738. (select in kernel configuration)
+  2. Enable S/PDIF-in to S/PDIF-out (S/PDIF loop).
+  3. Enable 4 channels analog duplicate mode on 3 jack or 4 jack
+     configurateion.
+
+
    Be aware: C-Media Electronics Inc. is basically an IC design house,
    and whose development of software drivers is mainly for use by its OEM
    customers in their products. C-Media Electronics Inc. itself does not
@@ -27,6 +44,23 @@
 7. To install the driver, enter 'modprobe cmpci'.
 
 
-Bugs:
+DRIVER PARAMETERS
+================================================================================
+
+  Some functions for the cm8738 can be configured in Kernel Configuration
+  or modules parameters. Set these parameters to 1 to enable.
 
-1. Real player cannot be run (the same as es1371).
+  spdif_loop:   Enable S/PDIF loop, this route S/PDIF-in to S/PDIF-out
+                directly.
+  four_ch:      Enable 4 channels mode, rear-out or line-in will output
+                the same as line-out.
+  rear_out:     Enable this if you have independent rear-out jacket on
+                your sound card, otherwise line-in will be used as
+                rear-out.
+  modem:	You will need to set this parameter if you want to use
+		the HSP modem. You need install the pctel.o, the modem
+		driver itself.
+
+  (You will need to get the pctel driver (binary only) and the support for
+  this option from the CMI site. It is not included in the Linux kernel 
+  proper as it is non-free).
diff -u --recursive --new-file v2.3.29/linux/Documentation/video4linux/zr36120.txt linux/Documentation/video4linux/zr36120.txt
--- v2.3.29/linux/Documentation/video4linux/zr36120.txt	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/video4linux/zr36120.txt	Sat Nov 27 15:27:48 1999
@@ -0,0 +1,159 @@
+Driver for Trust Computer Products Framegrabber, version 0.6.1
+------ --- ----- -------- -------- ------------  ------- - - -
+
+- ZORAN ------------------------------------------------------
+ Author: Pauline Middelink <middelin@polyware.nl> 
+   Date: 18 September 1999
+Version: 0.6.1
+
+- Description ------------------------------------------------
+
+Video4Linux compatible driver for an unknown brand framegrabber
+(Sold in the Netherlands by TRUST Computer Products) and various
+other zoran zr36120 based framegrabbers.
+
+The card contains a ZR36120 Multimedia PCI Interface and a Philips
+SAA7110 Onechip Frontend videodecoder. There is also an DSP of
+which I have forgotten the number, since i will never get that thing
+to work without specs from the vendor itself.
+
+The SAA711x are capable of processing 6 different video inputs,
+CVBS1..6 and Y1+C1, Y2+C2, Y3+C3. All in 50/60Hz, NTSC, PAL or
+SECAM and delivering a YUV datastream.  On my card the input
+'CVBS-0' corresponds to channel CVBS2 and 'S-Video' to Y2+C2.
+
+I have some reports of other cards working with the mentioned
+chip sets. For a list of other working cards please have a look
+at the cards named in the tvcards struct in the beginning of
+zr36120.c
+
+After some testing, I discovered that the carddesigner messed up
+on the I2C interface. The Zoran chip includes 2 lines SDA and SCL
+which (s)he connected reversely. So we have to clock on the SDA
+and r/w data on the SCL pin. Life is fun... Each cardtype now has
+a bit which signifies if you have a card with the same deficiancy.
+
+Oh, for the completness of this story I must mention that my
+card delivers the VSYNC pulse of the SAA chip to GIRQ1, not
+GIRQ0 as some other cards have. This is also incorperated in
+the driver be clearing/setting the 'useirq1' bit in the tvcard
+description.
+
+Another problems of contingious capturing data with a Zoran chip
+is something nasty inside the chip. It effectively halves the
+fps we ought to get... Here is the scenario: capturing frames
+to memory is done in the so-called snapshot mode. In this mode
+the Zoran stops after capturing a frame worth of data and wait
+till the application set GRAB bit to indicate readyness for the
+next frame. After detecting a set bit, the chip neetly waits
+till the start of a frame, captures it and it goes back to off.
+Smart ppl will notice the problem here. Its the waiting on the
+_next_ frame each time we set the GRAB bit... Oh well, 12,5 fps
+is still plenty fast for me.
+-- update 28/7/1999 --
+Don't believe a word I just said... Proof is the output
+of `streamer -t 300 -r 25 -f avi15 -o /dev/null`
+	++--+-+-+-+-+-+-+-+-+-+-+-+-s+-+-+-+-+-+-+-+-+-+-+- 25/25
+	+-s+-+-+-+-+-+-+-+-+-+-+-+-+-s+-+-+-+-+-+-+-+-+-+-+- 25/25
+	+-s+-+-+-+-+-+-+-+-+-+-+-+-+-s+-+-+-+-+-+-+-+-+-+-+- 25/25
+	+-s+-+-+-+-+-+-+-+-+-+-+-+-+-s+-+-+-+-+-+-+-+-+-+-+- 25/25
+	+-s+-+-+-+-+-+-+-+-+-+-+-+-+-s+-+-+-+-+-+-+-+-+-+-+- 25/25
+	+-s+-+-+-+-+-+-+-+-+-+-+-+-+-s+-+-+-+-+-+-+-+-+-+-+- 25/25
+	+-s+-+-+-+-+-+-+-+-+-+-+-+-+-s+-+-+-+-+-+-+-+-+-+-+- 25/25
+	+-s+-+-+-+-+-+-+-+-+-+-+-+-+-s+-+-+-+-+-+-+-+-+-+-+- 25/25
+	+-s+-+-+-+-+-+-+-+-+-+-+-+-+-s+-+-+-+-+-+-+-+-+-+-+- 25/25
+	+-s+-+-+-+-+-+-+-+-+-+-+-+-+-s+-+-+-+-+-+-+-+-+-+-+- 25/25
+	+-s+-+-+-+-+-+-+-+-+-+-+-+-+-s+-+-+-+-+-+-+-+-+-+-+- 25/25
+	+-s+-+-+-+-+-+-+-+-+-+-+-+-+-s+-+-+-+-+-+-+-+-+-+-+-
+	syncer: done
+	writer: done
+(note the /dev/null is prudent here, my system is not able to
+ grab /and/ write 25 fps to a file... gifts welcome :) )
+The technical reasoning follows: The zoran completed the last
+frame, the VSYNC goes low, and GRAB is cleared. The interrupt
+routine starts to work since its VSYNC driven, and again
+activates the GRAB bit. A few ms later the VSYNC (re-)rises and
+the zoran starts to work on a new and freshly broadcasted frame....
+
+For pointers I used the specs of both chips. Below are the URLs:
+	http://www.zoran.com/ftp/download/devices/pci/ZR36120/36120data.pdf
+	http://www-us.semiconductor.philips.com/acrobat/datasheets/SAA_7110_A_1.pdf
+
+The documentation has very little on absolute numbers or timings
+needed for the various modes/resolutions, but there are other
+programs you can borrow those from.
+
+------ Install --------------------------------------------
+Read the file called TODO.  Note its long list of limitations.
+
+Build a kernel with VIDEO4LINUX enabled. Activate the
+BT848 driver; we need this because we have need for the
+other modules (i2c and videodev) it enables.
+
+To install this software, extract it into a suitable directory.
+Examine the makefile and change anything you don't like.  Type "make".
+
+After making the modules check if you have the much needed
+/dev/video devices. If not, execute the following 4 lines:
+	mknod /dev/video c 81 0
+	mknod /dev/video1 c 81 1
+	mknod /dev/video2 c 81 2
+	mknod /dev/video3 c 81 3
+	mknod /dev/video4 c 81 4
+
+After makeing/checking the devices do:
+	modprobe i2c
+	modprobe videodev
+	modprobe saa7110	(optional)
+	modprobe saa7111	(optional)
+	modprobe tuner		(optional)
+	insmod zoran cardtype=<n>
+
+<n> is the cardtype of the card you have. The cardnumber can
+be found in the source of zr36120. Look for tvcards. If your
+card is not there, please try if any other card gives some
+response, and mail me if you got a working tvcard addition. 
+
+PS. <TVCard editors behold!)
+    Dont forget to set video_input to the number of inputs
+    you defined in the video_mux part of the tvcard definition.
+    Its a common error to add a channel but not incrementing
+    video_input and getting angry with me/v4l/linux/linus :(
+
+You are now ready to test the framegrabber with your favorite
+video4linux compatible tool
+
+------ Application ----------------------------------------
+
+This device works with all Video4Linux compatible applications,
+given the limitations in the TODO file.
+
+------ API ------------------------------------------------
+
+This uses the V4L interface as of kernel release 2.1.116, and in
+fact has not been tested on any lower version.  There are a couple
+of minor differences due to the fact that the amount of data returned
+with each frame varies, and no doubt there are discrepancies due to my
+misunderstanding of the API.  I intend to convert this driver to the
+new V4L2 API when it has stabilized more.
+
+------ Current state --------------------------------------
+
+The driver is capable of overlaying a video image in screen, and
+even capable of grabbing frames. It uses the BIGPHYSAREA patch
+to allocate lots of large memory blocks when tis patch is
+found in the kernel, but it doesn't need it.
+The consequence is that, when loading the driver as a module,
+the module may tell you it's out of memory, but 'free' says
+otherwise. The reason is simple; the modules wants its memory
+contingious, not fragmented, and after a long uptime there
+probably isn't a fragment of memory large enough...
+
+The driver uses a double buffering scheme, which should realy
+be an n-way buffer, depending on the size of allocated framebuffer
+and the requested grab-size/format.
+This current version also fixes a dead-lock situation during irq
+time, which really, really froze my system... :)
+
+Good luck.
+  Pauline
diff -u --recursive --new-file v2.3.29/linux/Documentation/vm/locking linux/Documentation/vm/locking
--- v2.3.29/linux/Documentation/vm/locking	Wed Oct 27 16:34:12 1999
+++ linux/Documentation/vm/locking	Mon Dec  6 10:17:31 1999
@@ -75,7 +75,11 @@
 The vmlist lock nests with the inode i_shared_lock and the kmem cache
 c_spinlock spinlocks. This is okay, since code that holds i_shared_lock 
 never asks for memory, and the kmem code asks for pages after dropping
-c_spinlock.
+c_spinlock. The vmlist lock also nests with pagecache_lock and 
+pagemap_lru_lock spinlocks, and no code asks for memory with these locks
+held.
+
+The vmlist lock is grabbed while holding the kernel_lock spinning monitor.
 
 The vmlist lock can be a sleeping or spin lock. In either case, care
 must be taken that it is not held on entry to the driver methods, since
@@ -85,3 +89,50 @@
 which is also the spinlock that page stealers use to protect changes to
 the victim process' ptes. Thus we have a reduction in the total number
 of locks. 
+
+swap_list_lock/swap_device_lock
+-------------------------------
+The swap devices are chained in priority order from the "swap_list" header. 
+The "swap_list" is used for the round-robin swaphandle allocation strategy.
+The #free swaphandles is maintained in "nr_swap_pages". These two together
+are protected by the swap_list_lock. 
+
+The swap_device_lock, which is per swap device, protects the reference 
+counts on the corresponding swaphandles, maintained in the "swap_map"
+array, and the "highest_bit" and "lowest_bit" fields.
+
+Both of these are spinlocks, and are never acquired from intr level. The
+locking heirarchy is swap_list_lock -> swap_device_lock.
+
+To prevent races between swap space deletion or async readahead swapins
+deciding whether a swap handle is being used, ie worthy of being read in
+from disk, and an unmap -> swap_free making the handle unused, the swap
+delete and readahead code grabs a temp reference on the swaphandle to
+prevent warning messages from swap_duplicate <- read_swap_cache_async.
+
+Swap cache locking
+------------------
+Pages are added into the swap cache with kernel_lock held, to make sure
+that multiple pages are not being added (and hence lost) by associating
+all of them with the same swaphandle.
+
+Pages are guaranteed not to be removed from the scache if the page is 
+"shared": ie, other processes hold reference on the page or the associated 
+swap handle. The only code that does not follow this rule is shrink_mmap,
+which deletes pages from the swap cache if no process has a reference on 
+the page (multiple processes might have references on the corresponding
+swap handle though). lookup_swap_cache() races with shrink_mmap, when
+establishing a reference on a scache page, so, it must check whether the
+page it located is still in the swapcache, or shrink_mmap deleted it.
+(This race is due to the fact that shrink_mmap looks at the page ref
+count with pagecache_lock, but then drops pagecache_lock before deleting
+the page from the scache).
+
+do_wp_page and do_swap_page have MP races in them while trying to figure
+out whether a page is "shared", by looking at the page_count + swap_count.
+To preserve the sum of the counts, the page lock _must_ be acquired before
+calling is_page_shared (else processes might switch their swap_count refs
+to the page count refs, after the page count ref has been snapshotted).
+
+Swap device deletion code currently breaks all the scache assumptions,
+since it grabs neither mmap_sem nor page_table_lock.
diff -u --recursive --new-file v2.3.29/linux/Documentation/vm/numa linux/Documentation/vm/numa
--- v2.3.29/linux/Documentation/vm/numa	Wed Dec 31 16:00:00 1969
+++ linux/Documentation/vm/numa	Mon Dec  6 10:14:13 1999
@@ -0,0 +1,41 @@
+Started Nov 1999 by Kanoj Sarcar <kanoj@sgi.com>
+
+The intent of this file is to have an uptodate, running commentary 
+from different people about NUMA specific code in the Linux vm.
+
+What is NUMA? It is an architecture where the memory access times
+for different regions of memory from a given processor varies
+according to the "distance" of the memory region from the processor.
+Each region of memory to which access times are the same from any 
+cpu, is called a node. On such architectures, it is beneficial if
+the kernel tries to minimize inter node communications. Schemes
+for this range from kernel text and read-only data replication
+across nodes, and trying to house all the data structures that
+key components of the kernel need on memory on that node.
+
+Currently, all the numa support is to provide efficient handling
+of widely discontiguous physical memory, so architectures which 
+are not NUMA but can have huge holes in the physical address space
+can use the same code. All this code is bracketed by CONFIG_DISCONTIGMEM.
+
+The initial port includes NUMAizing the bootmem allocator code by
+encapsulating all the pieces of information into a bootmem_data_t
+structure. Node specific calls have been added to the allocator. 
+In theory, any platform which uses the bootmem allocator should 
+be able to to put the bootmem and mem_map data structures anywhere
+it deems best.
+
+Each node's page allocation data structures have also been encapsulated
+into a pg_data_t. The bootmem_data_t is just one part of this. To 
+make the code look uniform between NUMA and regular UMA platforms, 
+UMA platforms have a statically allocated pg_data_t too (contig_page_data).
+For the sake of uniformity, the variable "numnodes" is also defined
+for all platforms. As we run benchmarks, we might decide to NUMAize 
+more variables like low_on_memory, nr_free_pages etc into the pg_data_t.
+
+The NUMA aware page allocation code currently tries to allocate pages 
+from different nodes in a round robin manner.  This will be changed to 
+do concentratic circle search, starting from current node, once the 
+NUMA port achieves more maturity. The call alloc_pages_node has been 
+added, so that drivers can make the call and not worry about whether 
+it is running on a NUMA or UMA platform.
diff -u --recursive --new-file v2.3.29/linux/MAINTAINERS linux/MAINTAINERS
--- v2.3.29/linux/MAINTAINERS	Tue Nov 23 22:42:20 1999
+++ linux/MAINTAINERS	Fri Dec  3 10:55:09 1999
@@ -426,12 +426,6 @@
 P:      Keith Mitchell
 M:      ipslinux@us.ibm.com
 W:      http://www.developer.ibm.com/welcome/netfinity/serveraid_beta.html
-S:      Supported
-
-IBM ServeRAID RAID DRIVER
-P:      Keith Mitchell
-M:      ipslinux@us.ibm.com
-W:      http://www.developer.ibm.com/welcome/netfinity/serveraid_beta.html
 S:      Supported 
 
 IDE DRIVER [GENERAL]
@@ -708,7 +702,7 @@
 
 PCI SUBSYSTEM
 P:	Martin Mares
-M:	mj@atrey.karlin.mff.cuni.cz
+M:	mj@suse.cz
 L:	linux-kernel@vger.rutgers.edu
 S:	Maintained
 
@@ -889,10 +883,8 @@
 S:	Maintained
 
 TLAN NETWORK DRIVER
-P:	James Banks
-M:	james@sovereign.org
 L:	tlan@vuser.vu.union.edu
-S:	Maintained
+S:	Orphan
 
 TOKEN-RING NETWORK DRIVER
 P:	Paul Norton
@@ -1005,6 +997,13 @@
 W:	http://poboxes.com/jreuter/
 W:	http://qsl.net/dl1bke/
 L:	linux-hams@vger.rutgers.edu
+S:	Maintained
+
+ZR36120 VIDEO FOR LINUX DRIVER
+P:	Pauline Middelink
+M:	middelin@polyware.nl
+W:	http://www.polyware.nl/~middelin/En/hobbies.html
+W:	http://www.polyware.nl/~middelin/hobbies.html
 S:	Maintained
 
 THE REST
diff -u --recursive --new-file v2.3.29/linux/Makefile linux/Makefile
--- v2.3.29/linux/Makefile	Tue Nov 23 22:42:20 1999
+++ linux/Makefile	Sat Nov 27 15:27:48 1999
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 3
-SUBLEVEL = 29
+SUBLEVEL = 30
 EXTRAVERSION =
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/Makefile linux/arch/alpha/Makefile
--- v2.3.29/linux/arch/alpha/Makefile	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/Makefile	Sat Nov 27 15:27:48 1999
@@ -59,27 +59,14 @@
 endif
 
 # For TSUNAMI, we must have the assembler not emulate our instructions.
-# The same is true for POLARIS, and now PYXIS.
+# The same is true for IRONGATE, POLARIS, PYXIS.
 # BWX is most important, but we don't really want any emulation ever.
+
 ifeq ($(old_gas),y)
- ifneq ($(CONFIG_ALPHA_GENERIC)$(CONFIG_ALPHA_TSUNAMI)$(CONFIG_ALPHA_POLARIS)$(CONFIG_ALPHA_PYXIS),)
-   # How do we do #error in make?
-   CFLAGS := --error-please-upgrade-your-assembler
- endif
-else
- ifeq ($(CONFIG_ALPHA_GENERIC),y)
-   CFLAGS := $(CFLAGS) -Wa,-mev6
- endif
- ifeq ($(CONFIG_ALPHA_PYXIS),y)
-   CFLAGS := $(CFLAGS) -Wa,-m21164a
- endif
- ifeq ($(CONFIG_ALPHA_POLARIS),y)
-   CFLAGS := $(CFLAGS) -Wa,-m21164pc
- endif
- ifeq ($(CONFIG_ALPHA_TSUNAMI),y)
-   CFLAGS := $(CFLAGS) -Wa,-mev6
- endif
+  # How do we do #error in make?
+  CFLAGS := --error-please-upgrade-your-assembler
 endif
+CFLAGS := $(CFLAGS) -Wa,-mev6
 
 HEAD := arch/alpha/kernel/head.o
 
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.3.29/linux/arch/alpha/config.in	Sun Nov  7 16:37:33 1999
+++ linux/arch/alpha/config.in	Sat Nov 27 15:27:48 1999
@@ -33,10 +33,12 @@
 	 EB64+			CONFIG_ALPHA_EB64P		\
 	 EB66			CONFIG_ALPHA_EB66		\
 	 EB66+			CONFIG_ALPHA_EB66P		\
+	 Eiger			CONFIG_ALPHA_EIGER		\
 	 Jensen			CONFIG_ALPHA_JENSEN		\
 	 LX164			CONFIG_ALPHA_LX164		\
 	 Miata			CONFIG_ALPHA_MIATA		\
 	 Mikasa			CONFIG_ALPHA_MIKASA		\
+	 Nautilus		CONFIG_ALPHA_NAUTILUS		\
 	 Noname			CONFIG_ALPHA_NONAME		\
 	 Noritake		CONFIG_ALPHA_NORITAKE		\
 	 PC164			CONFIG_ALPHA_PC164		\
@@ -54,6 +56,7 @@
 unset CONFIG_ALPHA_LCA CONFIG_ALPHA_APECS CONFIG_ALPHA_CIA
 unset CONFIG_ALPHA_T2 CONFIG_ALPHA_PYXIS CONFIG_ALPHA_POLARIS
 unset CONFIG_ALPHA_TSUNAMI CONFIG_ALPHA_MCPCIA
+unset CONFIG_ALPHA_IRONGATE
 
 if [ "$CONFIG_ALPHA_GENERIC" = "y" ]
 then
@@ -117,7 +120,7 @@
 	define_bool CONFIG_ALPHA_EV5 y
 	define_bool CONFIG_ALPHA_PYXIS y
 fi
-if [ "$CONFIG_ALPHA_DP264" = "y" ]
+if [ "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_EIGER" = "y" ]
 then
 	define_bool CONFIG_PCI y
 	define_bool CONFIG_ALPHA_EV6 y
@@ -139,6 +142,12 @@
 then
 	define_bool CONFIG_ALPHA_EV4 y
 fi
+if [ "$CONFIG_ALPHA_NAUTILUS" = "y" ]
+then
+	define_bool CONFIG_PCI y
+	define_bool CONFIG_ALPHA_EV6 y
+	define_bool CONFIG_ALPHA_IRONGATE y
+fi
 
 if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \
 	-o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_JENSEN" = "y" \
@@ -147,7 +156,8 @@
 	-o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_MIATA" = "y" \
 	-o "$CONFIG_ALPHA_NORITAKE" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
 	-o "$CONFIG_ALPHA_LX164" = "y" -o "$CONFIG_ALPHA_SX164" = "y" \
-	-o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" ]
+	-o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \
+	-o "$CONFIG_ALPHA_EIGER" = "y" ]
 then
   bool 'Use SRM as bootloader' CONFIG_ALPHA_SRM
 fi
@@ -244,11 +254,10 @@
   mainmenu_option next_comment
   comment 'Console drivers'
   bool 'VGA text console' CONFIG_VGA_CONSOLE
-  bool 'Support for frame buffer devices' CONFIG_FB
+  source drivers/video/Config.in
   if [ "$CONFIG_FB" = "y" ]; then
     define_bool CONFIG_PCI_CONSOLE y
   fi
-  source drivers/video/Config.in
   endmenu
 fi
 
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/defconfig linux/arch/alpha/defconfig
--- v2.3.29/linux/arch/alpha/defconfig	Sun Nov  7 16:37:33 1999
+++ linux/arch/alpha/defconfig	Sat Nov 27 15:27:48 1999
@@ -32,6 +32,7 @@
 # CONFIG_ALPHA_LX164 is not set
 # CONFIG_ALPHA_MIATA is not set
 # CONFIG_ALPHA_MIKASA is not set
+# CONFIG_ALPHA_NAUTILUS is not set
 # CONFIG_ALPHA_NONAME is not set
 # CONFIG_ALPHA_NORITAKE is not set
 # CONFIG_ALPHA_PC164 is not set
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/Makefile linux/arch/alpha/kernel/Makefile
--- v2.3.29/linux/arch/alpha/kernel/Makefile	Tue Sep  7 12:14:05 1999
+++ linux/arch/alpha/kernel/Makefile	Thu Dec  2 15:28:54 1999
@@ -12,22 +12,20 @@
 .S.o:
 	$(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $<
 
-all: kernel.o head.o
-
 O_TARGET := kernel.o
 O_OBJS   := entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o \
-	    ptrace.o time.o fpreg.o semaphore.o
+	    ptrace.o time.o semaphore.o
 OX_OBJS  := alpha_ksyms.o
 
 
 ifdef CONFIG_ALPHA_GENERIC
 
-O_OBJS	 += core_apecs.o core_cia.o core_lca.o core_mcpcia.o core_pyxis.o \
-	    core_t2.o core_tsunami.o core_polaris.o \
-	    sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o \
-	    sys_jensen.o sys_miata.o sys_mikasa.o sys_noritake.o \
-	    sys_rawhide.o sys_ruffian.o sys_sable.o sys_sio.o \
-	    sys_sx164.o sys_takara.o sys_rx164.o \
+O_OBJS	 += core_apecs.o core_cia.o core_irongate.o core_lca.o core_mcpcia.o \
+	    core_polaris.o core_pyxis.o core_t2.o core_tsunami.o \
+	    sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o sys_eiger.o \
+	    sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o \
+	    sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \
+	    sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_rx164.o \
 	    es1888.o smc37c669.o smc37c93x.o ns87312.o pci.o
 else
 
@@ -42,6 +40,9 @@
 ifdef CONFIG_ALPHA_CIA
 O_OBJS   += core_cia.o
 endif
+ifdef CONFIG_ALPHA_IRONGATE
+O_OBJS   += core_irongate.o
+endif
 ifdef CONFIG_ALPHA_LCA
 O_OBJS   += core_lca.o
 endif
@@ -74,6 +75,9 @@
 ifneq ($(CONFIG_ALPHA_EB64P)$(CONFIG_ALPHA_EB66),)
 O_OBJS   += sys_eb64p.o
 endif
+ifdef CONFIG_ALPHA_EIGER
+O_OBJS   += sys_eiger.o
+endif
 ifdef CONFIG_ALPHA_JENSEN
 O_OBJS   += sys_jensen.o
 endif
@@ -82,6 +86,9 @@
 endif
 ifdef CONFIG_ALPHA_MIKASA
 O_OBJS   += sys_mikasa.o
+endif
+ifdef CONFIG_ALPHA_NAUTILUS
+O_OBJS   += sys_nautilus.o
 endif
 ifdef CONFIG_ALPHA_NORITAKE
 O_OBJS   += sys_noritake.o
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/alpha_ksyms.c linux/arch/alpha/kernel/alpha_ksyms.c
--- v2.3.29/linux/arch/alpha/kernel/alpha_ksyms.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/kernel/alpha_ksyms.c	Thu Dec  2 15:28:54 1999
@@ -103,7 +103,9 @@
 EXPORT_SYMBOL(wrusp);
 EXPORT_SYMBOL(start_thread);
 EXPORT_SYMBOL(alpha_read_fp_reg);
+EXPORT_SYMBOL(alpha_read_fp_reg_s);
 EXPORT_SYMBOL(alpha_write_fp_reg);
+EXPORT_SYMBOL(alpha_write_fp_reg_s);
 
 /* In-kernel system calls.  */
 EXPORT_SYMBOL(kernel_thread);
@@ -123,6 +125,7 @@
 EXPORT_SYMBOL(ip_compute_csum);
 EXPORT_SYMBOL(ip_fast_csum);
 EXPORT_SYMBOL(csum_partial_copy);
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
 EXPORT_SYMBOL(csum_partial_copy_from_user);
 EXPORT_SYMBOL(csum_ipv6_magic);
 
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/core_cia.c linux/arch/alpha/kernel/core_cia.c
--- v2.3.29/linux/arch/alpha/kernel/core_cia.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/kernel/core_cia.c	Sat Nov 27 15:42:54 1999
@@ -435,8 +435,10 @@
 	hae_mem->start = 0;
 	hae_mem->end = CIA_MEM_R1_MASK;
 	hae_mem->name = pci_hae0_name;
+	hae_mem->flags = IORESOURCE_MEM;
 
-	request_resource(&iomem_resource, hae_mem);
+	if (request_resource(&iomem_resource, hae_mem) < 0)
+		printk(KERN_ERR "Failed to request HAE_MEM\n");
 }
 
 static inline void
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/core_irongate.c linux/arch/alpha/kernel/core_irongate.c
--- v2.3.29/linux/arch/alpha/kernel/core_irongate.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/kernel/core_irongate.c	Sat Nov 27 15:42:54 1999
@@ -0,0 +1,353 @@
+/*
+ *	linux/arch/alpha/kernel/core_irongate.c
+ *
+ * Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com).
+ *
+ *	Copyright (C) 1999 Alpha Processor, Inc.,
+ *		(David Daniel, Stig Telfer, Soohoon Lee)
+ *
+ * Code common to all IRONGATE core logic chips.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/pci.h>
+#include <asm/hwrpb.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/core_irongate.h>
+#undef __EXTERN_INLINE
+
+#include "proto.h"
+#include "pci_impl.h"
+
+
+/*
+ * NOTE: Herein lie back-to-back mb instructions.  They are magic.
+ * One plausible explanation is that the I/O controller does not properly
+ * handle the system transaction.  Another involves timing.  Ho hum.
+ */
+
+/*
+ * BIOS32-style PCI interface:
+ */
+
+#define DEBUG_CONFIG 0
+
+#if DEBUG_CONFIG
+# define DBG_CFG(args)	printk args
+#else
+# define DBG_CFG(args)
+#endif
+
+
+/*
+ * Given a bus, device, and function number, compute resulting
+ * configuration space address accordingly.  It is therefore not safe
+ * to have concurrent invocations to configuration space access
+ * routines, but there really shouldn't be any need for this.
+ *
+ *	addr[31:24]		reserved
+ *	addr[23:16]		bus number (8 bits = 128 possible buses)
+ *	addr[15:11]		Device number (5 bits)
+ *	addr[10: 8]		function number
+ *	addr[ 7: 2]		register number
+ *
+ * For IRONGATE:
+ *    if (bus = addr[23:16]) == 0
+ *    then
+ *	  type 0 config cycle:
+ *	      addr_on_pci[31:11] = id selection for device = addr[15:11]
+ *	      addr_on_pci[10: 2] = addr[10: 2] ???
+ *	      addr_on_pci[ 1: 0] = 00
+ *    else
+ *	  type 1 config cycle (pass on with no decoding):
+ *	      addr_on_pci[31:24] = 0
+ *	      addr_on_pci[23: 2] = addr[23: 2]
+ *	      addr_on_pci[ 1: 0] = 01
+ *    fi
+ *
+ * Notes:
+ *	The function number selects which function of a multi-function device
+ *	(e.g., SCSI and Ethernet).
+ *
+ *	The register selects a DWORD (32 bit) register offset.	Hence it
+ *	doesn't get shifted by 2 bits as we want to "drop" the bottom two
+ *	bits.
+ */
+
+static int
+mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
+	     unsigned char *type1)
+{
+	unsigned long addr;
+	u8 bus = dev->bus->number;
+	u8 device_fn = dev->devfn;
+
+	DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
+		 "pci_addr=0x%p, type1=0x%p)\n",
+		 bus, device_fn, where, pci_addr, type1));
+
+	*type1 = (bus != 0);
+
+	addr = (bus << 16) | (device_fn << 8) | where;
+	addr |= IRONGATE_CONF;
+
+	*pci_addr = addr;
+	DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+	return 0;
+}
+
+static int
+irongate_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+	unsigned long addr;
+	unsigned char type1;
+
+	if (mk_conf_addr(dev, where, &addr, &type1))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	*value = __kernel_ldbu(*(vucp)addr);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+	unsigned long addr;
+	unsigned char type1;
+
+	if (mk_conf_addr(dev, where, &addr, &type1))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	*value = __kernel_ldwu(*(vusp)addr);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+	unsigned long addr;
+	unsigned char type1;
+
+	if (mk_conf_addr(dev, where, &addr, &type1))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	*value = *(vuip)addr;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+	unsigned long addr;
+	unsigned char type1;
+
+	if (mk_conf_addr(dev, where, &addr, &type1))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	__kernel_stb(value, *(vucp)addr);
+	mb();
+	__kernel_ldbu(*(vucp)addr);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+	unsigned long addr;
+	unsigned char type1;
+
+	if (mk_conf_addr(dev, where, &addr, &type1))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	__kernel_stw(value, *(vusp)addr);
+	mb();
+	__kernel_ldwu(*(vusp)addr);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+	unsigned long addr;
+	unsigned char type1;
+
+	if (mk_conf_addr(dev, where, &addr, &type1))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	*(vuip)addr = value;
+	mb();
+	*(vuip)addr;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+struct pci_ops irongate_pci_ops =
+{
+	read_byte:	irongate_read_config_byte,
+	read_word:	irongate_read_config_word,
+	read_dword:	irongate_read_config_dword,
+	write_byte:	irongate_write_config_byte,
+	write_word:	irongate_write_config_word,
+	write_dword:	irongate_write_config_dword
+};
+
+#if 0
+static void
+irongate_register_dump(const char *function_name)
+{
+	printk("%s: Irongate registers:\n"
+	       "\tdev_vendor\t0x%08x\n"
+	       "\tstat_cmd\t0x%08x\n"
+	       "\tclass\t\t0x%08x\n"
+	       "\tlatency\t\t0x%08x\n"
+	       "\tbar0\t\t0x%08x\n"
+	       "\tbar1\t\t0x%08x\n"
+	       "\tbar2\t\t0x%08x\n"
+	       "\trsrvd0[0]\t0x%08x\n"
+	       "\trsrvd0[1]\t0x%08x\n"
+	       "\trsrvd0[2]\t0x%08x\n"
+	       "\trsrvd0[3]\t0x%08x\n"
+	       "\trsrvd0[4]\t0x%08x\n"
+	       "\trsrvd0[5]\t0x%08x\n"
+	       "\tcapptr\t\t0x%08x\n"
+	       "\trsrvd1[0]\t0x%08x\n"
+	       "\trsrvd1[1]\t0x%08x\n"
+	       "\tbacsr10\t\t0x%08x\n"
+	       "\tbacsr32\t\t0x%08x\n"
+	       "\tbacsr54\t\t0x%08x\n"
+	       "\trsrvd2[0]\t0x%08x\n"
+	       "\tdrammap\t\t0x%08x\n"
+	       "\tdramtm\t\t0x%08x\n"
+	       "\tdramms\t\t0x%08x\n"
+	       "\trsrvd3[0]\t0x%08x\n"
+	       "\tbiu0\t\t0x%08x\n"
+	       "\tbiusip\t\t0x%08x\n"
+	       "\trsrvd4[0]\t0x%08x\n"
+	       "\trsrvd4[1]\t0x%08x\n"
+	       "\tmro\t\t0x%08x\n"
+	       "\trsrvd5[0]\t0x%08x\n"
+	       "\trsrvd5[1]\t0x%08x\n"
+	       "\trsrvd5[2]\t0x%08x\n"
+	       "\twhami\t\t0x%08x\n"
+	       "\tpciarb\t\t0x%08x\n"
+	       "\tpcicfg\t\t0x%08x\n"
+	       "\trsrvd6[0]\t0x%08x\n"
+	       "\trsrvd6[1]\t0x%08x\n"
+	       "\trsrvd6[2]\t0x%08x\n"
+	       "\trsrvd6[3]\t0x%08x\n"
+	       "\trsrvd6[4]\t0x%08x\n"
+	       "\tagpcap\t\t0x%08x\n"
+	       "\tagpstat\t\t0x%08x\n"
+	       "\tagpcmd\t\t0x%08x\n"
+	       "\tagpva\t\t0x%08x\n"
+	       "\tagpmode\t\t0x%08x\n",
+	       function_name,
+	       IRONGATE0->dev_vendor,
+	       IRONGATE0->stat_cmd,
+	       IRONGATE0->class,
+	       IRONGATE0->latency,
+	       IRONGATE0->bar0,
+	       IRONGATE0->bar1,
+	       IRONGATE0->bar2,
+	       IRONGATE0->rsrvd0[0],
+	       IRONGATE0->rsrvd0[1],
+	       IRONGATE0->rsrvd0[2],
+	       IRONGATE0->rsrvd0[3],
+	       IRONGATE0->rsrvd0[4],
+	       IRONGATE0->rsrvd0[5],
+	       IRONGATE0->capptr,
+	       IRONGATE0->rsrvd1[0],
+	       IRONGATE0->rsrvd1[1],
+	       IRONGATE0->bacsr10,
+	       IRONGATE0->bacsr32,
+	       IRONGATE0->bacsr54,
+	       IRONGATE0->rsrvd2[0],
+	       IRONGATE0->drammap,
+	       IRONGATE0->dramtm,
+	       IRONGATE0->dramms,
+	       IRONGATE0->rsrvd3[0],
+	       IRONGATE0->biu0,
+	       IRONGATE0->biusip,
+	       IRONGATE0->rsrvd4[0],
+	       IRONGATE0->rsrvd4[1],
+	       IRONGATE0->mro,
+	       IRONGATE0->rsrvd5[0],
+	       IRONGATE0->rsrvd5[1],
+	       IRONGATE0->rsrvd5[2],
+	       IRONGATE0->whami,
+	       IRONGATE0->pciarb,
+	       IRONGATE0->pcicfg,
+	       IRONGATE0->rsrvd6[0],
+	       IRONGATE0->rsrvd6[1],
+	       IRONGATE0->rsrvd6[2],
+	       IRONGATE0->rsrvd6[3],
+	       IRONGATE0->rsrvd6[4],
+	       IRONGATE0->agpcap,
+	       IRONGATE0->agpstat,
+	       IRONGATE0->agpcmd,
+	       IRONGATE0->agpva,
+	       IRONGATE0->agpmode);
+}
+#else
+#define irongate_register_dump(x)
+#endif
+
+int
+irongate_pci_clr_err(void)
+{
+	unsigned int nmi_ctl=0;
+	unsigned int IRONGATE_jd;
+
+again:
+	IRONGATE_jd = IRONGATE0->stat_cmd;
+	printk("Iron stat_cmd %x\n", IRONGATE_jd);
+	IRONGATE0->stat_cmd = IRONGATE_jd; /* write again clears error bits */
+	mb();
+	IRONGATE_jd = IRONGATE0->stat_cmd;  /* re-read to force write */
+
+	IRONGATE_jd = IRONGATE0->dramms;
+	printk("Iron dramms %x\n", IRONGATE_jd);
+	IRONGATE0->dramms = IRONGATE_jd; /* write again clears error bits */
+	mb();
+	IRONGATE_jd = IRONGATE0->dramms;  /* re-read to force write */
+
+	/* Clear ALI NMI */
+        nmi_ctl = inb(0x61);
+        nmi_ctl |= 0x0c;
+        outb(nmi_ctl, 0x61);
+        nmi_ctl &= ~0x0c;
+        outb(nmi_ctl, 0x61);
+
+	IRONGATE_jd = IRONGATE0->dramms;
+	if (IRONGATE_jd & 0x300) goto again;
+
+	return 0;
+}
+
+void __init
+irongate_init_arch(void)
+{
+	struct pci_controler *hose;
+
+	irongate_pci_clr_err();
+	irongate_register_dump(__FUNCTION__);
+
+	/*
+	 * Create our single hose.
+	 */
+
+	hose = alloc_pci_controler();
+	hose->io_space = &ioport_resource;
+	hose->mem_space = &iomem_resource;
+	hose->config_space = IRONGATE_CONF;
+	hose->index = 0;
+}
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/core_mcpcia.c linux/arch/alpha/kernel/core_mcpcia.c
--- v2.3.29/linux/arch/alpha/kernel/core_mcpcia.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/kernel/core_mcpcia.c	Sat Nov 27 19:34:31 1999
@@ -43,7 +43,7 @@
 # define DBG_CFG(args)
 #endif
 
-#define MCPCIA_MAX_HOSES 2
+#define MCPCIA_MAX_HOSES 4
 
 /* Dodge has PCI0 and PCI1 at MID 4 and 5 respectively.  Durango adds
    PCI2 and PCI3 at MID 6 and 7 respectively.  */
@@ -305,6 +305,7 @@
 	mb();
 	mb();
 	draina();
+	wrmces(7);
 	mcheck_expected(cpu) = 1;
 	mcheck_taken(cpu) = 0;
 	mcheck_extra(cpu) = mid;
@@ -346,18 +347,33 @@
 	io->start = MCPCIA_IO(mid) - MCPCIA_IO_BIAS;
 	io->end = io->start + 0xffff;
 	io->name = pci_io_names[h];
+	io->flags = IORESOURCE_IO;
 
 	mem->start = MCPCIA_DENSE(mid) - MCPCIA_MEM_BIAS;
 	mem->end = mem->start + 0xffffffff;
 	mem->name = pci_mem_names[h];
+	mem->flags = IORESOURCE_MEM;
 
 	hae_mem->start = mem->start;
 	hae_mem->end = mem->start + MCPCIA_MEM_MASK;
 	hae_mem->name = pci_hae0_name;
+	hae_mem->flags = IORESOURCE_MEM;
 
-	request_resource(&ioport_resource, io);
-	request_resource(&iomem_resource, mem);
-	request_resource(mem, hae_mem);
+	if (request_resource(&ioport_resource, io) < 0)
+		printk(KERN_ERR "Failed to request IO on hose %d\n", h);
+	if (request_resource(&iomem_resource, mem) < 0)
+		printk(KERN_ERR "Failed to request MEM on hose %d\n", h);
+	if (request_resource(mem, hae_mem) < 0)
+		printk(KERN_ERR "Failed to request HAE_MEM on hose %d\n", h);
+}
+
+static void
+mcpcia_pci_clr_err(int mid)
+{
+	*(vuip)MCPCIA_CAP_ERR(mid);
+	*(vuip)MCPCIA_CAP_ERR(mid) = 0xffffffff;   /* Clear them all.  */
+	mb();
+	*(vuip)MCPCIA_CAP_ERR(mid);  /* Re-read for force write.  */
 }
 
 static void __init
@@ -366,19 +382,13 @@
 	int mid = hose2mid(hose->index);
 	unsigned int tmp;
 
+	mcpcia_pci_clr_err(mid);
+
 	/* 
-	 * Set up error reporting. Make sure CPU_PE is OFF in the mask.
+	 * Set up error reporting.
 	 */
-#if 0
-	tmp = *(vuip)MCPCIA_ERR_MASK(mid);
-	tmp &= ~4;
-	*(vuip)MCPCIA_ERR_MASK(mid) = tmp;
-	mb();
-	tmp = *(vuip)MCPCIA_ERR_MASK(mid);
-#endif
-
 	tmp = *(vuip)MCPCIA_CAP_ERR(mid);
-	tmp |= 0x0006;   /* master/target abort */
+	tmp |= 0x0006;		/* master/target abort */
 	*(vuip)MCPCIA_CAP_ERR(mid) = tmp;
 	mb();
 	tmp = *(vuip)MCPCIA_CAP_ERR(mid);
@@ -422,27 +432,37 @@
 void __init
 mcpcia_init_arch(void)
 {
-	extern asmlinkage void entInt(void);
-	struct pci_controler *hose;
-	int h, hose_count = 0;
-
-	/* Ho hum.. init_arch is called before init_IRQ, but we need to be
-	   able to handle machine checks.  So install the handler now.  */
-	wrent(entInt, 0);
-
 	/* With multiple PCI busses, we play with I/O as physical addrs.  */
 	ioport_resource.end = ~0UL;
 	iomem_resource.end = ~0UL;
 
+	/* Allocate hose 0.  That's the one that all the ISA junk hangs
+	   off of, from which we'll be registering stuff here in a bit.
+	   Other hose detection is done in mcpcia_init_hoses, which is
+	   called from init_IRQ.  */
+
+	mcpcia_new_hose(0);
+}
+
+/* This is called from init_IRQ, since we cannot take interrupts
+   before then.  Which means we cannot do this in init_arch.  */
+
+void __init
+mcpcia_init_hoses(void)
+{
+	struct pci_controler *hose;
+	int h, hose_count = 0;
+
 	/* First, find how many hoses we have.  */
 	for (h = 0; h < MCPCIA_MAX_HOSES; ++h) {
 		if (mcpcia_probe_hose(h)) {
-			mcpcia_new_hose(h);
+			if (h != 0)
+				mcpcia_new_hose(h);
 			hose_count++;
 		}
 	}
 
-	printk("mcpcia_init_arch: found %d hoses\n", hose_count);
+	printk("mcpcia_init_hoses: found %d hoses\n", hose_count);
 
 	/* Now do init for each hose.  */
 	for (hose = hose_head; hose; hose = hose->next)
@@ -450,15 +470,6 @@
 }
 
 static void
-mcpcia_pci_clr_err(int mid)
-{
-	*(vuip)MCPCIA_CAP_ERR(mid);
-	*(vuip)MCPCIA_CAP_ERR(mid) = 0xffffffff;   /* Clear them all.  */
-	mb();
-	*(vuip)MCPCIA_CAP_ERR(mid);  /* Re-read for force write.  */
-}
-
-static void
 mcpcia_print_uncorrectable(struct el_MCPCIA_uncorrected_frame_mcheck *logout)
 {
 	struct el_common_EV5_uncorrectable_mcheck *frame;
@@ -468,65 +479,65 @@
 
 	/* Print PAL fields */
 	for (i = 0; i < 24; i += 2) {
-		printk("\tpal temp[%d-%d]\t\t= %16lx %16lx\n\r",
+		printk("  paltmp[%d-%d] = %16lx %16lx\n",
 		       i, i+1, frame->paltemp[i], frame->paltemp[i+1]);
 	}
 	for (i = 0; i < 8; i += 2) {
-		printk("\tshadow[%d-%d]\t\t= %16lx %16lx\n\r",
+		printk("  shadow[%d-%d] = %16lx %16lx\n",
 		       i, i+1, frame->shadow[i], 
 		       frame->shadow[i+1]);
 	}
-	printk("\tAddr of excepting instruction\t= %16lx\n\r",
+	printk("  Addr of excepting instruction  = %16lx\n",
 	       frame->exc_addr);
-	printk("\tSummary of arithmetic traps\t= %16lx\n\r",
+	printk("  Summary of arithmetic traps    = %16lx\n",
 	       frame->exc_sum);
-	printk("\tException mask\t\t\t= %16lx\n\r",
+	printk("  Exception mask                 = %16lx\n",
 	       frame->exc_mask);
-	printk("\tBase address for PALcode\t= %16lx\n\r",
+	printk("  Base address for PALcode       = %16lx\n",
 	       frame->pal_base);
-	printk("\tInterrupt Status Reg\t\t= %16lx\n\r",
+	printk("  Interrupt Status Reg           = %16lx\n",
 	       frame->isr);
-	printk("\tCURRENT SETUP OF EV5 IBOX\t= %16lx\n\r",
+	printk("  CURRENT SETUP OF EV5 IBOX      = %16lx\n",
 	       frame->icsr);
-	printk("\tI-CACHE Reg %s parity error\t= %16lx\n\r",
+	printk("  I-CACHE Reg %s parity error   = %16lx\n",
 	       (frame->ic_perr_stat & 0x800L) ? 
 	       "Data" : "Tag", 
 	       frame->ic_perr_stat); 
-	printk("\tD-CACHE error Reg\t\t= %16lx\n\r",
+	printk("  D-CACHE error Reg              = %16lx\n",
 	       frame->dc_perr_stat);
 	if (frame->dc_perr_stat & 0x2) {
 		switch (frame->dc_perr_stat & 0x03c) {
 		case 8:
-			printk("\t\tData error in bank 1\n\r");
+			printk("    Data error in bank 1\n");
 			break;
 		case 4:
-			printk("\t\tData error in bank 0\n\r");
+			printk("    Data error in bank 0\n");
 			break;
 		case 20:
-			printk("\t\tTag error in bank 1\n\r");
+			printk("    Tag error in bank 1\n");
 			break;
 		case 10:
-			printk("\t\tTag error in bank 0\n\r");
+			printk("    Tag error in bank 0\n");
 			break;
 		}
 	}
-	printk("\tEffective VA\t\t\t= %16lx\n\r",
+	printk("  Effective VA                   = %16lx\n",
 	       frame->va);
-	printk("\tReason for D-stream\t\t= %16lx\n\r",
+	printk("  Reason for D-stream            = %16lx\n",
 	       frame->mm_stat);
-	printk("\tEV5 SCache address\t\t= %16lx\n\r",
+	printk("  EV5 SCache address             = %16lx\n",
 	       frame->sc_addr);
-	printk("\tEV5 SCache TAG/Data parity\t= %16lx\n\r",
+	printk("  EV5 SCache TAG/Data parity     = %16lx\n",
 	       frame->sc_stat);
-	printk("\tEV5 BC_TAG_ADDR\t\t\t= %16lx\n\r",
+	printk("  EV5 BC_TAG_ADDR                = %16lx\n",
 	       frame->bc_tag_addr);
-	printk("\tEV5 EI_ADDR: Phys addr of Xfer\t= %16lx\n\r",
+	printk("  EV5 EI_ADDR: Phys addr of Xfer = %16lx\n",
 	       frame->ei_addr);
-	printk("\tFill Syndrome\t\t\t= %16lx\n\r",
+	printk("  Fill Syndrome                  = %16lx\n",
 	       frame->fill_syndrome);
-	printk("\tEI_STAT reg\t\t\t= %16lx\n\r",
+	printk("  EI_STAT reg                    = %16lx\n",
 	       frame->ei_stat);
-	printk("\tLD_LOCK\t\t\t\t= %16lx\n\r",
+	printk("  LD_LOCK                        = %16lx\n",
 	       frame->ld_lock);
 }
 
@@ -547,7 +558,8 @@
 	if (mcheck_expected(cpu)) {
 		mcpcia_pci_clr_err(mcheck_extra(cpu));
 	} else {
-		/* FIXME: how do we figure out which hose the error was on?  */	
+		/* FIXME: how do we figure out which hose the
+		   error was on?  */	
 		struct pci_controler *hose;
 		for (hose = hose_head; hose; hose = hose->next)
 			mcpcia_pci_clr_err(hose2mid(hose->index));
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/core_polaris.c linux/arch/alpha/kernel/core_polaris.c
--- v2.3.29/linux/arch/alpha/kernel/core_polaris.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/kernel/core_polaris.c	Sat Nov 27 15:42:54 1999
@@ -146,7 +146,7 @@
 
         __kernel_stw(value, *(vusp)pci_addr);
 	mb();
-	__kernel_ldbu(*(vusp)pci_addr);
+	__kernel_ldwu(*(vusp)pci_addr);
 	return PCIBIOS_SUCCESSFUL;
 }
 
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/core_pyxis.c linux/arch/alpha/kernel/core_pyxis.c
--- v2.3.29/linux/arch/alpha/kernel/core_pyxis.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/kernel/core_pyxis.c	Sat Nov 27 15:42:54 1999
@@ -389,8 +389,10 @@
 static inline void
 pyxis_pci_clr_err(void)
 {
-	*(vuip)PYXIS_ERR;
-	*(vuip)PYXIS_ERR = 0x0180;
+	unsigned int tmp;
+
+	tmp = *(vuip)PYXIS_ERR;
+	*(vuip)PYXIS_ERR = tmp;
 	mb();
 	*(vuip)PYXIS_ERR;  /* re-read to force write */
 }
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/core_tsunami.c linux/arch/alpha/kernel/core_tsunami.c
--- v2.3.29/linux/arch/alpha/kernel/core_tsunami.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/kernel/core_tsunami.c	Thu Dec  2 15:27:02 1999
@@ -26,6 +26,13 @@
 
 int TSUNAMI_bootcpu;
 
+static struct 
+{
+	unsigned long wsba[4];
+	unsigned long wsm[4];
+	unsigned long tba[4];
+} saved_pchip[2];
+
 /*
  * NOTE: Herein lie back-to-back mb instructions.  They are magic. 
  * One plausible explanation is that the I/O controller does not properly
@@ -155,6 +162,7 @@
 
 	__kernel_stb(value, *(vucp)addr);
 	mb();
+	__kernel_ldbu(*(vucp)addr);
 	return PCIBIOS_SUCCESSFUL;
 }
 
@@ -169,6 +177,7 @@
 
 	__kernel_stw(value, *(vusp)addr);
 	mb();
+	__kernel_ldwu(*(vusp)addr);
 	return PCIBIOS_SUCCESSFUL;
 }
 
@@ -183,6 +192,7 @@
 
 	*(vuip)addr = value;
 	mb();
+	*(vuip)addr;
 	return PCIBIOS_SUCCESSFUL;
 }
 
@@ -261,22 +271,40 @@
 	hose->index = index;
 
 	hose->io_space->start = TSUNAMI_IO(index) - TSUNAMI_IO_BIAS;
-	hose->io_space->end = hose->io_space->start + TSUNAMI_IO_SPACE;
+	hose->io_space->end = hose->io_space->start + TSUNAMI_IO_SPACE - 1;
 	hose->io_space->name = pci_io_names[index];
 	hose->io_space->flags = IORESOURCE_IO;
 
 	hose->mem_space->start = TSUNAMI_MEM(index) - TSUNAMI_MEM_BIAS;
-	/* the IOMEM address space is larger than 32bit but most pci
-	   cars doesn't support 64bit address space so we stick with
-	   32bit here (see the TSUNAMI_MEM_SPACE define). */
 	hose->mem_space->end = hose->mem_space->start + 0xffffffff;
 	hose->mem_space->name = pci_mem_names[index];
 	hose->mem_space->flags = IORESOURCE_MEM;
 
 	if (request_resource(&ioport_resource, hose->io_space) < 0)
-		printk(KERN_ERR "failed to request IO on hose %d", index);
+		printk(KERN_ERR "Failed to request IO on hose %d\n", index);
 	if (request_resource(&iomem_resource, hose->mem_space) < 0)
-		printk(KERN_ERR "failed to request IOMEM on hose %d", index);
+		printk(KERN_ERR "Failed to request MEM on hose %d\n", index);
+
+	/*
+	 * Save the existing PCI window translations.  SRM will 
+	 * need them when we go to reboot.
+	 */
+
+	saved_pchip[index].wsba[0] = pchip->wsba[0].csr;
+	saved_pchip[index].wsm[0] = pchip->wsm[0].csr;
+	saved_pchip[index].tba[0] = pchip->tba[0].csr;
+
+	saved_pchip[index].wsba[1] = pchip->wsba[1].csr;
+	saved_pchip[index].wsm[1] = pchip->wsm[1].csr;
+	saved_pchip[index].tba[1] = pchip->tba[1].csr;
+
+	saved_pchip[index].wsba[2] = pchip->wsba[2].csr;
+	saved_pchip[index].wsm[2] = pchip->wsm[2].csr;
+	saved_pchip[index].tba[2] = pchip->tba[2].csr;
+
+	saved_pchip[index].wsba[3] = pchip->wsba[3].csr;
+	saved_pchip[index].wsm[3] = pchip->wsm[3].csr;
+	saved_pchip[index].tba[3] = pchip->tba[3].csr;
 
 	/*
 	 * Set up the PCI->physical memory translation windows.
@@ -350,6 +378,34 @@
 	tsunami_init_one_pchip(TSUNAMI_pchip0, 0);
 	if (TSUNAMI_cchip->csc.csr & 1L<<14)
 		tsunami_init_one_pchip(TSUNAMI_pchip1, 1);
+}
+
+static void
+tsunami_kill_one_pchip(tsunami_pchip *pchip, int index)
+{
+	pchip->wsba[0].csr = saved_pchip[index].wsba[0];
+	pchip->wsm[0].csr = saved_pchip[index].wsm[0];
+	pchip->tba[0].csr = saved_pchip[index].tba[0];
+
+	pchip->wsba[1].csr = saved_pchip[index].wsba[1];
+	pchip->wsm[1].csr = saved_pchip[index].wsm[1];
+	pchip->tba[1].csr = saved_pchip[index].tba[1];
+
+	pchip->wsba[2].csr = saved_pchip[index].wsba[2];
+	pchip->wsm[2].csr = saved_pchip[index].wsm[2];
+	pchip->tba[2].csr = saved_pchip[index].tba[2];
+
+	pchip->wsba[3].csr = saved_pchip[index].wsba[3];
+	pchip->wsm[3].csr = saved_pchip[index].wsm[3];
+	pchip->tba[3].csr = saved_pchip[index].tba[3];
+}
+
+void
+tsunami_kill_arch(int mode)
+{
+	tsunami_kill_one_pchip(TSUNAMI_pchip0, 0);
+	if (TSUNAMI_cchip->csc.csr & 1L<<14)
+		tsunami_kill_one_pchip(TSUNAMI_pchip1, 1);
 }
 
 static inline void
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/fpreg.c linux/arch/alpha/kernel/fpreg.c
--- v2.3.29/linux/arch/alpha/kernel/fpreg.c	Fri May 14 12:41:22 1999
+++ linux/arch/alpha/kernel/fpreg.c	Wed Dec 31 16:00:00 1969
@@ -1,98 +0,0 @@
-/*
- * arch/alpha/kernel/fpreg.c
- *
- * (C) Copyright 1998 Linus Torvalds
- */
-
-#if defined(__alpha_cix__) || defined(__alpha_fix__)
-#define STT(reg,val)  asm volatile ("ftoit $f"#reg",%0" : "=r"(val));
-#else
-#define STT(reg,val)  asm volatile ("stt $f"#reg",%0" : "=m"(val));
-#endif
-
-unsigned long
-alpha_read_fp_reg (unsigned long reg)
-{
-	unsigned long val;
-
-	switch (reg) {
-	      case  0: STT( 0, val); break;
-	      case  1: STT( 1, val); break;
-	      case  2: STT( 2, val); break;
-	      case  3: STT( 3, val); break;
-	      case  4: STT( 4, val); break;
-	      case  5: STT( 5, val); break;
-	      case  6: STT( 6, val); break;
-	      case  7: STT( 7, val); break;
-	      case  8: STT( 8, val); break;
-	      case  9: STT( 9, val); break;
-	      case 10: STT(10, val); break;
-	      case 11: STT(11, val); break;
-	      case 12: STT(12, val); break;
-	      case 13: STT(13, val); break;
-	      case 14: STT(14, val); break;
-	      case 15: STT(15, val); break;
-	      case 16: STT(16, val); break;
-	      case 17: STT(17, val); break;
-	      case 18: STT(18, val); break;
-	      case 19: STT(19, val); break;
-	      case 20: STT(20, val); break;
-	      case 21: STT(21, val); break;
-	      case 22: STT(22, val); break;
-	      case 23: STT(23, val); break;
-	      case 24: STT(24, val); break;
-	      case 25: STT(25, val); break;
-	      case 26: STT(26, val); break;
-	      case 27: STT(27, val); break;
-	      case 28: STT(28, val); break;
-	      case 29: STT(29, val); break;
-	      case 30: STT(30, val); break;
-	      case 31: STT(31, val); break;
-	}
-	return val;
-}
-
-#if defined(__alpha_cix__) || defined(__alpha_fix__)
-#define LDT(reg,val)  asm volatile ("itoft %0,$f"#reg : : "r"(val));
-#else
-#define LDT(reg,val)  asm volatile ("ldt $f"#reg",%0" : : "m"(val));
-#endif
-
-void
-alpha_write_fp_reg (unsigned long reg, unsigned long val)
-{
-	switch (reg) {
-	      case  0: LDT( 0, val); break;
-	      case  1: LDT( 1, val); break;
-	      case  2: LDT( 2, val); break;
-	      case  3: LDT( 3, val); break;
-	      case  4: LDT( 4, val); break;
-	      case  5: LDT( 5, val); break;
-	      case  6: LDT( 6, val); break;
-	      case  7: LDT( 7, val); break;
-	      case  8: LDT( 8, val); break;
-	      case  9: LDT( 9, val); break;
-	      case 10: LDT(10, val); break;
-	      case 11: LDT(11, val); break;
-	      case 12: LDT(12, val); break;
-	      case 13: LDT(13, val); break;
-	      case 14: LDT(14, val); break;
-	      case 15: LDT(15, val); break;
-	      case 16: LDT(16, val); break;
-	      case 17: LDT(17, val); break;
-	      case 18: LDT(18, val); break;
-	      case 19: LDT(19, val); break;
-	      case 20: LDT(20, val); break;
-	      case 21: LDT(21, val); break;
-	      case 22: LDT(22, val); break;
-	      case 23: LDT(23, val); break;
-	      case 24: LDT(24, val); break;
-	      case 25: LDT(25, val); break;
-	      case 26: LDT(26, val); break;
-	      case 27: LDT(27, val); break;
-	      case 28: LDT(28, val); break;
-	      case 29: LDT(29, val); break;
-	      case 30: LDT(30, val); break;
-	      case 31: LDT(31, val); break;
-	}
-}
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c
--- v2.3.29/linux/arch/alpha/kernel/irq.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/irq.c	Mon Dec  6 17:15:53 1999
@@ -22,15 +22,15 @@
 #include <linux/random.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/irq.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
-#include <asm/irq.h>
 #include <asm/bitops.h>
 #include <asm/machvec.h>
+#include <asm/spinlock.h>
 
 #include "proto.h"
-#include "irq_impl.h"
 
 #define vulp	volatile unsigned long *
 #define vuip	volatile unsigned int *
@@ -42,8 +42,8 @@
 int __local_bh_count;
 #endif
 
-#if NR_IRQS > 64
-#  error Unable to handle more than 64 irq levels.
+#if NR_IRQS > 128
+#  error Unable to handle more than 128 irq levels.
 #endif
 
 #ifdef CONFIG_ALPHA_GENERIC
@@ -60,7 +60,8 @@
 /*
  * Shadow-copy of masked interrupts.
  */
-unsigned long alpha_irq_mask = ~0UL;
+
+unsigned long _alpha_irq_masks[2] = { ~0UL, ~0UL };
 
 /*
  * The ack_irq routine used by 80% of the systems.
@@ -110,6 +111,8 @@
 # define IACK_SC	TSUNAMI_IACK_SC
 #elif defined(CONFIG_ALPHA_POLARIS)
 # define IACK_SC	POLARIS_IACK_SC
+#elif defined(CONFIG_ALPHA_IRONGATE)
+# define IACK_SC        IRONGATE_IACK_SC
 #else
   /* This is bogus but necessary to get it to compile on all platforms. */
 # define IACK_SC	1L
@@ -179,19 +182,22 @@
  */
 
 static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL};
-static struct irqaction *irq_action[NR_IRQS];
+spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { [0 ... NR_IRQS-1] = {0,} };
 
 
 static inline void
 mask_irq(unsigned long irq)
 {
-	alpha_mv.update_irq_hw(irq, alpha_irq_mask |= 1UL << irq, 0);
+	set_bit(irq, _alpha_irq_masks);
+	alpha_mv.update_irq_hw(irq, alpha_irq_mask, 0);
 }
 
 static inline void
 unmask_irq(unsigned long irq)
 {
-	alpha_mv.update_irq_hw(irq, alpha_irq_mask &= ~(1UL << irq), 1);
+	clear_bit(irq, _alpha_irq_masks);
+	alpha_mv.update_irq_hw(irq, alpha_irq_mask, 1);
 }
 
 void
@@ -225,12 +231,7 @@
 int
 check_irq(unsigned int irq)
 {
-	struct irqaction **p;
-
-	p = irq_action + irq;
-	if (*p == NULL)
-		return 0;
-	return -EBUSY;
+	return irq_desc[irq].action ? -EBUSY : 0;
 }
 
 int
@@ -248,7 +249,7 @@
 	if (!handler)
 		return -EINVAL;
 
-	p = irq_action + irq;
+	p = &irq_desc[irq].action;
 	action = *p;
 	if (action) {
 		/* Can't share interrupts unless both agree to */
@@ -309,14 +310,14 @@
 		printk("Trying to free reserved IRQ %d\n", irq);
 		return;
 	}
-	for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
+	for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) {
 		if (action->dev_id != dev_id)
 			continue;
 
 		/* Found it - now free it */
 		save_and_cli(flags);
 		*p = action->next;
-		if (!irq[irq_action])
+		if (!irq_desc[irq].action)
 			mask_irq(irq);
 		restore_flags(flags);
 		kfree(action);
@@ -339,7 +340,7 @@
 #endif
 
 	for (i = 0; i < NR_IRQS; i++) {
-		action = irq_action[i];
+		action = irq_desc[i].action;
 		if (!action) 
 			continue;
 		p += sprintf(p, "%3d: ",i);
@@ -387,8 +388,6 @@
 
 static void show(char * str, void *where);
 
-#define SYNC_OTHER_CPUS(x)	udelay((x)+1);
-
 static inline void
 wait_on_irq(int cpu, void *where)
 {
@@ -409,7 +408,6 @@
 
 		/* Duh, we have to loop. Release the lock to avoid deadlocks */
 		spin_unlock(&global_irq_lock);
-		mb();
 
 		for (;;) {
 			if (!--count) {
@@ -417,7 +415,7 @@
 				count = MAXCOUNT;
 			}
 			__sti();
-			SYNC_OTHER_CPUS(cpu);
+			udelay(1); /* make sure to run pending irqs */
 			__cli();
 
 			if (atomic_read(&global_irq_count))
@@ -437,17 +435,13 @@
 get_irqlock(int cpu, void* where)
 {
 	if (!spin_trylock(&global_irq_lock)) {
-		/* do we already hold the lock? */
-		if (cpu == global_irq_holder) {
-#if 0
-			printk("get_irqlock: already held at %08lx\n",
-			       previous_irqholder);
-#endif
+		/* Do we already hold the lock?  */
+		if (cpu == global_irq_holder)
 			return;
-		}
-		/* Uhhuh.. Somebody else got it. Wait.. */
+		/* Uhhuh.. Somebody else got it.  Wait.  */
 		spin_lock(&global_irq_lock);
 	}
+
 	/*
 	 * Ok, we got the lock bit.
 	 * But that's actually just the easy part.. Now
@@ -543,63 +537,6 @@
         }
 }
 
-#undef INIT_STUCK
-#define INIT_STUCK (1<<26)
-
-#undef STUCK
-#define STUCK							\
-  if (!--stuck) {						\
-    printk("irq_enter stuck (irq=%d, cpu=%d, global=%d)\n",	\
-	   irq, cpu, global_irq_holder);			\
-    stuck = INIT_STUCK;						\
-  }
-
-#undef VERBOSE_IRQLOCK_DEBUGGING
-
-void
-irq_enter(int cpu, int irq)
-{
-#ifdef VERBOSE_IRQLOCK_DEBUGGING
-	extern void smp_show_backtrace_all_cpus(void);
-#endif
-	int stuck = INIT_STUCK;
-
-	hardirq_enter(cpu, irq);
-	barrier();
-	while (spin_is_locked(&global_irq_lock)) {
-		if (cpu == global_irq_holder) {
-			int globl_locked = spin_is_locked(&global_irq_lock);
-			int globl_icount = atomic_read(&global_irq_count);
-			int local_count = local_irq_count(cpu);
-
-			/* It is very important that we load the state
-			   variables before we do the first call to
-			   printk() as printk() could end up changing
-			   them...  */
-
-			printk("CPU[%d]: where [%p] glocked[%d] gicnt[%d]"
-			       " licnt[%d]\n",
-			       cpu, previous_irqholder, globl_locked,
-			       globl_icount, local_count);
-#ifdef VERBOSE_IRQLOCK_DEBUGGING
-			printk("Performing backtrace on all CPUs,"
-			       " write this down!\n");
-			smp_show_backtrace_all_cpus();
-#endif
-			break;
-		}
-		STUCK;
-		barrier();
-	}
-}
-
-void
-irq_exit(int cpu, int irq)
-{
-	hardirq_exit(cpu, irq);
-	release_irqlock(cpu);
-}
-
 static void
 show(char * str, void *where)
 {
@@ -700,12 +637,6 @@
 	}
 #endif
 }
-
-#else /* !__SMP__ */
-
-#define irq_enter(cpu, irq)	(++local_irq_count(cpu))
-#define irq_exit(cpu, irq)	(--local_irq_count(cpu))
-
 #endif /* __SMP__ */
 
 static void
@@ -722,7 +653,7 @@
 	printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
 	printk("Expecting: ");
 	for (i = 0; i < ACTUAL_NR_IRQS; i++)
-		if ((action = irq_action[i]))
+		if ((action = irq_desc[i].action))
 			while (action->handler) {
 				printk("[%s:%d] ", action->name, i);
 				action = action->next;
@@ -776,7 +707,7 @@
 
 	irq_enter(cpu, irq);
 	kstat.irqs[cpu][irq] += 1;
-	action = irq_action[irq];
+	action = irq_desc[irq].action;
 
 	/*
 	 * For normal interrupts, we mask it out, and then ACK it.
@@ -819,11 +750,13 @@
 	unsigned long delay;
 	unsigned int i;
 
-	for (i = ACTUAL_NR_IRQS - 1; i > 0; i--) {
+	/* Handle only the first 64 IRQs here.  This is enough for
+	   [E]ISA, which is the only thing that needs probing anyway.  */
+	for (i = (ACTUAL_NR_IRQS - 1) & 63; i > 0; i--) {
 		if (!(PROBE_MASK & (1UL << i))) {
 			continue;
 		}
-		action = irq_action[i];
+		action = irq_desc[i].action;
 		if (!action) {
 			enable_irq(i);
 			irqs |= (1UL << i);
@@ -852,6 +785,8 @@
 {
 	int i;
 	
+	/* Handle only the first 64 IRQs here.  This is enough for
+	   [E]ISA, which is the only thing that needs probing anyway.  */
         irqs &= alpha_irq_mask;
 	if (!irqs)
 		return 0;
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/irq_impl.h linux/arch/alpha/kernel/irq_impl.h
--- v2.3.29/linux/arch/alpha/kernel/irq_impl.h	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/irq_impl.h	Wed Dec 31 16:00:00 1969
@@ -1,49 +0,0 @@
-/*
- *	linux/arch/alpha/kernel/irq.h
- *
- *	Copyright (C) 1995 Linus Torvalds
- *	Copyright (C) 1998 Richard Henderson
- *
- * This file contains declarations and inline functions for interfacing
- * with the IRQ handling routines in irq.c.
- */
-
-#include <linux/config.h>
-
-#define STANDARD_INIT_IRQ_PROLOG	\
-	outb(0, DMA1_RESET_REG);	\
-	outb(0, DMA2_RESET_REG);	\
-	outb(0, DMA1_CLR_MASK_REG);	\
-	outb(0, DMA2_CLR_MASK_REG)
-
-extern unsigned long alpha_irq_mask;
-
-extern void common_ack_irq(unsigned long irq);
-extern void isa_device_interrupt(unsigned long vector, struct pt_regs * regs);
-extern void srm_device_interrupt(unsigned long vector, struct pt_regs * regs);
-
-extern void handle_irq(int irq, int ack, struct pt_regs * regs);
-
-#define RTC_IRQ    8
-#ifdef CONFIG_RTC
-#define TIMER_IRQ  0			 /* timer is the pit */
-#else
-#define TIMER_IRQ  RTC_IRQ		 /* timer is the rtc */
-#endif
-
-extern char _stext;
-static inline void alpha_do_profile (unsigned long pc)
-{
-	if (prof_buffer && current->pid) {
-		pc -= (unsigned long) &_stext;
-		pc >>= prof_shift;
-		/*
-		 * Don't ignore out-of-bounds PC values silently,
-		 * put them into the last histogram slot, so if
-		 * present, they will show up as a sharp peak.
-		 */
-		if (pc > prof_len - 1)
-			pc = prof_len - 1;
-		atomic_inc((atomic_t *)&prof_buffer[pc]);
-	}
-}
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/machvec_impl.h linux/arch/alpha/kernel/machvec_impl.h
--- v2.3.29/linux/arch/alpha/kernel/machvec_impl.h	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/kernel/machvec_impl.h	Sat Nov 27 15:42:54 1999
@@ -9,11 +9,12 @@
 #include <linux/config.h>
 #include <asm/pgalloc.h>
 
-/* Whee.  Both TSUNAMI and POLARIS don't have an HAE.  Fix things up for
+/* Whee.  IRONGATE, POLARIS and TSUNAMI don't have an HAE.  Fix things up for
    the GENERIC kernel by defining the HAE address to be that of the cache.
    Now we can read and write it as we like.  ;-)  */
-#define TSUNAMI_HAE_ADDRESS	(&alpha_mv.hae_cache)
+#define IRONGATE_HAE_ADDRESS	(&alpha_mv.hae_cache)
 #define POLARIS_HAE_ADDRESS	(&alpha_mv.hae_cache)
+#define TSUNAMI_HAE_ADDRESS	(&alpha_mv.hae_cache)
 
 #if CIA_ONE_HAE_WINDOW
 #define CIA_HAE_ADDRESS		(&alpha_mv.hae_cache)
@@ -91,10 +92,11 @@
 
 #define DO_APECS_IO	IO(APECS,apecs)
 #define DO_CIA_IO	IO(CIA,cia)
+#define DO_IRONGATE_IO	IO(IRONGATE,irongate)
 #define DO_LCA_IO	IO(LCA,lca)
 #define DO_MCPCIA_IO	IO(MCPCIA,mcpcia)
-#define DO_PYXIS_IO	IO(PYXIS,pyxis)
 #define DO_POLARIS_IO	IO(POLARIS,polaris)
+#define DO_PYXIS_IO	IO(PYXIS,pyxis)
 #define DO_T2_IO	IO(T2,t2)
 #define DO_TSUNAMI_IO	IO(TSUNAMI,tsunami)
 
@@ -104,6 +106,7 @@
 
 #define DO_APECS_BUS	BUS(apecs)
 #define DO_CIA_BUS	BUS(cia)
+#define DO_IRONGATE_BUS	BUS(irongate)
 #define DO_LCA_BUS	BUS(lca)
 #define DO_MCPCIA_BUS	BUS(mcpcia)
 #define DO_PYXIS_BUS	BUS(pyxis)
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/pci.c linux/arch/alpha/kernel/pci.c
--- v2.3.29/linux/arch/alpha/kernel/pci.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/kernel/pci.c	Mon Dec  6 17:15:53 1999
@@ -57,11 +57,32 @@
 	dev->class = PCI_CLASS_BRIDGE_ISA;
 }
 
+static void __init
+quirk_vga_enable_rom(struct pci_dev *dev)
+{
+	/* If it's a VGA, enable its BIOS ROM at C0000.
+	   But if its a Cirrus 543x/544x DISABLE it, since
+	   enabling ROM disables the memory... */
+	if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA &&
+	    /* But if its a Cirrus 543x/544x DISABLE it */
+	    (dev->vendor != PCI_VENDOR_ID_CIRRUS ||
+	     (dev->device < 0x00a0) || (dev->device > 0x00ac)))
+	{
+		u32 reg;
+
+		pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+		reg |= PCI_ROM_ADDRESS_ENABLE;
+		pci_write_config_dword(dev, dev->rom_base_reg, reg);
+		dev->resource[PCI_ROM_RESOURCE].flags |= PCI_ROM_ADDRESS_ENABLE;
+	}
+}
+
 struct pci_fixup pcibios_fixups[] __initdata = {
 	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375,
 	  quirk_eisa_bridge },
 	{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378,
 	  quirk_isa_bridge },
+	{ PCI_FIXUP_FINAL, PCI_ANY_ID, PCI_ANY_ID, quirk_vga_enable_rom },
 	{ 0 }
 };
 
@@ -70,13 +91,15 @@
 #define KB			1024
 #define MB			(1024*KB)
 #define GB			(1024*MB)
-unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
-			     unsigned long start, unsigned long size)
+
+void
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
 {
+	struct pci_dev * dev = data;
 	unsigned long alignto;
+	unsigned long start = res->start;
 
-	if (res->flags & IORESOURCE_IO)
-	{
+	if (res->flags & IORESOURCE_IO) {
 		/*
 		 * Aligning to 0x800 rather than the minimum base of
 		 * 0x400 is an attempt to avoid having devices in 
@@ -88,8 +111,7 @@
 		alignto = MAX(0x800, size);
 		start = ALIGN(start, alignto);
 	}
-	else if	(res->flags & IORESOURCE_MEM)
-	{
+	else if	(res->flags & IORESOURCE_MEM) {
 		/*
 		 * The following holds at least for the Low Cost
 		 * Alpha implementation of the PCI interface:
@@ -105,17 +127,17 @@
 		 * address space must be accessed through
 		 * dense memory space only!
 		 */
-		/* align to multiple of size of minimum base */
+
+		/* Align to multiple of size of minimum base.  */
 		alignto = MAX(0x1000, size);
 		start = ALIGN(start, alignto);
-		if (size > 7 * 16*MB)
+		if (size > 7 * 16*MB) {
 			printk(KERN_WARNING "PCI: dev %s "
 			       "requests %ld bytes of contiguous "
 			       "address space---don't use sparse "
 			       "memory accesses on this device!\n",
 			       dev->name, size);
-		else
-		{
+		} else {
 			if (((start / (16*MB)) & 0x7) == 0) {
 				start &= ~(128*MB - 1);
 				start += 16*MB;
@@ -129,7 +151,7 @@
 		}
 	}
 
-	return start;
+	res->start = start;
 }
 #undef MAX
 #undef ALIGN
@@ -144,14 +166,13 @@
 static void __init
 pcibios_assign_special(struct pci_dev * dev)
 {
+	int i;
+
 	/* The first three resources of an IDE controler are often magic, 
 	   so leave them unchanged.  This is true, for instance, of the
 	   Contaq 82C693 as seen on SX164 and DP264.  */
 
-	if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE)
-	{
-		int i;
-
+	if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE) {
 		/* Resource 1 of IDE controller is the address of HD_CMD
 		   register which actually occupies a single byte (0x3f6
 		   for ide0) in reported 0x3f4-3f7 range. We have to fix
@@ -163,6 +184,16 @@
 			if (dev->resource[i].flags && dev->resource[i].start)
 				pci_claim_resource(dev, i);
 	}
+	/*
+	 * We don't have code that will init the CYPRESS bridge correctly
+	 * so we do the next best thing, and depend on the previous
+	 * console code to do the right thing, and ignore it here... :-\
+	 */
+	else if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
+		 dev->device == PCI_DEVICE_ID_CONTAQ_82C693)
+		for (i = 0; i < PCI_NUM_RESOURCES; i++)
+			if (dev->resource[i].flags && dev->resource[i].start)
+				pci_claim_resource(dev, i);
 }
 
 
@@ -217,9 +248,10 @@
 
 	bus->resource[0] = hose->io_space;
 	bus->resource[1] = hose->mem_space;
-	for (dev = bus->devices; dev; dev = dev->sibling)
+	for (dev = bus->devices; dev; dev = dev->sibling) {
 		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
 			pcibios_fixup_device_resources(dev, bus);
+	}
 }
 
 void __init
@@ -232,9 +264,10 @@
 	where = PCI_BASE_ADDRESS_0 + (resource * 4);
 	reg = (res->start - root->start) | (res->flags & 0xf);
 	pci_write_config_dword(dev, where, reg);
-	if ((res->flags & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
-	    == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64))
-	{
+	if ((res->flags & (PCI_BASE_ADDRESS_SPACE
+			   | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
+	    == (PCI_BASE_ADDRESS_SPACE_MEMORY
+		| PCI_BASE_ADDRESS_MEM_TYPE_64)) {
 		pci_write_config_dword(dev, where+4, 0);
 		printk(KERN_WARNING "PCI: dev %s type 64-bit\n", dev->name);
 	}
@@ -273,7 +306,8 @@
 }
 
 void __init
-pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
+pcibios_fixup_pbus_ranges(struct pci_bus * bus,
+			  struct pbus_set_ranges_data * ranges)
 {
 	ranges->io_start -= bus->resource[0]->start;
 	ranges->io_end -= bus->resource[0]->start;
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c
--- v2.3.29/linux/arch/alpha/kernel/process.c	Thu Nov 11 20:11:31 1999
+++ linux/arch/alpha/kernel/process.c	Thu Dec  2 15:27:02 1999
@@ -94,8 +94,8 @@
 	}
 }
 
-void
-common_kill_arch (int mode, char *restart_cmd)
+static void
+common_shutdown(int mode, char *restart_cmd)
 {
 	/* The following currently only has any effect on SRM.  We should
 	   fix MILO to understand it.  Should be pretty easy.  Also we can
@@ -141,24 +141,12 @@
 
 #ifdef CONFIG_RTC
 	/* Reset rtc to defaults.  */
-	{
-		unsigned char control;
-
-		cli();
-
-		/* Reset periodic interrupt frequency.  */
-		CMOS_WRITE(0x26, RTC_FREQ_SELECT);
-
-		/* Turn on periodic interrupts.  */
-		control = CMOS_READ(RTC_CONTROL);
-		control |= RTC_PIE;
-		CMOS_WRITE(control, RTC_CONTROL);	
-		CMOS_READ(RTC_INTR_FLAGS);
-
-		sti();
-	}
+	rtc_kill_pit();
 #endif
 
+	if (alpha_mv.kill_arch)
+		alpha_mv.kill_arch(mode);
+
 	if (!alpha_using_srm && mode != LINUX_REBOOT_CMD_RESTART) {
 		/* Unfortunately, since MILO doesn't currently understand
 		   the hwrpb bits above, we can't reliably halt the 
@@ -175,21 +163,23 @@
 void
 machine_restart(char *restart_cmd)
 {
-	alpha_mv.kill_arch(LINUX_REBOOT_CMD_RESTART, restart_cmd);
+	common_shutdown(LINUX_REBOOT_CMD_RESTART, restart_cmd);
 }
 
 void
 machine_halt(void)
 {
-	alpha_mv.kill_arch(LINUX_REBOOT_CMD_HALT, NULL);
+	common_shutdown(LINUX_REBOOT_CMD_HALT, NULL);
 }
 
-void machine_power_off(void)
+void
+machine_power_off(void)
 {
-	alpha_mv.kill_arch(LINUX_REBOOT_CMD_POWER_OFF, NULL);
+	common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL);
 }
 
-void show_regs(struct pt_regs * regs)
+void
+show_regs(struct pt_regs * regs)
 {
 	printk("\nps: %04lx pc: [<%016lx>]\n", regs->ps, regs->pc);
 	printk("rp: [<%016lx>] sp: %p\n", regs->r26, regs+1);
@@ -210,7 +200,8 @@
 /*
  * Re-start a thread when doing execve()
  */
-void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
+void
+start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
 {
 	set_fs(USER_DS);
 	regs->pc = pc;
@@ -221,11 +212,13 @@
 /*
  * Free current thread data structures etc..
  */
-void exit_thread(void)
+void
+exit_thread(void)
 {
 }
 
-void flush_thread(void)
+void
+flush_thread(void)
 {
 	/* Arrange for each exec'ed process to start off with a clean slate
 	   with respect to the FPU.  This is all exceptions disabled.  Note
@@ -236,7 +229,8 @@
 	wrfpcr(FPCR_DYN_NORMAL | FPCR_INVD | FPCR_DZED | FPCR_OVFD | FPCR_INED);
 }
 
-void release_thread(struct task_struct *dead_task)
+void
+release_thread(struct task_struct *dead_task)
 {
 }
 
@@ -249,15 +243,17 @@
  * Notice that "fork()" is implemented in terms of clone,
  * with parameters (SIGCHLD, 0).
  */
-int alpha_clone(unsigned long clone_flags, unsigned long usp,
-		struct switch_stack * swstack)
+int
+alpha_clone(unsigned long clone_flags, unsigned long usp,
+	    struct switch_stack * swstack)
 {
 	if (!usp)
 		usp = rdusp();
 	return do_fork(clone_flags, usp, (struct pt_regs *) (swstack+1));
 }
 
-int alpha_vfork(struct switch_stack * swstack)
+int
+alpha_vfork(struct switch_stack * swstack)
 {
 	return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(),
 			(struct pt_regs *) (swstack+1));
@@ -274,8 +270,9 @@
  * for a kernel fork().
  */
 
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
-	struct task_struct * p, struct pt_regs * regs)
+int
+copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+	    struct task_struct * p, struct pt_regs * regs)
 {
 	extern void ret_from_sys_call(void);
 	extern void ret_from_smp_fork(void);
@@ -313,7 +310,8 @@
 /*
  * fill in the user structure for a core dump..
  */
-void dump_thread(struct pt_regs * pt, struct user * dump)
+void
+dump_thread(struct pt_regs * pt, struct user * dump)
 {
 	/* switch stack follows right below pt_regs: */
 	struct switch_stack * sw = ((struct switch_stack *) pt) - 1;
@@ -370,7 +368,8 @@
 	memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8);
 }
 
-int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
+int
+dump_fpu(struct pt_regs * regs, elf_fpregset_t *r)
 {
 	/* switch stack follows right below pt_regs: */
 	struct switch_stack * sw = ((struct switch_stack *) regs) - 1;
@@ -388,7 +387,8 @@
  *
  * Don't do this at home.
  */
-asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+asmlinkage int
+sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
 	unsigned long a3, unsigned long a4, unsigned long a5,
 	struct pt_regs regs)
 {
@@ -415,7 +415,8 @@
 #define first_sched	((unsigned long) scheduling_functions_start_here)
 #define last_sched	((unsigned long) scheduling_functions_end_here)
 
-unsigned long get_wchan(struct task_struct *p)
+unsigned long
+get_wchan(struct task_struct *p)
 {
 	unsigned long schedule_frame;
 	unsigned long pc;
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/proto.h linux/arch/alpha/kernel/proto.h
--- v2.3.29/linux/arch/alpha/kernel/proto.h	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/kernel/proto.h	Thu Dec  2 15:27:02 1999
@@ -21,6 +21,12 @@
 extern void cia_init_arch(void);
 extern void cia_machine_check(u64, u64, struct pt_regs *);
 
+/* core_irongate.c */
+extern struct pci_ops irongate_pci_ops;
+extern int irongate_pci_clr_err(void);
+extern void irongate_init_arch(void);
+extern void irongate_machine_check(u64, u64, struct pt_regs *);
+
 /* core_lca.c */
 extern struct pci_ops lca_pci_ops;
 extern void lca_init_arch(void);
@@ -29,6 +35,7 @@
 /* core_mcpcia.c */
 extern struct pci_ops mcpcia_pci_ops;
 extern void mcpcia_init_arch(void);
+extern void mcpcia_init_hoses(void);
 extern void mcpcia_machine_check(u64, u64, struct pt_regs *);
 
 /* core_polaris.c */
@@ -49,6 +56,7 @@
 /* core_tsunami.c */
 extern struct pci_ops tsunami_pci_ops;
 extern void tsunami_init_arch(void);
+extern void tsunami_kill_arch(int);
 extern void tsunami_machine_check(u64, u64, struct pt_regs *);
 
 /* setup.c */
@@ -67,6 +75,7 @@
 /* time.c */
 extern void timer_interrupt(int irq, void *dev, struct pt_regs * regs);
 extern void rtc_init_pit(void);
+extern void rtc_kill_pit(void);
 extern void common_init_pit(void);
 extern unsigned long est_cycle_freq;
 
@@ -102,7 +111,6 @@
 extern void entDbg(void);
 
 /* process.c */
-extern void common_kill_arch (int mode, char *reboot_cmd);
 extern void cpu_idle(void) __attribute__((noreturn));
 
 /* ptrace.c */
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/ptrace.c linux/arch/alpha/kernel/ptrace.c
--- v2.3.29/linux/arch/alpha/kernel/ptrace.c	Thu Jul 29 13:37:22 1999
+++ linux/arch/alpha/kernel/ptrace.c	Sat Nov 27 15:42:54 1999
@@ -57,12 +57,6 @@
  *  |	        		     | v
  *  +================================+
  */
-#define PT_REG(reg)	(PAGE_SIZE*2 - sizeof(struct pt_regs)		\
-			 + (long)&((struct pt_regs *)0)->reg)
-
-#define SW_REG(reg)	(PAGE_SIZE*2 - sizeof(struct pt_regs)		\
-			 - sizeof(struct switch_stack)			\
-			 + (long)&((struct switch_stack *)0)->reg)
 
 /* 
  * The following table maps a register index into the stack offset at
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
--- v2.3.29/linux/arch/alpha/kernel/setup.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/kernel/setup.c	Thu Dec  2 15:20:56 1999
@@ -119,12 +119,14 @@
 WEAK(eb64p_mv);
 WEAK(eb66_mv);
 WEAK(eb66p_mv);
+WEAK(eiger_mv);
 WEAK(jensen_mv);
 WEAK(lx164_mv);
 WEAK(miata_mv);
 WEAK(mikasa_mv);
 WEAK(mikasa_primo_mv);
 WEAK(monet_mv);
+WEAK(nautilus_mv);
 WEAK(noname_mv);
 WEAK(noritake_mv);
 WEAK(noritake_primo_mv);
@@ -189,33 +191,32 @@
 #define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
 #define PFN_PHYS(x)	((x) << PAGE_SHIFT)
 #define PFN_MAX		PFN_DOWN(0x80000000)
-static void __init setup_memory(void)
+#define for_each_mem_cluster(memdesc, cluster, i)		\
+	for ((cluster) = (memdesc)->cluster, (i) = 0;		\
+	     (i) < (memdesc)->numclusters; (i)++, (cluster)++)
+
+static void __init
+setup_memory(void)
 {
 	struct memclust_struct * cluster;
 	struct memdesc_struct * memdesc;
-	unsigned long start_pfn, bootmap_size;
+	unsigned long start_pfn, bootmap_size, bootmap_pages, bootmap_start;
+	unsigned long start, end;
 	extern char _end[];
 	int i;
 
-	/* alloc the bootmem after the kernel */
-	start_pfn = PFN_UP(virt_to_phys(_end));
-	SRM_printf("_end %p\n", _end);
-
-	/* find free clusters, and init and free the bootmem accordingly */
-	memdesc = (struct memdesc_struct *) (hwrpb->mddt_offset + (unsigned long) hwrpb);
-
-	for (cluster = memdesc->cluster, i = memdesc->numclusters;
-	     i > 0; i--, cluster++)
-	{
-		unsigned long end;
+	/* Find free clusters, and init and free the bootmem accordingly.  */
+	memdesc = (struct memdesc_struct *)
+	  (hwrpb->mddt_offset + (unsigned long) hwrpb);
 
-		printk("memcluster %d, usage %02lx, start %8lu, end %8lu\n",
+	for_each_mem_cluster(memdesc, cluster, i) {
+		printk("memcluster %d, usage %01lx, start %8lu, end %8lu\n",
 		       i, cluster->usage, cluster->start_pfn,
-		       cluster->numpages);
+		       cluster->start_pfn + cluster->numpages);
 
 		/* Bit 0 is console/PALcode reserved.  Bit 1 is
 		   non-volatile memory -- we might want to mark
-		   this for later */
+		   this for later.  */
 		if (cluster->usage & 3)
 			continue;
 
@@ -223,41 +224,89 @@
 		if (end > max_low_pfn)
 			max_low_pfn = end;
 	}
+
 	/* Enforce maximum of 2GB even if there is more.  Blah.  */
 	if (max_low_pfn > PFN_MAX)
 		max_low_pfn = PFN_MAX;
-	SRM_printf("max_low_pfn %d\n", max_low_pfn);
+	printk("max_low_pfn %ld\n", max_low_pfn);
 
-	/* allocate the bootmem array after the kernel and mark
-	   the whole MM as reserved */
-	bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+	/* Find the end of the kernel memory.  */
+	start_pfn = PFN_UP(virt_to_phys(_end));
+	printk("_end %p, start_pfn %ld\n", _end, start_pfn);
 
-	for (cluster = memdesc->cluster, i = memdesc->numclusters;
-	     i > 0; i--, cluster++)
-	{
-		unsigned long end, start;
+	bootmap_start = -1;
 
-		/* Bit 0 is console/PALcode reserved.  Bit 1 is
-		   non-volatile memory -- we might want to mark
-		   this for later */
+ try_again:
+	if (max_low_pfn <= start_pfn)
+		panic("not enough memory to boot");
+
+	/* We need to know how many physically contigous pages
+	   we'll need for the bootmap.  */
+	bootmap_pages = bootmem_bootmap_pages(max_low_pfn);
+	printk("bootmap size: %ld pages\n", bootmap_pages);
+
+	/* Now find a good region where to allocate the bootmap.  */
+	for_each_mem_cluster(memdesc, cluster, i) {
 		if (cluster->usage & 3)
 			continue;
 
-		start = PFN_PHYS(cluster->start_pfn);
-		if (start < PFN_PHYS(start_pfn) + bootmap_size)
-			start = PFN_PHYS(start_pfn) + bootmap_size;
-		if (PFN_DOWN(start) >= PFN_MAX)
+		start = cluster->start_pfn;
+		end = start + cluster->numpages;
+		if (end <= start_pfn)
 			continue;
+		if (start >= max_low_pfn)
+			continue;
+		if (start < start_pfn)
+			start = start_pfn;
+		if (end > max_low_pfn)
+			end = max_low_pfn;
+		if (end - start >= bootmap_pages) {
+			printk("allocating bootmap in area %ld:%ld\n",
+			       start, start+bootmap_pages);
+			bootmap_start = start;
+			break;
+		}
+	}
+
+	if (bootmap_start == -1) {
+		max_low_pfn >>= 1;
+		printk("bootmap area not found now trying with %ld pages\n",
+		       max_low_pfn);
+		goto try_again;
+	}
 
-		end = PFN_PHYS(cluster->start_pfn + cluster->numpages);
-		if (PFN_DOWN(end) > PFN_MAX)
-			end = PFN_PHYS(PFN_MAX);
+	/* Allocate the bootmap and mark the whole MM as reserved.  */
+	bootmap_size = init_bootmem(bootmap_start, max_low_pfn);
+
+	/* Mark the free regions.  */
+	for_each_mem_cluster(memdesc, cluster, i) {
+		if (cluster->usage & 3)
+			continue;
+
+		start = cluster->start_pfn;
+		if (start < start_pfn)
+			start = start_pfn;
+
+		end = cluster->start_pfn + cluster->numpages;
+		if (end > max_low_pfn)
+			end = max_low_pfn;
 
 		if (start >= end)
 			continue;
-		free_bootmem(start, end-start);
+
+		start = PFN_PHYS(start);
+		end = PFN_PHYS(end);
+
+		free_bootmem(start, end - start);
+		printk("freeing pages %ld:%ld\n",
+		       PFN_UP(start), PFN_DOWN(end));
 	}
 
+	/* Reserve the bootmap memory.  */
+	reserve_bootmem(PFN_PHYS(bootmap_start), bootmap_size);
+	printk("reserving bootmap %ld:%ld\n", bootmap_start,
+	       bootmap_start + PFN_UP(bootmap_size));
+
 #ifdef CONFIG_BLK_DEV_INITRD
 	initrd_start = INITRD_START;
 	if (initrd_start) {
@@ -268,14 +317,38 @@
 		if (initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {
 			printk("initrd extends beyond end of memory "
 			       "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-			       initrd_end, phys_to_virt(PFN_PHYS(max_low_pfn)));
+			       initrd_end,
+			       phys_to_virt(PFN_PHYS(max_low_pfn)));
 			initrd_start = initrd_end = 0;
+		} else {
+			reserve_bootmem(virt_to_phys(initrd_start),
+					INITRD_SIZE);
 		}
-		else
-			reserve_bootmem(virt_to_phys(initrd_start), INITRD_SIZE);
 	}
 #endif /* CONFIG_BLK_DEV_INITRD */
 }
+
+int __init page_is_ram(unsigned long pfn)
+{
+	struct memclust_struct * cluster;
+	struct memdesc_struct * memdesc;
+	int i;
+
+	memdesc = (struct memdesc_struct *) (hwrpb->mddt_offset + (unsigned long) hwrpb);
+	for_each_mem_cluster(memdesc, cluster, i)
+	{
+		if (pfn >= cluster->start_pfn  &&
+		    pfn < cluster->start_pfn + cluster->numpages)
+		{
+			if (cluster->usage & 3)
+				return 0;
+			else
+				return 1;
+		}
+	}
+
+	return 0;
+}
 #undef PFN_UP
 #undef PFN_DOWN
 #undef PFN_PHYS
@@ -288,7 +361,7 @@
 	struct percpu_struct *cpu;
 	char *type_name, *var_name, *p;
 
-	hwrpb = (struct hwrpb_struct*)(IDENT_ADDR + INIT_HWRPB->phys_addr);
+	hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr);
 
 	/* 
 	 * Locate the command line.
@@ -346,19 +419,16 @@
 		      type_name, (*var_name ? " variation " : ""), var_name,
 		      hwrpb->sys_type, hwrpb->sys_variation);
 	}
-	if (vec != &alpha_mv)
+	if (vec != &alpha_mv) {
 		alpha_mv = *vec;
-
+	}
+	
 #ifdef CONFIG_ALPHA_GENERIC
 	/* Assume that we've booted from SRM if we havn't booted from MILO.
 	   Detect the later by looking for "MILO" in the system serial nr.  */
 	alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
 #endif
 
-	SRM_printf("Booting on %s%s%s using machine vector %s\n",
-	       type_name, (*var_name ? " variation " : ""),
-	       var_name, alpha_mv.vector_name);
-
 	printk("Booting "
 #ifdef CONFIG_ALPHA_GENERIC
 	       "GENERIC "
@@ -446,11 +516,13 @@
 	"Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1",
 	"Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake",
 	"Cortex", "29", "Miata", "XXM", "Takara", "Yukon",
-	"Tsunami", "Wildfire", "CUSCO"
+	"Tsunami", "Wildfire", "CUSCO", "Eiger"
 };
 
 static char unofficial_names[][8] = {"100", "Ruffian"};
 
+static char api_names[][16] = {"200", "Nautilus"};
+
 static char eb164_names[][8] = {"EB164", "PC164", "LX164", "SX164", "RX164"};
 static int eb164_indices[] = {0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3,4};
 
@@ -474,7 +546,6 @@
 };
 static int tsunami_indices[] = {0,1,2,3,4,5,6,7,8};
 
-
 static struct alpha_machine_vector * __init
 get_sysvec(long type, long variation, long cpu)
 {
@@ -517,6 +588,7 @@
 		NULL,		/* Tsunami -- see variation.  */
 		NULL,		/* Wildfire */
 		NULL,		/* CUSCO */
+		&eiger_mv,	/* Eiger */
 	};
 
 	static struct alpha_machine_vector *unofficial_vecs[] __initlocaldata =
@@ -525,6 +597,12 @@
 		&ruffian_mv,
 	};
 
+	static struct alpha_machine_vector *api_vecs[] __initlocaldata =
+	{
+		NULL,		/* 200 */
+		&nautilus_mv,
+	};
+
 	static struct alpha_machine_vector *alcor_vecs[] __initlocaldata = 
 	{
 		&alcor_mv, &xlt_mv, &xlt_mv
@@ -573,6 +651,9 @@
 	vec = NULL;
 	if (type < N(systype_vecs)) {
 		vec = systype_vecs[type];
+	} else if ((type > ST_API_BIAS) &&
+		   (type - ST_API_BIAS) < N(api_vecs)) {
+		vec = api_vecs[type - ST_API_BIAS];
 	} else if ((type > ST_UNOFFICIAL_BIAS) &&
 		   (type - ST_UNOFFICIAL_BIAS) < N(unofficial_vecs)) {
 		vec = unofficial_vecs[type - ST_UNOFFICIAL_BIAS];
@@ -646,12 +727,14 @@
 		&eb64p_mv,
 		&eb66_mv,
 		&eb66p_mv,
+		&eiger_mv,
 		&jensen_mv,
 		&lx164_mv,
 		&miata_mv,
 		&mikasa_mv,
 		&mikasa_primo_mv,
 		&monet_mv,
+		&nautilus_mv,
 		&noname_mv,
 		&noritake_mv,
 		&noritake_primo_mv,
@@ -692,6 +775,9 @@
 	   else set type name to family */
 	if (type < N(systype_names)) {
 		*type_name = systype_names[type];
+	} else if ((type > ST_API_BIAS) &&
+		   (type - ST_API_BIAS) < N(api_names)) {
+		*type_name = api_names[type - ST_API_BIAS];
 	} else if ((type > ST_UNOFFICIAL_BIAS) &&
 		   (type - ST_UNOFFICIAL_BIAS) < N(unofficial_names)) {
 		*type_name = unofficial_names[type - ST_UNOFFICIAL_BIAS];
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c
--- v2.3.29/linux/arch/alpha/kernel/smp.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/kernel/smp.c	Mon Dec  6 17:15:53 1999
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
+#include <linux/irq.h>
 
 #include <asm/hwrpb.h>
 #include <asm/ptrace.h>
@@ -32,7 +33,6 @@
 #include <asm/unistd.h>
 
 #include "proto.h"
-#include "irq_impl.h"
 
 
 #define DEBUG_SMP 0
@@ -47,8 +47,8 @@
 
 /* A collection of single bit ipi messages.  */
 static struct {
-	unsigned long bits __cacheline_aligned;
-} ipi_data[NR_CPUS];
+	unsigned long bits ____cacheline_aligned;
+} ipi_data[NR_CPUS] __cacheline_aligned;
 
 enum ipi_message_type {
         IPI_RESCHEDULE,
@@ -56,7 +56,7 @@
         IPI_CPU_STOP,
 };
 
-spinlock_t kernel_flag __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
 
 /* Set to a secondary's cpuid when it comes online.  */
 static unsigned long smp_secondary_alive;
@@ -396,6 +396,16 @@
 	return 0;
 }
 
+static int __init fork_by_hand(void)
+{
+	struct pt_regs regs;
+	/*
+	 * don't care about the regs settings since
+	 * we'll never reschedule the forked task.
+	 */
+	return do_fork(CLONE_VM|CLONE_PID, 0, &regs);
+}
+
 /*
  * Bring one cpu online.
  */
@@ -409,18 +419,25 @@
 	   to kernel_thread is irrelevant -- it's going to start where
 	   HWRPB.CPU_restart says to start.  But this gets all the other
 	   task-y sort of data structures set up like we wish.  */
-	kernel_thread((void *)__smp_callin, NULL, CLONE_PID|CLONE_VM);
+	/*
+	 * We can't use kernel_thread since we must avoid to
+	 * reschedule the child.
+	 */
+	if (fork_by_hand() < 0)
+		panic("failed fork for CPU %d", cpuid);
 
         idle = init_task.prev_task;
         if (!idle)
-                panic("No idle process for CPU %d", cpunum);
-        del_from_runqueue(idle);
-        init_tasks[cpunum] = idle;
-        idle->processor = cpuid;
-
-	/* Schedule the first task manually.  */
-	/* ??? Ingo, what is this?  */
-	idle->has_cpu = 1;
+                panic("No idle process for CPU %d", cpuid);
+
+	idle->processor = cpuid;
+	__cpu_logical_map[cpunum] = cpuid;
+	cpu_number_map[cpuid] = cpunum;
+	idle->has_cpu = 1; /* we schedule the first task manually */
+ 
+	del_from_runqueue(idle);
+	unhash_process(idle);
+	init_tasks[cpunum] = idle;
 
 	DBGS(("smp_boot_one_cpu: CPU %d state 0x%lx flags 0x%lx\n",
 	      cpuid, idle->state, idle->flags));
@@ -442,13 +459,18 @@
 		barrier();
 	}
 
+	/* we must invalidate our stuff as we failed to boot the CPU */
+	__cpu_logical_map[cpunum] = -1;
+	cpu_number_map[cpuid] = -1;
+
+	/* the idle task is local to us so free it as we don't use it */
+	free_task_struct(idle);
+
 	printk(KERN_ERR "SMP: Processor %d is stuck.\n", cpuid);
 	return -1;
 
 alive:
 	/* Another "Red Snapper". */
-	cpu_number_map[cpuid] = cpunum;
-	__cpu_logical_map[cpunum] = cpuid;
 	return 0;
 }
 
@@ -579,16 +601,6 @@
 {
 	/* smp_init sets smp_threads_ready -- that's enough.  */
 	mb();
-}
-
-/*
- * Only broken Intel needs this, thus it should not even be
- * referenced globally.
- */
-
-void __init
-initialize_secondary(void)
-{
 }
 
 
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_alcor.c linux/arch/alpha/kernel/sys_alcor.c
--- v2.3.29/linux/arch/alpha/kernel/sys_alcor.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/sys_alcor.c	Mon Dec  6 17:15:53 1999
@@ -27,7 +27,7 @@
 #include <asm/core_cia.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -176,15 +176,13 @@
 }
 
 static void
-alcor_kill_arch(int mode, char *reboot_cmd)
+alcor_kill_arch(int mode)
 {
 	/* Who said DEC engineer's have no sense of humor? ;-)  */
 	if (alpha_using_srm) {
 		*(vuip) GRU_RESET = 0x0000dead;
 		mb();
 	}
-
-	common_kill_arch(mode, reboot_cmd);
 }
 
 
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_cabriolet.c linux/arch/alpha/kernel/sys_cabriolet.c
--- v2.3.29/linux/arch/alpha/kernel/sys_cabriolet.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/sys_cabriolet.c	Mon Dec  6 17:15:53 1999
@@ -31,7 +31,7 @@
 #include <asm/core_pyxis.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -269,7 +269,7 @@
 	init_irq:		cabriolet_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		cabriolet_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		NULL,
 	pci_map_irq:		cabriolet_map_irq,
 	pci_swizzle:		common_swizzle,
 };
@@ -298,7 +298,6 @@
 	init_irq:		cabriolet_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		cabriolet_init_pci,
-	kill_arch:		common_kill_arch,
 	pci_map_irq:		cabriolet_map_irq,
 	pci_swizzle:		common_swizzle,
 };
@@ -327,7 +326,6 @@
 	init_irq:		cabriolet_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		cabriolet_init_pci,
-	kill_arch:		common_kill_arch,
 	pci_map_irq:		eb66p_map_irq,
 	pci_swizzle:		common_swizzle,
 };
@@ -356,7 +354,6 @@
 	init_irq:		cabriolet_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		alphapc164_init_pci,
-	kill_arch:		common_kill_arch,
 	pci_map_irq:		alphapc164_map_irq,
 	pci_swizzle:		common_swizzle,
 };
@@ -385,7 +382,6 @@
 	init_irq:		cabriolet_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		alphapc164_init_pci,
-	kill_arch:		common_kill_arch,
 	pci_map_irq:		alphapc164_map_irq,
 	pci_swizzle:		common_swizzle,
 };
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_dp264.c linux/arch/alpha/kernel/sys_dp264.c
--- v2.3.29/linux/arch/alpha/kernel/sys_dp264.c	Sat Oct  9 11:47:50 1999
+++ linux/arch/alpha/kernel/sys_dp264.c	Mon Dec  6 17:15:53 1999
@@ -27,7 +27,7 @@
 #include <asm/hwrpb.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -39,28 +39,30 @@
 static void
 dp264_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
 {
-	if (irq >= 16) {
-		volatile unsigned long *csr;
+	volatile unsigned long *csr;
 
-		if (TSUNAMI_bootcpu < 2)
-			if (!TSUNAMI_bootcpu)
-				csr = &TSUNAMI_cchip->dim0.csr;
-			else
-				csr = &TSUNAMI_cchip->dim1.csr;
+	if (TSUNAMI_bootcpu < 2) {
+		if (!TSUNAMI_bootcpu)
+			csr = &TSUNAMI_cchip->dim0.csr;
 		else
-			if (TSUNAMI_bootcpu == 2)
-				csr = &TSUNAMI_cchip->dim2.csr;
-			else
-				csr = &TSUNAMI_cchip->dim3.csr;
-		
-		*csr = ~mask;
-		mb();
-		*csr;
+			csr = &TSUNAMI_cchip->dim1.csr;
+	} else {
+		if (TSUNAMI_bootcpu == 2)
+			csr = &TSUNAMI_cchip->dim2.csr;
+		else
+			csr = &TSUNAMI_cchip->dim3.csr;
+	}
+
+	*csr = ~mask;
+	mb();
+	*csr;
+
+	if (irq < 16) {
+		if (irq >= 8)
+			outb(mask >> 8, 0xA1);	/* ISA PIC2 */
+		else
+			outb(mask, 0x21);	/* ISA PIC1 */
 	}
-	else if (irq >= 8)
-		outb(mask >> 8, 0xA1);	/* ISA PIC2 */
-	else
-		outb(mask, 0x21);	/* ISA PIC1 */
 }
 
 static void
@@ -274,8 +276,19 @@
 	struct pci_controler *hose = dev->sysdata;
 	int irq = COMMON_TABLE_LOOKUP;
 
-	if (irq > 0)
+	if (irq > 0) {
 		irq += 16 * hose->index;
+	} else {
+		/* ??? The Contaq IDE controler on the ISA bridge uses
+		   "legacy" interrupts 14 and 15.  I don't know if anything
+		   can wind up at the same slot+pin on hose1, so we'll
+		   just have to trust whatever value the console might
+		   have assigned.  */
+
+		u8 irq8;
+		pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
+		irq = irq8;
+	}
 
 	return irq;
 }
@@ -418,7 +431,7 @@
 	min_mem_address:	DEFAULT_MEM_BASE,
 
 	nr_irqs:		64,
-	irq_probe_mask:		_PROBE_MASK(64),
+	irq_probe_mask:		TSUNAMI_PROBE_MASK,
 	update_irq_hw:		dp264_update_irq_hw,
 	ack_irq:		common_ack_irq,
 	device_interrupt:	dp264_device_interrupt,
@@ -427,7 +440,7 @@
 	init_irq:		dp264_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		dp264_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		tsunami_kill_arch,
 	pci_map_irq:		dp264_map_irq,
 	pci_swizzle:		common_swizzle,
 };
@@ -445,7 +458,7 @@
 	min_mem_address:	DEFAULT_MEM_BASE,
 
 	nr_irqs:		64,
-	irq_probe_mask:		_PROBE_MASK(64),
+	irq_probe_mask:		TSUNAMI_PROBE_MASK,
 	update_irq_hw:		dp264_update_irq_hw,
 	ack_irq:		common_ack_irq,
 	device_interrupt:	dp264_device_interrupt,
@@ -454,7 +467,7 @@
 	init_irq:		dp264_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		monet_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		tsunami_kill_arch,
 	pci_map_irq:		monet_map_irq,
 	pci_swizzle:		monet_swizzle,
 };
@@ -471,7 +484,7 @@
 	min_mem_address:	DEFAULT_MEM_BASE,
 
 	nr_irqs:		64,
-	irq_probe_mask:		_PROBE_MASK(64),
+	irq_probe_mask:		TSUNAMI_PROBE_MASK,
 	update_irq_hw:		dp264_update_irq_hw,
 	ack_irq:		common_ack_irq,
 	device_interrupt:	dp264_device_interrupt,
@@ -479,8 +492,8 @@
 	init_arch:		tsunami_init_arch,
 	init_irq:		dp264_init_irq,
 	init_pit:		common_init_pit,
-	init_pci:		dp264_init_pci,
-	kill_arch:		common_kill_arch,
+	init_pci:		common_init_pci,
+	kill_arch:		tsunami_kill_arch,
 	pci_map_irq:		webbrick_map_irq,
 	pci_swizzle:		common_swizzle,
 };
@@ -497,7 +510,7 @@
 	min_mem_address:	DEFAULT_MEM_BASE,
 
 	nr_irqs:		64,
-	irq_probe_mask:		_PROBE_MASK(64),
+	irq_probe_mask:		TSUNAMI_PROBE_MASK,
 	update_irq_hw:		clipper_update_irq_hw,
 	ack_irq:		common_ack_irq,
 	device_interrupt:	dp264_device_interrupt,
@@ -506,7 +519,7 @@
 	init_irq:		clipper_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		common_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		tsunami_kill_arch,
 	pci_map_irq:		clipper_map_irq,
 	pci_swizzle:		common_swizzle,
 };
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_eb64p.c linux/arch/alpha/kernel/sys_eb64p.c
--- v2.3.29/linux/arch/alpha/kernel/sys_eb64p.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/sys_eb64p.c	Mon Dec  6 17:15:53 1999
@@ -28,7 +28,7 @@
 #include <asm/core_lca.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -183,7 +183,7 @@
 	init_irq:		eb64p_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		common_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		NULL,
 	pci_map_irq:		eb64p_map_irq,
 	pci_swizzle:		common_swizzle,
 };
@@ -212,7 +212,6 @@
 	init_irq:		eb64p_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		common_init_pci,
-	kill_arch:		common_kill_arch,
 	pci_map_irq:		eb64p_map_irq,
 	pci_swizzle:		common_swizzle,
 };
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_eiger.c linux/arch/alpha/kernel/sys_eiger.c
--- v2.3.29/linux/arch/alpha/kernel/sys_eiger.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/kernel/sys_eiger.c	Mon Dec  6 17:15:53 1999
@@ -0,0 +1,215 @@
+/*
+ *	linux/arch/alpha/kernel/sys_eiger.c
+ *
+ *	Copyright (C) 1995 David A Rusling
+ *	Copyright (C) 1996, 1999 Jay A Estabrook
+ *	Copyright (C) 1998, 1999 Richard Henderson
+ *	Copyright (C) 1999 Iain Grant
+ *
+ * Code supporting the EIGER (EV6+TSUNAMI).
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/pgtable.h>
+#include <asm/core_tsunami.h>
+#include <asm/hwrpb.h>
+
+#include "proto.h"
+#include <asm/hw_irq.h>
+#include "pci_impl.h"
+#include "machvec_impl.h"
+
+
+/*
+ * HACK ALERT! only the boot cpu is used for interrupts.
+ */
+
+static void
+eiger_update_irq_hw(unsigned long irq, unsigned long unused, int unmask_p)
+{
+	unsigned int regaddr;
+	unsigned long mask;
+
+	if (irq <= 15) {
+		if (irq <= 7)
+			outb(alpha_irq_mask, 0x21);		/* ISA PIC1 */
+		else
+			outb(alpha_irq_mask >> 8, 0xA1);	/* ISA PIC2 */
+	} else {
+		if (irq > 63)
+			mask = _alpha_irq_masks[1] << 16;
+		else
+			mask = _alpha_irq_masks[0] >> ((irq - 16) & 0x30);
+
+		regaddr = 0x510 + (((irq - 16) >> 2) & 0x0c);
+
+		outl(mask & 0xffff0000UL, regaddr);
+	}
+}
+
+static void
+eiger_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+	unsigned intstatus;
+
+	/*
+	 * The PALcode will have passed us vectors 0x800 or 0x810,
+	 * which are fairly arbitrary values and serve only to tell
+	 * us whether an interrupt has come in on IRQ0 or IRQ1. If
+	 * it's IRQ1 it's a PCI interrupt; if it's IRQ0, it's
+	 * probably ISA, but PCI interrupts can come through IRQ0
+	 * as well if the interrupt controller isn't in accelerated
+	 * mode.
+	 *
+	 * OTOH, the accelerator thing doesn't seem to be working
+	 * overly well, so what we'll do instead is try directly
+	 * examining the Master Interrupt Register to see if it's a
+	 * PCI interrupt, and if _not_ then we'll pass it on to the
+	 * ISA handler.
+	 */
+
+	intstatus = inw(0x500) & 15;
+	if (intstatus) {
+		/*
+		 * This is a PCI interrupt. Check each bit and
+		 * despatch an interrupt if it's set.
+		 */
+
+		if (intstatus & 8) handle_irq(16+3, 16+3, regs);
+		if (intstatus & 4) handle_irq(16+2, 16+2, regs);
+		if (intstatus & 2) handle_irq(16+1, 16+1, regs);
+		if (intstatus & 1) handle_irq(16+0, 16+0, regs);
+	} else {
+		isa_device_interrupt (vector, regs);
+	}
+}
+
+static void
+eiger_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+   int irq = (vector - 0x800) >> 4;
+   handle_irq(irq, irq, regs);
+}
+
+static void __init
+eiger_init_irq(void)
+{
+	outb(0, DMA1_RESET_REG);
+	outb(0, DMA2_RESET_REG);
+	outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
+	outb(0, DMA2_MASK_REG);
+
+	if (alpha_using_srm)
+		alpha_mv.device_interrupt = eiger_srm_device_interrupt;
+
+	eiger_update_irq_hw(16, alpha_irq_mask, 0);
+
+	enable_irq(2);
+}
+
+static int __init
+eiger_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	u8 irq_orig;
+
+	/* The SRM console has already calculated out the IRQ value's for
+	   option cards. As this works lets just read in the value already
+	   set and change it to a useable value by Linux.
+
+	   All the IRQ values generated by the console are greater than 90,
+	   so we subtract 80 because it is (90 - allocated ISA IRQ's).  */
+
+	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq_orig);
+
+	return irq_orig - 0x80;
+}
+
+static u8 __init
+eiger_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+	struct pci_controler *hose = dev->sysdata;
+	int slot, pin = *pinp;
+	int bridge_count = 0;
+
+	/* Find the number of backplane bridges.  */
+	int backplane = inw(0x502) & 0x0f;
+
+	switch (backplane)
+	{
+	   case 0x00: bridge_count = 0; break; /* No bridges */
+	   case 0x01: bridge_count = 1; break; /* 1 */
+	   case 0x03: bridge_count = 2; break; /* 2 */
+	   case 0x07: bridge_count = 3; break; /* 3 */
+	   case 0x0f: bridge_count = 4; break; /* 4 */
+	};
+
+	/*  Check first for the built-in bridges on hose 0. */
+	if (hose->index == 0
+	    && PCI_SLOT(dev->bus->self->devfn) > 20-bridge_count) {
+		slot = PCI_SLOT(dev->devfn);
+	} else {
+		/* Must be a card-based bridge.  */
+		do {
+			/* Check for built-in bridges on hose 0. */
+			if (hose->index == 0
+			    && (PCI_SLOT(dev->bus->self->devfn)
+				> 20 - bridge_count)) {
+                  		slot = PCI_SLOT(dev->devfn);
+				break;
+			}
+			pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+
+			/* Move up the chain of bridges.  */
+			dev = dev->bus->self;
+			/* Slot of the next bridge.  */
+			slot = PCI_SLOT(dev->devfn);
+		} while (dev->bus->self);
+	}
+	*pinp = pin;
+	return slot;
+}
+
+/*
+ * The System Vectors
+ */
+
+struct alpha_machine_vector eiger_mv __initmv = {
+	vector_name:		"Eiger",
+	DO_EV6_MMU,
+	DO_DEFAULT_RTC,
+	DO_TSUNAMI_IO,
+	DO_TSUNAMI_BUS,
+	machine_check:		tsunami_machine_check,
+	max_dma_address:	ALPHA_MAX_DMA_ADDRESS,
+	min_io_address:		DEFAULT_IO_BASE,
+	min_mem_address:	DEFAULT_MEM_BASE,
+
+	nr_irqs:		128,
+	irq_probe_mask:		TSUNAMI_PROBE_MASK,
+	update_irq_hw:		eiger_update_irq_hw,
+	ack_irq:		common_ack_irq,
+	device_interrupt:	eiger_device_interrupt,
+
+	init_arch:		tsunami_init_arch,
+	init_irq:		eiger_init_irq,
+	init_pit:		common_init_pit,
+	init_pci:		common_init_pci,
+	kill_arch:		tsunami_kill_arch,
+	pci_map_irq:		eiger_map_irq,
+	pci_swizzle:		eiger_swizzle,
+};
+ALIAS_MV(eiger)
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_jensen.c linux/arch/alpha/kernel/sys_jensen.c
--- v2.3.29/linux/arch/alpha/kernel/sys_jensen.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/sys_jensen.c	Mon Dec  6 17:15:53 1999
@@ -28,7 +28,7 @@
 #include <asm/pgtable.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "machvec_impl.h"
 
 
@@ -140,6 +140,6 @@
 	init_irq:		jensen_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		NULL,
-	kill_arch:		common_kill_arch,
+	kill_arch:		NULL,
 };
 ALIAS_MV(jensen)
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_miata.c linux/arch/alpha/kernel/sys_miata.c
--- v2.3.29/linux/arch/alpha/kernel/sys_miata.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/sys_miata.c	Mon Dec  6 17:15:53 1999
@@ -25,7 +25,7 @@
 #include <asm/core_pyxis.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -274,14 +274,13 @@
 }
 
 static void
-miata_kill_arch (int mode, char *reboot_cmd)
+miata_kill_arch(int mode)
 {
 	/* Who said DEC engineers have no sense of humor? ;-)  */
 	if (alpha_using_srm) {
 		*(vuip) PYXIS_RESET = 0x0000dead;
 		mb();
 	}
-	common_kill_arch(mode, reboot_cmd);
 }
 
 
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_mikasa.c linux/arch/alpha/kernel/sys_mikasa.c
--- v2.3.29/linux/arch/alpha/kernel/sys_mikasa.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/sys_mikasa.c	Mon Dec  6 17:15:53 1999
@@ -28,7 +28,7 @@
 #include <asm/core_cia.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -194,7 +194,7 @@
 	init_irq:		mikasa_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		common_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		NULL,
 	pci_map_irq:		mikasa_map_irq,
 	pci_swizzle:		common_swizzle,
 };
@@ -223,7 +223,6 @@
 	init_irq:		mikasa_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		common_init_pci,
-	kill_arch:		common_kill_arch,
 	pci_map_irq:		mikasa_map_irq,
 	pci_swizzle:		common_swizzle,
 };
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_nautilus.c linux/arch/alpha/kernel/sys_nautilus.c
--- v2.3.29/linux/arch/alpha/kernel/sys_nautilus.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/kernel/sys_nautilus.c	Mon Dec  6 17:15:53 1999
@@ -0,0 +1,535 @@
+/*
+ *	linux/arch/alpha/kernel/sys_nautilus.c
+ *
+ *	Copyright (C) 1995 David A Rusling
+ *	Copyright (C) 1998 Richard Henderson
+ *	Copyright (C) 1999 Alpha Processor, Inc.,
+ *		(David Daniel, Stig Telfer, Soohoon Lee)
+ *
+ * Code supporting NAUTILUS systems.
+ *
+ *
+ * NAUTILUS has the following I/O features:
+ *
+ * a) Driven by AMD 751 aka IRONGATE (northbridge):
+ *     4 PCI slots
+ *     1 AGP slot
+ *
+ * b) Driven by ALI M1543C (southbridge)
+ *     2 ISA slots
+ *     2 IDE connectors
+ *     1 dual drive capable FDD controller
+ *     2 serial ports
+ *     1 ECP/EPP/SP parallel port
+ *     2 USB ports
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/reboot.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/pgtable.h>
+#include <asm/core_irongate.h>
+#include <asm/hwrpb.h>
+
+#include "proto.h"
+#include <asm/hw_irq.h>
+#include "pci_impl.h"
+#include "machvec_impl.h"
+
+#define dev2hose(d) (bus2hose[(d)->bus->number]->pci_hose_index)
+
+static void
+nautilus_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+	/* The timer is connected to PIC interrupt line also on Nautilus.
+	   The timer interrupt handler enables the PIC line, so in order
+	   not to get multiple timer interrupt sources, we mask it out
+	   at all times.  */
+
+	mask |= 0x100;
+	if (irq >= 8)
+		outb(mask >> 8, 0xA1);
+	else
+		outb(mask, 0x21);
+}
+
+static void __init
+nautilus_init_irq(void)
+{
+	STANDARD_INIT_IRQ_PROLOG;
+
+	enable_irq(2);			/* enable cascade */
+	disable_irq(8);
+}
+
+static int __init
+nautilus_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	/* Preserve the IRQ set up by the console.  */
+
+	u8 irq;
+	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
+	return irq;
+}
+
+void
+nautilus_kill_arch(int mode)
+{
+	u8 tmp;
+
+	if (mode == LINUX_REBOOT_CMD_RESTART) {
+		pcibios_read_config_byte(0, 0x38, 0x43, &tmp);
+		pcibios_write_config_byte(0, 0x38, 0x43, tmp | 0x80);
+		outb(1, 0x92);
+		outb(0, 0x92);
+	}
+}
+
+/* Machine check handler code
+ *
+ * Perform analysis of a machine check that was triggered by the EV6
+ * CPU's fault-detection mechanism.
+ */
+
+/* IPR structures for EV6, containing the necessary data for the
+ * machine check handler to unpick the logout frame
+ */
+
+/* I_STAT */
+
+#define EV6__I_STAT__PAR                ( 1 << 29 )
+
+/* MM_STAT */
+
+#define EV6__MM_STAT__DC_TAG_PERR       ( 1 << 10 )
+
+/* DC_STAT */
+
+#define EV6__DC_STAT__SEO               ( 1 << 4 )
+#define EV6__DC_STAT__ECC_ERR_LD        ( 1 << 3 )
+#define EV6__DC_STAT__ECC_ERR_ST        ( 1 << 2 )
+#define EV6__DC_STAT__TPERR_P1          ( 1 << 1 )
+#define EV6__DC_STAT__TPERR_P0          ( 1      )
+
+/* C_STAT */
+
+#define EV6__C_STAT__BC_PERR            ( 0x01 )
+#define EV6__C_STAT__DC_PERR            ( 0x02 )
+#define EV6__C_STAT__DSTREAM_MEM_ERR    ( 0x03 )
+#define EV6__C_STAT__DSTREAM_BC_ERR     ( 0x04 )
+#define EV6__C_STAT__DSTREAM_DC_ERR     ( 0x05 )
+#define EV6__C_STAT__PROBE_BC_ERR0      ( 0x06 )
+#define EV6__C_STAT__PROBE_BC_ERR1      ( 0x07 )
+#define EV6__C_STAT__ISTREAM_MEM_ERR    ( 0x0B )
+#define EV6__C_STAT__ISTREAM_BC_ERR     ( 0x0C )
+#define EV6__C_STAT__DSTREAM_MEM_DBL    ( 0x13 )
+#define EV6__C_STAT__DSTREAM_BC_DBL     ( 0x14 )
+#define EV6__C_STAT__ISTREAM_MEM_DBL    ( 0x1B )
+#define EV6__C_STAT__ISTREAM_BC_DBL     ( 0x1C )
+
+
+/* Take the two syndromes from the CBOX error chain and convert them
+ * into a bit number.  */
+
+/* NOTE - since I don't know of any difference between C0 and C1 I
+   just ignore C1, since in all cases I've seen so far they are
+   identical.  */
+
+static const unsigned char ev6_bit_to_syndrome[72] =
+{
+	0xce, 0xcb, 0xd3, 0xd5, 0xd6, 0xd9, 0xda, 0xdc,     /* 0 */
+	0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x31, 0x34,     /* 8 */
+	0x0e, 0x0b, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c,     /* 16 */
+	0xe3, 0xe5, 0xe6, 0xe9, 0xea, 0xec, 0xf1, 0xf4,     /* 24 */
+	0x4f, 0x4a, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d,     /* 32 */
+	0xa2, 0xa4, 0xa7, 0xa8, 0xab, 0xad, 0xb0, 0xb5,     /* 40 */
+	0x8f, 0x8a, 0x92, 0x94, 0x97, 0x98, 0x9b, 0x9d,     /* 48 */
+	0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x70, 0x75,     /* 56 */
+	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80      /* 64 */
+};
+
+
+static int ev6_syn2bit(unsigned long c0, unsigned long c1)
+{
+	int bit;
+
+	for (bit = 0; bit < 72; bit++)
+		if (ev6_bit_to_syndrome[bit] == c0)	return bit;
+	for (bit = 0; bit < 72; bit++)
+		if (ev6_bit_to_syndrome[bit] == c1)	return bit + 64;
+
+	return -1;                  /* not found */
+}
+
+
+/* Single bit ECC errors are categorized here.  */
+
+#if 0
+static const char *interr = "CPU internal error";
+static const char *slotb= "Slot-B error";
+static const char *membus= "Memory/EV6-bus error";
+#else
+static const char *interr = "";
+static const char *slotb = "";
+static const char *membus = "";
+#endif
+
+static void
+ev6_crd_interp(char *interp, struct el_common_EV6_mcheck * L)
+{
+	/* Icache data or tag parity error.  */
+	if (L->I_STAT & EV6__I_STAT__PAR) {
+		sprintf(interp, "%s: I_STAT[PAR]\n "
+			"Icache data or tag parity error", interr);
+		return;
+	}
+
+	/* Dcache tag parity error (on issue) (DFAULT).  */
+	if (L->MM_STAT & EV6__MM_STAT__DC_TAG_PERR) {
+		sprintf(interp, "%s: MM_STAT[DC_TAG_PERR]\n "
+			"Dcache tag parity error(on issue)", interr);
+		return;
+	}
+
+	/* Errors relating to D-stream set non-zero DC_STAT.
+	   Mask CRD bits.  */
+	switch (L->DC_STAT & (EV6__DC_STAT__ECC_ERR_ST
+			      | EV6__DC_STAT__ECC_ERR_LD)) {
+	case EV6__DC_STAT__ECC_ERR_ST:
+		/* Dcache single-bit ECC error on small store */
+		sprintf(interp, "%s: DC_STAT[ECC_ERR_ST]\n "
+			"Dcache single-bit ECC error on small store", interr);
+		return;
+
+	case EV6__DC_STAT__ECC_ERR_LD:
+		switch (L->C_STAT) {
+		case 0:
+			/* Dcache single-bit error on speculative load */
+			/* Bcache victim read on Dcache/Bcache miss */
+			sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT=0\n "
+				"Dcache single-bit ECC error on speculative load",
+				slotb);
+			return;
+
+		case EV6__C_STAT__DSTREAM_DC_ERR:
+			/* Dcache single bit error on load */
+			sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT[DSTREAM_DC_ERR]\n"
+				" Dcache single-bit ECC error on speculative load, bit %d",
+				interr, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+			return;
+
+		case EV6__C_STAT__DSTREAM_BC_ERR:
+			/* Bcache single-bit error on Dcache fill */
+			sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT[DSTREAM_BC_ERR]\n"
+				" Bcache single-bit error on Dcache fill, bit %d",
+				slotb, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+			return;
+
+		case EV6__C_STAT__DSTREAM_MEM_ERR:
+			/* Memory single-bit error on Dcache fill */
+			sprintf(interp, "%s (to Dcache): DC_STAT[ECC_ERR_LD] "
+				"C_STAT[DSTREAM_MEM_ERR]\n "
+				"Memory single-bit error on Dcache fill, "
+				"Address 0x%lX, bit %d",
+				membus, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
+							       L->DC1_SYNDROME));
+			return;
+		}
+	}
+
+	/* I-stream, other misc errors go on C_STAT alone */
+	switch (L->C_STAT) {
+	case EV6__C_STAT__ISTREAM_BC_ERR:
+		/* Bcache single-bit error on Icache fill (also MCHK) */
+		sprintf(interp, "%s: C_STAT[ISTREAM_BC_ERR]\n "
+			"Bcache single-bit error on Icache fill, bit %d",
+			slotb, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+		return;
+
+	case EV6__C_STAT__ISTREAM_MEM_ERR:
+		/* Memory single-bit error on Icache fill (also MCHK) */
+		sprintf(interp, "%s : C_STATISTREAM_MEM_ERR]\n "
+			"Memory single-bit error on Icache fill "
+			"addr 0x%lX, bit %d",
+			membus, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
+						       L->DC1_SYNDROME));
+		return;
+
+	case EV6__C_STAT__PROBE_BC_ERR0:
+	case EV6__C_STAT__PROBE_BC_ERR1:
+		/* Bcache single-bit error on a probe hit */
+		sprintf(interp, "%s: C_STAT[PROBE_BC_ERR]\n "
+			"Bcache single-bit error on a probe hit, "
+			"addr 0x%lx, bit %d",
+			slotb, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
+						      L->DC1_SYNDROME));
+		return;
+	}
+}
+
+static void
+ev6_mchk_interp(char *interp, struct el_common_EV6_mcheck * L)
+{
+	/* Machine check errors described by DC_STAT */
+	switch (L->DC_STAT) {
+	case EV6__DC_STAT__TPERR_P0:
+	case EV6__DC_STAT__TPERR_P1:
+		/* Dcache tag parity error (on retry) */
+		sprintf(interp, "%s: DC_STAT[TPERR_P0|TPERR_P1]\n "
+			"Dcache tag parity error(on retry)", interr);
+		return;
+
+	case EV6__DC_STAT__SEO:
+		/* Dcache second error on store */
+		sprintf(interp, "%s: DC_STAT[SEO]\n "
+			"Dcache second error during mcheck", interr);
+		return;
+	}
+
+	/* Machine check errors described by C_STAT */
+	switch (L->C_STAT) {
+	case EV6__C_STAT__DC_PERR:
+		/* Dcache duplicate tag parity error */
+		sprintf(interp, "%s: C_STAT[DC_PERR]\n "
+			"Dcache duplicate tag parity error at 0x%lX",
+			interr, L->C_ADDR);
+		return;
+
+	case EV6__C_STAT__BC_PERR:
+		/* Bcache tag parity error */
+		sprintf(interp, "%s: C_STAT[BC_PERR]\n "
+			"Bcache tag parity error at 0x%lX",
+			slotb, L->C_ADDR);
+		return;
+
+	case EV6__C_STAT__ISTREAM_BC_ERR:
+		/* Bcache single-bit error on Icache fill (also CRD) */
+		sprintf(interp, "%s: C_STAT[ISTREAM_BC_ERR]\n "
+			"Bcache single-bit error on Icache fill 0x%lX bit %d",
+			slotb, L->C_ADDR,
+			ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+		return;
+
+
+	case EV6__C_STAT__ISTREAM_MEM_ERR:
+		/* Memory single-bit error on Icache fill (also CRD) */
+		sprintf(interp, "%s: C_STAT[ISTREAM_MEM_ERR]\n "
+			"Memory single-bit error on Icache fill 0x%lX, bit %d",
+			membus, L->C_ADDR,
+			ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+		return;
+
+
+	case EV6__C_STAT__ISTREAM_BC_DBL:
+		/* Bcache double-bit error on Icache fill */
+		sprintf(interp, "%s: C_STAT[ISTREAM_BC_DBL]\n "
+			"Bcache double-bit error on Icache fill at 0x%lX",
+			slotb, L->C_ADDR);
+		return;
+	case EV6__C_STAT__DSTREAM_BC_DBL:
+		/* Bcache double-bit error on Dcache fill */
+		sprintf(interp, "%s: C_STAT[DSTREAM_BC_DBL]\n "
+			"Bcache double-bit error on Dcache fill at 0x%lX",
+			slotb, L->C_ADDR);
+		return;
+
+	case EV6__C_STAT__ISTREAM_MEM_DBL:
+		/* Memory double-bit error on Icache fill */
+		sprintf(interp, "%s: C_STAT[ISTREAM_MEM_DBL]\n "
+			"Memory double-bit error on Icache fill at 0x%lX",
+			membus, L->C_ADDR);
+		return;
+
+	case EV6__C_STAT__DSTREAM_MEM_DBL:
+		/* Memory double-bit error on Dcache fill */
+		sprintf(interp, "%s: C_STAT[DSTREAM_MEM_DBL]\n "
+			"Memory double-bit error on Dcache fill at 0x%lX",
+			membus, L->C_ADDR);
+		return;
+	}
+}
+
+static void
+ev6_cpu_machine_check(unsigned long vector, struct el_common_EV6_mcheck *L,
+		      struct pt_regs *regs)
+{
+	char interp[80];
+
+	/* This is verbose and looks intimidating.  Should it be printed for
+	   corrected (CRD) machine checks? */
+
+	printk(KERN_CRIT "PALcode logout frame:  "
+	       "MCHK_Code       %d  "
+	       "MCHK_Frame_Rev  %d\n"
+	       "I_STAT  %016lx  "
+	       "DC_STAT %016lx  "
+	       "C_ADDR  %016lx\n"
+	       "SYND1   %016lx  "
+	       "SYND0   %016lx  "
+	       "C_STAT  %016lx\n"
+	       "C_STS   %016lx  "
+	       "RES     %016lx  "
+	       "EXC_ADDR%016lx\n"
+	       "IER_CM  %016lx  "
+	       "ISUM    %016lx  "
+	       "MM_STAT %016lx\n"
+	       "PALBASE %016lx  "
+	       "I_CTL   %016lx  "
+	       "PCTX    %016lx\n"
+	       "CPU registers: "
+	       "PC      %016lx  "
+	       "Return  %016lx\n",
+	       L->MCHK_Code, L->MCHK_Frame_Rev, L->I_STAT, L->DC_STAT,
+	       L->C_ADDR, L->DC1_SYNDROME, L->DC0_SYNDROME, L->C_STAT,
+	       L->C_STS, L->RESERVED0, L->EXC_ADDR, L->IER_CM, L->ISUM,
+	       L->MM_STAT, L->PAL_BASE, L->I_CTL, L->PCTX,
+	       regs->pc, regs->r26);
+
+	/* Attempt an interpretation on the meanings of the fields above.  */
+	sprintf(interp, "No interpretation available!" );
+	if (vector == SCB_Q_PROCERR)
+		ev6_crd_interp(interp, L);
+	else if (vector == SCB_Q_PROCMCHK)
+		ev6_mchk_interp(interp, L);
+
+	printk(KERN_CRIT "interpretation: %s\n\n", interp);
+}
+
+
+/* Perform analysis of a machine check that arrived from the system (NMI) */
+
+static void
+naut_sys_machine_check(unsigned long vector, unsigned long la_ptr,
+		       struct pt_regs *regs)
+{
+	printk("xtime %lx\n", CURRENT_TIME);
+	printk("PC %lx RA %lx\n", regs->pc, regs->r26);
+	irongate_pci_clr_err();
+}
+
+/* Machine checks can come from two sources - those on the CPU and those
+   in the system.  They are analysed separately but all starts here.  */
+
+void
+nautilus_machine_check(unsigned long vector, unsigned long la_ptr,
+		       struct pt_regs *regs)
+{
+	char *mchk_class;
+	unsigned cpu_analysis=0, sys_analysis=0;
+
+	/* Now for some analysis.  Machine checks fall into two classes --
+	   those picked up by the system, and those picked up by the CPU.
+	   Add to that the two levels of severity - correctable or not.  */
+
+	if (vector == SCB_Q_SYSMCHK
+	    && ((IRONGATE0->dramms & 0x3FF) == 0x300)) {
+		unsigned long nmi_ctl, temp;
+
+		/* Clear ALI NMI */
+		nmi_ctl = inb(0x61);
+		nmi_ctl |= 0x0c;
+		outb(nmi_ctl, 0x61);
+		nmi_ctl &= ~0x0c;
+		outb(nmi_ctl, 0x61);
+
+		temp = IRONGATE0->stat_cmd;
+		IRONGATE0->stat_cmd = temp; /* write again clears error bits */
+		mb();
+		temp = IRONGATE0->stat_cmd;  /* re-read to force write */
+
+		temp = IRONGATE0->dramms;
+		IRONGATE0->dramms = temp; /* write again clears error bits */
+		mb();
+		temp = IRONGATE0->dramms;  /* re-read to force write */
+
+		draina();
+		wrmces(0x7);
+		mb();
+		return;
+	}
+
+	switch (vector) {
+	case SCB_Q_SYSERR:
+		mchk_class = "Correctable System Machine Check (NMI)";
+		sys_analysis = 1;
+		break;
+	case SCB_Q_SYSMCHK:
+		mchk_class = "Fatal System Machine Check (NMI)";
+		sys_analysis = 1;
+		break;
+
+	case SCB_Q_PROCERR:
+		mchk_class = "Correctable Processor Machine Check";
+		cpu_analysis = 1;
+		break;
+	case SCB_Q_PROCMCHK:
+		mchk_class = "Fatal Processor Machine Check";
+		cpu_analysis = 1;
+		break;
+
+	default:
+		mchk_class = "Unknown vector!";
+		break;
+	}
+
+	printk(KERN_CRIT "NAUTILUS Machine check 0x%lx [%s]\n",
+	       vector, mchk_class);
+
+	if (cpu_analysis)
+		ev6_cpu_machine_check(vector,
+				      (struct el_common_EV6_mcheck *)la_ptr,
+				      regs);
+	if (sys_analysis)
+		naut_sys_machine_check(vector, la_ptr, regs);
+
+	/* Tell the PALcode to clear the machine check */
+	draina();
+	wrmces(0x7);
+	mb();
+}
+
+
+
+/*
+ * The System Vectors
+ */
+
+struct alpha_machine_vector nautilus_mv __initmv = {
+	vector_name:		"Nautilus",
+	DO_EV6_MMU,
+	DO_DEFAULT_RTC,
+	DO_IRONGATE_IO,
+	DO_IRONGATE_BUS,
+	machine_check:		nautilus_machine_check,
+	max_dma_address:	ALPHA_NAUTILUS_MAX_DMA_ADDRESS,
+	min_io_address:		DEFAULT_IO_BASE,
+	min_mem_address:	DEFAULT_MEM_BASE,
+
+	nr_irqs:		16,
+	irq_probe_mask:		(_PROBE_MASK(16) & ~0x101UL),
+	update_irq_hw:		nautilus_update_irq_hw,
+	ack_irq:		common_ack_irq,
+	device_interrupt:	isa_device_interrupt,
+
+	init_arch:		irongate_init_arch,
+	init_irq:		nautilus_init_irq,
+	init_pit:		common_init_pit,
+	init_pci:		common_init_pci,
+	kill_arch:		nautilus_kill_arch,
+	pci_map_irq:		nautilus_map_irq,
+	pci_swizzle:		common_swizzle,
+};
+ALIAS_MV(nautilus)
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_noritake.c linux/arch/alpha/kernel/sys_noritake.c
--- v2.3.29/linux/arch/alpha/kernel/sys_noritake.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/sys_noritake.c	Mon Dec  6 17:15:53 1999
@@ -29,7 +29,7 @@
 #include <asm/core_cia.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -254,7 +254,7 @@
 	init_irq:		noritake_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		common_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		NULL,
 	pci_map_irq:		noritake_map_irq,
 	pci_swizzle:		noritake_swizzle,
 };
@@ -283,7 +283,6 @@
 	init_irq:		noritake_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		common_init_pci,
-	kill_arch:		common_kill_arch,
 	pci_map_irq:		noritake_map_irq,
 	pci_swizzle:		noritake_swizzle,
 };
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_rawhide.c linux/arch/alpha/kernel/sys_rawhide.c
--- v2.3.29/linux/arch/alpha/kernel/sys_rawhide.c	Sat Oct  9 11:47:50 1999
+++ linux/arch/alpha/kernel/sys_rawhide.c	Mon Dec  6 17:15:53 1999
@@ -25,46 +25,59 @@
 #include <asm/core_mcpcia.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
+static unsigned int hose_irq_masks[4] = {
+	0xff0000, 0xfe0000, 0xff0000, 0xff0000
+};
+
+
+/* Note that `mask' initially contains only the low 64 bits.  */
 
 static void
 rawhide_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
 {
-	if (irq >= 40) {
-		/* PCI bus 1 with builtin NCR810 SCSI */
-		*(vuip)MCPCIA_INT_MASK0(5) =
-			(~((mask) >> 40) & 0x00ffffffU) | 0x00fe0000U;
-		mb();
-		/* ... and read it back to make sure it got written.  */
-	  	*(vuip)MCPCIA_INT_MASK0(5);
+	unsigned int saddle, hose, new_irq;
+
+	if (irq < 16) {
+		if (irq < 8)
+			outb(mask, 0x21);		/* ISA PIC1 */
+		else
+			outb(mask >> 8, 0xA1);		/* ISA PIC2 */
+		return;
 	}
-	else if (irq >= 16) {
-		/* PCI bus 0 with EISA bridge */
-		*(vuip)MCPCIA_INT_MASK0(4) =
-			(~((mask) >> 16) & 0x00ffffffU) | 0x00ff0000U;
-		mb();
-		/* ... and read it back to make sure it got written.  */
-	  	*(vuip)MCPCIA_INT_MASK0(4);
+
+	saddle = (irq > 63);
+	mask = _alpha_irq_masks[saddle];
+
+	if (saddle == 0) {
+		/* Saddle 0 includes EISA interrupts.  */
+		mask >>= 16;
+		new_irq = irq - 16;
+	} else {
+		new_irq = irq - 64;
+	}
+
+	hose = saddle << 1;
+	if (new_irq >= 24) {
+		mask >>= 24;
+		hose += 1;
 	}
-	else if (irq >= 8)
-		outb(mask >> 8, 0xA1);	/* ISA PIC2 */
-	else
-		outb(mask, 0x21);	/* ISA PIC1 */
+
+	*(vuip)MCPCIA_INT_MASK0(hose) =
+		(~mask & 0x00ffffff) | hose_irq_masks[hose];
+	mb();
+	*(vuip)MCPCIA_INT_MASK0(hose);
 }
 
 static void 
 rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
 {
-	int irq, ack;
-
-	ack = irq = (vector - 0x800) >> 4;
+	int irq;
 
-	/* ??? A 4 bus RAWHIDE has 67 interrupts.  Oops.  We need
-	   something wider than one word for our own internal
-	   manipulations.  */
+	irq = (vector - 0x800) >> 4;
 
         /*
          * The RAWHIDE SRM console reports PCI interrupts with a vector
@@ -73,37 +86,37 @@
 	 * it line up with the actual bit numbers from the REQ registers,
 	 * which is how we manage the interrupts/mask. Sigh...
 	 *
-	 * also, PCI #1 interrupts are offset some more... :-(
+	 * Also, PCI #1 interrupts are offset some more... :-(
          */
-	if (irq == 52)
-		ack = irq = 56; /* SCSI on PCI 1 is special */
-	else {
-		if (irq >= 24) /* adjust all PCI interrupts down 8 */
-			ack = irq = irq - 8;
-		if (irq >= 48) /* adjust PCI bus 1 interrupts down another 8 */
-			ack = irq = irq - 8;
+
+	if (irq == 52) {
+		/* SCSI on PCI1 is special.  */
+		irq = 72;
 	}
 
-	handle_irq(irq, ack, regs);
+	/* Adjust by which hose it is from.  */
+	irq -= ((irq + 16) >> 2) & 0x38;
+
+	handle_irq(irq, irq, regs);
 }
 
 static void __init
 rawhide_init_irq(void)
 {
+	struct pci_controler *hose;
+
+	mcpcia_init_hoses();
+
 	STANDARD_INIT_IRQ_PROLOG;
 
-	/* HACK ALERT! only PCI busses 0 and 1 are used currently,
-	   (MIDs 4 and 5 respectively) and routing is only to CPU #1*/
+	/* HACK ALERT! Routing is only to CPU #0.  */
+	for (hose = hose_head; hose; hose = hose->next) {
+		int h = hose->index;
 
-	*(vuip)MCPCIA_INT_MASK0(4) =
-		(~((alpha_irq_mask) >> 16) & 0x00ffffffU) | 0x00ff0000U; mb();
-	/* ... and read it back to make sure it got written.  */
-	*(vuip)MCPCIA_INT_MASK0(4);
-
-	*(vuip)MCPCIA_INT_MASK0(5) =
-		(~((alpha_irq_mask) >> 40) & 0x00ffffffU) | 0x00fe0000U; mb();
-	/* ... and read it back to make sure it got written.  */
-	*(vuip)MCPCIA_INT_MASK0(5);
+		*(vuip)MCPCIA_INT_MASK0(h) = hose_irq_masks[h];
+		mb();
+		*(vuip)MCPCIA_INT_MASK0(h);
+	}
 
 	enable_irq(2);
 }
@@ -177,8 +190,8 @@
 	min_io_address:		DEFAULT_IO_BASE,
 	min_mem_address:	MCPCIA_DEFAULT_MEM_BASE,
 
-	nr_irqs:		64,
-	irq_probe_mask:		_PROBE_MASK(64),
+	nr_irqs:		128,
+	irq_probe_mask:		_PROBE_MASK(128),
 	update_irq_hw:		rawhide_update_irq_hw,
 	ack_irq:		common_ack_irq,
 	device_interrupt:	rawhide_srm_device_interrupt,
@@ -187,7 +200,7 @@
 	init_irq:		rawhide_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		common_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		NULL,
 	pci_map_irq:		rawhide_map_irq,
 	pci_swizzle:		common_swizzle,
 };
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_ruffian.c linux/arch/alpha/kernel/sys_ruffian.c
--- v2.3.29/linux/arch/alpha/kernel/sys_ruffian.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/sys_ruffian.c	Mon Dec  6 17:15:53 1999
@@ -26,7 +26,7 @@
 #include <asm/core_pyxis.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -212,15 +212,14 @@
 }
 
 static void
-ruffian_kill_arch (int mode, char *reboot_cmd)
+ruffian_kill_arch (int mode)
 {
 #if 0
-	/* this only causes re-entry to ARCSBIOS */
+	/* This only causes re-entry to ARCSBIOS */
 	/* Perhaps this works for other PYXIS as well?  */
 	*(vuip) PYXIS_RESET = 0x0000dead;
 	mb();
 #endif
-	common_kill_arch(mode, reboot_cmd);
 }
 
 static int __init
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_rx164.c linux/arch/alpha/kernel/sys_rx164.c
--- v2.3.29/linux/arch/alpha/kernel/sys_rx164.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/sys_rx164.c	Mon Dec  6 17:15:53 1999
@@ -26,7 +26,7 @@
 #include <asm/core_polaris.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -229,7 +229,7 @@
 	init_irq:		rx164_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		common_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		NULL,
 	pci_map_irq:		rx164_map_irq,
 	pci_swizzle:		common_swizzle,
 };
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_sable.c linux/arch/alpha/kernel/sys_sable.c
--- v2.3.29/linux/arch/alpha/kernel/sys_sable.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/sys_sable.c	Mon Dec  6 17:15:53 1999
@@ -26,7 +26,7 @@
 #include <asm/core_t2.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -248,7 +248,7 @@
 	init_irq:		sable_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		common_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		NULL,
 	pci_map_irq:		sable_map_irq,
 	pci_swizzle:		common_swizzle,
 
@@ -283,7 +283,6 @@
 	init_irq:		sable_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		common_init_pci,
-	kill_arch:		common_kill_arch,
 	pci_map_irq:		sable_map_irq,
 	pci_swizzle:		common_swizzle,
 
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_sio.c linux/arch/alpha/kernel/sys_sio.c
--- v2.3.29/linux/arch/alpha/kernel/sys_sio.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/kernel/sys_sio.c	Mon Dec  6 17:15:53 1999
@@ -30,7 +30,7 @@
 #include <asm/core_lca.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -325,7 +325,7 @@
 	init_irq:		sio_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		alphabook1_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		NULL,
 	pci_map_irq:		noname_map_irq,
 	pci_swizzle:		common_swizzle,
 
@@ -359,7 +359,6 @@
 	init_irq:		sio_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		noname_init_pci,
-	kill_arch:		common_kill_arch,
 	pci_map_irq:		noname_map_irq,
 	pci_swizzle:		common_swizzle,
 
@@ -392,7 +391,6 @@
 	init_irq:		sio_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		noname_init_pci,
-	kill_arch:		common_kill_arch,
 	pci_map_irq:		noname_map_irq,
 	pci_swizzle:		common_swizzle,
 
@@ -434,7 +432,6 @@
 	init_irq:		sio_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		noname_init_pci,
-	kill_arch:		common_kill_arch,
 	pci_map_irq:		p2k_map_irq,
 	pci_swizzle:		common_swizzle,
 
@@ -467,7 +464,6 @@
 	init_irq:		sio_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		noname_init_pci,
-	kill_arch:		common_kill_arch,
 	pci_map_irq:		noname_map_irq,
 	pci_swizzle:		common_swizzle,
 
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_sx164.c linux/arch/alpha/kernel/sys_sx164.c
--- v2.3.29/linux/arch/alpha/kernel/sys_sx164.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/sys_sx164.c	Mon Dec  6 17:15:53 1999
@@ -26,7 +26,7 @@
 #include <asm/core_pyxis.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -211,7 +211,7 @@
 	init_irq:		sx164_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		sx164_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		NULL,
 	pci_map_irq:		sx164_map_irq,
 	pci_swizzle:		common_swizzle,
 };
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/sys_takara.c linux/arch/alpha/kernel/sys_takara.c
--- v2.3.29/linux/arch/alpha/kernel/sys_takara.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/sys_takara.c	Mon Dec  6 17:15:53 1999
@@ -25,7 +25,7 @@
 #include <asm/core_cia.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 #include "pci_impl.h"
 #include "machvec_impl.h"
 
@@ -40,9 +40,13 @@
 			outb(mask, 0x21);	/* ISA PIC1 */
 		else
 			outb(mask >> 8, 0xA1);	/* ISA PIC2 */
-	} else if (irq <= 31) {
-		regaddr = 0x510 + ((irq - 16) & 0x0c);
-		outl((mask >> ((irq - 16) & 0x0c)) & 0xf0000Ul, regaddr);
+	} else {
+		if (irq > 63)
+			mask = _alpha_irq_masks[1] << 16;
+		else
+			mask = mask >> ((irq - 16) & 0x30);
+		regaddr = 0x510 + (((irq - 16) >> 2) & 0x0c);
+		outl(mask & 0xffff0000UL, regaddr);
 	}
 }
 
@@ -87,10 +91,6 @@
 takara_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
 {
 	int irq = (vector - 0x800) >> 4;
-
-	if (irq > 15)
-		irq = ((vector - 0x800) >> 6) + 12;
-	
 	handle_irq(irq, irq, regs);
 }
 
@@ -99,10 +99,9 @@
 {
 	STANDARD_INIT_IRQ_PROLOG;
 
-	if (alpha_using_srm)
+	if (alpha_using_srm) {
 		alpha_mv.device_interrupt = takara_srm_device_interrupt;
-
-	if (!alpha_using_srm) {
+	} else {
 		unsigned int ctlreg = inl(0x500);
 
 		/* Return to non-accelerated mode.  */
@@ -127,6 +126,37 @@
  */
 
 static int __init
+takara_map_irq_srm(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	static char irq_tab[15][5] __initlocaldata = {
+		{ 16+3, 16+3, 16+3, 16+3, 16+3},   /* slot  6 == device 3 */
+		{ 16+2, 16+2, 16+2, 16+2, 16+2},   /* slot  7 == device 2 */
+		{ 16+1, 16+1, 16+1, 16+1, 16+1},   /* slot  8 == device 1 */
+		{   -1,   -1,   -1,   -1,   -1},   /* slot  9 == nothing */
+		{   -1,   -1,   -1,   -1,   -1},   /* slot 10 == nothing */
+		{   -1,   -1,   -1,   -1,   -1},   /* slot 11 == nothing */
+		/* These are behind the bridges.  */
+		{   12,   12,   13,   14,   15},   /* slot 12 == nothing */
+		{    8,    8,    9,   19,   11},   /* slot 13 == nothing */
+		{    4,    4,    5,    6,    7},   /* slot 14 == nothing */
+		{    0,    0,    1,    2,    3},   /* slot 15 == nothing */
+		{   -1,   -1,   -1,   -1,   -1},   /* slot 16 == nothing */
+		{64+ 0, 64+0, 64+1, 64+2, 64+3},   /* slot 17= device 4 */
+		{48+ 0, 48+0, 48+1, 48+2, 48+3},   /* slot 18= device 3 */
+		{32+ 0, 32+0, 32+1, 32+2, 32+3},   /* slot 19= device 2 */
+		{16+ 0, 16+0, 16+1, 16+2, 16+3},   /* slot 20= device 1 */
+	};
+	const long min_idsel = 6, max_idsel = 20, irqs_per_slot = 5;
+        int irq = COMMON_TABLE_LOOKUP;
+	if (irq >= 0 && irq < 16) {
+		/* Guess that we are behind a bridge.  */
+		unsigned int busslot = PCI_SLOT(dev->bus->self->devfn);
+		irq += irq_tab[busslot-min_idsel][0];
+	}
+	return irq;
+}
+
+static int __init
 takara_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
 {
 	static char irq_tab[15][5] __initlocaldata = {
@@ -165,10 +195,13 @@
 		if (pin == 1)
 			pin += (20 - busslot);
 		else {
-			/* Must be a card-based bridge.  */
-			printk(KERN_WARNING "takara_swizzle: cannot handle "
-			       "card-bridge behind builtin bridge yet.\n");
+			printk(KERN_WARNING "takara_swizzle: can only "
+			       "handle cards with INTA IRQ pin.\n");
 		}
+	} else {
+		/* Must be a card-based bridge.  */
+		printk(KERN_WARNING "takara_swizzle: cannot handle "
+		       "card-bridge behind builtin bridge yet.\n");
 	}
 
 	*pinp = pin;
@@ -178,8 +211,11 @@
 static void __init
 takara_init_pci(void)
 {
+	if (alpha_using_srm)
+		alpha_mv.pci_map_irq = takara_map_irq_srm;
+
 	common_init_pci();
-	/* ns87312_enable_ide(0x26e); */
+	ns87312_enable_ide(0x26e);
 }
 
 
@@ -198,8 +234,8 @@
 	min_io_address:		DEFAULT_IO_BASE,
 	min_mem_address:	CIA_DEFAULT_MEM_BASE,
 
-	nr_irqs:		20,
-	irq_probe_mask:		_PROBE_MASK(20),
+	nr_irqs:		128,
+	irq_probe_mask:		_PROBE_MASK(48),
 	update_irq_hw:		takara_update_irq_hw,
 	ack_irq:		common_ack_irq,
 	device_interrupt:	takara_device_interrupt,
@@ -208,7 +244,7 @@
 	init_irq:		takara_init_irq,
 	init_pit:		common_init_pit,
 	init_pci:		takara_init_pci,
-	kill_arch:		common_kill_arch,
+	kill_arch:		NULL,
 	pci_map_irq:		takara_map_irq,
 	pci_swizzle:		takara_swizzle,
 };
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c
--- v2.3.29/linux/arch/alpha/kernel/time.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/time.c	Mon Dec  6 17:15:53 1999
@@ -40,7 +40,7 @@
 #include <linux/timex.h>
 
 #include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
 
 extern rwlock_t xtime_lock;
 extern volatile unsigned long lost_ticks;	/* kernel/sched.c */
@@ -174,7 +174,7 @@
 
 #ifdef CONFIG_RTC
 void
-rtc_init_pit (void)
+rtc_init_pit(void)
 {
 	unsigned char control;
 
@@ -192,6 +192,25 @@
 	outb(0xb6, 0x43);	/* pit counter 2: speaker */
 	outb(0x31, 0x42);
 	outb(0x13, 0x42);
+}
+
+void
+rtc_kill_pit(void)
+{
+	unsigned char control;
+
+	cli();
+
+	/* Reset periodic interrupt frequency.  */
+	CMOS_WRITE(0x26, RTC_FREQ_SELECT);
+
+	/* Turn on periodic interrupts.  */
+	control = CMOS_READ(RTC_CONTROL);
+	control |= RTC_PIE;
+	CMOS_WRITE(control, RTC_CONTROL);	
+	CMOS_READ(RTC_INTR_FLAGS);
+
+	sti();
 }
 #endif
 
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/kernel/traps.c linux/arch/alpha/kernel/traps.c
--- v2.3.29/linux/arch/alpha/kernel/traps.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/kernel/traps.c	Thu Dec  2 15:28:54 1999
@@ -113,7 +113,7 @@
 }
 
 #ifndef CONFIG_MATHEMU
-static long dummy_emul() { return 0; }
+static long dummy_emul(void) { return 0; }
 long (*alpha_fp_emul_imprecise)(struct pt_regs *regs, unsigned long writemask)
   = (void *)dummy_emul;
 long (*alpha_fp_emul) (unsigned long pc)
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/lib/Makefile linux/arch/alpha/lib/Makefile
--- v2.3.29/linux/arch/alpha/lib/Makefile	Fri Aug  6 10:41:47 1999
+++ linux/arch/alpha/lib/Makefile	Thu Dec  2 15:28:54 1999
@@ -7,7 +7,7 @@
 	strcat.o strcpy.o strncat.o strncpy.o stxcpy.o stxncpy.o \
 	strchr.o strrchr.o memchr.o \
 	copy_user.o clear_user.o strncpy_from_user.o strlen_user.o \
-	csum_ipv6_magic.o strcasecmp.o semaphore.o \
+	csum_ipv6_magic.o strcasecmp.o semaphore.o fpreg.o \
 	srm_dispatch.o srm_fixup.o srm_puts.o srm_printk.o
 
 lib.a: $(OBJS)
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/lib/fpreg.c linux/arch/alpha/lib/fpreg.c
--- v2.3.29/linux/arch/alpha/lib/fpreg.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/lib/fpreg.c	Thu Dec  2 15:28:54 1999
@@ -0,0 +1,191 @@
+/*
+ * arch/alpha/lib/fpreg.c
+ *
+ * (C) Copyright 1998 Linus Torvalds
+ */
+
+#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#define STT(reg,val)  asm volatile ("ftoit $f"#reg",%0" : "=r"(val));
+#else
+#define STT(reg,val)  asm volatile ("stt $f"#reg",%0" : "=m"(val));
+#endif
+
+unsigned long
+alpha_read_fp_reg (unsigned long reg)
+{
+	unsigned long val;
+
+	switch (reg) {
+	      case  0: STT( 0, val); break;
+	      case  1: STT( 1, val); break;
+	      case  2: STT( 2, val); break;
+	      case  3: STT( 3, val); break;
+	      case  4: STT( 4, val); break;
+	      case  5: STT( 5, val); break;
+	      case  6: STT( 6, val); break;
+	      case  7: STT( 7, val); break;
+	      case  8: STT( 8, val); break;
+	      case  9: STT( 9, val); break;
+	      case 10: STT(10, val); break;
+	      case 11: STT(11, val); break;
+	      case 12: STT(12, val); break;
+	      case 13: STT(13, val); break;
+	      case 14: STT(14, val); break;
+	      case 15: STT(15, val); break;
+	      case 16: STT(16, val); break;
+	      case 17: STT(17, val); break;
+	      case 18: STT(18, val); break;
+	      case 19: STT(19, val); break;
+	      case 20: STT(20, val); break;
+	      case 21: STT(21, val); break;
+	      case 22: STT(22, val); break;
+	      case 23: STT(23, val); break;
+	      case 24: STT(24, val); break;
+	      case 25: STT(25, val); break;
+	      case 26: STT(26, val); break;
+	      case 27: STT(27, val); break;
+	      case 28: STT(28, val); break;
+	      case 29: STT(29, val); break;
+	      case 30: STT(30, val); break;
+	      case 31: STT(31, val); break;
+	}
+	return val;
+}
+
+#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#define LDT(reg,val)  asm volatile ("itoft %0,$f"#reg : : "r"(val));
+#else
+#define LDT(reg,val)  asm volatile ("ldt $f"#reg",%0" : : "m"(val));
+#endif
+
+void
+alpha_write_fp_reg (unsigned long reg, unsigned long val)
+{
+	switch (reg) {
+	      case  0: LDT( 0, val); break;
+	      case  1: LDT( 1, val); break;
+	      case  2: LDT( 2, val); break;
+	      case  3: LDT( 3, val); break;
+	      case  4: LDT( 4, val); break;
+	      case  5: LDT( 5, val); break;
+	      case  6: LDT( 6, val); break;
+	      case  7: LDT( 7, val); break;
+	      case  8: LDT( 8, val); break;
+	      case  9: LDT( 9, val); break;
+	      case 10: LDT(10, val); break;
+	      case 11: LDT(11, val); break;
+	      case 12: LDT(12, val); break;
+	      case 13: LDT(13, val); break;
+	      case 14: LDT(14, val); break;
+	      case 15: LDT(15, val); break;
+	      case 16: LDT(16, val); break;
+	      case 17: LDT(17, val); break;
+	      case 18: LDT(18, val); break;
+	      case 19: LDT(19, val); break;
+	      case 20: LDT(20, val); break;
+	      case 21: LDT(21, val); break;
+	      case 22: LDT(22, val); break;
+	      case 23: LDT(23, val); break;
+	      case 24: LDT(24, val); break;
+	      case 25: LDT(25, val); break;
+	      case 26: LDT(26, val); break;
+	      case 27: LDT(27, val); break;
+	      case 28: LDT(28, val); break;
+	      case 29: LDT(29, val); break;
+	      case 30: LDT(30, val); break;
+	      case 31: LDT(31, val); break;
+	}
+}
+
+#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#define STS(reg,val)  asm volatile ("ftois $f"#reg",%0" : "=r"(val));
+#else
+#define STS(reg,val)  asm volatile ("sts $f"#reg",%0" : "=m"(val));
+#endif
+
+unsigned long
+alpha_read_fp_reg_s (unsigned long reg)
+{
+	unsigned long val;
+
+	switch (reg) {
+	      case  0: STS( 0, val); break;
+	      case  1: STS( 1, val); break;
+	      case  2: STS( 2, val); break;
+	      case  3: STS( 3, val); break;
+	      case  4: STS( 4, val); break;
+	      case  5: STS( 5, val); break;
+	      case  6: STS( 6, val); break;
+	      case  7: STS( 7, val); break;
+	      case  8: STS( 8, val); break;
+	      case  9: STS( 9, val); break;
+	      case 10: STS(10, val); break;
+	      case 11: STS(11, val); break;
+	      case 12: STS(12, val); break;
+	      case 13: STS(13, val); break;
+	      case 14: STS(14, val); break;
+	      case 15: STS(15, val); break;
+	      case 16: STS(16, val); break;
+	      case 17: STS(17, val); break;
+	      case 18: STS(18, val); break;
+	      case 19: STS(19, val); break;
+	      case 20: STS(20, val); break;
+	      case 21: STS(21, val); break;
+	      case 22: STS(22, val); break;
+	      case 23: STS(23, val); break;
+	      case 24: STS(24, val); break;
+	      case 25: STS(25, val); break;
+	      case 26: STS(26, val); break;
+	      case 27: STS(27, val); break;
+	      case 28: STS(28, val); break;
+	      case 29: STS(29, val); break;
+	      case 30: STS(30, val); break;
+	      case 31: STS(31, val); break;
+	}
+	return val;
+}
+
+#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#define LDS(reg,val)  asm volatile ("itofs %0,$f"#reg : : "r"(val));
+#else
+#define LDS(reg,val)  asm volatile ("lds $f"#reg",%0" : : "m"(val));
+#endif
+
+void
+alpha_write_fp_reg_s (unsigned long reg, unsigned long val)
+{
+	switch (reg) {
+	      case  0: LDS( 0, val); break;
+	      case  1: LDS( 1, val); break;
+	      case  2: LDS( 2, val); break;
+	      case  3: LDS( 3, val); break;
+	      case  4: LDS( 4, val); break;
+	      case  5: LDS( 5, val); break;
+	      case  6: LDS( 6, val); break;
+	      case  7: LDS( 7, val); break;
+	      case  8: LDS( 8, val); break;
+	      case  9: LDS( 9, val); break;
+	      case 10: LDS(10, val); break;
+	      case 11: LDS(11, val); break;
+	      case 12: LDS(12, val); break;
+	      case 13: LDS(13, val); break;
+	      case 14: LDS(14, val); break;
+	      case 15: LDS(15, val); break;
+	      case 16: LDS(16, val); break;
+	      case 17: LDS(17, val); break;
+	      case 18: LDS(18, val); break;
+	      case 19: LDS(19, val); break;
+	      case 20: LDS(20, val); break;
+	      case 21: LDS(21, val); break;
+	      case 22: LDS(22, val); break;
+	      case 23: LDS(23, val); break;
+	      case 24: LDS(24, val); break;
+	      case 25: LDS(25, val); break;
+	      case 26: LDS(26, val); break;
+	      case 27: LDS(27, val); break;
+	      case 28: LDS(28, val); break;
+	      case 29: LDS(29, val); break;
+	      case 30: LDS(30, val); break;
+	      case 31: LDS(31, val); break;
+	}
+}
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/lib/io.c linux/arch/alpha/lib/io.c
--- v2.3.29/linux/arch/alpha/lib/io.c	Thu Aug 26 13:05:34 1999
+++ linux/arch/alpha/lib/io.c	Sat Nov 27 15:27:48 1999
@@ -2,8 +2,11 @@
  * Alpha IO and memory functions.. Just expand the inlines in the header
  * files..
  */
+
 #include <linux/kernel.h>
 #include <linux/types.h>
+#include <linux/string.h>
+
 #include <asm/io.h>
 
 unsigned int _inb(unsigned long addr)
@@ -561,4 +564,29 @@
 		__raw_writeb(c, to);
 	}
 	mb();
+}
+
+void
+scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
+{
+	if (! __is_ioaddr((unsigned long) s)) {
+		/* Source is memory.  */
+		if (! __is_ioaddr((unsigned long) d))
+			memcpy(d, s, count);
+		else
+			memcpy_toio(d, s, count);
+	} else {
+		/* Source is screen.  */
+		if (! __is_ioaddr((unsigned long) d))
+			memcpy_fromio(d, s, count);
+		else {
+			/* FIXME: Should handle unaligned ops and
+			   operation widening.  */
+			count /= 2;
+			while (count--) {
+				u16 tmp = __raw_readw((unsigned long)(s++));
+				__raw_writew(tmp, (unsigned long)(d++));
+			}
+		}
+	}
 }
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/math-emu/Makefile linux/arch/alpha/math-emu/Makefile
--- v2.3.29/linux/arch/alpha/math-emu/Makefile	Thu Feb 12 13:31:28 1998
+++ linux/arch/alpha/math-emu/Makefile	Thu Dec  2 15:28:54 1999
@@ -1,9 +1,15 @@
 #
-# Makefile for math-emulator files...
+# Makefile for the FPU instruction emulation.
 #
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := math-emu.o
-O_OBJS   := fp-emul.o ieee-math.o
+O_OBJS   := math.o
+CFLAGS += -I. -I$(TOPDIR)/include/math-emu -w
 
 ifeq ($(CONFIG_MATHEMU),m)
 M_OBJS   := $(O_TARGET)
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/math-emu/fp-emul.c linux/arch/alpha/math-emu/fp-emul.c
--- v2.3.29/linux/arch/alpha/math-emu/fp-emul.c	Thu Jul 29 13:37:22 1999
+++ linux/arch/alpha/math-emu/fp-emul.c	Wed Dec 31 16:00:00 1969
@@ -1,354 +0,0 @@
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/uaccess.h>
-
-#include "ieee-math.h"
-
-#define	OPC_PAL		0x00
-
-#define OPC_INTA	0x10
-#define OPC_INTL	0x11
-#define OPC_INTS	0x12
-#define OPC_INTM	0x13
-#define OPC_FLTC	0x14
-#define OPC_FLTV	0x15
-#define OPC_FLTI	0x16
-#define OPC_FLTL	0x17
-
-#define OPC_MISC	0x18
-
-#define	OPC_JSR		0x1a
-
-#define OP_FUN(OP,FUN)	((OP << 26) | (FUN << 5))
-
-/*
- * "Base" function codes for the FLTI-class instructions.
- * Note that in most cases these actually correspond to the "chopped"
- * form of the instruction.  Not to worry---we extract the qualifier
- * bits separately and deal with them separately.  Notice that base
- * function code 0x2c is used for both CVTTS and CVTST.  The other bits
- * in the function code are used to distinguish the two.
- */
-#define FLTI_FUNC_ADDS			OP_FUN(OPC_FLTI, 0x000)
-#define FLTI_FUNC_ADDT			OP_FUN(OPC_FLTI, 0x020)
-#define FLTI_FUNC_CMPTEQ		OP_FUN(OPC_FLTI, 0x025)
-#define FLTI_FUNC_CMPTLT		OP_FUN(OPC_FLTI, 0x026)
-#define FLTI_FUNC_CMPTLE		OP_FUN(OPC_FLTI, 0x027)
-#define FLTI_FUNC_CMPTUN		OP_FUN(OPC_FLTI, 0x024)
-#define FLTI_FUNC_CVTTS_or_CVTST	OP_FUN(OPC_FLTI, 0x02c)
-#define FLTI_FUNC_CVTTQ			OP_FUN(OPC_FLTI, 0x02f)
-#define FLTI_FUNC_CVTQS			OP_FUN(OPC_FLTI, 0x03c)
-#define FLTI_FUNC_CVTQT			OP_FUN(OPC_FLTI, 0x03e)
-#define FLTI_FUNC_DIVS			OP_FUN(OPC_FLTI, 0x003)
-#define FLTI_FUNC_DIVT			OP_FUN(OPC_FLTI, 0x023)
-#define FLTI_FUNC_MULS			OP_FUN(OPC_FLTI, 0x002)
-#define FLTI_FUNC_MULT			OP_FUN(OPC_FLTI, 0x022)
-#define FLTI_FUNC_SUBS			OP_FUN(OPC_FLTI, 0x001)
-#define FLTI_FUNC_SUBT			OP_FUN(OPC_FLTI, 0x021)
-
-#define FLTC_FUNC_SQRTS			OP_FUN(OPC_FLTC, 0x00B)
-#define FLTC_FUNC_SQRTT			OP_FUN(OPC_FLTC, 0x02B)
-
-#define FLTL_FUNC_CVTQL			OP_FUN(OPC_FLTL, 0x030)
-
-#define MISC_TRAPB	0x0000
-#define MISC_EXCB	0x0400
-
-extern unsigned long alpha_read_fp_reg (unsigned long reg);
-extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
-
-
-#ifdef MODULE
-
-MODULE_DESCRIPTION("FP Software completion module");
-
-extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long);
-extern long (*alpha_fp_emul) (unsigned long pc);
-
-static long (*save_emul_imprecise)(struct pt_regs *, unsigned long);
-static long (*save_emul) (unsigned long pc);
-
-long do_alpha_fp_emul_imprecise(struct pt_regs *, unsigned long);
-long do_alpha_fp_emul(unsigned long);
-
-int init_module(void)
-{
-	save_emul_imprecise = alpha_fp_emul_imprecise;
-	save_emul = alpha_fp_emul;
-	alpha_fp_emul_imprecise = do_alpha_fp_emul_imprecise;
-	alpha_fp_emul = do_alpha_fp_emul;
-	return 0;
-}
-
-void cleanup_module(void)
-{
-	alpha_fp_emul_imprecise = save_emul_imprecise;
-	alpha_fp_emul = save_emul;
-}
-
-#undef  alpha_fp_emul_imprecise
-#define alpha_fp_emul_imprecise		do_alpha_fp_emul_imprecise
-#undef  alpha_fp_emul
-#define alpha_fp_emul			do_alpha_fp_emul
-
-#endif /* MODULE */
-
-/*
- * Emulate the floating point instruction at address PC.  Returns 0 if
- * emulation fails.  Notice that the kernel does not and cannot use FP
- * regs.  This is good because it means that instead of
- * saving/restoring all fp regs, we simply stick the result of the
- * operation into the appropriate register.
- */
-long
-alpha_fp_emul (unsigned long pc)
-{
-	unsigned long op_fun, fa, fb, fc, func, mode;
-	unsigned long fpcw = current->thread.flags;
-	unsigned long va, vb, vc, res, fpcr;
-	__u32 insn;
-
-	MOD_INC_USE_COUNT;
-
-	get_user(insn, (__u32*)pc);
-	fc     = (insn >>  0) &  0x1f;	/* destination register */
-	fb     = (insn >> 16) &  0x1f;
-	fa     = (insn >> 21) &  0x1f;
-	func   = (insn >>  5) & 0x7ff;
-	mode   = (insn >>  5) & 0xc0;
-	op_fun = insn & OP_FUN(0x3f, 0x3f);
-	
-	va = alpha_read_fp_reg(fa);
-	vb = alpha_read_fp_reg(fb);
-	fpcr = rdfpcr();
-
-	/*
-	 * Try the operation in software.  First, obtain the rounding
-	 * mode...
-	 */
-	if (mode == 0xc0) {
-	    /* dynamic---get rounding mode from fpcr: */
-	    mode = ((fpcr & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT) << ROUND_SHIFT;
-	}
-	mode |= (fpcw & IEEE_TRAP_ENABLE_MASK);
-
-	if ((IEEE_TRAP_ENABLE_MASK & 0xc0)) {
-		extern int something_is_wrong (void);
-		something_is_wrong();
-	}
-
-	switch (op_fun) {
-	      case FLTI_FUNC_CMPTEQ:
-		res = ieee_CMPTEQ(va, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_CMPTLT:
-		res = ieee_CMPTLT(va, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_CMPTLE:
-		res = ieee_CMPTLE(va, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_CMPTUN:
-		res = ieee_CMPTUN(va, vb, &vc);
-		break;
-
-	      case FLTL_FUNC_CVTQL:
-		/*
-		 * Notice: We can get here only due to an integer
-		 * overflow.  Such overflows are reported as invalid
-		 * ops.  We return the result the hw would have
-		 * computed.
-		 */
-		vc = ((vb & 0xc0000000) << 32 |	/* sign and msb */
-		      (vb & 0x3fffffff) << 29);	/* rest of the integer */
-		res = FPCR_INV;
-		break;
-
-	      case FLTI_FUNC_CVTQS:
-		res = ieee_CVTQS(mode, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_CVTQT:
-		res = ieee_CVTQT(mode, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_CVTTS_or_CVTST:
-		if (func == 0x6ac) {
-			/*
-			 * 0x2ac is also CVTST, but if the /S
-			 * qualifier isn't set, we wouldn't be here in
-			 * the first place...
-			 */
-			res = ieee_CVTST(mode, vb, &vc);
-		} else {
-			res = ieee_CVTTS(mode, vb, &vc);
-		}
-		break; 
-
-	      case FLTI_FUNC_DIVS:
-		res = ieee_DIVS(mode, va, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_DIVT:
-		res = ieee_DIVT(mode, va, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_MULS:
-		res = ieee_MULS(mode, va, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_MULT:
-		res = ieee_MULT(mode, va, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_SUBS:
-		res = ieee_SUBS(mode, va, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_SUBT:
-		res = ieee_SUBT(mode, va, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_ADDS:
-		res = ieee_ADDS(mode, va, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_ADDT:
-		res = ieee_ADDT(mode, va, vb, &vc);
-		break;
-
-	      case FLTI_FUNC_CVTTQ:
-		res = ieee_CVTTQ(mode, vb, &vc);
-		break;
-
-	      case FLTC_FUNC_SQRTS:
-		res = ieee_SQRTS(mode, vb, &vc);
-		break;
-
-	      case FLTC_FUNC_SQRTT:
-		res = ieee_SQRTT(mode, vb, &vc);
-		break;
-
-	      default:
-		printk("alpha_fp_emul: unexpected function code %#lx at %#lx\n",
-		       func & 0x3f, pc);
-		MOD_DEC_USE_COUNT;
-		return 0;
-	}
-
-	/*
-	 * Take the appropriate action for each possible
-	 * floating-point result:
-	 *
-	 *	- Set the appropriate bits in the FPCR
-	 *	- If the specified exception is enabled in the FPCR,
-	 *	  return.  The caller (entArith) will dispatch
-	 *	  the appropriate signal to the translated program.
-	 *
-	 * In addition, properly track the exception state in software
-	 * as described in the Alpha Architectre Handbook section 4.7.7.3.
-	 */
-	if (res) {
-		/* Record exceptions in software control word.  */
-		current->thread.flags = fpcw |= res >> 35;
-
-		/* Update hardware control register */
-		fpcr &= (~FPCR_MASK | FPCR_DYN_MASK);
-		fpcr |= ieee_swcr_to_fpcr(fpcw);
-		wrfpcr(fpcr);
-
-		/* Do we generate a signal?  */
-		if (res >> 51 & fpcw & IEEE_TRAP_ENABLE_MASK) {
-			MOD_DEC_USE_COUNT;
-			return 0;
-		}
-	}
-
-	/*
-	 * Whoo-kay... we got this far, and we're not generating a signal
-	 * to the translated program.  All that remains is to write the
-	 * result:
-	 */
-	alpha_write_fp_reg(fc, vc);
-
-	MOD_DEC_USE_COUNT;
-	return 1;
-}
-
-
-long
-alpha_fp_emul_imprecise (struct pt_regs *regs, unsigned long write_mask)
-{
-	unsigned long trigger_pc = regs->pc - 4;
-	unsigned long insn, opcode, rc;
-
-	MOD_INC_USE_COUNT;
-
-	/*
-	 * Turn off the bits corresponding to registers that are the
-	 * target of instructions that set bits in the exception
-	 * summary register.  We have some slack doing this because a
-	 * register that is the target of a trapping instruction can
-	 * be written at most once in the trap shadow.
-	 *
-	 * Branches, jumps, TRAPBs, EXCBs and calls to PALcode all
-	 * bound the trap shadow, so we need not look any further than
-	 * up to the first occurrence of such an instruction.
-	 */
-	while (write_mask) {
-		get_user(insn, (__u32*)(trigger_pc));
-		opcode = insn >> 26;
-		rc = insn & 0x1f;
-
-		switch (opcode) {
-		      case OPC_PAL:
-		      case OPC_JSR:
-		      case 0x30 ... 0x3f:	/* branches */
-			MOD_DEC_USE_COUNT;
-			return 0;
-
-		      case OPC_MISC:
-			switch (insn & 0xffff) {
-			      case MISC_TRAPB:
-			      case MISC_EXCB:
-				MOD_DEC_USE_COUNT;
-				return 0;
-
-			      default:
-				break;
-			}
-			break;
-
-		      case OPC_INTA:
-		      case OPC_INTL:
-		      case OPC_INTS:
-		      case OPC_INTM:
-			write_mask &= ~(1UL << rc);
-			break;
-
-		      case OPC_FLTC:
-		      case OPC_FLTV:
-		      case OPC_FLTI:
-		      case OPC_FLTL:
-			write_mask &= ~(1UL << (rc + 32));
-			break;
-		}
-		if (!write_mask) {
-			if (alpha_fp_emul(trigger_pc)) {
-				/* re-execute insns in trap-shadow: */
-				regs->pc = trigger_pc + 4;
-				MOD_DEC_USE_COUNT;
-				return 1;
-			}
-			break;
-		}
-		trigger_pc -= 4;
-	}
-	MOD_DEC_USE_COUNT;
-	return 0;
-}
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/math-emu/fp-emul.h linux/arch/alpha/math-emu/fp-emul.h
--- v2.3.29/linux/arch/alpha/math-emu/fp-emul.h	Thu Apr 11 23:49:30 1996
+++ linux/arch/alpha/math-emu/fp-emul.h	Wed Dec 31 16:00:00 1969
@@ -1,10 +0,0 @@
-/*
- * These defines correspond to the dynamic rounding mode bits in the
- * Floating Point Control Register.  They also happen to correspond to
- * the instruction encodings except that 0x03 signifies dynamic
- * rounding mode in that case.
- */
-#define ROUND_CHOP	0x00	/* chopped (aka round towards zero) */
-#define ROUND_NINF	0x01	/* round towards negative infinity */
-#define ROUND_NEAR	0x02	/* round towards nearest number */
-#define ROUND_PINF	0x03	/* round towards positive infinity */
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/math-emu/ieee-math.c linux/arch/alpha/math-emu/ieee-math.c
--- v2.3.29/linux/arch/alpha/math-emu/ieee-math.c	Mon Jul 12 07:49:36 1999
+++ linux/arch/alpha/math-emu/ieee-math.c	Wed Dec 31 16:00:00 1969
@@ -1,1382 +0,0 @@
-/*
- * ieee-math.c - IEEE floating point emulation code
- * Copyright (C) 1989,1990,1991,1995 by
- * Digital Equipment Corporation, Maynard, Massachusetts.
- *
- * Heavily modified for Linux/Alpha.  Changes are Copyright (c) 1995
- * by David Mosberger (davidm@azstarnet.com).
- *
- * This file may be redistributed according to the terms of the
- * GNU General Public License.
- */
-/*
- * The original code did not have any comments. I have created many
- * comments as I fix the bugs in the code.  My comments are based on
- * my observation and interpretation of the code.  If the original
- * author would have spend a few minutes to comment the code, we would
- * never had a problem of misinterpretation.  -HA
- *
- * This code could probably be a lot more optimized (especially the
- * division routine).  However, my foremost concern was to get the
- * IEEE behavior right.  Performance is less critical as these
- * functions are used on exceptional numbers only (well, assuming you
- * don't turn on the "trap on inexact"...).
- */
-#include <linux/sched.h>
-#include "ieee-math.h"
-
-#define STICKY_S	0x20000000	/* both in longword 0 of fraction */
-#define STICKY_T	1
-
-/*
- * Careful: order matters here!
- */
-enum {
-	NaN, QNaN, INFTY, ZERO, DENORM, NORMAL
-};
-
-enum {
-	SINGLE, DOUBLE
-};
-
-typedef unsigned long fpclass_t;
-
-#define IEEE_TMAX	0x7fefffffffffffff
-#define IEEE_SMAX	0x47efffffe0000000
-#define IEEE_SNaN	0xfff00000000f0000
-#define IEEE_QNaN	0xfff8000000000000
-#define IEEE_PINF	0x7ff0000000000000
-#define IEEE_NINF	0xfff0000000000000
-
-
-/*
- * The memory format of S floating point numbers differs from the
- * register format.  In the following, the bitnumbers above the
- * diagram below give the memory format while the numbers below give
- * the register format.
- *
- *	  31 30	     23 22				0
- *	+-----------------------------------------------+
- * S	| s |	exp    |       fraction			|
- *	+-----------------------------------------------+
- *	  63 62	     52 51			      29
- *	
- * For T floating point numbers, the register and memory formats
- * match:
- *
- *	+-------------------------------------------------------------------+
- * T	| s |	     exp	|	    frac | tion			    |
- *	+-------------------------------------------------------------------+
- *	  63 62		      52 51	       32 31			   0
- */
-typedef struct {
-	unsigned long	f[2];	/* bit 55 in f[0] is the factor of 2^0*/
-	int		s;	/* 1 bit sign (0 for +, 1 for -) */
-	int		e;	/* 16 bit signed exponent */
-} EXTENDED;
-
-
-/*
- * Return the sign of a Q integer, S or T fp number in the register
- * format.
- */
-static inline int
-sign (unsigned long a)
-{
-	if ((long) a < 0)
-		return -1;
-	else
-		return 1;
-}
-
-
-static inline long
-cmp128 (const long a[2], const long b[2])
-{
-	if (a[1] < b[1]) return -1;
-	if (a[1] > b[1]) return  1;
-	return a[0] - b[0];
-}
-
-
-static inline void
-sll128 (unsigned long a[2])
-{
-	a[1] = (a[1] << 1) | (a[0] >> 63);
-	a[0] <<= 1;
-}
-
-
-static inline void
-srl128 (unsigned long a[2])
-{
-	a[0] = (a[0] >> 1) | (a[1] << 63);
-	a[1] >>= 1;
-}
-
-
-static inline void
-add128 (const unsigned long a[2], const unsigned long b[2], unsigned long c[2])
-{
-	unsigned long carry = a[0] > (0xffffffffffffffff - b[0]);
-
-	c[0] = a[0] + b[0];
-	c[1] = a[1] + b[1] + carry;
-}
-
-
-static inline void
-sub128 (const unsigned long a[2], const unsigned long b[2], unsigned long c[2])
-{
-	unsigned long borrow = a[0] < b[0];
-
-	c[0] = a[0] - b[0];
-	c[1] = a[1] - b[1] - borrow;
-}
-
-
-static inline void
-mul64 (const unsigned long a, const unsigned long b, unsigned long c[2])
-{
-	c[0] = a * b;
-	asm ("umulh %1,%2,%0" : "=r"(c[1]) : "r"(a), "r"(b));
-}
-
-
-static void
-div128 (unsigned long a[2], unsigned long b[2], unsigned long c[2])
-{
-	unsigned long mask[2] = {1, 0};
-
-	/*
-	 * Shift b until either the sign bit is set or until it is at
-	 * least as big as the dividend:
-	 */
-	while (cmp128(b, a) < 0 && sign(b[1]) >= 0) {
-		sll128(b);
-		sll128(mask);
-	}
-	c[0] = c[1] = 0;
-	do {
-		if (cmp128(a, b) >= 0) {
-			sub128(a, b, a);
-			add128(mask, c, c);
-		}
-		srl128(mask);
-		srl128(b);
-	} while (mask[0] || mask[1]);
-}
-
-
-static void
-normalize (EXTENDED *a)
-{
-	if (!a->f[0] && !a->f[1])
-		return;		/* zero fraction, unnormalizable... */
-	/*
-	 * In "extended" format, the "1" in "1.f" is explicit; it is
-	 * in bit 55 of f[0], and the decimal point is understood to
-	 * be between bit 55 and bit 54.  To normalize, shift the
-	 * fraction until we have a "1" in bit 55.
-	 */
-	if ((a->f[0] & 0xff00000000000000) != 0 || a->f[1] != 0) {
-		/*
-		 * Mantissa is greater than 1.0:
-		 */
-		while ((a->f[0] & 0xff80000000000000) != 0x0080000000000000 ||
-		       a->f[1] != 0)
-		{
-			unsigned long sticky;
-
-			++a->e;
-			sticky = a->f[0] & 1;
-			srl128(a->f);
-			a->f[0] |= sticky;
-		}
-		return;
-	}
-
-	if (!(a->f[0] & 0x0080000000000000)) {
-		/*
-		 * Mantissa is less than 1.0:
-		 */
-		while (!(a->f[0] & 0x0080000000000000)) {
-			--a->e;
-			a->f[0] <<= 1;
-		}
-		return;
-	}
-}
-
-
-static inline fpclass_t
-ieee_fpclass (unsigned long a)
-{
-	unsigned long exp, fract;
-
-	exp   = (a >> 52) & 0x7ff;	/* 11 bits of exponent */
-	fract = a & 0x000fffffffffffff;	/* 52 bits of fraction */
-	if (exp == 0) {
-		if (fract == 0)
-			return ZERO;
-		return DENORM;
-	}
-	if (exp == 0x7ff) {
-		if (fract == 0)
-			return INFTY;
-		if (((fract >> 51) & 1) != 0)
-			return QNaN;
-		return NaN;
-	}
-	return NORMAL;
-}
-
-
-/*
- * Translate S/T fp number in register format into extended format.
- */
-static fpclass_t
-extend_ieee (unsigned long a, EXTENDED *b, int prec)
-{
-	fpclass_t result_kind;
-
-	b->s = a >> 63;
-	b->e = ((a >> 52) & 0x7ff) - 0x3ff;	/* remove bias */
-	b->f[1] = 0;
-	/*
-	 * We shift f[1] left three bits so that the higher order bits
-	 * of the fraction will reside in bits 55 through 0 of f[0].
-	 */
-	b->f[0] = (a & 0x000fffffffffffff) << 3;
-	result_kind = ieee_fpclass(a);
-	if (result_kind == NORMAL) {
-		/* set implied 1. bit: */
-		b->f[0] |= 1UL << 55;
-	} else if (result_kind == DENORM) {
-		if (prec == SINGLE)
-			b->e = -126;
-		else
-			b->e = -1022;
-	}
-	return result_kind;
-}
-
-
-/*
- * INPUT PARAMETERS:
- *       a           a number in EXTENDED format to be converted to
- *                   s-floating format.
- *	 f	     rounding mode and exception enable bits.
- * OUTPUT PARAMETERS:
- *       b          will contain the s-floating number that "a" was
- *                  converted to (in register format).
- */
-static unsigned long
-make_s_ieee (long f, EXTENDED *a, unsigned long *b)
-{
-	unsigned long res, sticky;
-
-	if (!a->e && !a->f[0] && !a->f[1]) {
-		*b = (unsigned long) a->s << 63;	/* return +/-0 */
-		return 0;
-	}
-
-	normalize(a);
-	res = 0;
-
-	if (a->e < -0x7e) {
-		res = FPCR_INE;
-		if (f & IEEE_TRAP_ENABLE_UNF) {
-			res |= FPCR_UNF;
-			a->e += 0xc0;	/* scale up result by 2^alpha */
-		} else {
-			/* try making denormalized number: */
-			while (a->e < -0x7e) {
-				++a->e;
-				sticky = a->f[0] & 1;
-				srl128(a->f);
-				if (!a->f[0] && !a->f[0]) {
-					/* underflow: replace with exact 0 */
-					res |= FPCR_UNF;
-					break;
-				}
-				a->f[0] |= sticky;
-			}
-			a->e = -0x3ff;
-		}
-	}
-	if (a->e >= 0x80) {
-		res = FPCR_OVF | FPCR_INE;
-		if (f & IEEE_TRAP_ENABLE_OVF) {
-			a->e -= 0xc0;	/* scale down result by 2^alpha */
-		} else {
-			/*
-			 * Overflow without trap enabled, substitute
-			 * result according to rounding mode:
-			 */
-			switch (RM(f)) {
-			      case ROUND_NEAR:
-				*b = IEEE_PINF;
-				break;
-
-			      case ROUND_CHOP:
-				*b = IEEE_SMAX;
-				break;
-
-			      case ROUND_NINF:
-				if (a->s) {
-					*b = IEEE_PINF;
-				} else {
-					*b = IEEE_SMAX;
-				}
-				break;
-
-			      case ROUND_PINF: 
-				if (a->s) {
-					*b = IEEE_SMAX;
-				} else {
-					*b = IEEE_PINF;
-				}
-				break;
-			}
-			*b |= ((unsigned long) a->s << 63);
-			return res;
-		}
-	}
-
-	*b = (((unsigned long) a->s << 63) |
-	      (((unsigned long) a->e + 0x3ff) << 52) |
-	      ((a->f[0] >> 3) & 0x000fffffe0000000));
-	return res;
-}
-
-
-static unsigned long
-make_t_ieee (long f, EXTENDED *a, unsigned long *b)
-{
-	unsigned long res, sticky;
-
-	if (!a->e && !a->f[0] && !a->f[1]) {
-		*b = (unsigned long) a->s << 63;	/* return +/-0 */
-		return 0;
-	}
-
-	normalize(a);
-	res = 0;
-	if (a->e < -0x3fe) {
-		res = FPCR_INE;
-		if (f & IEEE_TRAP_ENABLE_UNF) {
-			res |= FPCR_UNF;
-			a->e += 0x600;
-		} else {
-			/* try making denormalized number: */
-			while (a->e < -0x3fe) {
-				++a->e;
-				sticky = a->f[0] & 1;
-				srl128(a->f);
-				if (!a->f[0] && !a->f[0]) {
-					/* underflow: replace with exact 0 */
-					res |= FPCR_UNF;
-					break;
-				}
-				a->f[0] |= sticky;
-			}
-			a->e = -0x3ff;
-		}
-	}
-	if (a->e >= 0x3ff) {
-		res = FPCR_OVF | FPCR_INE;
-		if (f & IEEE_TRAP_ENABLE_OVF) {
-			a->e -= 0x600;	/* scale down result by 2^alpha */
-		} else {
-			/*
-			 * Overflow without trap enabled, substitute
-			 * result according to rounding mode:
-			 */
-			switch (RM(f)) {
-			      case ROUND_NEAR:
-				*b = IEEE_PINF;
-				break;
-
-			      case ROUND_CHOP:
-				*b = IEEE_TMAX;
-				break;
-
-			      case ROUND_NINF:
-				if (a->s) {
-					*b = IEEE_PINF;
-				} else {
-					*b = IEEE_TMAX;
-				}
-				break;
-
-			      case ROUND_PINF: 
-				if (a->s) {
-					*b = IEEE_TMAX;
-				} else {
-					*b = IEEE_PINF;
-				}
-				break;
-			}
-			*b |= ((unsigned long) a->s << 63);
-			return res;
-		}
-	}
-	*b = (((unsigned long) a->s << 63) |
-	      (((unsigned long) a->e + 0x3ff) << 52) |
-	      ((a->f[0] >> 3) & 0x000fffffffffffff));
-	return res;
-}
-
-
-/*
- * INPUT PARAMETERS:
- *       a          EXTENDED format number to be rounded.
- *       rm	    integer with value ROUND_NEAR, ROUND_CHOP, etc.
- *                  indicates how "a" should be rounded to produce "b".
- * OUTPUT PARAMETERS:
- *       b          s-floating number produced by rounding "a".
- * RETURN VALUE:
- *       if no errors occurred, will be zero.  Else will contain flags
- *       like FPCR_INE_OP, etc.
- */
-static unsigned long
-round_s_ieee (int f, EXTENDED *a, unsigned long *b)
-{
-	unsigned long diff1, diff2, res = 0;
-	EXTENDED z1, z2;
-
-	if (!(a->f[0] & 0xffffffff)) {
-		return make_s_ieee(f, a, b);	/* no rounding error */
-	}
-
-	/*
-	 * z1 and z2 are the S-floating numbers with the next smaller/greater
-	 * magnitude than a, respectively.
-	 */
-	z1.s = z2.s = a->s;
-	z1.e = z2.e = a->e;
-	z1.f[0] = z2.f[0] = a->f[0] & 0xffffffff00000000;
-	z1.f[1] = z2.f[1] = 0;
-	z2.f[0] += 0x100000000;	/* next bigger S float number */
-
-	switch (RM(f)) {
-	      case ROUND_NEAR:
-		diff1 = a->f[0] - z1.f[0];
-		diff2 = z2.f[0] - a->f[0];
-		if (diff1 > diff2)
-			res = make_s_ieee(f, &z2, b);
-		else if (diff2 > diff1)
-			res = make_s_ieee(f, &z1, b);
-		else
-			/* equal distance: round towards even */
-			if (z1.f[0] & 0x100000000)
-				res = make_s_ieee(f, &z2, b);
-			else
-				res = make_s_ieee(f, &z1, b);
-		break;
-
-	      case ROUND_CHOP:
-		res = make_s_ieee(f, &z1, b);
-		break;
-
-	      case ROUND_PINF:
-		if (a->s) {
-			res = make_s_ieee(f, &z1, b);
-		} else {
-			res = make_s_ieee(f, &z2, b);
-		}
-		break;
-
-	      case ROUND_NINF:
-		if (a->s) {
-			res = make_s_ieee(f, &z2, b);
-		} else {
-			res = make_s_ieee(f, &z1, b);
-		}
-		break;
-	}
-	return FPCR_INE | res;
-}
-
-
-static unsigned long
-round_t_ieee (int f, EXTENDED *a, unsigned long *b)
-{
-	unsigned long diff1, diff2, res;
-	EXTENDED z1, z2;
-
-	if (!(a->f[0] & 0x7)) {
-		/* no rounding error */
-		return make_t_ieee(f, a, b);
-	}
-
-	z1.s = z2.s = a->s;
-	z1.e = z2.e = a->e;
-	z1.f[0] = z2.f[0] = a->f[0] & ~0x7;
-	z1.f[1] = z2.f[1] = 0;
-	z2.f[0] += (1 << 3);
-
-	res = 0;
-	switch (RM(f)) {
-	      case ROUND_NEAR:
-		diff1 = a->f[0] - z1.f[0];
-		diff2 = z2.f[0] - a->f[0];
-		if (diff1 > diff2)
-			res = make_t_ieee(f, &z2, b);
-		else if (diff2 > diff1)
-			res = make_t_ieee(f, &z1, b);
-		else
-			/* equal distance: round towards even */
-			if (z1.f[0] & (1 << 3))
-				res = make_t_ieee(f, &z2, b);
-			else
-				res = make_t_ieee(f, &z1, b);
-		break;
-
-	      case ROUND_CHOP:
-		res = make_t_ieee(f, &z1, b);
-		break;
-
-	      case ROUND_PINF:
-		if (a->s) {
-			res = make_t_ieee(f, &z1, b);
-		} else {
-			res = make_t_ieee(f, &z2, b);
-		}
-		break;
-
-	      case ROUND_NINF:
-		if (a->s) {
-			res = make_t_ieee(f, &z2, b);
-		} else {
-			res = make_t_ieee(f, &z1, b);
-		}
-		break;
-	}
-	return FPCR_INE | res;
-}
-
-
-static fpclass_t
-add_kernel_ieee (EXTENDED *op_a, EXTENDED *op_b, EXTENDED *op_c)
-{
-	unsigned long mask, fa, fb, fc;
-	int diff;
-
-	diff = op_a->e - op_b->e;
-	fa = op_a->f[0];
-	fb = op_b->f[0];
-	if (diff < 0) {
-		diff = -diff;
-		op_c->e = op_b->e;
-		mask = (1UL << diff) - 1;
-		fa >>= diff;
-		if (op_a->f[0] & mask) {
-			fa |= 1;		/* set sticky bit */
-		}
-	} else {
-		op_c->e = op_a->e;
-		mask = (1UL << diff) - 1;
-		fb >>= diff;
-		if (op_b->f[0] & mask) {
-			fb |= 1;		/* set sticky bit */
-		}
-	}
-	if (op_a->s)
-		fa = -fa;
-	if (op_b->s)
-		fb = -fb;
-	fc = fa + fb;
-	op_c->f[1] = 0;
-	op_c->s = fc >> 63;
-	if (op_c->s) {
-		fc = -fc;
-	}
-	op_c->f[0] = fc;
-	normalize(op_c);
-	return 0;
-}
-
-
-/*
- * converts s-floating "a" to t-floating "b".
- *
- * INPUT PARAMETERS:
- *       a           a s-floating number to be converted
- *       f           the rounding mode (ROUND_NEAR, etc. )
- * OUTPUT PARAMETERS:
- *       b           the t-floating number that "a" is converted to.
- * RETURN VALUE:
- *       error flags - i.e., zero if no errors occurred,
- *       FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTST (int f, unsigned long a, unsigned long *b)
-{
-	EXTENDED temp;
-	fpclass_t a_type;
-
-	a_type = extend_ieee(a, &temp, SINGLE);
-	if (a_type >= NaN && a_type <= INFTY) {
-		*b = a;
-		if (a_type == NaN) {
-			*b |= (1UL << 51);	/* turn SNaN into QNaN */
-			return FPCR_INV;
-		}
-		return 0;
-	}
-	return round_t_ieee(f, &temp, b);
-}
-
-
-/*
- * converts t-floating "a" to s-floating "b".
- *
- * INPUT PARAMETERS:
- *       a           a t-floating number to be converted
- *       f           the rounding mode (ROUND_NEAR, etc. )
- * OUTPUT PARAMETERS:
- *       b           the s-floating number that "a" is converted to.
- * RETURN VALUE:
- *       error flags - i.e., zero if no errors occurred,
- *       FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTTS (int f, unsigned long a, unsigned long *b)
-{
-	EXTENDED temp;
-	fpclass_t a_type;
-
-	a_type = extend_ieee(a, &temp, DOUBLE);
-	if (a_type >= NaN && a_type <= INFTY) {
-		*b = a;
-		if (a_type == NaN) {
-			*b |= (1UL << 51);	/* turn SNaN into QNaN */
-			return FPCR_INV;
-		}
-		return 0;
-	}
-	return round_s_ieee(f, &temp, b);
-}
-
-
-/*
- * converts q-format (64-bit integer) "a" to s-floating "b".
- *
- * INPUT PARAMETERS:
- *       a           an 64-bit integer to be converted.
- *       f           the rounding mode (ROUND_NEAR, etc. )
- * OUTPUT PARAMETERS:
- *       b           the s-floating number "a" is converted to.
- * RETURN VALUE:
- *       error flags - i.e., zero if no errors occurred,
- *       FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTQS (int f, unsigned long a, unsigned long *b)
-{
-	EXTENDED op_b;
-
-	op_b.s    = 0;
-	op_b.f[0] = a;
-	op_b.f[1] = 0;
-	if (sign(a) < 0) {
-		op_b.s = 1;
-		op_b.f[0] = -a;
-	}
-	op_b.e = 55;
-	normalize(&op_b);
-	return round_s_ieee(f, &op_b, b);
-}
-
-
-/*
- * converts 64-bit integer "a" to t-floating "b".
- *
- * INPUT PARAMETERS:
- *       a           a 64-bit integer to be converted.
- *       f           the rounding mode (ROUND_NEAR, etc.)
- * OUTPUT PARAMETERS:
- *       b           the t-floating number "a" is converted to.
- * RETURN VALUE:
- *       error flags - i.e., zero if no errors occurred,
- *       FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTQT (int f, long a, unsigned long *b)
-{
-	EXTENDED op_b;
-
-	if (a != 0) {
-		op_b.s = (a < 0 ? 1 : 0);
-		op_b.f[0] = (a < 0 ? -a : a);
-		op_b.f[1] = 0;
-		op_b.e = 55;
-		normalize(&op_b);
-		return round_t_ieee(f, &op_b, b);
-	} else {
-		*b = 0;
-		return 0;
-	}
-}
-
-
-/*
- * converts t-floating "a" to 64-bit integer (q-format) "b".
- *
- * INPUT PARAMETERS:
- *       a           a t-floating number to be converted.
- *       f           the rounding mode (ROUND_NEAR, etc. )
- * OUTPUT PARAMETERS:
- *       b           the 64-bit integer "a" is converted to.
- * RETURN VALUE:
- *       error flags - i.e., zero if no errors occurred,
- *       FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTTQ (int f, unsigned long a, unsigned long *pb)
-{
-	unsigned int midway;
-	unsigned long ov, uv, res, b;
-	fpclass_t a_type;
-	EXTENDED temp;
-
-	a_type = extend_ieee(a, &temp, DOUBLE);
-
-	b = 0x7fffffffffffffff;
-	res = FPCR_INV;
-	if (a_type == NaN || a_type == INFTY)
-		goto out;
-
-	res = 0;
-	if (a_type == QNaN)
-		goto out;
-
-	if (temp.e > 0) {
-		ov = 0;
-		while (temp.e > 0) {
-			--temp.e;
-			ov |= temp.f[1] >> 63;
-			sll128(temp.f);
-		}
-		if (ov || (temp.f[1] & 0xffc0000000000000))
-			res |= FPCR_IOV | FPCR_INE;
-	}
-	else if (temp.e < 0) {
-		while (temp.e < 0) {
-			++temp.e;
-			uv = temp.f[0] & 1;		/* save sticky bit */
-			srl128(temp.f);
-			temp.f[0] |= uv;
-		}
-	}
-	b = (temp.f[1] << 9) | (temp.f[0] >> 55);
-
-	/*
-	 * Notice: the fraction is only 52 bits long.  Thus, rounding
-	 * cannot possibly result in an integer overflow.
-	 */
-	switch (RM(f)) {
-	      case ROUND_NEAR:
-		if (temp.f[0] & 0x0040000000000000) {
-			midway = (temp.f[0] & 0x003fffffffffffff) == 0;
-			if ((midway && (temp.f[0] & 0x0080000000000000)) ||
-			    !midway)
-				++b;
-		}
-		break;
-
-	      case ROUND_PINF:
-		b += ((temp.f[0] & 0x007fffffffffffff) != 0 && !temp.s);
-		break;
-
-	      case ROUND_NINF:
-		b += ((temp.f[0] & 0x007fffffffffffff) != 0 && temp.s);
-		break;
-
-	      case ROUND_CHOP:
-		/* no action needed */
-		break;
-	}
-	if ((temp.f[0] & 0x007fffffffffffff) != 0)
-		res |= FPCR_INE;
-
-	if (temp.s) {
-		b = -b;
-	}
-
-out:
-	*pb = b;
-	return res;
-}
-
-
-unsigned long
-ieee_CMPTEQ (unsigned long a, unsigned long b, unsigned long *c)
-{
-	EXTENDED op_a, op_b;
-	fpclass_t a_type, b_type;
-
-	*c = 0;
-	a_type = extend_ieee(a, &op_a, DOUBLE);
-	b_type = extend_ieee(b, &op_b, DOUBLE);
-	if (a_type == NaN || b_type == NaN)
-		return FPCR_INV;
-	if (a_type == QNaN || b_type == QNaN)
-		return 0;
-
-	if ((op_a.e == op_b.e && op_a.s == op_b.s &&
-	     op_a.f[0] == op_b.f[0] && op_a.f[1] == op_b.f[1]) ||
-	    (a_type == ZERO && b_type == ZERO))
-		*c = 0x4000000000000000;
-	return 0;
-}
-
-
-unsigned long
-ieee_CMPTLT (unsigned long a, unsigned long b, unsigned long *c)
-{
-	fpclass_t a_type, b_type;
-	EXTENDED op_a, op_b;
-
-	*c = 0;
-	a_type = extend_ieee(a, &op_a, DOUBLE);
-	b_type = extend_ieee(b, &op_b, DOUBLE);
-	if (a_type == NaN || b_type == NaN)
-		return FPCR_INV;
-	if (a_type == QNaN || b_type == QNaN)
-		return 0;
-
-	if ((op_a.s == 1 && op_b.s == 0 &&
-	     (a_type != ZERO || b_type != ZERO)) ||
-	    (op_a.s == 1 && op_b.s == 1 &&
-	     (op_a.e > op_b.e || (op_a.e == op_b.e &&
-				  cmp128(op_a.f, op_b.f) > 0))) ||
-	    (op_a.s == 0 && op_b.s == 0 &&
-	     (op_a.e < op_b.e || (op_a.e == op_b.e &&
-				  cmp128(op_a.f,op_b.f) < 0))))
-		*c = 0x4000000000000000;
-	return 0;
-}
-
-
-unsigned long
-ieee_CMPTLE (unsigned long a, unsigned long b, unsigned long *c)
-{
-	fpclass_t a_type, b_type;
-	EXTENDED op_a, op_b;
-
-	*c = 0;
-	a_type = extend_ieee(a, &op_a, DOUBLE);
-	b_type = extend_ieee(b, &op_b, DOUBLE);
-	if (a_type == NaN || b_type == NaN)
-		return FPCR_INV;
-	if (a_type == QNaN || b_type == QNaN)
-		return 0;
-
-	if ((a_type == ZERO && b_type == ZERO) ||
-	    (op_a.s == 1 && op_b.s == 0) ||
-	    (op_a.s == 1 && op_b.s == 1 &&
-	     (op_a.e > op_b.e || (op_a.e == op_b.e &&
-				  cmp128(op_a.f,op_b.f) >= 0))) ||
-	    (op_a.s == 0 && op_b.s == 0 &&
-	     (op_a.e < op_b.e || (op_a.e == op_b.e &&
-				  cmp128(op_a.f,op_b.f) <= 0))))
-		*c = 0x4000000000000000;
-	return 0;
-}
-
-
-unsigned long
-ieee_CMPTUN (unsigned long a, unsigned long b, unsigned long *c)
-{
-	fpclass_t a_type, b_type;
-	EXTENDED op_a, op_b;
-
-	*c = 0x4000000000000000;
-	a_type = extend_ieee(a, &op_a, DOUBLE);
-	b_type = extend_ieee(b, &op_b, DOUBLE);
-	if (a_type == NaN || b_type == NaN)
-		return FPCR_INV;
-	if (a_type == QNaN || b_type == QNaN)
-		return 0;
-	*c = 0;
-	return 0;
-}
-
-
-/*
- * Add a + b = c, where a, b, and c are ieee s-floating numbers.  "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_ADDS (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-	fpclass_t a_type, b_type;
-	EXTENDED op_a, op_b, op_c;
-
-	a_type = extend_ieee(a, &op_a, SINGLE);
-	b_type = extend_ieee(b, &op_b, SINGLE);
-	if ((a_type >= NaN && a_type <= INFTY) ||
-	    (b_type >= NaN && b_type <= INFTY))
-	{
-		/* propagate NaNs according to arch. ref. handbook: */
-		if (b_type == QNaN)
-			*c = b;
-		else if (b_type == NaN)
-			*c = b | (1UL << 51);
-		else if (a_type == QNaN)
-			*c = a;
-		else if (a_type == NaN)
-			*c = a | (1UL << 51);
-
-		if (a_type == NaN || b_type == NaN)
-			return FPCR_INV;
-		if (a_type == QNaN || b_type == QNaN)
-			return 0;
-
-		if (a_type == INFTY && b_type == INFTY && sign(a) != sign(b)) {
-			*c = IEEE_QNaN;
-			return FPCR_INV;
-		}
-		if (a_type == INFTY)
-			*c = a;
-		else
-			*c = b;
-		return 0;
-	}
-
-	add_kernel_ieee(&op_a, &op_b, &op_c);
-	/* special case for -0 + -0 ==> -0 */
-	if (a_type == ZERO && b_type == ZERO)
-		op_c.s = op_a.s && op_b.s;
-	return round_s_ieee(f, &op_c, c);
-}
-
-
-/*
- * Add a + b = c, where a, b, and c are ieee t-floating numbers.  "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_ADDT (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-	fpclass_t a_type, b_type;
-	EXTENDED op_a, op_b, op_c;
-
-	a_type = extend_ieee(a, &op_a, DOUBLE);
-	b_type = extend_ieee(b, &op_b, DOUBLE);
-	if ((a_type >= NaN && a_type <= INFTY) ||
-	    (b_type >= NaN && b_type <= INFTY))
-	{
-		/* propagate NaNs according to arch. ref. handbook: */
-		if (b_type == QNaN)
-			*c = b;
-		else if (b_type == NaN)
-			*c = b | (1UL << 51);
-		else if (a_type == QNaN)
-			*c = a;
-		else if (a_type == NaN)
-			*c = a | (1UL << 51);
-
-		if (a_type == NaN || b_type == NaN)
-			return FPCR_INV;
-		if (a_type == QNaN || b_type == QNaN)
-			return 0;
-
-		if (a_type == INFTY && b_type == INFTY && sign(a) != sign(b)) {
-			*c = IEEE_QNaN;
-			return FPCR_INV;
-		}
-		if (a_type == INFTY)
-			*c = a;
-		else
-			*c = b;
-		return 0;
-	}
-	add_kernel_ieee(&op_a, &op_b, &op_c);
-	/* special case for -0 + -0 ==> -0 */
-	if (a_type == ZERO && b_type == ZERO)
-		op_c.s = op_a.s && op_b.s;
-
-	return round_t_ieee(f, &op_c, c);
-}
-
-
-/*
- * Subtract a - b = c, where a, b, and c are ieee s-floating numbers.
- * "f" contains the rounding mode etc.
- */
-unsigned long
-ieee_SUBS (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-	fpclass_t a_type, b_type;
-	EXTENDED op_a, op_b, op_c;
-
-	a_type = extend_ieee(a, &op_a, SINGLE);
-	b_type = extend_ieee(b, &op_b, SINGLE);
-	if ((a_type >= NaN && a_type <= INFTY) ||
-	    (b_type >= NaN && b_type <= INFTY))
-	{
-		/* propagate NaNs according to arch. ref. handbook: */
-		if (b_type == QNaN)
-			*c = b;
-		else if (b_type == NaN)
-			*c = b | (1UL << 51);
-		else if (a_type == QNaN)
-			*c = a;
-		else if (a_type == NaN)
-			*c = a | (1UL << 51);
-
-		if (a_type == NaN || b_type == NaN)
-			return FPCR_INV;
-		if (a_type == QNaN || b_type == QNaN)
-			return 0;
-
-		if (a_type == INFTY && b_type == INFTY && sign(a) == sign(b)) {
-			*c = IEEE_QNaN;
-			return FPCR_INV;
-		}
-		if (a_type == INFTY)
-			*c = a;
-		else
-			*c = b ^ (1UL << 63);
-		return 0;
-	}
-	op_b.s = !op_b.s;
-	add_kernel_ieee(&op_a, &op_b, &op_c);
-	/* special case for -0 - +0 ==> -0 */
-	if (a_type == ZERO && b_type == ZERO)
-		op_c.s = op_a.s && op_b.s;
-
-	return round_s_ieee(f, &op_c, c);
-}
-
-
-/*
- * Subtract a - b = c, where a, b, and c are ieee t-floating numbers.
- * "f" contains the rounding mode etc.
- */
-unsigned long
-ieee_SUBT (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-	fpclass_t a_type, b_type;
-	EXTENDED op_a, op_b, op_c;
-
-	a_type = extend_ieee(a, &op_a, DOUBLE);
-	b_type = extend_ieee(b, &op_b, DOUBLE);
-	if ((a_type >= NaN && a_type <= INFTY) ||
-	    (b_type >= NaN && b_type <= INFTY))
-	{
-		/* propagate NaNs according to arch. ref. handbook: */
-		if (b_type == QNaN)
-			*c = b;
-		else if (b_type == NaN)
-			*c = b | (1UL << 51);
-		else if (a_type == QNaN)
-			*c = a;
-		else if (a_type == NaN)
-			*c = a | (1UL << 51);
-
-		if (a_type == NaN || b_type == NaN)
-			return FPCR_INV;
-		if (a_type == QNaN || b_type == QNaN)
-			return 0;
-
-		if (a_type == INFTY && b_type == INFTY && sign(a) == sign(b)) {
-			*c = IEEE_QNaN;
-			return FPCR_INV;
-		}
-		if (a_type == INFTY)
-			*c = a;
-		else
-			*c = b ^ (1UL << 63);
-		return 0;
-	}
-	op_b.s = !op_b.s;
-	add_kernel_ieee(&op_a, &op_b, &op_c);
-	/* special case for -0 - +0 ==> -0 */
-	if (a_type == ZERO && b_type == ZERO)
-		op_c.s = op_a.s && op_b.s;
-
-	return round_t_ieee(f, &op_c, c);
-}
-
-
-/*
- * Multiply a x b = c, where a, b, and c are ieee s-floating numbers.
- * "f" contains the rounding mode.
- */
-unsigned long
-ieee_MULS (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-	fpclass_t a_type, b_type;
-	EXTENDED op_a, op_b, op_c;
-
-	a_type = extend_ieee(a, &op_a, SINGLE);
-	b_type = extend_ieee(b, &op_b, SINGLE);
-	if ((a_type >= NaN && a_type <= INFTY) ||
-	    (b_type >= NaN && b_type <= INFTY))
-	{
-		/* propagate NaNs according to arch. ref. handbook: */
-		if (b_type == QNaN)
-			*c = b;
-		else if (b_type == NaN)
-			*c = b | (1UL << 51);
-		else if (a_type == QNaN)
-			*c = a;
-		else if (a_type == NaN)
-			*c = a | (1UL << 51);
-
-		if (a_type == NaN || b_type == NaN)
-			return FPCR_INV;
-		if (a_type == QNaN || b_type == QNaN)
-			return 0;
-
-		if ((a_type == INFTY && b_type == ZERO) ||
-		    (b_type == INFTY && a_type == ZERO))
-		{
-			*c = IEEE_QNaN;		/* return canonical QNaN */
-			return FPCR_INV;
-		}
-		if (a_type == INFTY)
-			*c = a ^ ((b >> 63) << 63);
-		else if (b_type == INFTY)
-			*c = b ^ ((a >> 63) << 63);
-		else
-			/* either of a and b are +/-0 */
-			*c = ((unsigned long) op_a.s ^ op_b.s) << 63;
-		return 0;
-	}
-	op_c.s = op_a.s ^ op_b.s;
-	op_c.e = op_a.e + op_b.e - 55;
-	mul64(op_a.f[0], op_b.f[0], op_c.f);
-
-	return round_s_ieee(f, &op_c, c);
-}
-
-
-/*
- * Multiply a x b = c, where a, b, and c are ieee t-floating numbers.
- * "f" contains the rounding mode.
- */
-unsigned long
-ieee_MULT (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-	fpclass_t a_type, b_type;
-	EXTENDED op_a, op_b, op_c;
-
-	*c = IEEE_QNaN;
-	a_type = extend_ieee(a, &op_a, DOUBLE);
-	b_type = extend_ieee(b, &op_b, DOUBLE);
-	if ((a_type >= NaN && a_type <= ZERO) ||
-	    (b_type >= NaN && b_type <= ZERO))
-	{
-		/* propagate NaNs according to arch. ref. handbook: */
-		if (b_type == QNaN)
-			*c = b;
-		else if (b_type == NaN)
-			*c = b | (1UL << 51);
-		else if (a_type == QNaN)
-			*c = a;
-		else if (a_type == NaN)
-			*c = a | (1UL << 51);
-
-		if (a_type == NaN || b_type == NaN)
-			return FPCR_INV;
-		if (a_type == QNaN || b_type == QNaN)
-			return 0;
-
-		if ((a_type == INFTY && b_type == ZERO) ||
-		    (b_type == INFTY && a_type == ZERO))
-		{
-			*c = IEEE_QNaN;		/* return canonical QNaN */
-			return FPCR_INV;
-		}
-		if (a_type == INFTY)
-			*c = a ^ ((b >> 63) << 63);
-		else if (b_type == INFTY)
-			*c = b ^ ((a >> 63) << 63);
-		else
-			/* either of a and b are +/-0 */
-			*c = ((unsigned long) op_a.s ^ op_b.s) << 63;
-		return 0;
-	}
-	op_c.s = op_a.s ^ op_b.s;
-	op_c.e = op_a.e + op_b.e - 55;
-	mul64(op_a.f[0], op_b.f[0], op_c.f);
-
-	return round_t_ieee(f, &op_c, c);
-}
-
-
-/*
- * Divide a / b = c, where a, b, and c are ieee s-floating numbers.
- * "f" contains the rounding mode etc.
- */
-unsigned long
-ieee_DIVS (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-	fpclass_t a_type, b_type;
-	EXTENDED op_a, op_b, op_c;
-
-	a_type = extend_ieee(a, &op_a, SINGLE);
-	b_type = extend_ieee(b, &op_b, SINGLE);
-	if ((a_type >= NaN && a_type <= ZERO) ||
-	    (b_type >= NaN && b_type <= ZERO))
-	{
-		unsigned long res;
-
-		/* propagate NaNs according to arch. ref. handbook: */
-		if (b_type == QNaN)
-			*c = b;
-		else if (b_type == NaN)
-			*c = b | (1UL << 51);
-		else if (a_type == QNaN)
-			*c = a;
-		else if (a_type == NaN)
-			*c = a | (1UL << 51);
-
-		if (a_type == NaN || b_type == NaN)
-			return FPCR_INV;
-		if (a_type == QNaN || b_type == QNaN)
-			return 0;
-
-		res = 0;
-		*c = IEEE_PINF;
-		if (a_type == INFTY) {
-			if (b_type == INFTY) {
-				*c = IEEE_QNaN;
-				return FPCR_INV;
-			}
-		} else if (b_type == ZERO) {
-			if (a_type == ZERO) {
-				*c = IEEE_QNaN;
-				return FPCR_INV;
-			}
-			res = FPCR_DZE;
-		} else
-			/* a_type == ZERO || b_type == INFTY */
-			*c = 0;
-		*c |= (unsigned long) (op_a.s ^ op_b.s) << 63;
-		return res;
-	}
-	op_c.s = op_a.s ^ op_b.s;
-	op_c.e = op_a.e - op_b.e;
-
-	op_a.f[1] = op_a.f[0];
-	op_a.f[0] = 0;
-	div128(op_a.f, op_b.f, op_c.f);
-	if (a_type != ZERO)
-		/* force a sticky bit because DIVs never hit exact .5: */
-		op_c.f[0] |= STICKY_S;
-	normalize(&op_c);
-	op_c.e -= 9;		/* remove excess exp from original shift */
-	return round_s_ieee(f, &op_c, c);
-}
-
-
-/*
- * Divide a/b = c, where a, b, and c are ieee t-floating numbers.  "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_DIVT (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
-	fpclass_t a_type, b_type;
-	EXTENDED op_a, op_b, op_c;
-
-	*c = IEEE_QNaN;
-	a_type = extend_ieee(a, &op_a, DOUBLE);
-	b_type = extend_ieee(b, &op_b, DOUBLE);
-	if ((a_type >= NaN && a_type <= ZERO) ||
-	    (b_type >= NaN && b_type <= ZERO))
-	{
-		unsigned long res;
-
-		/* propagate NaNs according to arch. ref. handbook: */
-		if (b_type == QNaN)
-			*c = b;
-		else if (b_type == NaN)
-			*c = b | (1UL << 51);
-		else if (a_type == QNaN)
-			*c = a;
-		else if (a_type == NaN)
-			*c = a | (1UL << 51);
-
-		if (a_type == NaN || b_type == NaN)
-			return FPCR_INV;
-		if (a_type == QNaN || b_type == QNaN)
-			return 0;
-
-		res = 0;
-		*c = IEEE_PINF;
-		if (a_type == INFTY) {
-			if (b_type == INFTY) {
-				*c = IEEE_QNaN;
-				return FPCR_INV;
-			}
-		} else if (b_type == ZERO) {
-			if (a_type == ZERO) {
-				*c = IEEE_QNaN;
-				return FPCR_INV;
-			}
-			res = FPCR_DZE;
-		} else
-			/* a_type == ZERO || b_type == INFTY */
-			*c = 0;
-		*c |= (unsigned long) (op_a.s ^ op_b.s) << 63;
-		return res;
-	}
-	op_c.s = op_a.s ^ op_b.s;
-	op_c.e = op_a.e - op_b.e;
-
-	op_a.f[1] = op_a.f[0];
-	op_a.f[0] = 0;
-	div128(op_a.f, op_b.f, op_c.f);
-	if (a_type != ZERO)
-		/* force a sticky bit because DIVs never hit exact .5 */
-		op_c.f[0] |= STICKY_T;
-	normalize(&op_c);
-	op_c.e -= 9;		/* remove excess exp from original shift */
-	return round_t_ieee(f, &op_c, c);
-}
-
-/*
- * Sqrt a = b, where a and b are ieee s-floating numbers.  "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_SQRTS (int f, unsigned long a, unsigned long *b)
-{
-	fpclass_t a_type;
-	EXTENDED op_a, op_b;
-
-	*b = IEEE_QNaN;
-	a_type = extend_ieee(a, &op_a, SINGLE);
-	if (op_a.s == 0) {
-		/* FIXME -- handle positive denormals.  */
-		send_sig(SIGFPE, current, 1);
-	}
-	return FPCR_INV;
-}
-
-/*
- * Sqrt a = b, where a and b are ieee t-floating numbers.  "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_SQRTT (int f, unsigned long a, unsigned long *b)
-{
-	fpclass_t a_type;
-	EXTENDED op_a, op_b;
-
-	*b = IEEE_QNaN;
-	a_type = extend_ieee(a, &op_a, DOUBLE);
-	if (op_a.s == 0) {
-		/* FIXME -- handle positive denormals.  */
-		send_sig(SIGFPE, current, 1);
-	}
-	return FPCR_INV;
-}
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/math-emu/ieee-math.h linux/arch/alpha/math-emu/ieee-math.h
--- v2.3.29/linux/arch/alpha/math-emu/ieee-math.h	Mon Jul 12 07:49:36 1999
+++ linux/arch/alpha/math-emu/ieee-math.h	Wed Dec 31 16:00:00 1969
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 1992,1995 by
- * Digital Equipment Corporation, Maynard, Massachusetts.
- * This file may be redistributed according to the terms of the
- * GNU General Public License.
- */
-#ifndef __ieee_math_h__
-#define __ieee_math_h__
-
-#include <asm/fpu.h>
-
-#define ROUND_SHIFT	6		/* make space for trap-enable bits */
-#define RM(f)		(((f) >> ROUND_SHIFT) & 0x3)
-
-#define ROUND_CHOP 	(FPCR_DYN_CHOPPED >> FPCR_DYN_SHIFT)
-#define ROUND_NINF 	(FPCR_DYN_MINUS   >> FPCR_DYN_SHIFT)
-#define ROUND_NEAR 	(FPCR_DYN_NORMAL  >> FPCR_DYN_SHIFT)
-#define ROUND_PINF 	(FPCR_DYN_PLUS    >> FPCR_DYN_SHIFT)
-
-extern unsigned long ieee_CVTST (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_CVTTS (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_CVTQS (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_CVTQT (int rm, long a, unsigned long *b);
-extern unsigned long ieee_CVTTQ (int rm, unsigned long a, unsigned long *b);
-
-extern unsigned long ieee_CMPTEQ (unsigned long a, unsigned long b,
-				  unsigned long *c);
-extern unsigned long ieee_CMPTLT (unsigned long a, unsigned long b,
-				  unsigned long *c);
-extern unsigned long ieee_CMPTLE (unsigned long a, unsigned long b,
-				  unsigned long *c);
-extern unsigned long ieee_CMPTUN (unsigned long a, unsigned long b,
-				  unsigned long *c);
-
-extern unsigned long ieee_ADDS (int rm, unsigned long a, unsigned long b,
-				unsigned long *c);
-extern unsigned long ieee_ADDT (int rm, unsigned long a, unsigned long b,
-				unsigned long *c);
-extern unsigned long ieee_SUBS (int rm, unsigned long a, unsigned long b,
-				unsigned long *c);
-extern unsigned long ieee_SUBT (int rm, unsigned long a, unsigned long b,
-				unsigned long *c);
-extern unsigned long ieee_MULS (int rm, unsigned long a, unsigned long b,
-				unsigned long *c);
-extern unsigned long ieee_MULT (int rm, unsigned long a, unsigned long b,
-				unsigned long *c);
-extern unsigned long ieee_DIVS (int rm, unsigned long a, unsigned long b,
-				unsigned long *c);
-extern unsigned long ieee_DIVT (int rm, unsigned long a, unsigned long b,
-				unsigned long *c);
-extern unsigned long ieee_SQRTS (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_SQRTT (int rm, unsigned long a, unsigned long *b);
-
-#endif /* __ieee_math_h__ */
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/math-emu/math.c linux/arch/alpha/math-emu/math.c
--- v2.3.29/linux/arch/alpha/math-emu/math.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/math-emu/math.c	Thu Dec  2 15:28:54 1999
@@ -0,0 +1,447 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/uaccess.h>
+
+#include "sfp-util.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+#include <math-emu/double.h>
+
+#define	OPC_PAL		0x00
+#define OPC_INTA	0x10
+#define OPC_INTL	0x11
+#define OPC_INTS	0x12
+#define OPC_INTM	0x13
+#define OPC_FLTC	0x14
+#define OPC_FLTV	0x15
+#define OPC_FLTI	0x16
+#define OPC_FLTL	0x17
+#define OPC_MISC	0x18
+#define	OPC_JSR		0x1a
+
+#define FOP_SRC_S	0
+#define FOP_SRC_T	2
+#define FOP_SRC_Q	3
+
+#define FOP_FNC_ADDx	0
+#define FOP_FNC_CVTQL	0
+#define FOP_FNC_SUBx	1
+#define FOP_FNC_MULx	2
+#define FOP_FNC_DIVx	3
+#define FOP_FNC_CMPxUN	4
+#define FOP_FNC_CMPxEQ	5
+#define FOP_FNC_CMPxLT	6
+#define FOP_FNC_CMPxLE	7
+#define FOP_FNC_SQRTx	11
+#define FOP_FNC_CVTxS	12
+#define FOP_FNC_CVTxT	14
+#define FOP_FNC_CVTxQ	15
+
+#define MISC_TRAPB	0x0000
+#define MISC_EXCB	0x0400
+
+extern unsigned long alpha_read_fp_reg (unsigned long reg);
+extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
+extern unsigned long alpha_read_fp_reg_s (unsigned long reg);
+extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val);
+
+
+#ifdef MODULE
+
+MODULE_DESCRIPTION("FP Software completion module");
+
+extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long);
+extern long (*alpha_fp_emul) (unsigned long pc);
+
+static long (*save_emul_imprecise)(struct pt_regs *, unsigned long);
+static long (*save_emul) (unsigned long pc);
+
+long do_alpha_fp_emul_imprecise(struct pt_regs *, unsigned long);
+long do_alpha_fp_emul(unsigned long);
+
+int init_module(void)
+{
+	save_emul_imprecise = alpha_fp_emul_imprecise;
+	save_emul = alpha_fp_emul;
+	alpha_fp_emul_imprecise = do_alpha_fp_emul_imprecise;
+	alpha_fp_emul = do_alpha_fp_emul;
+	return 0;
+}
+
+void cleanup_module(void)
+{
+	alpha_fp_emul_imprecise = save_emul_imprecise;
+	alpha_fp_emul = save_emul;
+}
+
+#undef  alpha_fp_emul_imprecise
+#define alpha_fp_emul_imprecise		do_alpha_fp_emul_imprecise
+#undef  alpha_fp_emul
+#define alpha_fp_emul			do_alpha_fp_emul
+
+#endif /* MODULE */
+
+/* For 128-bit division.  */
+
+void
+udiv128(unsigned long divisor_f0, unsigned long divisor_f1,
+	unsigned long dividend_f0, unsigned long dividend_f1,
+	unsigned long *quot, unsigned long *remd)
+{
+	_FP_FRAC_DECL_2(quo);
+	_FP_FRAC_DECL_2(rem);
+	_FP_FRAC_DECL_2(tmp);
+	unsigned long i, num_bits, bit;
+
+	_FP_FRAC_SET_2(rem, _FP_ZEROFRAC_2);
+	_FP_FRAC_SET_2(quo, _FP_ZEROFRAC_2);
+
+	if (_FP_FRAC_ZEROP_2(divisor))
+		goto out;
+
+	if (_FP_FRAC_GT_2(divisor, dividend)) {
+		_FP_FRAC_COPY_2(rem, dividend);
+		goto out;
+	}
+
+	if (_FP_FRAC_EQ_2(divisor, dividend)) {
+		__FP_FRAC_SET_2(quo, 0, 1);
+		goto out;
+	}
+
+	num_bits = 128;
+	while (1) {
+		bit = _FP_FRAC_NEGP_2(dividend);
+		_FP_FRAC_COPY_2(tmp, rem);
+		_FP_FRAC_SLL_2(tmp, 1);
+		_FP_FRAC_LOW_2(tmp) |= bit;
+		if (! _FP_FRAC_GE_2(tmp, divisor))
+			break;
+		_FP_FRAC_COPY_2(rem, tmp);
+		_FP_FRAC_SLL_2(dividend, 1);
+		num_bits--;
+	}
+
+	for (i = 0; i < num_bits; i++) {
+		bit = _FP_FRAC_NEGP_2(dividend);
+		_FP_FRAC_SLL_2(rem, 1);
+		_FP_FRAC_LOW_2(rem) |= bit;
+		_FP_FRAC_SUB_2(tmp, rem, divisor);
+		bit = _FP_FRAC_NEGP_2(tmp);
+		_FP_FRAC_SLL_2(dividend, 1);
+		_FP_FRAC_SLL_2(quo, 1);
+		if (!bit) {
+			_FP_FRAC_LOW_2(quo) |= 1;
+			_FP_FRAC_COPY_2(rem, tmp);
+		}
+	}
+
+out:
+	*quot = quo_f1;
+	*remd = rem_f1;
+	return;
+}
+
+/*
+ * Emulate the floating point instruction at address PC.  Returns 0 if
+ * emulation fails.  Notice that the kernel does not and cannot use FP
+ * regs.  This is good because it means that instead of
+ * saving/restoring all fp regs, we simply stick the result of the
+ * operation into the appropriate register.
+ */
+long
+alpha_fp_emul (unsigned long pc)
+{
+	FP_DECL_EX;
+	FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
+	FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
+
+	unsigned long fa, fb, fc, func, mode, src;
+	unsigned long fpcw = current->thread.flags;
+	unsigned long res, va, vb, vc, fpcr;
+	__u32 insn;
+
+	MOD_INC_USE_COUNT;
+
+	get_user(insn, (__u32*)pc);
+	fc     = (insn >>  0) & 0x1f;	/* destination register */
+	fb     = (insn >> 16) & 0x1f;
+	fa     = (insn >> 21) & 0x1f;
+	func   = (insn >>  5) & 0xf;
+	src    = (insn >>  9) & 0x3;
+	mode   = (insn >> 11) & 0x3;
+	
+	fpcr = rdfpcr();
+
+	if (mode == 3) {
+	    /* Dynamic -- get rounding mode from fpcr.  */
+	    mode = (fpcr >> FPCR_DYN_SHIFT) & 3;
+	}
+
+	switch (src) {
+	case FOP_SRC_S:
+		va = alpha_read_fp_reg_s(fa);
+		vb = alpha_read_fp_reg_s(fb);
+		
+		FP_UNPACK_SP(SA, &va);
+		FP_UNPACK_SP(SB, &vb);
+
+		switch (func) {
+		case FOP_FNC_SUBx:
+			FP_SUB_S(SR, SA, SB);
+			goto pack_s;
+
+		case FOP_FNC_ADDx:
+			FP_ADD_S(SR, SA, SB);
+			goto pack_s;
+
+		case FOP_FNC_MULx:
+			FP_MUL_S(SR, SA, SB);
+			goto pack_s;
+
+		case FOP_FNC_DIVx:
+			FP_DIV_S(SR, SA, SB);
+			goto pack_s;
+
+		case FOP_FNC_SQRTx:
+			FP_SQRT_S(SR, SB);
+			goto pack_s;
+		}
+		goto bad_insn;
+
+	case FOP_SRC_T:
+		va = alpha_read_fp_reg(fa);
+		vb = alpha_read_fp_reg(fb);
+
+		if ((func & ~3) == FOP_FNC_CMPxUN) {
+			FP_UNPACK_RAW_DP(DA, &va);
+			FP_UNPACK_RAW_DP(DB, &vb);
+			if (!DA_e && !_FP_FRAC_ZEROP_1(DA)) {
+				FP_SET_EXCEPTION(FP_EX_DENORM);
+				if (FP_DENORM_ZERO)
+					_FP_FRAC_SET_1(DA, _FP_ZEROFRAC_1);
+			}
+			if (!DB_e && !_FP_FRAC_ZEROP_1(DB)) {
+				FP_SET_EXCEPTION(FP_EX_DENORM);
+				if (FP_DENORM_ZERO)
+					_FP_FRAC_SET_1(DB, _FP_ZEROFRAC_1);
+			}
+			FP_CMP_D(res, DA, DB, 3);
+			vc = 0x4000000000000000;
+			/* CMPTEQ, CMPTUN don't trap on QNaN, while CMPTLT and CMPTLE do */
+			if (res == 3 && ((func & 3) >= 2 || FP_ISSIGNAN_D(DA) || FP_ISSIGNAN_D(DB)))
+				FP_SET_EXCEPTION(FP_EX_INVALID);
+			switch (func) {
+			case FOP_FNC_CMPxUN: if (res != 3) vc = 0; break;
+			case FOP_FNC_CMPxEQ: if (res) vc = 0; break;
+			case FOP_FNC_CMPxLT: if (res != -1) vc = 0; break;
+			case FOP_FNC_CMPxLE: if ((long)res > 0) vc = 0; break;
+			}
+			goto done_d;
+		}
+
+		FP_UNPACK_DP(DA, &va);
+		FP_UNPACK_DP(DB, &vb);
+
+		switch (func) {
+		case FOP_FNC_SUBx:
+			FP_SUB_D(DR, DA, DB);
+			goto pack_d;
+
+		case FOP_FNC_ADDx:
+			FP_ADD_D(DR, DA, DB);
+			goto pack_d;
+
+		case FOP_FNC_MULx:
+			FP_MUL_D(DR, DA, DB);
+			goto pack_d;
+
+		case FOP_FNC_DIVx:
+			FP_DIV_D(DR, DA, DB);
+			goto pack_d;
+
+		case FOP_FNC_SQRTx:
+			FP_SQRT_D(DR, DB);
+			goto pack_d;
+
+		case FOP_FNC_CVTxS:
+			/* It is irritating that DEC encoded CVTST with
+			   SRC == T_floating.  It is also interesting that
+			   the bit used to tell the two apart is /U... */
+			if (insn & 0x2000) {
+				FP_CONV(S,D,1,1,SR,DB);
+				goto pack_s;
+			} else {
+				/* CVTST need do nothing else but copy the
+				   bits and repack.  */
+				DR_c = DB_c;
+				DR_s = DB_s;
+				DR_e = DB_e;
+				DR_f = DB_f;
+				goto pack_d;
+			}
+
+		case FOP_FNC_CVTxQ:
+			if (DB_c == FP_CLS_NAN && (_FP_FRAC_HIGH_RAW_D(DB) & _FP_QNANBIT_D))
+				vc = 0; /* AAHB Table B-2 sais QNaN should not trigger INV */
+			else
+				FP_TO_INT_ROUND_D(vc, DB, 64, 2);
+			goto done_d;
+		}
+		goto bad_insn;
+
+	case FOP_SRC_Q:
+		vb = alpha_read_fp_reg(fb);
+
+		switch (func) {
+		case FOP_FNC_CVTQL:
+			/* Notice: We can get here only due to an integer
+			   overflow.  Such overflows are reported as invalid
+			   ops.  We return the result the hw would have
+			   computed.  */
+			vc = ((vb & 0xc0000000) << 32 |	/* sign and msb */
+			      (vb & 0x3fffffff) << 29);	/* rest of the int */
+			FP_SET_EXCEPTION (FP_EX_INVALID);
+			goto done_d;
+
+		case FOP_FNC_CVTxS:
+			FP_FROM_INT_S(SR, ((long)vb), 64, long);
+			goto pack_s;
+
+		case FOP_FNC_CVTxT:
+			FP_FROM_INT_D(DR, ((long)vb), 64, long);
+			goto pack_d;
+		}
+		goto bad_insn;
+	}
+	goto bad_insn;
+
+pack_s:
+	FP_PACK_SP(&vc, SR);
+	alpha_write_fp_reg_s(fc, vc);
+	goto done;
+
+pack_d:
+	FP_PACK_DP(&vc, DR);
+done_d:
+	alpha_write_fp_reg(fc, vc);
+	goto done;
+
+	/*
+	 * Take the appropriate action for each possible
+	 * floating-point result:
+	 *
+	 *	- Set the appropriate bits in the FPCR
+	 *	- If the specified exception is enabled in the FPCR,
+	 *	  return.  The caller (entArith) will dispatch
+	 *	  the appropriate signal to the translated program.
+	 *
+	 * In addition, properly track the exception state in software
+	 * as described in the Alpha Architectre Handbook section 4.7.7.3.
+	 */
+done:
+	if (_fex) {
+		/* Record exceptions in software control word.  */
+		current->thread.flags
+		  = fpcw |= (_fex << IEEE_STATUS_TO_EXCSUM_SHIFT);
+
+		/* Update hardware control register */
+		fpcr &= (~FPCR_MASK | FPCR_DYN_MASK);
+		fpcr |= ieee_swcr_to_fpcr(fpcw);
+		wrfpcr(fpcr);
+
+		/* Do we generate a signal?  */
+		if (_fex & fpcw & IEEE_TRAP_ENABLE_MASK) {
+			MOD_DEC_USE_COUNT;
+			return 0;
+		}
+	}
+
+	/* We used to write the destination register here, but DEC FORTRAN
+	   requires that the result *always* be written... so we do the write
+	   immediately after the operations above.  */
+
+	MOD_DEC_USE_COUNT;
+	return 1;
+
+bad_insn:
+	printk(KERN_ERR "alpha_fp_emul: Invalid FP insn %#x at %#lx\n",
+	       insn, pc);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+long
+alpha_fp_emul_imprecise (struct pt_regs *regs, unsigned long write_mask)
+{
+	unsigned long trigger_pc = regs->pc - 4;
+	unsigned long insn, opcode, rc;
+
+	MOD_INC_USE_COUNT;
+
+	/*
+	 * Turn off the bits corresponding to registers that are the
+	 * target of instructions that set bits in the exception
+	 * summary register.  We have some slack doing this because a
+	 * register that is the target of a trapping instruction can
+	 * be written at most once in the trap shadow.
+	 *
+	 * Branches, jumps, TRAPBs, EXCBs and calls to PALcode all
+	 * bound the trap shadow, so we need not look any further than
+	 * up to the first occurrence of such an instruction.
+	 */
+	while (write_mask) {
+		get_user(insn, (__u32*)(trigger_pc));
+		opcode = insn >> 26;
+		rc = insn & 0x1f;
+
+		switch (opcode) {
+		      case OPC_PAL:
+		      case OPC_JSR:
+		      case 0x30 ... 0x3f:	/* branches */
+			MOD_DEC_USE_COUNT;
+			return 0;
+
+		      case OPC_MISC:
+			switch (insn & 0xffff) {
+			      case MISC_TRAPB:
+			      case MISC_EXCB:
+				MOD_DEC_USE_COUNT;
+				return 0;
+
+			      default:
+				break;
+			}
+			break;
+
+		      case OPC_INTA:
+		      case OPC_INTL:
+		      case OPC_INTS:
+		      case OPC_INTM:
+			write_mask &= ~(1UL << rc);
+			break;
+
+		      case OPC_FLTC:
+		      case OPC_FLTV:
+		      case OPC_FLTI:
+		      case OPC_FLTL:
+			write_mask &= ~(1UL << (rc + 32));
+			break;
+		}
+		if (!write_mask) {
+			if (alpha_fp_emul(trigger_pc)) {
+				/* re-execute insns in trap-shadow: */
+				regs->pc = trigger_pc + 4;
+				MOD_DEC_USE_COUNT;
+				return 1;
+			}
+			break;
+		}
+		trigger_pc -= 4;
+	}
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/math-emu/sfp-util.h linux/arch/alpha/math-emu/sfp-util.h
--- v2.3.29/linux/arch/alpha/math-emu/sfp-util.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/alpha/math-emu/sfp-util.h	Thu Dec  2 15:28:54 1999
@@ -0,0 +1,40 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/fpu.h>
+
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  ((sl) = (al) + (bl), (sh) = (ah) + (bh) + ((sl) < (al)))
+
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  ((sl) = (al) - (bl), (sh) = (ah) - (bh) - ((al) < (bl)))
+
+#define umul_ppmm(wh, wl, u, v)			\
+  __asm__ ("mulq %2,%3,%1; umulh %2,%3,%0"	\
+	   : "=r" ((UDItype)(wh)),		\
+	     "=&r" ((UDItype)(wl))		\
+	   : "r" ((UDItype)(u)),		\
+	     "r" ((UDItype)(v)))
+
+extern void udiv128(unsigned long, unsigned long,
+		    unsigned long, unsigned long,
+		    unsigned long *,
+		    unsigned long *);
+
+#define udiv_qrnnd(q, r, n1, n0, d)		\
+  do {						\
+    unsigned long xr, xi;			\
+    udiv128((n0), (n1), 0, (d), &xr, &xi);	\
+    (q) = xr; 					\
+    (r) = xi;					\
+  } while (0)
+
+#define UDIV_NEEDS_NORMALIZATION 1  
+
+#define abort()			goto bad_insn
+
+#ifndef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN -1
+#endif
+#define __BYTE_ORDER __LITTLE_ENDIAN
diff -u --recursive --new-file v2.3.29/linux/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c
--- v2.3.29/linux/arch/alpha/mm/init.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/alpha/mm/init.c	Thu Dec  2 20:31:31 1999
@@ -17,6 +17,7 @@
 #include <linux/mman.h>
 #include <linux/mm.h>
 #include <linux/swap.h>
+#include <linux/init.h>
 #include <linux/bootmem.h> /* max_low_pfn */
 #ifdef CONFIG_BLK_DEV_INITRD
 #include <linux/blk.h>
@@ -189,7 +190,8 @@
  * paging_init() sets up the page tables: in the alpha version this actually
  * unmaps the bootup page table (as we're now in KSEG, so we don't need it).
  */
-void paging_init(void)
+void
+paging_init(void)
 {
 	unsigned long newptbr;
 	unsigned long original_pcb_ptr;
@@ -210,13 +212,12 @@
 
 	if (dma_pfn > high_pfn)
 		zones_size[ZONE_DMA] = high_pfn;
-	else
-	{
-		zones_size[0] = dma_pfn;
+	else {
+		zones_size[ZONE_DMA] = dma_pfn;
 		zones_size[ZONE_NORMAL] = high_pfn - dma_pfn;
 	}
 
-	/* initialize mem_map[] */
+	/* Initialize mem_map[].  */
 	free_area_init(zones_size);
 
 	/* Initialize the kernel's page tables.  Linux puts the vptb in
@@ -273,12 +274,42 @@
 }
 #endif
 
-void
+static void __init printk_memory_info(void)
+{
+	unsigned long codesize, reservedpages, datasize, initsize, tmp;
+	extern int page_is_ram(unsigned long) __init;
+	extern char _text, _etext, _data, _edata;
+	extern char __init_begin, __init_end;
+
+	/* printk all informations */
+	reservedpages = 0;
+	for (tmp = 0; tmp < max_low_pfn; tmp++)
+		/*
+		 * Only count reserved RAM pages
+		 */
+		if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
+			reservedpages++;
+
+	codesize =  (unsigned long) &_etext - (unsigned long) &_text;
+	datasize =  (unsigned long) &_edata - (unsigned long) &_data;
+	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+	printk("Memory: %luk/%luk available (%luk kernel code, %luk reserved, %luk data, %luk init)\n",
+	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+	       max_mapnr << (PAGE_SHIFT-10),
+	       codesize >> 10,
+	       reservedpages << (PAGE_SHIFT-10),
+	       datasize >> 10,
+	       initsize >> 10);
+}
+
+void __init
 mem_init(void)
 {
 	max_mapnr = num_physpages = max_low_pfn;
 	totalram_pages += free_all_bootmem();
-	printk("Memory: %luk available\n", totalram_pages >> 10);
+
+	printk_memory_info();
 }
 
 void
@@ -299,7 +330,8 @@
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
-void free_initrd_mem(unsigned long start, unsigned long end)
+void
+free_initrd_mem(unsigned long start, unsigned long end)
 {
 	for (; start < end; start += PAGE_SIZE) {
 		ClearPageReserved(mem_map + MAP_NR(start));
diff -u --recursive --new-file v2.3.29/linux/arch/arm/Makefile linux/arch/arm/Makefile
--- v2.3.29/linux/arch/arm/Makefile	Tue Nov 23 22:42:20 1999
+++ linux/arch/arm/Makefile	Thu Dec  2 15:41:02 1999
@@ -156,7 +156,7 @@
 ifeq ($(CONFIG_ARCH_ACORN),y)
 SUBDIRS		+= drivers/acorn
 DRIVERS		+= drivers/acorn/block/acorn-block.a
-DRIVERS		+= drivers/acorn/char/acorn-char.a
+DRIVERS		+= drivers/acorn/char/acorn-char.o
 DRIVERS		+= drivers/acorn/net/acorn-net.a
 DRIVERS		+= drivers/acorn/scsi/acorn-scsi.a
 endif
diff -u --recursive --new-file v2.3.29/linux/arch/arm/kernel/bios32.c linux/arch/arm/kernel/bios32.c
--- v2.3.29/linux/arch/arm/kernel/bios32.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/arm/kernel/bios32.c	Thu Dec  2 15:41:02 1999
@@ -203,6 +203,15 @@
 	}
 }
 
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
+{
+	ranges->io_start -= bus->resource[0]->start;
+	ranges->io_end -= bus->resource[0]->start;
+	ranges->mem_start -= bus->resource[1]->start;
+	ranges->mem_end -= bus->resource[1]->start;
+}
+
 static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
 {
 	return 0;
@@ -349,4 +358,9 @@
 		return NULL;
 	}
 	return str;
+}
+
+void __init
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
 }
diff -u --recursive --new-file v2.3.29/linux/arch/arm/kernel/ecard.c linux/arch/arm/kernel/ecard.c
--- v2.3.29/linux/arch/arm/kernel/ecard.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/arm/kernel/ecard.c	Thu Dec  2 15:41:02 1999
@@ -43,7 +43,7 @@
 #include <asm/hardware.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/mmu_context.h>
 
 #ifdef CONFIG_ARCH_ARC
@@ -892,7 +892,7 @@
 
 static void ecard_proc_init(void)
 {
-	proc_bus_ecard_dir = create_proc_entry("ecard", S_IFDIR, proc_bus);
+	proc_bus_ecard_dir = proc_mkdir("ecard", proc_bus);
 	create_proc_info_entry("devices", 0, proc_bus_ecard_dir,
 		get_ecard_dev_info);
 }
diff -u --recursive --new-file v2.3.29/linux/arch/arm/kernel/entry-armv.S linux/arch/arm/kernel/entry-armv.S
--- v2.3.29/linux/arch/arm/kernel/entry-armv.S	Tue Nov 23 22:42:20 1999
+++ linux/arch/arm/kernel/entry-armv.S	Thu Dec  2 15:41:02 1999
@@ -899,7 +899,7 @@
 		b	__real_stubs_start + (vector_IRQ - __stubs_start)
 		b	__real_stubs_start + (vector_FIQ - __stubs_start)
 
-ENTRY(trap_init)
+ENTRY(__trap_init)
 		stmfd	sp!, {r4 - r6, lr}
 
 		adr	r1, .LCvectors			@ set up the vectors
diff -u --recursive --new-file v2.3.29/linux/arch/arm/kernel/fiq.c linux/arch/arm/kernel/fiq.c
--- v2.3.29/linux/arch/arm/kernel/fiq.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/arm/kernel/fiq.c	Thu Dec  2 15:41:02 1999
@@ -42,7 +42,7 @@
 
 #include <asm/fiq.h>
 #include <asm/io.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
diff -u --recursive --new-file v2.3.29/linux/arch/arm/kernel/ioport.c linux/arch/arm/kernel/ioport.c
--- v2.3.29/linux/arch/arm/kernel/ioport.c	Thu Nov 18 20:25:37 1999
+++ linux/arch/arm/kernel/ioport.c	Thu Dec  2 15:41:02 1999
@@ -15,6 +15,13 @@
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 
+unsigned long
+resource_fixup(struct pci_dev * dev, struct resource * res,
+	       unsigned long start, unsigned long size)
+{
+	return start;
+}
+
 #ifdef CONFIG_CPU_32
 asmlinkage int sys_iopl(unsigned long turn_on)
 {
diff -u --recursive --new-file v2.3.29/linux/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c
--- v2.3.29/linux/arch/arm/kernel/process.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/arm/kernel/process.c	Thu Dec  2 15:41:02 1999
@@ -5,10 +5,6 @@
  *  Origional Copyright (C) 1995  Linus Torvalds
  */
 
-/*
- * This file handles the architecture-dependent parts of process handling..
- */
-
 #include <stdarg.h>
 
 #include <linux/errno.h>
@@ -39,7 +35,7 @@
 
 asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
 
-static int hlt_counter=0;
+static int hlt_counter;
 
 void disable_hlt(void)
 {
@@ -51,6 +47,21 @@
 	hlt_counter--;
 }
 
+static int __init nohlt_setup(char *__unused)
+{
+	hlt_counter = 1;
+	return 0;
+}
+
+static int __init hlt_setup(char *__unused)
+{
+	hlt_counter = 0;
+	return 0;
+}
+
+__setup("nohlt", nohlt_setup);
+__setup("hlt", hlt_setup);
+
 /*
  * The idle loop on an ARM...
  */
@@ -93,6 +104,7 @@
 
 	mdelay(1000);
 	printk("Reboot failed -- System halted\n");
+	cli();
 	while (1);
 }
 
@@ -110,18 +122,18 @@
 
 	flags = condition_codes(regs);
 
-	printk( "pc : [<%08lx>]    lr : [<%08lx>]\n"
-		"sp : %08lx  ip : %08lx  fp : %08lx\n",
+	printk("pc : [<%08lx>]    lr : [<%08lx>]\n"
+	       "sp : %08lx  ip : %08lx  fp : %08lx\n",
 		instruction_pointer(regs),
 		regs->ARM_lr, regs->ARM_sp,
 		regs->ARM_ip, regs->ARM_fp);
-	printk( "r10: %08lx  r9 : %08lx  r8 : %08lx\n",
+	printk("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
 		regs->ARM_r10, regs->ARM_r9,
 		regs->ARM_r8);
-	printk( "r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
+	printk("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
 		regs->ARM_r7, regs->ARM_r6,
 		regs->ARM_r5, regs->ARM_r4);
-	printk( "r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
+	printk("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
 		regs->ARM_r3, regs->ARM_r2,
 		regs->ARM_r1, regs->ARM_r0);
 	printk("Flags: %c%c%c%c",
diff -u --recursive --new-file v2.3.29/linux/arch/arm/kernel/setup.c linux/arch/arm/kernel/setup.c
--- v2.3.29/linux/arch/arm/kernel/setup.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/arm/kernel/setup.c	Thu Dec  2 15:41:02 1999
@@ -3,12 +3,6 @@
  *
  *  Copyright (C) 1995-1999 Russell King
  */
-
-/*
- * This file obtains various parameters about the system that the kernel
- * is running on.
- */
-
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -37,11 +31,7 @@
 #define CONFIG_CMDLINE ""
 #endif
 
-#ifndef PARAMS_BASE
-#define PARAMS_BASE NULL
-#endif
-
-extern void reboot_setup(char *str, int *ints);
+extern void reboot_setup(char *str);
 extern void disable_hlt(void);
 extern int root_mountflags;
 extern int _stext, _text, _etext, _edata, _end;
@@ -61,6 +51,20 @@
 
 struct meminfo meminfo;
 
+struct machine_desc {
+	const char	*name;		/* architecture name	*/
+	unsigned int	param_offset;	/* parameter page	*/
+	unsigned int	reserve_lp0 :1;	/* never has lp0	*/
+	unsigned int	reserve_lp1 :1;	/* never has lp1	*/
+	unsigned int	reserve_lp2 :1;	/* never has lp2	*/
+	unsigned int	broken_hlt  :1;	/* hlt is broken	*/
+	unsigned int	soft_reboot :1;	/* soft reboot		*/
+	unsigned int	video_start;	/* start of video RAM	*/
+	unsigned int	video_end;	/* end of video RAM	*/
+	void		(*fixup)(struct machine_desc *,
+				 struct param_struct *, char **);
+};
+
 #ifdef MULTI_CPU
 struct processor processor;
 #endif
@@ -81,6 +85,7 @@
 char saved_command_line[COMMAND_LINE_SIZE];
 
 static struct proc_info_item proc_info;
+static const char *machine_name;
 static char command_line[COMMAND_LINE_SIZE] = { 0, };
 
 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
@@ -91,16 +96,14 @@
  * Standard memory resources
  */
 static struct resource mem_res[] = {
-	{ "System RAM",  0,     0,     IORESOURCE_MEM | IORESOURCE_BUSY },
 	{ "Video RAM",   0,     0,     IORESOURCE_MEM			},
 	{ "Kernel code", 0,     0,     IORESOURCE_MEM			},
 	{ "Kernel data", 0,     0,     IORESOURCE_MEM			}
 };
 
-#define system_ram  mem_res[0]
-#define video_ram   mem_res[1]
-#define kernel_code mem_res[2]
-#define kernel_data mem_res[3]
+#define video_ram   mem_res[0]
+#define kernel_code mem_res[1]
+#define kernel_data mem_res[2]
 
 static struct resource io_res[] = {
 	{ "reserved",    0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY },
@@ -140,6 +143,10 @@
 
 #ifdef MULTI_CPU
 	processor = *list->proc;
+
+	printk("Processor: %s %s revision %d\n",
+	       proc_info.manufacturer, proc_info.cpu_name,
+	       (int)processor_id & 15);
 #endif
 
 	sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
@@ -218,10 +225,7 @@
 setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
 {
 #ifdef CONFIG_BLK_DEV_RAM
-	extern int rd_doload;
-	extern int rd_prompt;
-	extern int rd_image_start;
-	extern int rd_size;
+	extern int rd_doload, rd_prompt, rd_image_start, rd_size;
 
 	rd_image_start = image_start;
 	rd_prompt = prompt;
@@ -309,69 +313,76 @@
 #endif
 }
 
-static void __init request_standard_resources(void)
+static void __init request_standard_resources(struct machine_desc *mdesc)
 {
-	kernel_code.start  = __virt_to_bus((unsigned long) &_text);
-	kernel_code.end    = __virt_to_bus((unsigned long) &_etext - 1);
-	kernel_data.start  = __virt_to_bus((unsigned long) &_etext);
-	kernel_data.end    = __virt_to_bus((unsigned long) &_edata - 1);
-	system_ram.start   = __virt_to_bus(PAGE_OFFSET);
-	system_ram.end     = __virt_to_bus(meminfo.end + PAGE_OFFSET - 1);
-
-	request_resource(&iomem_resource, &system_ram);
-	request_resource(&system_ram, &kernel_code);
-	request_resource(&system_ram, &kernel_data);
+	struct resource *res;
+	int i;
+
+	kernel_code.start  = __virt_to_bus(init_mm.start_code);
+	kernel_code.end    = __virt_to_bus(init_mm.end_code - 1);
+	kernel_data.start  = __virt_to_bus(init_mm.end_code);
+	kernel_data.end    = __virt_to_bus(init_mm.brk - 1);
+
+	for (i = 0; i < meminfo.nr_banks; i++) {
+		unsigned long virt_start, virt_end;
+
+		if (meminfo.bank[i].size == 0)
+			continue;
+
+		virt_start = __phys_to_virt(meminfo.bank[i].start);
+		virt_end   = virt_start + meminfo.bank[i].size - 1;
+
+		res = alloc_bootmem(sizeof(*res));
+		res->name  = "System RAM";
+		res->start = __virt_to_bus(virt_start);
+		res->end   = __virt_to_bus(virt_end);
+		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+		request_resource(&iomem_resource, res);
+
+		if (kernel_code.start >= res->start &&
+		    kernel_code.end <= res->end)
+			request_resource(res, &kernel_code);
+		if (kernel_data.start >= res->start &&
+		    kernel_data.end <= res->end)
+			request_resource(res, &kernel_data);
+	}
 
-	if (video_ram.start != video_ram.end)
+	if (mdesc->video_start) {
+		video_ram.start = mdesc->video_start;
+		video_ram.end   = mdesc->video_end;
 		request_resource(&iomem_resource, &video_ram);
+	}
 
 	/*
 	 * Some machines don't have the possibility of ever
-	 * possessing LPT1 (lp0) and LPT3 (lp2)
+	 * possessing lp0, lp1 or lp2
 	 */
-	if (machine_is_ebsa110() || machine_is_riscpc() ||
-	    machine_is_netwinder())
+	if (mdesc->reserve_lp0)
 		request_resource(&ioport_resource, &lp0);
-	if (machine_is_riscpc())
+	if (mdesc->reserve_lp1)
 		request_resource(&ioport_resource, &lp1);
-	if (machine_is_ebsa110() || machine_is_netwinder())
+	if (mdesc->reserve_lp2)
 		request_resource(&ioport_resource, &lp2);
 }
 
-void __init setup_arch(char **cmdline_p)
+/*
+ * Architecture specific fixups.  This is where any
+ * parameters in the params struct are fixed up, or
+ * any additional architecture specific information
+ * is pulled from the params struct.
+ */
+static void __init
+fixup_acorn(struct machine_desc *desc, struct param_struct *params,
+	    char **cmdline)
 {
-	struct param_struct *params = (struct param_struct *)PARAMS_BASE;
-	char *from = default_command_line;
-
-#if defined(CONFIG_ARCH_ARC)
-	__machine_arch_type = MACH_TYPE_ARCHIMEDES;
-#elif defined(CONFIG_ARCH_A5K)
-	__machine_arch_type = MACH_TYPE_A5K;
-#endif
-
-	setup_processor();
-
-	/*
-	 * Defaults
-	 */
-	ROOT_DEV = MKDEV(0, 255);
-	setup_ramdisk(1, 1, 0, 0);
-
-	/*
-	 * Add your machine dependencies here
-	 */
-	switch (machine_arch_type) {
-	case MACH_TYPE_EBSA110:
-		/* EBSA110 locks if we execute 'wait for interrupt' */
-		disable_hlt();
-		if (params && params->u1.s.page_size != PAGE_SIZE)
-			params = NULL;
-		break;
-
 #ifdef CONFIG_ARCH_ACORN
-#ifdef CONFIG_ARCH_RPC
-	case MACH_TYPE_RISCPC:
-		/* RiscPC can't handle half-word loads and stores */
+	int i;
+
+	if (machine_is_riscpc()) {
+		/*
+		 * RiscPC can't handle half-word loads and stores
+		 */
 		elf_hwcap &= ~HWCAP_HALF;
 
 		switch (params->u1.s.pages_in_vram) {
@@ -382,106 +393,219 @@
 		default:
 			break;
 		}
-		{
-			int i;
 
-			for (i = 0; i < 4; i++) {
-				meminfo.bank[i].start = i << 26;
-				meminfo.bank[i].size  =
-					params->u1.s.pages_in_bank[i] *
-					params->u1.s.page_size;
-			}
-			meminfo.nr_banks = 4;
+		if (vram_size) {
+			desc->video_start = 0x02000000;
+			desc->video_end   = 0x02000000 + vram_size;
 		}
-#endif
-	case MACH_TYPE_ARCHIMEDES:
-	case MACH_TYPE_A5K:
-		memc_ctrl_reg	  = params->u1.s.memc_control_reg;
-		number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
-		break;
-#endif
 
-	case MACH_TYPE_EBSA285:
-		if (params) {
-			ORIG_X		 = params->u1.s.video_x;
-			ORIG_Y		 = params->u1.s.video_y;
-			ORIG_VIDEO_COLS  = params->u1.s.video_num_cols;
-			ORIG_VIDEO_LINES = params->u1.s.video_num_rows;
-			video_ram.start  = 0x0a0000;
-			video_ram.end    = 0x0bffff;
+		for (i = 0; i < 4; i++) {
+			meminfo.bank[i].start = i << 26;
+			meminfo.bank[i].size  =
+				params->u1.s.pages_in_bank[i] *
+				params->u1.s.page_size;
 		}
-		break;
+		meminfo.nr_banks = 4;
+	}
+	memc_ctrl_reg	  = params->u1.s.memc_control_reg;
+	number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
+#endif
+}
+
+static void __init
+fixup_ebsa285(struct machine_desc *desc, struct param_struct *params,
+	      char **cmdline)
+{
+	ORIG_X		 = params->u1.s.video_x;
+	ORIG_Y		 = params->u1.s.video_y;
+	ORIG_VIDEO_COLS  = params->u1.s.video_num_cols;
+	ORIG_VIDEO_LINES = params->u1.s.video_num_rows;
+}
+
+/*
+ * Older NeTTroms either do not provide a parameters
+ * page, or they don't supply correct information in
+ * the parameter page.
+ */
+static void __init
+fixup_netwinder(struct machine_desc *desc, struct param_struct *params,
+		char **cmdline)
+{
+	if (params->u1.s.nr_pages != 0x2000 &&
+	    params->u1.s.nr_pages != 0x4000) {
+		printk(KERN_WARNING "Warning: bad NeTTrom parameters "
+		       "detected, using defaults\n");
+
+		params->u1.s.nr_pages = 0x2000;	/* 32MB */
+		params->u1.s.ramdisk_size = 0;
+		params->u1.s.flags = FLAG_READONLY;
+		params->u1.s.initrd_start = 0;
+		params->u1.s.initrd_size = 0;
+		params->u1.s.rd_start = 0;
+	}
+}
+
+/*
+ * CATS uses soft-reboot by default, since
+ * hard reboots fail on early boards.
+ */
+static void __init
+fixup_cats(struct machine_desc *desc, struct param_struct *params,
+	   char **cmdline)
+{
+	ORIG_VIDEO_LINES  = 25;
+	ORIG_VIDEO_POINTS = 16;
+	ORIG_Y = 24;
+}
 
-	case MACH_TYPE_CO285:
-		{
+static void __init
+fixup_coebsa285(struct machine_desc *desc, struct param_struct *params,
+		char **cmdline)
+{
 #if 0
-			extern unsigned long boot_memory_end;
-			extern char boot_command_line[];
+	if (machine_is_co285()) {
+		extern unsigned long boot_memory_end;
+		extern char boot_command_line[];
 
-			from = boot_command_line;
-			memory_end = boot_memory_end;
-#endif
-			params = NULL;
-		}
-		break;
+		meminfo.nr_banks      = 1;
+		meminfo.bank[0].start = PHYS_OFFSET;
+		meminfo.bank[0].size  = boot_memory_end;
 
-	case MACH_TYPE_CATS:
-		/* CATS uses soft-reboot by default, since hard reboots
-		 * fail on early boards.
-		 */
-		reboot_setup("s", NULL);
-		params = NULL;
-		ORIG_VIDEO_LINES  = 25;
-		ORIG_VIDEO_POINTS = 16;
-		ORIG_Y = 24;
-		video_ram.start = 0x0a0000;
-		video_ram.end   = 0x0bffff;
-		break;
+		*cmdline = boot_command_line;
+	}
+#endif
+}
 
-	case MACH_TYPE_NETWINDER:
-		/*
-		 * to be fixed in a future NeTTrom
-		 */
-		if (params->u1.s.page_size == PAGE_SIZE) {
-			if (params->u1.s.nr_pages != 0x2000 &&
-			    params->u1.s.nr_pages != 0x4000) {
-				printk("Warning: bad NeTTrom parameters detected, using defaults\n");
-				/*
-				 * This stuff doesn't appear to be initialised
-				 * properly by NeTTrom 2.0.6 and 2.0.7
-				 */
-				params->u1.s.nr_pages = 0x2000;	/* 32MB */
-				params->u1.s.ramdisk_size = 0;
-				params->u1.s.flags = FLAG_READONLY;
-				params->u1.s.initrd_start = 0;
-				params->u1.s.initrd_size = 0;
-				params->u1.s.rd_start = 0;
-			}
-		} else {
-			printk("Warning: no NeTTrom parameter page detected, using "
-			       "compiled-in settings\n");
-			params = NULL;
-		}
-		video_ram.start = 0x0a0000;
-		video_ram.end   = 0x0bffff;
-		break;
+#define NO_PARAMS	0
+#define NO_VIDEO	0, 0
 
-	default:
-		break;
+/*
+ * This is the list of all architectures supported by
+ * this kernel.  This should be integrated with the list
+ * in head-armv.S.
+ */
+static struct machine_desc machine_desc[] __initdata = {
+	{ "EBSA110",		/* RMK			*/
+		0x00000400,
+		NO_VIDEO,
+		1, 0, 1, 1, 1,
+		NULL
+	}, { "Acorn-RiscPC",	/* RMK			*/
+		0x10000100,
+		NO_VIDEO,
+		1, 1, 0, 0, 0,
+		fixup_acorn
+	}, { "unknown",
+		NO_PARAMS,
+		NO_VIDEO,
+		0, 0, 0, 0, 0,
+		NULL
+	}, { "Nexus-FTV/PCI",	/* Philip Blundell	*/
+		NO_PARAMS,
+		NO_VIDEO,
+		0, 0, 0, 0, 0,
+		NULL
+	}, { "EBSA285",		/* RMK			*/
+		0x00000100,
+		0x000a0000, 0x000bffff,
+		0, 0, 0, 0, 0,
+		fixup_ebsa285
+	}, { "Rebel-NetWinder",	/* RMK			*/
+		0x00000100,
+		0x000a0000, 0x000bffff,
+		1, 0, 1, 0, 0,
+		fixup_netwinder
+	}, { "Chalice-CATS",	/* Philip Blundell	*/
+		NO_PARAMS,
+		0x000a0000, 0x000bffff,
+		0, 0, 0, 0, 1,
+		fixup_cats
+	}, { "unknown-TBOX",	/* Philip Blundell	*/
+		NO_PARAMS,
+		NO_VIDEO,
+		0, 0, 0, 0, 0,
+		NULL
+	}, { "co-EBSA285",	/* Mark van Doesburg	*/
+		NO_PARAMS,
+		NO_VIDEO,
+		0, 0, 0, 0, 0,
+		fixup_coebsa285
+	}, { "CL-PS7110",	/* Werner Almesberger	*/
+		NO_PARAMS,
+		NO_VIDEO,
+		0, 0, 0, 0, 0,
+		NULL
+	}, { "Acorn-Archimedes",/* RMK/DAG		*/
+		0x0207c000,
+		NO_VIDEO,
+		0, 0, 0, 0, 0,
+		fixup_acorn
+	}, { "Acorn-A5000",	/* RMK/PB		*/
+		0x0207c000,
+		NO_VIDEO,
+		0, 0, 0, 0, 0,
+		fixup_acorn
+	}, { "Etoile",		/* Alex de Vries	*/
+		NO_PARAMS,
+		NO_VIDEO,
+		0, 0, 0, 0, 0,
+		NULL
+	}, { "LaCie_NAS",	/* Benjamin Herrenschmidt */
+		NO_PARAMS,
+		NO_VIDEO,
+		0, 0, 0, 0, 0,
+		NULL
+	}, { "CL-PS7500",	/* Philip Blundell	*/
+		NO_PARAMS,
+		NO_VIDEO,
+		0, 0, 0, 0, 0,
+		NULL
+	}, { "Shark",		/* Alexander Schulz	*/
+		NO_PARAMS,
+		NO_VIDEO,
+		0, 0, 0, 0, 0,
+		NULL
 	}
+};
+
+void __init setup_arch(char **cmdline_p)
+{
+	struct param_struct *params = NULL;
+	struct machine_desc *mdesc;
+	char *from = default_command_line;
+
+#if defined(CONFIG_ARCH_ARC)
+	__machine_arch_type = MACH_TYPE_ARCHIMEDES;
+#elif defined(CONFIG_ARCH_A5K)
+	__machine_arch_type = MACH_TYPE_A5K;
+#endif
+
+	setup_processor();
+
+	ROOT_DEV = MKDEV(0, 255);
+
+	mdesc = machine_desc + machine_arch_type;
+	machine_name = mdesc->name;
+
+	if (mdesc->broken_hlt)
+		disable_hlt();
+
+	if (mdesc->soft_reboot)
+		reboot_setup("s");
+
+	if (mdesc->param_offset)
+		params = phys_to_virt(mdesc->param_offset);
+
+	if (mdesc->fixup)
+		mdesc->fixup(mdesc, params, &from);
 
 	if (params && params->u1.s.page_size != PAGE_SIZE) {
-		printk("Warning: wrong page size configuration, "
+		printk(KERN_WARNING "Warning: bad configuration page, "
 		       "trying to continue\n");
 		params = NULL;
 	}
 
 	if (params) {
-		if (meminfo.nr_banks == 0) {
-			meminfo.nr_banks      = 1;
-			meminfo.bank[0].start = 0;
-			meminfo.bank[0].size  = params->u1.s.nr_pages << PAGE_SHIFT;
-		}
 		ROOT_DEV	   = to_kdev_t(params->u1.s.rootdev);
 		system_rev	   = params->u1.s.system_rev;
 		system_serial_low  = params->u1.s.system_serial_low;
@@ -504,7 +628,10 @@
 	if (meminfo.nr_banks == 0) {
 		meminfo.nr_banks      = 1;
 		meminfo.bank[0].start = 0;
-		meminfo.bank[0].size  = MEM_SIZE;
+		if (params)
+			meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT;
+		else
+			meminfo.bank[0].size = MEM_SIZE;
 	}
 
 	init_mm.start_code = (unsigned long) &_text;
@@ -512,12 +639,11 @@
 	init_mm.end_data   = (unsigned long) &_edata;
 	init_mm.brk	   = (unsigned long) &_end;
 
-	/* Save unparsed command line copy for /proc/cmdline */
 	memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
 	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 	parse_cmdline(cmdline_p, from);
 	setup_bootmem();
-	request_standard_resources();
+	request_standard_resources(mdesc);
 
 #ifdef CONFIG_VT
 #if defined(CONFIG_VGA_CONSOLE)
@@ -528,26 +654,6 @@
 #endif
 }
 
-static const char *machine_desc[] = {
-	/* Machine name		Allocater			*/
-	"EBSA110",		/* RMK				*/
-	"Acorn-RiscPC",		/* RMK				*/
-	"unknown",
-	"Nexus-FTV/PCI",	/* Philip Blundell		*/
-	"EBSA285",		/* RMK				*/
-	"Rebel-NetWinder",	/* RMK				*/
-	"Chalice-CATS",		/* Philip Blundell		*/
-	"unknown-TBOX",		/* Philip Blundell		*/
-	"co-EBSA285",		/* Mark van Doesburg		*/
-	"CL-PS7110",		/* Werner Almesberger		*/
-	"Acorn-Archimedes",	/* RMK/DAG			*/
-	"Acorn-A5000",		/* RMK/PB			*/
-	"Etoile",		/* Alex de Vries		*/
-	"LaCie_NAS",		/* Benjamin Herrenschmidt	*/
-	"CL-PS7500",		/* Philip Blundell		*/
-	"Shark"			/* Alexander Schulz		*/
-};
-
 int get_cpuinfo(char * buffer)
 {
 	char *p = buffer;
@@ -560,8 +666,7 @@
 		     (loops_per_sec+2500) / 500000,
 		     ((loops_per_sec+2500) / 5000) % 100);
 
-	p += sprintf(p, "Hardware\t: %s\n",
-		     machine_desc[machine_arch_type]);
+	p += sprintf(p, "Hardware\t: %s\n", machine_name);
 
 	p += sprintf(p, "Revision\t: %04x\n",
 		     system_rev);
diff -u --recursive --new-file v2.3.29/linux/arch/arm/kernel/traps.c linux/arch/arm/kernel/traps.c
--- v2.3.29/linux/arch/arm/kernel/traps.c	Mon Nov  1 13:56:26 1999
+++ linux/arch/arm/kernel/traps.c	Thu Dec  2 15:41:02 1999
@@ -17,6 +17,7 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/spinlock.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -422,4 +423,14 @@
 {
 	printk("Division by zero in kernel.\n");
 	__backtrace();
+}
+
+void __init trap_init(void)
+{
+	extern void __trap_init(void);
+
+	__trap_init();
+#ifdef CONFIG_CPU_32
+	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+#endif
 }
diff -u --recursive --new-file v2.3.29/linux/arch/arm/mm/init.c linux/arch/arm/mm/init.c
--- v2.3.29/linux/arch/arm/mm/init.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/arm/mm/init.c	Thu Dec  2 15:41:02 1999
@@ -244,6 +244,10 @@
 	unsigned int codepages, datapages, initpages;
 	int i;
 
+	codepages = &_etext - &_text;
+	datapages = &_end - &_etext;
+	initpages = &__init_end - &__init_begin;
+
 	max_mapnr   = max_low_pfn;
 	high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
 
@@ -261,29 +265,28 @@
 	 * Since our memory may not be contiguous, calculate the
 	 * real number of pages we have in this system
 	 */
+	printk("Memory:");
+
 	num_physpages = 0;
-	for (i = 0; i < meminfo.nr_banks; i++)
+	for (i = 0; i < meminfo.nr_banks; i++) {
 		num_physpages += meminfo.bank[i].size >> PAGE_SHIFT;
+		printk(" %ldMB", meminfo.bank[i].size >> 20);
+	}
 
-	codepages = (int)&_etext - &_text;
-	datapages = (int)&_end - &_etext;
-	initpages = (int)&__init_end - &__init_start;
-
-	printk("Memory: %luk/%luM available (%dK code, %dK data, %dK init)\n",
+	printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT)); 
+	printk("Memory: %luKB available (%dK code, %dK data, %dK init)\n",
 		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
-		num_physpages >> (20 - PAGE_SHIFT),
-		codepages << (PAGE_SHIFT-10),
-		datapages << (PAGE_SHIFT-10),
-		initpages << (PAGE_SHIFT-10));
+		codepages >> 10, datapages >> 10, initpages >> 10);
 
-#ifdef CONFIG_CPU_26
-	if (max_mapnr <= 128) {
+	if (PAGE_SIZE >= 16384 && max_mapnr <= 128) {
 		extern int sysctl_overcommit_memory;
-		/* On a machine this small we won't get anywhere without
-		   overcommit, so turn it on by default.  */
+		/*
+		 * On a machine this small we won't get
+		 * anywhere without overcommit, so turn
+		 * it on by default.
+		 */
 		sysctl_overcommit_memory = 1;
 	}
-#endif
 }
 
 static inline void free_area(unsigned long addr, unsigned long end, char *s)
@@ -332,6 +335,19 @@
 
 	printk("\n");
 }
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(mem_map + MAP_NR(start));
+		set_page_count(mem_map+MAP_NR(start), 1);
+		free_page(start);
+		totalram_pages++;
+	}
+	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
 
 void si_meminfo(struct sysinfo *val)
 {
diff -u --recursive --new-file v2.3.29/linux/arch/arm/mm/mm-armv.c linux/arch/arm/mm/mm-armv.c
--- v2.3.29/linux/arch/arm/mm/mm-armv.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/arm/mm/mm-armv.c	Thu Dec  2 15:41:02 1999
@@ -25,6 +25,29 @@
 extern pte_t *get_bad_pte_table(void);
 
 /*
+ * These are useful for identifing cache coherency
+ * problems by allowing the cache or the cache and
+ * writebuffer to be turned off.  (Note: the write
+ * buffer should not be on and the cache off).
+ */
+static int __init nocache_setup(char *__unused)
+{
+	cr_alignment &= ~4;
+	cr_no_alignment &= ~4;
+	set_cr(cr_alignment);
+}
+
+static int __init nowrite_setup(char *__unused)
+{
+	cr_alignment &= ~(8|4);
+	cr_no_alignment &= ~(8|4);
+	set_cr(cr_alignment);
+}
+
+__setup("nocache", nocache_setup);
+__setup("nowb", nowrite_setup);
+
+/*
  * need to get a 16k page for level 1
  */
 pgd_t *get_pgd_slow(void)
@@ -353,7 +376,7 @@
 {
 	unsigned int start_pfn, end_pfn = -1;
 	struct page *pg = NULL;
-	unsigned int sz, i;
+	unsigned int i;
 
 	for (i = 0; i < meminfo.nr_banks; i++) {
 		if (meminfo.bank[i].size == 0)
diff -u --recursive --new-file v2.3.29/linux/arch/arm/mm/proc-arm2,3.S linux/arch/arm/mm/proc-arm2,3.S
--- v2.3.29/linux/arch/arm/mm/proc-arm2,3.S	Mon Nov  1 13:56:26 1999
+++ linux/arch/arm/mm/proc-arm2,3.S	Thu Dec  2 15:41:02 1999
@@ -270,9 +270,9 @@
 		bics	pc, lr, #0x04000000		@ Clear FIQ disable bit
 
 armvlsi_name:	.asciz	"ARM/VLSI"
-_arm2_name:	.asciz	"arm2"
-_arm250_name:	.asciz	"arm250"
-_arm3_name:	.asciz	"arm3"
+_arm2_name:	.asciz	"ARM 2"
+_arm250_name:	.asciz	"ARM 250"
+_arm3_name:	.asciz	"ARM 3"
 
 		.section ".text.init", #alloc, #execinstr
 /*
diff -u --recursive --new-file v2.3.29/linux/arch/arm/mm/proc-arm6,7.S linux/arch/arm/mm/proc-arm6,7.S
--- v2.3.29/linux/arch/arm/mm/proc-arm6,7.S	Mon Nov  1 13:56:26 1999
+++ linux/arch/arm/mm/proc-arm6,7.S	Thu Dec  2 15:41:02 1999
@@ -413,12 +413,12 @@
 
 cpu_armvlsi_name:
 		.asciz	"ARM/VLSI"
-cpu_arm6_name:	.asciz	"arm6"
+cpu_arm6_name:	.asciz	"ARM 6"
 cpu_arm610_name:
-		.asciz	"arm610"
-cpu_arm7_name:	.asciz	"arm7"
+		.asciz	"ARM 610"
+cpu_arm7_name:	.asciz	"ARM 7"
 cpu_arm710_name:
-		.asciz	"arm710"
+		.asciz	"ARM 710"
 		.align
 
 		.section ".text.init", #alloc, #execinstr
diff -u --recursive --new-file v2.3.29/linux/arch/arm/mm/proc-sa110.S linux/arch/arm/mm/proc-sa110.S
--- v2.3.29/linux/arch/arm/mm/proc-sa110.S	Mon Nov  1 13:56:26 1999
+++ linux/arch/arm/mm/proc-sa110.S	Thu Dec  2 15:41:02 1999
@@ -456,9 +456,9 @@
 
 cpu_manu_name:	.asciz	"Intel"
 ENTRY(cpu_sa110_name)
-		.asciz	"sa110"
+		.asciz	"StrongARM-110"
 ENTRY(cpu_sa1100_name)
-		.asciz	"sa1100"
+		.asciz	"StrongARM-1100"
 		.align
 
 		.section ".text.init", #alloc, #execinstr
diff -u --recursive --new-file v2.3.29/linux/arch/arm/mm/small_page.c linux/arch/arm/mm/small_page.c
--- v2.3.29/linux/arch/arm/mm/small_page.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/arm/mm/small_page.c	Mon Dec  6 10:14:13 1999
@@ -116,7 +116,7 @@
 		remove_page_from_queue(page);
 	restore_flags(flags);
 
-	return __page_address(page) + (offset << order->shift);
+	return page_address(page) + (offset << order->shift);
 
 need_new_page:
 	page = alloc_page(priority);
diff -u --recursive --new-file v2.3.29/linux/arch/i386/boot/setup.S linux/arch/i386/boot/setup.S
--- v2.3.29/linux/arch/i386/boot/setup.S	Tue Nov 23 22:42:20 1999
+++ linux/arch/i386/boot/setup.S	Fri Dec  3 20:37:07 1999
@@ -208,7 +208,7 @@
 	addw	$SYSSEG, %bx
 	movw	%bx, %cs:start_sys_seg
 # Move rest of setup code/data to here
-	movw	$4096, %di			# four sectors loaded by LILO
+	movw	$2048, %di			# four sectors loaded by LILO
 	subw	%si, %si
 	movw	%cs, %ax			# aka SETUPSEG
 	movw	%ax, %es
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/i386_ksyms.c linux/arch/i386/kernel/i386_ksyms.c
--- v2.3.29/linux/arch/i386/kernel/i386_ksyms.c	Thu Nov 11 20:11:31 1999
+++ linux/arch/i386/kernel/i386_ksyms.c	Thu Dec  2 15:08:02 1999
@@ -23,6 +23,11 @@
 extern void dump_thread(struct pt_regs *, struct user *);
 extern int dump_fpu(elf_fpregset_t *);
 
+#ifdef __SMP__
+extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
+extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
+#endif
+
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
 extern struct drive_info_struct drive_info;
 EXPORT_SYMBOL(drive_info);
@@ -92,6 +97,8 @@
 EXPORT_SYMBOL(smp_num_cpus);
 EXPORT_SYMBOL(cpu_present_map);
 EXPORT_SYMBOL(cpu_online_map);
+EXPORT_SYMBOL_NOVERS(__write_lock_failed);
+EXPORT_SYMBOL_NOVERS(__read_lock_failed);
 
 /* Global SMP irq stuff */
 EXPORT_SYMBOL(synchronize_irq);
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
--- v2.3.29/linux/arch/i386/kernel/io_apic.c	Sat Oct  9 11:47:50 1999
+++ linux/arch/i386/kernel/io_apic.c	Sat Nov 27 15:27:48 1999
@@ -940,7 +940,7 @@
 	print_local_APIC(NULL);
 }
 
-static void __init init_sym_mode(void)
+static void __init enable_IO_APIC(void)
 {
 	struct IO_APIC_reg_01 reg_01;
 	int i;
@@ -976,31 +976,15 @@
 	clear_IO_APIC();
 }
 
-static void clear_lapic_ints (void * dummy)
-{
-	int maxlvt;
-
-	maxlvt = get_maxlvt();
-	apic_write_around(APIC_LVTT, 0x00010000);
-	apic_write_around(APIC_LVT0, 0x00010000);
-	apic_write_around(APIC_LVT1, 0x00010000);
-	if (maxlvt >= 3)
-		apic_write_around(APIC_LVTERR, 0x00010000);
-	if (maxlvt >= 4)
-		apic_write_around(APIC_LVTPC, 0x00010000);
-}
-
 /*
  * Not an __init, needed by the reboot code
  */
-void init_pic_mode(void)
+void disable_IO_APIC(void)
 {
 	/*
-	 * Clear the IO-APIC and local APICs before rebooting:
+	 * Clear the IO-APIC before rebooting:
 	 */
 	clear_IO_APIC();
-	smp_call_function(clear_lapic_ints, NULL, 1, 1);
-	clear_lapic_ints(NULL);
 
 	/*
 	 * Put it back into PIC mode (has an effect only on
@@ -1379,8 +1363,10 @@
 	}
 	printk(" failed.\n");
 
-	if (nmi_watchdog)
-		printk("timer doesnt work through the IO-APIC - cannot activate NMI Watchdog!\n");
+	if (nmi_watchdog) {
+		printk("timer doesnt work through the IO-APIC - disabling NMI Watchdog!\n");
+		nmi_watchdog = 0;
+	}
 
 	printk("...trying to set up timer as Virtual Wire IRQ...");
 
@@ -1417,7 +1403,7 @@
 
 void __init setup_IO_APIC(void)
 {
-	init_sym_mode();
+	enable_IO_APIC();
 
 	printk("ENABLING IO-APIC IRQs\n");
 	io_apic_irqs = ~PIC_IRQS;
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c
--- v2.3.29/linux/arch/i386/kernel/irq.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/i386/kernel/irq.c	Sat Nov 27 15:27:48 1999
@@ -204,13 +204,8 @@
  */
 static inline void check_smp_invalidate(int cpu)
 {
-	if (test_bit(cpu, &smp_invalidate_needed)) {
-		struct mm_struct *mm = current->mm;
-		clear_bit(cpu, &smp_invalidate_needed);
-		if (mm)
-			atomic_set_mask(1 << cpu, &mm->cpu_vm_mask);
-		local_flush_tlb();
-	}
+	if (test_bit(cpu, &smp_invalidate_needed))
+		do_flush_tlb_local();
 }
 
 static void show(char * str)
@@ -263,7 +258,7 @@
  * i thought that such things are guaranteed by design, since we use
  * the 'LOCK' prefix.
  */
-#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 1
+#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 0
 
 #if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
 # define SYNC_OTHER_CORES(x) udelay(x+1)
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/mtrr.c linux/arch/i386/kernel/mtrr.c
--- v2.3.29/linux/arch/i386/kernel/mtrr.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/i386/kernel/mtrr.c	Sun Dec  5 08:42:03 1999
@@ -1488,25 +1488,6 @@
 
 static struct inode_operations proc_mtrr_inode_operations = {
 	&mtrr_fops,             /* default property file-ops */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* get_block */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* flushpage */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL,			/* smap */
-	NULL			/* revalidate */
 };
 
 static struct proc_dir_entry *proc_root_mtrr;
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/pci-i386.c linux/arch/i386/kernel/pci-i386.c
--- v2.3.29/linux/arch/i386/kernel/pci-i386.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/i386/kernel/pci-i386.c	Sat Nov 27 15:27:48 1999
@@ -12,7 +12,7 @@
  *	Hannover, Germany
  *	hm@ix.de
  *
- * Copyright 1997--1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ * Copyright 1997--1999 Martin Mares <mj@suse.cz>
  *
  * For more information, please consult the following manuals (look at
  * http://www.pcisig.com/ for how to get them):
@@ -122,12 +122,12 @@
 			printk(KERN_ERR "PCI: I/O Region %s/%d too large (%ld bytes)\n", dev->slot_name, i, size);
 			return -EFBIG;
 		}
-		if (allocate_resource(pr, r, size, 0x1000, ~0, 1024, dev)) {
+		if (allocate_resource(pr, r, size, 0x1000, ~0, 1024, NULL, NULL)) {
 			printk(KERN_ERR "PCI: Allocation of I/O region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size);
 			return -EBUSY;
 		}
 	} else {
-		if (allocate_resource(pr, r, size, 0x10000000, ~0, size, dev)) {
+		if (allocate_resource(pr, r, size, 0x10000000, ~0, size, NULL, NULL)) {
 			printk(KERN_ERR "PCI: Allocation of memory region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size);
 			return -EBUSY;
 		}
@@ -291,12 +291,6 @@
 	pcibios_allocate_resources(0);
 	pcibios_allocate_resources(1);
 	pcibios_assign_resources();
-}
-
-unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
-			     unsigned long start, unsigned long size)
-{
-	return start;
 }
 
 int pcibios_enable_resources(struct pci_dev *dev)
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/pci-pc.c linux/arch/i386/kernel/pci-pc.c
--- v2.3.29/linux/arch/i386/kernel/pci-pc.c	Fri Oct 22 13:21:45 1999
+++ linux/arch/i386/kernel/pci-pc.c	Sat Nov 27 15:27:48 1999
@@ -1,7 +1,7 @@
 /*
  *	Low-Level PCI Support for PC
  *
- *	(c) 1999 Martin Mares <mj@ucw.cz>
+ *	(c) 1999 Martin Mares <mj@suse.cz>
  */
 
 #include <linux/config.h>
@@ -404,7 +404,7 @@
 		DBG("PCI: BIOS probe returned s=%02x hw=%02x ver=%02x.%02x l=%02x\n",
 			status, hw_mech, major_ver, minor_ver, last_bus);
 		if (status || signature != PCI_SIGNATURE) {
-			printk (KERN_ERR "PCI: BIOS BUG #%x[%08x] found, report to <mj@ucw.cz>\n",
+			printk (KERN_ERR "PCI: BIOS BUG #%x[%08x] found, report to <mj@suse.cz>\n",
 				status, signature);
 			return 0;
 		}
@@ -594,7 +594,7 @@
 		if (sum != 0)
 			continue;
 		if (check->fields.revision != 0) {
-			printk("PCI: unsupported BIOS32 revision %d at 0x%p, report to <mj@ucw.cz>\n",
+			printk("PCI: unsupported BIOS32 revision %d at 0x%p, report to <mj@suse.cz>\n",
 				check->fields.revision, check);
 			continue;
 		}
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/pci-visws.c linux/arch/i386/kernel/pci-visws.c
--- v2.3.29/linux/arch/i386/kernel/pci-visws.c	Fri Oct 22 13:21:45 1999
+++ linux/arch/i386/kernel/pci-visws.c	Sat Nov 27 15:27:48 1999
@@ -1,7 +1,7 @@
 /*
  *	Low-Level PCI Support for SGI Visual Workstation
  *
- *	(c) 1999 Martin Mares <mj@ucw.cz>
+ *	(c) 1999 Martin Mares <mj@suse.cz>
  */
 
 #include <linux/config.h>
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
--- v2.3.29/linux/arch/i386/kernel/process.c	Thu Nov 11 20:11:31 1999
+++ linux/arch/i386/kernel/process.c	Sat Nov 27 15:27:48 1999
@@ -204,9 +204,11 @@
 {
 #if __SMP__
 	/*
-	 * turn off the IO-APIC, so we can do a clean reboot
+	 * Stop all CPUs and turn off local APICs and the IO-APIC, so
+	 * other OSs see a clean IRQ state.
 	 */
-	init_pic_mode();
+	smp_send_stop();
+	disable_IO_APIC();
 #endif
 
 	if(!reboot_thru_bios) {
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/semaphore.c linux/arch/i386/kernel/semaphore.c
--- v2.3.29/linux/arch/i386/kernel/semaphore.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/i386/kernel/semaphore.c	Sat Nov 27 16:04:04 1999
@@ -2,7 +2,17 @@
  * i386 semaphore implementation.
  *
  * (C) Copyright 1999 Linus Torvalds
+ *
+ * Portions Copyright 1999 Red Hat, Inc.
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@redhat.com>
  */
+#include <linux/config.h>
 #include <linux/sched.h>
 
 #include <asm/semaphore.h>
@@ -218,3 +228,226 @@
 	"popl %eax\n\t"
 	"ret"
 );
+
+asm(
+"
+.align 4
+.globl __down_read_failed
+__down_read_failed:
+	pushl	%edx
+	pushl	%ecx
+	jnc	2f
+
+3:	call	down_read_failed_biased
+
+1:	popl	%ecx
+	popl	%edx
+	ret
+
+2:	call	down_read_failed
+	" LOCK "subl	$1,(%eax)
+	jns	1b
+	jnc	2b
+	jmp	3b
+"
+);
+
+asm(
+"
+.align 4
+.globl __down_write_failed
+__down_write_failed:
+	pushl	%edx
+	pushl	%ecx
+	jnc	2f
+
+3:	call	down_write_failed_biased
+
+1:	popl	%ecx
+	popl	%edx
+	ret
+
+2:	call	down_write_failed
+	" LOCK "subl	$" RW_LOCK_BIAS_STR ",(%eax)
+	jz	1b
+	jnc	2b
+	jmp	3b
+"
+);
+
+struct rw_semaphore *FASTCALL(rwsem_wake_readers(struct rw_semaphore *sem));
+struct rw_semaphore *FASTCALL(rwsem_wake_writer(struct rw_semaphore *sem));
+
+struct rw_semaphore *FASTCALL(down_read_failed_biased(struct rw_semaphore *sem));
+struct rw_semaphore *FASTCALL(down_write_failed_biased(struct rw_semaphore *sem));
+struct rw_semaphore *FASTCALL(down_read_failed(struct rw_semaphore *sem));
+struct rw_semaphore *FASTCALL(down_write_failed(struct rw_semaphore *sem));
+
+struct rw_semaphore *down_read_failed_biased(struct rw_semaphore *sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	add_wait_queue(&sem->wait, &wait);	/* put ourselves at the head of the list */
+
+	for (;;) {
+		if (sem->read_bias_granted && xchg(&sem->read_bias_granted, 0))
+			break;
+		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+		if (!sem->read_bias_granted)
+			schedule();
+	}
+
+	remove_wait_queue(&sem->wait, &wait);
+	tsk->state = TASK_RUNNING;
+
+	return sem;
+}
+
+struct rw_semaphore *down_write_failed_biased(struct rw_semaphore *sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	add_wait_queue_exclusive(&sem->write_bias_wait, &wait);	/* put ourselves at the end of the list */
+
+	for (;;) {
+		if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0))
+			break;
+		set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE);
+		if (!sem->write_bias_granted)
+			schedule();
+	}
+
+	remove_wait_queue(&sem->write_bias_wait, &wait);
+	tsk->state = TASK_RUNNING;
+
+	/* if the lock is currently unbiased, awaken the sleepers
+	 * FIXME: this wakes up the readers early in a bit of a
+	 * stampede -> bad!
+	 */
+	if (atomic_read(&sem->count) >= 0)
+		wake_up(&sem->wait);
+
+	return sem;
+}
+
+/* Wait for the lock to become unbiased.  Readers
+ * are non-exclusive. =)
+ */
+struct rw_semaphore *down_read_failed(struct rw_semaphore *sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	__up_read(sem);	/* this takes care of granting the lock */
+
+	add_wait_queue(&sem->wait, &wait);
+
+	while (atomic_read(&sem->count) < 0) {
+		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+		if (atomic_read(&sem->count) >= 0)
+			break;
+		schedule();
+	}
+
+	remove_wait_queue(&sem->wait, &wait);
+	tsk->state = TASK_RUNNING;
+
+	return sem;
+}
+
+/* Wait for the lock to become unbiased. Since we're
+ * a writer, we'll make ourselves exclusive.
+ */
+struct rw_semaphore *down_write_failed(struct rw_semaphore *sem)
+{
+	struct task_struct *tsk = current;
+	DECLARE_WAITQUEUE(wait, tsk);
+
+	__up_write(sem);	/* this takes care of granting the lock */
+
+	add_wait_queue_exclusive(&sem->wait, &wait);
+
+	while (atomic_read(&sem->count) < 0) {
+		set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE);
+		if (atomic_read(&sem->count) >= 0)
+			break;	/* we must attempt to aquire or bias the lock */
+		schedule();
+	}
+
+	remove_wait_queue(&sem->wait, &wait);
+	tsk->state = TASK_RUNNING;
+
+	return sem;
+}
+
+asm(
+"
+.align 4
+.globl __rwsem_wake
+__rwsem_wake:
+	pushl	%edx
+	pushl	%ecx
+
+	jz	1f
+	call	rwsem_wake_readers
+	jmp	2f
+
+1:	call	rwsem_wake_writer
+
+2:	popl	%ecx
+	popl	%edx
+	ret
+"
+);
+
+/* Called when someone has done an up that transitioned from
+ * negative to non-negative, meaning that the lock has been
+ * granted to whomever owned the bias.
+ */
+struct rw_semaphore *rwsem_wake_readers(struct rw_semaphore *sem)
+{
+	if (xchg(&sem->read_bias_granted, 1))
+		BUG();
+	wake_up(&sem->wait);
+	return sem;
+}
+
+struct rw_semaphore *rwsem_wake_writer(struct rw_semaphore *sem)
+{
+	if (xchg(&sem->write_bias_granted, 1))
+		BUG();
+	wake_up(&sem->write_bias_wait);
+	return sem;
+}
+
+#if defined(CONFIG_SMP)
+asm(
+"
+.align	4
+.globl	__write_lock_failed
+__write_lock_failed:
+	" LOCK "addl	$" RW_LOCK_BIAS_STR ",(%eax)
+1:	cmpl	$" RW_LOCK_BIAS_STR ",(%eax)
+	jne	1b
+
+	" LOCK "subl	$" RW_LOCK_BIAS_STR ",(%eax)
+	jnz	__write_lock_failed
+	ret
+
+
+.align	4
+.globl	__read_lock_failed
+__read_lock_failed:
+	lock ; incl	(%eax)
+1:	cmpl	$1,(%eax)
+	js	1b
+
+	lock ; decl	(%eax)
+	js	__read_lock_failed
+	ret
+"
+);
+#endif
+
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- v2.3.29/linux/arch/i386/kernel/setup.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/i386/kernel/setup.c	Sat Nov 27 15:27:48 1999
@@ -286,16 +286,9 @@
 
 #define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
 
-/* System RAM - interrupted by the 640kB-1M hole */
-#define code_resource (ram_resources[3])
-#define data_resource (ram_resources[4])
-static struct resource ram_resources[] = {
-	{ "System RAM", 0x000000, 0x09ffff, IORESOURCE_BUSY },
-	{ "System RAM", 0x100000, 0x100000, IORESOURCE_BUSY },
-	{ "Video RAM area", 0x0a0000, 0x0bffff, IORESOURCE_BUSY },
-	{ "Kernel code", 0x100000, 0 },
-	{ "Kernel data", 0, 0 }
-};
+static struct resource code_resource = { "Kernel code", 0x100000, 0 };
+static struct resource data_resource = { "Kernel data", 0, 0 };
+static struct resource vram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_BUSY };
 
 /* System ROM resources */
 #define MAXROMS 6
@@ -647,11 +640,6 @@
 	bootmap_size = init_bootmem(start_pfn, max_low_pfn);
 
 	/*
-	 * FIXME: what about high memory?
-	 */
-	ram_resources[1].end = PFN_PHYS(max_low_pfn);
-
-	/*
 	 * Register fully available low RAM pages with the bootmem allocator.
 	 */
 	for (i = 0; i < e820.nr_map; i++) {
@@ -736,15 +724,36 @@
 #endif
 
 	/*
-	 * Request the standard RAM and ROM resources -
-	 * they eat up PCI memory space
+	 * Request address space for all standard RAM and ROM resources
+	 * and also for regions reported as reserved by the e820.
 	 */
-	request_resource(&iomem_resource, ram_resources+0);
-	request_resource(&iomem_resource, ram_resources+1);
-	request_resource(&iomem_resource, ram_resources+2);
-	request_resource(ram_resources+1, &code_resource);
-	request_resource(ram_resources+1, &data_resource);
 	probe_roms();
+	for (i = 0; i < e820.nr_map; i++) {
+		struct resource *res;
+		if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
+			continue;
+		res = alloc_bootmem_low(sizeof(struct resource));
+		switch (e820.map[i].type) {
+		case E820_RAM:	res->name = "System RAM"; break;
+		case E820_ACPI:	res->name = "ACPI Tables"; break;
+		case E820_NVS:	res->name = "ACPI Non-volatile Storage"; break;
+		default:	res->name = "reserved";
+		}
+		res->start = e820.map[i].addr;
+		res->end = res->start + e820.map[i].size - 1;
+		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+		request_resource(&iomem_resource, res);
+		if (e820.map[i].type == E820_RAM) {
+			/*
+			 *  We dont't know which RAM region contains kernel data,
+			 *  so we try it repeatedly and let the resource manager
+			 *  test it.
+			 */
+			request_resource(res, &code_resource);
+			request_resource(res, &data_resource);
+		}
+	}
+	request_resource(&iomem_resource, &vram_resource);
 
 	/* request I/O space for devices used on all i[345]86 PCs */
 	for (i = 0; i < STANDARD_IO_RESOURCES; i++)
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
--- v2.3.29/linux/arch/i386/kernel/smp.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/i386/kernel/smp.c	Thu Dec  2 19:54:52 1999
@@ -102,7 +102,8 @@
 /* The 'big kernel lock' */
 spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
 
-volatile unsigned long smp_invalidate_needed;
+volatile unsigned long smp_invalidate_needed; /* immediate flush required */
+unsigned int cpu_tlbbad[NR_CPUS]; /* flush before returning to user space */
 
 /*
  * the following functions deal with sending IPIs between CPUs.
@@ -319,13 +320,9 @@
 			/*
 			 * Take care of "crossing" invalidates
 			 */
-			if (test_bit(cpu, &smp_invalidate_needed)) {
-				struct mm_struct *mm = current->mm;
-				clear_bit(cpu, &smp_invalidate_needed);
-				if (mm)
-					atomic_set_mask(1 << cpu, &mm->cpu_vm_mask);
-				local_flush_tlb();
-			}
+			if (test_bit(cpu, &smp_invalidate_needed))
+				do_flush_tlb_local();
+
 			--stuck;
 			if (!stuck) {
 				printk("stuck on TLB IPI wait (CPU#%d)\n",cpu);
@@ -345,7 +342,7 @@
  */	
 void flush_tlb_current_task(void)
 {
-	unsigned long vm_mask = 1 << current->processor;
+	unsigned long vm_mask = 1 << smp_processor_id();
 	struct mm_struct *mm = current->mm;
 	unsigned long cpu_mask = mm->cpu_vm_mask & ~vm_mask;
 
@@ -356,7 +353,7 @@
 
 void flush_tlb_mm(struct mm_struct * mm)
 {
-	unsigned long vm_mask = 1 << current->processor;
+	unsigned long vm_mask = 1 << smp_processor_id();
 	unsigned long cpu_mask = mm->cpu_vm_mask & ~vm_mask;
 
 	mm->cpu_vm_mask = 0;
@@ -369,7 +366,7 @@
 
 void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
 {
-	unsigned long vm_mask = 1 << current->processor;
+	unsigned long vm_mask = 1 << smp_processor_id();
 	struct mm_struct *mm = vma->vm_mm;
 	unsigned long cpu_mask = mm->cpu_vm_mask & ~vm_mask;
 
@@ -381,12 +378,30 @@
 	flush_tlb_others(cpu_mask);
 }
 
-void flush_tlb_all(void)
+static inline void do_flush_tlb_all_local(void)
 {
-	flush_tlb_others(~(1 << current->processor));
 	local_flush_tlb();
+	if (!current->mm && current->active_mm) {
+		unsigned long cpu = smp_processor_id();
+
+		clear_bit(cpu, &current->active_mm->cpu_vm_mask);
+		cpu_tlbbad[cpu] = 1;
+	}
 }
 
+static void flush_tlb_all_ipi(void* info)
+{
+	do_flush_tlb_all_local();
+}
+
+void flush_tlb_all(void)
+{
+	if (cpu_online_map ^ (1 << smp_processor_id()))
+		while (smp_call_function (flush_tlb_all_ipi,0,0,1) == -EBUSY)
+			mb();
+
+	do_flush_tlb_all_local();
+}
 
 /*
  * this function sends a 'reschedule' IPI to another CPU.
@@ -439,9 +454,6 @@
 		if (down_trylock(&lock))
 			return -EBUSY;
 
-	if (call_data) // temporary debugging check
-		BUG();
-
 	call_data = &data;
 	data.func = func;
 	data.info = info;
@@ -478,7 +490,8 @@
 	 * Remove this CPU:
 	 */
 	clear_bit(smp_processor_id(), &cpu_online_map);
-
+	__cli();
+	disable_local_APIC();
 	if (cpu_data[smp_processor_id()].hlt_works_ok)
 		for(;;) __asm__("hlt");
 	for (;;);
@@ -490,7 +503,14 @@
 
 void smp_send_stop(void)
 {
+	unsigned long flags;
+
+	__save_flags(flags);
+	__cli();
         smp_call_function(stop_this_cpu, NULL, 1, 0);
+	disable_local_APIC();
+	__restore_flags(flags);
+
 }
 
 /*
@@ -513,15 +533,9 @@
  */
 asmlinkage void smp_invalidate_interrupt(void)
 {
-	struct task_struct *tsk = current;
-	unsigned int cpu = tsk->processor;
+	if (test_bit(smp_processor_id(), &smp_invalidate_needed))
+		do_flush_tlb_local();
 
-	if (test_and_clear_bit(cpu, &smp_invalidate_needed)) {
-		struct mm_struct *mm = tsk->mm;
-		if (mm)
-			atomic_set_mask(1 << cpu, &mm->cpu_vm_mask);
-		local_flush_tlb();
-	}
 	ack_APIC_irq();
 
 }
@@ -539,7 +553,7 @@
 	 */
 	atomic_inc(&call_data->started);
 	/*
-	 * At this point the structure may be out of scope unless wait==1
+	 * At this point the info structure may be out of scope unless wait==1
 	 */
 	(*func)(info);
 	if (wait)
@@ -575,8 +589,27 @@
 	printk("... APIC ESR0: %08lx\n", v);
 
 	apic_write(APIC_ESR, 0);
-	v = apic_read(APIC_ESR);
+	v |= apic_read(APIC_ESR);
 	printk("... APIC ESR1: %08lx\n", v);
+	/*
+	 * Be a bit more verbose. (multiple bits can be set)
+	 */
+	if (v & 0x01)
+		printk("... bit 0: APIC Send CS Error (hw problem).\n");
+	if (v & 0x02)
+		printk("... bit 1: APIC Receive CS Error (hw problem).\n");
+	if (v & 0x04)
+		printk("... bit 2: APIC Send Accept Error.\n");
+	if (v & 0x08)
+		printk("... bit 3: APIC Receive Accept Error.\n");
+	if (v & 0x10)
+		printk("... bit 4: Reserved!.\n");
+	if (v & 0x20)
+		printk("... bit 5: Send Illegal Vector (kernel bug).\n");
+	if (v & 0x40)
+		printk("... bit 6: Received Illegal Vector.\n");
+	if (v & 0x80)
+		printk("... bit 7: Illegal Register Address.\n");
 
 	ack_APIC_irq();
 
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/smpboot.c linux/arch/i386/kernel/smpboot.c
--- v2.3.29/linux/arch/i386/kernel/smpboot.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/i386/kernel/smpboot.c	Sat Nov 27 15:27:48 1999
@@ -708,7 +708,35 @@
 	return maxlvt;
 }
 
-void __init setup_local_APIC(void)
+void disable_local_APIC (void)
+{
+	unsigned long value;
+        int maxlvt;
+
+	/*
+	 * Disable APIC
+	 */
+ 	value = apic_read(APIC_SPIV);
+ 	value &= ~(1<<8);
+ 	apic_write(APIC_SPIV,value);
+
+	/*
+	 * Clean APIC state for other OSs:
+	 */
+ 	value = apic_read(APIC_SPIV);
+ 	value &= ~(1<<8);
+ 	apic_write(APIC_SPIV,value);
+	maxlvt = get_maxlvt();
+	apic_write_around(APIC_LVTT, 0x00010000);
+	apic_write_around(APIC_LVT0, 0x00010000);
+	apic_write_around(APIC_LVT1, 0x00010000);
+	if (maxlvt >= 3)
+		apic_write_around(APIC_LVTERR, 0x00010000);
+	if (maxlvt >= 4)
+		apic_write_around(APIC_LVTPC, 0x00010000);
+}
+
+void __init setup_local_APIC (void)
 {
 	unsigned long value, ver, maxlvt;
 
@@ -716,12 +744,25 @@
 		__error_in_io_apic_c();
 
  	value = apic_read(APIC_SPIV);
-	value = 0xf;
 	/*
 	 * Enable APIC
 	 */
  	value |= (1<<8);
-#if 1
+
+	/*
+	 * Some unknown Intel IO/APIC (or APIC) errata is biting us with
+	 * certain networking cards. If high frequency interrupts are
+	 * happening on a particular IOAPIC pin, plus the IOAPIC routing
+	 * entry is masked/unmasked at a high rate as well then sooner or
+	 * later IOAPIC line gets 'stuck', no more interrupts are received
+	 * from the device. If focus CPU is disabled then the hang goes
+	 * away, oh well :-(
+	 *
+	 * [ This bug can be reproduced easily with a level-triggered
+	 *   PCI Ne2000 networking cards and PII/PIII processors, dual
+	 *   BX chipset. ]
+	 */
+#if 0
 	/* Enable focus processor (bit==0) */
  	value &= ~(1<<9);
 #else
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
--- v2.3.29/linux/arch/i386/kernel/traps.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/i386/kernel/traps.c	Sat Nov 27 15:46:24 1999
@@ -201,7 +201,7 @@
 	printk("\n");
 }	
 
-spinlock_t die_lock;
+spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
diff -u --recursive --new-file v2.3.29/linux/arch/i386/kernel/visws_apic.c linux/arch/i386/kernel/visws_apic.c
--- v2.3.29/linux/arch/i386/kernel/visws_apic.c	Fri Oct 22 13:21:45 1999
+++ linux/arch/i386/kernel/visws_apic.c	Sat Nov 27 15:27:48 1999
@@ -104,7 +104,7 @@
 /*
  * Not an __init, needed by the reboot code
  */
-void init_pic_mode(void)
+void disable_IO_APIC(void)
 {
 	/* Nop on Cobalt */
 } 
diff -u --recursive --new-file v2.3.29/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c
--- v2.3.29/linux/arch/i386/mm/init.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/i386/mm/init.c	Fri Dec  3 11:12:23 1999
@@ -76,7 +76,7 @@
 	pmd_t v;
 	int i;
 
-	pmd_val(v) = _PAGE_TABLE + __pa(empty_bad_pte_table);
+	set_pmd(&v, __pmd(_PAGE_TABLE + __pa(empty_bad_pte_table)));
 
 	for (i = 0; i < PAGE_SIZE/sizeof(pmd_t); i++)
 		empty_bad_pmd_table[i] = v;
@@ -103,13 +103,13 @@
 void __handle_bad_pmd(pmd_t *pmd)
 {
 	pmd_ERROR(*pmd);
-	pmd_val(*pmd) = _PAGE_TABLE + __pa(get_bad_pte_table());
+	set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(get_bad_pte_table())));
 }
 
 void __handle_bad_pmd_kernel(pmd_t *pmd)
 {
 	pmd_ERROR(*pmd);
-	pmd_val(*pmd) = _KERNPG_TABLE + __pa(get_bad_pte_table());
+	set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(get_bad_pte_table())));
 }
 
 pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
@@ -120,10 +120,10 @@
 	if (pmd_none(*pmd)) {
 		if (pte) {
 			clear_page(pte);
-			pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte);
+			set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
 			return pte + offset;
 		}
-		pmd_val(*pmd) = _KERNPG_TABLE + __pa(get_bad_pte_table());
+		set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(get_bad_pte_table())));
 		return NULL;
 	}
 	free_page((unsigned long)pte);
@@ -142,10 +142,10 @@
 	if (pmd_none(*pmd)) {
 		if (pte) {
 			clear_page((void *)pte);
-			pmd_val(*pmd) = _PAGE_TABLE + __pa(pte);
+			set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)));
 			return (pte_t *)pte + offset;
 		}
-		pmd_val(*pmd) = _PAGE_TABLE + __pa(get_bad_pte_table());
+		set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(get_bad_pte_table())));
 		return NULL;
 	}
 	free_page(pte);
@@ -268,7 +268,7 @@
 		printk("Invalid set_fixmap\n");
 		return;
 	}
-	set_pte_phys (address,phys);
+	set_pte_phys(address,phys);
 }
 
 static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
@@ -286,7 +286,7 @@
 #if CONFIG_X86_PAE
 		if (pgd_none(*pgd)) {
 			pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-			pgd_val(*pgd) = __pa(pmd) + 0x1;
+			set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
 			if (pmd != pmd_offset(pgd, start))
 				BUG();
 		}
@@ -297,7 +297,7 @@
 		for (; (j < PTRS_PER_PMD) && start; pmd++, j++) {
 			if (pmd_none(*pmd)) {
 				pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-				pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte);
+				set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
 				if (pte != pte_offset(pmd, 0))
 					BUG();
 			}
@@ -326,7 +326,7 @@
 		vaddr = i*PGDIR_SIZE;
 #if CONFIG_X86_PAE
 		pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-		pgd_val(*pgd) = __pa(pmd) + 0x1;
+		set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
 #else
 		pmd = (pmd_t *)pgd;
 #endif
@@ -345,12 +345,12 @@
 					set_in_cr4(X86_CR4_PGE);
 					__pe += _PAGE_GLOBAL;
 				}
-				pmd_val(*pmd) = __pe;
+				set_pmd(pmd, __pmd(__pe));
 				continue;
 			}
 
 			pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
-			pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte);
+			set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
 
 			if (pte != pte_offset(pmd, 0))
 				BUG();
@@ -376,7 +376,7 @@
 	 * Permanent kmaps:
 	 */
 	vaddr = PKMAP_BASE;
-	fixrange_init(vaddr, vaddr + 4*1024*1024, pgd_base);
+	fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
 
 	pgd = swapper_pg_dir + __pgd_offset(vaddr);
 	pmd = pmd_offset(pgd, vaddr);
@@ -412,7 +412,7 @@
 #if CONFIG_X86_PAE
 		pgd_clear(swapper_pg_dir+i);
 #else
-		pgd_val(swapper_pg_dir[i]) = 0;
+		set_pgd(swapper_pg_dir+i, __pgd(0));
 #endif
 	flush_tlb_all();
 }
diff -u --recursive --new-file v2.3.29/linux/arch/m68k/atari/stram.c linux/arch/m68k/atari/stram.c
--- v2.3.29/linux/arch/m68k/atari/stram.c	Mon Aug  9 12:27:30 1999
+++ linux/arch/m68k/atari/stram.c	Thu Dec  2 15:06:20 1999
@@ -649,6 +649,7 @@
 
 	/* now swapping to this device ok */
 	p->pages = j + k;
+	swap_list_lock();
 	nr_swap_pages += j;
 	p->flags = SWP_WRITEOK;
 
@@ -666,6 +667,7 @@
 	} else {
 		swap_info[prev].next = p - swap_info;
 	}
+	swap_list_unlock();
 
 	printk( KERN_INFO "Using %dk (%d pages) of ST-RAM as swap space.\n",
 			p->pages << 2, p->pages );
@@ -924,6 +926,9 @@
 			DPRINTK("unswap: map[i=%lu]=%u nr_swap=%u\n",
 				i, map[i], nr_swap_pages);
 
+			swap_device_lock(stram_swap_info);
+			map[i]++;
+			swap_device_unlock(stram_swap_info);
 			/* Get a page for the entry, using the existing
 			   swap cache page if there is one.  Otherwise,
 			   get a clean page and read the swap into it. */
@@ -945,18 +950,24 @@
 				stat_swap_force++;
 	#endif
 			}
-			else if (map[i])
+			else {
+				swap_free(entry);
 				return -ENOMEM;
+			}
 		}
 
 		DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%u\n",
 				 i, map[i], nr_swap_pages );
+		swap_list_lock();
+		swap_device_lock(stram_swap_info);
 		map[i] = SWAP_MAP_BAD;
 		if (stram_swap_info->lowest_bit == i)
 			stram_swap_info->lowest_bit++;
 		if (stram_swap_info->highest_bit == i)
 			stram_swap_info->highest_bit--;
 		--nr_swap_pages;
+		swap_device_unlock(stram_swap_info);
+		swap_list_unlock();
 	}
 
 	return 0;
@@ -1022,6 +1033,8 @@
 		return;
 	}
 
+	swap_list_lock();
+	swap_device_lock(stram_swap_info);
 	/* un-reserve the freed pages */
 	for( ; n_pages > 0; ++offset, --n_pages ) {
 		if (map[offset] != SWAP_MAP_BAD)
@@ -1038,6 +1051,8 @@
 	if (stram_swap_info->prio > swap_info[swap_list.next].prio)
 		swap_list.next = swap_list.head;
 	nr_swap_pages += n_pages;
+	swap_device_unlock(stram_swap_info);
+	swap_list_unlock();
 }
 
 
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/Makefile linux/arch/ppc/Makefile
--- v2.3.29/linux/arch/ppc/Makefile	Fri Oct 15 15:25:13 1999
+++ linux/arch/ppc/Makefile	Thu Dec  2 14:37:34 1999
@@ -21,11 +21,15 @@
 ASFLAGS		=
 LINKFLAGS	= -T arch/ppc/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic
 CFLAGSINC	= -D__KERNEL__ -I$(TOPDIR)/include -D__powerpc__
-CFLAGS		:= $(CFLAGS) -I$(HPATH) -D__powerpc__ -fsigned-char -msoft-float \
-		-pipe -fno-builtin -ffixed-r2 -Wno-uninitialized -mmultiple \
-		-mstring
+CFLAGS		:= $(CFLAGS) -I$(HPATH) -D__powerpc__ -fsigned-char \
+		-msoft-float -pipe -fno-builtin -ffixed-r2 -Wno-uninitialized \
+		-mmultiple -mstring
 CPP		= $(CC) -E $(CFLAGS)
 
+ifdef CONFIG_4xx
+CFLAGS := $(CFLAGS) -mcpu=403
+endif
+
 ifdef CONFIG_8xx
 CFLAGS := $(CFLAGS) -mcpu=860 -I../8xx_io
 endif
@@ -34,10 +38,14 @@
 CFLAGS := $(CFLAGS) -Wa,-mppc64bridge #-mpowerpc64
 endif
 
-ifndef CONFIG_8xx
-HEAD := arch/ppc/kernel/head.o
+ifdef CONFIG_4xx
+  HEAD := arch/ppc/kernel/head_4xx.o
 else
-HEAD := arch/ppc/kernel/head_8xx.o
+  ifdef CONFIG_8xx
+    HEAD := arch/ppc/kernel/head_8xx.o
+  else
+    HEAD := arch/ppc/kernel/head.o
+  endif
 endif
 
 ARCH_SUBDIRS = arch/ppc/kernel arch/ppc/mm arch/ppc/lib
@@ -60,6 +68,7 @@
 MAKECOFFBOOT = $(MAKE) -C arch/$(ARCH)/coffboot
 MAKECHRPBOOT = $(MAKE) -C arch/$(ARCH)/chrpboot
 MAKEMBXBOOT = $(MAKE) -C arch/$(ARCH)/mbxboot
+MAKETREEBOOT = $(MAKE) -C arch/$(ARCH)/treeboot
 
 ifdef CONFIG_8xx
 SUBDIRS += arch/ppc/8xx_io
@@ -77,11 +86,18 @@
 
 BOOT_TARGETS = zImage znetboot.initrd zImage.initrd
 
+ifdef CONFIG_4xx
+$(BOOT_TARGETS): $(CHECKS) vmlinux
+	@$(MAKETREEBOOT) $@
+endif
+
 ifdef CONFIG_8xx
 $(BOOT_TARGETS): $(CHECKS) vmlinux
 	@$(MAKECOFFBOOT) $@
 	@$(MAKEMBXBOOT) $@
-else
+endif
+
+ifdef CONFIG_6xx
 $(BOOT_TARGETS): $(CHECKS) vmlinux
 	@$(MAKECOFFBOOT) $@
 	@$(MAKEBOOT) $@
@@ -108,33 +124,36 @@
 	@$(MAKECHRPBOOT) $@
 endif
 
-gemini_config:
+.PHONY: clean_config
+clean_config:
 	rm -f .config arch/ppc/defconfig
-	ln -s gemini_defconfig arch/ppc/defconfig
 
-pmac_config:
-	rm -f .config arch/ppc/defconfig
-	ln -s pmac_defconfig arch/ppc/defconfig
+gemini_config: clean_config
+	ln -s configs/gemini_defconfig arch/ppc/defconfig
 
-prep_config:
-	rm -f .config arch/ppc/defconfig
-	ln -s prep_defconfig arch/ppc/defconfig
+pmac_config: clean_config
+	ln -s configs/pmac_defconfig arch/ppc/defconfig
 
-chrp_config:
-	rm -f .config arch/ppc/defconfig
-	ln -s chrp_defconfig arch/ppc/defconfig
+prep_config: clean_config
+	ln -s configs/prep_defconfig arch/ppc/defconfig
 
-common_config:
-	rm -f .config arch/ppc/defconfig
-	ln -s common_defconfig arch/ppc/defconfig
+chrp_config: clean_config
+	ln -s configs/chrp_defconfig arch/ppc/defconfig
 
-mbx_config:
-	rm -f .config arch/ppc/defconfig
-	ln -s mbx_defconfig arch/ppc/defconfig
+common_config: clean_config
+	ln -s configs/common_defconfig arch/ppc/defconfig
 
-apus_config:
-	rm -f .config arch/ppc/defconfig
-	ln -s apus_defconfig arch/ppc/defconfig
+mbx_config: clean_config
+	ln -s configs/mbx_defconfig arch/ppc/defconfig
+
+apus_config: clean_config
+	ln -s configs/apus_defconfig arch/ppc/defconfig
+
+oak_config: clean_config
+	ln -s configs/oak_defconfig arch/ppc/defconfig
+
+walnut_config: clean_config
+	ln -s configs/walnut_defconfig arch/ppc/defconfig
 
 tags:
 	etags */*.c include/{asm,linux}/*.h arch/ppc/kernel/*.{c,h}
@@ -145,6 +164,7 @@
 	@$(MAKEBOOT) clean
 	@$(MAKECHRPBOOT) clean
 	@$(MAKEMBXBOOT) clean
+	@$(MAKETREEBOOT) clean
 
 archmrproper:
 
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/apus_defconfig linux/arch/ppc/apus_defconfig
--- v2.3.29/linux/arch/ppc/apus_defconfig	Sat Jun 26 08:34:19 1999
+++ linux/arch/ppc/apus_defconfig	Wed Dec 31 16:00:00 1969
@@ -1,397 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-
-#
-# Platform support
-#
-CONFIG_PPC=y
-CONFIG_6xx=y
-# CONFIG_8xx is not set
-CONFIG_PMAC=y
-# CONFIG_PREP is not set
-# CONFIG_CHRP is not set
-# CONFIG_ALL_PPC is not set
-# CONFIG_APUS is not set
-# CONFIG_MBX is not set
-# CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-CONFIG_PCI=y
-# CONFIG_PCI_QUIRKS is not set
-CONFIG_PCI_OLD_PROC=y
-CONFIG_NET=y
-CONFIG_SYSCTL=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_KERNEL_ELF=y
-CONFIG_BINFMT_MISC=m
-# CONFIG_BINFMT_JAVA is not set
-# CONFIG_PARPORT is not set
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FB=y
-CONFIG_FB_COMPAT_XPMAC=y
-CONFIG_PMAC_PBOOK=y
-CONFIG_MAC_KEYBOARD=y
-CONFIG_MAC_FLOPPY=y
-CONFIG_MAC_SERIAL=y
-CONFIG_ADBMOUSE=y
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
-# CONFIG_TOTALMP is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_BLK_DEV_CMD640 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_IDE_PMAC=y
-CONFIG_BLK_DEV_IDEDMA_PMAC=y
-CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDEDMA_PMAC_AUTO=y
-# CONFIG_IDE_CHIPSETS is not set
-
-#
-# Additional Block Devices
-#
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_MD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=y
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
-# CONFIG_NETLINK_DEV is not set
-# CONFIG_FIREWALL is not set
-# CONFIG_FILTER is not set
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_IP_ROUTER is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-CONFIG_IP_ALIAS=y
-# CONFIG_SYN_COOKIES is not set
-
-#
-# (it is safe to leave these untouched)
-#
-CONFIG_INET_RARP=y
-CONFIG_IP_NOSR=y
-CONFIG_SKB_LARGE=y
-# CONFIG_IPV6 is not set
-
-#
-#  
-#
-# CONFIG_IPX is not set
-CONFIG_ATALK=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_LLC 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
-# CONFIG_CPU_IS_SLOW is not set
-# CONFIG_NET_SCHED is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-CONFIG_SCSI_AIC7XXX=y
-# CONFIG_OVERRIDE_CMDS is not set
-CONFIG_AIC7XXX_PROC_STATS=y
-CONFIG_AIC7XXX_RESET_DELAY=15
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_EATA 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_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_NCR53C8XX 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_SEAGATE is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_DEBUG is not set
-CONFIG_SCSI_MESH=y
-CONFIG_SCSI_MESH_SYNC_RATE=5
-CONFIG_SCSI_MAC53C94=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_ETHERTAP is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MACE=y
-CONFIG_BMAC=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_RTL8139 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_EISA=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
-CONFIG_DE4X5=y
-CONFIG_DEC_ELCP=m
-# CONFIG_DGRS is not set
-# CONFIG_EEXPRESS_PRO100 is not set
-# CONFIG_LNE390 is not set
-# CONFIG_NE3210 is not set
-# CONFIG_NE2K_PCI 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_ZNET is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_DLCI is not set
-# CONFIG_LTPC is not set
-# CONFIG_COPS is not set
-# CONFIG_IPDDP is not set
-CONFIG_PPP=y
-
-#
-# CCP compressors for PPP are only built as modules.
-#
-# CONFIG_SLIP is not set
-# CONFIG_NET_RADIO is not set
-# CONFIG_TR is not set
-# CONFIG_SHAPER is not set
-# CONFIG_HOSTESS_SV11 is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Console drivers
-#
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FB_OF=y
-CONFIG_FB_CONTROL=y
-CONFIG_FB_PLATINUM=y
-CONFIG_FB_VALKYRIE=y
-CONFIG_FB_ATY=y
-CONFIG_FB_IMSTT=y
-CONFIG_FB_CT65550=y
-# CONFIG_FB_S3TRIO is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_CFB8=y
-CONFIG_FBCON_CFB16=y
-CONFIG_FBCON_CFB24=y
-CONFIG_FBCON_CFB32=y
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-# CONFIG_FONT_8x8 is not set
-CONFIG_FONT_8x16=y
-CONFIG_FONT_SUN8x16=y
-CONFIG_FONT_SUN12x22=y
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-# CONFIG_MOUSE is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_VIDEO_DEV is not set
-CONFIG_NVRAM=y
-# CONFIG_JOYSTICK is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-
-#
-# Filesystems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=m
-CONFIG_PROC_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFSD=y
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-# CONFIG_CODA_FS is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_AFFS_FS is not set
-CONFIG_HFS_FS=y
-# CONFIG_ROMFS_FS is not set
-CONFIG_AUTOFS_FS=y
-# CONFIG_UFS_FS is not set
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SMD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-CONFIG_MAC_PARTITION=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_CODEPAGE_437=y
-# 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_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_KOI8_R is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-CONFIG_DMASOUND=y
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_OSS is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/boot/Makefile linux/arch/ppc/boot/Makefile
--- v2.3.29/linux/arch/ppc/boot/Makefile	Fri Oct 15 15:25:13 1999
+++ linux/arch/ppc/boot/Makefile	Sat Nov 27 15:41:59 1999
@@ -134,7 +134,7 @@
 	cp zImage.initrd $(TFTPIMAGE)
 
 clean:
-	rm -f vmlinux* zvmlinux* mkprep zImage*
+	rm -f vmlinux* zvmlinux* mkprep zImage* sImage*
 
 fastdep:
 	$(TOPDIR)/scripts/mkdep *.[Sch] > .depend
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/boot/head.S linux/arch/ppc/boot/head.S
--- v2.3.29/linux/arch/ppc/boot/head.S	Fri Sep 10 23:57:27 1999
+++ linux/arch/ppc/boot/head.S	Sat Nov 27 15:41:59 1999
@@ -112,14 +112,6 @@
 	cmpi	0,r2,0
 	bne	00b
 
-	/* r4,r5 have initrd_start, size */
-	lis	r2,initrd_start@h
-	ori	r2,r2,initrd_start@l
-	lwz	r4,0(r2)
-	lis	r2,initrd_end@h
-	ori	r2,r2,initrd_end@l
-	lwz	r5,0(r2)
-	
 	/* tell kernel we're prep */
 	/* 
 	 * get start address of kernel code which is stored as a coff
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/boot/misc.c linux/arch/ppc/boot/misc.c
--- v2.3.29/linux/arch/ppc/boot/misc.c	Wed Oct 27 16:34:12 1999
+++ linux/arch/ppc/boot/misc.c	Sat Nov 27 15:41:59 1999
@@ -16,6 +16,7 @@
 #include <linux/config.h>
 #include <asm/page.h>
 #include <asm/processor.h>
+#include <asm/bootinfo.h>
 #include <asm/mmu.h>
 #if defined(CONFIG_SERIAL_CONSOLE)
 #include "ns16550.h"
@@ -518,17 +519,39 @@
 	*cp = 0;
 	puts("\n");
 
-	/* mappings on early boot can only handle 16M */
-	if ( (int)(cmd_line[0]) > (16<<20))
-		puts("cmd_line located > 16M\n");
-	if ( (int)hold_residual > (16<<20))
-		puts("hold_residual located > 16M\n");
-	if ( initrd_start > (16<<20))
-		puts("initrd_start located > 16M\n");
-       
 	puts("Uncompressing Linux...");
 	gunzip(0, 0x400000, zimage_start, &zimage_size);
 	puts("done.\n");
+	
+	{
+		struct bi_record *rec;
+	    
+		rec = (struct bi_record *)PAGE_ALIGN(zimage_size);
+	    
+		rec->tag = BI_FIRST;
+		rec->size = sizeof(struct bi_record);
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+		rec->tag = BI_BOOTLOADER_ID;
+		memcpy( (void *)rec->data, "prepboot", 9);
+		rec->size = sizeof(struct bi_record) + 8 + 1;
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	    
+		rec->tag = BI_MACHTYPE;
+		rec->data[0] = _MACH_prep;
+		rec->data[1] = 1;
+		rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	    
+		rec->tag = BI_CMD_LINE;
+		memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
+		rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
+		rec = (struct bi_record *)((ulong)rec + rec->size);
+		
+		rec->tag = BI_LAST;
+		rec->size = sizeof(struct bi_record);
+		rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	}
 	puts("Now booting the kernel\n");
 	return (unsigned long)hold_residual;
 }
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/chrp_defconfig linux/arch/ppc/chrp_defconfig
--- v2.3.29/linux/arch/ppc/chrp_defconfig	Thu Feb 25 10:46:47 1999
+++ linux/arch/ppc/chrp_defconfig	Wed Dec 31 16:00:00 1969
@@ -1,319 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-
-#
-# Platform support
-#
-CONFIG_PPC=y
-CONFIG_6xx=y
-# CONFIG_8xx is not set
-# CONFIG_PMAC is not set
-# CONFIG_PREP is not set
-CONFIG_CHRP=y
-# CONFIG_ALL_PPC is not set
-# CONFIG_APUS is not set
-# CONFIG_MBX is not set
-# CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_KMOD is not set
-CONFIG_PCI=y
-# CONFIG_PCI_QUIRKS is not set
-CONFIG_PCI_OLD_PROC=y
-CONFIG_NET=y
-CONFIG_SYSCTL=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_KERNEL_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_BINFMT_JAVA is not set
-# CONFIG_PARPORT is not set
-CONFIG_FB=y
-CONFIG_FB_COMPAT_XPMAC=y
-# CONFIG_PMAC_PBOOK is not set
-CONFIG_MAC_KEYBOARD=y
-# CONFIG_MAC_FLOPPY is not set
-# CONFIG_MAC_SERIAL is not set
-# CONFIG_ADBMOUSE is not set
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
-# CONFIG_TOTALMP is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_FD=y
-CONFIG_BLK_DEV_IDE=y
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_BLK_DEV_SL82C105=y
-# CONFIG_IDE_CHIPSETS is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_MD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=y
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
-# CONFIG_FIREWALL is not set
-# CONFIG_FILTER is not set
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_IP_ROUTER is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-CONFIG_IP_ALIAS=y
-# CONFIG_SYN_COOKIES is not set
-CONFIG_INET_RARP=y
-CONFIG_IP_NOSR=y
-CONFIG_SKB_LARGE=y
-# CONFIG_IPV6 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_LLC 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
-# CONFIG_CPU_IS_SLOW is not set
-# CONFIG_NET_SCHED is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=y
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST 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_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_EATA 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_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-CONFIG_SCSI_NCR53C8XX=y
-CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
-CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4
-CONFIG_SCSI_NCR53C8XX_SYNC=5
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-# CONFIG_SCSI_NCR53C8XX_IOMAPPED 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_SEAGATE is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_DEBUG is not set
-CONFIG_SCSI_MESH=y
-CONFIG_SCSI_MESH_SYNC_RATE=10
-CONFIG_SCSI_MAC53C94=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_NET_ETHERNET=y
-# CONFIG_MACE is not set
-# CONFIG_BMAC 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_RTL8139 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_EISA=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_DE4X5 is not set
-CONFIG_DEC_ELCP=y
-# CONFIG_DGRS is not set
-# CONFIG_EEXPRESS_PRO100 is not set
-# CONFIG_LNE390 is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_TLAN is not set
-# CONFIG_ES3210 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_ZNET is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FDDI is not set
-# CONFIG_DLCI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_RADIO is not set
-# CONFIG_TR is not set
-# CONFIG_SHAPER is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Console drivers
-#
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FB_OF=y
-# CONFIG_FB_CONTROL is not set
-# CONFIG_FB_PLATINUM is not set
-# CONFIG_FB_VALKYRIE is not set
-CONFIG_FB_ATY=y
-CONFIG_FB_IMSTT=y
-# CONFIG_FB_CT65550 is not set
-# CONFIG_FB_S3TRIO is not set
-CONFIG_FB_VGA=y
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_CFB8=y
-CONFIG_FBCON_CFB16=y
-CONFIG_FBCON_CFB24=y
-CONFIG_FBCON_CFB32=y
-CONFIG_FBCON_VGA=y
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-# CONFIG_FBCON_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
-# CONFIG_MOUSE is not set
-# CONFIG_UMISC is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_VIDEO_DEV is not set
-CONFIG_NVRAM=y
-# CONFIG_JOYSTICK is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-
-#
-# Filesystems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET 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_PROC_FS=y
-CONFIG_NFS_FS=y
-# CONFIG_NFSD is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-# CONFIG_CODA_FS is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_AFFS_FS is not set
-CONFIG_HFS_FS=y
-# CONFIG_ROMFS_FS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_ADFS_FS is not set
-CONFIG_MAC_PARTITION=y
-# CONFIG_NLS is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_OSS is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/chrpboot/main.c linux/arch/ppc/chrpboot/main.c
--- v2.3.29/linux/arch/ppc/chrpboot/main.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/ppc/chrpboot/main.c	Sat Nov 27 15:41:59 1999
@@ -8,6 +8,10 @@
  */
 #include "../coffboot/nonstdio.h"
 #include "../coffboot/zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#define __KERNEL__
+#include <asm/page.h>
 
 extern void *finddevice(const char *);
 extern int getprop(void *, const char *, void *, int);
@@ -71,6 +75,30 @@
     sa = (unsigned long)PROG_START;
     printf("start address = 0x%x\n\r", sa);
 
+    {
+	    struct bi_record *rec;
+	    
+	    rec = (struct bi_record *)PAGE_ALIGN((unsigned long)dst+len);
+	    
+	    rec->tag = BI_FIRST;
+	    rec->size = sizeof(struct bi_record);
+	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+	    rec->tag = BI_BOOTLOADER_ID;
+	    sprintf( (char *)rec->data, "chrpboot");
+	    rec->size = sizeof(struct bi_record) + strlen("chrpboot") + 1;
+	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	    
+	    rec->tag = BI_MACHTYPE;
+	    rec->data[0] = _MACH_chrp;
+	    rec->data[1] = 1;
+	    rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	    
+	    rec->tag = BI_LAST;
+	    rec->size = sizeof(struct bi_record);
+	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
+    }
     (*(void (*)())sa)(0, 0, prom, a1, a2);
 
     printf("returned?\n\r");
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/chrpboot/string.S linux/arch/ppc/chrpboot/string.S
--- v2.3.29/linux/arch/ppc/chrpboot/string.S	Mon Jan 12 15:18:13 1998
+++ linux/arch/ppc/chrpboot/string.S	Wed Dec 31 16:00:00 1969
@@ -1,206 +0,0 @@
-/*
- * String handling functions for PowerPC.
- *
- * Copyright (C) 1996 Paul Mackerras.
- *
- * 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.
- */
-#define r0	0
-#define r3	3
-#define r4	4
-#define r5	5
-#define r6	6
-#define r7	7
-#define r8	8
-
-	.globl	strcpy
-strcpy:
-	addi	r5,r3,-1
-	addi	r4,r4,-1
-1:	lbzu	r0,1(r4)
-	cmpwi	0,r0,0
-	stbu	r0,1(r5)
-	bne	1b
-	blr
-
-	.globl	strncpy
-strncpy:
-	cmpwi	0,r5,0
-	beqlr
-	mtctr	r5
-	addi	r6,r3,-1
-	addi	r4,r4,-1
-1:	lbzu	r0,1(r4)
-	cmpwi	0,r0,0
-	stbu	r0,1(r6)
-	bdnzf	2,1b		/* dec ctr, branch if ctr != 0 && !cr0.eq */
-	blr
-
-	.globl	strcat
-strcat:
-	addi	r5,r3,-1
-	addi	r4,r4,-1
-1:	lbzu	r0,1(r5)
-	cmpwi	0,r0,0
-	bne	1b
-	addi	r5,r5,-1
-1:	lbzu	r0,1(r4)
-	cmpwi	0,r0,0
-	stbu	r0,1(r5)
-	bne	1b
-	blr
-
-	.globl	strcmp
-strcmp:
-	addi	r5,r3,-1
-	addi	r4,r4,-1
-1:	lbzu	r3,1(r5)
-	cmpwi	1,r3,0
-	lbzu	r0,1(r4)
-	subf.	r3,r0,r3
-	beqlr	1
-	beq	1b
-	blr
-
-	.globl	strlen
-strlen:
-	addi	r4,r3,-1
-1:	lbzu	r0,1(r4)
-	cmpwi	0,r0,0
-	bne	1b
-	subf	r3,r3,r4
-	blr
-
-	.globl	memset
-memset:
-	rlwimi	r4,r4,8,16,23
-	rlwimi	r4,r4,16,0,15
-	addi	r6,r3,-4
-	cmplwi	0,r5,4
-	blt	7f
-	stwu	r4,4(r6)
-	beqlr
-	andi.	r0,r6,3
-	add	r5,r0,r5
-	subf	r6,r0,r6
-	rlwinm	r0,r5,32-2,2,31
-	mtctr	r0
-	bdz	6f
-1:	stwu	r4,4(r6)
-	bdnz	1b
-6:	andi.	r5,r5,3
-7:	cmpwi	0,r5,0
-	beqlr
-	mtctr	r5
-	addi	r6,r6,3
-8:	stbu	r4,1(r6)
-	bdnz	8b
-	blr
-
-	.globl	bcopy
-bcopy:
-	mr	r6,r3
-	mr	r3,r4
-	mr	r4,r6
-	b	memcpy
-
-	.globl	memmove
-memmove:
-	cmplw	0,r3,r4
-	bgt	backwards_memcpy
-	/* fall through */
-
-	.globl	memcpy
-memcpy:
-	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
-	addi	r6,r3,-4
-	addi	r4,r4,-4
-	beq	2f			/* if less than 8 bytes to do */
-	andi.	r0,r6,3			/* get dest word aligned */
-	mtctr	r7
-	bne	5f
-1:	lwz	r7,4(r4)
-	lwzu	r8,8(r4)
-	stw	r7,4(r6)
-	stwu	r8,8(r6)
-	bdnz	1b
-	andi.	r5,r5,7
-2:	cmplwi	0,r5,4
-	blt	3f
-	lwzu	r0,4(r4)
-	addi	r5,r5,-4
-	stwu	r0,4(r6)
-3:	cmpwi	0,r5,0
-	beqlr
-	mtctr	r5
-	addi	r4,r4,3
-	addi	r6,r6,3
-4:	lbzu	r0,1(r4)
-	stbu	r0,1(r6)
-	bdnz	4b
-	blr
-5:	subfic	r0,r0,4
-	mtctr	r0
-6:	lbz	r7,4(r4)
-	addi	r4,r4,1
-	stb	r7,4(r6)
-	addi	r6,r6,1
-	bdnz	6b
-	subf	r5,r0,r5
-	rlwinm.	r7,r5,32-3,3,31
-	beq	2b
-	mtctr	r7
-	b	1b
-
-	.globl	backwards_memcpy
-backwards_memcpy:
-	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
-	add	r6,r3,r5
-	add	r4,r4,r5
-	beq	2f
-	andi.	r0,r6,3
-	mtctr	r7
-	bne	5f
-1:	lwz	r7,-4(r4)
-	lwzu	r8,-8(r4)
-	stw	r7,-4(r6)
-	stwu	r8,-8(r6)
-	bdnz	1b
-	andi.	r5,r5,7
-2:	cmplwi	0,r5,4
-	blt	3f
-	lwzu	r0,-4(r4)
-	subi	r5,r5,4
-	stwu	r0,-4(r6)
-3:	cmpwi	0,r5,0
-	beqlr
-	mtctr	r5
-4:	lbzu	r0,-1(r4)
-	stbu	r0,-1(r6)
-	bdnz	4b
-	blr
-5:	mtctr	r0
-6:	lbzu	r7,-1(r4)
-	stbu	r7,-1(r6)
-	bdnz	6b
-	subf	r5,r0,r5
-	rlwinm.	r7,r5,32-3,3,31
-	beq	2b
-	mtctr	r7
-	b	1b
-
-	.globl	memcmp
-memcmp:
-	cmpwi	0,r5,0
-	blelr
-	mtctr	r5
-	addi	r6,r3,-1
-	addi	r4,r4,-1
-1:	lbzu	r3,1(r6)
-	lbzu	r0,1(r4)
-	subf.	r3,r0,r3
-	bdnzt	2,1b
-	blr
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/coffboot/Makefile linux/arch/ppc/coffboot/Makefile
--- v2.3.29/linux/arch/ppc/coffboot/Makefile	Mon Jun 28 13:40:39 1999
+++ linux/arch/ppc/coffboot/Makefile	Thu Dec  2 14:37:34 1999
@@ -9,25 +9,26 @@
 LD	= $(CROSS_COMPILE)ld
 CFLAGS	= -O -fno-builtin -I$(TOPDIR)/include
 OBJCOPY = $(CROSS_COMPILE)objcopy
-OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment \
-	--add-section=image=vmlinux.gz
-LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
+OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
+COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
+CHRP_LD_ARGS = -Ttext 0x00400000
 GZ = gzip -9
 
-OBJS = crt0.o start.o main.o misc.o string.o zlib.o
+COFFOBJS = coffcrt0.o start.o coffmain.o misc.o string.o zlib.o image.o
+CHRPOBJS = crt0.o start.o chrpmain.o misc.o string.o zlib.o image.o
 LIBS = $(TOPDIR)/lib/lib.a
 
-ifeq ($(CONFIG_ALL_PPC),y)
-# yes, we want to build pmac stuff
-CONFIG_PMAC = y
-endif
-
 ifeq ($(CONFIG_PPC64),y)
 MSIZE=.64
 else
 MSIZE=
 endif
 
+ifeq ($(CONFIG_ALL_PPC),y)
+# yes, we want to build pmac stuff
+CONFIG_PMAC = y
+endif
+
 ifeq ($(CONFIG_SMP),y)
 TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE)
 else
@@ -38,33 +39,57 @@
 hack-coff: hack-coff.c
 	$(HOSTCC) $(HOSTCFLAGS) -o hack-coff hack-coff.c
 
+znetboot: vmlinux.coff zImage
+	cp vmlinux.coff $(TFTPIMAGE)
+
+znetboot.initrd: vmlinux.coff.initrd
+	cp vmlinux.coff.initrd $(TFTPIMAGE)
+
 floppy: zImage
 #	mount -t hfs /dev/fd0 /mnt
 #	cp vmlinux.coff /mnt
 #	umount /mnt
 
-znetboot: vmlinux.coff
-	cp vmlinux.coff $(TFTPIMAGE)
+coffboot: $(COFFOBJS) no_initrd.o ld.script
+	$(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) no_initrd.o $(LIBS)
 
-znetboot.initrd: vmlinux.coff.initrd
-	cp vmlinux.coff.initrd $(TFTPIMAGE)
+coffboot.initrd: $(COFFOBJS) initrd.o ld.script
+	$(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) initrd.o $(LIBS)
 
-coffboot: $(OBJS) ld.script
-	$(LD) -o coffboot $(LD_ARGS) $(OBJS) $(LIBS)
+piggyback: piggyback.c
+	$(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c
 
-zImage: vmlinux.coff
+mknote: mknote.c
+	$(HOSTCC) $(HOSTCFLAGS) -o mknote mknote.c
 
-zImage.initrd: vmlinux.coff.initrd
+image.o: piggyback vmlinux.gz
+	./piggyback image < vmlinux.gz | $(AS) -o image.o
 
-vmlinux.coff: coffboot hack-coff vmlinux.gz
+initrd.o: ramdisk.image.gz piggyback
+	./piggyback initrd < ramdisk.image.gz | $(AS) -o initrd.o
+
+vmlinux.coff: coffboot hack-coff
 	$(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@
 	./hack-coff $@
 	ln -sf vmlinux.coff zImage
 
-vmlinux.coff.initrd: coffboot hack-coff vmlinux.gz ramdisk.image.gz
-	$(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=ramdisk.image.gz \
-		coffboot $@
+vmlinux.coff.initrd: coffboot.initrd hack-coff
+	$(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@
 	./hack-coff $@
+
+vmlinux.elf: $(CHRPOBJS) no_initrd.o mknote
+	$(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) no_initrd.o $(LIBS)
+	./mknote > note
+	$(OBJCOPY) $@ $@ --add-section=.note=note -R .comment
+
+vmlinux.elf.initrd: $(CHRPOBJS) initrd.o mknote
+	$(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) initrd.o $(LIBS)
+	./mknote > note
+	$(OBJCOPY) $@ $@ --add-section=.note=note -R .comment
+
+zImage: vmlinux.coff vmlinux.elf
+
+zImage.initrd: vmlinux.coff.initrd vmlinux.elf.initrd
 
 else
 znetboot: vmlinux.gz
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/coffboot/chrpmain.c linux/arch/ppc/coffboot/chrpmain.c
--- v2.3.29/linux/arch/ppc/coffboot/chrpmain.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/coffboot/chrpmain.c	Thu Dec  2 14:37:34 1999
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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 "nonstdio.h"
+#include "zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#define __KERNEL__
+#include <asm/page.h>
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+void make_bi_recs(unsigned long);
+void gunzip(void *, int, unsigned char *, int *);
+void stop_imac_ethernet(void);
+void stop_imac_usb(void);
+
+#define get_16be(x)	(*(unsigned short *)(x))
+#define get_32be(x)	(*(unsigned *)(x))
+
+#define RAM_START	0x00000000
+#define RAM_END		(8<<20)
+
+#define PROG_START	0x00010000
+
+char *avail_ram;
+char *end_avail;
+
+extern char _end[];
+extern char image_data[];
+extern int image_len;
+extern char initrd_data[];
+extern int initrd_len;
+
+
+boot(int a1, int a2, void *prom)
+{
+    int ns, oh, i;
+    unsigned sa, len;
+    void *dst;
+    unsigned char *im;
+    unsigned initrd_start, initrd_size;
+    extern char _start;
+    
+    printf("chrpboot starting: loaded at 0x%x\n", &_start);
+    if (initrd_len) {
+	initrd_size = initrd_len;
+	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+	a1 = initrd_start;
+	a2 = initrd_size;
+	claim(initrd_start, RAM_END - initrd_start, 0);
+	printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", initrd_start,
+	       initrd_data,initrd_size);
+	memcpy((char *)initrd_start, initrd_data, initrd_size);
+    }
+    im = image_data;
+    len = image_len;
+    /* claim 3MB starting at PROG_START */
+    claim(PROG_START, 3 << 20, 0);
+    dst = (void *) PROG_START;
+    if (im[0] == 0x1f && im[1] == 0x8b) {
+	/* claim 512kB for scratch space */
+	avail_ram = (char *) claim(0, 512 << 10, 0x10);
+	end_avail = avail_ram + (512 << 10);
+	printf("avail_ram = %x\n", avail_ram);
+	printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+	gunzip(dst, 3 << 20, im, &len);
+	printf("done %u bytes\n", len);
+    } else {
+	memmove(dst, im, len);
+    }
+
+    flush_cache(dst, len);
+    stop_imac_ethernet();
+    stop_imac_usb();
+    make_bi_recs((unsigned long) dst + len);
+
+    sa = (unsigned long)PROG_START;
+    printf("start address = 0x%x\n", sa);
+
+    (*(void (*)())sa)(0, 0, prom, a1, a2);
+
+    printf("returned?\n");
+
+    pause();
+}
+
+void make_bi_recs(unsigned long addr)
+{
+	struct bi_record *rec;
+
+	rec = (struct bi_record *)PAGE_ALIGN(addr);
+	    
+	rec->tag = BI_FIRST;
+	rec->size = sizeof(struct bi_record);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+	rec->tag = BI_BOOTLOADER_ID;
+	sprintf( (char *)rec->data, "coffboot");
+	rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	    
+	rec->tag = BI_MACHTYPE;
+	rec->data[0] = _MACH_Pmac;
+	rec->data[1] = 1;
+	rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	    
+	rec->tag = BI_LAST;
+	rec->size = sizeof(struct bi_record);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+}
+
+#define eieio()	asm volatile("eieio");
+
+void stop_imac_ethernet(void)
+{
+    void *macio, *enet;
+    unsigned int macio_addr[5], enet_reg[6];
+    int len;
+    volatile unsigned int *dbdma;
+
+    macio = finddevice("/pci/mac-io");
+    enet = finddevice("/pci/mac-io/ethernet");
+    if (macio == NULL || enet == NULL)
+	return;
+    len = getprop(macio, "assigned-addresses", macio_addr, sizeof(macio_addr));
+    if (len != sizeof(macio_addr))
+	return;
+    len = getprop(enet, "reg", enet_reg, sizeof(enet_reg));
+    if (len != sizeof(enet_reg))
+	return;
+    printf("macio base %x, dma at %x & %x\n",
+	   macio_addr[2], enet_reg[2], enet_reg[4]);
+
+    /* hope this is mapped... */
+    dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[2]);
+    *dbdma = 0x80;	/* clear the RUN bit */
+    eieio();
+    dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[4]);
+    *dbdma = 0x80;	/* clear the RUN bit */
+    eieio();
+}
+
+void stop_imac_usb(void)
+{
+    void *usb;
+    unsigned int usb_addr[5];
+    int len;
+    volatile unsigned int *usb_ctrl;
+
+    usb = finddevice("/pci/usb");
+    if (usb == NULL)
+	return;
+    len = getprop(usb, "assigned-addresses", usb_addr, sizeof(usb_addr));
+    if (len != sizeof(usb_addr))
+	return;
+    printf("usb base %x\n", usb_addr[2]);
+
+    usb_ctrl = (volatile unsigned int *) (usb_addr[2] + 8);
+    *usb_ctrl = 0x01000000;	/* cpu_to_le32(1) */
+    eieio();
+}
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+    void *p = avail_ram;
+
+    size *= items;
+    size = (size + 7) & -8;
+    avail_ram += size;
+    if (avail_ram > end_avail) {
+	printf("oops... out of memory\n");
+	pause();
+    }
+    return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+}
+
+#define HEAD_CRC	2
+#define EXTRA_FIELD	4
+#define ORIG_NAME	8
+#define COMMENT		0x10
+#define RESERVED	0xe0
+
+#define DEFLATED	8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+    z_stream s;
+    int r, i, flags;
+
+    /* skip header */
+    i = 10;
+    flags = src[3];
+    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+	printf("bad gzipped data\n");
+	exit();
+    }
+    if ((flags & EXTRA_FIELD) != 0)
+	i = 12 + src[10] + (src[11] << 8);
+    if ((flags & ORIG_NAME) != 0)
+	while (src[i++] != 0)
+	    ;
+    if ((flags & COMMENT) != 0)
+	while (src[i++] != 0)
+	    ;
+    if ((flags & HEAD_CRC) != 0)
+	i += 2;
+    if (i >= *lenp) {
+	printf("gunzip: ran out of data in header\n");
+	exit();
+    }
+
+    s.zalloc = zalloc;
+    s.zfree = zfree;
+    r = inflateInit2(&s, -MAX_WBITS);
+    if (r != Z_OK) {
+	printf("inflateInit2 returned %d\n", r);
+	exit();
+    }
+    s.next_in = src + i;
+    s.avail_in = *lenp - i;
+    s.next_out = dst;
+    s.avail_out = dstlen;
+    r = inflate(&s, Z_FINISH);
+    if (r != Z_OK && r != Z_STREAM_END) {
+	printf("inflate returned %d msg: %s\n", r, s.msg);
+	exit();
+    }
+    *lenp = s.next_out - (unsigned char *) dst;
+    inflateEnd(&s);
+}
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/coffboot/coffcrt0.S linux/arch/ppc/coffboot/coffcrt0.S
--- v2.3.29/linux/arch/ppc/coffboot/coffcrt0.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/coffboot/coffcrt0.S	Thu Dec  2 14:37:34 1999
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ */
+	.text
+	.globl	_start
+_start:
+	.long	__start,0,0
+
+	.globl	__start
+__start:
+	lis	9,_start@h
+	lis	8,_etext@ha
+	addi	8,8,_etext@l
+1:	dcbf	0,9
+	icbi	0,9
+	addi	9,9,0x20
+	cmplwi	0,9,8
+	blt	1b
+	b	start
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/coffboot/coffmain.c linux/arch/ppc/coffboot/coffmain.c
--- v2.3.29/linux/arch/ppc/coffboot/coffmain.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/coffboot/coffmain.c	Thu Dec  2 14:37:34 1999
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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 "nonstdio.h"
+#include "zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#define __KERNEL__
+#include <asm/page.h>
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+extern char *claim(unsigned, unsigned, unsigned);
+void make_bi_recs(unsigned long);
+void gunzip(void *, int, unsigned char *, int *);
+
+#define get_16be(x)	(*(unsigned short *)(x))
+#define get_32be(x)	(*(unsigned *)(x))
+
+#define RAM_START	0xc0000000
+#define PROG_START	RAM_START
+#define RAM_END		(RAM_START + 0x800000)	/* only 8M mapped with BATs */
+
+char *avail_ram;
+char *end_avail;
+
+extern char _start[], _end[];
+extern char image_data[];
+extern int image_len;
+extern char initrd_data[];
+extern int initrd_len;
+
+
+boot(int a1, int a2, void *prom)
+{
+    int ns, oh, i;
+    unsigned sa, len;
+    void *dst;
+    unsigned char *im;
+    unsigned initrd_start, initrd_size;
+    
+    printf("coffboot starting: loaded at 0x%x\n", _start);
+    setup_bats(RAM_START);
+    if (initrd_len) {
+	initrd_size = initrd_len;
+	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+	a1 = initrd_start;
+	a2 = initrd_size;
+	claim(initrd_start - RAM_START, RAM_END - initrd_start, 0);
+	printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n",
+	       initrd_start, initrd_data, initrd_size);
+	memcpy((char *)initrd_start, initrd_data, initrd_size);
+    }
+    im = image_data;
+    len = image_len;
+    /* claim 3MB starting at 0 */
+    claim(0, 3 << 20, 0);
+    dst = (void *) RAM_START;
+    if (im[0] == 0x1f && im[1] == 0x8b) {
+	/* claim 512kB for scratch space */
+	avail_ram = claim(0, 512 << 10, 0x10) + RAM_START;
+	end_avail = avail_ram + (512 << 10);
+	printf("avail_ram = %x\n", avail_ram);
+	printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+	gunzip(dst, 3 << 20, im, &len);
+	printf("done %u bytes\n", len);
+    } else {
+	memmove(dst, im, len);
+    }
+
+    flush_cache(dst, len);
+    make_bi_recs((unsigned long)dst + len);
+    
+    sa = (unsigned long)PROG_START;
+    printf("start address = 0x%x\n", sa);
+
+#if 0
+    pause();
+#endif
+    (*(void (*)())sa)(a1, a2, prom);
+
+    printf("returned?\n");
+
+    pause();
+}
+
+void make_bi_recs(unsigned long addr)
+{
+	struct bi_record *rec;
+
+	rec = (struct bi_record *)PAGE_ALIGN(addr);
+	    
+	rec->tag = BI_FIRST;
+	rec->size = sizeof(struct bi_record);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+	rec->tag = BI_BOOTLOADER_ID;
+	sprintf( (char *)rec->data, "coffboot");
+	rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	    
+	rec->tag = BI_MACHTYPE;
+	rec->data[0] = _MACH_Pmac;
+	rec->data[1] = 1;
+	rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	    
+	rec->tag = BI_LAST;
+	rec->size = sizeof(struct bi_record);
+	rec = (struct bi_record *)((unsigned long)rec + rec->size);
+}
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+    void *p = avail_ram;
+
+    size *= items;
+    size = (size + 7) & -8;
+    avail_ram += size;
+    if (avail_ram > end_avail) {
+	printf("oops... out of memory\n");
+	pause();
+    }
+    return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+}
+
+#define HEAD_CRC	2
+#define EXTRA_FIELD	4
+#define ORIG_NAME	8
+#define COMMENT		0x10
+#define RESERVED	0xe0
+
+#define DEFLATED	8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+    z_stream s;
+    int r, i, flags;
+
+    /* skip header */
+    i = 10;
+    flags = src[3];
+    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+	printf("bad gzipped data\n");
+	exit();
+    }
+    if ((flags & EXTRA_FIELD) != 0)
+	i = 12 + src[10] + (src[11] << 8);
+    if ((flags & ORIG_NAME) != 0)
+	while (src[i++] != 0)
+	    ;
+    if ((flags & COMMENT) != 0)
+	while (src[i++] != 0)
+	    ;
+    if ((flags & HEAD_CRC) != 0)
+	i += 2;
+    if (i >= *lenp) {
+	printf("gunzip: ran out of data in header\n");
+	exit();
+    }
+
+    s.zalloc = zalloc;
+    s.zfree = zfree;
+    r = inflateInit2(&s, -MAX_WBITS);
+    if (r != Z_OK) {
+	printf("inflateInit2 returned %d\n", r);
+	exit();
+    }
+    s.next_in = src + i;
+    s.avail_in = *lenp - i;
+    s.next_out = dst;
+    s.avail_out = dstlen;
+    r = inflate(&s, Z_FINISH);
+    if (r != Z_OK && r != Z_STREAM_END) {
+	printf("inflate returned %d msg: %s\n", r, s.msg);
+	exit();
+    }
+    *lenp = s.next_out - (unsigned char *) dst;
+    inflateEnd(&s);
+}
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/coffboot/crt0.S linux/arch/ppc/coffboot/crt0.S
--- v2.3.29/linux/arch/ppc/coffboot/crt0.S	Sat Aug 16 09:51:08 1997
+++ linux/arch/ppc/coffboot/crt0.S	Thu Dec  2 14:37:34 1999
@@ -9,10 +9,6 @@
 	.text
 	.globl	_start
 _start:
-	.long	__start,0,0
-
-	.globl	__start
-__start:
 	lis	9,_start@h
 	lis	8,_etext@ha
 	addi	8,8,_etext@l
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/coffboot/main.c linux/arch/ppc/coffboot/main.c
--- v2.3.29/linux/arch/ppc/coffboot/main.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/ppc/coffboot/main.c	Sat Nov 27 15:41:59 1999
@@ -9,6 +9,10 @@
 #include "nonstdio.h"
 #include "rs6000.h"
 #include "zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#define __KERNEL__
+#include <asm/page.h>
 
 extern void *finddevice(const char *);
 extern int getprop(void *, const char *, void *, int);
@@ -106,6 +110,31 @@
 #if 0
     pause();
 #endif
+    {
+	    struct bi_record *rec;
+
+	    rec = (struct bi_record *)PAGE_ALIGN((unsigned long)dst+len);
+	    
+	    rec->tag = BI_FIRST;
+	    rec->size = sizeof(struct bi_record);
+	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+	    rec->tag = BI_BOOTLOADER_ID;
+	    sprintf( (char *)rec->data, "coffboot");
+	    rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
+	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	    
+	    rec->tag = BI_MACHTYPE;
+	    rec->data[0] = _MACH_Pmac;
+	    rec->data[1] = 1;
+	    rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
+	    
+	    rec->tag = BI_LAST;
+	    rec->size = sizeof(struct bi_record);
+	    rec = (struct bi_record *)((unsigned long)rec + rec->size);
+    }
+    
     (*(void (*)())sa)(a1, a2, prom);
 
     printf("returned?\n");
@@ -165,7 +194,6 @@
 	printf("gunzip: ran out of data in header\n");
 	exit();
     }
-printf("done 1\n");
     s.zalloc = zalloc;
     s.zfree = zfree;
     r = inflateInit2(&s, -MAX_WBITS);
@@ -177,14 +205,11 @@
     s.avail_in = *lenp - i;
     s.next_out = dst;
     s.avail_out = dstlen;
-printf("doing inflate\n");
     r = inflate(&s, Z_FINISH);
-printf("done inflate\n");
     if (r != Z_OK && r != Z_STREAM_END) {
 	printf("inflate returned %d\n", r);
 	exit();
     }
     *lenp = s.next_out - (unsigned char *) dst;
-printf("doing end\n");
     inflateEnd(&s);
 }
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/coffboot/misc.S linux/arch/ppc/coffboot/misc.S
--- v2.3.29/linux/arch/ppc/coffboot/misc.S	Wed Sep 30 10:14:16 1998
+++ linux/arch/ppc/coffboot/misc.S	Thu Dec  2 14:37:34 1999
@@ -14,23 +14,26 @@
  */
 	.globl	setup_bats
 setup_bats:
-	mr	4,3
-	mfpvr	3
-	rlwinm	3,3,16,16,31		/* r3 = 1 for 601, 4 for 604 */
-	cmpi	0,3,1
+	mfpvr	5
+	rlwinm	5,5,16,16,31		/* r3 = 1 for 601, 4 for 604 */
+	cmpi	0,5,1
+	li	0,0
 	bne	4f
-	ori	4,4,4			/* set up BAT registers for 601 */
-	li	5,0x7f
-	mtibatu	3,4
-	mtibatl	3,5
-	isync
-	blr
-4:	ori	4,4,0xfe		/* set up BAT registers for 604 */
-	li	5,2
-	mtdbatl	3,5
-	mtdbatu	3,4
-	mtibatl	3,5
-	mtibatu	3,4
+	mtibatl	3,0			/* invalidate BAT first */
+	ori	3,3,4			/* set up BAT registers for 601 */
+	li	4,0x7f
+	mtibatu	3,3
+	mtibatl	3,4
+	b	5f
+4:	mtdbatu	3,0			/* invalidate BATs first */
+	mtibatu	3,0
+	ori	3,3,0xff		/* set up BAT registers for 604 */
+	li	4,2
+	mtdbatl	3,4
+	mtdbatu	3,3
+	mtibatl	3,4
+	mtibatu	3,3
+5:	sync
 	isync
 	blr
 
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/coffboot/mknote.c linux/arch/ppc/coffboot/mknote.c
--- v2.3.29/linux/arch/ppc/coffboot/mknote.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/coffboot/mknote.c	Thu Dec  2 14:37:34 1999
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) Cort Dougan 1999.
+ *
+ * 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.
+ *
+ * Generate a note section as per the CHRP specification.
+ *
+ */
+
+#include <stdio.h>
+
+#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
+
+int main(void)
+{
+/* header */
+	/* namesz */
+	PL(strlen("PowerPC")+1);
+	/* descrsz */
+	PL(6*4);
+	/* type */
+	PL(0x1275);
+	/* name */
+	printf("PowerPC"); printf("%c", 0);
+	
+/* descriptor */
+	/* real-mode */
+	PL(0xffffffff);
+	/* real-base */
+	PL(0x00c00000);
+	/* real-size */
+	PL(0xffffffff);
+	/* virt-base */
+	PL(0xffffffff);
+	/* virt-size */
+	PL(0xffffffff);
+	/* load-base */
+	PL(0x4000);
+	return 0;
+}
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/coffboot/no_initrd.c linux/arch/ppc/coffboot/no_initrd.c
--- v2.3.29/linux/arch/ppc/coffboot/no_initrd.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/coffboot/no_initrd.c	Thu Dec  2 14:37:34 1999
@@ -0,0 +1,2 @@
+char initrd_data[1];
+int initrd_len = 0;
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/coffboot/piggyback.c linux/arch/ppc/coffboot/piggyback.c
--- v2.3.29/linux/arch/ppc/coffboot/piggyback.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/coffboot/piggyback.c	Thu Dec  2 14:37:34 1999
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+extern long ce_exec_config[];
+
+main(int argc, char *argv[])
+{
+	int i, cnt, pos, len;
+	unsigned int cksum, val;
+	unsigned char *lp;
+	unsigned char buf[8192];
+	if (argc != 2)
+	{
+		fprintf(stderr, "usage: %s name <in-file >out-file\n",
+			argv[0]);
+		exit(1);
+	}
+	fprintf(stdout, "#\n");
+	fprintf(stdout, "# Miscellaneous data structures:\n");
+	fprintf(stdout, "# WARNING - this file is automatically generated!\n");
+	fprintf(stdout, "#\n");
+	fprintf(stdout, "\n");
+	fprintf(stdout, "\t.data\n");
+	fprintf(stdout, "\t.globl %s_data\n", argv[1]);
+	fprintf(stdout, "%s_data:\n", argv[1]);
+	pos = 0;
+	cksum = 0;
+	while ((len = read(0, buf, sizeof(buf))) > 0)
+	{
+		cnt = 0;
+		lp = (unsigned char *)buf;
+		len = (len + 3) & ~3;  /* Round up to longwords */
+		for (i = 0;  i < len;  i += 4)
+		{
+			if (cnt == 0)
+			{
+				fprintf(stdout, "\t.long\t");
+			}
+			fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
+			val = *(unsigned long *)lp;
+			cksum ^= val;
+			lp += 4;
+			if (++cnt == 4)
+			{
+				cnt = 0;
+				fprintf(stdout, " # %x \n", pos+i-12);
+				fflush(stdout);
+			} else
+			{
+				fprintf(stdout, ",");
+			}
+		}
+		if (cnt)
+		{
+			fprintf(stdout, "0\n");
+		}
+		pos += len;
+	}
+	fprintf(stdout, "\t.globl %s_len\n", argv[1]);
+	fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos);
+	fflush(stdout);
+	fclose(stdout);
+	fprintf(stderr, "cksum = %x\n", cksum);
+	exit(0);
+}
+
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/coffboot/start.c linux/arch/ppc/coffboot/start.c
--- v2.3.29/linux/arch/ppc/coffboot/start.c	Mon Jan 12 15:18:13 1998
+++ linux/arch/ppc/coffboot/start.c	Thu Dec  2 14:37:34 1999
@@ -33,7 +33,7 @@
     if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
 	exit();
 
-    coffboot(a1, a2, promptr);
+    boot(a1, a2, promptr);
     for (;;)
 	exit();
 }
@@ -62,6 +62,25 @@
     return args.actual;
 }
 
+int writestring(void *f, char *ptr, int nb)
+{
+	int w = 0, i;
+	char *ret = "\r";
+
+	for (i = 0; i < nb; ++i) {
+		if (ptr[i] == '\n') {
+			if (i > w) {
+				write(f, ptr + w, i - w);
+				w = i;
+			}
+			write(f, ret, 1);
+		}
+	}
+	if (w < nb)
+		write(f, ptr + w, nb - w);
+	return nb;
+}
+
 int
 read(void *handle, void *ptr, int nb)
 {
@@ -130,6 +149,29 @@
     return args.phandle;
 }
 
+void *
+claim(unsigned int virt, unsigned int size, unsigned int align)
+{
+    struct prom_args {
+	char *service;
+	int nargs;
+	int nret;
+	unsigned int virt;
+	unsigned int size;
+	unsigned int align;
+	void *ret;
+    } args;
+
+    args.service = "claim";
+    args.nargs = 3;
+    args.nret = 1;
+    args.virt = virt;
+    args.size = size;
+    args.align = align;
+    (*prom)(&args);
+    return args.ret;
+}
+
 int
 getprop(void *phandle, const char *name, void *buf, int buflen)
 {
@@ -161,9 +203,7 @@
 {
     char ch = c;
 
-    if (c == '\n')
-	putc('\r', f);
-    return write(f, &ch, 1) == 1? c: -1;
+    return writestring(f, &ch, 1) == 1? c: -1;
 }
 
 int
@@ -177,7 +217,7 @@
 {
     int n = strlen(str);
 
-    return write(f, str, n) == n? 0: -1;
+    return writestring(f, str, n) == n? 0: -1;
 }
 
 int
@@ -190,7 +230,7 @@
 	case 1:
 	    return ch;
 	case -1:
-	    printk("read(stdin) returned -1\r\n");
+	    printk("read(stdin) returned -1\n");
 	    return -1;
 	}
     }
@@ -264,7 +304,7 @@
 	va_start(args, fmt);
 	n = vsprintf(sprint_buf, fmt, args);
 	va_end(args);
-	write(stdout, sprint_buf, n);
+	writestring(stdout, sprint_buf, n);
 }
 
 int
@@ -276,6 +316,6 @@
 	va_start(args, fmt);
 	n = vsprintf(sprint_buf, fmt, args);
 	va_end(args);
-	write(stdout, sprint_buf, n);
+	writestring(stdout, sprint_buf, n);
 	return n;
 }
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/common_defconfig linux/arch/ppc/common_defconfig
--- v2.3.29/linux/arch/ppc/common_defconfig	Sun Nov  7 16:37:34 1999
+++ linux/arch/ppc/common_defconfig	Wed Dec 31 16:00:00 1969
@@ -1,578 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-
-#
-# Platform support
-#
-CONFIG_PPC=y
-CONFIG_6xx=y
-# CONFIG_PPC64 is not set
-# CONFIG_82xx is not set
-# CONFIG_8xx is not set
-# CONFIG_PMAC is not set
-# CONFIG_PREP is not set
-# CONFIG_CHRP is not set
-CONFIG_ALL_PPC=y
-# CONFIG_GEMINI is not set
-# CONFIG_APUS is not set
-# CONFIG_SMP is not set
-CONFIG_6xx=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
-
-#
-# General setup
-#
-CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_SYSCTL=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_KERNEL_ELF=y
-# CONFIG_BINFMT_MISC is not set
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
-# CONFIG_PARPORT is not set
-CONFIG_VGA_CONSOLE=y
-CONFIG_FB=y
-CONFIG_FB_COMPAT_XPMAC=y
-CONFIG_PMAC_PBOOK=y
-CONFIG_MAC_FLOPPY=y
-CONFIG_MAC_SERIAL=y
-CONFIG_ADB=y
-CONFIG_ADB_CUDA=y
-CONFIG_ADB_MACIO=y
-CONFIG_ADB_PMU=y
-CONFIG_ADB_KEYBOARD=y
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_TOTALMP is not set
-CONFIG_BOOTX_TEXT=y
-# CONFIG_MOTOROLA_HOTSWAP is not set
-# CONFIG_CMDLINE_BOOL is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_FD=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_BLK_DEV_SL82C105=y
-CONFIG_BLK_DEV_IDE_PMAC=y
-CONFIG_BLK_DEV_IDEDMA_PMAC=y
-CONFIG_IDEDMA_PMAC_AUTO=y
-CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_BLK_CPQ_DA is not set
-
-#
-# Additional Block Devices
-#
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_MD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_PARIDE_PARPORT=y
-# CONFIG_PARIDE is not set
-CONFIG_BLK_DEV_IDE_MODES=y
-# CONFIG_BLK_DEV_HD 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 is not set
-# CONFIG_FILTER is not set
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_IP_ROUTER is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-CONFIG_IP_ALIAS=y
-CONFIG_SYN_COOKIES=y
-
-#
-# (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
-
-#
-#  
-#
-# CONFIG_IPX is not set
-CONFIG_ATALK=m
-# CONFIG_DECNET is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_LLC 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
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# 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=y
-# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
-CONFIG_AIC7XXX_PROC_STATS=y
-CONFIG_AIC7XXX_RESET_DELAY=15
-# CONFIG_SCSI_IPS 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_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_SYM53C416 is not set
-# CONFIG_SCSI_SIM710 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_SEAGATE is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_DEBUG is not set
-CONFIG_SCSI_MESH=y
-CONFIG_SCSI_MESH_SYNC_RATE=5
-CONFIG_SCSI_MAC53C94=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_ETHERTAP is not set
-# CONFIG_NET_SB1000 is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MACE=y
-CONFIG_BMAC=y
-# CONFIG_NCR885E 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_YELLOWFIN is not set
-# CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_DM9102 is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_EISA=y
-CONFIG_PCNET32=y
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_ACENIC is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
-CONFIG_DE4X5=y
-# CONFIG_DEC_ELCP is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEXPRESS_PRO100 is not set
-# CONFIG_LNE390 is not set
-# CONFIG_NE3210 is not set
-# CONFIG_NE2K_PCI 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_ZNET is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_LTPC is not set
-# CONFIG_COPS is not set
-# CONFIG_IPDDP is not set
-CONFIG_PPP=y
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring driver support
-#
-# 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
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Console drivers
-#
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_CLGEN is not set
-# CONFIG_FB_PM2 is not set
-CONFIG_FB_OF=y
-CONFIG_FB_CONTROL=y
-CONFIG_FB_PLATINUM=y
-CONFIG_FB_VALKYRIE=y
-CONFIG_FB_IMSTT=y
-CONFIG_FB_CT65550=y
-# CONFIG_FB_S3TRIO is not set
-# CONFIG_FB_VGA16 is not set
-CONFIG_FB_MATROX=y
-# CONFIG_FB_MATROX_MILLENIUM is not set
-CONFIG_FB_MATROX_MYSTIQUE=y
-CONFIG_FB_MATROX_G100=y
-# CONFIG_FB_MATROX_MULTIHEAD is not set
-CONFIG_FB_ATY=y
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_CFB8=y
-CONFIG_FBCON_CFB16=y
-CONFIG_FBCON_CFB24=y
-CONFIG_FBCON_CFB32=y
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-# CONFIG_FONT_8x8 is not set
-CONFIG_FONT_8x16=y
-CONFIG_FONT_SUN8x16=y
-CONFIG_FONT_SUN12x22=y
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# Mice
-#
-CONFIG_BUSMOUSE=y
-# CONFIG_ATIXL_BUSMOUSE is not set
-# CONFIG_LOGIBUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
-# CONFIG_ADBMOUSE is not set
-CONFIG_MOUSE=y
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_NVRAM=y
-# CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK 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
-
-#
-# USB drivers - not for the faint of heart
-#
-# CONFIG_USB is not set
-
-#
-# Filesystems
-#
-# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-CONFIG_HFS_FS=y
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_BFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFSD=y
-# CONFIG_NFSD_SUN is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MAC_PARTITION=y
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-# 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_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_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
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-CONFIG_DMASOUND=y
-# 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_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-CONFIG_SOUND_OSS=y
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_SGALAXY is not set
-CONFIG_SOUND_CS4232=m
-# 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_SOUND_PSS is not set
-# CONFIG_SOUND_SOFTOSS is not set
-# CONFIG_SOUND_SB 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
-
-#
-# Additional low level sound drivers
-#
-# CONFIG_LOWLEVEL_SOUND is not set
-
-#
-# Kernel hacking
-#
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_KGDB is not set
-CONFIG_XMON=y
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v2.3.29/linux/arch/ppc/config.in	Thu Nov 11 20:11:32 1999
+++ linux/arch/ppc/config.in	Thu Dec  2 14:37:34 1999
@@ -12,35 +12,49 @@
 mainmenu_option next_comment
 comment 'Platform support'
 define_bool CONFIG_PPC y
-choice 'Processor type' \
-	"6xx/7xx		CONFIG_6xx \
-	 630/Power3(64-Bit) 	CONFIG_PPC64 \
-	 82xx		 	CONFIG_82xx \
-	 8xx			CONFIG_8xx" 6xx/7xx
+choice 'Processor Type'	\
+	"6xx/7xx		CONFIG_6xx	\
+	 4xx			CONFIG_4xx	\
+	 630/Power3(64-Bit)	CONFIG_PPC64	\
+	 82xx			CONFIG_82xx	\
+	 8xx			CONFIG_8xx"	6xx/7xx
+
+if [ "$CONFIG_4xx" = "y" ]; then
+    choice 'Machine Type'			\
+	"Oak			CONFIG_OAK 	\
+	 Walnut			CONFIG_WALNUT"	Oak
+fi
 
 if [ "$CONFIG_8xx" = "y" ]; then
-  choice 'Processor Model' \
-  	"821	CONFIG_MPC821 \
-  	 823	CONFIG_MPC823 \
-  	 850	CONFIG_MPC850 \
-  	 855	CONFIG_MPC855 \
-  	 860	CONFIG_MPC860 \
-  	 860T	CONFIG_MPC860T" 860
   define_bool CONFIG_SERIAL_CONSOLE y
-  choice 'Machine Type' \
-	"RPX-Lite	CONFIG_RPXLITE \
-	 RPX-Classic	CONFIG_RPXCLASSIC \
-	 BSE-IP		CONFIG_BSEIP \
-  	 MBX		CONFIG_MBX \
-	 WinCept	CONFIG_WINCEPT" RPX-Lite
-else
-  choice 'Machine Type' \
-	"PowerMac	CONFIG_PMAC \
-	 PReP/MTX	CONFIG_PREP \
-	 CHRP		CONFIG_CHRP \
-	 PowerMac/PReP/CHRP	CONFIG_ALL_PPC \
-	 Gemini		CONFIG_GEMINI \
-  	 APUS           CONFIG_APUS" PowerMac
+
+  choice 'Processor Model'	\
+	"821		CONFIG_MPC821		\
+	 823		CONFIG_MPC823		\
+	 850		CONFIG_MPC850		\
+	 855		CONFIG_MPC855		\
+	 860		CONFIG_MPC860		\
+	 860T		CONFIG_MPC860T"		860
+
+  choice 'Machine Type'		\
+	"RPX-Lite	CONFIG_RPXLITE		\
+	 RPX-Classic	CONFIG_RPXCLASSIC	\
+	 BSE-IP		CONFIG_BSEIP		\
+	 MBX		CONFIG_MBX		\
+	 WinCept	CONFIG_WINCEPT"		RPX-Lite
+fi
+if [ "$CONFIG_6xx" = "y" ]; then
+  choice 'Machine Type'		\
+	"PowerMac	CONFIG_PMAC		\
+	 PReP/MTX	CONFIG_PREP		\
+	 CHRP		CONFIG_CHRP		\
+	 PowerMac/PReP/CHRP	CONFIG_ALL_PPC	\
+	 Gemini		CONFIG_GEMINI		\
+	 APUS		CONFIG_APUS"		PowerMac
+fi
+
+if [ "$CONFIG_PPC64" = "y" ]; then
+  define_bool CONFIG_ALL_PPC y
 fi
 
 bool 'Symmetric multi-processing support' CONFIG_SMP
@@ -52,12 +66,8 @@
   define_bool CONFIG_MACH_SPECIFIC y
 fi
 
-if [ "$CONFIG_8xx" = "y" ]; then
+if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then
   bool 'Math emulation' CONFIG_MATH_EMULATION
-else
-  if [ "$CONFIG_PPC64" != "y" ];then
-    define_bool CONFIG_6xx y
-  fi
 fi
 endmenu
 
@@ -75,12 +85,12 @@
 
 if [ "$CONFIG_APUS" = "y" ]; then
   define_bool CONFIG_PCI n
-else
-  if [ "$CONFIG_8xx" = "y" ]; then
+else if [ "$CONFIG_OAK" = "y" ]; then
+  define_bool CONFIG_PCI n
+else if [ "$CONFIG_8xx" = "y" ]; then
     bool 'QSpan PCI' CONFIG_PCI
-  else
+else
     define_bool CONFIG_PCI y
-  fi
 fi
 
 bool 'Networking support' CONFIG_NET
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/configs/apus_defconfig linux/arch/ppc/configs/apus_defconfig
--- v2.3.29/linux/arch/ppc/configs/apus_defconfig	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/configs/apus_defconfig	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,397 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_6xx=y
+# CONFIG_8xx is not set
+CONFIG_PMAC=y
+# CONFIG_PREP is not set
+# CONFIG_CHRP is not set
+# CONFIG_ALL_PPC is not set
+# CONFIG_APUS is not set
+# CONFIG_MBX is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+CONFIG_PCI=y
+# CONFIG_PCI_QUIRKS is not set
+CONFIG_PCI_OLD_PROC=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_BINFMT_JAVA is not set
+# CONFIG_PARPORT is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FB=y
+CONFIG_FB_COMPAT_XPMAC=y
+CONFIG_PMAC_PBOOK=y
+CONFIG_MAC_KEYBOARD=y
+CONFIG_MAC_FLOPPY=y
+CONFIG_MAC_SERIAL=y
+CONFIG_ADBMOUSE=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
+# CONFIG_TOTALMP is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_CMD640 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_IDE_PMAC=y
+CONFIG_BLK_DEV_IDEDMA_PMAC=y
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDEDMA_PMAC_AUTO=y
+# CONFIG_IDE_CHIPSETS is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_NETLINK=y
+# CONFIG_RTNETLINK is not set
+# CONFIG_NETLINK_DEV is not set
+# CONFIG_FIREWALL is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+# CONFIG_SYN_COOKIES is not set
+
+#
+# (it is safe to leave these untouched)
+#
+CONFIG_INET_RARP=y
+CONFIG_IP_NOSR=y
+CONFIG_SKB_LARGE=y
+# CONFIG_IPV6 is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+CONFIG_ATALK=m
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC 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
+# CONFIG_CPU_IS_SLOW is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+CONFIG_SCSI_AIC7XXX=y
+# CONFIG_OVERRIDE_CMDS is not set
+CONFIG_AIC7XXX_PROC_STATS=y
+CONFIG_AIC7XXX_RESET_DELAY=15
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_EATA 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX 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_SEAGATE is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_SCSI_MESH=y
+CONFIG_SCSI_MESH_SYNC_RATE=5
+CONFIG_SCSI_MAC53C94=y
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_ETHERTAP is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MACE=y
+CONFIG_BMAC=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_RTL8139 is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_EISA=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_DE4X5=y
+CONFIG_DEC_ELCP=m
+# CONFIG_DGRS is not set
+# CONFIG_EEXPRESS_PRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_NE3210 is not set
+# CONFIG_NE2K_PCI 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_ZNET is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_DLCI is not set
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_IPDDP is not set
+CONFIG_PPP=y
+
+#
+# CCP compressors for PPP are only built as modules.
+#
+# CONFIG_SLIP is not set
+# CONFIG_NET_RADIO is not set
+# CONFIG_TR is not set
+# CONFIG_SHAPER is not set
+# CONFIG_HOSTESS_SV11 is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_OF=y
+CONFIG_FB_CONTROL=y
+CONFIG_FB_PLATINUM=y
+CONFIG_FB_VALKYRIE=y
+CONFIG_FB_ATY=y
+CONFIG_FB_IMSTT=y
+CONFIG_FB_CT65550=y
+# CONFIG_FB_S3TRIO is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+CONFIG_FONT_SUN8x16=y
+CONFIG_FONT_SUN12x22=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=m
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_VIDEO_DEV is not set
+CONFIG_NVRAM=y
+# CONFIG_JOYSTICK is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_EXT2_FS=y
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=m
+CONFIG_PROC_FS=y
+CONFIG_NFS_FS=y
+CONFIG_NFSD=y
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_CODA_FS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_AFFS_FS is not set
+CONFIG_HFS_FS=y
+# CONFIG_ROMFS_FS is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_UFS_FS is not set
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SMD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_CODEPAGE_437=y
+# 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_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_KOI8_R is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+CONFIG_DMASOUND=y
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_OSS is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/configs/chrp_defconfig linux/arch/ppc/configs/chrp_defconfig
--- v2.3.29/linux/arch/ppc/configs/chrp_defconfig	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/configs/chrp_defconfig	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,319 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_6xx=y
+# CONFIG_8xx is not set
+# CONFIG_PMAC is not set
+# CONFIG_PREP is not set
+CONFIG_CHRP=y
+# CONFIG_ALL_PPC is not set
+# CONFIG_APUS is not set
+# CONFIG_MBX is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+CONFIG_PCI=y
+# CONFIG_PCI_QUIRKS is not set
+CONFIG_PCI_OLD_PROC=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_BINFMT_JAVA is not set
+# CONFIG_PARPORT is not set
+CONFIG_FB=y
+CONFIG_FB_COMPAT_XPMAC=y
+# CONFIG_PMAC_PBOOK is not set
+CONFIG_MAC_KEYBOARD=y
+# CONFIG_MAC_FLOPPY is not set
+# CONFIG_MAC_SERIAL is not set
+# CONFIG_ADBMOUSE is not set
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
+# CONFIG_TOTALMP is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+CONFIG_BLK_DEV_IDE=y
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI is not set
+CONFIG_BLK_DEV_SL82C105=y
+# CONFIG_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_FIREWALL is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_RARP=y
+CONFIG_IP_NOSR=y
+CONFIG_SKB_LARGE=y
+# CONFIG_IPV6 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC 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
+# CONFIG_CPU_IS_SLOW is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_CHR_DEV_SG=y
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_7000FASST 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_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_EATA 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+CONFIG_SCSI_NCR53C8XX=y
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4
+CONFIG_SCSI_NCR53C8XX_SYNC=5
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+# CONFIG_SCSI_NCR53C8XX_IOMAPPED 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_SEAGATE is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_SCSI_MESH=y
+CONFIG_SCSI_MESH_SYNC_RATE=10
+CONFIG_SCSI_MAC53C94=y
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC 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_RTL8139 is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_EISA=y
+# CONFIG_PCNET32 is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_DE4X5 is not set
+CONFIG_DEC_ELCP=y
+# CONFIG_DGRS is not set
+# CONFIG_EEXPRESS_PRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_TLAN is not set
+# CONFIG_ES3210 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_ZNET is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI is not set
+# CONFIG_DLCI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_RADIO is not set
+# CONFIG_TR is not set
+# CONFIG_SHAPER is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_OF=y
+# CONFIG_FB_CONTROL is not set
+# CONFIG_FB_PLATINUM is not set
+# CONFIG_FB_VALKYRIE is not set
+CONFIG_FB_ATY=y
+CONFIG_FB_IMSTT=y
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_S3TRIO is not set
+CONFIG_FB_VGA=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+CONFIG_FBCON_VGA=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_MOUSE is not set
+# CONFIG_UMISC is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_VIDEO_DEV is not set
+CONFIG_NVRAM=y
+# CONFIG_JOYSTICK is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_EXT2_FS=y
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET 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_PROC_FS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_CODA_FS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_AFFS_FS is not set
+CONFIG_HFS_FS=y
+# CONFIG_ROMFS_FS is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_ADFS_FS is not set
+CONFIG_MAC_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_OSS is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/configs/common_defconfig linux/arch/ppc/configs/common_defconfig
--- v2.3.29/linux/arch/ppc/configs/common_defconfig	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/configs/common_defconfig	Thu Dec  2 14:37:34 1999
@@ -0,0 +1,587 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_6xx=y
+# CONFIG_4xx is not set
+# CONFIG_PPC64 is not set
+# CONFIG_82xx is not set
+# CONFIG_8xx is not set
+# CONFIG_PMAC is not set
+# CONFIG_PREP is not set
+# CONFIG_CHRP is not set
+CONFIG_ALL_PPC=y
+# CONFIG_GEMINI is not set
+# CONFIG_APUS is not set
+# CONFIG_SMP is not set
+# CONFIG_ALTIVEC is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# General setup
+#
+# CONFIG_PCI 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
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+# CONFIG_PARPORT is not set
+CONFIG_VGA_CONSOLE=y
+CONFIG_FB=y
+CONFIG_FB_COMPAT_XPMAC=y
+CONFIG_PMAC_PBOOK=y
+CONFIG_MAC_FLOPPY=y
+CONFIG_MAC_SERIAL=y
+CONFIG_ADB=y
+CONFIG_ADB_CUDA=y
+CONFIG_ADB_MACIO=y
+CONFIG_ADB_PMU=y
+CONFIG_ADB_KEYBOARD=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_TOTALMP is not set
+CONFIG_BOOTX_TEXT=y
+# CONFIG_MOTOROLA_HOTSWAP is not set
+# CONFIG_CMDLINE_BOOL is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI is not set
+CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_IDE_PMAC=y
+CONFIG_BLK_DEV_IDEDMA_PMAC=y
+CONFIG_IDEDMA_PMAC_AUTO=y
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_CPQ_DA is not set
+
+#
+# Additional Block Devices
+#
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_HD 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 is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+CONFIG_SYN_COOKIES=y
+
+#
+# (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
+
+#
+#  
+#
+# CONFIG_IPX is not set
+CONFIG_ATALK=m
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC 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
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# 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=y
+# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
+CONFIG_AIC7XXX_PROC_STATS=y
+CONFIG_AIC7XXX_RESET_DELAY=15
+# CONFIG_SCSI_IPS 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_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_SYM53C416 is not set
+# CONFIG_SCSI_SIM710 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_SEAGATE is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_SCSI_MESH=y
+CONFIG_SCSI_MESH_SYNC_RATE=5
+CONFIG_SCSI_MAC53C94=y
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MACE=y
+CONFIG_BMAC=y
+# CONFIG_NCR885E 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_RTL8139 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_EISA=y
+CONFIG_PCNET32=y
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_DE4X5=y
+# CONFIG_DEC_ELCP is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEXPRESS_PRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_NE3210 is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_SIS900 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_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_FDDI is not set
+# CONFIG_HIPPI is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_IPDDP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring driver support
+#
+# 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
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# 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_OF=y
+CONFIG_FB_CONTROL=y
+CONFIG_FB_PLATINUM=y
+CONFIG_FB_VALKYRIE=y
+CONFIG_FB_IMSTT=y
+CONFIG_FB_CT65550=y
+# CONFIG_FB_S3TRIO is not set
+# CONFIG_FB_VGA16 is not set
+CONFIG_FB_MATROX=y
+CONFIG_FB_MATROX_MILLENIUM=y
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G100=y
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+CONFIG_FB_ATY=y
+CONFIG_FB_ATY128=y
+CONFIG_FB_3DFX=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+CONFIG_FONT_SUN8x16=y
+CONFIG_FONT_SUN12x22=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=m
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# Mice
+#
+CONFIG_BUSMOUSE=y
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_LOGIBUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+# CONFIG_ADBMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_NVRAM=y
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK 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
+
+#
+# Support for USB
+#
+CONFIG_USB=y
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+CONFIG_USB_OHCI=y
+CONFIG_USB_OHCI_DEBUG=y
+# CONFIG_USB_OHCI_HCD is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEBUG_ISOC=y
+CONFIG_USB_PROC=y
+# CONFIG_USB_EZUSB is not set
+
+#
+# USB Devices
+#
+CONFIG_USB_HUB=y
+CONFIG_USB_MOUSE=y
+CONFIG_USB_HP_SCANNER=m
+CONFIG_USB_KBD=y
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_CPIA is not set
+# CONFIG_USB_DC2XX is not set
+CONFIG_USB_SCSI=m
+CONFIG_USB_SCSI_DEBUG=y
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_ADFS_FS 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_EFS_FS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFSD=y
+# CONFIG_NFSD_SUN is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+CONFIG_DMASOUND=y
+# 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_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+CONFIG_SOUND_CS4232=m
+# 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_SOUND_PSS is not set
+# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_SB 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
+
+#
+# Additional low level sound drivers
+#
+# CONFIG_LOWLEVEL_SOUND is not set
+
+#
+# Kernel hacking
+#
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_KGDB is not set
+CONFIG_XMON=y
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/configs/gemini_defconfig linux/arch/ppc/configs/gemini_defconfig
--- v2.3.29/linux/arch/ppc/configs/gemini_defconfig	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/configs/gemini_defconfig	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,409 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_6xx=y
+# CONFIG_4xx is not set
+# CONFIG_PPC64 is not set
+# CONFIG_82xx is not set
+# CONFIG_8xx is not set
+# CONFIG_PMAC is not set
+# CONFIG_PREP is not set
+# CONFIG_CHRP is not set
+# CONFIG_ALL_PPC is not set
+CONFIG_GEMINI=y
+# CONFIG_APUS is not set
+# CONFIG_SMP is not set
+# CONFIG_ALTIVEC is not set
+CONFIG_MACH_SPECIFIC=y
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
+# General setup
+#
+# CONFIG_PCI 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
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+# CONFIG_PARPORT is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_FB is not set
+# CONFIG_PMAC_PBOOK is not set
+# CONFIG_MAC_FLOPPY is not set
+# CONFIG_MAC_SERIAL is not set
+# CONFIG_ADB is not set
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_TOTALMP is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_MOTOROLA_HOTSWAP is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_CPQ_DA is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD 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 is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+CONFIG_SYN_COOKIES=y
+
+#
+# (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
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC 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
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# 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_IPS 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_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_SYM53C416 is not set
+# CONFIG_SCSI_SIM710 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_SEAGATE is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_MESH is not set
+# CONFIG_SCSI_MAC53C94 is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER 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_NCR885E=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_YELLOWFIN is not set
+# CONFIG_RTL8139 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_EISA is not set
+# CONFIG_NET_POCKET 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 driver support
+#
+# 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
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+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
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK 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
+
+#
+# Support for USB
+#
+# CONFIG_USB is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_ADFS_FS 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_EFS_FS is not set
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SUNRPC is not set
+# CONFIG_LOCKD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/configs/mbx_defconfig linux/arch/ppc/configs/mbx_defconfig
--- v2.3.29/linux/arch/ppc/configs/mbx_defconfig	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/configs/mbx_defconfig	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,266 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+# CONFIG_6xx is not set
+CONFIG_8xx=y
+# CONFIG_PMAC is not set
+# CONFIG_PREP is not set
+# CONFIG_CHRP is not set
+# CONFIG_ALL_PPC is not set
+# CONFIG_APUS is not set
+CONFIG_MBX=y
+CONFIG_MACH_SPECIFIC=y
+# CONFIG_SMP is not set
+CONFIG_SERIAL_CONSOLE=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_MODULES is not set
+CONFIG_PCI=y
+# CONFIG_PCI_QUIRKS is not set
+CONFIG_PCI_OLD_PROC=y
+CONFIG_NET=y
+# CONFIG_SYSCTL is not set
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_BINFMT_JAVA is not set
+# CONFIG_PARPORT is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_FB is not set
+# CONFIG_PMAC_PBOOK is not set
+# CONFIG_MAC_KEYBOARD is not set
+# CONFIG_MAC_FLOPPY is not set
+# CONFIG_MAC_SERIAL is not set
+# CONFIG_ADBMOUSE is not set
+# CONFIG_BLK_DEV_IDE_PMAC is not set
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
+# CONFIG_TOTALMP is not set
+# CONFIG_BOOTX_TEXT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV_IDE=y
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# 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
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_CMD646 is not set
+CONFIG_BLK_DEV_SL82C105=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_FIREWALL is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_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_SYN_COOKIES is not set
+# CONFIG_INET_RARP is not set
+CONFIG_IP_NOSR=y
+CONFIG_SKB_LARGE=y
+# CONFIG_IPV6 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC 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
+CONFIG_CPU_IS_SLOW=y
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC 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_RTL8139 is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_EISA is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_DLCI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_RADIO is not set
+# CONFIG_TR is not set
+# CONFIG_SHAPER is not set
+# CONFIG_HOSTESS_SV11 is not set
+# CONFIG_COSA is not set
+# CONFIG_RCPCI is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_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_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_SMD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/configs/oak_defconfig linux/arch/ppc/configs/oak_defconfig
--- v2.3.29/linux/arch/ppc/configs/oak_defconfig	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/configs/oak_defconfig	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,296 @@
+#
+# Default configuration for the IBM PowerPC 403 "Oak" evaluation boards.
+#
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_4xx=y
+# CONFIG_6xx is not set
+# CONFIG_PPC64 is not set
+# CONFIG_82xx is not set
+# CONFIG_8xx is not set
+CONFIG_403=y
+# CONFIG_405 is not set
+CONFIG_OAK=y
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+# CONFIG_MATH_EMULATION is not set
+
+#
+# General setup
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+# CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+CONFIG_BINFMT_MISC=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+# CONFIG_PARPORT is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_FB is not set
+# CONFIG_PMAC_PBOOK is not set
+# CONFIG_MAC_FLOPPY is not set
+# CONFIG_MAC_SERIAL is not set
+# CONFIG_ADB is not set
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_TOTALMP is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_MOTOROLA_HOTSWAP 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_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_CPQ_DA is not set
+
+#
+# Additional Block Devices
+#
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+CONFIG_SYN_COOKIES=y
+
+#
+# (it is safe to leave these untouched)
+#
+# CONFIG_SKB_LARGE is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER 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_NCR885E 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_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_EISA is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI 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 driver support
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO 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
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK 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
+
+#
+# USB drivers - not for the faint of heart
+#
+# CONFIG_USB is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_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_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/configs/pmac_defconfig linux/arch/ppc/configs/pmac_defconfig
--- v2.3.29/linux/arch/ppc/configs/pmac_defconfig	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/configs/pmac_defconfig	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,549 @@
+#
+# Automatically generated make config: don't edit
+#
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_6xx=y
+# CONFIG_PPC64 is not set
+# CONFIG_82xx is not set
+# CONFIG_8xx is not set
+CONFIG_PMAC=y
+# CONFIG_PREP is not set
+# CONFIG_CHRP is not set
+# CONFIG_ALL_PPC is not set
+# CONFIG_GEMINI is not set
+# CONFIG_APUS is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+CONFIG_6xx=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+CONFIG_BINFMT_MISC=m
+
+#
+# PCMCIA/Cardbus support
+#
+CONFIG_PCMCIA=m
+CONFIG_CARDBUS=y
+# CONFIG_PARPORT is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FB=y
+CONFIG_FB_COMPAT_XPMAC=y
+CONFIG_PMAC_PBOOK=y
+CONFIG_MAC_FLOPPY=y
+CONFIG_MAC_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
+CONFIG_ADB=y
+CONFIG_ADB_CUDA=y
+CONFIG_ADB_MACIO=y
+CONFIG_ADB_PMU=y
+CONFIG_ADB_KEYBOARD=y
+CONFIG_PROC_DEVICETREE=y
+# CONFIG_TOTALMP is not set
+CONFIG_BOOTX_TEXT=y
+# CONFIG_MOTOROLA_HOTSWAP 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_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_IDEDMA_PCI_AUTO=y
+CONFIG_IDEDMA_NEW_DRIVE_LISTINGS=y
+CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_AEC6210 is not set
+CONFIG_BLK_DEV_CMD646=y
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_PDC202XX is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDE_PMAC=y
+CONFIG_BLK_DEV_IDEDMA_PMAC=y
+CONFIG_IDEDMA_PMAC_AUTO=y
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_CPQ_DA is not set
+
+#
+# Additional Block Devices
+#
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+CONFIG_BLK_DEV_IDE_MODES=y
+# CONFIG_BLK_DEV_HD 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=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+# 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
+
+#
+#  
+#
+# CONFIG_IPX is not set
+CONFIG_ATALK=m
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC 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
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# 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=y
+# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
+CONFIG_AIC7XXX_PROC_STATS=y
+CONFIG_AIC7XXX_RESET_DELAY=15
+# CONFIG_SCSI_IPS 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_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_SYM53C416 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_SEAGATE is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_SCSI_MESH=y
+CONFIG_SCSI_MESH_SYNC_RATE=5
+CONFIG_SCSI_MAC53C94=y
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_ETHERTAP is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MACE=y
+CONFIG_BMAC=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_YELLOWFIN is not set
+# CONFIG_RTL8139 is not set
+# CONFIG_SIS900 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_EISA=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ACENIC is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_DE4X5=y
+# CONFIG_DEC_ELCP is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEXPRESS_PRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_NE3210 is not set
+# CONFIG_NE2K_PCI 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_ZNET is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_IPDDP is not set
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring driver support
+#
+# 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
+
+#
+# PCMCIA network devices
+#
+# CONFIG_PCMCIA_PCNET is not set
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_RAYCS is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO 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
+#
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+CONFIG_FB_OF=y
+CONFIG_FB_CONTROL=y
+CONFIG_FB_PLATINUM=y
+CONFIG_FB_VALKYRIE=y
+CONFIG_FB_IMSTT=y
+CONFIG_FB_CT65550=y
+# CONFIG_FB_S3TRIO is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_MATROX is not set
+CONFIG_FB_ATY=y
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+CONFIG_FONT_SUN8x16=y
+CONFIG_FONT_SUN12x22=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=m
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+
+#
+# Mice
+#
+CONFIG_BUSMOUSE=y
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_LOGIBUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+CONFIG_ADBMOUSE=y
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_NVRAM=y
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK 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
+
+#
+# USB drivers - not for the faint of heart
+#
+CONFIG_USB=y
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+CONFIG_USB_OHCI=y
+CONFIG_USB_OHCI_DEBUG=y
+# CONFIG_USB_OHCI_HCD is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEBUG_ISOC=y
+CONFIG_USB_PROC=y
+# CONFIG_USB_EZUSB is not set
+
+#
+# USB Devices
+#
+CONFIG_USB_HUB=y
+CONFIG_USB_MOUSE=y
+CONFIG_USB_HP_SCANNER=m
+CONFIG_USB_KBD=y
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_CPIA is not set
+CONFIG_USB_SCSI=m
+CONFIG_USB_SCSI_DEBUG=y
+# CONFIG_USB_USS720 is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_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_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFSD=y
+# CONFIG_NFSD_SUN is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_OSF_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+CONFIG_DMASOUND=y
+# 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_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_OSS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/configs/prep_defconfig linux/arch/ppc/configs/prep_defconfig
--- v2.3.29/linux/arch/ppc/configs/prep_defconfig	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/configs/prep_defconfig	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,361 @@
+#
+# Automatically generated by make menuconfig: don't edit
+#
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_6xx=y
+# CONFIG_8xx is not set
+# CONFIG_PMAC is not set
+CONFIG_PREP=y
+# CONFIG_CHRP is not set
+# CONFIG_ALL_PPC is not set
+# CONFIG_APUS is not set
+# CONFIG_MBX is not set
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+CONFIG_PCI=y
+# CONFIG_PCI_QUIRKS is not set
+CONFIG_PCI_OLD_PROC=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_BINFMT_JAVA is not set
+# CONFIG_PARPORT is not set
+# CONFIG_FB is not set
+CONFIG_VGA_CONSOLE=y
+# CONFIG_PMAC_PBOOK is not set
+# CONFIG_MAC_KEYBOARD is not set
+# CONFIG_MAC_FLOPPY is not set
+# CONFIG_MAC_SERIAL is not set
+# CONFIG_ADBMOUSE is not set
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+CONFIG_BLK_DEV_FD=y
+CONFIG_BLK_DEV_IDE=y
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_CMD640 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_IDE_CHIPSETS is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XD is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_FIREWALL 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_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_RARP is not set
+# CONFIG_IP_NOSR is not set
+CONFIG_SKB_LARGE=y
+# CONFIG_IPV6 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC 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
+# CONFIG_CPU_IS_SLOW is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_SCSI_7000FASST 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_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_EATA 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_NCR53C406A is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+CONFIG_SCSI_NCR53C8XX=y
+CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
+CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4
+CONFIG_SCSI_NCR53C8XX_SYNC=5
+# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
+CONFIG_SCSI_NCR53C8XX_IOMAPPED=y
+# 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_SEAGATE is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_ULTRASTOR is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_MESH is not set
+# CONFIG_SCSI_MAC53C94 is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# CONFIG_NET_VENDOR_3COM is not set
+CONFIG_LANCE=y
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_RTL8139 is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_EISA=y
+CONFIG_PCNET32=y
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_DE4X5=y
+# CONFIG_DEC_ELCP is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEXPRESS_PRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_TLAN is not set
+# CONFIG_ES3210 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_ZNET is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI is not set
+# CONFIG_DLCI is not set
+CONFIG_PPP=m
+# CONFIG_SLIP is not set
+# CONFIG_NET_RADIO is not set
+# CONFIG_TR is not set
+# CONFIG_SHAPER is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console 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_MOUSE=y
+# CONFIG_ATIXL_BUSMOUSE is not set
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MS_BUSMOUSE is not set
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+# CONFIG_UMISC is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_RTC is not set
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_NVRAM is not set
+# CONFIG_JOYSTICK is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_EXT2_FS=y
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_CODA_FS is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+# 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_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_KOI8_R is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_PAS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+CONFIG_SOUND_CS4232=y
+CONFIG_CS4232_BASE=530
+CONFIG_CS4232_IRQ=11
+CONFIG_CS4232_DMA=0
+CONFIG_CS4232_DMA2=3
+CONFIG_CS4232_MPU_BASE=330
+CONFIG_CS4232_MPU_IRQ=9
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_UART6850 is not set
+
+#
+# Additional low level sound drivers
+#
+# CONFIG_LOWLEVEL_SOUND is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/configs/walnut_defconfig linux/arch/ppc/configs/walnut_defconfig
--- v2.3.29/linux/arch/ppc/configs/walnut_defconfig	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/configs/walnut_defconfig	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,296 @@
+#
+# Default configuration for the IBM PowerPC 405GP "Walnut" evaluation board.
+#
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_4xx=y
+# CONFIG_6xx is not set
+# CONFIG_PPC64 is not set
+# CONFIG_82xx is not set
+# CONFIG_8xx is not set
+CONFIG_403=y
+# CONFIG_405 is not set
+CONFIG_OAK=y
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+# CONFIG_MATH_EMULATION is not set
+
+#
+# General setup
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+CONFIG_BINFMT_MISC=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+# CONFIG_PARPORT is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_FB is not set
+# CONFIG_PMAC_PBOOK is not set
+# CONFIG_MAC_FLOPPY is not set
+# CONFIG_MAC_SERIAL is not set
+# CONFIG_ADB is not set
+# CONFIG_PROC_DEVICETREE is not set
+# CONFIG_TOTALMP is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_MOTOROLA_HOTSWAP 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_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_CPQ_DA is not set
+
+#
+# Additional Block Devices
+#
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_PARIDE_PARPORT=y
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+CONFIG_SYN_COOKIES=y
+
+#
+# (it is safe to leave these untouched)
+#
+# CONFIG_SKB_LARGE is not set
+
+#
+#  
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER 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_NCR885E 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_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_EISA is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI 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 driver support
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO 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
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK 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
+
+#
+# USB drivers - not for the faint of heart
+#
+# CONFIG_USB is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_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_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/defconfig linux/arch/ppc/defconfig
--- v2.3.29/linux/arch/ppc/defconfig	Thu Nov 11 20:11:32 1999
+++ linux/arch/ppc/defconfig	Thu Dec  2 14:37:34 1999
@@ -12,6 +12,7 @@
 #
 CONFIG_PPC=y
 CONFIG_6xx=y
+# CONFIG_4xx is not set
 # CONFIG_PPC64 is not set
 # CONFIG_82xx is not set
 # CONFIG_8xx is not set
@@ -22,7 +23,7 @@
 # CONFIG_GEMINI is not set
 # CONFIG_APUS is not set
 # CONFIG_SMP is not set
-CONFIG_6xx=y
+# CONFIG_ALTIVEC is not set
 
 #
 # Loadable module support
@@ -34,11 +35,13 @@
 #
 # General setup
 #
+# CONFIG_PCI 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
@@ -271,9 +274,7 @@
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_YELLOWFIN is not set
 # CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
 # CONFIG_DM9102 is not set
 # CONFIG_AT1700 is not set
 # CONFIG_DEPCA is not set
@@ -281,7 +282,6 @@
 CONFIG_NET_EISA=y
 CONFIG_PCNET32=y
 # CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_ACENIC is not set
 # CONFIG_AC3200 is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
@@ -292,12 +292,20 @@
 # CONFIG_LNE390 is not set
 # CONFIG_NE3210 is not set
 # CONFIG_NE2K_PCI is not set
+# CONFIG_SIS900 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_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_FDDI is not set
 # CONFIG_HIPPI is not set
 
@@ -356,6 +364,7 @@
 #
 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_OF=y
@@ -367,13 +376,13 @@
 # CONFIG_FB_S3TRIO is not set
 # CONFIG_FB_VGA16 is not set
 CONFIG_FB_MATROX=y
-# CONFIG_FB_MATROX_MILLENIUM is not set
+CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
 CONFIG_FB_MATROX_G100=y
 # CONFIG_FB_MATROX_MULTIHEAD is not set
 CONFIG_FB_ATY=y
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_3DFX is not set
+CONFIG_FB_ATY128=y
+CONFIG_FB_3DFX=y
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB8=y
@@ -414,6 +423,10 @@
 # CONFIG_82C710_MOUSE is not set
 # CONFIG_PC110_PAD is not set
 # CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
 # CONFIG_WATCHDOG is not set
 CONFIG_NVRAM=y
 # CONFIG_RTC is not set
@@ -438,9 +451,40 @@
 # CONFIG_DRM is not set
 
 #
-# USB drivers - not for the faint of heart
+# Support for USB
+#
+CONFIG_USB=y
+
+#
+# USB Controllers
 #
-# CONFIG_USB is not set
+# CONFIG_USB_UHCI is not set
+CONFIG_USB_OHCI=y
+CONFIG_USB_OHCI_DEBUG=y
+# CONFIG_USB_OHCI_HCD is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEBUG_ISOC=y
+CONFIG_USB_PROC=y
+# CONFIG_USB_EZUSB is not set
+
+#
+# USB Devices
+#
+CONFIG_USB_HUB=y
+CONFIG_USB_MOUSE=y
+CONFIG_USB_HP_SCANNER=m
+CONFIG_USB_KBD=y
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_CPIA is not set
+# CONFIG_USB_DC2XX is not set
+CONFIG_USB_SCSI=m
+CONFIG_USB_SCSI_DEBUG=y
 
 #
 # Filesystems
@@ -449,11 +493,9 @@
 CONFIG_AUTOFS_FS=y
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
-CONFIG_HFS_FS=y
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
 # CONFIG_EFS_FS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
@@ -466,7 +508,6 @@
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
 CONFIG_EXT2_FS=y
-# CONFIG_BFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
 
@@ -493,39 +534,7 @@
 # CONFIG_UNIXWARE_DISKLABEL is not set
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-# 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_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_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 is not set
 
 #
 # Sound
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/gemini_defconfig linux/arch/ppc/gemini_defconfig
--- v2.3.29/linux/arch/ppc/gemini_defconfig	Sat Oct  9 11:47:50 1999
+++ linux/arch/ppc/gemini_defconfig	Wed Dec 31 16:00:00 1969
@@ -1,407 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-
-#
-# Platform support
-#
-CONFIG_PPC=y
-CONFIG_6xx=y
-# CONFIG_PPC64 is not set
-# CONFIG_82xx is not set
-# CONFIG_8xx is not set
-# CONFIG_MPC821 is not set
-# CONFIG_MPC823 is not set
-# CONFIG_MPC850 is not set
-# CONFIG_MPC855 is not set
-# CONFIG_MPC860 is not set
-# CONFIG_MPC860T is not set
-# CONFIG_RPXLITE is not set
-# CONFIG_RPXCLASSIC is not set
-# CONFIG_BSEIP is not set
-# CONFIG_MBX is not set
-# CONFIG_WINCEPT is not set
-# CONFIG_PMAC is not set
-# CONFIG_PREP is not set
-# CONFIG_CHRP is not set
-# CONFIG_ALL_PPC is not set
-CONFIG_GEMINI=y
-# CONFIG_APUS is not set
-# CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
-CONFIG_6xx=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
-CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_SYSCTL=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_KERNEL_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_PARPORT is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_FB is not set
-# CONFIG_PMAC_PBOOK is not set
-# CONFIG_MAC_FLOPPY is not set
-# CONFIG_MAC_SERIAL is not set
-# CONFIG_ADB is not set
-# CONFIG_PROC_DEVICETREE is not set
-# CONFIG_TOTALMP is not set
-# CONFIG_BOOTX_TEXT is not set
-# CONFIG_MOTOROLA_HOTSWAP is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_IDE is not set
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_CPQ_DA is not set
-
-#
-# Additional Block Devices
-#
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=y
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_HD 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 is not set
-# CONFIG_FILTER is not set
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_IP_ROUTER is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-CONFIG_IP_ALIAS=y
-CONFIG_SYN_COOKIES=y
-
-#
-# (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
-
-#
-#  
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_LLC 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
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-CONFIG_BLK_DEV_SR=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# 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_IPS 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_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_G_NCR5380_PORT is not set
-# CONFIG_SCSI_G_NCR5380_MEM is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_SYM53C416 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_SEAGATE is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_MESH is not set
-# CONFIG_SCSI_MAC53C94 is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_EQUALIZER 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_NCR885E=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_RTL8139 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_ACENIC is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_EISA is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# 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_HOSTESS_SV11 is not set
-# CONFIG_COSA is not set
-# CONFIG_SEALEVEL_4021 is not set
-# CONFIG_DLCI is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO 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
-#
-
-#
-# 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
-
-#
-# Mice
-#
-CONFIG_BUSMOUSE=y
-# CONFIG_ATIXL_BUSMOUSE is not set
-# CONFIG_LOGIBUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
-CONFIG_MOUSE=y
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK 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_FT_NORMAL_DEBUG is not set
-# CONFIG_FT_FULL_DEBUG is not set
-# CONFIG_FT_NO_TRACE is not set
-# CONFIG_FT_NO_TRACE_AT_ALL is not set
-# CONFIG_FT_STD_FDC is not set
-# CONFIG_FT_MACH2 is not set
-# CONFIG_FT_PROBE_FC10 is not set
-# CONFIG_FT_ALT_FDC is not set
-# CONFIG_DRM is not set
-
-#
-# USB drivers - not for the faint of heart
-#
-# CONFIG_USB is not set
-
-#
-# Filesystems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_EFS_FS is not set
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_NFS_FS is not set
-# CONFIG_NFSD is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_LOCKD is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MAC_PARTITION=y
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_NLS is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile
--- v2.3.29/linux/arch/ppc/kernel/Makefile	Sun Nov  7 16:37:34 1999
+++ linux/arch/ppc/kernel/Makefile	Sat Nov 27 15:41:59 1999
@@ -12,7 +12,17 @@
 
 O_TARGET := kernel.o
 OX_OBJS := ppc_ksyms.o setup.o
-KHEAD := head.o
+
+
+ifeq ($(CONFIG_4xx),y)
+  KHEAD := head_4xx.o
+else
+  ifeq ($(CONFIG_8xx),y)
+    KHEAD := head_8xx.o
+  else
+    KHEAD := head.o
+  endif
+endif
 
 ifdef CONFIG_ALL_PPC
 CONFIG_PMAC=y
@@ -47,48 +57,50 @@
 O_OBJS += smp.o
 endif
 
-ifeq ($(CONFIG_8xx),y)
-KHEAD := head_8xx.o
-O_OBJS += m8xx_setup.o ppc8xx_pic.o
-ifndef CONFIG_MATH_EMULATION
-O_OBJS += softemu8xx.o
-endif
-ifdef CONFIG_PCI
-O_OBJS += qspan_pci.c
+ifeq ($(CONFIG_OAK),y)
+  O_OBJS += oak_setup.o
 endif
-ifdef CONFIG_MBX
-O_OBJS += i8259.o
+
+ifeq ($(CONFIG_8xx),y)
+  O_OBJS += m8xx_setup.o ppc8xx_pic.o
+  ifndef CONFIG_MATH_EMULATION
+    O_OBJS += softemu8xx.o
+  endif
+  ifdef CONFIG_PCI
+    O_OBJS += qspan_pci.c
+  endif
+  ifdef CONFIG_MBX
+    O_OBJS += i8259.o
+  endif
 endif
-else
-O_OBJS += chrp_setup.o chrp_pci.o chrp_time.o \
-	  pmac_time.o pmac_pci.o pmac_setup.o \
-	  prom.o open_pic.o feature.o \
-	  i8259.o pmac_pic.o indirect_pci.o \
-	  gemini_pci.o gemini_prom.o gemini_setup.o
 
 ifeq ($(CONFIG_NVRAM),y)
-O_OBJS += pmac_support.o
+  O_OBJS += pmac_nvram.o
 endif
-
-ifeq ($(CONFIG_PREP), y)
-O_OBJS += prep_pci.o prep_setup.o prep_nvram.o prep_time.o residual.o
+ifeq ($(CONFIG_6xx),y)
+  O_OBJS += open_pic.o indirect_pci.o
 endif
-
-ifeq ($(CONFIG_PMAC), y)
+ifeq ($(CONFIG_APUS),y)
+  O_OBJS += apus_setup.o
 endif
-
-ifeq ($(CONFIG_PMAC), y)
+ifeq ($(CONFIG_PMAC),y)
+  O_OBJS += pmac_pic.o pmac_setup.o pmac_time.o feature.o pmac_pci.o prom.o
 endif
-
-ifdef CONFIG_APUS
-O_OBJS += apus_setup.o
+ifeq ($(CONFIG_CHRP),y)
+  O_OBJS += chrp_pci.o pmac_pci.o chrp_setup.o i8259.o \
+	chrp_time.o pmac_time.o prom.o
 endif
+ifeq ($(CONFIG_PREP),y)
+  O_OBJS += prep_pci.o i8259.o prep_setup.o prep_nvram.o prep_time.o residual.o
+endif
+ifeq ($(CONFIG_GEMINI),y)
+  O_OBJS += gemini_prom.o gemini_pci.o gemini_setup.o
 endif
 
 all: $(KHEAD) kernel.o
 
 head.o: head.S ppc_defs.h
-
+head_4xx.o: head_4xx.S ppc_defs.h
 head_8xx.o: head_8xx.S ppc_defs.h
 
 ppc_defs.h: mk_defs.c ppc_defs.head \
@@ -98,7 +110,7 @@
 		$(TOPDIR)/include/asm/ptrace.h
 	$(CC) $(CFLAGS) -S mk_defs.c
 	cp ppc_defs.head ppc_defs.h
-	grep '^#define' mk_defs.s >>ppc_defs.h
+	grep '^#define' mk_defs.s >> ppc_defs.h
 	rm mk_defs.s
 
 find_name : find_name.c
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/align.c linux/arch/ppc/kernel/align.c
--- v2.3.29/linux/arch/ppc/kernel/align.c	Tue Aug 31 17:29:12 1999
+++ linux/arch/ppc/kernel/align.c	Sat Nov 27 23:06:26 1999
@@ -1,9 +1,13 @@
 /*
  * align.c - handle alignment exceptions for the Power PC.
  *
- * Paul Mackerras	August 1996.
- * Copyright (C) 1996 Paul Mackerras	(paulus@cs.anu.edu.au).
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Copyright (c) 1998-1999 TiVo, Inc.
+ *   PowerPC 403GCX modifications.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *   PowerPC 403GCX/405GP modifications.
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <asm/ptrace.h>
@@ -16,6 +20,13 @@
 	unsigned char flags;
 };
 
+#if defined(CONFIG_4xx)
+#define	OPCD(inst)	(((inst) & 0xFC000000) >> 26)
+#define	RS(inst)	(((inst) & 0x03E00000) >> 21)
+#define	RA(inst)	(((inst) & 0x001F0000) >> 16)
+#define	IS_DFORM(code)	((code) >= 32 && (code) <= 47)
+#endif
+
 #define INVALID	{ 0, 0 }
 
 #define LD	1	/* load */
@@ -170,6 +181,9 @@
 fix_alignment(struct pt_regs *regs)
 {
 	int instr, nb, flags;
+#if defined(CONFIG_4xx)
+	int opcode, f1, f2, f3;
+#endif
 	int i, t;
 	int reg, areg;
 	unsigned char *addr;
@@ -180,13 +194,42 @@
 		unsigned char v[8];
 	} data;
 
+#if defined(CONFIG_4xx)
+	/* The 4xx-family processors have no DSISR register,
+	 * so we emulate it.
+	 */
+
+	instr = *((unsigned int *)regs->nip);
+	opcode = OPCD(instr);
+	reg = RS(instr);
+	areg = RA(instr);
+
+	if (IS_DFORM(opcode)) {
+		f1 = 0;
+		f2 = (instr & 0x04000000) >> 26;
+		f3 = (instr & 0x78000000) >> 27;
+	} else {
+		f1 = (instr & 0x00000006) >> 1;
+		f2 = (instr & 0x00000040) >> 6;
+		f3 = (instr & 0x00000780) >> 7;
+	}
+
+	instr = ((f1 << 5) | (f2 << 4) | f3);
+#else
+	reg = (regs->dsisr >> 5) & 0x1f;	/* source/dest register */
+	areg = regs->dsisr & 0x1f;		/* register to update */
 	instr = (regs->dsisr >> 10) & 0x7f;
+#endif
 	nb = aligninfo[instr].len;
 	if (nb == 0)
 		return 0;	/* too hard or invalid instruction bits */
 	flags = aligninfo[instr].flags;
-	addr = (unsigned char *) regs->dar;
-	reg = (regs->dsisr >> 5) & 0x1f;	/* source/dest register */
+
+	/* For the 4xx-family processors, the 'dar' field of the
+	 * pt_regs structure is overloaded and is really from the DEAR.
+	 */
+
+	addr = (unsigned char *)regs->dar;
 
 	/* Verify the address of the operand */
 	if (user_mode(regs)) {
@@ -280,7 +323,6 @@
 	}
 
 	if (flags & U) {
-		areg = regs->dsisr & 0x1f;	/* register to update */
 		regs->gpr[areg] = regs->dar;
 	}
 
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/entry.S linux/arch/ppc/kernel/entry.S
--- v2.3.29/linux/arch/ppc/kernel/entry.S	Thu Nov 11 20:11:32 1999
+++ linux/arch/ppc/kernel/entry.S	Thu Dec  2 14:37:34 1999
@@ -386,13 +386,13 @@
 	mtlr	r0
 	blr
 
-#ifndef CONFIG_8xx
+
 /*
  * PROM code for specific machines follows.  Put it 
  * here so it's easy to add arch-specific sections later.
  * -- Cort
  */
-	
+#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
 /*
  * On CHRP, the Run-Time Abstraction Services (RTAS) have to be
  * called with the MMU off.
@@ -432,4 +432,4 @@
 	mtspr	SRR0,r8
 	mtspr	SRR1,r9
 	rfi			/* return to caller */
-#endif /* CONFIG_8xx */
+#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/gemini_prom.S linux/arch/ppc/kernel/gemini_prom.S
--- v2.3.29/linux/arch/ppc/kernel/gemini_prom.S	Tue Sep  7 12:14:06 1999
+++ linux/arch/ppc/kernel/gemini_prom.S	Sat Nov 27 15:41:59 1999
@@ -23,6 +23,7 @@
  *
  */
 
+_GLOBAL(prom_init)
 _GLOBAL(gemini_prom_init)
 #ifdef __SMP__
 	/* Since the MMU's on, get stuff in rom space that we'll need */
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/gemini_setup.c linux/arch/ppc/kernel/gemini_setup.c
--- v2.3.29/linux/arch/ppc/kernel/gemini_setup.c	Wed Oct 27 16:34:12 1999
+++ linux/arch/ppc/kernel/gemini_setup.c	Thu Dec  2 14:37:34 1999
@@ -36,7 +36,6 @@
 
 void gemini_setup_pci_ptrs(void);
 
-static int l2_printed = 0;
 static unsigned char gemini_switch_map = 0;
 static char *gemini_board_families[] = {
 	"VGM", "VSS", "KGM", "VGR", "KSS"
@@ -178,10 +177,8 @@
 
 	/* take special pains to map the MPIC, since it isn't mapped yet */
 	gemini_openpic_init();
-
 	/* start the L2 */
 	gemini_init_l2();
-
 }
 
 
@@ -219,7 +216,6 @@
 	return clock;
 }
 
-
 #define L2CR_PIPE_LATEWR   (0x01800000)   /* late-write SRAM */
 #define L2CR_L2CTL         (0x00100000)   /* RAM control */
 #define L2CR_INST_DISABLE  (0x00400000)   /* disable for insn's */
@@ -259,18 +255,17 @@
 		   probably always going to be late-write".  --Dan */
 
 		if (reg & 0xc0) {
-			if (!l2_printed) {
-				printk("Enabling 750 L2 cache: %dKb\n", 
-				       (128 << ((reg & 0xc0)>>6)));
-				l2_printed=1;
-			}
-    
+			printk("Enabling 750 L2 cache: %dKb\n", 
+			       (128 << ((reg & 0xc0)>>6)));
 			/* take the size given */
 			cache = (((reg>>6) & 0x3)<<28);
 		}
 		else
+		{
+			printk("Enabling 750 L2 cache: 1M\n");
 			/* default of 1Mb */
 			cache = 0x3<<28;
+		}
  
 		reg &= 0x3;
 
@@ -278,6 +273,7 @@
 		   things.  If found, tune it down to 1:1.5.  -- Dan */
 		if (!reg) {
 
+printk("3\n");
 			speed = gemini_get_clock_speed();
    
 			if (speed >= 300) {
@@ -297,7 +293,10 @@
 		   write-through.  This is fixed in IBM's 3.1 rev (I'm told), but
 		   for now, always make 2.x versions use L2 write-through. --Dan */
 		if (((_get_PVR()>>8) & 0xf) <= 2)
+		{
 			cache |= L2CR_L2WT;
+			printk("L2 cache: Enabling Write-Through due to 750 Errata.\n");
+		}
 #endif
 		cache |= L2CR_PIPE_LATEWR|L2CR_L2CTL|L2CR_INST_DISABLE;
 		_set_L2CR(0);
@@ -332,7 +331,7 @@
 
 	/* gemini has no 8259 */
 	open_pic.irq_offset = 0;
-	for( i=0; i < OPENPIC_VEC_SPURIOUS; i++ ) 
+	for( i=0; i < NR_IRQS; i++ ) 
 		irq_desc[i].ctl = &open_pic;
 	openpic_init(1);
 #ifdef __SMP__
@@ -480,6 +479,39 @@
 	count_period_den = freq / 1000000;
 }
 
+int gemini_get_irq( struct pt_regs *regs )
+{
+        int irq;
+
+        irq = openpic_irq( smp_processor_id() );
+        if (irq == OPENPIC_VEC_SPURIOUS)
+                /*
+                 * Spurious interrupts should never be
+                 * acknowledged
+                 */
+		irq = -1;
+	/*
+	 * I would like to openpic_eoi here but there seem to be timing problems
+	 * between the openpic ack and the openpic eoi.
+	 *   -- Cort
+	 */
+	return irq;
+}
+
+void gemini_post_irq(int irq)
+{
+	/*
+	 * If it's an i8259 irq then we've already done the
+	 * openpic irq.  So we just check to make sure the controller
+	 * is an openpic and if it is then eoi
+	 *
+	 * We do it this way since our irq_desc[irq].ctl can change
+	 * with RTL and no longer be open_pic -- Cort
+	 */
+	if ( irq >= open_pic.irq_offset)
+		openpic_eoi( smp_processor_id() );
+}
+
 
 void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5,
 			unsigned long r6, unsigned long r7)
@@ -506,8 +538,8 @@
 	ppc_md.get_cpuinfo = gemini_get_cpuinfo;
 	ppc_md.irq_cannonicalize = NULL;
 	ppc_md.init_IRQ = gemini_init_IRQ;
-	ppc_md.get_irq = chrp_get_irq;
-	ppc_md.post_irq = chrp_post_irq;
+	ppc_md.get_irq = gemini_get_irq;
+	ppc_md.post_irq = gemini_post_irq;
 	ppc_md.init = NULL;
 
 	ppc_md.restart = gemini_restart;
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
--- v2.3.29/linux/arch/ppc/kernel/head.S	Thu Nov 11 20:11:32 1999
+++ linux/arch/ppc/kernel/head.S	Thu Dec  2 14:37:34 1999
@@ -137,7 +137,7 @@
 #endif	
 /*
  * We have to do any OF calls before we map ourselves to KERNELBASE,
- * because OF may have I/O devices mapped in in that area
+ * because OF may have I/O devices mapped into that area
  * (particularly on CHRP).
  */
 	mr	r31,r3			/* save parameters */
@@ -444,7 +444,9 @@
 	STD_EXCEPTION(0xd00, SingleStep, SingleStepException)
 
 	STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
+#ifdef CONFIG_ALTIVEC	
 	STD_EXCEPTION(0xf20, AltiVec, AltiVecUnavailable)
+#endif /* CONFIG_ALTIVEC */
 
 /*
  * Handle TLB miss for instruction on 603/603e.
@@ -1166,7 +1168,6 @@
 	mtspr	SRR0,r3
 	mtspr	SRR1,r4
 	rfi
-
 #endif /* CONFIG_SMP */
 
 /*
@@ -1351,6 +1352,42 @@
 	SYNC
 	blr
 
+/* 
+ * An undocumented "feature" of 604e requires that the v bit
+ * be cleared before changing BAT values.
+ *
+ * Also, newer IBM firmware does not clear bat3 and 4 so
+ * this makes sure it's done.
+ *  -- 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 */
+	cmpwi	r9, 1
+	beq	1f
+	
+	mtspr	DBAT0U,r20
+	mtspr	DBAT0L,r20	
+	mtspr	DBAT1U,r20
+	mtspr	DBAT1L,r20
+	mtspr	DBAT2U,r20
+	mtspr	DBAT2L,r20	
+	mtspr	DBAT3U,r20
+	mtspr	DBAT3L,r20
+1:	
+	mtspr	IBAT0U,r20
+	mtspr	IBAT0L,r20
+	mtspr	IBAT1U,r20
+	mtspr	IBAT1L,r20
+	mtspr	IBAT2U,r20
+	mtspr	IBAT2L,r20
+	mtspr	IBAT3U,r20
+	mtspr	IBAT3L,r20
+#endif /* !defined(CONFIG_GEMINI) */
+	blr
+
 /*
  * We put a few things here that have to be page-aligned.
  * This stuff goes at the beginning of the data segment,
@@ -1374,45 +1411,3 @@
 	.globl	cmd_line
 cmd_line:
 	.space	512
-	
-/* 
- * An undocumented "feature" of 604e requires that the v bit
- * be cleared before changing BAT values.
- *
- * Also, newer IBM firmware does not clear bat3 and 4 so
- * this makes sure it's done.
- *  -- Cort 
- */
-clear_bats:
-	mfmsr	r20
-	andi.	r19,r20,MSR_DR
-	beqlr
-	
-	li	r20,0
-	
-	mtspr	DBAT0U,r20
-	mtspr	DBAT0L,r20
-	mtspr	IBAT0U,r20
-	mtspr	IBAT0L,r20
-	sync
-	isync
-	
-	mtspr	DBAT1U,r20
-	mtspr	DBAT1L,r20
-	mtspr	IBAT1U,r20
-	mtspr	IBAT1L,r20
-	sync
-	isync	
-
-	mtspr	DBAT2U,r20
-	mtspr	DBAT2L,r20
-	mtspr	IBAT2U,r20
-	mtspr	IBAT2L,r20
-	
-	mtspr	DBAT3U,r20
-	mtspr	DBAT3L,r20
-	mtspr	IBAT3U,r20
-	mtspr	IBAT3L,r20
-	
-	blr
-
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/head_4xx.S linux/arch/ppc/kernel/head_4xx.S
--- v2.3.29/linux/arch/ppc/kernel/head_4xx.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/head_4xx.S	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,600 @@
+/*
+ *    Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
+ *      Initial PowerPC version.
+ *    Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
+ *      Rewritten for PReP
+ *    Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ *      Low-level exception handers, MMU support, and rewrite.
+ *    Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
+ *      PowerPC 8xx modifications.
+ *    Copyright (c) 1998-1999 TiVo, Inc.
+ *      PowerPC 403GCX modifications.
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *      PowerPC 403GCX/405GP modifications.
+ *
+ *    Module name: head_4xx.S
+ *
+ *    Description:
+ *      Kernel execution entry point code.
+ *
+ *    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 <linux/config.h>
+
+#include <asm/processor.h>
+#include <asm/4xx.h>
+#include <asm/403gcx.h>
+#include <asm/405gp.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+
+#include "ppc_asm.h"
+
+
+/* Preprocessor Defines */
+
+#define	STND_EXC	0
+#define	CRIT_EXC	1
+
+###
+### Check to make sure the right processor has been defined.
+###
+
+#if !defined(CONFIG_4xx)
+#error "This file is only appropriate for kernels supporting the PPC4xx."
+#endif
+
+###
+### Execution entry point.
+###
+
+###
+### As with the other PowerPC ports, it is expected that when code
+### execution begins here, the following registers contain valid, yet
+### optional, information:
+###
+###   r3 - ???
+###   r4 - Starting address of the init RAM disk
+###   r5 - Ending address of the init RAM disk
+###   r6 - Start of kernel command line string (e.g. "mem=96m")
+###   r7 - End of kernel command line string
+### 
+	
+	.text
+_GLOBAL(_stext)
+_GLOBAL(_start)
+	## Save residual data, init RAM disk, and command line parameters
+	
+	mr	r31,r3
+	mr	r30,r4
+	mr	r29,r5
+	mr	r28,r6
+	mr	r27,r7
+
+	## Set the ID for this CPU
+
+	li	r24,0
+
+	## Establish exception vector base
+	
+	lis	r0,KERNELBASE@h
+	mtspr	SPRN_EVPR,r0
+
+	## Jump to the main PowerPC kernel start-up code
+	
+1:	lis	r7,start_here@ha
+	addi	r7,r7,start_here@l
+	mtlr	r7
+	blr
+
+###
+### Exception vector entry code. This code runs with address translation
+### turned off (i.e. using physical addresses). We assume SPRG3 has the
+### physical address of the current task thread_struct.
+### 
+
+	## Common exception code for all exception types.
+
+#define COMMON_PROLOG							     \
+0:	mtspr	SPRN_SPRG0,r20;		/* We need r20, move it to SPRG0   */\
+	mtspr	SPRN_SPRG1,r21;		/* We need r21, move it to SPRG1   */\
+	mfcr	r20;			/* We need the CR, move it to r20  */\
+	mfspr	r21,SPRN_SPRG2;		/* Exception stack to use	   */\
+	cmpwi	cr0,r21,0;		/* From user mode or RTAS?	   */\
+	bne	1f;			/* Not RTAS, branch		   */\
+	tophys(r21, r1);		/* Convert vka in r1 to pka in r21 */\
+	subi	r21,r21,INT_FRAME_SIZE;	/* Allocate an exception frame	   */\
+1:	stw	r20,_CCR(r21);		/* Save CR on the stack		   */\
+	stw	r22,GPR22(r21);		/* Save r22 on the stack	   */\
+	stw	r23,GPR23(r21);		/* r23 Save on the stack	   */\
+	mfspr	r20,SPRN_SPRG0;		/* Get r20 back out of SPRG0	   */\
+	stw	r20,GPR20(r21);		/* Save r20 on the stack	   */\
+	mfspr	r22,SPRN_SPRG1;		/* Get r21 back out of SPRG0	   */\
+	stw	r22,GPR21(r21);		/* Save r21 on the stack	   */\
+	mflr	r20;							     \
+	stw	r20,_LINK(r21);		/* Save LR on the stack		   */\
+	mfctr	r22;							     \
+	stw	r22,_CTR(r21);		/* Save CTR on the stack	   */\
+	mfspr	r20,XER;						     \
+	stw	r20,_XER(r21);		/* Save XER on the stack	   */
+
+#define	COMMON_EPILOG							     \
+	stw	r0,GPR0(r21);		/* Save r0 on the stack		   */\
+	stw	r1,GPR1(r21);		/* Save r1 on the stack		   */\
+	stw	r2,GPR2(r21);		/* Save r2 on the stack		   */\
+	stw	r1,0(r21);						     \
+	tovirt(r1,r21);			/* Set-up new kernel stack pointer */\
+	SAVE_4GPRS(3, r21);		/* Save r3 through r6 on the stack */
+
+	## Common exception code for standard (non-critical) exceptions.
+
+#define	STND_EXCEPTION_PROLOG						     \
+	COMMON_PROLOG;							     \
+	mfspr	r22,SPRN_SRR0;		/* Faulting instruction address	   */\
+	mfspr	r23,SPRN_SRR1;		/* MSR at the time of fault	   */\
+	COMMON_EPILOG;
+
+	## Common exception code for critical exceptions.
+	
+#define	CRIT_EXCEPTION_PROLOG						     \
+	COMMON_PROLOG;							     \
+	mfspr	r22,SPRN_SRR2;		/* Faulting instruction address	   */\
+	mfspr	r23,SPRN_SRR3;		/* MSR at the time of fault	   */\
+	COMMON_EPILOG;
+
+###
+### Macros for specific exception types
+### 
+
+#define	START_EXCEPTION(n, label)					     \
+	. = n;								     \
+label:
+
+
+#define FINISH_EXCEPTION(func)						     \
+	bl	transfer_to_handler;					     \
+	.long	func;							     \
+	.long	ret_from_except
+	
+		
+#define STND_EXCEPTION(n, label, func)					     \
+	START_EXCEPTION(n, label);					     \
+	STND_EXCEPTION_PROLOG;						     \
+	addi	r3,r1,STACK_FRAME_OVERHEAD;				     \
+	li	r0,STND_EXC;						     \
+	li	r20,MSR_KERNEL;						     \
+	FINISH_EXCEPTION(func)
+
+	
+#define	CRIT_EXCEPTION(n, label, func)					     \
+	START_EXCEPTION(n, label);					     \
+	CRIT_EXCEPTION_PROLOG;						     \
+	addi	r3,r1,STACK_FRAME_OVERHEAD;				     \
+	li	r0,CRIT_EXC;						     \
+	li	r20,MSR_KERNEL;						     \
+	FINISH_EXCEPTION(func)
+
+
+#define	INTR_EXCEPTION(n, label, func)					     \
+	START_EXCEPTION(n, label);					     \
+	STND_EXCEPTION_PROLOG;						     \
+	addi	r3,r1,STACK_FRAME_OVERHEAD;				     \
+	li	r0,STND_EXC;						     \
+	li	r20,MSR_KERNEL;						     \
+	li	r4,0;							     \
+	bl	transfer_to_handler;					     \
+_GLOBAL(do_IRQ_intercept);						     \
+	.long	func;							     \
+	.long	ret_from_except
+
+	
+###
+### Exception vectors.
+### 
+	
+### 0x0100 - Critical Interrupt Exception
+
+	CRIT_EXCEPTION(0x0100,	CriticalInterrupt,	UnknownException)
+
+### 0x0200 - Machine Check Exception
+	
+	CRIT_EXCEPTION(0x0200,	MachineCheck,		MachineCheckException)
+
+### 0x0300 - Data Storage Exception
+
+	START_EXCEPTION(0x0300,	DataAccess)
+	STND_EXCEPTION_PROLOG
+	mfspr	r5,SPRN_ESR		# Grab the ESR, save it, pass as arg3
+	stw	r5,_ESR(r21)
+	mfspr	r4,SPRN_DEAR		# Grab the DEAR, save it, pass as arg2
+	stw	r4,_DEAR(r21)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r0,STND_EXC		# This is a standard exception
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		# Copy EE bit from the saved MSR
+	FINISH_EXCEPTION(do_page_fault)	# do_page_fault(regs, ESR, DEAR)
+	
+### 0x0400 - Instruction Storage Exception
+
+	START_EXCEPTION(0x0400, InstructionAccess)
+	STND_EXCEPTION_PROLOG
+	mr	r4,r22			# Pass SRR0 as arg2
+	mr	r5,r23			# Pass SRR1 as arg3
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r0,STND_EXC		# This is a standard exception
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		# Copy EE bit from the saved MSR
+	FINISH_EXCEPTION(do_page_fault)	# do_page_fault(regs, SRR0, SRR1)
+	
+### 0x0500 - External Interrupt Exception
+
+	INTR_EXCEPTION(0x0500,	HardwareInterrupt,	do_IRQ)
+	
+### 0x0600 - Alignment Exception
+	
+	START_EXCEPTION(0x0600, Alignment)
+	STND_EXCEPTION_PROLOG
+	mfspr	r4,SPRN_DEAR		# Grab the DEAR and save it
+	stw	r4,_DEAR(r21)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r0,STND_EXC		# This is a standard exception
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		# Copy EE bit from the saved MSR
+	FINISH_EXCEPTION(AlignmentException)
+
+### 0x0700 - Program Exception
+
+	START_EXCEPTION(0x0700,	ProgramCheck)
+	STND_EXCEPTION_PROLOG
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r0,STND_EXC		# This is a standard exception
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		# Copy EE bit from the saved MSR
+	FINISH_EXCEPTION(ProgramCheckException)
+	
+	STND_EXCEPTION(0x0800,	Trap_08,		UnknownException)
+	STND_EXCEPTION(0x0900,	Trap_09,		UnknownException)
+	STND_EXCEPTION(0x0A00,	Trap_0A,		UnknownException)
+	STND_EXCEPTION(0x0B00,	Trap_0B,		UnknownException)		
+### 0x0C00 - System Call Exception
+
+	START_EXCEPTION(0x0C00,	SystemCall)
+	STND_EXCEPTION_PROLOG
+	stw	r3,ORIG_GPR3(r21)
+	li	r0,STND_EXC		# This is a standard exception
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		# Copy EE bit from the saved MSR
+	FINISH_EXCEPTION(DoSyscall)
+
+	STND_EXCEPTION(0x0D00,	Trap_0D,		UnknownException)
+	STND_EXCEPTION(0x0E00,	Trap_0E,		UnknownException)
+	STND_EXCEPTION(0x0F00,	Trap_0F,		UnknownException)
+
+#if 0
+### 0x1000 - Programmable Interval Timer (PIT) Exception
+
+	STND_EXCEPTION(0x1000,	PITException,		UnknownException)
+
+### 0x1010 - Fixed Interval Timer (FIT) Exception
+	
+	STND_EXCEPTION(0x1010,	FITException,		UnknownException)
+
+### 0x1020 - Watchdog Timer (WDT) Exception
+
+	CRIT_EXCEPTION(0x1020,	WDTException,		UnknownException)
+#endif
+
+### 0x1100 - Data TLB Miss Exception
+	
+	START_EXCEPTION(0x1100,	DTLBMiss)
+	STND_EXCEPTION_PROLOG
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r0,STND_EXC
+	li	r20,MSR_KERNEL
+	FINISH_EXCEPTION(UnknownException)
+
+### 0x1200 - Instruction TLB Miss Exception
+	
+	START_EXCEPTION(0x1200,	ITLBMiss)
+	STND_EXCEPTION_PROLOG
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r0,STND_EXC
+	li	r20,MSR_KERNEL
+	FINISH_EXCEPTION(UnknownException)	
+
+	STND_EXCEPTION(0x1300,	Trap_13,		UnknownException)
+	STND_EXCEPTION(0x1400,	Trap_14,		UnknownException)
+	STND_EXCEPTION(0x1500,	Trap_15,		UnknownException)
+	STND_EXCEPTION(0x1600,	Trap_16,		UnknownException)
+	STND_EXCEPTION(0x1700,	Trap_17,		UnknownException)
+	STND_EXCEPTION(0x1800,	Trap_18,		UnknownException)
+	STND_EXCEPTION(0x1900,	Trap_19,		UnknownException)
+	STND_EXCEPTION(0x1A00,	Trap_1A,		UnknownException)
+	STND_EXCEPTION(0x1B00,	Trap_1B,		UnknownException)
+	STND_EXCEPTION(0x1C00,	Trap_1C,		UnknownException)
+	STND_EXCEPTION(0x1D00,	Trap_1D,		UnknownException)
+	STND_EXCEPTION(0x1E00,	Trap_1E,		UnknownException)
+	STND_EXCEPTION(0x1F00,	Trap_1F,		UnknownException)
+	
+### 0x2000 - Debug Exception
+
+	CRIT_EXCEPTION(0x2000,	DebugTrap,		UnknownException)
+
+###
+### Other PowerPC processors, namely those derived from the 6xx-series
+### have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
+### However, for the 4xx-series processors these are neither defined nor
+### reserved.
+### 
+
+### 
+### This code finishes saving the registers to the exception frame
+### and jumps to the appropriate handler for the exception, turning
+### on address translation.
+###
+
+_GLOBAL(transfer_to_handler)
+	stw	r22,_NIP(r21)		# Save the faulting IP on the stack
+	stw	r23,_MSR(r21)		# Save the exception MSR on the stack
+	SAVE_GPR(7, r21)		# Save r7 on the stack
+	SAVE_4GPRS(8, r21)		# Save r8 through r11 on the stack
+	SAVE_8GPRS(12, r21)		# Save r12 through r19 on the stack
+	SAVE_8GPRS(24, r21)		# Save r24 through r31 on the stack
+	andi.	r23,r23,MSR_PR		# Is this from user space?
+	mfspr	r23,SPRN_SPRG3		# If from user, fix up THREAD.regs
+	beq	2f			# No, it is from the kernel; branch.
+	addi	r24,r1,STACK_FRAME_OVERHEAD
+	stw	r24,PT_REGS(r23)	# 
+2:	addi	r2,r23,-THREAD		# Set r2 to current thread
+	tovirt(r2,r2)
+	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
+	addi	r24,r2,TASK_STRUCT_SIZE	# Check for kernel stack overflow
+	cmplw	cr0,r1,r2
+	cmplw	cr1,r1,r24
+	crand	cr1,cr1,cr4
+	bgt-	stack_ovf		# If r2 < r1 < r2 + TASK_STRUCT_SIZE
+	lwz	r24,0(r23)		# Virtual address of the handler
+	lwz	r23,4(r23)		# Handler return pointer
+	cmpwi	cr0,r0,STND_EXC		# What type of exception is this?
+	bne	3f			# It is a critical exception...
+
+	## Standard exception jump path
+	
+	mtspr	SPRN_SRR0,r24		# Set up the instruction pointer
+	mtspr	SPRN_SRR1,r20		# Set up the machine state register
+	mtlr	r23			# Set up the return pointer
+	SYNC
+	rfi				# Enable the MMU, jump to the handler
+
+	## Critical exception jump path
+
+3:	mtspr	SPRN_SRR2,r24		# Set up the instruction pointer
+	mtspr	SPRN_SRR3,r20		# Set up the machine state register
+	mtlr	r23			# Set up the return pointer
+	SYNC
+	rfci				# Enable the MMU, jump to the handler
+
+###
+### On kernel stack overlow, load up an initial stack pointer and call
+### StackOverflow(regs), which should NOT return.
+### 
+
+stack_ovf:
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	lis	r1,init_task_union@ha
+	addi	r1,r1,init_task_union@l
+	addi	r1,r1,TASK_UNION_SIZE - STACK_FRAME_OVERHEAD
+	lis	r24,StackOverflow@ha
+	addi	r24,r24,StackOverflow@l
+	li	r20,MSR_KERNEL
+	mtspr	SPRN_SRR0,r24		# Set up the instruction pointer
+	mtspr	SPRN_SRR1,r20		# Set up the machine state register
+	SYNC
+	rfi				# Enable the MMU, jump to StackOverflow
+
+###
+### extern void giveup_altivec(struct task_struct *prev)
+###
+### The PowerPC 4xx family of processors do not have AltiVec capabilities, so
+### this just returns.
+###
+
+_GLOBAL(giveup_altivec)
+	blr
+	
+###
+### extern void giveup_fpu(struct task_struct *prev)
+###
+### The PowerPC 4xx family of processors do not have an FPU, so this just
+### returns.
+###
+
+_GLOBAL(giveup_fpu)
+	blr
+
+###
+### extern void abort(void)
+###
+### At present, this routine just applies a system reset.
+### 
+	
+_GLOBAL(abort)
+	mfspr	r13,SPRN_DBCR
+	ori	r13,r13,DBCR_RST(SYSTEM)@h
+	mtspr	SPRN_DBCR,r13
+
+	
+###
+### This code is jumped-to from the startup code. It copies the kernel
+### image from wherever it happens to be currently running at in physical
+### address space to physical address 0.
+###
+### In general, for a running Linux/PPC system:
+###   Kernel Physical Address (KPA) = 0x00000000
+###   Kernel Virtual Address (KVA)  = 0xC0000000
+###
+ 
+#if 0
+relocate_kernel:
+	lis	r9,0x426f		/* if booted from BootX, don't */
+	addi	r9,r9,0x6f58		/* translate source addr */
+	cmpw	r31,r9			/* (we have to on chrp) */
+	beq	7f
+	rlwinm	r4,r4,0,8,31		/* translate source address */
+	add	r4,r4,r3		/* to region mapped with BATs */
+7:	addis	r9,r26,klimit@ha	/* fetch klimit */
+	lwz	r25,klimit@l(r9)
+	addis	r25,r25,-KERNELBASE@h
+	li	r6,0			/* Destination offset */
+	li	r5,0x4000		/* # bytes of memory to copy */
+	bl	copy_and_flush		/* copy the first 0x4000 bytes */
+	addi	r0,r3,4f@l		/* jump to the address of 4f */
+	mtctr	r0			/* in copy and do the rest. */
+	bctr				/* jump to the copy */
+4:	mr	r5,r25
+	bl	copy_and_flush		/* copy the rest */
+	b	turn_on_mmu
+
+/*
+ * Copy routine used to copy the kernel to start at physical address 0
+ * and flush and invalidate the caches as needed.
+ * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
+ * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
+ */
+copy_and_flush:
+	addi	r5,r5,-4
+	addi	r6,r6,-4
+4:	li	r0,8
+	mtctr	r0
+3:	addi	r6,r6,4			/* copy a cache line */
+	lwzx	r0,r6,r4
+	stwx	r0,r6,r3
+	bdnz	3b
+	dcbst	r6,r3			/* write it to memory */
+	sync
+	icbi	r6,r3			/* flush the icache line */
+	cmplw	0,r6,r5
+	blt	4b
+	isync
+	addi	r5,r5,4
+	addi	r6,r6,4
+	blr
+#endif
+	
+### 
+### This is where the main kernel code starts.
+### 
+
+start_here:
+	## Establish a pointer to the current task
+	
+	lis	r2,init_task_union@h
+	ori	r2,r2,init_task_union@l
+	
+	## Clear out the BSS as per ANSI C requirements
+
+	lis	r7,_end@ha
+	addi	r7,r7,_end@l
+	lis	r8,__bss_start@ha
+	addi	r8,r8,__bss_start@l
+	subf	r7,r8,r7
+	addi	r7,r7,3
+	srwi.	r7,r7,2
+	beq	2f
+	addi	r8,r8,-4
+	mtctr	r7
+	li	r0,0
+3:	stwu	r0,4(r8)
+	bdnz	3b
+
+	## Stack
+	
+2:	addi	r1,r2,TASK_UNION_SIZE
+	li	r0,0
+	stwu	r0,-STACK_FRAME_OVERHEAD(r1)
+
+	## Determine what type of platform this is.
+
+	mr	r3,r31
+	mr	r4,r30
+	mr	r5,r29
+	mr	r6,r28
+	mr	r7,r27
+	bl	identify_machine
+	
+	## Initialize the memory management unit.
+
+	bl	MMU_init
+
+	## Go back to running unmapped so that we can change to our
+	## exception vectors.
+
+	lis	r4,2f@h
+	ori	r4,r4,2f@l
+	tophys(r4,r4)
+	li	r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
+	mtspr	SPRN_SRR0,r4		# Set up the instruction pointer
+	mtspr	SPRN_SRR1,r3		# Set up the machine state register
+	rfi
+
+	## Load up the kernel context
+
+2:	SYNC				# Force all PTE updates to finish
+#	tlbia				# Clear all TLB entries
+#	sync				# Wait for tlbia to finish...
+
+	## Set up for using our exception vectors
+	
+	tophys(r4,r2)			# Pointer to physical current thread
+	addi	r4,r4,THREAD		# The init task thread
+	mtspr	SPRN_SPRG3,r4		# Save it for exceptions later
+	li	r3,0			# 
+	mtspr	SPRN_SPRG2,r3		# 0 implies r1 has kernel stack pointer
+	
+	## Really turn on the MMU and jump into the kernel
+
+        lis     r4,MSR_KERNEL@h
+        ori     r4,r4,MSR_KERNEL@l
+        lis     r3,start_kernel@h
+        ori     r3,r3,start_kernel@l
+        mtspr   SPRN_SRR0,r3		# Set up the instruction pointer
+        mtspr   SPRN_SRR1,r4		# Set up the machine state register
+        rfi				# Enable the MMU, jump to the kernel
+
+_GLOBAL(set_context)
+	mtspr	SPRN_PID,r3
+	tlbia
+	SYNC
+	blr
+
+###
+### We put a few things here that have to be page-aligned. This stuff
+### goes at the beginning of the data segment, which is page-aligned.
+###
+
+	.data
+_GLOBAL(sdata)
+_GLOBAL(empty_zero_page)
+	.space	4096
+_GLOBAL(swapper_pg_dir)
+	.space	4096	
+
+###
+### This space gets a copy of optional info passed to us by the bootstrap
+### which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+###
+
+_GLOBAL(cmd_line)
+	.space	512
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
--- v2.3.29/linux/arch/ppc/kernel/misc.S	Fri Oct 22 13:21:45 1999
+++ linux/arch/ppc/kernel/misc.S	Thu Dec  2 14:37:34 1999
@@ -103,8 +103,7 @@
  * We were about to enable interrupts but we have to simulate
  * some interrupts that were lost by enable_irq first.
  */
-	.globl do_lost_interrupts
-do_lost_interrupts:
+_GLOBAL(do_lost_interrupts)
 	stwu	r1,-16(r1)
 	mflr	r0
 	stw	r0,20(r1)
@@ -405,8 +404,10 @@
  * The *_ns versions don't do byte-swapping.
  */
 _GLOBAL(_insb)
+	cmpw	0,r5,0
 	mtctr	r5
 	subi	r4,r4,1
+	blelr-
 00:	lbz	r5,0(r3)
 	eieio
 	stbu	r5,1(r4)
@@ -414,8 +415,10 @@
 	blr
 
 _GLOBAL(_outsb)
+	cmpw	0,r5,0
 	mtctr	r5
 	subi	r4,r4,1
+	blelr-
 00:	lbzu	r5,1(r4)
 	stb	r5,0(r3)
 	eieio
@@ -423,8 +426,10 @@
 	blr	
 
 _GLOBAL(_insw)
+	cmpw	0,r5,0
 	mtctr	r5
 	subi	r4,r4,2
+	blelr-
 00:	lhbrx	r5,0,r3
 	eieio
 	sthu	r5,2(r4)
@@ -432,8 +437,10 @@
 	blr
 
 _GLOBAL(_outsw)
+	cmpw	0,r5,0
 	mtctr	r5
 	subi	r4,r4,2
+	blelr-
 00:	lhzu	r5,2(r4)
 	eieio
 	sthbrx	r5,0,r3	
@@ -441,8 +448,10 @@
 	blr	
 
 _GLOBAL(_insl)
+	cmpw	0,r5,0
 	mtctr	r5
 	subi	r4,r4,4
+	blelr-
 00:	lwbrx	r5,0,r3
 	eieio
 	stwu	r5,4(r4)
@@ -450,8 +459,10 @@
 	blr
 
 _GLOBAL(_outsl)
+	cmpw	0,r5,0
 	mtctr	r5
 	subi	r4,r4,4
+	blelr-
 00:	lwzu	r5,4(r4)
 	stwbrx	r5,0,r3
 	eieio
@@ -460,8 +471,10 @@
 
 _GLOBAL(ide_insw)
 _GLOBAL(_insw_ns)
+	cmpw	0,r5,0
 	mtctr	r5
 	subi	r4,r4,2
+	blelr-
 00:	lhz	r5,0(r3)
 	eieio
 	sthu	r5,2(r4)
@@ -470,8 +483,10 @@
 
 _GLOBAL(ide_outsw)
 _GLOBAL(_outsw_ns)
+	cmpw	0,r5,0
 	mtctr	r5
 	subi	r4,r4,2
+	blelr-
 00:	lhzu	r5,2(r4)
 	sth	r5,0(r3)
 	eieio
@@ -479,8 +494,10 @@
 	blr	
 
 _GLOBAL(_insl_ns)
+	cmpw	0,r5,0
 	mtctr	r5
 	subi	r4,r4,4
+	blelr-
 00:	lwz	r5,0(r3)
 	eieio
 	stwu	r5,4(r4)
@@ -488,8 +505,10 @@
 	blr
 
 _GLOBAL(_outsl_ns)
+	cmpw	0,r5,0
 	mtctr	r5
 	subi	r4,r4,4
+	blelr-
 00:	lwzu	r5,4(r4)
 	stw	r5,0(r3)
 	eieio
@@ -758,8 +777,19 @@
  * We restore and save the fpscr so the task gets the same result
  * and exceptions as if the cpu had performed the load or store.
  */
+
+#if defined(CONFIG_4xx)
+_GLOBAL(cvt_fd)
+	lfs	0,0(r3)
+	stfd	0,0(r4)
+	blr
+
+_GLOBAL(cvt_df)
+	lfd	0,0(r3)
+	stfs	0,0(r4)
+	blr
+#else
 _GLOBAL(cvt_fd)
-cvt_fd:
 	lfd	0,-4(r5)	/* load up fpscr value */
 	mtfsf	0xff,0
 	lfs	0,0(r3)
@@ -769,7 +799,6 @@
 	blr
 
 _GLOBAL(cvt_df)
-cvt_df:
 	lfd	0,-4(r5)	/* load up fpscr value */
 	mtfsf	0xff,0
 	lfd	0,0(r3)
@@ -777,9 +806,9 @@
 	mffs	0		/* save new fpscr value */
 	stfd	0,-4(r5)
 	blr
+#endif
 
-        .globl  __clear_msr_me
-__clear_msr_me:
+_GLOBAL(__clear_msr_me)
         mfmsr   r0                      /* Get current interrupt state */
         lis     r3,0
         ori     r3,r3,MSR_ME
@@ -843,8 +872,7 @@
 /* Why isn't this a) automatic, b) written in 'C'? */	
 	.data
 	.align 4
-	.globl	sys_call_table
-sys_call_table:
+_GLOBAL(sys_call_table)
 	.long sys_ni_syscall	/* 0  -  old "setup()" system call */
 	.long sys_exit
 	.long sys_fork
@@ -921,7 +949,7 @@
 	.long sys_sigpending
 	.long sys_sethostname
 	.long sys_setrlimit	/* 75 */
-	.long sys_getrlimit
+	.long sys_old_getrlimit
 	.long sys_getrusage
 	.long sys_gettimeofday
 	.long sys_settimeofday
@@ -1039,4 +1067,5 @@
 	.long sys_ni_syscall		/* streams1 */
 	.long sys_ni_syscall		/* streams2 */
 	.long sys_vfork
-	.space (NR_syscalls-183)*4
+	.long sys_getrlimit	/* 190 */
+	.space (NR_syscalls-190)*4
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/mk_defs.c linux/arch/ppc/kernel/mk_defs.c
--- v2.3.29/linux/arch/ppc/kernel/mk_defs.c	Sun Nov  7 16:37:34 1999
+++ linux/arch/ppc/kernel/mk_defs.c	Sat Nov 27 15:41:59 1999
@@ -88,7 +88,9 @@
 	DEFINE(GPR29, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[29]));
 	DEFINE(GPR30, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[30]));
 	DEFINE(GPR31, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[31]));
-	/* Note: these symbols include _ because they overlap with special register names */
+	/* Note: these symbols include _ because they overlap with special
+	 * register names
+	 */
 	DEFINE(_NIP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, nip));
 	DEFINE(_MSR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, msr));
 	DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr));
@@ -97,6 +99,12 @@
 	DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
 	DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
 	DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
+	/* The PowerPC 400-class processors have neither the DAR nor the DSISR
+	 * SPRs. Hence, we overload them to hold the similar DEAR and ESR SPRs
+	 * for such processors.
+	 */
+	DEFINE(_DEAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
+	DEFINE(_ESR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
 	DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3));
 	DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result));
 	DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/oak_setup.c linux/arch/ppc/kernel/oak_setup.c
--- v2.3.29/linux/arch/ppc/kernel/oak_setup.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/oak_setup.c	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,84 @@
+/*
+ *
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Module name: oak_setup.c
+ *
+ *    Description:
+ *      Architecture- / platform-specific boot-time initialization code for
+ *      the IBM PowerPC 403GCX "Oak" evaluation board. Adapted from original
+ *      code by Gary Thomas, Cort Dougan <cort@cs.nmt.edu>, and Dan Malek
+ *      <dmalek@jlc.net>.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/machdep.h>
+#include <asm/page.h>
+
+#include "oak_setup.h"
+
+
+void __init
+oak_init(unsigned long r3, unsigned long r4, unsigned long r5, 
+	 unsigned long r6, unsigned long r7)
+{
+#if 0
+#if defined(CONFIG_BLK_DEV_INITRD)
+	/*
+	 * If the init RAM disk has been configured in, and there's a valid
+	 * starting address for it, set it up.
+	 */
+	if (r4) {
+		initrd_start = r4 + KERNELBASE;
+		initrd_end = r5 + KERNELBASE;
+	}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+	/* Copy the kernel command line arguments to a safe place. */
+
+	if (r6) {
+ 		*(char *)(r7 + KERNELBASE) = 0;
+		strcpy(cmd_line, (char *)(r6 + KERNELBASE));
+	}
+#endif /* 0 */
+
+	ppc_md.setup_arch	 = oak_setup_arch;
+	ppc_md.setup_residual	 = NULL;
+	ppc_md.get_cpuinfo	 = NULL;
+	ppc_md.irq_cannonicalize = NULL;
+	ppc_md.init_IRQ		 = NULL;
+	ppc_md.get_irq		 = NULL;
+	ppc_md.init		 = NULL;
+
+	ppc_md.restart		 = NULL;
+	ppc_md.power_off	 = NULL;
+	ppc_md.halt		 = NULL;
+
+	ppc_md.time_init	 = NULL;
+	ppc_md.set_rtc_time	 = NULL;
+	ppc_md.get_rtc_time	 = NULL;
+	ppc_md.calibrate_decr	 = NULL;
+
+	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;
+
+#if defined(CONFIG_MAGIC_SYSRQ)
+	ppc_md.kbd_sysrq_xlate	 = NULL;
+#endif
+
+	return;
+}
+
+void __init
+oak_setup_arch(void)
+{
+
+}
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/oak_setup.h linux/arch/ppc/kernel/oak_setup.h
--- v2.3.29/linux/arch/ppc/kernel/oak_setup.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/oak_setup.h	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,32 @@
+/*
+ *
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Module name: oak_setup.c
+ *
+ *    Description:
+ *      Architecture- / platform-specific boot-time initialization code for
+ *      the IBM PowerPC 403GCX "Oak" evaluation board. Adapted from original
+ *      code by Gary Thomas, Cort Dougan <cort@cs.nmt.edu>, and Dan Malek
+ *      <dmalek@jlc.net>.
+ *
+ */
+
+#ifndef	__OAK_SETUP_H__
+#define	__OAK_SETUP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void	 oak_init(unsigned long r3,
+			  unsigned long ird_start, unsigned long ird_end,
+			  unsigned long cline_start, unsigned long cline_end);
+extern void	 oak_setup_arch(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OAK_SETUP_H__ */
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/open_pic.c linux/arch/ppc/kernel/open_pic.c
--- v2.3.29/linux/arch/ppc/kernel/open_pic.c	Wed Oct 27 16:34:12 1999
+++ linux/arch/ppc/kernel/open_pic.c	Thu Dec  2 14:37:34 1999
@@ -63,9 +63,15 @@
 #define check_arg_pri(pri) \
     if (pri < 0 || pri >= OPENPIC_NUM_PRI) \
 	printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri);
-#define check_arg_irq(irq) \
+/*
+ * Turned this check off since the IPI's are treated as irqs
+ * but they're above NumSources -- Cort
+ */
+#define check_arg_irq(irq)
+#if 0
     if (irq < 0 || irq >= (NumSources+open_pic.irq_offset)) \
 	printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq);
+#endif
 #define check_arg_cpu(cpu) \
     if (cpu < 0 || cpu >= NumProcessors) \
 	printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu);
@@ -201,15 +207,12 @@
 		/* Initialize IPI interrupts */
 		if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb);
 		for (i = 0; i < OPENPIC_NUM_IPI; i++) {
-			/* Disabled, Priority 0 */
-			openpic_initipi(i, 0, OPENPIC_VEC_IPI+i);
+			/* Disabled, Priority 8 */
+			openpic_initipi(i, 8, OPENPIC_VEC_IPI+i);
 		}
 	    
 		/* Initialize external interrupts */
 		if ( ppc_md.progress ) ppc_md.progress("openpic ext",0x3bc);
-		/* SIOint (8259 cascade) is special */
-		openpic_initirq(0, 8, open_pic.irq_offset, 1, 1);
-		openpic_mapirq(0, 1<<0);
 		for (i = 1; i < NumSources; i++) {
 			/* Enabled, Priority 8 */
 			openpic_initirq(i, 8, open_pic.irq_offset+i, 0,
@@ -223,6 +226,9 @@
 		openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
 		if ( _machine != _MACH_gemini )
 		{
+			/* SIOint (8259 cascade) is special */
+			openpic_initirq(0, 8, open_pic.irq_offset, 1, 1);
+			openpic_mapirq(0, 1<<0);
 			if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT,
 					"82c59 cascade", NULL))
 				printk("Unable to get OpenPIC IRQ 0 for cascade\n");
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/open_pic.h linux/arch/ppc/kernel/open_pic.h
--- v2.3.29/linux/arch/ppc/kernel/open_pic.h	Tue Aug 31 17:29:13 1999
+++ linux/arch/ppc/kernel/open_pic.h	Sat Nov 27 15:41:59 1999
@@ -4,5 +4,6 @@
 extern struct hw_interrupt_type open_pic;
 
 void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
+void openpic_enable_IPI(u_int ipi);
 
 #endif /* _PPC_KERNEL_OPEN_PIC_H */
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/pci.c linux/arch/ppc/kernel/pci.c
--- v2.3.29/linux/arch/ppc/kernel/pci.c	Fri Oct 22 13:21:45 1999
+++ linux/arch/ppc/kernel/pci.c	Sat Nov 27 23:06:26 1999
@@ -8,7 +8,6 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/config.h>
 #include <linux/openpic.h>
 
 #include <asm/processor.h>
@@ -77,6 +76,21 @@
 		ppc_md.pcibios_fixup();
 }
 
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
+{
+	ranges->io_start -= bus->resource[0]->start;
+	ranges->io_end -= bus->resource[0]->start;
+	ranges->mem_start -= bus->resource[1]->start;
+	ranges->mem_end -= bus->resource[1]->start;
+}
+
+unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
+			     unsigned long start, unsigned long size)
+{
+	return start;
+}
+
 static void __init pcibios_claim_resources(struct pci_bus *bus)
 {
 	struct pci_dev *dev;
@@ -117,31 +131,6 @@
 	return str;
 }
 
-#ifndef CONFIG_8xx
-/* Recursively searches any node that is of type PCI-PCI bridge. Without
- * this, the old code would miss children of P2P bridges and hence not
- * fix IRQ's for cards located behind P2P bridges.
- * - Ranjit Deshpande, 01/20/99
- */
-void __init fix_intr(struct device_node *node, struct pci_dev *dev)
-{
-	unsigned int *reg, *class_code;
-
-	for (; node != 0;node = node->sibling) {
-		class_code = (unsigned int *) get_property(node, "class-code", 0);
-		if((*class_code >> 8) == PCI_CLASS_BRIDGE_PCI)
-			fix_intr(node->child, dev);
-		reg = (unsigned int *) get_property(node, "reg", 0);
-		if (reg == 0 || ((reg[0] >> 8) & 0xff) != dev->devfn)
-			continue;
-		/* this is the node, see if it has interrupts */
-		if (node->n_intrs > 0) 
-			dev->irq = node->intrs[0].line;
-		break;
-	}
-}
-#endif
-
 int pcibios_assign_resource(struct pci_dev *pdev, int resource)
 {
 	return 0;
@@ -167,4 +156,9 @@
 {
 	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
 	/* XXX FIXME - update OF device tree node interrupt property */
+}
+
+void __init
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
 }
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/pmac_nvram.c linux/arch/ppc/kernel/pmac_nvram.c
--- v2.3.29/linux/arch/ppc/kernel/pmac_nvram.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/kernel/pmac_nvram.c	Thu Dec  2 14:37:34 1999
@@ -0,0 +1,105 @@
+/*
+ * Miscellaneous procedures for dealing with the PowerMac hardware.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/nvram.h>
+#include <linux/init.h>
+#include <asm/init.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/prom.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+
+/*
+ * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
+ */
+static int nvram_naddrs;
+static volatile unsigned char *nvram_addr;
+static volatile unsigned char *nvram_data;
+static int nvram_mult;
+
+#define NVRAM_SIZE	0x2000	/* 8kB of non-volatile RAM */
+
+__init
+void pmac_nvram_init(void)
+{
+	struct device_node *dp;
+
+	dp = find_devices("nvram");
+	if (dp == NULL) {
+		printk(KERN_ERR "Can't find NVRAM device\n");
+		nvram_naddrs = 0;
+		return;
+	}
+	nvram_naddrs = dp->n_addrs;
+	if (_machine == _MACH_chrp && nvram_naddrs == 1) {
+		nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
+		nvram_mult = 1;
+	} else if (nvram_naddrs == 1) {
+		nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
+		nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE;
+	} else if (nvram_naddrs == 2) {
+		nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size);
+		nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size);
+	} else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
+		nvram_naddrs = -1;
+	} else {
+		printk(KERN_ERR "Don't know how to access NVRAM with %d addresses\n",
+		       nvram_naddrs);
+	}
+}
+
+__openfirmware
+unsigned char nvram_read_byte(int addr)
+{
+	struct adb_request req;
+
+	switch (nvram_naddrs) {
+#ifdef CONFIG_ADB_PMU
+	case -1:
+		if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM,
+				(addr >> 8) & 0xff, addr & 0xff))
+			break;
+		while (!req.complete)
+			pmu_poll();
+		return req.reply[1];
+#endif
+	case 1:
+		return nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult];
+	case 2:
+		*nvram_addr = addr >> 5;
+		eieio();
+		return nvram_data[(addr & 0x1f) << 4];
+	}
+	return 0;
+}
+
+__openfirmware
+void nvram_write_byte(unsigned char val, int addr)
+{
+	struct adb_request req;
+
+	switch (nvram_naddrs) {
+#ifdef CONFIG_ADB_PMU
+	case -1:
+		if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM,
+				(addr >> 8) & 0xff, addr & 0xff, val))
+			break;
+		while (!req.complete)
+			pmu_poll();
+		break;
+#endif
+	case 1:
+		nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult] = val;
+		break;
+	case 2:
+		*nvram_addr = addr >> 5;
+		eieio();
+		nvram_data[(addr & 0x1f) << 4] = val;
+		break;
+	}
+	eieio();
+}
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/pmac_pci.c linux/arch/ppc/kernel/pmac_pci.c
--- v2.3.29/linux/arch/ppc/kernel/pmac_pci.c	Fri Oct 22 13:21:45 1999
+++ linux/arch/ppc/kernel/pmac_pci.c	Thu Dec  2 14:37:34 1999
@@ -21,7 +21,6 @@
 
 #include <asm/init.h>
 #include <asm/io.h>
-#include <asm/pgtable.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
 #include <asm/machdep.h>
@@ -439,6 +438,30 @@
 
 		if (strcmp(dev->name, "bandit") == 0)
 			init_bandit(bp);
+	}
+}
+
+/* Recursively searches any node that is of type PCI-PCI bridge. Without
+ * this, the old code would miss children of P2P bridges and hence not
+ * fix IRQ's for cards located behind P2P bridges.
+ * - Ranjit Deshpande, 01/20/99
+ */
+void __init
+fix_intr(struct device_node *node, struct pci_dev *dev)
+{
+	unsigned int *reg, *class_code;
+
+	for (; node != 0;node = node->sibling) {
+		class_code = (unsigned int *) get_property(node, "class-code", 0);
+		if((*class_code >> 8) == PCI_CLASS_BRIDGE_PCI)
+			fix_intr(node->child, dev);
+		reg = (unsigned int *) get_property(node, "reg", 0);
+		if (reg == 0 || ((reg[0] >> 8) & 0xff) != dev->devfn)
+			continue;
+		/* this is the node, see if it has interrupts */
+		if (node->n_intrs > 0) 
+			dev->irq = node->intrs[0].line;
+		break;
 	}
 }
 
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/pmac_support.c linux/arch/ppc/kernel/pmac_support.c
--- v2.3.29/linux/arch/ppc/kernel/pmac_support.c	Thu Nov 18 20:25:37 1999
+++ linux/arch/ppc/kernel/pmac_support.c	Wed Dec 31 16:00:00 1969
@@ -1,107 +0,0 @@
-/*
- * Miscellaneous procedures for dealing with the PowerMac hardware.
- */
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/reboot.h>
-#include <linux/nvram.h>
-#include <linux/init.h>
-#include <asm/init.h>
-#include <asm/ptrace.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/prom.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-
-/*
- * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
- */
-static int nvram_naddrs;
-static volatile unsigned char *nvram_addr;
-static volatile unsigned char *nvram_data;
-static int nvram_mult;
-
-#define NVRAM_SIZE	0x2000	/* 8kB of non-volatile RAM */
-
-
-__init
-void pmac_nvram_init(void)
-{
-	struct device_node *dp;
-
-	dp = find_devices("nvram");
-	if (dp == NULL) {
-		printk(KERN_ERR "Can't find NVRAM device\n");
-		nvram_naddrs = 0;
-		return;
-	}
-	nvram_naddrs = dp->n_addrs;
-	if (_machine == _MACH_chrp && nvram_naddrs == 1) {
-		nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
-		nvram_mult = 1;
-	} else if (nvram_naddrs == 1) {
-		nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
-		nvram_mult = (dp->addrs[0].size + NVRAM_SIZE - 1) / NVRAM_SIZE;
-	} else if (nvram_naddrs == 2) {
-		nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size);
-		nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size);
-	} else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
-		nvram_naddrs = -1;
-	} else {
-		printk(KERN_ERR "Don't know how to access NVRAM with %d addresses\n",
-		       nvram_naddrs);
-	}
-}
-
-unsigned char nvram_read_byte(int addr)
-{
-	struct adb_request req;
-
-	switch (nvram_naddrs) {
-#ifdef CONFIG_ADB_PMU
-	case -1:
-		if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM,
-				(addr >> 8) & 0xff, addr & 0xff))
-			break;
-		while (!req.complete)
-			pmu_poll();
-		return req.reply[1];
-#endif
-	case 1:
-		return nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult];
-	case 2:
-		*nvram_addr = addr >> 5;
-		eieio();
-		return nvram_data[(addr & 0x1f) << 4];
-	}
-	return 0;
-}
-
-void nvram_write_byte(unsigned char val, int addr)
-{
-	struct adb_request req;
-
-	switch (nvram_naddrs) {
-#ifdef CONFIG_ADB_PMU
-	case -1:
-		if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM,
-				(addr >> 8) & 0xff, addr & 0xff, val))
-			break;
-		while (!req.complete)
-			pmu_poll();
-		break;
-#endif
-	case 1:
-		nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult] = val;
-		break;
-	case 2:
-		*nvram_addr = addr >> 5;
-		eieio();
-		nvram_data[(addr & 0x1f) << 4] = val;
-		break;
-	}
-	eieio();
-}
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/ppc_asm.h linux/arch/ppc/kernel/ppc_asm.h
--- v2.3.29/linux/arch/ppc/kernel/ppc_asm.h	Tue Aug 31 17:29:13 1999
+++ linux/arch/ppc/kernel/ppc_asm.h	Sat Nov 27 15:41:59 1999
@@ -10,6 +10,9 @@
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
  */
+
+#include <linux/config.h>
+
 #include "ppc_asm.tmpl"
 #include "ppc_defs.h"
 
@@ -45,14 +48,20 @@
 	sync; \
 	isync
 
-/* This instruction is not implemented on the PPC 603 or 601 */
-#define tlbia \
-	li	r4,128; \
-	mtctr	r4; \
-	lis	r4,KERNELBASE@h; \
-0:	tlbie	r4; \
-	addi	r4,r4,0x1000; \
+/*
+ * This instruction is not implemented on the PPC 603 or 601; however, on
+ * the 403GCX and 405GP tlbia IS defined and tlbie is not.
+ */
+
+#if !defined(CONFIG_4xx)
+#define tlbia					\
+	li	r4,128;				\
+	mtctr	r4;				\
+	lis	r4,KERNELBASE@h;		\
+0:	tlbie	r4;				\
+	addi	r4,r4,0x1000;			\
 	bdnz	0b
+#endif
 
 /*
  * On APUS (Amiga PowerPC cpu upgrade board), we don't know the
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/ppc_asm.tmpl linux/arch/ppc/kernel/ppc_asm.tmpl
--- v2.3.29/linux/arch/ppc/kernel/ppc_asm.tmpl	Mon Jan 12 15:18:13 1998
+++ linux/arch/ppc/kernel/ppc_asm.tmpl	Sat Nov 27 15:41:59 1999
@@ -1,4 +1,17 @@
-/* Register names */
+/* Condition Register Bit Fields */
+
+#define	cr0	0
+#define	cr1	1
+#define	cr2	2
+#define	cr3	3
+#define	cr4	4
+#define	cr5	5
+#define	cr6	6
+#define	cr7	7
+
+
+/* General Purpose Registers (GPRs) */
+
 #define	r0	0
 #define	r1	1
 #define	r2	2
@@ -31,6 +44,9 @@
 #define	r29	29
 #define	r30	30
 #define	r31	31
+
+
+/* Floating Point Registers (FPRs) */
 
 #define	fr0	0
 #define	fr1	1
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/ppc_htab.c linux/arch/ppc/kernel/ppc_htab.c
--- v2.3.29/linux/arch/ppc/kernel/ppc_htab.c	Sat Oct  9 11:47:50 1999
+++ linux/arch/ppc/kernel/ppc_htab.c	Sun Dec  5 08:42:03 1999
@@ -63,25 +63,6 @@
  */
 struct inode_operations proc_ppc_htab_inode_operations = {
     &ppc_htab_operations,  /* default proc file-ops */
-    NULL,	    /* create	   */
-    NULL,	    /* lookup	   */
-    NULL,	    /* link	   */
-    NULL,	    /* unlink	   */
-    NULL,	    /* symlink	   */
-    NULL,	    /* mkdir	   */
-    NULL,	    /* rmdir	   */
-    NULL,	    /* mknod	   */
-    NULL,	    /* rename	   */
-    NULL,	    /* readlink	   */
-    NULL,	    /* follow_link */
-    NULL,	    /* get_block   */
-    NULL,	    /* readpage	   */
-    NULL,	    /* writepage   */
-    NULL,	    /* flushpage   */
-    NULL,	    /* truncate	   */
-    NULL,	    /* permission  */
-    NULL,	    /* smap        */
-    NULL	    /* revalidate  */
 };
 
 /* these will go into processor.h when I'm done debugging -- Cort */
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c
--- v2.3.29/linux/arch/ppc/kernel/ppc_ksyms.c	Thu Nov 11 20:11:32 1999
+++ linux/arch/ppc/kernel/ppc_ksyms.c	Thu Dec  2 14:37:34 1999
@@ -76,7 +76,7 @@
 EXPORT_SYMBOL(kernel_flag);
 #endif /* __SMP__ */
 
-#ifndef CONFIG_8xx
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
 EXPORT_SYMBOL(isa_io_base);
 EXPORT_SYMBOL(isa_mem_base);
 EXPORT_SYMBOL(pci_dram_offset);
@@ -219,21 +219,22 @@
 EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
 EXPORT_SYMBOL(pmu_enable_irled);
 #endif CONFIG_PMAC_PBOOK
-EXPORT_SYMBOL(abort);
-#ifndef CONFIG_8xx
+#if defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
 EXPORT_SYMBOL(find_devices);
 EXPORT_SYMBOL(find_type_devices);
 EXPORT_SYMBOL(find_compatible_devices);
 EXPORT_SYMBOL(find_path_device);
 EXPORT_SYMBOL(find_phandle);
+EXPORT_SYMBOL(device_is_compatible);
+EXPORT_SYMBOL(machine_is_compatible);
 EXPORT_SYMBOL(get_property);
 EXPORT_SYMBOL(pci_io_base);
 EXPORT_SYMBOL(pci_device_loc);
 EXPORT_SYMBOL(feature_set);
 EXPORT_SYMBOL(feature_clear);
 EXPORT_SYMBOL(feature_test);
-#endif
-#ifdef CONFIG_SCSI
+#endif /* defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC) */
+#if defined(CONFIG_SCSI) && (defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC))
 EXPORT_SYMBOL(note_scsi_host);
 #endif
 EXPORT_SYMBOL(kd_mksound);
@@ -251,17 +252,16 @@
 EXPORT_SYMBOL_NOVERS(memcmp);
 
 EXPORT_SYMBOL(abs);
-#ifndef CONFIG_8xx
-EXPORT_SYMBOL(device_is_compatible);
-#endif
 
 #ifdef CONFIG_VT
 EXPORT_SYMBOL(screen_info);
 #endif
 
 EXPORT_SYMBOL(int_control);
+#if !defined(CONFIG_4xx)
 EXPORT_SYMBOL(timer_interrupt_intercept);
 EXPORT_SYMBOL(timer_interrupt);
+#endif
 extern unsigned long do_IRQ_intercept;
 EXPORT_SYMBOL(do_IRQ_intercept);
 EXPORT_SYMBOL(irq_desc);
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/prep_setup.c linux/arch/ppc/kernel/prep_setup.c
--- v2.3.29/linux/arch/ppc/kernel/prep_setup.c	Thu Nov 11 20:11:32 1999
+++ linux/arch/ppc/kernel/prep_setup.c	Sat Nov 27 15:41:59 1999
@@ -760,22 +760,6 @@
 
 	prep_setup_pci_ptrs();
 
-#ifdef CONFIG_BLK_DEV_INITRD
-	/* take care of initrd if we have one */
-	if ( r4 )
-	{
-		initrd_start = r4 + KERNELBASE;
-		initrd_end = r5 + KERNELBASE;
-	}
-#endif /* CONFIG_BLK_DEV_INITRD */
-
-	/* take care of cmd line */
-	if ( r6  && (((char *) r6) != '\0'))
-	{
-		*(char *)(r7+KERNELBASE) = 0;
-		strcpy(cmd_line, (char *)(r6+KERNELBASE));
-	}
-
 	ppc_md.setup_arch     = prep_setup_arch;
 	ppc_md.setup_residual = prep_setup_residual;
 	ppc_md.get_cpuinfo    = prep_get_cpuinfo;
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- v2.3.29/linux/arch/ppc/kernel/process.c	Thu Nov 11 20:11:32 1999
+++ linux/arch/ppc/kernel/process.c	Sat Nov 27 15:41:59 1999
@@ -204,9 +204,15 @@
 	if ( (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) &&
 	     prev->thread.vrsave )
 		giveup_altivec(prev);
-	if ( (new->last_processor != NO_PROC_ID) &&
+	/*
+	 * The 750 doesn't broadcast invalidates with tlbie's
+	 * so flush every processor switch.
+	 *  -- Cort
+	 */
+	if ( ((_get_PVR()>>16) == 8) &&
+	     (new->last_processor != NO_PROC_ID) &&
 	     (new->last_processor != new->processor) && new->mm )
-		flush_tlb_mm(new->mm);
+	     flush_tlb_mm(new->mm);
 	prev->last_processor = prev->processor;
 	current_set[smp_processor_id()] = new;
 #endif /* __SMP__ */
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/prom.c linux/arch/ppc/kernel/prom.c
--- v2.3.29/linux/arch/ppc/kernel/prom.c	Fri Oct 15 15:25:13 1999
+++ linux/arch/ppc/kernel/prom.c	Sat Nov 27 15:41:59 1999
@@ -283,11 +283,6 @@
 	int l;
 	char *p, *d;
 
-#ifdef CONFIG_GEMINI
-	gemini_prom_init();
-	return;
-#endif /* CONFIG_GEMINI */
-
 	/* check if we're apus, return if we are */
 	if ( r3 == 0x61707573 )
 		return;
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- v2.3.29/linux/arch/ppc/kernel/setup.c	Thu Nov 11 20:11:32 1999
+++ linux/arch/ppc/kernel/setup.c	Thu Dec  2 14:37:34 1999
@@ -30,6 +30,8 @@
 #include <asm/bootx.h>
 #include <asm/machdep.h>
 
+#include "oak_setup.h"
+
 extern void pmac_init(unsigned long r3,
                       unsigned long r4,
                       unsigned long r5,
@@ -67,11 +69,11 @@
                       unsigned long r7);
 
 extern boot_infos_t *boot_infos;
-extern char cmd_line[512];
 char saved_command_line[256];
 unsigned char aux_device_present;
 struct int_control_struct int_control;
 struct ide_machdep_calls ppc_ide_md;
+int parse_bootinfo(void);
 
 unsigned long ISA_DMA_THRESHOLD;
 unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
@@ -84,14 +86,9 @@
 #ifdef CONFIG_MAGIC_SYSRQ
 unsigned long SYSRQ_KEY;
 #endif /* CONFIG_MAGIC_SYSRQ */
-/* For MTX/MVME boards.. with Raven/Falcon Chipset
-      Real close to CHRP, but boot like PReP (via PPCbug)
-      There's probably a nicer way to do this.. --Troy */
-int is_powerplus = 0;
 
 struct machdep_calls ppc_md;
 
-
 /* copy of the residual data */
 #ifndef CONFIG_8xx
 extern unsigned char __res[sizeof(RESIDUAL)];
@@ -196,6 +193,7 @@
 	unsigned long len = 0;
 	unsigned long bogosum = 0;
 	unsigned long i;
+	unsigned short maj, min;
 	
 #ifdef __SMP__
 #define CPU_PRESENT(x) (cpu_callin_map[(x)])
@@ -215,8 +213,8 @@
 		if ( i )
 			len += sprintf(len+buffer,"\n");
 		len += sprintf(len+buffer,"processor\t: %lu\n",i);
-		len += sprintf(len+buffer,"cpu\t\t: ");
-	
+		len += sprintf(len+buffer,"cpu\t\t:  ");
+
 		switch (GET_PVR >> 16)
 		{
 		case 1:
@@ -254,7 +252,7 @@
 			len += sprintf(len+buffer, "860\n");
 			break;
 		default:
-			len += sprintf(len+buffer, "unknown (%lu)\n",
+			len += sprintf(len+buffer, "unknown (%lx)\n",
 				       GET_PVR>>16);
 			break;
 		}
@@ -294,8 +292,7 @@
 			len += ppc_md.setup_residual(buffer + len);
 		}
 		
-		len += sprintf(len+buffer, "revision\t: %ld.%ld\n",
-			       (GET_PVR & 0xff00) >> 8, GET_PVR & 0xff);
+		len += sprintf(len+buffer, "revision\t: %hd.%hd\n", maj, min);
 
 		len += sprintf(buffer+len, "bogomips\t: %lu.%02lu\n",
 			       (CD(loops_per_sec)+2500)/500000,
@@ -333,6 +330,30 @@
 	return len;
 }
 
+#ifndef CONFIG_MACH_SPECIFIC
+void __init
+intuit_machine_type(void)
+{
+	char *model;
+	struct device_node *root;
+			
+	/* ask the OF info if we're a chrp or pmac */
+	root = find_path_device("/");
+	if (root != 0) {
+		/* assume pmac unless proven to be chrp -- Cort */
+		_machine = _MACH_Pmac;
+		model = get_property(root, "device_type", NULL);
+		if (model && !strncmp("chrp", model, 4))
+			_machine = _MACH_chrp;
+		else {
+			model = get_property(root, "model", NULL);
+			if (model && !strncmp(model, "IBM", 3))
+				_machine = _MACH_chrp;
+		}
+	}
+}
+#endif /* CONFIG_MACH_SPECIFIC */
+
 /*
  * Find out what kind of machine we're on and save any data we need
  * from the early boot process (devtree is copied on pmac by prom_init() )
@@ -341,49 +362,31 @@
 identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
 		 unsigned long r6, unsigned long r7)
 {
+	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;
 
-#ifndef CONFIG_8xx
-	if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100);
+	parse_bootinfo();
 	
+	if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100);
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
 #ifndef CONFIG_MACH_SPECIFIC
-	/* boot loader will tell us if we're APUS */
-	if ( r3 == 0x61707573 )
+	/* if we didn't get any bootinfo telling us what we are... */
+	if ( _machine == 0 )
 	{
-		_machine = _MACH_apus;
-		r3 = 0;
-	}
-	/* prep boot loader tells us if we're prep or not */
-	else if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
-	{
-		_machine = _MACH_prep;
-	} else
-	{
-		char *model;
-		struct device_node *root;
-
-		have_of = 1;
-
-		/* prom_init has already been called from __start */
-		if (boot_infos)
-			relocate_nodes();
-
-		/* ask the OF info if we're a chrp or pmac */
-		/* we need to set _machine before calling finish_device_tree */
-		root = find_path_device("/");
-		if (root != 0) {
-			/* assume pmac unless proven to be chrp -- Cort */
-			_machine = _MACH_Pmac;
-			model = get_property(root, "device_type", NULL);
-			if (model && !strncmp("chrp", model, 4))
-				_machine = _MACH_chrp;
-			else {
-				model = get_property(root, "model", NULL);
-				if (model && !strncmp(model, "IBM", 3))
-					_machine = _MACH_chrp;
-			}
+		/* boot loader will tell us if we're APUS */
+		if ( r3 == 0x61707573 )
+		{
+			_machine = _MACH_apus;
+			r3 = 0;
 		}
-
-		finish_device_tree();
+		/* prep boot loader tells us if we're prep or not */
+		else if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
+		{
+			_machine = _MACH_prep;
+		} else
+			have_of = 1;
 	}
 #endif /* CONFIG_MACH_SPECIFIC */
 
@@ -392,7 +395,13 @@
 		/* 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
 		 * address of the command-line parameters.
@@ -444,11 +453,6 @@
 		cmd_line[sizeof(cmd_line) - 1] = 0;
 	}
 
-	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;
-
 	switch (_machine)
 	{
 	case _MACH_Pmac:
@@ -469,7 +473,7 @@
 	case _MACH_gemini:
 		gemini_init(r3, r4, r5, r6, r7);
 		break;
-#endif		
+#endif
 	default:
 		printk("Unknown machine type in identify_machine!\n");
 	}
@@ -478,14 +482,15 @@
 		extern int __map_without_bats;
 		__map_without_bats = 1;
 	}
-#else /* CONFIG_8xx */
-	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;
-
+#else
+#if defined(CONFIG_4xx)
+	oak_init(r3, r4, r5, r6, r7);
+#elif defined(CONFIG_8xx)
         m8xx_init(r3, r4, r5, r6, r7);
-#endif
+#else
+#error "No board type has been defined for identify_machine()!"
+#endif /* CONFIG_4xx */
+#endif /* !CONFIG_4xx && !CONFIG_8xx */
 
 	/* Look for mem= option on command line */
 	if (strstr(cmd_line, "mem=")) {
@@ -513,6 +518,53 @@
 	ppc_md.ppc_machine = _machine;
 
 	if ( ppc_md.progress ) ppc_md.progress("id mach(): done", 0x200);
+
+	return 0;
+}
+
+int parse_bootinfo(void)
+{
+	struct bi_record *rec;
+	extern char _end[];
+
+	rec = (struct bi_record *)PAGE_ALIGN((ulong)_end);
+	if ( rec->tag != BI_FIRST )
+	{
+		/*
+		 * This 0x10000 offset is a terrible hack but it will go away when
+		 * we have the bootloader handle all the relocation and
+		 * prom calls -- Cort
+		 */
+		rec = (struct bi_record *)PAGE_ALIGN((ulong)_end+0x10000);
+		if ( rec->tag != BI_FIRST )
+			return -1;
+	}
+
+	for ( ; rec->tag != BI_LAST ;
+	      rec = (struct bi_record *)((ulong)rec + rec->size) )
+	{
+		ulong *data = rec->data;
+		switch (rec->tag)
+		{
+		case BI_CMD_LINE:
+			memcpy(cmd_line, (void *)data, rec->size);
+			break;
+#ifdef CONFIG_BLK_DEV_INITRD
+		case BI_INITRD:
+			initrd_start = data[0];
+			initrd_end = data[0] + rec->size;
+			break;
+#endif /* CONFIG_BLK_DEV_INITRD */
+#ifndef CONFIG_MACH_SPECIFIC
+		case BI_MACHTYPE:
+			_machine = data[0];
+			have_of = data[1];
+			break;
+#endif /* CONFIG_MACH_SPECIFIC */
+			
+		}
+	}
+
 	return 0;
 }
 
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/smp.c linux/arch/ppc/kernel/smp.c
--- v2.3.29/linux/arch/ppc/kernel/smp.c	Wed Oct 27 16:34:12 1999
+++ linux/arch/ppc/kernel/smp.c	Thu Dec  2 14:37:34 1999
@@ -39,6 +39,7 @@
 #include <asm/gemini.h>
 
 #include "time.h"
+#include "open_pic.h"
 int smp_threads_ready = 0;
 volatile int smp_commenced = 0;
 int smp_num_cpus = 1;
@@ -160,14 +161,15 @@
 void smp_send_reschedule(int cpu)
 {
 	/*
+	 * This is only used if `cpu' is running an idle task,
+	 * so it will reschedule itself anyway...
+	 *
 	 * This isn't the case anymore since the other CPU could be
 	 * sleeping and won't reschedule until the next interrupt (such
 	 * as the timer).
 	 *  -- Cort
 	 */
-	/* This is only used if `cpu' is running an idle task,
-	   so it will reschedule itself anyway... */
-	/*smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);*/
+	smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);
 }
 
 void smp_send_stop(void)
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- v2.3.29/linux/arch/ppc/kernel/traps.c	Thu Nov 11 20:11:32 1999
+++ linux/arch/ppc/kernel/traps.c	Sat Nov 27 15:41:59 1999
@@ -128,6 +128,7 @@
 	_exception(SIGSEGV, regs);	
 }
 
+#if defined(CONFIG_ALTIVEC)
 void
 AltiVecUnavailable(struct pt_regs *regs)
 {
@@ -163,6 +164,7 @@
 	/* enable altivec for the task on return */
 	regs->msr |= MSR_VEC;
 }
+#endif /* CONFIG_ALTIVEC */
 
 void
 UnknownException(struct pt_regs *regs)
@@ -191,6 +193,20 @@
 void
 ProgramCheckException(struct pt_regs *regs)
 {
+#if defined(CONFIG_4xx)
+	unsigned int instr;
+	unsigned int esr = mfspr(SPRN_ESR);
+
+	if (esr & ESR_PTR) {
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+		if (debugger_bpt(regs))
+			return;
+#endif
+		_exception(SIGTRAP, regs);
+	} else {
+		_exception(SIGILL, regs);
+	}
+#else
 	if (regs->msr & 0x100000) {
 		/* IEEE FP exception */
 		_exception(SIGFPE, regs);
@@ -204,6 +220,7 @@
 	} else {
 		_exception(SIGILL, regs);
 	}
+#endif
 }
 
 void
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/lib/checksum.S linux/arch/ppc/lib/checksum.S
--- v2.3.29/linux/arch/ppc/lib/checksum.S	Sun Nov  7 16:37:34 1999
+++ linux/arch/ppc/lib/checksum.S	Thu Dec  2 14:37:34 1999
@@ -24,13 +24,12 @@
  * len is in words and is always >= 5.
  */
 _GLOBAL(ip_fast_csum)
-	cmpi	0,r4,0
-	beq	10f
 	lwz	r0,0(r3)
 	lwzu	r5,4(r3)
-	addi	r4,r4,-2
+	addic.	r4,r4,-2
 	addc	r0,r0,r5
 	mtctr	r4
+	blelr-
 1:	lwzu	r4,4(r3)
 	adde	r0,r0,r4
 	bdnz	1b
@@ -40,8 +39,6 @@
 	not	r3,r3
 	srwi	r3,r3,16
 	blr
-10:	li	r3,0
-	blr	
 
 /*
  * Compute checksum of TCP or UDP pseudo-header:
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/mbx_defconfig linux/arch/ppc/mbx_defconfig
--- v2.3.29/linux/arch/ppc/mbx_defconfig	Fri Oct 22 13:21:45 1999
+++ linux/arch/ppc/mbx_defconfig	Wed Dec 31 16:00:00 1969
@@ -1,266 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-
-#
-# Platform support
-#
-CONFIG_PPC=y
-# CONFIG_6xx is not set
-CONFIG_8xx=y
-# CONFIG_PMAC is not set
-# CONFIG_PREP is not set
-# CONFIG_CHRP is not set
-# CONFIG_ALL_PPC is not set
-# CONFIG_APUS is not set
-CONFIG_MBX=y
-CONFIG_MACH_SPECIFIC=y
-# CONFIG_SMP is not set
-CONFIG_SERIAL_CONSOLE=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_MODULES is not set
-CONFIG_PCI=y
-# CONFIG_PCI_QUIRKS is not set
-CONFIG_PCI_OLD_PROC=y
-CONFIG_NET=y
-# CONFIG_SYSCTL is not set
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_KERNEL_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_BINFMT_JAVA is not set
-# CONFIG_PARPORT is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_FB is not set
-# CONFIG_PMAC_PBOOK is not set
-# CONFIG_MAC_KEYBOARD is not set
-# CONFIG_MAC_FLOPPY is not set
-# CONFIG_MAC_SERIAL is not set
-# CONFIG_ADBMOUSE is not set
-# CONFIG_BLK_DEV_IDE_PMAC is not set
-# CONFIG_PROC_DEVICETREE is not set
-# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
-# CONFIG_TOTALMP is not set
-# CONFIG_BOOTX_TEXT is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-CONFIG_BLK_DEV_IDE=y
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# 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
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_BLK_DEV_CMD646 is not set
-CONFIG_BLK_DEV_SL82C105=y
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=y
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
-# CONFIG_FIREWALL is not set
-# CONFIG_FILTER is not set
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_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_SYN_COOKIES is not set
-# CONFIG_INET_RARP is not set
-CONFIG_IP_NOSR=y
-CONFIG_SKB_LARGE=y
-# CONFIG_IPV6 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_LLC 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
-CONFIG_CPU_IS_SLOW=y
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_NET_ETHERNET=y
-# CONFIG_MACE is not set
-# CONFIG_BMAC 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_RTL8139 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_ACENIC is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_EISA is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_DLCI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_RADIO is not set
-# CONFIG_TR is not set
-# CONFIG_SHAPER is not set
-# CONFIG_HOSTESS_SV11 is not set
-# CONFIG_COSA is not set
-# CONFIG_RCPCI is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Console drivers
-#
-
-#
-# Character devices
-#
-CONFIG_VT=y
-# CONFIG_VT_CONSOLE is not set
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
-# CONFIG_MOUSE is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-
-#
-# Filesystems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_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_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-# CONFIG_NFSD is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MAC_PARTITION is not set
-# CONFIG_SMD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_NLS is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/mm/Makefile linux/arch/ppc/mm/Makefile
--- v2.3.29/linux/arch/ppc/mm/Makefile	Sat Aug 16 09:51:08 1997
+++ linux/arch/ppc/mm/Makefile	Sat Nov 27 15:41:59 1999
@@ -8,6 +8,10 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 O_TARGET := mm.o
-O_OBJS	= fault.o init.o extable.o
+O_OBJS	= fault.o init.o mem_pieces.o extable.o
+
+ifeq ($(CONFIG_4xx),y)
+O_OBJS	+= 4xx_tlb.o
+endif
 
 include $(TOPDIR)/Rules.make
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/mm/fault.c linux/arch/ppc/mm/fault.c
--- v2.3.29/linux/arch/ppc/mm/fault.c	Sat Oct  9 11:47:50 1999
+++ linux/arch/ppc/mm/fault.c	Sat Nov 27 15:41:59 1999
@@ -52,36 +52,36 @@
 void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
 
 /*
- * The error_code parameter is DSISR for a data fault, SRR1 for
- * an instruction fault.
+ * For 600- and 800-family processors, the error_code parameter is DSISR
+ * for a data fault, SRR1 for an instruction fault. For 400-family processors
+ * the error_code parameter is ESR for a data fault, 0 for an instruction
+ * fault.
  */
 void do_page_fault(struct pt_regs *regs, unsigned long address,
 		   unsigned long error_code)
 {
 	struct vm_area_struct * vma;
 	struct mm_struct *mm = current->mm;
+#if defined(CONFIG_4xx)
+	int is_write = error_code & ESR_DST;
+#else
+	int is_write = error_code & 0x02000000;
+#endif /* CONFIG_4xx */
 
-	/*printk("address: %08lx nip:%08lx code: %08lx %s%s%s%s%s%s\n",
-	       address,regs->nip,error_code,
-	       (error_code&0x40000000)?"604 tlb&htab miss ":"",
-	       (error_code&0x20000000)?"603 tlbmiss ":"",
-	       (error_code&0x02000000)?"write ":"",
-	       (error_code&0x08000000)?"prot ":"",
-	       (error_code&0x80000000)?"I/O ":"",
-	       (regs->trap == 0x400)?"instr":"data"
-	       );*/
-	       
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
 	if (debugger_fault_handler && regs->trap == 0x300) {
 		debugger_fault_handler(regs);
 		return;
 	}
+#if !defined(CONFIG_4xx)
 	if (error_code & 0x00400000) {
 		/* DABR match */
 		if (debugger_dabr_match(regs))
 			return;
 	}
-#endif
+#endif /* !CONFIG_4xx */
+#endif /* CONFIG_XMON || CONFIG_KGDB */
+
 	if (in_interrupt()) {
 		static int complained;
 		if (complained < 20) {
@@ -107,12 +107,12 @@
 		goto bad_area;
 
 good_area:
-#ifdef CONFIG_6xx
+#if defined(CONFIG_6xx)
 	if (error_code & 0x95700000)
 		/* an error such as lwarx to I/O controller space,
 		   address matching DABR, eciwx, etc. */
 #endif /* CONFIG_6xx */
-#ifdef CONFIG_8xx
+#if defined(CONFIG_8xx)
         /* The MPC8xx seems to always set 0x80000000, which is
          * "undefined".  Of those that can be set, this is the only
          * one which seems bad.
@@ -124,7 +124,7 @@
 	
 	
 	/* a write */
-	if (error_code & 0x02000000) {
+	if (is_write) {
 		if (!(vma->vm_flags & VM_WRITE))
 			goto bad_area;
 	/* a read */
@@ -135,7 +135,7 @@
 		if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
 			goto bad_area;
 	}
-	if (!handle_mm_fault(current, vma, address, error_code & 0x02000000))
+	if (!handle_mm_fault(current, vma, address, is_write))
 		goto bad_area;
 	up(&mm->mmap_sem);
 	/*
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v2.3.29/linux/arch/ppc/mm/init.c	Tue Nov 23 22:42:20 1999
+++ linux/arch/ppc/mm/init.c	Thu Dec  2 14:37:34 1999
@@ -40,6 +40,7 @@
 #include <linux/blk.h>		/* for initrd_* */
 #endif
 
+#include <asm/pgalloc.h>
 #include <asm/prom.h>
 #include <asm/io.h>
 #include <asm/mmu_context.h>
@@ -56,6 +57,10 @@
 #include <asm/amigahw.h>
 #include <asm/gemini.h>
 
+#include "mem_pieces.h"
+
+#define	PGTOKB(pages)	(((pages) * PAGE_SIZE) >> 10)
+
 int prom_trashed;
 atomic_t next_mmu_context;
 unsigned long *end_of_DRAM;
@@ -71,7 +76,6 @@
 extern char __pmac_begin, __pmac_end;
 extern char __apus_begin, __apus_end;
 extern char __openfirmware_begin, __openfirmware_end;
-char *klimit = _end;
 struct device_node *memory_node;
 unsigned long ioremap_base;
 unsigned long ioremap_bot;
@@ -98,34 +102,13 @@
 extern void die_if_kernel(char *,struct pt_regs *,long);
 extern void show_net_buffers(void);
 
-
-/*
- * The following stuff defines a data structure for representing
- * areas of memory as an array of (address, length) pairs, and
- * procedures for manipulating them.
- */
-#define MAX_MEM_REGIONS	32
-
-struct mem_pieces {
-	int n_regions;
-	struct reg_property regions[MAX_MEM_REGIONS];
-};
 struct mem_pieces phys_mem;
-struct mem_pieces phys_avail;
-
-static void remove_mem_piece(struct mem_pieces *, unsigned, unsigned, int);
-static void set_phys_avail(void);
-void *find_mem_piece(unsigned, unsigned);
-static void print_mem_pieces(struct mem_pieces *);
-#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC)
-static void append_mem_piece(struct mem_pieces *, unsigned, unsigned);
-#endif
 
 extern struct task_struct *current_set[NR_CPUS];
 
 PTE *Hash, *Hash_end;
 unsigned long Hash_size, Hash_mask;
-#ifndef CONFIG_8xx
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
 #ifdef CONFIG_PPC64
 unsigned long long _SDR1;
 #else
@@ -174,12 +157,10 @@
 	return 0;
 }
 
-#else /* CONFIG_8xx */
-
-/* 8xx doesn't have BATs */
+#else /* CONFIG_4xx || CONFIG_8xx */
 #define v_mapped_by_bats(x)	(0UL)
 #define p_mapped_by_bats(x)	(0UL)
-#endif /* CONFIG_8xx */
+#endif /* !CONFIG_4xx && !CONFIG_8xx */
 
 /*
  * this tells the system to map all of ram with the segregs
@@ -343,24 +324,23 @@
 
 void si_meminfo(struct sysinfo *val)
 {
-	int i;
+	int i, c;
 
 	i = max_mapnr;
-	val->totalram = 0;
-	val->sharedram = 0;
+	val->totalram = totalram_pages;
 	val->freeram = nr_free_pages();
 	val->bufferram = atomic_read(&buffermem_pages);
+	val->sharedram = 0;
 	while (i-- > 0)  {
 		if (PageReserved(mem_map+i))
 			continue;
-		val->totalram++;
-		if (!atomic_read(&mem_map[i].count))
-			continue;
-		val->sharedram += atomic_read(&mem_map[i].count) - 1;
-	}
-	val->totalram <<= PAGE_SHIFT;
-	val->sharedram <<= PAGE_SHIFT;
-	return;
+		c = atomic_read(&mem_map[i].count);
+		if (c > 1)
+			val->sharedram += c - 1;
+	}
+	val->totalhigh = 0;
+	val->freehigh = 0;
+	val->mem_unit = PAGE_SIZE;
 }
 
 void *
@@ -422,7 +402,7 @@
 	
 	if (mem_init_done) {
 		struct vm_struct *area;
-		area = get_vm_area(size, VM_ALLOC);
+		area = get_vm_area(size, VM_IOREMAP);
 		if (area == 0)
 			return NULL;
 		v = VMALLOC_VMADDR(area->addr);
@@ -593,195 +573,14 @@
 }
 #endif /* CONFIG_8xx */
 
-/*
- * Set phys_avail to phys_mem less the kernel text/data/bss.
- */
-static void __init set_phys_avail(void)
-{
-	unsigned long kstart, ksize;
-
-	/* we can't call the prom any more at this stage, so
-	   all of memory is available (after klimit) */
-	phys_avail = phys_mem;
-
-	/*
-	 * phys_avail records memory we can use.
-	 * Make sure the kernel text/data/bss is not in it.
-	 */
-	kstart = __pa(_stext);	/* should be 0 */
-	ksize = PAGE_ALIGN(klimit - _stext);
-	remove_mem_piece(&phys_avail, kstart, ksize, 0);
-	remove_mem_piece(&phys_avail, 0, 0x4000, 0);
-
-#ifdef CONFIG_BLK_DEV_INITRD
-	if (initrd_start) {
-		/*
-		 * Remove the initialized ramdisk from the available memory.
-		 */
-		remove_mem_piece(&phys_avail, __pa(initrd_start),
-				 initrd_end - initrd_start, 1);
-	}
-#endif /* CONFIG_BLK_DEV_INITRD */
-}
-
-/*
- * Scan a region for a piece of a given size with the required alignment.
- */
-void __init *find_mem_piece(unsigned size, unsigned align)
-{
-	int i;
-	unsigned a, e;
-	struct mem_pieces *mp = &phys_avail;
-
-	for (i = 0; i < mp->n_regions; ++i) {
-		a = mp->regions[i].address;
-		e = a + mp->regions[i].size;
-		a = (a + align - 1) & -align;
-		if (a + size <= e) {
-			remove_mem_piece(mp, a, size, 1);
-			return __va(a);
-		}
-	}
-	printk("Couldn't find %u bytes at %u alignment\n", size, align);
-	abort();
-	return NULL;
-}
-
-/*
- * Remove some memory from an array of pieces
- */
-static void __init 
-remove_mem_piece(struct mem_pieces *mp, unsigned start, unsigned size,
-		 int must_exist)
-{
-	int i, j;
-	unsigned end, rs, re;
-	struct reg_property *rp;
-
-	end = start + size;
-	for (i = 0, rp = mp->regions; i < mp->n_regions; ++i, ++rp) {
-		if (end > rp->address && start < rp->address + rp->size)
-			break;
-	}
-	if (i >= mp->n_regions) {
-		if (must_exist)
-			printk("remove_mem_piece: [%x,%x) not in any region\n",
-			       start, end);
-		return;
-	}
-	for (; i < mp->n_regions && end > rp->address; ++i, ++rp) {
-		rs = rp->address;
-		re = rs + rp->size;
-		if (must_exist && (start < rs || end > re)) {
-			printk("remove_mem_piece: bad overlap [%x,%x) with",
-			       start, end);
-			print_mem_pieces(mp);
-			must_exist = 0;
-		}
-		if (start > rs) {
-			rp->size = start - rs;
-			if (end < re) {
-				/* need to split this entry */
-				if (mp->n_regions >= MAX_MEM_REGIONS)
-					panic("eek... mem_pieces overflow");
-				for (j = mp->n_regions; j > i + 1; --j)
-					mp->regions[j] = mp->regions[j-1];
-				++mp->n_regions;
-				rp[1].address = end;
-				rp[1].size = re - end;
-			}
-		} else {
-			if (end < re) {
-				rp->address = end;
-				rp->size = re - end;
-			} else {
-				/* need to delete this entry */
-				for (j = i; j < mp->n_regions - 1; ++j)
-					mp->regions[j] = mp->regions[j+1];
-				--mp->n_regions;
-				--i;
-				--rp;
-			}
-		}
-	}
-}
-
-static void __init print_mem_pieces(struct mem_pieces *mp)
-{
-	int i;
-
-	for (i = 0; i < mp->n_regions; ++i)
-		printk(" [%x, %x)", mp->regions[i].address,
-		       mp->regions[i].address + mp->regions[i].size);
-	printk("\n");
-}
-
-#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC)
-/*
- * Add some memory to an array of pieces
- */
-static void __init
-append_mem_piece(struct mem_pieces *mp, unsigned start, unsigned size)
-{
-	struct reg_property *rp;
-
-	if (mp->n_regions >= MAX_MEM_REGIONS)
-		return;
-	rp = &mp->regions[mp->n_regions++];
-	rp->address = start;
-	rp->size = size;
-}
-#endif
-
-#ifndef CONFIG_8xx
-static void hash_init(void);
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
 static void get_mem_prop(char *, struct mem_pieces *);
-static void sort_mem_pieces(struct mem_pieces *);
-static void coalesce_mem_pieces(struct mem_pieces *);
-
-static void __init sort_mem_pieces(struct mem_pieces *mp)
-{
-	unsigned long a, s;
-	int i, j;
-
-	for (i = 1; i < mp->n_regions; ++i) {
-		a = mp->regions[i].address;
-		s = mp->regions[i].size;
-		for (j = i - 1; j >= 0; --j) {
-			if (a >= mp->regions[j].address)
-				break;
-			mp->regions[j+1] = mp->regions[j];
-		}
-		mp->regions[j+1].address = a;
-		mp->regions[j+1].size = s;
-	}
-}
-
-static void __init coalesce_mem_pieces(struct mem_pieces *mp)
-{
-	unsigned long a, s, ns;
-	int i, j, d;
-
-	d = 0;
-	for (i = 0; i < mp->n_regions; i = j) {
-		a = mp->regions[i].address;
-		s = mp->regions[i].size;
-		for (j = i + 1; j < mp->n_regions
-			     && mp->regions[j].address - a <= s; ++j) {
-			ns = mp->regions[j].address + mp->regions[j].size - a;
-			if (ns > s)
-				s = ns;
-		}
-		mp->regions[d].address = a;
-		mp->regions[d].size = s;
-		++d;
-	}
-	mp->n_regions = d;
-}
 
+#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP) || 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;
@@ -797,9 +596,10 @@
 	memcpy(mp->regions, rp, s);
 
 	/* Make sure the pieces are sorted. */
-	sort_mem_pieces(mp);
-	coalesce_mem_pieces(mp);
+	mem_pieces_sort(mp);
+	mem_pieces_coalesce(mp);
 }
+#endif /* CONFIG_PMAC || CONFIG_CHRP || CONFIG_ALL_PPC */
 
 /*
  * Set up one of the I/D BAT (block address translation) register pairs.
@@ -915,7 +715,7 @@
 				f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE;
 #ifndef CONFIG_8xx
 			else
-				/* On the powerpc (not 8xx), no user access
+				/* On the powerpc, denying user access
 				   forces R/W kernel access */
 				f |= _PAGE_USER;
 #endif /* CONFIG_8xx */
@@ -936,7 +736,7 @@
 	} else if (init_bootmem_done) {
 		p = alloc_bootmem_pages(PAGE_SIZE);
 	} else {
-		p = find_mem_piece(PAGE_SIZE, PAGE_SIZE);
+		p = mem_pieces_find(PAGE_SIZE, PAGE_SIZE);
 	}
 	if (p == 0)
 		panic("couldn't get a page in MMU_get_page");
@@ -997,18 +797,32 @@
 			 num_openfirmware_pages );
 	
 	printk ("Freeing unused kernel memory: %ldk init",
-		(num_freed_pages * PAGE_SIZE) >> 10);
+		PGTOKB(num_freed_pages));
+
 	if ( num_prep_pages )
-		printk(" %ldk prep",(num_prep_pages*PAGE_SIZE)>>10);
+		printk(" %ldk prep", PGTOKB(num_prep_pages));
 	if ( num_pmac_pages )
-		printk(" %ldk pmac",(num_pmac_pages*PAGE_SIZE)>>10);
+		printk(" %ldk pmac", PGTOKB(num_pmac_pages));
 	if ( num_openfirmware_pages )
-		printk(" %ldk open firmware",(num_openfirmware_pages*PAGE_SIZE)>>10);
+		printk(" %ldk open firmware", PGTOKB(num_openfirmware_pages));
 	if ( num_apus_pages )
-		printk(" %ldk apus",(num_apus_pages*PAGE_SIZE)>>10);
+		printk(" %ldk apus", PGTOKB(num_apus_pages));
 	printk("\n");
 }
 
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+	for (; start < end; start += PAGE_SIZE) {
+		ClearPageReserved(mem_map + MAP_NR(start));
+		set_page_count(mem_map+MAP_NR(start), 1);
+		free_page(start);
+		totalram_pages++;
+	}
+	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
 /*
  * Do very early mm setup such as finding the size of memory
  * and setting up the hash table.
@@ -1060,7 +874,7 @@
 		setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
 		break;
 	case _MACH_Pmac:
-#if 0
+#if 1
 		{
 			unsigned long base = 0xf3000000;
 			struct device_node *macio = find_devices("mac-io");
@@ -1152,7 +966,8 @@
 				    __pa(end_of_DRAM) >> PAGE_SHIFT);
 
 	/* remove the bootmem bitmap from the available memory */
-	remove_mem_piece(&phys_avail, start, boot_mapsize, 1);
+	mem_pieces_remove(&phys_avail, start, boot_mapsize, 1);
+
 	/* add everything in phys_avail into the bootmem map */
 	for (i = 0; i < phys_avail.n_regions; ++i)
 		free_bootmem(phys_avail.regions[i].address,
@@ -1213,15 +1028,21 @@
 	empty_bad_page = alloc_bootmem_pages(PAGE_SIZE);
 	empty_bad_page_table = alloc_bootmem_pages(PAGE_SIZE);
 	{
-		unsigned int zones_size[2];
+		unsigned int zones_size[MAX_NR_ZONES], i;
 		/*
-		 * All pages are DMA-able so this is wrong - the zone code is assuming
-		 * both regions have a value so this is necessary for now.
+		 * All pages are DMA-able so this is wrong - the zone code is
+		 * assuming both regions have a value so this is necessary for
+		 * now.
 		 * -- Cort
 		 */
-		zones_size[0] = virt_to_phys(end_of_DRAM-(1<<20)) >> PAGE_SHIFT;
-		zones_size[1] = (1<<20) >> PAGE_SHIFT;
-
+#if 1
+		for ( i = 1; i < MAX_NR_ZONES; i++ )
+			zones_size[i] = 1<<MAX_ORDER;
+		zones_size[0] = (virt_to_phys(end_of_DRAM) >> PAGE_SHIFT) -
+			((MAX_NR_ZONES-1)*(1<<MAX_ORDER));
+#else
+		zones_size[0] = virt_to_phys(end_of_DRAM) >> PAGE_SHIFT;
+#endif
 		free_area_init(zones_size);
 	}
 }
@@ -1232,8 +1053,9 @@
 	int codepages = 0;
 	int datapages = 0;
 	int initpages = 0;
+#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
 	extern unsigned int rtas_data, rtas_size;
-
+#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */
 	max_mapnr = max_low_pfn;
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 	num_physpages = max_mapnr;	/* RAM is assumed contiguous */
@@ -1249,11 +1071,13 @@
 	}
 #endif /* CONFIG_BLK_DEV_INITRD */
 
+#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
 	/* mark the RTAS pages as reserved */
 	if ( rtas_data )
-		for (addr = (rtas_data+PAGE_OFFSET); addr < PAGE_ALIGN(PAGE_OFFSET+rtas_data+rtas_size) ;
-		     rtas_data += PAGE_SIZE)
+		for (addr = rtas_data; addr < PAGE_ALIGN(rtas_data+rtas_size) ;
+		     addr += PAGE_SIZE)
 			SetPageReserved(mem_map + MAP_NR(addr));
+#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */
 	
 	for (addr = PAGE_OFFSET; addr < (unsigned long)end_of_DRAM;
 	     addr += PAGE_SIZE) {
@@ -1264,12 +1088,12 @@
 		else if (addr >= (unsigned long)&__init_begin
 			 && addr < (unsigned long)&__init_end)
 			initpages++;
-		else if (addr < (ulong) klimit)
+		else
 			datapages++;
 	}
 
         printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08x,%08lx]\n",
-	       (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
+	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
 	       codepages << (PAGE_SHIFT-10),
 	       datapages << (PAGE_SHIFT-10), 
 	       initpages << (PAGE_SHIFT-10),
@@ -1277,7 +1101,7 @@
 	mem_init_done = 1;
 }
 
-#ifndef CONFIG_8xx
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
 #if defined(CONFIG_PMAC) || defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC)
 /*
  * On systems with Open Firmware, collect information about
@@ -1339,7 +1163,7 @@
 		phys_mem.n_regions = 1;
 	}
 
-	set_phys_avail();
+	set_phys_avail(&phys_mem);
 
 #undef RAM_LIMIT
 	return __va(total);
@@ -1368,8 +1192,8 @@
 		total = 0x02000000;
 		printk("Ramsize default to be %ldM\n", total>>20);
 	}
-	append_mem_piece(&phys_mem, 0, total);
-	set_phys_avail();
+	mem_pieces_append(&phys_mem, 0, total);
+	set_phys_avail(&phys_mem);
 
 	return (__va(total));
 }
@@ -1391,7 +1215,7 @@
 	phys_mem.n_regions = 1;
 	
 	ret = __va(phys_mem.regions[0].size);
-	set_phys_avail();
+	set_phys_avail(&phys_mem);
 	return ret;
 }
 #endif /* defined(CONFIG_GEMINI) */
@@ -1427,8 +1251,8 @@
 	}
 
 	/* Now register the memory block. */
-	append_mem_piece(&phys_mem, memory[0].addr, memory[0].size);
-	set_phys_avail();
+	mem_pieces_append(&phys_mem, memory[0].addr, memory[0].size);
+	set_phys_avail(&phys_mem);
 
 	/* Remove the memory chunks that are controlled by special
            Phase5 hardware. */
@@ -1442,8 +1266,8 @@
 		if (shadow)
 		{
 			top -= HARDWARE_MAPPED_SIZE;
-			remove_mem_piece(&phys_avail, top,
-					 HARDWARE_MAPPED_SIZE, 0);
+			mem_pieces_remove(&phys_avail, top,
+					  HARDWARE_MAPPED_SIZE, 0);
 		}
 
 		/* Remove the upper 512KB where the PPC exception
@@ -1451,9 +1275,9 @@
 		top -= HARDWARE_MAPPED_SIZE;
 #if 0
 		/* This would be neat, but it breaks on A3000 machines!? */
-		remove_mem_piece(&phys_avail, top, 16384, 0);
+		mem_pieces_remove(&phys_avail, top, 16384, 0);
 #else
-		remove_mem_piece(&phys_avail, top, HARDWARE_MAPPED_SIZE, 0);
+		mem_pieces_remove(&phys_avail, top, HARDWARE_MAPPED_SIZE, 0);
 #endif
 
 	}
@@ -1512,7 +1336,7 @@
 	if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
 	/* Find some memory for the hash table. */
 	if ( Hash_size )
-		Hash = find_mem_piece(Hash_size, Hash_size);
+		Hash = mem_pieces_find(Hash_size, Hash_size);
 	else
 		Hash = 0;
 
@@ -1590,7 +1414,7 @@
 	ret = __va(phys_mem.regions[0].address+
 		   phys_mem.regions[0].size);
 
-	set_phys_avail();
+	set_phys_avail(&phys_mem);
 	return ret;
 }
 #endif /* ndef CONFIG_8xx */
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/mm/mem_pieces.c linux/arch/ppc/mm/mem_pieces.c
--- v2.3.29/linux/arch/ppc/mm/mem_pieces.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/mm/mem_pieces.c	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,224 @@
+/*
+ *    Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ *      Changes to accomodate Power Macintoshes.
+ *    Cort Dougan <cort@cs.nmt.edu>
+ *      Rewrites.
+ *    Grant Erickson <grant@lcse.umn.edu>
+ *      General rework and split from mm/init.c.
+ *
+ *    Module name: mem_pieces.c
+ *
+ *    Description:
+ *      Routines and data structures for manipulating and representing
+ *      phyiscal memory extents (i.e. address/length pairs).
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/blk.h>
+
+#include <asm/page.h>
+#include <asm/prom.h>
+
+#include "mem_pieces.h"
+
+extern char _start[], _end[];
+extern char _stext[], etext[];
+
+char *klimit = _end;
+
+struct mem_pieces phys_avail;
+
+static void mem_pieces_print(struct mem_pieces *);
+
+/*
+ * Scan a region for a piece of a given size with the required alignment.
+ */
+void __init *
+mem_pieces_find(unsigned int size, unsigned int align)
+{
+	int i;
+	unsigned a, e;
+	struct mem_pieces *mp = &phys_avail;
+
+	for (i = 0; i < mp->n_regions; ++i) {
+		a = mp->regions[i].address;
+		e = a + mp->regions[i].size;
+		a = (a + align - 1) & -align;
+		if (a + size <= e) {
+			mem_pieces_remove(mp, a, size, 1);
+			return __va(a);
+		}
+	}
+	panic("Couldn't find %u bytes at %u alignment\n", size, align);
+	
+	return NULL;
+}
+
+/*
+ * Remove some memory from an array of pieces
+ */
+void __init 
+mem_pieces_remove(struct mem_pieces *mp, unsigned int start, unsigned int size,
+		  int must_exist)
+{
+	int i, j;
+	unsigned int end, rs, re;
+	struct reg_property *rp;
+
+	end = start + size;
+	for (i = 0, rp = mp->regions; i < mp->n_regions; ++i, ++rp) {
+		if (end > rp->address && start < rp->address + rp->size)
+			break;
+	}
+	if (i >= mp->n_regions) {
+		if (must_exist)
+			printk("mem_pieces_remove: [%x,%x) not in any region\n",
+			       start, end);
+		return;
+	}
+	for (; i < mp->n_regions && end > rp->address; ++i, ++rp) {
+		rs = rp->address;
+		re = rs + rp->size;
+		if (must_exist && (start < rs || end > re)) {
+			printk("mem_pieces_remove: bad overlap [%x,%x) with",
+			       start, end);
+			mem_pieces_print(mp);
+			must_exist = 0;
+		}
+		if (start > rs) {
+			rp->size = start - rs;
+			if (end < re) {
+				/* need to split this entry */
+				if (mp->n_regions >= MEM_PIECES_MAX)
+					panic("eek... mem_pieces overflow");
+				for (j = mp->n_regions; j > i + 1; --j)
+					mp->regions[j] = mp->regions[j-1];
+				++mp->n_regions;
+				rp[1].address = end;
+				rp[1].size = re - end;
+			}
+		} else {
+			if (end < re) {
+				rp->address = end;
+				rp->size = re - end;
+			} else {
+				/* need to delete this entry */
+				for (j = i; j < mp->n_regions - 1; ++j)
+					mp->regions[j] = mp->regions[j+1];
+				--mp->n_regions;
+				--i;
+				--rp;
+			}
+		}
+	}
+}
+
+static void __init
+mem_pieces_print(struct mem_pieces *mp)
+{
+	int i;
+
+	for (i = 0; i < mp->n_regions; ++i)
+		printk(" [%x, %x)", mp->regions[i].address,
+		       mp->regions[i].address + mp->regions[i].size);
+	printk("\n");
+}
+
+#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC)
+/*
+ * Add some memory to an array of pieces
+ */
+void __init
+mem_pieces_append(struct mem_pieces *mp, unsigned int start, unsigned int size)
+{
+	struct reg_property *rp;
+
+	if (mp->n_regions >= MEM_PIECES_MAX)
+		return;
+	rp = &mp->regions[mp->n_regions++];
+	rp->address = start;
+	rp->size = size;
+}
+#endif
+
+void __init
+mem_pieces_sort(struct mem_pieces *mp)
+{
+	unsigned long a, s;
+	int i, j;
+
+	for (i = 1; i < mp->n_regions; ++i) {
+		a = mp->regions[i].address;
+		s = mp->regions[i].size;
+		for (j = i - 1; j >= 0; --j) {
+			if (a >= mp->regions[j].address)
+				break;
+			mp->regions[j+1] = mp->regions[j];
+		}
+		mp->regions[j+1].address = a;
+		mp->regions[j+1].size = s;
+	}
+}
+
+void __init
+mem_pieces_coalesce(struct mem_pieces *mp)
+{
+	unsigned long a, s, ns;
+	int i, j, d;
+
+	d = 0;
+	for (i = 0; i < mp->n_regions; i = j) {
+		a = mp->regions[i].address;
+		s = mp->regions[i].size;
+		for (j = i + 1; j < mp->n_regions
+			     && mp->regions[j].address - a <= s; ++j) {
+			ns = mp->regions[j].address + mp->regions[j].size - a;
+			if (ns > s)
+				s = ns;
+		}
+		mp->regions[d].address = a;
+		mp->regions[d].size = s;
+		++d;
+	}
+	mp->n_regions = d;
+}
+
+/*
+ * Set phys_avail to phys_mem less the kernel text/data/bss.
+ */
+void __init
+set_phys_avail(struct mem_pieces *mp)
+{
+	unsigned long kstart, ksize;
+
+	/*
+	 * Initially, available phyiscal memory is equivalent to all
+	 * physical memory.
+	 */
+
+	phys_avail = *mp;
+
+	/*
+	 * Map out the kernel text/data/bss from the available physical
+	 * memory.
+	 */
+
+	kstart = __pa(_stext);	/* should be 0 */
+	ksize = PAGE_ALIGN(klimit - _stext);
+
+	printk("kstart = 0x%08lx, ksize = 0x%08lx\n", kstart, ksize);
+
+	mem_pieces_remove(&phys_avail, kstart, ksize, 0);
+	mem_pieces_remove(&phys_avail, 0, 0x4000, 0);
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+	/* Remove the init RAM disk from the available memory. */
+	if (initrd_start) {
+		mem_pieces_remove(&phys_avail, __pa(initrd_start),
+				  initrd_end - initrd_start, 1);
+	}
+#endif /* CONFIG_BLK_DEV_INITRD */
+}
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/mm/mem_pieces.h linux/arch/ppc/mm/mem_pieces.h
--- v2.3.29/linux/arch/ppc/mm/mem_pieces.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/mm/mem_pieces.h	Sat Nov 27 23:06:26 1999
@@ -0,0 +1,61 @@
+/*
+ *    Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ *      Changes to accomodate Power Macintoshes.
+ *    Cort Dougan <cort@cs.nmt.edu>
+ *      Rewrites.
+ *    Grant Erickson <grant@lcse.umn.edu>
+ *      General rework and split from mm/init.c.
+ *
+ *    Module name: mem_pieces.h
+ *
+ *    Description:
+ *      Routines and data structures for manipulating and representing
+ *      phyiscal memory extents (i.e. address/length pairs).
+ *
+ */
+
+#ifndef __MEM_PIECES_H__
+#define	__MEM_PIECES_H__
+
+#include <linux/init.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Type Definitions */
+
+#define	MEM_PIECES_MAX	32
+
+struct mem_pieces {
+    int n_regions;
+    struct reg_property regions[MEM_PIECES_MAX];
+};
+
+
+/* Global Variables */
+
+extern char *klimit;
+extern struct mem_pieces phys_avail;
+
+
+/* Function Prototypes */
+
+extern void	*mem_pieces_find(unsigned int size, unsigned int align);
+extern void	 mem_pieces_remove(struct mem_pieces *mp, unsigned int start,
+				   unsigned int size, int must_exist);
+extern void	 mem_pieces_append(struct mem_pieces *mp, unsigned int start,
+				   unsigned int size);
+extern void	 mem_pieces_coalesce(struct mem_pieces *mp);
+extern void	 mem_pieces_sort(struct mem_pieces *mp);
+
+extern void	 set_phys_avail(struct mem_pieces *mp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MEM_PIECES_H__ */
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/pmac_defconfig linux/arch/ppc/pmac_defconfig
--- v2.3.29/linux/arch/ppc/pmac_defconfig	Fri Oct 15 15:25:13 1999
+++ linux/arch/ppc/pmac_defconfig	Wed Dec 31 16:00:00 1969
@@ -1,549 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-
-#
-# Platform support
-#
-CONFIG_PPC=y
-CONFIG_6xx=y
-# CONFIG_PPC64 is not set
-# CONFIG_82xx is not set
-# CONFIG_8xx is not set
-CONFIG_PMAC=y
-# CONFIG_PREP is not set
-# CONFIG_CHRP is not set
-# CONFIG_ALL_PPC is not set
-# CONFIG_GEMINI is not set
-# CONFIG_APUS is not set
-# CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
-CONFIG_6xx=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-CONFIG_PCI=y
-CONFIG_NET=y
-CONFIG_SYSCTL=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_KERNEL_ELF=y
-CONFIG_BINFMT_MISC=m
-
-#
-# PCMCIA/Cardbus support
-#
-CONFIG_PCMCIA=m
-CONFIG_CARDBUS=y
-# CONFIG_PARPORT is not set
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FB=y
-CONFIG_FB_COMPAT_XPMAC=y
-CONFIG_PMAC_PBOOK=y
-CONFIG_MAC_FLOPPY=y
-CONFIG_MAC_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-CONFIG_ADB=y
-CONFIG_ADB_CUDA=y
-CONFIG_ADB_MACIO=y
-CONFIG_ADB_PMU=y
-CONFIG_ADB_KEYBOARD=y
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_TOTALMP is not set
-CONFIG_BOOTX_TEXT=y
-# CONFIG_MOTOROLA_HOTSWAP 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_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDEFLOPPY=y
-# CONFIG_BLK_DEV_IDESCSI is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_IDEDMA_PCI_AUTO=y
-CONFIG_IDEDMA_NEW_DRIVE_LISTINGS=y
-CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-# CONFIG_BLK_DEV_AEC6210 is not set
-CONFIG_BLK_DEV_CMD646=y
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_PDC202XX is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
-CONFIG_BLK_DEV_IDE_PMAC=y
-CONFIG_BLK_DEV_IDEDMA_PMAC=y
-CONFIG_IDEDMA_PMAC_AUTO=y
-CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_BLK_CPQ_DA is not set
-
-#
-# Additional Block Devices
-#
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_MD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=y
-# CONFIG_PARIDE is not set
-CONFIG_BLK_DEV_IDE_MODES=y
-# CONFIG_BLK_DEV_HD 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=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_IP_ROUTER is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-CONFIG_IP_ALIAS=y
-# 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
-
-#
-#  
-#
-# CONFIG_IPX is not set
-CONFIG_ATALK=m
-# CONFIG_DECNET is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_LLC 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
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# 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=y
-# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set
-CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
-CONFIG_AIC7XXX_PROC_STATS=y
-CONFIG_AIC7XXX_RESET_DELAY=15
-# CONFIG_SCSI_IPS 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_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_SYM53C416 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_SEAGATE is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_DEBUG is not set
-CONFIG_SCSI_MESH=y
-CONFIG_SCSI_MESH_SYNC_RATE=5
-CONFIG_SCSI_MAC53C94=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_ETHERTAP is not set
-# CONFIG_NET_SB1000 is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MACE=y
-CONFIG_BMAC=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_YELLOWFIN is not set
-# CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_DM9102 is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_EISA=y
-# CONFIG_PCNET32 is not set
-# CONFIG_ACENIC is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
-CONFIG_DE4X5=y
-# CONFIG_DEC_ELCP is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEXPRESS_PRO100 is not set
-# CONFIG_LNE390 is not set
-# CONFIG_NE3210 is not set
-# CONFIG_NE2K_PCI 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_ZNET is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_LTPC is not set
-# CONFIG_COPS is not set
-# CONFIG_IPDDP is not set
-CONFIG_PPP=y
-CONFIG_PPP_ASYNC=y
-CONFIG_PPP_DEFLATE=y
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring driver support
-#
-# 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
-
-#
-# PCMCIA network devices
-#
-# CONFIG_PCMCIA_PCNET is not set
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_RAYCS is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO 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
-#
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_CLGEN is not set
-# CONFIG_FB_PM2 is not set
-CONFIG_FB_OF=y
-CONFIG_FB_CONTROL=y
-CONFIG_FB_PLATINUM=y
-CONFIG_FB_VALKYRIE=y
-CONFIG_FB_IMSTT=y
-CONFIG_FB_CT65550=y
-# CONFIG_FB_S3TRIO is not set
-# CONFIG_FB_VGA16 is not set
-# CONFIG_FB_MATROX is not set
-CONFIG_FB_ATY=y
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_CFB8=y
-CONFIG_FBCON_CFB16=y
-CONFIG_FBCON_CFB24=y
-CONFIG_FBCON_CFB32=y
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-# CONFIG_FONT_8x8 is not set
-CONFIG_FONT_8x16=y
-CONFIG_FONT_SUN8x16=y
-CONFIG_FONT_SUN12x22=y
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# Mice
-#
-CONFIG_BUSMOUSE=y
-# CONFIG_ATIXL_BUSMOUSE is not set
-# CONFIG_LOGIBUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
-CONFIG_ADBMOUSE=y
-# CONFIG_MOUSE is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_NVRAM=y
-# CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK 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
-
-#
-# USB drivers - not for the faint of heart
-#
-CONFIG_USB=y
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-CONFIG_USB_OHCI=y
-CONFIG_USB_OHCI_DEBUG=y
-# CONFIG_USB_OHCI_HCD is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEBUG_ISOC=y
-CONFIG_USB_PROC=y
-# CONFIG_USB_EZUSB is not set
-
-#
-# USB Devices
-#
-CONFIG_USB_HUB=y
-CONFIG_USB_MOUSE=y
-CONFIG_USB_HP_SCANNER=m
-CONFIG_USB_KBD=y
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_CPIA is not set
-CONFIG_USB_SCSI=m
-CONFIG_USB_SCSI_DEBUG=y
-# CONFIG_USB_USS720 is not set
-
-#
-# Filesystems
-#
-# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_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_ISO9660_FS=y
-# CONFIG_JOLIET is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFSD=y
-# CONFIG_NFSD_SUN is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_OSF_PARTITION is not set
-CONFIG_MAC_PARTITION=y
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_NLS is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-CONFIG_DMASOUND=y
-# 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_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_OSS is not set
-
-#
-# Kernel hacking
-#
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/prep_defconfig linux/arch/ppc/prep_defconfig
--- v2.3.29/linux/arch/ppc/prep_defconfig	Thu Feb 25 10:46:47 1999
+++ linux/arch/ppc/prep_defconfig	Wed Dec 31 16:00:00 1969
@@ -1,361 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-
-#
-# Platform support
-#
-CONFIG_PPC=y
-CONFIG_6xx=y
-# CONFIG_8xx is not set
-# CONFIG_PMAC is not set
-CONFIG_PREP=y
-# CONFIG_CHRP is not set
-# CONFIG_ALL_PPC is not set
-# CONFIG_APUS is not set
-# CONFIG_MBX is not set
-# CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
-CONFIG_PCI=y
-# CONFIG_PCI_QUIRKS is not set
-CONFIG_PCI_OLD_PROC=y
-CONFIG_NET=y
-CONFIG_SYSCTL=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_KERNEL_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_BINFMT_JAVA is not set
-# CONFIG_PARPORT is not set
-# CONFIG_FB is not set
-CONFIG_VGA_CONSOLE=y
-# CONFIG_PMAC_PBOOK is not set
-# CONFIG_MAC_KEYBOARD is not set
-# CONFIG_MAC_FLOPPY is not set
-# CONFIG_MAC_SERIAL is not set
-# CONFIG_ADBMOUSE is not set
-# CONFIG_PROC_DEVICETREE is not set
-# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_FD=y
-CONFIG_BLK_DEV_IDE=y
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_BLK_DEV_CMD640 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_IDE_CHIPSETS is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_MD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=y
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK is not set
-# CONFIG_FIREWALL 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_IP_ROUTER is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_ALIAS is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_RARP is not set
-# CONFIG_IP_NOSR is not set
-CONFIG_SKB_LARGE=y
-# CONFIG_IPV6 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_LLC 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
-# CONFIG_CPU_IS_SLOW is not set
-# CONFIG_NET_SCHED is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_BLK_DEV_SR_VENDOR=y
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST 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_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_EATA 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_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-CONFIG_SCSI_NCR53C8XX=y
-CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
-CONFIG_SCSI_NCR53C8XX_MAX_TAGS=4
-CONFIG_SCSI_NCR53C8XX_SYNC=5
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-CONFIG_SCSI_NCR53C8XX_IOMAPPED=y
-# 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_SEAGATE is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_MESH is not set
-# CONFIG_SCSI_MAC53C94 is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_NET_ETHERNET=y
-# CONFIG_MACE is not set
-# CONFIG_BMAC is not set
-# CONFIG_NET_VENDOR_3COM is not set
-CONFIG_LANCE=y
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_RTL8139 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_EISA=y
-CONFIG_PCNET32=y
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_CS89x0 is not set
-CONFIG_DE4X5=y
-# CONFIG_DEC_ELCP is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEXPRESS_PRO100 is not set
-# CONFIG_LNE390 is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_TLAN is not set
-# CONFIG_ES3210 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_ZNET is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FDDI is not set
-# CONFIG_DLCI is not set
-CONFIG_PPP=m
-# CONFIG_SLIP is not set
-# CONFIG_NET_RADIO is not set
-# CONFIG_TR is not set
-# CONFIG_SHAPER is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# CD-ROM drivers (not for SCSI or IDE/ATAPI drives)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Console 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_MOUSE=y
-# CONFIG_ATIXL_BUSMOUSE is not set
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_UMISC is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_NVRAM is not set
-# CONFIG_JOYSTICK is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-
-#
-# Filesystems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-# CONFIG_JOLIET is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_NFS_FS=y
-# CONFIG_NFSD is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-# CONFIG_CODA_FS is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_DEVPTS_FS is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-# 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_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_KOI8_R is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-CONFIG_SOUND_OSS=y
-# CONFIG_SOUND_PAS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-CONFIG_SOUND_CS4232=y
-CONFIG_CS4232_BASE=530
-CONFIG_CS4232_IRQ=11
-CONFIG_CS4232_DMA=0
-CONFIG_CS4232_DMA2=3
-CONFIG_CS4232_MPU_BASE=330
-CONFIG_CS4232_MPU_IRQ=9
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_SOFTOSS is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_UART6850 is not set
-
-#
-# Additional low level sound drivers
-#
-# CONFIG_LOWLEVEL_SOUND is not set
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/treeboot/Makefile linux/arch/ppc/treeboot/Makefile
--- v2.3.29/linux/arch/ppc/treeboot/Makefile	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/treeboot/Makefile	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,62 @@
+#
+#    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+#
+#    Module name: Makefile
+#
+#    Description:
+#      Makefile for the IBM "tree" evaluation board Linux kernel
+#      boot loaders.
+#
+
+HOSTCFLAGS = -O -I$(TOPDIR)/include
+
+CC	= $(CROSS_COMPILE)gcc
+LD	= $(CROSS_COMPILE)ld
+OBJCOPY = $(CROSS_COMPILE)objcopy
+OBJDUMP	= $(CROSS_COMPILE)objdump
+
+GZIP	= gzip -vf9
+RM	= rm -f
+MKEVIMG	= mkevimg -l
+MKIRIMG	= mkirimg
+
+CFLAGS	= -O -fno-builtin -I$(TOPDIR)/include
+LD_ARGS = -e _start -T ld.script -Ttext 80200000 -Bstatic
+
+OBJS	= crt0.o main.o misc.o string.o zlib.o irSect.o
+LIBS	=
+
+treeboot: $(OBJS) ld.script
+	$(LD) -o $@ $(LD_ARGS) $(OBJS) $(LIBS)
+
+zImage:	vmlinux.img
+
+zImage.initrd: vmlinux.initrd.img
+
+treeboot.image: treeboot vmlinux.gz
+	$(OBJCOPY) --add-section=image=vmlinux.gz treeboot $@
+
+treeboot.initrd: treeboot.image ramdisk.image.gz
+	$(OBJCOPY) --add-section=initrd=ramdisk.image.gz treeboot.image $@
+
+vmlinux.img: treeboot.image
+	$(OBJDUMP) --syms treeboot.image | grep irSectStart > irSectStart.txt
+	$(MKIRIMG) treeboot.image treeboot.image.out irSectStart.txt
+	$(MKEVIMG) treeboot.image.out $@
+	$(RM) treeboot.image treeboot.image.out irSectStart.txt
+
+vmlinux.initrd.img: treeboot.initrd
+	$(OBJDUMP) --all-headers treeboot.initrd | grep irSectStart > irSectStart.txt
+	$(MKIRIMG) treeboot.initrd treeboot.initrd.out irSectStart.txt
+	$(MKEVIMG) treeboot.initrd.out $@
+	$(RM) treeboot.initrd treeboot.initrd.out irSectStart.txt
+
+vmlinux.gz: $(TOPDIR)/vmlinux
+	$(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux
+	$(GZIP) vmlinux
+
+clean:
+	rm -f treeboot treeboot.image treeboot.initrd irSectStart.txt vmlinux.* *.o
+
+fastdep:
+
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/treeboot/crt0.S linux/arch/ppc/treeboot/crt0.S
--- v2.3.29/linux/arch/ppc/treeboot/crt0.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/treeboot/crt0.S	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,70 @@
+/*
+ *    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.h"
+
+	.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.3.29/linux/arch/ppc/treeboot/elf.pl linux/arch/ppc/treeboot/elf.pl
--- v2.3.29/linux/arch/ppc/treeboot/elf.pl	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/treeboot/elf.pl	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,33 @@
+#
+# ELF header field numbers
+#
+
+$e_ident	=  0;	# Identification bytes / magic number
+$e_type		=  1;	# ELF file type
+$e_machine	=  2;	# Target machine type
+$e_version	=  3;	# File version
+$e_entry	=  4;	# Start address
+$e_phoff	=  5;	# Program header file offset
+$e_shoff	=  6;	# Section header file offset
+$e_flags	=  7;	# File flags
+$e_ehsize	=  8;	# Size of ELF header
+$e_phentsize	=  9;	# Size of program header
+$e_phnum	= 10;	# Number of program header entries
+$e_shentsize	= 11;	# Size of section header
+$e_shnum	= 12;	# Number of section header entries
+$e_shstrndx	= 13;	# Section header table string index
+
+#
+# Section header field numbers
+#
+
+$sh_name	=  0;	# Section name
+$sh_type	=  1;	# Section header type
+$sh_flags	=  2;	# Section header flags
+$sh_addr	=  3;	# Virtual address
+$sh_offset	=  4;	# File offset
+$sh_size	=  5;	# Section size
+$sh_link	=  6;	# Miscellaneous info
+$sh_info	=  7;	# More miscellaneous info
+$sh_addralign	=  8;	# Memory alignment
+$sh_entsize	=  9;	# Entry size if this is a table
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/treeboot/irSect.c linux/arch/ppc/treeboot/irSect.c
--- v2.3.29/linux/arch/ppc/treeboot/irSect.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/treeboot/irSect.c	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,36 @@
+/*
+ *
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Module name: irSect.c
+ *
+ *    Description:
+ *      Defines variables to hold the absolute starting address and size
+ *      of the Linux kernel "image" and the initial RAM disk "initrd"
+ *      sections within the boot loader.
+ *
+ */
+
+#include "irSect.h"
+
+
+/*
+ * The order of globals below must not change. If more globals are added,
+ * you must change the script 'mkirimg' accordingly.
+ *
+ */
+
+/* 
+ * irSectStart must be at beginning of file 
+ */
+unsigned int irSectStart = 0xdeadbeaf;
+
+unsigned int imageSect_start	= 0;
+unsigned int imageSect_size	= 0;
+unsigned int initrdSect_start	= 0;
+unsigned int initrdSect_size	= 0;
+
+/* 
+ * irSectEnd must be at end of file 
+ */
+unsigned int irSectEnd   = 0xdeadbeaf;
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/treeboot/irSect.h linux/arch/ppc/treeboot/irSect.h
--- v2.3.29/linux/arch/ppc/treeboot/irSect.h	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/treeboot/irSect.h	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,32 @@
+/*
+ *
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Module name: irSect.h
+ *    
+ *    Description:
+ *      Defines variables to hold the absolute starting address and size
+ *      of the Linux kernel "image" and the initial RAM disk "initrd"   
+ *      sections within the boot loader.
+ *      
+ */
+
+#ifndef __IRSECT_H__
+#define __IRSECT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern unsigned int imageSect_start;
+extern unsigned int imageSect_size;
+
+extern unsigned int initrdSect_start;
+extern unsigned int initrdSect_size;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IRSECT_H__ */
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/treeboot/ld.script linux/arch/ppc/treeboot/ld.script
--- v2.3.29/linux/arch/ppc/treeboot/ld.script	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/treeboot/ld.script	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,68 @@
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	} =0
+  .plt : { *(.plt) }
+  .text      :
+  {
+    *(.text)
+    *(.rodata)
+    *(.rodata1)
+    *(.got1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+  _etext = .;
+  PROVIDE (etext = .);
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.got.plt) *(.got)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
+
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/treeboot/main.c linux/arch/ppc/treeboot/main.c
--- v2.3.29/linux/arch/ppc/treeboot/main.c	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/treeboot/main.c	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,209 @@
+/*
+ *    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 an ELF-based IBM evaluation board version.
+ *
+ *    Module name: main.c
+ *
+ *    Description:
+ *      This module does most of the real work for the boot loader. It
+ *      checks the variables holding the absolute start address and size
+ *      of the Linux kernel "image" and initial RAM disk "initrd" sections
+ *      and if they are present, moves them to their "proper" locations.
+ *
+ *      For the Linux kernel, "proper" is physical address 0x00000000.
+ *      For the RAM disk, "proper" is the image's size below the top
+ *      of physical memory. The Linux kernel may be in either raw
+ *      binary form or compressed with GNU zip (aka gzip).
+ *
+ *    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 "nonstdio.h"
+#include "zlib.h"
+#include "irSect.h"
+
+
+/* Preprocessor Defines */
+
+#define	RAM_SIZE	(4 * 1024 * 1024)
+
+#define	RAM_PBASE	0x00000000
+#define	RAM_PEND	(RAM_PBASE + RAM_SIZE)
+
+#define	RAM_VBASE	0xC0000000
+#define	RAM_VEND	(RAM_VBASE + RAM_SIZE)
+
+#define	RAM_START	RAM_PBASE
+#define	RAM_END		RAM_PEND
+#define	RAM_FREE	(imageSect_start + imageSect_size + initrdSect_size)
+
+#define	PROG_START	RAM_START
+
+
+/* Function Macros */
+
+#define	ALIGN_UP(x, align)	(((x) + ((align) - 1)) & ~((align) - 1))
+
+
+/* Global Variables */
+
+/* Needed by zalloc and zfree for allocating memory */
+
+char *avail_ram;	/* Indicates start of RAM available for heap */
+char *end_avail;	/* Indicates end of RAM available for heap */
+
+
+/* Function Prototypes */
+
+void *zalloc(void *x, unsigned items, unsigned size);
+void zfree(void *x, void *addr, unsigned nb);
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp);
+
+void printf () {}
+void pause () {}
+void exit () {}
+
+
+void start(void)
+{
+    void *options;
+    int ns, oh, i;
+    unsigned sa, len;
+    void *dst;
+    unsigned char *im;
+    unsigned initrd_start, initrd_size;
+
+    /* setup_bats(RAM_START); */
+
+    /* Init RAM disk (initrd) section */
+
+    if (initrdSect_start != 0 && (initrd_size = initrdSect_size) != 0) {
+        initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+
+	printf("Initial RAM disk at 0x%08x (%u bytes)\n",
+	       initrd_start, initrd_size);
+
+	memcpy((char *)initrd_start,
+	       (char *)(initrdSect_start),
+	       initrdSect_size);
+
+	end_avail = (char *)initrd_start;
+    } else {
+	end_avail = (char *)RAM_END;
+    }
+
+    /* Linux kernel image section */
+	
+    im = (unsigned char *)(imageSect_start);
+    len = imageSect_size;
+    dst = (void *)PROG_START;
+
+    /* Check for the gzip archive magic numbers */
+
+    if (im[0] == 0x1f && im[1] == 0x8b) {
+
+        /* The gunzip routine needs everything nice and aligned */
+
+	void *cp = (void *)ALIGN_UP(RAM_FREE, 8);
+	avail_ram = (void *)(cp + ALIGN_UP(len, 8));
+	memcpy(cp, im, len);
+
+	/* I'm not sure what the 0x200000 parameter is for, but it works. */
+
+	gunzip(dst, 0x200000, cp, &len);
+    } else {
+	memmove(dst, im, len);
+    }
+
+    /* flush_cache(dst, len); */
+
+    sa = (unsigned long)dst;
+
+    (*(void (*)())sa)();
+
+    pause();
+}
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+    void *p = avail_ram;
+
+    size *= items;
+    size = ALIGN_UP(size, 8);
+    avail_ram += size;
+    if (avail_ram > end_avail) {
+	printf("oops... out of memory\n");
+	pause();
+    }
+    return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+
+}
+
+#define HEAD_CRC	2
+#define EXTRA_FIELD	4
+#define ORIG_NAME	8
+#define COMMENT		0x10
+#define RESERVED	0xe0
+
+#define DEFLATED	8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+    z_stream s;
+    int r, i, flags;
+
+    /* skip header */
+    i = 10;
+    flags = src[3];
+    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+	printf("bad gzipped data\n");
+	exit();
+    }
+    if ((flags & EXTRA_FIELD) != 0)
+	i = 12 + src[10] + (src[11] << 8);
+    if ((flags & ORIG_NAME) != 0)
+	while (src[i++] != 0)
+	    ;
+    if ((flags & COMMENT) != 0)
+	while (src[i++] != 0)
+	    ;
+    if ((flags & HEAD_CRC) != 0)
+	i += 2;
+    if (i >= *lenp) {
+	printf("gunzip: ran out of data in header\n");
+	exit();
+    }
+    printf("done 1\n");
+    s.zalloc = zalloc;
+    s.zfree = zfree;
+    r = inflateInit2(&s, -MAX_WBITS);
+    if (r != Z_OK) {
+	printf("inflateInit2 returned %d\n", r);
+	exit();
+    }
+    s.next_in = src + i;
+    s.avail_in = *lenp - i;
+    s.next_out = dst;
+    s.avail_out = dstlen;
+    printf("doing inflate\n");
+    r = inflate(&s, Z_FINISH);
+    printf("done inflate\n");
+    if (r != Z_OK && r != Z_STREAM_END) {
+	printf("inflate returned %d\n", r);
+	exit();
+    }
+    *lenp = s.next_out - (unsigned char *) dst;
+    printf("doing end\n");
+    inflateEnd(&s);
+}
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/treeboot/misc.S linux/arch/ppc/treeboot/misc.S
--- v2.3.29/linux/arch/ppc/treeboot/misc.S	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/treeboot/misc.S	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ */
+	.text
+
+/*
+ * Flush the dcache and invalidate the icache for a range of addresses.
+ *
+ * flush_cache(addr, len)
+ */
+	.global	flush_cache
+flush_cache:
+	addi	4,4,0x1f	/* len = (len + 0x1f) / 0x20 */
+	rlwinm.	4,4,27,5,31
+	mtctr	4
+	beqlr
+1:	dcbf	0,3
+	icbi	0,3
+	addi	3,3,0x20
+	bdnz	1b
+	sync
+	isync
+	blr
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/treeboot/mkevimg linux/arch/ppc/treeboot/mkevimg
--- v2.3.29/linux/arch/ppc/treeboot/mkevimg	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/treeboot/mkevimg	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,437 @@
+#!/usr/local/bin/perl
+
+#
+#    Copyright (c) 1998-1999 TiVo, Inc.
+#    All rights reserved.
+#
+#    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+#      Major syntactic and usability rework.
+#
+#    Module name: mkevimg
+#
+#    Description:
+#      Converts an ELF output file from the linker into the format used by
+#      the IBM evaluation board ROM Monitor to load programs from a host
+#      onto the evaluation board. The ELF file must be an otherwise execut-
+#      able file (with the text and data addresses bound at link time) and
+#      have space reserved after the entry point for the load information
+#      block:
+#
+#      typedef struct boot_block {
+#        unsigned long magic;	        0x0052504F
+#	 unsigned long dest;	        Target address of the image
+#	 unsigned long num_512blocks;   Size, rounded-up, in 512 byte blocks
+#	 unsigned long debug_flag;      Run the debugger or image after load
+#        unsigned long entry_point;	The image address to jump to after load
+#	 unsigned long reserved[3];
+#      } boot_block_t;
+#
+#   
+
+use File::Basename;
+use Getopt::Std;
+
+#
+# usage()
+#
+# Description:
+#   This routine prints out the proper command line usage for this program
+#
+# Input(s):
+#   status - Flag determining what usage information will be printed and what
+#            the exit status of the program will be after the information is
+#            printed.
+#
+# Output(s):
+#   N/A
+#
+# Returns:
+#   This subroutine does not return.
+#
+
+sub usage {
+  my($status);
+  $status = $_[0];
+
+  printf("Usage: %s [-hlvV] <ELF input file> <Evaluation board output file>\n",
+	$program);
+
+  if ($status != 0) {
+    printf("Try `%s -h' for more information.\n", $program);
+  }
+
+  if ($status != 1) {
+    print("  -h         Print out this message and exit.\n");
+    print("  -l         Linux mode; if present, copy 'image' and 'initrd' sections.\n");
+    print("  -v         Verbose. Print out lots of ELF information.\n");
+    print("  -V         Print out version information and exit.\n");
+  }
+
+  exit($status);
+}
+
+#
+# version()
+#
+# Description:
+#   This routine prints out program version information
+#
+# Input(s):
+#   N/A
+#
+# Output(s):
+#   N/A
+#
+# Returns:
+#   This subroutine does not return.
+#
+
+sub version {
+  print("mkevimg Version 1.1.0\n");
+  print("Copyright (c) 1998-1999 TiVo, Inc.\n");
+  print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n");
+
+  exit (0);
+}
+
+#
+# file_check()
+#
+# Description:
+#   This routine checks an input file to ensure that it exists, is a
+#   regular file, and is readable.
+#
+# Input(s):
+#   file - Input file to be checked.
+#
+# Output(s):
+#   N/A
+#
+# Returns:
+#   0 if the file exists, is a regular file, and is readable, otherwise -1.
+#
+
+sub file_check {
+  my($file);
+  $file = $_[0];
+
+  if (!(-e $file)) {
+    printf("The file \"%s\" does not exist.\n", $file);
+    return (-1);
+  } elsif (!(-f $file)) {
+    printf("The file \"%s\" is not a regular file.\n", $file);
+    return (-1);
+  } elsif (!(-r $file)) {
+    printf("The file \"%s\" is not readable.\n", $file);
+    return (-1);
+  }
+
+  return (0);
+}
+
+#
+# decode_options()
+#
+# Description:
+#   This routine steps through the command-line arguments, parsing out
+#   recognzied options.
+#
+# Input(s):
+#   N/A
+#
+# Output(s):
+#   N/A
+#
+# Returns:
+#   N/A
+#
+
+sub decode_options {
+
+  if (!getopts("hlvV")) {
+    usage(1);
+  }
+
+  if ($opt_h) {
+    usage(0);
+  }
+
+  if ($opt_l) {
+    $linux = 1;
+  }
+
+  if ($opt_V) {
+    version();
+    exit (0);
+  }
+
+  if ($opt_v) {
+    $verbose = 1;
+  }
+
+  if (!($ifile = shift(@ARGV))) {
+    usage(1);
+  }
+
+  if (!($ofile = shift(@ARGV))) {
+    usage (1);
+  }
+
+  if (file_check($ifile)) {
+    exit(1);
+  }
+
+}
+
+#
+# ELF file and section header field numbers
+#
+
+require 'elf.pl';
+
+#
+# Main program body
+#
+
+{
+  $program = basename($0);
+
+  decode_options();
+
+  open(ELF, "<$ifile") || die "Cannot open input file";
+
+  $ifilesize = (-s $ifile);
+
+  if ($verbose) {
+    print("Output file: $ofile\n");
+    print("Input file: $ifile, $ifilesize bytes.\n");
+  }
+
+  if (read(ELF, $ibuf, $ifilesize) != $ifilesize) {
+    print("Failed to read input file!\n");
+    exit(1);
+  }
+
+  # 
+  # Parse ELF header
+  #
+
+  @eh = unpack("a16n2N5n6", $ibuf);
+
+  #
+  # Make sure this is actually a PowerPC ELF file.
+  #
+
+  if (substr($eh[$e_ident], 0, 4) ne "\177ELF") {
+    printf("The file \"%s\" is not an ELF file.\n", $ifile);
+    exit (1);
+  } elsif ($eh[$e_machine] != 20) {
+    printf("The file \"%s\" is not a PowerPC ELF file.\n", $ifile);
+    exit (1);
+  }
+
+  if ($verbose) {
+    print("File header:\n");
+    printf("  Identifier:            %s\n",	$eh[$e_ident]);
+    printf("  Type:                  %d\n",	$eh[$e_type]);
+    printf("  Machine:               %d\n",	$eh[$e_machine]);
+    printf("  Version:               %d\n",	$eh[$e_version]);
+    printf("  Entry point:           0x%08x\n", $eh[$e_entry]);
+    printf("  Program header offset: 0x%x\n",	$eh[$e_phoff]);
+    printf("  Section header offset: 0x%x\n",	$eh[$e_shoff]);
+    printf("  Flags:                 0x%08x\n", $eh[$e_flags]);
+    printf("  Header size:           %d\n", $eh[$e_ehsize]);
+    printf("  Program entry size:    %d\n", $eh[$e_phentsize]);
+    printf("  Program table entries: %d\n", $eh[$e_phnum]);
+    printf("  Section header size:   %d\n", $eh[$e_shentsize]);
+    printf("  Section table entries: %d\n", $eh[$e_shnum]);
+    printf("  String table section:  %d\n", $eh[$e_shstrndx]);
+  }
+
+  #
+  # Find the section header for the string table.
+  #
+
+  $strtable_section_offset =  $eh[$e_shoff] +
+    $eh[$e_shstrndx] * $eh[$e_shentsize];
+
+  if ($verbose) {
+    printf("String table section header offset: 0x%x\n",
+	   $strtable_section_offset);
+  }
+  
+  #
+  # Find the start of the string table.
+  #
+
+  @strh = unpack("N10", substr($ibuf, $strtable_section_offset, 
+			       $eh[$e_shentsize]));
+
+  if ($verbose) {
+    printf("Section name strings start at: 0x%x, %d bytes.\n",
+	   $strh[$sh_offset], $strh[$sh_size]);
+  }
+
+  $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]);
+
+  # Grab each section header and find '.text' and '.bss' sections in
+  # particular.
+
+  if ($verbose) {
+  print("Section headers:\n");
+  print("Idx  Name                      Size      Address   File off  Algn\n");
+  print("---  ------------------------  --------  --------  --------  ----\n");
+  }
+
+  $off = $eh[$e_shoff];
+
+  for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) {
+    @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize]));
+
+    # Take the first section name from the array returned by split.
+
+    ($name) = split(/\000/, substr($names, $sh[$sh_name]));
+    
+    if ($verbose) {
+      printf("%3d  %-24s  %8x  %08x  %08x  %4d\n", 
+	     $i, $name, $sh[$sh_size], $sh[$sh_addr], 
+	     $sh[$sh_offset], $sh[$sh_addralign]);
+    }
+
+    # Attempt to find the .text and .bss sections
+
+    if ($name =~ /^\.bss$/) {
+      ($bss_addr, $bss_offset, $bss_size) =
+	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+    } elsif ($name =~ /^\.text$/) {
+      ($text_addr, $text_offset, $text_size) = 
+	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+    } elsif ($linux && ($name =~ /^\image$/)) {
+      $image_found = 1;
+
+      ($image_addr, $image_offset, $image_size) = 
+	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+    } elsif ($linux && ($name =~ /^\initrd$/)) {
+      $initrd_found = 1;
+
+      ($initrd_addr, $initrd_offset, $initrd_size) = 
+	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+    }
+  }
+
+  printf("Text section   - Address: 0x%08x, Size: 0x%08x\n",
+	 $text_addr, $text_size);
+  printf("Bss  section   - Address: 0x%08x, Size: 0x%08x\n",
+	 $bss_addr, $bss_size);
+
+  if ($linux) {
+    if ($image_found) {
+      printf("Image section  - Address: 0x%08x, Size: 0x%08x\n",
+	     $image_addr, $image_size);
+    }
+
+    if ($initrd_found) {
+      printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n",
+	     $initrd_addr, $initrd_size);
+    }
+  }
+
+  #
+  # Open output file
+  #
+
+  open(BOOT, ">$ofile") || die "Cannot open output file";
+
+  #
+  # Compute image size
+  #
+
+  $output_size = $bss_offset - $text_offset + $bss_size;
+
+  if ($linux && $image_found) {
+    $output_size += $image_size;
+  }
+
+  if ($linux && $initrd_found) {
+    $output_size += $initrd_size;
+  }
+
+  $num_blocks = $output_size / 512 + 1;
+
+  #
+  # Write IBM PowerPC evaluation board boot_block_t header
+  #
+
+  $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0,
+		 $text_addr, 0, 0, 0);
+
+  $bytes = length($header);
+  
+  if (($resid = syswrite(BOOT, $header, $bytes)) != $bytes) {
+    die("Could not write boot image header to output file.");
+  }
+
+  printf("Entry point = 0x%08x\n", $text_addr);
+  printf("Image size  = 0x%08x (%d bytes) (%d blocks).\n", 
+	 $output_size, $output_size, $num_blocks);
+
+  #
+  # Write image starting after ELF and program headers and 
+  # continuing to beginning of bss
+  #
+
+  $bytes = $bss_offset - $text_offset + $bss_size;
+
+  if (($resid = syswrite(BOOT, $ibuf, $bytes, $text_offset)) != $bytes) {
+    die("Could not write boot image to output file.\n");
+  }
+
+  #
+  # If configured, write out the image and initrd sections as well
+  #
+
+  if ($linux) {
+    if ($image_found) {
+      $bytes = $image_size;
+      if (($resid = syswrite(BOOT, $ibuf, $bytes, $image_offset)) != $bytes) {
+	die("Could not write boot image to output file.\n");
+      }
+    }
+
+    if ($initrd_found) {
+      $bytes = $initrd_size;
+      if (($resid = syswrite(BOOT, $ibuf, $bytes, $initrd_offset)) != $bytes) {
+	die("Could not write boot image to output file.\n");
+      }
+    }
+  }
+
+  #
+  # Pad to a multiple of 512 bytes
+  #
+
+  $pad_size = 512 - (length($header) + $output_size) % 512;
+
+  if ($verbose) {
+    print("Padding boot image by an additional $pad_size bytes.\n");
+  }
+
+  $pad_string = pack(("H8","deadbeef") x 128);
+
+  syswrite(BOOT, $pad_string, $pad_size) or
+    die "Could not pad boot image in output file.\n";
+
+  #
+  # Clean-up and leave
+  #
+
+  close(BOOT);
+
+  print("\nBoot image file \"$ofile\" built successfuly.\n\n");
+
+  exit(0);
+}
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/treeboot/mkirimg linux/arch/ppc/treeboot/mkirimg
--- v2.3.29/linux/arch/ppc/treeboot/mkirimg	Wed Dec 31 16:00:00 1969
+++ linux/arch/ppc/treeboot/mkirimg	Sat Nov 27 15:41:59 1999
@@ -0,0 +1,367 @@
+#!/usr/local/bin/perl
+#
+#    Copyright (c) 1998-1999 TiVo, Inc.
+#      Original ELF parsing code.
+#
+#    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+#      Original code from 'mkevimg'.
+#
+#    Module name: mkirimg
+#
+#    Description:
+#      Reads an ELF file and assigns global variables 'imageSect_start',
+#      'imageSect_size', 'initrdSect_start', and 'initrdSect_size' from
+#      the "image" and "initrd" section header information. It then
+#      rewrites the input ELF file with assigned globals to an output
+#      file.
+#
+#      An input file, "irSectStart.txt" has the memory address of
+#      'irSectStart'. The irSectStart memory address is used to find
+#      the global variables in the ".data" section of the ELF file.
+#      The 'irSectStart' and the above global variables are defined
+#      in "irSect.c".
+#
+#
+
+use File::Basename;
+use Getopt::Std;
+
+#
+# usage()
+#
+# Description:
+#   This routine prints out the proper command line usage for this program
+#
+# Input(s):
+#   status - Flag determining what usage information will be printed and what
+#            the exit status of the program will be after the information is
+#            printed.
+#
+# Output(s):
+#   N/A
+#
+# Returns:
+#   This subroutine does not return.
+#
+
+sub usage {
+  my($status);
+  $status = $_[0];
+
+  printf("Usage: %s [-hvV] <ELF input file> <Evaluation board output file> <irSectStart.txt file>\n",
+	 $program);
+
+  if ($status != 0) {
+    printf("Try `%s -h' for more information.\n", $program);
+  }
+
+  if ($status != 1) {
+    print("  -h             Print out this message and exit.\n");
+    print("  -v             Verbose. Print out lots of ELF information.\n");
+    print("  -V             Print out version information and exit.\n");
+  }
+
+  exit($status);
+}
+
+#
+# version()
+#
+# Description:
+#   This routine prints out program version information
+#
+# Input(s):
+#   N/A
+#
+# Output(s):
+#   N/A
+#
+# Returns:
+#   This subroutine does not return.
+#
+
+sub version {
+  print("mkirimg Version 1.1.0\n");
+  print("Copyright (c) 1998-1999 TiVo, Inc.\n");
+  print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n");
+
+  exit (0);
+}
+
+#
+# file_check()
+#
+# Description:
+#   This routine checks an input file to ensure that it exists, is a
+#   regular file, and is readable.
+#
+# Input(s):
+#   file - Input file to be checked.
+#
+# Output(s):
+#   N/A
+#
+# Returns:
+#   0 if the file exists, is a regular file, and is readable, otherwise -1.
+#
+
+sub file_check {
+  my($file);
+  $file = $_[0];
+
+  if (!(-e $file)) {
+     printf("The file \"%s\" does not exist.\n", $file);
+     return (-1);
+  } elsif (!(-f $file)) {
+     printf("The file \"%s\" is not a regular file.\n", $file);
+     return (-1);
+  } elsif (!(-r $file)) {
+     printf("The file \"%s\" is not readable.\n", $file);
+     return (-1);
+  }
+
+  return (0);
+}
+
+#
+# decode_options()
+#
+# Description:
+#   This routine steps through the command-line arguments, parsing out
+#   recognzied options.
+#
+# Input(s):
+#   N/A
+#
+# Output(s):
+#   N/A
+#
+# Returns:
+#   N/A
+#
+
+sub decode_options {
+
+  if (!getopts("hvV")) {
+      usage(1);
+  }
+
+  if ($opt_h) {
+      usage(0);
+  }
+
+  if ($opt_V) {
+      version();
+      exit (0);
+  }
+
+  if ($opt_v) {
+      $verbose = 1;
+  }
+
+  if (!($ElfFile = shift(@ARGV))) {
+      usage(1);
+  }
+
+  if (!($OutputFile = shift(@ARGV))) {
+      usage (1);
+  }
+
+  if (!($IrFile = shift(@ARGV))) {
+      usage (1);
+  }
+
+  if (file_check($ElfFile)) {
+      exit(1);
+  }
+
+  if (file_check($IrFile)) {
+      exit(1);
+  }
+}
+
+#
+# ELF file and section header field numbers
+#
+
+require 'elf.pl';
+
+#
+# Main program body
+#
+
+{
+  $program = basename($0);
+  decode_options();
+
+  open(ELF, "<$ElfFile") || die "Cannot open input file";
+  open(OUTPUT, ">$OutputFile") || die "Cannot open output file";
+  open(IR, "$IrFile") || die "Cannot open input file";
+
+  $ElfFilesize = (-s $ElfFile);
+
+  if (read(ELF, $ibuf, $ElfFilesize) != $ElfFilesize) {
+    print("Failed to read ELF input file!\n");
+    exit(1);
+  }
+
+  if (read(IR, $irbuf, 8) != 8) {
+      print("Failed to read Ir input file!\n");
+      exit(1);
+  }
+
+  #
+  # Parse ELF header
+  #
+
+  @eh = unpack("a16n2N5n6", $ibuf);
+
+  #
+  # Make sure this is actually a PowerPC ELF file.
+  #
+
+  if (substr($eh[$e_ident], 0, 4) ne "\177ELF") {
+      printf("The file \"%s\" is not an ELF file.\n", $ElfFile);
+      exit (1);
+  } elsif ($eh[$e_machine] != 20) {
+      printf("The file \"%s\" is not a PowerPC ELF file.\n", $ElfFile);
+      exit (1);
+  }
+
+  #
+  # Find the section header for the string table.
+  #
+
+  $strtable_section_offset =  $eh[$e_shoff] +
+
+  $eh[$e_shstrndx] * $eh[$e_shentsize];
+
+  if ($verbose) {
+     printf("String table section header offset: 0x%x\n",
+     $strtable_section_offset);
+  }
+
+  #
+  # Find the start of the string table.
+  #
+
+  @strh = unpack("N10", substr($ibuf, $strtable_section_offset,
+			       $eh[$e_shentsize]));
+
+  if ($verbose) {
+     printf("Section name strings start at: 0x%x, %d bytes.\n",
+     $strh[$sh_offset], $strh[$sh_size]);
+  }
+
+  $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]);
+
+  # Grab each section header and find '.data', 'image', and 
+  # 'initrd' sections in particular.
+
+  $off = $eh[$e_shoff];
+  $imageFound = 0;
+  $initrdFound = 0;
+  
+  for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) {
+    @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize]));
+
+    # Take the first section name from the array returned by split.
+
+    ($name) = split(/\000/, substr($names, $sh[$sh_name]));
+
+    # Attempt to find the .data, image, and initrd sections
+
+    if ($name =~ /^\image$/) {
+      ($image_addr, $image_offset, $image_size) =
+	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+      $imageFound = 1;
+
+    } elsif ($name =~ /^\initrd$/) {
+      ($initrd_addr, $initrd_offset, $initrd_size) =
+	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+      $initrdFound = 1;
+
+    } elsif ($name =~ /^\.data$/) {
+      ($data_addr, $data_offset, $data_size) =
+	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+    } elsif ($name =~ /^\.bss$/) {
+      ($bss_addr, $bss_offset, $bss_size) =
+	($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+    }
+   }
+
+  if ($verbose) {
+    printf("Data section   - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n",
+	   $data_addr, $data_size, $data_offset);
+    printf("Bss  section   - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n",
+	 $bss_addr, $bss_size, $bss_offset);
+   }
+
+  if ($verbose) {
+    if ($imageFound) {
+      printf("Image section  - Address: 0x%08x, Size: 0x%08x\n",
+	     $image_addr, $image_size);
+    } else {
+      printf("Image section not found in file: $ElfFile\n");
+    }
+
+    if ($initrdFound) {
+      printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n",
+	     $initrd_addr, $initrd_size);
+    } else {
+      printf("Initrd section not found in file: $ElfFile\n");
+    }
+  }
+
+  # get file offset of irSectStart
+
+  $irSectStartoffset = hex ($irbuf);
+
+  if ($verbose) {
+    printf("irSectStartOffset Address: 0x%08x\n", $irSectStartoffset);
+  }
+
+  # get the offset of global variables 
+
+  $initialOffset = ($irSectStartoffset - $data_addr) + $data_offset + 4;
+
+  # write modified values to OUTPUT file
+
+  syswrite(OUTPUT, $ibuf, $initialOffset);
+
+  if ($imageFound) {
+    $testN = pack ("I2", $bss_addr + $bss_size, $image_size);
+    syswrite(OUTPUT, $testN, length($testN));
+    printf("Updated symbol \"imageSect_start\" to 0x%08x\n",
+	   $bss_addr + $bss_size);
+    printf("Updated symbol \"imageSect_size\" to 0x%08x\n", $image_size);
+  } else {
+    syswrite(OUTPUT, $ibuf, 8, $initialOffset);
+  }
+
+  if ($initrdFound) {
+    $testN = pack ("I2", $bss_addr + $bss_size + $image_size, $initrd_size);
+    syswrite(OUTPUT, $testN, length($testN));
+    printf("Updated symbol \"initrdSect_start\" to 0x%08x\n",
+	   $bss_addr + $bss_size + $image_size);
+    printf("Updated symbol \"initrdSect_size\" to 0x%08x\n", $initrd_size);
+  } else {
+    syswrite(OUTPUT, $ibuf,8, $initialOffset + 8);
+  }
+
+  syswrite(OUTPUT, $ibuf, $ElfFilesize - ($initialOffset + 16),
+	   $initialOffset + 16);
+
+  #
+  # Clean-up and leave
+  #
+
+  close (ELF);
+  close (OUTPUT);
+  close (IR);
+
+  exit (0);
+}
+
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/xmon/ppc-opc.c linux/arch/ppc/xmon/ppc-opc.c
--- v2.3.29/linux/arch/ppc/xmon/ppc-opc.c	Sat May 22 13:03:00 1999
+++ linux/arch/ppc/xmon/ppc-opc.c	Sat Nov 27 15:41:59 1999
@@ -533,8 +533,7 @@
 /* Check for legal values of a BO field.  */
 
 static int
-valid_bo (value)
-     long value;
+valid_bo (long value)
 {
   /* Certain encodings have bits that are required to be zero.  These
      are (z must be zero, y may be anything):
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/xmon/privinst.h linux/arch/ppc/xmon/privinst.h
--- v2.3.29/linux/arch/ppc/xmon/privinst.h	Sat May 22 13:03:00 1999
+++ linux/arch/ppc/xmon/privinst.h	Thu Dec  2 14:37:34 1999
@@ -70,4 +70,13 @@
     asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
 }
 
+static inline void cflush(void *p)
+{
+    asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
+}
+
+static inline void cinval(void *p)
+{
+    asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
+}
 
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/xmon/start.c linux/arch/ppc/xmon/start.c
--- v2.3.29/linux/arch/ppc/xmon/start.c	Sat Oct  9 11:47:50 1999
+++ linux/arch/ppc/xmon/start.c	Thu Dec  2 14:37:34 1999
@@ -6,11 +6,11 @@
 #include <asm/machdep.h>
 #include <asm/io.h>
 #include <asm/page.h>
-#include <asm/pgtable.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <asm/prom.h>
 #include <asm/bootx.h>
+#include <asm/processor.h>
 
 static volatile unsigned char *sccc, *sccd;
 unsigned long TXRDY, RXRDY;
@@ -41,7 +41,7 @@
 
 #ifdef CONFIG_BOOTX_TEXT
 		if (boot_infos != 0 && find_via_pmu()) {
-			printk(KERN_INFO "xmon uses screen and keyboard\n");
+			printk("xmon uses screen and keyboard\n");
 			use_screen = 1;
 			map_bootx_text();
 			return;
diff -u --recursive --new-file v2.3.29/linux/arch/ppc/xmon/xmon.c linux/arch/ppc/xmon/xmon.c
--- v2.3.29/linux/arch/ppc/xmon/xmon.c	Tue Aug 31 17:29:13 1999
+++ linux/arch/ppc/xmon/xmon.c	Thu Dec  2 14:37:34 1999
@@ -79,6 +79,7 @@
 static void insert_bpts(void);
 static struct bpt *at_breakpoint(unsigned pc);
 static void bpt_cmds(void);
+static void cacheflush(void);
 
 extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned);
 extern void printf(const char *fmt, ...);
@@ -342,11 +343,9 @@
 		case 't':
 			backtrace(excp);
 			break;
-#if 0
 		case 'f':
-			openforth();
+			cacheflush();
 			break;
-#endif
 		case 'h':
 			dump_hash_table();
 			break;
@@ -539,6 +538,30 @@
 	       fp->nip, fp->msr, fp->link, fp->ccr);
 	printf("ctr = %.8x   xer = %.8x   trap = %4x\n",
 	       fp->ctr, fp->xer, fp->trap);
+}
+
+void
+cacheflush(void)
+{
+	int cmd;
+	unsigned nflush;
+
+	cmd = inchar();
+	if (cmd != 'i')
+		termch = cmd;
+	scanhex(&adrs);
+	if (termch != '\n')
+		termch = 0;
+	nflush = 1;
+	scanhex(&nflush);
+	nflush = (nflush + 31) / 32;
+	if (cmd != 'i') {
+		for (; nflush > 0; --nflush, adrs += 0x20)
+			cflush((void *) adrs);
+	} else {
+		for (; nflush > 0; --nflush, adrs += 0x20)
+			cinval((void *) adrs);
+	}
 }
 
 unsigned int
diff -u --recursive --new-file v2.3.29/linux/arch/sparc/math-emu/math.c linux/arch/sparc/math-emu/math.c
--- v2.3.29/linux/arch/sparc/math-emu/math.c	Tue Aug 31 17:29:13 1999
+++ linux/arch/sparc/math-emu/math.c	Thu Dec  2 15:28:54 1999
@@ -70,10 +70,10 @@
 #include <asm/uaccess.h>
 
 #include "sfp-util.h"
-#include "soft-fp.h"
-#include "single.h"
-#include "double.h"
-#include "quad.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+#include <math-emu/double.h>
+#include <math-emu/quad.h>
 
 #define FLOATFUNC(x) extern int x(void *,void *,void *)
 
diff -u --recursive --new-file v2.3.29/linux/arch/sparc/math-emu/sfp-machine.h linux/arch/sparc/math-emu/sfp-machine.h
--- v2.3.29/linux/arch/sparc/math-emu/sfp-machine.h	Tue Aug 31 17:29:13 1999
+++ linux/arch/sparc/math-emu/sfp-machine.h	Wed Dec 31 16:00:00 1969
@@ -1,205 +0,0 @@
-/* Machine-dependent software floating-point definitions.
-   Sparc userland (_Q_*) version.
-   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Richard Henderson (rth@cygnus.com),
-		  Jakub Jelinek (jj@ultra.linux.cz),
-		  David S. Miller (davem@redhat.com) and
-		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If
-   not, write to the Free Software Foundation, Inc.,
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#ifndef _SFP_MACHINE_H
-#define _SFP_MACHINE_H
-   
-#define _FP_W_TYPE_SIZE		32
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-#define _FP_MUL_MEAT_S(R,X,Y)					\
-  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_D(R,X,Y)					\
-  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_Q(R,X,Y)					\
-  _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
-#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
-#define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_4_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
-#define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1), -1
-#define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
-#define _FP_NANSIGN_S		0
-#define _FP_NANSIGN_D		0
-#define _FP_NANSIGN_Q		0
-
-#define _FP_KEEPNANFRACP 1
-
-/* If one NaN is signaling and the other is not,
- * we choose that one, otherwise we choose X.
- */
-/* For _Qp_* and _Q_*, this should prefer X, for
- * CPU instruction emulation this should prefer Y.
- * (see SPAMv9 B.2.2 section).
- */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)		\
-	&& !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))	\
-      {								\
-	R##_s = X##_s;						\
-	_FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-	_FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-/* Some assembly to speed things up. */
-#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
-  __asm__ ("addcc %r7,%8,%2
-	    addxcc %r5,%6,%1
-	    addx %r3,%4,%0"						\
-	   : "=r" ((USItype)(r2)),					\
-	     "=&r" ((USItype)(r1)),					\
-	     "=&r" ((USItype)(r0))					\
-	   : "%rJ" ((USItype)(x2)),					\
-	     "rI" ((USItype)(y2)),					\
-	     "%rJ" ((USItype)(x1)),					\
-	     "rI" ((USItype)(y1)),					\
-	     "%rJ" ((USItype)(x0)),					\
-	     "rI" ((USItype)(y0))					\
-	   : "cc")
-
-#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
-  __asm__ ("subcc %r7,%8,%2
-	    subxcc %r5,%6,%1
-	    subx %r3,%4,%0"						\
-	   : "=r" ((USItype)(r2)),					\
-	     "=&r" ((USItype)(r1)),					\
-	     "=&r" ((USItype)(r0))					\
-	   : "%rJ" ((USItype)(x2)),					\
-	     "rI" ((USItype)(y2)),					\
-	     "%rJ" ((USItype)(x1)),					\
-	     "rI" ((USItype)(y1)),					\
-	     "%rJ" ((USItype)(x0)),					\
-	     "rI" ((USItype)(y0))					\
-	   : "cc")
-
-#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
-  do {									\
-    /* We need to fool gcc,  as we need to pass more than 10		\
-       input/outputs.  */						\
-    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");		\
-    __asm__ __volatile__ ("
-	    addcc %r8,%9,%1
-	    addxcc %r6,%7,%0
-	    addxcc %r4,%5,%%g2
-	    addx %r2,%3,%%g1"						\
-	   : "=&r" ((USItype)(r1)),					\
-	     "=&r" ((USItype)(r0))					\
-	   : "%rJ" ((USItype)(x3)),					\
-	     "rI" ((USItype)(y3)),					\
-	     "%rJ" ((USItype)(x2)),					\
-	     "rI" ((USItype)(y2)),					\
-	     "%rJ" ((USItype)(x1)),					\
-	     "rI" ((USItype)(y1)),					\
-	     "%rJ" ((USItype)(x0)),					\
-	     "rI" ((USItype)(y0))					\
-	   : "cc", "g1", "g2");						\
-    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));			\
-    r3 = _t1; r2 = _t2;							\
-  } while (0)
-
-#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
-  do {									\
-    /* We need to fool gcc,  as we need to pass more than 10		\
-       input/outputs.  */						\
-    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");		\
-    __asm__ __volatile__ ("
-	    subcc %r8,%9,%1
-	    subxcc %r6,%7,%0
-	    subxcc %r4,%5,%%g2
-	    subx %r2,%3,%%g1"						\
-	   : "=&r" ((USItype)(r1)),					\
-	     "=&r" ((USItype)(r0))					\
-	   : "%rJ" ((USItype)(x3)),					\
-	     "rI" ((USItype)(y3)),					\
-	     "%rJ" ((USItype)(x2)),					\
-	     "rI" ((USItype)(y2)),					\
-	     "%rJ" ((USItype)(x1)),					\
-	     "rI" ((USItype)(y1)),					\
-	     "%rJ" ((USItype)(x0)),					\
-	     "rI" ((USItype)(y0))					\
-	   : "cc", "g1", "g2");						\
-    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));			\
-    r3 = _t1; r2 = _t2;							\
-  } while (0)
-
-#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0)
-
-#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0)
-
-#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)					\
-  __asm__ ("addcc %3,%4,%3
-	    addxcc %2,%%g0,%2
-	    addxcc %1,%%g0,%1
-	    addx %0,%%g0,%0"						\
-	   : "=&r" ((USItype)(x3)),					\
-	     "=&r" ((USItype)(x2)),					\
-	     "=&r" ((USItype)(x1)),					\
-	     "=&r" ((USItype)(x0))					\
-	   : "rI" ((USItype)(i)),					\
-	     "0" ((USItype)(x3)),					\
-	     "1" ((USItype)(x2)),					\
-	     "2" ((USItype)(x1)),					\
-	     "3" ((USItype)(x0))					\
-	   : "cc")
-
-#ifndef __SMP__
-extern struct task_struct *last_task_used_math;
-#endif
-
-/* Obtain the current rounding mode. */
-#ifndef FP_ROUNDMODE
-#ifdef __SMP__
-#define FP_ROUNDMODE	((current->thread.fsr >> 30) & 0x3)
-#else
-#define FP_ROUNDMODE	((last_task_used_math->thread.fsr >> 30) & 0x3)
-#endif
-#endif
-
-/* Exception flags. */
-#define FP_EX_INVALID		(1 << 4)
-#define FP_EX_OVERFLOW		(1 << 3)
-#define FP_EX_UNDERFLOW		(1 << 2)
-#define FP_EX_DIVZERO		(1 << 1)
-#define FP_EX_INEXACT		(1 << 0)
-
-#define FP_HANDLE_EXCEPTIONS return _fex
-
-#ifdef __SMP__
-#define FP_INHIBIT_RESULTS ((current->thread.fsr >> 23) & _fex)
-#else
-#define FP_INHIBIT_RESULTS ((last_task_used_math->thread.fsr >> 23) & _fex)
-#endif
-
-#endif
diff -u --recursive --new-file v2.3.29/linux/arch/sparc/mm/generic.c linux/arch/sparc/mm/generic.c
--- v2.3.29/linux/arch/sparc/mm/generic.c	Mon Nov 16 10:37:28 1998
+++ linux/arch/sparc/mm/generic.c	Mon Dec  6 10:17:31 1999
@@ -91,7 +91,9 @@
 		pte_t * pte = pte_alloc(pmd, address);
 		if (!pte)
 			return -ENOMEM;
+		spin_lock(&current->mm->page_table_lock);
 		io_remap_pte_range(pte, address, end - address, address + offset, prot, space);
+		spin_unlock(&current->mm->page_table_lock);
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
 	} while (address < end);
diff -u --recursive --new-file v2.3.29/linux/arch/sparc64/math-emu/math.c linux/arch/sparc64/math-emu/math.c
--- v2.3.29/linux/arch/sparc64/math-emu/math.c	Tue Aug 31 17:29:13 1999
+++ linux/arch/sparc64/math-emu/math.c	Thu Dec  2 15:28:54 1999
@@ -16,10 +16,10 @@
 #include <asm/uaccess.h>
 
 #include "sfp-util.h"
-#include "soft-fp.h"
-#include "single.h"
-#include "double.h"
-#include "quad.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+#include <math-emu/double.h>
+#include <math-emu/quad.h>
 
 /* QUAD - ftt == 3 */
 #define FMOVQ	0x003
diff -u --recursive --new-file v2.3.29/linux/arch/sparc64/math-emu/sfp-machine.h linux/arch/sparc64/math-emu/sfp-machine.h
--- v2.3.29/linux/arch/sparc64/math-emu/sfp-machine.h	Mon Aug  2 22:07:16 1999
+++ linux/arch/sparc64/math-emu/sfp-machine.h	Wed Dec 31 16:00:00 1969
@@ -1,91 +0,0 @@
-/* Machine-dependent software floating-point definitions.
-   Sparc64 kernel version.
-   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Richard Henderson (rth@cygnus.com),
-		  Jakub Jelinek (jj@ultra.linux.cz) and
-		  David S. Miller (davem@redhat.com).
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If
-   not, write to the Free Software Foundation, Inc.,
-   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
-
-#ifndef _SFP_MACHINE_H
-#define _SFP_MACHINE_H
-   
-#define _FP_W_TYPE_SIZE		64
-#define _FP_W_TYPE		unsigned long
-#define _FP_WS_TYPE		signed long
-#define _FP_I_TYPE		long
-
-#define _FP_MUL_MEAT_S(R,X,Y)					\
-  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
-#define _FP_MUL_MEAT_D(R,X,Y)					\
-  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_Q(R,X,Y)					\
-  _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
-#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_1_udiv(D,R,X,Y)
-#define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
-#define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1)
-#define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1
-#define _FP_NANSIGN_S		0
-#define _FP_NANSIGN_D		0
-#define _FP_NANSIGN_Q		0
-
-#define _FP_KEEPNANFRACP 1
-
-/* If one NaN is signaling and the other is not,
- * we choose that one, otherwise we choose X.
- */
-/* For _Qp_* and _Q_*, this should prefer X, for
- * CPU instruction emulation this should prefer Y.
- * (see SPAMv9 B.2.2 section).
- */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
-  do {								\
-    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)		\
-	&& !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))	\
-      {								\
-	R##_s = X##_s;						\
-	_FP_FRAC_COPY_##wc(R,X);				\
-      }								\
-    else							\
-      {								\
-	R##_s = Y##_s;						\
-	_FP_FRAC_COPY_##wc(R,Y);				\
-      }								\
-    R##_c = FP_CLS_NAN;						\
-  } while (0)
-
-/* Obtain the current rounding mode. */
-#ifndef FP_ROUNDMODE
-#define FP_ROUNDMODE	((current->thread.xfsr[0] >> 30) & 0x3)
-#endif
-
-/* Exception flags. */
-#define FP_EX_INVALID		(1 << 4)
-#define FP_EX_OVERFLOW		(1 << 3)
-#define FP_EX_UNDERFLOW		(1 << 2)
-#define FP_EX_DIVZERO		(1 << 1)
-#define FP_EX_INEXACT		(1 << 0)
-
-#define FP_HANDLE_EXCEPTIONS return _fex
-
-#define FP_INHIBIT_RESULTS ((current->thread.xfsr[0] >> 23) & _fex)
-
-#endif
diff -u --recursive --new-file v2.3.29/linux/arch/sparc64/mm/generic.c linux/arch/sparc64/mm/generic.c
--- v2.3.29/linux/arch/sparc64/mm/generic.c	Mon Aug  2 22:07:16 1999
+++ linux/arch/sparc64/mm/generic.c	Mon Dec  6 10:17:31 1999
@@ -127,7 +127,9 @@
 		pte_t * pte = pte_alloc(pmd, address);
 		if (!pte)
 			return -ENOMEM;
+		spin_lock(&current->mm->page_table_lock);
 		io_remap_pte_range(pte, address, end - address, address + offset, prot, space);
+		spin_unlock(&current->mm->page_table_lock);
 		address = (address + PMD_SIZE) & PMD_MASK;
 		pmd++;
 	} while (address < end);
diff -u --recursive --new-file v2.3.29/linux/drivers/acorn/char/serial-atomwide.c linux/drivers/acorn/char/serial-atomwide.c
--- v2.3.29/linux/drivers/acorn/char/serial-atomwide.c	Fri May  8 00:42:38 1998
+++ linux/drivers/acorn/char/serial-atomwide.c	Thu Dec  2 15:41:02 1999
@@ -12,9 +12,12 @@
 #define MY_CARD_LIST { MANU_ATOMWIDE, PROD_ATOMWIDE_3PSERIAL }
 #define MY_NUMPORTS 3
 #define MY_BAUD_BASE (7372800 / 16)
-#define MY_INIT atomwide_serial_init
 #define MY_BASE_ADDRESS(ec) \
 	ecard_address ((ec), ECARD_IOC, ECARD_SLOW) + (0x2000 >> 2)
 #define MY_PORT_ADDRESS(port,cardaddr) \
 	((cardaddr) + 0x200 - (port) * 0x100)
+
+#define INIT serial_card_atomwide_init
+#define EXIT serial_card_atomwide_exit
+
 #include "serial-card.c"
diff -u --recursive --new-file v2.3.29/linux/drivers/acorn/char/serial-card.c linux/drivers/acorn/char/serial-card.c
--- v2.3.29/linux/drivers/acorn/char/serial-card.c	Tue Nov 23 22:42:20 1999
+++ linux/drivers/acorn/char/serial-card.c	Thu Dec  2 15:41:02 1999
@@ -1,7 +1,7 @@
 /*
  * linux/arch/arm/drivers/char/serial-card.c
  *
- * Copyright (c) 1996 Russell King.
+ * Copyright (c) 1996-1999 Russell King.
  *
  * A generic handler of serial expansion cards that use 16550s or
  * the like.
@@ -22,9 +22,13 @@
  *  22-04-1998	RMK	Removed old register_pre_init_serial
  */
 #include <linux/module.h>
+#include <linux/types.h>
 #include <linux/serial.h>
 #include <linux/errno.h>
+#include <linux/init.h>
+
 #include <asm/ecard.h>
+#include <asm/string.h>
 
 #ifndef NUM_SERIALS
 #define NUM_SERIALS	MY_NUMPORTS * MAX_ECARDS
@@ -42,8 +46,6 @@
 		__serial_addr[__serial_pcount] = (addr);	\
 		__serial_pcount += 1;				\
 	} while (0)
-#undef MY_INIT
-#define MY_INIT init_module
 #else
 #define ADD_ECARD(ec,card)
 #define ADD_PORT(port,addr)
@@ -55,8 +57,7 @@
 {
     struct serial_struct req;
 
-    memset(&req, 0, sizeof(serial_struct));
-
+    memset(&req, 0, sizeof(req));
     req.baud_base = MY_BAUD_BASE;
     req.irq = irq;
     req.port = port;
@@ -65,7 +66,7 @@
     return register_serial(&req);
 }
 
-int MY_INIT (void)
+static int __init INIT (void)
 {
     int card = 0;
 
@@ -103,9 +104,9 @@
     return card ? 0 : -ENODEV;
 }
 
-#ifdef MODULE
-void cleanup_module (void)
+static void __exit EXIT (void)
 {
+#ifdef MODULE
     int i;
 
     for (i = 0; i < __serial_pcount; i++) {
@@ -116,5 +117,10 @@
     for (i = 0; i < MAX_ECARDS; i++)
 	if (expcard[i])
 	    ecard_release (expcard[i]);
-}
 #endif
+}
+
+EXPORT_NO_SYMBOLS;
+
+module_init(INIT);
+module_exit(EXIT);
diff -u --recursive --new-file v2.3.29/linux/drivers/acorn/char/serial-dualsp.c linux/drivers/acorn/char/serial-dualsp.c
--- v2.3.29/linux/drivers/acorn/char/serial-dualsp.c	Sat Jul 18 11:55:24 1998
+++ linux/drivers/acorn/char/serial-dualsp.c	Thu Dec  2 15:41:02 1999
@@ -9,9 +9,12 @@
 #define MY_CARD_LIST { MANU_SERPORT, PROD_SERPORT_DSPORT }
 #define MY_NUMPORTS 2
 #define MY_BAUD_BASE (3686400 / 16)
-#define MY_INIT dualsp_serial_init
 #define MY_BASE_ADDRESS(ec) \
 	ecard_address (ec, ECARD_IOC, ECARD_SLOW) + (0x2000 >> 2)
 #define MY_PORT_ADDRESS(port,cardaddress) \
 	((cardaddress) + (port) * 8)
+
+#define INIT serial_card_dualsp_init
+#define EXIT serial_card_dualsp_exit
+
 #include "serial-card.c"
diff -u --recursive --new-file v2.3.29/linux/drivers/ap1000/ringbuf.c linux/drivers/ap1000/ringbuf.c
--- v2.3.29/linux/drivers/ap1000/ringbuf.c	Sun Jul  4 10:02:30 1999
+++ linux/drivers/ap1000/ringbuf.c	Sun Dec  5 08:42:03 1999
@@ -308,23 +308,4 @@
 
 struct inode_operations proc_ringbuf_inode_operations = {
 	&proc_ringbuf_operations,	/* default base directory file-ops */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* get_block */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* flushpage */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL,			/* smap */
-	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/drivers/block/DAC960.c linux/drivers/block/DAC960.c
--- v2.3.29/linux/drivers/block/DAC960.c	Tue Nov 23 22:42:20 1999
+++ linux/drivers/block/DAC960.c	Sat Nov 27 15:27:48 1999
@@ -3474,7 +3474,7 @@
 {
   static PROC_DirectoryEntry_T *StatusProcEntry;
   int ControllerNumber;
-  DAC960_ProcDirectoryEntry = create_proc_entry("driver/rd", S_IFDIR, NULL);
+  DAC960_ProcDirectoryEntry = proc_mkdir("driver/rd", NULL);
   StatusProcEntry = create_proc_read_entry("status", 0,
 					   DAC960_ProcDirectoryEntry,
 					   DAC960_ProcReadStatus, NULL);
diff -u --recursive --new-file v2.3.29/linux/drivers/block/cpqarray.c linux/drivers/block/cpqarray.c
--- v2.3.29/linux/drivers/block/cpqarray.c	Thu Nov 18 20:25:37 1999
+++ linux/drivers/block/cpqarray.c	Sat Nov 27 15:27:48 1999
@@ -223,7 +223,7 @@
 static void __init ida_procinit(int i)
 {
 	if (proc_array == NULL) {
-		proc_array = create_proc_entry("driver/array", S_IFDIR, NULL);
+		proc_array = proc_mkdir("driver/array", NULL);
 		if (!proc_array) return;
 	}
 
diff -u --recursive --new-file v2.3.29/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
--- v2.3.29/linux/drivers/block/ide-cd.c	Tue Nov 23 22:42:20 1999
+++ linux/drivers/block/ide-cd.c	Thu Dec  2 19:39:36 1999
@@ -665,7 +665,6 @@
 	struct packet_command *pc = (struct packet_command *) rq->buffer;
 	unsigned long wait = 0;
 
-	printk("in expiry\n");
 	/* blank and format can take an extremly long time to
 	 * complete, if the IMMED bit was not set.
 	 */
diff -u --recursive --new-file v2.3.29/linux/drivers/block/ide-features.c linux/drivers/block/ide-features.c
--- v2.3.29/linux/drivers/block/ide-features.c	Tue Nov 23 22:42:20 1999
+++ linux/drivers/block/ide-features.c	Fri Dec  3 10:55:09 1999
@@ -13,6 +13,7 @@
  *  Gadi Oxman    <gadio@netvision.net.il>
  */
 
+#define __NO_VERSION__
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/string.h>
diff -u --recursive --new-file v2.3.29/linux/drivers/block/ide-proc.c linux/drivers/block/ide-proc.c
--- v2.3.29/linux/drivers/block/ide-proc.c	Tue Nov 23 22:42:20 1999
+++ linux/drivers/block/ide-proc.c	Sat Nov 27 15:27:48 1999
@@ -684,7 +684,7 @@
 		if (drive->proc)
 			continue;
 
-		drive->proc = create_proc_entry(drive->name, S_IFDIR, parent);
+		drive->proc = proc_mkdir(drive->name, parent);
 		if (drive->proc) {
 			ide_add_proc_entries(drive->proc, generic_drive_entries, drive);
 			if (driver) {
@@ -731,16 +731,15 @@
 
 	for (h = 0; h < MAX_HWIFS; h++) {
 		ide_hwif_t *hwif = &ide_hwifs[h];
-		int exist = (hwif->proc != NULL);
 
 		if (!hwif->present)
 			continue;
-		if (!exist)
-			hwif->proc = create_proc_entry(hwif->name, S_IFDIR, proc_ide_root);
-		if (!hwif->proc)
-			return;
-		if (!exist)
+		if (!hwif->proc) {
+			hwif->proc = proc_mkdir(hwif->name, proc_ide_root);
+			if (!hwif->proc)
+				return;
 			ide_add_proc_entries(hwif->proc, hwif_entries, hwif);
+		}
 		create_proc_ide_drives(hwif);
 	}
 }
@@ -768,7 +767,7 @@
 
 void proc_ide_create(void)
 {
-	proc_ide_root = create_proc_entry("ide", S_IFDIR, 0);
+	proc_ide_root = proc_mkdir("ide", 0);
 	if (!proc_ide_root) return;
 
 	create_proc_ide_interfaces();
diff -u --recursive --new-file v2.3.29/linux/drivers/block/loop.c linux/drivers/block/loop.c
--- v2.3.29/linux/drivers/block/loop.c	Sun Nov  7 16:37:34 1999
+++ linux/drivers/block/loop.c	Mon Dec  6 16:24:48 1999
@@ -425,7 +425,7 @@
 		lo->lo_flags |= LO_FLAGS_READ_ONLY;
 		set_device_ro(dev, 1);
 	} else {
-		invalidate_inode_pages (inode);
+		vmtruncate (inode, 0);
 		set_device_ro(dev, 0);
 	}
 
diff -u --recursive --new-file v2.3.29/linux/drivers/block/md.c linux/drivers/block/md.c
--- v2.3.29/linux/drivers/block/md.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/block/md.c	Sat Nov 27 19:37:05 1999
@@ -1176,98 +1176,85 @@
 
 #ifdef CONFIG_MD_BOOT
 struct {
-	int set;
-	int ints[100];
-	char str[100];
+	unsigned long set;
+	int pers[MAX_MD_DEV];
+	kdev_t devices[MAX_MD_DEV][MAX_REAL];
 } md_setup_args __initdata = {
-	0,{0},{0}
+	0,{0},{{0}}
 };
 
-/* called from init/main.c */
-void __init md_setup(char *str,int *ints)
+/*
+ * Parse the command-line parameters given our kernel, but do not
+ * actually try to invoke the MD device now; that is handled by
+ * md_setup_drive after the low-level disk drivers have initialised.
+ *
+ * 27/11/1999: Fixed to work correctly with the 2.3 kernel (which
+ *             assigns the task of parsing integer arguments to the
+ *             invoked program now).  Added ability to initialise all
+ *             the MD devices (by specifying multiple "md=" lines)
+ *             instead of just one.  -- KTK
+ */
+int __init md_setup(char *str)
 {
-	int i;
-	for(i=0;i<=ints[0];i++) {
-		md_setup_args.ints[i] = ints[i];
-		strcpy(md_setup_args.str, str);
-/*      printk ("md: ints[%d]=%d.\n", i, ints[i]);*/
-	}
-	md_setup_args.set=1;
-	return;
-}
-
-void __init do_md_setup(char *str,int *ints)
-{
-	int minor, pers, factor, fault;
-	kdev_t dev;
-	int i=1;
-
-	if(ints[0] < 4) {
-		printk ("md: Too few Arguments (%d).\n", ints[0]);
-		return;
-	}
-   
-	minor=ints[i++];
-   
-	if (minor >= MAX_MD_DEV) {
+	int minor, level, factor, fault, i;
+	kdev_t device;
+	char *devnames, *pername;
+
+	if(get_option(&str, &minor) != 2 ||	/* MD Number */
+	   get_option(&str, &level) != 2 ||	/* RAID Personality */
+	   get_option(&str, &factor) != 2 ||	/* Chunk Size */
+	   get_option(&str, &fault) != 2) {
+		printk("md: Too few arguments supplied to md=.\n");
+		return 0;
+	} else if (minor >= MAX_MD_DEV) {
 		printk ("md: Minor device number too high.\n");
-		return;
+		return 0;
+	} else if (md_setup_args.set & (1 << minor)) {
+		printk ("md: Warning - md=%d,... has been specified twice;\n"
+			"    will discard the first definition.\n", minor);
 	}
-
-	pers = 0;
-	
-	switch(ints[i++]) {  /* Raidlevel  */
-	case -1:
+	switch(level) {
 #ifdef CONFIG_MD_LINEAR
-		pers = LINEAR;
-		printk ("md: Setting up md%d as linear device.\n",minor);
-#else 
-	        printk ("md: Linear mode not configured." 
-			"Recompile the kernel with linear mode enabled!\n");
-#endif
+	case -1:
+		level = LINEAR;
+		pername = "linear";
 		break;
-	case 0:
-		pers = STRIPED;
-#ifdef CONFIG_MD_STRIPED
-		printk ("md: Setting up md%d as a striped device.\n",minor);
-#else 
-	        printk ("md: Striped mode not configured." 
-			"Recompile the kernel with striped mode enabled!\n");
 #endif
+#ifdef CONFIG_MD_STRIPED
+	case 0:
+		level = STRIPED;
+		pername = "striped";
 		break;
-/*      not supported yet
-	case 1:
-		pers = RAID1;
-		printk ("md: Setting up md%d as a raid1 device.\n",minor);
-		break;
-	case 5:
-		pers = RAID5;
-		printk ("md: Setting up md%d as a raid5 device.\n",minor);
-		break;
-*/
-	default:	   
-		printk ("md: Unknown or not supported raid level %d.\n", ints[--i]);
-		return;
+#endif
+	default:
+		printk ("md: The kernel has not been configured for raid%d"
+			" support!\n", level);
+		return 0;
 	}
-
-	if(pers) {
-
-	  factor=ints[i++]; /* Chunksize  */
-	  fault =ints[i++]; /* Faultlevel */
-   
-	  pers=pers | factor | (fault << FAULT_SHIFT);   
-   
-	  while( str && (dev = name_to_kdev_t(str))) {
-	    do_md_add (minor, dev);
-	    if((str = strchr (str, ',')) != NULL)
-	      str++;
-	  }
-
-	  do_md_run (minor, pers);
-	  printk ("md: Loading md%d.\n",minor);
+	devnames = str;
+	for (i = 0; str; i++) {
+		if ((device = name_to_kdev_t(str))) {
+			md_setup_args.devices[minor][i] = device;
+		} else {
+			printk ("md: Unknown device name, %s.\n", str);
+			return 0;
+		}
+		if ((str = strchr(str, ',')) != NULL)
+			str++;
 	}
-   
+	if (!i) {
+		printk ("md: No devices specified for md%d?\n", minor);
+		return 0;
+	}
+
+	printk ("md: Will configure md%d (%s) from %s, below.\n",
+		minor, pername, devnames);
+	md_setup_args.devices[minor][i] = (kdev_t) 0;
+	md_setup_args.pers[minor] = level | factor | (fault << FAULT_SHIFT);
+	md_setup_args.set |= (1 << minor);
+	return 0;
 }
+
 #endif
 
 void linear_init (void);
@@ -1318,7 +1305,18 @@
 #ifdef CONFIG_MD_BOOT
 void __init md_setup_drive(void)
 {
-	if(md_setup_args.set)
-		do_md_setup(md_setup_args.str, md_setup_args.ints);
+	int minor, i;
+	kdev_t dev;
+
+	for (minor = 0; minor < MAX_MD_DEV; minor++) {
+		if ((md_setup_args.set & (1 << minor)) == 0)
+			continue;
+		printk("md: Loading md%d.\n", minor);
+		for (i = 0; (dev = md_setup_args.devices[minor][i]); i++)
+			do_md_add (minor, dev);
+		do_md_run (minor, md_setup_args.pers[minor]);
+	}
 }
+
+__setup("md=", md_setup);
 #endif
diff -u --recursive --new-file v2.3.29/linux/drivers/block/sl82c105.c linux/drivers/block/sl82c105.c
--- v2.3.29/linux/drivers/block/sl82c105.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/block/sl82c105.c	Thu Dec  2 15:41:39 1999
@@ -61,6 +61,7 @@
 static int ide_set_drive_pio_mode(ide_drive_t *drive, byte pio)
 {
 	ide_hwif_t *hwif = HWIF(drive);
+	ide_startstop_t startstop;
 
 	if (pio > 2) {
 		/* FIXME: I don't believe that this SELECT_DRIVE is required,
@@ -74,7 +75,7 @@
 		OUT_BYTE(0x03, IDE_FEATURE_REG);
 		OUT_BYTE(WIN_SETFEATURES, IDE_COMMAND_REG);
 
-		if (ide_wait_stat(drive, DRIVE_READY,
+		if (ide_wait_stat(&startstop, drive, DRIVE_READY,
 				  BUSY_STAT|DRQ_STAT|ERR_STAT, WAIT_CMD)) {
 			printk("%s: drive not ready for command\n",
 			       drive->name);
diff -u --recursive --new-file v2.3.29/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c
--- v2.3.29/linux/drivers/cdrom/cdrom.c	Thu Nov 11 20:11:33 1999
+++ linux/drivers/cdrom/cdrom.c	Thu Dec  2 19:39:36 1999
@@ -1072,6 +1072,31 @@
 			return ret;
 		break;
 
+	/* Get region settings */
+	case DVD_LU_SEND_RPC_STATE:
+		cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
+		setup_report_key(&cgc, 0, 8);
+
+		if ((ret = cdo->generic_packet(cdi, &cgc)))
+			return ret;
+
+		ai->lrpcs.type = (buf[4] >> 6) & 3;
+		ai->lrpcs.vra = (buf[4] >> 3) & 7;
+		ai->lrpcs.ucca = buf[4] & 7;
+		ai->lrpcs.region_mask = buf[5];
+		ai->lrpcs.rpc_scheme = buf[6];
+		break;
+
+		/* Set region settings */
+	case DVD_HOST_SEND_RPC_STATE:
+		cdinfo(CD_DVD, "entering DVD_HOST_SEND_RPC_STATE\n");
+		setup_send_key(&cgc, 0, 6);
+		buf[4] = ai->hrpcs.pdrc;
+
+		if ((ret = cdo->generic_packet(cdi, &cgc)))
+			return ret;
+		break;
+
 	default:
 		cdinfo(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type);
 		return -ENOTTY;
@@ -1528,6 +1553,9 @@
 		if (!CDROM_CAN(CDC_LOCK))
 			return -EDRIVE_CANT_DO_THIS;
 		keeplocked = arg ? 1 : 0;
+		/* don't unlock the door on multiple opens */
+		if ((cdi->use_count != 1) && !arg)
+			return -EBUSY;
 		return cdo->lock_door(cdi, arg);
 		}
 
@@ -1861,14 +1889,19 @@
 	case CDROMPLAYTRKIND: {
 		struct cdrom_ti ti;
 		struct cdrom_tocentry entry;
+		struct cdrom_tochdr tochdr;
 
 		cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
 		IOCTL_IN(arg, struct cdrom_ti, ti);
 		entry.cdte_format = CDROM_MSF;
 
 		/* get toc entry for start and end track */
-		entry.cdte_track = ti.cdti_trk0;
-		if (cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry))
+		if (cdo->audio_ioctl(cdi, CDROMREADTOCHDR, &tochdr))
+			return -EINVAL;
+		entry.cdte_track = ti.cdti_trk1 + 1;
+		if (entry.cdte_track > tochdr.cdth_trk1)
+			return -EINVAL;
+		if (cdo->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry))
 			return -EINVAL;
 
 		cgc.cmd[3] = entry.cdte_addr.msf.minute;
diff -u --recursive --new-file v2.3.29/linux/drivers/char/Config.in linux/drivers/char/Config.in
--- v2.3.29/linux/drivers/char/Config.in	Tue Nov 23 22:42:20 1999
+++ linux/drivers/char/Config.in	Sat Nov 27 15:27:48 1999
@@ -141,6 +141,7 @@
    fi
    if [ "$CONFIG_PCI" != "n" ]; then
       dep_tristate '  BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV
+	dep_tristate 'Zoran ZR36120/36125 support' CONFIG_VIDEO_ZR36120 $CONFIG_VIDEO_DEV
    fi
    dep_tristate '  GemTek Radio Card support' CONFIG_RADIO_GEMTEK $CONFIG_VIDEO_DEV
    if [ "$CONFIG_RADIO_GEMTEK" = "y" ]; then
@@ -192,8 +193,9 @@
    if [ "$CONFIG_RADIO_ZOLTRIX" = "y" ]; then
       hex '    ZOLTRIX I/O port (0x20c or 0x30c)' CONFIG_RADIO_ZOLTRIX_PORT 20c
    fi
-   dep_tristate '  Zoran ZR36057/36060 support' CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV
+   dep_tristate '  Zoran ZR36057/36060 support' CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV $CONFIG_PCI
    dep_tristate '    Include support for Iomega Buz' CONFIG_VIDEO_BUZ $CONFIG_VIDEO_ZORAN
+   dep_tristate '  Zoran ZR36120/36125 support' CONFIG_VIDEO_ZR36120 $CONFIG_VIDEO_DEV $CONFIG_PCI
 fi
 
 endmenu
diff -u --recursive --new-file v2.3.29/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.3.29/linux/drivers/char/Makefile	Thu Nov 11 20:11:33 1999
+++ linux/drivers/char/Makefile	Sat Nov 27 15:27:48 1999
@@ -348,6 +348,9 @@
   endif
 endif
 
+#
+# for external dependencies in arm/config.in and video/config.in
+#
 ifeq ($(CONFIG_BUS_I2C),y)
 	L_I2C=y
 else
@@ -357,12 +360,28 @@
 endif
 
 ifeq ($(CONFIG_VIDEO_BT848),y)
-O_OBJS += bttv.o msp3400.o tuner.o
+O_OBJS += bttv.o msp3400.o
 L_I2C=y
+L_TUNERS=y
 else
   ifeq ($(CONFIG_VIDEO_BT848),m)
-    M_OBJS += bttv.o msp3400.o tuner.o
+    M_OBJS += bttv.o msp3400.o
     M_I2C=y
+    M_TUNERS=y
+  endif
+endif
+
+ifeq ($(CONFIG_VIDEO_ZR36120),y)
+O_OBJS += zoran.o
+L_I2C=y
+L_TUNERS=y
+L_DECODERS=y
+else
+  ifeq ($(CONFIG_VIDEO_ZR36120),m)
+    M_OBJS += zoran.o
+    M_I2C=y
+    M_TUNERS=y
+    M_DECODERS=y
   endif
 endif
 
@@ -404,9 +423,13 @@
 
 ifeq ($(CONFIG_VIDEO_ZORAN),y)
 O_OBJS += buz.o
+L_I2C=y
+L_DECODERS=y
 else
   ifeq ($(CONFIG_VIDEO_ZORAN),m)
     M_OBJS += buz.o
+    M_I2C=y
+    M_DECODERS=y
   endif
 endif
 
@@ -418,14 +441,6 @@
   endif
 endif
 
-ifeq ($(CONFIG_VIDEO_BUZ),y)
-O_OBJS += saa7111.o saa7185.o
-else
-  ifeq ($(CONFIG_VIDEO_BUZ),m)
-    M_OBJS += saa7111.o saa7185.o
-  endif
-endif
-
 ifeq ($(CONFIG_VIDEO_PMS),y)
 O_OBJS += pms.o
 else
@@ -578,11 +593,31 @@
   endif
 endif
 
+
+# set when a framegrabber supports external tuners
+ifeq ($(L_TUNERS),y)
+O_OBJS += tuner.o
+else
+  ifeq ($(M_TUNERS),y)
+    M_OBJS += tuner.o
+  endif
+endif
+
+# set when a framegrabber supports external decoders
+ifeq ($(L_DECODERS),y)
+O_OBJS += saa7110.o saa7111.o saa7185.o
+else
+  ifeq ($(M_DECODERS),y)
+    M_OBJS += saa7110.o saa7111.o saa7185.o
+  endif
+endif
+
+# set when a framegrabber implements i2c support
 ifeq ($(L_I2C),y)
 OX_OBJS += i2c.o
 else
-  ifeq ($(M_I2C),y)
-  MX_OBJS += i2c.o
+ ifeq ($(M_I2C),y)
+ MX_OBJS += i2c.o
   endif
 endif
 
@@ -615,3 +650,5 @@
 defkeymap.c: defkeymap.map
 	loadkeys --mktable defkeymap.map > defkeymap.c
 
+zoran.o: zr36120.o zr36120_i2c.o zr36120_mem.o
+	$(LD) $(LD_RFLAG) -r -o $@ zr36120.o zr36120_i2c.o zr36120_mem.o
diff -u --recursive --new-file v2.3.29/linux/drivers/char/buz.c linux/drivers/char/buz.c
--- v2.3.29/linux/drivers/char/buz.c	Fri Oct 15 15:25:13 1999
+++ linux/drivers/char/buz.c	Sat Nov 27 15:27:48 1999
@@ -3035,7 +3035,7 @@
 	BUZ_NAME,
 	VID_TYPE_CAPTURE | VID_TYPE_OVERLAY | VID_TYPE_CLIPPING | VID_TYPE_FRAMERAM |
 	VID_TYPE_SCALES | VID_TYPE_SUBCAPTURE,
-	VID_HARDWARE_BT848,	/* Not true, but the buz is not yet in the list */
+	VID_HARDWARE_ZR36067,
 	zoran_open,
 	zoran_close,
 	zoran_read,
diff -u --recursive --new-file v2.3.29/linux/drivers/char/drm/proc.c linux/drivers/char/drm/proc.c
--- v2.3.29/linux/drivers/char/drm/proc.c	Sun Nov  7 16:37:34 1999
+++ linux/drivers/char/drm/proc.c	Sat Nov 27 15:27:48 1999
@@ -79,7 +79,7 @@
 	struct proc_dir_entry *ent;
 	int		      i, j;
 
-	drm_root = create_proc_entry("video", S_IFDIR, NULL);
+	drm_root = proc_mkdir("video", NULL);
 	if (!drm_root) {
 		DRM_ERROR("Cannot create /proc/video\n");
 		return -1;
@@ -89,7 +89,7 @@
 				   add some global support for /proc/video. */
 	for (i = 0; i < 8; i++) {
 		sprintf(drm_slot_name, "video/%d", i);
-		drm_dev_root = create_proc_entry(drm_slot_name, S_IFDIR, NULL);
+		drm_dev_root = proc_mkdir(drm_slot_name, NULL);
 		if (!drm_dev_root) {
 			DRM_ERROR("Cannot create /proc/%s\n", drm_slot_name);
 			remove_proc_entry("video", NULL);
@@ -103,20 +103,17 @@
 	}
 
 	for (i = 0; i < DRM_PROC_ENTRIES; i++) {
-		ent = create_proc_entry(drm_proc_list[i].name,
-					S_IFREG|S_IRUGO, drm_dev_root);
-		if (!ent) {
-			DRM_ERROR("Cannot create /proc/%s/%s\n",
-				  drm_slot_name, drm_proc_list[i].name);
-			for (j = 0; j < i; j++)
-				remove_proc_entry(drm_proc_list[i].name,
-						  drm_dev_root);
-			remove_proc_entry(drm_slot_name, NULL);
-			remove_proc_entry("video", NULL);
-			return -1;
-		}
-		ent->read_proc = drm_proc_list[i].f;
-		ent->data      = dev;
+		if (create_proc_read_entry(drm_proc_list[i].name,0,drm_dev_root,
+					   drm_proc_list[i].f, dev))
+			continue;
+
+		DRM_ERROR("Cannot create /proc/%s/%s\n",
+			  drm_slot_name, drm_proc_list[i].name);
+		for (j = 0; j < i; j++)
+			remove_proc_entry(drm_proc_list[i].name, drm_dev_root);
+		remove_proc_entry(drm_slot_name, NULL);
+		remove_proc_entry("video", NULL);
+		return -1;
 	}
 
 	return 0;
diff -u --recursive --new-file v2.3.29/linux/drivers/char/lp.c linux/drivers/char/lp.c
--- v2.3.29/linux/drivers/char/lp.c	Mon Aug  9 10:23:09 1999
+++ linux/drivers/char/lp.c	Thu Dec  2 14:56:27 1999
@@ -278,7 +278,7 @@
 	int error = 0;
 	unsigned int last = lp_table[minor].last_error;
 	unsigned char status = r_str(minor);
-	if (status & LP_PERRORP)
+	if ((status & LP_PERRORP) && !(LP_F(minor) & LP_CAREFUL))
 		/* No error. */
 		last = 0;
 	else if ((status & LP_POUTPA)) {
@@ -293,12 +293,15 @@
 			printk(KERN_INFO "lp%d off-line\n", minor);
 		}
 		error = -EIO;
-	} else {
+	} else if (!(status & LP_PERRORP)) {
 		if (last != LP_PERRORP) {
 			last = LP_PERRORP;
 			printk(KERN_INFO "lp%d on fire\n", minor);
 		}
 		error = -EIO;
+	} else {
+		last = 0; /* Come here if LP_CAREFUL is set and no
+                             errors are reported. */
 	}
 
 	lp_table[minor].last_error = last;
@@ -542,14 +545,12 @@
 			else
 				LP_F(minor) &= ~LP_ABORTOPEN;
 			break;
-#ifdef OBSOLETED
 		case LPCAREFUL:
 			if (arg)
 				LP_F(minor) |= LP_CAREFUL;
 			else
 				LP_F(minor) &= ~LP_CAREFUL;
 			break;
-#endif
 		case LPWAIT:
 			LP_WAIT(minor) = arg;
 			break;
diff -u --recursive --new-file v2.3.29/linux/drivers/char/mem.c linux/drivers/char/mem.c
--- v2.3.29/linux/drivers/char/mem.c	Tue Nov 23 22:42:20 1999
+++ linux/drivers/char/mem.c	Sat Nov 27 15:27:48 1999
@@ -56,9 +56,6 @@
 #ifdef CONFIG_USB
 extern void usb_init(void);
 #endif
-#ifdef CONFIG_PPDEV
-extern int pp_init(void);
-#endif
      
 static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
 			    const char * buf, size_t count, loff_t *ppos)
@@ -675,9 +672,6 @@
 #endif
 #ifdef CONFIG_VIDEO_DEV
 	videodev_init();
-#endif
-#ifdef CONFIG_PPDEV
-	pp_init();
 #endif
 	return 0;
 }
diff -u --recursive --new-file v2.3.29/linux/drivers/char/pc110pad.c linux/drivers/char/pc110pad.c
--- v2.3.29/linux/drivers/char/pc110pad.c	Mon Oct 11 15:38:14 1999
+++ linux/drivers/char/pc110pad.c	Fri Dec  3 10:55:09 1999
@@ -53,7 +53,7 @@
 static wait_queue_head_t queue;
 static struct fasync_struct *asyncptr;
 static int active=0;	/* number of concurrent open()s */
-static struct semaphore read_lock;
+static struct semaphore reader_lock;
 
 /*
  * Utility to reset a timer to go off some time in the future.
@@ -561,7 +561,7 @@
 {
 	int r;
 
-	down(&read_lock);
+	down(&reader_lock);
 	for(r=0; r<count; r++)
 	{
 		if(!read_byte_count)
@@ -573,7 +573,7 @@
 		}
 		read_byte_count = (read_byte_count+1)%3;
 	}
-	up(&read_lock);
+	up(&reader_lock);
 	return r;
 }
 
@@ -691,7 +691,7 @@
 
 int init_module(void)
 {
-	init_MUTEX(&read_lock);
+	init_MUTEX(&reader_lock);
 	return pc110pad_init();
 }
 
diff -u --recursive --new-file v2.3.29/linux/drivers/char/ppdev.c linux/drivers/char/ppdev.c
--- v2.3.29/linux/drivers/char/ppdev.c	Thu Nov 11 20:11:34 1999
+++ linux/drivers/char/ppdev.c	Sat Nov 27 15:27:48 1999
@@ -43,6 +43,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/ioctl.h>
 #include <linux/parport.h>
@@ -578,11 +579,7 @@
 	pp_release
 };
 
-#ifdef MODULE
-#define pp_init init_module
-#endif
-
-int pp_init (void)
+static int __init ppdev_init (void)
 {
 	if (register_chrdev (PP_MAJOR, CHRDEV, &pp_fops)) {
 		printk (KERN_WARNING CHRDEV ": unable to get major %d\n",
@@ -594,10 +591,11 @@
 	return 0;
 }
 
-#ifdef MODULE
-void cleanup_module (void)
+static void __exit ppdev_cleanup (void)
 {
 	/* Clean up all parport stuff */
 	unregister_chrdev (PP_MAJOR, CHRDEV);
 }
-#endif /* MODULE */
+
+module_init(ppdev_init);
+module_exit(ppdev_cleanup);
diff -u --recursive --new-file v2.3.29/linux/drivers/char/saa7110.c linux/drivers/char/saa7110.c
--- v2.3.29/linux/drivers/char/saa7110.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/saa7110.c	Sat Nov 27 15:27:48 1999
@@ -0,0 +1,429 @@
+/*
+    saa7110 - Philips SAA7110(A) video decoder driver
+
+    Copyright (C) 1998 Pauline Middelink <middelin@polyware.nl>
+
+    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/types.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <linux/i2c.h>
+#include <linux/videodev.h>
+#include "linux/video_decoder.h"
+
+#define DEBUG(x...)	x		/* remove when no long debugging */
+
+#define SAA7110_MAX_INPUT	9	/* 6 CVBS, 3 SVHS */
+#define SAA7110_MAX_OUTPUT	0	/* its a decoder only */
+
+#define	I2C_SAA7110		0x9C	/* or 0x9E */
+
+#define	I2C_DELAY		10	/* 10 us or 100khz */
+
+struct saa7110 {
+	struct	i2c_bus	*bus;
+	int		addr;
+	unsigned char	reg[36];
+
+	int		norm;
+	int		input;
+	int		enable;
+	int		bright;
+	int		contrast;
+	int		hue;
+	int		sat;
+};
+
+/* ----------------------------------------------------------------------- */
+/* I2C support functions						   */
+/* ----------------------------------------------------------------------- */
+static
+int saa7110_write(struct saa7110 *decoder, unsigned char subaddr, unsigned char data)
+{
+	int ack;
+
+	LOCK_I2C_BUS(decoder->bus);
+	i2c_start(decoder->bus);
+	i2c_sendbyte(decoder->bus, decoder->addr, I2C_DELAY);
+	i2c_sendbyte(decoder->bus, subaddr, I2C_DELAY);
+	ack = i2c_sendbyte(decoder->bus, data, I2C_DELAY);
+	i2c_stop(decoder->bus);
+	decoder->reg[subaddr] = data;
+	UNLOCK_I2C_BUS(decoder->bus);
+	return ack;
+}
+
+static
+int saa7110_write_block(struct saa7110* decoder, unsigned const char *data, unsigned int len)
+{
+	unsigned subaddr = *data;
+
+	LOCK_I2C_BUS(decoder->bus);
+        i2c_start(decoder->bus);
+        i2c_sendbyte(decoder->bus,decoder->addr,I2C_DELAY);
+	while (len-- > 0) {
+                if (i2c_sendbyte(decoder->bus,*data,0)) {
+                        i2c_stop(decoder->bus);
+                        return -EAGAIN;
+                }
+		decoder->reg[subaddr++] = *data++;
+        }
+	i2c_stop(decoder->bus);
+	UNLOCK_I2C_BUS(decoder->bus);
+
+	return 0;
+}
+
+static
+int saa7110_read(struct saa7110* decoder)
+{
+	int data;
+
+	LOCK_I2C_BUS(decoder->bus);
+	i2c_start(decoder->bus);
+	i2c_sendbyte(decoder->bus, decoder->addr, I2C_DELAY);
+	i2c_start(decoder->bus);
+	i2c_sendbyte(decoder->bus, decoder->addr | 1, I2C_DELAY);
+	data = i2c_readbyte(decoder->bus, 1);
+	i2c_stop(decoder->bus);
+	UNLOCK_I2C_BUS(decoder->bus);
+	return data;
+}
+
+/* ----------------------------------------------------------------------- */
+/* SAA7110 functions							   */
+/* ----------------------------------------------------------------------- */
+static
+int saa7110_selmux(struct i2c_device *device, int chan)
+{
+static	const unsigned char modes[9][8] = {
+/* mode 0 */	{ 0x00, 0xD9, 0x17, 0x40, 0x03, 0x44, 0x75, 0x16 },
+/* mode 1 */	{ 0x00, 0xD8, 0x17, 0x40, 0x03, 0x44, 0x75, 0x16 },
+/* mode 2 */	{ 0x00, 0xBA, 0x07, 0x91, 0x03, 0x60, 0xB5, 0x05 },
+/* mode 3 */	{ 0x00, 0xB8, 0x07, 0x91, 0x03, 0x60, 0xB5, 0x05 },
+/* mode 4 */	{ 0x00, 0x7C, 0x07, 0xD2, 0x83, 0x60, 0xB5, 0x03 },
+/* mode 5 */	{ 0x00, 0x78, 0x07, 0xD2, 0x83, 0x60, 0xB5, 0x03 },
+/* mode 6 */	{ 0x80, 0x59, 0x17, 0x42, 0xA3, 0x44, 0x75, 0x12 },
+/* mode 7 */	{ 0x80, 0x9A, 0x17, 0xB1, 0x13, 0x60, 0xB5, 0x14 },
+/* mode 8 */	{ 0x80, 0x3C, 0x27, 0xC1, 0x23, 0x44, 0x75, 0x21 } };
+	struct saa7110* decoder = device->data;
+	const unsigned char* ptr = modes[chan];
+
+	saa7110_write(decoder,0x06,ptr[0]);	/* Luminance control	*/
+	saa7110_write(decoder,0x20,ptr[1]);	/* Analog Control #1	*/
+	saa7110_write(decoder,0x21,ptr[2]);	/* Analog Control #2	*/
+	saa7110_write(decoder,0x22,ptr[3]);	/* Mixer Control #1	*/
+	saa7110_write(decoder,0x2C,ptr[4]);	/* Mixer Control #2	*/
+	saa7110_write(decoder,0x30,ptr[5]);	/* ADCs gain control	*/
+	saa7110_write(decoder,0x31,ptr[6]);	/* Mixer Control #3	*/
+	saa7110_write(decoder,0x21,ptr[7]);	/* Analog Control #2	*/
+
+	return 0;
+}
+
+static
+int determine_norm(struct i2c_device* dev)
+{
+	struct	saa7110* decoder = dev->data;
+	int	status;
+
+	/* mode changed, start automatic detection */
+	status = saa7110_read(decoder);
+	if ((status & 3) == 0) {
+		saa7110_write(decoder,0x06,0x80);
+		if (status & 0x20) {
+			DEBUG(printk(KERN_INFO "%s: norm=bw60\n",dev->name));
+			saa7110_write(decoder,0x2E,0x81);
+			return VIDEO_MODE_NTSC;
+		}
+		DEBUG(printk(KERN_INFO "%s: norm=bw50\n",dev->name));
+		saa7110_write(decoder,0x2E,0x9A);
+		return VIDEO_MODE_PAL;
+	}
+
+	saa7110_write(decoder,0x06,0x00);
+	if (status & 0x20) {	/* 60Hz */
+		DEBUG(printk(KERN_INFO "%s: norm=ntsc\n",dev->name));
+		saa7110_write(decoder,0x0D,0x06);
+		saa7110_write(decoder,0x11,0x2C);
+		saa7110_write(decoder,0x2E,0x81);
+		return VIDEO_MODE_NTSC;
+	}
+
+	/* 50Hz -> PAL/SECAM */
+	saa7110_write(decoder,0x0D,0x06);
+	saa7110_write(decoder,0x11,0x59);
+	saa7110_write(decoder,0x2E,0x9A);
+
+	mdelay(150);	/* pause 150 ms */
+
+	status = saa7110_read(decoder);
+	if ((status & 0x03) == 0x01) {
+		DEBUG(printk(KERN_INFO "%s: norm=secam\n",dev->name));
+		saa7110_write(decoder,0x0D,0x07);
+		return VIDEO_MODE_SECAM;
+	}
+	DEBUG(printk(KERN_INFO "%s: norm=pal\n",dev->name));
+	return VIDEO_MODE_PAL;
+}
+
+static
+int saa7110_attach(struct i2c_device *device)
+{
+static	const unsigned char initseq[] = {
+	     0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF0, 0x00, 0x00,
+		0xF8, 0xF8, 0x60, 0x60, 0x00, 0x06, 0x18, 0x90,
+		0x00, 0x2C, 0x40, 0x46, 0x42, 0x1A, 0xFF, 0xDA,
+		0xF0, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0xD9, 0x17, 0x40, 0x41, 0x80, 0x41, 0x80, 0x4F,
+		0xFE, 0x01, 0xCF, 0x0F, 0x03, 0x01, 0x81, 0x03,
+		0x40, 0x75, 0x01, 0x8C, 0x03};
+	struct	saa7110*	decoder;
+	int			rv;
+
+	device->data = decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL);
+	if (device->data == 0)
+		return -ENOMEM;
+
+	MOD_INC_USE_COUNT;
+
+	/* clear our private data */
+	memset(decoder, 0, sizeof(struct saa7110));
+	strcpy(device->name, "saa7110");
+	decoder->bus = device->bus;
+	decoder->addr = device->addr;
+	decoder->norm = VIDEO_MODE_PAL;
+	decoder->input = 0;
+	decoder->enable = 1;
+	decoder->bright = 32768;
+	decoder->contrast = 32768;
+	decoder->hue = 32768;
+	decoder->sat = 32768;
+
+	rv = saa7110_write_block(decoder, initseq, sizeof(initseq));
+	if (rv < 0)
+		printk(KERN_ERR "%s_attach: init status %d\n", device->name, rv);
+	else {
+		saa7110_write(decoder,0x21,0x16);
+		saa7110_write(decoder,0x0D,0x04);
+		printk(KERN_INFO "%s_attach: chip version %x\n", device->name, saa7110_read(decoder));
+		saa7110_write(decoder,0x0D,0x06);
+	}
+
+	/* setup and implicit mode 0 select has been performed */
+	return 0;
+}
+
+static
+int saa7110_detach(struct i2c_device *device)
+{
+	struct saa7110* decoder = device->data;
+
+	DEBUG(printk(KERN_INFO "%s_detach\n",device->name));
+
+	/* stop further output */
+	saa7110_write(decoder,0x0E,0x00);
+
+	kfree(device->data);
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static
+int saa7110_command(struct i2c_device *device, unsigned int cmd, void *arg)
+{
+	struct saa7110* decoder = device->data;
+	int	v;
+
+	switch (cmd) {
+	 case DECODER_GET_CAPABILITIES:
+		{
+			struct video_decoder_capability *dc = arg;
+			dc->flags = VIDEO_DECODER_PAL
+				  | VIDEO_DECODER_NTSC
+				  | VIDEO_DECODER_SECAM
+				  | VIDEO_DECODER_AUTO
+				  | VIDEO_DECODER_CCIR;
+			dc->inputs = SAA7110_MAX_INPUT;
+			dc->outputs = SAA7110_MAX_OUTPUT;
+		}
+		break;
+
+	 case DECODER_GET_STATUS:
+		{
+			struct saa7110* decoder = device->data;
+			int status;
+			int res = 0;
+
+			status = i2c_read(device->bus,device->addr|1);
+			if (status & 0x40)
+				res |= DECODER_STATUS_GOOD;
+			if (status & 0x03)
+				res |= DECODER_STATUS_COLOR;
+
+			switch (decoder->norm) {
+			 case VIDEO_MODE_NTSC:
+				res |= DECODER_STATUS_NTSC;
+				break;
+			 case VIDEO_MODE_PAL:
+				res |= DECODER_STATUS_PAL;
+				break;
+			 case VIDEO_MODE_SECAM:
+				res |= DECODER_STATUS_SECAM;
+				break;
+			}
+			*(int*)arg = res;
+		}
+		break;
+
+	 case DECODER_SET_NORM:
+		v = *(int*)arg;
+		if (decoder->norm != v) {
+			decoder->norm = v;
+			saa7110_write(decoder, 0x06, 0x00);
+			switch (v) {
+			 case VIDEO_MODE_NTSC:
+				saa7110_write(decoder, 0x0D, 0x06);
+				saa7110_write(decoder, 0x11, 0x2C);
+				saa7110_write(decoder, 0x30, 0x81);
+saa7110_write(decoder, 0x2A, 0xDF);
+				break;
+			 case VIDEO_MODE_PAL:
+				saa7110_write(decoder, 0x0D, 0x06);
+				saa7110_write(decoder, 0x11, 0x59);
+				saa7110_write(decoder, 0x2E, 0x9A);
+				break;
+			 case VIDEO_MODE_SECAM:
+				saa7110_write(decoder, 0x0D, 0x07);
+				saa7110_write(decoder, 0x11, 0x59);
+				saa7110_write(decoder, 0x2E, 0x9A);
+				break;
+			 case VIDEO_MODE_AUTO:
+				*(int*)arg = determine_norm(device);
+				break;
+			 default:
+				return -EPERM;
+			}
+		}
+		break;
+
+	 case DECODER_SET_INPUT:
+		v = *(int*)arg;
+		if (v<0 || v>SAA7110_MAX_INPUT)
+			return -EINVAL;
+		if (decoder->input != v) {
+			decoder->input = v;
+			saa7110_selmux(device, v);
+		}
+		break;
+
+	 case DECODER_SET_OUTPUT:
+		v = *(int*)arg;
+		/* not much choice of outputs */
+		if (v != 0)
+			return -EINVAL;
+		break;
+
+	 case DECODER_ENABLE_OUTPUT:
+		v = *(int*)arg;
+		if (decoder->enable != v) {
+			decoder->enable = v;
+			saa7110_write(decoder,0x0E, v ? 0x18 : 0x00);
+		}
+		break;
+
+	 case DECODER_SET_PICTURE:
+		{
+			struct video_picture *pic = arg;
+
+			if (decoder->bright != pic->brightness) {
+				/* We want 0 to 255 we get 0-65535 */
+				decoder->bright = pic->brightness;
+				saa7110_write(decoder, 0x19, decoder->bright >> 8);
+			}
+			if (decoder->contrast != pic->contrast) {
+				/* We want 0 to 127 we get 0-65535 */
+				decoder->contrast = pic->contrast;
+				saa7110_write(decoder, 0x13, decoder->contrast >> 9);
+			}
+			if (decoder->sat != pic->colour) {
+				/* We want 0 to 127 we get 0-65535 */
+				decoder->sat = pic->colour;
+				saa7110_write(decoder, 0x12, decoder->sat >> 9);
+			}
+			if (decoder->hue != pic->hue) {
+				/* We want -128 to 127 we get 0-65535 */
+				decoder->hue = pic->hue;
+				saa7110_write(decoder, 0x07, (decoder->hue>>8)-128);
+			}
+		}
+		break;
+
+	 case DECODER_DUMP:
+		for (v=0; v<34; v+=16) {
+			int j;
+			DEBUG(printk(KERN_INFO "%s: %03x\n",device->name,v));
+			for (j=0; j<16; j++) {
+				DEBUG(printk(KERN_INFO " %02x",decoder->reg[v+j]));
+			}
+			DEBUG(printk(KERN_INFO "\n"));
+		}
+		break;
+
+	 default:
+		DEBUG(printk(KERN_INFO "unknown saa7110_command??(%d)\n",cmd));
+		return -EINVAL;
+	}
+	return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+struct i2c_driver i2c_driver_saa7110 =
+{
+	"saa7110",			/* name */
+
+	I2C_DRIVERID_VIDEODECODER,	/* in i2c.h */
+	I2C_SAA7110, I2C_SAA7110+1,	/* Addr range */
+
+	saa7110_attach,
+	saa7110_detach,
+	saa7110_command
+};
+
+EXPORT_NO_SYMBOLS;
+
+#ifdef MODULE
+int init_module(void)
+#else
+int saa7110_init(void)
+#endif
+{
+	return i2c_register_driver(&i2c_driver_saa7110);
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+	i2c_unregister_driver(&i2c_driver_saa7110);
+}
+#endif
diff -u --recursive --new-file v2.3.29/linux/drivers/char/serial.c linux/drivers/char/serial.c
--- v2.3.29/linux/drivers/char/serial.c	Tue Nov 23 22:42:20 1999
+++ linux/drivers/char/serial.c	Thu Dec  2 15:41:20 1999
@@ -4142,15 +4142,6 @@
 {
 	int i;
 	struct serial_state * state;
-	extern void atomwide_serial_init (void);
-	extern void dualsp_serial_init (void);
-
-#ifdef CONFIG_ATOMWIDE_SERIAL
-	atomwide_serial_init ();
-#endif
-#ifdef CONFIG_DUALSP_SERIAL
-	dualsp_serial_init ();
-#endif
 
 	if (timer_table[RS_TIMER].fn) {
 		printk("RS_TIMER already set, another serial driver "
diff -u --recursive --new-file v2.3.29/linux/drivers/char/videodev.c linux/drivers/char/videodev.c
--- v2.3.29/linux/drivers/char/videodev.c	Thu Nov 11 20:11:34 1999
+++ linux/drivers/char/videodev.c	Sat Nov 27 15:27:48 1999
@@ -54,6 +54,9 @@
 #ifdef CONFIG_VIDEO_ZORAN
 extern int init_zoran_cards(struct video_init *);
 #endif
+#ifdef CONFIG_VIDEO_ZR36120
+extern int init_zr36120_cards(struct video_init *);
+#endif
 
 static struct video_init video_init_list[]={
 #ifdef CONFIG_VIDEO_BT848
@@ -71,6 +74,9 @@
 #endif
 #ifdef CONFIG_VIDEO_ZORAN
 	{"zoran", init_zoran_cards},
+#endif	
+#ifdef CONFIG_VIDEO_ZR36120
+	{"zr36120", init_zr36120_cards},
 #endif	
 	{"end", NULL}
 };
diff -u --recursive --new-file v2.3.29/linux/drivers/char/zr36120.c linux/drivers/char/zr36120.c
--- v2.3.29/linux/drivers/char/zr36120.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/zr36120.c	Sat Nov 27 15:27:48 1999
@@ -0,0 +1,1609 @@
+/*
+    zr36120.c - Zoran 36120/36125 based framegrabbers
+
+    Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
+
+    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/config.h>
+#include <linux/module.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/vmalloc.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/version.h>
+#include <asm/uaccess.h>
+
+#include "linux/video_decoder.h"
+#include "tuner.h"
+#include "zr36120.h"
+#include "zr36120_mem.h"
+
+/* sensible default */
+#ifndef CARDTYPE
+#define CARDTYPE 0
+#endif
+
+/* Anybody who uses more than four? */
+#define ZORAN_MAX 4
+
+static ulong irq1 = 0;
+
+       unsigned int triton1=0;			/* triton1 chipset? */
+static unsigned int cardtype[ZORAN_MAX]={ [ 0 ... ZORAN_MAX-1 ] = CARDTYPE };
+
+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");
+
+static int zoran_cards;
+static struct zoran zorans[ZORAN_MAX];
+
+/*
+ * the meaning of each element can be found in zr36120.h
+ * Determining the value of gpdir/gpval can be tricky. The
+ * best way is to run the card under the original software
+ * and read the values from the general purpose registers
+ * 0x28 and 0x2C. How you do that is left as an exercise
+ * to the impatient reader :)
+ */
+#define T 1	/* to seperate the bools from the ints */
+#define F 0
+static struct tvcard tvcards[] = {
+	/* reported working by <middelin@polyware.nl> */
+/*0*/	{ "Trust Victor II",
+	  2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
+	/* reported working by <Michael.Paxton@aihw.gov.au>  */
+/*1*/   { "Aitech WaveWatcher TV-PCI",
+	  3, 0, T, F, T, T, 0x7F, 0x80, { 1, TUNER(3), SVHS(6) }, { 0 } },
+	/* reported working by ? */
+/*2*/	{ "Genius Video Wonder PCI Video Capture Card",
+	  2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
+	/* reported working by <Pascal.Gabriel@wanadoo.fr> */
+/*3*/	{ "Guillemot Maxi-TV PCI",
+	  2, 0, T, T, T, T, 0x7F, 0x80, { 1, SVHS(6) }, { 0 } },
+	/* reported working by "Craig Whitmore <lennon@igrin.co.nz> */
+/*4*/	{ "Quadrant Buster",
+	  3, 3, T, F, T, T, 0x7F, 0x80, { SVHS(1), TUNER(2), 3 }, { 1, 2, 3 } },
+	/* a debug entry which has all inputs mapped */
+/*5*/	{ "ZR36120 based framegrabber (all inputs enabled)",
+	  6, 0, T, T, T, T, 0x7F, 0x80, { 1, 2, 3, 4, 5, 6 }, { 0 } }
+};
+#undef T
+#undef F
+#define NRTVCARDS (sizeof(tvcards)/sizeof(tvcards[0]))
+
+static struct { const char name[8]; int mode; int bpp; } palette2fmt[] = {
+/* n/a     */	{ "n/a",     0, 0 },
+/* GREY    */	{ "GRAY",    0, 0 },
+/* HI240   */	{ "HI240",   0, 0 },
+/* RGB565  */	{ "RGB565",  ZORAN_VFEC_RGB_RGB565|ZORAN_VFEC_LE, 2 },
+/* RGB24   */	{ "RGB24",   ZORAN_VFEC_RGB_RGB888|ZORAN_VFEC_LE|ZORAN_VFEC_PACK24, 3 },
+/* RGB32   */	{ "RGB32",   ZORAN_VFEC_RGB_RGB888|ZORAN_VFEC_LE, 4 },
+/* RGB555  */	{ "RGB555",  ZORAN_VFEC_RGB_RGB555|ZORAN_VFEC_LE, 2 },
+/* YUV422  */	{ "YUV422",  ZORAN_VFEC_RGB_YUV422|ZORAN_VFEC_LE, 3 },
+/* YUYV    */	{ "YUYV",    0, 0 },
+/* UYVY    */	{ "UYVY",    0, 0 },
+/* YUV420  */	{ "YUV420",  0, 0 },
+/* YUV411  */	{ "YUV411",  0, 0 },
+/* RAW     */	{ "RAW",     0, 0 },
+/* YUV422P */	{ "YUV422P", 0, 0 },
+/* YUV411P */	{ "YUV411P", 0, 0 }};
+#define NRPALETTES (sizeof(palette2fmt)/sizeof(palette2fmt[0]))
+
+/* ----------------------------------------------------------------------- */
+/* ZORAN chipset detector						   */
+/* shamelessly stolen from bttv.c					   */
+/* Reason for beeing here: we need to detect if we are running on a        */
+/* Triton based chipset, and if so, enable a certain bit                   */
+/* ----------------------------------------------------------------------- */
+
+void handle_chipset(void)
+{
+	struct pci_dev *dev = NULL;
+  
+	/* Just in case some nut set this to something dangerous */
+	if (triton1)
+		triton1 = ZORAN_VDC_TRICOM;
+	
+	while ((dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, dev))) 
+	{
+		printk(KERN_INFO "zoran: Host bridge 82437FX Triton PIIX\n");
+		triton1 = ZORAN_VDC_TRICOM;
+	}
+}
+
+/* ----------------------------------------------------------------------- */
+/* ZORAN functions							   */
+/* ----------------------------------------------------------------------- */
+
+static void zoran_set_geo(struct zoran* ztv, struct vidinfo* i);
+
+static
+void zoran_dump(struct zoran *ztv)
+{
+	char	str[1024];
+	char	*p=str; /* shut up, gcc! */
+	int	i;
+
+	for (i=0; i<0x60; i+=4) {
+		if ((i % 16) == 0) {
+			if (i) printk(/*KERN_DEBUG*/ "%s\n",str);
+			p = str;
+			p+= sprintf(str, "       %04x: ",i);
+		}
+		p += sprintf(p, "%08x ",zrread(i));
+	}
+}
+
+static
+void reap_states(struct zoran* ztv)
+{
+	irq1++;		/* debugging... */
+
+	/*
+	 * GRABBING?
+	 */
+	if ( test_bit(STATE_GRAB, &ztv->state) ) {
+		int i;
+
+		/* are we already grabbing? */
+		if (test_bit(STATE_GRAB, &ztv->prevstate)) {
+
+			/* did we get a complete grab? */
+			if (zrread(ZORAN_VSTR) & ZORAN_VSTR_GRAB)
+				goto out;
+
+			/* we are done with this buffer, tell everyone */
+			ztv->grabinfo[ztv->lastframe].status = FBUFFER_DONE;
+			wake_up_interruptible(&ztv->grabq);
+		}
+
+		/* locate a new frame to grab */
+		for (i=0; i<ZORAN_MAX_FBUFFERS; i++)
+			if (ztv->grabinfo[i].status == FBUFFER_GRABBING) {
+
+				/* there is a buffer more to be grabbed... */
+				ztv->lastframe = i;
+
+DEBUG(printk(KERN_DEBUG "irq(%ld): starting grab(%d)\n",irq1,i));
+
+				/* loadup the frame settings */
+				read_lock(&ztv->lock);
+				zoran_set_geo(ztv,&ztv->grabinfo[i]);
+				read_unlock(&ztv->lock);
+
+				zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
+				zrand(~ZORAN_OCR_OVLEN, ZORAN_OCR);
+				zror(ZORAN_VSTR_SNAPSHOT,ZORAN_VSTR);
+				zror(ZORAN_VDC_VIDEN,ZORAN_VDC);
+
+				/* start single-shot grab */
+				zror(ZORAN_VSTR_GRAB, ZORAN_VSTR);
+				goto out;
+			}
+
+DEBUG(printk(KERN_DEBUG "irq(%ld): nothing more to grab\n",irq1));
+
+		/* turn grabbing off the next time around */
+		clear_bit(STATE_GRAB, &ztv->state);
+
+		/* force re-init of Read or Overlay settings */
+		clear_bit(STATE_READ, &ztv->prevstate);
+		clear_bit(STATE_OVERLAY, &ztv->prevstate);
+	}
+
+	/*
+	 * READING?
+	 */
+	if ( test_bit(STATE_READ, &ztv->state) ) {
+		/* are we already reading? */
+		if (!test_bit(STATE_READ, &ztv->prevstate)) {
+
+DEBUG(printk(KERN_DEBUG "irq(%ld): starting read\n",irq1));
+
+			read_lock(&ztv->lock);
+			zoran_set_geo(ztv,&ztv->readinfo);
+			read_unlock(&ztv->lock);
+
+			zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
+			zrand(~ZORAN_OCR_OVLEN, ZORAN_OCR);
+			zror(ZORAN_VSTR_SNAPSHOT,ZORAN_VSTR);
+			zror(ZORAN_VDC_VIDEN,ZORAN_VDC);
+
+			/* start single-shot grab */
+			zror(ZORAN_VSTR_GRAB, ZORAN_VSTR);
+			goto out;
+		}
+
+		/* did we get a complete grab? */
+		if (zrread(ZORAN_VSTR) & ZORAN_VSTR_GRAB)
+			goto out;
+
+DEBUG(printk(KERN_DEBUG "irq(%ld): nothing more to read\n",irq1));
+
+		/* turn reading off the next time around */
+		clear_bit(STATE_READ, &ztv->state);
+		/* force re-init of Overlay settings */
+		clear_bit(STATE_OVERLAY, &ztv->prevstate);
+
+		/* we are done, tell everyone */
+		wake_up_interruptible(&ztv->readq);
+	}
+
+	/*
+	 * OVERLAYING?
+	 */
+	if ( test_bit(STATE_OVERLAY, &ztv->state) ) {
+		/* are we already overlaying? */
+		if (!test_bit(STATE_OVERLAY, &ztv->prevstate)) {
+
+DEBUG(printk(KERN_DEBUG "irq(%ld): starting overlay\n",irq1));
+
+			read_lock(&ztv->lock);
+			zoran_set_geo(ztv,&ztv->overinfo);
+			read_unlock(&ztv->lock);
+
+			zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
+			zrand(~ZORAN_VSTR_SNAPSHOT,ZORAN_VSTR);
+			zror(ZORAN_OCR_OVLEN, ZORAN_OCR);
+			zror(ZORAN_VDC_VIDEN,ZORAN_VDC);
+		}
+
+		/*
+		 * leave overlaying on, but turn interrupts off.
+		 */
+		zrand(~ZORAN_ICR_EN,ZORAN_ICR);
+		goto out;
+	}
+
+	/*
+	 * THEN WE MUST BE IDLING
+	 */
+DEBUG(printk(KERN_DEBUG "irq(%ld): turning off\n",irq1));
+	/* nothing further to do, disable DMA and further IRQs */
+	zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
+	zrand(~ZORAN_ICR_EN,ZORAN_ICR);
+out:
+	ztv->prevstate = ztv->state;
+}
+
+static
+void zoran_irq(int irq, void *dev_id, struct pt_regs * regs)
+{
+	u32 stat,estat;
+	int count = 0;
+	struct zoran *ztv = (struct zoran *)dev_id;
+
+	for (;;) {
+		/* get/clear interrupt status bits */
+		stat=zrread(ZORAN_ISR);
+		estat=stat & zrread(ZORAN_ICR);
+		if (!estat)
+			return;
+		zrwrite(estat,ZORAN_ISR);
+		IDEBUG(printk(KERN_DEBUG "%s: estat %08x\n",CARD,estat));
+		IDEBUG(printk(KERN_DEBUG "%s:  stat %08x\n",CARD,stat));
+
+		if (estat & ZORAN_ISR_CODE)
+		{
+			IDEBUG(printk(KERN_DEBUG "%s: CodReplIRQ\n",CARD));
+		}
+		if (estat & ZORAN_ISR_GIRQ0)
+		{
+			IDEBUG(printk(KERN_DEBUG "%s: GIRQ0\n",CARD));
+			if (!ztv->card->usegirq1)
+				reap_states(ztv);
+		}
+		if (estat & ZORAN_ISR_GIRQ1)
+		{
+			IDEBUG(printk(KERN_DEBUG "%s: GIRQ1\n",CARD));
+			if (ztv->card->usegirq1)
+				reap_states(ztv);
+		}
+
+		count++;
+		if (count > 10)
+			printk(KERN_ERR "%s: irq loop %d (%x)\n",CARD,count,estat);
+		if (count > 20)
+		{
+			zrwrite(0, ZORAN_ICR);
+			printk(KERN_ERR "%s: IRQ lockup, cleared int mask\n",CARD);
+		}
+	}
+}
+
+/*
+ *      Scan for a Zoran chip, request the irq and map the io memory
+ */
+static int find_zoran(void)
+{
+	unsigned char command, latency;
+	int result;
+	struct zoran *ztv;
+	struct pci_dev *dev;
+	int zoran_num=0;
+
+	if (!pcibios_present())
+	{
+		DEBUG(printk(KERN_DEBUG "zoran: PCI-BIOS not present or not accessible!\n"));
+		return 0;
+	}
+
+	for (dev = pci_devices; dev != NULL; dev = dev->next)
+	{
+		if (dev->vendor != PCI_VENDOR_ID_ZORAN)
+			continue;
+		if (dev->device != PCI_DEVICE_ID_ZORAN_36120)
+			continue;
+
+		/* Ok, ZR36120 found! */
+		ztv=&zorans[zoran_num];
+		ztv->dev=dev;
+		ztv->id=dev->device;
+		ztv->zoran_mem=NULL;
+
+		ztv->zoran_adr = ztv->dev->resource[0].start;
+		pci_read_config_byte(ztv->dev, PCI_CLASS_REVISION,
+			     &ztv->revision);
+		printk(KERN_INFO "zoran: Zoran %x (rev %d) ",
+			ztv->id, ztv->revision);
+		printk("bus: %d, devfn: %d, ",
+			ztv->dev->bus->number, ztv->dev->devfn);
+		printk("irq: %d, ",ztv->dev->irq);
+		printk("memory: 0x%08x.\n", ztv->zoran_adr);
+
+		ztv->zoran_mem = ioremap(ztv->zoran_adr, 0x1000);
+		DEBUG(printk(KERN_DEBUG "zoran: mapped-memory at 0x%p\n",ztv->zoran_mem));
+
+		result = request_irq(ztv->dev->irq, zoran_irq,
+			SA_SHIRQ|SA_INTERRUPT,"zoran",(void *)ztv);
+		if (result==-EINVAL)
+		{
+			printk(KERN_ERR "zoran: Bad irq number or handler\n");
+			return -EINVAL;
+		}
+		if (result==-EBUSY)
+		{
+			printk(KERN_ERR "zoran: IRQ %d busy, change your PnP config in BIOS\n",ztv->dev->irq);
+			return result;
+		}
+		if (result < 0)
+			return result;
+
+		/* Enable bus-mastering */
+		pci_read_config_byte(ztv->dev, PCI_COMMAND, &command);
+		command|=PCI_COMMAND_MASTER|PCI_COMMAND_MEMORY;
+		pci_write_config_byte(ztv->dev, PCI_COMMAND, command);
+		pci_read_config_byte(ztv->dev, PCI_COMMAND, &command);
+		if (!(command&PCI_COMMAND_MASTER))
+		{
+			printk(KERN_ERR "zoran: PCI bus-mastering could not be enabled\n");
+			return -1;
+		}
+		pci_read_config_byte(ztv->dev, PCI_LATENCY_TIMER, &latency);
+		if (!latency)
+		{
+			latency=32;
+			pci_write_config_byte(ztv->dev, PCI_LATENCY_TIMER, latency);
+			DEBUG(printk(KERN_INFO "zoran: latency set to %d\n",latency));
+		}
+		zoran_num++;
+	}
+	if(zoran_num)
+		printk(KERN_INFO "zoran: %d Zoran card(s) found.\n",zoran_num);
+	return zoran_num;
+}
+
+static
+int zoran_muxsel(struct zoran* ztv, int channel, int norm)
+{
+	int	rv;
+
+	/* set the new video norm */
+	rv = i2c_control_device(&(ztv->i2c), I2C_DRIVERID_VIDEODECODER, DECODER_SET_NORM, &norm);
+	if (rv)
+		return rv;
+	ztv->norm = norm;
+
+	/* map the given channel to the cards decoder's channel */
+	channel = ztv->card->video_mux[channel] & CHANNEL_MASK;
+
+	/* set the new channel */
+	rv = i2c_control_device(&(ztv->i2c), I2C_DRIVERID_VIDEODECODER, DECODER_SET_INPUT, &channel);
+	return rv;
+}
+
+/* Tell the interrupt handler what to to.  */
+static
+void zoran_cap(struct zoran* ztv, int on)
+{
+	DEBUG(printk(KERN_DEBUG "       zoran_cap(%d) at %ld, state=%x\n",on,irq1,ztv->state));
+
+	if (on) {
+		ztv->running = 1;
+		/* 
+		 * Clear the previous state flag. This way the irq
+		 * handler will be forced to re-examine its current
+		 * state from scratch, setting up the registers along
+		 * the way.
+		 */
+		clear_bit(STATE_OVERLAY, &ztv->prevstate);
+		/*
+		 * turn interrupts back on. The DMA will be enabled
+		 * inside the irq handler when it detects a restart.
+		 */
+		zror(ZORAN_ICR_CODE|ZORAN_ICR_GIRQ0|ZORAN_ICR_GIRQ1,ZORAN_ICR);
+		zror(ZORAN_ICR_EN,ZORAN_ICR);
+	}
+	else {
+		ztv->running = 0;
+		/*
+		 * turn interrupts and DMA both off
+		 */
+		zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
+		zrand(~ZORAN_ICR_EN,ZORAN_ICR);
+	}
+}
+
+static ulong dmask[] = {
+	0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFC, 0xFFFFFFF8,
+	0xFFFFFFF0, 0xFFFFFFE0, 0xFFFFFFC0, 0xFFFFFF80,
+	0xFFFFFF00, 0xFFFFFE00, 0xFFFFFC00, 0xFFFFF800,
+	0xFFFFF000, 0xFFFFE000, 0xFFFFC000, 0xFFFF8000,
+	0xFFFF0000, 0xFFFE0000, 0xFFFC0000, 0xFFF80000,
+	0xFFF00000, 0xFFE00000, 0xFFC00000, 0xFF800000,
+	0xFF000000, 0xFE000000, 0xFC000000, 0xF8000000,
+	0xF0000000, 0xE0000000, 0xC0000000, 0x80000000
+};
+
+static
+void zoran_built_overlay(struct zoran* ztv, int count, struct video_clip *vcp)
+{
+	ulong*	mtop;
+	int	ystep = (ztv->vidXshift + ztv->vidWidth+31)/32;	/* next DWORD */
+	int	mult = ztv->interlace;		/* double height? */
+	int	i;
+
+	DEBUG(printk(KERN_DEBUG "       overlay at %p, ystep=%d, clips=%d\n",ztv->overinfo.overlay,ystep,count));
+	if (ztv->overinfo.overlay == 0) {
+		zrand(~ZORAN_OCR_OVLEN, ZORAN_OCR);
+		return;
+	}
+
+for (i=0; i<count; i++) {
+	struct video_clip *vp = vcp+i;
+	DEBUG(printk(KERN_DEBUG "       %d: clip(%d,%d,%d,%d)\n",
+		i,vp->x,vp->y,vp->width,vp->height));
+}
+
+	/* clear entire blob */
+/*	memset(ztv->overinfo.overlay, 0, 1024*1024/8); */
+
+	/*
+	 * activate the visible portion of the screen
+	 * Note we take some shortcuts here, because we
+	 * know the width can never be < 32. (I.e. a DWORD)
+	 * We also assume the overlay starts somewhere in
+	 * the FIRST dword.
+	 */
+	{
+		int start = ztv->vidXshift;
+		ulong firstd = dmask[start];
+		ulong lastd = ~dmask[(start + ztv->overinfo.w) & 31];
+		mtop = ztv->overinfo.overlay;
+		for (i=0; i<ztv->overinfo.h; i++) {
+			int w = ztv->vidWidth;
+			ulong* line = mtop;
+			if (start & 31) {
+				*line++ = firstd;
+				w -= 32-(start&31);
+			}
+			memset(line, ~0, w/8);
+			if (w & 31)
+				line[w/32] = lastd;
+			mtop += ystep;
+		}
+	}
+
+	/* process clipping regions */
+	for (i=0; i<count; i++) {
+		int h;
+		if (vcp->x < 0 || vcp->x > ztv->overinfo.w ||
+		    vcp->y < 0 || vcp->y > ztv->overinfo.h ||
+		    vcp->width < 0 || (vcp->x+vcp->width) > ztv->overinfo.w ||
+		    vcp->height < 0 || (vcp->y+vcp->height) > ztv->overinfo.h)
+		{
+			DEBUG(printk(KERN_DEBUG "%s: illegal clipzone (%d,%d,%d,%d) not in (0,0,%d,%d), adapting\n",CARD,vcp->x,vcp->y,vcp->width,vcp->height,ztv->overinfo.w,ztv->overinfo.h));
+			if (vcp->x < 0) vcp->x = 0;
+			if (vcp->x > ztv->overinfo.w) vcp->x = ztv->overinfo.w;
+			if (vcp->y < 0) vcp->y = 0;
+			if (vcp->y > ztv->overinfo.h) vcp->y = ztv->overinfo.h;
+			if (vcp->width < 0) vcp->width = 0;
+			if (vcp->x+vcp->width > ztv->overinfo.w) vcp->width = ztv->overinfo.w - vcp->x;
+			if (vcp->height < 0) vcp->height = 0;
+			if (vcp->y+vcp->height > ztv->overinfo.h) vcp->height = ztv->overinfo.h - vcp->y;
+//			continue;
+		}
+
+		mtop = &ztv->overinfo.overlay[vcp->y*ystep];
+		for (h=0; h<=vcp->height; h++) {
+			int w;
+			int x = ztv->vidXshift + vcp->x;
+			for (w=0; w<=vcp->width; w++) {
+				clear_bit(x&31, &mtop[x/32]);
+				x++;
+			}
+			mtop += ystep;
+		}
+		++vcp;
+	}
+
+	mtop = ztv->overinfo.overlay;
+	zrwrite(virt_to_bus(mtop), ZORAN_MTOP);
+	zrwrite(virt_to_bus(mtop+ystep), ZORAN_MBOT);
+	zraor((mult*ystep)<<0,~ZORAN_OCR_MASKSTRIDE,ZORAN_OCR);
+}
+
+struct tvnorm 
+{
+	u16 Wt, Wa, Ht, Ha, HStart, VStart;
+};
+
+static struct tvnorm tvnorms[] = {
+	/* PAL-BDGHI */
+/*	{ 864, 720, 625, 576, 131, 21 },*/
+/*00*/	{ 864, 768, 625, 576, 81, 17 },
+	/* NTSC */
+/*01*/	{ 858, 720, 525, 480, 121, 10 },
+	/* SECAM */
+/*02*/	{ 864, 720, 625, 576, 131, 21 },
+	/* BW50 */
+/*03*/	{ 864, 720, 625, 576, 131, 21 },
+	/* BW60 */
+/*04*/	{ 858, 720, 525, 480, 121, 10 }
+};
+#define TVNORMS (sizeof(tvnorms)/sizeof(tvnorm))
+
+static
+void zoran_set_geo(struct zoran* ztv, struct vidinfo* i)
+{
+	ulong	top, bot;
+	int	stride;
+	int	winWidth, winHeight;
+	int	maxWidth, maxHeight, maxXOffset, maxYOffset;
+	int	filter;
+
+	DEBUG(printk(KERN_DEBUG "       set_geo(rect=(%d,%d,%d,%d), norm=%d, format=%d, bpp=%d, bpl=%d, vidadr=%lx, overlay=%p)\n", i->x,i->y,i->w,i->h,ztv->norm,i->format,i->bpp,i->bpl,i->vidadr,i->overlay));
+
+	/*
+	 * make sure the DMA transfers are inhibited during our
+	 * reprogramming of the chip
+	 */
+	zrand(~ZORAN_VDC_VIDEN,ZORAN_VDC);
+
+	maxWidth = tvnorms[ztv->norm].Wa;
+	maxHeight = tvnorms[ztv->norm].Ha;
+	maxXOffset = tvnorms[ztv->norm].HStart;
+	maxYOffset = tvnorms[ztv->norm].VStart;
+
+	/*
+	 * Set top, bottom ptrs. Since these must be DWORD aligned,
+	 * possible adjust the x and the width of the window.
+	 * so the endposition stay the same. The vidXshift will make
+	 * sure we are not writing pixels before the requested x.
+	 */
+	ztv->vidXshift = 0;
+	winWidth = i->w;
+	top = i->vidadr + i->x*i->bpp + i->y*i->bpl;
+	if (top & 3) {
+		ztv->vidXshift = (top & 3) / i->bpp;
+		winWidth += ztv->vidXshift;
+		DEBUG(printk(KERN_DEBUG "       window-x shifted %d pixels left\n",ztv->vidXshift));
+		top &= ~3;
+	}
+
+	/*
+	 * bottom points to next frame but in interleaved mode we want
+	 * to 'mix' the 2 frames to one capture, so 'bot' points to one
+	 * (physical) line below the top line.
+	 */
+	bot = top + i->bpl;
+	zrwrite(top,ZORAN_VTOP);
+	zrwrite(bot,ZORAN_VBOT);
+
+	/*
+	 * Make sure the winWidth is DWORD aligned too,
+	 * thereby automaticly making sure the stride to the
+	 * next line is DWORD aligned too (as required by spec).
+	 */
+	if ((winWidth*i->bpp) & 3) {
+		DEBUG(printk(KERN_DEBUG "       window-width enlarged by %d pixels\n",(winWidth*i->bpp) & 3));
+		winWidth += (winWidth*i->bpp) & 3;
+	}
+
+	/* determine the DispMode and stride */
+	if (i->h <= maxHeight/2) {
+		/* single frame suffices for this height */
+		zror(ZORAN_VFEC_DISPMOD, ZORAN_VFEC);
+		ztv->interlace = 0;
+		winHeight = i->h;
+		if (winHeight < 0)	/* can happen for read's! */
+			winHeight = -winHeight;
+		stride = i->bpl - (winWidth*i->bpp);
+	}
+	else {
+		/* interleaving needed for this height */
+		zrand(~ZORAN_VFEC_DISPMOD, ZORAN_VFEC);
+		ztv->interlace = 1;
+		winHeight = i->h/2;
+		stride = i->bpl*2 - (winWidth*i->bpp);
+	}
+	/* safety net, sometimes bpl is too short??? */
+	if (stride<0) {
+		DEBUG(printk(KERN_DEBUG "%s: WARNING stride = %d\n",CARD,stride));
+		stride = 0;
+	}
+
+	zraor((winHeight<<12)|(winWidth<<0),~(ZORAN_VDC_VIDWINHT|ZORAN_VDC_VIDWINWID), ZORAN_VDC);
+	zraor(stride<<16,~ZORAN_VSTR_DISPSTRIDE,ZORAN_VSTR);
+
+	/* remember vidWidth, vidHeight for overlay calculations */
+	ztv->vidWidth = winWidth;
+	ztv->vidHeight = winHeight;
+DEBUG(printk(KERN_DEBUG "       top=%08lx, bottom=%08lx, winWidth=%d, winHeight=%d, maxWidth=%d, maxHeight=%d, stride=%d\n",top,bot,winWidth,winHeight,maxWidth,maxHeight,stride));
+
+	/* determine scales and crops */
+	if (1) {
+		int Wa, X, We, HorDcm, hcrop1, hcrop2, Hstart, Hend;
+
+A:		Wa = maxWidth;
+		X = (winWidth*64+Wa-1)/Wa;
+		We = winWidth*64/X;
+		HorDcm = 64-X;
+		hcrop1 = 2*(Wa-We)/4;
+		hcrop2 = Wa-We-hcrop1;
+		Hstart = maxXOffset + hcrop1;
+		Hend = maxXOffset + Wa-1-hcrop2;
+
+		/*
+		 * BUGFIX: Juha Nurmela <junki@qn-lpr2-165.quicknet.inet.fi> 
+		 * found the solution to the color phase shift.
+		 * See ChangeLog for the full explanation)
+		 */
+		if (!(Hstart & 1)) {
+DEBUG(printk(KERN_DEBUG "       correcting horizontal start/end by one\n"));
+			winWidth--;
+			goto A;
+		}
+
+DEBUG(printk(KERN_DEBUG "       X: scale=%d, start=%d, end=%d\n", HorDcm, Hstart, Hend));
+
+		zraor((Hstart<<10)|(Hend<<0),~(ZORAN_VFEH_HSTART|ZORAN_VFEH_HEND),ZORAN_VFEH);
+		zraor((HorDcm<<14),~ZORAN_VFEC_HORDCM, ZORAN_VFEC);
+
+		filter = ZORAN_VFEC_HFILTER_1;
+		if (HorDcm >= 48)
+			filter = ZORAN_VFEC_HFILTER_5; /* 5 tap filter */
+		else if (HorDcm >= 32)
+			filter = ZORAN_VFEC_HFILTER_4; /* 4 tap filter */
+		else if (HorDcm >= 16)
+			filter = ZORAN_VFEC_HFILTER_3; /* 3 tap filter */
+		zraor(filter, ~ZORAN_VFEC_HFILTER, ZORAN_VFEC);
+	}
+	/* when height is negative, we want to read from line 0 */
+	if (i->h < 0) {
+		int Vstart = 0;
+		int Vend = Vstart + winHeight;
+		int VerDcm = 0;
+DEBUG(printk(KERN_DEBUG "       Y: scale=%d, start=%d, end=%d\n", VerDcm, Vstart, Vend));
+		zraor((Vstart<<10)|(Vend<<0),~(ZORAN_VFEV_VSTART|ZORAN_VFEV_VEND),ZORAN_VFEV);
+		zraor((VerDcm<<8),~ZORAN_VFEC_VERDCM, ZORAN_VFEC);
+	}
+	else {
+		int Ha = maxHeight/2;
+		int Y = (winHeight*64+Ha-1)/Ha;
+		int He = winHeight*64/Y;
+		int VerDcm = 64-Y;
+		int vcrop1 = 2*(Ha-He)/4;
+		int vcrop2 = Ha-He-vcrop1;
+		int Vstart = maxYOffset + vcrop1;
+		int Vend = maxYOffset + Ha-1-vcrop2;
+
+DEBUG(printk(KERN_DEBUG "       Y: scale=%d, start=%d, end=%d\n", VerDcm, Vstart, Vend));
+		zraor((Vstart<<10)|(Vend<<0),~(ZORAN_VFEV_VSTART|ZORAN_VFEV_VEND),ZORAN_VFEV);
+		zraor((VerDcm<<8),~ZORAN_VFEC_VERDCM, ZORAN_VFEC);
+	}
+
+DEBUG(printk(KERN_DEBUG "       F: format=%d(=%s)\n",i->format,palette2fmt[i->format].name));
+	/* setup the requested format */
+	zraor(palette2fmt[i->format].mode, ~(ZORAN_VFEC_RGB|ZORAN_VFEC_LE|ZORAN_VFEC_PACK24), ZORAN_VFEC);
+}
+
+#if LINUX_VERSION_CODE >= 0x020100
+static
+unsigned int zoran_poll(struct video_device *dev, struct file *file, poll_table *wait)
+{
+	struct zoran *ztv = (struct zoran *)dev;
+
+	poll_wait(file, &ztv->readq, wait);
+
+	return (POLLIN | POLLRDNORM);
+}
+#endif
+
+/*
+ * Open a zoran card. Right now the flags are just a hack
+ */
+static int zoran_open(struct video_device *dev, int flags)
+{
+	struct zoran *ztv = (struct zoran*)dev;
+	int	i;
+
+	DEBUG(printk(KERN_DEBUG "%s: open(dev,%d)\n",CARD,flags));
+
+	switch (flags) {
+	 case 0:
+		/* already active? */
+		if (ztv->user)
+			return -EBUSY;
+		ztv->user++;
+
+		/* unmute audio */
+		/* /what/ audio? */
+
+/******************************************
+ We really should be doing lazy allocing...
+ ******************************************/
+		/* allocate a frame buffer */
+		if (!ztv->fbuffer)
+			ztv->fbuffer = bmalloc(ZORAN_MAX_FBUFSIZE);
+		if (!ztv->fbuffer) {
+			/* could not get a buffer, bail out */
+			ztv->user--;
+			return -ENOBUFS;
+		}
+		/* at this time we _always_ have a framebuffer */
+		memset(ztv->fbuffer,0,ZORAN_MAX_FBUFSIZE);
+
+		if (!ztv->overinfo.overlay)
+			ztv->overinfo.overlay = (void*)kmalloc(1024*1024/8, GFP_KERNEL);
+		if (!ztv->overinfo.overlay) {
+			/* could not get an overlay buffer, bail out */
+			ztv->user--;
+			bfree(ztv->fbuffer, ZORAN_MAX_FBUFSIZE);
+			return -ENOBUFS;
+		}
+		/* at this time we _always_ have a overlay */
+
+		/* clear buffer status */
+		for (i=0; i<ZORAN_MAX_FBUFFERS; i++)
+			ztv->grabinfo[i].status = FBUFFER_UNUSED;
+		ztv->state = 0;
+		ztv->prevstate = 0;
+		ztv->lastframe = -1;
+
+		/* setup the encoder to the initial values */
+		i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &ztv->picture);
+
+		/* default to the compisite input since my camera is there */
+		zoran_muxsel(ztv, 0, VIDEO_MODE_PAL);
+		break;
+	 case 1:
+		break;
+	}
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static
+void zoran_close(struct video_device* dev)
+{
+	struct zoran *ztv = (struct zoran*)dev;
+
+	DEBUG(printk(KERN_DEBUG "%s: close(dev)\n",CARD));
+
+	/* we are no longer active, goodbye */
+	ztv->user--;
+
+	/* mute audio */
+	/* stop the chip */
+	zoran_cap(ztv, 0);
+
+	/* free the allocated framebuffer */
+	if (ztv->fbuffer)
+		bfree( ztv->fbuffer, ZORAN_MAX_FBUFSIZE );
+	ztv->fbuffer = 0;
+	if (ztv->overinfo.overlay)
+		kfree( ztv->overinfo.overlay );
+	ztv->overinfo.overlay = 0;
+
+	MOD_DEC_USE_COUNT;
+}
+
+static
+long zoran_write(struct video_device* dev, const char* buf, unsigned long count, int nonblock)
+{
+	DEBUG(printk(KERN_DEBUG "zoran_write\n"));
+	return -EINVAL;
+}
+
+static
+long zoran_read(struct video_device* dev, char* buf, unsigned long count, int nonblock)
+{
+	struct zoran *ztv = (struct zoran*)dev;
+	int	max;
+
+	DEBUG(printk(KERN_DEBUG "zoran_read(%p,%ld,%d)\n",buf,count,nonblock));
+
+	/* tell the state machine we want in too */
+	write_lock_irq(&ztv->lock);
+	ztv->readinfo.vidadr = virt_to_bus(phys_to_virt((ulong)ztv->fbuffer));
+	set_bit(STATE_READ, &ztv->state);
+	write_unlock_irq(&ztv->lock);
+	zoran_cap(ztv, 1);
+
+	/* wait for data to arrive */
+	interruptible_sleep_on(&ztv->readq);
+
+	/* see if a signal did it */
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+
+	/* give the user what he requested */
+	max = ztv->readinfo.w*ztv->readinfo.bpp - ztv->readinfo.h*ztv->readinfo.bpl;
+	if (count > max)
+		count = max;
+	if (copy_to_user((void*)buf, (void*)ztv->fbuffer, count))
+		return -EFAULT;
+
+	/* goodbye */
+	return count;
+}
+
+/* append a new clipregion to the vector of video_clips */
+static
+void new_clip(struct video_window* vw, struct video_clip* vcp, int x, int y, int w, int h)
+{
+	vcp[vw->clipcount].x = x;
+	vcp[vw->clipcount].y = y;
+	vcp[vw->clipcount].width = w;
+	vcp[vw->clipcount].height = h;
+	vw->clipcount++;
+}
+
+static
+int zoran_ioctl(struct video_device* dev, unsigned int cmd, void *arg)
+{
+	struct zoran* ztv = (struct zoran*)dev;
+
+	switch (cmd) {
+	 case VIDIOCGCAP:
+	 {	/* get video capabilities */
+		struct video_capability c;
+		struct video_decoder_capability dc;
+		int rv;
+		DEBUG(printk(KERN_DEBUG "%s: GetCapabilities\n",CARD));
+
+		/* fetch the capabilites of the decoder */
+		dc.flags = 0;
+		dc.inputs = -1;
+		dc.outputs = -1;
+		rv = i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_GET_CAPABILITIES, &dc);
+		if (rv)
+			return rv;
+		DEBUG(printk(KERN_DEBUG "%s: capabilities %d %d %d\n",CARD,dc.flags,dc.inputs,dc.outputs));
+
+		strcpy(c.name,ztv->video_dev.name);
+		c.type = VID_TYPE_CAPTURE|
+			 VID_TYPE_OVERLAY|
+			 VID_TYPE_CLIPPING|
+			 VID_TYPE_FRAMERAM|
+			 VID_TYPE_SCALES;
+		c.channels = ztv->card->video_inputs;
+		c.audios = ztv->card->audio_inputs;
+		c.maxwidth = 768;
+		c.maxheight = 576;
+		c.minwidth = 32;
+		c.minheight = 32;
+		if (copy_to_user(arg,&c,sizeof(c)))
+			return -EFAULT;
+		return 0;
+	 }
+
+	 case VIDIOCGCHAN:
+	 {
+		struct video_channel v;
+		int mux;
+
+		if (copy_from_user(&v, arg,sizeof(v)))
+			return -EFAULT;
+		DEBUG(printk(KERN_DEBUG "%s: GetChannel(%d)\n",CARD,v.channel));
+		v.flags=VIDEO_VC_AUDIO
+#ifdef VIDEO_VC_NORM
+			|VIDEO_VC_NORM
+#endif
+			;
+		v.tuners=0;
+		v.type=VIDEO_TYPE_CAMERA;
+#ifdef I_EXPECT_POSSIBLE_NORMS_IN_THE_API
+		v.norm=VIDEO_MODE_PAL|
+		       VIDEO_MODE_NTSC|
+		       VIDEO_MODE_SECAM;
+#else
+		v.norm=VIDEO_MODE_PAL;
+#endif
+		/* too many inputs? */
+		if (v.channel >= ztv->card->video_inputs)
+			return -EINVAL;
+
+		/* now determine the name of the channel */
+		mux = ztv->card->video_mux[v.channel];
+		if (mux & IS_TUNER) {
+			/* lets assume only one tuner, yes? */
+			strcpy(v.name,"Television");
+			v.type = VIDEO_TYPE_TV;
+			if (ztv->have_tuner) {
+				v.flags |= VIDEO_VC_TUNER;
+				v.tuners = 1;
+			}
+		}
+		else if (mux & IS_SVHS)
+			sprintf(v.name,"S-Video-%d",v.channel);
+		else
+			sprintf(v.name,"CVBS-%d",v.channel);
+
+		if (copy_to_user(arg,&v,sizeof(v)))
+			return -EFAULT;
+		return 0;
+	 }
+	 case VIDIOCSCHAN:
+	 {	/* set video channel */
+		struct video_channel v;
+		if (copy_from_user(&v, arg,sizeof(v)))
+			return -EFAULT;
+		DEBUG(printk(KERN_DEBUG "%s: SetChannel(%d,%d)\n",CARD,v.channel,v.norm));
+		if (v.channel >= ztv->card->video_inputs)
+			return -EINVAL;
+
+		if (v.norm != VIDEO_MODE_PAL &&
+		    v.norm != VIDEO_MODE_NTSC &&
+		    v.norm != VIDEO_MODE_SECAM &&
+		    v.norm != VIDEO_MODE_AUTO)
+			return -EOPNOTSUPP;
+
+		/* make it happen, nr1! */
+		return zoran_muxsel(ztv,v.channel,v.norm);
+	 }
+
+	 case VIDIOCGTUNER:
+	 {
+		struct video_tuner v;
+		if (copy_from_user(&v, arg,sizeof(v)))
+			return -EFAULT;
+
+		/* Only one tuner for now */
+		if (!ztv->have_tuner && v.tuner)
+			return -EINVAL;
+
+		strcpy(v.name,"Television");
+		v.rangelow  = 0;
+		v.rangehigh = ~0;
+		v.flags     = VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
+		v.mode      = ztv->norm;
+		v.signal    = 0xFFFF; /* unknown */
+
+		if (copy_to_user(arg,&v,sizeof(v)))
+			return -EFAULT;
+		return 0;
+	 }
+
+	 case VIDIOCSTUNER:
+	 {
+		struct video_tuner v;
+		if (copy_from_user(&v, arg, sizeof(v)))
+			return -EFAULT;
+
+		/* Only one tuner for now */
+		if (!ztv->have_tuner && v.tuner)
+			return -EINVAL;
+
+		/* and it only has certain valid modes */
+		if( v.mode != VIDEO_MODE_PAL &&
+		    v.mode != VIDEO_MODE_NTSC &&
+		    v.mode != VIDEO_MODE_SECAM)
+			return -EOPNOTSUPP;
+
+		/* engage! */
+		return zoran_muxsel(ztv,v.tuner,v.mode);
+	 }
+
+	 case VIDIOCGPICT:
+	 {
+		struct video_picture p = ztv->picture;
+		DEBUG(printk(KERN_DEBUG "%s: GetPicture\n",CARD));
+		p.depth = ztv->depth;
+		switch (p.depth) {
+		 case  8: p.palette=VIDEO_PALETTE_YUV422;
+			  break;
+		 case 15: p.palette=VIDEO_PALETTE_RGB555;
+			  break;
+		 case 16: p.palette=VIDEO_PALETTE_RGB565;
+			  break;
+		 case 24: p.palette=VIDEO_PALETTE_RGB24;
+			  break;
+		 case 32: p.palette=VIDEO_PALETTE_RGB32;
+			  break;
+		}
+		if (copy_to_user(arg, &p, sizeof(p)))
+			return -EFAULT;
+		return 0;
+	 }
+	 case VIDIOCSPICT:
+	 {
+		struct video_picture p;
+		DEBUG(printk(KERN_DEBUG "%s: SetPicture\n",CARD));
+		if (copy_from_user(&p, arg,sizeof(p)))
+			return -EFAULT;
+
+		/* depth must match with framebuffer */
+		if (p.depth != ztv->depth)
+			return -EINVAL;
+
+		/* check if palette matches this bpp */
+		if (p.palette<1 || p.palette>NRPALETTES ||
+		    palette2fmt[p.palette].bpp != ztv->overinfo.bpp)
+			return -EINVAL;
+
+		write_lock_irq(&ztv->lock);
+		ztv->overinfo.format = p.palette;
+		ztv->picture = p;
+		write_unlock_irq(&ztv->lock);
+
+		/* tell the decoder */
+		i2c_control_device(&ztv->i2c, I2C_DRIVERID_VIDEODECODER, DECODER_SET_PICTURE, &p);
+		return 0;
+	 }
+
+	 case VIDIOCGWIN:
+	 {
+		struct video_window vw;
+		DEBUG(printk(KERN_DEBUG "%s: GetWindow\n",CARD));
+		read_lock(&ztv->lock);
+		vw.x      = ztv->overinfo.x;
+		vw.y      = ztv->overinfo.y;
+		vw.width  = ztv->overinfo.w;
+		vw.height = ztv->overinfo.h;
+		vw.chromakey= 0;
+		vw.flags  = 0;
+		if (ztv->interlace)
+			vw.flags|=VIDEO_WINDOW_INTERLACE;
+		read_unlock(&ztv->lock);
+		if (copy_to_user(arg,&vw,sizeof(vw)))
+			return -EFAULT;
+		return 0;
+	 }
+	 case VIDIOCSWIN:
+	 {
+		struct video_window vw;
+		struct video_clip *vcp;
+		int on;
+
+		if (copy_from_user(&vw,arg,sizeof(vw)))
+			return -EFAULT;
+
+		DEBUG(printk(KERN_DEBUG "%s: SetWindow(%d,%d,%d,%d,%x,%d)\n",CARD,vw.x,vw.y,vw.width,vw.height,vw.flags,vw.clipcount));
+
+		if (vw.flags)
+			return -EINVAL;
+
+		if (vw.clipcount>256)
+			return -EDOM;   /* Too many! */
+
+		/*
+		 *      Do any clips.
+		 */
+		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))
+			return -EFAULT;
+
+		on = ztv->running;
+		if (on)
+			zoran_cap(ztv, 0);
+
+		/* by now we are committed to the new data... */
+		write_lock_irq(&ztv->lock);
+		ztv->overinfo.x = vw.x;
+		ztv->overinfo.y = vw.y;
+		ztv->overinfo.w = vw.width;
+		ztv->overinfo.h = vw.height;
+		write_unlock_irq(&ztv->lock);
+
+		/*
+		 *      Impose display clips
+		 */
+		if (vw.x<0)
+			new_clip(&vw, vcp, 0, 0, -vw.x, vw.height-1);
+		if (vw.y<0)
+			new_clip(&vw, vcp, 0, 0, vw.width-1,-vw.y);
+		if (vw.x+vw.width > ztv->swidth)
+			new_clip(&vw, vcp, ztv->swidth-vw.x, 0, vw.width-1, vw.height-1);
+		if (vw.y+vw.height > ztv->sheight)
+			new_clip(&vw, vcp, 0, ztv->sheight-vw.y, vw.width-1, vw.height-1);
+
+		/* built the requested clipping zones */
+		zoran_set_geo(ztv, &ztv->overinfo);
+		zoran_built_overlay(ztv, vw.clipcount, vcp);
+		vfree(vcp);
+
+		/* if we were on, restart the video engine */
+		if (on) zoran_cap(ztv, on);
+		return 0;
+	 }
+	 case VIDIOCCAPTURE:
+	 {
+		int v;
+		get_user_ret(v,(int*)arg, -EFAULT);
+		DEBUG(printk(KERN_DEBUG "%s: Capture(%d)\n",CARD,v));
+
+		if (v==0) {
+			zoran_cap(ztv, 0);
+			clear_bit(STATE_OVERLAY, &ztv->state);
+		}
+		else {
+			/* is VIDIOCSFBUF, VIDIOCSWIN done? */
+			if (ztv->overinfo.vidadr==0 || ztv->overinfo.w==0 || ztv->overinfo.h==0)
+				return -EINVAL;
+
+			set_bit(STATE_OVERLAY, &ztv->state);
+			zoran_cap(ztv, 1);
+		}
+		return 0;
+	 }
+
+	 case VIDIOCGFBUF:
+	 {
+		struct video_buffer v;
+		DEBUG(printk(KERN_DEBUG "%s: GetFramebuffer\n",CARD));
+		read_lock(&ztv->lock);
+		v.base   = (void *)ztv->overinfo.vidadr;
+		v.height = ztv->sheight;
+		v.width  = ztv->swidth;
+		v.depth  = ztv->depth;
+		v.bytesperline = ztv->overinfo.bpl;
+		read_unlock(&ztv->lock);
+		if(copy_to_user(arg, &v,sizeof(v)))
+			return -EFAULT;
+		return 0;
+	 }
+	 case VIDIOCSFBUF:
+	 {
+		struct video_buffer v;
+#if LINUX_VERSION_CODE >= 0x020100
+			if(!capable(CAP_SYS_ADMIN))
+#else
+			if(!suser())
+#endif
+			return -EPERM;
+		if (copy_from_user(&v, arg,sizeof(v)))
+			return -EFAULT;
+		if (v.depth!=15 && v.depth!=16 && v.depth!=24 && v.depth!=32)
+			return -EINVAL;
+		if (v.bytesperline<1)
+			return -EINVAL;
+		if (ztv->running)
+			return -EBUSY;
+		write_lock_irq(&ztv->lock);
+		ztv->overinfo.vidadr  = (unsigned long)v.base;
+		ztv->sheight      = v.height;
+		ztv->swidth       = v.width;
+		ztv->overinfo.bpp = ((v.depth+1)&0x38)/8;/* bytes per pixel */
+		ztv->depth        = v.depth;		/* bits per pixel */
+		ztv->overinfo.bpl = v.bytesperline;
+		write_unlock_irq(&ztv->lock);
+
+		DEBUG(printk(KERN_DEBUG "%s: SetFrameBuffer(%p,%dx%d, bpp %d, bpl %d)\n",CARD,v.base, v.width,v.height, ztv->overinfo.bpp, ztv->overinfo.bpl));
+		return 0;
+	 }
+
+	 case VIDIOCSYNC:
+	 {
+		int i;
+		get_user_ret(i,(int*)arg, -EFAULT);
+		DEBUG(printk(KERN_DEBUG "%s: VIDEOCSYNC(%d)\n",CARD,i));
+		if (i<0 || i>ZORAN_MAX_FBUFFERS)
+			return -EINVAL;
+		switch (ztv->grabinfo[i].status) {
+		 case FBUFFER_UNUSED:
+			return -EINVAL;
+		 case FBUFFER_GRABBING:
+			/* wait till this buffer gets grabbed */
+			while (ztv->grabinfo[i].status == FBUFFER_GRABBING) {
+				interruptible_sleep_on(&ztv->grabq);
+				/* see if a signal did it */
+				if (signal_pending(current))
+					return -ERESTARTSYS;
+			}
+			/* fall through */
+		 case FBUFFER_DONE:
+			ztv->grabinfo[i].status = FBUFFER_UNUSED;
+			break;
+		}
+		return 0;
+	 }
+
+	 case VIDIOCKEY:
+	 {
+		/* Will be handled higher up .. */
+		return 0;
+	 }
+
+	 case VIDIOCMCAPTURE:
+	 {
+		struct video_mmap vm;
+		struct vidinfo* frame;
+		if (copy_from_user(&vm,arg,sizeof(vm)))
+			return -EFAULT;
+		if (vm.frame<0 || vm.frame>ZORAN_MAX_FBUFFERS ||
+		    vm.width<32 || vm.width>768 ||
+		    vm.height<32 || vm.height>576 ||
+		    vm.format<0 || vm.format>NRPALETTES ||
+		    palette2fmt[vm.format].mode == 0)
+			return -EINVAL;
+
+		DEBUG(printk(KERN_DEBUG "%s: Mcapture(%d,(%d,%d),%d=%s)\n",CARD,vm.frame,vm.width,vm.height,vm.format,palette2fmt[vm.format].name));
+		frame = &ztv->grabinfo[vm.frame];
+		if (frame->status == FBUFFER_GRABBING)
+			return -EBUSY;
+
+		/* setup the other parameters if they are given */
+		write_lock_irq(&ztv->lock);
+		if (vm.width)
+			frame->w = vm.width;
+		if (vm.height)
+			frame->h = vm.height;
+		if (vm.format)
+			frame->format = vm.format;
+		frame->bpp = palette2fmt[frame->format].bpp;
+		frame->bpl = frame->w*frame->bpp;
+		frame->vidadr = virt_to_bus(phys_to_virt((ulong)ztv->fbuffer+vm.frame*ZORAN_MAX_FBUFFER));
+		frame->status = FBUFFER_GRABBING;
+		set_bit(STATE_GRAB, &ztv->state);
+		write_unlock_irq(&ztv->lock);
+
+		zoran_cap(ztv, 1);
+		return 0;
+	 }
+
+	 case VIDIOCGMBUF:
+	 {
+		struct video_mbuf mb;
+		int i;
+		DEBUG(printk(KERN_DEBUG "%s: GetMemoryBuffer\n",CARD));
+		mb.size = ZORAN_MAX_FBUFSIZE;
+		mb.frames = ZORAN_MAX_FBUFFERS;
+		for (i=0; i<ZORAN_MAX_FBUFFERS; i++)
+			mb.offsets[i] = i*ZORAN_MAX_FBUFFER;
+		if(copy_to_user(arg, &mb,sizeof(mb)))
+			return -EFAULT;
+		return 0;
+	 }
+
+	 case VIDIOCGUNIT:
+	 {
+		struct video_unit vu;
+		DEBUG(printk(KERN_DEBUG "%s: GetUnit\n",CARD));
+		vu.video = ztv->video_dev.minor;
+		vu.vbi = VIDEO_NO_UNIT;
+		vu.radio = VIDEO_NO_UNIT;
+		vu.audio = VIDEO_NO_UNIT;
+		vu.teletext = VIDEO_NO_UNIT;
+		if(copy_to_user(arg, &vu,sizeof(vu)))
+			return -EFAULT;
+		return 0;
+	 }
+
+	 case VIDIOCGFREQ:
+	 {
+		unsigned long v = ztv->tuner_freq;
+		if (copy_to_user(arg,&v,sizeof(v)))
+			return -EFAULT;
+		return 0;
+	 }
+
+	 case VIDIOCSFREQ:
+	 {
+		unsigned long v;
+		if (copy_from_user(&v, arg, sizeof(v)))
+			return -EFAULT;
+
+		if (ztv->have_tuner) {
+			int fixme = v;
+			if (i2c_control_device(&(ztv->i2c), I2C_DRIVERID_TUNER, TUNER_SET_TVFREQ, &fixme) < 0)
+				return -EAGAIN;
+		}
+		ztv->tuner_freq = v;
+		return 0;
+	 }
+
+	 case VIDIOCGAUDIO:
+	 case VIDIOCSAUDIO:
+	 case VIDIOCGCAPTURE:
+	 case VIDIOCSCAPTURE:
+		DEBUG(printk(KERN_DEBUG "%s: unhandled video ioctl(%x)\n",CARD,cmd));
+		return -EINVAL;
+
+	 default:
+		DEBUG(printk(KERN_DEBUG "%s: bad ioctl(%x)\n",CARD,cmd));
+	}
+	return -EPERM;
+}
+
+static
+int zoran_mmap(struct video_device* dev, const char* adr, unsigned long size)
+{
+	struct zoran* ztv = (struct zoran*)dev;
+	unsigned long start = (unsigned long)adr;
+	unsigned long pos;
+
+	DEBUG(printk(KERN_DEBUG "zoran_mmap(0x%p,%ld)\n",adr,size));
+
+	/* sanity checks */
+	if (size > ZORAN_MAX_FBUFSIZE || !ztv->fbuffer)
+		return -EINVAL;
+
+	/* start mapping the whole shabang to user memory */
+	pos = (unsigned long)ztv->fbuffer;
+	while (size>0) {
+#ifdef CONFIG_BIGPHYS_AREA
+		unsigned long page = virt_to_phys((void*)pos);
+#else
+		unsigned long page = kvirt_to_phys(pos);
+#endif
+		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
+			return -EAGAIN;
+		start += PAGE_SIZE;
+		pos += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+	return 0;
+}
+
+static struct video_device zoran_template=
+{
+	"UNSET",
+	VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY,
+	VID_HARDWARE_ZR36120,
+
+	zoran_open,
+	zoran_close,
+	zoran_read,
+	zoran_write,
+#if LINUX_VERSION_CODE >= 0x020100
+	zoran_poll,		/* poll */
+#endif
+	zoran_ioctl,
+	zoran_mmap,
+	NULL,			/* initialize */
+	NULL,
+	0,
+	-1
+};
+
+static
+int init_zoran(int card)
+{
+	struct zoran *ztv = &zorans[card];
+	int	i;
+
+	/* if the given cardtype valid? */
+	if (cardtype[card]<0 || cardtype[card]>=NRTVCARDS) {
+		printk(KERN_INFO "invalid cardtype(%d) detected\n",cardtype[card]);
+		return -1;
+	}
+
+	/* reset the zoran */
+	zrand(~ZORAN_PCI_SOFTRESET,ZORAN_PCI);
+	udelay(10);
+	zror(ZORAN_PCI_SOFTRESET,ZORAN_PCI);
+	udelay(10);
+
+	/* default setup for max. PAL size in a 1024xXXX hicolor framebuffer */
+
+	/* framegrabber details */
+	ztv->swidth=800;
+	ztv->sheight=600;
+	ztv->depth=16;
+
+	/* channel details */
+	ztv->norm=0;				/* PAL */
+	ztv->card=tvcards+cardtype[card];	/* point to the selected card */
+	ztv->tuner_freq = 0;
+
+	ztv->overinfo.status = FBUFFER_UNUSED;
+	ztv->overinfo.x = 0;
+	ztv->overinfo.y = 0;
+	ztv->overinfo.w = 768; /* 640 */
+	ztv->overinfo.h = 576; /* 480 */
+	ztv->overinfo.format = VIDEO_PALETTE_RGB565;
+	ztv->overinfo.bpp = palette2fmt[ztv->overinfo.format].bpp;
+	ztv->overinfo.bpl = ztv->overinfo.bpp*ztv->swidth;
+	ztv->overinfo.vidadr = 0;
+	ztv->overinfo.overlay = 0;
+
+	ztv->readinfo = ztv->overinfo;
+	ztv->readinfo.w = 768;
+	ztv->readinfo.h = -22;
+	ztv->readinfo.format = VIDEO_PALETTE_YUV422;
+	ztv->readinfo.bpp = palette2fmt[ztv->readinfo.format].bpp;
+	ztv->readinfo.bpl = ztv->readinfo.w*ztv->readinfo.bpp;
+
+	/* grabbing details */
+	for (i=0; i<ZORAN_MAX_FBUFFERS; i++) {
+		ztv->grabinfo[i] = ztv->overinfo;
+		ztv->grabinfo[i].format = VIDEO_PALETTE_RGB24;
+	}
+
+	/* maintenance data */
+	ztv->fbuffer = NULL;
+	ztv->user = 0;
+	ztv->have_decoder = 0;
+	ztv->have_tuner = 0;
+	ztv->running = 0;
+	init_waitqueue_head(&ztv->grabq);
+	init_waitqueue_head(&ztv->readq);
+	ztv->lock = RW_LOCK_UNLOCKED;
+	ztv->state = 0;
+	ztv->prevstate = 0;
+	ztv->lastframe = -1;
+
+	/* picture details */
+	ztv->picture.colour=254<<7;
+	ztv->picture.brightness=128<<8;
+	ztv->picture.hue=128<<8;
+	ztv->picture.contrast=216<<7;
+
+	if (triton1)
+		zrand(~ZORAN_VDC_TRICOM, ZORAN_VDC);
+
+	/* external FL determines TOP frame */
+	zror(ZORAN_VFEC_EXTFL, ZORAN_VFEC); 
+
+	/* set HSpol */
+	if (ztv->card->hsync_pos)
+		zrwrite(ZORAN_VFEH_HSPOL, ZORAN_VFEH);
+	/* set VSpol */
+	if (ztv->card->vsync_pos)
+		zrwrite(ZORAN_VFEV_VSPOL, ZORAN_VFEV);
+
+	/* Set the proper General Purpuse register bits */
+	/* implicit: no softreset, 0 waitstates */
+	zrwrite(ZORAN_PCI_SOFTRESET|(ztv->card->gpdir<<0),ZORAN_PCI);
+	/* implicit: 3 duration and recovery PCI clocks on guest 0-3 */
+	zrwrite(ztv->card->gpval<<24,ZORAN_GUEST);
+	
+	/* clear interrupt status */
+	zrwrite(~0, ZORAN_ISR);
+
+	/*
+	 * i2c template
+	 */
+	ztv->i2c = zoran_i2c_bus_template;
+	sprintf(ztv->i2c.name,"zoran-%d",card);
+	ztv->i2c.data = ztv;
+
+	/*
+	 * Now add the template and register the device unit
+	 */
+	ztv->video_dev = zoran_template;
+	strcpy(ztv->video_dev.name, ztv->i2c.name);
+	if (video_register_device(&ztv->video_dev, VFL_TYPE_GRABBER) < 0)
+		return -1;
+	i2c_register_bus(&ztv->i2c);
+
+	/* set interrupt mask - the PIN enable will be set later */
+	zrwrite(ZORAN_ICR_GIRQ0|ZORAN_ICR_GIRQ1|ZORAN_ICR_CODE, ZORAN_ICR);
+
+	printk(KERN_INFO "%s: installed %s\n",CARD,ztv->card->name);
+	return 0;
+}
+
+static
+void release_zoran(int max)
+{
+	u8 command;
+	struct zoran *ztv;
+	int i;
+
+	for (i=0;i<max; i++) 
+	{
+		ztv=&zorans[i];
+
+		/* turn off all capturing, DMA and IRQs */
+		/* reset the zoran */
+		zrand(~ZORAN_PCI_SOFTRESET,ZORAN_PCI);
+		udelay(10);
+		zror(ZORAN_PCI_SOFTRESET,ZORAN_PCI);
+		udelay(10);
+
+		/* first disable interrupts before unmapping the memory! */
+		zrwrite(0, ZORAN_ICR);
+		zrwrite(0xffffffffUL,ZORAN_ISR);
+
+		/* free it */
+		free_irq(ztv->dev->irq,ztv);
+ 
+    		/* unregister i2c_bus */
+		i2c_unregister_bus((&ztv->i2c));
+
+		/* disable PCI bus-mastering */
+		pci_read_config_byte(ztv->dev, PCI_COMMAND, &command);
+ 		command&=PCI_COMMAND_MASTER;
+		pci_write_config_byte(ztv->dev, PCI_COMMAND, command);
+    
+		/* unmap and free memory */
+		if (ztv->zoran_mem)
+			iounmap(ztv->zoran_mem);
+
+		video_unregister_device(&ztv->video_dev);
+	}
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+	release_zoran(zoran_cards);
+}
+
+int init_module(void)
+{
+#else
+int init_zr36120_cards(struct video_init *unused)
+{
+#endif
+	int	card;
+ 
+	handle_chipset();
+	zoran_cards = find_zoran();
+	if (zoran_cards<0)
+		/* no cards found, no need for a driver */
+		return -EIO;
+
+	/* initialize Zorans */
+	for (card=0; card<zoran_cards; card++) {
+		if (init_zoran(card)<0) {
+			/* only release the zorans we have registered */
+			release_zoran(card);
+			return -EIO;
+		} 
+	}
+	return 0;
+}
diff -u --recursive --new-file v2.3.29/linux/drivers/char/zr36120.h linux/drivers/char/zr36120.h
--- v2.3.29/linux/drivers/char/zr36120.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/zr36120.h	Sat Nov 27 15:27:48 1999
@@ -0,0 +1,272 @@
+/* 
+    zr36120.h - Zoran 36120/36125 based framegrabbers
+
+    Copyright (C) 1998-1999 Pauline Middelink (middelin@polyware.nl)
+
+    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.
+*/
+
+#ifndef _ZR36120_H
+#define _ZR36120_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/wait.h>
+
+#include <linux/i2c.h>
+#include <linux/videodev.h>
+
+#include <asm/io.h>
+
+/*
+ * Debug macro's, place an x behind the ) for actual debug-compilation
+ * E.g. #define DEBUG(x...)	x
+ */
+#define DEBUG(x...)			/* Debug driver */
+#define IDEBUG(x...)			/* Debug interrupt handler */
+#define PDEBUG		0		/* Debug PCI writes */
+
+/* defined in zr36120_i2c */
+extern struct i2c_bus zoran_i2c_bus_template;
+
+#define	ZORAN_MAX_FBUFFERS	2
+#define ZORAN_MAX_FBUFFER	0x0A2000
+#define ZORAN_MAX_FBUFSIZE	(ZORAN_MAX_FBUFFERS*ZORAN_MAX_FBUFFER)
+
+/* external declarations */
+extern unsigned long zoran_alloc_memory(void);
+extern void zoran_free_memory(void);
+
+struct tvcard {
+	char*	name;		/* name of the cardtype */
+	int	video_inputs;	/* number of channels defined in video_mux */
+	int	audio_inputs;	/* number of channels defined in audio_mux */
+	__u32	swapi2c:1,	/* need to swap i2c wires SDA/SCL? */
+		usegirq1:1,	/* VSYNC at GIRQ1 instead of GIRQ0? */
+		vsync_pos:1,	/* positive VSYNC signal? */
+		hsync_pos:1,	/* positive HSYNC signal? */
+		gpdir:8,	/* General Purpose Direction register */
+		gpval:8;	/* General Purpose Value register */
+	int	video_mux[6];	/* mapping channel number to physical input */
+#define		IS_TUNER	0x80
+#define		IS_SVHS		0x40
+#define		CHANNEL_MASK	0x3F
+	int	audio_mux[6];	/* mapping channel number to physical input */
+};
+#define	TUNER(x)	((x)|IS_TUNER)
+#define	SVHS(x)		((x)|IS_SVHS)
+
+struct vidinfo {
+	int	status;
+#define FBUFFER_UNUSED       0
+#define FBUFFER_GRABBING     1
+#define FBUFFER_DONE         2
+	int	x,y;
+	int	w,h;
+	int	bpl;
+	int	bpp;		/* should be calculated */
+	int	format;
+	ulong	vidadr;		/* physical video address */
+	ulong*	overlay;
+};
+
+struct zoran 
+{
+	struct video_device video_dev;
+#define CARD	ztv->video_dev.name
+	struct i2c_bus	i2c;
+	struct video_picture picture;	/* Current picture params */
+	struct video_audio audio_dev;	/* Current audio params */
+
+	/* zoran chip specific details */
+	struct pci_dev*	dev;		/* ptr to PCI device */
+	ushort		id;		/* chip id */
+	unsigned char	revision;	/* chip revision */
+	int		zoran_adr;	/* bus address of IO memory */
+	char*		zoran_mem;	/* pointer to mapped IO memory */
+  
+	/* videocard details */
+	int		swidth;		/* screen width */
+	int		sheight;	/* screen height */
+	int		depth;		/* depth in bits */
+
+	/* channel details */
+	int		norm;		/* 0=PAL, 1=NTSC, 2=SECAM */
+	struct tvcard*	card;		/* the cardtype */
+	int		tuner_freq;	/* in Hz */
+
+	/* State details */
+	struct vidinfo	overinfo;	/* overlay data */
+	struct vidinfo	grabinfo[ZORAN_MAX_FBUFFERS];	/* grabbing data */
+	struct vidinfo	readinfo;	/* reading data */
+
+	/* maintenance data */
+	char*		fbuffer;	/* framebuffers for mmap */
+	int		user;		/* # users */
+	int		have_decoder;	/* did we detect a mux? */
+	int		have_tuner;	/* did we detect a tuner? */
+	int		tuner_type;	/* tuner type, when found */
+	int		running;
+	wait_queue_head_t grabq;	/* waiting capturers */
+	wait_queue_head_t readq;	/* waiting readers */
+	rwlock_t	lock;
+	int		state;		/* what is requested of us? */
+#define STATE_READ	0
+#define STATE_GRAB	1
+#define STATE_OVERLAY	2
+	int		prevstate;
+	int		lastframe;
+
+	int		interlace;	/* calculated */
+	int		vidXshift;	/* calculated */
+	int		vidWidth;	/* calculated */
+	int		vidHeight;	/* calculated */
+};
+
+#define zrwrite(dat,adr)    writel((dat),(char *) (ztv->zoran_mem+(adr)))
+#define zrread(adr)         readl(ztv->zoran_mem+(adr))
+
+#if !defined(PDEBUG) || (PDEBUG == 0)
+#define zrand(dat,adr)      zrwrite((dat) & zrread(adr), adr)
+#define zror(dat,adr)       zrwrite((dat) | zrread(adr), adr)
+#define zraor(dat,mask,adr) zrwrite( ((dat)&~(mask)) | ((mask)&zrread(adr)), adr)
+#else
+#define zrand(dat, adr) \
+do { \
+	ulong data = (dat) & zrread((adr)); \
+	zrwrite(data, (adr)); \
+	if (0 != (~(dat) & zrread((adr)))) \
+		printk(KERN_DEBUG "zoran: zrand at %d(%d) detected set bits(%x)\n", __LINE__, (adr), (dat)); \
+} while(0)
+
+#define zror(dat, adr) \
+do { \
+	ulong data = (dat) | zrread((adr)); \
+	zrwrite(data, (adr)); \
+	if ((dat) != ((dat) & zrread(adr))) \
+		printk(KERN_DEBUG "zoran: zror at %d(%d) detected unset bits(%x)\n", __LINE__, (adr), (dat)); \
+} while(0)
+
+#define zraor(dat, mask, adr) \
+do { \
+	ulong data; \
+	if ((dat) & (mask)) \
+		printk(KERN_DEBUG "zoran: zraor at %d(%d) detected bits(%x:%x)\n", __LINE__, (adr), (dat), (mask)); \
+	data = ((dat)&~(mask)) | ((mask) & zrread((adr))); \
+	zrwrite(data,(adr)); \
+	if ( (dat) != (~(mask) & zrread((adr))) ) \
+		printk(KERN_DEBUG "zoran: zraor at %d(%d) could not set all bits(%x:%x)\n", __LINE__, (adr), (dat), (mask)); \
+} while(0)
+#endif
+
+#endif
+
+/* zoran PCI address space */
+#define ZORAN_VFEH		0x000	/* Video Front End Horizontal Conf. */
+#define	ZORAN_VFEH_HSPOL	(1<<30)
+#define	ZORAN_VFEH_HSTART	(0x3FF<<10)
+#define	ZORAN_VFEH_HEND		(0x3FF<<0)
+
+#define ZORAN_VFEV		0x004	/* Video Front End Vertical Conf. */
+#define	ZORAN_VFEV_VSPOL	(1<<30)
+#define	ZORAN_VFEV_VSTART	(0x3FF<<10)
+#define	ZORAN_VFEV_VEND		(0x3FF<<0)
+
+#define	ZORAN_VFEC		0x008	/* Video Front End Scaler and Pixel */
+#define ZORAN_VFEC_EXTFL	(1<<26)
+#define	ZORAN_VFEC_TOPFIELD	(1<<25)
+#define	ZORAN_VFEC_VCLKPOL	(1<<24)
+#define	ZORAN_VFEC_HFILTER	(7<<21)
+#define	ZORAN_VFEC_HFILTER_1	(0<<21)	/* no lumi,    3-tap chromo */
+#define	ZORAN_VFEC_HFILTER_2	(1<<21)	/* 3-tap lumi, 3-tap chromo */
+#define	ZORAN_VFEC_HFILTER_3	(2<<21)	/* 4-tap lumi, 4-tap chromo */
+#define	ZORAN_VFEC_HFILTER_4	(3<<21)	/* 5-tap lumi, 4-tap chromo */
+#define	ZORAN_VFEC_HFILTER_5	(4<<21)	/* 4-tap lumi, 4-tap chromo */
+#define	ZORAN_VFEC_DUPFLD	(1<<20)
+#define	ZORAN_VFEC_HORDCM	(63<<14)
+#define	ZORAN_VFEC_VERDCM	(63<<8)
+#define	ZORAN_VFEC_DISPMOD	(1<<6)
+#define	ZORAN_VFEC_RGB		(3<<3)
+#define	ZORAN_VFEC_RGB_YUV422	(0<<3)
+#define	ZORAN_VFEC_RGB_RGB888	(1<<3)
+#define	ZORAN_VFEC_RGB_RGB565	(2<<3)
+#define	ZORAN_VFEC_RGB_RGB555	(3<<3)
+#define	ZORAN_VFEC_ERRDIF	(1<<2)
+#define	ZORAN_VFEC_PACK24	(1<<1)
+#define	ZORAN_VFEC_LE		(1<<0)
+
+#define	ZORAN_VTOP		0x00C	/* Video Display "Top" */
+
+#define	ZORAN_VBOT		0x010	/* Video Display "Bottom" */
+
+#define	ZORAN_VSTR		0x014	/* Video Display Stride */
+#define	ZORAN_VSTR_DISPSTRIDE	(0xFFFF<<16)
+#define	ZORAN_VSTR_VIDOVF	(1<<8)
+#define	ZORAN_VSTR_SNAPSHOT	(1<<1)
+#define	ZORAN_VSTR_GRAB		(1<<0)
+
+#define	ZORAN_VDC		0x018	/* Video Display Conf. */
+#define	ZORAN_VDC_VIDEN		(1<<31)
+#define	ZORAN_VDC_MINPIX	(0x1F<<25)
+#define	ZORAN_VDC_TRICOM	(1<<24)
+#define	ZORAN_VDC_VIDWINHT	(0x3FF<<12)
+#define	ZORAN_VDC_VIDWINWID	(0x3FF<<0)
+
+#define	ZORAN_MTOP		0x01C	/* Masking Map "Top" */
+
+#define	ZORAN_MBOT		0x020	/* Masking Map "Bottom" */
+
+#define	ZORAN_OCR		0x024	/* Overlay Control */
+#define	ZORAN_OCR_OVLEN		(1<<15)
+#define	ZORAN_OCR_MASKSTRIDE	(0xFF<<0)
+
+#define	ZORAN_PCI		0x028	/* System, PCI and GPP Control */
+#define	ZORAN_PCI_SOFTRESET	(1<<24)
+#define	ZORAN_PCI_WAITSTATE	(3<<16)
+#define	ZORAN_PCI_GENPURDIR	(0xFF<<0)
+
+#define	ZORAN_GUEST		0x02C	/* GuestBus Control */
+
+#define	ZORAN_CSOURCE		0x030	/* Code Source Address */
+
+#define	ZORAN_CTRANS		0x034	/* Code Transfer Control */
+
+#define	ZORAN_CMEM		0x038	/* Code Memory Pointer */
+
+#define	ZORAN_ISR		0x03C	/* Interrupt Status Register */
+#define	ZORAN_ISR_CODE		(1<<28)
+#define	ZORAN_ISR_GIRQ0		(1<<29)
+#define	ZORAN_ISR_GIRQ1		(1<<30)
+
+#define	ZORAN_ICR		0x040	/* Interrupt Control Register */
+#define	ZORAN_ICR_EN		(1<<24)
+#define	ZORAN_ICR_CODE		(1<<28)
+#define	ZORAN_ICR_GIRQ0		(1<<29)
+#define	ZORAN_ICR_GIRQ1		(1<<30)
+
+#define	ZORAN_I2C		0x044	/* I2C-Bus */
+#define ZORAN_I2C_SCL		(1<<1)
+#define ZORAN_I2C_SDA		(1<<0)
+
+#define	ZORAN_POST		0x48	/* PostOffice */
+#define	ZORAN_POST_PEN		(1<<25)
+#define	ZORAN_POST_TIME		(1<<24)
+#define	ZORAN_POST_DIR		(1<<23)
+#define	ZORAN_POST_GUESTID	(3<<20)
+#define	ZORAN_POST_GUEST	(7<<16)
+#define	ZORAN_POST_DATA		(0xFF<<0)
+
+#endif
diff -u --recursive --new-file v2.3.29/linux/drivers/char/zr36120_i2c.c linux/drivers/char/zr36120_i2c.c
--- v2.3.29/linux/drivers/char/zr36120_i2c.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/zr36120_i2c.c	Sat Nov 27 15:27:48 1999
@@ -0,0 +1,118 @@
+/*
+    zr36120_i2c.c - Zoran 36120/36125 based framegrabbers
+
+    Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
+
+    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/types.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+
+#include <linux/version.h>
+#include <asm/uaccess.h>
+
+#include "linux/video_decoder.h"
+#include "tuner.h"
+#include "zr36120.h"
+
+/* ----------------------------------------------------------------------- */
+/* I2C functions							   */
+/* ----------------------------------------------------------------------- */
+
+/* software I2C functions */
+
+#define I2C_DELAY   10
+
+static void i2c_setlines(struct i2c_bus *bus,int ctrl,int data)
+{
+	struct zoran *ztv = (struct zoran*)bus->data;
+	unsigned int b = 0;
+	if (data) b |= ztv->card->swapi2c ? ZORAN_I2C_SCL : ZORAN_I2C_SDA;
+	if (ctrl) b |= ztv->card->swapi2c ? ZORAN_I2C_SDA : ZORAN_I2C_SCL;
+	zrwrite(b, ZORAN_I2C);
+	udelay(I2C_DELAY);
+}
+
+static int i2c_getdataline(struct i2c_bus *bus)
+{
+	struct zoran *ztv = (struct zoran*)bus->data;
+	if (ztv->card->swapi2c)
+		return zrread(ZORAN_I2C) & ZORAN_I2C_SCL;
+	return zrread(ZORAN_I2C) & ZORAN_I2C_SDA;
+}
+
+static
+void attach_inform(struct i2c_bus *bus, int id)
+{
+	struct zoran *ztv = (struct zoran*)bus->data;
+
+	switch (id) {
+	 case I2C_DRIVERID_VIDEODECODER:
+		ztv->have_decoder = 1;
+		DEBUG(printk(KERN_INFO "%s: decoder attached\n",CARD));
+		break;
+	 case I2C_DRIVERID_TUNER:
+		ztv->have_tuner = 1;
+		DEBUG(printk(KERN_INFO "%s: tuner attached\n",CARD));
+		if (ztv->tuner_type >= 0)
+		{
+			if (i2c_control_device(&ztv->i2c,I2C_DRIVERID_TUNER,TUNER_SET_TYPE,&ztv->tuner_type)<0)
+			DEBUG(printk(KERN_INFO "%s: attach_inform; tuner wont be set to type %d\n",CARD,ztv->tuner_type));
+		}
+		break;
+	 default:
+		DEBUG(printk(KERN_INFO "%s: attach_inform; unknown device id=%d\n",CARD,id));
+		break;
+	}
+}
+
+static
+void detach_inform(struct i2c_bus *bus, int id)
+{
+	struct zoran *ztv = (struct zoran*)bus->data;
+
+	switch (id) {
+	 case I2C_DRIVERID_VIDEODECODER:
+		ztv->have_decoder = 0;
+		DEBUG(printk(KERN_INFO "%s: decoder detached\n",CARD));
+		break;
+	 case I2C_DRIVERID_TUNER:
+		ztv->have_tuner = 0;
+		DEBUG(printk(KERN_INFO "%s: tuner detached\n",CARD));
+		break;
+	 default:
+		DEBUG(printk(KERN_INFO "%s: detach_inform; unknown device id=%d\n",CARD,id));
+		break;
+	}
+}
+
+struct i2c_bus zoran_i2c_bus_template =
+{
+	"ZR36120",
+	I2C_BUSID_ZORAN,
+	NULL,
+
+	SPIN_LOCK_UNLOCKED,
+
+	attach_inform,
+	detach_inform,
+
+	i2c_setlines,
+	i2c_getdataline,
+	NULL,
+	NULL
+};
diff -u --recursive --new-file v2.3.29/linux/drivers/char/zr36120_mem.c linux/drivers/char/zr36120_mem.c
--- v2.3.29/linux/drivers/char/zr36120_mem.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/zr36120_mem.c	Sat Nov 27 15:27:48 1999
@@ -0,0 +1,128 @@
+/*
+    zr36120_mem.c - Zoran 36120/36125 based framegrabbers
+
+    Copyright (C) 1998-1999 Pauline Middelink <middelin@polyware.nl>
+
+    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/config.h>
+#include <linux/mm.h>
+#include <linux/pci.h>
+#include <linux/wrapper.h>
+#include <asm/io.h>
+#ifdef CONFIG_BIGPHYS_AREA
+#include <linux/bigphysarea.h>
+#endif
+
+#include "zr36120.h"
+#include "zr36120_mem.h"
+
+/* ----------------------------------------------------------------------- */
+/* Memory functions							   */
+/* shamelessly stolen and adapted from bttv.c				   */
+/* ----------------------------------------------------------------------- */
+
+/*
+ * convert virtual user memory address to physical address
+ * (virt_to_phys only works for kmalloced kernel memory)
+ */
+inline unsigned long uvirt_to_phys(unsigned long adr)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *ptep, pte;
+
+	pgd = pgd_offset(current->mm, adr);
+	if (pgd_none(*pgd))
+		return 0;
+	pmd = pmd_offset(pgd, adr);
+	if (pmd_none(*pmd))
+		return 0;
+	ptep = pte_offset(pmd, adr/*&(~PGDIR_MASK)*/);
+	pte = *ptep;
+	/* Note; page_address will panic for us if the page is high */
+        if(pte_present(pte))
+        	return page_address(pte_page(pte))|(adr&(PAGE_SIZE-1));
+	return 0;
+}
+
+/*
+ * vmalloced address to physical address
+ */
+inline unsigned long kvirt_to_phys(unsigned long adr)
+{
+	return uvirt_to_phys(VMALLOC_VMADDR(adr));
+}
+
+/*
+ * vmalloced address to bus address
+ */
+inline unsigned long kvirt_to_bus(unsigned long adr)
+{
+	return virt_to_bus(phys_to_virt(kvirt_to_phys(adr)));
+}
+
+inline int order(unsigned long size)
+{
+	int ordr = 0;
+	size = (size+PAGE_SIZE-1)/PAGE_SIZE;
+	while (size) {
+		size /= 2;
+		ordr++;
+	}
+	return ordr;
+}
+
+void* bmalloc(unsigned long size)
+{
+	void* mem;
+#ifdef CONFIG_BIGPHYS_AREA
+	mem = bigphysarea_alloc_pages(size/PAGE_SIZE, 1, GFP_KERNEL);
+#else
+	/*
+	 * The following function got a lot of memory at boottime,
+	 * so we know its always there...
+	 */
+	mem = (void*)__get_free_pages(GFP_USER,order(size));
+#endif
+	if (mem) {
+		unsigned long adr = (unsigned long)mem;
+		while (size > 0) {
+			mem_map_reserve(MAP_NR(phys_to_virt(adr)));
+			adr += PAGE_SIZE;
+			size -= PAGE_SIZE;
+		}
+	}
+	return mem;
+}
+
+void bfree(void* mem, unsigned long size)
+{
+	if (mem) {
+		unsigned long adr = (unsigned long)mem;
+		unsigned long siz = size;
+		while (siz > 0) {
+			mem_map_unreserve(MAP_NR(phys_to_virt(adr)));
+			adr += PAGE_SIZE;
+			siz -= PAGE_SIZE;
+		}
+#ifdef CONFIG_BIGPHYS_AREA
+		bigphysarea_free_pages(mem);
+#else
+		free_pages((unsigned long)mem,order(size));
+#endif
+	}
+}
diff -u --recursive --new-file v2.3.29/linux/drivers/char/zr36120_mem.h linux/drivers/char/zr36120_mem.h
--- v2.3.29/linux/drivers/char/zr36120_mem.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/char/zr36120_mem.h	Sat Nov 27 15:27:48 1999
@@ -0,0 +1,17 @@
+extern inline unsigned long uvirt_to_phys(unsigned long adr);
+
+/* vmalloced address to physical address */
+extern inline unsigned long kvirt_to_phys(unsigned long adr)
+{ return uvirt_to_phys(VMALLOC_VMADDR(adr)); }
+
+/* vmalloced address to bus address */
+extern inline unsigned long kvirt_to_bus(unsigned long adr)
+{ return virt_to_bus(phys_to_virt(kvirt_to_phys(adr))); }
+
+/* always vmalloced memory - not always continuous! */
+void*	rvmalloc(unsigned long size);
+void	rvfree(void* mem, unsigned long size);
+
+/* either kmalloc() or bigphysarea() alloced memory - continuous */
+void*	bmalloc(unsigned long size);
+void	bfree(void* mem, unsigned long size);
diff -u --recursive --new-file v2.3.29/linux/drivers/i2o/i2o_proc.c linux/drivers/i2o/i2o_proc.c
--- v2.3.29/linux/drivers/i2o/i2o_proc.c	Thu Nov 11 20:11:35 1999
+++ linux/drivers/i2o/i2o_proc.c	Sat Nov 27 15:27:48 1999
@@ -3181,7 +3181,7 @@
 
 	sprintf(buff, "iop%d", pctrl->unit);
 
-	dir = create_proc_entry(buff, S_IFDIR, root);
+	dir = proc_mkdir(buff, root);
 	if(!dir)
 		return -1;
 
@@ -3193,7 +3193,7 @@
 	{
 		sprintf(buff, "%0#5x", dev->lct_data->tid);
 
-		dir1 = create_proc_entry(buff, S_IFDIR, dir);
+		dir1 = proc_mkdir(buff, dir);
 		dev->proc_entry = dir1;
 
 		if(!dir1)
@@ -3295,7 +3295,7 @@
 	struct i2o_controller *pctrl = NULL;
 	int i;
 
-	i2o_proc_dir_root = create_proc_entry("i2o", S_IFDIR, 0);
+	i2o_proc_dir_root = proc_mkdir("i2o", 0);
 	if(!i2o_proc_dir_root)
 		return -1;
 
diff -u --recursive --new-file v2.3.29/linux/drivers/isdn/avmb1/kcapi.c linux/drivers/isdn/avmb1/kcapi.c
--- v2.3.29/linux/drivers/isdn/avmb1/kcapi.c	Thu Nov 11 20:11:36 1999
+++ linux/drivers/isdn/avmb1/kcapi.c	Sat Nov 27 15:27:48 1999
@@ -877,14 +877,8 @@
 	*pp = card;
 	driver->ncontroller++;
 	sprintf(card->procfn, "capi/controllers/%d", card->cnr);
-	card->procent = create_proc_entry(card->procfn, 0, 0);
-	if (card->procent) {
-	   card->procent->read_proc = 
-		(int (*)(char *,char **,off_t,int,int *,void *))
-			driver->ctr_read_proc;
-	   card->procent->data = card;
-	}
-
+	card->procent = create_proc_read_entry(card->procfn, 0, 0,
+					driver->ctr_read_proc, card);
 	ncards++;
 	printk(KERN_NOTICE "kcapi: Controller %d: %s attached\n",
 			card->cnr, card->name);
@@ -960,17 +954,11 @@
 		t1isa_driver = driver;
 #endif
 	sprintf(driver->procfn, "capi/drivers/%s", driver->name);
-	driver->procent = create_proc_entry(driver->procfn, 0, 0);
-	if (driver->procent) {
-	   if (driver->driver_read_proc) {
-		   driver->procent->read_proc = 
-	       		(int (*)(char *,char **,off_t,int,int *,void *))
-					driver->driver_read_proc;
-	   } else {
-		   driver->procent->read_proc = driver_read_proc;
-	   }
-	   driver->procent->data = driver;
-	}
+	driver->procent = create_proc_read_entry(driver->procfn, 0, 0,
+						driver->driver_read_proc
+						? driver->driver_read_proc
+						: driver_read_proc,
+					        driver);
 	return &di;
 }
 
diff -u --recursive --new-file v2.3.29/linux/drivers/isdn/divert/divert_procfs.c linux/drivers/isdn/divert/divert_procfs.c
--- v2.3.29/linux/drivers/isdn/divert/divert_procfs.c	Thu Nov 11 20:11:36 1999
+++ linux/drivers/isdn/divert/divert_procfs.c	Sun Dec  5 08:42:03 1999
@@ -294,22 +294,6 @@
 
 struct inode_operations divert_file_inode_operations = {
     &isdn_fops,  /* default proc file-ops */
-    NULL,	 /* create	*/
-    NULL,	 /* lookup	*/
-    NULL,	 /* link		*/
-    NULL,	 /* unlink	*/
-    NULL,	 /* symlink	*/
-    NULL,	 /* mkdir	*/
-    NULL,	 /* rmdir	   */
-    NULL,	 /* mknod	   */
-    NULL,	    /* rename	   */
-    NULL,	    /* readlink	   */
-    NULL,	    /* follow_link */
-    NULL,	    /* readpage	   */
-    NULL,	    /* writepage   */
-    NULL,	    /* bmap	   */
-    NULL,	    /* truncate	   */
-    NULL	    /* permission  */
 };
 
 
@@ -329,10 +313,10 @@
 	init_waitqueue_head(&rd_queue);
 
 #ifdef CONFIG_PROC_FS
-  isdn_proc_entry = create_proc_entry("isdn", S_IFDIR | S_IRUGO | S_IXUGO ,proc_net);
+  isdn_proc_entry = proc_mkdir("isdn", proc_net);
   if (!isdn_proc_entry) 
     return(-1);
-  isdn_divert_entry = create_proc_entry("divert",S_IFREG | S_IRUGO,isdn_proc_entry); 
+  isdn_divert_entry = create_proc_entry("divert",0,isdn_proc_entry); 
   if (!isdn_divert_entry) 
    {
      remove_proc_entry("isdn",proc_net);
diff -u --recursive --new-file v2.3.29/linux/drivers/misc/acpi.c linux/drivers/misc/acpi.c
--- v2.3.29/linux/drivers/misc/acpi.c	Tue Nov 23 22:42:20 1999
+++ linux/drivers/misc/acpi.c	Sat Nov 27 16:40:49 1999
@@ -27,6 +27,7 @@
 #include <linux/init.h>
 #include <linux/miscdevice.h>
 #include <linux/sched.h>
+#include <linux/time.h>
 #include <linux/wait.h>
 #include <linux/spinlock.h>
 #include <linux/ioport.h>
@@ -54,6 +55,13 @@
 #define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue * x = NULL
 #endif
 
+/*
+ * Yes, it's unfortunate that we are relying on get_cmos_time
+ * because it is slow (> 1 sec.) and i386 only.	 It might be better
+ * to use some of the code from drivers/char/rtc.c in the near future
+ */
+extern unsigned long get_cmos_time(void);
+
 static int acpi_control_thread(void *context);
 static int acpi_do_ulong(ctl_table *ctl,
 			 int write,
@@ -70,15 +78,13 @@
 			 struct file *file,
 			 void *buffer,
 			 size_t *len);
-#if 0
-static int acpi_do_sleep_wake(ctl_table *ctl,
-			      int write,
-			      struct file *file,
-			      void *buffer,
-			      size_t *len);
-#endif
+static int acpi_do_sleep(ctl_table *ctl,
+			 int write,
+			 struct file *file,
+			 void *buffer,
+			 size_t *len);
 
-DECLARE_WAIT_QUEUE_HEAD(acpi_idle_wait);
+DECLARE_WAIT_QUEUE_HEAD(acpi_control_wait);
 
 static struct ctl_table_header *acpi_sysctl = NULL;
 
@@ -88,10 +94,16 @@
 static unsigned long acpi_facp_addr = 0;
 static unsigned long acpi_dsdt_addr = 0;
 
+// current system sleep state (S0 - S4)
+static acpi_sstate_t acpi_sleep_state = ACPI_S0;
+// time sleep began
+static unsigned long acpi_sleep_start = 0;
+
 static spinlock_t acpi_event_lock = SPIN_LOCK_UNLOCKED;
 static volatile u32 acpi_pm1_status = 0;
 static volatile u32 acpi_gpe_status = 0;
 static volatile u32 acpi_gpe_level = 0;
+static volatile acpi_sstate_t acpi_event_state = ACPI_S0;
 static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait);
 
 static spinlock_t acpi_devs_lock = SPIN_LOCK_UNLOCKED;
@@ -153,14 +165,19 @@
 	 &acpi_p_lvl3_lat, sizeof(acpi_p_lvl3_lat),
 	 0644, NULL, &acpi_do_ulong},
 
+	{ACPI_S0_SLP_TYP, "s0_slp_typ",
+	 &acpi_slp_typ[ACPI_S0], sizeof(acpi_slp_typ[ACPI_S0]),
+	 0600, NULL, &acpi_do_ulong},
+
+	{ACPI_S1_SLP_TYP, "s1_slp_typ",
+	 &acpi_slp_typ[ACPI_S1], sizeof(acpi_slp_typ[ACPI_S1]),
+	 0600, NULL, &acpi_do_ulong},
+
 	{ACPI_S5_SLP_TYP, "s5_slp_typ",
-	 &acpi_slp_typ[5], sizeof(acpi_slp_typ[5]),
+	 &acpi_slp_typ[ACPI_S5], sizeof(acpi_slp_typ[ACPI_S5]),
 	 0600, NULL, &acpi_do_ulong},
 
-#if 0
-	{123, "sleep", (void*) 1, 0, 0600, NULL, &acpi_do_sleep_wake},
-	{124, "wake", NULL, 0, 0600, NULL, &acpi_do_sleep_wake},
-#endif
+	{ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep},
 
 	{0}
 };
@@ -578,6 +595,7 @@
 	acpi_pm1_status |= pm1_status;
 	acpi_gpe_status |= gpe_status;
 	spin_unlock_irqrestore(&acpi_event_lock, flags);
+	acpi_event_state = acpi_sleep_state;
 	wake_up_interruptible(&acpi_event_wait);
 }
 
@@ -735,6 +753,25 @@
 }
 
 /*
+ * Update system time from real-time clock
+ */
+static void acpi_update_clock(void)
+{
+	if (acpi_sleep_start) {
+		unsigned long delta;
+		struct timeval tv;
+		
+		delta = get_cmos_time() - acpi_sleep_start;
+		do_gettimeofday(&tv);
+		tv.tv_sec += delta;
+		do_settimeofday(&tv);
+		
+		acpi_sleep_start = 0;
+	}
+}
+
+
+/*
  * Enter system sleep state
  */
 static void acpi_enter_sx(acpi_sstate_t state)
@@ -751,9 +788,14 @@
 		typb = ((typb << ACPI_SLP_TYP_SHIFT) & ACPI_SLP_TYP_MASK);
 
 		if (state != ACPI_S0) {
+			acpi_sleep_start = get_cmos_time();
 			acpi_enter_dx(ACPI_D3);
+			acpi_sleep_state = state;
 		}
 
+		// clear wake status
+		acpi_write_pm1_status(acpi_facp, ACPI_WAK);
+
 		// set SLP_TYPa/b and SLP_EN
 		if (acpi_facp->pm1a_cnt) {
 			value = inw(acpi_facp->pm1a_cnt) & ~ACPI_SLP_TYP_MASK;
@@ -765,7 +807,15 @@
 		}
 
 		if (state == ACPI_S0) {
+			acpi_sleep_state = state;
 			acpi_enter_dx(ACPI_D0);
+			acpi_sleep_start = 0;
+		}
+		else if (state == ACPI_S1) {
+			// wait until S1 is entered
+			while (!(acpi_read_pm1_status(acpi_facp) & ACPI_WAK)) ;
+			// finished sleeping, update system time
+			acpi_update_clock();
 		}
 	}
 }
@@ -983,7 +1033,8 @@
 			 size_t *len)
 {
 	u32 pm1_status = 0, gpe_status = 0;
-	char str[4 * sizeof(u32) + 7];
+	acpi_sstate_t event_state = 0;
+	char str[27];
 	int size;
 
 	if (write)
@@ -1003,6 +1054,7 @@
 		gpe_status = acpi_gpe_status;
 		acpi_gpe_status = 0;
 		spin_unlock_irqrestore(&acpi_event_lock, flags);
+		event_state = acpi_event_state;
 		
 		if (pm1_status || gpe_status)
 			break;
@@ -1013,7 +1065,10 @@
 			return -ERESTARTSYS;
 	}
 
-	size = sprintf(str, "0x%08x 0x%08x\n", pm1_status, gpe_status);
+	size = sprintf(str, "0x%08x 0x%08x 0x%01x\n",
+		       pm1_status,
+		       gpe_status,
+		       event_state);
 	copy_to_user(buffer, str, size);
 	*len = size;
 	file->f_pos += size;
@@ -1021,15 +1076,14 @@
 	return 0;
 }
 
-#if 0
 /*
- * Sleep or wake system
+ * Enter system sleep state
  */
-static int acpi_do_sleep_wake(ctl_table *ctl,
-			      int write,
-			      struct file *file,
-			      void *buffer,
-			      size_t *len)
+static int acpi_do_sleep(ctl_table *ctl,
+			 int write,
+			 struct file *file,
+			 void *buffer,
+			 size_t *len)
 {
 	if (!write) {
 		if (file->f_pos) {
@@ -1039,18 +1093,12 @@
 	}
 	else
 	{
-		// just shutdown some devices for now
-		if (ctl->data) {
-			acpi_enter_dx(ACPI_D3);
-		}
-		else {
-			acpi_enter_dx(ACPI_D0);
-		}
+		acpi_enter_sx(ACPI_S1);
+		acpi_enter_sx(ACPI_S0);
 	}
 	file->f_pos += *len;
 	return 0;
 }
-#endif
 
 /*
  * Initialize and enable ACPI
@@ -1184,11 +1232,11 @@
 	strcpy(current->comm, "acpi");
 	
 	for(;;) {
-		interruptible_sleep_on(&acpi_idle_wait);
+		interruptible_sleep_on(&acpi_control_wait);
 		if (signal_pending(current))
 			break;
 
-		// find all idle devices and set idle timer based on policy
+		// find all idle devices and set idle timer
 	}
 
 	return 0;
@@ -1199,7 +1247,7 @@
 /*
  * Module visible symbols
  */
-EXPORT_SYMBOL(acpi_idle_wait);
+EXPORT_SYMBOL(acpi_control_wait);
 EXPORT_SYMBOL(acpi_register);
 EXPORT_SYMBOL(acpi_unregister);
 EXPORT_SYMBOL(acpi_wakeup);
diff -u --recursive --new-file v2.3.29/linux/drivers/net/de4x5.c linux/drivers/net/de4x5.c
--- v2.3.29/linux/drivers/net/de4x5.c	Fri Sep 10 23:57:29 1999
+++ linux/drivers/net/de4x5.c	Thu Dec  2 15:40:23 1999
@@ -425,11 +425,15 @@
       0.544   8-May-99    Fix for buggy SROM in Motorola embedded boards using
                            a 21143 by <mmporter@home.com>.
 			  Change PCI/EISA bus probing order.
+      0.545  28-Nov-99    Further Moto SROM bug fix from 
+                           <mporter@eng.mcd.mot.com>
+                          Remove double checking for DEBUG_RX in de4x5_dbg_rx()
+			   from report by <geert@linux-m68k.org>
  
     =========================================================================
 */
 
-static const char *version = "de4x5.c:V0.544 1999/5/8 davies@maniac.ultranet.com\n";
+static const char *version = "de4x5.c:V0.545 1999/11/28 davies@maniac.ultranet.com\n";
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -4817,6 +4821,7 @@
     } else if ((lp->media == INIT) && (lp->timeout < 0)) {
         lp->ibn = 3;
 	lp->active = *p;
+	if (MOTO_SROM_BUG) lp->active = 0;
 	lp->infoblock_csr6 = OMR_MII_100;
 	lp->useMII = TRUE;
 	lp->infoblock_media = ANS;
@@ -5521,14 +5526,12 @@
 	       (u_char)skb->data[12],
 	       (u_char)skb->data[13],
 	       len);
-	if (de4x5_debug & DEBUG_RX) {
-	    for (j=0; len>0;j+=16, len-=16) {
-		printk("    %03x: ",j);
-		for (i=0; i<16 && i<len; i++) {
-		    printk("%02x ",(u_char)skb->data[i+j]);
-		}
-		printk("\n");
-	    }
+	for (j=0; len>0;j+=16, len-=16) {
+	  printk("    %03x: ",j);
+	  for (i=0; i<16 && i<len; i++) {
+	    printk("%02x ",(u_char)skb->data[i+j]);
+	  }
+	  printk("\n");
 	}
     }
 
diff -u --recursive --new-file v2.3.29/linux/drivers/net/rrunner.c linux/drivers/net/rrunner.c
--- v2.3.29/linux/drivers/net/rrunner.c	Thu Nov 11 20:11:41 1999
+++ linux/drivers/net/rrunner.c	Mon Dec  6 17:15:53 1999
@@ -32,10 +32,10 @@
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
+#include <linux/cache.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
-#include <asm/cache.h>
 #include <asm/byteorder.h>
 #include <asm/io.h>
 #include <asm/irq.h>
diff -u --recursive --new-file v2.3.29/linux/drivers/net/sk98lin/skge.c linux/drivers/net/sk98lin/skge.c
--- v2.3.29/linux/drivers/net/sk98lin/skge.c	Tue Nov 23 22:42:20 1999
+++ linux/drivers/net/sk98lin/skge.c	Sat Nov 27 15:46:24 1999
@@ -2,8 +2,8 @@
  *
  * Name:      	skge.c
  * Project:	GEnesis, PCI Gigabit Ethernet Adapter
- * Version:	$Revision: 1.25 $
- * Date:       	$Date: 1999/10/07 14:47:52 $
+ * Version:	$Revision: 1.27 $
+ * Date:       	$Date: 1999/11/25 09:06:28 $
  * Purpose:	The main driver source module
  *
  ******************************************************************************/
@@ -46,6 +46,16 @@
  * History:
  *
  *	$Log: skge.c,v $
+ *	Revision 1.27  1999/11/25 09:06:28  cgoos
+ *	Changed base_addr to unsigned long.
+ *	
+ *	Revision 1.26  1999/11/22 13:29:16  cgoos
+ *	Changed license header to GPL.
+ *	Changes for inclusion in linux kernel (2.2.13).
+ *	Removed 2.0.x defines.
+ *	Changed SkGeProbe to skge_probe.
+ *	Added checks in SkGeIoctl.
+ *	
  *	Revision 1.25  1999/10/07 14:47:52  cgoos
  *	Changed 984x to 98xx.
  *	
@@ -337,7 +347,7 @@
 int		version_disp = 0;
 SK_AC		*pAC;
 struct pci_dev	*pdev = NULL;
-unsigned int	base_address;
+unsigned long	base_address;
 
 	if (probed)
 		return -ENODEV;
diff -u --recursive --new-file v2.3.29/linux/drivers/net/tokenring/olympic.c linux/drivers/net/tokenring/olympic.c
--- v2.3.29/linux/drivers/net/tokenring/olympic.c	Mon Oct 11 15:38:15 1999
+++ linux/drivers/net/tokenring/olympic.c	Sat Nov 27 15:27:48 1999
@@ -1614,10 +1614,7 @@
 
 #if OLYMPIC_NETWORK_MONITOR
 #ifdef CONFIG_PROC_FS
-	struct proc_dir_entry *ent ; 
-
-	ent = create_proc_entry("net/olympic_tr",0,0); 
-	ent->read_proc = &olympic_proc_info ; 
+	create_proc_read_entry("net/olympic_tr",0,0,olympic_proc_info,NULL); 
 #endif
 #endif
         for (i = 0; (i<OLYMPIC_MAX_ADAPTERS); i++) {
diff -u --recursive --new-file v2.3.29/linux/drivers/net/tokenring/tms380tr.c linux/drivers/net/tokenring/tms380tr.c
--- v2.3.29/linux/drivers/net/tokenring/tms380tr.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/net/tokenring/tms380tr.c	Sat Nov 27 15:27:48 1999
@@ -120,7 +120,7 @@
     "SK NET TR 4/16 ISA"},
   { TMS_PCI, PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_TOKENRING, 
     "Compaq 4/16 TR PCI"},
-  { TMS_PCI, PCI_VENDOR_ID_SK, PCI_DEVICE_ID_SK_TR, 
+  { TMS_PCI, PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_TR, 
     "SK NET TR 4/16 PCI"},
   { TMS_PCI, PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING,
     "Thomas-Conrad TC4048 PCI 4/16"},
diff -u --recursive --new-file v2.3.29/linux/drivers/net/wavelan.c linux/drivers/net/wavelan.c
--- v2.3.29/linux/drivers/net/wavelan.c	Mon Oct  4 15:49:29 1999
+++ linux/drivers/net/wavelan.c	Sat Nov 27 15:27:48 1999
@@ -1910,18 +1910,18 @@
 
     case SIOCSIWNWID:
       /* Set NWID in WaveLAN. */
-      if(wrq->u.nwid.on)
+      if(!wrq->u.nwid.disabled)
 	{
-	  /* Set NWID in psa. */
-	  psa.psa_nwid[0] = (wrq->u.nwid.nwid & 0xFF00) >> 8;
-	  psa.psa_nwid[1] = wrq->u.nwid.nwid & 0xFF;
+	  /* Set NWID in psa */
+	  psa.psa_nwid[0] = (wrq->u.nwid.value & 0xFF00) >> 8;
+	  psa.psa_nwid[1] = wrq->u.nwid.value & 0xFF;
 	  psa.psa_nwid_select = 0x01;
 	  psa_write(ioaddr, lp->hacr, (char *)psa.psa_nwid - (char *)&psa,
 		    (unsigned char *)psa.psa_nwid, 3);
 
 	  /* Set NWID in mmc. */
-	  m.w.mmw_netw_id_l = wrq->u.nwid.nwid & 0xFF;
-	  m.w.mmw_netw_id_h = (wrq->u.nwid.nwid & 0xFF00) >> 8;
+	  m.w.mmw_netw_id_l = psa.psa_nwid[1];
+	  m.w.mmw_netw_id_h = psa.psa_nwid[0];
 	  mmc_write(ioaddr, (char *)&m.w.mmw_netw_id_l - (char *)&m,
 		    (unsigned char *)&m.w.mmw_netw_id_l, 2);
 	  mmc_out(ioaddr, mmwoff(0, mmw_loopt_sel), 0x00);
@@ -1945,8 +1945,9 @@
       /* Read the NWID. */
       psa_read(ioaddr, lp->hacr, (char *)psa.psa_nwid - (char *)&psa,
 	       (unsigned char *)psa.psa_nwid, 3);
-      wrq->u.nwid.nwid = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
-      wrq->u.nwid.on = psa.psa_nwid_select;
+      wrq->u.nwid.value = (psa.psa_nwid[0] << 8) + psa.psa_nwid[1];
+      wrq->u.nwid.disabled = !(psa.psa_nwid_select);
+      wrq->u.nwid.fixed = 1;	/* Superfluous */
       break;
 
     case SIOCSIWFREQ:
@@ -2006,83 +2007,96 @@
       wrq->u.sens.fixed = 1;
       break;
 
-     case SIOCSIWENCODE:
-       /* Set encryption key. */
-       if(!mmc_encr(ioaddr))
-	 {
-	   ret = -EOPNOTSUPP;
-	   break;
-	 }
-
-       if(wrq->u.encoding.method)
-	 {	/* Enable encryption. */
-	   int		i;
-	   long long	key = wrq->u.encoding.code;
-
-	   for(i = 7; i >= 0; i--)
-	     {
-	       psa.psa_encryption_key[i] = key & 0xFF;
-	       key >>= 8;
-	     }
-           psa.psa_encryption_select = 1;
-	   psa_write(ioaddr, lp->hacr,
-		     (char *) &psa.psa_encryption_select - (char *) &psa,
-		     (unsigned char *) &psa.psa_encryption_select, 8+1);
-
-           mmc_out(ioaddr, mmwoff(0, mmw_encr_enable),
-		   MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
-           mmc_write(ioaddr, mmwoff(0, mmw_encr_key),
-		     (unsigned char *) &psa.psa_encryption_key, 8);
-	 }
-       else
-	 {	/* Disable encryption. */
-	   psa.psa_encryption_select = 0;
-	   psa_write(ioaddr, lp->hacr,
-		     (char *) &psa.psa_encryption_select - (char *) &psa,
-		     (unsigned char *) &psa.psa_encryption_select, 1);
-
-	   mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0);
-	 }
-       /* update the Wavelan checksum */
-       update_psa_checksum(dev, ioaddr, lp->hacr);
-       break;
-
-     case SIOCGIWENCODE:
-       /* Read the encryption key. */
-       if(!mmc_encr(ioaddr))
-	 {
-	   ret = -EOPNOTSUPP;
-	   break;
-	 }
-
-       /* Only super-user can see encryption key. */
-       if(!suser())
-	 {
-	   ret = -EPERM;
-	   break;
-	 }
-       else
-	 {
-	   int		i;
-	   long long	key = 0;
+    case SIOCSIWENCODE:
+      /* Set encryption key */
+      if(!mmc_encr(ioaddr))
+	{
+	  ret = -EOPNOTSUPP;
+	  break;
+	}
+
+      /* Basic checking... */
+      if(wrq->u.encoding.pointer != (caddr_t) 0)
+	{
+	  /* Check the size of the key */
+	  if(wrq->u.encoding.length != 8)
+	    {
+	      ret = -EINVAL;
+	      break;
+	    }
 
-	   psa_read(ioaddr, lp->hacr,
+	  /* Copy the key in the driver */
+	  if(copy_from_user(psa.psa_encryption_key, wrq->u.encoding.pointer,
+			    wrq->u.encoding.length))
+	    {
+	      ret = -EFAULT;
+	      break;
+	    }
+
+	  psa.psa_encryption_select = 1;
+	  psa_write(ioaddr, lp->hacr,
 		    (char *) &psa.psa_encryption_select - (char *) &psa,
-		    (unsigned char *) &psa.psa_encryption_select, 1+8);
-	   for(i = 0; i < 8; i++)
-	     {
-	       key <<= 8;
-	       key += psa.psa_encryption_key[i];
-	     }
-	   wrq->u.encoding.code = key;
-
-	   /* encryption is enabled */
-	   if(psa.psa_encryption_select)
-	     wrq->u.encoding.method = mmc_encr(ioaddr);
-	   else
-	     wrq->u.encoding.method = 0;
-	 }
-       break;
+		    (unsigned char *) &psa.psa_encryption_select, 8+1);
+
+	  mmc_out(ioaddr, mmwoff(0, mmw_encr_enable),
+		  MMW_ENCR_ENABLE_EN | MMW_ENCR_ENABLE_MODE);
+	  mmc_write(ioaddr, mmwoff(0, mmw_encr_key),
+		    (unsigned char *) &psa.psa_encryption_key, 8);
+	}
+
+      if(wrq->u.encoding.flags & IW_ENCODE_DISABLED)
+	{	/* disable encryption */
+	  psa.psa_encryption_select = 0;
+	  psa_write(ioaddr, lp->hacr,
+		    (char *) &psa.psa_encryption_select - (char *) &psa,
+		    (unsigned char *) &psa.psa_encryption_select, 1);
+
+	  mmc_out(ioaddr, mmwoff(0, mmw_encr_enable), 0);
+	}
+      /* update the Wavelan checksum */
+      update_psa_checksum(dev, ioaddr, lp->hacr);
+      break;
+
+    case SIOCGIWENCODE:
+      /* Read the encryption key */
+      if(!mmc_encr(ioaddr))
+	{
+	  ret = -EOPNOTSUPP;
+	  break;
+	}
+
+      /* only super-user can see encryption key */
+      if(!suser())
+	{
+	  ret = -EPERM;
+	  break;
+	}
+
+      /* Basic checking... */
+      if(wrq->u.encoding.pointer != (caddr_t) 0)
+	{
+	  /* Verify the user buffer */
+	  ret = verify_area(VERIFY_WRITE, wrq->u.encoding.pointer, 8);
+	  if(ret)
+	    break;
+
+	  psa_read(ioaddr, lp->hacr,
+		   (char *) &psa.psa_encryption_select - (char *) &psa,
+		   (unsigned char *) &psa.psa_encryption_select, 1+8);
+
+	  /* encryption is enabled ? */
+	  if(psa.psa_encryption_select)
+	    wrq->u.encoding.flags = IW_ENCODE_ENABLED;
+	  else
+	    wrq->u.encoding.flags = IW_ENCODE_DISABLED;
+	  wrq->u.encoding.flags |= mmc_encr(ioaddr);
+
+	  /* Copy the key to the user buffer */
+	  wrq->u.encoding.length = 8;
+	  if(copy_to_user(wrq->u.encoding.pointer, psa.psa_encryption_key, 8))
+	    ret = -EFAULT;
+	}
+      break;
 
     case SIOCGIWRANGE:
       /* basic checking */
@@ -2116,6 +2130,19 @@
 
 	  range.num_bitrates = 1;
 	  range.bitrate[0] = 2000000;	/* 2 Mb/s */
+
+	  /* Encryption supported ? */
+	  if(mmc_encr(ioaddr))
+	    {
+	      range.encoding_size[0] = 8;	/* DES = 64 bits key */
+	      range.num_encoding_sizes = 1;
+	      range.max_encoding_tokens = 1;	/* Only one key possible */
+	    }
+	  else
+	    {
+	      range.num_encoding_sizes = 0;
+	      range.max_encoding_tokens = 0;
+	    }
 
 	  /* Copy structure to the user buffer. */
 	  if (copy_to_user(wrq->u.data.pointer, &range, sizeof(struct iw_range)))
diff -u --recursive --new-file v2.3.29/linux/drivers/net/wavelan.p.h linux/drivers/net/wavelan.p.h
--- v2.3.29/linux/drivers/net/wavelan.p.h	Thu Aug 26 13:05:38 1999
+++ linux/drivers/net/wavelan.p.h	Sat Nov 27 15:27:48 1999
@@ -300,6 +300,11 @@
  *	- Add the (short) list of bit-rates in range
  *	- Developp a new sensitivity... (sens.value & sens.fixed)
  *
+ * Changes made for release in 2.2.14 & 2.3.23 :
+ * -------------------------------------------
+ *	- Fix check for root permission (break instead of exit)
+ *	- New nwid & encoding setting (Wireless Extension 9)
+ *
  * Wishes & dreams:
  * ----------------
  *	- roaming (see Pcmcia driver)
@@ -390,7 +395,7 @@
 /************************ CONSTANTS & MACROS ************************/
 
 #ifdef DEBUG_VERSION_SHOW
-static const char	*version	= "wavelan.c : v20 (wireless extensions) 29/7/99\n";
+static const char	*version	= "wavelan.c : v21 (wireless extensions) 16/10/99\n";
 #endif
 
 /* Watchdog temporisation */
diff -u --recursive --new-file v2.3.29/linux/drivers/nubus/proc.c linux/drivers/nubus/proc.c
--- v2.3.29/linux/drivers/nubus/proc.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/nubus/proc.c	Sat Nov 27 15:27:48 1999
@@ -95,7 +95,7 @@
 		struct nubus_dir dir;
 		
 		sprintf(name, "%x", ent.type);
-		e = create_proc_entry(name, S_IFDIR, parent);
+		e = proc_mkdir(name, parent);
 		if (!e) return;
 
 		/* And descend */
@@ -131,8 +131,7 @@
 		
 	/* Create a directory */
 	sprintf(name, "%x", dev->board->slot);
-	e = dev->procdir = create_proc_entry(name, S_IFDIR,
-					     proc_bus_nubus_dir);
+	e = dev->procdir = proc_mkdir(name, proc_bus_nubus_dir);
 	if (!e)
 		return -ENOMEM;
 
@@ -169,7 +168,7 @@
 {
 	if (!MACH_IS_MAC)
 		return;
-	proc_bus_nubus_dir = create_proc_entry("nubus", S_IFDIR, proc_bus);
+	proc_bus_nubus_dir = proc_mkdir("nubus", proc_bus);
 	create_proc_info_entry("devices", 0, proc_bus_nubus_dir,
 				get_nubus_dev_info);
 	proc_bus_nubus_add_devices();
diff -u --recursive --new-file v2.3.29/linux/drivers/pci/compat.c linux/drivers/pci/compat.c
--- v2.3.29/linux/drivers/pci/compat.c	Thu Aug 26 13:05:38 1999
+++ linux/drivers/pci/compat.c	Sat Nov 27 15:27:48 1999
@@ -3,7 +3,7 @@
  *
  *	PCI Bus Services -- Function For Backward Compatibility
  *
- *	Copyright 1998, 1999 Martin Mares <mj@ucw.cz>
+ *	Copyright 1998, 1999 Martin Mares <mj@suse.cz>
  */
 
 #include <linux/types.h>
diff -u --recursive --new-file v2.3.29/linux/drivers/pci/gen-devlist.c linux/drivers/pci/gen-devlist.c
--- v2.3.29/linux/drivers/pci/gen-devlist.c	Thu Nov 11 20:11:42 1999
+++ linux/drivers/pci/gen-devlist.c	Sat Nov 27 15:27:48 1999
@@ -1,7 +1,7 @@
 /*
  *	Generate devlist.h from the PCI ID file.
  *
- *	(c) 1999 Martin Mares <mj@ucw.cz>
+ *	(c) 1999 Martin Mares <mj@suse.cz>
  */
 
 #include <stdio.h>
diff -u --recursive --new-file v2.3.29/linux/drivers/pci/pci.c linux/drivers/pci/pci.c
--- v2.3.29/linux/drivers/pci/pci.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/pci/pci.c	Sat Nov 27 19:34:31 1999
@@ -6,7 +6,7 @@
  *	Copyright 1993 -- 1997 Drew Eckhardt, Frederic Potter,
  *	David Mosberger-Tang
  *
- *	Copyright 1997 -- 1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *	Copyright 1997 -- 1999 Martin Mares <mj@suse.cz>
  */
 
 #include <linux/types.h>
diff -u --recursive --new-file v2.3.29/linux/drivers/pci/pci.ids linux/drivers/pci/pci.ids
--- v2.3.29/linux/drivers/pci/pci.ids	Tue Nov 23 22:42:21 1999
+++ linux/drivers/pci/pci.ids	Sat Nov 27 15:27:48 1999
@@ -693,16 +693,17 @@
 1056  ICL
 # Motorola made a mistake and used this value, please duplicate Moto
 # entries here -- Cort
-1507  Motorola Computer Group
+1507  Motorola
 	0001  MPC105 [Eagle]
 	0002  MPC106 [Grackle]
+	0003  MPC8240 [Kahlua]
 	0100  MC145575 [HFC-PCI]
 	0431  KTI829c 100VG
 	4801  Raven
 	4802  Falcon
 	4803  Hawk
 	4806  CPX8216
-1057  Motorola Computer Group
+1057  Motorola
 	0001  MPC105 [Eagle]
 	0002  MPC106 [Grackle]
 	0100  MC145575 [HFC-PCI]
diff -u --recursive --new-file v2.3.29/linux/drivers/pci/proc.c linux/drivers/pci/proc.c
--- v2.3.29/linux/drivers/pci/proc.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/pci/proc.c	Sun Dec  5 08:42:03 1999
@@ -3,7 +3,7 @@
  *
  *	Procfs interface for the PCI bus.
  *
- *	Copyright (c) 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *	Copyright (c) 1997--1999 Martin Mares <mj@suse.cz>
  */
 
 #include <linux/types.h>
@@ -207,25 +207,6 @@
 
 static struct inode_operations proc_bus_pci_inode_operations = {
 	&proc_bus_pci_operations, /* default base directory file-ops */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* get_block */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* flushpage */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL,			/* smap */
-	NULL			/* revalidate */
 };
 
 #if BITS_PER_LONG == 32
@@ -281,7 +262,7 @@
 
 	if (!(de = bus->procdir)) {
 		sprintf(name, "%02x", bus->number);
-		de = bus->procdir = create_proc_entry(name, S_IFDIR, proc_bus_pci_dir);
+		de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir);
 		if (!de)
 			return -ENOMEM;
 	}
@@ -530,7 +511,7 @@
 static int __init pci_proc_init(void)
 {
 	if (pci_present()) {
-		proc_bus_pci_dir = create_proc_entry("pci", S_IFDIR, proc_bus);
+		proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
 		create_proc_info_entry("devices",0, proc_bus_pci_dir,
 					get_pci_dev_info);
 		proc_bus_pci_add(pci_root);
diff -u --recursive --new-file v2.3.29/linux/drivers/pci/quirks.c linux/drivers/pci/quirks.c
--- v2.3.29/linux/drivers/pci/quirks.c	Fri Oct 22 13:21:49 1999
+++ linux/drivers/pci/quirks.c	Sat Nov 27 15:27:48 1999
@@ -5,7 +5,7 @@
  *  bugs.  Devices present only on certain architectures (host
  *  bridges et cetera) should be handled in arch-specific code.
  *
- *  Copyright (c) 1999 Martin Mares <mj@ucw.cz>
+ *  Copyright (c) 1999 Martin Mares <mj@suse.cz>
  *
  *  The bridge optimization stuff has been removed. If you really
  *  have a silly BIOS which is unable to set your host bridge right,
diff -u --recursive --new-file v2.3.29/linux/drivers/pci/setup.c linux/drivers/pci/setup.c
--- v2.3.29/linux/drivers/pci/setup.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/pci/setup.c	Mon Dec  6 17:15:53 1999
@@ -16,8 +16,7 @@
 #include <linux/pci.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
-
-#include <asm/cache.h>
+#include <linux/cache.h>
 
 
 #define DEBUG_CONFIG 0
@@ -84,7 +83,7 @@
 		DBGC(("  for root[%lx:%lx] min[%lx] size[%lx]\n",
 		      root->start, root->end, min, size));
 
-		if (allocate_resource(root, res, size, min, -1, size, dev) < 0) {
+		if (allocate_resource(root, res, size, min, -1, size, pcibios_align_resource, dev) < 0) {
 			printk(KERN_ERR
 			       "PCI: Failed to allocate resource %d for %s\n",
 			       i, dev->name);
@@ -271,7 +270,7 @@
 		pbus_set_ranges(bus, NULL);
 }
 
-static void
+static void __init
 pdev_fixup_irq(struct pci_dev *dev,
 	       u8 (*swizzle)(struct pci_dev *, u8 *),
 	       int (*map_irq)(struct pci_dev *, u8, u8))
diff -u --recursive --new-file v2.3.29/linux/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
--- v2.3.29/linux/drivers/pcmcia/cs.c	Thu Nov 11 20:11:42 1999
+++ linux/drivers/pcmcia/cs.c	Sat Nov 27 15:27:48 1999
@@ -327,15 +327,10 @@
 #ifdef CONFIG_PROC_FS
 	if (proc_pccard) {
 	    char name[3];
-#ifdef PCMCIA_DEBUG
-	    struct proc_dir_entry *ent;
-#endif
 	    sprintf(name, "%02d", i);
-	    s->proc = create_proc_entry(name, S_IFDIR, proc_pccard);
+	    s->proc = proc_mkdir(name, proc_pccard);
 #ifdef PCMCIA_DEBUG
-	    ent = create_proc_entry("clients", 0, s->proc);
-	    ent->read_proc = proc_read_clients;
-	    ent->data = s;
+	    create_proc_read_entry("clients",0,s->proc,proc_read_clients,s);
 #endif
 	    ss_entry(ns, SS_ProcSetup, s->proc);
 	}
@@ -2236,7 +2231,7 @@
 	apm_register_callback(&handle_apm_event);
 #endif
 #ifdef CONFIG_PROC_FS
-    proc_pccard = create_proc_entry("pccard", S_IFDIR, proc_bus);
+    proc_pccard = proc_mkdir("pccard", proc_bus);
 #endif
     return 0;
 }
diff -u --recursive --new-file v2.3.29/linux/drivers/pcmcia/ds.c linux/drivers/pcmcia/ds.c
--- v2.3.29/linux/drivers/pcmcia/ds.c	Thu Nov 18 20:25:37 1999
+++ linux/drivers/pcmcia/ds.c	Sat Nov 27 15:27:48 1999
@@ -899,11 +899,8 @@
 	major_dev = i;
 
 #ifdef CONFIG_PROC_FS
-    if (proc_pccard) {
-	struct proc_dir_entry *ent;
-	ent = create_proc_entry("drivers", 0, proc_pccard);
-	ent->read_proc = proc_read_drivers;
-    }
+    if (proc_pccard)
+	create_proc_read_entry("drivers",0,proc_pccard,proc_read_drivers,NULL);
     init_status = 0;
 #endif
     return 0;
diff -u --recursive --new-file v2.3.29/linux/drivers/pcmcia/i82365.c linux/drivers/pcmcia/i82365.c
--- v2.3.29/linux/drivers/pcmcia/i82365.c	Thu Nov 11 20:11:42 1999
+++ linux/drivers/pcmcia/i82365.c	Sat Nov 27 15:27:48 1999
@@ -2602,26 +2602,15 @@
 static void pcic_proc_setup(u_short sock, struct proc_dir_entry *base)
 {
     socket_info_t *s = &socket[sock];
-    struct proc_dir_entry *ent;
-    ent = create_proc_entry("info", 0, base);
-    ent->read_proc = proc_read_info;
-    ent->data = s;
-    ent = create_proc_entry("exca", 0, base);
-    ent->read_proc = proc_read_exca;
-    ent->data = s;
+    create_proc_read_entry("info", 0, base, proc_read_info, s);
+    create_proc_read_entry("exca", 0, base, proc_read_exca, s);
 #ifdef CONFIG_PCI
-    if (s->flags & (IS_PCI|IS_CARDBUS)) {
-	ent = create_proc_entry("pci", 0, base);
-	ent->read_proc = proc_read_pci;
-	ent->data = s;
-    }
+    if (s->flags & (IS_PCI|IS_CARDBUS))
+	create_proc_read_entry("pci", 0, base, proc_read_pci, s);
 #endif
 #ifdef CONFIG_CARDBUS
-    if (s->flags & IS_CARDBUS) {
-	ent = create_proc_entry("cardbus", 0, base);
-	ent->read_proc = proc_read_cardbus;
-	ent->data = s;
-    }
+    if (s->flags & IS_CARDBUS)
+	create_proc_read_entry("cardbus", 0, base, proc_read_cardbus, s);
 #endif
     s->proc = base;
 }
diff -u --recursive --new-file v2.3.29/linux/drivers/pnp/isapnp.c linux/drivers/pnp/isapnp.c
--- v2.3.29/linux/drivers/pnp/isapnp.c	Tue Sep  7 12:14:06 1999
+++ linux/drivers/pnp/isapnp.c	Thu Dec  2 14:55:04 1999
@@ -56,7 +56,7 @@
 
 int isapnp_disable = 0;			/* Disable ISA PnP */
 int isapnp_rdp = 0;			/* Read Data Port */
-int isapnp_reset = 0;			/* reset all PnP cards (deactivate) */
+int isapnp_reset = 1;			/* reset all PnP cards (deactivate) */
 int isapnp_skip_pci_scan = 0;		/* skip PCI resource scanning */
 int isapnp_verbose = 1;			/* verbose mode */
 int isapnp_reserve_irq[16] = { [0 ... 15] = -1 };	/* reserve (don't use) some IRQ */
@@ -129,7 +129,7 @@
 static inline void write_address(unsigned char x)
 {
 	outb(x, _PIDXR);
-	udelay(10);
+	udelay(20);
 }
 
 static inline unsigned char read_data(void)
@@ -240,6 +240,7 @@
 {
 	isapnp_device(logdev);
 	isapnp_write_byte(ISAPNP_CFG_ACTIVATE, 0);
+	udelay(500);
 }
 
 static void __init isapnp_peek(unsigned char *data, int bytes)
@@ -252,7 +253,7 @@
 			d = isapnp_read_byte(0x05);
 			if (d & 1)
 				break;
-			udelay(10);
+			udelay(100);
 		}
 		if (!(d & 1)) {
 			*data++ = 0xff;
@@ -365,7 +366,10 @@
 			udelay(250);
 			iteration++;
 			isapnp_wake(0x00);
+			isapnp_set_rdp();
+			udelay(1000);
 			write_address(0x01);
+			udelay(1000);
 			goto __next;
 		}
 		if (iteration == 1) {
diff -u --recursive --new-file v2.3.29/linux/drivers/pnp/isapnp_proc.c linux/drivers/pnp/isapnp_proc.c
--- v2.3.29/linux/drivers/pnp/isapnp_proc.c	Thu Nov 11 20:11:43 1999
+++ linux/drivers/pnp/isapnp_proc.c	Sun Dec  5 08:42:03 1999
@@ -212,22 +212,6 @@
 static struct inode_operations isapnp_info_entry_inode_operations =
 {
 	&isapnp_info_entry_operations,	/* default sound info directory file-ops */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* bmap */
-	NULL,			/* truncate */
-	NULL			/* permission */
 };
 
 static int __init isapnp_proc_init(void)
@@ -605,11 +589,11 @@
 
 static unsigned char isapnp_get_hex(unsigned char c)
 {
-	if (c >= '0' || c <= '9')
+	if (c >= '0' && c <= '9')
 		return c - '0';
-	if (c >= 'a' || c <= 'f')
+	if (c >= 'a' && c <= 'f')
 		return (c - 'a') + 10;
-	if (c >= 'A' || c <= 'F')
+	if (c >= 'A' && c <= 'F')
 		return (c - 'A') + 10;
 	return 0;
 }
diff -u --recursive --new-file v2.3.29/linux/drivers/scsi/aic7xxx.c linux/drivers/scsi/aic7xxx.c
--- v2.3.29/linux/drivers/scsi/aic7xxx.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/scsi/aic7xxx.c	Sat Dec  4 09:38:41 1999
@@ -242,6 +242,7 @@
 #include <linux/proc_fs.h>
 #include <linux/blk.h>
 #include <linux/tqueue.h>
+#include <linux/init.h>
 #include "sd.h"
 #include "scsi.h"
 #include "hosts.h"
@@ -1499,8 +1500,8 @@
  *   to a parameter with a ':' between the parameter and the value.
  *   ie. aic7xxx=unpause:0x0A,extended
  *-F*************************************************************************/
-void
-aic7xxx_setup(char *s, int *dummy)
+static int
+aic7xxx_setup(char *s)
 {
   int   i, n;
   char *p;
@@ -1637,7 +1638,10 @@
       }
     }
   }
+  return 1;
 }
+
+__setup("aic7xxx=", aic7xxx_setup);
 
 /*+F*************************************************************************
  * Function:
diff -u --recursive --new-file v2.3.29/linux/drivers/scsi/megaraid.c linux/drivers/scsi/megaraid.c
--- v2.3.29/linux/drivers/scsi/megaraid.c	Thu Nov 11 20:11:48 1999
+++ linux/drivers/scsi/megaraid.c	Sat Nov 27 16:27:44 1999
@@ -287,9 +287,9 @@
 static Scsi_Cmnd *qCompleted = NULL;
 
 #if SERDEBUG
-volatile static spinlock_t serial_lock;
+volatile static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED;
 #endif
-volatile static spinlock_t mega_lock;
+volatile static spinlock_t mega_lock = SPIN_LOCK_UNLOCKED;
 
 #if SERDEBUG
 static char strbuf[MAX_SERBUF + 1];
diff -u --recursive --new-file v2.3.29/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c
--- v2.3.29/linux/drivers/scsi/ncr53c8xx.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/scsi/ncr53c8xx.c	Sat Nov 27 16:27:44 1999
@@ -528,7 +528,7 @@
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)
 
 #if 0	/* not yet needed */
-static spinlock_t driver_lock;
+static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;
 #define	NCR_LOCK_DRIVER(flags)     spin_lock_irqsave(&driver_lock, flags)
 #define	NCR_UNLOCK_DRIVER(flags)   spin_unlock_irqrestore(&driver_lock, flags)
 #endif
diff -u --recursive --new-file v2.3.29/linux/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c
--- v2.3.29/linux/drivers/scsi/qlogicisp.c	Thu Nov 11 20:11:48 1999
+++ linux/drivers/scsi/qlogicisp.c	Thu Dec  2 15:24:49 1999
@@ -126,11 +126,30 @@
 #define PCI_ID_LOW	0x00	/* vendor id */
 #define PCI_ID_HIGH	0x02	/* device id */
 #define ISP_CFG0	0x04	/* configuration register #0 */
+#define  ISP_CFG0_HWMSK  0x000f	/* Hardware revision mask */
+#define  ISP_CFG0_1020	 0x0001 /* ISP1020 */
+#define  ISP_CFG0_1020A	 0x0002 /* ISP1020A */
+#define  ISP_CFG0_1040	 0x0003 /* ISP1040 */
+#define  ISP_CFG0_1040A	 0x0004 /* ISP1040A */
+#define  ISP_CFG0_1040B	 0x0005 /* ISP1040B */
+#define  ISP_CFG0_1040C	 0x0006 /* ISP1040C */
 #define ISP_CFG1	0x06	/* configuration register #1 */
+#define  ISP_CFG1_F128	 0x0040	/* 128-byte FIFO threshold */
+#define  ISP_CFG1_F64	 0x0030	/* 128-byte FIFO threshold */
+#define  ISP_CFG1_F32	 0x0020	/* 128-byte FIFO threshold */
+#define  ISP_CFG1_F16	 0x0010	/* 128-byte FIFO threshold */
+#define  ISP_CFG1_BENAB	 0x0004	/* Global Bus burst enable */
+#define  ISP_CFG1_SXP	 0x0001	/* SXP register select */
 #define PCI_INTF_CTL	0x08	/* pci interface control */
 #define PCI_INTF_STS	0x0a	/* pci interface status */
 #define PCI_SEMAPHORE	0x0c	/* pci semaphore */
 #define PCI_NVRAM	0x0e	/* pci nvram interface */
+#define CDMA_CONF	0x20	/* Command DMA Config */
+#define DDMA_CONF	0x40	/* Data DMA Config */
+#define  DMA_CONF_SENAB	 0x0008	/* SXP to DMA Data enable */
+#define  DMA_CONF_RIRQ	 0x0004	/* RISC interrupt enable */
+#define  DMA_CONF_BENAB	 0x0002	/* Bus burst enable */
+#define  DMA_CONF_DIR	 0x0001	/* DMA direction (0=fifo->host 1=host->fifo) */
 
 /* mailbox registers */
 #define MBOX0		0x70	/* mailbox 0 */
@@ -489,6 +508,7 @@
 #define QUEUE_ENTRY_LEN		64
 
 struct isp1020_hostdata {
+	u_long	memaddr;
 	u_char	revision;
 	struct	host_param host_param;
 	struct	dev_param dev_param[MAX_TARGETS];
@@ -535,15 +555,33 @@
 static void	isp1020_print_status_entry(struct Status_Entry *);
 #endif
 
+static inline u_short isp_inw(struct Scsi_Host *host, long offset)
+{
+	struct isp1020_hostdata *h = (struct isp1020_hostdata *)host->hostdata;
+	if (h->memaddr)
+		return readw(h->memaddr + offset);
+	else
+		return inw(host->io_port + offset);
+}
+
+static inline void isp_outw(u_short val, struct Scsi_Host *host, long offset)
+{
+	struct isp1020_hostdata *h = (struct isp1020_hostdata *)host->hostdata;
+	if (h->memaddr)
+		writew(val, h->memaddr + offset);
+	else
+		outw(val, host->io_port + offset);
+}
+
 static inline void isp1020_enable_irqs(struct Scsi_Host *host)
 {
-	outw(ISP_EN_INT|ISP_EN_RISC, host->io_port + PCI_INTF_CTL);
+	isp_outw(ISP_EN_INT|ISP_EN_RISC, host, PCI_INTF_CTL);
 }
 
 
 static inline void isp1020_disable_irqs(struct Scsi_Host *host)
 {
-	outw(0x0, host->io_port + PCI_INTF_CTL);
+	isp_outw(0x0, host, PCI_INTF_CTL);
 }
 
 
@@ -604,8 +642,8 @@
 
 		request_region(host->io_port, 0xff, "qlogicisp");
 
-		outw(0x0, host->io_port + PCI_SEMAPHORE);
-		outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
+		isp_outw(0x0, host, PCI_SEMAPHORE);
+		isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);
 		isp1020_enable_irqs(host);
 
 		hosts++;
@@ -625,7 +663,7 @@
 
 	hostdata = (struct isp1020_hostdata *) host->hostdata;
 
-	outw(0x0, host->io_port + PCI_INTF_CTL);
+	isp_outw(0x0, host, PCI_INTF_CTL);
 	free_irq(host->irq, host);
 
 	release_region(host->io_port, 0xff);
@@ -645,9 +683,10 @@
 
 	hostdata = (struct isp1020_hostdata *) host->hostdata;
 	sprintf(buf,
-		"QLogic ISP1020 SCSI on PCI bus %02x device %02x irq %d base 0x%lx",
+		"QLogic ISP1020 SCSI on PCI bus %02x device %02x irq %d %s base 0x%lx",
 		hostdata->pci_dev->bus->number, hostdata->pci_dev->devfn, host->irq,
-		host->io_port);
+		(host->io_port ? "I/O" : "MEM"),
+		(host->io_port ? host->io_port : hostdata->memaddr));
 
 	LEAVE("isp1020_info");
 
@@ -680,7 +719,7 @@
 
 	DEBUG(isp1020_print_scsi_cmd(Cmnd));
 
-	out_ptr = inw(host->io_port + MBOX4);
+	out_ptr = isp_inw(host, + MBOX4);
 	in_ptr  = hostdata->req_in_ptr;
 
 	DEBUG(printk("qlogicisp : request queue depth %d\n",
@@ -709,7 +748,7 @@
 		hostdata->send_marker = 0;
 
 		if (((in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN) == out_ptr) {
-			outw(in_ptr, host->io_port + MBOX4);
+			isp_outw(in_ptr, host, MBOX4);
 			hostdata->req_in_ptr = in_ptr;
 			printk("qlogicisp : request queue overflow\n");
 			return 1;
@@ -785,7 +824,7 @@
 		cmd->segment_cnt = cpu_to_le16(1);
 	}
 
-	outw(in_ptr, host->io_port + MBOX4);
+	isp_outw(in_ptr, host, MBOX4);
 	hostdata->req_in_ptr = in_ptr;
 
 	num_free = QLOGICISP_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
@@ -824,16 +863,16 @@
 
 	DEBUG_INTR(printk("qlogicisp : interrupt on line %d\n", irq));
 
-	if (!(inw(host->io_port + PCI_INTF_STS) & 0x04)) {
+	if (!(isp_inw(host, PCI_INTF_STS) & 0x04)) {
 		/* spurious interrupts can happen legally */
 		DEBUG_INTR(printk("qlogicisp: got spurious interrupt\n"));
 		return;
 	}
-	in_ptr = inw(host->io_port + MBOX5);
-	outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
+	in_ptr = isp_inw(host, MBOX5);
+	isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);
 
-	if ((inw(host->io_port + PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) {
-		status = inw(host->io_port + MBOX0);
+	if ((isp_inw(host, PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) {
+		status = isp_inw(host, MBOX0);
 
 		DEBUG_INTR(printk("qlogicisp : mbox completion status: %x\n",
 				  status));
@@ -850,7 +889,7 @@
 			printk("qlogicisp : bad mailbox return status\n");
 			break;
 		}
-		outw(0x0, host->io_port + PCI_SEMAPHORE);
+		isp_outw(0x0, host, PCI_SEMAPHORE);
 	}
 	out_ptr = hostdata->res_out_ptr;
 
@@ -882,7 +921,7 @@
 		else
 			Cmnd->result = DID_ERROR << 16;
 
-		outw(out_ptr, host->io_port + MBOX5);
+		isp_outw(out_ptr, host, MBOX5);
 		(*Cmnd->scsi_done)(Cmnd);
 	}
 	hostdata->res_out_ptr = out_ptr;
@@ -1078,28 +1117,28 @@
 
 	ENTER("isp1020_reset_hardware");
 
-	outw(ISP_RESET, host->io_port + PCI_INTF_CTL);
+	isp_outw(ISP_RESET, host, PCI_INTF_CTL);
 	udelay(100);
-	outw(HCCR_RESET, host->io_port + HOST_HCCR);
+	isp_outw(HCCR_RESET, host, HOST_HCCR);
 	udelay(100);
-	outw(HCCR_RELEASE, host->io_port + HOST_HCCR);
-	outw(HCCR_BIOS_DISABLE, host->io_port + HOST_HCCR);
+	isp_outw(HCCR_RELEASE, host, HOST_HCCR);
+	isp_outw(HCCR_BIOS_DISABLE, host, HOST_HCCR);
 
 	loop_count = DEFAULT_LOOP_COUNT;
-	while (--loop_count && inw(host->io_port + HOST_HCCR) == RISC_BUSY)
+	while (--loop_count && isp_inw(host, HOST_HCCR) == RISC_BUSY)
 		barrier();
 	if (!loop_count)
 		printk("qlogicisp: reset_hardware loop timeout\n");
 
-	outw(0, host->io_port + ISP_CFG1);
+	isp_outw(0, host, ISP_CFG1);
 
 #if DEBUG_ISP1020
-	printk("qlogicisp : mbox 0 0x%04x \n", inw(host->io_port + MBOX0));
-	printk("qlogicisp : mbox 1 0x%04x \n", inw(host->io_port + MBOX1));
-	printk("qlogicisp : mbox 2 0x%04x \n", inw(host->io_port + MBOX2));
-	printk("qlogicisp : mbox 3 0x%04x \n", inw(host->io_port + MBOX3));
-	printk("qlogicisp : mbox 4 0x%04x \n", inw(host->io_port + MBOX4));
-	printk("qlogicisp : mbox 5 0x%04x \n", inw(host->io_port + MBOX5));
+	printk("qlogicisp : mbox 0 0x%04x \n", isp_inw(host, MBOX0));
+	printk("qlogicisp : mbox 1 0x%04x \n", isp_inw(host, MBOX1));
+	printk("qlogicisp : mbox 2 0x%04x \n", isp_inw(host, MBOX2));
+	printk("qlogicisp : mbox 3 0x%04x \n", isp_inw(host, MBOX3));
+	printk("qlogicisp : mbox 4 0x%04x \n", isp_inw(host, MBOX4));
+	printk("qlogicisp : mbox 5 0x%04x \n", isp_inw(host, MBOX5));
 #endif /* DEBUG_ISP1020 */
 
 	param[0] = MBOX_NO_OP;
@@ -1164,7 +1203,7 @@
 
 static int isp1020_init(struct Scsi_Host *sh)
 {
-	u_long io_base, io_flags;
+	u_long io_base, mem_base, io_flags, mem_flags;
 	struct isp1020_hostdata *hostdata;
 	u_char revision;
 	u_int irq;
@@ -1184,7 +1223,9 @@
 	}
 
 	io_base = pdev->resource[0].start;
+	mem_base = pdev->resource[1].start;
 	io_flags = pdev->resource[0].flags;
+	mem_flags = pdev->resource[1].flags;
 	irq = pdev->irq;
 
 	if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) {
@@ -1200,6 +1241,8 @@
 	}
 
 #ifdef __sparc__
+	if (mem_base)
+		mem_base = __pa(mem_base);
 	command |= (PCI_COMMAND_MASTER|PCI_COMMAND_IO|PCI_COMMAND_MEMORY|
 		    PCI_COMMAND_INVALIDATE|PCI_COMMAND_SERR);
 	pci_write_config_word(pdev, PCI_COMMAND, command);
@@ -1208,11 +1251,20 @@
 	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
 #endif
 
-	if (! ((command & PCI_COMMAND_IO)
-	       && ((io_flags & PCI_BASE_ADDRESS_SPACE)
-		   == PCI_BASE_ADDRESS_SPACE_IO))) {
-		printk("qlogicisp : i/o mapping is disabled\n");
-		return 1;
+ 	if ((command & PCI_COMMAND_MEMORY) &&
+ 	    ((mem_flags & 1) == 0)) {
+ 		mem_base = (u_long) ioremap(mem_base, PAGE_SIZE);
+ 		hostdata->memaddr = mem_base;
+ 		io_base = 0;
+ 	} else {
+ 		if (command & PCI_COMMAND_IO && (io_flags & 3) != 1)
+ 		{
+ 			printk("qlogicisp : i/o mapping is disabled\n");
+ 			return 1;
+ 		}
+ 		hostdata->memaddr = 0;
+ 		sh->io_port = io_base;
+ 		mem_base = 0;
 	}
 
 	if (!(command & PCI_COMMAND_MASTER)) {
@@ -1223,18 +1275,18 @@
 	if (revision != ISP1020_REV_ID)
 		printk("qlogicisp : new isp1020 revision ID (%d)\n", revision);
 
-	if (inw(io_base + PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC
-	    || inw(io_base + PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020)
+	if (isp_inw(sh,  PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC
+	    || isp_inw(sh, PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020)
 	{
-		printk("qlogicisp : can't decode i/o address space 0x%lx\n",
-		       io_base);
+		printk("qlogicisp : can't decode %s address space 0x%lx\n",
+		       (io_base ? "I/O" : "MEM"),
+		       (io_base ? io_base : mem_base));
 		return 1;
 	}
 
 	hostdata->revision = revision;
 
 	sh->irq = irq;
-	sh->io_port = io_base;
 	sh->max_id = MAX_TARGETS;
 	sh->max_lun = MAX_LUNS;
 
@@ -1391,20 +1443,20 @@
 
 	for (i = 8; i >= 0; i--) {
 		output = ((byte >> i) & 0x1) ? 0x4 : 0x0;
-		outw(output | 0x2, host->io_port + PCI_NVRAM); NVRAM_DELAY();
-		outw(output | 0x3, host->io_port + PCI_NVRAM); NVRAM_DELAY();
-		outw(output | 0x2, host->io_port + PCI_NVRAM); NVRAM_DELAY();
+		isp_outw(output | 0x2, host, PCI_NVRAM); NVRAM_DELAY();
+		isp_outw(output | 0x3, host, PCI_NVRAM); NVRAM_DELAY();
+		isp_outw(output | 0x2, host, PCI_NVRAM); NVRAM_DELAY();
 	}
 
 	for (i = 0xf, value = 0; i >= 0; i--) {
 		value <<= 1;
-		outw(0x3, host->io_port + PCI_NVRAM); NVRAM_DELAY();
-		input = inw(host->io_port + PCI_NVRAM); NVRAM_DELAY();
-		outw(0x2, host->io_port + PCI_NVRAM); NVRAM_DELAY();
+		isp_outw(0x3, host, PCI_NVRAM); NVRAM_DELAY();
+		input = isp_inw(host, PCI_NVRAM); NVRAM_DELAY();
+		isp_outw(0x2, host, PCI_NVRAM); NVRAM_DELAY();
 		if (input & 0x8) value |= 1;
 	}
 
-	outw(0x0, host->io_port + PCI_NVRAM); NVRAM_DELAY();
+	isp_outw(0x0, host, PCI_NVRAM); NVRAM_DELAY();
 
 	return value;
 }
@@ -1454,7 +1506,7 @@
 	int i, k;
 	u_int queue_addr;
 	u_short param[6];
-	u_short isp_cfg1;
+	u_short isp_cfg1, hwrev;
 	unsigned long flags;
 	struct isp1020_hostdata *hostdata =
 		(struct isp1020_hostdata *) host->hostdata;
@@ -1464,7 +1516,16 @@
 	save_flags(flags);
 	cli();
 
-	outw(hostdata->host_param.fifo_threshold, host->io_port + ISP_CFG1);
+	hwrev = isp_inw(host, ISP_CFG0) & ISP_CFG0_HWMSK;
+	isp_cfg1 = ISP_CFG1_F64 | ISP_CFG1_BENAB;
+	if (hwrev == ISP_CFG0_1040A) {
+		/* Busted fifo, says mjacob. */
+		isp_cfg1 &= ISP_CFG1_BENAB;
+	}
+
+	isp_outw(isp_inw(host, ISP_CFG1) | isp_cfg1, host, ISP_CFG1);
+	isp_outw(isp_inw(host, CDMA_CONF) | DMA_CONF_BENAB, host, CDMA_CONF);
+	isp_outw(isp_inw(host, DDMA_CONF) | DMA_CONF_BENAB, host, DDMA_CONF);
 
 	param[0] = MBOX_SET_INIT_SCSI_ID;
 	param[1] = hostdata->host_param.initiator_scsi_id;
@@ -1524,16 +1585,6 @@
 		return 1;
 	}
 
-	isp_cfg1 = inw(host->io_port + ISP_CFG1);
-
-	if (hostdata->host_param.data_dma_burst_enable 
-            || hostdata->host_param.command_dma_burst_enable)
-		isp_cfg1 |= 0x0004;
-	else
-		isp_cfg1 &= 0xfffb;
-
-	outw(isp_cfg1, host->io_port + ISP_CFG1);
-
 	param[0] = MBOX_SET_TAG_AGE_LIMIT;
 	param[1] = hostdata->host_param.tag_aging;
 
@@ -1646,47 +1697,47 @@
 		return 1;
 
 	loop_count = DEFAULT_LOOP_COUNT;
-	while (--loop_count && inw(host->io_port + HOST_HCCR) & 0x0080)
+	while (--loop_count && isp_inw(host, HOST_HCCR) & 0x0080)
 		barrier();
 	if (!loop_count)
 		printk("qlogicisp: mbox_command loop timeout #1\n");
 
 	switch(mbox_param[param[0]] >> 4) {
-	      case 6: outw(param[5], host->io_port + MBOX5);
-	      case 5: outw(param[4], host->io_port + MBOX4);
-	      case 4: outw(param[3], host->io_port + MBOX3);
-	      case 3: outw(param[2], host->io_port + MBOX2);
-	      case 2: outw(param[1], host->io_port + MBOX1);
-	      case 1: outw(param[0], host->io_port + MBOX0);
+	      case 6: isp_outw(param[5], host, MBOX5);
+	      case 5: isp_outw(param[4], host, MBOX4);
+	      case 4: isp_outw(param[3], host, MBOX3);
+	      case 3: isp_outw(param[2], host, MBOX2);
+	      case 2: isp_outw(param[1], host, MBOX1);
+	      case 1: isp_outw(param[0], host, MBOX0);
 	}
 
-	outw(0x0, host->io_port + PCI_SEMAPHORE);
-	outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
-	outw(HCCR_SET_HOST_INTR, host->io_port + HOST_HCCR);
+	isp_outw(0x0, host, PCI_SEMAPHORE);
+	isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);
+	isp_outw(HCCR_SET_HOST_INTR, host, HOST_HCCR);
 
 	loop_count = DEFAULT_LOOP_COUNT;
-	while (--loop_count && !(inw(host->io_port + PCI_INTF_STS) & 0x04))
+	while (--loop_count && !(isp_inw(host, PCI_INTF_STS) & 0x04))
 		barrier();
 	if (!loop_count)
 		printk("qlogicisp: mbox_command loop timeout #2\n");
 
 	loop_count = DEFAULT_LOOP_COUNT;
-	while (--loop_count && inw(host->io_port + MBOX0) == 0x04)
+	while (--loop_count && isp_inw(host, MBOX0) == 0x04)
 		barrier();
 	if (!loop_count)
 		printk("qlogicisp: mbox_command loop timeout #3\n");
 
 	switch(mbox_param[param[0]] & 0xf) {
-	      case 6: param[5] = inw(host->io_port + MBOX5);
-	      case 5: param[4] = inw(host->io_port + MBOX4);
-	      case 4: param[3] = inw(host->io_port + MBOX3);
-	      case 3: param[2] = inw(host->io_port + MBOX2);
-	      case 2: param[1] = inw(host->io_port + MBOX1);
-	      case 1: param[0] = inw(host->io_port + MBOX0);
+	      case 6: param[5] = isp_inw(host, MBOX5);
+	      case 5: param[4] = isp_inw(host, MBOX4);
+	      case 4: param[3] = isp_inw(host, MBOX3);
+	      case 3: param[2] = isp_inw(host, MBOX2);
+	      case 2: param[1] = isp_inw(host, MBOX1);
+	      case 1: param[0] = isp_inw(host, MBOX0);
 	}
 
-	outw(0x0, host->io_port + PCI_SEMAPHORE);
-	outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
+	isp_outw(0x0, host, PCI_SEMAPHORE);
+	isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR);
 
 	return 0;
 }
diff -u --recursive --new-file v2.3.29/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.3.29/linux/drivers/scsi/scsi.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/scsi/scsi.c	Sat Nov 27 15:27:48 1999
@@ -2049,7 +2049,7 @@
 	 * This makes /proc/scsi and /proc/scsi/scsi visible.
 	 */
 #ifdef CONFIG_PROC_FS
-	proc_scsi = create_proc_entry ("scsi", S_IFDIR, 0);
+	proc_scsi = proc_mkdir("scsi", 0);
 	if (!proc_scsi) {
 		printk (KERN_ERR "cannot init /proc/scsi\n");
 		return -ENOMEM;
@@ -3335,7 +3335,7 @@
 	 * This makes /proc/scsi and /proc/scsi/scsi visible.
 	 */
 #ifdef CONFIG_PROC_FS
-	proc_scsi = create_proc_entry ("scsi", S_IFDIR, 0);
+	proc_scsi = proc_mkdir("scsi", 0);
 	if (!proc_scsi) {
 		printk (KERN_ERR "cannot init /proc/scsi\n");
 		return -ENOMEM;
diff -u --recursive --new-file v2.3.29/linux/drivers/scsi/scsi_proc.c linux/drivers/scsi/scsi_proc.c
--- v2.3.29/linux/drivers/scsi/scsi_proc.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/scsi/scsi_proc.c	Sat Nov 27 15:27:48 1999
@@ -120,7 +120,7 @@
 	struct Scsi_Host *hpnt;
 	char name[10];	/* see scsi_unregister_host() */
 
-	tpnt->proc_dir = create_proc_entry(tpnt->proc_name, S_IFDIR, proc_scsi);
+	tpnt->proc_dir = proc_mkdir(tpnt->proc_name, proc_scsi);
 	tpnt->proc_dir->owner = tpnt->module;
 
 	hpnt = scsi_hostlist;
diff -u --recursive --new-file v2.3.29/linux/drivers/scsi/sd.c linux/drivers/scsi/sd.c
--- v2.3.29/linux/drivers/scsi/sd.c	Thu Nov 11 20:11:48 1999
+++ linux/drivers/scsi/sd.c	Sat Nov 27 15:27:48 1999
@@ -1247,7 +1247,7 @@
 			SCpnt->sense_buffer[2] = 0;
 
 			sd_wait_cmd (SCpnt, (void *) cmd, (void *) buffer,
-				512, sd_init_done,  SD_TIMEOUT, MAX_RETRIES);
+				0/*512*/, sd_init_done,  SD_TIMEOUT, MAX_RETRIES);
 
 			the_result = SCpnt->result;
 			retries++;
diff -u --recursive --new-file v2.3.29/linux/drivers/scsi/sym53c8xx.c linux/drivers/scsi/sym53c8xx.c
--- v2.3.29/linux/drivers/scsi/sym53c8xx.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/scsi/sym53c8xx.c	Sat Nov 27 16:27:44 1999
@@ -496,7 +496,7 @@
 
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)
 
-spinlock_t sym53c8xx_lock;
+spinlock_t sym53c8xx_lock = SPIN_LOCK_UNLOCKED;
 #define	NCR_LOCK_DRIVER(flags)     spin_lock_irqsave(&sym53c8xx_lock, flags)
 #define	NCR_UNLOCK_DRIVER(flags)   spin_unlock_irqrestore(&sym53c8xx_lock,flags)
 
diff -u --recursive --new-file v2.3.29/linux/drivers/scsi/u14-34f.c linux/drivers/scsi/u14-34f.c
--- v2.3.29/linux/drivers/scsi/u14-34f.c	Thu Nov 11 20:11:49 1999
+++ linux/drivers/scsi/u14-34f.c	Thu Dec  2 15:24:49 1999
@@ -691,10 +691,10 @@
    char *bus_type, dma_name[16];
 
    /* Allowed BIOS base addresses (NULL indicates reserved) */
-   void *bios_segment_table[8] = {
-      NULL,
-      (void *) 0xc4000, (void *) 0xc8000, (void *) 0xcc000, (void *) 0xd0000,
-      (void *) 0xd4000, (void *) 0xd8000, (void *) 0xdc000
+   unsigned long bios_segment_table[8] = {
+      0,
+      0xc4000, 0xc8000, 0xcc000, 0xd0000,
+      0xd4000, 0xd8000, 0xdc000
       };
 
    /* Allowed IRQs */
diff -u --recursive --new-file v2.3.29/linux/drivers/sound/Config.in linux/drivers/sound/Config.in
--- v2.3.29/linux/drivers/sound/Config.in	Mon Oct  4 15:49:30 1999
+++ linux/drivers/sound/Config.in	Fri Dec  3 10:55:09 1999
@@ -11,8 +11,11 @@
 
 dep_tristate '  C-Media PCI (CMI8338/8378)' CONFIG_SOUND_CMPCI $CONFIG_SOUND
 if [ "$CONFIG_SOUND_CMPCI" = "y" -o "$CONFIG_SOUND_CMPCI" = "m" ]; then
-   bool '    Enable legacy FM' CONFIG_SOUND_CMPCI_FM
-   bool '    Enable legacy MPU-401' CONFIG_SOUND_CMPCI_MIDI
+    bool '    Enable S/PDIF loop for CMI8738' CONFIG_SOUND_CMPCI_SPDIFLOOP
+    bool '    Enable 4 channel mode for CMI8738' CONFIG_SOUND_CMPCI_4CH
+    if [ "$CONFIG_SOUND_CMPCI_4CH" = "y" ]; then
+        bool '    Separate rear out jack' CONFIG_SOUND_CMPCI_REAR
+    fi
 fi
 dep_tristate '  Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND
 dep_tristate '  Creative Ensoniq AudioPCI 97 (ES1371)' CONFIG_SOUND_ES1371 $CONFIG_SOUND
@@ -24,6 +27,8 @@
 if [ "$CONFIG_VISWS" = "y" ]; then
     dep_tristate '  SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND
 fi
+
+dep_tristate '  Trident 4DWave-DX/NX' CONFIG_SOUND_TRIDENT $CONFIG_SOUND
 
 dep_tristate '  Support for Turtle Beach MultiSound Classic, Tahiti, Monterey' CONFIG_SOUND_MSNDCLAS $CONFIG_SOUND
 if [ "$CONFIG_SOUND_MSNDCLAS" = "y" -o "$CONFIG_SOUND_MSNDCLAS" = "m" ]; then
diff -u --recursive --new-file v2.3.29/linux/drivers/sound/Makefile linux/drivers/sound/Makefile
--- v2.3.29/linux/drivers/sound/Makefile	Mon Oct  4 15:49:30 1999
+++ linux/drivers/sound/Makefile	Fri Dec  3 10:55:09 1999
@@ -84,6 +84,7 @@
 obj-$(CONFIG_SOUND_ES1371)	+= es1371.o
 obj-$(CONFIG_SOUND_ESSSOLO1)	+= esssolo1.o
 obj-$(CONFIG_SOUND_MAESTRO)	+= maestro.o
+obj-$(CONFIG_SOUND_TRIDENT)	+= trident.o
 
 # Declare multi-part drivers.
 
diff -u --recursive --new-file v2.3.29/linux/drivers/sound/cmpci.c linux/drivers/sound/cmpci.c
--- v2.3.29/linux/drivers/sound/cmpci.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/sound/cmpci.c	Sat Nov 27 15:27:48 1999
@@ -21,7 +21,7 @@
  *      along with this program; if not, write to the Free Software
  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * Special thanks to David C. Niemi
+ * Special thanks to David C. Niemi, Jan Pfeifer
  *
  *
  * Module command line parameters:
@@ -59,8 +59,43 @@
  *                     read/write cannot be executed
  *    20 09 99   0.13  merged the generic changes in sonicvibes since this
  *		       diverged.
+ *    18.08.99   1.5   Only deallocate DMA buffer when unloading.
+ *    02.09.99   1.6   Enable SPDIF LOOP
+ *                     Change the mixer read back
+ *    21.09.99   2.33  Use RCS version aas driver version.
+ *                     Add support for modem, S/PDIF loop and 4 channels.
+ *                     (8738 only)
+ *                     Fix bug cause x11amp cannot play.
+ *    $Log: cmpci.c,v $
+ *    Revision 2.41  1999/10/27 02:00:05  cltien
+ *    Now the fragsize for modem is activated by parameter.
+ *
+ *    Revision 2.40  1999/10/26 23:38:26  cltien
+ *    Remove debugging message in cm_write which may cause module counter not 0.
+ *
+ *    Revision 2.39  1999/10/26 21:52:50  cltien
+ *    I forgor too adjust mic recording volume, as it should be moved to 5MUTEMONO.
+ *    Change the DYNAMIC macro to FIXEDDMA, which means static DMA buffer.
+ *
+ *    Revision 2.38  1999/10/08 21:59:03  cltien
+ *    Set FLINKON and reset FLINKOFF for modem.
+ *
+ *    Revision 2.37  1999/09/28 02:57:04  cltien
+ *    Add set_bus_master() to make sure bus master enabled.
+ *
+ *    Revision 2.36  1999/09/22 14:15:03  cltien
+ *    Use open_sem to avoid multiple access to open_mode.
+ *    Use wakeup in IntrClose to activate process in waiting queue.
+ *
+ *    Revision 2.35  1999/09/22 13:20:53  cltien
+ *    Use open_mode to check if DAC in used. Also more check in IntrWrite and IntrClose. Now the modem can access DAC safely.
+ *
+ *    Revision 2.34  1999/09/22 03:29:57  cltien
+ *    Use module count to decide which one to access the dac.
+ *
+ *
  */
-
+ 
 /*****************************************************************************/
       
 #include <linux/config.h>
@@ -252,6 +287,7 @@
 		unsigned fragsize;
 		unsigned dmasize;
 		unsigned fragsamples;
+		unsigned dmasamples;
 		/* OSS stuff */
 		unsigned mapped:1;
 		unsigned ready:1;
@@ -276,6 +312,7 @@
 /* --------------------------------------------------------------------- */
 
 static struct cm_state *devs = NULL;
+static struct cm_state *devaudio = NULL;
 static unsigned long wavetable_mem = 0;
 
 /* --------------------------------------------------------------------- */
@@ -331,7 +368,7 @@
 	outl(addr, s->iobase + CODEC_CMI_CH0_FRAME1);
 	outw(count, s->iobase + CODEC_CMI_CH0_FRAME2);
 	outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) & ~1, s->iobase + CODEC_CMI_FUNCTRL0);
-	outb(inb(s->iobase + CODEC_CMI_FUNCTRL0 + 2) | 1, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+//	outb(inb(s->iobase + CODEC_CMI_FUNCTRL0 + 2) | 1, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
 }
 
 static void set_dmaadc(struct cm_state *s, unsigned int addr, unsigned int count)
@@ -340,13 +377,16 @@
 	outl(addr, s->iobase + CODEC_CMI_CH1_FRAME1);
 	outw(count, s->iobase + CODEC_CMI_CH1_FRAME2);
 	outb(inb(s->iobase + CODEC_CMI_FUNCTRL0) | 2, s->iobase + CODEC_CMI_FUNCTRL0);
-	outb(inb(s->iobase + CODEC_CMI_FUNCTRL0 + 2) | 2, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+//	outb(inb(s->iobase + CODEC_CMI_FUNCTRL0 + 2) | 2, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
 }
 
 extern __inline__ unsigned get_dmadac(struct cm_state *s)
 {
 	unsigned int curr_addr;
 
+	if (!s->dma_dac.dmasize || !(s->enable & CM_CENABLE_PE))
+		return 0;
+
 	curr_addr = inl(s->iobase + CODEC_CMI_CH0_FRAME1);
 	curr_addr -= virt_to_bus(s->dma_dac.rawbuf);
 	curr_addr = s->dma_dac.dmasize - curr_addr;
@@ -358,6 +398,9 @@
 {
 	unsigned int curr_addr;
 
+	if (!s->dma_adc.dmasize || !(s->enable & CM_CENABLE_RE))
+		return 0;
+
 	curr_addr = inl(s->iobase + CODEC_CMI_CH1_FRAME1);
 	curr_addr -= virt_to_bus(s->dma_adc.rawbuf);
 	curr_addr = s->dma_adc.dmasize - curr_addr;
@@ -421,7 +464,7 @@
 	{ 22050,	(16000 + 22050) / 2,	(22050 + 32000) / 2,	2 },
 	{ 32000,	(22050 + 32000) / 2,	(32000 + 44100) / 2,	6 },
 	{ 44100,	(32000 + 44100) / 2,	(44100 + 48000) / 2,	3 },
-	{ 48000,	48000,			48000,			7 }
+	{ 48000,	(44100 + 48000) /2,	48000,			7 }
 };
 
 static void set_dac_rate(struct cm_state *s, unsigned rate)
@@ -485,10 +528,12 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&s->lock, flags);
+	/* disable channel */
+	outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
 	s->enable &= ~CM_CENABLE_RE;
 	/* disable interrupt */
 	outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) & ~2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-	/* disable channel and reset */
+	/* reset */
 	outb(s->enable | CM_CH1_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
 	udelay(10);
 	outb(s->enable & ~CM_CH1_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
@@ -500,10 +545,12 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&s->lock, flags);
+	/* disable channel */
 	s->enable &= ~CM_CENABLE_PE;
+	outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
 	/* disable interrupt */
 	outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) & ~1, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-	/* disable channel and reset */
+	/* reset */
 	outb(s->enable | CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
 	udelay(10);
 	outb(s->enable & ~CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
@@ -516,10 +563,10 @@
 
 	spin_lock_irqsave(&s->lock, flags);
 	if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
+		outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) | 1, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
 		s->enable |= CM_CENABLE_PE;
 		outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
 	}
-	outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) | 1, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
 	spin_unlock_irqrestore(&s->lock, flags);
 }	
 
@@ -530,10 +577,10 @@
 	spin_lock_irqsave(&s->lock, flags);
 	if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
 	    && s->dma_adc.ready) {
+		outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) | 2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
 		s->enable |= CM_CENABLE_RE;
 		outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
 	}
-	outb(inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2) | 2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
 	spin_unlock_irqrestore(&s->lock, flags);
 }	
 
@@ -593,10 +640,10 @@
 			return -ENOMEM;
 		db->buforder = order;
 		if ((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff)
-			printk(KERN_DEBUG "cm: DMA buffer crosses 64k boundary: busaddr 0x%lx  size %ld\n", 
+			printk(KERN_DEBUG "cmpci: DMA buffer crosses 64k boundary: busaddr 0x%lx  size %ld\n", 
 			       virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
 		if ((virt_to_bus(db->rawbuf) + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff)
-			printk(KERN_DEBUG "cm: DMA buffer beyond 16MB: busaddr 0x%lx  size %ld\n", 
+			printk(KERN_DEBUG "cmpci: DMA buffer beyond 16MB: busaddr 0x%lx  size %ld\n", 
 			       virt_to_bus(db->rawbuf), PAGE_SIZE << db->buforder);
 		/* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
 		mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
@@ -623,17 +670,21 @@
 	db->fragsize = 1 << db->fragshift;
 	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
 		db->numfrag = db->ossmaxfrags;
-#if 1
-	/* to make fragsize >= 4096 */
-	while (db->fragsize < 4096 && db->numfrag >= 4)
-	{
-		db->fragsize *= 2;
-		db->fragshift++;
-		db->numfrag /= 2;
+ 	/* to make fragsize >= 4096 */
+#if 0 	
+ 	if(s->modem)
+ 	{
+	 	while (db->fragsize < 4096 && db->numfrag >= 4)
+		{
+			db->fragsize *= 2;
+ 			db->fragshift++;
+ 			db->numfrag /= 2;
+ 		}
 	}
-#endif
+#endif	
 	db->fragsamples = db->fragsize >> sample_shift[fmt];
 	db->dmasize = db->numfrag << db->fragshift;
+	db->dmasamples = db->dmasize >> sample_shift[fmt];
 	memset(db->rawbuf, (fmt & CM_CFMT_16BIT) ? 0 : 0x80, db->dmasize);
 	spin_lock_irqsave(&s->lock, flags);
 	if (rec) {
@@ -665,6 +716,7 @@
 		len -= x;
 	}
 	memset(buf + bptr, c, len);
+	outb(s->enable, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
 }
 
 /* call with spinlock held! */
@@ -752,25 +804,26 @@
 	unsigned int intsrc, intstat;
 	
 	/* fastpath out, to ease interrupt sharing */
-	intsrc = inb(s->iobase + CODEC_CMI_INT_STATUS);
-	if (!(intsrc & (CM_INT_CH0 | CM_INT_CH1)))
+	intsrc = inl(s->iobase + CODEC_CMI_INT_STATUS);
+	if (!(intsrc & 0x80000000))
 		return;
 	spin_lock(&s->lock);
 	intstat = inb(s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-	/* disable interrupt */
+	/* acknowledge interrupt */
 	if (intsrc & CM_INT_CH0)
+	{
 		outb(intstat & ~1, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
+		udelay(10);
+		outb(intstat | 1, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
+	}
 	if (intsrc & CM_INT_CH1)
+	{
 		outb(intstat & ~2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
+		udelay(10);
+		outb(intstat | 2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
+	}
 	cm_update_ptr(s);
-#ifdef SOUND_CONFIG_CMPCI_MIDI
 	cm_handle_midi(s);
-#endif
-	/* enable interrupt */
-	if (intsrc & CM_INT_CH0)
-		outb(intstat | 1, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
-	if (intsrc & CM_INT_CH1)
-		outb(intstat | 2, s->iobase + CODEC_CMI_INT_HLDCLR + 2);
 	spin_unlock(&s->lock);
 }
 
@@ -788,7 +841,7 @@
 
 /* --------------------------------------------------------------------- */
 
-static const char invalid_magic[] = KERN_CRIT "cm: invalid magic value\n";
+static const char invalid_magic[] = KERN_CRIT "cmpci: invalid magic value\n";
 
 #ifdef CONFIG_SOUND_CMPCI	/* support multiple chips */
 #define VALIDATE_STATE(s)
@@ -808,6 +861,7 @@
 #define MT_5MUTE      2
 #define MT_4MUTEMONO  3
 #define MT_6MUTE      4
+#define MT_5MUTEMONO  5
 
 static const struct {
 	unsigned left;
@@ -818,7 +872,7 @@
 } mixtable[SOUND_MIXER_NRDEVICES] = {
 	[SOUND_MIXER_CD]     = { DSP_MIX_CDVOLIDX_L,     DSP_MIX_CDVOLIDX_R,     MT_5MUTE,     0x04, 0x02 },
 	[SOUND_MIXER_LINE]   = { DSP_MIX_LINEVOLIDX_L,   DSP_MIX_LINEVOLIDX_R,   MT_5MUTE,     0x10, 0x08 },
-	[SOUND_MIXER_MIC]    = { DSP_MIX_MICVOLIDX,      CODEC_CMI_MIXER2,       MT_4MUTEMONO, 0x01, 0x01 },
+	[SOUND_MIXER_MIC]    = { DSP_MIX_MICVOLIDX,      DSP_MIX_MICVOLIDX,      MT_5MUTEMONO, 0x01, 0x01 },
 	[SOUND_MIXER_SYNTH]  = { DSP_MIX_FMVOLIDX_L,  	 DSP_MIX_FMVOLIDX_R,     MT_5MUTE,     0x40, 0x00 },
 	[SOUND_MIXER_VOLUME] = { DSP_MIX_MASTERVOLIDX_L, DSP_MIX_MASTERVOLIDX_R, MT_5MUTE,     0x00, 0x00 },
 	[SOUND_MIXER_PCM]    = { DSP_MIX_VOICEVOLIDX_L,  DSP_MIX_VOICEVOLIDX_R,  MT_5MUTE,     0x00, 0x00 }
@@ -851,10 +905,16 @@
 		r = l;
 		break;
 
+	case MT_5MUTEMONO:
+		r = l;
+		rl = 100 - 3 * ((l >> 3) & 31);
+		rr = rl;
+		break;
+				
 	case MT_5MUTE:
 	default:
-		rl = 100 - 3 * (l & 31);
-		rr = 100 - 3 * (r & 31);
+		rl = 100 - 3 * ((l >> 3) & 31);
+		rr = 100 - 3 * ((r >> 3) & 31);
 		break;
 				
 	case MT_6MUTE:
@@ -992,7 +1052,7 @@
 		}
 		spin_lock_irqsave(&s->lock, flags);
 		wrmixer(s, DSP_MIX_ADCMIXIDX_L, j);
-		wrmixer(s, DSP_MIX_ADCMIXIDX_R, (j & 1) | j>>1);
+		wrmixer(s, DSP_MIX_ADCMIXIDX_R, (j & 1) | (j>>1));
 		spin_unlock_irqrestore(&s->lock, flags);
 		return 0;
 
@@ -1041,6 +1101,14 @@
 			outb((inb(s->iobase + CODEC_CMI_MIXER2) & ~0x0e) | rr<<1, s->iobase + CODEC_CMI_MIXER2);
 			break;
 			
+		case MT_5MUTEMONO:
+			r = l;
+			rl = l < 4 ? 0 : (l - 5) / 3;
+			rr = rl >> 2;
+ 			wrmixer(s, mixtable[i].left, rl<<3);
+			outb((inb(s->iobase + CODEC_CMI_MIXER2) & ~0x0e) | rr<<1, s->iobase + CODEC_CMI_MIXER2);
+			break;
+				
 		case MT_5MUTE:
 			rl = l < 4 ? 0 : (l - 5) / 3;
 			rr = r < 4 ? 0 : (r - 5) / 3;
@@ -1154,10 +1222,10 @@
                         current->state = TASK_RUNNING;
                         return -EBUSY;
                 }
-		tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
+		tmo = (count * HZ) / s->ratedac;
 		tmo >>= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
-		if (!schedule_timeout(tmo + 1))
-			printk(KERN_DEBUG "cm: dma timed out??\n");
+		if (!schedule_timeout(tmo ? : 1) && tmo)
+			printk(KERN_DEBUG "cmpci: dma timed out??\n");
         }
         remove_wait_queue(&s->dma_dac.wait, &wait);
         current->state = TASK_RUNNING;
@@ -1204,7 +1272,18 @@
 			start_adc(s);
 			if (file->f_flags & O_NONBLOCK)
 				return ret ? ret : -EAGAIN;
-			interruptible_sleep_on(&s->dma_adc.wait);
+			if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
+				printk(KERN_DEBUG "cmpci: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+				       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count,
+				       s->dma_adc.hwptr, s->dma_adc.swptr);
+				stop_adc(s);
+				spin_lock_irqsave(&s->lock, flags);
+				set_dmaadc(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.dmasamples);
+				/* program sample counts */
+				outw(s->dma_adc.fragsamples-1, s->iobase + CODEC_CMI_CH1_FRAME2 + 2);
+				s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
+				spin_unlock_irqrestore(&s->lock, flags);
+			}
 			if (signal_pending(current))
 				return ret ? ret : -ERESTARTSYS;
 			continue;
@@ -1264,7 +1343,18 @@
 			start_dac(s);
 			if (file->f_flags & O_NONBLOCK)
 				return ret ? ret : -EAGAIN;
-			interruptible_sleep_on(&s->dma_dac.wait);
+			if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
+				printk(KERN_DEBUG "cmpci: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+				       s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
+				       s->dma_dac.hwptr, s->dma_dac.swptr);
+				stop_dac(s);
+				spin_lock_irqsave(&s->lock, flags);
+				set_dmadac(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.dmasamples);
+				/* program sample counts */
+				outw(s->dma_dac.fragsamples-1, s->iobase + CODEC_CMI_CH0_FRAME2 + 2);
+				s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
+				spin_unlock_irqrestore(&s->lock, flags);
+			}
 			if (signal_pending(current))
 				return ret ? ret : -ERESTARTSYS;
 			continue;
@@ -1730,7 +1820,6 @@
 	NULL,  /* lock */
 };
 
-#ifdef CONFIG_SOUND_CMPCI_MIDI
 /* --------------------------------------------------------------------- */
 
 static ssize_t cm_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
@@ -1971,7 +2060,7 @@
 			}
 			tmo = (count * HZ) / 3100;
 			if (!schedule_timeout(tmo ? : 1) && tmo)
-				printk(KERN_DEBUG "cm: midi timed out??\n");
+				printk(KERN_DEBUG "cmpci: midi timed out??\n");
 		}
 		remove_wait_queue(&s->midi.owait, &wait);
 		set_current_state(TASK_RUNNING);
@@ -2011,11 +2100,9 @@
 	NULL,  /* revalidate */
 	NULL,  /* lock */
 };
-#endif
 
 /* --------------------------------------------------------------------- */
 
-#ifdef CONFIG_SOUND_CMPCI_FM
 static int cm_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	static const unsigned char op_offset[18] = {
@@ -2187,7 +2274,6 @@
 	NULL,  /* revalidate */
 	NULL,  /* lock */
 };
-#endif /* CONFIG_SOUND_CMPCI_FM */
 
 /* --------------------------------------------------------------------- */
 
@@ -2215,8 +2301,31 @@
 };
 
 #ifdef MODULE
-int __init init_module(void)
+static int	spdif_loop = 0;
+static int	four_ch = 0;
+static int	rear_out = 0;
+MODULE_PARM(spdif_loop, "i");
+MODULE_PARM(four_ch, "i");
+MODULE_PARM(rear_out, "i");
+
+int  __init init_module(void)
+#else
+#ifdef CONFIG_SOUND_CMPCI_SPDIFLOOP
+static int	spdif_loop = 1;
 #else
+static int	spdif_loop = 0;
+#endif
+#ifdef CONFIG_SOUND_CMPCI_4CH
+static int	four_ch = 1;
+#else
+static int	four_ch = 0;
+#endif
+#ifdef CONFIG_SOUND_CMPCI_REAR
+static int	rear_out = 1;
+#else
+static int	read_out = 0;
+#endif
+
 int __init init_cmpci(void)
 #endif
 {
@@ -2224,6 +2333,7 @@
 	struct pci_dev *pcidev = NULL;
 	mm_segment_t fs;
 	int i, val, index = 0;
+	
 	struct {
 		unsigned short	deviceid;
 		char		*devicename;
@@ -2239,10 +2349,10 @@
 	if (!pci_present())   /* No PCI bus in this machine! */
 #endif
 		return -ENODEV;
-	printk(KERN_INFO "cm: version v1.1 time " __TIME__ " " __DATE__ "\n");
+	printk(KERN_INFO "cmpci: version v2.41-nomodem time " __TIME__ " " __DATE__ "\n");
 #if 0
 	if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
-		printk(KERN_INFO "cm: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
+		printk(KERN_INFO "cmpci: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
 #endif
 	while (index < NR_DEVICE && pcidev == NULL && (
  	       (pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, pcidev)) ||
@@ -2251,7 +2361,7 @@
 		if (pcidev->irq == 0)
 			continue;
 		if (!(s = kmalloc(sizeof(struct cm_state), GFP_KERNEL))) {
-			printk(KERN_WARNING "cm: out of memory\n");
+			printk(KERN_WARNING "cmpci: out of memory\n");
 			continue;
 		}
 		/* search device name */
@@ -2272,65 +2382,60 @@
 		init_MUTEX(&s->open_sem);
 		s->magic = CM_MAGIC;
 		s->iobase = pcidev->resource[0].start;
-#ifdef CONFIG_SOUND_CMPCI_FM
 		s->iosynth = 0x388;
-#endif
-#ifdef CONFIG_SOUND_CMPCI_MIDI
 		s->iomidi = 0x330;
-#endif
 		if (s->iobase == 0)
 			continue;
 		s->irq = pcidev->irq;
 
 		if (check_region(s->iobase, CM_EXTENT_CODEC)) {
-			printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
+			printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
 			goto err_region5;
 		}
 		request_region(s->iobase, CM_EXTENT_CODEC, "cmpci");
-#ifdef CONFIG_SOUND_CMPCI_MIDI
 		if (check_region(s->iomidi, CM_EXTENT_MIDI)) {
-			printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
-			goto err_region4;
+			printk(KERN_WARNING "cmpci: io ports %#x-%#x in use, midi disabled.\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
+			s->iomidi = 0;
+		}
+		else
+		{
+			request_region(s->iomidi, CM_EXTENT_MIDI, "cmpci Midi");
+			/* set IO based at 0x330 */
+			outb(inb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3) & ~0x60, s->iobase + CODEC_CMI_LEGACY_CTRL + 3);
 		}
-		request_region(s->iomidi, CM_EXTENT_MIDI, "cmpci Midi");
-		/* set IO based at 0x330 */
-		outb(inb(s->iobase + CODEC_CMI_LEGACY_CTRL + 3) & ~0x60, s->iobase + CODEC_CMI_LEGACY_CTRL + 3);
-#endif
-#ifdef CONFIG_SOUND_CMPCI_FM
 		if (check_region(s->iosynth, CM_EXTENT_SYNTH)) {
-			printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
-			goto err_region1;
+			printk(KERN_WARNING "cmpci: io ports %#x-%#x in use, synth disabled.\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
+			s->iosynth = 0;
+		}
+		else
+		{
+			request_region(s->iosynth, CM_EXTENT_SYNTH, "cmpci FM");
+			/* enable FM */
+			outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 2) | 8, s->iobase + CODEC_CMI_MISC_CTRL);
 		}
-		request_region(s->iosynth, CM_EXTENT_SYNTH, "cmpci FM");
-		/* enable FM */
-		outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 2) | 8, s->iobase + CODEC_CMI_MISC_CTRL);
-#endif
 		/* initialize codec registers */
 		outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2);  /* disable ints */
-		outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* reset channels */
+		outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
 		/* reset mixer */
 		wrmixer(s, DSP_MIX_DATARESETIDX, 0);
 
 		/* request irq */
 		if (request_irq(s->irq, cm_interrupt, SA_SHIRQ, "cmpci", s)) {
-			printk(KERN_ERR "cm: irq %u in use\n", s->irq);
+			printk(KERN_ERR "cmpci: irq %u in use\n", s->irq);
 			goto err_irq;
 		}
-		printk(KERN_INFO "cm: found %s adapter at io %#06x irq %u\n",
+		printk(KERN_INFO "cmpci: found %s adapter at io %#06x irq %u\n",
 		       devicename, s->iobase, s->irq);
 		/* register devices */
 		if ((s->dev_audio = register_sound_dsp(&cm_audio_fops, -1)) < 0)
 			goto err_dev1;
 		if ((s->dev_mixer = register_sound_mixer(&cm_mixer_fops, -1)) < 0)
 			goto err_dev2;
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-		if ((s->dev_midi = register_sound_midi(&cm_midi_fops, -1)) < 0)
+		if (s->iomidi && (s->dev_midi = register_sound_midi(&cm_midi_fops, -1)) < 0)
 			goto err_dev3;
-#endif
-#ifdef CONFIG_SOUND_CMPCI_FM
-		if ((s->dev_dmfm = register_sound_special(&cm_dmfm_fops, 15 /* ?? */)) < 0)
+		if (s->iosynth && (s->dev_dmfm = register_sound_special(&cm_dmfm_fops, 15 /* ?? */)) < 0)
 			goto err_dev4;
-#endif
+		pci_set_master(pcidev);
 		/* initialize the chips */
 		fs = get_fs();
 		set_fs(KERNEL_DS);
@@ -2344,6 +2449,38 @@
 			mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
 		}
 		set_fs(fs);
+		if (pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738)
+		{
+			/* enable SPDIF loop */
+			if (spdif_loop)
+			{
+				/* turn on spdif-in to spdif-out */
+				outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) | 0x80, s->iobase + CODEC_CMI_FUNCTRL1);
+				printk(KERN_INFO "cmpci: Enable SPDIF loop\n");
+			}
+			else
+				outb(inb(s->iobase + CODEC_CMI_FUNCTRL1) & ~0x80, s->iobase + CODEC_CMI_FUNCTRL1);
+			/* enable 4 channels mode */
+			if (four_ch)
+			{
+				/* 4 channel mode (analog duplicate) */
+				outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 3) | 0x04, s->iobase + CODEC_CMI_MISC_CTRL + 3);
+				printk(KERN_INFO "cmpci: Enable 4 channels mode\n");
+				/* has separate rear-out jack ? */
+				if (rear_out)
+				{
+					/* has separate rear out jack */
+					outb(inb(s->iobase + CODEC_CMI_MIXER1) & ~0x20, s->iobase + CODEC_CMI_MIXER1);
+				}
+				else
+				{
+					outb(inb(s->iobase + CODEC_CMI_MIXER1) | 0x20, s->iobase + CODEC_CMI_MIXER1);
+					printk(KERN_INFO "cmpci: line-in routed as rear-out\n");
+				}
+			}
+			else
+				outb(inb(s->iobase + CODEC_CMI_MISC_CTRL + 3) & ~0x04, s->iobase + CODEC_CMI_MISC_CTRL + 3);
+		}
 		/* queue it for later freeing */
 		s->next = devs;
 		devs = s;
@@ -2357,16 +2494,14 @@
 	err_dev2:
 		unregister_sound_dsp(s->dev_audio);
 	err_dev1:
-		printk(KERN_ERR "cm: cannot register misc device\n");
+		printk(KERN_ERR "cmpci: cannot register misc device\n");
 		free_irq(s->irq, s);
 	err_irq:
-#ifdef CONFIG_SOUND_CMPCI_FM
-		release_region(s->iosynth, CM_EXTENT_SYNTH);
+		if(s->iosynth)
+			release_region(s->iosynth, CM_EXTENT_SYNTH);
 	err_region1:
-#endif
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-		release_region(s->iomidi, CM_EXTENT_MIDI);
-#endif
+		if(s->iomidi)
+			release_region(s->iomidi, CM_EXTENT_MIDI);
 	err_region4:
 		release_region(s->iobase, CM_EXTENT_CODEC);
 	err_region5:
@@ -2395,32 +2530,30 @@
 		devs = devs->next;
 		outb(0, s->iobase + CODEC_CMI_INT_HLDCLR + 2);  /* disable ints */
 		synchronize_irq();
-		outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* reset channels */
+		outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
 		free_irq(s->irq, s);
 
 		/* reset mixer */
 		wrmixer(s, DSP_MIX_DATARESETIDX, 0);
 
 		release_region(s->iobase, CM_EXTENT_CODEC);
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-		release_region(s->iomidi, CM_EXTENT_MIDI);
-#endif
-#ifdef CONFIG_SOUND_CMPCI_FM
-		release_region(s->iosynth, CM_EXTENT_SYNTH);
-#endif
+		if(s->iomidi)
+		{
+			release_region(s->iomidi, CM_EXTENT_MIDI);
+			unregister_sound_midi(s->dev_midi);
+		}
+		if(s->iosynth)
+		{
+			release_region(s->iosynth, CM_EXTENT_SYNTH);
+			unregister_sound_special(s->dev_dmfm);
+		}
 		unregister_sound_dsp(s->dev_audio);
 		unregister_sound_mixer(s->dev_mixer);
-#ifdef CONFIG_SOUND_CMPCI_MIDI
-		unregister_sound_midi(s->dev_midi);
-#endif
-#ifdef CONFIG_SOUND_CMPCI_FM
-		unregister_sound_special(s->dev_dmfm);
-#endif
 		kfree_s(s, sizeof(struct cm_state));
 	}
 	if (wavetable_mem)
 		free_pages(wavetable_mem, 20-PAGE_SHIFT);
-	printk(KERN_INFO "cm: unloading\n");
+	printk(KERN_INFO "cmpci: unloading\n");
 }
 
 #endif /* MODULE */
diff -u --recursive --new-file v2.3.29/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c
--- v2.3.29/linux/drivers/sound/es1371.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/sound/es1371.c	Sat Nov 27 15:27:48 1999
@@ -3101,9 +3101,7 @@
 		goto err_dev4;
 #ifdef ES1371_DEBUG
 	/* intialize the debug proc device */
-	s->ps = create_proc_entry("es1371", S_IFREG | S_IRUGO, NULL);
-	if (s->ps)
-		s->ps->read_proc = proc_es1371_dump;
+	s->ps = create_proc_read_entry("es1371",0,NULL,proc_es1371_dump,NULL);
 #endif /* ES1371_DEBUG */
 	
 	/* initialize codec registers */
diff -u --recursive --new-file v2.3.29/linux/drivers/sound/sb_card.c linux/drivers/sound/sb_card.c
--- v2.3.29/linux/drivers/sound/sb_card.c	Thu Nov 11 20:11:49 1999
+++ linux/drivers/sound/sb_card.c	Sat Nov 27 15:46:24 1999
@@ -11,13 +11,18 @@
  * for more info.
  */
 
+/* 26th Novemner 1999 - patched to compile without ISA PnP support in the
+   kernel. -Daniel Stone (tamriel@ductape.net) */
+
 #include <linux/config.h>
 #ifdef CONFIG_MCA
 #include <linux/mca.h>
 #endif
 #include <linux/module.h>
 #include <linux/init.h>
+#ifdef CONFIG_ISAPNP		/* Patched so it will compile withOUT ISA PnP */
 #include <linux/isapnp.h>
+#endif
 
 #include "sound_config.h"
 #include "soundmodule.h"
@@ -140,7 +145,11 @@
 int support = 0;	/* Set support to load this as a support module */
 int sm_games = 0;	/* Mixer - see sb_mixer.c */
 int acer = 0;		/* Do acer notebook init */
+#ifdef CONFIG_ISAPNP
+int isapnp = 1;
+#else
 int isapnp = 0;
+#endif
 
 MODULE_PARM(io, "i");
 MODULE_PARM(irq, "i");
@@ -154,10 +163,13 @@
 MODULE_PARM(pas2, "i");
 MODULE_PARM(sm_games, "i");
 MODULE_PARM(esstype, "i");
+#ifdef CONFIG_ISAPNP
 MODULE_PARM(isapnp, "i");
+#endif
 
 void *smw_free = NULL;
 
+#ifdef CONFIG_ISAPNP
 static struct { unsigned short vendor, function; char *name; }
 isapnp_sb_list[] __initdata = {
 	{ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0001), "Sound Blaster 16" },
@@ -212,6 +224,7 @@
 	}
 	return -ENODEV;
 }
+#endif
 
 int init_module(void)
 {
@@ -219,43 +232,39 @@
 
 	if (mad16 == 0 && trix == 0 && pas2 == 0 && support == 0)
 	{
-		if (isapnp == 1)
-		{
-			if (sb_probe_isapnp(&config, &config_mpu)<0)
-			{
-				printk(KERN_ERR "sb_card: No ISAPnP cards found\n");
-				return -EINVAL;
-			}
-		} 
-		else 
+#ifdef CONFIG_ISAPNP			
+		if (sb_probe_isapnp(&config, &config_mpu)<0)
 		{
-			if (io == -1 || dma == -1 || irq == -1)
-			{
-				printk(KERN_ERR "sb_card: I/O, IRQ, and DMA are mandatory\n");
-				return -EINVAL;
-			}
-			config.io_base = io;
-			config.irq = irq;
-			config.dma = dma;
-			config.dma2 = dma16;
+			printk(KERN_ERR "sb_card: No ISAPnP cards found\n");
+			return -EINVAL;
 		}
-		config.card_subtype = type;
-
-		if (!probe_sb(&config))
-			return -ENODEV;
-		attach_sb_card(&config);
-		
-		if(config.slots[0]==-1)
-			return -ENODEV;
-#ifdef CONFIG_MIDI
-		if (isapnp == 0) 
-		  config_mpu.io_base = mpu_io;
-		if (probe_sbmpu(&config_mpu))
-			sbmpu = 1;
-		if (sbmpu)
-			attach_sbmpu(&config_mpu);
 #endif
+	} 
+	if (io == -1 || dma == -1 || irq == -1)
+	{
+		printk(KERN_ERR "sb_card: I/O, IRQ, and DMA are mandatory\n");
+		return -EINVAL;
 	}
+	config.io_base = io;
+	config.irq = irq;
+	config.dma = dma;
+	config.dma2 = dma16;
+	config.card_subtype = type;
+
+	if (!probe_sb(&config))
+		return -ENODEV;
+	attach_sb_card(&config);
+	
+	if(config.slots[0]==-1)
+		return -ENODEV;
+#ifdef CONFIG_MIDI
+	if (isapnp == 0) 
+	  config_mpu.io_base = mpu_io;
+	if (probe_sbmpu(&config_mpu))
+		sbmpu = 1;
+	if (sbmpu)
+		attach_sbmpu(&config_mpu);
+#endif
 	SOUND_LOCK;
 	return 0;
 }
diff -u --recursive --new-file v2.3.29/linux/drivers/sound/sonicvibes.c linux/drivers/sound/sonicvibes.c
--- v2.3.29/linux/drivers/sound/sonicvibes.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/sound/sonicvibes.c	Thu Dec  2 15:15:34 1999
@@ -82,6 +82,7 @@
  *    03.09.99   0.21  change read semantics for MIDI to match
  *                     OSS more closely; remove possible wakeup race
  *    28.10.99   0.22  More waitqueue races fixed
+ *    01.12.99   0.23  New argument to allocate_resource
  *
  */
 
@@ -2433,7 +2434,7 @@
 
 	if (!pci_present())   /* No PCI bus in this machine! */
 		return -ENODEV;
-	printk(KERN_INFO "sv: version v0.22 time " __TIME__ " " __DATE__ "\n");
+	printk(KERN_INFO "sv: version v0.23 time " __TIME__ " " __DATE__ "\n");
 #if 0
 	if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
 		printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
@@ -2457,7 +2458,7 @@
 			memcpy(ddmaname, sv_ddma_name, ddmanamelen);
 			pcidev->resource[RESOURCE_DDMA].name = ddmaname;
 			if (allocate_resource(&ioport_resource, pcidev->resource+RESOURCE_DDMA, 
-					      2*SV_EXTENT_DMA, 0x1000, 0x10000-2*SV_EXTENT_DMA, 1024)) {
+					      2*SV_EXTENT_DMA, 0x1000, 0x10000-2*SV_EXTENT_DMA, 1024, pcidev)) {
 				pcidev->resource[RESOURCE_DDMA].name = NULL;
 				kfree(ddmaname);
 				printk(KERN_ERR "sv: cannot allocate DDMA controller io ports\n");
diff -u --recursive --new-file v2.3.29/linux/drivers/sound/trident.c linux/drivers/sound/trident.c
--- v2.3.29/linux/drivers/sound/trident.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/trident.c	Mon Dec  6 16:25:05 1999
@@ -0,0 +1,3042 @@
+/*****************************************************************************
+ *
+ *      Trident 4D-Wave OSS driver for Linux 2.2.x
+ *
+ *	Driver: Alan Cox <alan@redhat.com>
+ *
+ *  Built from:
+ *  	Low level code: <audio@tridentmicro.com> from ALSA
+ *  	Framework: Thomas Sailer <sailer@ife.ee.ethz.ch>
+ *  	Extended by: Zach Brown <zab@redhat.com>  
+ *
+ *	Hacked up by:
+ *	  Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ *
+ *      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/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/malloc.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/spinlock.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+
+#ifdef CONFIG_APM
+#include <linux/apm_bios.h>
+#endif
+
+#include "trident.h"
+#include "ac97.h"
+
+/* --------------------------------------------------------------------- */
+
+#define M_DEBUG 1
+
+#ifdef M_DEBUG
+static int debug=0;
+#define M_printk(args...) {if (debug) printk(args);}
+#else
+#define M_printk(x)
+#endif
+
+/* --------------------------------------------------------------------- */
+#define DRIVER_VERSION "0.01"
+
+#define TRIDENT_FMT_STEREO	0x01
+#define TRIDENT_FMT_16BIT	0x02
+#define TRIDENT_FMT_MASK	0x03
+#define TRIDENT_DAC_SHIFT	0   
+#define TRIDENT_ADC_SHIFT	4
+
+#define TRIDENT_ENABLE_PE	1
+#define TRIDENT_ENABLE_RE	2
+
+
+#define TRIDENT_CARD_MAGIC	0x5072696E
+#define TRIDENT_STATE_MAGIC	0x63657373
+
+#define DAC_RUNNING		1
+#define ADC_RUNNING		2
+
+#define NR_DSPS		8
+
+#define SND_DEV_DSP16   5 
+
+static const unsigned sample_size[] = { 1, 2, 2, 4 };
+static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+
+enum card_types_t {
+	TYPE_4DWAVE_DX,
+	TYPE_4DWAVE_NX
+};
+
+static const char *card_names[]={
+	[TYPE_4DWAVE_DX] = "Trident 4DWave DX",
+	[TYPE_4DWAVE_NX] = "Trident 4DWave NX",
+};
+
+
+typedef struct tChannelControl
+{
+    // register data
+    unsigned int *  lpChStart;
+    unsigned int *  lpChStop;
+    unsigned int *  lpChAint;
+    unsigned int *  lpChAinten;
+
+    // register addresses
+    unsigned int *  lpAChStart;
+    unsigned int *  lpAChStop;
+    unsigned int *  lpAChAint;
+    unsigned int *  lpAChAinten;
+    
+    unsigned int data[16];
+
+} CHANNELCONTROL;
+
+/* --------------------------------------------------------------------- */
+
+struct trident_state {
+	unsigned int magic;
+	int channel;
+	struct trident_card *card;	/* Card info */
+	/* wave stuff */
+	unsigned int rateadc, ratedac;
+	unsigned char fmt, enable;
+
+	struct semaphore open_sem;
+	mode_t open_mode;
+	wait_queue_head_t open_wait;
+
+	/* soundcore stuff */
+	int dev_audio;
+
+	struct dmabuf {
+		void *rawbuf;
+		unsigned buforder;
+		unsigned numfrag;
+		unsigned fragshift;
+		int chan[2];	/* Hardware channel */
+		/* XXX zab - swptr only in here so that it can be referenced by
+			clear_advance, as far as I can tell :( */
+		unsigned hwptr, swptr;
+		unsigned total_bytes;
+		int count;
+		unsigned error; /* over/underrun */
+		wait_queue_head_t wait;
+		/* redundant, but makes calculations easier */
+		unsigned fragsize;
+		unsigned dmasize;
+		unsigned fragsamples;
+		/* OSS stuff */
+		unsigned mapped:1;
+		unsigned ready:1;
+		unsigned endcleared:1;
+		unsigned ossfragshift;
+		int ossmaxfrags;
+		unsigned subdivision;
+		u16 base;		/* Offset for ptr */
+	} dma_dac, dma_adc;
+	
+	u8 bDMAStart;
+
+};
+	
+struct trident_card {
+	unsigned int magic;
+
+	/* We keep trident cards in a linked list */
+	struct trident_card *next;
+
+	/* The trident has a certain amount of cross channel interaction
+	   so we use a single per card lock */
+	   
+	spinlock_t lock;
+
+	int dev_mixer;
+
+	int card_type;
+
+	/* as most of this is static,
+		perhaps it should be a pointer to a global struct */
+	struct mixer_goo {
+		int modcnt;
+		int supported_mixers;
+		int stereo_mixers;
+		int record_sources;
+		/* the caller must guarantee arg sanity before calling these */
+/*		int (*read_mixer)(struct trident_card *card, int index);*/
+		void (*write_mixer)(struct trident_card *card,int mixer, unsigned int left,unsigned int right);
+		int (*recmask_io)(struct trident_card *card,int rw,int mask);
+		unsigned int mixer_state[SOUND_MIXER_NRDEVICES];
+	} mix;
+	
+	struct trident_state channels[NR_DSPS];
+
+	/* hardware resources */
+	unsigned long iobase;
+	u32 irq;
+
+	u32 ChanMap[2];
+	int ChanPCMcnt;
+	int ChanPCM;
+	CHANNELCONTROL ChRegs;
+	int ChanDwordCount;
+};
+
+static struct timer_list debug_timer;
+
+#define IWriteAinten( x ) \
+        {int i; \
+         for( i= 0; i < ChanDwordCount; i++) \
+		outl((x)->lpChAinten[i], TRID_REG(trident, (x)->lpAChAinten[i]));}
+
+#define IReadAinten( x ) \
+        {int i; \
+         for( i= 0; i < ChanDwordCount; i++) \
+         (x)->lpChAinten[i] = inl(TRID_REG(trident, (x)->lpAChAinten[i]));}
+
+#define ReadAint( x ) \
+        IReadAint( x ) 
+
+#define WriteAint( x ) \
+        IWriteAint( x ) 
+
+#define IWriteAint( x ) \
+        {int i; \
+         for( i= 0; i < ChanDwordCount; i++) \
+         outl((x)->lpChAint[i], TRID_REG(trident, (x)->lpAChAint[i]));}
+
+#define IReadAint( x ) \
+        {int i; \
+         for( i= 0; i < ChanDwordCount; i++) \
+         (x)->lpChAint[i] = inl(TRID_REG(trident, (x)->lpAChAint[i]));}
+
+
+/*
+ *	Trident support library routines
+ */
+ 
+/*---------------------------------------------------------------------------
+   void ResetAinten( struct trident_state *trident, int ChannelNum)
+  
+   Description: This routine will disable interrupts and ack any 
+                existing interrupts for specified channel.
+  
+   Parameters:  trident - pointer to target device class for 4DWave.
+                ChannelNum - channel number 
+  
+   returns:     TRUE if everything went ok, else FALSE.
+  
+  ---------------------------------------------------------------------------*/
+
+static void ResetAinten(struct trident_card * trident, int ChannelNum)
+{
+	unsigned int dwMask;
+	unsigned int x = ChannelNum >> 5;
+	unsigned int ChanDwordCount = trident->ChanDwordCount;
+
+	IReadAinten(&trident->ChRegs);
+	dwMask = 1 << (ChannelNum & 0x1f);
+	trident->ChRegs.lpChAinten[x] &= ~dwMask;
+	IWriteAinten(&trident->ChRegs);
+	// Ack the channel in case the interrupt was set before we disable it.
+	outl(dwMask, TRID_REG(trident, trident->ChRegs.lpAChAint[x]));
+}
+
+/*---------------------------------------------------------------------------
+   void EnableEndInterrupts( struct trident_card *trident)
+  
+   Description: This routine will enable end of loop interrupts.
+                End of loop interrupts will occur when a running
+                channel reaches ESO.
+  
+   Parameters:  trident - pointer to target device class for 4DWave.
+  
+   returns:     TRUE if everything went ok, else FALSE.
+  
+  ---------------------------------------------------------------------------*/
+
+static int EnableEndInterrupts(struct trident_card * trident)
+{
+	unsigned int GlobalControl;
+
+	GlobalControl = inb(TRID_REG(trident, T4D_LFO_GC_CIR + 1));
+	GlobalControl |= 0x10;
+	outb(GlobalControl, TRID_REG(trident, T4D_LFO_GC_CIR + 1));
+
+	M_printk("(trident) globctl=%02X\n", GlobalControl);
+	M_printk("(trident) enabled end interrupts\n");
+	return (TRUE);
+}
+
+/*---------------------------------------------------------------------------
+e   void DisableEndInterrupts( struct trident_card *trident)
+  
+   Description: This routine will disable end of loop interrupts.
+                End of loop interrupts will occur when a running
+                channel reaches ESO.
+  
+   Parameters:  
+                trident - pointer to target device class for 4DWave.
+  
+   returns:     TRUE if everything went ok, else FALSE.
+  
+  ---------------------------------------------------------------------------*/
+
+static int DisableEndInterrupts(struct trident_card * trident)
+{
+	unsigned int GlobalControl;
+
+	GlobalControl = inb(TRID_REG(trident, T4D_LFO_GC_CIR + 1));
+	GlobalControl &= ~0x10;
+	outb(GlobalControl, TRID_REG(trident, T4D_LFO_GC_CIR + 1));
+
+	M_printk("(trident) disabled end interrupts\n");
+	M_printk("(trident) globctl=%02X\n", GlobalControl);
+	return (TRUE);
+}
+
+/*---------------------------------------------------------------------------
+   void trident_enable_voice_irq( unsigned int HwChannel )
+  
+    Description: Enable an interrupt channel, any channel 0 thru n.
+                 This routine automatically handles the fact that there are
+                 more than 32 channels available.
+  
+    Parameters : HwChannel - Channel number 0 thru n.
+                 trident - pointer to target device class for 4DWave.
+  
+    Return Value: None.
+  
+  ---------------------------------------------------------------------------*/
+void trident_enable_voice_irq(struct trident_card * trident, unsigned int HwChannel)
+{
+	unsigned int x, Data, ChanDwordCount;
+
+	x = HwChannel >> 5;
+	Data = 1 << (HwChannel & 0x1f);
+	ChanDwordCount = trident->ChanDwordCount;
+	IReadAinten(&trident->ChRegs);
+	trident->ChRegs.lpChAinten[x] |= Data;
+	IWriteAinten(&trident->ChRegs);
+	M_printk("(trident) enabled voice IRQ %d\n", HwChannel);
+}
+
+/*---------------------------------------------------------------------------
+   void trident_disable_voice_irq( unsigned int HwChannel )
+  
+    Description: Disable an interrupt channel, any channel 0 thru n.
+                 This routine automatically handles the fact that there are
+                 more than 32 channels available.
+  
+    Parameters : HwChannel - Channel number 0 thru n.
+                 trident - pointer to target device class for 4DWave.
+  
+    Return Value: None.
+  
+  ---------------------------------------------------------------------------*/
+void trident_disable_voice_irq(struct trident_card * trident, unsigned int HwChannel)
+{
+	unsigned int x, Data, ChanDwordCount;
+
+	x = HwChannel >> 5;
+	Data = 1 << (HwChannel & 0x1f);
+	ChanDwordCount = trident->ChanDwordCount;
+	IReadAinten(&trident->ChRegs);
+	trident->ChRegs.lpChAinten[x] &= ~Data;
+	IWriteAinten(&trident->ChRegs);
+	M_printk("(trident) disabled voice IRQ %d\n", HwChannel);
+}
+
+/*---------------------------------------------------------------------------
+   unsigned int AllocateChannelPCM( void )
+  
+    Description: Allocate hardware channel by reverse order (63-0).
+  
+    Parameters :  trident - pointer to target device class for 4DWave.
+  
+    Return Value: hardware channel - 0-63 or -1 when no channel is available
+  
+  ---------------------------------------------------------------------------*/
+
+static int AllocateChannelPCM(struct trident_card *trident)
+{
+	int idx;
+
+	if (trident->ChanPCMcnt >= trident->ChanPCM)
+	{
+		M_printk(KERN_DEBUG "(trident) no channels available.\n");
+		return -1;
+	}
+	for (idx = 31; idx >= 0; idx--) {
+		if (!(trident->ChanMap[1] & (1 << idx))) {
+			trident->ChanMap[1] |= 1 << idx;
+			trident->ChanPCMcnt++;
+			return idx + 32;
+		}
+	}
+	for (idx = 31; idx >= 0; idx--) {
+		if (!(trident->ChanMap[0] & (1 << idx))) {
+			trident->ChanMap[0] |= 1 << idx;
+			trident->ChanPCMcnt++;
+			return idx;
+		}
+	}
+	return -1;
+}
+
+/*---------------------------------------------------------------------------
+   void FreeChannelPCM( int channel )
+  
+    Description: Free hardware channel.
+  
+    Parameters :  trident - pointer to target device class for 4DWave.
+	          channel - hardware channel number 0-63
+  
+    Return Value: none
+  
+  ---------------------------------------------------------------------------*/
+
+static void FreeChannelPCM(struct trident_card *trident, int channel)
+{
+	if (channel < 0 || channel > 63)
+		return;
+	if (trident->ChanMap[channel>>5] & (1 << (channel & 0x1f))) {
+		trident->ChanMap[channel>>5] &= ~(1 << (channel & 0x1f));
+		trident->ChanPCMcnt--;
+	}
+}
+
+/*---------------------------------------------------------------------------
+   void trident_start_voice( ULONG HwChannel )
+  
+    Description: Start a channel, any channel 0 thru n.
+                 This routine automatically handles the fact that there are
+                 more than 32 channels available.
+  
+    Parameters : HwChannel - Channel number 0 thru n.
+                 trident - pointer to target device class for 4DWave.
+  
+    Return Value: None.
+  
+  ---------------------------------------------------------------------------*/
+void trident_start_voice(struct trident_card * trident, unsigned int HwChannel)
+{
+	unsigned int x = HwChannel >> 5;
+	unsigned int Data = 1 << (HwChannel & 0x1f);
+
+	outl(Data, TRID_REG(trident, trident->ChRegs.lpAChStart[x]));
+	M_printk("(trident) start voice %d\n", HwChannel);
+}
+
+/*---------------------------------------------------------------------------
+   void trident_stop_voice( ULONG HwChannel )
+  
+    Description: Stop a channel, any channel 0 thru n.
+                 This routine automatically handles the fact that there are
+                 more than 32 channels available.
+  
+    Parameters : HwChannel - Channel number 0 thru n.
+                 trident - pointer to target device class for 4DWave.
+  
+    Return Value: None.
+  
+  ---------------------------------------------------------------------------*/
+void trident_stop_voice(struct trident_card * trident, unsigned int HwChannel)
+{
+	unsigned int x = HwChannel >> 5;
+	unsigned int Data = 1 << (HwChannel & 0x1f);
+
+	outl(Data, TRID_REG(trident, trident->ChRegs.lpAChStop[x]));
+  M_printk("(trident) stop voice %d\n", HwChannel);
+}
+
+/*---------------------------------------------------------------------------
+   int DidChannelInterrupt( )
+  
+   Description:  Check if interrupt channel occurred.
+  
+   Parameters :  trident - pointer to target device class for 4DWave.
+  
+   Return Value: TRUE if interrupt occurred, else FALSE.
+  
+  ---------------------------------------------------------------------------*/
+static int DidChannelInterrupt(struct trident_card * trident, int channel)
+{
+	unsigned int ChanDwordCount = trident->ChanDwordCount;
+	unsigned int x = channel >> 5;
+	unsigned int dwMask = 1 << (channel & 0x1f);
+
+	ReadAint(&trident->ChRegs);
+	return (trident->ChRegs.lpChAint[x] & dwMask) ? TRUE : FALSE;
+}
+
+/*---------------------------------------------------------------------------
+   void AckChannelInterrupt( )
+  
+   Description:  Acknowledge the interrupt bit for channel intrs.
+  
+   Parameters :  trident - pointer to target device class for 4DWave.
+  
+   Return Value: None
+  
+  ---------------------------------------------------------------------------*/
+static void AckChannelInterrupt(struct trident_card * trident, int channel)
+{
+	unsigned int ChanDwordCount = trident->ChanDwordCount;
+	unsigned int x = channel >> 5;
+	unsigned int dwMask = 1 << (channel & 0x1f);
+
+	ReadAint(&trident->ChRegs);
+	trident->ChRegs.lpChAint[x] &= dwMask;
+	IWriteAint(&trident->ChRegs);
+}
+
+/*---------------------------------------------------------------------------
+   int LoadDeltaHw( unsigned int HwChannel, unsigned int Delta )
+  
+   Description: This routine writes Delta to the hardware.
+  
+   Parameters:  Delta - data to write (2 Bytes only)
+                HwChannel - Hardware channel to write to.
+   		trident - pointer to target device class for 4DWave.
+  
+   Returns:     TRUE if all goes well, else FALSE. 
+  
+  ---------------------------------------------------------------------------*/
+static int LoadDeltaHw(struct trident_card * trident, unsigned int HwChannel, unsigned int Delta)
+{
+
+	outb(HwChannel, TRID_REG(trident, T4D_LFO_GC_CIR));
+
+	if (trident->card_type != TYPE_4DWAVE_NX) {
+		outw((unsigned short) Delta, TRID_REG(trident, CH_DX_ESO_DELTA));
+	} 
+	else			// ID_4DWAVE_NX
+	{
+		outb((unsigned char) Delta, TRID_REG(trident, CH_NX_DELTA_CSO + 3));
+		outb((unsigned char) (Delta >> 8), TRID_REG(trident, CH_NX_DELTA_ESO + 3));
+	}
+
+	return TRUE;
+}
+
+/*---------------------------------------------------------------------------
+   int LoadVirtualChannel( ULONG *Data, ULONG HwChannel)
+  
+   Description: This routine writes all required channel registers to hardware.
+  
+   Parameters:  *Data - a pointer to the data to write (5 ULONGS always).
+                HwChannel - Hardware channel to write to.
+   		trident - pointer to target device class for 4DWave.
+  
+   Returns:     TRUE if all goes well, else FALSE. 
+  
+  ---------------------------------------------------------------------------*/
+static int LoadVirtualChannel(struct trident_card * trident, unsigned int *Data, unsigned int HwChannel)
+{
+	unsigned int ChanData[CHANNEL_REGS];
+	unsigned int ULONGSToDo = CHANNEL_REGS;
+	unsigned int i;
+	unsigned int Address = CHANNEL_START;
+
+	/* Copy the data first... Hack... Before mucking with Volume! */
+	memcpy((unsigned char *) ChanData, (unsigned char *) Data, ULONGSToDo * 4);
+
+	outb((unsigned char) HwChannel, TRID_REG(trident, T4D_LFO_GC_CIR));
+
+	for (i = 0; i < ULONGSToDo; i++, Address += 4)
+		outl(ChanData[i], TRID_REG(trident, Address));
+
+	M_printk("(trident) load virtual channel %d\n", HwChannel);
+	return TRUE;
+}
+
+/*---------------------------------------------------------------------------
+   trident_write_voice_regs
+  
+   Description: This routine will write the 5 hardware channel registers
+                to hardware.
+  
+   Paramters:   trident - pointer to target device class for 4DWave.
+                Channel - Real or Virtual channel number.
+                Each register field.
+  
+   Returns:     TRUE if all goes well, else FALSE. 
+  
+  ---------------------------------------------------------------------------*/
+int trident_write_voice_regs(struct trident_card * trident,
+			 unsigned int Channel,
+			 unsigned int LBA,
+			 unsigned int CSO,
+			 unsigned int ESO,
+			 unsigned int DELTA,
+			 unsigned int ALPHA_FMS,
+			 unsigned int FMC_RVOL_CVOL,
+			 unsigned int GVSEL,
+			 unsigned int PAN,
+			 unsigned int VOL,
+			 unsigned int CTRL,
+			 unsigned int EC)
+{
+	unsigned int ChanData[CHANNEL_REGS + 1], FmcRvolCvol;
+
+	ChanData[1] = LBA;
+	ChanData[4] = (GVSEL << 31) |
+	    ((PAN & 0x0000007f) << 24) |
+	    ((VOL & 0x000000ff) << 16) |
+	    ((CTRL & 0x0000000f) << 12) |
+	    (EC & 0x00000fff);
+
+	FmcRvolCvol = FMC_RVOL_CVOL & 0x0000ffff;
+
+	if (trident->card_type != TYPE_4DWAVE_NX) 
+	{
+		ChanData[0] = (CSO << 16) | (ALPHA_FMS & 0x0000ffff);
+		ChanData[2] = (ESO << 16) | (DELTA & 0x0ffff);
+		ChanData[3] = FmcRvolCvol;
+	}
+	else			// ID_4DWAVE_NX
+	{
+		ChanData[0] = (DELTA << 24) | (CSO & 0x00ffffff);
+		ChanData[2] = ((DELTA << 16) & 0xff000000) | (ESO & 0x00ffffff);
+		ChanData[3] = (ALPHA_FMS << 16) | FmcRvolCvol;
+	}
+
+	LoadVirtualChannel(trident, ChanData, Channel);
+
+	return TRUE;
+}
+
+static int compute_rate(u32 rate)
+{
+	int delta;
+	// We special case 44100 and 8000 since rounding with the equation
+	// does not give us an accurate enough value. For 11025 and 22050
+	// the equation gives us the best answer. All other frequencies will
+	// also use the equation. JDW
+	if (rate == 44100)
+		delta = 0xeb3;
+	else if (rate == 8000)
+		delta = 0x2ab;
+	else if (rate == 48000)
+		delta = 0x1000;
+	else
+		delta = (((rate << 12) + rate) / 48000) & 0x0000ffff;
+	return delta;
+}
+
+/*---------------------------------------------------------------------------
+   trident_set_dac_rate
+  
+   Description: This routine will set the sample rate for playback.
+  
+   Paramters:   trident - pointer to target device class for 4DWave.
+                rate    - desired sample rate
+                set     - actually write hardware if set is true.
+  
+   Returns:     The rate allowed by device.
+  
+  ---------------------------------------------------------------------------*/
+
+static unsigned int trident_set_dac_rate(struct trident_state * trident,
+					     unsigned int rate, int set)
+{
+	unsigned int delta;
+
+
+	if (rate > 48000)
+		rate = 48000;
+	if (rate < 4000)
+		rate = 4000;
+
+	delta = compute_rate(rate);
+
+	if(set)
+	{
+		//Select channel window
+		outb(trident->dma_dac.chan[1], TRID_REG(trident->card, T4D_LFO_GC_CIR));
+
+		if (trident->card->card_type != TYPE_4DWAVE_NX) 
+			outw(delta,TRID_REG(trident->card,CH_DX_ESO_DELTA+2));
+		else			// ID_4DWAVE_NX
+		{
+			outb( delta     & 0xff,TRID_REG(trident->card,CH_NX_DELTA_CSO));
+			outb((delta>>8) & 0xff,TRID_REG(trident->card,CH_NX_DELTA_ESO));
+		}
+	}
+	 
+	M_printk("(trident) called trident_set_dac_rate : rate = %d, set = %d delta = %4x\n", 
+			rate, set,delta);
+
+	trident->ratedac = rate;
+	return rate;
+}
+
+/*---------------------------------------------------------------------------
+   trident_set_adc_rate
+  
+   Description: This routine will set the sample rate for capture.
+  
+   Paramters:   trident - pointer to target device class for 4DWave.
+                rate    - desired sample rate
+                set     - actually write hardware if set is true.
+  
+   Returns:     The rate allowed by device.
+  
+  ---------------------------------------------------------------------------*/
+
+static unsigned int trident_set_adc_rate(struct trident_state * trident,
+					     unsigned int rate,
+					     int set)
+{
+	//snd_printk("trid: called trident_set_adc_rate\n");
+	if (rate > 48000)
+		rate = 48000;
+	if (rate < 4000)
+		rate = 4000;
+
+	trident->rateadc = rate;
+	/*
+	 *	FIXME: hit the hardware
+	 */
+
+	return rate;
+}
+ 
+extern __inline__ unsigned ld2(unsigned int x)
+{
+	unsigned r = 0;
+	
+	if (x >= 0x10000) {
+		x >>= 16;
+		r += 16;
+	}
+	if (x >= 0x100) {
+		x >>= 8;
+		r += 8;
+	}
+	if (x >= 0x10) {
+		x >>= 4;
+		r += 4;
+	}
+	if (x >= 4) {
+		x >>= 2;
+		r += 2;
+	}
+	if (x >= 2)
+		r++;
+	return r;
+}
+
+
+/* --------------------------------------------------------------------- */
+
+static struct trident_card *devs = NULL;
+
+/* --------------------------------------------------------------------- */
+
+
+/*
+ *	Trident AC97 codec programming interface.
+ */
+	 
+static void trident_ac97_set(struct trident_card *trident, u8 cmd, u16 val)
+{
+	unsigned int    address, data;
+	unsigned short  count  = 0xffff;
+
+	data = ((unsigned long)val) << 16;
+
+	if (trident->card_type != TYPE_4DWAVE_NX)
+	{
+		address = DX_ACR0_AC97_W;
+		/* read AC-97 write register status */
+		do
+		{
+			if ((inw(TRID_REG(trident,address))&0x8000) == 0)
+			break;
+		}
+		while(count--);
+
+		data |= (0x8000 | (cmd & 0x000000ff));
+	}
+	else  // ID_4DWAVE_NX
+	{
+		address = NX_ACR1_AC97_W;
+		/* read AC-97 write register status */
+		do
+		{
+			if ((inw(TRID_REG(trident, address )) & 0x0800) == 0)
+				break;
+		}
+		while (count--);
+		data |= (0x0800 | (cmd & 0x000000ff));
+	}
+	if (count == 0) 
+	{
+		printk(KERN_ERR "trident: AC97 CODEC write timed out.\n");
+		return;
+	}
+
+	outl(data, TRID_REG(trident, address));
+}
+
+static u16 trident_ac97_get(struct trident_card *trident, u8 cmd)
+{
+	unsigned int data = 0;
+	unsigned short count = 0xffff;
+
+	if (trident->card_type != TYPE_4DWAVE_NX)
+	{
+		data = (0x00008000L | (cmd & 0x000000ff));
+		outl(data, TRID_REG(trident, DX_ACR1_AC97_R));
+		do
+		{
+			data = inl(TRID_REG(trident, DX_ACR1_AC97_R));
+			if ( ( data & 0x0008000 ) == 0 )
+				break;
+		}
+		while(count--);
+	}
+	else  // ID_4DWAVE_NX
+	{
+		data = (0x00000800L | (cmd & 0x000000ff));
+		outl(data, TRID_REG(trident, NX_ACR2_AC97_R_PRIMARY));
+		do
+		{
+			data = inl(TRID_REG(trident, NX_ACR2_AC97_R_PRIMARY));
+			if ( ( data & 0x00000C00 ) == 0 )
+				break;
+		}
+		while(count--);
+	}
+	if ( count == 0 ) 
+	{
+		printk("trident: AC97 CODEC read timed out.\n");
+		data = 0;
+	}
+	return ((unsigned short)(data >> 16));
+}
+
+/* OSS interface to the ac97s.. */
+
+#define AC97_STEREO_MASK (SOUND_MASK_VOLUME|\
+	SOUND_MASK_PCM|SOUND_MASK_LINE|SOUND_MASK_CD|\
+	SOUND_MASK_VIDEO|SOUND_MASK_LINE1|SOUND_MASK_IGAIN)
+
+#define AC97_SUPPORTED_MASK (AC97_STEREO_MASK | \
+	SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_MIC|\
+	SOUND_MASK_SPEAKER)
+
+#define AC97_RECORD_MASK (SOUND_MASK_MIC|\
+	SOUND_MASK_CD| SOUND_MASK_VIDEO| SOUND_MASK_LINE1| SOUND_MASK_LINE|\
+	SOUND_MASK_PHONEIN)
+
+#define supported_mixer(CARD,FOO) ( CARD->mix.supported_mixers & (1<<FOO) )
+
+/* this table has default mixer values for all OSS mixers.
+	be sure to fill it in if you add oss mixers
+	to anyone's supported mixer defines */
+
+/* possible __init */
+static struct mixer_defaults {
+	int mixer;
+	unsigned int value;
+} mixer_defaults[SOUND_MIXER_NRDEVICES] = {
+		/* all values 0 -> 100 in bytes */
+	{SOUND_MIXER_VOLUME,	0x3232},
+	{SOUND_MIXER_BASS,	0x3232},
+	{SOUND_MIXER_TREBLE,	0x3232},
+	{SOUND_MIXER_SPEAKER,	0x3232},
+	{SOUND_MIXER_MIC,	0x3232},
+	{SOUND_MIXER_LINE,	0x3232},
+	{SOUND_MIXER_CD,	0x3232},
+	{SOUND_MIXER_VIDEO,	0x3232},
+	{SOUND_MIXER_LINE1,	0x3232},
+	{SOUND_MIXER_PCM,	0x3232},
+	{SOUND_MIXER_IGAIN,	0x3232},
+	{-1,0}
+};
+	
+static struct ac97_mixer_hw {
+	unsigned char offset;
+	int scale;
+} ac97_hw[SOUND_MIXER_NRDEVICES]= {
+	[SOUND_MIXER_VOLUME]	=	{0x02,63},
+	[SOUND_MIXER_BASS]	=	{0x08,15},
+	[SOUND_MIXER_TREBLE]	=	{0x08,15},
+	[SOUND_MIXER_SPEAKER]	=	{0x0a,15},
+	[SOUND_MIXER_MIC]	=	{0x0e,31},
+	[SOUND_MIXER_LINE]	=	{0x10,31},
+	[SOUND_MIXER_CD]	=	{0x12,31},
+	[SOUND_MIXER_VIDEO]	=	{0x14,31},
+	[SOUND_MIXER_LINE1]	=	{0x16,31},
+	[SOUND_MIXER_PCM]	=	{0x18,31},
+	[SOUND_MIXER_IGAIN]	=	{0x1c,31}
+};
+
+#if 0 /* *shrug* removed simply because we never used it.
+		feel free to implement again if needed */
+
+/* reads the given OSS mixer from the ac97
+	the caller must have insured that the ac97 knows
+	about that given mixer, and should be holding a
+	spinlock for the card */
+static int ac97_read_mixer(struct trident_card *card, int mixer) 
+{
+	u16 val;
+	int ret=0;
+	struct ac97_mixer_hw *mh = &ac97_hw[mixer];
+
+	val = trident_ac97_get(card , mh->offset);
+
+	if(AC97_STEREO_MASK & (1<<mixer)) {
+		/* nice stereo mixers .. */
+		int left,right;
+
+		left = (val >> 8)  & 0x7f;
+		right = val  & 0x7f;
+
+		if (mixer == SOUND_MIXER_IGAIN) {
+			right = (right * 100) / mh->scale;
+			left = (left * 100) / mh->scale;
+		else {
+			right = 100 - ((right * 100) / mh->scale);
+			left = 100 - ((left * 100) / mh->scale);
+		}
+
+		ret = left | (right << 8);
+	} else if (mixer == SOUND_MIXER_SPEAKER) {
+		ret = 100 - ((((val & 0x1e)>>1) * 100) / mh->scale);
+	} else if (mixer == SOUND_MIXER_MIC) {
+		ret = 100 - (((val & 0x1f) * 100) / mh->scale);
+	/*  the low bit is optional in the tone sliders and masking
+		it lets is avoid the 0xf 'bypass'.. */
+	} else if (mixer == SOUND_MIXER_BASS) {
+		ret = 100 - ((((val >> 8) & 0xe) * 100) / mh->scale);
+	} else if (mixer == SOUND_MIXER_TREBLE) {
+		ret = 100 - (((val & 0xe) * 100) / mh->scale);
+	}
+
+	printk("read mixer %d (0x%x) %x -> %x\n",mixer,mh->offset,val,ret);
+
+	return ret;
+}
+#endif
+
+/* write the OSS encoded volume to the given OSS encoded mixer,
+	again caller's job to make sure all is well in arg land,
+	call with spinlock held */
+static void ac97_write_mixer(struct trident_card *card, int mixer, unsigned int left, unsigned int right)
+{
+	u16 val=0;
+	struct ac97_mixer_hw *mh = &ac97_hw[mixer];
+
+	printk("(trident) wrote ac97 mixer %d (0x%x) %d,%d",mixer,mh->offset,left,right);
+
+	if(AC97_STEREO_MASK & (1<<mixer)) {
+		/* stereo mixers */
+
+
+		if (mixer == SOUND_MIXER_IGAIN) {
+			right = (right * mh->scale) / 100;
+			left = (left * mh->scale) / 100;
+		} else {
+			right = ((100 - right) * mh->scale) / 100;
+			left = ((100 - left) * mh->scale) / 100;
+		}
+
+		val = (left << 8) | right;
+
+	} else if (mixer == SOUND_MIXER_SPEAKER) {
+		val = (((100 - left) * mh->scale) / 100) << 1;
+	} else if (mixer == SOUND_MIXER_MIC) {
+		val = trident_ac97_get(card , mh->offset) & ~0x801f;
+		val |= (((100 - left) * mh->scale) / 100);
+	/*  the low bit is optional in the tone sliders and masking
+		it lets us avoid the 0xf 'bypass'.. */
+	} else if (mixer == SOUND_MIXER_BASS) {
+		val = trident_ac97_get(card , mh->offset) & ~0x0f00;
+		val |= ((((100 - left) * mh->scale) / 100) << 8) & 0x0e00;
+	} else if (mixer == SOUND_MIXER_TREBLE)  {
+		val = trident_ac97_get(card , mh->offset) & ~0x000f;
+		val |= (((100 - left) * mh->scale) / 100) & 0x000e;
+	}
+
+	trident_ac97_set(card, mh->offset, val);
+	
+	printk(" -> %x\n",val);
+}
+
+/* the following tables allow us to go from 
+	OSS <-> ac97 quickly. */
+
+enum ac97_recsettings {
+	AC97_REC_MIC=0,
+	AC97_REC_CD,
+	AC97_REC_VIDEO,
+	AC97_REC_AUX,
+	AC97_REC_LINE,
+	AC97_REC_STEREO, /* combination of all enabled outputs..  */
+	AC97_REC_MONO,        /*.. or the mono equivalent */
+	AC97_REC_PHONE        
+};
+
+static unsigned int ac97_rm2oss[] = {
+	[AC97_REC_MIC] = SOUND_MIXER_MIC, 
+	[AC97_REC_CD] = SOUND_MIXER_CD, 
+	[AC97_REC_VIDEO] = SOUND_MIXER_VIDEO, 
+	[AC97_REC_AUX] = SOUND_MIXER_LINE1, 
+	[AC97_REC_LINE] = SOUND_MIXER_LINE, 
+	[AC97_REC_PHONE] = SOUND_MIXER_PHONEIN
+};
+
+/* indexed by bit position */
+static unsigned int ac97_oss_rm[] = {
+	[SOUND_MIXER_MIC] = AC97_REC_MIC,
+	[SOUND_MIXER_CD] = AC97_REC_CD,
+	[SOUND_MIXER_VIDEO] = AC97_REC_VIDEO,
+	[SOUND_MIXER_LINE1] = AC97_REC_AUX,
+	[SOUND_MIXER_LINE] = AC97_REC_LINE,
+	[SOUND_MIXER_PHONEIN] = AC97_REC_PHONE
+};
+	
+/* read or write the recmask 
+	the ac97 can really have left and right recording
+	inputs independantly set, but OSS doesn't seem to 
+	want us to express that to the user. 
+	the caller guarantees that we have a supported bit set,
+	and they must be holding the card's spinlock */
+	
+static int ac97_recmask_io(struct trident_card *card, int rw, int mask) 
+{
+	unsigned int val;
+
+	if (rw) {
+		/* read it from the card */
+		val = trident_ac97_get(card, 0x1a) & 0x7;
+		return ac97_rm2oss[val];
+	}
+
+	/* else, write the first set in the mask as the
+		output */	
+
+	val = ffs(mask); 
+	val = ac97_oss_rm[val-1];
+	val |= val << 8;  /* set both channels */
+
+	printk("trident: setting ac97 recmask to 0x%x\n",val);
+
+	trident_ac97_set(card,0x1a,val);
+
+	return 0;
+};
+
+/*
+ *	Generic AC97 codec initialisation. Need to check there are no
+ *	quirks for the Trident cards.
+ */
+ 
+static u16 trident_ac97_init(struct trident_card *trident)
+{
+	trident->mix.supported_mixers = AC97_SUPPORTED_MASK;
+	trident->mix.stereo_mixers = AC97_STEREO_MASK;
+	trident->mix.record_sources = AC97_RECORD_MASK;
+/*	trident->mix.read_mixer = ac97_read_mixer;*/
+	trident->mix.write_mixer = ac97_write_mixer;
+	trident->mix.recmask_io = ac97_recmask_io;
+
+	if(trident->card_type == TYPE_4DWAVE_NX)
+	{
+		unsigned short VendorID1, VendorID2;
+
+		outl(0x02, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
+
+		// 4 Speaker Codec initialization
+		VendorID1 = trident_ac97_get(trident, AC97_VENDOR_ID1);
+		VendorID2 = trident_ac97_get(trident, AC97_VENDOR_ID2);
+
+		if( (VendorID1 == 0x8384) && (VendorID2 == 0x7608) )
+		{
+			// Sigmatel 9708.
+            
+                	unsigned short TestReg;
+                	unsigned int DTemp;
+
+                	trident_ac97_set(trident, AC97_SIGMATEL_CIC1, 0xABBAL);  
+                	trident_ac97_set(trident, AC97_SIGMATEL_CIC2, 0x1000L);
+
+			TestReg = trident_ac97_get(trident, AC97_SIGMATEL_BIAS2);
+
+			if( TestReg != 0x8000 ) // Errata Notice.
+			{
+				trident_ac97_set(trident, AC97_SIGMATEL_BIAS1, 0xABBAL );
+				trident_ac97_set(trident, AC97_SIGMATEL_BIAS2, 0x0007L );
+			}
+			else // Newer version
+			{
+				trident_ac97_set(trident, AC97_SIGMATEL_CIC2, 0x1001L );  // recommended
+				trident_ac97_set(trident, AC97_SIGMATEL_DAC2INVERT, 0x0008L );
+			}
+
+			trident_ac97_set( trident, AC97_SURROUND_MASTER, 0x0000L );
+			trident_ac97_set( trident, AC97_HEADPHONE_VOL,   0x8000L );
+
+			DTemp = (unsigned int)trident_ac97_get( trident, AC97_GENERAL_PURPOSE );
+			trident_ac97_set( trident, AC97_GENERAL_PURPOSE, DTemp & 0x0000FDFFL );  // bit9 = 0.
+
+			DTemp = (unsigned int)trident_ac97_get( trident, AC97_MIC_VOL );
+			trident_ac97_set( trident, AC97_MIC_VOL, DTemp | 0x00008000L );  // bit15 = 1.
+
+			DTemp = inl(TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
+			outl(DTemp | 0x0010, TRID_REG(trident, NX_ACR0_AC97_COM_STAT));
+
+		}
+		else if((VendorID1 == 0x5452) && (VendorID2 == 0x4108) )
+		{   // TriTech TR28028
+			trident_ac97_set( trident, AC97_SURROUND_MASTER, 0x0000L );
+	                trident_ac97_set( trident, AC97_EXTENDED_STATUS, 0x0000L );
+		}
+		else if((VendorID1 == 0x574D) && 
+                	(VendorID2 >= 0x4C00) && (VendorID2 <= 0x4C0f))
+		{   // Wolfson WM9704
+			trident_ac97_set( trident, AC97_SURROUND_MASTER, 0x0000L );
+		}
+		else
+		{
+#if 0
+			printk("trident: No four Speaker Support with on board CODEC\n") ;
+#endif
+		}
+
+		// S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled
+		outl(0x200004, TRID_REG(trident, NX_SPCSTATUS));
+		// Enable S/PDIF out, 48khz only from ac97 fifo
+		outb(0x28, TRID_REG(trident, NX_SPCTRL_SPCSO+3));
+	}
+        else
+        {
+		outl(0x02, TRID_REG(trident, DX_ACR2_AC97_COM_STAT));
+        }
+	return 0;
+}
+
+
+/* this only fixes the output apu mode to be later set by start_dac and
+	company.  output apu modes are set in trident_rec_setup */
+static void set_fmt(struct trident_state *s, unsigned char mask, unsigned char data)
+{
+	s->fmt = (s->fmt & mask) | data;
+	/* Set the chip ? */
+}
+
+
+/*
+ *	Native play back driver 
+ */
+
+/* the mode passed should be already shifted and masked */
+
+static void trident_play_setup(struct trident_state *trident, int mode, u32 rate, void *buffer, int size)
+{
+	unsigned int LBA;
+	unsigned int Delta;
+	unsigned int ESO;
+	unsigned int CTRL;
+	unsigned int FMC_RVOL_CVOL;
+	unsigned int GVSEL;
+	unsigned int PAN;
+	unsigned int VOL;
+	unsigned int EC;
+
+
+
+	/* set Loop Back Address */
+	LBA = virt_to_bus(buffer);
+
+	Delta = compute_rate(rate);
+
+	M_printk("(trident) rate, delta = %d %d\n", rate, Delta);
+
+	/* set ESO */
+	ESO = size;
+	if (mode & TRIDENT_FMT_16BIT)
+		ESO /= 2;
+	if (mode & TRIDENT_FMT_STEREO)
+		ESO /= 2;
+
+	ESO = ESO - 1;
+	//snd_printk("trid: ESO = %d\n", ESO);
+
+	/* set ctrl mode
+	   CTRL default: 8-bit (unsigned) mono, loop mode enabled
+	 */
+	CTRL = 0x00000001;
+	if (mode & TRIDENT_FMT_16BIT)
+	{
+		CTRL |= 0x00000008;	// 16-bit data
+		CTRL |= 0x00000002;	// signed data
+	}
+	if (mode&TRIDENT_FMT_STEREO)
+		CTRL |= 0x00000004;	// stereo data
+
+	//FMC_RVOL_CVOL = 0x0000c000;
+	FMC_RVOL_CVOL = 0x0000ffff;
+	GVSEL = 1;
+	PAN = 0;
+	VOL = 0;
+	EC = 0;
+
+	trident_write_voice_regs(trident->card,
+			     trident->dma_dac.chan[1],
+			     LBA,
+			     0,	/* cso */
+			     ESO,
+			     Delta,
+			     0,	/* alpha */
+			     FMC_RVOL_CVOL,
+			     GVSEL,
+			     PAN,
+			     VOL,
+			     CTRL,
+			     EC);
+
+}
+
+/*
+ *	Native record driver 
+ */
+
+/* again, passed mode is alrady shifted/masked */
+
+static void trident_rec_setup(struct trident_state *trident, int mode, u32 rate, void *buffer, int size)
+{
+	unsigned int LBA;
+	unsigned int Delta;
+	unsigned int ESO;
+	unsigned int CTRL;
+	unsigned int FMC_RVOL_CVOL;
+	unsigned int GVSEL;
+	unsigned int PAN;
+	unsigned int VOL;
+	unsigned int EC;
+	unsigned char bValue;
+	unsigned short wValue;
+	unsigned int dwValue;
+	unsigned short wRecCODECSamples;
+	unsigned int dwChanFlags;
+	struct trident_card *card = trident->card;
+
+	// Enable AC-97 ADC (capture), disable capture interrupt
+	if (trident->card->card_type != TYPE_4DWAVE_NX) 
+	{
+		bValue = inb(TRID_REG(card, DX_ACR2_AC97_COM_STAT));
+		outb(bValue | 0x48, TRID_REG(card, DX_ACR2_AC97_COM_STAT));
+	}
+	else 
+	{
+		wValue = inw(TRID_REG(card, T4D_MISCINT));
+		outw(wValue | 0x1000, TRID_REG(card, T4D_MISCINT));
+	}
+
+	// Initilize the channel and set channel Mode
+	outb(0, TRID_REG(card, LEGACY_DMAR15));
+
+	// Set DMA channel operation mode register
+	bValue = inb(TRID_REG(card, LEGACY_DMAR11)) & 0x03;
+	outb(bValue | 0x54, TRID_REG(card, LEGACY_DMAR11));
+
+	// Set channel buffer Address
+	LBA = virt_to_bus(buffer);
+	outl(LBA, TRID_REG(card, LEGACY_DMAR0));
+
+	/* set ESO */
+	ESO = size;
+
+	dwValue = inl(TRID_REG(card, LEGACY_DMAR4)) & 0xff000000;
+	dwValue |= (ESO - 1) & 0x0000ffff;
+	outl(dwValue, TRID_REG(card, LEGACY_DMAR4));
+
+	// Set channel sample rate , 4.12 format
+	dwValue = (((unsigned int) 48000L << 12) / (unsigned long) (rate));
+	outw((unsigned short) dwValue, TRID_REG(card, T4D_SBDELTA_DELTA_R));
+
+	// Set channel interrupt blk length
+	if (mode & TRIDENT_FMT_16BIT) {
+		wRecCODECSamples = (unsigned short) ((ESO >> 1) - 1);
+		dwChanFlags = 0xffffb000;
+	} else {
+		wRecCODECSamples = (unsigned short) (ESO - 1);
+		dwChanFlags = 0xffff1000;
+	}
+
+	dwValue = ((unsigned int) wRecCODECSamples) << 16;
+	dwValue |= (unsigned int) (wRecCODECSamples) & 0x0000ffff;
+	outl(dwValue, TRID_REG(card, T4D_SBBL_SBCL));
+
+	// Right now, set format and start to run capturing, 
+	// continuous run loop enable.
+	trident->bDMAStart = 0x19;	// 0001 1001b
+
+	if (mode & TRIDENT_FMT_16BIT)
+		trident->bDMAStart |= 0xa0;
+	if (mode & TRIDENT_FMT_STEREO)
+		trident->bDMAStart |= 0x40;
+
+	// Prepare capture intr channel
+
+	Delta = ((((unsigned int) rate) << 12) / ((unsigned long) (48000L)));
+
+	/* set Loop Back Address */
+	LBA = virt_to_bus(buffer);
+
+	/* set ESO */
+	ESO = size;
+	if (mode & TRIDENT_FMT_16BIT)
+		ESO /= 2;
+	if (mode & TRIDENT_FMT_STEREO)
+		ESO /= 2;
+
+	ESO = ESO - 1;
+	//snd_printk("trid: ESO = %d\n", ESO);
+
+	/* set ctrl mode
+	   CTRL default: 8-bit (unsigned) mono, loop mode enabled
+	 */
+	CTRL = 0x00000001;
+	if (mode & TRIDENT_FMT_16BIT)
+		CTRL |= 0x00000008;	// 16-bit data
+	/* XXX DO UNSIGNED XXX */
+	//if (!(mode & SND_PCM1_MODE_U))
+	//	CTRL |= 0x00000002;	// signed data
+	if (mode& TRIDENT_FMT_STEREO)
+		CTRL |= 0x00000004;	// stereo data
+
+	FMC_RVOL_CVOL = 0x0000ffff;
+	GVSEL = 1;
+	PAN = 0xff;
+	VOL = 0xff;
+	EC = 0;
+
+	trident_write_voice_regs(card,
+			     trident->dma_adc.chan[0],
+			     LBA,
+			     0,	/* cso */
+			     ESO,
+			     Delta,
+			     0,	/* alpha */
+			     FMC_RVOL_CVOL,
+			     GVSEL,
+			     PAN,
+			     VOL,
+			     CTRL,
+			     EC);
+
+}
+
+/* Playback pointer */
+__inline__ unsigned int get_dmaa(struct trident_state *trident)
+{
+	unsigned int cso;
+	unsigned int eso;
+
+#if 0
+	if (!(trident->enable & ADC_RUNNING))
+		return 0;
+#endif
+
+	outb(trident->dma_dac.chan[1], TRID_REG(trident->card, T4D_LFO_GC_CIR));
+
+	if (trident->card->card_type != TYPE_4DWAVE_NX) 
+	{
+		cso = inw(TRID_REG(trident->card, CH_DX_CSO_ALPHA_FMS + 2));
+		eso = inw(TRID_REG(trident->card, CH_DX_ESO_DELTA + 2));
+	}
+	else			// ID_4DWAVE_NX
+	{
+		cso = (unsigned int) inl(TRID_REG(trident->card, CH_NX_DELTA_CSO)) & 0x00ffffff;
+		eso = (unsigned int) inl(TRID_REG(trident->card, CH_NX_DELTA_ESO)) & 0x00ffffff;
+	}
+	M_printk("(trident) get_dmaa: chip reported %d.%d\n", cso, eso);
+	cso++;
+
+	if (cso > eso)
+		cso = eso;
+
+	if (trident->fmt & TRIDENT_FMT_16BIT)
+		cso *= 2;
+	if (trident->fmt & TRIDENT_FMT_STEREO)
+		cso *= 2;
+	return cso;
+}
+
+/* Record pointer */
+extern __inline__ unsigned get_dmac(struct trident_state *trident)
+{
+	unsigned int cso;
+
+	if (!(trident->enable&DAC_RUNNING))
+		return 0;
+
+	outb(trident->dma_adc.chan[0], TRID_REG(trident->card, T4D_LFO_GC_CIR));
+
+	if (trident->card->card_type != TYPE_4DWAVE_NX) {
+		cso = inw(TRID_REG(trident->card, CH_DX_CSO_ALPHA_FMS + 2));
+	} else {		// ID_4DWAVE_NX 
+		cso = (unsigned int) inl(TRID_REG(trident->card, CH_NX_DELTA_CSO)) & 0x00ffffff;
+	}
+
+	printk("(trident) get_dmac: chip reported %d\n", cso);
+	
+	cso++;
+
+	if (trident->fmt & TRIDENT_FMT_16BIT)
+		cso *= 2;
+	if (trident->fmt & TRIDENT_FMT_STEREO)
+		cso *= 2;
+	return cso;
+}
+
+static void trident_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+static void trident_kick(unsigned long plop)
+{
+	trident_interrupt(5, (void *)plop, NULL);
+	debug_timer.expires=jiffies+1;
+	add_timer(&debug_timer);
+}
+
+/* Stop recording (lock held) */
+
+extern inline void __stop_adc(struct trident_state *s)
+{
+	struct trident_card *trident = s->card;
+
+	M_printk("(trident) stopping ADC\n");
+	
+
+	s->enable &= ~ADC_RUNNING;
+	trident_disable_voice_irq(trident, s->dma_adc.chan[0]);
+	outb(0x00, TRID_REG(trident, T4D_SBCTRL_SBE2R_SBDD));
+	trident_disable_voice_irq(trident, s->dma_adc.chan[0]);
+	trident_stop_voice(trident, s->dma_adc.chan[0]);
+	ResetAinten(trident, s->dma_adc.chan[0]);
+}	
+
+extern inline void stop_adc(struct trident_state *s)
+{
+	unsigned long flags;
+	struct trident_card *trident = s->card;
+
+	spin_lock_irqsave(&trident->lock, flags);
+	__stop_adc(s);
+	spin_unlock_irqrestore(&trident->lock, flags);
+}	
+
+/* stop playback (lock held) */
+
+extern inline void __stop_dac(struct trident_state *s)
+{
+	struct trident_card *trident = s->card;
+
+	M_printk("(trident) stopping DAC\n");
+	
+	//trident_stop_voice(trident, s->dma_dac.chan[0]);
+	//trident_disable_voice_irq(trident, s->dma_dac.chan[0]);
+	trident_stop_voice(trident, s->dma_dac.chan[1]);
+	trident_disable_voice_irq(trident, s->dma_dac.chan[1]);
+	s->enable &= ~DAC_RUNNING;
+}	
+
+extern inline void stop_dac(struct trident_state *s)
+{
+	struct trident_card *trident = s->card;
+	unsigned long flags;
+
+	spin_lock_irqsave(&trident->lock, flags);
+	__stop_dac(s);
+	spin_unlock_irqrestore(&trident->lock, flags);
+}	
+
+static void start_dac(struct trident_state *s)
+{
+	unsigned long flags;
+	struct trident_card *trident = s->card;
+
+	spin_lock_irqsave(&s->card->lock, flags);
+	if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) 
+	{
+		s->enable |= DAC_RUNNING;
+		trident_enable_voice_irq(trident, s->dma_dac.chan[1]);
+		trident_start_voice(trident, s->dma_dac.chan[1]);
+		//trident_start_voice(trident, s->dma_dac.chan[0]);
+		M_printk("(trident) starting DAC\n");
+	
+	}
+	spin_unlock_irqrestore(&s->card->lock, flags);
+}	
+
+static void start_adc(struct trident_state *s)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&s->card->lock, flags);
+	if ((s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) 
+	    && s->dma_adc.ready) {
+		s->enable |= ADC_RUNNING;
+		trident_enable_voice_irq(s->card, s->dma_adc.chan[0]);
+		outb(s->bDMAStart, TRID_REG(s->card, T4D_SBCTRL_SBE2R_SBDD));
+		trident_start_voice(s->card, s->dma_adc.chan[0]);
+		M_printk("(trident) starting ADC\n");
+	
+	}
+	spin_unlock_irqrestore(&s->card->lock, flags);
+}	
+
+/* --------------------------------------------------------------------- */
+
+/* we allocate both buffers at once */
+#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
+#define DMABUF_MINORDER 2
+
+static void dealloc_dmabuf(struct dmabuf *db)
+{
+	unsigned long map, mapend;
+
+	if (db->rawbuf) 
+	{
+		M_printk("(trident) freeing %p\n",db->rawbuf);
+		/* undo marking the pages as reserved */
+		mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
+		for (map = MAP_NR(db->rawbuf); map <= mapend; map++)
+			clear_bit(PG_reserved, &mem_map[map].flags);	
+		free_pages((unsigned long)db->rawbuf, db->buforder);
+	}
+	db->rawbuf = NULL;
+	db->mapped = db->ready = 0;
+}
+
+static int prog_dmabuf(struct trident_state *s, unsigned rec)
+{
+	struct dmabuf *db = rec ? &s->dma_adc : &s->dma_dac;
+	unsigned rate = rec ? s->rateadc : s->ratedac;
+	int order;
+	unsigned bytepersec;
+	unsigned bufs;
+	unsigned long map, mapend;
+	unsigned char fmt;
+	unsigned long flags;
+
+	spin_lock_irqsave(&s->card->lock, flags);
+	fmt = s->fmt;
+	if (rec) {
+		s->enable &= ~TRIDENT_ENABLE_RE;
+		fmt >>= TRIDENT_ADC_SHIFT;
+	} else {
+		s->enable &= ~TRIDENT_ENABLE_PE;
+		fmt >>= TRIDENT_DAC_SHIFT;
+	}
+	spin_unlock_irqrestore(&s->card->lock, flags);
+	fmt &= TRIDENT_FMT_MASK;
+
+	db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
+
+	if (!db->rawbuf) {
+		void *rawbuf;
+		/* haha, this thing is hacked to hell and back.
+			this is so ugly. */
+		s->dma_dac.ready = s->dma_dac.mapped = 0;
+		s->dma_adc.ready = s->dma_adc.mapped = 0;
+
+		/* alloc as big a chunk as we can */
+		for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
+			if((rawbuf = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, order)))
+
+				break;
+
+		if (!rawbuf)
+			return -ENOMEM;
+
+
+		/* we allocated both buffers */
+		s->dma_adc.rawbuf = rawbuf;
+		s->dma_dac.rawbuf = rawbuf + ( PAGE_SIZE << (order - 1) );
+
+		M_printk("(trident) allocated %ld bytes at %p\n",PAGE_SIZE<<order, db->rawbuf);
+
+		s->dma_adc.buforder = s->dma_dac.buforder = order - 1;
+
+		/* XXX these checks are silly now */
+#if 0
+		if ((virt_to_bus(db->rawbuf) ^ (virt_to_bus(db->rawbuf) + (PAGE_SIZE << order) - 1)) & ~0xffff)
+			printk(KERN_DEBUG "trident: DMA buffer crosses 64k boundary: busaddr 0x%lx  size %ld\n", 
+			       virt_to_bus(db->rawbuf), PAGE_SIZE << order);
+
+#endif
+		if ((virt_to_bus(db->rawbuf) + (PAGE_SIZE << order) - 1) & ~0xffffff)
+			M_printk(KERN_DEBUG "(trident) DMA buffer beyond 16MB: busaddr 0x%lx  size %ld\n", 
+			       virt_to_bus(db->rawbuf), PAGE_SIZE << order);
+
+		/* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
+		mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << order) - 1);
+		for (map = MAP_NR(db->rawbuf); map <= mapend; map++)
+			set_bit(PG_reserved, &mem_map[map].flags);
+	}
+	bytepersec = rate << sample_shift[fmt];
+	bufs = PAGE_SIZE << db->buforder;
+	if (db->ossfragshift) {
+		if ((1000 << db->ossfragshift) < bytepersec)
+			db->fragshift = ld2(bytepersec/1000);
+		else
+			db->fragshift = db->ossfragshift;
+	} else {
+	/*	lets hand out reasonable big ass buffers by default */
+		db->fragshift = (db->buforder + PAGE_SHIFT -2);
+#if 0
+		db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
+		if (db->fragshift < 3)
+			db->fragshift = 3; 
+#endif
+	}
+	db->numfrag = bufs >> db->fragshift;
+	while (db->numfrag < 4 && db->fragshift > 3) {
+		db->fragshift--;
+		db->numfrag = bufs >> db->fragshift;
+	}
+	db->fragsize = 1 << db->fragshift;
+	if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
+		db->numfrag = db->ossmaxfrags;
+	db->fragsamples = db->fragsize >> sample_shift[fmt];
+	db->dmasize = db->numfrag << db->fragshift;
+
+	memset(db->rawbuf, (fmt & TRIDENT_FMT_16BIT) ? 0 : 0x80, db->dmasize);
+
+	spin_lock_irqsave(&s->card->lock, flags);
+	if (rec) {
+		trident_rec_setup(s, fmt, s->rateadc, 
+			db->rawbuf, db->numfrag << db->fragshift);
+	} else {
+		trident_play_setup(s, fmt, s->ratedac, 
+			db->rawbuf, db->numfrag << db->fragshift);
+	}
+	spin_unlock_irqrestore(&s->card->lock, flags);
+	db->ready = 1;
+
+	return 0;
+}
+
+/* only called by trident_write */
+
+extern __inline__ void clear_advance(struct trident_state *s)
+{
+	unsigned char c = ((s->fmt >> TRIDENT_DAC_SHIFT) & TRIDENT_FMT_16BIT) ? 0 : 0x80;
+	unsigned char *buf = s->dma_dac.rawbuf;
+	unsigned bsize = s->dma_dac.dmasize;
+	unsigned bptr = s->dma_dac.swptr;
+	unsigned len = s->dma_dac.fragsize;
+
+	if (bptr + len > bsize) {
+		unsigned x = bsize - bptr;
+		memset(buf + bptr, c, x);
+		/* account for wrapping? */
+		bptr = 0;
+		len -= x;
+	}
+	memset(buf + bptr, c, len);
+}
+
+/* call with spinlock held! */
+static void trident_update_ptr(struct trident_state *s)
+{
+	unsigned hwptr;
+	int diff;
+
+	/* update ADC pointer */
+	if (s->dma_adc.ready) {
+		hwptr = get_dmac(s) % s->dma_adc.dmasize;
+		diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
+		s->dma_adc.hwptr = hwptr;
+		s->dma_adc.total_bytes += diff;
+		s->dma_adc.count += diff;
+		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) 
+			wake_up(&s->dma_adc.wait);
+		if (!s->dma_adc.mapped) {
+			if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) {
+				s->enable &= ~TRIDENT_ENABLE_RE;
+				__stop_adc(s); 
+				s->dma_adc.error++;
+			}
+		}
+	}
+	/* update DAC pointer */
+	if (s->dma_dac.ready) 
+	{
+		/* this is so gross.  */
+		hwptr = (/*s->dma_dac.dmasize -*/ get_dmaa(s)) % s->dma_dac.dmasize; 
+		diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
+		M_printk("(trident) updating dac: hwptr: %d diff: %d\n",hwptr,diff);
+		s->dma_dac.hwptr = hwptr;
+		s->dma_dac.total_bytes += diff;
+		if (s->dma_dac.mapped) 
+		{
+			s->dma_dac.count += diff;
+			if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
+				wake_up(&s->dma_dac.wait);
+		} 
+		else 
+		{
+			s->dma_dac.count -= diff;
+			M_printk("(trident) trident_update_ptr: diff: %d, count: %d\n", diff, s->dma_dac.count); 
+			if (s->dma_dac.count <= 0) 
+			{
+				s->enable &= ~TRIDENT_ENABLE_PE;
+				/* Lock already held */
+				__stop_dac(s);
+				/* brute force everyone back in sync, sigh */
+				s->dma_dac.count = 0; 
+				s->dma_dac.swptr = 0; 
+				s->dma_dac.hwptr = 0; 
+				s->dma_dac.error++;
+			} 
+			else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize && 
+					!s->dma_dac.endcleared) 
+			{
+				clear_advance(s);
+				s->dma_dac.endcleared = 1;
+			}
+
+			if (s->dma_dac.count + (signed)s->dma_dac.fragsize <= (signed)s->dma_dac.dmasize) 
+				wake_up(&s->dma_dac.wait);
+		}
+	}
+}
+
+/*
+ *	Trident interrupt handlers.
+ */
+ 
+static void trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+        struct trident_state *s;
+        struct trident_card *c = (struct trident_card *)dev_id;
+	int i;
+	u32 event;
+
+	spin_lock(&c->lock);
+	
+	event = inl(TRID_REG(c, T4D_MISCINT));
+	
+//	if(event & 0x28)
+//		printk("IRQ %04X (%08lX, %08lX)\n", event, c->iobase, TRID_REG(c, T4D_MISCINT));
+	
+	if(event & 8)
+	{
+		/* Midi - TODO */
+	}	
+	
+	if(event & 0x20)
+	{
+		/*
+		 *	Update the pointers for all channels we are running.
+		 */
+	 
+		for(i=0;i<NR_DSPS;i++)
+		{
+			s=&c->channels[i];
+			if(DidChannelInterrupt(c, i))
+			{
+				AckChannelInterrupt(c,i);
+				if(s->dev_audio != -1)
+					trident_update_ptr(s);
+				else
+				{
+					/* Spurious ? */
+					M_printk("(trident) spurious channel irq %d.\n", i);
+					trident_stop_voice(c, i);
+					trident_disable_voice_irq(c,i);
+				}
+			}
+		}
+		
+	}	
+	spin_unlock(&c->lock);
+}
+
+
+/* --------------------------------------------------------------------- */
+
+static const char invalid_magic[] = KERN_CRIT "trident: invalid magic value in %s\n";
+
+#define VALIDATE_MAGIC(FOO,MAG)                         \
+({                                                \
+	if (!(FOO) || (FOO)->magic != MAG) { \
+		printk(invalid_magic,__FUNCTION__);            \
+		return -ENXIO;                    \
+	}                                         \
+})
+
+#define VALIDATE_STATE(a) VALIDATE_MAGIC(a,TRIDENT_STATE_MAGIC)
+#define VALIDATE_CARD(a) VALIDATE_MAGIC(a,TRIDENT_CARD_MAGIC)
+
+static void set_mixer(struct trident_card *card,unsigned int mixer, unsigned int val ) 
+{
+	unsigned int left,right;
+	/* cleanse input a little */
+	right = ((val >> 8)  & 0xff) ;
+	left = (val  & 0xff) ;
+
+	if(right > 100) right = 100;
+	if(left > 100) left = 100;
+
+	card->mix.mixer_state[mixer]=(right << 8) | left;
+	card->mix.write_mixer(card,mixer,left,right);
+}
+
+static int mixer_ioctl(struct trident_card *card, unsigned int cmd, unsigned long arg)
+{
+	unsigned long flags;
+	int i, val=0;
+
+	VALIDATE_CARD(card);
+        if (cmd == SOUND_MIXER_INFO) {
+		mixer_info info;
+		strncpy(info.id, card_names[card->card_type], sizeof(info.id));
+		strncpy(info.name,card_names[card->card_type],sizeof(info.name));
+		info.modify_counter = card->mix.modcnt;
+		if (copy_to_user((void *)arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == SOUND_OLD_MIXER_INFO) {
+		_old_mixer_info info;
+		strncpy(info.id, card_names[card->card_type], sizeof(info.id));
+		strncpy(info.name,card_names[card->card_type],sizeof(info.name));
+		if (copy_to_user((void *)arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
+	}
+	if (cmd == OSS_GETVERSION)
+		return put_user(SOUND_VERSION, (int *)arg);
+
+	if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
+                return -EINVAL;
+
+        if (_IOC_DIR(cmd) == _IOC_READ) {
+                switch (_IOC_NR(cmd)) {
+                case SOUND_MIXER_RECSRC: /* give them the current record source */
+
+			if(!card->mix.recmask_io) {
+				val = 0;
+			} else {
+				spin_lock_irqsave(&card->lock, flags);
+				val = card->mix.recmask_io(card,1,0);
+				spin_unlock_irqrestore(&card->lock, flags);
+			}
+			break;
+			
+                case SOUND_MIXER_DEVMASK: /* give them the supported mixers */
+			val = card->mix.supported_mixers;
+			break;
+
+                case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */
+			val = card->mix.record_sources;
+			break;
+			
+                case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */
+			val = card->mix.stereo_mixers;
+			break;
+			
+                case SOUND_MIXER_CAPS:
+			val = SOUND_CAP_EXCL_INPUT;
+			break;
+
+		default: /* read a specific mixer */
+			i = _IOC_NR(cmd);
+
+			if ( ! supported_mixer(card,i)) 
+				return -EINVAL;
+
+			/* do we ever want to touch the hardware? */
+/*			spin_lock_irqsave(&s->lock, flags);
+			val = card->mix.read_mixer(card,i);
+			spin_unlock_irqrestore(&s->lock, flags);*/
+
+			val = card->mix.mixer_state[i];
+/*			printk("returned 0x%x for mixer %d\n",val,i);*/
+
+			break;
+		}
+		return put_user(val,(int *)arg);
+	}
+	
+        if (_IOC_DIR(cmd) != (_IOC_WRITE|_IOC_READ))
+		return -EINVAL;
+	
+	card->mix.modcnt++;
+
+	get_user_ret(val, (int *)arg, -EFAULT);
+
+	switch (_IOC_NR(cmd)) {
+	case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
+
+		if (!card->mix.recmask_io) return -EINVAL;
+		if(! (val &= card->mix.record_sources)) return -EINVAL;
+
+		spin_lock_irqsave(&card->lock, flags);
+		card->mix.recmask_io(card,0,val);
+		spin_unlock_irqrestore(&card->lock, flags);
+		return 0;
+
+	default:
+		i = _IOC_NR(cmd);
+
+		if ( ! supported_mixer(card,i)) 
+			return -EINVAL;
+
+		spin_lock_irqsave(&card->lock, flags);
+		set_mixer(card,i,val);
+		spin_unlock_irqrestore(&card->lock, flags);
+
+		return 0;
+	}
+}
+
+/* --------------------------------------------------------------------- */
+
+static loff_t trident_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+/* --------------------------------------------------------------------- */
+
+static int trident_open_mixdev(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+	struct trident_card *card = devs;
+
+	while (card && card->dev_mixer != minor)
+		card = card->next;
+	if (!card)
+		return -ENODEV;
+
+	file->private_data = card;
+	//FIXME put back in
+	//MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int trident_release_mixdev(struct inode *inode, struct file *file)
+{
+	struct trident_card *card = (struct trident_card *)file->private_data;
+
+	VALIDATE_CARD(card);
+	
+	//FIXME put back in
+	//MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static int trident_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct trident_card *card = (struct trident_card *)file->private_data;
+
+	VALIDATE_CARD(card);
+
+	return mixer_ioctl(card, cmd, arg);
+}
+
+static /*const*/ struct file_operations trident_mixer_fops = {
+	&trident_llseek,
+	NULL,  /* read */
+	NULL,  /* write */
+	NULL,  /* readdir */
+	NULL,  /* poll */
+	&trident_ioctl_mixdev,
+	NULL,  /* mmap */
+	&trident_open_mixdev,
+	NULL,	/* flush */
+	&trident_release_mixdev,
+	NULL,  /* fsync */
+	NULL,  /* fasync */
+	NULL,  /* check_media_change */
+	NULL,  /* revalidate */
+	NULL,  /* lock */
+};
+
+/* --------------------------------------------------------------------- */
+
+static int drain_dac(struct trident_state *s, int nonblock)
+{
+        DECLARE_WAITQUEUE(wait, current);
+	unsigned long flags;
+	int count;
+	signed long tmo;
+
+	if (s->dma_dac.mapped || !s->dma_dac.ready)
+		return 0;
+	current->state = TASK_INTERRUPTIBLE;
+	add_wait_queue(&s->dma_dac.wait, &wait);
+
+	for (;;) 
+	{
+		spin_lock_irqsave(&s->card->lock, flags);
+		count = s->dma_dac.count;
+		spin_unlock_irqrestore(&s->card->lock, flags);
+
+		if (count <= 0)
+			break;
+
+		if (signal_pending(current))
+			break;
+
+		if (nonblock) 
+		{
+			remove_wait_queue(&s->dma_dac.wait, &wait);
+			current->state = TASK_RUNNING;
+			return -EBUSY;
+		}
+
+		tmo = (count * HZ) / s->ratedac;
+		tmo >>= sample_shift[(s->fmt >> TRIDENT_DAC_SHIFT) & TRIDENT_FMT_MASK];
+
+		/* XXX this is just broken.  someone is waking us up alot, or schedule_timeout is broken.
+		or something.  who cares. - zach */
+		if (!schedule_timeout(tmo ? tmo : 1) && tmo)
+			printk(KERN_DEBUG "trident: dma timed out?? %ld\n",jiffies);
+	}
+	remove_wait_queue(&s->dma_dac.wait, &wait);
+	current->state = TASK_RUNNING;
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+	return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+/* in this loop, dma_adc.count signifies the amount of data thats waiting
+	to be copied to the user's buffer.  it is filled by the interrupt
+	handler and drained by this loop. */
+static ssize_t trident_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	struct trident_state *s = (struct trident_state *)file->private_data;
+	ssize_t ret;
+	unsigned long flags;
+	unsigned swptr;
+	int cnt;
+	
+	VALIDATE_STATE(s);
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (s->dma_adc.mapped)
+		return -ENXIO;
+	if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
+		return ret;
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+	ret = 0;
+
+	while (count > 0) {
+		spin_lock_irqsave(&s->card->lock, flags);
+		/* remember, all these things are expressed in bytes to be
+			sent to the user.. hence the evil / 2 down below */
+		swptr = s->dma_adc.swptr;
+		cnt = s->dma_adc.dmasize-swptr;
+		if (s->dma_adc.count < cnt)
+			cnt = s->dma_adc.count;
+		spin_unlock_irqrestore(&s->card->lock, flags);
+
+		if (cnt > count)
+			cnt = count;
+
+		if (cnt <= 0) {
+			start_adc(s);
+			if (file->f_flags & O_NONBLOCK) 
+			{
+				ret = ret ? ret : -EAGAIN;
+				return ret;
+			}
+			if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
+				M_printk(KERN_DEBUG "(trident) read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+				       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, 
+				       s->dma_adc.hwptr, s->dma_adc.swptr);
+				stop_adc(s);
+				spin_lock_irqsave(&s->card->lock, flags);
+//				set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
+				s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
+				spin_unlock_irqrestore(&s->card->lock, flags);
+			}
+			if (signal_pending(current)) 
+			{
+				ret = ret ? ret : -ERESTARTSYS;
+				return ret;
+			}
+			continue;
+		}
+	
+		if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {
+			ret = ret ? ret : -EFAULT;
+			return ret;
+		}
+
+		swptr = (swptr + cnt) % s->dma_adc.dmasize;
+		spin_lock_irqsave(&s->card->lock, flags);
+		s->dma_adc.swptr = swptr;
+		s->dma_adc.count -= cnt;
+		spin_unlock_irqrestore(&s->card->lock, flags);
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+		start_adc(s);
+	}
+
+	return ret;
+}
+
+static ssize_t trident_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+	struct trident_state *s = (struct trident_state *)file->private_data;
+	ssize_t ret;
+	unsigned long flags;
+	unsigned swptr;
+	int cnt;
+	int mode = (s->fmt >> TRIDENT_DAC_SHIFT) & TRIDENT_FMT_MASK;
+
+	M_printk("(trident) trident_write: count %d\n", count);
+	
+	VALIDATE_STATE(s);
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (s->dma_dac.mapped)
+		return -ENXIO;
+	if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+		return ret;
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+	ret = 0;
+
+	while (count > 0) {
+		spin_lock_irqsave(&s->card->lock, flags);
+
+		if (s->dma_dac.count < 0) 
+		{
+			s->dma_dac.count = 0;
+			s->dma_dac.swptr = s->dma_dac.hwptr;
+		}
+		swptr = s->dma_dac.swptr;
+
+		cnt = s->dma_dac.dmasize-swptr;
+
+		if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
+			cnt = s->dma_dac.dmasize - s->dma_dac.count;
+
+		spin_unlock_irqrestore(&s->card->lock, flags);
+
+		if (cnt > count)
+			cnt = count;
+
+		if (cnt <= 0) 
+		{
+			/* buffer is full, wait for it to be played */
+			start_dac(s);
+			if (file->f_flags & O_NONBLOCK) 
+			{
+				if(!ret) ret = -EAGAIN;
+				return ret;
+			}
+			if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) 
+			{
+				M_printk(KERN_DEBUG 
+						"trident: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n", 
+						s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count, s->dma_dac.hwptr, 
+						s->dma_dac.swptr);
+				stop_dac(s);
+				spin_lock_irqsave(&s->card->lock, flags);
+//			set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
+				s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
+				spin_unlock_irqrestore(&s->card->lock, flags);
+			}
+			if (signal_pending(current)) 
+			{
+				if (!ret) ret = -ERESTARTSYS;
+				return ret;
+			}
+			continue;
+		}
+		if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt)) 
+		{
+			if (!ret)
+				ret = -EFAULT;
+			return ret;
+		}
+
+		swptr = (swptr + cnt) % s->dma_dac.dmasize;
+
+		spin_lock_irqsave(&s->card->lock, flags);
+		s->dma_dac.swptr = swptr;
+		s->dma_dac.count += cnt;
+		s->dma_dac.endcleared = 0;
+		spin_unlock_irqrestore(&s->card->lock, flags);
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+		start_dac(s);
+	}
+	return ret;
+}
+
+static unsigned int trident_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct trident_state *s = (struct trident_state *)file->private_data;
+	unsigned long flags;
+	unsigned int mask = 0;
+
+	VALIDATE_STATE(s);
+	if (file->f_mode & FMODE_WRITE)
+		poll_wait(file, &s->dma_dac.wait, wait);
+	if (file->f_mode & FMODE_READ)
+		poll_wait(file, &s->dma_adc.wait, wait);
+	spin_lock_irqsave(&s->card->lock, flags);
+	trident_update_ptr(s);
+	if (file->f_mode & FMODE_READ) {
+		if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+			mask |= POLLIN | POLLRDNORM;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		if (s->dma_dac.mapped) {
+			if (s->dma_dac.count >= (signed)s->dma_dac.fragsize) 
+				mask |= POLLOUT | POLLWRNORM;
+		} else {
+			if ((signed)s->dma_dac.dmasize >= s->dma_dac.count + (signed)s->dma_dac.fragsize)
+				mask |= POLLOUT | POLLWRNORM;
+		}
+	}
+	spin_unlock_irqrestore(&s->card->lock, flags);
+	return mask;
+}
+
+/* this needs to be fixed to deal with the dual apus/buffers */
+#if 0
+static int trident_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct trident_state *s = (struct trident_state *)file->private_data;
+	struct dmabuf *db;
+	int ret;
+	unsigned long size;
+
+	VALIDATE_STATE(s);
+	if (vma->vm_flags & VM_WRITE) {
+		if ((ret = prog_dmabuf(s, 1)) != 0)
+			return ret;
+		db = &s->dma_dac;
+	} else if (vma->vm_flags & VM_READ) {
+		if ((ret = prog_dmabuf(s, 0)) != 0)
+			return ret;
+		db = &s->dma_adc;
+	} else 
+		return -EINVAL;
+	if (vma->vm_offset != 0)
+		return -EINVAL;
+	size = vma->vm_end - vma->vm_start;
+	if (size > (PAGE_SIZE << db->buforder))
+		return -EINVAL;
+	if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
+		return -EAGAIN;
+	db->mapped = 1;
+	return 0;
+}
+#endif
+
+static int trident_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct trident_state *s = (struct trident_state *)file->private_data;
+	unsigned long flags;
+        audio_buf_info abinfo;
+        count_info cinfo;
+	int val, mapped, ret;
+	unsigned char fmtm, fmtd;
+
+/*	printk("trident: trident_ioctl: cmd %d\n", cmd);*/
+	
+	VALIDATE_STATE(s);
+  mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+		((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+
+	switch (cmd) 
+	{
+		case OSS_GETVERSION:
+		return put_user(SOUND_VERSION, (int *)arg);
+
+		case SNDCTL_DSP_SYNC:
+			if (file->f_mode & FMODE_WRITE)
+				return drain_dac(s, file->f_flags & O_NONBLOCK);
+		return 0;
+
+		case SNDCTL_DSP_SETDUPLEX:
+		/* XXX fix */
+		return 0;
+
+		case SNDCTL_DSP_GETCAPS:
+			return put_user(0/*DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP*/, (int *)arg);
+
+		case SNDCTL_DSP_RESET:
+			if (file->f_mode & FMODE_WRITE) 
+			{
+				stop_dac(s);
+				synchronize_irq();
+				s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
+			}
+			if (file->f_mode & FMODE_READ) 
+			{
+				stop_adc(s);
+				synchronize_irq();
+				s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
+			}
+		return 0;
+
+		case SNDCTL_DSP_SPEED:
+			get_user_ret(val, (int *)arg, -EFAULT);
+			if (val >= 0) 
+			{
+				if (file->f_mode & FMODE_READ) 
+				{
+					stop_adc(s);
+					s->dma_adc.ready = 0;
+					trident_set_adc_rate(s, val, 1);
+				}
+				if (file->f_mode & FMODE_WRITE) 
+				{
+					stop_dac(s);
+					s->dma_dac.ready = 0;
+					trident_set_dac_rate(s, val, 1);
+				}
+			}
+		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+
+		case SNDCTL_DSP_STEREO:
+			get_user_ret(val, (int *)arg, -EFAULT);
+			fmtd = 0;
+			fmtm = ~0;
+			if (file->f_mode & FMODE_READ) 
+			{
+				stop_adc(s);
+				s->dma_adc.ready = 0;
+				if (val)
+					fmtd |= TRIDENT_FMT_STEREO << TRIDENT_ADC_SHIFT;
+				else
+					fmtm &= ~(TRIDENT_FMT_STEREO << TRIDENT_ADC_SHIFT);
+			}
+			if (file->f_mode & FMODE_WRITE) 
+			{
+				stop_dac(s);
+				s->dma_dac.ready = 0;
+				if (val)
+					fmtd |= TRIDENT_FMT_STEREO << TRIDENT_DAC_SHIFT;
+				else
+					fmtm &= ~(TRIDENT_FMT_STEREO << TRIDENT_DAC_SHIFT);
+			}
+			set_fmt(s, fmtm, fmtd);
+
+		return 0;
+
+		case SNDCTL_DSP_CHANNELS:
+			get_user_ret(val, (int *)arg, -EFAULT);
+			if (val != 0) 
+			{
+				fmtd = 0;
+				fmtm = ~0;
+
+				if (file->f_mode & FMODE_READ) 
+				{
+				stop_adc(s);
+				s->dma_adc.ready = 0;
+				if (val >= 2)
+					fmtd |= TRIDENT_FMT_STEREO << TRIDENT_ADC_SHIFT;
+				else
+					fmtm &= ~(TRIDENT_FMT_STEREO << TRIDENT_ADC_SHIFT);
+				}
+
+				if (file->f_mode & FMODE_WRITE) 
+				{
+					stop_dac(s);
+					s->dma_dac.ready = 0;
+					if (val >= 2)
+						fmtd |= TRIDENT_FMT_STEREO << TRIDENT_DAC_SHIFT;
+					else
+						fmtm &= ~(TRIDENT_FMT_STEREO << TRIDENT_DAC_SHIFT);
+				}
+				set_fmt(s, fmtm, fmtd);
+			}
+		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? 
+							(TRIDENT_FMT_STEREO << TRIDENT_ADC_SHIFT) : 
+							(TRIDENT_FMT_STEREO << TRIDENT_DAC_SHIFT))) ? 2 : 1, (int *)arg);
+
+		case SNDCTL_DSP_GETFMTS: /* Returns a mask */
+		return put_user(AFMT_S8|AFMT_S16_LE, (int *)arg);
+
+		case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
+			get_user_ret(val, (int *)arg, -EFAULT);
+			if (val != AFMT_QUERY) 
+			{
+				fmtd = 0;
+				fmtm = ~0;
+				if (file->f_mode & FMODE_READ) 
+				{
+					stop_adc(s);
+					s->dma_adc.ready = 0;
+					/* fixed at 16bit for now */
+					fmtd |= TRIDENT_FMT_16BIT << TRIDENT_ADC_SHIFT;
+#if 0
+					if (val == AFMT_S16_LE)
+					fmtd |= TRIDENT_FMT_16BIT << TRIDENT_ADC_SHIFT;
+					else
+					fmtm &= ~(TRIDENT_FMT_16BIT << TRIDENT_ADC_SHIFT);
+#endif
+				}
+				if (file->f_mode & FMODE_WRITE) 
+				{
+					stop_dac(s);
+					s->dma_dac.ready = 0;
+					if (val == AFMT_S16_LE)
+						fmtd |= TRIDENT_FMT_16BIT << TRIDENT_DAC_SHIFT;
+					else
+						fmtm &= ~(TRIDENT_FMT_16BIT << TRIDENT_DAC_SHIFT);
+				}
+				set_fmt(s, fmtm, fmtd);
+			}
+		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? 
+			(TRIDENT_FMT_16BIT << TRIDENT_ADC_SHIFT) : 
+			(TRIDENT_FMT_16BIT << TRIDENT_DAC_SHIFT))) ? 
+			AFMT_S16_LE : AFMT_S8, (int *)arg);
+
+		case SNDCTL_DSP_POST:
+		return 0;
+
+		case SNDCTL_DSP_GETTRIGGER:
+			val = 0;
+			if (file->f_mode & FMODE_READ && s->enable & TRIDENT_ENABLE_RE) 
+				val |= PCM_ENABLE_INPUT;
+			if (file->f_mode & FMODE_WRITE && s->enable & TRIDENT_ENABLE_PE) 
+				val |= PCM_ENABLE_OUTPUT;
+		return put_user(val, (int *)arg);
+
+		case SNDCTL_DSP_SETTRIGGER:
+			get_user_ret(val, (int *)arg, -EFAULT);
+			if (file->f_mode & FMODE_READ) 
+			{
+				if (val & PCM_ENABLE_INPUT) 
+				{
+					if (!s->dma_adc.ready && (ret =  prog_dmabuf(s, 1)))
+						return ret;
+					start_adc(s);
+				} 
+				else
+					stop_adc(s);
+			}
+			if (file->f_mode & FMODE_WRITE) 
+			{
+				if (val & PCM_ENABLE_OUTPUT) 
+				{
+					if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+						return ret;
+					start_dac(s);
+				} 
+				else
+					stop_dac(s);
+			}
+		return 0;
+
+		case SNDCTL_DSP_GETOSPACE:
+			if (!(file->f_mode & FMODE_WRITE))
+				return -EINVAL;
+			if (!(s->enable & TRIDENT_ENABLE_PE) && (val = prog_dmabuf(s, 0)) != 0)
+				return val;
+			spin_lock_irqsave(&s->card->lock, flags);
+			trident_update_ptr(s);
+			abinfo.fragsize = s->dma_dac.fragsize;
+			abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
+			abinfo.fragstotal = s->dma_dac.numfrag;
+			abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;      
+			spin_unlock_irqrestore(&s->card->lock, flags);
+		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+		case SNDCTL_DSP_GETISPACE:
+			if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+			if (!(s->enable & TRIDENT_ENABLE_RE) && (val = prog_dmabuf(s, 1)) != 0)
+			return val;
+			spin_lock_irqsave(&s->card->lock, flags);
+			trident_update_ptr(s);
+			abinfo.fragsize = s->dma_adc.fragsize;
+			abinfo.bytes = s->dma_adc.count;
+			abinfo.fragstotal = s->dma_adc.numfrag;
+			abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;      
+			spin_unlock_irqrestore(&s->card->lock, flags);
+		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+		case SNDCTL_DSP_NONBLOCK:
+			file->f_flags |= O_NONBLOCK;
+		return 0;
+
+		case SNDCTL_DSP_GETODELAY:
+			if (!(file->f_mode & FMODE_WRITE))
+				return -EINVAL;
+			spin_lock_irqsave(&s->card->lock, flags);
+			trident_update_ptr(s);
+			val = s->dma_dac.count;
+			spin_unlock_irqrestore(&s->card->lock, flags);
+		return put_user(val, (int *)arg);
+
+		case SNDCTL_DSP_GETIPTR:
+			if (!(file->f_mode & FMODE_READ))
+				return -EINVAL;
+			spin_lock_irqsave(&s->card->lock, flags);
+			trident_update_ptr(s);
+			cinfo.bytes = s->dma_adc.total_bytes;
+			cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
+			cinfo.ptr = s->dma_adc.hwptr;
+			if (s->dma_adc.mapped)
+				s->dma_adc.count &= s->dma_adc.fragsize-1;
+			spin_unlock_irqrestore(&s->card->lock, flags);
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+		case SNDCTL_DSP_GETOPTR:
+			if (!(file->f_mode & FMODE_WRITE))
+				return -EINVAL;
+			spin_lock_irqsave(&s->card->lock, flags);
+			trident_update_ptr(s);
+			cinfo.bytes = s->dma_dac.total_bytes;
+			cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
+			cinfo.ptr = s->dma_dac.hwptr;
+			if (s->dma_dac.mapped)
+				s->dma_dac.count &= s->dma_dac.fragsize-1;
+			spin_unlock_irqrestore(&s->card->lock, flags);
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+		case SNDCTL_DSP_GETBLKSIZE:
+			if (file->f_mode & FMODE_WRITE) 
+			{
+				if ((val = prog_dmabuf(s, 0)))
+					return val;
+				return put_user(s->dma_dac.fragsize, (int *)arg);
+			}
+			if ((val = prog_dmabuf(s, 1)))
+				return val;
+		return put_user(s->dma_adc.fragsize, (int *)arg);
+
+		case SNDCTL_DSP_SETFRAGMENT:
+			get_user_ret(val, (int *)arg, -EFAULT);
+			if (file->f_mode & FMODE_READ) 
+			{
+				s->dma_adc.ossfragshift = val & 0xffff;
+				s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
+				if (s->dma_adc.ossfragshift < 4)
+					s->dma_adc.ossfragshift = 4;
+				if (s->dma_adc.ossfragshift > 15)
+					s->dma_adc.ossfragshift = 15;
+				if (s->dma_adc.ossmaxfrags < 4)
+					s->dma_adc.ossmaxfrags = 4;
+			}
+			if (file->f_mode & FMODE_WRITE) 
+			{
+				s->dma_dac.ossfragshift = val & 0xffff;
+				s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
+				if (s->dma_dac.ossfragshift < 4)
+					s->dma_dac.ossfragshift = 4;
+				if (s->dma_dac.ossfragshift > 15)
+					s->dma_dac.ossfragshift = 15;
+				if (s->dma_dac.ossmaxfrags < 4)
+					s->dma_dac.ossmaxfrags = 4;
+			}
+		return 0;
+
+		case SNDCTL_DSP_SUBDIVIDE:
+			if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || 
+					(file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
+				return -EINVAL;
+			get_user_ret(val, (int *)arg, -EFAULT);
+			if (val != 1 && val != 2 && val != 4)
+				return -EINVAL;
+			if (file->f_mode & FMODE_READ)
+				s->dma_adc.subdivision = val;
+			if (file->f_mode & FMODE_WRITE)
+				s->dma_dac.subdivision = val;
+		return 0;
+
+		case SOUND_PCM_READ_RATE:
+		return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+
+		case SOUND_PCM_READ_CHANNELS:
+		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? 
+						(TRIDENT_FMT_STEREO << TRIDENT_ADC_SHIFT) : 
+						(TRIDENT_FMT_STEREO << TRIDENT_DAC_SHIFT))) ? 2 : 1, (int *)arg);
+
+		case SOUND_PCM_READ_BITS:
+		return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? 
+						(TRIDENT_FMT_16BIT << TRIDENT_ADC_SHIFT) : 
+						(TRIDENT_FMT_16BIT << TRIDENT_DAC_SHIFT))) ? 16 : 8, (int *)arg);
+
+		case SOUND_PCM_WRITE_FILTER:
+		case SNDCTL_DSP_SETSYNCRO:
+		case SOUND_PCM_READ_FILTER:
+		return -EINVAL;
+
+	}
+	return -EINVAL;
+}
+
+static int trident_open(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+	struct trident_card *c = devs;
+	struct trident_state *s = NULL, *sp;
+	int i;
+	unsigned char fmtm = ~0, fmts = 0;
+
+	/*
+	 *	Scan the cards and find the channel. We only
+	 *	do this at open time so it is ok
+	 */
+	 
+	while (c!=NULL)
+	{
+		for(i=0;i<NR_DSPS;i++)
+		{
+			sp=&c->channels[i];
+			if(sp->dev_audio < 0)
+				continue;
+			if((sp->dev_audio ^ minor) & ~0xf)
+				continue;
+			s=sp;
+		}
+		c=c->next;
+	}
+		
+	if (!s)
+		return -ENODEV;
+		
+	VALIDATE_STATE(s);
+	file->private_data = s;
+	/* wait for device to become free */
+	down(&s->open_sem);
+	while (s->open_mode & file->f_mode) 
+	{
+		if (file->f_flags & O_NONBLOCK) 
+		{
+			up(&s->open_sem);
+			return -EWOULDBLOCK;
+		}
+		up(&s->open_sem);
+		interruptible_sleep_on(&s->open_wait);
+		if (signal_pending(current))
+			return -ERESTARTSYS;
+		down(&s->open_sem);
+	}
+	if (file->f_mode & FMODE_READ) 
+	{
+/*
+		fmtm &= ~((TRIDENT_FMT_STEREO | TRIDENT_FMT_16BIT) << TRIDENT_ADC_SHIFT);
+		if ((minor & 0xf) == SND_DEV_DSP16)
+			fmts |= TRIDENT_FMT_16BIT << TRIDENT_ADC_SHIFT; */
+
+		fmtm = (TRIDENT_FMT_STEREO|TRIDENT_FMT_16BIT) << TRIDENT_ADC_SHIFT;
+
+		s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
+		trident_set_adc_rate(s, 8000, 0);
+	}
+	if (file->f_mode & FMODE_WRITE) 
+	{
+		fmtm &= ~((TRIDENT_FMT_STEREO | TRIDENT_FMT_16BIT) << TRIDENT_DAC_SHIFT);
+		if ((minor & 0xf) == SND_DEV_DSP16)
+			fmts |= TRIDENT_FMT_16BIT << TRIDENT_DAC_SHIFT;
+		s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
+		trident_set_dac_rate(s, 8000, 1);
+	}
+	set_fmt(s, fmtm, fmts);
+	s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+
+	up(&s->open_sem);
+	//FIXME put back in
+	//MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int trident_release(struct inode *inode, struct file *file)
+{
+	struct trident_state *s = (struct trident_state *)file->private_data;
+
+	VALIDATE_STATE(s);
+	if (file->f_mode & FMODE_WRITE)
+		drain_dac(s, file->f_flags & O_NONBLOCK);
+	down(&s->open_sem);
+	if (file->f_mode & FMODE_WRITE) {
+		stop_dac(s);
+	}
+	if (file->f_mode & FMODE_READ) {
+		stop_adc(s);
+	}
+
+	/* free our shared dma buffers */
+	dealloc_dmabuf(&s->dma_adc);
+	dealloc_dmabuf(&s->dma_dac);
+		
+	s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
+	/* we're covered by the open_sem */
+	up(&s->open_sem);
+	wake_up(&s->open_wait);
+	//FIXME put back in
+	//MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static /*const*/ struct file_operations trident_audio_fops = {
+	&trident_llseek,
+	&trident_read,
+	&trident_write,
+	NULL,  /* readdir */
+	&trident_poll,
+	&trident_ioctl,
+	NULL,	/* XXX &trident_mmap, */
+	&trident_open,
+	NULL,	/* flush */
+	&trident_release,
+	NULL,  /* fsync */
+	NULL,  /* fasync */
+	NULL,  /* check_media_change */
+	NULL,  /* revalidate */
+	NULL,  /* lock */
+};
+
+#ifdef CONFIG_APM
+int trident_apm_callback(apm_event_t ae) {
+}
+#endif
+
+/* --------------------------------------------------------------------- */
+
+static int trident_install(struct pci_dev *pcidev, int card_type)
+{
+	u16 w;
+	u32 l;
+	unsigned long iobase;
+	int i;
+	struct trident_card *card;
+	struct trident_state *trident;
+	int num = 0;
+	u32 ChanDwordCount;
+	
+	iobase = pcidev->resource[0].start;
+	
+	if(check_region(iobase, 256))
+	{
+		M_printk(KERN_WARNING "(trident) can't allocate 256 bytes I/O at 0x%4.4lx\n", iobase);
+		return 0;
+	}
+
+	/* this was tripping up some machines */
+	if(pcidev->irq == 0) 
+	{
+		printk(KERN_WARNING "(trident) pci subsystem reports irq 0, this might not be correct.\n");
+	}
+
+	/* just to be sure */
+	pci_set_master(pcidev);
+	
+	pci_read_config_word(pcidev, PCI_COMMAND, &w);
+	if((w&(PCI_COMMAND_IO|PCI_COMMAND_MASTER)) != (PCI_COMMAND_IO|PCI_COMMAND_MASTER))
+	{
+		printk("(trident) BIOS did not enable I/O access.\n");
+		w|=PCI_COMMAND_IO|PCI_COMMAND_MASTER;
+		pci_write_config_word(pcidev, PCI_COMMAND,w);
+	}
+
+	card = kmalloc(sizeof(struct trident_card), GFP_KERNEL);
+
+	if(card == NULL)
+	{
+		printk(KERN_WARNING "(trident) out of memory\n");
+		return 0;
+	}
+	
+	memset(card, 0, sizeof(*card));
+
+#ifdef CONFIG_APM
+	printk("(trident) apm_reg_callback: %d\n",apm_register_callback(trident_apm_callback));
+#endif
+
+	card->iobase = iobase;
+	card->card_type = card_type;
+	card->irq = pcidev->irq;
+	card->next = devs;
+	card->magic = TRIDENT_CARD_MAGIC;
+	devs = card;
+
+	ChanDwordCount = card->ChanDwordCount = 2;
+	card->ChanPCM = 32;
+
+	card->ChRegs.lpChStart = card->ChRegs.data;
+	card->ChRegs.lpChStop = card->ChRegs.lpChStart + ChanDwordCount;
+	card->ChRegs.lpChAint = card->ChRegs.lpChStop + ChanDwordCount;
+	card->ChRegs.lpChAinten = card->ChRegs.lpChAint + ChanDwordCount;
+	card->ChRegs.lpAChStart = card->ChRegs.lpChAinten + ChanDwordCount;
+	card->ChRegs.lpAChStop = card->ChRegs.lpAChStart + ChanDwordCount;
+	card->ChRegs.lpAChAint = card->ChRegs.lpAChStop + ChanDwordCount;
+	card->ChRegs.lpAChAinten = card->ChRegs.lpAChAint + ChanDwordCount;
+	// Assign addresses.
+	card->ChRegs.lpAChStart[0] = T4D_START_A;
+	card->ChRegs.lpAChStop[0] = T4D_STOP_A;
+	card->ChRegs.lpAChAint[0] = T4D_AINT_A;
+	card->ChRegs.lpAChAinten[0] = T4D_AINTEN_A;
+
+
+	card->ChRegs.lpAChStart[1] = T4D_START_B;
+	card->ChRegs.lpAChStop[1] = T4D_STOP_B;
+	card->ChRegs.lpAChAint[1] = T4D_AINT_B;
+	card->ChRegs.lpAChAinten[1] = T4D_AINTEN_B;
+	
+
+	outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL));
+	trident_ac97_set(card, 0x0L  , 0L);
+	trident_ac97_set(card, 0x02L , 0L);
+	trident_ac97_set(card, 0x18L , 0L);
+
+	if(card->card_type == TYPE_4DWAVE_NX)
+	{
+	// Enable rear channels
+		outl(0x12, TRID_REG(card, NX_ACR0_AC97_COM_STAT));
+				// ...or not, since they sound ugly. :)
+				// outl(0x02, TRID_REG(card, NX_ACR0_AC97_COM_STAT));
+	// S/PDIF C Channel bits 0-31 : 48khz, SCMS disabled
+	// outl(0x200004, TRID_REG(card, NX_SPCSTATUS));
+	// Disable S/PDIF out, 48khz only from ac97 fifo
+		// outb(0x00, TRID_REG(card, NX_SPCTRL_SPCSO + 3));
+	}
+	else 
+	{
+		outl(0x02, TRID_REG(card, DX_ACR2_AC97_COM_STAT));
+	}
+     				        	        	        					 		        	                		
+	for(i=0;i<NR_DSPS;i++)
+	{
+		struct trident_state *s=&card->channels[i];
+
+		s->card = card;
+		init_waitqueue_head(&s->dma_adc.wait);
+		init_waitqueue_head(&s->dma_dac.wait);
+		init_waitqueue_head(&s->open_wait);
+		init_MUTEX(&s->open_sem);
+		s->magic = TRIDENT_STATE_MAGIC;
+		s->channel = i;		
+
+		if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf)
+			printk("(trident) BOTCH!\n");
+		
+		/*
+		 *	Now allocate the hardware resources
+		 */
+		
+		//s->dma_dac.chan[0] = AllocateChannelPCM(card);
+		s->dma_dac.chan[1] = AllocateChannelPCM(card);
+		//s->dma_adc.chan[0] = AllocateChannelPCM(card);
+		
+		/* register devices */
+		if ((s->dev_audio = register_sound_dsp(&trident_audio_fops, -1)) < 0)
+			break;
+	}
+	
+	num = i;
+	
+	/* clear the rest if we ran out of slots to register */
+	for(;i<NR_DSPS;i++)
+	{
+		struct trident_state *s=&card->channels[i];
+		s->dev_audio = -1;
+	}
+	
+	trident = &card->channels[0];
+
+	/*
+	 *	Ok card ready. Begin setup proper
+	 */
+
+	printk(KERN_INFO "(trident) Configuring %s found at IO 0x%04lX IRQ %d\n", 
+		card_names[card_type],card->iobase,card->irq);
+
+
+	/* stake our claim on the iospace */
+	request_region(iobase, 256, card_names[card_type]);
+	
+	/*
+	 *	Reset the CODEC
+	 */
+	 
+	trident_ac97_init(card);
+
+	if ((card->dev_mixer = register_sound_mixer(&trident_mixer_fops, -1)) < 0) 
+	{
+		printk("(trident) couldn't register mixer!\n");
+	} 
+	else 
+	{
+		int i;
+		for(i = 0 ; i < SOUND_MIXER_NRDEVICES ; i++) 
+		{
+			struct mixer_defaults *md = &mixer_defaults[i];
+
+			if(md->mixer == -1) 
+				break;
+			if(!supported_mixer(card,md->mixer)) 
+				continue;
+			set_mixer(card,md->mixer,md->value);
+		}
+	}
+	
+	if(request_irq(card->irq, trident_interrupt, SA_SHIRQ, card_names[card_type], card))
+	{
+		printk(KERN_ERR "(trident) unable to allocate irq %d,\n", card->irq);
+		unregister_sound_mixer(card->dev_mixer);
+		for(i=0;i<NR_DSPS;i++)
+		{
+			struct trident_state *s = &card->channels[i];
+			if(s->dev_audio != -1)
+				unregister_sound_dsp(s->dev_audio);
+		}
+		release_region(card->iobase, 256);		
+		kfree(card);
+		return 0;
+	}
+
+	init_timer(&debug_timer);	
+	debug_timer.function = trident_kick;
+	debug_timer.data = (unsigned long)card;
+	debug_timer.expires = jiffies+1;
+	
+//	add_timer(&debug_timer);
+
+	printk("(trident) %d channels configured.\n", num);
+
+	EnableEndInterrupts(card);
+	return 1; 
+}
+
+#ifdef MODULE
+int init_module(void)
+#else
+int __init init_trident(void)
+#endif
+{
+	struct pci_dev *pcidev = NULL;
+	int foundone = 0;
+
+	if (!pci_present())   /* No PCI bus in this machine! */
+		return -ENODEV;
+	printk(KERN_INFO "(trident) version " DRIVER_VERSION " time " __TIME__ " " __DATE__ "\n");
+
+	pcidev = NULL;
+
+	/*
+	 *	Find the 4DWave DX
+	 */
+
+	while( (pcidev = pci_find_device(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX, pcidev))!=NULL
+			&&
+		( trident_install(pcidev, TYPE_4DWAVE_DX) )) {
+			foundone=1;
+	}
+
+	/*
+	 *	Find the 4DWave NX
+	 */
+
+	while((pcidev = pci_find_device(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX, pcidev))!=NULL
+			&&
+		( trident_install(pcidev, TYPE_4DWAVE_NX) )) {
+			foundone=1;
+	}
+
+	if( ! foundone )
+		return -ENODEV;
+	return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Alan Cox <alan@redhat.com>");
+MODULE_DESCRIPTION("Trident 4DWave Driver");
+#ifdef M_DEBUG
+MODULE_PARM(debug,"i");
+#endif
+
+void cleanup_module(void)
+{
+	struct trident_card *s;
+
+#ifdef CONFIG_APM
+	apm_unregister_callback(trident_apm_callback);
+#endif
+
+	del_timer(&debug_timer);
+	
+	while ((s = devs)) {
+		int i;
+		devs = devs->next;
+		
+		
+		/* Kill interrupts, and SP/DIF */
+		
+		DisableEndInterrupts(s);
+		if(s->card_type == TYPE_4DWAVE_NX)
+			outb(0x00, TRID_REG(s, NX_SPCTRL_SPCSO+3));
+	
+		free_irq(s->irq, s);
+		unregister_sound_mixer(s->dev_mixer);
+		for(i=0;i<NR_DSPS;i++)
+		{
+			struct trident_state *trident = &s->channels[i];
+			if(trident->dev_audio != -1)
+				unregister_sound_dsp(trident->dev_audio);
+		}
+		release_region(s->iobase, 256);
+		kfree(s);
+	}
+	printk("(trident) unloading\n");
+}
+
+#endif /* MODULE */
+
+
diff -u --recursive --new-file v2.3.29/linux/drivers/sound/trident.h linux/drivers/sound/trident.h
--- v2.3.29/linux/drivers/sound/trident.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/sound/trident.h	Fri Dec  3 10:55:09 1999
@@ -0,0 +1,127 @@
+#ifndef __TRID4DWAVE_H
+#define __TRID4DWAVE_H
+
+/*
+ *  audio@tridentmicro.com
+ *  Fri Feb 19 15:55:28 MST 1999
+ *  Definitions for Trident 4DWave DX/NX chips
+ *
+ *
+ *   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.
+ *
+ */
+
+#ifndef PCI_VENDOR_ID_TRIDENT
+#define PCI_VENDOR_ID_TRIDENT          0x1023
+#endif
+#ifndef PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 
+#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000
+#endif
+#ifndef PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 
+#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001
+#endif
+
+/*
+ * Direct registers
+ */
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE  1
+#endif
+
+#define TRID_REG( trident, x ) ( (trident) -> iobase + (x) )
+
+#define CHANNEL_REGS    5
+#define CHANNEL_START   0xe0   // The first bytes of the contiguous register space.
+
+#define ID_4DWAVE_DX        0x2000
+#define ID_4DWAVE_NX        0x2001
+
+
+// Register definitions
+
+// Global registers
+
+// T2 legacy dma control registers.
+#define LEGACY_DMAR0                0x00  // ADR0
+#define LEGACY_DMAR4                0x04  // CNT0
+#define LEGACY_DMAR11               0x0b  // MOD 
+#define LEGACY_DMAR15               0x0f  // MMR 
+
+#define T4D_START_A		     0x80
+#define T4D_STOP_A		     0x84
+#define T4D_DLY_A		     0x88
+#define T4D_SIGN_CSO_A		     0x8c
+#define T4D_CSPF_A		     0x90
+#define T4D_CEBC_A		     0x94
+#define T4D_AINT_A		     0x98
+#define T4D_AINTEN_A		     0x9c
+#define T4D_LFO_GC_CIR               0xa0
+#define T4D_MUSICVOL_WAVEVOL         0xa8
+#define T4D_SBDELTA_DELTA_R          0xac
+#define T4D_MISCINT                  0xb0
+#define T4D_START_B                  0xb4
+#define T4D_STOP_B                   0xb8
+#define T4D_SBBL_SBCL                0xc0
+#define T4D_SBCTRL_SBE2R_SBDD        0xc4
+#define T4D_AINT_B                   0xd8
+#define T4D_AINTEN_B                 0xdc
+
+// MPU-401 UART
+#define T4D_MPU401_BASE             0x20
+#define T4D_MPUR0                   0x20
+#define T4D_MPUR1                   0x21
+#define T4D_MPUR2                   0x22
+#define T4D_MPUR3                   0x23
+
+// S/PDIF Registers
+#define NX_SPCTRL_SPCSO             0x24
+#define NX_SPLBA                    0x28
+#define NX_SPESO                    0x2c
+#define NX_SPCSTATUS                0x64
+
+// Channel Registers
+
+#define CH_DX_CSO_ALPHA_FMS         0xe0
+#define CH_DX_ESO_DELTA             0xe8
+#define CH_DX_FMC_RVOL_CVOL         0xec
+
+#define CH_NX_DELTA_CSO             0xe0
+#define CH_NX_DELTA_ESO             0xe8
+#define CH_NX_ALPHA_FMS_FMC_RVOL_CVOL 0xec
+
+#define CH_LBA                      0xe4
+#define CH_GVSEL_PAN_VOL_CTRL_EC    0xf0
+
+// AC-97 Registers
+
+#define DX_ACR0_AC97_W              0x40
+#define DX_ACR1_AC97_R              0x44
+#define DX_ACR2_AC97_COM_STAT       0x48
+
+#define NX_ACR0_AC97_COM_STAT       0x40
+#define NX_ACR1_AC97_W              0x44
+#define NX_ACR2_AC97_R_PRIMARY      0x48
+#define NX_ACR3_AC97_R_SECONDARY    0x4c
+
+#define AC97_SIGMATEL_DAC2INVERT    0x6E
+#define AC97_SIGMATEL_BIAS1         0x70
+#define AC97_SIGMATEL_BIAS2         0x72
+#define AC97_SIGMATEL_CIC1          0x76
+#define AC97_SIGMATEL_CIC2          0x78
+
+#endif				/* __TRID4DWAVE_H */
+
diff -u --recursive --new-file v2.3.29/linux/drivers/sound/waveartist.c linux/drivers/sound/waveartist.c
--- v2.3.29/linux/drivers/sound/waveartist.c	Fri Oct 22 13:21:51 1999
+++ linux/drivers/sound/waveartist.c	Thu Dec  2 15:41:02 1999
@@ -1656,7 +1656,7 @@
 
 		if (prev_auto_state != devc->no_autoselect)
 			vnc_configure_mixer(devc);
-		waveartist_mixer_set(devc, SOUND_MIXER_RECSRC, SOUND_MASK_MIC);
+
 		return 0;
 	}
 
diff -u --recursive --new-file v2.3.29/linux/drivers/usb/keyboard.c linux/drivers/usb/keyboard.c
--- v2.3.29/linux/drivers/usb/keyboard.c	Sun Nov  7 16:37:34 1999
+++ linux/drivers/usb/keyboard.c	Sat Nov 27 15:46:24 1999
@@ -219,7 +219,7 @@
         usb_set_protocol(dev, 0);
         usb_set_idle(dev, 0, 0);
         
-	kbd->irqpipe = usb_rcvctrlpipe(dev, endpoint->bEndpointAddress);
+	kbd->irqpipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
 	ret = usb_request_irq(dev, kbd->irqpipe,
 				usb_kbd_irq, endpoint->bInterval,
 				kbd, &kbd->irq_handler);
diff -u --recursive --new-file v2.3.29/linux/drivers/usb/mouse.c linux/drivers/usb/mouse.c
--- v2.3.29/linux/drivers/usb/mouse.c	Sun Nov  7 16:37:34 1999
+++ linux/drivers/usb/mouse.c	Sun Nov 28 09:21:45 1999
@@ -212,6 +212,8 @@
 
 /*
  * Look like a PS/2 mouse, please..
+ * In XFree86 (3.3.5 tested) you must select Protocol "NetMousePS/2",
+ *  then use your wheel as Button 4 and 5 via ZAxisMapping 4 5.
  *
  * The PS/2 protocol is fairly strange, but
  * oh, well, it's at least common..
diff -u --recursive --new-file v2.3.29/linux/drivers/usb/ohci-hcd.c linux/drivers/usb/ohci-hcd.c
--- v2.3.29/linux/drivers/usb/ohci-hcd.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/ohci-hcd.c	Sat Nov 27 15:46:24 1999
@@ -90,7 +90,7 @@
 {  
 	struct usb_ohci_ed *ed = td->ed;
 	if(lw0 != NULL) {
-		if(0 < 0 && (status == USB_ST_DATAUNDERRUN || status == USB_ST_NOERROR)) 
+		if((status == USB_ST_DATAUNDERRUN || status == USB_ST_NOERROR)) 
 			((struct ohci_state * )lw0)->status = data_len;
 		else
 			((struct ohci_state * )lw0)->status = status;
@@ -123,7 +123,7 @@
  
 	ret = handler(status, data, data_len, dev_id);
 	if(ret == 0) return 0; /* 0 .. do not requeue  */
-	if(status > 0) return -1; /* error occured do not requeue ? */
+	if(status < 0) return -1; /* error occured do not requeue ? */
 	ohci_trans_req(ohci, ed, 0, NULL, data, (ed->hwINFO >> 16) & 0x3f, (__OHCI_BAG) handler, (__OHCI_BAG) dev_id, INT_IN, sohci_int_handler); /* requeue int request */
  
 	return 0;
@@ -342,15 +342,13 @@
  
 static int sohci_terminate_bulk(struct usb_device *usb_dev, void * ed) 
 {
-	DECLARE_WAITQUEUE(wait, current);
 	
 	OHCI_DEBUG( printk("USB HC TERM_BULK>>>:%4x\n", (unsigned int) ed);)
  	
-	current->state = TASK_UNINTERRUPTIBLE;
-    usb_ohci_rm_ep(usb_dev, (struct usb_ohci_ed *) ed, sohci_blocking_handler, NULL, &wait, SEND);
-    schedule();
-    remove_wait_queue(&op_wakeup, &wait); 
-	return 1;
+	ED_setSTATE((struct usb_ohci_ed *)ed, ED_STOP);
+	 
+    usb_ohci_rm_ep(usb_dev, (struct usb_ohci_ed *) ed, NULL, NULL, NULL, 0);
+	return 0;
 }
 
 static int sohci_alloc_dev(struct usb_device *usb_dev)
@@ -382,7 +380,7 @@
 	struct ohci_device *dev = usb_to_ohci(usb_dev);
 
 	OHCI_DEBUG(printk("USB HC ***** free %x\n", usb_dev->devnum);)
-
+	wait_ms(10);
 	if(usb_dev->devnum >= 0) {
 		current->state = TASK_UNINTERRUPTIBLE;
     	cnt = usb_ohci_rm_function(usb_dev, sohci_blocking_handler, NULL, &wait);
@@ -409,7 +407,7 @@
 
 	struct ohci * ohci = usb_dev->bus->hcpriv;
 	
-	return readl(&ohci->regs->fmnumber) & 0xffff;
+	return ohci->hc_area->hcca.frame_no & 0xffff;
 }
 
 
@@ -509,7 +507,9 @@
 	for (i = 0; i < id->frame_count; i++) {
 		if(td[i]) {
 			td[i]->type |= DEL;
-			ed = td[i]->ed; printk(" %d", i);	
+			ed = td[i]->ed; 
+			OHCI_DEBUG(printk(" %d", i);)	
+			td[i] = NULL;
 		}
 	} 
 	if(ed) usb_ohci_rm_ep(id->usb_dev, ed, NULL, NULL, NULL, TD_RM);
@@ -1100,7 +1100,7 @@
 	__u32 * td_hw; 
 	
 	for(ed = ohci->ed_rm_list; ed != NULL; ed = ed->ed_prev) {
-		 OHCI_DEBUG(printk("USB HC ed_rm_list: %4x :\n", ed->hwINFO);)
+		 OHCI_DEBUG(printk("USB HC ed_rm_list: %4x :next : %p\n", ed->hwINFO, ed->ed_prev);)
 		  
   			
 		for( td_hw = &(ed->hwHeadP); (*td_hw & 0xfffffff0) != ed->hwTailP; td_hw = &(td->hwNextTD)) {
@@ -1483,6 +1483,8 @@
 static int handle_apm_event(apm_event_t event)
 {
 	static int down = 0;
+	struct ohci * ohci;
+	struct list_head *ohci_l;
 
 	switch (event) {
 	case APM_SYS_SUSPEND:
@@ -1491,6 +1493,12 @@
 			printk(KERN_DEBUG "ohci: received extra suspend event\n");
 			break;
 		}
+		for(ohci_l = ohci_hcd_list.next; ohci_l != &ohci_hcd_list; ohci_l = ohci_l->next) {
+			ohci = list_entry(ohci_l, struct ohci, ohci_hcd_list);
+			OHCI_DEBUG(printk("USB OHCI suspend: %p\n", ohci);)
+			writel(0xff, &ohci->regs->control); /* Suspend */
+		}
+		wait_ms(10);
 		down = 1;
 		break;
 	case APM_NORMAL_RESUME:
@@ -1499,8 +1507,14 @@
 			printk(KERN_DEBUG "ohci: received bogus resume event\n");
 			break;
 		}
+		for(ohci_l = ohci_hcd_list.next; ohci_l != &ohci_hcd_list; ohci_l = ohci_l->next) {
+			ohci = list_entry(ohci_l, struct ohci, ohci_hcd_list);
+			OHCI_DEBUG(printk("USB OHCI resume: %p\n", ohci);)
+			writel(0x7f, &ohci->regs->control); /* Resume */
+			wait_ms(20);
+			writel(0xBF, &ohci->regs->control); /* Operational */
+		}
 		down = 0;
-//		start_hc(ohci);
 		break;
 	}
 	return 0;
diff -u --recursive --new-file v2.3.29/linux/drivers/usb/ohci-root-hub.c linux/drivers/usb/ohci-root-hub.c
--- v2.3.29/linux/drivers/usb/ohci-root-hub.c	Fri Sep 10 23:57:36 1999
+++ linux/drivers/usb/ohci-root-hub.c	Sat Nov 27 15:46:24 1999
@@ -205,7 +205,7 @@
 					len = min(leni, min(sizeof(root_hub_config_des), wLength));
 					memcpy(data, root_hub_config_des, len); OK(len);
 				case (0x03): /* string descriptors */
-				default:
+				default: OK(-4);
 			}
 			break;
 		
@@ -229,13 +229,15 @@
 		case RH_GET_CONFIGURATION: 	*(__u8 *)data = 0x01; OK(1);
 
 		case RH_SET_CONFIGURATION: 	WR_RH_STAT( 0x10000); OK(0);
+
+		default: OK(-4);
 	}
 	
 	OHCI_DEBUG(printk("USB HC roothubstat1: %x \n", readl( &(ohci->regs->roothub.portstatus[0]) ));)
 	OHCI_DEBUG(printk("USB HC roothubstat2: %x \n", readl( &(ohci->regs->roothub.portstatus[1]) ));)
   		
 	
-	return req_reply;
+	return len;
 }
 
 /* prepare Interrupt pipe transaction data; HUB INTERRUPT ENDPOINT */ 
diff -u --recursive --new-file v2.3.29/linux/drivers/usb/proc_usb.c linux/drivers/usb/proc_usb.c
--- v2.3.29/linux/drivers/usb/proc_usb.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/usb/proc_usb.c	Sun Dec  5 08:42:03 1999
@@ -949,25 +949,6 @@
 
 static struct inode_operations proc_usb_device_inode_operations = {
         &proc_usb_device_file_operations,  /* file-ops */
-        NULL,                              /* create       */
-        NULL,                              /* lookup       */
-        NULL,                              /* link         */
-        NULL,                              /* unlink       */
-        NULL,                              /* symlink      */
-        NULL,                              /* mkdir        */
-        NULL,                              /* rmdir        */
-        NULL,                              /* mknod        */
-        NULL,                              /* rename       */
-        NULL,                              /* readlink     */
-        NULL,                              /* follow_link  */
-        NULL,                              /* get_block    */
-        NULL,                              /* readpage     */
-        NULL,                              /* writepage    */
-        NULL,                              /* flushpage    */
-        NULL,                              /* truncate     */
-        NULL,                              /* permission   */
-        NULL,                              /* smap         */
-        NULL                               /* revalidate   */
 };
 
 void proc_usb_add_bus(struct usb_bus *bus)
@@ -978,7 +959,7 @@
 	if (!usbdir)
 		return;
 	sprintf(buf, "%03d", bus->busnum);
-	if (!(bus->proc_entry = create_proc_entry(buf, S_IFDIR, usbdir)))
+	if (!(bus->proc_entry = proc_mkdir(buf, usbdir)))
 		return;
 	bus->proc_entry->data = bus;
 }
@@ -1024,7 +1005,7 @@
 
 int proc_usb_init (void)
 {
-	usbdir = create_proc_entry ("usb", S_IFDIR, proc_bus);
+	usbdir = proc_mkdir ("usb", proc_bus);
 	if (!usbdir) {
 		printk ("proc_usb: cannot create /proc/bus/usb entry\n");
 		return -1;
diff -u --recursive --new-file v2.3.29/linux/drivers/video/Config.in linux/drivers/video/Config.in
--- v2.3.29/linux/drivers/video/Config.in	Sun Nov  7 16:37:34 1999
+++ linux/drivers/video/Config.in	Thu Dec  2 20:02:32 1999
@@ -14,7 +14,7 @@
          bool '  nVidia Riva support (EXPERIMENTAL)' CONFIG_FB_RIVA
       fi
       if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then
-	 tristate '  Cirrus Logic suport (EXPERIMENTAL)' CONFIG_FB_CLGEN
+	 tristate '  Cirrus Logic support (EXPERIMENTAL)' CONFIG_FB_CLGEN
 	 tristate '  Permedia2 support (EXPERIMENTAL)' CONFIG_FB_PM2
 	 if [ "$CONFIG_FB_PM2" = "y" ]; then
 	    if [ "$CONFIG_PCI" = "y" ]; then
@@ -197,7 +197,7 @@
 	   "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
            "$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
 	   "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
-	   "$CONFIG_FB_P9100" = "y" -o \
+	   "$CONFIG_FB_P9100" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
 	   "$CONFIG_FB_RIVA" = "y" -o \
 	   "$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
 	   "$CONFIG_FB_3DFX" = "y" ]; then
@@ -214,7 +214,7 @@
 	      "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
               "$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
 	      "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
-	      "$CONFIG_FB_P9100" = "m" -o \
+	      "$CONFIG_FB_P9100" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
 	      "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB8 m
 	 fi
@@ -228,14 +228,14 @@
 	   "$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
 	   "$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
 	   "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
-	   "$CONFIG_FB_RIVA" = "y" -o \
+	   "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
 	   "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB16 y
       else
 	 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
 	      "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \
 	      "$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
-	      "$CONFIG_FB_Q40" = "m" -o \
+	      "$CONFIG_FB_Q40" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
 	      "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
 	      "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
 	      "$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
@@ -248,12 +248,14 @@
       if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
 	   "$CONFIG_FB_CLGEN" = "y" -o "$CONFIG_FB_VESA" = "y" -o \
 	   "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
+           "$CONFIG_FB_ATY128" = "y" -o \
 	   "$CONFIG_FB_CYBER2000" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB24 y
       else
 	 if [ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
 	      "$CONFIG_FB_CLGEN" = "m" -o "$CONFIG_FB_VESA" = "m" -o \
 	      "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
+	      "$CONFIG_FB_ATY128" = "m" -o \
 	      "$CONFIG_FB_CYBER2000" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB24 m
 	 fi
@@ -263,7 +265,7 @@
 	   "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
 	   "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
 	   "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
-	   "$CONFIG_FB_RIVA" = "y" -o \
+	   "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
 	   "$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
 	   "$CONFIG_FB_3DFX" = "y" ]; then
 	 define_tristate CONFIG_FBCON_CFB32 y
@@ -273,6 +275,7 @@
 	      "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
 	      "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
 	      "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
+	      "$CONFIG_FB_ATY128" = "m" -o \
               "$CONFIG_FB_SGIVW" = "m" ]; then
 	    define_tristate CONFIG_FBCON_CFB32 m
 	 fi
diff -u --recursive --new-file v2.3.29/linux/drivers/video/acornfb.c linux/drivers/video/acornfb.c
--- v2.3.29/linux/drivers/video/acornfb.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/video/acornfb.c	Thu Dec  2 15:41:02 1999
@@ -418,15 +418,19 @@
 
 	ext_ctl = acornfb_default_econtrol();
 
-	if (var->sync & FB_SYNC_HOR_HIGH_ACT)
-		ext_ctl |= VIDC20_ECTL_HS_HSYNC;
-	else
-		ext_ctl |= VIDC20_ECTL_HS_NHSYNC;
+	if (var->sync & FB_SYNC_COMP_HIGH_ACT) /* should be FB_SYNC_COMP */
+		ext_ctl |= VIDC20_ECTL_HS_NCSYNC | VIDC20_ECTL_VS_NCSYNC;
+	else {
+		if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+			ext_ctl |= VIDC20_ECTL_HS_HSYNC;
+		else
+			ext_ctl |= VIDC20_ECTL_HS_NHSYNC;
 
-	if (var->sync & FB_SYNC_VERT_HIGH_ACT)
-		ext_ctl |= VIDC20_ECTL_VS_VSYNC;
-	else
-		ext_ctl |= VIDC20_ECTL_VS_NVSYNC;
+		if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+			ext_ctl |= VIDC20_ECTL_VS_VSYNC;
+		else
+			ext_ctl |= VIDC20_ECTL_VS_NVSYNC;
+	}
 
 	outl(VIDC20_ECTL | ext_ctl, IO_VIDC_BASE);
 
@@ -1211,43 +1215,55 @@
  * Everything after here is initialisation!!!
  */
 static struct fb_videomode modedb[] __initdata = {
-	{	/* 640x250 @ 50Hz, 15.6 kHz hsync */
-		NULL, 50, 640, 250, 62500, 185, 123,  38, 21,  76, 3,
+	{	/* 320x256 @ 50Hz */
+		NULL, 50,  320,  256, 125000,  92,  62,  35, 19,  38, 2,
+		FB_SYNC_COMP_HIGH_ACT,
+		FB_VMODE_NONINTERLACED
+	}, {	/* 640x250 @ 50Hz, 15.6 kHz hsync */
+		NULL, 50,  640,  250,  62500, 185, 123,  38, 21,  76, 3,
 		0,
 		FB_VMODE_NONINTERLACED
 	}, {	/* 640x256 @ 50Hz, 15.6 kHz hsync */
-		NULL, 50, 640, 256, 62500, 185, 123,  35, 18,  76, 3,
+		NULL, 50,  640,  256,  62500, 185, 123,  35, 18,  76, 3,
 		0,
 		FB_VMODE_NONINTERLACED
 	}, {	/* 640x512 @ 50Hz, 26.8 kHz hsync */
-		NULL, 50, 640, 512, 41667, 113,  87,  18,  1,  56, 3,
+		NULL, 50,  640,  512,  41667, 113,  87,  18,  1,  56, 3,
 		0,
 		FB_VMODE_NONINTERLACED
 	}, {	/* 640x250 @ 70Hz, 31.5 kHz hsync */
-		NULL, 70, 640, 250, 39722,  48,  16, 109, 88,  96, 2,
+		NULL, 70,  640,  250,  39722,  48,  16, 109, 88,  96, 2,
 		0,
 		FB_VMODE_NONINTERLACED
 	}, {	/* 640x256 @ 70Hz, 31.5 kHz hsync */
-		NULL, 70, 640, 256, 39722,  48,  16, 106, 85,  96, 2,
+		NULL, 70,  640,  256,  39722,  48,  16, 106, 85,  96, 2,
 		0,
 		FB_VMODE_NONINTERLACED
 	}, {	/* 640x352 @ 70Hz, 31.5 kHz hsync */
-		NULL, 70, 640, 352, 39722,  48,  16,  58, 37,  96, 2,
+		NULL, 70,  640,  352,  39722,  48,  16,  58, 37,  96, 2,
 		0,
 		FB_VMODE_NONINTERLACED
 	}, {	/* 640x480 @ 60Hz, 31.5 kHz hsync */
-		NULL, 60, 640, 480, 39722,  48,  16,  32, 11,  96, 2,
+		NULL, 60,  640,  480,  39722,  48,  16,  32, 11,  96, 2,
 		0,
 		FB_VMODE_NONINTERLACED
 	}, {	/* 800x600 @ 56Hz, 35.2 kHz hsync */
-		NULL, 56, 800, 600, 27778, 101,  23,  22,  1, 100, 2,
+		NULL, 56,  800,  600,  27778, 101,  23,  22,  1, 100, 2,
 		0,
 		FB_VMODE_NONINTERLACED
 	}, {	/* 896x352 @ 60Hz, 21.8 kHz hsync */
-		NULL, 60, 896, 352, 41667,  59,  27,   9,  0, 118, 3,
+		NULL, 60,  896,  352,  41667,  59,  27,   9,  0, 118, 3,
+		0,
+		FB_VMODE_NONINTERLACED
+	}, {	/* 1024x 768 @ 60Hz, 48.4 kHz hsync */
+		NULL, 60, 1024,  768,  15385, 160,  24,  29,  3, 136, 6,
 		0,
 		FB_VMODE_NONINTERLACED
-	},
+	}, {	/* 1280x1024 @ 60Hz, 63.8 kHz hsync */
+		NULL, 60, 1280, 1024,   9090, 186,  96,  38,  1, 160, 3,
+		0,
+		FB_VMODE_NONINTERLACED
+	}
 };
 
 static struct fb_videomode __initdata
diff -u --recursive --new-file v2.3.29/linux/drivers/video/atafb.c linux/drivers/video/atafb.c
--- v2.3.29/linux/drivers/video/atafb.c	Thu Nov 11 20:11:49 1999
+++ linux/drivers/video/atafb.c	Sat Nov 27 19:38:13 1999
@@ -71,6 +71,7 @@
 #include <linux/fb.h>
 #include <asm/atarikb.h>
 
+#include <video/fbcon.h>
 #include <video/fbcon-cfb8.h>
 #include <video/fbcon-cfb16.h>
 #include <video/fbcon-iplan2p2.h>
diff -u --recursive --new-file v2.3.29/linux/drivers/video/cyber2000fb.c linux/drivers/video/cyber2000fb.c
--- v2.3.29/linux/drivers/video/cyber2000fb.c	Thu Nov 18 20:25:37 1999
+++ linux/drivers/video/cyber2000fb.c	Thu Dec  2 15:41:02 1999
@@ -622,18 +622,32 @@
 static int
 cyber2000fb_decode_clock(struct par_info *hw, struct fb_var_screeninfo *var)
 {
+	static unsigned int divisors_2000[] = { 1, 2, 4, 8 };
+	static unsigned int divisors_2010[] = { 1, 2, 4, 6 };
 	unsigned long pll_ps = var->pixclock;
 	unsigned long ref_ps = 69842;
+	unsigned int *divisors;
 	int div2, div1, mult;
 
 	/*
 	 * Step 1:
-	 *   find div2 such that 150MHz < fpll < 220MHz
+	 *   find div2 such that 115MHz < fpll < 257MHz
 	 *   and 0 <= div2 < 4
 	 */
-	for (div2 = 0; div2 < 4; div2++, pll_ps >>= 1)
-		if (6667 > pll_ps && pll_ps > 4545)
+	if (current_par.dev_id == PCI_DEVICE_ID_INTERG_2010)
+		divisors = divisors_2010;
+	else
+		divisors = divisors_2000;
+
+	for (div2 = 0; div2 < 4; div2++) {
+		unsigned long new_pll;
+
+		new_pll = pll_ps / divisors[div2];
+		if (8696 > new_pll && new_pll > 3891) {
+			pll_ps = new_pll;
 			break;
+		}
+	}
 
 	if (div2 == 4)
 		return -EINVAL;
@@ -656,20 +670,22 @@
 			break;
 	}
 #else
-	if (pll_ps == 4630) {		/* 216.0, 108.0, 54.00, 27.000 */
-		mult = 181;		/* 4630   9260   18520  37040  */
+					/*  /1     /2     /4     /6     /8    */
+					/*                      (2010) (2000) */
+	if (pll_ps == 4630) {		/* 216.0, 108.0, 54.00, 36.000 27.000 */
+		mult = 181;		/* 4630   9260   18520  27780  37040  */
 		div1 = 12;
-	} else if (pll_ps == 4965) {	/* 201.0, 100.5, 50.25, 25.125 */
-		mult = 211;		/* 4965   9930   19860  39720  */
+	} else if (pll_ps == 4965) {	/* 201.0, 100.5, 50.25, 33.500 25.125 */
+		mult = 211;		/* 4965   9930   19860  29790  39720  */
 		div1 = 15;
-	} else if (pll_ps == 5050) {	/* 198.0,  99.0, 49.50, 24.750 */
-		mult = 83;		/* 5050   10100  20200  40400  */
+	} else if (pll_ps == 5050) {	/* 198.0,  99.0, 49.50, 33.000 24.750 */
+		mult = 83;		/* 5050   10100  20200  30300  40400  */
 		div1 = 6;
-	} else if (pll_ps == 6349) {	/* 158.0,  79.0, 39.50, 19.750 */
-		mult = 209;		/* 6349   12698  25396  50792  */
+	} else if (pll_ps == 6349) {	/* 158.0,  79.0, 39.50, 26.333 19.750 */
+		mult = 209;		/* 6349   12698  25396  38094  50792  */
 		div1 = 19;
-	} else if (pll_ps == 6422) {	/* 156.0,  78.0, 39.00, 19.500 */
-		mult = 190;		/* 6422   12844  25688  51376  */
+	} else if (pll_ps == 6422) {	/* 156.0,  78.0, 39.00, 26.000 19.500 */
+		mult = 190;		/* 6422   12844  25688  38532  51376  */
 		div1 = 17;
 	} else
 		return -EINVAL;
@@ -1043,6 +1059,29 @@
 	cyber2000fb_ioctl
 };
 
+int cyber2000fb_attach(struct cyberpro_info *info)
+{
+	if (current_par.initialised) {
+		info->regs    = CyberRegs;
+		info->fb      = current_par.screen_base;
+		info->fb_size = current_par.screen_size;
+
+		strncpy(info->dev_name, current_par.dev_name, sizeof(info->dev_name));
+
+		MOD_INC_USE_COUNT;
+	}
+
+	return current_par.initialised;
+}
+
+void cyber2000fb_detach(void)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+EXPORT_SYMBOL(cyber2000fb_attach);
+EXPORT_SYMBOL(cyber2000fb_detach);
+
 /*
  * These parameters give
  * 640x480, hsync 31.5kHz, vsync 60Hz
@@ -1244,6 +1283,7 @@
 
 	smem_base = dev->resource[0].start;
 	mmio_base = dev->resource[0].start + 0x00800000;
+	current_par.dev_id = dev->device;
 
 	/*
 	 * Map in the registers
diff -u --recursive --new-file v2.3.29/linux/drivers/video/cyber2000fb.h linux/drivers/video/cyber2000fb.h
--- v2.3.29/linux/drivers/video/cyber2000fb.h	Mon Nov  1 13:56:27 1999
+++ linux/drivers/video/cyber2000fb.h	Thu Dec  2 15:41:02 1999
@@ -51,6 +51,7 @@
 	  signed int	currcon;
 	char		dev_name[32];
 	unsigned int	initialised;
+	unsigned int	dev_id;
 
 	/*
 	 * palette
@@ -82,6 +83,120 @@
 #define VISUALID_16M		4
 #define VISUALID_32K		6
 
+#define K_CAP_X2_CTL1		0x49
+
+#define CAP_X_START		0x60
+#define CAP_X_END		0x62
+#define CAP_Y_START		0x64
+#define CAP_Y_END		0x66
+#define CAP_DDA_X_INIT		0x68
+#define CAP_DDA_X_INC		0x6a
+#define CAP_DDA_Y_INIT		0x6c
+#define CAP_DDA_Y_INC		0x6e
+
+#define EXT_FIFO_CTL		0x74
+
+#define CAP_PIP_X_START		0x80
+#define CAP_PIP_X_END		0x82
+#define CAP_PIP_Y_START		0x84
+#define CAP_PIP_Y_END		0x86
+
+#define CAP_NEW_CTL1		0x88
+
+#define CAP_NEW_CTL2		0x89
+
+#define CAP_MODE1		0xa4
+#define CAP_MODE1_8BIT			0x01	/* enable 8bit capture mode	*/
+#define CAP_MODE1_CCIR656		0x02	/* CCIR656 mode			*/
+#define CAP_MODE1_IGNOREVGT		0x04	/* ignore VGT			*/
+#define CAP_MODE1_ALTFIFO		0x10	/* use alternate FIFO for capture */
+#define CAP_MODE1_SWAPUV		0x20	/* swap UV bytes		*/
+#define CAP_MODE1_MIRRORY		0x40	/* mirror vertically		*/
+#define CAP_MODE1_MIRRORX		0x80	/* mirror horizontally		*/
+
+#define CAP_MODE2		0xa5
+
+#define Y_TV_CTL		0xae
+
+#define EXT_MEM_START		0xc0		/* ext start address 21 bits */
+#define HOR_PHASE_SHIFT		0xc2		/* high 3 bits */
+#define EXT_SRC_WIDTH		0xc3		/* ext offset phase  10 bits */
+#define EXT_SRC_HEIGHT		0xc4		/* high 6 bits */
+#define EXT_X_START		0xc5		/* ext->screen, 16 bits */
+#define EXT_X_END		0xc7		/* ext->screen, 16 bits */
+#define EXT_Y_START		0xc9		/* ext->screen, 16 bits */
+#define EXT_Y_END		0xcb		/* ext->screen, 16 bits */
+#define EXT_SRC_WIN_WIDTH	0xcd		/* 8 bits */
+#define EXT_COLOUR_COMPARE	0xce		/* 24 bits */
+#define EXT_DDA_X_INIT		0xd1		/* ext->screen 16 bits */
+#define EXT_DDA_X_INC		0xd3		/* ext->screen 16 bits */
+#define EXT_DDA_Y_INIT		0xd5		/* ext->screen 16 bits */
+#define EXT_DDA_Y_INC		0xd7		/* ext->screen 16 bits */
+
+#define VID_FIFO_CTL		0xd9
+
+#define VID_CAP_VFC		0xdb
+#define VID_CAP_VFC_YUV422		0x00	/* formats - does this cause conversion? */
+#define VID_CAP_VFC_RGB555		0x01
+#define VID_CAP_VFC_RGB565		0x02
+#define VID_CAP_VFC_RGB888_24		0x03
+#define VID_CAP_VFC_RGB888_32		0x04
+#define VID_CAP_VFC_DUP_PIX_ZOON	0x08	/* duplicate pixel zoom			*/
+#define VID_CAP_VFC_MOD_3RD_PIX		0x20	/* modify 3rd duplicated pixel		*/
+#define VID_CAP_VFC_DBL_H_PIX		0x40	/* double horiz pixels			*/
+#define VID_CAP_VFC_UV128		0x80	/* UV data offset by 128		*/
+
+#define VID_DISP_CTL1		0xdc
+#define VID_DISP_CTL1_INTRAM		0x01	/* video pixels go to internal RAM	*/
+#define VID_DISP_CTL1_IGNORE_CCOMP	0x02	/* ignore colour compare registers	*/
+#define VID_DISP_CTL1_NOCLIP		0x04	/* do not clip to 16235,16240		*/
+#define VID_DISP_CTL1_UV_AVG		0x08	/* U/V data is averaged			*/
+#define VID_DISP_CTL1_Y128		0x10	/* Y data offset by 128			*/
+#define VID_DISP_CTL1_VINTERPOL_OFF	0x20	/* vertical interpolation off		*/
+#define VID_DISP_CTL1_VID_OUT_WIN_FULL	0x40	/* video out window full		*/
+#define VID_DISP_CTL1_ENABLE_VID_WINDOW	0x80	/* enable video window			*/
+
+#define VID_FIFO_CTL1		0xdd
+
+#define VFAC_CTL1		0xe8
+#define VFAC_CTL1_CAPTURE		0x01	/* capture enable			*/
+#define VFAC_CTL1_VFAC_ENABLE		0x02	/* vfac enable				*/
+#define VFAC_CTL1_FREEZE_CAPTURE	0x04	/* freeze capture			*/
+#define VFAC_CTL1_FREEZE_CAPTURE_SYNC	0x08	/* sync freeze capture			*/
+#define VFAC_CTL1_VALIDFRAME_SRC	0x10	/* select valid frame source		*/
+#define VFAC_CTL1_PHILIPS		0x40	/* select Philips mode			*/
+#define VFAC_CTL1_MODVINTERPOLCLK	0x80	/* modify vertical interpolation clocl	*/
+
+#define VFAC_CTL2		0xe9
+#define VFAC_CTL2_INVERT_VIDDATAVALID	0x01	/* invert video data valid		*/
+#define VFAC_CTL2_INVERT_GRAPHREADY	0x02	/* invert graphic ready output sig	*/
+#define VFAC_CTL2_INVERT_DATACLK	0x04	/* invert data clock signal		*/
+#define VFAC_CTL2_INVERT_HSYNC		0x08	/* invert hsync input			*/
+#define VFAC_CTL2_INVERT_VSYNC		0x10	/* invert vsync input			*/
+#define VFAC_CTL2_INVERT_FRAME		0x20	/* invert frame odd/even input		*/
+#define VFAC_CTL2_INVERT_BLANK		0x40	/* invert blank output			*/
+#define VFAC_CTL2_INVERT_OVSYNC		0x80	/* invert other vsync input		*/
+
+#define VFAC_CTL3		0xea
+
+#define CAP_MEM_START		0xeb		/* 18 bits */
+#define CAP_MAP_WIDTH		0xed		/* high 6 bits */
+#define CAP_PITCH		0xee		/* 8 bits */
+
+#define CAP_CTL_MISC		0xef
+#define CAP_CTL_MISC_HDIV		0x01
+#define CAP_CTL_MISC_HDIV4		0x02
+#define CAP_CTL_MISC_ODDEVEN		0x04
+#define CAP_CTL_MISC_HSYNCDIV2		0x08
+#define CAP_CTL_MISC_SYNCTZHIGH		0x10
+#define CAP_CTL_MISC_SYNCTZOR		0x20
+#define CAP_CTL_MISC_DISPUSED		0x80
+
+#define REG_BANK		0xfa
+#define REG_BANK_Y			0x01
+#define REG_BANK_K			0x05
+
+
 #define CO_CMD_L_PATTERN_FGCOL	0x8000
 #define CO_CMD_L_INC_LEFT	0x0004
 #define CO_CMD_L_INC_UP		0x0002
@@ -102,3 +217,18 @@
 #define CO_REG_SRC_PTR		0xbf170
 #define CO_REG_DEST_PTR		0xbf178
 #define CO_REG_DEST_WIDTH	0xbf218
+
+struct cyberpro_info {
+	unsigned char	*regs;
+	char		*fb;
+	char		dev_name[32];
+	unsigned int	fb_size;
+};
+
+/*
+ * Note! Writing to the Cyber20x0 registers from an interrupt
+ * routine is definitely a bad idea atm.
+ */
+int cyber2000fb_attach(struct cyberpro_info *info);
+void cyber2000fb_detach(void);
+
diff -u --recursive --new-file v2.3.29/linux/drivers/video/dnfb.c linux/drivers/video/dnfb.c
--- v2.3.29/linux/drivers/video/dnfb.c	Thu Aug 26 13:05:40 1999
+++ linux/drivers/video/dnfb.c	Sat Nov 27 19:38:13 1999
@@ -14,6 +14,7 @@
 #include <linux/fb.h>
 #include <linux/module.h>
 
+#include <video/fbcon.h>
 #include <video/fbcon-mfb.h>
 
 
diff -u --recursive --new-file v2.3.29/linux/drivers/video/fbcon.c linux/drivers/video/fbcon.c
--- v2.3.29/linux/drivers/video/fbcon.c	Mon Oct 11 15:38:15 1999
+++ linux/drivers/video/fbcon.c	Sat Nov 27 19:38:13 1999
@@ -112,10 +112,11 @@
 #define LOGO_LINE	(LOGO_W/8)
 
 struct display fb_display[MAX_NR_CONSOLES];
+char con2fb_map[MAX_NR_CONSOLES];
 static int logo_lines;
 static int logo_shown = -1;
 /* Software scrollback */
-extern int fbcon_softback_size;
+int fbcon_softback_size = 32768;
 static unsigned long softback_buf, softback_curr;
 static unsigned long softback_in;
 static unsigned long softback_top, softback_end;
@@ -238,6 +239,84 @@
       cursor_timer.data = 0;
       cursor_timer.next = cursor_timer.next = NULL;
       add_timer(&cursor_timer);
+}
+
+int PROC_CONSOLE(const struct fb_info *info)
+{
+        int fgc;
+        
+        if (info->display_fg != NULL)
+                fgc = info->display_fg->vc_num;
+        else
+                return -1;
+                
+        if (!current->tty)
+                return fgc;
+
+        if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
+                /* XXX Should report error here? */
+                return fgc;
+
+        if (MINOR(current->tty->device) < 1)
+                return fgc;
+
+        return MINOR(current->tty->device) - 1;
+}
+
+int set_all_vcs(int fbidx, struct fb_ops *fb, struct fb_var_screeninfo *var,
+                struct fb_info *info)
+{
+    int unit, err;
+
+    var->activate |= FB_ACTIVATE_TEST;
+    err = fb->fb_set_var(var, PROC_CONSOLE(info), info);
+    var->activate &= ~FB_ACTIVATE_TEST;
+    if (err)
+            return err;
+    for (unit = 0; unit < MAX_NR_CONSOLES; unit++)
+            if (fb_display[unit].conp && con2fb_map[unit] == fbidx)
+                    fb->fb_set_var(var, unit, info);
+    return 0;
+}
+
+void set_con2fb_map(int unit, int newidx)
+{
+    int oldidx = con2fb_map[unit];
+    struct fb_info *oldfb, *newfb;
+    struct vc_data *conp;
+    char *fontdata;
+    unsigned short fontwidth, fontheight, fontwidthlog, fontheightlog;
+    int userfont;
+
+    if (newidx != con2fb_map[unit]) {
+       oldfb = registered_fb[oldidx];
+       newfb = registered_fb[newidx];
+       if (newfb->fbops->fb_open(newfb,0))
+           return;
+       oldfb->fbops->fb_release(oldfb,0);
+       conp = fb_display[unit].conp;
+       fontdata = fb_display[unit].fontdata;
+       fontwidth = fb_display[unit]._fontwidth;
+       fontheight = fb_display[unit]._fontheight;
+       fontwidthlog = fb_display[unit]._fontwidthlog;
+       fontheightlog = fb_display[unit]._fontheightlog;
+       userfont = fb_display[unit].userfont;
+       con2fb_map[unit] = newidx;
+       fb_display[unit] = *(newfb->disp);
+       fb_display[unit].conp = conp;
+       fb_display[unit].fontdata = fontdata;
+       fb_display[unit]._fontwidth = fontwidth;
+       fb_display[unit]._fontheight = fontheight;
+       fb_display[unit]._fontwidthlog = fontwidthlog;
+       fb_display[unit]._fontheightlog = fontheightlog;
+       fb_display[unit].userfont = userfont;
+       fb_display[unit].fb_info = newfb;
+       if (!newfb->changevar)
+           newfb->changevar = oldfb->changevar;
+       /* tell console var has changed */
+       if (newfb->changevar)
+           newfb->changevar(unit);
+   }
 }
 
 /*
diff -u --recursive --new-file v2.3.29/linux/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- v2.3.29/linux/drivers/video/fbmem.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/video/fbmem.c	Wed Dec  1 07:41:11 1999
@@ -20,7 +20,6 @@
 #include <linux/mman.h>
 #include <linux/tty.h>
 #include <linux/console.h>
-#include <linux/console_struct.h>
 #include <linux/init.h>
 #include <linux/proc_fs.h>
 #ifdef CONFIG_KMOD
@@ -30,15 +29,14 @@
 #if defined(__mc68000__) || defined(CONFIG_APUS)
 #include <asm/setup.h>
 #endif
-#ifdef __powerpc__
+
 #include <asm/io.h>
-#endif
 #include <asm/uaccess.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
 #include <linux/fb.h>
-
+#include <video/fbcon.h>
 
     /*
      *  Frame buffer device initialization and setup routines
@@ -228,36 +226,12 @@
 
 struct fb_info *registered_fb[FB_MAX];
 int num_registered_fb = 0;
-int fbcon_softback_size = 32768;
-
-char con2fb_map[MAX_NR_CONSOLES];
+extern int fbcon_softback_size; 
 
 static int first_fb_vc = 0;
 static int last_fb_vc = MAX_NR_CONSOLES-1;
 static int fbcon_is_default = 1;
 
-static int PROC_CONSOLE(const struct fb_info *info)
-{
-	int fgc;
-	
-	if (info->display_fg != NULL)
-		fgc = info->display_fg->vc_num;
-	else
-		return -1;
-		
-	if (!current->tty)
-		return fgc;
-
-	if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
-		/* XXX Should report error here? */
-		return fgc;
-
-	if (MINOR(current->tty->device) < 1)
-		return fgc;
-
-	return MINOR(current->tty->device) - 1;
-}
-
 static int fbmem_read_proc(char *buf, char **start, off_t offset,
 			   int len, int *eof, void *private)
 {
@@ -319,63 +293,6 @@
 	    return -EFAULT;
 	file->f_pos += copy_size;
 	return copy_size;
-}
-
-
-static int set_all_vcs(int fbidx, struct fb_ops *fb,
-		       struct fb_var_screeninfo *var, struct fb_info *info)
-{
-    int unit, err;
-
-    var->activate |= FB_ACTIVATE_TEST;
-    err = fb->fb_set_var(var, PROC_CONSOLE(info), info);
-    var->activate &= ~FB_ACTIVATE_TEST;
-    if (err)
-	    return err;
-    for (unit = 0; unit < MAX_NR_CONSOLES; unit++)
-	    if (fb_display[unit].conp && con2fb_map[unit] == fbidx)
-		    fb->fb_set_var(var, unit, info);
-    return 0;
-}
-
-static void set_con2fb_map(int unit, int newidx)
-{
-    int oldidx = con2fb_map[unit];
-    struct fb_info *oldfb, *newfb;
-    struct vc_data *conp;
-    char *fontdata;
-    unsigned short fontwidth, fontheight, fontwidthlog, fontheightlog;
-    int userfont;
-
-    if (newidx != con2fb_map[unit]) {
-       oldfb = registered_fb[oldidx];
-       newfb = registered_fb[newidx];
-       if (newfb->fbops->fb_open(newfb,0))
-	   return;
-       oldfb->fbops->fb_release(oldfb,0);
-       conp = fb_display[unit].conp;
-       fontdata = fb_display[unit].fontdata;
-       fontwidth = fb_display[unit]._fontwidth;
-       fontheight = fb_display[unit]._fontheight;
-       fontwidthlog = fb_display[unit]._fontwidthlog;
-       fontheightlog = fb_display[unit]._fontheightlog;
-       userfont = fb_display[unit].userfont;
-       con2fb_map[unit] = newidx;
-       fb_display[unit] = *(newfb->disp);
-       fb_display[unit].conp = conp;
-       fb_display[unit].fontdata = fontdata;
-       fb_display[unit]._fontwidth = fontwidth;
-       fb_display[unit]._fontheight = fontheight;
-       fb_display[unit]._fontwidthlog = fontwidthlog;
-       fb_display[unit]._fontheightlog = fontheightlog;
-       fb_display[unit].userfont = userfont;
-       fb_display[unit].fb_info = newfb;
-       if (!newfb->changevar)
-	   newfb->changevar = oldfb->changevar;
-       /* tell console var has changed */
-       if (newfb->changevar)
-	   newfb->changevar(unit);
-    }
 }
 
 #ifdef CONFIG_KMOD
diff -u --recursive --new-file v2.3.29/linux/drivers/video/hpfb.c linux/drivers/video/hpfb.c
--- v2.3.29/linux/drivers/video/hpfb.c	Thu Aug 26 13:05:40 1999
+++ linux/drivers/video/hpfb.c	Sat Nov 27 19:38:13 1999
@@ -22,6 +22,7 @@
 #include <asm/blinken.h>
 #include <asm/hwtest.h>
 
+#include <video/fbcon.h>
 #include <video/fbcon-mfb.h>
 #include <video/fbcon-cfb2.h>
 #include <video/fbcon-cfb4.h>
diff -u --recursive --new-file v2.3.29/linux/drivers/zorro/proc.c linux/drivers/zorro/proc.c
--- v2.3.29/linux/drivers/zorro/proc.c	Tue Nov 23 22:42:21 1999
+++ linux/drivers/zorro/proc.c	Sun Dec  5 08:42:03 1999
@@ -78,25 +78,6 @@
 
 static struct inode_operations proc_bus_zorro_inode_operations = {
 	&proc_bus_zorro_operations, /* default base directory file-ops */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* get_block */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* flushpage */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL,			/* smap */
-	NULL			/* revalidate */
 };
 
 static int
@@ -142,7 +123,7 @@
 	char name[4];
 
 	sprintf(name, "%02x", slot);
-	entry = create_proc_entry(name, S_IFREG | S_IRUGO, proc_bus_zorro_dir);
+	entry = create_proc_entry(name, 0, proc_bus_zorro_dir);
 	if (!entry)
 		return -ENOMEM;
 	entry->ops = &proc_bus_zorro_inode_operations;
@@ -157,7 +138,7 @@
 
 	if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
 		return;
-	proc_bus_zorro_dir = create_proc_entry("zorro", S_IFDIR, proc_bus);
+	proc_bus_zorro_dir = proc_mkdir("zorro", proc_bus);
 	create_proc_info_entry("devices", 0, proc_bus_zorro_dir, get_zorro_dev_info);
 	for (slot = 0; slot < zorro_num_autocon; slot++)
 	    zorro_proc_attach_device(slot);
diff -u --recursive --new-file v2.3.29/linux/fs/adfs/dir.c linux/fs/adfs/dir.c
--- v2.3.29/linux/fs/adfs/dir.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/adfs/dir.c	Sun Dec  5 08:42:03 1999
@@ -54,10 +54,8 @@
 	NULL,			/* get_block */
 	NULL,			/* read page */
 	NULL,			/* write page */
-	NULL,			/* flush page */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/adfs/file.c linux/fs/adfs/file.c
--- v2.3.29/linux/fs/adfs/file.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/adfs/file.c	Sun Dec  5 08:42:03 1999
@@ -64,9 +64,7 @@
 	adfs_bmap,		/* get_block			*/
 	block_read_full_page,	/* readpage			*/
 	NULL,			/* writepage			*/
-	NULL,			/* flushpage			*/
 	NULL,			/* truncate			*/
 	NULL,			/* permission			*/
-	NULL,			/* smap				*/
 	NULL			/* revalidate			*/
 };
diff -u --recursive --new-file v2.3.29/linux/fs/affs/dir.c linux/fs/affs/dir.c
--- v2.3.29/linux/fs/affs/dir.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/affs/dir.c	Sun Dec  5 08:42:03 1999
@@ -60,10 +60,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permissions */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/affs/file.c linux/fs/affs/file.c
--- v2.3.29/linux/fs/affs/file.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/affs/file.c	Sun Dec  5 08:42:03 1999
@@ -77,10 +77,8 @@
 	affs_bmap,		/* get_block */
 	block_read_full_page,	/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	affs_truncate,		/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
@@ -118,10 +116,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	affs_truncate,		/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/affs/symlink.c linux/fs/affs/symlink.c
--- v2.3.29/linux/fs/affs/symlink.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/affs/symlink.c	Sun Dec  5 08:42:03 1999
@@ -38,10 +38,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/autofs/dir.c linux/fs/autofs/dir.c
--- v2.3.29/linux/fs/autofs/dir.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/autofs/dir.c	Sun Dec  5 08:42:03 1999
@@ -76,10 +76,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/autofs/root.c linux/fs/autofs/root.c
--- v2.3.29/linux/fs/autofs/root.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/autofs/root.c	Sun Dec  5 08:42:03 1999
@@ -57,10 +57,8 @@
         NULL,                   /* get_block */
         NULL,                   /* readpage */
         NULL,                   /* writepage */
-        NULL,                   /* flushpage */
         NULL,                   /* truncate */
         NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/autofs/symlink.c linux/fs/autofs/symlink.c
--- v2.3.29/linux/fs/autofs/symlink.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/autofs/symlink.c	Sun Dec  5 08:42:03 1999
@@ -52,9 +52,7 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/bad_inode.c linux/fs/bad_inode.c
--- v2.3.29/linux/fs/bad_inode.c	Sat Jun 26 12:04:39 1999
+++ linux/fs/bad_inode.c	Sun Dec  5 08:42:03 1999
@@ -63,10 +63,8 @@
 	EIO_ERROR,		/* get_block */
 	EIO_ERROR,		/* readpage */
 	EIO_ERROR,		/* writepage */
-	EIO_ERROR,		/* flushpage */
 	EIO_ERROR,		/* truncate */
 	EIO_ERROR,		/* permission */
-	EIO_ERROR,		/* smap */
 	EIO_ERROR		/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/bfs/dir.c linux/fs/bfs/dir.c
--- v2.3.29/linux/fs/bfs/dir.c	Sun Nov  7 16:37:34 1999
+++ linux/fs/bfs/dir.c	Sun Dec  5 08:42:03 1999
@@ -283,10 +283,8 @@
 	get_block:		NULL,
 	readpage:		NULL,
 	writepage:		NULL,
-	flushpage:		NULL,
 	truncate:		NULL,
 	permission:		NULL,
-	smap:			NULL,
 	revalidate:		NULL
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/bfs/file.c linux/fs/bfs/file.c
--- v2.3.29/linux/fs/bfs/file.c	Sun Nov  7 16:37:34 1999
+++ linux/fs/bfs/file.c	Sun Dec  5 08:42:03 1999
@@ -68,9 +68,7 @@
 	get_block:		bfs_get_block,	
 	readpage:		block_read_full_page,
 	writepage:		block_write_full_page,
-	flushpage:		block_flushpage,
 	truncate:		NULL,
 	permission:		NULL,
-	smap:			NULL,
 	revalidate:		NULL
 };
diff -u --recursive --new-file v2.3.29/linux/fs/binfmt_misc.c linux/fs/binfmt_misc.c
--- v2.3.29/linux/fs/binfmt_misc.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/binfmt_misc.c	Sat Nov 27 15:27:49 1999
@@ -15,6 +15,7 @@
  *  1997-08-09 removed extension stripping, locking cleanup
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -475,7 +476,7 @@
 	int error = -ENOENT;
 	struct proc_dir_entry *status = NULL, *reg;
 
-	bm_dir = create_proc_entry("sys/fs/binfmt_misc", S_IFDIR, NULL);
+	bm_dir = proc_mkdir("sys/fs/binfmt_misc", NULL); /* WTF??? */
 	if (!bm_dir)
 		goto out;
 	bm_dir->owner = THIS_MODULE;
diff -u --recursive --new-file v2.3.29/linux/fs/buffer.c linux/fs/buffer.c
--- v2.3.29/linux/fs/buffer.c	Thu Nov 11 20:11:49 1999
+++ linux/fs/buffer.c	Sun Dec  5 08:42:03 1999
@@ -1236,7 +1236,7 @@
  * we have truncated the file and are going to free the
  * blocks on-disk..
  */
-int block_flushpage(struct inode *inode, struct page *page, unsigned long offset)
+int block_flushpage(struct page *page, unsigned long offset)
 {
 	struct buffer_head *head, *bh, *next;
 	unsigned int curr_off = 0;
@@ -1324,9 +1324,8 @@
  * block_write_full_page() is SMP-safe - currently it's still
  * being called with the kernel lock held, but the code is ready.
  */
-int block_write_full_page(struct file *file, struct page *page)
+int block_write_full_page(struct dentry *dentry, struct page *page)
 {
-	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	int err, i;
 	unsigned long block;
@@ -1379,24 +1378,17 @@
 	return err;
 }
 
-int block_write_partial_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
+int block_write_range(struct dentry *dentry, struct page *page,
+		unsigned zerofrom, unsigned from, unsigned to,
+		const char * buf)
 {
-	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
+	unsigned zeroto = 0, block_start, block_end;
 	unsigned long block;
-	int err, partial;
-	unsigned long blocksize, start_block, end_block;
-	unsigned long start_offset, start_bytes, end_bytes;
-	unsigned long bbits, blocks, i, len;
-	struct buffer_head *bh, *head;
-	char *target_buf, *kaddr;
-	int need_balance_dirty;
-
-	kaddr = (char *)kmap(page);
-	target_buf = kaddr + offset;
-
-	if (!PageLocked(page))
-		BUG();
+	int err = 0, partial = 0, need_balance_dirty = 0;
+	unsigned blocksize, bbits;
+	struct buffer_head *bh, *head, *wait[2], **wait_bh=wait;
+	char *kaddr = (char *)kmap(page);
 
 	blocksize = inode->i_sb->s_blocksize;
 	if (!page->buffers)
@@ -1405,49 +1397,21 @@
 
 	bbits = inode->i_sb->s_blocksize_bits;
 	block = page->index << (PAGE_CACHE_SHIFT - bbits);
-	blocks = PAGE_CACHE_SIZE >> bbits;
-	start_block = offset >> bbits;
-	end_block = (offset + bytes - 1) >> bbits;
-	start_offset = offset & (blocksize - 1);
-	start_bytes = blocksize - start_offset;
-	if (start_bytes > bytes)
-		start_bytes = bytes;
-	end_bytes = (offset+bytes) & (blocksize - 1);
-	if (end_bytes > bytes)
-		end_bytes = bytes;
-
-	if (offset < 0 || offset >= PAGE_SIZE)
-		BUG();
-	if (bytes+offset < 0 || bytes+offset > PAGE_SIZE)
-		BUG();
-	if (start_block < 0 || start_block >= blocks)
-		BUG();
-	if (end_block < 0 || end_block >= blocks)
-		BUG();
 
-	i = 0;
-	bh = head;
-	partial = 0;
-	need_balance_dirty = 0;
-	do {
+	/*
+	 * First pass - map what needs to be mapped, initiate reads
+	 * on the boundaries if needed (i.e. if block is partially covered
+	 * _and_ is not up-to-date _and_ is not new).
+	 */
+	for(bh = head, block_start = 0; bh != head || !block_start;
+	    block++, block_start=block_end, bh = bh->b_this_page) {
 		if (!bh)
 			BUG();
-
-		if ((i < start_block) || (i > end_block)) {
-			if (!buffer_uptodate(bh))
-				partial = 1;
-			goto skip;
-		}
-
-		/*
-		 * If the buffer is not up-to-date, we need to ask the low-level
-		 * FS to do something for us (we used to have assumptions about
-		 * the meaning of b_blocknr etc, that's bad).
-		 *
-		 * If "update" is set, that means that the low-level FS should
-		 * try to make sure that the block is up-to-date because we're
-		 * not going to fill it completely.
-		 */
+		block_end = block_start+blocksize;
+		if (block_end <= zerofrom)
+			continue;
+		if (block_start >= to)
+			break;
 		bh->b_end_io = end_buffer_io_sync;
 		if (!buffer_mapped(bh)) {
 			err = inode->i_op->get_block(inode, block, bh, 1);
@@ -1455,71 +1419,73 @@
 				goto out;
 			unmap_underlying_metadata(bh);
 		}
-
-		if (!buffer_uptodate(bh) && (start_offset || (end_bytes && (i == end_block)))) {
-			if (buffer_new(bh)) {
-				memset(kaddr + i*blocksize, 0, blocksize);
-			} else {
-				ll_rw_block(READ, 1, &bh);
-				wait_on_buffer(bh);
-				err = -EIO;
-				if (!buffer_uptodate(bh))
-					goto out;
-			}
+		if (buffer_new(bh)) {
+			zeroto = block_end;
+			if (block_start < zerofrom)
+				zerofrom = block_start;
+			continue;
+		}
+		if (!buffer_uptodate(bh) &&
+		     (block_start < zerofrom || block_end > to)) {
+			ll_rw_block(READ, 1, &bh);
+			*wait_bh++=bh;
 		}
-
-		len = blocksize;
-		if (start_offset) {
-			len = start_bytes;
-			start_offset = 0;
-		} else if (end_bytes && (i == end_block)) {
-			len = end_bytes;
-			end_bytes = 0;
-		}
-		if (target_buf >= kaddr + PAGE_SIZE)
-			BUG();
-		if (target_buf+len-1 >= kaddr + PAGE_SIZE)
-			BUG();
-		err = copy_from_user(target_buf, buf, len);
-		target_buf += len;
-		buf += len;
-
-		/*
-		 * we dirty buffers only after copying the data into
-		 * the page - this way we can dirty the buffer even if
-		 * the bh is still doing IO.
-		 *
-		 * NOTE! This also does a direct dirty balace check,
-		 * rather than relying on bdflush just waking up every
-		 * once in a while. This is to catch (and slow down)
-		 * the processes that write tons of buffer..
-		 *
-		 * Note how we do NOT want to do this in the full block
-		 * case: full pages are flushed not by the people who
-		 * dirtied them, but by people who need memory. And we
-		 * should not penalize them for somebody else writing
-		 * lots of dirty pages.
-		 */
-		set_bit(BH_Uptodate, &bh->b_state);
-		if (!test_and_set_bit(BH_Dirty, &bh->b_state)) {
-			__mark_dirty(bh, 0);
-			need_balance_dirty = 1;
-		}
-
-		if (err) {
-			err = -EFAULT;
+	}
+	/*
+	 * If we issued read requests - let them complete.
+	 */
+	while(wait_bh > wait) {
+		wait_on_buffer(*--wait_bh);
+		err = -EIO;
+		if (!buffer_uptodate(*wait_bh))
 			goto out;
+	}
+	/*
+	 * Now we can copy the data.
+	 */
+	if (zerofrom < from)
+		memset(kaddr+zerofrom, 0, from-zerofrom);
+	if (from < to)
+		err = copy_from_user(kaddr+from, buf, to-from);
+	if (to < zeroto)
+		memset(kaddr+to, 0, zeroto-to);
+	else
+		zeroto = to;
+	if (err < 0)
+		goto out;
+	/*
+	 * Second pass: check if all out-of-range blocks are up-to-date
+	 * and mark the rest up-to-date and dirty.
+	 *
+	 * NOTE! This also does a direct dirty balace check,
+	 * rather than relying on bdflush just waking up every
+	 * once in a while. This is to catch (and slow down)
+	 * the processes that write tons of buffer..
+	 *
+	 * Note how we do NOT want to do this in the full block
+	 * case: full pages are flushed not by the people who
+	 * dirtied them, but by people who need memory. And we
+	 * should not penalize them for somebody else writing
+	 * lots of dirty pages.
+	 */
+	for(bh = head, block_start = 0;
+	    bh != head || !block_start;
+	    block_start=block_end, bh = bh->b_this_page) {
+		block_end = block_start + blocksize;
+		if (block_end <= zerofrom || block_start >= zeroto) {
+			if (!buffer_uptodate(bh))
+				partial = 1;
+		} else {
+			set_bit(BH_Uptodate, &bh->b_state);
+			if (!test_and_set_bit(BH_Dirty, &bh->b_state)) {
+				__mark_dirty(bh, 0);
+				need_balance_dirty = 1;
+			}
 		}
-
-skip:
-		i++;
-		block++;
-		bh = bh->b_this_page;
-	} while (bh != head);
+	}
 
 	if (need_balance_dirty)
 		balance_dirty(bh->b_dev);
-
 	/*
 	 * is this a partial write that happened to make all buffers
 	 * uptodate then we can optimize away a bogus readpage() for
@@ -1529,183 +1495,48 @@
 	if (!partial)
 		SetPageUptodate(page);
 	kunmap(page);
-	return bytes;
+	return 0;
 out:
 	ClearPageUptodate(page);
 	kunmap(page);
 	return err;
 }
 
-/*
- * For moronic filesystems that do not allow holes in file.
- * we allow offset==PAGE_SIZE, bytes==0
- */
-
-int block_write_cont_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
+int block_write_partial_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
 {
 	struct dentry *dentry = file->f_dentry;
-	struct inode *inode = dentry->d_inode;
-	unsigned long block;
-	int err, partial;
-	unsigned long blocksize, start_block, end_block;
-	unsigned long start_offset, start_bytes, end_bytes;
-	unsigned long bbits, blocks, i, len;
-	struct buffer_head *bh, *head;
-	char * target_buf, *target_data;
-	unsigned long data_offset = offset;
-	int need_balance_dirty;
-
-	offset = inode->i_size - (page->index << PAGE_CACHE_SHIFT);
-	if (page->index > (inode->i_size >> PAGE_CACHE_SHIFT))
-		offset = 0;
-	else if (offset >= data_offset)
-		offset = data_offset;
-	bytes += data_offset - offset;
-
-	target_buf = (char *)page_address(page) + offset;
-	target_data = (char *)page_address(page) + data_offset;
+	int err;
 
 	if (!PageLocked(page))
 		BUG();
-
-	blocksize = inode->i_sb->s_blocksize;
-	if (!page->buffers)
-		create_empty_buffers(page, inode, blocksize);
-	head = page->buffers;
-
-	bbits = inode->i_sb->s_blocksize_bits;
-	block = page->index << (PAGE_CACHE_SHIFT - bbits);
-	blocks = PAGE_CACHE_SIZE >> bbits;
-	start_block = offset >> bbits;
-	end_block = (offset + bytes - 1) >> bbits;
-	start_offset = offset & (blocksize - 1);
-	start_bytes = blocksize - start_offset;
-	if (start_bytes > bytes)
-		start_bytes = bytes;
-	end_bytes = (offset+bytes) & (blocksize - 1);
-	if (end_bytes > bytes)
-		end_bytes = bytes;
-
-	if (offset < 0 || offset > PAGE_SIZE)
+	if (offset < 0 || offset >= PAGE_SIZE)
 		BUG();
 	if (bytes+offset < 0 || bytes+offset > PAGE_SIZE)
 		BUG();
-	if (start_block < 0 || start_block > blocks)
-		BUG();
-	if (end_block < 0 || end_block >= blocks)
-		BUG();
-
-	i = 0;
-	bh = head;
-	partial = 0;
-	need_balance_dirty = 0;
-	do {
-		if (!bh)
-			BUG();
-
-		if ((i < start_block) || (i > end_block)) {
-			if (!buffer_uptodate(bh))
-				partial = 1;
-			goto skip;
-		}
-
-		/*
-		 * If the buffer is not up-to-date, we need to ask the low-level
-		 * FS to do something for us (we used to have assumptions about
-		 * the meaning of b_blocknr etc, that's bad).
-		 *
-		 * If "update" is set, that means that the low-level FS should
-		 * try to make sure that the block is up-to-date because we're
-		 * not going to fill it completely.
-		 */
-		bh->b_end_io = end_buffer_io_sync;
-		if (!buffer_mapped(bh)) {
-			err = inode->i_op->get_block(inode, block, bh, 1);
-			if (err)
-				goto out;
-			unmap_underlying_metadata(bh);
-		}
-
-		if (!buffer_uptodate(bh) && (start_offset || (end_bytes && (i == end_block)))) {
-			if (buffer_new(bh)) {
-				memset(bh->b_data, 0, bh->b_size);
-			} else {
-				ll_rw_block(READ, 1, &bh);
-				wait_on_buffer(bh);
-				err = -EIO;
-				if (!buffer_uptodate(bh))
-					goto out;
-			}
-		}
 
-		len = blocksize;
-		if (start_offset) {
-			len = start_bytes;
-			start_offset = 0;
-		} else if (end_bytes && (i == end_block)) {
-			len = end_bytes;
-			end_bytes = 0;
-		}
-		err = 0;
-		if (target_buf+len<=target_data)
-			memset(target_buf, 0, len);
-		else if (target_buf<target_data) {
-			memset(target_buf, 0, target_data-target_buf);
-			copy_from_user(target_data, buf,
-					len+target_buf-target_data);
-		} else
-			err = copy_from_user(target_buf, buf, len);
-		target_buf += len;
-		buf += len;
-
-		/*
-		 * we dirty buffers only after copying the data into
-		 * the page - this way we can dirty the buffer even if
-		 * the bh is still doing IO.
-		 *
-		 * NOTE! This also does a direct dirty balace check,
-		 * rather than relying on bdflush just waking up every
-		 * once in a while. This is to catch (and slow down)
-		 * the processes that write tons of buffer..
-		 *
-		 * Note how we do NOT want to do this in the full block
-		 * case: full pages are flushed not by the people who
-		 * dirtied them, but by people who need memory. And we
-		 * should not penalize them for somebody else writing
-		 * lots of dirty pages.
-		 */
-		set_bit(BH_Uptodate, &bh->b_state);
-		if (!test_and_set_bit(BH_Dirty, &bh->b_state)) {
-			__mark_dirty(bh, 0);
-			need_balance_dirty = 1;
-		}
-
-		if (err) {
-			err = -EFAULT;
-			goto out;
-		}
+	err = block_write_range(dentry, page, offset,offset,offset+bytes, buf);
+	return err ? err : bytes;
+}
 
-skip:
-		i++;
-		block++;
-		bh = bh->b_this_page;
-	} while (bh != head);
+/*
+ * For moronic filesystems that do not allow holes in file.
+ * we allow offset==PAGE_SIZE, bytes==0
+ */
 
-	if (need_balance_dirty)
-		balance_dirty(bh->b_dev);
+int block_write_cont_page(struct file *file, struct page *page, unsigned long offset, unsigned long bytes, const char * buf)
+{
+	struct dentry *dentry = file->f_dentry;
+	struct inode *inode = dentry->d_inode;
+	int err;
+	unsigned zerofrom = offset;
 
-	/*
-	 * is this a partial write that happened to make all buffers
-	 * uptodate then we can optimize away a bogus readpage() for
-	 * the next read(). Here we 'discover' wether the page went
-	 * uptodate as a result of this (potentially partial) write.
-	 */
-	if (!partial)
-		SetPageUptodate(page);
-	return bytes;
-out:
-	ClearPageUptodate(page);
-	return err;
+	if (page->index > (inode->i_size >> PAGE_CACHE_SHIFT))
+		zerofrom = 0;
+	else if (page->index == (inode->i_size >> PAGE_CACHE_SHIFT) &&
+		 offset > (inode->i_size & ~PAGE_CACHE_MASK))
+		zerofrom = inode->i_size & ~PAGE_CACHE_MASK;
+	err = block_write_range(dentry, page, zerofrom,offset,offset+bytes,buf);
+	return err ? err : bytes;
 }
 
 
@@ -1998,9 +1829,8 @@
  * mark_buffer_uptodate() functions propagate buffer state into the
  * page struct once IO has completed.
  */
-int block_read_full_page(struct file * file, struct page * page)
+int block_read_full_page(struct dentry * dentry, struct page * page)
 {
-	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	unsigned long iblock;
 	struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];
diff -u --recursive --new-file v2.3.29/linux/fs/coda/dir.c linux/fs/coda/dir.c
--- v2.3.29/linux/fs/coda/dir.c	Thu Aug 26 13:05:40 1999
+++ linux/fs/coda/dir.c	Sun Dec  5 08:42:03 1999
@@ -80,11 +80,8 @@
 	NULL,		        /* get_block */
 	NULL,	                /* readpage */
 	NULL,		        /* writepage */
-	NULL,		        /* flushpage */
 	NULL,	                /* truncate */
 	coda_permission,        /* permission */
-	NULL,                   /* smap */
-	NULL,                   /* update page */
         coda_revalidate_inode   /* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/coda/file.c linux/fs/coda/file.c
--- v2.3.29/linux/fs/coda/file.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/coda/file.c	Sun Dec  5 08:42:03 1999
@@ -26,7 +26,7 @@
 #include <linux/coda_proc.h>
 
 /* file operations */
-static int coda_readpage(struct file *file, struct page * page);
+static int coda_readpage(struct dentry *dentry, struct page * page);
 static ssize_t coda_file_read(struct file *f, char *buf, size_t count, loff_t *off);
 static ssize_t coda_file_write(struct file *f, const char *buf, size_t count, loff_t *off);
 static int coda_file_mmap(struct file * file, struct vm_area_struct * vma);
@@ -50,10 +50,8 @@
 	NULL,			/* get_block */
 	coda_readpage,    	/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
         coda_permission,        /* permission */
-	NULL,                   /* smap */
         coda_revalidate_inode   /* revalidate */
 };
 
@@ -76,12 +74,10 @@
 };
 
 /*  File file operations */
-static int coda_readpage(struct file * coda_file, struct page * page)
+static int coda_readpage(struct dentry * dentry, struct page * page)
 {
-	struct dentry *de = coda_file->f_dentry;
-	struct inode *coda_inode = de->d_inode;
+	struct inode *coda_inode = dentry->d_inode;
 	struct dentry cont_dentry;
-	struct file cont_file;
         struct coda_inode_info *cii;
 
         ENTRY;
@@ -91,17 +87,16 @@
 
         if ( ! cii->c_ovp ) {
 		printk("coda_readpage: no open inode for ino %ld, %s\n", 
-		       coda_inode->i_ino, de->d_name.name);
+		       coda_inode->i_ino, dentry->d_name.name);
                 return -ENXIO;
         }
        
-        coda_prepare_openfile(coda_inode, coda_file, cii->c_ovp,
-			      &cont_file, &cont_dentry);
+        cont_dentry.d_inode = cii->c_ovp;
 
         CDEBUG(D_INODE, "coda ino: %ld, cached ino %ld, page offset: %lx\n", 
 	       coda_inode->i_ino, cii->c_ovp->i_ino, page->index);
 
-        block_read_full_page(&cont_file, page);
+        block_read_full_page(&cont_dentry, page);
         EXIT;
         return 0;
 }
diff -u --recursive --new-file v2.3.29/linux/fs/coda/pioctl.c linux/fs/coda/pioctl.c
--- v2.3.29/linux/fs/coda/pioctl.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/coda/pioctl.c	Sun Dec  5 08:42:03 1999
@@ -49,10 +49,8 @@
 	NULL,		        /* get_block */
 	NULL,	                /* readpage */
 	NULL,		        /* writepage */
-	NULL,		        /* flushpage */
 	NULL,	                /* truncate */
 	coda_ioctl_permission,  /* permission */
-	NULL,                   /* smap */
         NULL                    /* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/coda/symlink.c linux/fs/coda/symlink.c
--- v2.3.29/linux/fs/coda/symlink.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/coda/symlink.c	Sun Dec  5 08:42:03 1999
@@ -45,10 +45,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,            	/* permission */
-	NULL,                   /* smap */
         NULL                    /* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/coda/sysctl.c linux/fs/coda/sysctl.c
--- v2.3.29/linux/fs/coda/sysctl.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/coda/sysctl.c	Sat Nov 27 15:27:49 1999
@@ -492,7 +492,7 @@
 	reset_coda_cache_inv_stats();
 
 #ifdef CONFIG_PROC_FS
-	proc_fs_coda = create_proc_entry("coda", S_IFDIR, proc_root_fs);
+	proc_fs_coda = proc_mkdir("coda", proc_root_fs);
 	proc_fs_coda->owner = THIS_MODULE;
 	coda_proc_create("vfs_stats", coda_vfs_stats_get_info);
 	coda_proc_create("upcall_stats", coda_upcall_stats_get_info);
diff -u --recursive --new-file v2.3.29/linux/fs/devices.c linux/fs/devices.c
--- v2.3.29/linux/fs/devices.c	Sun Jul  4 10:02:30 1999
+++ linux/fs/devices.c	Sun Dec  5 08:42:03 1999
@@ -281,10 +281,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
@@ -338,10 +336,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/devpts/root.c linux/fs/devpts/root.c
--- v2.3.29/linux/fs/devpts/root.c	Tue Aug 31 17:29:14 1999
+++ linux/fs/devpts/root.c	Sun Dec  5 08:42:03 1999
@@ -54,10 +54,8 @@
 	NULL,                   /* get_block */
 	NULL,                   /* readpage */
 	NULL,                   /* writepage */
-	NULL,                   /* flushpage */
 	NULL,                   /* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/dquot.c linux/fs/dquot.c
--- v2.3.29/linux/fs/dquot.c	Thu Nov 18 20:25:37 1999
+++ linux/fs/dquot.c	Mon Dec  6 17:09:28 1999
@@ -786,110 +786,113 @@
 	dquot->dq_flags |= DQ_MOD;
 }
 
-static inline char need_print_warning(short type, uid_t initiator, struct dquot *dquot)
+static inline int need_print_warning(struct dquot *dquot, int flag)
 {
-	switch (type) {
+	switch (dquot->dq_type) {
 		case USRQUOTA:
-			return(initiator == dquot->dq_id);
+			return current->fsuid == dquot->dq_id && !(dquot->dq_flags & flag);
 		case GRPQUOTA:
-			return(initiator == dquot->dq_id);
+			return in_group_p(dquot->dq_id) && !(dquot->dq_flags & flag);
 	}
-	return(0);
+	return 0;
 }
 
-static inline char ignore_hardlimit(struct dquot *dquot, uid_t initiator)
+static void print_warning(struct dquot *dquot, int flag, char *fmtstr, ...)
 {
-	return(initiator == 0 && dquot->dq_mnt->mnt_dquot.rsquash[dquot->dq_type] == 0);
+	va_list args;
+
+	if (!need_print_warning(dquot, flag))
+		return;
+	va_start(args, fmtstr);
+	vsprintf(quotamessage, fmtstr, args);
+	va_end(args);
+	tty_write_message(current->tty, quotamessage);
+	dquot->dq_flags |= flag;
 }
 
-static int check_idq(struct dquot *dquot, short type, u_long inodes, uid_t initiator, 
-			struct tty_struct *tty)
+static inline char ignore_hardlimit(struct dquot *dquot)
 {
+	return capable(CAP_SYS_RESOURCE) && !dquot->dq_mnt->mnt_dquot.rsquash[dquot->dq_type];
+}
+
+static int check_idq(struct dquot *dquot, u_long inodes)
+{
+	short type = dquot->dq_type;
+
 	if (inodes <= 0 || dquot->dq_flags & DQ_FAKE)
-		return(QUOTA_OK);
+		return QUOTA_OK;
 
 	if (dquot->dq_ihardlimit &&
 	   (dquot->dq_curinodes + inodes) > dquot->dq_ihardlimit &&
-            !ignore_hardlimit(dquot, initiator)) {
-		if ((dquot->dq_flags & DQ_INODES) == 0 &&
-                     need_print_warning(type, initiator, dquot)) {
-			sprintf(quotamessage, "%s: write failed, %s file limit reached\n",
-			        dquot->dq_mnt->mnt_dirname, quotatypes[type]);
-			tty_write_message(tty, quotamessage);
-			dquot->dq_flags |= DQ_INODES;
-		}
-		return(NO_QUOTA);
+            !ignore_hardlimit(dquot)) {
+		print_warning(dquot, DQ_INODES, "%s: write failed, %s file limit reached\n",
+			      dquot->dq_mnt->mnt_dirname, quotatypes[type]);
+		return NO_QUOTA;
 	}
 
 	if (dquot->dq_isoftlimit &&
 	   (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
 	    dquot->dq_itime && CURRENT_TIME >= dquot->dq_itime &&
-            !ignore_hardlimit(dquot, initiator)) {
-                if (need_print_warning(type, initiator, dquot)) {
-			sprintf(quotamessage, "%s: warning, %s file quota exceeded too long.\n",
-		        	dquot->dq_mnt->mnt_dirname, quotatypes[type]);
-			tty_write_message(tty, quotamessage);
-		}
-		return(NO_QUOTA);
+            !ignore_hardlimit(dquot)) {
+		print_warning(dquot, DQ_INODES, "%s: warning, %s file quota exceeded too long.\n",
+				dquot->dq_mnt->mnt_dirname, quotatypes[type]);
+		return NO_QUOTA;
 	}
 
 	if (dquot->dq_isoftlimit &&
 	   (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
 	    dquot->dq_itime == 0) {
-                if (need_print_warning(type, initiator, dquot)) {
-			sprintf(quotamessage, "%s: warning, %s file quota exceeded\n",
-		        	dquot->dq_mnt->mnt_dirname, quotatypes[type]);
-			tty_write_message(tty, quotamessage);
-		}
+		print_warning(dquot, 0, "%s: warning, %s file quota exceeded\n",
+				dquot->dq_mnt->mnt_dirname, quotatypes[type]);
 		dquot->dq_itime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.inode_expire[type];
 	}
 
-	return(QUOTA_OK);
+	return QUOTA_OK;
 }
 
-static int check_bdq(struct dquot *dquot, short type, u_long blocks, uid_t initiator, 
-			struct tty_struct *tty, char warn)
+static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc)
 {
+	short type = dquot->dq_type;
+
 	if (blocks <= 0 || dquot->dq_flags & DQ_FAKE)
-		return(QUOTA_OK);
+		return QUOTA_OK;
 
 	if (dquot->dq_bhardlimit &&
 	   (dquot->dq_curblocks + blocks) > dquot->dq_bhardlimit &&
-            !ignore_hardlimit(dquot, initiator)) {
-		if (warn && (dquot->dq_flags & DQ_BLKS) == 0 &&
-                     need_print_warning(type, initiator, dquot)) {
-			sprintf(quotamessage, "%s: write failed, %s disk limit reached.\n",
-			        dquot->dq_mnt->mnt_dirname, quotatypes[type]);
-			tty_write_message(tty, quotamessage);
-			dquot->dq_flags |= DQ_BLKS;
-		}
-		return(NO_QUOTA);
+            !ignore_hardlimit(dquot)) {
+		if (!prealloc)
+			print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk limit reached.\n",
+					dquot->dq_mnt->mnt_dirname, quotatypes[type]);
+		return NO_QUOTA;
 	}
 
 	if (dquot->dq_bsoftlimit &&
 	   (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
 	    dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime &&
-            !ignore_hardlimit(dquot, initiator)) {
-                if (warn && need_print_warning(type, initiator, dquot)) {
-			sprintf(quotamessage, "%s: write failed, %s disk quota exceeded too long.\n",
-		        	dquot->dq_mnt->mnt_dirname, quotatypes[type]);
-			tty_write_message(tty, quotamessage);
-		}
-		return(NO_QUOTA);
+            !ignore_hardlimit(dquot)) {
+		if (!prealloc)
+			print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk quota exceeded too long.\n",
+					dquot->dq_mnt->mnt_dirname, quotatypes[type]);
+		return NO_QUOTA;
 	}
 
 	if (dquot->dq_bsoftlimit &&
 	   (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
 	    dquot->dq_btime == 0) {
-                if (warn && need_print_warning(type, initiator, dquot)) {
-			sprintf(quotamessage, "%s: warning, %s disk quota exceeded\n",
-		        	dquot->dq_mnt->mnt_dirname, quotatypes[type]);
-			tty_write_message(tty, quotamessage);
+		if (!prealloc) {
+			print_warning(dquot, 0, "%s: warning, %s disk quota exceeded\n",
+					dquot->dq_mnt->mnt_dirname, quotatypes[type]);
+			dquot->dq_btime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.block_expire[type];
 		}
-		dquot->dq_btime = CURRENT_TIME + dquot->dq_mnt->mnt_dquot.block_expire[type];
+		else
+			/*
+			 * We don't allow preallocation to exceed softlimit so exceeding will
+			 * be always printed
+			 */
+			return NO_QUOTA;
 	}
 
-	return(QUOTA_OK);
+	return QUOTA_OK;
 }
 
 /*
@@ -1102,11 +1105,9 @@
 /*
  * Note: this is a blocking operation.
  */
-int dquot_alloc_block(const struct inode *inode, unsigned long number, uid_t initiator, 
-			char warn)
+int dquot_alloc_block(const struct inode *inode, unsigned long number, char warn)
 {
 	int cnt;
-	struct tty_struct *tty = current->tty;
 	struct dquot *dquot[MAXQUOTAS];
 
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@@ -1114,7 +1115,7 @@
 		if (dquot[cnt] == NODQUOT)
 			continue;
 		lock_dquot(dquot[cnt]);
-		if (check_bdq(dquot[cnt], cnt, number, initiator, tty, warn))
+		if (check_bdq(dquot[cnt], number, warn))
 			goto put_all;
 	}
 
@@ -1140,10 +1141,9 @@
 /*
  * Note: this is a blocking operation.
  */
-int dquot_alloc_inode(const struct inode *inode, unsigned long number, uid_t initiator)
+int dquot_alloc_inode(const struct inode *inode, unsigned long number)
 {
 	int cnt;
-	struct tty_struct *tty = current->tty;
 	struct dquot *dquot[MAXQUOTAS];
 
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@@ -1151,7 +1151,7 @@
 		if (dquot[cnt] == NODQUOT)
 			continue;
 		lock_dquot(dquot[cnt]);
-		if (check_idq(dquot[cnt], cnt, number, initiator, tty))
+		if (check_idq(dquot[cnt], number))
 			goto put_all;
 	}
 
@@ -1213,13 +1213,12 @@
  *
  * Note: this is a blocking operation.
  */
-int dquot_transfer(struct dentry *dentry, struct iattr *iattr, uid_t initiator)
+int dquot_transfer(struct dentry *dentry, struct iattr *iattr)
 {
 	struct inode *inode = dentry -> d_inode;
 	unsigned long blocks;
 	struct dquot *transfer_from[MAXQUOTAS];
 	struct dquot *transfer_to[MAXQUOTAS];
-	struct tty_struct *tty = current->tty;
 	short cnt, disc;
 	int error = -EDQUOT;
 
@@ -1293,8 +1292,8 @@
 		 * invalidated or locked...
 		 */
 		if (!transfer_to[cnt]->dq_mnt || !transfer_from[cnt]->dq_mnt ||
-		    check_idq(transfer_to[cnt], cnt, 1, initiator, tty) == NO_QUOTA ||
-		    check_bdq(transfer_to[cnt], cnt, blocks, initiator, tty, 0) == NO_QUOTA) {
+		    check_idq(transfer_to[cnt], 1) == NO_QUOTA ||
+		    check_bdq(transfer_to[cnt], blocks, 0) == NO_QUOTA) {
 			cnt++;
 			goto put_all;
 		}
@@ -1458,9 +1457,9 @@
 static inline int check_quotafile_size(loff_t size)
 {
 	ulong blocks = size >> BLOCK_SIZE_BITS;
-	size_t off = size & ~(BLOCK_SIZE - 1);
+	size_t off = size & (BLOCK_SIZE - 1);
 
-	return !((blocks % sizeof(struct dqblk) + off % sizeof(struct dqblk)) % sizeof(struct dqblk));
+	return !(((blocks % sizeof(struct dqblk)) * BLOCK_SIZE + off % sizeof(struct dqblk)) % sizeof(struct dqblk));
 }
 
 int quota_on(kdev_t dev, short type, char *path)
@@ -1555,7 +1554,7 @@
 			break;
 		case Q_GETQUOTA:
 			if (((type == USRQUOTA && current->euid != id) ||
-			     (type == GRPQUOTA && in_group_p(id))) &&
+			     (type == GRPQUOTA && in_egroup_p(id))) &&
 			    !capable(CAP_SYS_RESOURCE))
 				goto out;
 			break;
diff -u --recursive --new-file v2.3.29/linux/fs/efs/dir.c linux/fs/efs/dir.c
--- v2.3.29/linux/fs/efs/dir.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/efs/dir.c	Sun Dec  5 08:42:03 1999
@@ -43,10 +43,8 @@
 	efs_get_block,		/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/efs/file.c linux/fs/efs/file.c
--- v2.3.29/linux/fs/efs/file.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/efs/file.c	Sun Dec  5 08:42:03 1999
@@ -94,9 +94,7 @@
 	efs_get_block,		/* get_block */
 	block_read_full_page,	/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/efs/symlink.c linux/fs/efs/symlink.c
--- v2.3.29/linux/fs/efs/symlink.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/efs/symlink.c	Sun Dec  5 08:42:03 1999
@@ -29,10 +29,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/exec.c linux/fs/exec.c
--- v2.3.29/linux/fs/exec.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/exec.c	Mon Dec  6 10:57:15 1999
@@ -371,6 +371,7 @@
 	if (mm) {
 		struct mm_struct *active_mm = current->active_mm;
 
+		init_new_context(current, mm);
 		current->mm = mm;
 		current->active_mm = mm;
 		activate_mm(active_mm, mm);
diff -u --recursive --new-file v2.3.29/linux/fs/ext2/acl.c linux/fs/ext2/acl.c
--- v2.3.29/linux/fs/ext2/acl.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ext2/acl.c	Thu Dec  2 15:24:49 1999
@@ -7,7 +7,6 @@
  * Universite Pierre et Marie Curie (Paris VI)
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 
diff -u --recursive --new-file v2.3.29/linux/fs/ext2/balloc.c linux/fs/ext2/balloc.c
--- v2.3.29/linux/fs/ext2/balloc.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ext2/balloc.c	Thu Dec  2 15:24:49 1999
@@ -11,7 +11,6 @@
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/locks.h>
 #include <linux/quotaops.h>
diff -u --recursive --new-file v2.3.29/linux/fs/ext2/bitmap.c linux/fs/ext2/bitmap.c
--- v2.3.29/linux/fs/ext2/bitmap.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ext2/bitmap.c	Thu Dec  2 15:24:49 1999
@@ -7,7 +7,6 @@
  * Universite Pierre et Marie Curie (Paris VI)
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 
 
diff -u --recursive --new-file v2.3.29/linux/fs/ext2/dir.c linux/fs/ext2/dir.c
--- v2.3.29/linux/fs/ext2/dir.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ext2/dir.c	Sun Dec  5 08:42:03 1999
@@ -18,7 +18,6 @@
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 
 
@@ -67,10 +66,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	ext2_permission,	/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/ext2/file.c linux/fs/ext2/file.c
--- v2.3.29/linux/fs/ext2/file.c	Thu Nov 11 20:11:49 1999
+++ linux/fs/ext2/file.c	Sun Dec  5 08:42:03 1999
@@ -18,7 +18,6 @@
  * 	(jj@sunsite.ms.mff.cuni.cz)
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 
@@ -177,9 +176,7 @@
 	ext2_get_block,		/* get_block */
 	block_read_full_page,	/* readpage */
 	block_write_full_page,	/* writepage */
-	block_flushpage,	/* flushpage */
 	ext2_truncate,		/* truncate */
 	ext2_permission,	/* permission */
-	NULL,			/* smap */
 	NULL,			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/ext2/fsync.c linux/fs/ext2/fsync.c
--- v2.3.29/linux/fs/ext2/fsync.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ext2/fsync.c	Thu Dec  2 15:24:49 1999
@@ -22,7 +22,6 @@
  * we can depend on generic_block_fdatasync() to sync the data blocks.
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 
 
diff -u --recursive --new-file v2.3.29/linux/fs/ext2/ialloc.c linux/fs/ext2/ialloc.c
--- v2.3.29/linux/fs/ext2/ialloc.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ext2/ialloc.c	Thu Dec  2 15:24:49 1999
@@ -12,7 +12,6 @@
  *        David S. Miller (davem@caip.rutgers.edu), 1995
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/locks.h>
 #include <linux/quotaops.h>
diff -u --recursive --new-file v2.3.29/linux/fs/ext2/inode.c linux/fs/ext2/inode.c
--- v2.3.29/linux/fs/ext2/inode.c	Sun Nov  7 16:37:34 1999
+++ linux/fs/ext2/inode.c	Thu Dec  2 15:24:49 1999
@@ -20,7 +20,6 @@
  * 	(jj@sunsite.ms.mff.cuni.cz)
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/locks.h>
 #include <linux/smp_lock.h>
diff -u --recursive --new-file v2.3.29/linux/fs/ext2/ioctl.c linux/fs/ext2/ioctl.c
--- v2.3.29/linux/fs/ext2/ioctl.c	Thu Nov 11 20:11:49 1999
+++ linux/fs/ext2/ioctl.c	Thu Dec  2 15:24:49 1999
@@ -7,7 +7,6 @@
  * Universite Pierre et Marie Curie (Paris VI)
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/sched.h>
 #include <asm/uaccess.h>
diff -u --recursive --new-file v2.3.29/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
--- v2.3.29/linux/fs/ext2/namei.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ext2/namei.c	Thu Dec  2 15:24:49 1999
@@ -18,7 +18,6 @@
  *  	for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/locks.h>
 #include <linux/quotaops.h>
diff -u --recursive --new-file v2.3.29/linux/fs/ext2/symlink.c linux/fs/ext2/symlink.c
--- v2.3.29/linux/fs/ext2/symlink.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ext2/symlink.c	Sun Dec  5 08:42:03 1999
@@ -15,7 +15,6 @@
  *  ext2 symlink handling code
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <asm/uaccess.h>
 
@@ -43,10 +42,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/ext2/truncate.c linux/fs/ext2/truncate.c
--- v2.3.29/linux/fs/ext2/truncate.c	Sun Nov  7 16:37:34 1999
+++ linux/fs/ext2/truncate.c	Thu Dec  2 15:24:49 1999
@@ -18,7 +18,6 @@
  *  General cleanup and race fixes, wsh, 1998
  */
 
-#include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/locks.h>
 
diff -u --recursive --new-file v2.3.29/linux/fs/fat/file.c linux/fs/fat/file.c
--- v2.3.29/linux/fs/fat/file.c	Sun Nov  7 16:37:34 1999
+++ linux/fs/fat/file.c	Sun Dec  5 08:42:03 1999
@@ -60,10 +60,8 @@
 	fat_get_block,		/* get_block */
 	block_read_full_page,	/* readpage */
 	NULL,			/* writepage */
-	block_flushpage,	/* flushpage */
 	fat_truncate,		/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
@@ -113,39 +111,23 @@
 {
 	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
-	struct page *new_page, **hash;
+	struct page *new_page;
 	unsigned long pgpos;
-	struct page *page_cache = NULL;
 	long status;
 
-	pgpos = MSDOS_I(inode)->i_realsize >> PAGE_CACHE_SHIFT;
-	while (pgpos < page->index) {
-		hash = page_hash(&inode->i_data, pgpos);
-repeat_find:	new_page = __find_lock_page(&inode->i_data, pgpos, hash);
-		if (!new_page) {
-			if (!page_cache) {
-				page_cache = page_cache_alloc();
-				if (page_cache)
-					goto repeat_find;
-				status = -ENOMEM;
-				goto out;
-			}
-			new_page = page_cache;
-			if (add_to_page_cache_unique(new_page,&inode->i_data,pgpos,hash))
-				goto repeat_find;
-			page_cache = NULL;
-		}
+	while((pgpos=MSDOS_I(inode)->i_realsize>>PAGE_CACHE_SHIFT)<page->index){
+		status = -ENOMEM;
+		new_page = grab_cache_page(&inode->i_data, pgpos);
+		if (!new_page)
+			goto out;
 		status = block_write_cont_page(file, new_page, PAGE_SIZE, 0, NULL);
 		UnlockPage(new_page);
 		page_cache_release(new_page);
 		if (status < 0)
 			goto out;
-		pgpos = MSDOS_I(inode)->i_realsize >> PAGE_CACHE_SHIFT;
 	}
 	status = block_write_cont_page(file, page, offset, bytes, buf);
 out:
-	if (page_cache)
-		page_cache_free(page_cache);
 	return status;
 }
 
diff -u --recursive --new-file v2.3.29/linux/fs/fifo.c linux/fs/fifo.c
--- v2.3.29/linux/fs/fifo.c	Thu Aug 26 13:05:40 1999
+++ linux/fs/fifo.c	Sun Dec  5 08:42:03 1999
@@ -169,25 +169,6 @@
 
 struct inode_operations fifo_inode_operations = {
 	&def_fifo_fops,		/* default file operations */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* get_block */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* flushpage */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL,			/* smap */
-	NULL			/* revalidate */
 };
 
 
diff -u --recursive --new-file v2.3.29/linux/fs/filesystems.c linux/fs/filesystems.c
--- v2.3.29/linux/fs/filesystems.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/filesystems.c	Thu Dec  2 15:42:51 1999
@@ -31,6 +31,7 @@
 #include <linux/hfs_fs.h>
 #include <linux/devpts_fs.h>
 #include <linux/bfs_fs.h>
+#include <linux/adfs_fs.h>
 #include <linux/major.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
diff -u --recursive --new-file v2.3.29/linux/fs/hfs/dir_cap.c linux/fs/hfs/dir_cap.c
--- v2.3.29/linux/fs/hfs/dir_cap.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/hfs/dir_cap.c	Sun Dec  5 08:42:03 1999
@@ -90,10 +90,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
@@ -113,10 +111,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
@@ -136,10 +132,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/hfs/dir_dbl.c linux/fs/hfs/dir_dbl.c
--- v2.3.29/linux/fs/hfs/dir_dbl.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/hfs/dir_dbl.c	Sun Dec  5 08:42:03 1999
@@ -89,10 +89,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/hfs/dir_nat.c linux/fs/hfs/dir_nat.c
--- v2.3.29/linux/fs/hfs/dir_nat.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/hfs/dir_nat.c	Sun Dec  5 08:42:03 1999
@@ -96,10 +96,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL                    /* revalidate */
 };
 
@@ -119,10 +117,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL                    /* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/hfs/file.c linux/fs/hfs/file.c
--- v2.3.29/linux/fs/hfs/file.c	Sun Nov  7 16:37:34 1999
+++ linux/fs/hfs/file.c	Sun Dec  5 08:42:03 1999
@@ -66,10 +66,8 @@
 	hfs_bmap,		/* get_block */
 	block_read_full_page,	/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	hfs_file_truncate,	/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/hfs/file_cap.c linux/fs/hfs/file_cap.c
--- v2.3.29/linux/fs/hfs/file_cap.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/hfs/file_cap.c	Sun Dec  5 08:42:03 1999
@@ -80,10 +80,8 @@
 	NULL,				/* get_block - none */
 	NULL,				/* readpage */
 	NULL,				/* writepage */
-	NULL,				/* flushpage */
 	cap_info_truncate,		/* truncate */
 	NULL,				/* permission */
-	NULL,				/* smap */
 	NULL				/* revalidata */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/hfs/file_hdr.c linux/fs/hfs/file_hdr.c
--- v2.3.29/linux/fs/hfs/file_hdr.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/hfs/file_hdr.c	Sun Dec  5 08:42:03 1999
@@ -82,10 +82,8 @@
 				   header part has no disk block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	hdr_truncate,		/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/hpfs/file.c linux/fs/hpfs/file.c
--- v2.3.29/linux/fs/hpfs/file.c	Wed Oct 27 16:34:12 1999
+++ linux/fs/hpfs/file.c	Sat Nov 27 15:51:32 1999
@@ -89,55 +89,25 @@
 {
 	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
-	struct page *new_page, **hash;
+	struct page *new_page;
 	unsigned long pgpos;
-	struct page * page_cache = NULL;
 	long status;
 
-	printk("- off: %08x\n", (int)page->offset);
-	pgpos = (inode->i_blocks - 1) * 512 & PAGE_CACHE_MASK;
-	while (pgpos < page->offset) {
-long pgp = pgpos;
-		printk("pgpos: %08x, bl: %d\n", (int)pgpos, (int)inode->i_blocks);
-		hash = page_hash(&inode->i_data, pgpos);
-repeat_find:	new_page = __find_lock_page(&inode->i_data, pgpos, hash);
-		if (!new_page) {
-			if (!page_cache) {
-				page_cache = page_cache_alloc();
-				if (page_cache)
-					goto repeat_find;
-				status = -ENOMEM;
-				goto out;
-			}
-			new_page = page_cache;
-			if (add_to_page_cache_unique(new_page,&inode->i_data,pgpos,hash))
-				goto repeat_find;
-			page_cache = NULL;
-		}
-		printk("A\n");
+	pgpos = ((inode->i_blocks - 1) * 512) >> PAGE_CACHE_SHIFT;
+	while (pgpos < page->index) {
+		status = -ENOMEM;
+		new_page = grab_page_cache(&inode->i_data, pgpos);
+		if (!new_page)
+			goto out;
 		status = block_write_cont_page(file, new_page, PAGE_SIZE, 0, NULL);
-		printk("B\n");
 		UnlockPage(new_page);
 		page_cache_release(new_page);
 		if (status < 0)
 			goto out;
-		pgpos = (inode->i_blocks - 1) * 512 & PAGE_CACHE_MASK;
-		printk("pgpos2: %08x, bl: %d\n", (int)pgpos, (int)inode->i_blocks);
-		if (pgpos == pgp) {
-			status = -1;
-			printk("ERROR\n");
-			goto out;
-		}
+		pgpos = ((inode->i_blocks - 1) * 512) >> PAGE_CACHE_SHIFT;
 	}
-	//if ((status = block_write_cont_page(file, page, PAGE_SIZE, 0, NULL)) < 0) goto out;
-	printk("C\n");
 	status = block_write_cont_page(file, page, offset, bytes, buf);
-	printk("D\n");
 out:
-	printk("O\n");
-	if (page_cache)
-		page_cache_free(page_cache);
-	printk("E\n");
 	return status;
 }
 
@@ -147,7 +117,7 @@
 	ssize_t retval;
 
 	retval = generic_file_write(file, buf, count,
-				    ppos, /*hpfs_write_partial_page*/block_write_partial_page);
+				    ppos, hpfs_write_partial_page);
 	if (retval > 0) {
 		struct inode *inode = file->f_dentry->d_inode;
 		inode->i_mtime = CURRENT_TIME;
diff -u --recursive --new-file v2.3.29/linux/fs/hpfs/inode.c linux/fs/hpfs/inode.c
--- v2.3.29/linux/fs/hpfs/inode.c	Fri Oct 22 13:21:52 1999
+++ linux/fs/hpfs/inode.c	Sun Dec  5 08:42:03 1999
@@ -44,10 +44,8 @@
 	&hpfs_get_block,		/* get_block */
 	block_read_full_page,		/* readpage */
 	block_write_full_page,		/* writepage */
-	block_flushpage,		/* flushpage */
 	hpfs_truncate,			/* truncate */
 	NULL,				/* permission */
-	NULL,				/* smap */
 	NULL,				/* revalidate */
 };
 
@@ -87,10 +85,8 @@
 	NULL,				/* get_block */
 	NULL,				/* readpage */
 	NULL,				/* writepage */
-	NULL,				/* flushpage */
 	NULL,				/* truncate */
 	NULL,				/* permission */
-	NULL,				/* smap */
 	NULL				/* revalidate */
 };
 
@@ -111,10 +107,8 @@
 	NULL,				/* get_block */
 	NULL,				/* readpage */
 	NULL,				/* writepage */
-	NULL,				/* flushpage */
 	NULL,				/* truncate */
 	NULL,				/* permission */
-	NULL,				/* smap */
 	NULL				/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/isofs/dir.c linux/fs/isofs/dir.c
--- v2.3.29/linux/fs/isofs/dir.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/isofs/dir.c	Sun Dec  5 08:42:03 1999
@@ -60,10 +60,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/isofs/file.c linux/fs/isofs/file.c
--- v2.3.29/linux/fs/isofs/file.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/isofs/file.c	Sun Dec  5 08:42:03 1999
@@ -51,9 +51,7 @@
 	isofs_get_block,	/* get_block */
 	block_read_full_page,	/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,	       		/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/isofs/symlink.c linux/fs/isofs/symlink.c
--- v2.3.29/linux/fs/isofs/symlink.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/isofs/symlink.c	Sun Dec  5 08:42:03 1999
@@ -41,10 +41,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/minix/dir.c linux/fs/minix/dir.c
--- v2.3.29/linux/fs/minix/dir.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/minix/dir.c	Sun Dec  5 08:42:03 1999
@@ -55,10 +55,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/minix/file.c linux/fs/minix/file.c
--- v2.3.29/linux/fs/minix/file.c	Fri Jul 23 10:30:42 1999
+++ linux/fs/minix/file.c	Sun Dec  5 08:42:03 1999
@@ -73,9 +73,7 @@
 	minix_get_block,	/* get_block */
 	block_read_full_page,	/* readpage */
 	block_write_full_page,	/* writepage */
-	block_flushpage,	/* flushpage */
 	minix_truncate,		/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL,			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/minix/symlink.c linux/fs/minix/symlink.c
--- v2.3.29/linux/fs/minix/symlink.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/minix/symlink.c	Sun Dec  5 08:42:03 1999
@@ -36,10 +36,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/msdos/namei.c linux/fs/msdos/namei.c
--- v2.3.29/linux/fs/msdos/namei.c	Tue Aug 31 17:29:14 1999
+++ linux/fs/msdos/namei.c	Sun Dec  5 08:42:03 1999
@@ -600,10 +600,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,                   /* smap */
 	NULL,                   /* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/ncpfs/Config.in linux/fs/ncpfs/Config.in
--- v2.3.29/linux/fs/ncpfs/Config.in	Sat Oct  9 11:47:50 1999
+++ linux/fs/ncpfs/Config.in	Fri Dec  3 11:10:14 1999
@@ -10,6 +10,6 @@
    bool '    Lowercase DOS filenames' CONFIG_NCPFS_SMALLDOS
 fi
 bool '  Allow mounting of volume subdirectories' CONFIG_NCPFS_MOUNT_SUBDIR
-# bool '  NDS interserver authentication support' CONFIG_NCPFS_NDS_DOMAINS
+bool '  NDS authentication support' CONFIG_NCPFS_NDS_DOMAINS
 bool '  Use Native Language Support' CONFIG_NCPFS_NLS
 bool '  Enable symbolic links and execute flags' CONFIG_NCPFS_EXTRAS
diff -u --recursive --new-file v2.3.29/linux/fs/ncpfs/dir.c linux/fs/ncpfs/dir.c
--- v2.3.29/linux/fs/ncpfs/dir.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/ncpfs/dir.c	Sun Dec  5 08:42:03 1999
@@ -81,10 +81,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL,			/* revalidate */
 };
 
@@ -368,37 +366,6 @@
 	return val;
 }
 
-static struct page *
-ncp_get_cache_page(struct inode *inode, unsigned long offset, int used)
-{
-	struct address_space *i_data = &inode->i_data;
-	struct page *new_page, *page, **hash;
-
-	hash = page_hash(i_data, offset);
-
-	page = __find_lock_page(i_data, offset, hash);
-	if (used || page)
-		return page;
-
-	new_page = page_cache_alloc();
-	if (!new_page)
-		return NULL;
-
-	for (;;) {
-		page = new_page;
-		if (!add_to_page_cache_unique(page, i_data, offset, hash))
-			break;
-		page_cache_release(page);
-		page = __find_lock_page(i_data, offset, hash);
-		if (page) {
-			page_cache_free(new_page);
-			break;
-		}
-	}
-
-	return page;
-}
-
 /* most parts from nfsd_d_validate() */
 static int
 ncp_d_validate(struct dentry *dentry)
@@ -518,7 +485,7 @@
 		filp->f_pos = 2;
 	}
 
-	page = ncp_get_cache_page(inode, 0, 0);
+	page = grab_cache_page(&inode->i_data, 0);
 	if (!page)
 		goto read_really;
 
@@ -547,7 +514,7 @@
 
 	for (;;) {
 		if (ctl.ofs != 0) {
-			ctl.page = ncp_get_cache_page(inode, ctl.ofs, 1);
+			ctl.page = find_lock_page(&inode->i_data, ctl.ofs);
 			if (!ctl.page)
 				goto invalid_cache;
 			ctl.cache = (union ncp_dir_cache *)
@@ -616,8 +583,8 @@
 	ctl.head.eof = ctl.valid;
 finished:
 	if (page) {
-		kunmap(page);
 		cache->head = ctl.head;
+		kunmap(page);
 		SetPageUptodate(page);
 		UnlockPage(page);
 		page_cache_release(page);
@@ -692,7 +659,7 @@
 		ctl.cache = NULL;
 		ctl.idx  -= NCP_DIRCACHE_SIZE;
 		ctl.ofs  += 1;
-		ctl.page  = ncp_get_cache_page(inode, ctl.ofs, 0);
+		ctl.page  = grab_cache_page(&inode->i_data, ctl.ofs);
 		if (ctl.page)
 			ctl.cache = (union ncp_dir_cache *)
 					kmap(ctl.page);
diff -u --recursive --new-file v2.3.29/linux/fs/ncpfs/file.c linux/fs/ncpfs/file.c
--- v2.3.29/linux/fs/ncpfs/file.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ncpfs/file.c	Sun Dec  5 08:42:03 1999
@@ -294,9 +294,7 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/ncpfs/ioctl.c linux/fs/ncpfs/ioctl.c
--- v2.3.29/linux/fs/ncpfs/ioctl.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ncpfs/ioctl.c	Fri Dec  3 11:10:14 1999
@@ -364,8 +364,7 @@
 
 #ifdef CONFIG_NCPFS_NDS_DOMAINS
 	case NCP_IOC_GETOBJECTNAME:
-		if (   (permission(inode, MAY_READ) != 0)
-		    && (current->uid != server->m.mounted_uid)) {
+		if (current->uid != server->m.mounted_uid) {
 			return -EACCES;
 		}
 		{
@@ -396,8 +395,7 @@
 			return 0;
 		}
 	case NCP_IOC_SETOBJECTNAME:
-		if (   (permission(inode, MAY_WRITE) != 0)
-		    && (current->uid != server->m.mounted_uid)) {
+		if (current->uid != server->m.mounted_uid) {
 			return -EACCES;
 		}
 		{
@@ -441,8 +439,7 @@
 			return 0;
 		}
 	case NCP_IOC_GETPRIVATEDATA:
-		if (   (permission(inode, MAY_READ) != 0)
-		    && (current->uid != server->m.mounted_uid)) {
+		if (current->uid != server->m.mounted_uid) {
 			return -EACCES;
 		}
 		{
@@ -471,8 +468,7 @@
 			return 0;
 		}
 	case NCP_IOC_SETPRIVATEDATA:
-		if (   (permission(inode, MAY_WRITE) != 0)
-		    && (current->uid != server->m.mounted_uid)) {
+		if (current->uid != server->m.mounted_uid) {
 			return -EACCES;
 		}
 		{
diff -u --recursive --new-file v2.3.29/linux/fs/ncpfs/symlink.c linux/fs/ncpfs/symlink.c
--- v2.3.29/linux/fs/ncpfs/symlink.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ncpfs/symlink.c	Sun Dec  5 08:42:03 1999
@@ -62,10 +62,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/nfs/dir.c linux/fs/nfs/dir.c
--- v2.3.29/linux/fs/nfs/dir.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/nfs/dir.c	Sun Dec  5 08:42:03 1999
@@ -81,10 +81,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	nfs_revalidate,		/* revalidate */
 };
 
@@ -302,51 +300,23 @@
  *	 page-in of the RPC reply, nowhere else, this simplies
  *	 things substantially.
  */
-static struct page *try_to_get_dirent_page(struct file *file, __u32 cookie, int refetch_ok)
+
+static int nfs_dir_filler(struct dentry *dentry, struct page *page)
 {
 	struct nfs_readdirargs rd_args;
 	struct nfs_readdirres rd_res;
-	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
-	struct page *page, **hash, *page_cache;
-	long offset;
+	long offset = page->index;
 	__u32 *cookiep;
+	int err;
 
-	page = NULL;
-	page_cache = page_cache_alloc();
-	if (!page_cache)
-		goto out;
-
-	if ((offset = nfs_readdir_offset(inode, cookie)) < 0) {
-		if (!refetch_ok ||
-		    (offset = refetch_to_readdir_cookie(file, inode)) < 0) {
-			page_cache_free(page_cache);
-			goto out;
-		}
-	}
+	kmap(page);
 
+	err = -EIO;
 	cookiep = find_cookie(inode, offset);
-	if (!cookiep) {
-		/* Gross fatal error. */
-		page_cache_free(page_cache);
-		goto out;
-	}
-
-	hash = page_hash(&inode->i_data, offset);
-repeat:
-	page = __find_lock_page(&inode->i_data, offset, hash);
-	if (page) {
-		page_cache_free(page_cache);
-		goto unlock_out;
-	}
+	if (!cookiep)
+		goto fail;
 
-	page = page_cache;
-	if (add_to_page_cache_unique(page, &inode->i_data, offset, hash)) {
-		page_cache_release(page);
-		goto repeat;
-	}
-
-	kmap(page);
 	rd_args.fh = NFS_FH(dentry);
 	rd_res.buffer = (char *)page_address(page);
 	rd_res.bufsiz = PAGE_CACHE_SIZE;
@@ -355,27 +325,55 @@
 		rd_args.buffer = rd_res.buffer;
 		rd_args.bufsiz = rd_res.bufsiz;
 		rd_args.cookie = rd_res.cookie;
-		if (rpc_call(NFS_CLIENT(inode),
-			     NFSPROC_READDIR, &rd_args, &rd_res, 0) < 0)
-			goto error;
+		err = rpc_call(NFS_CLIENT(inode),
+			     NFSPROC_READDIR, &rd_args, &rd_res, 0); 
+		if (err < 0)
+			goto fail;
 	} while(rd_res.bufsiz > 0);
 
+	err = -EIO;
 	if (rd_res.bufsiz < 0)
 		NFS_DIREOF(inode) = rd_res.cookie;
 	else if (create_cookie(rd_res.cookie, offset, inode))
-		goto error;
+		goto fail;
 
 	SetPageUptodate(page);
-unmap_out:
 	kunmap(page);
-unlock_out:
 	UnlockPage(page);
-out:
+	return 0;
+fail:
+	SetPageError(page);
+	kunmap(page);
+	UnlockPage(page);
+	return err;
+}
+
+static struct page *try_to_get_dirent_page(struct file *file, __u32 cookie, int refetch_ok)
+{
+	struct dentry *dentry = file->f_dentry;
+	struct inode *inode = dentry->d_inode;
+	struct page *page;
+	long offset;
+
+	if ((offset = nfs_readdir_offset(inode, cookie)) < 0) {
+		if (!refetch_ok ||
+		    (offset = refetch_to_readdir_cookie(file, inode)) < 0) {
+			goto fail;
+		}
+	}
+
+	page = read_cache_page(&inode->i_data, offset,
+				(filler_t *)nfs_dir_filler, dentry);
+	if (IS_ERR(page))
+		goto fail;
+	if (!Page_Uptodate(page))
+		goto fail2;
 	return page;
 
-error:
-	SetPageError(page);
-	goto unmap_out;
+fail2:
+	page_cache_release(page);
+fail:
+	return NULL;
 }
 
 /* Seek up to dirent assosciated with the passed in cookie,
diff -u --recursive --new-file v2.3.29/linux/fs/nfs/file.c linux/fs/nfs/file.c
--- v2.3.29/linux/fs/nfs/file.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/nfs/file.c	Sun Dec  5 08:42:03 1999
@@ -74,10 +74,8 @@
 	NULL,			/* get_block */
 	nfs_readpage,		/* readpage */
 	nfs_writepage,		/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	nfs_revalidate,		/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/nfs/read.c linux/fs/nfs/read.c
--- v2.3.29/linux/fs/nfs/read.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/nfs/read.c	Sat Nov 27 15:51:32 1999
@@ -227,9 +227,8 @@
  *  -	The server is congested.
  */
 int
-nfs_readpage(struct file *file, struct page *page)
+nfs_readpage(struct dentry *dentry, struct page *page)
 {
-	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	int		error;
 
diff -u --recursive --new-file v2.3.29/linux/fs/nfs/symlink.c linux/fs/nfs/symlink.c
--- v2.3.29/linux/fs/nfs/symlink.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/nfs/symlink.c	Sun Dec  5 08:42:03 1999
@@ -46,126 +46,101 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
 /* Symlink caching in the page cache is even more simplistic
  * and straight-forward than readdir caching.
  */
-static struct page *try_to_get_symlink_page(struct dentry *dentry, struct inode *inode)
+static int nfs_symlink_filler(struct dentry *dentry, struct page *page)
 {
 	struct nfs_readlinkargs rl_args;
-	struct page *page, **hash, *page_cache;
-
-	page = NULL;
-	page_cache = page_cache_alloc();
-	if (!page_cache)
-		goto out;
-
-	hash = page_hash(&inode->i_data, 0);
-repeat:
-	page = __find_lock_page(&inode->i_data, 0, hash);
-	if (page) {
-		page_cache_free(page_cache);
-		goto unlock_out;
-	}
-
-	page = page_cache;
-	if (add_to_page_cache_unique(page, &inode->i_data, 0, hash)) {
-		page_cache_release(page);
-		goto repeat;
-	}
-
 	kmap(page);
-
 	/* We place the length at the beginning of the page,
 	 * in host byte order, followed by the string.  The
 	 * XDR response verification will NULL terminate it.
 	 */
 	rl_args.fh = NFS_FH(dentry);
-	rl_args.buffer = (const void *)page_address(page_cache);
-	if (rpc_call(NFS_CLIENT(inode), NFSPROC_READLINK,
+	rl_args.buffer = (const void *)page_address(page);
+	if (rpc_call(NFS_CLIENT(dentry->d_inode), NFSPROC_READLINK,
 		     &rl_args, NULL, 0) < 0)
 		goto error;
 	SetPageUptodate(page);
-unlock_out:
 	kunmap(page);
 	UnlockPage(page);
-out:
-	return page;
+	return 0;
 
 error:
 	SetPageError(page);
-	goto unlock_out;
+	kunmap(page);
+	UnlockPage(page);
+	return -EIO;
 }
 
-static int nfs_readlink(struct dentry *dentry, char *buffer, int buflen)
+static char *nfs_getlink(struct dentry *dentry, struct page **ppage)
 {
 	struct inode *inode = dentry->d_inode;
 	struct page *page;
-	u32 *p, len;
+	u32 *p;
 
 	/* Caller revalidated the directory inode already. */
-	page = find_get_page(&inode->i_data, 0);
-	if (!page)
-		goto no_readlink_page;
+	page = read_cache_page(&inode->i_data, 0,
+				(filler_t *)nfs_symlink_filler, dentry);
+	if (IS_ERR(page))
+		goto read_failed;
 	if (!Page_Uptodate(page))
-		goto readlink_read_error;
-success:
+		goto followlink_read_error;
+	*ppage = page;
 	p = (u32 *) kmap(page);
-	len = *p++;
+	return (char*)(p+1);
+		
+followlink_read_error:
+	page_cache_release(page);
+	return ERR_PTR(-EIO);
+read_failed:
+	return (char*)page;
+}
+
+static int nfs_readlink(struct dentry *dentry, char *buffer, int buflen)
+{
+	struct page *page = NULL;
+	u32 len;
+	char *s = nfs_getlink(dentry, &page);
+	UPDATE_ATIME(dentry->d_inode);
+
+	len = PTR_ERR(s);
+	if (IS_ERR(s))
+		goto out;
+
+	len = strlen(s);
 	if (len > buflen)
 		len = buflen;
-	copy_to_user(buffer, p, len);
+	copy_to_user(buffer, s, len);
 	kunmap(page);
 	page_cache_release(page);
+out:
 	return len;
-
-no_readlink_page:
-	page = try_to_get_symlink_page(dentry, inode);
-	if (!page)
-		goto no_page;
-	if (Page_Uptodate(page))
-		goto success;
-readlink_read_error:
-	page_cache_release(page);
-no_page:
-	return -EIO;
 }
 
 static struct dentry *
 nfs_follow_link(struct dentry *dentry, struct dentry *base, unsigned int follow)
 {
 	struct dentry *result;
-	struct inode *inode = dentry->d_inode;
-	struct page *page;
-	u32 *p;
+	struct page *page = NULL;
+	char *s = nfs_getlink(dentry, &page);
+	UPDATE_ATIME(dentry->d_inode);
+
+	if (IS_ERR(s))
+		goto fail;
+
+	result = lookup_dentry(s, base, follow);
 
-	/* Caller revalidated the directory inode already. */
-	page = find_get_page(&inode->i_data, 0);
-	if (!page)
-		goto no_followlink_page;
-	if (!Page_Uptodate(page))
-		goto followlink_read_error;
-success:
-	p = (u32 *) kmap(page);
-	result = lookup_dentry((char *) (p + 1), base, follow);
 	kunmap(page);
 	page_cache_release(page);
 	return result;
 
-no_followlink_page:
-	page = try_to_get_symlink_page(dentry, inode);
-	if (!page)
-		goto no_page;
-	if (Page_Uptodate(page))
-		goto success;
-followlink_read_error:
-	page_cache_release(page);
-no_page:
-	return ERR_PTR(-EIO);
+fail:
+	return (struct dentry *)s;
 }
diff -u --recursive --new-file v2.3.29/linux/fs/nfs/write.c linux/fs/nfs/write.c
--- v2.3.29/linux/fs/nfs/write.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/nfs/write.c	Sat Nov 27 15:51:32 1999
@@ -414,9 +414,8 @@
  * (for now), and we currently do this synchronously only.
  */
 int
-nfs_writepage(struct file * file, struct page *page)
+nfs_writepage(struct dentry * dentry, struct page *page)
 {
-	struct dentry *dentry = file->f_dentry;
 	return nfs_writepage_sync(dentry, dentry->d_inode, page, 0, PAGE_SIZE);
 }
 
diff -u --recursive --new-file v2.3.29/linux/fs/nfsd/nfsctl.c linux/fs/nfsd/nfsctl.c
--- v2.3.29/linux/fs/nfsd/nfsctl.c	Thu Nov 11 20:11:50 1999
+++ linux/fs/nfsd/nfsctl.c	Sat Nov 27 15:27:49 1999
@@ -57,7 +57,7 @@
 
 void proc_export_init(void)
 {
-	if (!create_proc_entry("fs/nfs", S_IFDIR, 0))
+	if (!proc_mkdir("fs/nfs", 0))
 		return;
 	create_proc_read_entry("fs/nfs/exports", 0, 0, exp_procfs_exports,NULL);
 }
diff -u --recursive --new-file v2.3.29/linux/fs/ntfs/fs.c linux/fs/ntfs/fs.c
--- v2.3.29/linux/fs/ntfs/fs.c	Tue Aug 31 17:29:14 1999
+++ linux/fs/ntfs/fs.c	Sun Dec  5 08:42:03 1999
@@ -442,10 +442,8 @@
 	NULL, /* get_block */
 	NULL, /* readpage */
 	NULL, /* writepage */
-	NULL, /* flushpage */
 	NULL, /* truncate */
 	NULL, /* permission */
-	NULL, /* smap */
 	NULL, /* revalidate */
 };
 
@@ -625,10 +623,8 @@
 	ntfs_bmap, /* get_block */
 	block_read_full_page, /* readpage */
 	NULL, /* writepage */
-	NULL, /* flushpage */
 	NULL, /* truncate */
 	NULL, /* permission */
-	NULL, /* smap */
 	NULL, /* revalidate */
 };
 
@@ -674,10 +670,8 @@
 	NULL, /* get_block */
 	NULL, /* readpage */
 	NULL, /* writepage */
-	NULL, /* flushpage */
 	NULL, /* truncate */
 	NULL, /* permission */
-	NULL, /* smap */
 	NULL, /* revalidate */
 };
 
@@ -835,7 +829,7 @@
 	/* Number of files is limited by free space only, so we lie here */
 	fs.f_ffree=0;
 	mft=iget(sb,FILE_MFT);
-	fs.f_files=mft->i_size/vol->mft_recordsize;
+	fs.f_files=mft->i_size >> vol->mft_recordbits;
 	iput(mft);
 
 	/* should be read from volume */
diff -u --recursive --new-file v2.3.29/linux/fs/ntfs/super.c linux/fs/ntfs/super.c
--- v2.3.29/linux/fs/ntfs/super.c	Mon Apr 12 10:05:58 1999
+++ linux/fs/ntfs/super.c	Fri Dec  3 10:55:09 1999
@@ -91,12 +91,13 @@
 	if(vol->mft_clusters_per_record<0 && vol->mft_clusters_per_record!=-10)
 		ntfs_error("Unexpected data #4 in boot block\n");
 
-	vol->clustersize=vol->blocksize*vol->clusterfactor;
-	if(vol->mft_clusters_per_record>0)
-		vol->mft_recordsize=
-			vol->clustersize*vol->mft_clusters_per_record;
+	vol->clustersize = vol->blocksize * vol->clusterfactor;
+	if (vol->mft_clusters_per_record > 0)
+		vol->mft_recordbits = vol->clustersize * vol->mft_clusters_per_record;
 	else
-		vol->mft_recordsize=1<<(-vol->mft_clusters_per_record);
+		vol->mft_recordbits = -vol->mft_clusters_per_record;
+
+	vol->mft_recordsize = 1 << vol->mft_recordbits;
 	vol->index_recordsize=vol->clustersize*vol->index_clusters_per_record;
 	/* FIXME: long long value */
 	vol->mft_cluster=NTFS_GETU64(boot+0x30);
diff -u --recursive --new-file v2.3.29/linux/fs/open.c linux/fs/open.c
--- v2.3.29/linux/fs/open.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/open.c	Mon Dec  6 14:47:51 1999
@@ -55,14 +55,14 @@
 	return error;
 }
 
-int do_truncate(struct dentry *dentry, unsigned long length)
+int do_truncate(struct dentry *dentry, loff_t length)
 {
 	struct inode *inode = dentry->d_inode;
 	int error;
 	struct iattr newattrs;
 
-	/* Not pretty: "inode->i_size" shouldn't really be "off_t". But it is. */
-	if ((off_t) length < 0)
+	/* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */
+	if (length < 0)
 		return -EINVAL;
 
 	down(&inode->i_sem);
diff -u --recursive --new-file v2.3.29/linux/fs/pipe.c linux/fs/pipe.c
--- v2.3.29/linux/fs/pipe.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/pipe.c	Sun Dec  5 08:42:03 1999
@@ -608,25 +608,6 @@
 
 struct inode_operations pipe_inode_operations = {
 	&rdwr_pipe_fops,
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* get_block */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* flushpage */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL,			/* smap */
-	NULL			/* revalidate */
 };
 
 int do_pipe(int *fd)
diff -u --recursive --new-file v2.3.29/linux/fs/proc/base.c linux/fs/proc/base.c
--- v2.3.29/linux/fs/proc/base.c	Thu Nov 18 20:25:37 1999
+++ linux/fs/proc/base.c	Sun Dec  5 08:42:03 1999
@@ -369,10 +369,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	proc_permission,	/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
@@ -794,7 +792,6 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	proc_permission,	/* permission */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/proc/kmsg.c linux/fs/proc/kmsg.c
--- v2.3.29/linux/fs/proc/kmsg.c	Sat Jun 26 12:04:40 1999
+++ linux/fs/proc/kmsg.c	Sun Dec  5 08:42:03 1999
@@ -61,23 +61,4 @@
 
 struct inode_operations proc_kmsg_inode_operations = {
 	&proc_kmsg_operations,	/* default base directory file-ops */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* get_block */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* flushpage */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL,			/* smap */
-	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/proc/omirr.c linux/fs/proc/omirr.c
--- v2.3.29/linux/fs/proc/omirr.c	Sat Jun 26 12:04:40 1999
+++ linux/fs/proc/omirr.c	Sun Dec  5 08:42:03 1999
@@ -278,23 +278,4 @@
 
 struct inode_operations proc_omirr_inode_operations = {
 	&omirr_operations,
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* get_block */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* flushpage */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL,			/* smap */
-	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/proc/openpromfs.c linux/fs/proc/openpromfs.c
--- v2.3.29/linux/fs/proc/openpromfs.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/proc/openpromfs.c	Sun Dec  5 08:42:03 1999
@@ -565,25 +565,6 @@
 
 static struct inode_operations openpromfs_prop_inode_ops = {
 	&openpromfs_prop_ops,	/* default property file-ops */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* get_block */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* flushpage */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL,			/* smap */
-	NULL			/* revalidate */
 };
 
 static struct file_operations openpromfs_nodenum_ops = {
@@ -602,25 +583,6 @@
 
 static struct inode_operations openpromfs_nodenum_inode_ops = {
 	&openpromfs_nodenum_ops,/* default .node file-ops */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	NULL,			/* readlink */
-	NULL,			/* follow_link */
-	NULL,			/* get_block */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* flushpage */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL,			/* smap */
-	NULL			/* revalidate */
 };
 
 static struct file_operations openprom_alias_operations = {
@@ -653,10 +615,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/proc/proc_devtree.c linux/fs/proc/proc_devtree.c
--- v2.3.29/linux/fs/proc/proc_devtree.c	Fri Oct 15 15:25:14 1999
+++ linux/fs/proc/proc_devtree.c	Sat Dec  4 00:30:56 1999
@@ -41,62 +41,6 @@
  * and "@10" to it.
  */
 
-static int devtree_readlink(struct dentry *, char *, int);
-static struct dentry *devtree_follow_link(struct dentry *, struct dentry *, unsigned int);
-
-struct inode_operations devtree_symlink_inode_operations = {
-	NULL,			/* no file-operations */
-	NULL,			/* create */
-	NULL,			/* lookup */
-	NULL,			/* link */
-	NULL,			/* unlink */
-	NULL,			/* symlink */
-	NULL,			/* mkdir */
-	NULL,			/* rmdir */
-	NULL,			/* mknod */
-	NULL,			/* rename */
-	devtree_readlink,	/* readlink */
-	devtree_follow_link,	/* follow_link */
-	NULL,			/* get_block */
-	NULL,			/* readpage */
-	NULL,			/* writepage */
-	NULL,			/* flushpage */
-	NULL,			/* truncate */
-	NULL,			/* permission */
-	NULL,			/* smap */
-	NULL			/* revalidate */
-};
-
-static struct dentry *devtree_follow_link(struct dentry *dentry,
-					  struct dentry *base,
-					  unsigned int follow)
-{
-	struct inode *inode = dentry->d_inode;
-	struct proc_dir_entry * de;
-	char *link;
-
-	de = (struct proc_dir_entry *) inode->u.generic_ip;
-	link = (char *) de->data;
-	return lookup_dentry(link, base, follow);
-}
-
-static int devtree_readlink(struct dentry *dentry, char *buffer, int buflen)
-{
-	struct inode *inode = dentry->d_inode;
-	struct proc_dir_entry * de;
-	char *link;
-	int linklen;
-
-	de = (struct proc_dir_entry *) inode->u.generic_ip;
-	link = (char *) de->data;
-	linklen = strlen(link);
-	if (linklen > buflen)
-		linklen = buflen;
-	if (copy_to_user(buffer, link, linklen))
-		return -EFAULT;
-	return linklen;
-}
-
 /*
  * Process a node, adding entries for its children and its properties.
  */
@@ -115,18 +59,11 @@
 		 * Unfortunately proc_register puts each new entry
 		 * at the beginning of the list.  So we rearrange them.
 		 */
-		ent = kmalloc(sizeof(struct proc_dir_entry), GFP_KERNEL);
+		ent = create_proc_read_entry(de, 0, pp->name,
+						property_read_proc, pp);
 		if (ent == 0)
 			break;
-		memset(ent, 0, sizeof(struct proc_dir_entry));
-		ent->name = pp->name;
-		ent->namelen = strlen(pp->name);
-		ent->mode = S_IFREG | S_IRUGO;
-		ent->nlink = 1;
-		ent->data = pp;
-		ent->read_proc = property_read_proc;
 		ent->size = pp->length;
-		proc_register(de, ent);
 		*lastp = ent;
 		lastp = &ent->next;
 	}
@@ -140,15 +77,9 @@
 		l = strlen(p);
 		if (l > 2 && p[l-2] == '@' && p[l-1] == '0')
 			l -= 2;
-		ent = kmalloc(sizeof(struct proc_dir_entry), GFP_KERNEL);
+		ent = proc_mkdir(de, p);
 		if (ent == 0)
 			break;
-		memset(ent, 0, sizeof(struct proc_dir_entry));
-		ent->name = p;
-		ent->namelen = l;
-		ent->mode = S_IFDIR | S_IRUGO | S_IXUGO;
-		ent->nlink = 2;
-		proc_register(de, ent);
 		*lastp = ent;
 		lastp = &ent->next;
 		add_node(child, ent);
@@ -168,18 +99,9 @@
 			if (sib->name && strcmp(sib->name, child->name) == 0)
 				break;
 		if (sib == child && strncmp(p, child->name, l) != 0) {
-			al = kmalloc(sizeof(struct proc_dir_entry),
-				     GFP_KERNEL);
+			al = proc_symlink(de, child->name, ent->name);
 			if (al == 0)
 				break;
-			memset(al, 0, sizeof(struct proc_dir_entry));
-			al->name = child->name;
-			al->namelen = strlen(child->name);
-			al->mode = S_IFLNK | S_IRUGO | S_IXUGO;
-			al->nlink = 1;
-			al->data = (void *) ent->name;
-			al->ops = &devtree_symlink_inode_operations;
-			proc_register(de, al);
 			*lastp = al;
 			lastp = &al->next;
 		}
@@ -187,16 +109,9 @@
 		/*
 		 * Add another directory with the @address part as its name.
 		 */
-		al = kmalloc(sizeof(struct proc_dir_entry), GFP_KERNEL);
+		al = proc_symlink(de, at, ent->name);
 		if (al == 0)
 			break;
-		memset(al, 0, sizeof(struct proc_dir_entry));
-		al->name = at;
-		al->namelen = strlen(at);
-		al->mode = S_IFLNK | S_IRUGO | S_IXUGO;
-		al->nlink = 1;
-		al->data = (void *) ent->name;
-		al->ops = &devtree_symlink_inode_operations;
 		proc_register(de, al);
 		*lastp = al;
 		lastp = &al->next;
@@ -213,7 +128,7 @@
 	struct device_node *root;
 	if ( !have_of )
 		return;
-	proc_device_tree = create_proc_entry("device-tree", S_IFDIR, 0);
+	proc_device_tree = proc_mkdir("device-tree", 0);
 	if (proc_device_tree == 0)
 		return;
 	root = find_path_device("/");
diff -u --recursive --new-file v2.3.29/linux/fs/proc/proc_tty.c linux/fs/proc/proc_tty.c
--- v2.3.29/linux/fs/proc/proc_tty.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/proc/proc_tty.c	Sat Nov 27 15:27:49 1999
@@ -171,18 +171,11 @@
  */
 void __init proc_tty_init(void)
 {
-	struct proc_dir_entry *ent;
-	
-	ent = create_proc_entry("tty", S_IFDIR, 0);
-	if (!ent)
+	if (!proc_mkdir("tty", 0))
 		return;
-	proc_tty_ldisc = create_proc_entry("tty/ldisc", S_IFDIR, 0);
-	proc_tty_driver = create_proc_entry("tty/driver", S_IFDIR, 0);
+	proc_tty_ldisc = proc_mkdir("tty/ldisc", 0);
+	proc_tty_driver = proc_mkdir("tty/driver", 0);
 
-	ent = create_proc_entry("tty/ldiscs", 0, 0);
-	ent->read_proc = tty_ldiscs_read_proc;
-
-	ent = create_proc_entry("tty/drivers", 0, 0);
-	ent->read_proc = tty_drivers_read_proc;
+	create_proc_read_entry("tty/ldiscs", 0, 0, tty_ldiscs_read_proc,NULL);
+	create_proc_read_entry("tty/drivers", 0, 0, tty_drivers_read_proc,NULL);
 }
-
diff -u --recursive --new-file v2.3.29/linux/fs/qnx4/dir.c linux/fs/qnx4/dir.c
--- v2.3.29/linux/fs/qnx4/dir.c	Mon Jul  5 19:59:55 1999
+++ linux/fs/qnx4/dir.c	Sun Dec  5 08:42:03 1999
@@ -122,9 +122,7 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/qnx4/file.c linux/fs/qnx4/file.c
--- v2.3.29/linux/fs/qnx4/file.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/qnx4/file.c	Sun Dec  5 08:42:03 1999
@@ -34,7 +34,7 @@
 #define MAX(a,b) (((a)>(b))?(a):(b))
 
 
-static int qnx4_readpage(struct file *file, struct page *page);
+static int qnx4_readpage(struct dentry *dentry, struct page *page);
 
 #ifdef CONFIG_QNX4FS_RW
 static ssize_t qnx4_file_write(struct file *filp, const char *buf,
@@ -192,20 +192,17 @@
 	qnx4_bmap,	        /* get_block */
 	qnx4_readpage,		/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 #ifdef CONFIG_QNX4FS_RW
 	qnx4_truncate,		/* truncate */
 #else
 	NULL,
 #endif
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
-static int qnx4_readpage(struct file *file, struct page *page)
+static int qnx4_readpage(struct dentry *dentry, struct page *page)
 {
-	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	struct qnx4_inode_info *qnx4_ino = &inode->u.qnx4_i;
 	unsigned long buf;
@@ -215,18 +212,17 @@
 	struct buffer_head *bh;
 	int res = -EIO;
 
-	QNX4DEBUG(("qnx4: readpage offset=[%ld]\n", (long) page->offset));
+	QNX4DEBUG(("qnx4: readpage index=[%ld]\n", (long) page->index));
 
 	if (qnx4_ino->i_xblk != 0) {
 		printk("qnx4: sorry, this file is extended, don't know how to handle it (yet) !\n");
 		return -EIO;
 	}
 	atomic_inc(&page->count);
-	set_bit(PG_locked, &page->flags);
 	buf = page_address(page);
 	clear_bit(PG_uptodate, &page->flags);
 	clear_bit(PG_error, &page->flags);
-	offset = page->offset;
+	offset = page->index<<PAGE_SHIFT;
 
 	if (offset < inode->i_size) {
 		res = 0;
@@ -253,8 +249,7 @@
 	} else {
 		set_bit(PG_uptodate, &page->flags);
 	}
-	clear_bit(PG_locked, &page->flags);
-	wake_up(&page->wait);
+	Unlock_Page(page);
 /*  free_page(buf); */
 
 	return res;
diff -u --recursive --new-file v2.3.29/linux/fs/qnx4/inode.c linux/fs/qnx4/inode.c
--- v2.3.29/linux/fs/qnx4/inode.c	Mon Oct  4 15:49:30 1999
+++ linux/fs/qnx4/inode.c	Sat Nov 27 15:27:49 1999
@@ -72,14 +72,6 @@
 	sb->s_dirt = 0;
 }
 
-static void qnx4_put_inode(struct inode *inode)
-{
-	if (inode->i_nlink != 0) {
-		return;
-	}
-	inode->i_size = 0;
-}
-
 static void qnx4_write_inode(struct inode *inode)
 {
 	struct qnx4_inode_entry *raw_inode;
@@ -134,15 +126,13 @@
 #else
 	NULL,
 #endif
+	NULL,			/* put_inode */
 #ifdef CONFIG_QNX4FS_RW
-	qnx4_put_inode,
 	qnx4_delete_inode,
-	NULL,			/* notify_change */
 #else
-	NULL,			/* put_inode */
 	NULL,			/* delete_inode */
-	NULL,			/* notify_change */
 #endif
+	NULL,			/* notify_change */
 	qnx4_put_super,
 #ifdef CONFIG_QNX4FS_RW
 	qnx4_write_super,
diff -u --recursive --new-file v2.3.29/linux/fs/qnx4/symlinks.c linux/fs/qnx4/symlinks.c
--- v2.3.29/linux/fs/qnx4/symlinks.c	Mon Jul  5 19:59:55 1999
+++ linux/fs/qnx4/symlinks.c	Sun Dec  5 08:42:03 1999
@@ -46,10 +46,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/romfs/inode.c linux/fs/romfs/inode.c
--- v2.3.29/linux/fs/romfs/inode.c	Thu Nov 11 20:11:51 1999
+++ linux/fs/romfs/inode.c	Sun Dec  5 08:42:03 1999
@@ -407,9 +407,8 @@
  */
 
 static int
-romfs_readpage(struct file * file, struct page * page)
+romfs_readpage(struct dentry * dentry, struct page * page)
 {
-	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
 	unsigned long buf;
 	unsigned long offset, avail, readlen;
@@ -537,10 +536,8 @@
 	NULL,			/* get_block -- not really */
 	romfs_readpage,		/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
@@ -581,10 +578,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
@@ -604,10 +599,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/smbfs/cache.c linux/fs/smbfs/cache.c
--- v2.3.29/linux/fs/smbfs/cache.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/smbfs/cache.c	Sat Dec  4 00:30:56 1999
@@ -38,102 +38,54 @@
 }
 #endif
 
-/*
- * Get a page for this inode, if new is set then we want to allocate
- * the page if it isn't in memory. As I understand it the rest of the
- * smb-cache code assumes we return a locked page.
- */
-static unsigned long
-get_cached_page(struct address_space *mapping, unsigned long offset, int new)
-{
-	struct page * page;
-	struct page ** hash;
-	struct page *cached_page = NULL;
-
- again:
-	hash = page_hash(mapping, offset);
-	page = __find_lock_page(mapping, offset, hash);
-	if(!page && new) {
-		/* not in cache, alloc a new page if we didn't do it yet */
-		if (!cached_page) {
-			cached_page = page_cache_alloc();
-			if (!cached_page)
-				return 0;
-			/* smb code assumes pages are zeroed */
-			clear_page(page_address(cached_page));
-			goto again;
-		}
-		page = cached_page;
-		if (page->buffers)
-			BUG();
-		printk(KERN_DEBUG "smbfs: get_cached_page\n");
-		if (add_to_page_cache_unique(page, mapping, offset, hash))
-			/* Hmm, a page has materialized in the
-                           cache. Fine. Go back and get that page
-                          instead... */
-			goto again;
-		cached_page = NULL;
-	}
-	printk(KERN_DEBUG "smbfs: get_cached_page done\n");
-	if (cached_page)
-		page_cache_free(cached_page);
-	if(!page)
-		return 0;
-	if(!PageLocked(page))
-		BUG();
-	return page_address(page);
-}
-
 static inline struct address_space * 
 get_cache_inode(struct cache_head *cachep)
 {
-	return (mem_map + MAP_NR((unsigned long) cachep))->mapping;
+	return page_cache_entry((unsigned long) cachep)->mapping;
 }
 
 /*
- * Get a pointer to the cache_head structure,
- * mapped as the page at offset 0. The page is
- * kept locked while we're using the cache.
+ * Try to reassemble the old dircache. If we fail - set ->valid to 0.
+ * In any case, get at least the page at offset 0 (with ->valid==0 if
+ * the old one didn't make it, indeed).
  */
 struct cache_head *
 smb_get_dircache(struct dentry * dentry)
 {
 	struct address_space * mapping = &dentry->d_inode->i_data;
-	struct cache_head * cachep;
+	struct cache_head * cachep = NULL;
+	struct page *page;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-	printk("smb_get_dircache: finding cache for %s/%s\n",
-	       dentry->d_parent->d_name.name, dentry->d_name.name);
-#endif
-	cachep = (struct cache_head *) get_cached_page(mapping, 0, 1);
-	if (!cachep)
+	page = find_lock_page(mapping, 0);
+	if (!page) {
+		/* Sorry, not even page 0 around */
+		page = grab_cache_page(mapping, 0);
+		if (!page)
+			goto out;
+		cachep = (struct cache_head *)kmap(page);
+		memset((char*)cachep, 0, PAGE_SIZE);
 		goto out;
-	if (cachep->valid)
-	{
+	}
+	cachep = (struct cache_head *)kmap(page);
+	if (cachep->valid) {
+		/*
+		 * OK, at least the page 0 survived and seems to be promising.
+		 * Let's try to reassemble the rest.
+		 */
 		struct cache_index * index = cachep->index;
-		struct cache_block * block;
 		unsigned long offset;
 		int i;
 
-		cachep->valid = 0;
-		/*
-		 * Here we only want to find existing cache blocks,
-		 * not add new ones.
-		 */
-		for (i = 0; i < cachep->pages; i++, index++) {
-#ifdef SMBFS_PARANOIA
-if (index->block)
-printk("smb_get_dircache: cache %s/%s has existing block!\n",
-dentry->d_parent->d_name.name, dentry->d_name.name);
-#endif
-			offset = PAGE_SIZE + (i << PAGE_SHIFT);
-			block = (struct cache_block *) get_cached_page(mapping,
-								offset, 0);
-			if (!block)
+		for (offset = 0, i = 0; i < cachep->pages; i++, index++) {
+			offset += PAGE_SIZE;
+			page = find_lock_page(mapping,offset>>PAGE_CACHE_SHIFT);
+			if (!page) {
+				/* Alas, poor Yorick */
+				cachep->valid = 0;
 				goto out;
-			index->block = block;
+			}
+			index->block = (struct cache_block *) kmap(page);
 		}
-		cachep->valid = 1;
 	}
 out:
 	return cachep;
@@ -146,18 +98,20 @@
 smb_free_cache_blocks(struct cache_head * cachep)
 {
 	struct cache_index * index = cachep->index;
+	struct page * page;
 	int i;
 
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_free_cache_blocks: freeing %d blocks\n", cachep->pages);
 #endif
-	for (i = 0; i < cachep->pages; i++, index++)
-	{
-		if (index->block)
-		{
-			put_cached_page((unsigned long) index->block);
-			index->block = NULL;
-		}
+	for (i = 0; i < cachep->pages; i++, index++) {
+		if (!index->block)
+			continue;
+		page = page_cache_entry((unsigned long) index->block);
+		index->block = NULL;
+		kunmap(page);
+		UnlockPage(page);
+		page_cache_release(page);
 	}
 }
 
@@ -167,11 +121,15 @@
 void
 smb_free_dircache(struct cache_head * cachep)
 {
+	struct page *page;
 #ifdef SMBFS_DEBUG_VERBOSE
 printk("smb_free_dircache: freeing cache\n");
 #endif
 	smb_free_cache_blocks(cachep);
-	put_cached_page((unsigned long) cachep);
+	page = page_cache_entry((unsigned long) cachep);
+	kunmap(page);
+	UnlockPage(page);
+	page_cache_release(page);
 }
 
 /*
@@ -199,6 +157,7 @@
 	struct address_space * mapping = get_cache_inode(cachep);
 	struct cache_index * index;
 	struct cache_block * block;
+	struct page *page;
 	unsigned long page_off;
 	unsigned int nent, offset, len = entry->len;
 	unsigned int needed = len + sizeof(struct cache_entry);
@@ -220,8 +179,7 @@
 		goto get_block;
 
 	/* space available? */
-	if (needed < index->space)
-	{
+	if (needed < index->space) {
 	add_entry:
 		nent = index->num_entries;
 		index->num_entries++;
@@ -249,26 +207,17 @@
 	if (cachep->idx > NINDEX) /* not likely */
 		goto out_full;
 	index++;
-#ifdef SMBFS_PARANOIA
-if (index->block)
-printk("smb_add_to_cache: new index already has block!\n");
-#endif
-
 	/*
-	 * Get the next cache block
+	 * Get the next cache block. We don't care for its contents.
 	 */
 get_block:
 	cachep->pages++;
 	page_off = PAGE_SIZE + (cachep->idx << PAGE_SHIFT);
-	block = (struct cache_block *) get_cached_page(mapping, page_off, 1);
-	if (block)
-	{
+	page = grab_cache_page(mapping, page_off>>PAGE_CACHE_SHIFT);
+	if (page) {
+		block = (struct cache_block *)kmap(page);
 		index->block = block;
 		index->space = PAGE_SIZE;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_add_to_cache: mapping=%p, pages=%d, block at %ld\n",
-mapping, cachep->pages, page_off);
-#endif
 		goto add_entry;
 	}
 	/*
diff -u --recursive --new-file v2.3.29/linux/fs/smbfs/dir.c linux/fs/smbfs/dir.c
--- v2.3.29/linux/fs/smbfs/dir.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/smbfs/dir.c	Sun Dec  5 08:42:03 1999
@@ -62,10 +62,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	smb_revalidate_inode,	/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/smbfs/file.c linux/fs/smbfs/file.c
--- v2.3.29/linux/fs/smbfs/file.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/smbfs/file.c	Sun Dec  5 08:42:03 1999
@@ -97,10 +97,9 @@
 	return result;
 }
 
-int
-smb_readpage(struct file *file, struct page *page)
+static int
+smb_readpage(struct dentry *dentry, struct page *page)
 {
-	struct dentry *dentry = file->f_dentry;
 	int		error;
 
 	pr_debug("SMB: smb_readpage %08lx\n", page_address(page));
@@ -168,9 +167,8 @@
  * We are called with the page locked and the caller unlocks.
  */
 static int
-smb_writepage(struct file *file, struct page *page)
+smb_writepage(struct dentry *dentry, struct page *page)
 {
-	struct dentry *dentry = file->f_dentry;
 	int 	result;
 
 #ifdef SMBFS_PARANOIA
@@ -403,9 +401,7 @@
 	NULL,			/* get_block */
 	smb_readpage,		/* readpage */
 	smb_writepage,		/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	smb_file_permission,	/* permission */
-	NULL,			/* smap */
 	smb_revalidate_inode,	/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/sysv/dir.c linux/fs/sysv/dir.c
--- v2.3.29/linux/fs/sysv/dir.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/sysv/dir.c	Sun Dec  5 08:42:03 1999
@@ -62,10 +62,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/sysv/file.c linux/fs/sysv/file.c
--- v2.3.29/linux/fs/sysv/file.c	Mon Jul  5 20:35:18 1999
+++ linux/fs/sysv/file.c	Sun Dec  5 08:42:03 1999
@@ -77,9 +77,7 @@
 	sysv_get_block,		/* get_block */
 	block_read_full_page,	/* readpage */
 	block_write_full_page,	/* writepage */
-	block_flushpage,	/* flushpage */
 	sysv_truncate,		/* truncate */
 	NULL,   		/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/sysv/symlink.c linux/fs/sysv/symlink.c
--- v2.3.29/linux/fs/sysv/symlink.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/sysv/symlink.c	Sun Dec  5 08:42:03 1999
@@ -42,10 +42,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/sysv/truncate.c linux/fs/sysv/truncate.c
--- v2.3.29/linux/fs/sysv/truncate.c	Tue Jun 29 09:22:08 1999
+++ linux/fs/sysv/truncate.c	Sat Nov 27 15:27:49 1999
@@ -36,7 +36,7 @@
  */
 
 #define DATA_BUFFER_USED(bh) \
-	(atomic_read(&bh->b_count) || buffer_locked(bh))
+	(atomic_read(&bh->b_count)>1 || buffer_locked(bh))
 
 /* We throw away any data beyond inode->i_size. */
 
diff -u --recursive --new-file v2.3.29/linux/fs/udf/dir.c linux/fs/udf/dir.c
--- v2.3.29/linux/fs/udf/dir.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/udf/dir.c	Sun Dec  5 08:42:03 1999
@@ -97,10 +97,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/udf/file.c linux/fs/udf/file.c
--- v2.3.29/linux/fs/udf/file.c	Tue Nov 23 22:42:21 1999
+++ linux/fs/udf/file.c	Sun Dec  5 08:42:03 1999
@@ -89,14 +89,12 @@
 	udf_get_block,			/* get_block */
 	block_read_full_page,	/* readpage */
 	block_write_full_page,	/* writepage */
-	block_flushpage,		/* flushpage */
 #ifdef CONFIG_UDF_RW
 	udf_truncate,			/* truncate */
 #else
 	NULL,					/* truncate */
 #endif
 	NULL,					/* permission */
-	NULL,					/* smap */
 	NULL					/* revalidate */
 };
 
@@ -134,14 +132,12 @@
 	udf_get_block,			/* get_block */
 	block_read_full_page,	/* readpage */
 	block_write_full_page,	/* writepage */
-	block_flushpage,		/* flushpage */
 #ifdef CONFIG_UDF_RW
 	udf_truncate,			/* truncate */
 #else
 	NULL,					/* truncate */
 #endif
 	NULL,					/* permission */
-	NULL,					/* smap */
 	NULL					/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/udf/symlink.c linux/fs/udf/symlink.c
--- v2.3.29/linux/fs/udf/symlink.c	Tue Sep  7 12:14:07 1999
+++ linux/fs/udf/symlink.c	Sun Dec  5 08:42:03 1999
@@ -43,25 +43,23 @@
  * symlinks can't do much...
  */
 struct inode_operations udf_symlink_inode_operations = {
-    NULL,			/* no file-operations */
-    NULL,			/* create */
-    NULL,			/* lookup */
-    NULL,			/* link */
-    NULL,			/* unlink */
-    NULL,			/* symlink */
-    NULL,			/* mkdir */
-    NULL,			/* rmdir */
-    NULL,			/* mknod */
-    NULL,			/* rename */
-    udf_readlink,	/* readlink */
-    udf_follow_link,/* follow_link */
+	NULL,			/* no file-operations */
+	NULL,			/* create */
+	NULL,			/* lookup */
+	NULL,			/* link */
+	NULL,			/* unlink */
+	NULL,			/* symlink */
+	NULL,			/* mkdir */
+	NULL,			/* rmdir */
+	NULL,			/* mknod */
+	NULL,			/* rename */
+	udf_readlink,		/* readlink */
+	udf_follow_link,	/* follow_link */
 	NULL,			/* get_block */
-    NULL,			/* readpage */
-    NULL,			/* writepage */
-	NULL,			/* flushpage */
-    NULL,			/* truncate */
-    NULL,			/* permission */
-    NULL,			/* smap */
+	NULL,			/* readpage */
+	NULL,			/* writepage */
+	NULL,			/* truncate */
+	NULL,			/* permission */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/ufs/dir.c linux/fs/ufs/dir.c
--- v2.3.29/linux/fs/ufs/dir.c	Thu Nov 11 20:11:51 1999
+++ linux/fs/ufs/dir.c	Sun Dec  5 08:42:03 1999
@@ -210,9 +210,7 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	ufs_permission,		/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/ufs/file.c linux/fs/ufs/file.c
--- v2.3.29/linux/fs/ufs/file.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/ufs/file.c	Sun Dec  5 08:42:03 1999
@@ -153,9 +153,7 @@
 	ufs_getfrag_block,	/* get_block */
 	block_read_full_page,	/* readpage */
 	block_write_full_page,	/* writepage */
-	block_flushpage,	/* flushpage */
 	ufs_truncate,		/* truncate */
 	NULL, 			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/ufs/symlink.c linux/fs/ufs/symlink.c
--- v2.3.29/linux/fs/ufs/symlink.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/ufs/symlink.c	Sun Dec  5 08:42:03 1999
@@ -132,9 +132,7 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/ufs/truncate.c linux/fs/ufs/truncate.c
--- v2.3.29/linux/fs/ufs/truncate.c	Thu Nov 11 20:11:51 1999
+++ linux/fs/ufs/truncate.c	Sat Nov 27 15:27:49 1999
@@ -63,7 +63,7 @@
 #define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift)
 
 #define DATA_BUFFER_USED(bh) \
-	(atomic_read(&bh->b_count) || buffer_locked(bh))
+	(atomic_read(&bh->b_count)>1 || buffer_locked(bh))
 
 static int ufs_trunc_direct (struct inode * inode)
 {
diff -u --recursive --new-file v2.3.29/linux/fs/umsdos/dir.c linux/fs/umsdos/dir.c
--- v2.3.29/linux/fs/umsdos/dir.c	Mon Aug  9 11:43:49 1999
+++ linux/fs/umsdos/dir.c	Sun Dec  5 08:42:03 1999
@@ -834,9 +834,7 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL,			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/umsdos/rdir.c linux/fs/umsdos/rdir.c
--- v2.3.29/linux/fs/umsdos/rdir.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/umsdos/rdir.c	Sun Dec  5 08:42:03 1999
@@ -252,6 +252,5 @@
 	NULL,			/* get_block */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL,			/* revalidate */
 };
diff -u --recursive --new-file v2.3.29/linux/fs/umsdos/symlink.c linux/fs/umsdos/symlink.c
--- v2.3.29/linux/fs/umsdos/symlink.c	Mon Aug  9 11:43:49 1999
+++ linux/fs/umsdos/symlink.c	Sun Dec  5 08:42:03 1999
@@ -138,10 +138,8 @@
 	fat_get_block,		/* get_block */
 	block_read_full_page,	/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/fs/vfat/namei.c linux/fs/vfat/namei.c
--- v2.3.29/linux/fs/vfat/namei.c	Mon Aug  9 11:43:49 1999
+++ linux/fs/vfat/namei.c	Sun Dec  5 08:42:03 1999
@@ -1205,10 +1205,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	NULL,			/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/cache.h linux/include/asm-alpha/cache.h
--- v2.3.29/linux/include/asm-alpha/cache.h	Fri Aug  6 10:41:47 1999
+++ linux/include/asm-alpha/cache.h	Mon Dec  6 17:15:53 1999
@@ -10,6 +10,4 @@
 #define L1_CACHE_ALIGN(x)  (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
 #define SMP_CACHE_BYTES    L1_CACHE_BYTES
 
-#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
-
 #endif
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/core_irongate.h linux/include/asm-alpha/core_irongate.h
--- v2.3.29/linux/include/asm-alpha/core_irongate.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-alpha/core_irongate.h	Sat Nov 27 15:27:49 1999
@@ -0,0 +1,563 @@
+#ifndef __ALPHA_IRONGATE__H__
+#define __ALPHA_IRONGATE__H__
+
+#include <linux/types.h>
+#include <asm/compiler.h>
+
+/*
+ * IRONGATE is the internal name for the AMD-751 K7 core logic chipset
+ * which provides memory controller and PCI access for NAUTILUS-based
+ * EV6 (21264) systems.
+ *
+ * This file is based on:
+ *
+ * IronGate management library, (c) 1999 Alpha Processor, Inc.
+ * Begun 19 January 1999 by Stig Telfer, Alpha Processor, Inc.
+ */
+
+/*
+ * The 21264 supports, and internally recognizes, a 44-bit physical
+ * address space that is divided equally between memory address space
+ * and I/O address space. Memory address space resides in the lower
+ * half of the physical address space (PA[43]=0) and I/O address space
+ * resides in the upper half of the physical address space (PA[43]=1).
+ *
+ */
+
+/* Eh? Not offset from memory?  */
+#define IRONGATE_DMA_WIN_BASE		 (0U)
+#define IRONGATE_DMA_WIN_SIZE		 (0U)
+
+/*
+ * Irongate CSR map.  Some of the CSRs are 8 or 16 bits, but all access
+ * through the routines given is 32-bit.
+ *
+ * The first 0x40 bytes are standard as per the PCI spec.
+ */
+
+typedef volatile __u32	igcsr32;
+
+typedef struct {
+	igcsr32 dev_vendor;		/* 0x00 - device ID, vendor ID */
+	igcsr32 stat_cmd;		/* 0x04 - status, command */
+	igcsr32 class;			/* 0x08 - class code, rev ID */
+	igcsr32 latency;		/* 0x0C - header type, PCI latency */
+	igcsr32 bar0;			/* 0x10 - BAR0 - AGP */
+	igcsr32 bar1;			/* 0x14 - BAR1 - GART */
+	igcsr32 bar2;			/* 0x18 - Power Management reg block */
+
+	igcsr32 rsrvd0[6];		/* 0x1C-0x33 reserved */
+
+	igcsr32 capptr;			/* 0x34 - Capabilities pointer */
+
+	igcsr32 rsrvd1[2];		/* 0x38-0x3F reserved */
+
+	igcsr32 bacsr10;		/* 0x40 - base address chip selects */
+	igcsr32 bacsr32;		/* 0x44 - base address chip selects */
+	igcsr32 bacsr54;		/* 0x48 - base address chip selects */
+
+	igcsr32 rsrvd2[1];		/* 0x4C-0x4F reserved */
+
+	igcsr32 drammap;		/* 0x50 - address mapping control */
+	igcsr32 dramtm;			/* 0x54 - timing, driver strength */
+	igcsr32 dramms;			/* 0x58 - ECC, mode/status */
+
+	igcsr32 rsrvd3[1];		/* 0x5C-0x5F reserved */
+
+	igcsr32 biu0;			/* 0x60 - bus interface unit */
+	igcsr32 biusip;			/* 0x64 - Serial initialisation pkt */
+
+	igcsr32 rsrvd4[2];		/* 0x68-0x6F reserved */
+
+	igcsr32 mro;			/* 0x70 - memory request optimiser */
+
+	igcsr32 rsrvd5[3];		/* 0x74-0x7F reserved */
+
+	igcsr32 whami;			/* 0x80 - who am I */
+	igcsr32 pciarb;			/* 0x84 - PCI arbitration control */
+	igcsr32 pcicfg;			/* 0x88 - PCI config status */
+
+	igcsr32 rsrvd6[5];		/* 0x8C-0x9F reserved */
+
+	/* AGP (bus 1) control registers */
+	igcsr32 agpcap;			/* 0xA0 - AGP Capability Identifier */
+	igcsr32 agpstat;		/* 0xA4 - AGP status register */
+	igcsr32 agpcmd;			/* 0xA8 - AGP control register */
+	igcsr32 agpva;			/* 0xAC - AGP Virtual Address Space */
+	igcsr32 agpmode;		/* 0xB0 - AGP/GART mode control */
+} Irongate0;
+
+/* Bitfield and mask register definitions */
+
+/* Device, vendor IDs - offset 0x00 */
+
+typedef union {
+	igcsr32 i;			/* integer value of CSR */
+	struct {
+		unsigned v : 16;
+		unsigned d : 16;
+	} r;				/* structured interpretation */
+} ig_dev_vendor_t;
+
+
+/* Status, command registers - offset 0x04 */
+
+typedef union {
+	igcsr32 i;
+	struct {
+		unsigned command;
+		unsigned status;
+	} s;
+	struct {
+		/* command register fields */
+		unsigned iospc : 1;		/* always reads zero */
+		unsigned memspc	 : 1;		/* PCI memory space accesses? */
+		unsigned iten : 1;		/* always 1: can be bus initiator */
+		unsigned scmon : 1;		/* always 0 special cycles not chckd */
+		unsigned mwic : 1;		/* always 0 - no mem write & invalid */
+		unsigned vgaps : 1;		/* always 0 - palette rds not special */
+		unsigned per : 1;		/* parity error resp: always 0 */
+		unsigned step : 1;		/* address/data stepping : always 0 */
+		unsigned serre : 1;		/* 1 = sys err output driver enable */
+		unsigned fbbce : 1;		/* fast back-back cycle : always 0 */
+		unsigned zero1 : 6;		/* must be zero */
+
+		/* status register fields */
+		unsigned zero2 : 4;	     /* must be zero */
+		unsigned cl : 1;	    /* config space capa list: always 1 */
+		unsigned pci66 : 1;	    /* 66 MHz PCI support - always 0 */
+		unsigned udf : 1;	    /* user defined features - always 0 */
+		unsigned fbbc : 1;	    /* back-back transactions - always 0 */
+		unsigned ppe : 1;	    /* PCI parity error detected (0) */
+		unsigned devsel : 2;	    /* DEVSEL timing (always 01) */
+		unsigned sta : 1;	    /* signalled target abort (0) */
+		unsigned rta : 1;	    /* recvd target abort */
+		unsigned ria : 1;	    /* recvd initiator abort */
+		unsigned serr : 1;	    /* SERR has been asserted */
+		unsigned dpe : 1;	    /* DRAM parity error (0) */
+	} r;
+} ig_stat_cmd_t;
+
+
+/* Revision ID, Programming interface, subclass, baseclass - offset 0x08 */
+
+typedef union {
+	igcsr32 i;
+	struct {
+		/* revision ID */
+		unsigned step : 4;		/* stepping Revision ID */
+		unsigned die : 4;		/* die Revision ID */
+		unsigned pif : 8;		/* programming interface (0x00) */
+		unsigned sub : 8;		/* subclass code (0x00) */
+		unsigned base: 8;		/* baseclass code (0x06) */
+	} r;
+} ig_class_t;
+
+
+/* Latency Timer, PCI Header type - offset 0x0C */
+
+typedef union {
+	igcsr32 i;
+	struct {
+		unsigned zero1:8;		/* reserved */
+		unsigned lat : 8;		/* latency in PCI bus clocks */
+		unsigned hdr : 8;		/* PCI header type */
+		unsigned zero2:8;		/* reserved */
+	} r;
+} ig_latency_t;
+
+
+/* Base Address Register 0 - offset 0x10 */
+
+typedef union {
+	igcsr32 i;
+	struct {
+		unsigned mem : 1;		/* Reg pts to memory (always 0) */
+		unsigned type: 2;		/* 32 bit register = 0b00 */
+		unsigned pref: 1;		/* graphics mem prefetchable=1 */
+		unsigned baddrl : 21;		/* 32M = minimum alloc -> all zero */
+		unsigned size : 6;		/* size requirements for AGP */
+		unsigned zero : 1;		/* reserved=0 */
+	} r;
+} ig_bar0_t;
+
+
+/* Base Address Register 1 - offset 0x14 */
+
+typedef union {
+	igcsr32 i;
+	struct {
+		unsigned mem : 1;		/* BAR0 maps to memory -> 0 */
+		unsigned type : 2;		/* BAR1 is 32-bit -> 0b00 */
+		unsigned pref : 1;		/* graphics mem prefetchable=1 */
+		unsigned baddrl : 8;		/* 4K alloc for AGP CSRs -> 0b00 */
+		unsigned baddrh : 20;		/* base addr of AGP CSRs A[30:11] */
+	} r;
+} ig_bar1_t;
+
+
+/* Base Address Register 2 - offset 0x18 */
+
+typedef union {
+	igcsr32 i;
+	struct {
+		unsigned io  : 1;		/* BAR2 maps to I/O space -> 1 */
+		unsigned zero1: 1;		/* reserved */
+		unsigned addr : 22;		/* BAR2[31:10] - PM2_BLK base */
+		unsigned zero2: 8;		/* reserved */
+	} r;
+} ig_bar2_t;
+
+
+/* Capabilities Pointer - offset 0x34 */
+
+typedef union {
+	igcsr32 i;
+	struct {
+		unsigned cap : 8;		/* =0xA0, offset of AGP ctrl regs */
+		unsigned zero: 24;		/* reserved */
+	} r;
+} ig_capptr_t;
+
+
+/* Base Address Chip Select Register 1,0 - offset 0x40 */
+/* Base Address Chip Select Register 3,2 - offset 0x44 */
+/* Base Address Chip Select Register 5,4 - offset 0x48 */
+
+typedef union {
+
+	igcsr32 i;
+	struct {
+		/* lower bank */
+		unsigned en0 : 1;		/* memory bank enabled */
+		unsigned mask0 : 6;		/* Address mask for A[28:23] */
+		unsigned base0 : 9;		/* Bank Base Address A[31:23] */
+
+		/* upper bank */
+		unsigned en1 : 1;		/* memory bank enabled */
+		unsigned mask1 : 6;		/* Address mask for A[28:23] */
+		unsigned base1 : 9;		/* Bank Base Address A[31:23] */
+	} r;
+} ig_bacsr_t, ig_bacsr10_t, ig_bacsr32_t, ig_bacsr54_t;
+
+
+/* SDRAM Address Mapping Control Register - offset 0x50 */
+
+typedef union {
+	igcsr32 i;
+	struct {
+		unsigned z1 : 1;		/* reserved */
+		unsigned bnks0: 1;		/* 0->2 banks in chip select 0 */
+		unsigned am0 : 1;		/* row/column addressing */
+		unsigned z2 : 1;		/* reserved */
+
+		unsigned z3 : 1;		/* reserved */
+		unsigned bnks1: 1;		/* 0->2 banks in chip select 1 */
+		unsigned am1 : 1;		/* row/column addressing */
+		unsigned z4 : 1;		/* reserved */
+
+		unsigned z5 : 1;		/* reserved */
+		unsigned bnks2: 1;		/* 0->2 banks in chip select 2 */
+		unsigned am2 : 1;		/* row/column addressing */
+		unsigned z6 : 1;		/* reserved */
+
+		unsigned z7 : 1;		/* reserved */
+		unsigned bnks3: 1;		/* 0->2 banks in chip select 3 */
+		unsigned am3 : 1;		/* row/column addressing */
+		unsigned z8 : 1;		/* reserved */
+
+		unsigned z9 : 1;		/* reserved */
+		unsigned bnks4: 1;		/* 0->2 banks in chip select 4 */
+		unsigned am4 : 1;		/* row/column addressing */
+		unsigned z10 : 1;		/* reserved */
+
+		unsigned z11 : 1;		/* reserved */
+		unsigned bnks5: 1;		/* 0->2 banks in chip select 5 */
+		unsigned am5 : 1;		/* row/column addressing */
+		unsigned z12 : 1;		/* reserved */
+
+		unsigned rsrvd: 8;		/* reserved */
+	} r;
+} ig_drammap_t;
+
+
+/* DRAM timing and driver strength register - offset 0x54 */
+
+typedef union {
+	igcsr32 i;
+	struct {
+		/* DRAM timing parameters */
+		unsigned trcd : 2;
+		unsigned tcl : 2;
+		unsigned tras: 3;
+		unsigned trp : 2;
+		unsigned trc : 3;
+		unsigned icl: 2;
+		unsigned ph : 2;
+
+		/* Chipselect driver strength */
+		unsigned adra : 1;
+		unsigned adrb : 1;
+		unsigned ctrl : 3;
+		unsigned dqm : 1;
+		unsigned cs : 1;
+		unsigned clk: 1;
+		unsigned rsrvd:8;
+	} r;
+} ig_dramtm_t;
+
+
+/* DRAM Mode / Status and ECC Register - offset 0x58 */
+
+typedef union {
+	igcsr32 i;
+	struct {
+		unsigned chipsel : 6;		/* failing ECC chip select */
+		unsigned zero1 : 2;		/* always reads zero */
+		unsigned status : 2;		/* ECC Detect logic status */
+		unsigned zero2 : 6;		/* always reads zero */
+
+		unsigned cycles : 2;		/* cycles per refresh, see table */
+		unsigned en : 1;		/* ECC enable */
+		unsigned r : 1;			/* Large burst enable (=0) */
+		unsigned bre : 1;		/* Burst refresh enable */
+		unsigned zero3 : 2;		/* reserved = 0 */
+		unsigned mwe : 1;		/* Enable writes to DRAM mode reg */
+		unsigned type : 1;		/* SDRAM = 0, default */
+		unsigned sdraminit : 1;		/* SDRAM init - set params first! */
+		unsigned zero4 : 6;		/* reserved = 0 */
+	} r;
+} ig_dramms_t;
+
+
+/*
+ * Memory spaces:
+ */
+
+/* ??? the following probably needs fixing */
+/* Irongate is consistent with a subset of the Tsunami memory map */
+/* XXX: Do we need to conditionalize on this?  */
+#ifdef USE_48_BIT_KSEG
+#define IRONGATE_BIAS 0x80000000000UL
+#else
+#define IRONGATE_BIAS 0x10000000000UL
+#endif
+
+
+#define IRONGATE_MEM		(IDENT_ADDR | IRONGATE_BIAS | 0x000000000UL)
+#define IRONGATE_IACK_SC	(IDENT_ADDR | IRONGATE_BIAS | 0x1F8000000UL)
+#define IRONGATE_IO		(IDENT_ADDR | IRONGATE_BIAS | 0x1FC000000UL)
+#define IRONGATE_CONF		(IDENT_ADDR | IRONGATE_BIAS | 0x1FE000000UL)
+
+
+#define IRONGATE0		((Irongate0 *) IRONGATE_CONF)
+
+/*
+ * Data structure for handling IRONGATE machine checks:
+ * This is the standard OSF logout frame
+ */
+
+#define SCB_Q_SYSERR	0x620			/* OSF definitions */
+#define SCB_Q_PROCERR	0x630
+#define SCB_Q_SYSMCHK	0x660
+#define SCB_Q_PROCMCHK	0x670
+
+struct el_IRONGATE_sysdata_mcheck {
+	__u32 FrameSize;                 /* Bytes, including this field */
+	__u32 FrameFlags;                /* <31> = Retry, <30> = Second Error */
+	__u32 CpuOffset;                 /* Offset to CPU-specific into */
+	__u32 SystemOffset;              /* Offset to system-specific info */
+	__u32 MCHK_Code;
+	__u32 MCHK_Frame_Rev;
+	__u64 I_STAT;
+	__u64 DC_STAT;
+	__u64 C_ADDR;
+	__u64 DC1_SYNDROME;
+	__u64 DC0_SYNDROME;
+	__u64 C_STAT;
+	__u64 C_STS;
+	__u64 RESERVED0;
+	__u64 EXC_ADDR;
+	__u64 IER_CM;
+	__u64 ISUM;
+	__u64 MM_STAT;
+	__u64 PAL_BASE;
+	__u64 I_CTL;
+	__u64 PCTX;
+};
+
+
+#ifdef __KERNEL__
+
+#ifndef __EXTERN_INLINE
+#define __EXTERN_INLINE extern inline
+#define __IO_EXTERN_INLINE
+#endif
+
+/*
+ * Translate physical memory address as seen on (PCI) bus into
+ * a kernel virtual address and vv.
+ */
+
+__EXTERN_INLINE unsigned long irongate_virt_to_bus(void * address)
+{
+	return virt_to_phys(address) + IRONGATE_DMA_WIN_BASE;
+}
+
+__EXTERN_INLINE void * irongate_bus_to_virt(unsigned long address)
+{
+	return phys_to_virt(address - IRONGATE_DMA_WIN_BASE);
+}
+
+/*
+ * I/O functions:
+ *
+ * IRONGATE (AMD-751) PCI/memory support chip for the EV6 (21264) and
+ * K7 can only use linear accesses to get at PCI memory and I/O spaces.
+ */
+
+#define vucp	volatile unsigned char *
+#define vusp	volatile unsigned short *
+#define vuip	volatile unsigned int *
+#define vulp	volatile unsigned long *
+
+__EXTERN_INLINE unsigned int irongate_inb(unsigned long addr)
+{
+	return __kernel_ldbu(*(vucp)(addr + IRONGATE_IO));
+}
+
+__EXTERN_INLINE void irongate_outb(unsigned char b, unsigned long addr)
+{
+        __kernel_stb(b, *(vucp)(addr + IRONGATE_IO));
+	mb();
+}
+
+__EXTERN_INLINE unsigned int irongate_inw(unsigned long addr)
+{
+	return __kernel_ldwu(*(vusp)(addr + IRONGATE_IO));
+}
+
+__EXTERN_INLINE void irongate_outw(unsigned short b, unsigned long addr)
+{
+        __kernel_stw(b, *(vusp)(addr + IRONGATE_IO));
+	mb();
+}
+
+__EXTERN_INLINE unsigned int irongate_inl(unsigned long addr)
+{
+	return *(vuip)(addr + IRONGATE_IO);
+}
+
+__EXTERN_INLINE void irongate_outl(unsigned int b, unsigned long addr)
+{
+        *(vuip)(addr + IRONGATE_IO) = b;
+	mb();
+}
+
+/*
+ * Memory functions.  All accesses are done through linear space.
+ */
+
+__EXTERN_INLINE unsigned long irongate_readb(unsigned long addr)
+{
+	return __kernel_ldbu(*(vucp)addr);
+}
+
+__EXTERN_INLINE unsigned long irongate_readw(unsigned long addr)
+{
+	return __kernel_ldwu(*(vusp)addr);
+}
+
+__EXTERN_INLINE unsigned long irongate_readl(unsigned long addr)
+{
+	return *(vuip)addr;
+}
+
+__EXTERN_INLINE unsigned long irongate_readq(unsigned long addr)
+{
+	return *(vulp)addr;
+}
+
+__EXTERN_INLINE void irongate_writeb(unsigned char b, unsigned long addr)
+{
+	__kernel_stb(b, *(vucp)addr);
+}
+
+__EXTERN_INLINE void irongate_writew(unsigned short b, unsigned long addr)
+{
+	__kernel_stw(b, *(vusp)addr);
+}
+
+__EXTERN_INLINE void irongate_writel(unsigned int b, unsigned long addr)
+{
+	*(vuip)addr = b;
+}
+
+__EXTERN_INLINE void irongate_writeq(unsigned long b, unsigned long addr)
+{
+	*(vulp)addr = b;
+}
+
+__EXTERN_INLINE unsigned long irongate_ioremap(unsigned long addr)
+{
+	return addr + IRONGATE_MEM;
+}
+
+__EXTERN_INLINE int irongate_is_ioaddr(unsigned long addr)
+{
+	return addr >= IRONGATE_MEM;
+}
+
+#undef vucp
+#undef vusp
+#undef vuip
+#undef vulp
+
+#ifdef __WANT_IO_DEF
+
+#define virt_to_bus	irongate_virt_to_bus
+#define bus_to_virt	irongate_bus_to_virt
+
+#define __inb		irongate_inb
+#define __inw		irongate_inw
+#define __inl		irongate_inl
+#define __outb		irongate_outb
+#define __outw		irongate_outw
+#define __outl		irongate_outl
+#define __readb		irongate_readb
+#define __readw		irongate_readw
+#define __writeb	irongate_writeb
+#define __writew	irongate_writew
+#define __readl		irongate_readl
+#define __readq		irongate_readq
+#define __writel	irongate_writel
+#define __writeq	irongate_writeq
+#define __ioremap	irongate_ioremap
+#define __is_ioaddr	irongate_is_ioaddr
+
+#define inb(port)	__inb((port))
+#define inw(port)	__inw((port))
+#define inl(port)	__inl((port))
+#define outb(v, port)	__outb((v),(port))
+#define outw(v, port)	__outw((v),(port))
+#define outl(v, port)	__outl((v),(port))
+
+#define __raw_readb(a)		__readb((unsigned long)(a))
+#define __raw_readw(a)		__readw((unsigned long)(a))
+#define __raw_readl(a)		__readl((unsigned long)(a))
+#define __raw_readq(a)		__readq((unsigned long)(a))
+#define __raw_writeb(v,a)	__writeb((v),(unsigned long)(a))
+#define __raw_writew(v,a)	__writew((v),(unsigned long)(a))
+#define __raw_writel(v,a)	__writel((v),(unsigned long)(a))
+#define __raw_writeq(v,a)	__writeq((v),(unsigned long)(a))
+
+#endif /* __WANT_IO_DEF */
+
+#ifdef __IO_EXTERN_INLINE
+#undef __EXTERN_INLINE
+#undef __IO_EXTERN_INLINE
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ALPHA_IRONGATE__H__ */
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/core_tsunami.h linux/include/asm-alpha/core_tsunami.h
--- v2.3.29/linux/include/asm-alpha/core_tsunami.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-alpha/core_tsunami.h	Sat Nov 27 19:34:31 1999
@@ -293,7 +293,6 @@
 
 /* The IO address space is larger than 0xffff */
 #define TSUNAMI_IO_SPACE	(TSUNAMI_CONF(0) - TSUNAMI_IO(0))
-#define TSUNAMI_MEM_SPACE	(_TSUNAMI_IACK_SC(0) - TSUNAMI_MEM(0))
 
 /*
  * Data structure for handling TSUNAMI machine checks:
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/dma.h linux/include/asm-alpha/dma.h
--- v2.3.29/linux/include/asm-alpha/dma.h	Fri Sep 10 23:57:36 1999
+++ linux/include/asm-alpha/dma.h	Sat Nov 27 15:27:49 1999
@@ -91,6 +91,7 @@
 */
 #define ALPHA_XL_MAX_DMA_ADDRESS	(IDENT_ADDR+0x3000000UL)
 #define ALPHA_RUFFIAN_MAX_DMA_ADDRESS	(IDENT_ADDR+0x1000000UL)
+#define ALPHA_NAUTILUS_MAX_DMA_ADDRESS	(IDENT_ADDR+0x1000000UL)
 #define ALPHA_MAX_DMA_ADDRESS		(~0UL)
 
 #ifdef CONFIG_ALPHA_GENERIC
@@ -100,6 +101,8 @@
 #  define MAX_DMA_ADDRESS		ALPHA_XL_MAX_DMA_ADDRESS
 # elif defined(CONFIG_ALPHA_RUFFIAN)
 #  define MAX_DMA_ADDRESS		ALPHA_RUFFIAN_MAX_DMA_ADDRESS
+# elif defined(CONFIG_ALPHA_NAUTILUS)
+#  define MAX_DMA_ADDRESS		ALPHA_NAUTILUS_MAX_DMA_ADDRESS
 # else
 #  define MAX_DMA_ADDRESS		ALPHA_MAX_DMA_ADDRESS
 # endif
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/floppy.h linux/include/asm-alpha/floppy.h
--- v2.3.29/linux/include/asm-alpha/floppy.h	Sun Sep  6 10:34:33 1998
+++ linux/include/asm-alpha/floppy.h	Sat Nov 27 15:27:49 1999
@@ -64,7 +64,7 @@
 #ifdef CONFIG_ALPHA_GENERIC
 # define CROSS_64KB(a,s)   (__CROSS_64KB(a,s) && ~alpha_mv.max_dma_address)
 #else
-# if defined(CONFIG_ALPHA_XL) || defined(CONFIG_ALPHA_RUFFIAN)
+# if defined(CONFIG_ALPHA_XL) || defined(CONFIG_ALPHA_RUFFIAN) || defined(CONFIG_ALPHA_NAUTILUS)
 #  define CROSS_64KB(a,s)  __CROSS_64KB(a,s)
 # else
 #  define CROSS_64KB(a,s)  (0)
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/fpu.h linux/include/asm-alpha/fpu.h
--- v2.3.29/linux/include/asm-alpha/fpu.h	Mon May 10 09:55:21 1999
+++ linux/include/asm-alpha/fpu.h	Thu Dec  2 15:28:54 1999
@@ -4,6 +4,8 @@
 /*
  * Alpha floating-point control register defines:
  */
+#define FPCR_DNOD	(1UL<<47)	/* denorm INV trap disable */
+#define FPCR_DNZ	(1UL<<48)	/* denorms to zero */
 #define FPCR_INVD	(1UL<<49)	/* invalid op disable (opt.) */
 #define FPCR_DZED	(1UL<<50)	/* division by zero disable (opt.) */
 #define FPCR_OVFD	(1UL<<51)	/* overflow disable (optional) */
@@ -42,9 +44,16 @@
 #define IEEE_TRAP_ENABLE_OVF	(1UL<<3)	/* overflow */
 #define IEEE_TRAP_ENABLE_UNF	(1UL<<4)	/* underflow */
 #define IEEE_TRAP_ENABLE_INE	(1UL<<5)	/* inexact */
+#define IEEE_TRAP_ENABLE_DNO	(1UL<<6)	/* denorm */
 #define IEEE_TRAP_ENABLE_MASK	(IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE |\
 				 IEEE_TRAP_ENABLE_OVF | IEEE_TRAP_ENABLE_UNF |\
-				 IEEE_TRAP_ENABLE_INE)
+				 IEEE_TRAP_ENABLE_INE | IEEE_TRAP_ENABLE_DNO)
+
+/* Denorm and Underflow flushing */
+#define IEEE_MAP_DMZ		(1UL<<12)	/* Map denorm inputs to zero */
+#define IEEE_MAP_UMZ		(1UL<<13)	/* Map underflowed outputs to zero */
+
+#define IEEE_MAP_MASK		(IEEE_MAP_DMZ | IEEE_MAP_UMZ)
 
 /* status bits coming from fpcr: */
 #define IEEE_STATUS_INV		(1UL<<17)
@@ -52,12 +61,16 @@
 #define IEEE_STATUS_OVF		(1UL<<19)
 #define IEEE_STATUS_UNF		(1UL<<20)
 #define IEEE_STATUS_INE		(1UL<<21)
+#define IEEE_STATUS_DNO		(1UL<<22)
 
 #define IEEE_STATUS_MASK	(IEEE_STATUS_INV | IEEE_STATUS_DZE |	\
 				 IEEE_STATUS_OVF | IEEE_STATUS_UNF |	\
-				 IEEE_STATUS_INE)
+				 IEEE_STATUS_INE | IEEE_STATUS_DNO)
+
+#define IEEE_SW_MASK		(IEEE_TRAP_ENABLE_MASK | IEEE_STATUS_MASK | IEEE_MAP_MASK)
 
-#define IEEE_SW_MASK		(IEEE_TRAP_ENABLE_MASK | IEEE_STATUS_MASK)
+#define IEEE_CURRENT_RM_SHIFT	32
+#define IEEE_CURRENT_RM_MASK	(3UL<<IEEE_CURRENT_RM_SHIFT)
 
 #define IEEE_STATUS_TO_EXCSUM_SHIFT	16
 
@@ -78,6 +91,7 @@
 		      | IEEE_TRAP_ENABLE_DZE
 		      | IEEE_TRAP_ENABLE_OVF)) << 48;
 	fp |= (~sw & (IEEE_TRAP_ENABLE_UNF | IEEE_TRAP_ENABLE_INE)) << 57;
+	fp |= (~sw & IEEE_TRAP_ENABLE_DNO) << 41;
 	return fp;
 }
 
@@ -90,6 +104,7 @@
 			     | IEEE_TRAP_ENABLE_DZE
 			     | IEEE_TRAP_ENABLE_OVF);
 	sw |= (~fp >> 57) & (IEEE_TRAP_ENABLE_UNF | IEEE_TRAP_ENABLE_INE);
+	sw |= (~fp >> 41) & IEEE_TRAP_ENABLE_DNO;
 	return sw;
 }
 
@@ -124,6 +139,8 @@
 
 extern unsigned long alpha_read_fp_reg (unsigned long reg);
 extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
+extern unsigned long alpha_read_fp_reg_s (unsigned long reg);
+extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val);
 
 #endif /* __KERNEL__ */
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/hardirq.h linux/include/asm-alpha/hardirq.h
--- v2.3.29/linux/include/asm-alpha/hardirq.h	Fri Sep 10 23:57:36 1999
+++ linux/include/asm-alpha/hardirq.h	Mon Dec  6 17:15:53 1999
@@ -28,8 +28,8 @@
 #define hardirq_trylock(cpu)	(local_irq_count(cpu) == 0)
 #define hardirq_endlock(cpu)	((void) 0)
 
-#define hardirq_enter(cpu, irq)	(local_irq_count(cpu)++)
-#define hardirq_exit(cpu, irq)	(local_irq_count(cpu)--)
+#define irq_enter(cpu, irq)	(local_irq_count(cpu)++)
+#define irq_exit(cpu, irq)	(local_irq_count(cpu)--)
 
 #define synchronize_irq()	barrier()
 
@@ -52,13 +52,16 @@
         }
 }
 
-static inline void hardirq_enter(int cpu, int irq)
+static inline void irq_enter(int cpu, int irq)
 {
 	++local_irq_count(cpu);
         atomic_inc(&global_irq_count);
+
+	while (spin_is_locked(&global_irq_lock))
+		barrier();
 }
 
-static inline void hardirq_exit(int cpu, int irq)
+static inline void irq_exit(int cpu, int irq)
 {
 	atomic_dec(&global_irq_count);
         --local_irq_count(cpu);
@@ -66,11 +69,10 @@
 
 static inline int hardirq_trylock(int cpu)
 {
-	return (!atomic_read(&global_irq_count)
-		&& !spin_is_locked(&global_irq_lock));
+	return !local_irq_count(cpu) && !spin_is_locked(&global_irq_lock);
 }
 
-#define hardirq_endlock(cpu)  ((void)0)
+#define hardirq_endlock(cpu)	do { } while (0)
 
 extern void synchronize_irq(void);
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/hw_irq.h linux/include/asm-alpha/hw_irq.h
--- v2.3.29/linux/include/asm-alpha/hw_irq.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-alpha/hw_irq.h	Mon Dec  6 17:15:53 1999
@@ -0,0 +1,91 @@
+#ifndef _ALPHA_HW_IRQ_H
+#define _ALPHA_HW_IRQ_H
+/*
+ *	linux/arch/alpha/kernel/irq.h
+ *
+ *	Copyright (C) 1995 Linus Torvalds
+ *	Copyright (C) 1998 Richard Henderson
+ *
+ * This file contains declarations and inline functions for interfacing
+ * with the IRQ handling routines in irq.c.
+ */
+
+#include <linux/config.h>
+
+#define STANDARD_INIT_IRQ_PROLOG	\
+	outb(0, DMA1_RESET_REG);	\
+	outb(0, DMA2_RESET_REG);	\
+	outb(0, DMA1_CLR_MASK_REG);	\
+	outb(0, DMA2_CLR_MASK_REG)
+
+extern unsigned long _alpha_irq_masks[2];
+#define alpha_irq_mask _alpha_irq_masks[0]
+
+extern void common_ack_irq(unsigned long irq);
+extern void isa_device_interrupt(unsigned long vector, struct pt_regs * regs);
+extern void srm_device_interrupt(unsigned long vector, struct pt_regs * regs);
+
+extern void handle_irq(int irq, int ack, struct pt_regs * regs);
+
+#define RTC_IRQ    8
+#ifdef CONFIG_RTC
+#define TIMER_IRQ  0			 /* timer is the pit */
+#else
+#define TIMER_IRQ  RTC_IRQ		 /* timer is the rtc */
+#endif
+
+/*
+ * PROBE_MASK is the bitset of irqs that we consider for autoprobing.
+ */
+
+/* NOTE: we only handle the first 64 IRQs in this code. */
+
+/* The normal mask includes all the IRQs except timer IRQ 0.  */
+#define _PROBE_MASK(nr_irqs)	\
+	(((nr_irqs > 63) ? ~0UL : ((1UL << (nr_irqs & 63)) - 1)) & ~1UL)
+
+/* Mask out unused timer irq 0 and RTC irq 8. */
+#define P2K_PROBE_MASK		(_PROBE_MASK(16) & ~0x101UL)
+
+/* Mask out unused timer irq 0, "irqs" 20-30, and the EISA cascade. */
+#define ALCOR_PROBE_MASK	(_PROBE_MASK(48) & ~0xfff000000001UL)
+
+/* Leave timer IRQ 0 in the mask.  */
+#define RUFFIAN_PROBE_MASK	(_PROBE_MASK(48) | 1UL)
+
+/* Do not probe/enable beyond the PCI devices. */
+#define TSUNAMI_PROBE_MASK	_PROBE_MASK(48)
+
+#if defined(CONFIG_ALPHA_GENERIC)
+# define PROBE_MASK	alpha_mv.irq_probe_mask
+#elif defined(CONFIG_ALPHA_P2K)
+# define PROBE_MASK	P2K_PROBE_MASK
+#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
+# define PROBE_MASK	ALCOR_PROBE_MASK
+#elif defined(CONFIG_ALPHA_RUFFIAN)
+# define PROBE_MASK	RUFFIAN_PROBE_MASK
+#elif defined(CONFIG_ALPHA_DP264)
+# define PROBE_MASK	TSUNAMI_PROBE_MASK
+#else
+# define PROBE_MASK	_PROBE_MASK(NR_IRQS)
+#endif
+
+
+extern char _stext;
+static inline void alpha_do_profile (unsigned long pc)
+{
+	if (prof_buffer && current->pid) {
+		pc -= (unsigned long) &_stext;
+		pc >>= prof_shift;
+		/*
+		 * Don't ignore out-of-bounds PC values silently,
+		 * put them into the last histogram slot, so if
+		 * present, they will show up as a sharp peak.
+		 */
+		if (pc > prof_len - 1)
+			pc = prof_len - 1;
+		atomic_inc((atomic_t *)&prof_buffer[pc]);
+	}
+}
+
+#endif
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/hwrpb.h linux/include/asm-alpha/hwrpb.h
--- v2.3.29/linux/include/asm-alpha/hwrpb.h	Mon Oct 12 11:40:13 1998
+++ linux/include/asm-alpha/hwrpb.h	Sat Nov 27 15:27:49 1999
@@ -55,10 +55,15 @@
 #define ST_DEC_TSUNAMI		 34	/* Tsunami systype	*/
 #define ST_DEC_WILDFIRE		 35	/* Wildfire systype	*/
 #define ST_DEC_CUSCO		 36	/* CUSCO systype	*/
+#define ST_DEC_EIGER		 37	/* Eiger systype	*/
 
 /* UNOFFICIAL!!! */
 #define ST_UNOFFICIAL_BIAS	100
 #define ST_DTI_RUFFIAN		101	/* RUFFIAN systype	*/
+
+/* Alpha Processor, Inc. systems */
+#define ST_API_BIAS		200			/* Offset for API systems */
+#define ST_API_NAUTILUS		(ST_API_BIAS + 1)	/* Nautilus systype */
 
 struct pcb_struct {
 	unsigned long ksp;
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/io.h linux/include/asm-alpha/io.h
--- v2.3.29/linux/include/asm-alpha/io.h	Tue Aug 31 17:29:14 1999
+++ linux/include/asm-alpha/io.h	Sat Nov 27 15:27:49 1999
@@ -132,20 +132,22 @@
 # include <asm/core_apecs.h>
 #elif defined(CONFIG_ALPHA_CIA)
 # include <asm/core_cia.h>
+#elif defined(CONFIG_ALPHA_IRONGATE)
+# include <asm/core_irongate.h>
+#elif defined(CONFIG_ALPHA_JENSEN)
+# include <asm/jensen.h>
 #elif defined(CONFIG_ALPHA_LCA)
 # include <asm/core_lca.h>
 #elif defined(CONFIG_ALPHA_MCPCIA)
 # include <asm/core_mcpcia.h>
+#elif defined(CONFIG_ALPHA_POLARIS)
+# include <asm/core_polaris.h>
 #elif defined(CONFIG_ALPHA_PYXIS)
 # include <asm/core_pyxis.h>
 #elif defined(CONFIG_ALPHA_T2)
 # include <asm/core_t2.h>
 #elif defined(CONFIG_ALPHA_TSUNAMI)
 # include <asm/core_tsunami.h>
-#elif defined(CONFIG_ALPHA_JENSEN)
-# include <asm/jensen.h>
-#elif defined(CONFIG_ALPHA_POLARIS)
-# include <asm/core_polaris.h>
 #else
 #error "What system is this?"
 #endif
@@ -223,6 +225,8 @@
 #ifndef outl_p
 # define outl_p		outl
 #endif
+
+#define IO_SPACE_LIMIT 0xffff
 
 #else 
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/irq.h linux/include/asm-alpha/irq.h
--- v2.3.29/linux/include/asm-alpha/irq.h	Fri May 14 12:41:23 1999
+++ linux/include/asm-alpha/irq.h	Mon Dec  6 17:15:53 1999
@@ -16,7 +16,7 @@
    many places throughout the kernel to size static arrays.  That's ok,
    we'll use alpha_mv.nr_irqs when we want the real thing.  */
 
-# define NR_IRQS	64
+# define NR_IRQS	128
 
 #elif defined(CONFIG_ALPHA_CABRIOLET) || \
       defined(CONFIG_ALPHA_EB66P)     || \
@@ -43,45 +43,17 @@
 # define NR_IRQS	40
 
 #elif defined(CONFIG_ALPHA_DP264) || \
-      defined(CONFIG_ALPHA_RAWHIDE)
+      defined(CONFIG_ALPHA_EIGER)
 # define NR_IRQS	64
 
-#elif defined(CONFIG_ALPHA_TAKARA)
-# define NR_IRQS	20
+#elif defined(CONFIG_ALPHA_RAWHIDE) || \
+	defined(CONFIG_ALPHA_TAKARA)
+# define NR_IRQS	128
 
 #else /* everyone else */
 # define NR_IRQS	16
 #endif
 
-/*
- * PROBE_MASK is the bitset of irqs that we consider for autoprobing.
- */
-
-/* The normal mask includes all the IRQs except the timer.  */
-#define _PROBE_MASK(nr_irqs)	(((1UL << (nr_irqs & 63)) - 1) & ~1UL)
-
-/* Mask out unused timer irq 0 and RTC irq 8. */
-#define P2K_PROBE_MASK		(_PROBE_MASK(16) & ~0x101UL)
-
-/* Mask out unused timer irq 0, "irqs" 20-30, and the EISA cascade. */
-#define ALCOR_PROBE_MASK	(_PROBE_MASK(48) & ~0xfff000000001UL)
-
-/* Leave timer irq 0 in the mask.  */
-#define RUFFIAN_PROBE_MASK	(_PROBE_MASK(48) | 1UL)
-
-#if defined(CONFIG_ALPHA_GENERIC)
-# define PROBE_MASK	alpha_mv.irq_probe_mask
-#elif defined(CONFIG_ALPHA_P2K)
-# define PROBE_MASK	P2K_PROBE_MASK
-#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
-# define PROBE_MASK	ALCOR_PROBE_MASK
-#elif defined(CONFIG_ALPHA_RUFFIAN)
-# define PROBE_MASK	RUFFIAN_PROBE_MASK
-#else
-# define PROBE_MASK	_PROBE_MASK(NR_IRQS)
-#endif
-
-
 static __inline__ int irq_cannonicalize(int irq)
 {
 	/*
@@ -94,9 +66,6 @@
 extern void disable_irq(unsigned int);
 extern void disable_irq_nosync(unsigned int);
 extern void enable_irq(unsigned int);
-
-extern void irq_enter(int cpu, int irq);
-extern void irq_exit(int cpu, int irq);
 
 struct pt_regs;
 extern void (*perf_irq)(unsigned long, struct pt_regs *);
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/machvec.h linux/include/asm-alpha/machvec.h
--- v2.3.29/linux/include/asm-alpha/machvec.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-alpha/machvec.h	Thu Dec  2 15:27:02 1999
@@ -82,7 +82,7 @@
 	void (*init_irq)(void);
 	void (*init_pit)(void);
 	void (*init_pci)(void);
-	void (*kill_arch)(int, char *);
+	void (*kill_arch)(int);
 
 	u8 (*pci_swizzle)(struct pci_dev *, u8 *);
 	int (*pci_map_irq)(struct pci_dev *, u8, u8);
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/mmu_context.h linux/include/asm-alpha/mmu_context.h
--- v2.3.29/linux/include/asm-alpha/mmu_context.h	Thu Jul 29 13:42:27 1999
+++ linux/include/asm-alpha/mmu_context.h	Thu Dec  2 15:20:56 1999
@@ -160,6 +160,8 @@
 
         current->thread.ptbr
 	  = ((unsigned long) next_mm->pgd - IDENT_ADDR) >> PAGE_SHIFT;
+
+	__reload_thread(&current->thread);
 }
 
 __EXTERN_INLINE void
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/page.h linux/include/asm-alpha/page.h
--- v2.3.29/linux/include/asm-alpha/page.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-alpha/page.h	Sat Nov 27 15:27:49 1999
@@ -106,16 +106,7 @@
 
 #endif /* STRICT_MM_TYPECHECKS */
 
-#if 0
 #define BUG()		__asm__ __volatile__("call_pal 129 # bugchk")
-#else
-/* hack to see the BUG() information in the early boot stage */
-#define BUG()								\
-do {									\
-	SRM_printf("kernel BUG at %s:%d!\n", __FILE__, __LINE__);	\
-	halt();								\
-} while(0)
-#endif
 #define PAGE_BUG(page)	BUG()
 
 #endif /* !ASSEMBLY */
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/pgtable.h linux/include/asm-alpha/pgtable.h
--- v2.3.29/linux/include/asm-alpha/pgtable.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-alpha/pgtable.h	Mon Dec  6 10:14:13 1999
@@ -221,7 +221,6 @@
 extern inline void pgd_clear(pgd_t * pgdp)	{ pgd_val(*pgdp) = 0; }
 
 #define page_address(page)	((page)->virtual)
-#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
 
 /*
  * The following only work if pte_present() is true.
@@ -297,7 +296,7 @@
 #define kern_addr_valid(addr)	(1)
 
 #define io_remap_page_range(start, busaddr, size, prot) \
-	remap_page_range(start, virt_to_phys(__ioremap(busaddr), 0), size, prot)
+	remap_page_range(start, virt_to_phys(__ioremap(busaddr)), size, prot)
 
 #define pte_ERROR(e) \
 	printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h
--- v2.3.29/linux/include/asm-alpha/processor.h	Thu Nov 11 20:11:51 1999
+++ linux/include/asm-alpha/processor.h	Sat Nov 27 15:27:49 1999
@@ -127,13 +127,18 @@
 #define forget_segments()		do { } while (0)
 
 unsigned long get_wchan(struct task_struct *p);
-/*
-* See arch/alpha/kernel/ptrace.c for details.
-*/
-#define PT_REG(reg)		(PAGE_SIZE - sizeof(struct pt_regs)	\
-				 + (long)&((struct pt_regs *)0)->reg)
+
+/* See arch/alpha/kernel/ptrace.c for details.  */
+#define PT_REG(reg)	(PAGE_SIZE*2 - sizeof(struct pt_regs)		\
+			 + (long)&((struct pt_regs *)0)->reg)
+
+#define SW_REG(reg)	(PAGE_SIZE*2 - sizeof(struct pt_regs)		\
+			 - sizeof(struct switch_stack)			\
+			 + (long)&((struct switch_stack *)0)->reg)
+
 #define KSTK_EIP(tsk) \
-    (*(unsigned long *)(PT_REG(pc) + PAGE_SIZE + (unsigned long)(tsk)))
+    (*(unsigned long *)(PT_REG(pc) + (unsigned long)(tsk)))
+
 #define KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
 
 /* NOTE: The task struct and the stack go together!  */
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/sfp-machine.h linux/include/asm-alpha/sfp-machine.h
--- v2.3.29/linux/include/asm-alpha/sfp-machine.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-alpha/sfp-machine.h	Thu Dec  2 15:28:54 1999
@@ -0,0 +1,84 @@
+/* Machine-dependent software floating-point definitions.
+   Alpha kernel version.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jakub@redhat.com) and
+		  David S. Miller (davem@redhat.com).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _SFP_MACHINE_H
+#define _SFP_MACHINE_H
+   
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_1_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		_FP_QNANBIT_S
+#define _FP_NANFRAC_D		_FP_QNANBIT_D
+#define _FP_NANFRAC_Q		_FP_QNANBIT_Q
+#define _FP_NANSIGN_S		1
+#define _FP_NANSIGN_D		1
+#define _FP_NANSIGN_Q		1
+
+#define _FP_KEEPNANFRACP 1
+
+/* Alpha Architecture Handbook, 4.7.10.4 sais that
+ * we should prefer any type of NaN in Fb, then Fa.
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    R##_s = Y##_s;						\
+    _FP_FRAC_COPY_##wc(R,X);					\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+/* Obtain the current rounding mode. */
+#define FP_ROUNDMODE	mode
+#define FP_RND_NEAREST	(FPCR_DYN_NORMAL >> FPCR_DYN_SHIFT)
+#define FP_RND_ZERO	(FPCR_DYN_CHOPPED >> FPCR_DYN_SHIFT)
+#define FP_RND_PINF	(FPCR_DYN_PLUS >> FPCR_DYN_SHIFT)
+#define FP_RND_MINF	(FPCR_DYN_MINUS >> FPCR_DYN_SHIFT)
+
+/* Exception flags. */
+#define FP_EX_INVALID		IEEE_TRAP_ENABLE_INV
+#define FP_EX_OVERFLOW		IEEE_TRAP_ENABLE_OVF
+#define FP_EX_UNDERFLOW		IEEE_TRAP_ENABLE_UNF
+#define FP_EX_DIVZERO		IEEE_TRAP_ENABLE_DZE
+#define FP_EX_INEXACT		IEEE_TRAP_ENABLE_INE
+#define FP_EX_DENORM		IEEE_TRAP_ENABLE_DNO
+
+#define FP_DENORM_ZERO		(fpcw & IEEE_MAP_DMZ)
+
+#define FP_HANDLE_EXCEPTIONS return _fex
+
+/* We write the results always */
+#define FP_INHIBIT_RESULTS 0
+
+#endif
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h
--- v2.3.29/linux/include/asm-alpha/system.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-alpha/system.h	Sat Nov 27 15:27:49 1999
@@ -86,6 +86,30 @@
         unsigned long   ld_lock;          /* Contents of EV5 LD_LOCK register*/
 };
 
+struct el_common_EV6_mcheck {
+	unsigned int FrameSize;		/* Bytes, including this field */
+	unsigned int FrameFlags;	/* <31> = Retry, <30> = Second Error */
+	unsigned int CpuOffset;		/* Offset to CPU-specific info */
+	unsigned int SystemOffset;	/* Offset to system-specific info */
+	unsigned int MCHK_Code;
+	unsigned int MCHK_Frame_Rev;
+	unsigned long I_STAT;		/* EV6 Internal Processor Registers */
+	unsigned long DC_STAT;		/* (See the 21264 Spec) */
+	unsigned long C_ADDR;
+	unsigned long DC1_SYNDROME;
+	unsigned long DC0_SYNDROME;
+	unsigned long C_STAT;
+	unsigned long C_STS;
+	unsigned long RESERVED0;
+	unsigned long EXC_ADDR;
+	unsigned long IER_CM;
+	unsigned long ISUM;
+	unsigned long MM_STAT;
+	unsigned long PAL_BASE;
+	unsigned long I_CTL;
+	unsigned long PCTX;
+};
+
 extern void halt(void) __attribute__((noreturn));
 
 #define prepare_to_switch()	do { } while(0)
@@ -362,17 +386,6 @@
 #define xchg(ptr,x) \
   ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
 #define tas(ptr) (xchg((ptr),1))
-
-/* Very dirty but nevertheless very fun hack ;). I recall the aboot printf()
-   that will in turn use the SRM  console to do the debugging of the boot
-   process. As there's no runtime symbol table, the address of printf()
-   is hardwired and is in function of the bootlx binary you have in /boot...
-   1999 Andrea Arcangeli <andrea@suse.de> */
-#if 0
-#define SRM_printf(args...) ({ int (*__SRM_printf)(const char *fmt, ...) = (int (*)(const char *fmt, ...)) 0x20000aa0; __SRM_printf(args); })
-#else
-#define SRM_printf(args...)
-#endif
 
 #endif /* __ASSEMBLY__ */
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-alpha/vga.h linux/include/asm-alpha/vga.h
--- v2.3.29/linux/include/asm-alpha/vga.h	Tue Aug 31 17:29:14 1999
+++ linux/include/asm-alpha/vga.h	Sat Nov 27 15:27:49 1999
@@ -11,6 +11,7 @@
 
 #define VT_BUF_HAVE_RW
 #define VT_BUF_HAVE_MEMSETW
+#define VT_BUF_HAVE_MEMCPYW
 #define VT_BUF_HAVE_MEMCPYF
 
 extern inline void scr_writew(u16 val, u16 *addr)
@@ -37,15 +38,10 @@
 		memsetw(s, c, count);
 }
 
-extern inline void scr_memcpyw_from(u16 *d, const u16 *s, unsigned int count)
-{
-	memcpy_fromio(d, s, count);
-}
-
-extern inline void scr_memcpyw_to(u16 *d, const u16 *s, unsigned int count)
-{
-	memcpy_toio(d, s, count);
-}
+/* Do not trust that the usage will be correct; analyze the arguments.  */
+extern void scr_memcpyw(u16 *d, const u16 *s, unsigned int count);
+#define scr_memcpyw_from scr_memcpyw
+#define scr_memcpyw_to   scr_memcpyw
 
 /* ??? These are currently only used for downloading character sets.  As
    such, they don't need memory barriers.  Is this all they are intended
diff -u --recursive --new-file v2.3.29/linux/include/asm-arm/arch-cl7500/acornfb.h linux/include/asm-arm/arch-cl7500/acornfb.h
--- v2.3.29/linux/include/asm-arm/arch-cl7500/acornfb.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-arm/arch-cl7500/acornfb.h	Sat Nov 27 15:27:49 1999
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #define acornfb_valid_pixrate(rate) (rate >= 39325 && rate <= 40119)
 
 static inline void
diff -u --recursive --new-file v2.3.29/linux/include/asm-arm/arch-cl7500/system.h linux/include/asm-arm/arch-cl7500/system.h
--- v2.3.29/linux/include/asm-arm/arch-cl7500/system.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-arm/arch-cl7500/system.h	Thu Dec  2 15:41:02 1999
@@ -8,20 +8,20 @@
 
 #include <asm/iomd.h>
 
-#define arch_reset(mode) {						\
-	outb (0, IOMD_ROMCR0);						\
-	cli();								\
-	__asm__ __volatile__("msr  spsr, r1;"				\
-			     "mcr  p15, 0, %0, c1, c0, 0;"		\
-			     "movs pc, #0"				\
-			 : 						\
-			 : "r" (cpu_reset()));				\
+#define arch_reset(mode) {			\
+	outb (0, IOMD_ROMCR0);			\
+	cli();					\
+	__asm__ __volatile__(			\
+		"mcr	p15, 0, %0, c1, c0, 0;"	\
+		"mov	pc, #0"			\
+	 : 					\
+	 : "r" (cpu_reset()));			\
 	}
 
 /*
  * We can wait for an interrupt...
  */
-#define proc_idle()						\
+#define arch_do_idle()				\
 	outb(0, IOMD_SUSMODE)
 
 #endif
diff -u --recursive --new-file v2.3.29/linux/include/asm-arm/arch-ebsa110/system.h linux/include/asm-arm/arch-ebsa110/system.h
--- v2.3.29/linux/include/asm-arm/arch-ebsa110/system.h	Fri Oct 22 13:21:53 1999
+++ linux/include/asm-arm/arch-ebsa110/system.h	Thu Dec  2 15:41:02 1999
@@ -6,7 +6,16 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#define arch_do_idle()		do { } while (0)
-#define arch_reset(mode)	do { } while (0)
+#define arch_do_idle()		cpu_do_idle()
+
+extern __inline__ void arch_reset(char mode)
+{
+	if (mode == 's') {
+		__asm__ volatile(
+		"mcr	p15, 0, %0, c1, c0, 0	@ MMU off
+		 mov	pc, #0x80000000		@ jump to flash"
+		: : "r" (cpu_reset()) : "cc");
+	}
+}
 
 #endif
diff -u --recursive --new-file v2.3.29/linux/include/asm-arm/arch-ebsa285/system.h linux/include/asm-arm/arch-ebsa285/system.h
--- v2.3.29/linux/include/asm-arm/arch-ebsa285/system.h	Fri Oct 22 13:21:53 1999
+++ linux/include/asm-arm/arch-ebsa285/system.h	Thu Dec  2 15:41:02 1999
@@ -14,9 +14,9 @@
 {
 	if (mode == 's') {
 		__asm__ volatile (
-		"mov	lr, #0x41000000		@ prepare to jump to ROM
-		 mcr	p15, 0, %0, c1, c0, 0	@ MMU off
-		 mov	pc, lr" : : "r" (cpu_reset()) : "cc");
+		"mcr	p15, 0, %0, c1, c0, 0	@ MMU off
+		 mov	pc, #0x41000000		@ jump to ROM" : :
+		"r" (cpu_reset()) : "cc");
 	} else {
 		if (machine_is_netwinder()) {
 			/* open up the SuperIO chip
diff -u --recursive --new-file v2.3.29/linux/include/asm-arm/arch-sa1100/system.h linux/include/asm-arm/arch-sa1100/system.h
--- v2.3.29/linux/include/asm-arm/arch-sa1100/system.h	Thu Nov 18 20:25:38 1999
+++ linux/include/asm-arm/arch-sa1100/system.h	Thu Dec  2 15:41:02 1999
@@ -16,10 +16,10 @@
 
 #else
 
-#define arch_reset( x ) {					\
+#define arch_reset(x) {						\
 	__asm__ volatile (					\
 "	mcr	p15, 0, %0, c1, c0	@ MMU off\n"		\
-"	mov	pc, #0\n" : : "r" (cpu_reset()));		\
+"	mov	pc, #0\n" : : "r" (cpu_reset()) : "cc");	\
 	}
 
 #endif
diff -u --recursive --new-file v2.3.29/linux/include/asm-arm/io.h linux/include/asm-arm/io.h
--- v2.3.29/linux/include/asm-arm/io.h	Mon Nov  1 13:56:27 1999
+++ linux/include/asm-arm/io.h	Sat Nov 27 15:27:49 1999
@@ -211,6 +211,8 @@
 #define memset_io(addr,c,len)		_memset_io((unsigned long)(addr),(c),(len))
 #endif
 
+#define IO_SPACE_LIMIT 0xffff
+
 /*
  * This isn't especially architecture dependent so it seems like it
  * might as well go here as anywhere.
diff -u --recursive --new-file v2.3.29/linux/include/asm-arm/pgtable.h linux/include/asm-arm/pgtable.h
--- v2.3.29/linux/include/asm-arm/pgtable.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-arm/pgtable.h	Mon Dec  6 10:14:13 1999
@@ -4,8 +4,6 @@
 #ifndef _ASMARM_PGTABLE_H
 #define _ASMARM_PGTABLE_H
 
-#include <linux/config.h>
-
 #include <asm/arch/memory.h>
 #include <asm/proc-fns.h>
 #include <asm/system.h>
@@ -87,7 +85,6 @@
  * Permanent address of a page.
  */
 #define page_address(page)	({ if (!(page)->virtual) BUG(); (page)->virtual; })
-#define __page_address(page)	(PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
 #define pages_to_mb(x)		((x) >> (20 - PAGE_SHIFT))
 #define pte_page(x)		(mem_map + pte_pagenr(x))
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-arm/processor.h linux/include/asm-arm/processor.h
--- v2.3.29/linux/include/asm-arm/processor.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-arm/processor.h	Sat Nov 27 15:27:49 1999
@@ -7,7 +7,6 @@
 #ifndef __ASM_ARM_PROCESSOR_H
 #define __ASM_ARM_PROCESSOR_H
 
-#include <linux/config.h>
 /*
  * Default implementation of macro that returns current
  * instruction pointer ("program counter").
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/atomic.h linux/include/asm-i386/atomic.h
--- v2.3.29/linux/include/asm-i386/atomic.h	Thu Aug 26 13:05:40 1999
+++ linux/include/asm-i386/atomic.h	Mon Dec  6 17:22:06 1999
@@ -46,6 +46,17 @@
 		:"ir" (i), "m" (__atomic_fool_gcc(v)));
 }
 
+static __inline__ int atomic_sub_and_test(int i, volatile atomic_t *v)
+{
+	unsigned char c;
+
+	__asm__ __volatile__(
+		LOCK "subl %2,%0; sete %1"
+		:"=m" (__atomic_fool_gcc(v)), "=qm" (c)
+		:"ir" (i), "m" (__atomic_fool_gcc(v)));
+	return c;
+}
+
 static __inline__ void atomic_inc(volatile atomic_t *v)
 {
 	__asm__ __volatile__(
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/cache.h linux/include/asm-i386/cache.h
--- v2.3.29/linux/include/asm-i386/cache.h	Wed Aug  4 15:48:00 1999
+++ linux/include/asm-i386/cache.h	Mon Dec  6 17:15:53 1999
@@ -11,16 +11,4 @@
 #define        L1_CACHE_BYTES  16
 #endif
 
-#define        L1_CACHE_ALIGN(x)       (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
-
-#define        SMP_CACHE_BYTES L1_CACHE_BYTES
-
-#ifdef MODULE
-#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES)))
-#else
-#define __cacheline_aligned					\
-  __attribute__((__aligned__(L1_CACHE_BYTES),			\
-		 __section__(".data.cacheline_aligned")))
-#endif
-
 #endif
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/hardirq.h linux/include/asm-i386/hardirq.h
--- v2.3.29/linux/include/asm-i386/hardirq.h	Thu Aug 26 13:05:40 1999
+++ linux/include/asm-i386/hardirq.h	Mon Dec  6 17:22:07 1999
@@ -17,8 +17,8 @@
 #define hardirq_trylock(cpu)	(local_irq_count[cpu] == 0)
 #define hardirq_endlock(cpu)	do { } while (0)
 
-#define hardirq_enter(cpu)	(local_irq_count[cpu]++)
-#define hardirq_exit(cpu)	(local_irq_count[cpu]--)
+#define irq_enter(cpu, irq)	(local_irq_count[cpu]++)
+#define irq_exit(cpu, irq)	(local_irq_count[cpu]--)
 
 #define synchronize_irq()	barrier()
 
@@ -39,13 +39,17 @@
 	}
 }
 
-static inline void hardirq_enter(int cpu)
+static inline void irq_enter(int cpu, int irq)
 {
 	++local_irq_count[cpu];
 	atomic_inc(&global_irq_count);
+
+	while (test_bit(0,&global_irq_lock)) {
+		/* nothing */;
+	}
 }
 
-static inline void hardirq_exit(int cpu)
+static inline void irq_exit(int cpu, int irq)
 {
 	atomic_dec(&global_irq_count);
 	--local_irq_count[cpu];
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/highmem.h linux/include/asm-i386/highmem.h
--- v2.3.29/linux/include/asm-i386/highmem.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-i386/highmem.h	Mon Dec  6 17:22:09 1999
@@ -20,6 +20,7 @@
 
 #ifdef __KERNEL__
 
+#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <asm/kmap_types.h>
@@ -42,7 +43,7 @@
  * easily, subsequent pte tables have to be allocated in one physical
  * chunk of RAM.
  */
-#define PKMAP_BASE (0xff000000UL)
+#define PKMAP_BASE (0xfe000000UL)
 #ifdef CONFIG_X86_PAE
 #define LAST_PKMAP 512
 #else
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/hw_irq.h linux/include/asm-i386/hw_irq.h
--- v2.3.29/linux/include/asm-i386/hw_irq.h	Sat Oct  9 11:47:50 1999
+++ linux/include/asm-i386/hw_irq.h	Mon Dec  6 17:24:05 1999
@@ -79,10 +79,10 @@
 extern void FASTCALL(send_IPI_self(int vector));
 extern void init_VISWS_APIC_irqs(void);
 extern void setup_IO_APIC(void);
+extern void disable_IO_APIC(void);
+extern void print_IO_APIC(void);
 extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
 extern void send_IPI(int dest, int vector);
-extern void init_pic_mode(void);
-extern void print_IO_APIC(void);
 
 extern unsigned long io_apic_irqs;
 extern volatile unsigned long irq_err_count;
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/io.h linux/include/asm-i386/io.h
--- v2.3.29/linux/include/asm-i386/io.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-i386/io.h	Mon Dec  6 17:22:35 1999
@@ -101,6 +101,8 @@
 __OUTS(w)
 __OUTS(l)
 
+#define IO_SPACE_LIMIT 0xffff
+
 #ifdef __KERNEL__
 
 #include <linux/vmalloc.h>
@@ -242,9 +244,6 @@
 out:
 	return retval;
 }
-
-
-
 
 /* Nothing to do */
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/mmu_context.h linux/include/asm-i386/mmu_context.h
--- v2.3.29/linux/include/asm-i386/mmu_context.h	Wed Aug 18 16:43:30 1999
+++ linux/include/asm-i386/mmu_context.h	Mon Dec  6 17:23:37 1999
@@ -3,6 +3,7 @@
 
 #include <asm/desc.h>
 #include <asm/atomic.h>
+#include <asm/pgalloc.h>
 
 /*
  * possibly do the LDT unload here?
@@ -10,9 +11,12 @@
 #define destroy_context(mm)		do { } while(0)
 #define init_new_context(tsk,mm)	do { } while (0)
 
+#ifdef __SMP__
+extern unsigned int cpu_tlbbad[NR_CPUS];
+#endif
+
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
 {
-
 	if (prev != next) {
 		/*
 		 * Re-load LDT if necessary
@@ -24,6 +28,13 @@
 		asm volatile("movl %0,%%cr3": :"r" (__pa(next->pgd)));
 		clear_bit(cpu, &prev->cpu_vm_mask);
 	}
+#ifdef __SMP__
+	else {
+		if(cpu_tlbbad[cpu])
+			local_flush_tlb();
+	}
+	cpu_tlbbad[cpu] = 0;
+#endif
 	set_bit(cpu, &next->cpu_vm_mask);
 }
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/page.h linux/include/asm-i386/page.h
--- v2.3.29/linux/include/asm-i386/page.h	Mon Nov  1 13:56:27 1999
+++ linux/include/asm-i386/page.h	Fri Dec  3 11:12:23 1999
@@ -50,6 +50,9 @@
 #define pgd_val(x)	((x).pgd)
 #define pgprot_val(x)	((x).pgprot)
 
+#define __pte(x) ((pte_t) { (x) } )
+#define __pmd(x) ((pmd_t) { (x) } )
+#define __pgd(x) ((pgd_t) { (x) } )
 #define __pgprot(x)	((pgprot_t) { (x) } )
 
 #endif /* !__ASSEMBLY__ */
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/pgalloc-3level.h linux/include/asm-i386/pgalloc-3level.h
--- v2.3.29/linux/include/asm-i386/pgalloc-3level.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-i386/pgalloc-3level.h	Fri Dec  3 11:12:23 1999
@@ -54,7 +54,7 @@
 			page = get_pmd_slow();
 		if (page) {
 			if (pgd_none(*pgd)) {
-				pgd_val(*pgd) = 1 + __pa(page);
+				set_pgd(pgd, __pgd(1 + __pa(page)));
 				__flush_tlb();
 				return page + address;
 			} else
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/pgalloc.h linux/include/asm-i386/pgalloc.h
--- v2.3.29/linux/include/asm-i386/pgalloc.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-i386/pgalloc.h	Mon Dec  6 17:22:09 1999
@@ -107,7 +107,7 @@
 		
 		if (!page)
 			return get_pte_kernel_slow(pmd, address);
-		pmd_val(*pmd) = _KERNPG_TABLE + __pa(page);
+		set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(page)));
 		return page + address;
 	}
 	if (pmd_bad(*pmd)) {
@@ -132,7 +132,7 @@
 	
 	if (!page)
 		return get_pte_slow(pmd, address);
-	pmd_val(*pmd) = _PAGE_TABLE + __pa(page);
+	set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(page)));
 	return (pte_t *)page + address;
 }
 fix:
@@ -240,6 +240,23 @@
 static inline void flush_tlb_range(struct mm_struct * mm, unsigned long start, unsigned long end)
 {
 	flush_tlb_mm(mm);
+}
+
+extern volatile unsigned long smp_invalidate_needed;
+extern unsigned int cpu_tlbbad[NR_CPUS];
+
+static inline void do_flush_tlb_local(void)
+{
+	unsigned long cpu = smp_processor_id();
+	struct mm_struct *mm = current->mm;
+
+	clear_bit(cpu, &smp_invalidate_needed);
+	if (mm) {
+		set_bit(cpu, &mm->cpu_vm_mask);
+		local_flush_tlb();
+	} else {
+		cpu_tlbbad[cpu] = 1;
+	}
 }
 
 #endif
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/pgtable-2level.h linux/include/asm-i386/pgtable-2level.h
--- v2.3.29/linux/include/asm-i386/pgtable-2level.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-i386/pgtable-2level.h	Fri Dec  3 11:12:23 1999
@@ -34,6 +34,19 @@
 extern inline int pgd_present(pgd_t pgd)	{ return 1; }
 #define pgd_clear(xp)				do { } while (0)
 
+/*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
+/*
+ * (pmds are folded into pgds so this doesnt get actually called,
+ * but the define is needed for a generic inline function.)
+ */
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
+#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval)
+
 #define pgd_page(pgd) \
 ((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/pgtable-3level.h linux/include/asm-i386/pgtable-3level.h
--- v2.3.29/linux/include/asm-i386/pgtable-3level.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-i386/pgtable-3level.h	Mon Dec  6 16:19:13 1999
@@ -35,11 +35,23 @@
 
 /*
  * Subtle, in PAE mode we cannot have zeroes in the top level
- * page directory, the CPU enforces this.
+ * page directory, the CPU enforces this. (ie. the PGD entry
+ * always has to have the present bit set.) The CPU caches
+ * the 4 pgd entries internally, so there is no extra memory
+ * load on TLB miss, despite one more level of indirection.
  */
-#define pgd_none(x)	(pgd_val(x) == 1ULL)
+#define EMPTY_PGD (__pa(empty_zero_page) + 1)
+#define pgd_none(x)	(pgd_val(x) == EMPTY_PGD)
 extern inline int pgd_bad(pgd_t pgd)		{ return 0; }
 extern inline int pgd_present(pgd_t pgd)	{ return !pgd_none(pgd); }
+
+#define set_pte(pteptr,pteval) \
+		set_64bit((unsigned long long *)(pteptr),pte_val(pteval))
+#define set_pmd(pmdptr,pmdval) \
+		set_64bit((unsigned long long *)(pmdptr),pmd_val(pmdval))
+#define set_pgd(pgdptr,pgdval) \
+		set_64bit((unsigned long long *)(pgdptr),pgd_val(pgdval))
+
 /*
  * Pentium-II errata A13: in PAE mode we explicitly have to flush
  * the TLB via cr3 if the top-level pgd is changed... This was one tough
@@ -48,7 +60,7 @@
  */
 extern inline void __pgd_clear (pgd_t * pgd)
 {
-	pgd_val(*pgd) = 1; // no zero allowed!
+	set_pgd(pgd, __pgd(EMPTY_PGD));
 }
 
 extern inline void pgd_clear (pgd_t * pgd)
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/pgtable.h linux/include/asm-i386/pgtable.h
--- v2.3.29/linux/include/asm-i386/pgtable.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-i386/pgtable.h	Mon Dec  6 17:22:07 1999
@@ -37,6 +37,13 @@
 __asm__ __volatile__("invlpg %0": :"m" (*(char *) addr))
 #endif
 
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern unsigned long empty_zero_page[1024];
+#define ZERO_PAGE(vaddr) (mem_map + MAP_NR(empty_zero_page))
+
 #endif /* !__ASSEMBLY__ */
 
 /*
@@ -52,13 +59,6 @@
 #endif
 #endif
 
-/*
- * Certain architectures need to do special things when PTEs
- * within a page table are directly modified.  Thus, the following
- * hook is made available.
- */
-#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
-
 #define __beep() asm("movb $0x3,%al; outb %al,$0x61")
 
 #define PMD_SIZE	(1UL << PMD_SHIFT)
@@ -152,13 +152,6 @@
 extern unsigned long pg0[1024];
 
 /*
- * ZERO_PAGE is a global shared page that is always zero: used
- * for zero-mapped memory areas etc..
- */
-extern unsigned long empty_zero_page[1024];
-#define ZERO_PAGE(vaddr) (mem_map + MAP_NR(empty_zero_page))
-
-/*
  * Handling allocation failures during page table setup.
  */
 extern void __handle_bad_pmd(pmd_t * pmd);
@@ -166,20 +159,19 @@
 
 #define pte_none(x)	(!pte_val(x))
 #define pte_present(x)	(pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE))
-#define pte_clear(xp)	do { pte_val(*(xp)) = 0; } while (0)
+#define pte_clear(xp)	do { set_pte(xp, __pte(0)); } while (0)
 #define pte_pagenr(x)	((unsigned long)((pte_val(x) >> PAGE_SHIFT)))
 
 #define pmd_none(x)	(!pmd_val(x))
-#define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
 #define pmd_present(x)	(pmd_val(x) & _PAGE_PRESENT)
-#define pmd_clear(xp)	do { pmd_val(*(xp)) = 0; } while (0)
+#define pmd_clear(xp)	do { set_pmd(xp, __pmd(0)); } while (0)
+#define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
 
 /*
  * Permanent address of a page. Obviously must never be
  * called on a highmem page.
  */
 #define page_address(page) ({ if (!(page)->virtual) BUG(); (page)->virtual; })
-#define __page_address(page) ({ if (PageHighMem(page)) BUG(); PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT); })
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 #define pte_page(x) (mem_map+pte_pagenr(x))
 
@@ -193,16 +185,16 @@
 extern inline int pte_young(pte_t pte)		{ return pte_val(pte) & _PAGE_ACCESSED; }
 extern inline int pte_write(pte_t pte)		{ return pte_val(pte) & _PAGE_RW; }
 
-extern inline pte_t pte_rdprotect(pte_t pte)	{ pte_val(pte) &= ~_PAGE_USER; return pte; }
-extern inline pte_t pte_exprotect(pte_t pte)	{ pte_val(pte) &= ~_PAGE_USER; return pte; }
-extern inline pte_t pte_mkclean(pte_t pte)	{ pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkold(pte_t pte)	{ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_wrprotect(pte_t pte)	{ pte_val(pte) &= ~_PAGE_RW; return pte; }
-extern inline pte_t pte_mkread(pte_t pte)	{ pte_val(pte) |= _PAGE_USER; return pte; }
-extern inline pte_t pte_mkexec(pte_t pte)	{ pte_val(pte) |= _PAGE_USER; return pte; }
-extern inline pte_t pte_mkdirty(pte_t pte)	{ pte_val(pte) |= _PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkyoung(pte_t pte)	{ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_mkwrite(pte_t pte)	{ pte_val(pte) |= _PAGE_RW; return pte; }
+extern inline pte_t pte_rdprotect(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
+extern inline pte_t pte_exprotect(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
+extern inline pte_t pte_mkclean(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
+extern inline pte_t pte_mkold(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
+extern inline pte_t pte_wrprotect(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
+extern inline pte_t pte_mkread(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
+extern inline pte_t pte_mkexec(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
+extern inline pte_t pte_mkdirty(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
+extern inline pte_t pte_mkyoung(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
+extern inline pte_t pte_mkwrite(pte_t pte)	{ set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
 
 /*
  * Conversion functions: convert a page and protection to a page entry,
@@ -213,17 +205,17 @@
 ({									\
 	pte_t __pte;							\
 									\
-	pte_val(__pte) = ((page)-mem_map)*(unsigned long long)PAGE_SIZE + \
-				pgprot_val(pgprot);			\
+	set_pte(&__pte, __pte(((page)-mem_map) * 			\
+		(unsigned long long)PAGE_SIZE + pgprot_val(pgprot)));	\
 	__pte;								\
 })
 
 /* This takes a physical page address that is used by the remapping functions */
 #define mk_pte_phys(physpage, pgprot) \
-({ pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); __pte; })
+({ pte_t __pte; set_pte(&__pte, __pte(physpage + pgprot_val(pgprot))); __pte; })
 
 extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
+{ set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))); return pte; }
 
 #define page_pte(page) page_pte_prot(page, __pgprot(0))
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/rwlock.h linux/include/asm-i386/rwlock.h
--- v2.3.29/linux/include/asm-i386/rwlock.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-i386/rwlock.h	Sat Nov 27 16:04:04 1999
@@ -0,0 +1,86 @@
+/* include/asm-i386/rwlock.h
+ *
+ *	Helpers used by both rw spinlocks and rw semaphores.
+ *
+ *	Based in part on code from semaphore.h and
+ *	spinlock.h Copyright 1996 Linus Torvalds.
+ *
+ *	Copyright 1999 Red Hat, Inc.
+ *
+ *	Written by Benjamin LaHaise.
+ *
+ *	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.
+ */
+#ifndef _ASM_I386_RWLOCK_H
+#define _ASM_I386_RWLOCK_H
+
+typedef struct { unsigned long a[100]; } __dummy_lock_t;
+#define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
+
+#define RW_LOCK_BIAS		 0x01000000
+#define RW_LOCK_BIAS_STR	"0x01000000"
+
+#define __build_read_lock_ptr(rw, helper)   \
+	asm volatile(LOCK "subl $1,(%0)\n\t" \
+		     "js 2f\n" \
+		     "1:\n" \
+		     ".section .text.lock,\"ax\"\n" \
+		     "2:\tcall " helper "\n\t" \
+		     "jmp 1b\n" \
+		     ".previous" \
+		     ::"a" (rw) : "memory")
+
+#define __build_read_lock_const(rw, helper)   \
+	asm volatile(LOCK "subl $1,%0\n\t" \
+		     "js 2f\n" \
+		     "1:\n" \
+		     ".section .text.lock,\"ax\"\n" \
+		     "2:\tpushl %%eax\n\t" \
+		     "leal %0,%%eax\n\t" \
+		     "call " helper "\n\t" \
+		     "popl %%eax\n\t" \
+		     "jmp 1b\n" \
+		     ".previous" \
+		     :"=m" (__dummy_lock(rw)))
+
+#define __build_read_lock(rw, helper)	do { \
+						if (__builtin_constant_p(rw)) \
+							__build_read_lock_const(rw, helper); \
+						else \
+							__build_read_lock_ptr(rw, helper); \
+					} while (0)
+
+#define __build_write_lock_ptr(rw, helper) \
+	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
+		     "jnz 2f\n" \
+		     "1:\n" \
+		     ".section .text.lock,\"ax\"\n" \
+		     "2:\tcall " helper "\n\t" \
+		     "jmp 1b\n" \
+		     ".previous" \
+		     ::"a" (rw) : "memory")
+
+#define __build_write_lock_const(rw, helper) \
+	asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
+		     "jnz 2f\n" \
+		     "1:\n" \
+		     ".section .text.lock,\"ax\"\n" \
+		     "2:\tpushl %%eax\n\t" \
+		     "leal %0,%%eax\n\t" \
+		     "call " helper "\n\t" \
+		     "popl %%eax\n\t" \
+		     "jmp 1b\n" \
+		     ".previous" \
+		     :"=m" (__dummy_lock(rw)))
+
+#define __build_write_lock(rw, helper)	do { \
+						if (__builtin_constant_p(rw)) \
+							__build_write_lock_const(rw, helper); \
+						else \
+							__build_write_lock_ptr(rw, helper); \
+					} while (0)
+
+#endif
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/semaphore.h linux/include/asm-i386/semaphore.h
--- v2.3.29/linux/include/asm-i386/semaphore.h	Wed Oct 27 16:34:12 1999
+++ linux/include/asm-i386/semaphore.h	Mon Dec  6 17:22:09 1999
@@ -30,7 +30,7 @@
 
 #include <asm/system.h>
 #include <asm/atomic.h>
-#include <linux/spinlock.h>
+#include <asm/rwlock.h>
 #include <linux/wait.h>
 
 struct semaphore {
@@ -111,10 +111,7 @@
 
 	__asm__ __volatile__(
 		"# atomic down operation\n\t"
-#ifdef __SMP__
-		"lock ; "
-#endif
-		"decl (%0)\n\t"     /* --sem->count */
+		LOCK "decl (%0)\n\t"     /* --sem->count */
 		"js 2f\n"
 		"1:\n"
 		".section .text.lock,\"ax\"\n"
@@ -136,10 +133,7 @@
 
 	__asm__ __volatile__(
 		"# atomic interruptible down operation\n\t"
-#ifdef __SMP__
-		"lock ; "
-#endif
-		"decl (%1)\n\t"     /* --sem->count */
+		LOCK "decl (%1)\n\t"     /* --sem->count */
 		"js 2f\n\t"
 		"xorl %0,%0\n"
 		"1:\n"
@@ -163,10 +157,7 @@
 
 	__asm__ __volatile__(
 		"# atomic interruptible down operation\n\t"
-#ifdef __SMP__
-		"lock ; "
-#endif
-		"decl (%1)\n\t"     /* --sem->count */
+		LOCK "decl (%1)\n\t"     /* --sem->count */
 		"js 2f\n\t"
 		"xorl %0,%0\n"
 		"1:\n"
@@ -193,10 +184,7 @@
 #endif
 	__asm__ __volatile__(
 		"# atomic up operation\n\t"
-#ifdef __SMP__
-		"lock ; "
-#endif
-		"incl (%0)\n\t"     /* ++sem->count */
+		LOCK "incl (%0)\n\t"     /* ++sem->count */
 		"jle 2f\n"
 		"1:\n"
 		".section .text.lock,\"ax\"\n"
@@ -206,6 +194,175 @@
 		:/* no outputs */
 		:"c" (sem)
 		:"memory");
+}
+
+/* rw mutexes (should that be mutices? =) -- throw rw
+ * spinlocks and semaphores together, and this is what we
+ * end up with...
+ *
+ * The lock is initialized to BIAS.  This way, a writer
+ * subtracts BIAS ands gets 0 for the case of an uncontended
+ * lock.  Readers decrement by 1 and see a positive value
+ * when uncontended, negative if there are writers waiting
+ * (in which case it goes to sleep).
+ *
+ * The value 0x01000000 supports up to 128 processors and
+ * lots of processes.  BIAS must be chosen such that subl'ing
+ * BIAS once per CPU will result in the long remaining
+ * negative.
+ *
+ * In terms of fairness, this should result in the lock
+ * flopping back and forth between readers and writers
+ * under heavy use.
+ *
+ *		-ben
+ */
+struct rw_semaphore {
+	atomic_t		count;
+	volatile unsigned char	write_bias_granted;
+	volatile unsigned char	read_bias_granted;
+	volatile unsigned char	pad1;
+	volatile unsigned char	pad2;
+	wait_queue_head_t	wait;
+	wait_queue_head_t	write_bias_wait;
+#if WAITQUEUE_DEBUG
+	long			__magic;
+	atomic_t		readers;
+	atomic_t		writers;
+#endif
+};
+
+#if WAITQUEUE_DEBUG
+#define __RWSEM_DEBUG_INIT	, ATOMIC_INIT(0), ATOMIC_INIT(0)
+#else
+#define __RWSEM_DEBUG_INIT	/* */
+#endif
+
+#define __RWSEM_INITIALIZER(name) \
+{ ATOMIC_INIT(RW_LOCK_BIAS), 0, 0, 0, 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait), \
+	__WAIT_QUEUE_HEAD_INITIALIZER((name).write_bias_wait) \
+	__SEM_DEBUG_INIT(name) __RWSEM_DEBUG_INIT }
+
+extern inline void init_rwsem(struct rw_semaphore *sem)
+{
+	atomic_set(&sem->count, RW_LOCK_BIAS);
+	sem->read_bias_granted = 0;
+	sem->write_bias_granted = 0;
+	init_waitqueue_head(&sem->wait);
+	init_waitqueue_head(&sem->write_bias_wait);
+#if WAITQUEUE_DEBUG
+	sem->__magic = (long)&sem->__magic;
+	atomic_set(&sem->readers, 0);
+	atomic_set(&sem->writers, 0);
+#endif
+}
+
+/* we use FASTCALL convention for the helpers */
+extern struct rw_semaphore *FASTCALL(down_read_failed(struct rw_semaphore *sem));
+extern struct rw_semaphore *FASTCALL(down_write_failed(struct rw_semaphore *sem));
+extern struct rw_semaphore *FASTCALL(rwsem_wake(struct rw_semaphore *sem));
+
+extern inline void down_read(struct rw_semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+	if (sem->__magic != (long)&sem->__magic)
+		BUG();
+#endif
+	__build_read_lock(sem, "__down_read_failed");
+#if WAITQUEUE_DEBUG
+	if (sem->write_bias_granted)
+		BUG();
+	if (atomic_read(&sem->writers))
+		BUG();
+	atomic_inc(&sem->readers);
+#endif
+}
+
+extern inline void down_write(struct rw_semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+	if (sem->__magic != (long)&sem->__magic)
+		BUG();
+#endif
+	__build_write_lock(sem, "__down_write_failed");
+#if WAITQUEUE_DEBUG
+	if (atomic_read(&sem->writers))
+		BUG();
+	if (atomic_read(&sem->readers))
+		BUG();
+	if (sem->read_bias_granted)
+		BUG();
+	if (sem->write_bias_granted)
+		BUG();
+	atomic_inc(&sem->writers);
+#endif
+}
+
+/* When a reader does a release, the only significant
+ * case is when there was a writer waiting, and we've
+ * bumped the count to 0: we must wake the writer up.
+ */
+extern inline void __up_read(struct rw_semaphore *sem)
+{
+	__asm__ __volatile__(
+		"# up_read\n\t"
+		LOCK "incl (%%eax)\n\t"
+		"jz 2f\n"			/* only do the wake if result == 0 (ie, a writer) */
+		"1:\n\t"
+		".section .text.lock,\"ax\"\n"
+		"2:\tcall __rwsem_wake\n\t"
+		"jmp 1b\n"
+		".previous"
+		::"a" (sem)
+		:"memory"
+		);
+}
+
+/* releasing the writer is easy -- just release it and
+ * wake up any sleepers.
+ */
+extern inline void __up_write(struct rw_semaphore *sem)
+{
+	__asm__ __volatile__(
+		"# up_write\n\t"
+		LOCK "addl $" RW_LOCK_BIAS_STR ",(%%eax)\n"
+		"jc 2f\n"			/* only do the wake if the result was -'ve to 0/+'ve */
+		"1:\n\t"
+		".section .text.lock,\"ax\"\n"
+		"2:\tcall __rwsem_wake\n\t"
+		"jmp 1b\n"
+		".previous"
+		::"a" (sem)
+		:"memory"
+		);
+}
+
+extern inline void up_read(struct rw_semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+	if (sem->write_bias_granted)
+		BUG();
+	if (atomic_read(&sem->writers))
+		BUG();
+	atomic_dec(&sem->readers);
+#endif
+	__up_read(sem);
+}
+
+extern inline void up_write(struct rw_semaphore *sem)
+{
+#if WAITQUEUE_DEBUG
+	if (sem->read_bias_granted)
+		BUG();
+	if (sem->write_bias_granted)
+		BUG();
+	if (atomic_read(&sem->readers))
+		BUG();
+	if (atomic_read(&sem->writers) != 1)
+		BUG();
+	atomic_dec(&sem->writers);
+#endif
+	__up_write(sem);
 }
 
 #endif
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/smp.h linux/include/asm-i386/smp.h
--- v2.3.29/linux/include/asm-i386/smp.h	Fri Oct 22 13:21:54 1999
+++ linux/include/asm-i386/smp.h	Mon Dec  6 17:22:08 1999
@@ -174,6 +174,7 @@
 extern int pic_mode;
 extern void smp_flush_tlb(void);
 extern int get_maxlvt(void);
+extern void disable_local_APIC (void);
 extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
 extern void smp_send_reschedule(int cpu);
 extern void smp_invalidate_rcv(void);		/* Process an NMI */
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/smplock.h linux/include/asm-i386/smplock.h
--- v2.3.29/linux/include/asm-i386/smplock.h	Fri Sep 10 23:57:36 1999
+++ linux/include/asm-i386/smplock.h	Mon Dec  6 17:22:10 1999
@@ -38,6 +38,10 @@
  */
 extern __inline__ void lock_kernel(void)
 {
+#if 1
+	if (!++current->lock_depth)
+		spin_lock(&kernel_flag);
+#else
 	__asm__ __volatile__(
 		"incl %1\n\t"
 		"jne 9f"
@@ -45,12 +49,17 @@
 		"\n9:"
 		:"=m" (__dummy_lock(&kernel_flag)),
 		 "=m" (current->lock_depth));
+#endif
 }
 
 extern __inline__ void unlock_kernel(void)
 {
 	if (current->lock_depth < 0)
 		BUG();
+#if 1
+	if (--current->lock_depth < 0)
+		spin_unlock(&kernel_flag);
+#else
 	__asm__ __volatile__(
 		"decl %1\n\t"
 		"jns 9f\n\t"
@@ -58,4 +67,5 @@
 		"\n9:"
 		:"=m" (__dummy_lock(&kernel_flag)),
 		 "=m" (current->lock_depth));
+#endif
 }
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/spinlock.h linux/include/asm-i386/spinlock.h
--- v2.3.29/linux/include/asm-i386/spinlock.h	Mon Oct  4 15:49:30 1999
+++ linux/include/asm-i386/spinlock.h	Mon Dec  6 17:22:07 1999
@@ -1,17 +1,41 @@
 #ifndef __ASM_SPINLOCK_H
 #define __ASM_SPINLOCK_H
 
+#include <asm/atomic.h>
+#include <asm/rwlock.h>
+#include <asm/page.h>
+
+extern int printk(const char * fmt, ...)
+	__attribute__ ((format (printf, 1, 2)));
+
+/* It seems that people are forgetting to
+ * initialize their spinlocks properly, tsk tsk.
+ * Remember to turn this off in 2.4. -ben
+ */
+#define SPINLOCK_DEBUG	1
+
 /*
  * Your basic SMP spinlocks, allowing only a single CPU anywhere
  */
 
 typedef struct {
 	volatile unsigned int lock;
+#if SPINLOCK_DEBUG
+	unsigned magic;
+#endif
 } spinlock_t;
 
-#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
+#define SPINLOCK_MAGIC	0xdead4ead
+
+#if SPINLOCK_DEBUG
+#define SPINLOCK_MAGIC_INIT	, SPINLOCK_MAGIC
+#else
+#define SPINLOCK_MAGIC_INIT	/* */
+#endif
 
-#define spin_lock_init(x)	do { (x)->lock = 0; } while(0)
+#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 SPINLOCK_MAGIC_INIT }
+
+#define spin_lock_init(x)	do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
 /*
  * Simple spin lock operations.  There are two variants, one clears IRQ's
  * on the local processor, one does not.
@@ -21,9 +45,6 @@
 
 #define spin_unlock_wait(x)	do { barrier(); } while(((volatile spinlock_t *)(x))->lock)
 
-typedef struct { unsigned long a[100]; } __dummy_lock_t;
-#define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
-
 #define spin_lock_string \
 	"\n1:\t" \
 	"lock ; btsl $0,%0\n\t" \
@@ -35,18 +56,43 @@
 	"jmp 1b\n" \
 	".previous"
 
+/*
+ * Sadly, some early PPro chips require the locked access,
+ * otherwise we could just always simply do
+ *
+ * 	#define spin_unlock_string \
+ *		"movb $0,%0"
+ *
+ * Which is noticeably faster.
+ */
 #define spin_unlock_string \
 	"lock ; btrl $0,%0"
 
-#define spin_lock(lock) \
-__asm__ __volatile__( \
-	spin_lock_string \
-	:"=m" (__dummy_lock(lock)))
-
-#define spin_unlock(lock) \
-__asm__ __volatile__( \
-	spin_unlock_string \
-	:"=m" (__dummy_lock(lock)))
+extern inline void spin_lock(spinlock_t *lock)
+{
+#if SPINLOCK_DEBUG
+	__label__ here;
+here:
+	if (lock->magic != SPINLOCK_MAGIC) {
+printk("eip: %p\n", &&here);
+		BUG();
+	}
+#endif
+	__asm__ __volatile__(
+		spin_lock_string
+		:"=m" (__dummy_lock(lock)));
+}
+
+extern inline void spin_unlock(spinlock_t *lock)
+{
+#if SPINLOCK_DEBUG
+	if (lock->magic != SPINLOCK_MAGIC)
+		BUG();
+#endif
+	__asm__ __volatile__(
+		spin_unlock_string
+		:"=m" (__dummy_lock(lock)));
+}
 
 #define spin_trylock(lock) (!test_and_set_bit(0,(lock)))
 
@@ -62,47 +108,60 @@
  */
 typedef struct {
 	volatile unsigned int lock;
+#if SPINLOCK_DEBUG
+	unsigned magic;
+#endif
 } rwlock_t;
 
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
+#define RWLOCK_MAGIC	0xdeaf1eed
+
+#if SPINLOCK_DEBUG
+#define RWLOCK_MAGIC_INIT	, RWLOCK_MAGIC
+#else
+#define RWLOCK_MAGIC_INIT	/* */
+#endif
+
+#define RW_LOCK_UNLOCKED (rwlock_t) { RW_LOCK_BIAS RWLOCK_MAGIC_INIT }
 
 /*
  * On x86, we implement read-write locks as a 32-bit counter
- * with the high bit (sign) being the "write" bit.
+ * with the high bit (sign) being the "contended" bit.
  *
  * The inline assembly is non-obvious. Think about it.
+ *
+ * Changed to use the same technique as rw semaphores.  See
+ * semaphore.h for details.  -ben
  */
-#define read_lock(rw)	\
-	asm volatile("\n1:\t" \
-		     "lock ; incl %0\n\t" \
-		     "js 2f\n" \
-		     ".section .text.lock,\"ax\"\n" \
-		     "2:\tlock ; decl %0\n" \
-		     "3:\tcmpl $0,%0\n\t" \
-		     "js 3b\n\t" \
-		     "jmp 1b\n" \
-		     ".previous" \
-		     :"=m" (__dummy_lock(&(rw)->lock)))
-
-#define read_unlock(rw) \
-	asm volatile("lock ; decl %0" \
-		:"=m" (__dummy_lock(&(rw)->lock)))
-
-#define write_lock(rw) \
-	asm volatile("\n1:\t" \
-		     "lock ; btsl $31,%0\n\t" \
-		     "jc 4f\n" \
-		     "2:\ttestl $0x7fffffff,%0\n\t" \
-		     "jne 3f\n" \
-		     ".section .text.lock,\"ax\"\n" \
-		     "3:\tlock ; btrl $31,%0\n" \
-		     "4:\tcmp $0,%0\n\t" \
-		     "jne 4b\n\t" \
-		     "jmp 1b\n" \
-		     ".previous" \
-		     :"=m" (__dummy_lock(&(rw)->lock)))
+/* the spinlock helpers are in arch/i386/kernel/semaphore.S */
 
-#define write_unlock(rw) \
-	asm volatile("lock ; btrl $31,%0":"=m" (__dummy_lock(&(rw)->lock)))
+extern inline void read_lock(rwlock_t *rw)
+{
+#if SPINLOCK_DEBUG
+	if (rw->magic != RWLOCK_MAGIC)
+		BUG();
+#endif
+	__build_read_lock(rw, "__read_lock_failed");
+}
+
+extern inline void write_lock(rwlock_t *rw)
+{
+#if SPINLOCK_DEBUG
+	if (rw->magic != RWLOCK_MAGIC)
+		BUG();
+#endif
+	__build_write_lock(rw, "__write_lock_failed");
+}
+
+#define read_unlock(rw)		asm volatile("lock ; incl %0" :"=m" (__dummy_lock(&(rw)->lock)))
+#define write_unlock(rw)	asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" (__dummy_lock(&(rw)->lock)))
+
+extern inline int write_trylock(rwlock_t *lock)
+{
+	atomic_t *count = (atomic_t *)lock;
+	if (atomic_sub_and_test(RW_LOCK_BIAS, count))
+		return 1;
+	atomic_add(RW_LOCK_BIAS, count);
+	return 0;
+}
 
 #endif /* __ASM_SPINLOCK_H */
diff -u --recursive --new-file v2.3.29/linux/include/asm-i386/system.h linux/include/asm-i386/system.h
--- v2.3.29/linux/include/asm-i386/system.h	Tue Aug 31 17:29:14 1999
+++ linux/include/asm-i386/system.h	Mon Dec  6 17:22:07 1999
@@ -122,11 +122,61 @@
 
 #define nop() __asm__ __volatile__ ("nop")
 
-#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
+
 #define tas(ptr) (xchg((ptr),1))
 
 struct __xchg_dummy { unsigned long a[100]; };
 #define __xg(x) ((struct __xchg_dummy *)(x))
+
+
+/*
+ * The semantics of XCHGCMP8B are a bit strange, this is why
+ * there is a loop and the loading of %%eax and %%edx has to
+ * be inside. This inlines well in most cases, the cached
+ * cost is around ~38 cycles. (in the future we might want
+ * to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that
+ * might have an implicit FPU-save as a cost, so it's not
+ * clear which path to go.)
+ */
+extern inline void __set_64bit (unsigned long long * ptr,
+		unsigned int low, unsigned int high)
+{
+__asm__ __volatile__ (
+	"1:	movl (%0), %%eax;
+		movl 4(%0), %%edx;
+		cmpxchg8b (%0);
+		jnz 1b"
+	::		"D"(ptr),
+			"b"(low),
+			"c"(high)
+	:
+			"ax","dx","memory");
+}
+
+extern void inline __set_64bit_constant (unsigned long long *ptr,
+						 unsigned long long value)
+{
+	__set_64bit(ptr,(unsigned int)(value), (unsigned int)((value)>>32ULL));
+}
+#define ll_low(x)	*(((unsigned int*)&(x))+0)
+#define ll_high(x)	*(((unsigned int*)&(x))+1)
+
+extern void inline __set_64bit_var (unsigned long long *ptr,
+			 unsigned long long value)
+{
+	__set_64bit(ptr,ll_low(value), ll_high(value));
+}
+
+#define set_64bit(ptr,value) \
+(__builtin_constant_p(value) ? \
+ __set_64bit_constant(ptr, value) : \
+ __set_64bit_var(ptr, value) )
+
+#define _set_64bit(ptr,value) \
+(__builtin_constant_p(value) ? \
+ __set_64bit(ptr, (unsigned int)(value), (unsigned int)((value)>>32ULL) ) : \
+ __set_64bit(ptr, ll_low(value), ll_high(value)) )
 
 /*
  * Note: no "lock" prefix even on SMP: xchg always implies lock anyway
diff -u --recursive --new-file v2.3.29/linux/include/asm-m68k/io.h linux/include/asm-m68k/io.h
--- v2.3.29/linux/include/asm-m68k/io.h	Tue Sep  7 12:14:07 1999
+++ linux/include/asm-m68k/io.h	Sat Nov 27 15:27:49 1999
@@ -47,6 +47,8 @@
 #define outb(x,addr) ((void) writeb(x,addr))
 #define outb_p(x,addr) outb(x,addr)
 
+#define IO_SPACE_LIMIT 0xffff
+
 
 /* Values for nocacheflag and cmode */
 #define IOMAP_FULL_CACHING		0
diff -u --recursive --new-file v2.3.29/linux/include/asm-mips/io.h linux/include/asm-mips/io.h
--- v2.3.29/linux/include/asm-mips/io.h	Wed Jun 30 11:24:55 1999
+++ linux/include/asm-mips/io.h	Sat Nov 27 15:27:49 1999
@@ -375,6 +375,8 @@
 	__inslc((port),(addr),(count)) : \
 	__insl((port),(addr),(count)))
 
+#define IO_SPACE_LIMIT 0xffff
+
 /*
  * The caches on some architectures aren't dma-coherent and have need to
  * handle this in software.  There are three types of operations that
diff -u --recursive --new-file v2.3.29/linux/include/asm-ppc/board.h linux/include/asm-ppc/board.h
--- v2.3.29/linux/include/asm-ppc/board.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ppc/board.h	Sat Nov 27 15:42:33 1999
@@ -0,0 +1,36 @@
+/*
+ *
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Module name: board.h
+ *
+ *    Description:
+ *	A generic include file which pulls in appropriate include files
+ *      for specific board types based on configuration settings.
+ *
+ */
+
+#ifndef __BOARD_H__
+#define	__BOARD_H__
+
+#include <linux/config.h>
+
+#if defined(CONFIG_OAK)
+#include <asm/oak.h>
+#endif
+
+#if defined(CONFIG_WALNUT)
+#include <asm/walnut.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOARD_H__ */
diff -u --recursive --new-file v2.3.29/linux/include/asm-ppc/bootinfo.h linux/include/asm-ppc/bootinfo.h
--- v2.3.29/linux/include/asm-ppc/bootinfo.h	Tue Aug  4 16:06:36 1998
+++ linux/include/asm-ppc/bootinfo.h	Thu Dec  2 14:37:35 1999
@@ -1,375 +1,27 @@
 /*
-** asm/bootinfo.h -- Definition of the Linux/m68k boot information structure
-**
-** Copyright 1992 by Greg Harp
-**
-** This file is subject to the terms and conditions of the GNU General Public
-** License.  See the file COPYING in the main directory of this archive
-** for more details.
-**
-** Created 09/29/92 by Greg Harp
-**
-** 5/2/94 Roman Hodek:
-**   Added bi_atari part of the machine dependent union bi_un; for now it
-**   contains just a model field to distinguish between TT and Falcon.
-** 26/7/96 Roman Zippel:
-**   Renamed to setup.h; added some useful macros to allow gcc some
-**   optimizations if possible.
-** 5/10/96 Geert Uytterhoeven:
-**   Redesign of the boot information structure; renamed to bootinfo.h again
-** 27/11/96 Geert Uytterhoeven:
-**   Backwards compatibility with bootinfo interface version 1.0
-*/
+ * Non-machine dependent bootinfo structure.  Basic idea
+ * borrowed from the m68k.
+ *
+ * Copyright (C) 1999 Cort Dougan <cort@ppc.kernel.org>
+ */
 
-#ifndef _BOOTINFO_H
-#define _BOOTINFO_H
 
-
-    /*
-     *  Bootinfo definitions
-     *
-     *  This is an easily parsable and extendable structure containing all
-     *  information to be passed from the bootstrap to the kernel.
-     *
-     *  This way I hope to keep all future changes back/forewards compatible.
-     *  Thus, keep your fingers crossed...
-     *
-     *  This structure is copied right after the kernel bss by the bootstrap
-     *  routine.
-     */
-
-#ifndef __ASSEMBLY__
+#ifndef _PPC_BOOTINFO_H
+#define _PPC_BOOTINFO_H
 
 struct bi_record {
-    unsigned short tag;			/* tag ID */
-    unsigned short size;		/* size of record (in bytes) */
+    unsigned long tag;			/* tag ID */
+    unsigned long size;			/* size of record (in bytes) */
     unsigned long data[0];		/* data */
 };
 
-#else /* __ASSEMBLY__ */
-
-BIR_tag		= 0
-BIR_size	= BIR_tag+2
-BIR_data	= BIR_size+2
-
-#endif /* __ASSEMBLY__ */
-
-
-    /*
-     *  Tag Definitions
-     *
-     *  Machine independent tags start counting from 0x0000
-     *  Machine dependent tags start counting from 0x8000
-     */
-
-#define BI_LAST			0x0000	/* last record (sentinel) */
-#define BI_MACHTYPE		0x0001	/* machine type (u_long) */
-#define BI_CPUTYPE		0x0002	/* cpu type (u_long) */
-#define BI_FPUTYPE		0x0003	/* fpu type (u_long) */
-#define BI_MMUTYPE		0x0004	/* mmu type (u_long) */
-#define BI_MEMCHUNK		0x0005	/* memory chunk address and size */
-					/* (struct mem_info) */
-#define BI_RAMDISK		0x0006	/* ramdisk address and size */
-					/* (struct mem_info) */
-#define BI_COMMAND_LINE		0x0007	/* kernel command line parameters */
-					/* (string) */
-
-    /*
-     *  Amiga-specific tags
-     */
-
-#define BI_AMIGA_MODEL		0x8000	/* model (u_long) */
-#define BI_AMIGA_AUTOCON	0x8001	/* AutoConfig device */
-					/* (struct ConfigDev) */
-#define BI_AMIGA_CHIP_SIZE	0x8002	/* size of Chip RAM (u_long) */
-#define BI_AMIGA_VBLANK		0x8003	/* VBLANK frequency (u_char) */
-#define BI_AMIGA_PSFREQ		0x8004	/* power supply frequency (u_char) */
-#define BI_AMIGA_ECLOCK		0x8005	/* EClock frequency (u_long) */
-#define BI_AMIGA_CHIPSET	0x8006	/* native chipset present (u_long) */
-#define BI_AMIGA_SERPER		0x8007	/* serial port period (u_short) */
-
-    /*
-     *  Atari-specific tags
-     */
-
-#define BI_ATARI_MCH_COOKIE	0x8000	/* _MCH cookie from TOS (u_long) */
-#define BI_ATARI_MCH_TYPE	0x8001	/* special machine type (u_long) */
-					/* (values are ATARI_MACH_* defines */
-
-/* mch_cookie values (upper word) */
-#define ATARI_MCH_ST		0
-#define ATARI_MCH_STE		1
-#define ATARI_MCH_TT		2
-#define ATARI_MCH_FALCON	3
-
-/* mch_type values */
-#define ATARI_MACH_NORMAL	0	/* no special machine type */
-#define ATARI_MACH_MEDUSA	1	/* Medusa 040 */
-#define ATARI_MACH_HADES	2	/* Hades 040 or 060 */
-#define ATARI_MACH_AB40		3	/* Afterburner040 on Falcon */
-
-    /*
-     *  Macintosh-specific tags (all u_long)
-     */
-
-#define BI_MAC_MODEL		0x8000	/* Mac Gestalt ID (model type) */
-#define BI_MAC_VADDR		0x8001	/* Mac video base address */
-#define BI_MAC_VDEPTH		0x8002	/* Mac video depth */
-#define BI_MAC_VROW		0x8003	/* Mac video rowbytes */
-#define BI_MAC_VDIM		0x8004	/* Mac video dimensions */
-#define BI_MAC_VLOGICAL		0x8005	/* Mac video logical base */
-#define BI_MAC_SCCBASE		0x8006	/* Mac SCC base address */
-#define BI_MAC_BTIME		0x8007	/* Mac boot time */
-#define BI_MAC_GMTBIAS		0x8008	/* Mac GMT timezone offset */
-#define BI_MAC_MEMSIZE		0x8009	/* Mac RAM size (sanity check) */
-#define BI_MAC_CPUID		0x800a	/* Mac CPU type (sanity check) */
-#define BI_MAC_ROMBASE		0x800b	/* Mac system ROM base address */ 
-
-    /*
-     *  Macintosh hardware profile data - unused, see macintosh.h for 
-     *  resonable type values 
-     */
-
-#define BI_MAC_VIA1BASE		0x8010	/* Mac VIA1 base address (always present) */
-#define BI_MAC_VIA2BASE		0x8011	/* Mac VIA2 base address (type varies) */
-#define BI_MAC_VIA2TYPE		0x8012	/* Mac VIA2 type (VIA, RBV, OSS) */
-#define BI_MAC_ADBTYPE		0x8013	/* Mac ADB interface type */
-#define BI_MAC_ASCBASE		0x8014	/* Mac Apple Sound Chip base address */
-#define BI_MAC_SCSI5380		0x8015	/* Mac NCR 5380 SCSI (base address, multi) */
-#define BI_MAC_SCSIDMA		0x8016	/* Mac SCSI DMA (base address) */
-#define BI_MAC_SCSI5396		0x8017	/* Mac NCR 53C96 SCSI (base address, multi) */
-#define BI_MAC_IDETYPE		0x8018	/* Mac IDE interface type */
-#define BI_MAC_IDEBASE		0x8019	/* Mac IDE interface base address */
-#define BI_MAC_NUBUS		0x801a	/* Mac Nubus type (none, regular, pseudo) */
-#define BI_MAC_SLOTMASK		0x801b	/* Mac Nubus slots present */
-#define BI_MAC_SCCTYPE		0x801c	/* Mac SCC serial type (normal, IOP) */
-#define BI_MAC_ETHTYPE		0x801d	/* Mac builtin ethernet type (Sonic, MACE */
-#define BI_MAC_ETHBASE		0x801e	/* Mac builtin ethernet base address */
-#define BI_MAC_PMU		0x801f	/* Mac power managment / poweroff hardware */
-#define BI_MAC_IOP_SWIM		0x8020	/* Mac SWIM floppy IOP */
-#define BI_MAC_IOP_ADB		0x8021	/* Mac ADB IOP */
-
-    /*
-     * Mac: compatibility with old booter data format (temporarily)
-     * Fields unused with the new bootinfo can be deleted now; instead of
-     * adding new fields the struct might be splitted into a hardware address
-     * part and a hardware type part
-     */
-
-#ifndef __ASSEMBLY__
-
-struct mac_booter_data 
-{
-	unsigned long videoaddr;
-	unsigned long videorow;
-	unsigned long videodepth;
-	unsigned long dimensions;
-	unsigned long args;
-	unsigned long boottime;
-	unsigned long gmtbias;
-	unsigned long bootver;
-	unsigned long videological;
-	unsigned long sccbase;
-	unsigned long id;
-	unsigned long memsize;
-	unsigned long serialmf;
-	unsigned long serialhsk;
-	unsigned long serialgpi;
-	unsigned long printmf;
-	unsigned long printhsk;
-	unsigned long printgpi;
-	unsigned long cpuid;
-	unsigned long rombase;
-	unsigned long adbdelay;
-	unsigned long timedbra;
-};
-
-extern struct mac_booter_data 
-	mac_bi_data;
-
-#endif
-
-    /*
-     * Stuff for bootinfo interface versioning
-     *
-     * At the start of kernel code, a 'struct bootversion' is located.
-     * bootstrap checks for a matching version of the interface before booting
-     * a kernel, to avoid user confusion if kernel and bootstrap don't work
-     * together :-)
-     *
-     * If incompatible changes are made to the bootinfo interface, the major
-     * number below should be stepped (and the minor reset to 0) for the
-     * appropriate machine. If a change is backward-compatible, the minor
-     * should be stepped. "Backwards-compatible" means that booting will work,
-     * but certain features may not.
-     */
-
-#define BOOTINFOV_MAGIC			0x4249561A	/* 'BIV^Z' */
-#define MK_BI_VERSION(major,minor)	(((major)<<16)+(minor))
-#define BI_VERSION_MAJOR(v)		(((v) >> 16) & 0xffff)
-#define BI_VERSION_MINOR(v)		((v) & 0xffff)
-
-#ifndef __ASSEMBLY__
-
-struct bootversion {
-    unsigned short branch;
-    unsigned long magic;
-    struct {
-	unsigned long machtype;
-	unsigned long version;
-    } machversions[0];
-};
-
-#endif /* __ASSEMBLY__ */
-
-#define AMIGA_BOOTI_VERSION    MK_BI_VERSION( 2, 0 )
-#define ATARI_BOOTI_VERSION    MK_BI_VERSION( 2, 1 )
-#define MAC_BOOTI_VERSION      MK_BI_VERSION( 2, 0 )
-#define MVME16x_BOOTI_VERSION  MK_BI_VERSION( 2, 0 )
-#define BVME6000_BOOTI_VERSION MK_BI_VERSION( 2, 0 )
-
-
-#ifdef BOOTINFO_COMPAT_1_0
-
-    /*
-     *  Backwards compatibility with bootinfo interface version 1.0
-     */
-
-#define COMPAT_AMIGA_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
-#define COMPAT_ATARI_BOOTI_VERSION    MK_BI_VERSION( 1, 0 )
-#define COMPAT_MAC_BOOTI_VERSION      MK_BI_VERSION( 1, 0 )
-
-#include <linux/zorro.h>
-
-#define COMPAT_NUM_AUTO    16
-
-struct compat_bi_Amiga {
-    int model;
-    int num_autocon;
-    struct ConfigDev autocon[COMPAT_NUM_AUTO];
-    unsigned long chip_size;
-    unsigned char vblank;
-    unsigned char psfreq;
-    unsigned long eclock;
-    unsigned long chipset;
-    unsigned long hw_present;
-};
-
-struct compat_bi_Atari {
-    unsigned long hw_present;
-    unsigned long mch_cookie;
-};
-
-#ifndef __ASSEMBLY__
-
-#define MACHW_DECLARE(name)    unsigned name : 1
-#define MACHW_SET(name)                (boot_info.bi_mac.hw_present.name = 1)
-#define MACHW_PRESENT(name)    (boot_info.bi_mac.hw_present.name)
-
-struct compat_bi_Macintosh
-{
-	unsigned long videoaddr;
-	unsigned long videorow;
-	unsigned long videodepth;
-	unsigned long dimensions;
-	unsigned long args;
-	unsigned long boottime;
-	unsigned long gmtbias;
-	unsigned long bootver;
-	unsigned long videological;
-	unsigned long sccbase;
-	unsigned long id;
-	unsigned long memsize;
-	unsigned long serialmf;
-	unsigned long serialhsk;
-	unsigned long serialgpi;
-	unsigned long printmf;
-	unsigned long printhsk;
-	unsigned long printgpi;
-	unsigned long cpuid;
-	unsigned long rombase;
-	unsigned long adbdelay;
-	unsigned long timedbra;
-	struct {
-		/* video hardware */
-		/* sound hardware */
-		/* disk storage interfaces */
-		MACHW_DECLARE(MAC_SCSI);        /* Directly mapped NCR5380 */
-		MACHW_DECLARE(IDE);             /* IDE Interface */
-		/* other I/O hardware */
-		MACHW_DECLARE(SCC);             /* Serial Communications Contr. */
-		/* DMA */
-		MACHW_DECLARE(SCSI_DMA);        /* DMA for the NCR5380 */
-		/* real time clocks */
-		MACHW_DECLARE(RTC_CLK);         /* clock chip */
-		/* supporting hardware */
-		MACHW_DECLARE(VIA1);            /* Versatile Interface Ad. 1 */
-		MACHW_DECLARE(VIA2);            /* Versatile Interface Ad. 2 */
-		MACHW_DECLARE(RBV);             /* Versatile Interface Ad. 2+ */
-		/* NUBUS */
-		MACHW_DECLARE(NUBUS);           /* NUBUS */
-	} hw_present;
-};
-#else
-
-#define BI_videoaddr	BI_un
-#define BI_videorow	BI_videoaddr+4
-#define BI_videodepth	BI_videorow+4
-#define BI_dimensions	BI_videodepth+4
-#define BI_args		BI_dimensions+4
-#define BI_cpuid	BI_args+56
-
-#endif
-
-struct compat_mem_info {
-    unsigned long addr;
-    unsigned long size;
-};
-
-#define COMPAT_NUM_MEMINFO  4
-
-#define COMPAT_CPUB_68020 0
-#define COMPAT_CPUB_68030 1
-#define COMPAT_CPUB_68040 2
-#define COMPAT_CPUB_68060 3
-#define COMPAT_FPUB_68881 5
-#define COMPAT_FPUB_68882 6
-#define COMPAT_FPUB_68040 7
-#define COMPAT_FPUB_68060 8
-
-#define COMPAT_CPU_68020    (1<<COMPAT_CPUB_68020)
-#define COMPAT_CPU_68030    (1<<COMPAT_CPUB_68030)
-#define COMPAT_CPU_68040    (1<<COMPAT_CPUB_68040)
-#define COMPAT_CPU_68060    (1<<COMPAT_CPUB_68060)
-#define COMPAT_CPU_MASK     (31)
-#define COMPAT_FPU_68881    (1<<COMPAT_FPUB_68881)
-#define COMPAT_FPU_68882    (1<<COMPAT_FPUB_68882)
-#define COMPAT_FPU_68040    (1<<COMPAT_FPUB_68040)
-#define COMPAT_FPU_68060    (1<<COMPAT_FPUB_68060)
-#define COMPAT_FPU_MASK     (0xfe0)
-
-#define COMPAT_CL_SIZE      (256)
-
-struct compat_bootinfo {
-    unsigned long machtype;
-    unsigned long cputype;
-    struct compat_mem_info memory[COMPAT_NUM_MEMINFO];
-    int num_memory;
-    unsigned long ramdisk_size;
-    unsigned long ramdisk_addr;
-    char command_line[COMPAT_CL_SIZE];
-    union {
-	struct compat_bi_Amiga     bi_ami;
-	struct compat_bi_Atari     bi_ata;
-	struct compat_bi_Macintosh bi_mac;
-    } bi_un;
-};
-
-#define bi_amiga	bi_un.bi_ami
-#define bi_atari	bi_un.bi_ata
-#define bi_mac		bi_un.bi_mac
-
-#endif /* BOOTINFO_COMPAT_1_0 */
+#define BI_FIRST		0x1010  /* first record - marker */
+#define BI_LAST			0x1011	/* last record - marker */
+#define BI_CMD_LINE		0x1012
+#define BI_BOOTLOADER_ID	0x1013
+#define BI_INITRD		0x1014
+#define BI_SYSMAP		0x1015
+#define BI_MACHTYPE		0x1016
 
+#endif /* _PPC_BOOTINFO_H */
 
-#endif /* _BOOTINFO_H */
diff -u --recursive --new-file v2.3.29/linux/include/asm-ppc/io.h linux/include/asm-ppc/io.h
--- v2.3.29/linux/include/asm-ppc/io.h	Sat Oct  9 11:47:50 1999
+++ linux/include/asm-ppc/io.h	Sat Nov 27 15:42:33 1999
@@ -19,7 +19,9 @@
 #define PREP_ISA_MEM_BASE 	0xc0000000
 #define PREP_PCI_DRAM_OFFSET 	0x80000000
 
-#ifdef CONFIG_8xx
+#if defined(CONFIG_4xx)
+#include <asm/board.h>
+#elif defined(CONFIG_8xx)
 #include <asm/mpc8xx.h>
 #else
 #ifdef CONFIG_APUS
@@ -34,7 +36,7 @@
 #define _ISA_MEM_BASE	isa_mem_base
 #define PCI_DRAM_OFFSET	pci_dram_offset
 #endif /* CONFIG_APUS */
-#endif /* CONFIG_8xx */
+#endif
 
 #define readb(addr) in_8((volatile unsigned char *)(addr))
 #define writeb(b,addr) out_8((volatile unsigned char *)(addr), (b))
@@ -97,6 +99,8 @@
 extern void _outsw_ns(volatile unsigned short *port, const void *buf, int ns);
 extern void _insl_ns(volatile unsigned long *port, void *buf, int nl);
 extern void _outsl_ns(volatile unsigned long *port, const void *buf, int nl);
+
+#define IO_SPACE_LIMIT 0xffff
 
 #define memset_io(a,b,c)	memset((a),(b),(c))
 #define memcpy_fromio(a,b,c)	memcpy((a),(b),(c))
diff -u --recursive --new-file v2.3.29/linux/include/asm-ppc/machdep.h linux/include/asm-ppc/machdep.h
--- v2.3.29/linux/include/asm-ppc/machdep.h	Fri Oct 22 13:21:54 1999
+++ linux/include/asm-ppc/machdep.h	Sat Nov 27 15:42:33 1999
@@ -83,23 +83,6 @@
 
 extern void setup_pci_ptrs(void);
 
-#define BOOT_INFO_VER 0x1
-#define BOOT_INFO_MAGIC 0x05027800
-
-struct boot_info
-{
-	unsigned long magic_start;
-	char cmd_line[256];
-	char boot_loader[128];
-	int _machine_type;
-	unsigned long initrd_start, initrd_size;
-	unsigned long systemmap_start, systemmap_size;
-	unsigned long prom_entry;
-	char reserved[3680];	/* pad to 1 page */
-	unsigned long magic_end;
-};
-struct boot_info *binfo;
-
 /*
  * Power macintoshes have either a CUDA or a PMU controlling
  * system reset, power, NVRAM, RTC.
diff -u --recursive --new-file v2.3.29/linux/include/asm-ppc/oak.h linux/include/asm-ppc/oak.h
--- v2.3.29/linux/include/asm-ppc/oak.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ppc/oak.h	Sat Nov 27 15:42:33 1999
@@ -0,0 +1,31 @@
+/*
+ *
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Module name: oak.h
+ *
+ *    Description:
+ *	Macros, definitions, and data structures specific to the IBM PowerPC
+ *      403G{A,B,C,CX} "Oak" evaluation board. Anything specific to the pro-
+ *      cessor itself is defined elsewhere.
+ *
+ */
+
+#ifndef	__OAK_H__
+#define	__OAK_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _IO_BASE	0
+#define _ISA_MEM_BASE	0
+#define PCI_DRAM_OFFSET	0
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OAK_H__ */
diff -u --recursive --new-file v2.3.29/linux/include/asm-ppc/pgalloc.h linux/include/asm-ppc/pgalloc.h
--- v2.3.29/linux/include/asm-ppc/pgalloc.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-ppc/pgalloc.h	Thu Dec  2 21:14:20 1999
@@ -1,7 +1,81 @@
 #ifndef _PPC_PGALLOC_H
 #define _PPC_PGALLOC_H
 
+#include <linux/threads.h>
+#include <asm/processor.h>
 
+/*
+ * This is handled very differently on the PPC since out page tables
+ * are all 0's and I want to be able to use these zero'd pages elsewhere
+ * as well - it gives us quite a speedup.
+ *
+ * Note that the SMP/UP versions are the same but we don't need a
+ * per cpu list of zero pages because we do the zero-ing with the cache
+ * off and the access routines are lock-free but the pgt cache stuff
+ * is per-cpu since it isn't done with any lock-free access routines
+ * (although I think we need arch-specific routines so I can do lock-free).
+ *
+ * I need to generalize this so we can use it for other arch's as well.
+ * -- Cort
+ */
+#ifdef __SMP__
+#define quicklists	cpu_data[smp_processor_id()]
+#else
+extern struct pgtable_cache_struct {
+	unsigned long *pgd_cache;
+	unsigned long *pte_cache;
+	unsigned long pgtable_cache_sz;
+} quicklists;
+#endif
+
+#define pgd_quicklist 		(quicklists.pgd_cache)
+#define pmd_quicklist 		((unsigned long *)0)
+#define pte_quicklist 		(quicklists.pte_cache)
+#define pgtable_cache_size 	(quicklists.pgtable_cache_sz)
+
+extern unsigned long *zero_cache;    /* head linked list of pre-zero'd pages */
+extern atomic_t zero_sz;	     /* # currently pre-zero'd pages */
+extern atomic_t zeropage_hits;	     /* # zero'd pages request that we've done */
+extern atomic_t zeropage_calls;      /* # zero'd pages request that've been made */
+extern atomic_t zerototal;	     /* # pages zero'd over time */
+
+#define zero_quicklist     	(zero_cache)
+#define zero_cache_sz  	 	(zero_sz)
+#define zero_cache_calls 	(zeropage_calls)
+#define zero_cache_hits  	(zeropage_hits)
+#define zero_cache_total 	(zerototal)
+
+/* return a pre-zero'd page from the list, return NULL if none available -- Cort */
+extern unsigned long get_zero_page_fast(void);
+
+extern void __bad_pte(pmd_t *pmd);
+
+extern inline void set_pgdir(unsigned long address, pgd_t entry)
+{
+	struct task_struct * p;
+	pgd_t *pgd;
+#ifdef __SMP__
+	int i;
+#endif	
+        
+	read_lock(&tasklist_lock);
+	for_each_task(p) {
+		if (!p->mm)
+			continue;
+		*pgd_offset(p->mm,address) = entry;
+	}
+	read_unlock(&tasklist_lock);
+#ifndef __SMP__
+	for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+		pgd[address >> PGDIR_SHIFT] = entry;
+#else
+	/* To pgd_alloc/pgd_free, one holds master kernel lock and so does our callee, so we can
+	   modify pgd caches of other CPUs as well. -jj */
+	for (i = 0; i < NR_CPUS; i++)
+		for (pgd = (pgd_t *)cpu_data[i].pgd_cache; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+			pgd[address >> PGDIR_SHIFT] = entry;
+#endif
+}
 
 /* We don't use pmd cache, so this is a dummy routine */
 extern __inline__ pmd_t *get_pmd_fast(void)
@@ -52,9 +126,9 @@
 {
         unsigned long *ret;
 
-        if((ret = pgd_quicklist) != NULL) {
+        if ((ret = pgd_quicklist) != NULL) {
                 pgd_quicklist = (unsigned long *)(*ret);
-                ret[0] = ret[1];
+                ret[0] = 0;
                 pgtable_cache_size--;
         } else
                 ret = (unsigned long *)get_pgd_slow();
@@ -63,7 +137,7 @@
 
 extern __inline__ void free_pgd_fast(pgd_t *pgd)
 {
-        *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
+        *(unsigned long **)pgd = pgd_quicklist;
         pgd_quicklist = (unsigned long *) pgd;
         pgtable_cache_size++;
 }
@@ -79,9 +153,9 @@
 {
         unsigned long *ret;
 
-        if((ret = (unsigned long *)pte_quicklist) != NULL) {
+        if ((ret = pte_quicklist) != NULL) {
                 pte_quicklist = (unsigned long *)(*ret);
-                ret[0] = ret[1];
+                ret[0] = 0;
                 pgtable_cache_size--;
 	}
         return (pte_t *)ret;
@@ -89,7 +163,7 @@
 
 extern __inline__ void free_pte_fast(pte_t *pte)
 {
-        *(unsigned long *)pte = (unsigned long) pte_quicklist;
+        *(unsigned long **)pte = pte_quicklist;
         pte_quicklist = (unsigned long *) pte;
         pgtable_cache_size++;
 }
@@ -98,6 +172,7 @@
 {
 	free_page((unsigned long)pte);
 }
+
 #define pte_free_kernel(pte)    free_pte_fast(pte)
 #define pte_free(pte)           free_pte_fast(pte)
 #define pgd_free(pgd)           free_pgd_fast(pgd)
@@ -122,30 +197,5 @@
 }
 
 extern int do_check_pgt_cache(int, int);
-
-extern __inline__ pte_t *find_pte(struct mm_struct *mm,unsigned long va)
-{
-	pgd_t *dir;
-	pmd_t *pmd;
-	pte_t *pte;
-
-	va &= PAGE_MASK;
-	
-	dir = pgd_offset( mm, va );
-	if (dir)
-	{
-		pmd = pmd_offset(dir, va & PAGE_MASK);
-		if (pmd && pmd_present(*pmd))
-		{
-			pte = pte_offset(pmd, va);
-			if (pte && pte_present(*pte))
-			{			
-				pte_uncache(*pte);
-				flush_tlb_page(find_vma(mm,va),va);
-			}
-		}
-	}
-	return pte;
-}
 
 #endif /* _PPC_PGALLOC_H */
diff -u --recursive --new-file v2.3.29/linux/include/asm-ppc/pgtable.h linux/include/asm-ppc/pgtable.h
--- v2.3.29/linux/include/asm-ppc/pgtable.h	Tue Nov 23 22:42:21 1999
+++ linux/include/asm-ppc/pgtable.h	Mon Dec  6 10:14:13 1999
@@ -1,12 +1,10 @@
-#include <linux/config.h>
-
 #ifndef _PPC_PGTABLE_H
 #define _PPC_PGTABLE_H
 
+#include <linux/config.h>
+
 #ifndef __ASSEMBLY__
 #include <linux/threads.h>
-#include <linux/sched.h>
-#include <asm/atomic.h>
 #include <asm/processor.h>		/* For TASK_SIZE */
 #include <asm/mmu.h>
 #include <asm/page.h>
@@ -276,8 +274,7 @@
 /*
  * Permanent address of a page.
  */
-#define page_address(page) (PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT))
-#define __page_address(page) ({ if (PageHighMem(page)) BUG(); PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT); })
+#define page_address(page)  ({ if (!(page)->virtual) BUG(); (page)->virtual; })
 #define pages_to_mb(x)		((x) >> (20-PAGE_SHIFT))
 #define pte_page(x)		(mem_map+pte_pagenr(x))
 
@@ -290,7 +287,7 @@
 extern inline int pgd_none(pgd_t pgd)		{ return 0; }
 extern inline int pgd_bad(pgd_t pgd)		{ return 0; }
 extern inline int pgd_present(pgd_t pgd)	{ return 1; }
-#define pgd_clear(xp)	do { pgd_val(*(xp)) = 0; } while (0)
+#define pgd_clear(xp)				do { } while (0)
 
 #define pgd_page(pgd) \
 	((unsigned long) __va(pgd_val(pgd) & PAGE_MASK))
@@ -371,19 +368,13 @@
 	return pte;
 }
 
-#define page_pte_prot(page,prot) mk_pte(page, prot)
-#define page_pte(page)	page_pte_prot(page, __pgprot(0))
-
 #define pmd_page(pmd)	(pmd_val(pmd))
 
 /* to find an entry in a kernel page-table-directory */
 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
 /* to find an entry in a page-table-directory */
-extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
-{
-	return mm->pgd + (address >> PGDIR_SHIFT);
-}
+#define pgd_offset(mm, address)	 ((mm)->pgd + ((address) >> PGDIR_SHIFT))
 
 /* Find an entry in the second-level page table.. */
 extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
@@ -397,79 +388,6 @@
 	return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
 }
 
-/*
- * This is handled very differently on the PPC since out page tables
- * are all 0's and I want to be able to use these zero'd pages elsewhere
- * as well - it gives us quite a speedup.
- *
- * Note that the SMP/UP versions are the same but we don't need a
- * per cpu list of zero pages because we do the zero-ing with the cache
- * off and the access routines are lock-free but the pgt cache stuff
- * is per-cpu since it isn't done with any lock-free access routines
- * (although I think we need arch-specific routines so I can do lock-free).
- *
- * I need to generalize this so we can use it for other arch's as well.
- * -- Cort
- */
-#ifdef __SMP__
-#define quicklists	cpu_data[smp_processor_id()]
-#else
-extern struct pgtable_cache_struct {
-	unsigned long *pgd_cache;
-	unsigned long *pte_cache;
-	unsigned long pgtable_cache_sz;
-} quicklists;
-#endif
-
-#define pgd_quicklist 		(quicklists.pgd_cache)
-#define pmd_quicklist 		((unsigned long *)0)
-#define pte_quicklist 		(quicklists.pte_cache)
-#define pgtable_cache_size 	(quicklists.pgtable_cache_sz)
-
-extern unsigned long *zero_cache;    /* head linked list of pre-zero'd pages */
-extern atomic_t zero_sz;	     /* # currently pre-zero'd pages */
-extern atomic_t zeropage_hits;	     /* # zero'd pages request that we've done */
-extern atomic_t zeropage_calls;      /* # zero'd pages request that've been made */
-extern atomic_t zerototal;	     /* # pages zero'd over time */
-
-#define zero_quicklist     	(zero_cache)
-#define zero_cache_sz  	 	(zero_sz)
-#define zero_cache_calls 	(zeropage_calls)
-#define zero_cache_hits  	(zeropage_hits)
-#define zero_cache_total 	(zerototal)
-
-/* return a pre-zero'd page from the list, return NULL if none available -- Cort */
-extern unsigned long get_zero_page_fast(void);
-
-extern void __bad_pte(pmd_t *pmd);
-
-extern inline void set_pgdir(unsigned long address, pgd_t entry)
-{
-	struct task_struct * p;
-	pgd_t *pgd;
-#ifdef __SMP__
-	int i;
-#endif	
-        
-	read_lock(&tasklist_lock);
-	for_each_task(p) {
-		if (!p->mm)
-			continue;
-		*pgd_offset(p->mm,address) = entry;
-	}
-	read_unlock(&tasklist_lock);
-#ifndef __SMP__
-	for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
-		pgd[address >> PGDIR_SHIFT] = entry;
-#else
-	/* To pgd_alloc/pgd_free, one holds master kernel lock and so does our callee, so we can
-	   modify pgd caches of other CPUs as well. -jj */
-	for (i = 0; i < NR_CPUS; i++)
-		for (pgd = (pgd_t *)cpu_data[i].pgd_cache; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
-			pgd[address >> PGDIR_SHIFT] = entry;
-#endif
-}
-
 extern pgd_t swapper_pg_dir[1024];
 
 /*
@@ -486,11 +404,10 @@
 extern void flush_hash_segments(unsigned low_vsid, unsigned high_vsid);
 extern void flush_hash_page(unsigned context, unsigned long va);
 
-
 /* Encode and de-code a swap entry */
-#define SWP_TYPE(entry) (((entry).val >> 1) & 0x3f)
-#define SWP_OFFSET(entry) ((entry).val >> 8)
-#define SWP_ENTRY(type,offset) ((swp_entry_t) { (((type) << 1) | ((offset) << 8)) })
+#define SWP_TYPE(entry)			(((entry).val >> 1) & 0x3f)
+#define SWP_OFFSET(entry)		((entry).val >> 8)
+#define SWP_ENTRY(type, offset)		((swp_entry_t) { ((type) << 1) | ((offset) << 8) })
 #define pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
 #define swp_entry_to_pte(x)		((pte_t) { (x).val })
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h
--- v2.3.29/linux/include/asm-ppc/processor.h	Thu Nov 11 20:11:52 1999
+++ linux/include/asm-ppc/processor.h	Sat Nov 27 15:42:33 1999
@@ -217,8 +217,6 @@
 #ifndef CONFIG_MACH_SPECIFIC
 extern int _machine;
 extern int have_of;
-extern int is_chrp;
-extern int is_powerplus;
 #endif /* CONFIG_MACH_SPECIFIC */
 
 /* what kind of prep workstation we are */
diff -u --recursive --new-file v2.3.29/linux/include/asm-ppc/ptrace.h linux/include/asm-ppc/ptrace.h
--- v2.3.29/linux/include/asm-ppc/ptrace.h	Tue Aug 31 17:29:14 1999
+++ linux/include/asm-ppc/ptrace.h	Sat Nov 27 15:42:33 1999
@@ -49,7 +49,7 @@
 #define __SIGNAL_FRAMESIZE	64
 
 #define instruction_pointer(regs) ((regs)->nip)
-#define user_mode(regs) ((regs)->msr & 0x4000)
+#define user_mode(regs) ((regs)->msr & MSR_PR)
 
 /*
  * Offsets used by 'ptrace' system call interface.
diff -u --recursive --new-file v2.3.29/linux/include/asm-ppc/resource.h linux/include/asm-ppc/resource.h
--- v2.3.29/linux/include/asm-ppc/resource.h	Tue Aug 31 17:29:14 1999
+++ linux/include/asm-ppc/resource.h	Thu Dec  2 14:37:35 1999
@@ -18,16 +18,16 @@
 
 #define INIT_RLIMITS							\
 {									\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_CPU */	\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_FSIZE */	\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_DATA */	\
-    {_STK_LIM, LONG_MAX},			/* RLIMIT_STACK */	\
-    {       0, LONG_MAX},			/* RLIMIT_CORE */	\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_RSS */	\
-    {0, 0},								\
-    {INR_OPEN, INR_OPEN},			/* RLIMIT_NOFILE */	\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_MEMLOCK */	\
-    {LONG_MAX, LONG_MAX},			/* RLIMIT_AS */		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{      _STK_LIM, RLIM_INFINITY },		\
+	{             0, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{             0,             0 },		\
+	{      INR_OPEN,     INR_OPEN  },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
+	{ RLIM_INFINITY, RLIM_INFINITY },		\
 }
 
 #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.3.29/linux/include/asm-ppc/unistd.h linux/include/asm-ppc/unistd.h
--- v2.3.29/linux/include/asm-ppc/unistd.h	Tue Aug 31 17:29:14 1999
+++ linux/include/asm-ppc/unistd.h	Thu Dec  2 14:37:35 1999
@@ -194,6 +194,7 @@
 #define __NR_getpmsg		187	/* some people actually want streams */
 #define __NR_putpmsg		188	/* some people actually want streams */
 #define __NR_vfork		189
+#define __NR_ugetrlimit		191	/* SuS compliant getrlimit */
 
 #define __NR(n)	#n
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-ppc/walnut.h linux/include/asm-ppc/walnut.h
--- v2.3.29/linux/include/asm-ppc/walnut.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-ppc/walnut.h	Sat Nov 27 15:42:33 1999
@@ -0,0 +1,28 @@
+/*
+ *
+ *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ *    Module name: walnut.h
+ *
+ *    Description:
+ *	Macros, definitions, and data structures specific to the IBM PowerPC
+ *      405GP "Walnut" evaluation board. Anything specific to the processor
+ *      itself is defined elsewhere.
+ *
+ */
+
+#ifndef	__WALNUT_H__
+#define	__WALNUT_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WALNUT_H__ */
diff -u --recursive --new-file v2.3.29/linux/include/asm-sh/io.h linux/include/asm-sh/io.h
--- v2.3.29/linux/include/asm-sh/io.h	Sun Nov  7 16:37:34 1999
+++ linux/include/asm-sh/io.h	Sat Nov 27 15:27:49 1999
@@ -158,6 +158,8 @@
 
 #ifdef __KERNEL__
 
+#define IO_SPACE_LIMIT 0xffff
+
 #include <asm/addrspace.h>
 
 /*
diff -u --recursive --new-file v2.3.29/linux/include/asm-sparc/io.h linux/include/asm-sparc/io.h
--- v2.3.29/linux/include/asm-sparc/io.h	Wed Jun  9 14:44:26 1999
+++ linux/include/asm-sparc/io.h	Sat Nov 27 15:27:49 1999
@@ -98,6 +98,8 @@
 #define inb_p inb
 #define outb_p outb
 
+#define IO_SPACE_LIMIT 0xffffffff
+
 extern void sun4c_mapioaddr(unsigned long, unsigned long, int bus_type, int rdonly);
 extern void srmmu_mapioaddr(unsigned long, unsigned long, int bus_type, int rdonly);
 
diff -u --recursive --new-file v2.3.29/linux/include/asm-sparc/sfp-machine.h linux/include/asm-sparc/sfp-machine.h
--- v2.3.29/linux/include/asm-sparc/sfp-machine.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sparc/sfp-machine.h	Thu Dec  2 15:28:54 1999
@@ -0,0 +1,205 @@
+/* Machine-dependent software floating-point definitions.
+   Sparc userland (_Q_*) version.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz),
+		  David S. Miller (davem@redhat.com) and
+		  Peter Maydell (pmaydell@chiark.greenend.org.uk).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _SFP_MACHINE_H
+#define _SFP_MACHINE_H
+   
+#define _FP_W_TYPE_SIZE		32
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_5_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_udiv(S,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_2_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_4_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S		0
+#define _FP_NANSIGN_D		0
+#define _FP_NANSIGN_Q		0
+
+#define _FP_KEEPNANFRACP 1
+
+/* If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose X.
+ */
+/* For _Qp_* and _Q_*, this should prefer X, for
+ * CPU instruction emulation this should prefer Y.
+ * (see SPAMv9 B.2.2 section).
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)		\
+	&& !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))	\
+      {								\
+	R##_s = X##_s;						\
+	_FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+	_FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+/* Some assembly to speed things up. */
+#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("addcc %r7,%8,%2
+	    addxcc %r5,%6,%1
+	    addx %r3,%4,%0"						\
+	   : "=r" ((USItype)(r2)),					\
+	     "=&r" ((USItype)(r1)),					\
+	     "=&r" ((USItype)(r0))					\
+	   : "%rJ" ((USItype)(x2)),					\
+	     "rI" ((USItype)(y2)),					\
+	     "%rJ" ((USItype)(x1)),					\
+	     "rI" ((USItype)(y1)),					\
+	     "%rJ" ((USItype)(x0)),					\
+	     "rI" ((USItype)(y0))					\
+	   : "cc")
+
+#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0)			\
+  __asm__ ("subcc %r7,%8,%2
+	    subxcc %r5,%6,%1
+	    subx %r3,%4,%0"						\
+	   : "=r" ((USItype)(r2)),					\
+	     "=&r" ((USItype)(r1)),					\
+	     "=&r" ((USItype)(r0))					\
+	   : "%rJ" ((USItype)(x2)),					\
+	     "rI" ((USItype)(y2)),					\
+	     "%rJ" ((USItype)(x1)),					\
+	     "rI" ((USItype)(y1)),					\
+	     "%rJ" ((USItype)(x0)),					\
+	     "rI" ((USItype)(y0))					\
+	   : "cc")
+
+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  do {									\
+    /* We need to fool gcc,  as we need to pass more than 10		\
+       input/outputs.  */						\
+    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");		\
+    __asm__ __volatile__ ("
+	    addcc %r8,%9,%1
+	    addxcc %r6,%7,%0
+	    addxcc %r4,%5,%%g2
+	    addx %r2,%3,%%g1"						\
+	   : "=&r" ((USItype)(r1)),					\
+	     "=&r" ((USItype)(r0))					\
+	   : "%rJ" ((USItype)(x3)),					\
+	     "rI" ((USItype)(y3)),					\
+	     "%rJ" ((USItype)(x2)),					\
+	     "rI" ((USItype)(y2)),					\
+	     "%rJ" ((USItype)(x1)),					\
+	     "rI" ((USItype)(y1)),					\
+	     "%rJ" ((USItype)(x0)),					\
+	     "rI" ((USItype)(y0))					\
+	   : "cc", "g1", "g2");						\
+    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));			\
+    r3 = _t1; r2 = _t2;							\
+  } while (0)
+
+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0)		\
+  do {									\
+    /* We need to fool gcc,  as we need to pass more than 10		\
+       input/outputs.  */						\
+    register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2");		\
+    __asm__ __volatile__ ("
+	    subcc %r8,%9,%1
+	    subxcc %r6,%7,%0
+	    subxcc %r4,%5,%%g2
+	    subx %r2,%3,%%g1"						\
+	   : "=&r" ((USItype)(r1)),					\
+	     "=&r" ((USItype)(r0))					\
+	   : "%rJ" ((USItype)(x3)),					\
+	     "rI" ((USItype)(y3)),					\
+	     "%rJ" ((USItype)(x2)),					\
+	     "rI" ((USItype)(y2)),					\
+	     "%rJ" ((USItype)(x1)),					\
+	     "rI" ((USItype)(y1)),					\
+	     "%rJ" ((USItype)(x0)),					\
+	     "rI" ((USItype)(y0))					\
+	   : "cc", "g1", "g2");						\
+    __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2));			\
+    r3 = _t1; r2 = _t2;							\
+  } while (0)
+
+#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0)
+
+#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0)
+
+#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i)					\
+  __asm__ ("addcc %3,%4,%3
+	    addxcc %2,%%g0,%2
+	    addxcc %1,%%g0,%1
+	    addx %0,%%g0,%0"						\
+	   : "=&r" ((USItype)(x3)),					\
+	     "=&r" ((USItype)(x2)),					\
+	     "=&r" ((USItype)(x1)),					\
+	     "=&r" ((USItype)(x0))					\
+	   : "rI" ((USItype)(i)),					\
+	     "0" ((USItype)(x3)),					\
+	     "1" ((USItype)(x2)),					\
+	     "2" ((USItype)(x1)),					\
+	     "3" ((USItype)(x0))					\
+	   : "cc")
+
+#ifndef __SMP__
+extern struct task_struct *last_task_used_math;
+#endif
+
+/* Obtain the current rounding mode. */
+#ifndef FP_ROUNDMODE
+#ifdef __SMP__
+#define FP_ROUNDMODE	((current->thread.fsr >> 30) & 0x3)
+#else
+#define FP_ROUNDMODE	((last_task_used_math->thread.fsr >> 30) & 0x3)
+#endif
+#endif
+
+/* Exception flags. */
+#define FP_EX_INVALID		(1 << 4)
+#define FP_EX_OVERFLOW		(1 << 3)
+#define FP_EX_UNDERFLOW		(1 << 2)
+#define FP_EX_DIVZERO		(1 << 1)
+#define FP_EX_INEXACT		(1 << 0)
+
+#define FP_HANDLE_EXCEPTIONS return _fex
+
+#ifdef __SMP__
+#define FP_INHIBIT_RESULTS ((current->thread.fsr >> 23) & _fex)
+#else
+#define FP_INHIBIT_RESULTS ((last_task_used_math->thread.fsr >> 23) & _fex)
+#endif
+
+#endif
diff -u --recursive --new-file v2.3.29/linux/include/asm-sparc64/io.h linux/include/asm-sparc64/io.h
--- v2.3.29/linux/include/asm-sparc64/io.h	Fri Sep 10 23:57:37 1999
+++ linux/include/asm-sparc64/io.h	Sat Nov 27 15:27:49 1999
@@ -180,6 +180,8 @@
 #define writew(__w, __addr)	(_writew((__w), (unsigned long)(__addr)))
 #define writel(__l, __addr)	(_writel((__l), (unsigned long)(__addr)))
 
+#define IO_SPACE_LIMIT 0xffffffff
+
 /*
  * Memcpy to/from I/O space is just a regular memory operation on
  * Ultra as well.
diff -u --recursive --new-file v2.3.29/linux/include/asm-sparc64/sfp-machine.h linux/include/asm-sparc64/sfp-machine.h
--- v2.3.29/linux/include/asm-sparc64/sfp-machine.h	Wed Dec 31 16:00:00 1969
+++ linux/include/asm-sparc64/sfp-machine.h	Thu Dec  2 15:28:54 1999
@@ -0,0 +1,91 @@
+/* Machine-dependent software floating-point definitions.
+   Sparc64 kernel version.
+   Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Richard Henderson (rth@cygnus.com),
+		  Jakub Jelinek (jj@ultra.linux.cz) and
+		  David S. Miller (davem@redhat.com).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If
+   not, write to the Free Software Foundation, Inc.,
+   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _SFP_MACHINE_H
+#define _SFP_MACHINE_H
+   
+#define _FP_W_TYPE_SIZE		64
+#define _FP_W_TYPE		unsigned long
+#define _FP_WS_TYPE		signed long
+#define _FP_I_TYPE		long
+
+#define _FP_MUL_MEAT_S(R,X,Y)					\
+  _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
+#define _FP_MUL_MEAT_D(R,X,Y)					\
+  _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_Q(R,X,Y)					\
+  _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
+
+#define _FP_DIV_MEAT_S(R,X,Y)	_FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
+#define _FP_DIV_MEAT_D(R,X,Y)	_FP_DIV_MEAT_1_udiv(D,R,X,Y)
+#define _FP_DIV_MEAT_Q(R,X,Y)	_FP_DIV_MEAT_2_udiv(Q,R,X,Y)
+
+#define _FP_NANFRAC_S		((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D		((_FP_QNANBIT_D << 1) - 1)
+#define _FP_NANFRAC_Q		((_FP_QNANBIT_Q << 1) - 1), -1
+#define _FP_NANSIGN_S		0
+#define _FP_NANSIGN_D		0
+#define _FP_NANSIGN_Q		0
+
+#define _FP_KEEPNANFRACP 1
+
+/* If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose X.
+ */
+/* For _Qp_* and _Q_*, this should prefer X, for
+ * CPU instruction emulation this should prefer Y.
+ * (see SPAMv9 B.2.2 section).
+ */
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP)			\
+  do {								\
+    if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)		\
+	&& !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs))	\
+      {								\
+	R##_s = X##_s;						\
+	_FP_FRAC_COPY_##wc(R,X);				\
+      }								\
+    else							\
+      {								\
+	R##_s = Y##_s;						\
+	_FP_FRAC_COPY_##wc(R,Y);				\
+      }								\
+    R##_c = FP_CLS_NAN;						\
+  } while (0)
+
+/* Obtain the current rounding mode. */
+#ifndef FP_ROUNDMODE
+#define FP_ROUNDMODE	((current->thread.xfsr[0] >> 30) & 0x3)
+#endif
+
+/* Exception flags. */
+#define FP_EX_INVALID		(1 << 4)
+#define FP_EX_OVERFLOW		(1 << 3)
+#define FP_EX_UNDERFLOW		(1 << 2)
+#define FP_EX_DIVZERO		(1 << 1)
+#define FP_EX_INEXACT		(1 << 0)
+
+#define FP_HANDLE_EXCEPTIONS return _fex
+
+#define FP_INHIBIT_RESULTS ((current->thread.xfsr[0] >> 23) & _fex)
+
+#endif
diff -u --recursive --new-file v2.3.29/linux/include/linux/acpi.h linux/include/linux/acpi.h
--- v2.3.29/linux/include/linux/acpi.h	Tue Nov 23 22:42:21 1999
+++ linux/include/linux/acpi.h	Mon Dec  6 17:24:05 1999
@@ -23,36 +23,39 @@
 
 #include <linux/types.h>
 #include <linux/ioctl.h>
-
 #ifdef __KERNEL__
-
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
+#endif /* __KERNEL__ */
 
 /*
- * Device types
+ * System sleep states
  */
 enum
 {
-	ACPI_SYS_DEV,	/* system device (fan, KB controller, ...) */
-	ACPI_PCI_DEV,	/* generic PCI device */
-	ACPI_PCI_BUS,	/* PCI bus */
-	ACPI_ISA_DEV,	/* generic ISA device */
-	ACPI_ISA_BUS,	/* ISA bus */
-	ACPI_USB_DEV,	/* generic USB device */
-	ACPI_USB_HUB,	/* USB hub device */
-	ACPI_USB_CTRL,	/* USB controller */
-	ACPI_SCSI_DEV,	/* generic SCSI device */
-	ACPI_SCSI_CTRL, /* SCSI controller */
+	ACPI_S0, /* working */
+	ACPI_S1, /* sleep */
+	ACPI_S2, /* sleep */
+	ACPI_S3, /* sleep */
+	ACPI_S4, /* non-volatile sleep */
+	ACPI_S5, /* soft-off */
 };
 
-typedef int acpi_dev_t;
+typedef int acpi_sstate_t;
 
 /*
- * Device addresses
+ * Device states
  */
-#define ACPI_PCI_ADR(dev) ((dev)->bus->number << 16 | (dev)->devfn)
+enum
+{
+	ACPI_D0, /* fully-on */
+	ACPI_D1, /* partial-on */
+	ACPI_D2, /* partial-on */
+	ACPI_D3, /* fully-off */
+};
+
+typedef int acpi_dstate_t;
 
 /*
  * HID (PnP) values
@@ -71,33 +74,31 @@
 
 typedef int acpi_hid_t;
 
+#ifdef __KERNEL__
+
 /*
- * Device states
+ * Device types
  */
 enum
 {
-	ACPI_D0, /* fully-on */
-	ACPI_D1, /* partial-on */
-	ACPI_D2, /* partial-on */
-	ACPI_D3, /* fully-off */
+	ACPI_SYS_DEV,	/* system device (fan, KB controller, ...) */
+	ACPI_PCI_DEV,	/* generic PCI device */
+	ACPI_PCI_BUS,	/* PCI bus */
+	ACPI_ISA_DEV,	/* generic ISA device */
+	ACPI_ISA_BUS,	/* ISA bus */
+	ACPI_USB_DEV,	/* generic USB device */
+	ACPI_USB_HUB,	/* USB hub device */
+	ACPI_USB_CTRL,	/* USB controller */
+	ACPI_SCSI_DEV,	/* generic SCSI device */
+	ACPI_SCSI_CTRL, /* SCSI controller */
 };
 
-typedef int acpi_dstate_t;
+typedef int acpi_dev_t;
 
 /*
- * System sleep states
+ * Device addresses
  */
-enum
-{
-	ACPI_S0, /* working */
-	ACPI_S1, /* sleep */
-	ACPI_S2, /* sleep */
-	ACPI_S3, /* sleep */
-	ACPI_S4, /* non-volatile sleep */
-	ACPI_S5, /* soft-off */
-};
-
-typedef int acpi_sstate_t;
+#define ACPI_PCI_ADR(dev) ((dev)->bus->number << 16 | (dev)->devfn)
 
 struct acpi_dev;
 
@@ -136,7 +137,7 @@
 
 #ifdef CONFIG_ACPI
 
-extern wait_queue_head_t acpi_idle_wait;
+extern wait_queue_head_t acpi_control_wait;
 
 /*
  * Register a device with the ACPI subsystem
@@ -168,8 +169,8 @@
 {
 	if (dev) {
 		dev->idle = jiffies;
-		if (waitqueue_active(&acpi_idle_wait))
-			wake_up(&acpi_idle_wait);
+		if (waitqueue_active(&acpi_control_wait))
+			wake_up(&acpi_control_wait);
 	}
 }
 
@@ -361,7 +362,10 @@
 	ACPI_P_BLK,
 	ACPI_P_LVL2_LAT,
 	ACPI_P_LVL3_LAT,
+	ACPI_S0_SLP_TYP,
+	ACPI_S1_SLP_TYP,
 	ACPI_S5_SLP_TYP,
+	ACPI_SLEEP,
 };
 
 #define ACPI_SLP_TYP_DISABLED	(~0UL)
diff -u --recursive --new-file v2.3.29/linux/include/linux/bootmem.h linux/include/linux/bootmem.h
--- v2.3.29/linux/include/linux/bootmem.h	Tue Nov 23 22:42:21 1999
+++ linux/include/linux/bootmem.h	Mon Dec  6 17:23:20 1999
@@ -1,9 +1,12 @@
+/*
+ * Discontiguous memory support, Kanoj Sarcar, SGI, Nov 1999
+ */
 #ifndef _LINUX_BOOTMEM_H
 #define _LINUX_BOOTMEM_H
 
 #include <asm/pgtable.h>
 #include <asm/dma.h>
-#include <asm/cache.h>
+#include <linux/cache.h>
 #include <linux/init.h>
 
 /*
@@ -12,17 +15,44 @@
 
 extern unsigned long max_low_pfn;
 
+/*
+ * node_bootmem_map is a map pointer - the bits represent all physical 
+ * memory pages (including holes) on the node.
+ */
+typedef struct bootmem_data {
+	unsigned long node_boot_start;
+	unsigned long node_low_pfn;
+	void *node_bootmem_map;
+	unsigned long last_offset;
+	unsigned long last_pos;
+} bootmem_data_t;
+
+extern unsigned long __init bootmem_bootmap_pages (unsigned long);
 extern unsigned long __init init_bootmem (unsigned long addr, unsigned long memend);
 extern void __init reserve_bootmem (unsigned long addr, unsigned long size);
 extern void __init free_bootmem (unsigned long addr, unsigned long size);
 extern void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal);
 #define alloc_bootmem(x) \
 	__alloc_bootmem((x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
+#define alloc_bootmem_low(x) \
+	__alloc_bootmem((x), SMP_CACHE_BYTES, 0)
 #define alloc_bootmem_pages(x) \
 	__alloc_bootmem((x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
 #define alloc_bootmem_low_pages(x) \
 	__alloc_bootmem((x), PAGE_SIZE, 0)
 extern unsigned long __init free_all_bootmem (void);
+
+extern unsigned long __init init_bootmem_node (int nid, unsigned long freepfn, unsigned long startpfn, unsigned long endpfn);
+extern void __init reserve_bootmem_node (int nid, unsigned long physaddr, unsigned long size);
+extern void __init free_bootmem_node (int nid, unsigned long addr, unsigned long size);
+extern unsigned long __init free_all_bootmem_node (int nid);
+extern void * __init __alloc_bootmem_node (int nid, unsigned long size, unsigned long align, unsigned long goal);
+#define alloc_bootmem_node(nid, x) \
+	__alloc_bootmem_node((nid), (x), SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
+#define alloc_bootmem_pages_node(nid, x) \
+	__alloc_bootmem_node((nid), (x), PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
+#define alloc_bootmem_low_pages_node(nid, x) \
+	__alloc_bootmem_node((nid), (x), PAGE_SIZE, 0)
 
 #endif /* _LINUX_BOOTMEM_H */
 
diff -u --recursive --new-file v2.3.29/linux/include/linux/cache.h linux/include/linux/cache.h
--- v2.3.29/linux/include/linux/cache.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/cache.h	Mon Dec  6 17:15:53 1999
@@ -0,0 +1,28 @@
+#ifndef __LINUX_CACHE_H
+#define __LINUX_CACHE_H
+
+#include <asm/cache.h>
+
+#ifndef L1_CACHE_ALIGN
+#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))
+#endif
+
+#ifndef SMP_CACHE_BYTES
+#define SMP_CACHE_BYTES L1_CACHE_BYTES
+#endif
+
+#ifndef ____cacheline_aligned
+#define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
+#endif
+
+#ifndef __cacheline_aligned
+#ifdef MODULE
+#define __cacheline_aligned ____cacheline_aligned
+#else
+#define __cacheline_aligned					\
+  __attribute__((__aligned__(SMP_CACHE_BYTES),			\
+		 __section__(".data.cacheline_aligned")))
+#endif
+#endif /* __cacheline_aligned */
+
+#endif /* __LINUX_CACHE_H */
diff -u --recursive --new-file v2.3.29/linux/include/linux/cdrom.h linux/include/linux/cdrom.h
--- v2.3.29/linux/include/linux/cdrom.h	Sun Nov  7 16:37:34 1999
+++ linux/include/linux/cdrom.h	Thu Dec  2 19:39:36 1999
@@ -584,6 +584,8 @@
 #define DVD_LU_SEND_TITLE_KEY	7
 #define DVD_LU_SEND_ASF		8
 #define DVD_INVALIDATE_AGID	9
+#define DVD_LU_SEND_RPC_STATE	10
+#define DVD_HOST_SEND_RPC_STATE	11
 
 /* State data */
 typedef __u8 dvd_key[5];		/* 40-bit value, MSB is first elem. */
@@ -643,6 +645,18 @@
 	unsigned asf		: 1;
 };
 
+struct dvd_host_send_rpcstate {
+	__u8 pdrc;
+};
+
+struct dvd_lu_send_rpcstate {
+	__u8 type		: 2;
+	__u8 vra		: 3;
+	__u8 ucca		: 3;
+	__u8 region_mask;
+	__u8 rpc_scheme;
+};
+
 typedef union {
 	__u8 type;
 
@@ -653,6 +667,8 @@
 	struct dvd_send_key		hsk;
 	struct dvd_lu_send_title_key	lstk;
 	struct dvd_lu_send_asf		lsasf;
+	struct dvd_host_send_rpcstate	hrpcs;
+	struct dvd_lu_send_rpcstate	lrpcs;
 } dvd_authinfo;
 
 #ifdef __KERNEL__
diff -u --recursive --new-file v2.3.29/linux/include/linux/fb.h linux/include/linux/fb.h
--- v2.3.29/linux/include/linux/fb.h	Tue Nov 23 22:42:21 1999
+++ linux/include/linux/fb.h	Sat Nov 27 19:38:13 1999
@@ -255,61 +255,6 @@
     int (*fb_rasterimg)(struct fb_info *info, int start);
 };
 
-
-   /*
-    *    This is the interface between the low-level console driver and the
-    *    low-level frame buffer device
-    */
-
-struct display {
-    /* Filled in by the frame buffer device */
-
-    struct fb_var_screeninfo var;   /* variable infos. yoffset and vmode */
-				    /* are updated by fbcon.c */
-    struct fb_cmap cmap;            /* colormap */
-    char *screen_base;              /* pointer to top of virtual screen */    
-				    /* (virtual address) */
-    int visual;
-    int type;                       /* see FB_TYPE_* */
-    int type_aux;                   /* Interleave for interleaved Planes */
-    u_short ypanstep;               /* zero if no hardware ypan */
-    u_short ywrapstep;              /* zero if no hardware ywrap */
-    u_long line_length;             /* length of a line in bytes */
-    u_short can_soft_blank;         /* zero if no hardware blanking */
-    u_short inverse;                /* != 0 text black on white as default */
-    struct display_switch *dispsw;  /* low level operations */
-    void *dispsw_data;		    /* optional dispsw helper data */
-
-#if 0
-    struct fb_fix_cursorinfo fcrsr;
-    struct fb_var_cursorinfo *vcrsr;
-    struct fb_cursorstate crsrstate;
-#endif
-
-    /* Filled in by the low-level console driver */
-
-    struct vc_data *conp;           /* pointer to console data */
-    struct fb_info *fb_info;        /* frame buffer for this console */
-    int vrows;                      /* number of virtual rows */
-    unsigned short cursor_x;	    /* current cursor position */
-    unsigned short cursor_y;
-    int fgcol;                      /* text colors */
-    int bgcol;
-    u_long next_line;               /* offset to one line below */
-    u_long next_plane;              /* offset to next plane */
-    u_char *fontdata;               /* Font associated to this display */
-    unsigned short _fontheightlog;
-    unsigned short _fontwidthlog;
-    unsigned short _fontheight;
-    unsigned short _fontwidth;
-    int userfont;                   /* != 0 if fontdata kmalloc()ed */
-    u_short scrollmode;             /* Scroll Method */
-    short yscroll;                  /* Hardware scrolling */
-    unsigned char fgshift, bgshift;
-    unsigned short charmask;	    /* 0xff or 0x1ff */
-};
-
-
 struct fb_info {
    char modename[40];			/* default video mode */
    kdev_t node;
@@ -415,15 +360,11 @@
 
 extern int num_registered_fb;
 extern struct fb_info *registered_fb[FB_MAX];
-extern char con2fb_map[MAX_NR_CONSOLES];
 
 /* drivers/video/fbmon.c */
 extern int fbmon_valid_timings(u_int pixclock, u_int htotal, u_int vtotal,
 			       const struct fb_info *fb_info);
 extern int fbmon_dpms(const struct fb_info *fb_info);
-
-/* drivers/video/fbcon.c */
-extern struct display fb_display[MAX_NR_CONSOLES];
 
 /* drivers/video/fbcmap.c */
 extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
diff -u --recursive --new-file v2.3.29/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.3.29/linux/include/linux/fs.h	Tue Nov 23 22:42:21 1999
+++ linux/include/linux/fs.h	Mon Dec  6 17:22:09 1999
@@ -18,10 +18,10 @@
 #include <linux/list.h>
 #include <linux/dcache.h>
 #include <linux/stat.h>
+#include <linux/cache.h>
 
 #include <asm/atomic.h>
 #include <asm/bitops.h>
-#include <asm/cache.h>
 
 struct poll_table_struct;
 
@@ -637,7 +637,7 @@
 	/*
 	 * the order of these functions within the VFS template has been
 	 * changed because SMP locking has changed: from now on all get_block,
-	 * readpage, writepage and flushpage functions are supposed to do
+	 * readpage and writepage functions are supposed to do
 	 * whatever locking they need to get proper SMP operation - for
 	 * now in most cases this means a lock/unlock_kernel at entry/exit.
 	 * [The new order is also slightly more logical :)]
@@ -649,13 +649,11 @@
 	 */
 	int (*get_block) (struct inode *, long, struct buffer_head *, int);
 
-	int (*readpage) (struct file *, struct page *);
-	int (*writepage) (struct file *, struct page *);
-	int (*flushpage) (struct inode *, struct page *, unsigned long);
+	int (*readpage) (struct dentry *, struct page *);
+	int (*writepage) (struct dentry *, struct page *);
 
 	void (*truncate) (struct inode *);
 	int (*permission) (struct inode *, int);
-	int (*smap) (struct inode *,int);
 	int (*revalidate) (struct dentry *);
 };
 
@@ -676,11 +674,11 @@
 struct dquot_operations {
 	void (*initialize) (struct inode *, short);
 	void (*drop) (struct inode *);
-	int (*alloc_block) (const struct inode *, unsigned long, uid_t, char);
-	int (*alloc_inode) (const struct inode *, unsigned long, uid_t);
+	int (*alloc_block) (const struct inode *, unsigned long, char);
+	int (*alloc_inode) (const struct inode *, unsigned long);
 	void (*free_block) (const struct inode *, unsigned long);
 	void (*free_inode) (const struct inode *, unsigned long);
-	int (*transfer) (struct dentry *, struct iattr *, uid_t);
+	int (*transfer) (struct dentry *, struct iattr *);
 };
 
 struct file_system_type {
@@ -733,7 +731,7 @@
 asmlinkage long sys_open(const char *, int, int);
 asmlinkage long sys_close(unsigned int);	/* yes, it's really unsigned */
 extern int do_close(unsigned int, int);		/* yes, it's really unsigned */
-extern int do_truncate(struct dentry *, unsigned long);
+extern int do_truncate(struct dentry *, loff_t start);
 extern int get_unused_fd(void);
 extern void put_unused_fd(unsigned int);
 
@@ -944,18 +942,17 @@
 typedef int (*writepage_t)(struct file *, struct page *, unsigned long, unsigned long, const char *);
 
 /* Generic buffer handling for block filesystems.. */
-extern int block_read_full_page(struct file *, struct page *);
-extern int block_write_full_page (struct file *, struct page *);
+extern int block_read_full_page(struct dentry *, struct page *);
+extern int block_write_full_page (struct dentry *, struct page *);
 extern int block_write_partial_page (struct file *, struct page *, unsigned long, unsigned long, const char *);
 extern int block_write_cont_page (struct file *, struct page *, unsigned long, unsigned long, const char *);
-extern int block_flushpage(struct inode *, struct page *, unsigned long);
+extern int block_flushpage(struct page *, unsigned long);
 
 extern int generic_file_mmap(struct file *, struct vm_area_struct *);
 extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *);
 extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *, writepage_t);
 extern void do_generic_file_read(struct file * filp, loff_t *ppos, read_descriptor_t * desc, read_actor_t actor);
 
-
 extern struct super_block *get_super(kdev_t);
 struct super_block *get_empty_super(void);
 void remove_vfsmnt(kdev_t dev);
@@ -981,7 +978,7 @@
 
 extern int block_fsync(struct file *, struct dentry *);
 extern int file_fsync(struct file *, struct dentry *);
-extern int generic_buffer_fdatasync(struct inode *inode, unsigned long start, unsigned long end);
+extern int generic_buffer_fdatasync(struct inode *inode, unsigned long start_idx, unsigned long end_idx);
 
 extern int inode_change_ok(struct inode *, struct iattr *);
 extern void inode_setattr(struct inode *, struct iattr *);
diff -u --recursive --new-file v2.3.29/linux/include/linux/highmem.h linux/include/linux/highmem.h
--- v2.3.29/linux/include/linux/highmem.h	Tue Nov 23 22:42:21 1999
+++ linux/include/linux/highmem.h	Mon Dec  6 17:22:09 1999
@@ -23,7 +23,7 @@
 extern inline unsigned int nr_free_highpages(void) { return 0; }
 #define prepare_highmem_swapout(page) page
 #define replace_with_highmem(page) page
-#define kmap(page) __page_address(page)
+#define kmap(page) page_address(page)
 #define kunmap(page) do { } while (0)
 
 #endif /* CONFIG_HIGHMEM */
diff -u --recursive --new-file v2.3.29/linux/include/linux/ioport.h linux/include/linux/ioport.h
--- v2.3.29/linux/include/linux/ioport.h	Tue Nov 23 22:42:21 1999
+++ linux/include/linux/ioport.h	Sat Nov 27 15:27:49 1999
@@ -80,11 +80,12 @@
 
 extern int request_resource(struct resource *root, struct resource *new);
 extern int release_resource(struct resource *new);
-struct pci_dev;
 extern int allocate_resource(struct resource *root, struct resource *new,
 			     unsigned long size,
 			     unsigned long min, unsigned long max,
-			     unsigned long align, struct pci_dev *);
+			     unsigned long align,
+			     void (*alignf)(void *, struct resource *, unsigned long),
+			     void *alignf_data);
 
 /* Convenience shorthand with allocation */
 #define request_region(start,n,name)	__request_region(&ioport_resource, (start), (n), (name))
@@ -107,8 +108,5 @@
 #define HAVE_AUTOIRQ
 extern void autoirq_setup(int waittime);
 extern int autoirq_report(int waittime);
-
-extern unsigned long resource_fixup(struct pci_dev *, struct resource *,
-				    unsigned long, unsigned long);
 
 #endif	/* _LINUX_IOPORT_H */
diff -u --recursive --new-file v2.3.29/linux/include/linux/ipc.h linux/include/linux/ipc.h
--- v2.3.29/linux/include/linux/ipc.h	Thu Nov 11 20:11:53 1999
+++ linux/include/linux/ipc.h	Sat Nov 27 15:27:49 1999
@@ -38,10 +38,6 @@
 
 #ifdef __KERNEL__
 
-/* special shmsegs[id]  values */
-#define IPC_UNUSED	((void *) -1)
-#define IPC_NOID	((void *) -2)		/* being allocated/destroyed */
-
 #define IPCMNI 32768  /* <= MAX_INT limit for ipc arrays (including sysctl changes) */
 
 #endif /* __KERNEL__ */
diff -u --recursive --new-file v2.3.29/linux/include/linux/irq.h linux/include/linux/irq.h
--- v2.3.29/linux/include/linux/irq.h	Wed Aug 18 16:45:11 1999
+++ linux/include/linux/irq.h	Mon Dec  6 17:24:07 1999
@@ -42,7 +42,7 @@
 					   independent code */
 	struct irqaction *action;		/* IRQ action list */
 	unsigned int depth;			/* Disable depth for nested irq disables */
-} irq_desc_t;
+} ____cacheline_aligned irq_desc_t;
 
 #include <asm/hw_irq.h> /* the arch dependent stuff */
 
@@ -51,27 +51,6 @@
 extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
 extern spinlock_t irq_controller_lock;
 extern int setup_irq(unsigned int , struct irqaction * );
-
-#ifdef __SMP__
-
-#include <asm/atomic.h>
-
-static inline void irq_enter(int cpu, unsigned int irq)
-{
-	hardirq_enter(cpu);
-	while (test_bit(0,&global_irq_lock)) {
-		/* nothing */;
-	}
-}
-
-static inline void irq_exit(int cpu, unsigned int irq)
-{
-	hardirq_exit(cpu);
-}
-#else
-#define irq_enter(cpu, irq)	(++local_irq_count[cpu])
-#define irq_exit(cpu, irq)	(--local_irq_count[cpu])
-#endif
 
 extern hw_irq_controller no_irq_type;  /* needed in every arch ? */
 
diff -u --recursive --new-file v2.3.29/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.3.29/linux/include/linux/mm.h	Tue Nov 23 22:42:21 1999
+++ linux/include/linux/mm.h	Mon Dec  6 17:22:13 1999
@@ -9,6 +9,7 @@
 #include <linux/config.h>
 #include <linux/string.h>
 #include <linux/list.h>
+#include <linux/mmzone.h>
 
 extern unsigned long max_mapnr;
 extern unsigned long num_physpages;
@@ -119,8 +120,6 @@
 	unsigned long val;
 } swp_entry_t;
 
-struct zone_struct;
-
 /*
  * Try to keep the most commonly accessed fields in single cache lines
  * here (16 bytes or greater).  This ordering should be particularly
@@ -286,94 +285,30 @@
 extern mem_map_t * mem_map;
 
 /*
- * Free memory management - zoned buddy allocator.
- */
-
-#if CONFIG_AP1000
-/* the AP+ needs to allocate 8MB contiguous, aligned chunks of ram
-   for the ring buffers */
-#define MAX_ORDER 12
-#else
-#define MAX_ORDER 10
-#endif
-
-typedef struct free_area_struct {
-	struct list_head free_list;
-	unsigned int * map;
-} free_area_t;
-
-typedef struct zone_struct {
-	/*
-	 * Commonly accessed fields:
-	 */
-	spinlock_t lock;
-	unsigned long offset;
-	unsigned long free_pages;
-	int low_on_memory;
-	unsigned long pages_low, pages_high;
-
-	/*
-	 * free areas of different sizes
-	 */
-	free_area_t free_area[MAX_ORDER];
-
-	/*
-	 * rarely used fields:
-	 */
-	char * name;
-	unsigned long size;
-} zone_t;
-
-#define ZONE_DMA		0
-#define ZONE_NORMAL		1
-#define ZONE_HIGHMEM		2
-
-/*
- * NUMA architectures will have more:
- */
-#define MAX_NR_ZONES		3
-
-/*
- * One allocation request operates on a zonelist. A zonelist
- * is a list of zones, the first one is the 'goal' of the
- * allocation, the other zones are fallback zones, in decreasing
- * priority. On NUMA we want to fall back on other CPU's zones
- * as well.
- *
- * Right now a zonelist takes up less than a cacheline. We never
- * modify it apart from boot-up, and only a few indices are used,
- * so despite the zonelist table being relatively big, the cache
- * footprint of this construct is very small.
- */
-typedef struct zonelist_struct {
-	zone_t * zones [MAX_NR_ZONES+1]; // NULL delimited
-	int gfp_mask;
-} zonelist_t;
-
-#define NR_GFPINDEX		0x100
-
-extern zonelist_t zonelists [NR_GFPINDEX];
-
-/*
  * There is only one page-allocator function, and two main namespaces to
  * it. The alloc_page*() variants return 'struct page *' and as such
  * can allocate highmem pages, the *get*page*() variants return
  * virtual kernel addresses to the allocated page(s).
  */
 extern struct page * FASTCALL(__alloc_pages(zonelist_t *zonelist, unsigned long order));
+extern struct page * alloc_pages_node(int nid, int gfp_mask, unsigned long order);
 
+#ifndef CONFIG_DISCONTIGMEM
 extern inline struct page * alloc_pages(int gfp_mask, unsigned long order)
 {
 	/*  temporary check. */
-	if (zonelists[gfp_mask].gfp_mask != (gfp_mask))
+	if (contig_page_data.node_zonelists[gfp_mask].gfp_mask != (gfp_mask))
 		BUG();
 	/*
 	 * Gets optimized away by the compiler.
 	 */
 	if (order >= MAX_ORDER)
 		return NULL;
-	return __alloc_pages(zonelists+(gfp_mask), order);
+	return __alloc_pages(contig_page_data.node_zonelists+(gfp_mask), order);
 }
+#else /* !CONFIG_DISCONTIGMEM */
+extern struct page * alloc_pages(int gfp_mask, unsigned long order);
+#endif /* !CONFIG_DISCONTIGMEM */
 
 #define alloc_page(gfp_mask) \
 		alloc_pages(gfp_mask, 0)
@@ -385,7 +320,7 @@
 	page = alloc_pages(gfp_mask, order);
 	if (!page)
 		return 0;
-	return __page_address(page);
+	return page_address(page);
 }
 
 #define __get_free_page(gfp_mask) \
@@ -425,8 +360,12 @@
 
 extern inline void free_pages(unsigned long addr, unsigned long order)
 {
-	unsigned long map_nr = MAP_NR(addr);
+	unsigned long map_nr;
 
+#ifdef CONFIG_DISCONTIGMEM
+	if (addr == 0) return;
+#endif
+	map_nr = MAP_NR(addr);
 	if (map_nr < max_mapnr)
 		__free_pages(mem_map + map_nr, order);
 }
@@ -434,6 +373,7 @@
 #define free_page(addr) free_pages((addr),0)
 
 extern void show_free_areas(void);
+extern void show_free_areas_node(int nid);
 extern struct page * put_dirty_page(struct task_struct * tsk, struct page *page,
 	unsigned long address);
 
@@ -444,7 +384,7 @@
 extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size, pgprot_t prot);
 extern int zeromap_page_range(unsigned long from, unsigned long size, pgprot_t prot);
 
-extern void vmtruncate(struct inode * inode, unsigned long offset);
+extern void vmtruncate(struct inode * inode, loff_t offset);
 extern int handle_mm_fault(struct task_struct *tsk,struct vm_area_struct *vma, unsigned long address, int write_access);
 extern int make_pages_present(unsigned long addr, unsigned long end);
 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
@@ -456,6 +396,8 @@
 
 extern void paging_init(void);
 extern void free_area_init(unsigned int * zones_size);
+extern void free_area_init_node(int nid, pg_data_t *pgdat, 
+		unsigned int * zones_size, unsigned long zone_start_paddr);
 extern void mem_init(void);
 extern void show_mem(void);
 extern void oom(struct task_struct * tsk);
@@ -470,8 +412,23 @@
 extern void exit_mmap(struct mm_struct *);
 extern unsigned long get_unmapped_area(unsigned long, unsigned long);
 
-extern unsigned long do_mmap(struct file *, unsigned long, unsigned long,
-	unsigned long, unsigned long, unsigned long);
+extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
+	unsigned long len, unsigned long prot,
+	unsigned long flag, unsigned long pgoff);
+
+extern inline unsigned long do_mmap(struct file *file, unsigned long addr,
+	unsigned long len, unsigned long prot,
+	unsigned long flag, unsigned long offset)
+{
+	unsigned long ret = -EINVAL;
+	if ((offset + PAGE_ALIGN(len)) < offset)
+		goto out;
+	if (!(offset & ~PAGE_MASK))
+		ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
+out:
+	return ret;
+}
+
 extern int do_munmap(unsigned long, size_t);
 extern unsigned long do_brk(unsigned long, unsigned long);
 
@@ -479,8 +436,7 @@
 extern void remove_inode_page(struct page *);
 extern unsigned long page_unuse(struct page *);
 extern int shrink_mmap(int, int);
-extern void truncate_inode_pages(struct inode *, unsigned long);
-extern void put_cached_page(unsigned long);
+extern void truncate_inode_pages(struct inode *, loff_t);
 
 /*
  * GFP bitmasks..
diff -u --recursive --new-file v2.3.29/linux/include/linux/mmzone.h linux/include/linux/mmzone.h
--- v2.3.29/linux/include/linux/mmzone.h	Wed Dec 31 16:00:00 1969
+++ linux/include/linux/mmzone.h	Mon Dec  6 17:22:07 1999
@@ -0,0 +1,115 @@
+#ifndef _LINUX_MMZONE_H
+#define _LINUX_MMZONE_H
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+
+#include <linux/config.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+
+/*
+ * Free memory management - zoned buddy allocator.
+ */
+
+#if CONFIG_AP1000
+/* the AP+ needs to allocate 8MB contiguous, aligned chunks of ram
+   for the ring buffers */
+#define MAX_ORDER 12
+#else
+#define MAX_ORDER 10
+#endif
+
+typedef struct free_area_struct {
+	struct list_head free_list;
+	unsigned int * map;
+} free_area_t;
+
+typedef struct zone_struct {
+	/*
+	 * Commonly accessed fields:
+	 */
+	spinlock_t lock;
+	unsigned long offset;
+	unsigned long free_pages;
+	int low_on_memory;
+	unsigned long pages_low, pages_high;
+
+	/*
+	 * free areas of different sizes
+	 */
+	free_area_t free_area[MAX_ORDER];
+
+	/*
+	 * rarely used fields:
+	 */
+	char * name;
+	unsigned long size;
+} zone_t;
+
+#define ZONE_DMA		0
+#define ZONE_NORMAL		1
+#define ZONE_HIGHMEM		2
+#define MAX_NR_ZONES		3
+
+/*
+ * One allocation request operates on a zonelist. A zonelist
+ * is a list of zones, the first one is the 'goal' of the
+ * allocation, the other zones are fallback zones, in decreasing
+ * priority.
+ *
+ * Right now a zonelist takes up less than a cacheline. We never
+ * modify it apart from boot-up, and only a few indices are used,
+ * so despite the zonelist table being relatively big, the cache
+ * footprint of this construct is very small.
+ */
+typedef struct zonelist_struct {
+	zone_t * zones [MAX_NR_ZONES+1]; // NULL delimited
+	int gfp_mask;
+} zonelist_t;
+
+#define NR_GFPINDEX		0x100
+
+struct bootmem_data;
+typedef struct pglist_data {
+	zone_t node_zones[MAX_NR_ZONES];
+	zonelist_t node_zonelists[NR_GFPINDEX];
+	struct page *node_mem_map;
+	unsigned long *valid_addr_bitmap;
+	struct bootmem_data *bdata;
+} pg_data_t;
+
+extern int numnodes;
+
+#ifndef CONFIG_DISCONTIGMEM
+
+extern pg_data_t contig_page_data;
+
+#define NODE_DATA(nid)		(&contig_page_data)
+#define NODE_MEM_MAP(nid)	mem_map
+
+#else /* !CONFIG_DISCONTIGMEM */
+
+#include <asm/mmzone.h>
+
+#endif /* !CONFIG_DISCONTIGMEM */
+
+#define MAP_ALIGN(x)	((((x) % sizeof(mem_map_t)) == 0) ? (x) : ((x) + \
+		sizeof(mem_map_t) - ((x) % sizeof(mem_map_t))))
+
+#ifdef CONFIG_DISCONTIGMEM
+
+#define LOCAL_MAP_NR(kvaddr) \
+	(((unsigned long)(kvaddr)-LOCAL_BASE_ADDR((kvaddr))) >> PAGE_SHIFT)
+#define MAP_NR(kaddr)	(LOCAL_MAP_NR((kaddr)) + \
+		(((unsigned long)ADDR_TO_MAPBASE((kaddr)) - PAGE_OFFSET) / \
+		sizeof(mem_map_t)))
+#define kern_addr_valid(addr)	((KVADDR_TO_NID((unsigned long)addr) >= \
+	numnodes) ? 0 : (test_bit(LOCAL_MAP_NR((addr)), \
+	NODE_DATA(KVADDR_TO_NID((unsigned long)addr))->valid_addr_bitmap)))
+
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif /* !__ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* _LINUX_MMZONE_H */
diff -u --recursive --new-file v2.3.29/linux/include/linux/msg.h linux/include/linux/msg.h
--- v2.3.29/linux/include/linux/msg.h	Thu Nov 11 20:11:53 1999
+++ linux/include/linux/msg.h	Sat Nov 27 15:27:49 1999
@@ -45,7 +45,7 @@
 	unsigned short  msgseg; 
 };
 
-#define MSGMNI   128   /* <= IPCMNI */     /* max # of msg queue identifiers */
+#define MSGMNI    16   /* <= IPCMNI */     /* max # of msg queue identifiers */
 #define MSGMAX  8192   /* <= INT_MAX */   /* max size of message (bytes) */
 #define MSGMNB 16384   /* <= INT_MAX */   /* default max size of a message queue */
 
diff -u --recursive --new-file v2.3.29/linux/include/linux/nfs_fs.h linux/include/linux/nfs_fs.h
--- v2.3.29/linux/include/linux/nfs_fs.h	Fri Oct 22 13:21:55 1999
+++ linux/include/linux/nfs_fs.h	Mon Dec  6 17:22:35 1999
@@ -212,7 +212,7 @@
 /*
  * linux/fs/nfs/write.c
  */
-extern int  nfs_writepage(struct file *, struct page *);
+extern int  nfs_writepage(struct dentry *, struct page *);
 extern int  nfs_check_failed_request(struct inode *);
 
 /*
@@ -233,7 +233,7 @@
 /*
  * linux/fs/nfs/read.c
  */
-extern int  nfs_readpage(struct file *, struct page *);
+extern int  nfs_readpage(struct dentry *, struct page *);
 
 /*
  * linux/fs/mount_clnt.c
diff -u --recursive --new-file v2.3.29/linux/include/linux/ntfs_fs_sb.h linux/include/linux/ntfs_fs_sb.h
--- v2.3.29/linux/include/linux/ntfs_fs_sb.h	Fri Dec 19 15:24:22 1997
+++ linux/include/linux/ntfs_fs_sb.h	Fri Dec  3 10:55:09 1999
@@ -26,6 +26,7 @@
 	int clusterfactor;
 	int clustersize;
 	int mft_recordsize;
+	int mft_recordbits;
 	int mft_clusters_per_record;
 	int index_recordsize;
 	int index_clusters_per_record;
diff -u --recursive --new-file v2.3.29/linux/include/linux/pagemap.h linux/include/linux/pagemap.h
--- v2.3.29/linux/include/linux/pagemap.h	Tue Nov 23 22:42:21 1999
+++ linux/include/linux/pagemap.h	Mon Dec  6 17:22:15 1999
@@ -80,7 +80,6 @@
 extern void __add_page_to_hash_queue(struct page * page, struct page **p);
 
 extern void add_to_page_cache(struct page * page, struct address_space *mapping, unsigned long index);
-extern int add_to_page_cache_unique(struct page * page, struct address_space *mapping, unsigned long index, struct page **hash);
 
 extern inline void add_page_to_hash_queue(struct page * page, struct inode * inode, unsigned long index)
 {
@@ -118,4 +117,10 @@
 		___wait_on_page(page);
 }
 
+extern struct page * grab_cache_page (struct address_space *, unsigned long);
+
+typedef int filler_t(void *, struct page*);
+
+extern struct page *read_cache_page(struct address_space *, unsigned long,
+				filler_t *, void *);
 #endif
diff -u --recursive --new-file v2.3.29/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.3.29/linux/include/linux/pci.h	Tue Nov 23 22:42:21 1999
+++ linux/include/linux/pci.h	Mon Dec  6 17:22:08 1999
@@ -3,7 +3,7 @@
  *
  *	PCI defines and function prototypes
  *	Copyright 1994, Drew Eckhardt
- *	Copyright 1997--1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ *	Copyright 1997--1999 Martin Mares <mj@suse.cz>
  *
  *	For more information, please consult the following manuals (look at
  *	http://www.pcisig.com/ for how to get them):
@@ -417,6 +417,7 @@
 int pcibios_enable_device(struct pci_dev *);
 char *pcibios_setup (char *str);
 
+void pcibios_align_resource(void *, struct resource *, unsigned long);
 void pcibios_update_resource(struct pci_dev *, struct resource *,
 			     struct resource *, int);
 void pcibios_update_irq(struct pci_dev *, int irq);
diff -u --recursive --new-file v2.3.29/linux/include/linux/quota.h linux/include/linux/quota.h
--- v2.3.29/linux/include/linux/quota.h	Thu Nov 18 20:25:38 1999
+++ linux/include/linux/quota.h	Mon Dec  6 17:09:28 1999
@@ -44,8 +44,8 @@
 /*
  * Convert diskblocks to blocks and the other way around.
  */
-#define dbtob(num) (num << 10)
-#define btodb(num) (num >> 10)
+#define dbtob(num) (num << BLOCK_SIZE_BITS)
+#define btodb(num) (num >> BLOCK_SIZE_BITS)
 
 /*
  * Convert count of filesystem blocks to diskquota blocks, meant
diff -u --recursive --new-file v2.3.29/linux/include/linux/quotaops.h linux/include/linux/quotaops.h
--- v2.3.29/linux/include/linux/quotaops.h	Thu Nov 18 20:25:38 1999
+++ linux/include/linux/quotaops.h	Mon Dec  6 17:22:08 1999
@@ -23,16 +23,13 @@
 extern int  quota_off(kdev_t dev, short type);
 extern int  sync_dquots(kdev_t dev, short type);
 
-extern int  dquot_alloc_block(const struct inode *inode, unsigned long number,
-                              uid_t initiator, char warn);
-extern int  dquot_alloc_inode(const struct inode *inode, unsigned long number,
-                              uid_t initiator);
+extern int  dquot_alloc_block(const struct inode *inode, unsigned long number, char prealloc);
+extern int  dquot_alloc_inode(const struct inode *inode, unsigned long number);
 
 extern void dquot_free_block(const struct inode *inode, unsigned long number);
 extern void dquot_free_inode(const struct inode *inode, unsigned long number);
 
-extern int  dquot_transfer(struct dentry *dentry, struct iattr *iattr,
-                           uid_t initiator);
+extern int  dquot_transfer(struct dentry *dentry, struct iattr *iattr);
 
 /*
  * Operations supported for diskquotas.
@@ -54,8 +51,7 @@
 extern __inline__ int DQUOT_PREALLOC_BLOCK(struct super_block *sb, const struct inode *inode, int nr)
 {
 	if (sb->dq_op) {
-		if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize),
-					   current->fsuid, 0) == NO_QUOTA)
+		if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize), 1) == NO_QUOTA)
 			return 1;
 	}
 	return 0;
@@ -64,8 +60,7 @@
 extern __inline__ int DQUOT_ALLOC_BLOCK(struct super_block *sb, const struct inode *inode, int nr)
 {
 	if (sb->dq_op) {
-		if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize),
-					   current->fsuid, 1) == NO_QUOTA)
+		if (sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, sb->s_blocksize), 0) == NO_QUOTA)
 			return 1;
 	}
 	return 0;
@@ -75,7 +70,7 @@
 {
 	if (sb->dq_op) {
 		sb->dq_op->initialize (inode, -1);
-		if (sb->dq_op->alloc_inode (inode, 1, current->fsuid))
+		if (sb->dq_op->alloc_inode (inode, 1))
 			return 1;
 	}
 	inode->i_flags |= S_QUOTA;
@@ -100,7 +95,7 @@
 
 	if (dentry->d_inode->i_sb->dq_op) {
 		dentry->d_inode->i_sb->dq_op->initialize(dentry->d_inode, -1);
-		error = dentry->d_inode->i_sb->dq_op->transfer(dentry, iattr, current->fsuid);
+		error = dentry->d_inode->i_sb->dq_op->transfer(dentry, iattr);
 	} else {
 		error = notify_change(dentry, iattr);
 	}
diff -u --recursive --new-file v2.3.29/linux/include/linux/sched.h linux/include/linux/sched.h
--- v2.3.29/linux/include/linux/sched.h	Tue Nov 23 22:42:21 1999
+++ linux/include/linux/sched.h	Mon Dec  6 17:22:13 1999
@@ -84,20 +84,20 @@
 #define TASK_EXCLUSIVE		32
 
 #define __set_task_state(tsk, state_value)		\
-	do { tsk->state = state_value; } while (0)
+	do { (tsk)->state = (state_value); } while (0)
 #ifdef __SMP__
 #define set_task_state(tsk, state_value)		\
-	set_mb(tsk->state, state_value)
+	set_mb((tsk)->state, (state_value))
 #else
 #define set_task_state(tsk, state_value)		\
-	__set_task_state(tsk, state_value)
+	__set_task_state((tsk), (state_value))
 #endif
 
 #define __set_current_state(state_value)			\
-	do { current->state = state_value; } while (0)
+	do { current->state = (state_value); } while (0)
 #ifdef __SMP__
 #define set_current_state(state_value)		\
-	set_mb(current->state, state_value)
+	set_mb(current->state, (state_value))
 #else
 #define set_current_state(state_value)		\
 	__set_current_state(state_value)
@@ -513,6 +513,7 @@
 #define wake_up_interruptible_sync(x)	__wake_up_sync((x),TASK_INTERRUPTIBLE)
 
 extern int in_group_p(gid_t);
+extern int in_egroup_p(gid_t);
 
 extern void flush_signals(struct task_struct *);
 extern void flush_signal_handlers(struct task_struct *);
diff -u --recursive --new-file v2.3.29/linux/include/linux/slab.h linux/include/linux/slab.h
--- v2.3.29/linux/include/linux/slab.h	Fri Oct 22 13:21:55 1999
+++ linux/include/linux/slab.h	Mon Dec  6 17:22:13 1999
@@ -12,7 +12,7 @@
 typedef struct kmem_cache_s kmem_cache_t;
 
 #include	<linux/mm.h>
-#include	<asm/cache.h>
+#include	<linux/cache.h>
 
 /* flags for kmem_cache_alloc() */
 #define	SLAB_BUFFER		GFP_BUFFER
diff -u --recursive --new-file v2.3.29/linux/include/linux/swap.h linux/include/linux/swap.h
--- v2.3.29/linux/include/linux/swap.h	Thu Nov 11 20:11:53 1999
+++ linux/include/linux/swap.h	Mon Dec  6 17:22:07 1999
@@ -1,6 +1,7 @@
 #ifndef _LINUX_SWAP_H
 #define _LINUX_SWAP_H
 
+#include <linux/spinlock.h>
 #include <asm/page.h>
 
 #define SWAP_FLAG_PREFER	0x8000	/* set if swap priority specified */
@@ -48,6 +49,7 @@
 struct swap_info_struct {
 	unsigned int flags;
 	kdev_t swap_device;
+	spinlock_t sdev_lock;
 	struct dentry * swap_file;
 	unsigned short * swap_map;
 	unsigned int lowest_bit;
@@ -94,19 +96,17 @@
 /* linux/mm/swap_state.c */
 extern void show_swap_cache_info(void);
 extern void add_to_swap_cache(struct page *, swp_entry_t);
-extern int swap_duplicate(swp_entry_t);
 extern int swap_check_entry(unsigned long);
 extern struct page * lookup_swap_cache(swp_entry_t);
 extern struct page * read_swap_cache_async(swp_entry_t, int);
 #define read_swap_cache(entry) read_swap_cache_async(entry, 1);
-extern int swap_count(struct page *);
-extern swp_entry_t acquire_swap_entry(struct page *page);
 
 /*
  * Make these inline later once they are working properly.
  */
 extern void __delete_from_swap_cache(struct page *page);
 extern void delete_from_swap_cache(struct page *page);
+extern void delete_from_swap_cache_nolock(struct page *page);
 extern void free_page_and_swap_cache(struct page *page);
 
 /* linux/mm/swapfile.c */
@@ -115,6 +115,12 @@
 extern int is_swap_partition(kdev_t);
 extern void si_swapinfo(struct sysinfo *);
 extern swp_entry_t __get_swap_page(unsigned short);
+extern void get_swaphandle_info(swp_entry_t, unsigned long *, kdev_t *, 
+					struct inode **);
+extern int swap_duplicate(swp_entry_t);
+extern int swap_count(struct page *);
+extern swp_entry_t acquire_swap_entry(struct page *page);
+extern int valid_swaphandles(swp_entry_t, unsigned long *);
 #define get_swap_page() __get_swap_page(1)
 extern void __swap_free(swp_entry_t, unsigned short);
 #define swap_free(entry) __swap_free((entry), 1)
@@ -172,6 +178,13 @@
 	nr_lru_pages--;				\
 	spin_unlock(&pagemap_lru_lock);		\
 } while (0)
+
+extern spinlock_t swaplock;
+
+#define swap_list_lock()	spin_lock(&swaplock)
+#define swap_list_unlock()	spin_unlock(&swaplock)
+#define swap_device_lock(p)	spin_lock(&p->sdev_lock)
+#define swap_device_unlock(p)	spin_unlock(&p->sdev_lock)
 
 #endif /* __KERNEL__*/
 
diff -u --recursive --new-file v2.3.29/linux/include/linux/sysctl.h linux/include/linux/sysctl.h
--- v2.3.29/linux/include/linux/sysctl.h	Tue Nov 23 22:42:21 1999
+++ linux/include/linux/sysctl.h	Sat Nov 27 15:27:49 1999
@@ -97,7 +97,7 @@
 	KERN_RTSIGNR=32,	/* Number of rt sigs queued */
 	KERN_RTSIGMAX=33,	/* Max queuable */
 	
-	KERN_SHMMAX=34,         /* int: Maximum shared memory segment */
+	KERN_SHMMAX=34,         /* long: Maximum shared memory segment */
 	KERN_MSGMAX=35,         /* int: Maximum size of a messege */
 	KERN_MSGMNB=36,         /* int: Maximum message queue size */
 	KERN_MSGPOOL=37,        /* int: Maximum system message pool size */
@@ -106,8 +106,9 @@
  	KERN_RANDOM=40,		/* Random driver */
  	KERN_SHMALL=41,		/* int: Maximum size of shared memory */
  	KERN_MSGMNI=42,		/* int: msg queue identifiers */
- 	KERN_SEM=43,		/* int: sysv semaphore limits */
- 	KERN_SPARC_STOP_A=44	/* int: Sparc Stop-A enable */
+ 	KERN_SEM=43,		/* struct: sysv semaphore limits */
+ 	KERN_SPARC_STOP_A=44,	/* int: Sparc Stop-A enable */
+ 	KERN_SHMMNI=45		/* int: shm array identifiers */
 };
 
 
diff -u --recursive --new-file v2.3.29/linux/include/linux/videodev.h linux/include/linux/videodev.h
--- v2.3.29/linux/include/linux/videodev.h	Tue Nov 23 22:42:21 1999
+++ linux/include/linux/videodev.h	Sat Nov 27 15:27:49 1999
@@ -354,6 +354,8 @@
 #define VID_HARDWARE_TRUST	22	/* Trust FM Radio */
 #define VID_HARDWARE_TERRATEC	23	/* TerraTec ActiveRadio */
 #define VID_HARDWARE_CPIA	24
+#define VID_HARDWARE_ZR36120	25	/* Zoran ZR36120/ZR36125 */
+#define VID_HARDWARE_ZR36067	26	/* Zoran ZR36067/36060 */
 
 /*
  *	Initialiser list
diff -u --recursive --new-file v2.3.29/linux/include/linux/wireless.h linux/include/linux/wireless.h
--- v2.3.29/linux/include/linux/wireless.h	Thu Aug 26 13:05:41 1999
+++ linux/include/linux/wireless.h	Sat Nov 27 15:27:49 1999
@@ -1,7 +1,7 @@
 /*
  * This file define a set of standard wireless extensions
  *
- * Version :	8	28.7.99
+ * Version :	9	16.10.99
  *
  * Authors :	Jean Tourrilhes - HPL - <jt@hpl.hp.com>
  */
@@ -63,7 +63,7 @@
  * (there is some stuff that will be added in the future...)
  * I just plan to increment with each new version.
  */
-#define WIRELESS_EXT	8
+#define WIRELESS_EXT	9
 
 /*
  * Changes :
@@ -96,6 +96,14 @@
  *	- Changed my e-mail address
  *	- More 802.11 support (nickname, rate, rts, frag)
  *	- List index in frequencies
+ *
+ * V8 to V9
+ * --------
+ *	- Support for 'mode of operation' (ad-hoc, managed...)
+ *	- Support for unicast and multicast power saving
+ *	- Change encoding to support larger tokens (>64 bits)
+ *	- Updated iw_params (disable, flags) and use it for NWID
+ *	- Extracted iw_point from iwreq for clarity
  */
 
 /* -------------------------- IOCTL LIST -------------------------- */
@@ -103,12 +111,12 @@
 /* Basic operations */
 #define SIOCSIWNAME	0x8B00		/* Unused ??? */
 #define SIOCGIWNAME	0x8B01		/* get name */
-#define SIOCSIWNWID	0x8B02		/* set network id */
+#define SIOCSIWNWID	0x8B02		/* set network id (the cell) */
 #define SIOCGIWNWID	0x8B03		/* get network id */
 #define SIOCSIWFREQ	0x8B04		/* set channel/frequency */
 #define SIOCGIWFREQ	0x8B05		/* get channel/frequency */
-#define SIOCSIWENCODE	0x8B06		/* set encoding info */
-#define SIOCGIWENCODE	0x8B07		/* get encoding info */
+#define SIOCSIWMODE	0x8B06		/* set operation mode */
+#define SIOCGIWMODE	0x8B07		/* get operation mode */
 #define SIOCSIWSENS	0x8B08		/* set sensitivity */
 #define SIOCGIWSENS	0x8B09		/* get sensitivity */
 
@@ -146,11 +154,18 @@
 #define SIOCSIWFRAG	0x8B24		/* set fragmentation thr (bytes) */
 #define SIOCGIWFRAG	0x8B25		/* get fragmentation thr (bytes) */
 
+/* Encoding stuff (scrambling, hardware security, WEP...) */
+#define SIOCSIWENCODE	0x8B2A		/* set encoding token & mode */
+#define SIOCGIWENCODE	0x8B2B		/* get encoding token & mode */
+/* Power saving stuff (power management, unicast and multicast) */
+#define SIOCSIWPOWER	0x8B2C		/* set Power Management settings */
+#define SIOCGIWPOWER	0x8B2D		/* get Power Management settings */
+
 /* ------------------------- IOCTL STUFF ------------------------- */
 
 /* The first and the last (range) */
 #define SIOCIWFIRST	0x8B00
-#define SIOCIWLAST	0x8B25
+#define SIOCIWLAST	0x8B30
 
 /* Even : get (world access), odd : set (root access) */
 #define IW_IS_SET(cmd)	(!((cmd) & 0x1))
@@ -200,10 +215,67 @@
 /* Maximum size of the ESSID and NICKN strings */
 #define IW_ESSID_MAX_SIZE	32
 
+/* Modes of operation */
+#define IW_MODE_AUTO	0	/* Let the driver decides */
+#define IW_MODE_ADHOC	1	/* Single cell network */
+#define IW_MODE_INFRA	2	/* Multi cell network, roaming, ... */
+#define IW_MODE_MASTER	3	/* Synchronisation master or Access Point */
+#define IW_MODE_REPEAT	4	/* Wireless Repeater (forwarder) */
+#define IW_MODE_SECOND	5	/* Secondary master/repeater (backup) */
+
+/* Maximum number of size of encoding token available
+ * they are listed in the range structure */
+#define IW_MAX_ENCODING_SIZES	8
+
+/* Maximum size of the encoding token in bytes */
+#define IW_ENCODING_TOKEN_MAX	32	/* 256 bits (for now) */
+
+/* Flags for encoding (along with the token) */
+#define IW_ENCODE_INDEX		0x00FF	/* Token index (if needed) */
+#define IW_ENCODE_FLAGS		0xF000	/* Flags defined below */
+#define IW_ENCODE_DISABLED	0x8000	/* Encoding disabled */
+#define IW_ENCODE_ENABLED	0x0000	/* Encoding enabled */
+#define IW_ENCODE_RESTRICTED	0x4000	/* Refuse non-encoded packets */
+#define IW_ENCODE_OPEN		0x2000	/* Accept non-encoded packets */
+
+/* Power management flags available (along with the value, if any) */
+#define IW_POWER_ON		0x0000	/* No details... */
+#define IW_POWER_TYPE		0xF000	/* Type of parameter */
+#define IW_POWER_PERIOD		0x1000	/* Value is a period/duration of  */
+#define IW_POWER_TIMEOUT	0x2000	/* Value is a timeout (to go asleep) */
+#define IW_POWER_MODE		0x0F00	/* Power Management mode */
+#define IW_POWER_UNICAST_R	0x0100	/* Receive only unicast messages */
+#define IW_POWER_MULTICAST_R	0x0200	/* Receive only multicast messages */
+#define IW_POWER_ALL_R		0x0300	/* Receive all messages though PM */
+#define IW_POWER_FORCE_S	0x0400	/* Force PM procedure for sending unicast */
+#define IW_POWER_REPEATER	0x0800	/* Repeat broadcast messages in PM period */
+
 /****************************** TYPES ******************************/
 
 /* --------------------------- SUBTYPES --------------------------- */
 /*
+ *	Generic format for most parameters that fit in an int
+ */
+struct	iw_param
+{
+  __s32		value;		/* The value of the parameter itself */
+  __u8		fixed;		/* Hardware should not use auto select */
+  __u8		disabled;	/* Disable the feature */
+  __u16		flags;		/* Various specifc flags (if any) */
+};
+
+/*
+ *	For all data larger than 16 octets, we need to use a
+ *	pointer to memory alocated in user space.
+ */
+struct	iw_point
+{
+  caddr_t	pointer;	/* Pointer to the data  (in user space) */
+  __u16		length;		/* number of fields or size in bytes */
+  __u16		flags;		/* Optional params */
+};
+
+/*
  *	A frequency
  *	For numbers lower than 10^9, we encode the number in 'm' and
  *	set 'e' to 0
@@ -223,7 +295,7 @@
  */
 struct	iw_quality
 {
-	__u8		qual;		/* link quality (SNR or better...) */
+	__u8		qual;		/* link quality (%retries, SNR or better...) */
 	__u8		level;		/* signal level */
 	__u8		noise;		/* noise level */
 	__u8		updated;	/* Flags to know if updated */
@@ -240,33 +312,13 @@
 	__u32		misc;		/* Others cases */
 };
 
-/*
- *	Encoding information (setting and so on)
- *	Encoding might be hardware encryption, scrambing or others
- */
-struct	iw_encoding
-{
-  __u8	method;			/* Algorithm number / key used */
-  __u64	code;			/* Data/key used for algorithm */
-};
-
-/*
- *	Generic format for parameters
- */
-struct	iw_param
-{
-  __s32		value;		/* The value of the parameter itself */
-  __u8		fixed;		/* Hardware should not use auto select */
-};
-
-
 /* ------------------------ WIRELESS STATS ------------------------ */
 /*
  * Wireless statistics (used for /proc/net/wireless)
  */
 struct	iw_statistics
 {
-	__u8		status;		/* Status
+	__u16		status;		/* Status
 					 * - device dependent for now */
 
 	struct iw_quality	qual;		/* Quality of the link
@@ -295,37 +347,28 @@
 	union
 	{
 		/* Config - generic */
-		char	name[IFNAMSIZ];
+		char		name[IFNAMSIZ];
 		/* Name : used to verify the presence of  wireless extensions.
 		 * Name of the protocol/provider... */
 
-		struct		/* network id (or domain) : used to to */
-		{		/* create logical channels on the air */
-			__u32	nwid;		/* value */
-			__u8	on;		/* active/unactive nwid */
-		}	nwid;
-
+		struct iw_point	essid;	/* Extended network name */
+		struct iw_param	nwid;	/* network id (or domain - the cell) */
 		struct iw_freq	freq;	/* frequency or channel :
 					 * 0-1000 = channel
 					 * > 1000 = frequency in Hz */
 
-		struct iw_encoding	encoding;	/* Encoding stuff */
-
-		__u32	sensitivity;		/* Obsolete, but compatible */
 		struct iw_param	sens;		/* signal level threshold */
 		struct iw_param	bitrate;	/* default bit rate */
 		struct iw_param	rts;		/* RTS threshold threshold */
 		struct iw_param	frag;		/* Fragmentation threshold */
+		__u32		mode;		/* Operation mode */
+
+		struct iw_point	encoding;	/* Encoding stuff : tokens */
+		struct iw_param	power;		/* PM duration/timeout */
 
 		struct sockaddr	ap_addr;	/* Access point address */
 
-		struct		/* For all data bigger than 16 octets */
-		{
-			caddr_t	pointer;	/* Pointer to the data
-						 * (in user space) */
-			__u16	length;		/* fields or byte size */
-			__u16	flags;		/* Optional params */
-		}	data;
+		struct iw_point	data;		/* Other large parameters */
 	}	u;
 };
 
@@ -366,9 +409,6 @@
 	/* Quality of link & SNR stuff */
 	struct iw_quality	max_qual;	/* Quality of the link */
 
-	/* Encoder stuff */
-	struct iw_encoding	max_encoding;	/* Encoding max range */
-
 	/* Rates */
 	__u8		num_bitrates;	/* Number of entries in the list */
 	__s32		bitrate[IW_MAX_BITRATES];	/* list, in bps */
@@ -380,6 +420,17 @@
 	/* Frag threshold */
 	__s32		min_frag;	/* Minimal frag threshold */
 	__s32		max_frag;	/* Maximal frag threshold */
+
+	/* Power Management duration & timeout */
+	__s32		min_pmd;	/* Minimal PM duration */
+	__s32		max_pmd;	/* Maximal PM duration */
+	__s32		min_pmt;	/* Minimal PM timeout */
+	__s32		max_pmt;	/* Maximal PM timeout */
+
+	/* Encoder stuff */
+	__u16	encoding_size[IW_MAX_ENCODING_SIZES];	/* Different token sizes */
+	__u8	num_encoding_sizes;	/* Number of entry in the list */
+	__u8	max_encoding_tokens;	/* Max number of tokens */
 };
 
 /*
diff -u --recursive --new-file v2.3.29/linux/include/math-emu/double.h linux/include/math-emu/double.h
--- v2.3.29/linux/include/math-emu/double.h	Tue Aug 31 17:29:15 1999
+++ linux/include/math-emu/double.h	Thu Dec  2 15:28:54 1999
@@ -115,6 +115,7 @@
 #define FP_CMP_EQ_D(r,X,Y)	_FP_CMP_EQ(D,2,r,X,Y)
 
 #define FP_TO_INT_D(r,X,rsz,rsg)	_FP_TO_INT(D,2,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_D(r,X,rsz,rsg)	_FP_TO_INT_ROUND(D,2,r,X,rsz,rsg)
 #define FP_FROM_INT_D(X,r,rs,rt)	_FP_FROM_INT(D,2,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_D(X)	_FP_FRAC_HIGH_2(X)
@@ -189,6 +190,7 @@
 #define FP_CMP_EQ_D(r,X,Y)	_FP_CMP_EQ(D,1,r,X,Y)
 
 #define FP_TO_INT_D(r,X,rsz,rsg)	_FP_TO_INT(D,1,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_D(r,X,rsz,rsg)	_FP_TO_INT_ROUND(D,1,r,X,rsz,rsg)
 #define FP_FROM_INT_D(X,r,rs,rt)	_FP_FROM_INT(D,1,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_D(X)	_FP_FRAC_HIGH_1(X)
diff -u --recursive --new-file v2.3.29/linux/include/math-emu/extended.h linux/include/math-emu/extended.h
--- v2.3.29/linux/include/math-emu/extended.h	Tue Aug 31 17:29:15 1999
+++ linux/include/math-emu/extended.h	Thu Dec  2 15:28:54 1999
@@ -226,6 +226,7 @@
 #define FP_CMP_EQ_E(r,X,Y)	_FP_CMP_EQ(E,4,r,X,Y)
 
 #define FP_TO_INT_E(r,X,rsz,rsg)	_FP_TO_INT(E,4,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_E(r,X,rsz,rsg)	_FP_TO_INT_ROUND(E,4,r,X,rsz,rsg)
 #define FP_FROM_INT_E(X,r,rs,rt)	_FP_FROM_INT(E,4,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_E(X)	(X##_f[2])
@@ -380,6 +381,7 @@
 #define FP_CMP_EQ_E(r,X,Y)	_FP_CMP_EQ(E,2,r,X,Y)
 
 #define FP_TO_INT_E(r,X,rsz,rsg)	_FP_TO_INT(E,2,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_E(r,X,rsz,rsg)	_FP_TO_INT_ROUND(E,2,r,X,rsz,rsg)
 #define FP_FROM_INT_E(X,r,rs,rt)	_FP_FROM_INT(E,2,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_E(X)	(X##_f1)
diff -u --recursive --new-file v2.3.29/linux/include/math-emu/op-2.h linux/include/math-emu/op-2.h
--- v2.3.29/linux/include/math-emu/op-2.h	Tue Aug 31 17:29:15 1999
+++ linux/include/math-emu/op-2.h	Thu Dec  2 15:28:54 1999
@@ -113,9 +113,9 @@
 #define _FP_FRAC_OVERP_2(fs,X)	(_FP_FRAC_HIGH_##fs(X) & _FP_OVERFLOW_##fs)
 #define _FP_FRAC_EQ_2(X, Y)	(X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
 #define _FP_FRAC_GT_2(X, Y)	\
-  (X##_f1 > Y##_f1 || X##_f1 == Y##_f1 && X##_f0 > Y##_f0)
+  (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
 #define _FP_FRAC_GE_2(X, Y)	\
-  (X##_f1 > Y##_f1 || X##_f1 == Y##_f1 && X##_f0 >= Y##_f0)
+  (X##_f1 > Y##_f1 || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))
 
 #define _FP_ZEROFRAC_2		0, 0
 #define _FP_MINFRAC_2		0, 1
diff -u --recursive --new-file v2.3.29/linux/include/math-emu/op-common.h linux/include/math-emu/op-common.h
--- v2.3.29/linux/include/math-emu/op-common.h	Tue Aug 31 17:29:15 1999
+++ linux/include/math-emu/op-common.h	Thu Dec  2 15:28:54 1999
@@ -54,6 +54,11 @@
 	X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;				\
 	X##_c = FP_CLS_NORMAL;						\
 	FP_SET_EXCEPTION(FP_EX_DENORM);					\
+	if (FP_DENORM_ZERO)						\
+	  {								\
+	    FP_SET_EXCEPTION(FP_EX_INEXACT);				\
+	    X##_c = FP_CLS_ZERO;					\
+	  }								\
       }									\
     break;								\
 									\
@@ -618,6 +623,8 @@
  * 1:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
  *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
  *     on the sign in such case.
+ * 2:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
+ *     set plus the result is truncated to fit into destination.
  * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
  *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
  *     on the sign in such case.
@@ -638,12 +645,25 @@
 	  {	/* overflow */							\
 	  case FP_CLS_NAN:                                                      \
 	  case FP_CLS_INF:							\
-	    if (rsigned)							\
+	    if (rsigned == 2)							\
+	      {									\
+		if (X##_c != FP_CLS_NORMAL					\
+		    || X##_e >= rsize - 1 + _FP_WFRACBITS_##fs)			\
+		  r = 0;							\
+		else								\
+		  {								\
+		    _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));	\
+		    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);			\
+		  }								\
+	      }									\
+	    else if (rsigned)							\
 	      {									\
 		r = 1;								\
 		r <<= rsize - 1;						\
 		r -= 1 - X##_s;							\
-	      } else {								\
+	      }									\
+	    else								\
+	      {									\
 		r = 0;								\
 		if (X##_s)							\
 		  r = ~r;							\
@@ -675,6 +695,67 @@
 	      r = -r;								\
 	  }									\
 	break;									\
+      }										\
+  } while (0)
+
+#define _FP_TO_INT_ROUND(fs, wc, r, X, rsize, rsigned)				\
+  do {										\
+    r = 0;									\
+    switch (X##_c)								\
+      {										\
+      case FP_CLS_NORMAL:							\
+	if (X##_e >= _FP_FRACBITS_##fs - 1)					\
+	  {									\
+	    if (X##_e < rsize - 1 + _FP_WFRACBITS_##fs)				\
+	      {									\
+		if (X##_e >= _FP_WFRACBITS_##fs - 1)				\
+		  {								\
+		    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);			\
+		    r <<= X##_e - _FP_WFRACBITS_##fs + 1;			\
+		  }								\
+		else								\
+		  {								\
+		    _FP_FRAC_SRL_##wc(X, _FP_WORKBITS - X##_e			\
+				      + _FP_FRACBITS_##fs - 1);			\
+		    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);			\
+		  }								\
+	      }									\
+	  }									\
+	else									\
+	  {									\
+	    if (X##_e <= -_FP_WORKBITS - 1)					\
+	      _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);				\
+	    else								\
+	      _FP_FRAC_SRS_##wc(X, _FP_FRACBITS_##fs - 1 - X##_e,		\
+				_FP_WFRACBITS_##fs);				\
+	    _FP_ROUND(wc, X);							\
+	    _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);					\
+	    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);				\
+	  }									\
+	if (rsigned && X##_s)							\
+	  r = -r;								\
+	if (X##_e >= rsize - (rsigned > 0 || X##_s)				\
+	    || (!rsigned && X##_s))						\
+	  {	/* overflow */							\
+	  case FP_CLS_NAN:                                                      \
+	  case FP_CLS_INF:							\
+	    if (!rsigned)							\
+	      {									\
+		r = 0;								\
+		if (X##_s)							\
+		  r = ~r;							\
+	      }									\
+	    else if (rsigned != 2)						\
+	      {									\
+		r = 1;								\
+		r <<= rsize - 1;						\
+		r -= 1 - X##_s;							\
+	      }									\
+	    FP_SET_EXCEPTION(FP_EX_INVALID);					\
+	  }									\
+	break;									\
+      case FP_CLS_ZERO:								\
+        break;									\
       }										\
   } while (0)
 
diff -u --recursive --new-file v2.3.29/linux/include/math-emu/quad.h linux/include/math-emu/quad.h
--- v2.3.29/linux/include/math-emu/quad.h	Tue Aug 31 17:29:15 1999
+++ linux/include/math-emu/quad.h	Thu Dec  2 15:28:54 1999
@@ -121,6 +121,7 @@
 #define FP_CMP_EQ_Q(r,X,Y)	_FP_CMP_EQ(Q,4,r,X,Y)
 
 #define FP_TO_INT_Q(r,X,rsz,rsg)	_FP_TO_INT(Q,4,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_Q(r,X,rsz,rsg)	_FP_TO_INT_ROUND(Q,4,r,X,rsz,rsg)
 #define FP_FROM_INT_Q(X,r,rs,rt)	_FP_FROM_INT(Q,4,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_Q(X)	_FP_FRAC_HIGH_4(X)
@@ -193,6 +194,7 @@
 #define FP_CMP_EQ_Q(r,X,Y)	_FP_CMP_EQ(Q,2,r,X,Y)
 
 #define FP_TO_INT_Q(r,X,rsz,rsg)	_FP_TO_INT(Q,2,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_Q(r,X,rsz,rsg)	_FP_TO_INT_ROUND(Q,2,r,X,rsz,rsg)
 #define FP_FROM_INT_Q(X,r,rs,rt)	_FP_FROM_INT(Q,2,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_Q(X)	_FP_FRAC_HIGH_2(X)
diff -u --recursive --new-file v2.3.29/linux/include/math-emu/single.h linux/include/math-emu/single.h
--- v2.3.29/linux/include/math-emu/single.h	Tue Aug 31 17:29:15 1999
+++ linux/include/math-emu/single.h	Thu Dec  2 15:28:54 1999
@@ -104,6 +104,7 @@
 #define FP_CMP_EQ_S(r,X,Y)	_FP_CMP_EQ(S,1,r,X,Y)
 
 #define FP_TO_INT_S(r,X,rsz,rsg)	_FP_TO_INT(S,1,r,X,rsz,rsg)
+#define FP_TO_INT_ROUND_S(r,X,rsz,rsg)	_FP_TO_INT_ROUND(S,1,r,X,rsz,rsg)
 #define FP_FROM_INT_S(X,r,rs,rt)	_FP_FROM_INT(S,1,X,r,rs,rt)
 
 #define _FP_FRAC_HIGH_S(X)	_FP_FRAC_HIGH_1(X)
diff -u --recursive --new-file v2.3.29/linux/include/math-emu/soft-fp.h linux/include/math-emu/soft-fp.h
--- v2.3.29/linux/include/math-emu/soft-fp.h	Tue Aug 31 17:29:15 1999
+++ linux/include/math-emu/soft-fp.h	Thu Dec  2 15:28:54 1999
@@ -24,7 +24,7 @@
 #ifndef SOFT_FP_H
 #define SOFT_FP_H
 
-#include "sfp-machine.h"
+#include <asm/sfp-machine.h>
 
 /* Allow sfp-machine to have its own byte order definitions. */
 #ifndef __BYTE_ORDER
@@ -81,6 +81,11 @@
 
 #ifndef FP_HANDLE_EXCEPTIONS
 #define FP_HANDLE_EXCEPTIONS do {} while (0)
+#endif
+
+/* By default we never flush denormal input operands to signed zero. */
+#ifndef FP_DENORM_ZERO
+#define FP_DENORM_ZERO 0
 #endif
 
 #ifndef FP_INHIBIT_RESULTS
diff -u --recursive --new-file v2.3.29/linux/include/net/sock.h linux/include/net/sock.h
--- v2.3.29/linux/include/net/sock.h	Fri Sep 10 23:57:37 1999
+++ linux/include/net/sock.h	Mon Dec  6 17:23:07 1999
@@ -386,6 +386,7 @@
 
 #define sock_lock_init(__sk) \
 do {	spin_lock_init(&((__sk)->lock.slock)); \
+	(__sk)->dst_lock = RW_LOCK_UNLOCKED; \
 	(__sk)->lock.users = 0; \
 	init_waitqueue_head(&((__sk)->lock.wq)); \
 } while(0);
diff -u --recursive --new-file v2.3.29/linux/include/video/fbcon.h linux/include/video/fbcon.h
--- v2.3.29/linux/include/video/fbcon.h	Mon Oct 11 15:38:15 1999
+++ linux/include/video/fbcon.h	Sat Nov 27 19:38:13 1999
@@ -44,6 +44,67 @@
 
 extern struct display_switch fbcon_dummy;
 
+   /*
+    *    This is the interface between the low-level console driver and the
+    *    low-level frame buffer device
+    */
+
+struct display {
+    /* Filled in by the frame buffer device */
+
+    struct fb_var_screeninfo var;   /* variable infos. yoffset and vmode */
+                                    /* are updated by fbcon.c */
+    struct fb_cmap cmap;            /* colormap */
+    char *screen_base;              /* pointer to top of virtual screen */    
+                                    /* (virtual address) */
+    int visual;
+    int type;                       /* see FB_TYPE_* */
+    int type_aux;                   /* Interleave for interleaved Planes */
+    u_short ypanstep;               /* zero if no hardware ypan */
+    u_short ywrapstep;              /* zero if no hardware ywrap */
+    u_long line_length;             /* length of a line in bytes */
+    u_short can_soft_blank;         /* zero if no hardware blanking */
+    u_short inverse;                /* != 0 text black on white as default */
+    struct display_switch *dispsw;  /* low level operations */
+    void *dispsw_data;              /* optional dispsw helper data */
+
+#if 0
+    struct fb_fix_cursorinfo fcrsr;
+    struct fb_var_cursorinfo *vcrsr;
+    struct fb_cursorstate crsrstate;
+#endif
+
+    /* Filled in by the low-level console driver */
+
+    struct vc_data *conp;           /* pointer to console data */
+    struct fb_info *fb_info;        /* frame buffer for this console */
+    int vrows;                      /* number of virtual rows */
+    unsigned short cursor_x;        /* current cursor position */
+    unsigned short cursor_y;
+    int fgcol;                      /* text colors */
+    int bgcol;
+    u_long next_line;               /* offset to one line below */
+    u_long next_plane;              /* offset to next plane */
+    u_char *fontdata;               /* Font associated to this display */
+    unsigned short _fontheightlog;
+    unsigned short _fontwidthlog;
+    unsigned short _fontheight;
+    unsigned short _fontwidth;
+    int userfont;                   /* != 0 if fontdata kmalloc()ed */
+    u_short scrollmode;             /* Scroll Method */
+    short yscroll;                  /* Hardware scrolling */
+    unsigned char fgshift, bgshift;
+    unsigned short charmask;        /* 0xff or 0x1ff */
+};
+
+/* drivers/video/fbcon.c */
+extern struct display fb_display[MAX_NR_CONSOLES];
+extern char con2fb_map[MAX_NR_CONSOLES];
+extern int PROC_CONSOLE(const struct fb_info *info);
+extern void set_con2fb_map(int unit, int newidx);
+extern int set_all_vcs(int fbidx, struct fb_ops *fb,
+		       struct fb_var_screeninfo *var, struct fb_info *info);
+
 #define fontheight(p) ((p)->_fontheight)
 #define fontheightlog(p) ((p)->_fontheightlog)
 
diff -u --recursive --new-file v2.3.29/linux/ipc/sem.c linux/ipc/sem.c
--- v2.3.29/linux/ipc/sem.c	Tue Nov 23 22:42:21 1999
+++ linux/ipc/sem.c	Sat Nov 27 15:27:49 1999
@@ -190,12 +190,7 @@
 	smanew = sem_lock(semid);
 	if(smanew==NULL)
 		return -EIDRM;
-	if(smanew != sma)
-		goto out_EIDRM;
-	if(sem_checkid(sma,semid))
-		goto out_EIDRM;
-	if(sma->sem_nsems != nsems) {
-out_EIDRM:
+	if(smanew != sma || sem_checkid(sma,semid) || sma->sem_nsems != nsems) {
 		sem_unlock(semid);
 		return -EIDRM;
 	}
diff -u --recursive --new-file v2.3.29/linux/ipc/shm.c linux/ipc/shm.c
--- v2.3.29/linux/ipc/shm.c	Thu Nov 11 20:11:54 1999
+++ linux/ipc/shm.c	Thu Dec  2 15:06:20 1999
@@ -39,10 +39,22 @@
 	struct semaphore sem;
 };
 
-static int findkey (key_t key);
+static struct ipc_ids shm_ids;
+
+#define shm_lock(id)	((struct shmid_kernel*)ipc_lock(&shm_ids,id))
+#define shm_unlock(id)	ipc_unlock(&shm_ids,id)
+#define shm_lockall()	ipc_lockall(&shm_ids)
+#define shm_unlockall()	ipc_unlockall(&shm_ids)
+#define shm_get(id)	((struct shmid_kernel*)ipc_get(&shm_ids,id))
+#define shm_rmid(id)	((struct shmid_kernel*)ipc_rmid(&shm_ids,id))
+#define shm_checkid(s, id)	\
+	ipc_checkid(&shm_ids,&s->u.shm_perm,id)
+#define shm_buildid(id, seq) \
+	ipc_buildid(&shm_ids, id, seq)
+
 static int newseg (key_t key, int shmflg, size_t size);
 static int shm_map (struct vm_area_struct *shmd);
-static void killseg (int id);
+static void killseg (int shmid);
 static void shm_open (struct vm_area_struct *shmd);
 static void shm_close (struct vm_area_struct *shmd);
 static struct page * shm_nopage(struct vm_area_struct *, unsigned long, int);
@@ -51,21 +63,28 @@
 static int sysvipc_shm_read_proc(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
 #endif
 
-unsigned int shm_prm[3] = {SHMMAX, SHMALL, SHMMNI};
+size_t shm_ctlmax = SHMMAX;
+int shm_ctlall = SHMALL;
+int shm_ctlmni = SHMMNI;
 
 static int shm_tot = 0; /* total number of shared memory pages */
 static int shm_rss = 0; /* number of shared memory pages that are in memory */
 static int shm_swp = 0; /* number of shared memory pages that are in swap */
-static int max_shmid = -1; /* every used id is <= max_shmid */
-static DECLARE_WAIT_QUEUE_HEAD(shm_wait); /* calling findkey() may need to wait */
-static struct shmid_kernel **shm_segs = NULL;
-static unsigned int num_segs = 0;
-static unsigned short shm_seq = 0; /* incremented, for recognizing stale ids */
 
 /* locks order:
-	shm_lock -> pagecache_lock (end of shm_swap)
-	shp->sem -> other spinlocks (shm_nopage) */
-spinlock_t shm_lock = SPIN_LOCK_UNLOCKED;
+	pagecache_lock
+	shm_lock()/shm_lockall()
+	kernel lock
+	shp->sem
+	sem_ids.sem
+	mmap_sem
+
+  SMP assumptions:
+  - swap_free() never sleeps
+  - add_to_swap_cache() never sleeps
+  - add_to_swap_cache() doesn't acquire the big kernel lock.
+  - shm_unuse() is called with the kernel lock acquired.
+ */
 
 /* some statistics */
 static ulong swap_attempts = 0;
@@ -74,6 +93,7 @@
 
 void __init shm_init (void)
 {
+	ipc_init_ids(&shm_ids, shm_ctlmni);
 #ifdef CONFIG_PROC_FS
 	create_proc_read_entry("sysvipc/shm", 0, 0, sysvipc_shm_read_proc, NULL);
 #endif
@@ -135,127 +155,55 @@
 	kfree (dir);
 }
 
-static int shm_expand (unsigned int size)
+static int shm_revalidate(struct shmid_kernel* shp, int shmid, int pagecount, int flg)
 {
-	int id;
-	struct shmid_kernel ** new_array;
-
-	spin_unlock(&shm_lock);
-	new_array = kmalloc (size * sizeof(struct shmid_kernel *), GFP_KERNEL);
-	spin_lock(&shm_lock);
-
-	if (!new_array)
-		return -ENOMEM;
-
-	if (size <= num_segs){ /* We check this after kmalloc so
-				   nobody changes num_segs afterwards */
-		/*
-		 * We never shrink the segment. If we shrink we have to
-		 * check for stale handles in newseg
-		 */
-		kfree (new_array);
-		return 0;
+	struct shmid_kernel* new;
+	new = shm_lock(shmid);
+	if(new==NULL) {
+		return -EIDRM;
+	}
+	if(new!=shp || shm_checkid(shp, shmid) || shp->shm_npages != pagecount) {
+		shm_unlock(shmid);
+		return -EIDRM;
+	}
+	if (ipcperms(&shp->u.shm_perm, flg)) {
+		shm_unlock(shmid);
+		return -EACCES;
 	}
-
-	if (num_segs) {
-		memcpy (new_array, shm_segs,
-			size*sizeof(struct shmid_kernel *));
-		kfree (shm_segs);
-	}
-	for (id = num_segs; id < size; id++) 
-		new_array[id] = (void *) IPC_UNUSED;
-
-	shm_segs = new_array;
-	num_segs = size;
 	return 0;
 }
 
-static int findkey (key_t key)
-{
-	int id;
-	struct shmid_kernel *shp;
-	
-	if (!num_segs)
-		return -1;
-
-	for (id = 0; id <= max_shmid; id++) {
-		if ((shp = shm_segs[id]) == IPC_NOID) {
-			DECLARE_WAITQUEUE(wait, current);
-
-			add_wait_queue(&shm_wait, &wait);
-			for(;;) {
-				set_current_state(TASK_UNINTERRUPTIBLE);
-				if ((shp = shm_segs[id]) != IPC_NOID)
-					break;
-				spin_unlock(&shm_lock);
-				schedule();
-				spin_lock(&shm_lock);
-			}
-			__set_current_state(TASK_RUNNING);
-			remove_wait_queue(&shm_wait, &wait);
-		}
-		if (shp != IPC_UNUSED &&
-		    key == shp->u.shm_perm.key)
-			return id;
-	}
-	return -1;
-}
-
-/*
- * allocate new shmid_kernel and pgtable. protected by shm_segs[id] = NOID.
- * This has to be called with the shm_lock held
- */
 static int newseg (key_t key, int shmflg, size_t size)
 {
 	struct shmid_kernel *shp;
 	int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT;
-	int id, err;
-	unsigned int shmall, shmmni;
-
-	shmall = shm_prm[1];
-	shmmni = shm_prm[2];
-	if (shmmni > IPCMNI) {
-		printk ("shmmni reset to max of %u\n", IPCMNI);
-		shmmni = shm_prm[2] = IPCMNI;
-	}
+	int id;
 
-	if (shmmni < used_segs)
-		return -ENOSPC;
-	if ((err = shm_expand (shmmni)))
-		return err;
 	if (size < SHMMIN)
 		return -EINVAL;
-	if (shm_tot + numpages >= shmall)
+
+	if (size > shm_ctlmax)
+		return -EINVAL;
+	if (shm_tot + numpages >= shm_ctlall)
 		return -ENOSPC;
-	for (id = 0; id < num_segs; id++)
-		if (shm_segs[id] == IPC_UNUSED) {
-			shm_segs[id] = (struct shmid_kernel *) IPC_NOID;
-			goto found;
-		}
-	return -ENOSPC;
 
-found:
-	spin_unlock(&shm_lock);
 	shp = (struct shmid_kernel *) kmalloc (sizeof (*shp), GFP_KERNEL);
-	if (!shp) {
-		spin_lock(&shm_lock);
-		shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
-		wake_up (&shm_wait);
+	if (!shp)
 		return -ENOMEM;
-	}
+
 	shp->shm_dir = shm_alloc (numpages);
 	if (!shp->shm_dir) {
 		kfree(shp);
-		spin_lock(&shm_lock);
-		shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
-		wake_up (&shm_wait);
 		return -ENOMEM;
 	}
-
+	id = ipc_addid(&shm_ids, &shp->u.shm_perm, shm_ctlmni);
+	if(id == -1) {
+		shm_free(shp->shm_dir,numpages);
+		kfree(shp);
+		return -ENOSPC;
+	}
 	shp->u.shm_perm.key = key;
 	shp->u.shm_perm.mode = (shmflg & S_IRWXUGO);
-	shp->u.shm_perm.cuid = shp->u.shm_perm.uid = current->euid;
-	shp->u.shm_perm.cgid = shp->u.shm_perm.gid = current->egid;
 	shp->u.shm_segsz = size;
 	shp->u.shm_cpid = current->pid;
 	shp->attaches = NULL;
@@ -263,37 +211,24 @@
 	shp->u.shm_atime = shp->u.shm_dtime = 0;
 	shp->u.shm_ctime = CURRENT_TIME;
 	shp->shm_npages = numpages;
-	shp->id = id;
+	shp->id = shm_buildid(id,shp->u.shm_perm.seq);
 	init_MUTEX(&shp->sem);
 
-	spin_lock(&shm_lock);
-
 	shm_tot += numpages;
-	shp->u.shm_perm.seq = shm_seq;
+	shm_unlock(id);
 
-	if (id > max_shmid)
-		max_shmid = id;
-	shm_segs[id] = shp;
-	used_segs++;
-	wake_up (&shm_wait);
-	return (unsigned int) shp->u.shm_perm.seq * IPCMNI + id;
+	return shm_buildid(id,shp->u.shm_perm.seq);
 }
 
 asmlinkage long sys_shmget (key_t key, size_t size, int shmflg)
 {
 	struct shmid_kernel *shp;
 	int err, id = 0;
-	size_t shmmax;
 
-	shmmax = shm_prm[0];
-	if (size > shmmax)
-		return -EINVAL;
-
-	down(&current->mm->mmap_sem);
-	spin_lock(&shm_lock);
+	down(&shm_ids.sem);
 	if (key == IPC_PRIVATE) {
 		err = newseg(key, shmflg, size);
-	} else if ((id = findkey (key)) == -1) {
+	} else if ((id = ipc_findkey(&shm_ids,key)) == -1) {
 		if (!(shmflg & IPC_CREAT))
 			err = -ENOENT;
 		else
@@ -301,18 +236,16 @@
 	} else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) {
 		err = -EEXIST;
 	} else {
-		shp = shm_segs[id];
-		if (shp->u.shm_perm.mode & SHM_DEST)
-			err = -EIDRM;
-		else if (size > shp->u.shm_segsz)
-			err = -EINVAL;
-		else if (ipcperms (&shp->u.shm_perm, shmflg))
+		shp = shm_lock(id);
+		if(shp==NULL)
+			BUG();
+		if (ipcperms(&shp->u.shm_perm, shmflg))
 			err = -EACCES;
 		else
-			err = (int) shp->u.shm_perm.seq * IPCMNI + id;
+			err = shm_buildid(id, shp->u.shm_perm.seq);
+		shm_unlock(id);
 	}
-	spin_unlock(&shm_lock);
-	up(&current->mm->mmap_sem);
+	up(&shm_ids.sem);
 	return err;
 }
 
@@ -320,24 +253,32 @@
  * Only called after testing nattch and SHM_DEST.
  * Here pages, pgtable and shmid_kernel are freed.
  */
-static void killseg (int id)
+static void killseg (int shmid)
 {
 	struct shmid_kernel *shp;
 	int i, numpages;
 	int rss, swp;
 
-	shp = shm_segs[id];
-	if (shp == IPC_NOID || shp == IPC_UNUSED)
+	down(&shm_ids.sem);
+	shp = shm_lock(shmid);
+	if(shp==NULL) {
+out_up:
+		up(&shm_ids.sem);
+		return;
+	}
+	if(shm_checkid(shp,shmid) || shp->u.shm_nattch > 0 ||
+	    !(shp->u.shm_perm.mode & SHM_DEST)) {
+		shm_unlock(shmid);
+		goto out_up;
+	}
+	shp = shm_rmid(shmid);
+	if(shp==NULL)
 		BUG();
-	shp->u.shm_perm.seq++;     /* for shmat */
-	shm_seq = (shm_seq+1) % ((unsigned)(1<<31)/IPCMNI); /* increment, but avoid overflow */
-	shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
-	used_segs--;
-	if (id == max_shmid)
-		while (max_shmid-- > 0 && (shm_segs[max_shmid] == IPC_UNUSED));
 	if (!shp->shm_dir)
 		BUG();
-	spin_unlock(&shm_lock);
+	shm_unlock(shmid);
+	up(&shm_ids.sem);
+
 	numpages = shp->shm_npages;
 	for (i = 0, rss = 0, swp = 0; i < numpages ; i++) {
 		pte_t pte;
@@ -348,18 +289,17 @@
 			__free_page (pte_page(pte));
 			rss++;
 		} else {
-			lock_kernel();
 			swap_free(pte_to_swp_entry(pte));
-			unlock_kernel();
 			swp++;
 		}
 	}
 	shm_free (shp->shm_dir, numpages);
 	kfree(shp);
-	spin_lock(&shm_lock);
+	shm_lockall();
 	shm_rss -= rss;
 	shm_swp -= swp;
 	shm_tot -= numpages;
+	shm_unlockall();
 	return;
 }
 
@@ -367,148 +307,159 @@
 {
 	struct shmid_ds tbuf;
 	struct shmid_kernel *shp;
-	struct ipc_perm *ipcp;
-	int id, err = -EINVAL;
+	int err;
 
 	if (cmd < 0 || shmid < 0)
-		goto out_unlocked;
-	if (cmd == IPC_SET) {
-		err = -EFAULT;
-		if(copy_from_user (&tbuf, buf, sizeof (*buf)))
-			goto out_unlocked;
-	}
-	spin_lock(&shm_lock);
+		return -EINVAL;
 
 	switch (cmd) { /* replace with proc interface ? */
 	case IPC_INFO:
 	{
 		struct shminfo shminfo;
-		spin_unlock(&shm_lock);
-		err = -EFAULT;
-		if (!buf)
-			goto out;
-
-		shminfo.shmmni = shminfo.shmseg = shm_prm[2];
-		shminfo.shmmax = shm_prm[0];
-		shminfo.shmall = shm_prm[1];
+
+		memset(&shminfo,0,sizeof(shminfo));
+		shminfo.shmmni = shminfo.shmseg = shm_ctlmni;
+		shminfo.shmmax = shm_ctlmax;
+		shminfo.shmall = shm_ctlall;
 
 		shminfo.shmmin = SHMMIN;
 		if(copy_to_user (buf, &shminfo, sizeof(struct shminfo)))
-			goto out_unlocked;
-		spin_lock(&shm_lock);
-		err = max_shmid < 0 ? 0 : max_shmid;
-		goto out;
+			return -EFAULT;
+		/* reading a integer is always atomic */
+		err= shm_ids.max_id;
+		if(err<0)
+			err = 0;
+		return err;
 	}
 	case SHM_INFO:
 	{
 		struct shm_info shm_info;
-		err = -EFAULT;
+
+		memset(&shm_info,0,sizeof(shm_info));
+		shm_lockall();
 		shm_info.used_ids = used_segs;
 		shm_info.shm_rss = shm_rss;
 		shm_info.shm_tot = shm_tot;
 		shm_info.shm_swp = shm_swp;
 		shm_info.swap_attempts = swap_attempts;
 		shm_info.swap_successes = swap_successes;
-		spin_unlock(&shm_lock);
+		err = shm_ids.max_id;
+		shm_unlockall();
 		if(copy_to_user (buf, &shm_info, sizeof(shm_info)))
-			goto out_unlocked;
-		spin_lock(&shm_lock);
-		err = max_shmid < 0 ? 0 : max_shmid;
-		goto out;
+			return -EFAULT;
+
+		return err < 0 ? 0 : err;
 	}
 	case SHM_STAT:
-		err = -EINVAL;
-		if (shmid > max_shmid)
-			goto out;
-		shp = shm_segs[shmid];
-		if (shp == IPC_UNUSED || shp == IPC_NOID)
-			goto out;
+	case IPC_STAT:
+	{
+		struct shmid_ds tmp;
+		int result;
+		shp = shm_lock(shmid);
+		if(shp==NULL)
+			return -EINVAL;
+		if(cmd==SHM_STAT) {
+			err = -EINVAL;
+			if (shmid > shm_ids.max_id)
+				goto out_unlock;
+			result = shm_buildid(shmid, shp->u.shm_perm.seq);
+		} else {
+			err = -EIDRM;
+			if(shm_checkid(shp,shmid))
+				goto out_unlock;
+			result = 0;
+		}
+		err=-EACCES;
 		if (ipcperms (&shp->u.shm_perm, S_IRUGO))
-			goto out;
-		id = (unsigned int) shp->u.shm_perm.seq * IPCMNI + shmid;
-		err = -EFAULT;
-		spin_unlock(&shm_lock);
-		if(copy_to_user (buf, &shp->u, sizeof(*buf)))
-			goto out_unlocked;
-		spin_lock(&shm_lock);
-		err = id;
-		goto out;
+			goto out_unlock;
+		memcpy(&tmp,&shp->u,sizeof(tmp));
+		shm_unlock(shmid);
+		if(copy_to_user (buf, &tmp, sizeof(tmp)))
+			return -EFAULT;
+		return result;
 	}
-
-	err = -EINVAL;
-	if ((id = (unsigned int) shmid % IPCMNI) > max_shmid)
-		goto out;
-	if ((shp = shm_segs[id]) == IPC_UNUSED || shp == IPC_NOID)
-		goto out;
-	err = -EIDRM;
-	if (shp->u.shm_perm.seq != (unsigned int) shmid / IPCMNI)
-		goto out;
-	ipcp = &shp->u.shm_perm;
-
-	switch (cmd) {
-	case SHM_UNLOCK:
-		err = -EPERM;
-		if (!capable(CAP_IPC_LOCK))
-			goto out;
-		err = -EINVAL;
-		if (!(ipcp->mode & SHM_LOCKED))
-			goto out;
-		ipcp->mode &= ~SHM_LOCKED;
-		break;
 	case SHM_LOCK:
+	case SHM_UNLOCK:
+	{
 /* Allow superuser to lock segment in memory */
 /* Should the pages be faulted in here or leave it to user? */
 /* need to determine interaction with current->swappable */
-		err = -EPERM;
+		struct ipc_perm *ipcp;
 		if (!capable(CAP_IPC_LOCK))
-			goto out;
-		err = -EINVAL;
-		if (ipcp->mode & SHM_LOCKED)
-			goto out;
-		ipcp->mode |= SHM_LOCKED;
-		break;
-	case IPC_STAT:
-		err = -EACCES;
-		if (ipcperms (ipcp, S_IRUGO))
-			goto out;
-		err = -EFAULT;
-		spin_unlock(&shm_lock);
-		if(copy_to_user (buf, &shp->u, sizeof(shp->u)))
-			goto out_unlocked;
-		spin_lock(&shm_lock);
+			return -EPERM;
+
+		shp = shm_lock(shmid);
+		if(shp==NULL)
+			return -EINVAL;
+		err=-EIDRM;
+		if(shm_checkid(shp,shmid))
+			goto out_unlock;
+		ipcp = &shp->u.shm_perm;
+		if(cmd==SHM_LOCK) {
+			if (!(ipcp->mode & SHM_LOCKED)) {
+				ipcp->mode |= SHM_LOCKED;
+				err = 0;
+			}
+		} else {
+			if (ipcp->mode & SHM_LOCKED) {
+				ipcp->mode &= ~SHM_LOCKED;
+				err = 0;
+			}
+		}
+		shm_unlock(shmid);
+		return err;
+	}
+	case IPC_RMID:
+	case IPC_SET:
 		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (cmd == IPC_SET) {
+		if(copy_from_user (&tbuf, buf, sizeof (*buf)))
+			return -EFAULT;
+	}
+	down(&shm_ids.sem);
+	shp = shm_lock(shmid);
+	err=-EINVAL;
+	if(shp==NULL)
+		goto out_up;
+	err=-EIDRM;
+	if(shm_checkid(shp,shmid))
+		goto out_unlock_up;
+	err=-EPERM;
+	if (current->euid != shp->u.shm_perm.uid &&
+	    current->euid != shp->u.shm_perm.cuid && 
+	    !capable(CAP_SYS_ADMIN)) {
+		goto out_unlock_up;
+	}
+
+	switch (cmd) {
 	case IPC_SET:
-		if (current->euid == shp->u.shm_perm.uid ||
-		    current->euid == shp->u.shm_perm.cuid || 
-		    capable(CAP_SYS_ADMIN)) {
-			ipcp->uid = tbuf.shm_perm.uid;
-			ipcp->gid = tbuf.shm_perm.gid;
-			ipcp->mode = (ipcp->mode & ~S_IRWXUGO)
-				| (tbuf.shm_perm.mode & S_IRWXUGO);
-			shp->u.shm_ctime = CURRENT_TIME;
-			break;
-		}
-		err = -EPERM;
-		goto out;
+		shp->u.shm_perm.uid = tbuf.shm_perm.uid;
+		shp->u.shm_perm.gid = tbuf.shm_perm.gid;
+		shp->u.shm_perm.mode = (shp->u.shm_perm.mode & ~S_IRWXUGO)
+			| (tbuf.shm_perm.mode & S_IRWXUGO);
+		shp->u.shm_ctime = CURRENT_TIME;
+		break;
 	case IPC_RMID:
-		if (current->euid == shp->u.shm_perm.uid ||
-		    current->euid == shp->u.shm_perm.cuid || 
-		    capable(CAP_SYS_ADMIN)) {
-			shp->u.shm_perm.mode |= SHM_DEST;
-			if (shp->u.shm_nattch <= 0)
-				killseg (id);
-			break;
+		shp->u.shm_perm.mode |= SHM_DEST;
+		if (shp->u.shm_nattch <= 0) {
+			shm_unlock(shmid);
+			up(&shm_ids.sem);
+			killseg (shmid);
+			return 0;
 		}
-		err = -EPERM;
-		goto out;
-	default:
-		err = -EINVAL;
-		goto out;
 	}
 	err = 0;
-out:
-	spin_unlock(&shm_lock);
-out_unlocked:
+out_unlock_up:
+	shm_unlock(shmid);
+out_up:
+	up(&shm_ids.sem);
+	return err;
+out_unlock:
+	shm_unlock(shmid);
 	return err;
 }
 
@@ -586,37 +537,47 @@
 {
 	struct shmid_kernel *shp;
 	struct vm_area_struct *shmd;
-	int err = -EINVAL;
-	unsigned int id;
+	int err;
 	unsigned long addr;
 	unsigned long len;
+	short flg = shmflg & SHM_RDONLY ? S_IRUGO : S_IRUGO|S_IWUGO;
+
 
-	down(&current->mm->mmap_sem);
-	spin_lock(&shm_lock);
 	if (shmid < 0)
-		goto out;
+		return -EINVAL;
 
-	shp = shm_segs[id = (unsigned int) shmid % IPCMNI];
-	if (shp == IPC_UNUSED || shp == IPC_NOID)
-		goto out;
+	down(&current->mm->mmap_sem);
+	err = -EINVAL;
+	shp = shm_lock(shmid);
+	if(shp == NULL)
+		goto out_unlock_up;
+
+	err = -EACCES;
+	if (ipcperms(&shp->u.shm_perm, flg))
+		goto out_unlock_up;
+
+	err = -EIDRM;
+	if (shm_checkid(shp,shmid))
+		goto out_unlock_up;
 
 	if (!(addr = (ulong) shmaddr)) {
 		if (shmflg & SHM_REMAP)
-			goto out;
+			goto out_unlock_up;
 		err = -ENOMEM;
 		addr = 0;
 	again:
 		if (!(addr = get_unmapped_area(addr, (unsigned long)shp->u.shm_segsz)))
-			goto out;
+			goto out_unlock_up;
 		if(addr & (SHMLBA - 1)) {
 			addr = (addr + (SHMLBA - 1)) & ~(SHMLBA - 1);
 			goto again;
 		}
 	} else if (addr & (SHMLBA-1)) {
+		err=-EINVAL;
 		if (shmflg & SHM_RND)
 			addr &= ~(SHMLBA-1);       /* round down */
 		else
-			goto out;
+			goto out_unlock_up;
 	}
 	/*
 	 * Check if addr exceeds TASK_SIZE (from do_mmap)
@@ -624,37 +585,27 @@
 	len = PAGE_SIZE*shp->shm_npages;
 	err = -EINVAL;
 	if (addr >= TASK_SIZE || len > TASK_SIZE  || addr > TASK_SIZE - len)
-		goto out;
+		goto out_unlock_up;
 	/*
 	 * If shm segment goes below stack, make sure there is some
 	 * space left for the stack to grow (presently 4 pages).
 	 */
 	if (addr < current->mm->start_stack &&
 	    addr > current->mm->start_stack - PAGE_SIZE*(shp->shm_npages + 4))
-		goto out;
+		goto out_unlock_up;
 	if (!(shmflg & SHM_REMAP) && find_vma_intersection(current->mm, addr, addr + (unsigned long)shp->u.shm_segsz))
-		goto out;
+		goto out_unlock_up;
 
-	err = -EACCES;
-	if (ipcperms(&shp->u.shm_perm, shmflg & SHM_RDONLY ? S_IRUGO : S_IRUGO|S_IWUGO))
-		goto out;
-	err = -EIDRM;
-	if (shp->u.shm_perm.seq != (unsigned int) shmid / IPCMNI)
-		goto out;
-
-	spin_unlock(&shm_lock);
+	shm_unlock(shmid);
 	err = -ENOMEM;
 	shmd = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
-	spin_lock(&shm_lock);
-	if (!shmd)
-		goto out;
-	if ((shp != shm_segs[id]) || (shp->u.shm_perm.seq != (unsigned int) shmid / IPCMNI)) {
+	err = shm_revalidate(shp, shmid, len/PAGE_SIZE,flg);
+	if(err)	{
 		kmem_cache_free(vm_area_cachep, shmd);
-		err = -EIDRM;
-		goto out;
+		goto out_up;
 	}
 
-	shmd->vm_private_data = shm_segs[id];
+	shmd->vm_private_data = shp;
 	shmd->vm_start = addr;
 	shmd->vm_end = addr + shp->shm_npages * PAGE_SIZE;
 	shmd->vm_mm = current->mm;
@@ -667,9 +618,9 @@
 	shmd->vm_ops = &shm_vm_ops;
 
 	shp->u.shm_nattch++;	    /* prevent destruction */
-	spin_unlock(&shm_lock);
+	shm_unlock(shp->id);
 	err = shm_map (shmd);
-	spin_lock(&shm_lock);
+	shm_lock(shmid); /* cannot fail */
 	if (err)
 		goto failed_shm_map;
 
@@ -680,18 +631,24 @@
 
 	*raddr = addr;
 	err = 0;
-out:
-	spin_unlock(&shm_lock);
+out_unlock_up:
+	shm_unlock(shmid);
+out_up:
 	up(&current->mm->mmap_sem);
 	return err;
 
 failed_shm_map:
-	if (--shp->u.shm_nattch <= 0 && shp->u.shm_perm.mode & SHM_DEST)
-		killseg(id);
-	spin_unlock(&shm_lock);
-	up(&current->mm->mmap_sem);
-	kmem_cache_free(vm_area_cachep, shmd);
-	return err;
+	{
+		int delete = 0;
+		if (--shp->u.shm_nattch <= 0 && shp->u.shm_perm.mode & SHM_DEST)
+			delete = 1;
+		shm_unlock(shmid);
+		up(&current->mm->mmap_sem);
+		kmem_cache_free(vm_area_cachep, shmd);
+		if(delete)
+			killseg(shmid);
+		return err;
+	}
 }
 
 /* This is called by fork, once for every shm attach. */
@@ -699,13 +656,14 @@
 {
 	struct shmid_kernel *shp;
 
-	spin_lock(&shm_lock);
 	shp = (struct shmid_kernel *) shmd->vm_private_data;
+	if(shp != shm_lock(shp->id))
+		BUG();
 	insert_attach(shp,shmd);  /* insert shmd into shp->attaches */
 	shp->u.shm_nattch++;
 	shp->u.shm_atime = CURRENT_TIME;
 	shp->u.shm_lpid = current->pid;
-	spin_unlock(&shm_lock);
+	shm_unlock(shp->id);
 }
 
 /*
@@ -717,16 +675,21 @@
 static void shm_close (struct vm_area_struct *shmd)
 {
 	struct shmid_kernel *shp;
+	int id;
 
-	spin_lock(&shm_lock);
 	/* remove from the list of attaches of the shm segment */
 	shp = (struct shmid_kernel *) shmd->vm_private_data;
+	if(shp != shm_lock(shp->id))
+		BUG();
 	remove_attach(shp,shmd);  /* remove from shp->attaches */
   	shp->u.shm_lpid = current->pid;
 	shp->u.shm_dtime = CURRENT_TIME;
+	id=-1;
 	if (--shp->u.shm_nattch <= 0 && shp->u.shm_perm.mode & SHM_DEST)
-		killseg (shp->id);
-	spin_unlock(&shm_lock);
+		id=shp->id;
+	shm_unlock(shp->id);
+	if(id!=-1)
+		killseg(id);
 }
 
 /*
@@ -776,23 +739,26 @@
 	idx += shmd->vm_pgoff;
 
 	down(&shp->sem);
-	spin_lock(&shm_lock);
+	if(shp != shm_lock(shp->id))
+		BUG();
+
 	pte = SHM_ENTRY(shp,idx);
 	if (!pte_present(pte)) {
 		/* page not present so shm_swap can't race with us
 		   and the semaphore protects us by other tasks that
 		   could potentially fault on our pte under us */
 		if (pte_none(pte)) {
-			spin_unlock(&shm_lock);
+			shm_unlock(shp->id);
 			page = alloc_page(GFP_HIGHUSER);
 			if (!page)
 				goto oom;
 			clear_highpage(page);
-			spin_lock(&shm_lock);
+			if(shp != shm_lock(shp->id))
+				BUG();
 		} else {
 			swp_entry_t entry = pte_to_swp_entry(pte);
 
-			spin_unlock(&shm_lock);
+			shm_unlock(shp->id);
 			page = lookup_swap_cache(entry);
 			if (!page) {
 				lock_kernel();
@@ -804,10 +770,9 @@
 			}
 			delete_from_swap_cache(page);
 			page = replace_with_highmem(page);
-			lock_kernel();
 			swap_free(entry);
-			unlock_kernel();
-			spin_lock(&shm_lock);
+			if(shp != shm_lock(shp->id))
+				BUG();
 			shm_swp--;
 		}
 		shm_rss++;
@@ -818,7 +783,7 @@
 
 	/* pte_val(pte) == SHM_ENTRY (shp, idx) */
 	get_page(pte_page(pte));
-	spin_unlock(&shm_lock);
+	shm_unlock(shp->id);
 	up(&shp->sem);
 	current->min_flt++;
 	return pte_page(pte);
@@ -859,13 +824,13 @@
 	}
 	unlock_kernel();
 
-	spin_lock(&shm_lock);
- check_id:
-	shp = shm_segs[swap_id];
-	if (shp == IPC_UNUSED || shp == IPC_NOID || shp->u.shm_perm.mode & SHM_LOCKED ) {
- next_id:
+	shm_lockall();
+check_id:
+	shp = shm_get(swap_id);
+	if(shp==NULL || shp->u.shm_perm.mode & SHM_LOCKED) {
+next_id:
 		swap_idx = 0;
-		if (++swap_id > max_shmid) {
+		if (++swap_id > shm_ids.max_id) {
 			swap_id = 0;
 			if (loop)
 				goto failed;
@@ -875,7 +840,7 @@
 	}
 	id = swap_id;
 
- check_table:
+check_table:
 	idx = swap_idx++;
 	if (idx >= shp->shm_npages)
 		goto next_id;
@@ -892,14 +857,13 @@
 
 	if (--counter < 0) { /* failed */
 failed:
-		spin_unlock(&shm_lock);
-		lock_kernel();
+		shm_unlockall();
 		__swap_free(swap_entry, 2);
-		unlock_kernel();
 		return 0;
 	}
 	if (page_count(page_map) != 1)
 		goto check_table;
+
 	if (!(page_map = prepare_highmem_swapout(page_map)))
 		goto failed;
 	SHM_ENTRY (shp, idx) = swp_entry_to_pte(swap_entry);
@@ -913,7 +877,7 @@
 	   NOTE: we just accounted the swap space reference for this
 	   swap cache page at __get_swap_page() time. */
 	add_to_swap_cache(page_map, swap_entry);
-	spin_unlock(&shm_lock);
+	shm_unlockall();
 
 	lock_kernel();
 	rw_swap_page(WRITE, page_map, 0);
@@ -937,11 +901,8 @@
 	shm_rss++;
 
 	shm_swp--;
-	spin_unlock(&shm_lock);
 
-	lock_kernel();
 	swap_free(entry);
-	unlock_kernel();
 }
 
 /*
@@ -951,23 +912,24 @@
 {
 	int i, n;
 
-	spin_lock(&shm_lock);
-	for (i = 0; i <= max_shmid; i++) {
-		struct shmid_kernel *seg = shm_segs[i];
-		if ((seg == IPC_UNUSED) || (seg == IPC_NOID))
+	shm_lockall();
+	for (i = 0; i <= shm_ids.max_id; i++) {
+		struct shmid_kernel *shp = shm_get(i);
+		if(shp==NULL)
 			continue;
-		for (n = 0; n < seg->shm_npages; n++) {
-			if (pte_none(SHM_ENTRY(seg,n)))
+		for (n = 0; n < shp->shm_npages; n++) {
+			if (pte_none(SHM_ENTRY(shp,n)))
 				continue;
-			if (pte_present(SHM_ENTRY(seg,n)))
+			if (pte_present(SHM_ENTRY(shp,n)))
 				continue;
-			if (pte_to_swp_entry(SHM_ENTRY(seg,n)).val == entry.val) {
-				shm_unuse_page(seg, n, entry, page);
-				return;
+			if (pte_to_swp_entry(SHM_ENTRY(shp,n)).val == entry.val) {
+				shm_unuse_page(shp, n, entry, page);
+				goto out;
 			}
 		}
 	}
-	spin_unlock(&shm_lock);
+out:
+	shm_unlockall();
 }
 
 #ifdef CONFIG_PROC_FS
@@ -977,11 +939,12 @@
 	off_t begin = 0;
 	int i, len = 0;
 
-    	len += sprintf(buffer, "       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime\n");
+	down(&shm_ids.sem);
+	len += sprintf(buffer, "       key      shmid perms       size  cpid  lpid nattch   uid   gid  cuid  cgid      atime      dtime      ctime\n");
 
-	spin_lock(&shm_lock);
-    	for(i = 0; i <= max_shmid; i++)
-		if(shm_segs[i] != IPC_UNUSED) {
+    	for(i = 0; i <= shm_ids.max_id; i++) {
+		struct shmid_kernel* shp = shm_lock(i);
+		if(shp!=NULL) {
 #define SMALL_STRING "%10d %10d  %4o %10u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
 #define BIG_STRING   "%10d %10d  %4o %21u %5u %5u  %5d %5u %5u %5u %5u %10lu %10lu %10lu\n"
 			char *format;
@@ -991,20 +954,21 @@
 			else
 				format = BIG_STRING;
 	    		len += sprintf(buffer + len, format,
-			shm_segs[i]->u.shm_perm.key,
-			shm_segs[i]->u.shm_perm.seq * IPCMNI + i,
-			shm_segs[i]->u.shm_perm.mode,
-			shm_segs[i]->u.shm_segsz,
-			shm_segs[i]->u.shm_cpid,
-			shm_segs[i]->u.shm_lpid,
-			shm_segs[i]->u.shm_nattch,
-			shm_segs[i]->u.shm_perm.uid,
-			shm_segs[i]->u.shm_perm.gid,
-			shm_segs[i]->u.shm_perm.cuid,
-			shm_segs[i]->u.shm_perm.cgid,
-			shm_segs[i]->u.shm_atime,
-			shm_segs[i]->u.shm_dtime,
-			shm_segs[i]->u.shm_ctime);
+				shp->u.shm_perm.key,
+				shm_buildid(i, shp->u.shm_perm.seq),
+				shp->u.shm_perm.mode,
+				shp->u.shm_segsz,
+				shp->u.shm_cpid,
+				shp->u.shm_lpid,
+				shp->u.shm_nattch,
+				shp->u.shm_perm.uid,
+				shp->u.shm_perm.gid,
+				shp->u.shm_perm.cuid,
+				shp->u.shm_perm.cgid,
+				shp->u.shm_atime,
+				shp->u.shm_dtime,
+				shp->u.shm_ctime);
+			shm_unlock(i);
 
 			pos += len;
 			if(pos < offset) {
@@ -1014,15 +978,16 @@
 			if(pos > offset + length)
 				goto done;
 		}
+	}
 	*eof = 1;
 done:
+	up(&shm_ids.sem);
 	*start = buffer + (offset - begin);
 	len -= (offset - begin);
 	if(len > length)
 		len = length;
 	if(len < 0)
 		len = 0;
-	spin_unlock(&shm_lock);
 	return len;
 }
 #endif
diff -u --recursive --new-file v2.3.29/linux/ipc/util.c linux/ipc/util.c
--- v2.3.29/linux/ipc/util.c	Thu Nov 11 20:11:54 1999
+++ linux/ipc/util.c	Sat Nov 27 15:27:49 1999
@@ -35,11 +35,12 @@
 {
 	int i;
 	sema_init(&ids->sem,1);
+
+	if(size > IPCMNI)
+		size = IPCMNI;
 	ids->size = size;
 	if(size == 0)
 		return;
-	if(size > IPCMNI)
-		size = IPCMNI;
 
 	ids->in_use = 0;
 	ids->max_id = -1;
@@ -59,9 +60,8 @@
 		ids->size = 0;
 	}
 	ids->ary = SPIN_LOCK_UNLOCKED;
-	for(i=0;i<size;i++) {
+	for(i=0;i<size;i++)
 		ids->entries[i].p = NULL;
-	}
 }
 
 int ipc_findkey(struct ipc_ids* ids, key_t key)
diff -u --recursive --new-file v2.3.29/linux/ipc/util.h linux/ipc/util.h
--- v2.3.29/linux/ipc/util.h	Thu Nov 11 20:11:54 1999
+++ linux/ipc/util.h	Sat Nov 27 15:27:49 1999
@@ -45,6 +45,26 @@
 void* ipc_alloc(int size);
 void ipc_free(void* ptr, int size);
 
+extern inline void ipc_lockall(struct ipc_ids* ids)
+{
+	spin_lock(&ids->ary);
+}
+
+extern inline struct ipc_perm* ipc_get(struct ipc_ids* ids, int id)
+{
+	struct ipc_perm* out;
+	int lid = id % SEQ_MULTIPLIER;
+	if(lid > ids->size)
+		return NULL;
+
+	out = ids->entries[lid].p;
+	return out;
+}
+
+extern inline void ipc_unlockall(struct ipc_ids* ids)
+{
+	spin_unlock(&ids->ary);
+}
 extern inline struct ipc_perm* ipc_lock(struct ipc_ids* ids, int id)
 {
 	struct ipc_perm* out;
diff -u --recursive --new-file v2.3.29/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.3.29/linux/kernel/ksyms.c	Tue Nov 23 22:42:21 1999
+++ linux/kernel/ksyms.c	Mon Dec  6 14:47:51 1999
@@ -39,6 +39,7 @@
 #include <linux/iobuf.h>
 #include <linux/console.h>
 #include <linux/poll.h>
+#include <linux/mmzone.h>
 #include <linux/mm.h>
 #include <linux/capability.h>
 
@@ -83,7 +84,7 @@
 EXPORT_SYMBOL(get_options);
 
 /* process memory management */
-EXPORT_SYMBOL(do_mmap);
+EXPORT_SYMBOL(do_mmap_pgoff);
 EXPORT_SYMBOL(do_munmap);
 EXPORT_SYMBOL(do_brk);
 EXPORT_SYMBOL(exit_mm);
@@ -93,8 +94,11 @@
 
 /* internal kernel memory management */
 EXPORT_SYMBOL(__alloc_pages);
+EXPORT_SYMBOL(alloc_pages_node);
 EXPORT_SYMBOL(__free_pages_ok);
-EXPORT_SYMBOL(zonelists);
+#ifndef CONFIG_DISCONTIGMEM
+EXPORT_SYMBOL(contig_page_data);
+#endif
 EXPORT_SYMBOL(kmem_find_general_cachep);
 EXPORT_SYMBOL(kmem_cache_create);
 EXPORT_SYMBOL(kmem_cache_destroy);
@@ -184,7 +188,6 @@
 EXPORT_SYMBOL(block_write_full_page);
 EXPORT_SYMBOL(block_write_partial_page);
 EXPORT_SYMBOL(block_write_cont_page);
-EXPORT_SYMBOL(block_flushpage);
 EXPORT_SYMBOL(generic_file_read);
 EXPORT_SYMBOL(do_generic_file_read);
 EXPORT_SYMBOL(generic_file_write);
@@ -199,7 +202,6 @@
 EXPORT_SYMBOL(posix_unblock_lock);
 EXPORT_SYMBOL(locks_mandatory_area);
 EXPORT_SYMBOL(dput);
-EXPORT_SYMBOL(put_cached_page);
 EXPORT_SYMBOL(is_root_busy);
 EXPORT_SYMBOL(prune_dcache);
 EXPORT_SYMBOL(shrink_dcache_sb);
@@ -212,10 +214,11 @@
 EXPORT_SYMBOL(vfs_rename);
 EXPORT_SYMBOL(__pollwait);
 EXPORT_SYMBOL(ROOT_DEV);
-EXPORT_SYMBOL(add_to_page_cache_unique);
 EXPORT_SYMBOL(__find_get_page);
 EXPORT_SYMBOL(__find_lock_page);
-                        
+EXPORT_SYMBOL(grab_cache_page);
+EXPORT_SYMBOL(read_cache_page);
+
 #if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
 EXPORT_SYMBOL(do_nfsservctl);
 #endif
diff -u --recursive --new-file v2.3.29/linux/kernel/module.c linux/kernel/module.c
--- v2.3.29/linux/kernel/module.c	Tue Nov 23 22:42:21 1999
+++ linux/kernel/module.c	Sat Dec  4 01:29:53 1999
@@ -111,11 +111,9 @@
 	long namelen, error;
 	struct module *mod;
 
+	if (!capable(CAP_SYS_MODULE))
+		return -EPERM;
 	lock_kernel();
-	if (!capable(CAP_SYS_MODULE)) {
-		error = -EPERM;
-		goto err0;
-	}
 	if ((namelen = get_mod_name(name_user, &name)) < 0) {
 		error = namelen;
 		goto err0;
@@ -162,13 +160,13 @@
 {
 	struct module mod_tmp, *mod;
 	char *name, *n_name;
-	long namelen, n_namelen, i, error = -EPERM;
+	long namelen, n_namelen, i, error;
 	unsigned long mod_user_size;
 	struct module_ref *dep;
 
-	lock_kernel();
 	if (!capable(CAP_SYS_MODULE))
-		goto err0;
+		return -EPERM;
+	lock_kernel();
 	if ((namelen = get_mod_name(name_user, &name)) < 0) {
 		error = namelen;
 		goto err0;
@@ -354,13 +352,13 @@
 {
 	struct module *mod, *next;
 	char *name;
-	long error = -EPERM;
+	long error;
 	int something_changed;
 
-	lock_kernel();
 	if (!capable(CAP_SYS_MODULE))
-		goto out;
+		return -EPERM;
 
+	lock_kernel();
 	if (name_user) {
 		if ((error = get_mod_name(name_user, &name)) < 0)
 			goto out;
diff -u --recursive --new-file v2.3.29/linux/kernel/resource.c linux/kernel/resource.c
--- v2.3.29/linux/kernel/resource.c	Tue Nov 23 22:42:21 1999
+++ linux/kernel/resource.c	Sat Nov 27 15:27:49 1999
@@ -13,9 +13,10 @@
 #include <linux/init.h>
 #include <linux/malloc.h>
 #include <linux/spinlock.h>
+#include <asm/io.h>
 
-struct resource ioport_resource = { "PCI IO", 0x0000, 0xFFFF, IORESOURCE_IO };
-struct resource iomem_resource = { "PCI mem", 0x00000000, 0xFFFFFFFF, IORESOURCE_MEM };
+struct resource ioport_resource = { "PCI IO", 0x0000, IO_SPACE_LIMIT, IORESOURCE_IO };
+struct resource iomem_resource = { "PCI mem", 0x00000000, 0xffffffff, IORESOURCE_MEM };
 
 static rwlock_t resource_lock = RW_LOCK_UNLOCKED;
 
@@ -126,31 +127,32 @@
 static int find_resource(struct resource *root, struct resource *new,
 			 unsigned long size,
 			 unsigned long min, unsigned long max,
-			 unsigned long align, struct pci_dev * dev)
+			 unsigned long align,
+			 void (*alignf)(void *, struct resource *, unsigned long),
+			 void *alignf_data)
 {
 	struct resource *this = root->child;
-	unsigned long start, end;
 
-	start = root->start;
+	new->start = root->start;
 	for(;;) {
 		if (this)
-			end = this->start;
+			new->end = this->start;
 		else
-			end = root->end;
-		if (start < min)
-			start = min;
-		if (end > max)
-			end = max;
-		start = (start + align - 1) & ~(align - 1);
-		start = resource_fixup (dev, new, start, size);
-		if (start < end && end - start + 1 >= size) {
-			new->start = start;
-			new->end = start + size - 1;
+			new->end = root->end;
+		if (new->start < min)
+			new->start = min;
+		if (new->end > max)
+			new->end = max;
+		new->start = (new->start + align - 1) & ~(align - 1);
+		if (alignf)
+			alignf(alignf_data, new, size);
+		if (new->start < new->end && new->end - new->start + 1 >= size) {
+			new->end = new->start + size - 1;
 			return 0;
 		}
 		if (!this)
 			break;
-		start = this->end + 1;
+		new->start = this->end + 1;
 		this = this->sibling;
 	}
 	return -EBUSY;
@@ -162,12 +164,14 @@
 int allocate_resource(struct resource *root, struct resource *new,
 		      unsigned long size,
 		      unsigned long min, unsigned long max,
-		      unsigned long align, struct pci_dev * dev)
+		      unsigned long align,
+		      void (*alignf)(void *, struct resource *, unsigned long),
+		      void *alignf_data)
 {
 	int err;
 
 	write_lock(&resource_lock);
-	err = find_resource(root, new, size, min, max, align, dev);
+	err = find_resource(root, new, size, min, max, align, alignf, alignf_data);
 	if (err >= 0 && __request_resource(root, new))
 		err = -EBUSY;
 	write_unlock(&resource_lock);
diff -u --recursive --new-file v2.3.29/linux/kernel/sched.c linux/kernel/sched.c
--- v2.3.29/linux/kernel/sched.c	Tue Nov 23 22:42:21 1999
+++ linux/kernel/sched.c	Sat Nov 27 15:46:24 1999
@@ -254,10 +254,11 @@
 	 * wakeup, the frequent rescheduler will likely chose this
 	 * task during it's next schedule():
 	 */
-	tsk = cpu_curr(best_cpu);
- 	if ((p->avg_slice < cacheflush_time) &&
-			(tsk->avg_slice < cacheflush_time))
-		goto out_no_target;
+	if (p->policy == SCHED_OTHER) {
+		tsk = cpu_curr(best_cpu);
+		if (p->avg_slice + tsk->avg_slice < cacheflush_time)
+			goto out_no_target;
+	}
 
 	/*
 	 * We know that the preferred CPU has a cache-affine current
@@ -1006,7 +1007,7 @@
 	}
 }
 
-spinlock_t tqueue_lock;
+spinlock_t tqueue_lock = SPIN_LOCK_UNLOCKED;
 
 void tqueue_bh(void)
 {
diff -u --recursive --new-file v2.3.29/linux/kernel/sysctl.c linux/kernel/sysctl.c
--- v2.3.29/linux/kernel/sysctl.c	Tue Nov 23 22:42:21 1999
+++ linux/kernel/sysctl.c	Mon Dec  6 17:09:24 1999
@@ -49,7 +49,9 @@
 extern int sg_big_buff;
 #endif
 #ifdef CONFIG_SYSVIPC
-extern size_t shm_prm[];
+extern size_t shm_ctlmax;
+extern int shm_ctlall;
+extern int shm_ctlmni;
 extern int msg_ctlmax;
 extern int msg_ctlmnb;
 extern int msg_ctlmni;
@@ -133,10 +135,8 @@
 	NULL,		/* get_block */
 	NULL,		/* readpage */
 	NULL,		/* writepage */
-	NULL,		/* flushpage */
 	NULL,		/* truncate */
 	proc_sys_permission, /* permission */
-	NULL,		/* smap */
 	NULL		/* revalidate */
 };
 
@@ -217,8 +217,12 @@
 	{KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int),
 	 0644, NULL, &proc_dointvec},
 #ifdef CONFIG_SYSVIPC
-	{KERN_SHMMAX, "shmmax", &shm_prm, 3*sizeof (size_t),
+	{KERN_SHMMAX, "shmmax", &shm_ctlmax, sizeof (size_t),
 	 0644, NULL, &proc_doulongvec_minmax},
+	{KERN_SHMALL, "shmall", &shm_ctlall, sizeof (int),
+	 0644, NULL, &proc_dointvec},
+	{KERN_SHMMNI, "shmmni", &shm_ctlmni, sizeof (int),
+	 0644, NULL, &proc_dointvec},
 	{KERN_MSGMAX, "msgmax", &msg_ctlmax, sizeof (int),
 	 0644, NULL, &proc_dointvec},
 	{KERN_MSGMNI, "msgmni", &msg_ctlmni, sizeof (int),
@@ -351,7 +355,7 @@
 }
 
 /* Like in_group_p, but testing against egid, not fsgid */
-static int in_egroup_p(gid_t grp)
+int in_egroup_p(gid_t grp)
 {
 	if (grp != current->egid) {
 		int i = current->ngroups;
diff -u --recursive --new-file v2.3.29/linux/mm/Makefile linux/mm/Makefile
--- v2.3.29/linux/mm/Makefile	Fri Oct 22 13:21:55 1999
+++ linux/mm/Makefile	Mon Dec  6 10:14:13 1999
@@ -10,7 +10,7 @@
 O_TARGET := mm.o
 O_OBJS	 := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
 	    vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \
-	    page_alloc.o swap_state.o swapfile.o
+	    page_alloc.o swap_state.o swapfile.o numa.o
 
 ifeq ($(CONFIG_HIGHMEM),y)
 O_OBJS += highmem.o
diff -u --recursive --new-file v2.3.29/linux/mm/bootmem.c linux/mm/bootmem.c
--- v2.3.29/linux/mm/bootmem.c	Tue Nov 23 22:42:21 1999
+++ linux/mm/bootmem.c	Mon Dec  6 10:14:13 1999
@@ -2,6 +2,7 @@
  *  linux/mm/initmem.c
  *
  *  Copyright (C) 1999 Ingo Molnar
+ *  Discontiguous memory support, Kanoj Sarcar, SGI, Nov 1999
  *
  *  simple boot-time physical memory area allocator and
  *  free memory collector. It's used to deal with reserved
@@ -15,62 +16,75 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/mmzone.h>
 #include <asm/dma.h>
 
 /*
- * Pointer to a bitmap - the bits represent all physical memory pages
- * from physical address 0 to physical address end_mem.
- *
  * Access to this subsystem has to be serialized externally. (this is
  * true for the boot process anyway)
  */
 unsigned long max_low_pfn;
 
-static void * bootmem_map = NULL;
+/* return the number of _pages_ that will be allocated for the boot bitmap */
+unsigned long __init bootmem_bootmap_pages (unsigned long pages)
+{
+	unsigned long mapsize;
+
+	mapsize = (pages+7)/8;
+	mapsize = (mapsize + ~PAGE_MASK) & PAGE_MASK;
+	mapsize >>= PAGE_SHIFT;
+
+	return mapsize;
+}
 
 /*
  * Called once to set up the allocator itself.
  */
-unsigned long __init init_bootmem (unsigned long start, unsigned long pages)
+static unsigned long __init init_bootmem_core (bootmem_data_t *bdata,
+	unsigned long mapstart, unsigned long start, unsigned long end)
 {
-	unsigned long mapsize = (pages+7)/8;
+	unsigned long mapsize = ((end - start)+7)/8;
 
-	bootmem_map = phys_to_virt(start << PAGE_SHIFT);
-	max_low_pfn = pages;
+	bdata->node_bootmem_map = phys_to_virt(mapstart << PAGE_SHIFT);
+	bdata->node_boot_start = (start << PAGE_SHIFT);
+	bdata->node_low_pfn = end;
 
 	/*
 	 * Initially all pages are reserved - setup_arch() has to
 	 * register free RAM areas explicitly.
 	 */
-	memset(bootmem_map, 0xff, mapsize);
+	memset(bdata->node_bootmem_map, 0xff, mapsize);
 
 	return mapsize;
 }
 
 /*
- * Marks a particular physical memory range as usable. Usable RAM
+ * Marks a particular physical memory range as unallocatable. Usable RAM
  * might be used for boot-time allocations - or it might get added
  * to the free page pool later on.
  */
-void __init reserve_bootmem (unsigned long addr, unsigned long size)
+static void __init reserve_bootmem_core(bootmem_data_t *bdata, unsigned long addr, unsigned long size)
 {
 	unsigned long i;
 	/*
 	 * round up, partially reserved pages are considered
 	 * fully reserved.
 	 */
+	unsigned long sidx = (addr - bdata->node_boot_start)/PAGE_SIZE;
+	unsigned long eidx = (addr + size - bdata->node_boot_start + 
+							PAGE_SIZE-1)/PAGE_SIZE;
 	unsigned long end = (addr + size + PAGE_SIZE-1)/PAGE_SIZE;
 
 	if (!size) BUG();
 
-	if (end > max_low_pfn)
+	if (end > bdata->node_low_pfn)
 		BUG();
-	for (i = addr/PAGE_SIZE; i < end; i++)
-		if (test_and_set_bit(i, bootmem_map))
+	for (i = sidx; i < eidx; i++)
+		if (test_and_set_bit(i, bdata->node_bootmem_map))
 			BUG();
 }
 
-void __init free_bootmem (unsigned long addr, unsigned long size)
+static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr, unsigned long size)
 {
 	unsigned long i;
 	unsigned long start;
@@ -78,19 +92,22 @@
 	 * round down end of usable mem, partially free pages are
 	 * considered reserved.
 	 */
+	unsigned long sidx;
+	unsigned long eidx = (addr + size - bdata->node_boot_start)/PAGE_SIZE;
 	unsigned long end = (addr + size)/PAGE_SIZE;
 
 	if (!size) BUG();
-	if (end > max_low_pfn)
+	if (end > bdata->node_low_pfn)
 		BUG();
 
 	/*
 	 * Round up the beginning of the address.
 	 */
 	start = (addr + PAGE_SIZE-1) / PAGE_SIZE;
+	sidx = start - (bdata->node_boot_start/PAGE_SIZE);
 
-	for (i = start; i < end; i++) {
-		if (!test_and_clear_bit(i, bootmem_map))
+	for (i = sidx; i < eidx; i++) {
+		if (!test_and_clear_bit(i, bdata->node_bootmem_map))
 			BUG();
 	}
 }
@@ -104,19 +121,20 @@
  *
  * On low memory boxes we get it right in 100% of the cases.
  */
-static unsigned long last_pos = 0;
-static unsigned long last_offset = 0;
 
 /*
  * alignment has to be a power of 2 value.
  */
-void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal)
+static void * __init __alloc_bootmem_core (bootmem_data_t *bdata, 
+	unsigned long size, unsigned long align, unsigned long goal)
 {
 	int area = 0;
 	unsigned long i, start = 0, reserved;
 	void *ret;
 	unsigned long offset, remaining_size;
 	unsigned long areasize, preferred;
+	unsigned long eidx = bdata->node_low_pfn - (bdata->node_boot_start >>
+							PAGE_SHIFT);
 
 	if (!size) BUG();
 
@@ -124,18 +142,17 @@
 	 * We try to allocate bootmem pages above 'goal'
 	 * first, then we try to allocate lower pages.
 	 */
-	if (goal) {
-		preferred = goal >> PAGE_SHIFT;
-		if (preferred >= max_low_pfn)
-			preferred = 0;
+	if (goal && (goal >= bdata->node_boot_start) && 
+			((goal >> PAGE_SHIFT) < bdata->node_low_pfn)) {
+		preferred = (goal - bdata->node_boot_start) >> PAGE_SHIFT;
 	} else
 		preferred = 0;
 
 	areasize = (size+PAGE_SIZE-1)/PAGE_SIZE;
 
 restart_scan:
-	for (i = preferred; i < max_low_pfn; i++) {
-		reserved = test_bit(i, bootmem_map);
+	for (i = preferred; i < eidx; i++) {
+		reserved = test_bit(i, bdata->node_bootmem_map);
 		if (!reserved) {
 			if (!area) {
 				area = 1;
@@ -157,7 +174,7 @@
 	 */
 	BUG();
 found:
-	if (start >= max_low_pfn)
+	if (start >= eidx)
 		BUG();
 
 	/*
@@ -165,8 +182,8 @@
 	 * of this allocation's buffer? If yes then we can 'merge'
 	 * the previous partial page with this allocation.
 	 */
-	if (last_offset && (last_pos+1 == start)) {
-		offset = (last_offset+align-1) & ~(align-1);
+	if (bdata->last_offset && (bdata->last_pos+1 == start)) {
+		offset = (bdata->last_offset+align-1) & ~(align-1);
 		if (offset > PAGE_SIZE)
 			BUG();
 		remaining_size = PAGE_SIZE-offset;
@@ -175,46 +192,50 @@
 		if (size < remaining_size) {
 			areasize = 0;
 			// last_pos unchanged
-			last_offset = offset+size;
-			ret = phys_to_virt(last_pos*PAGE_SIZE + offset);
+			bdata->last_offset = offset+size;
+			ret = phys_to_virt(bdata->last_pos*PAGE_SIZE + offset +
+						bdata->node_boot_start);
 		} else {
 			remaining_size = size - remaining_size;
 			areasize = (remaining_size+PAGE_SIZE-1)/PAGE_SIZE;
-			ret = phys_to_virt(last_pos*PAGE_SIZE + offset);
-			last_pos = start+areasize-1;
-			last_offset = remaining_size;
+			ret = phys_to_virt(bdata->last_pos*PAGE_SIZE + offset +
+						bdata->node_boot_start);
+			bdata->last_pos = start+areasize-1;
+			bdata->last_offset = remaining_size;
 		}
- 		last_offset &= ~PAGE_MASK;
+ 		bdata->last_offset &= ~PAGE_MASK;
 	} else {
-		last_pos = start + areasize - 1;
-		last_offset = size & ~PAGE_MASK;
-		ret = phys_to_virt(start * PAGE_SIZE);
+		bdata->last_pos = start + areasize - 1;
+		bdata->last_offset = size & ~PAGE_MASK;
+		ret = phys_to_virt(start * PAGE_SIZE + bdata->node_boot_start);
 	}
 	/*
 	 * Reserve the area now:
 	 */
 	for (i = start; i < start+areasize; i++)
-		if (test_and_set_bit(i, bootmem_map))
+		if (test_and_set_bit(i, bdata->node_bootmem_map))
 			BUG();
 	memset(ret, 0, size);
 	return ret;
 }
 
-unsigned long __init free_all_bootmem (void)
+static unsigned long __init free_all_bootmem_core(int nid, bootmem_data_t *bdata)
 {
 	struct page * page;
 	unsigned long i, count, total = 0;
+	unsigned long idx;
 
-	if (!bootmem_map) BUG();
+	if (!bdata->node_bootmem_map) BUG();
 
-	page = mem_map;
+	page = NODE_MEM_MAP(nid);
 	count = 0;
-	for (i = 0; i < max_low_pfn; i++, page++) {
-		if (!test_bit(i, bootmem_map)) {
+	idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
+	for (i = 0; i < idx; i++, page++) {
+		if (!test_bit(i, bdata->node_bootmem_map)) {
 			count++;
 			ClearPageReserved(page);
 			set_page_count(page, 1);
-			if (i >= (virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT))
+			if ((i+(bdata->node_boot_start >> PAGE_SHIFT)) >= (virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT))
 				clear_bit(PG_DMA, &page->flags);
 			__free_page(page);
 		}
@@ -225,16 +246,72 @@
 	 * Now free the allocator bitmap itself, it's not
 	 * needed anymore:
 	 */
-	page = mem_map + MAP_NR(bootmem_map);
+	page = mem_map + MAP_NR(bdata->node_bootmem_map);
 	count = 0;
-	for (i = 0; i < (max_low_pfn/8 + PAGE_SIZE-1)/PAGE_SIZE; i++,page++) {
+	for (i = 0; i < ((bdata->node_low_pfn-(bdata->node_boot_start >> PAGE_SHIFT))/8 + PAGE_SIZE-1)/PAGE_SIZE; i++,page++) {
 		count++;
 		ClearPageReserved(page);
 		set_page_count(page, 1);
 		__free_page(page);
 	}
 	total += count;
-	bootmem_map = NULL;
+	bdata->node_bootmem_map = NULL;
 
 	return total;
 }
+
+unsigned long __init init_bootmem_node (int nid, unsigned long freepfn, unsigned long startpfn, unsigned long endpfn)
+{
+	return(init_bootmem_core(NODE_DATA(nid)->bdata, freepfn, startpfn, endpfn));
+}
+
+void __init reserve_bootmem_node (int nid, unsigned long physaddr, unsigned long size)
+{
+	reserve_bootmem_core(NODE_DATA(nid)->bdata, physaddr, size);
+}
+
+void __init free_bootmem_node (int nid, unsigned long physaddr, unsigned long size)
+{
+	return(free_bootmem_core(NODE_DATA(nid)->bdata, physaddr, size));
+}
+
+unsigned long __init free_all_bootmem_node (int nid)
+{
+	return(free_all_bootmem_core(nid, NODE_DATA(nid)->bdata));
+}
+
+unsigned long __init init_bootmem (unsigned long start, unsigned long pages)
+{
+	max_low_pfn = pages;
+	return(init_bootmem_core(NODE_DATA(0)->bdata, start, 0, pages));
+}
+
+void __init reserve_bootmem (unsigned long addr, unsigned long size)
+{
+	reserve_bootmem_core(NODE_DATA(0)->bdata, addr, size);
+}
+
+void __init free_bootmem (unsigned long addr, unsigned long size)
+{
+	return(free_bootmem_core(NODE_DATA(0)->bdata, addr, size));
+}
+
+unsigned long __init free_all_bootmem (void)
+{
+	return(free_all_bootmem_core(0, NODE_DATA(0)->bdata));
+}
+
+void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal)
+{
+	/*
+	 * In the discontigmem case, all non-node specific allocations come 
+	 * from the first node, node 0.
+	 */
+	return(__alloc_bootmem_core(NODE_DATA(0)->bdata, size, align, goal));
+}
+
+void * __init __alloc_bootmem_node (int nid, unsigned long size, unsigned long align, unsigned long goal)
+{
+	return(__alloc_bootmem_core(NODE_DATA(nid)->bdata, size, align, goal));
+}
+
diff -u --recursive --new-file v2.3.29/linux/mm/filemap.c linux/mm/filemap.c
--- v2.3.29/linux/mm/filemap.c	Tue Nov 23 22:42:21 1999
+++ linux/mm/filemap.c	Mon Dec  6 17:18:46 1999
@@ -124,13 +124,14 @@
  * Truncate the page cache at a set offset, removing the pages
  * that are beyond that offset (and zeroing out partial pages).
  */
-void truncate_inode_pages(struct inode * inode, unsigned long start)
+void truncate_inode_pages(struct inode * inode, loff_t lstart)
 {
 	struct list_head *head, *curr;
 	struct page * page;
-	unsigned partial = start & (PAGE_CACHE_SIZE - 1);
+	unsigned partial = lstart & (PAGE_CACHE_SIZE - 1);
+	unsigned long start;
 
-	start = (start + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	start = (lstart + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 
 repeat:
 	head = &inode->i_data.pages;
@@ -151,8 +152,7 @@
 
 			lock_page(page);
 
-			if (!inode->i_op->flushpage ||
-			    inode->i_op->flushpage(inode, page, 0))
+			if (!page->buffers || block_flushpage(page, 0))
 				lru_cache_del(page);
 
 			/*
@@ -195,8 +195,8 @@
 		lock_page(page);
 
 		memclear_highpage_flush(page, partial, PAGE_CACHE_SIZE-partial);
-		if (inode->i_op->flushpage)
-			inode->i_op->flushpage(inode, page, partial);
+		if (page->buffers)
+			block_flushpage(page, partial);
 
 		partial = 0;
 
@@ -303,7 +303,6 @@
 
 		/* is it a page-cache page? */
 		if (page->mapping) {
-			dispose = &old;
 			if (!pgcache_under_min())
 			{
 				remove_page_from_inode_queue(page);
@@ -456,10 +455,8 @@
  * Two-stage data sync: first start the IO, then go back and
  * collect the information..
  */
-int generic_buffer_fdatasync(struct inode *inode, unsigned long start, unsigned long end)
+int generic_buffer_fdatasync(struct inode *inode, unsigned long start_idx, unsigned long end_idx)
 {
-	unsigned long start_idx = start >> PAGE_CACHE_SHIFT;
-	unsigned long end_idx = (end + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 	int retval;
 
 	retval = do_buffer_fdatasync(inode, start_idx, end_idx, writeout_one_page);
@@ -497,7 +494,7 @@
 	spin_unlock(&pagecache_lock);
 }
 
-int add_to_page_cache_unique(struct page * page,
+static int add_to_page_cache_unique(struct page * page,
 	struct address_space *mapping, unsigned long offset,
 	struct page **hash)
 {
@@ -538,7 +535,7 @@
 		return -ENOMEM;
 
 	if (!add_to_page_cache_unique(page, &inode->i_data, offset, hash)) {
-		int error = inode->i_op->readpage(file, page);
+		int error = inode->i_op->readpage(file->f_dentry, page);
 		page_cache_release(page);
 		return error;
 	}
@@ -1075,7 +1072,7 @@
 
 readpage:
 		/* ... and start the actual read. The read will unlock the page. */
-		error = inode->i_op->readpage(filp, page);
+		error = inode->i_op->readpage(filp->f_dentry, page);
 
 		if (!error) {
 			if (Page_Uptodate(page))
@@ -1397,7 +1394,7 @@
 		goto success;
 	}
 
-	if (!inode->i_op->readpage(file, page)) {
+	if (!inode->i_op->readpage(file->f_dentry, page)) {
 		wait_on_page(page);
 		if (Page_Uptodate(page))
 			goto success;
@@ -1415,7 +1412,7 @@
 		goto success;
 	}
 	ClearPageError(page);
-	if (!inode->i_op->readpage(file, page)) {
+	if (!inode->i_op->readpage(file->f_dentry, page)) {
 		wait_on_page(page);
 		if (Page_Uptodate(page))
 			goto success;
@@ -1434,33 +1431,30 @@
  * if the disk is full.
  */
 static inline int do_write_page(struct inode * inode, struct file * file,
-	struct page * page, unsigned long offset)
+	struct page * page, unsigned long index)
 {
 	int retval;
-	unsigned long size;
-	int (*writepage) (struct file *, struct page *);
+	int (*writepage) (struct dentry *, struct page *);
 
-	size = (offset << PAGE_CACHE_SHIFT) + PAGE_CACHE_SIZE;
 	/* refuse to extend file size.. */
 	if (S_ISREG(inode->i_mode)) {
-		if (size > inode->i_size)
-			size = inode->i_size;
+		unsigned long size_idx = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+
 		/* Ho humm.. We should have tested for this earlier */
-		if (size < offset)
+		if (size_idx <= index)
 			return -EIO;
 	}
-	retval = -EIO;
 	writepage = inode->i_op->writepage;
 	lock_page(page);
 
-	retval = writepage(file, page);
+	retval = writepage(file->f_dentry, page);
 
 	UnlockPage(page);
 	return retval;
 }
 
 static int filemap_write_page(struct file *file,
-			      unsigned long offset,
+			      unsigned long index,
 			      struct page * page,
 			      int wait)
 {
@@ -1477,7 +1471,7 @@
 	 * vma/file is guaranteed to exist in the unmap/sync cases because
 	 * mmap_sem is held.
 	 */
-	result = do_write_page(inode, file, page, offset);
+	result = do_write_page(inode, file, page, index);
 	return result;
 }
 
@@ -1767,6 +1761,70 @@
 	return error;
 }
 
+struct page *read_cache_page(struct address_space *mapping,
+				unsigned long index,
+				int (*filler)(void *,struct page*),
+				void *data)
+{
+	struct page **hash = page_hash(mapping, index);
+	struct page *page, *cached_page = NULL;
+	int err;
+repeat:
+	page = __find_get_page(mapping, index, hash);
+	if (!page) {
+		if (!cached_page) {
+			cached_page = page_cache_alloc();
+			if (!cached_page)
+				return ERR_PTR(-ENOMEM);
+		}
+		page = cached_page;
+		if (add_to_page_cache_unique(page, mapping, index, hash))
+			goto repeat;
+		cached_page = NULL;
+		err = filler(data, page);
+		if (err < 0) {
+			page_cache_release(page);
+			page = ERR_PTR(err);
+		}
+	}
+	if (cached_page)
+		page_cache_free(cached_page);
+	return page;
+}
+
+static inline struct page * __grab_cache_page(struct address_space *mapping,
+				unsigned long index, struct page **cached_page)
+{
+	struct page *page, **hash = page_hash(mapping, index);
+repeat:
+	page = __find_lock_page(mapping, index, hash);
+	if (!page) {
+		if (!*cached_page) {
+			*cached_page = page_cache_alloc();
+			if (!*cached_page)
+				return NULL;
+		}
+		page = *cached_page;
+		if (add_to_page_cache_unique(page, mapping, index, hash))
+			goto repeat;
+		*cached_page = NULL;
+	}
+	return page;
+}
+
+/*
+ * Returns locked page at given index in given cache, creating it if needed.
+ */
+
+struct page *grab_cache_page(struct address_space *mapping, unsigned long index)
+{
+	struct page *cached_page = NULL;
+	struct page *page = __grab_cache_page(mapping,index,&cached_page);
+	if (cached_page)
+		page_cache_free(cached_page);
+	return page;
+}
+
 /*
  * Write to a file through the page cache. This is mainly for the
  * benefit of NFS and possibly other network-based file systems.
@@ -1792,7 +1850,7 @@
 	struct inode	*inode = dentry->d_inode; 
 	unsigned long	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
 	loff_t		pos;
-	struct page	*page, **hash, *cached_page;
+	struct page	*page, *cached_page;
 	unsigned long	written;
 	long		status;
 	int		err;
@@ -1847,23 +1905,10 @@
 		if (bytes > count)
 			bytes = count;
 
-		hash = page_hash(&inode->i_data, index);
-repeat_find:
-		page = __find_lock_page(&inode->i_data, index, hash);
-		if (!page) {
-			if (!cached_page) {
-				cached_page = page_cache_alloc();
-				if (cached_page)
-					goto repeat_find;
-				status = -ENOMEM;
-				break;
-			}
-			page = cached_page;
-			if (add_to_page_cache_unique(page, &inode->i_data, index, hash))
-				goto repeat_find;
-
-			cached_page = NULL;
-		}
+		status = -ENOMEM;	/* we'll assign it later anyway */
+		page = __grab_cache_page(&inode->i_data, index, &cached_page);
+		if (!page)
+			break;
 
 		/* We have exclusive IO access to the page.. */
 		if (!PageLocked(page)) {
@@ -1896,24 +1941,6 @@
 out:
 	up(&inode->i_sem);
 	return err;
-}
-
-/*
- * Support routines for directory caching using the page cache.
- */
-
-/*
- * Unlock and free a page.
- */
-void put_cached_page(unsigned long addr)
-{
-	struct page * page = page_cache_entry(addr);
-
-	UnlockPage(page);
-	if (page_count(page) != 2)
-		panic("put_cached_page: page count=%d\n", 
-			page_count(page));
-	page_cache_release(page);
 }
 
 void __init page_cache_init(unsigned long mempages)
diff -u --recursive --new-file v2.3.29/linux/mm/highmem.c linux/mm/highmem.c
--- v2.3.29/linux/mm/highmem.c	Tue Nov 23 22:42:21 1999
+++ linux/mm/highmem.c	Thu Dec  2 19:55:01 1999
@@ -16,7 +16,6 @@
  * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com>
  */
 
-#include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/pagemap.h>
 #include <linux/highmem.h>
@@ -97,7 +96,7 @@
  */
 static int pkmap_count[LAST_PKMAP];
 static unsigned int last_pkmap_nr = 0;
-static spinlock_t kmap_lock;
+static spinlock_t kmap_lock = SPIN_LOCK_UNLOCKED;
 
 pte_t * pkmap_page_table;
 
diff -u --recursive --new-file v2.3.29/linux/mm/memory.c linux/mm/memory.c
--- v2.3.29/linux/mm/memory.c	Tue Nov 23 22:42:21 1999
+++ linux/mm/memory.c	Mon Dec  6 14:47:51 1999
@@ -790,11 +790,19 @@
 	 */
 	switch (page_count(old_page)) {
 	case 2:
-		if (!PageSwapCache(old_page))
+		/*
+		 * Lock the page so that no one can look it up from
+		 * the swap cache, grab a reference and start using it.
+		 * Can not do lock_page, holding page_table_lock.
+		 */
+		if (!PageSwapCache(old_page) || TryLockPage(old_page))
 			break;
-		if (swap_count(old_page) != 1)
+		if (is_page_shared(old_page)) {
+			UnlockPage(old_page);
 			break;
-		delete_from_swap_cache(old_page);
+		}
+		delete_from_swap_cache_nolock(old_page);
+		UnlockPage(old_page);
 		/* FallThrough */
 	case 1:
 		flush_cache_page(vma, address);
@@ -885,7 +893,7 @@
  * between the file and the memory map for a potential last
  * incomplete page.  Ugly, but necessary.
  */
-void vmtruncate(struct inode * inode, unsigned long offset)
+void vmtruncate(struct inode * inode, loff_t offset)
 {
 	unsigned long partial, pgoff;
 	struct vm_area_struct * mpnt;
@@ -895,10 +903,8 @@
 	if (!inode->i_mmap)
 		goto out_unlock;
 
-	partial = offset & (PAGE_CACHE_SIZE - 1);
-	pgoff = offset >> PAGE_CACHE_SHIFT;
-	if (partial)
-		pgoff ++;
+	pgoff = (offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+	partial = (unsigned long)offset & (PAGE_CACHE_SIZE - 1);
 
 	mpnt = inode->i_mmap;
 	do {
@@ -947,33 +953,28 @@
  */
 void swapin_readahead(swp_entry_t entry)
 {
-	int i;
+	int i, num;
 	struct page *new_page;
-	unsigned long offset = SWP_OFFSET(entry);
-	struct swap_info_struct *swapdev = SWP_TYPE(entry) + swap_info;
-	
-	offset = (offset >> page_cluster) << page_cluster;
+	unsigned long offset;
 
-	i = 1 << page_cluster;
-	do {
-		/* Don't read-ahead past the end of the swap area */
-		if (offset >= swapdev->max)
-			break;
+	/*
+	 * Get the number of handles we should do readahead io to. Also,
+	 * grab temporary references on them, releasing them as io completes.
+	 */
+	num = valid_swaphandles(entry, &offset);
+	for (i = 0; i < num; offset++, i++) {
 		/* Don't block on I/O for read-ahead */
-		if (atomic_read(&nr_async_pages) >= pager_daemon.swap_cluster)
-			break;
-		/* Don't read in bad or busy pages */
-		if (!swapdev->swap_map[offset])
+		if (atomic_read(&nr_async_pages) >= pager_daemon.swap_cluster) {
+			while (i++ < num)
+				swap_free(SWP_ENTRY(SWP_TYPE(entry), offset++));
 			break;
-		if (swapdev->swap_map[offset] == SWAP_MAP_BAD)
-			break;
-
+		}
 		/* Ok, do the async read-ahead now */
 		new_page = read_swap_cache_async(SWP_ENTRY(SWP_TYPE(entry), offset), 0);
 		if (new_page != NULL)
 			__free_page(new_page);
-		offset++;
-	} while (--i);
+		swap_free(SWP_ENTRY(SWP_TYPE(entry), offset));
+	}
 	return;
 }
 
@@ -981,6 +982,7 @@
 	struct vm_area_struct * vma, unsigned long address,
 	pte_t * page_table, swp_entry_t entry, int write_access)
 {
+	int dograb = 0;
 	struct page *page = lookup_swap_cache(entry);
 	pte_t pte;
 
@@ -997,19 +999,26 @@
 
 	vma->vm_mm->rss++;
 	tsk->min_flt++;
-	lock_kernel();
-	swap_free(entry);
-	unlock_kernel();
 
 	pte = mk_pte(page, vma->vm_page_prot);
 
 	set_bit(PG_swap_entry, &page->flags);
+
+	/*
+	 * Freeze the "shared"ness of the page, ie page_count + swap_count.
+	 * Must lock page before transferring our swap count to already
+	 * obtained page count.
+	 */
+	lock_page(page);
+	swap_free(entry);
 	if (write_access && !is_page_shared(page)) {
-		delete_from_swap_cache(page);
+		delete_from_swap_cache_nolock(page);
 		page = replace_with_highmem(page);
 		pte = mk_pte(page, vma->vm_page_prot);
 		pte = pte_mkwrite(pte_mkdirty(pte));
 	}
+	UnlockPage(page);
+
 	set_pte(page_table, pte);
 	/* No need to invalidate - it was non-present before */
 	update_mmu_cache(vma, address, pte);
diff -u --recursive --new-file v2.3.29/linux/mm/mmap.c linux/mm/mmap.c
--- v2.3.29/linux/mm/mmap.c	Tue Nov 23 22:42:21 1999
+++ linux/mm/mmap.c	Mon Dec  6 14:47:51 1999
@@ -160,8 +160,8 @@
 #undef _trans
 }
 
-unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
-	unsigned long prot, unsigned long flags, unsigned long off)
+unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags, unsigned long pgoff)
 {
 	struct mm_struct * mm = current->mm;
 	struct vm_area_struct * vma;
@@ -176,15 +176,10 @@
 	if (len > TASK_SIZE || addr > TASK_SIZE-len)
 		return -EINVAL;
 
-	if (off & ~PAGE_MASK)
-		return -EINVAL;
-
 	/* offset overflow? */
-	if (off + len < off)
+	if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
 		return -EINVAL;
 
-	off = off >> PAGE_SHIFT;
-
 	/* Too many mappings? */
 	if (mm->map_count > MAX_MAP_COUNT)
 		return -ENOMEM;
@@ -274,7 +269,7 @@
 		vma->vm_flags |= VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
 	vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f];
 	vma->vm_ops = NULL;
-	vma->vm_pgoff = off;
+	vma->vm_pgoff = pgoff;
 	vma->vm_file = NULL;
 	vma->vm_private_data = NULL;
 
diff -u --recursive --new-file v2.3.29/linux/mm/numa.c linux/mm/numa.c
--- v2.3.29/linux/mm/numa.c	Wed Dec 31 16:00:00 1969
+++ linux/mm/numa.c	Mon Dec  6 10:14:13 1999
@@ -0,0 +1,103 @@
+/*
+ * Written by Kanoj Sarcar, SGI, Aug 1999
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/mmzone.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+int numnodes = 1;	/* Initialized for UMA platforms */
+
+#ifndef CONFIG_DISCONTIGMEM
+
+static bootmem_data_t contig_bootmem_data;
+pg_data_t contig_page_data = { bdata: &contig_bootmem_data };
+
+#endif /* !CONFIG_DISCONTIGMEM */
+
+struct page * alloc_pages_node(int nid, int gfp_mask, unsigned long order)
+{
+	return __alloc_pages(NODE_DATA(nid)->node_zonelists + gfp_mask, order);
+}
+
+#ifdef CONFIG_DISCONTIGMEM
+
+#define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
+
+static spinlock_t node_lock = SPIN_LOCK_UNLOCKED;
+
+extern void show_free_areas_core(int);
+extern void __init free_area_init_core(int nid, pg_data_t *pgdat, 
+	struct page **gmap, unsigned int *zones_size, unsigned long paddr);
+
+void show_free_areas_node(int nid)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&node_lock, flags);
+	printk("Memory information for node %d:\n", nid);
+	show_free_areas_core(nid);
+	spin_unlock_irqrestore(&node_lock, flags);
+}
+
+/*
+ * Nodes can be initialized parallely, in no particular order.
+ */
+void __init free_area_init_node(int nid, pg_data_t *pgdat, 
+		unsigned int *zones_size, unsigned long zone_start_paddr)
+{
+	int i, size = 0;
+	struct page *discard;
+
+	if (mem_map == (mem_map_t *)NULL)
+		mem_map = (mem_map_t *)PAGE_OFFSET;
+
+	free_area_init_core(nid, pgdat, &discard, zones_size, zone_start_paddr);
+
+	/*
+	 * Get space for the valid bitmap.
+	 */
+	for (i = 0; i < MAX_NR_ZONES; i++)
+		size += zones_size[i];
+	size = LONG_ALIGN((size + 7) >> 3);
+	pgdat->valid_addr_bitmap = (unsigned long *)alloc_bootmem_node(nid, size);
+	memset(pgdat->valid_addr_bitmap, 0, size);
+}
+
+/*
+ * This can be refined. Currently, tries to do round robin, instead
+ * should do concentratic circle search, starting from current node.
+ */
+struct page * alloc_pages(int gfp_mask, unsigned long order)
+{
+	struct page *ret = 0;
+	unsigned long flags;
+	int startnode, tnode;
+	static int nextnid = 0;
+
+	if (order >= MAX_ORDER)
+		return NULL;
+	spin_lock_irqsave(&node_lock, flags);
+	tnode = nextnid;
+	nextnid++;
+	if (nextnid == numnodes)
+		nextnid = 0;
+	spin_unlock_irqrestore(&node_lock, flags);
+	startnode = tnode;
+	while (tnode < numnodes) {
+		if ((ret = alloc_pages_node(tnode++, gfp_mask, order)))
+			return(ret);
+	}
+	tnode = 0;
+	while (tnode != startnode) {
+		if ((ret = alloc_pages_node(tnode++, gfp_mask, order)))
+			return(ret);
+	}
+	return(0);
+}
+
+#endif /* CONFIG_DISCONTIGMEM */
diff -u --recursive --new-file v2.3.29/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.3.29/linux/mm/page_alloc.c	Tue Nov 23 22:42:21 1999
+++ linux/mm/page_alloc.c	Mon Dec  6 10:14:13 1999
@@ -5,6 +5,7 @@
  *  Swap reorganised 29.12.95, Stephen Tweedie
  *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
  *  Reshaped it to be a zoned allocator, Ingo Molnar, Red Hat, 1999
+ *  Discontiguous memory support, Kanoj Sarcar, SGI, Nov 1999
  */
 
 #include <linux/config.h>
@@ -15,18 +16,18 @@
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
 
+/* Use NUMNODES instead of numnodes for better code inside kernel APIs */
+#ifndef CONFIG_DISCONTIGMEM
+#define NUMNODES 1
+#else
+#define NUMNODES numnodes
+#endif
+
 int nr_swap_pages = 0;
 int nr_lru_pages;
 LIST_HEAD(lru_cache);
 
-static zone_t zones [MAX_NR_ZONES] =
-	{
-		{ name: "DMA" },
-		{ name: "Normal" },
-		{ name: "HighMem" }
-	};
-
-zonelist_t zonelists [NR_GFPINDEX];
+static char *zone_names[MAX_NR_ZONES] = { "DMA", "Normal", "HighMem" };
 
 /*
  * Free_page() adds the page to the free lists. This is optimized for
@@ -351,10 +352,12 @@
 {
 	unsigned int sum;
 	zone_t *zone;
+	int i;
 
 	sum = 0;
-	for (zone = zones; zone < zones + MAX_NR_ZONES; zone++)
-		sum += zone->free_pages;
+	for (i = 0; i < NUMNODES; i++)
+		for (zone = NODE_DATA(i)->node_zones; zone < NODE_DATA(i)->node_zones + MAX_NR_ZONES; zone++)
+			sum += zone->free_pages;
 	return sum;
 }
 
@@ -365,17 +368,24 @@
 {
 	unsigned int sum;
 	zone_t *zone;
+	int i;
 
 	sum = nr_lru_pages;
-	for (zone = zones; zone <= zones+ZONE_NORMAL; zone++)
-		sum += zone->free_pages;
+	for (i = 0; i < NUMNODES; i++)
+		for (zone = NODE_DATA(i)->node_zones; zone <= NODE_DATA(i)->node_zones+ZONE_NORMAL; zone++)
+			sum += zone->free_pages;
 	return sum;
 }
 
 #if CONFIG_HIGHMEM
 unsigned int nr_free_highpages (void)
 {
-	return zones[ZONE_HIGHMEM].free_pages;
+	int i;
+	unsigned int pages = 0;
+
+	for (i = 0; i < NUMNODES; i++)
+		pages += NODE_DATA(i)->node_zones[ZONE_HIGHMEM].free_pages;
+	return pages;
 }
 #endif
 
@@ -384,7 +394,7 @@
  * We also calculate the percentage fragmentation. We do this by counting the
  * memory on each free list with the exception of the first item on the list.
  */
-void show_free_areas(void)
+void show_free_areas_core(int nid)
 {
  	unsigned long order;
 	unsigned type;
@@ -402,7 +412,7 @@
 
 	for (type = 0; type < MAX_NR_ZONES; type++) {
 		struct list_head *head, *curr;
-		zone_t *zone = zones + type;
+		zone_t *zone = NODE_DATA(nid)->node_zones + type;
  		unsigned long nr, total, flags;
 
 		printk("  %s: ", zone->name);
@@ -434,12 +444,15 @@
 #endif	
 }
 
+void show_free_areas(void)
+{
+	show_free_areas_core(0);
+}
+
 /*
- * Builds allocation fallback zone lists. We are basically ready
- * to do NUMA-allocations, only this function has to be modified
- * and the zonelists array be made per-CPU.
+ * Builds allocation fallback zone lists.
  */
-static inline void build_zonelists (void)
+static inline void build_zonelists(pg_data_t *pgdat)
 {
 	int i, j, k;
 
@@ -447,7 +460,7 @@
 		zonelist_t *zonelist;
 		zone_t *zone;
 
-		zonelist = zonelists + i;
+		zonelist = pgdat->node_zonelists + i;
 		memset(zonelist, 0, sizeof(*zonelist));
 
 		zonelist->gfp_mask = i;
@@ -465,7 +478,7 @@
 			 * fallthrough:
 			 */
 			case ZONE_HIGHMEM:
-				zone = zones + ZONE_HIGHMEM;
+				zone = pgdat->node_zones + ZONE_HIGHMEM;
 				if (zone->size) {
 #ifndef CONFIG_HIGHMEM
 					BUG();
@@ -473,11 +486,13 @@
 					zonelist->zones[j++] = zone;
 				}
 			case ZONE_NORMAL:
-				zone = zones + ZONE_NORMAL;
+				zone = pgdat->node_zones + ZONE_NORMAL;
 				if (zone->size)
 					zonelist->zones[j++] = zone;
 			case ZONE_DMA:
-				zonelist->zones[j++] = zones + ZONE_DMA;
+				zone = pgdat->node_zones + ZONE_DMA;
+				if (zone->size)
+					zonelist->zones[j++] = zone;
 		}
 		zonelist->zones[j++] = NULL;
 	} 
@@ -491,9 +506,10 @@
  *   - mark all memory queues empty
  *   - clear the memory bitmaps
  */
-void __init free_area_init(unsigned int *zones_size)
+void __init free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
+	unsigned int *zones_size, unsigned long zone_start_paddr)
 {
-	struct page * p;
+	struct page *p, *lmem_map;
 	unsigned long i, j;
 	unsigned long map_size;
 	unsigned int totalpages, offset;
@@ -503,7 +519,7 @@
 		unsigned long size = zones_size[i];
 		totalpages += size;
 	}
-	printk("totalpages: %08x\n", totalpages);
+	printk("On node %d totalpages: %08x\n", nid, totalpages);
 
 	/*
 	 * Select nr of pages we try to keep free for important stuff
@@ -524,16 +540,22 @@
 	/*
 	 * Some architectures (with lots of mem and discontinous memory
 	 * maps) have to search for a good mem_map area:
+	 * For discontigmem, the conceptual mem map array starts from 
+	 * PAGE_OFFSET, we need to align the actual array onto a mem map 
+	 * boundary, so that MAP_NR works.
 	 */
-	map_size = totalpages*sizeof(struct page);
-	mem_map = (struct page *) alloc_bootmem(map_size);
+	map_size = (totalpages + 1)*sizeof(struct page);
+	lmem_map = (struct page *) alloc_bootmem_node(nid, map_size);
+	lmem_map = (struct page *)(PAGE_OFFSET + 
+			MAP_ALIGN((unsigned long)lmem_map - PAGE_OFFSET));
+	*gmap = pgdat->node_mem_map = lmem_map;
 
 	/*
 	 * Initially all pages are reserved - free ones are freed
 	 * up by free_all_bootmem() once the early boot process is
 	 * done.
 	 */
-	for (p = mem_map; p < mem_map + totalpages; p++) {
+	for (p = lmem_map; p < lmem_map + totalpages; p++) {
 		set_page_count(p, 0);
 		p->flags = (1 << PG_DMA);
 		SetPageReserved(p);
@@ -541,9 +563,9 @@
 		memlist_init(&p->list);
 	}
 
-	offset = 0;	
+	offset = lmem_map - mem_map;	
 	for (j = 0; j < MAX_NR_ZONES; j++) {
-		zone_t *zone = zones + j;
+		zone_t *zone = pgdat->node_zones + j;
 		unsigned long mask = -1;
 		unsigned long size;
 
@@ -551,6 +573,8 @@
 
 		printk("zone(%ld): %ld pages.\n", j, size);
 		zone->size = size;
+		zone->name = zone_names[j];
+		zone->lock = SPIN_LOCK_UNLOCKED;
 		if (!size)
 			continue;
 
@@ -567,8 +591,10 @@
 		for (i = 0; i < size; i++) {
 			struct page *page = mem_map + offset + i;
 			page->zone = zone;
-			if (j != ZONE_HIGHMEM)
-				page->virtual = __page_address(page);
+			if (j != ZONE_HIGHMEM) {
+				page->virtual = (unsigned long)(__va(zone_start_paddr));
+				zone_start_paddr += PAGE_SIZE;
+			}
 		}
 
 		offset += size;
@@ -582,8 +608,13 @@
 			bitmap_size = (bitmap_size + 7) >> 3;
 			bitmap_size = LONG_ALIGN(bitmap_size);
 			zone->free_area[i].map = 
-				(unsigned int *) alloc_bootmem(bitmap_size);
+			  (unsigned int *) alloc_bootmem_node(nid, bitmap_size);
 		}
 	}
-	build_zonelists();
+	build_zonelists(pgdat);
+}
+
+void __init free_area_init(unsigned int *zones_size)
+{
+	free_area_init_core(0, NODE_DATA(0), &mem_map, zones_size, 0);
 }
diff -u --recursive --new-file v2.3.29/linux/mm/page_io.c linux/mm/page_io.c
--- v2.3.29/linux/mm/page_io.c	Mon Nov  1 13:56:27 1999
+++ linux/mm/page_io.c	Thu Dec  2 15:06:20 1999
@@ -35,54 +35,30 @@
 
 static int rw_swap_page_base(int rw, swp_entry_t entry, struct page *page, int wait)
 {
-	unsigned long type, offset;
-	struct swap_info_struct * p;
+	unsigned long offset;
 	int zones[PAGE_SIZE/512];
 	int zones_used;
 	kdev_t dev = 0;
 	int block_size;
-
-	type = SWP_TYPE(entry);
-	if (type >= nr_swapfiles) {
-		printk("Internal error: bad swap-device\n");
-		return 0;
-	}
+	struct inode *swapf = 0;
 
 	/* Don't allow too many pending pages in flight.. */
 	if (atomic_read(&nr_async_pages) > pager_daemon.swap_cluster)
 		wait = 1;
 
-	p = &swap_info[type];
-	offset = SWP_OFFSET(entry);
-	if (offset >= p->max) {
-		printk("rw_swap_page: weirdness\n");
-		return 0;
-	}
-	if (p->swap_map && !p->swap_map[offset]) {
-		printk("VM: Bad swap entry %08lx\n", entry.val);
-		return 0;
-	}
-	if (!(p->flags & SWP_USED)) {
-		printk(KERN_ERR "rw_swap_page: "
-			"Trying to swap to unused swap-device\n");
-		return 0;
-	}
-
 	if (rw == READ) {
 		ClearPageUptodate(page);
 		kstat.pswpin++;
 	} else
 		kstat.pswpout++;
 
-	if (p->swap_device) {
+	get_swaphandle_info(entry, &offset, &dev, &swapf);
+	if (dev) {
 		zones[0] = offset;
 		zones_used = 1;
-		dev = p->swap_device;
 		block_size = PAGE_SIZE;
-	} else if (p->swap_file) {
-		struct inode *swapf = p->swap_file->d_inode;
-		int i;
-		int j;
+	} else if (swapf) {
+		int i, j;
 		unsigned int block = offset
 			<< (PAGE_SHIFT - swapf->i_sb->s_blocksize_bits);
 
@@ -95,7 +71,6 @@
 		zones_used = i;
 		dev = swapf->i_dev;
 	} else {
-		printk(KERN_ERR "rw_swap_page: no swap file or device\n");
 		return 0;
 	}
  	if (!wait) {
diff -u --recursive --new-file v2.3.29/linux/mm/swap.c linux/mm/swap.c
--- v2.3.29/linux/mm/swap.c	Fri Jan  8 22:54:16 1999
+++ linux/mm/swap.c	Mon Dec  6 10:14:13 1999
@@ -30,13 +30,13 @@
  * start background swapping if we fall below freepages.high free
  * pages, and we begin intensive swapping below freepages.low.
  *
- * These values are there to keep GCC from complaining. Actual
- * initialization is done in mm/page_alloc.c or arch/sparc(64)/mm/init.c.
+ * Actual initialization is done in mm/page_alloc.c or 
+ * arch/sparc(64)/mm/init.c.
  */
 freepages_t freepages = {
-	48,	/* freepages.min */
-	96,	/* freepages.low */
-	144	/* freepages.high */
+	0,	/* freepages.min */
+	0,	/* freepages.low */
+	0	/* freepages.high */
 };
 
 /* How many pages do we try to swap or page in/out together? */
diff -u --recursive --new-file v2.3.29/linux/mm/swap_state.c linux/mm/swap_state.c
--- v2.3.29/linux/mm/swap_state.c	Sun Nov  7 16:37:34 1999
+++ linux/mm/swap_state.c	Mon Dec  6 10:19:45 1999
@@ -52,100 +52,13 @@
 	add_to_page_cache(page, &swapper_space, entry.val);
 }
 
-/*
- * Verify that a swap entry is valid and increment its swap map count.
- *
- * Note: if swap_map[] reaches SWAP_MAP_MAX the entries are treated as
- * "permanent", but will be reclaimed by the next swapoff.
- */
-int swap_duplicate(swp_entry_t entry)
-{
-	struct swap_info_struct * p;
-	unsigned long offset, type;
-	int result = 0;
-
-	/* Swap entry 0 is illegal */
-	if (!entry.val)
-		goto out;
-	type = SWP_TYPE(entry);
-	if (type >= nr_swapfiles)
-		goto bad_file;
-	p = type + swap_info;
-	offset = SWP_OFFSET(entry);
-	if (offset >= p->max)
-		goto bad_offset;
-	if (!p->swap_map[offset])
-		goto bad_unused;
-	/*
-	 * Entry is valid, so increment the map count.
-	 */
-	if (p->swap_map[offset] < SWAP_MAP_MAX)
-		p->swap_map[offset]++;
-	else {
-		static int overflow = 0;
-		if (overflow++ < 5)
-			printk("VM: swap entry overflow\n");
-		p->swap_map[offset] = SWAP_MAP_MAX;
-	}
-	result = 1;
-out:
-	return result;
-
-bad_file:
-	printk("Bad swap file entry %08lx\n", entry.val);
-	goto out;
-bad_offset:
-	printk("Bad swap offset entry %08lx\n", entry.val);
-	goto out;
-bad_unused:
-	printk("Unused swap offset entry %08lx\n", entry.val);
-	goto out;
-}
-
-int swap_count(struct page *page)
-{
-	struct swap_info_struct * p;
-	unsigned long offset, type;
-	swp_entry_t entry;
-	int retval = 0;
-
-	entry.val = page->index;
-	if (!entry.val)
-		goto bad_entry;
-	type = SWP_TYPE(entry);
-	if (type >= nr_swapfiles)
-		goto bad_file;
-	p = type + swap_info;
-	offset = SWP_OFFSET(entry);
-	if (offset >= p->max)
-		goto bad_offset;
-	if (!p->swap_map[offset])
-		goto bad_unused;
-	retval = p->swap_map[offset];
-out:
-	return retval;
-
-bad_entry:
-	printk(KERN_ERR "swap_count: null entry!\n");
-	goto out;
-bad_file:
-	printk("Bad swap file entry %08lx\n", entry.val);
-	goto out;
-bad_offset:
-	printk("Bad swap offset entry %08lx\n", entry.val);
-	goto out;
-bad_unused:
-	printk("Unused swap offset entry %08lx\n", entry.val);
-	goto out;
-}
-
 static inline void remove_from_swap_cache(struct page *page)
 {
 	struct address_space *mapping = page->mapping;
 
 	if (mapping != &swapper_space)
 		BUG();
-	if (!PageSwapCache(page))
+	if (!PageSwapCache(page) || !PageLocked(page))
 		PAGE_BUG(page);
 
 	PageClearSwapCache(page);
@@ -166,49 +79,49 @@
 	swap_cache_del_total++;
 #endif
 	remove_from_swap_cache(page);
-	lock_kernel();
 	swap_free(entry);
-	unlock_kernel();
 }
 
-static void delete_from_swap_cache_nolock(struct page *page)
+/*
+ * This will never put the page into the free list, the caller has
+ * a reference on the page.
+ */
+void delete_from_swap_cache_nolock(struct page *page)
 {
-	if (block_flushpage(NULL, page, 0))
+	if (block_flushpage(page, 0))
 		lru_cache_del(page);
 
 	__delete_from_swap_cache(page);
+	page_cache_release(page);
 }
 
 /*
  * This must be called only on pages that have
- * been verified to be in the swap cache.
+ * been verified to be in the swap cache and locked.
  */
 void delete_from_swap_cache(struct page *page)
 {
 	lock_page(page);
-
 	delete_from_swap_cache_nolock(page);
-
 	UnlockPage(page);
-	page_cache_release(page);
 }
 
 /* 
  * Perform a free_page(), also freeing any swap cache associated with
- * this page if it is the last user of the page. 
+ * this page if it is the last user of the page. Can not do a lock_page,
+ * as we are holding the page_table_lock spinlock.
  */
-
 void free_page_and_swap_cache(struct page *page)
 {
 	/* 
-	 * If we are the only user, then free up the swap cache. 
+	 * If we are the only user, then try to free up the swap cache. 
 	 */
-	lock_page(page);
-	if (PageSwapCache(page) && !is_page_shared(page)) {
-		delete_from_swap_cache_nolock(page);
-		page_cache_release(page);
+	if (PageSwapCache(page) && !TryLockPage(page)) {
+		if (!is_page_shared(page)) {
+			delete_from_swap_cache_nolock(page);
+		}
+		UnlockPage(page);
 	}
-	UnlockPage(page);
 	
 	clear_bit(PG_swap_entry, &page->flags);
 
@@ -234,10 +147,24 @@
 		/*
 		 * Right now the pagecache is 32-bit only.  But it's a 32 bit index. =)
 		 */
+repeat:
 		found = find_lock_page(&swapper_space, entry.val);
 		if (!found)
 			return 0;
-		if (found->mapping != &swapper_space || !PageSwapCache(found))
+		/*
+		 * Though the "found" page was in the swap cache an instant
+		 * earlier, it might have been removed by shrink_mmap etc.
+		 * Re search ... Since find_lock_page grabs a reference on
+		 * the page, it can not be reused for anything else, namely
+		 * it can not be associated with another swaphandle, so it
+		 * is enough to check whether the page is still in the scache.
+		 */
+		if (!PageSwapCache(found)) {
+			UnlockPage(found);
+			__free_page(found);
+			goto repeat;
+		}
+		if (found->mapping != &swapper_space)
 			goto out_bad;
 #ifdef SWAP_CACHE_INFO
 		swap_cache_find_success++;
diff -u --recursive --new-file v2.3.29/linux/mm/swapfile.c linux/mm/swapfile.c
--- v2.3.29/linux/mm/swapfile.c	Thu Nov 11 20:11:55 1999
+++ linux/mm/swapfile.c	Thu Dec  2 15:06:20 1999
@@ -17,6 +17,7 @@
 
 #include <asm/pgtable.h>
 
+spinlock_t swaplock = SPIN_LOCK_UNLOCKED;
 unsigned int nr_swapfiles = 0;
 
 struct swap_list_t swap_list = {-1, -1};
@@ -89,24 +90,29 @@
 	int type, wrapped = 0;
 
 	entry.val = 0;	/* Out of memory */
+	if (count >= SWAP_MAP_MAX)
+		goto bad_count;
+	swap_list_lock();
 	type = swap_list.next;
 	if (type < 0)
 		goto out;
 	if (nr_swap_pages == 0)
 		goto out;
-	if (count >= SWAP_MAP_MAX)
-		goto bad_count;
 
 	while (1) {
 		p = &swap_info[type];
 		if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
+			swap_device_lock(p);
 			offset = scan_swap_map(p, count);
+			swap_device_unlock(p);
 			if (offset) {
+				int curtp = type;
+
 				entry = SWP_ENTRY(type,offset);
 				type = swap_info[type].next;
 				if (type < 0 ||
 					p->prio != swap_info[type].prio) {
-						swap_list.next = swap_list.head;
+						swap_list.next = curtp;
 				} else {
 					swap_list.next = type;
 				}
@@ -124,6 +130,7 @@
 				goto out;	/* out of swap space */
 	}
 out:
+	swap_list_unlock();
 	return entry;
 
 bad_count:
@@ -133,6 +140,10 @@
 }
 
 
+/*
+ * Caller has made sure that the swapdevice corresponding to entry
+ * is still around or has not been recycled.
+ */
 void __swap_free(swp_entry_t entry, unsigned short count)
 {
 	struct swap_info_struct * p;
@@ -147,13 +158,15 @@
 	p = & swap_info[type];
 	if (!(p->flags & SWP_USED))
 		goto bad_device;
-	if (p->prio > swap_info[swap_list.next].prio)
-		swap_list.next = swap_list.head;
 	offset = SWP_OFFSET(entry);
 	if (offset >= p->max)
 		goto bad_offset;
 	if (!p->swap_map[offset])
 		goto bad_free;
+	swap_list_lock();
+	if (p->prio > swap_info[swap_list.next].prio)
+		swap_list.next = type;
+	swap_device_lock(p);
 	if (p->swap_map[offset] < SWAP_MAP_MAX) {
 		if (p->swap_map[offset] < count)
 			goto bad_count;
@@ -165,6 +178,8 @@
 			nr_swap_pages++;
 		}
 	}
+	swap_device_unlock(p);
+	swap_list_unlock();
 out:
 	return;
 
@@ -181,6 +196,8 @@
 	printk("VM: Bad swap entry %08lx\n", entry.val);
 	goto out;
 bad_count:
+	swap_device_unlock(p);
+	swap_list_unlock();
 	printk(KERN_ERR "VM: Bad count %hd current count %hd\n", count, p->swap_map[offset]);
 	goto out;
 }
@@ -209,14 +226,21 @@
 	if (offset >= p->max)
 		goto new_swap_entry;
 	/* Has it been re-used for something else? */
+	swap_list_lock();
+	swap_device_lock(p);
 	if (p->swap_map[offset])
-		goto new_swap_entry;
+		goto unlock_new_swap_entry;
 
 	/* We're cool, we can just use the old one */
 	p->swap_map[offset] = 1;
+	swap_device_unlock(p);
 	nr_swap_pages--;
+	swap_list_unlock();
 	return entry;
 
+unlock_new_swap_entry:
+	swap_device_unlock(p);
+	swap_list_unlock();
 new_swap_entry:
 	return get_swap_page();
 }
@@ -360,11 +384,22 @@
 		/*
 		 * Find a swap page in use and read it in.
 		 */
+		swap_device_lock(si);
 		for (i = 1; i < si->max ; i++) {
 			if (si->swap_map[i] > 0 && si->swap_map[i] != SWAP_MAP_BAD) {
+				/*
+				 * Prevent swaphandle from being completely
+				 * unused by swap_free while we are trying
+				 * to read in the page - this prevents warning
+				 * messages from rw_swap_page_base.
+				 */
+				if (si->swap_map[i] != SWAP_MAP_MAX)
+					si->swap_map[i]++;
+				swap_device_unlock(si);
 				goto found_entry;
 			}
 		}
+		swap_device_unlock(si);
 		break;
 
 	found_entry:
@@ -375,11 +410,7 @@
                    page and read the swap into it. */
 		page = read_swap_cache(entry);
 		if (!page) {
-			/*
-			 * Continue searching if the entry became unused.
-			 */
-			if (si->swap_map[i] == 0)
-				continue;
+			swap_free(entry);
   			return -ENOMEM;
 		}
 		read_lock(&tasklist_lock);
@@ -395,12 +426,18 @@
 		/*
 		 * Check for and clear any overflowed swap map counts.
 		 */
-		if (si->swap_map[i] != 0) {
+		swap_free(entry);
+		swap_list_lock();
+		swap_device_lock(si);
+		if (si->swap_map[i] > 0) {
 			if (si->swap_map[i] != SWAP_MAP_MAX)
-				printk("VM: Undead swap entry %08lx\n", entry.val);
-			si->swap_map[i] = 0;
+				printk("VM: Undead swap entry %08lx\n", 
+								entry.val);
 			nr_swap_pages++;
+			si->swap_map[i] = 0;
 		}
+		swap_device_unlock(si);
+		swap_list_unlock();
 	}
 	return 0;
 }
@@ -423,6 +460,7 @@
 		goto out;
 
 	prev = -1;
+	swap_list_lock();
 	for (type = swap_list.head; type >= 0; type = swap_info[type].next) {
 		p = swap_info + type;
 		if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) {
@@ -438,8 +476,10 @@
 		prev = type;
 	}
 	err = -EINVAL;
-	if (type < 0)
+	if (type < 0) {
+		swap_list_unlock();
 		goto out_dput;
+	}
 
 	if (prev < 0) {
 		swap_list.head = p->next;
@@ -450,10 +490,13 @@
 		/* just pick something that's safe... */
 		swap_list.next = swap_list.head;
 	}
+	nr_swap_pages -= p->pages;
+	swap_list_unlock();
 	p->flags = SWP_USED;
 	err = try_to_unuse(type);
 	if (err) {
 		/* re-insert swap space back into swap_list */
+		swap_list_lock();
 		for (prev = -1, i = swap_list.head; i >= 0; prev = i, i = swap_info[i].next)
 			if (p->prio >= swap_info[i].prio)
 				break;
@@ -462,6 +505,8 @@
 			swap_list.head = swap_list.next = p - swap_info;
 		else
 			swap_info[prev].next = p - swap_info;
+		nr_swap_pages += p->pages;
+		swap_list_unlock();
 		p->flags = SWP_WRITEOK;
 		goto out_dput;
 	}
@@ -480,7 +525,6 @@
 
 	dentry = p->swap_file;
 	p->swap_file = NULL;
-	nr_swap_pages -= p->pages;
 	p->swap_device = 0;
 	vfree(p->swap_map);
 	p->swap_map = NULL;
@@ -583,6 +627,7 @@
 	p->lowest_bit = 0;
 	p->highest_bit = 0;
 	p->cluster_nr = 0;
+	p->sdev_lock = SPIN_LOCK_UNLOCKED;
 	p->max = 1;
 	p->next = -1;
 	if (swap_flags & SWAP_FLAG_PREFER) {
@@ -746,6 +791,7 @@
 	p->swap_map[0] = SWAP_MAP_BAD;
 	p->flags = SWP_WRITEOK;
 	p->pages = nr_good_pages;
+	swap_list_lock();
 	nr_swap_pages += nr_good_pages;
 	printk(KERN_INFO "Adding Swap: %dk swap-space (priority %d)\n",
 	       nr_good_pages<<(PAGE_SHIFT-10), p->prio);
@@ -764,6 +810,7 @@
 	} else {
 		swap_info[prev].next = p - swap_info;
 	}
+	swap_list_unlock();
 	error = 0;
 	goto out;
 bad_swap:
@@ -810,4 +857,170 @@
 	val->freeswap = freeswap;
 	val->totalswap = totalswap;
 	return;
+}
+
+/*
+ * Verify that a swap entry is valid and increment its swap map count.
+ * Kernel_lock is held, which guarantees existance of swap device.
+ *
+ * Note: if swap_map[] reaches SWAP_MAP_MAX the entries are treated as
+ * "permanent", but will be reclaimed by the next swapoff.
+ */
+int swap_duplicate(swp_entry_t entry)
+{
+	struct swap_info_struct * p;
+	unsigned long offset, type;
+	int result = 0;
+
+	/* Swap entry 0 is illegal */
+	if (!entry.val)
+		goto out;
+	type = SWP_TYPE(entry);
+	if (type >= nr_swapfiles)
+		goto bad_file;
+	p = type + swap_info;
+	offset = SWP_OFFSET(entry);
+	if (offset >= p->max)
+		goto bad_offset;
+	if (!p->swap_map[offset])
+		goto bad_unused;
+	/*
+	 * Entry is valid, so increment the map count.
+	 */
+	swap_device_lock(p);
+	if (p->swap_map[offset] < SWAP_MAP_MAX)
+		p->swap_map[offset]++;
+	else {
+		static int overflow = 0;
+		if (overflow++ < 5)
+			printk("VM: swap entry overflow\n");
+		p->swap_map[offset] = SWAP_MAP_MAX;
+	}
+	swap_device_unlock(p);
+	result = 1;
+out:
+	return result;
+
+bad_file:
+	printk("Bad swap file entry %08lx\n", entry.val);
+	goto out;
+bad_offset:
+	printk("Bad swap offset entry %08lx\n", entry.val);
+	goto out;
+bad_unused:
+	printk("Unused swap offset entry in swap_dup %08lx\n", entry.val);
+	goto out;
+}
+
+/*
+ * Page lock needs to be held in all cases to prevent races with
+ * swap file deletion.
+ */
+int swap_count(struct page *page)
+{
+	struct swap_info_struct * p;
+	unsigned long offset, type;
+	swp_entry_t entry;
+	int retval = 0;
+
+	entry.val = page->index;
+	if (!entry.val)
+		goto bad_entry;
+	type = SWP_TYPE(entry);
+	if (type >= nr_swapfiles)
+		goto bad_file;
+	p = type + swap_info;
+	offset = SWP_OFFSET(entry);
+	if (offset >= p->max)
+		goto bad_offset;
+	if (!p->swap_map[offset])
+		goto bad_unused;
+	retval = p->swap_map[offset];
+out:
+	return retval;
+
+bad_entry:
+	printk(KERN_ERR "swap_count: null entry!\n");
+	goto out;
+bad_file:
+	printk("Bad swap file entry %08lx\n", entry.val);
+	goto out;
+bad_offset:
+	printk("Bad swap offset entry %08lx\n", entry.val);
+	goto out;
+bad_unused:
+	printk("Unused swap offset entry in swap_count %08lx\n", entry.val);
+	goto out;
+}
+
+/*
+ * Kernel_lock protects against swap device deletion.
+ */
+void get_swaphandle_info(swp_entry_t entry, unsigned long *offset, 
+			kdev_t *dev, struct inode **swapf)
+{
+	unsigned long type;
+	struct swap_info_struct *p;
+
+	type = SWP_TYPE(entry);
+	if (type >= nr_swapfiles) {
+		printk("Internal error: bad swap-device\n");
+		return;
+	}
+
+	p = &swap_info[type];
+	*offset = SWP_OFFSET(entry);
+	if (*offset >= p->max) {
+		printk("rw_swap_page: weirdness\n");
+		return;
+	}
+	if (p->swap_map && !p->swap_map[*offset]) {
+		printk("VM: Bad swap entry %08lx\n", entry.val);
+		return;
+	}
+	if (!(p->flags & SWP_USED)) {
+		printk(KERN_ERR "rw_swap_page: "
+			"Trying to swap to unused swap-device\n");
+		return;
+	}
+
+	if (p->swap_device) {
+		*dev = p->swap_device;
+	} else if (p->swap_file) {
+		*swapf = p->swap_file->d_inode;
+	} else {
+		printk(KERN_ERR "rw_swap_page: no swap file or device\n");
+	}
+	return;
+}
+
+/*
+ * Kernel_lock protects against swap device deletion. Grab an extra
+ * reference on the swaphandle so that it dos not become unused.
+ */
+int valid_swaphandles(swp_entry_t entry, unsigned long *offset)
+{
+	int ret = 0, i = 1 << page_cluster;
+	unsigned long toff;
+	struct swap_info_struct *swapdev = SWP_TYPE(entry) + swap_info;
+
+	*offset = SWP_OFFSET(entry);
+	toff = *offset = (*offset >> page_cluster) << page_cluster;
+
+	swap_device_lock(swapdev);
+	do {
+		/* Don't read-ahead past the end of the swap area */
+		if (toff >= swapdev->max)
+			break;
+		/* Don't read in bad or busy pages */
+		if (!swapdev->swap_map[toff])
+			break;
+		if (swapdev->swap_map[toff] == SWAP_MAP_BAD)
+			break;
+		swapdev->swap_map[toff]++;
+		toff++;
+		ret++;
+	} while (--i);
+	swap_device_unlock(swapdev);
+	return ret;
 }
diff -u --recursive --new-file v2.3.29/linux/mm/vmscan.c linux/mm/vmscan.c
--- v2.3.29/linux/mm/vmscan.c	Tue Nov 23 22:42:21 1999
+++ linux/mm/vmscan.c	Mon Dec  6 10:17:31 1999
@@ -158,15 +158,15 @@
 	if (!(page = prepare_highmem_swapout(page)))
 		goto out_swap_free;
 
-	vma->vm_mm->rss--;
-	set_pte(page_table, swp_entry_to_pte(entry));
-	vmlist_access_unlock(vma->vm_mm);
-
-	flush_tlb_page(vma, address);
 	swap_duplicate(entry);	/* One for the process, one for the swap cache */
 
 	/* This will also lock the page */
 	add_to_swap_cache(page, entry);
+	/* Put the swap entry into the pte after the page is in swapcache */
+	vma->vm_mm->rss--;
+	set_pte(page_table, swp_entry_to_pte(entry));
+	flush_tlb_page(vma, address);
+	vmlist_access_unlock(vma->vm_mm);
 
 	/* OK, do a physical asynchronous write to swap.  */
 	rw_swap_page(WRITE, page, 0);
diff -u --recursive --new-file v2.3.29/linux/net/atm/proc.c linux/net/atm/proc.c
--- v2.3.29/linux/net/atm/proc.c	Tue Nov 23 22:42:21 1999
+++ linux/net/atm/proc.c	Sat Nov 27 15:27:49 1999
@@ -523,7 +523,7 @@
 int __init atm_proc_init(void)
 {
 	struct proc_dir_entry *dev=NULL,*pvc=NULL,*svc=NULL,*arp=NULL,*lec=NULL;
-	atm_proc_root = create_proc_entry("atm", S_IFDIR, &proc_root);
+	atm_proc_root = proc_mkdir("atm", &proc_root);
 	if (!atm_proc_root)
 		return -ENOMEM;
 	dev = create_proc_entry("devices",0,atm_proc_root);
diff -u --recursive --new-file v2.3.29/linux/net/core/dev.c linux/net/core/dev.c
--- v2.3.29/linux/net/core/dev.c	Tue Nov 23 22:42:21 1999
+++ linux/net/core/dev.c	Fri Dec  3 10:55:09 1999
@@ -1323,8 +1323,9 @@
 	int size;
 
 	if(stats != (struct iw_statistics *) NULL)
+	{
 		size = sprintf(buffer,
-			       "%6s: %02x  %3d%c %3d%c  %3d%c %5d %5d %5d\n",
+			       "%6s: %04x  %3d%c  %3d%c  %3d%c  %6d %6d %6d\n",
 			       dev->name,
 			       stats->status,
 			       stats->qual.qual,
@@ -1336,6 +1337,8 @@
 			       stats->discard.nwid,
 			       stats->discard.code,
 			       stats->discard.misc);
+		stats->qual.updated = 0;
+	}
 	else
 		size = 0;
 
@@ -1357,8 +1360,9 @@
 	struct net_device *	dev;
 
 	size = sprintf(buffer,
-		       "Inter-|sta|  Quality       |  Discarded packets\n"
-		       " face |tus|link level noise| nwid crypt  misc\n");
+		       "Inter-| sta-|   Quality        |   Discarded packets\n"
+		       " face | tus | link level noise |  nwid  crypt   misc\n"
+			);
 	
 	pos+=size;
 	len+=size;
diff -u --recursive --new-file v2.3.29/linux/net/core/neighbour.c linux/net/core/neighbour.c
--- v2.3.29/linux/net/core/neighbour.c	Thu Aug 26 13:05:45 1999
+++ linux/net/core/neighbour.c	Sat Nov 27 16:04:04 1999
@@ -55,7 +55,7 @@
 static struct neigh_table *neigh_tables;
 
 #if defined(__i386__) && defined(__SMP__)
-#define ASSERT_WL(n) if ((int)((n)->lock.lock) >= 0) { printk("WL assertion failed at " __FILE__ "(%d):" __FUNCTION__ "\n", __LINE__); }
+#define ASSERT_WL(n) if ((int)((n)->lock.lock) > 0) { printk("WL assertion failed at " __FILE__ "(%d):" __FUNCTION__ "\n", __LINE__); }
 #else
 #define ASSERT_WL(n) do { } while(0)
 #endif
@@ -881,6 +881,7 @@
 
 	if (!hh && (hh = kmalloc(sizeof(*hh), GFP_ATOMIC)) != NULL) {
 		memset(hh, 0, sizeof(struct hh_cache));
+		hh->hh_lock = RW_LOCK_UNLOCKED;
 		hh->hh_type = protocol;
 		atomic_set(&hh->hh_refcnt, 0);
 		hh->hh_next = NULL;
diff -u --recursive --new-file v2.3.29/linux/net/irda/irproc.c linux/net/irda/irproc.c
--- v2.3.29/linux/net/irda/irproc.c	Tue Nov 23 22:42:21 1999
+++ linux/net/irda/irproc.c	Sat Nov 27 15:27:49 1999
@@ -66,7 +66,7 @@
 {
 	int i;
 
-	proc_irda = create_proc_entry("net/irda", S_IFDIR, NULL);
+	proc_irda = proc_mkdir("net/irda", NULL);
 	proc_irda->owner = THIS_MODULE;
 
 	for (i=0;i<IRDA_ENTRIES_NUM;i++)
diff -u --recursive --new-file v2.3.29/linux/net/khttpd/datasending.c linux/net/khttpd/datasending.c
--- v2.3.29/linux/net/khttpd/datasending.c	Tue Aug 31 17:29:15 1999
+++ linux/net/khttpd/datasending.c	Mon Dec  6 17:06:50 1999
@@ -55,16 +55,23 @@
 It sends the data to the socket indicated by desc->buf.
 
 */
-static int sock_send_actor(read_descriptor_t * desc, const char *area, unsigned long size)
+static int sock_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
 {
 	int written;
+	unsigned long kaddr;
 	unsigned long count = desc->count;
 	struct socket *sock = (struct socket *) desc->buf;
+	mm_segment_t old_fs;
 
 	if (size > count)
 		size = count;
-	written = SendBuffer_async(sock,(char *)area,size);
+	old_fs = get_fs();
+	set_fs(KERNEL_DS);
 
+	kaddr = kmap(page);
+	written = SendBuffer_async(sock,(char *)kaddr + offset,size);
+	kunmap(page);
+	set_fs(old_fs);
 	if (written < 0) {
 		desc->error = written;
 		written = 0;
diff -u --recursive --new-file v2.3.29/linux/net/khttpd/main.c linux/net/khttpd/main.c
--- v2.3.29/linux/net/khttpd/main.c	Tue Aug 31 17:29:15 1999
+++ linux/net/khttpd/main.c	Mon Dec  6 17:06:50 1999
@@ -50,6 +50,10 @@
  *
  ****************************************************************/
 
+
+static int errno;
+#define __KERNEL_SYSCALLS__
+
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -175,9 +179,6 @@
 }
 
 static int CountBuf[CONFIG_KHTTPD_NUMCPU];
-
-static int errno;
-inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options);
 
 
 
diff -u --recursive --new-file v2.3.29/linux/net/packet/af_packet.c linux/net/packet/af_packet.c
--- v2.3.29/linux/net/packet/af_packet.c	Mon Nov  1 13:56:27 1999
+++ linux/net/packet/af_packet.c	Sat Nov 27 15:27:49 1999
@@ -1858,8 +1858,7 @@
 	sock_register(&packet_family_ops);
 	register_netdevice_notifier(&packet_netdev_notifier);
 #ifdef CONFIG_PROC_FS
-	ent = create_proc_entry("net/packet", 0, 0);
-	ent->read_proc = packet_read_proc;
+	create_proc_read_entry("net/packet", 0, 0, packet_read_proc, NULL);
 #endif
 #ifdef MODULE
 	return 0;
diff -u --recursive --new-file v2.3.29/linux/net/socket.c linux/net/socket.c
--- v2.3.29/linux/net/socket.c	Mon Oct 11 15:38:15 1999
+++ linux/net/socket.c	Sat Nov 27 15:27:49 1999
@@ -340,18 +340,9 @@
 	struct inode * inode;
 	struct socket * sock;
 
-	lock_kernel();
-	/* Damn! get_empty_inode is not SMP safe.
-	   I ask, why does it have decorative spinlock
-	   at the very beginning? Probably, dcache ops should
-	   be lock_kernel'ed inside inode.c
-	 */
 	inode = get_empty_inode();
-	if (!inode) {
-		unlock_kernel();
+	if (!inode)
 		return NULL;
-	}
-	unlock_kernel();
 
 	sock = socki_lookup(inode);
 
diff -u --recursive --new-file v2.3.29/linux/net/sunrpc/stats.c linux/net/sunrpc/stats.c
--- v2.3.29/linux/net/sunrpc/stats.c	Thu Nov 11 20:11:56 1999
+++ linux/net/sunrpc/stats.c	Sat Nov 27 15:27:49 1999
@@ -162,7 +162,7 @@
 	dprintk("RPC: registering /proc/net/rpc\n");
 	if (!proc_net_rpc) {
 		struct proc_dir_entry *ent;
-		ent = create_proc_entry("net/rpc", S_IFDIR, 0);
+		ent = proc_mkdir("net/rpc", 0);
 		if (ent) {
 			ent->owner = THIS_MODULE;
 			proc_net_rpc = ent;
diff -u --recursive --new-file v2.3.29/linux/net/wanrouter/wanproc.c linux/net/wanrouter/wanproc.c
--- v2.3.29/linux/net/wanrouter/wanproc.c	Tue Nov 23 22:42:21 1999
+++ linux/net/wanrouter/wanproc.c	Sun Dec  5 08:42:03 1999
@@ -116,10 +116,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	router_proc_perms,	/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
@@ -159,10 +157,8 @@
 	NULL,			/* get_block */
 	NULL,			/* readpage */
 	NULL,			/* writepage */
-	NULL,			/* flushpage */
 	NULL,			/* truncate */
 	router_proc_perms,	/* permission */
-	NULL,			/* smap */
 	NULL			/* revalidate */
 };
 
diff -u --recursive --new-file v2.3.29/linux/scripts/Menuconfig linux/scripts/Menuconfig
--- v2.3.29/linux/scripts/Menuconfig	Mon Oct  4 15:49:30 1999
+++ linux/scripts/Menuconfig	Mon Dec  6 16:25:34 1999
@@ -54,7 +54,7 @@
 # Change a lot of places to call set_x_info uniformly.
 # Take out message about preparing version (old sound driver cruft).
 #
-# 13 Dec 1998, Riley H Williams (rhw@bigfoot.com)
+# 13 Dec 1998, Riley H Williams <rhw@memalpha.cx>
 # When an error occurs, actually display the error message as well as
 # our comments thereon.
 #
