diff -u --recursive --new-file v2.3.25/linux/CREDITS linux/CREDITS
--- v2.3.25/linux/CREDITS	Mon Nov  1 13:56:26 1999
+++ linux/CREDITS	Fri Nov  5 10:01:50 1999
@@ -1612,10 +1612,11 @@
 S: Czech Republic
 
 N: Vojtech Pavlik
-E: vojtech@ucw.cz
+E: vojtech@suse.cz
 D: Joystick driver
 D: arcnet-hardware readme
 D: Minor ARCnet hacking
+D: USB hacking
 S: Ucitelska 1576
 S: Prague 8
 S: 182 00 Czech Republic
@@ -2055,7 +2056,8 @@
 S: Canada K2L 1S2
 
 N: Andrew Tridgell
-E: Andrew.Tridgell@anu.edu.au
+E: tridge@samba.org
+W: http://linuxcare.com.au/tridge/
 D: dosemu, networking, samba
 S: 3 Ballow Crescent
 S: MacGregor A.C.T 2615
diff -u --recursive --new-file v2.3.25/linux/Documentation/Changes linux/Documentation/Changes
--- v2.3.25/linux/Documentation/Changes	Fri Oct 22 13:21:43 1999
+++ linux/Documentation/Changes	Wed Nov  3 09:17:32 1999
@@ -45,7 +45,7 @@
 
 - Kernel modutils	 2.3.6                   ; insmod -V
 - Gnu C 		 2.7.2.3                 ; gcc --version
-- Binutils		 2.8.1.0.23              ; ld -v
+- Binutils		 2.9.1.0.7               ; ld -v
 - Linux libc5 C Library	 5.4.46                  ; ls -l /lib/libc*
 - Linux libc6 C Library  2.0.7pre6               ; ls -l /lib/libc*
 - Dynamic Linker (ld.so) 1.9.9                   ; ldd --version or ldd -v
@@ -183,13 +183,10 @@
 to find out the proper way to upgrade it.  No, the instruction to "rm
 `which encaps`" is not a joke.
 
-   The last public release of the binutils 2.8.x series was 2.8.1.0.23.
-Binutils 2.8.1.0.25 to 2.9.1.0.2 are beta releases, and are known to be
-very buggy.  Binutils 2.9.1 (note the absence of a suffix) from the FSF
-should work, and binutils 2.9.1.0.7 and later releases are also good.
-Either use binutils-2.8.1.0.23 or binutils-2.9.1.0.7 or later.  Glibc2
-users should especially try to use the 2.9.1.0.x releases, as they
-resolve known issues with glibc2 and binutils-2.8.x releases.
+   You must use binutils 2.9.1.0.7 or later. Latest release is 2.9.1.0.25.
+Beware that binutils 2.9.1 (note the absence of a suffix) from the FSF
+does not work. If you are upgrading from earlier versions, you should
+consider upgrading to the latest 2.9.5.0.x release.
 
 Gnu C
 =====
@@ -503,23 +500,16 @@
 Binutils
 ========
 
-The 2.8.1.0.23 release:
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.8.1.0.23.bin.tar.gz
-ftp://metalab.unc.edu/pub/Linux/GCC/binutils-2.8.1.0.23.bin.tar.gz
+The 2.9.1.0.25 release:
+ftp://ftp.varesearch.com/pub/support/hjl/binutils/2.9.1/binutils-2.9.1.0.25-glibc.x86.tar.gz
+ftp://ftp.varesearch.com/pub/support/hjl/binutils/2.9.1/binutils-2.9.1.0.25.tar.gz
 Installation notes:
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.8.1.0.23
-ftp://metalab.unc.edu/pub/Linux/GCC/release.binutils-2.8.1.0.23
+ftp://ftp.varesearch.com/pub/support/hjl/binutils/2.9.1/release.binutils-2.9.1.0.25
 
-The 2.9.1.0.15 release:
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.15-glibc.x86.tar.gz
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.15-libc5.x86.tar.gz
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.15.tar.gz
-ftp://metalab.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.15-glibc.x86.tar.gz
-ftp://metalab.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.15-libc5.x86.tar.gz
-ftp://metalab.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.15.tar.gz
+The 2.9.5.0.16 release:
+ftp://ftp.varesearch.com/pub/support/hjl/binutils/binutils-2.9.5.0.16.tar.bz2
 Installation notes:
-ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.9.1.0.15
-ftp://metalab.unc.edu/pub/Linux/GCC/release.binutils-2.9.1.0.15
+ftp://ftp.varesearch.com/pub/support/hjl/binutils/release.binutils-2.9.5.0.16
 
 Gnu C
 =====
diff -u --recursive --new-file v2.3.25/linux/Documentation/Configure.help linux/Documentation/Configure.help
--- v2.3.25/linux/Documentation/Configure.help	Mon Nov  1 13:56:26 1999
+++ linux/Documentation/Configure.help	Sat Nov  6 10:38:40 1999
@@ -1912,6 +1912,23 @@
   building a kernel for install/rescue disks or your system is very
   limited in memory.
 
+Kernel core (/proc/kcore) format
+CONFIG_KCORE_ELF
+  If you enabled support for /proc filesystem then the file /proc/kcore
+  will contain the kernel core image. This can be used in gdb:
+
+  $ cd /usr/src/linux ; gdb vmlinux /proc/kcore
+
+  Selecting ELF will make /proc/kcore appear in ELF core format as defined
+  by the Executable and Linking Format specification. Selecting A.OUT will
+  choose the old "a.out" format which may be necessary for some old versions
+  of binutils or on some architectures.
+
+  This is especially useful if you have compiled the kernel with "-g" option
+  to preserve debugging information. It is mainly used for examining kernel
+  data structures on the live kernel so if you don't understand what this
+  means or are not a kernel hacker, just leave it at its default value ELF.
+  
 Kernel support for ELF binaries
 CONFIG_BINFMT_ELF
   ELF (Executable and Linkable Format) is a format for libraries and
@@ -2976,7 +2993,7 @@
   here and read Documentation/modules.txt. The module will be called
   unix.o. If you try building this as a module and you have said Y to
   "Kernel module loader support" above, be sure to add 'alias net-pf-1
-  unix' to your /etc/conf.modules file. Note that several important
+  unix' to your /etc/modules.conf file. Note that several important
   services won't work correctly if you say M here and then neglect to
   load the module.
 
@@ -3700,7 +3717,7 @@
   whenever you want). If you want to compile it as a module, say M
   here and read Documentation/modules.txt; if you use modprobe or
   kmod, you may also want to add "alias net-pf-17 af_packet" to 
-  /etc/conf.modules. 
+  /etc/modules.conf. 
 
   If unsure, say Y.
 
@@ -7841,6 +7858,18 @@
   The module will be called cpia.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
+USB Kodak DC-2xx Camera support
+CONFIG_USB_DC2XX
+  Say Y here if you want to connect this type of still camera to
+  your computer's USB port.  See drivers/usb/README.dc2xx for more
+  information; some non-Kodak cameras may also work with this
+  driver, given application support (such as www.gPhoto.org).
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called dc2xx.o. If you want to compile it as a
+  module, say M here and read Documentation/modules.txt.
+
 USB SCSI Support
 CONFIG_USB_SCSI
   Say Y here if you want to connect SCSI devices to your computer's
@@ -7977,7 +8006,9 @@
   during the boot process. It is usually mounted under /stand and
   corresponds to the slice marked as "STAND" in the UnixWare
   partition. This is useful if you want to access files on your /stand
-  slice from Linux. If you don't know what it is, say N.
+  slice from Linux. More information on this filesystem can be found in
+  Documentation/filesystems/bfs.txt file. If you do not know what it is, 
+  say N.
 
   If you want to compile this as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
@@ -8002,7 +8033,7 @@
   say M here and read Documentation/modules.txt. The module will be
   called isofs.o.
 
-Microsoft Joliet cdrom extensions
+Microsoft Joliet CDROM extensions
 CONFIG_JOLIET
   Joliet is a Microsoft extension for the ISO 9660 CDROM filesystem
   which allows for long filenames in unicode format (unicode is the
@@ -8011,7 +8042,7 @@
   http://www.unicode.org for more information). Say Y here if you want
   to be able to read Joliet CDROMs under Linux.
 
-UDF Filesystem support
+UDF Filesystem support (read only)
 CONFIG_UDF_FS
   This is the new filesystem used by some CDROMS and DVD drivers. Say
   Y if you intend to mount DVD discs or CDRW's written in packet mode,
@@ -8025,13 +8056,13 @@
 
   If unsure, say N.
 
-UDF read-write support (EXPERIMENTAL)
+UDF write support (DANGEROUS)
 CONFIG_UDF_RW
   Say Y if you want to test write support for UDF filesystems.
   Due to lack of support for writing to CDR/CDRW's, this option
   is only supported for Hard Discs, DVD-RAM, and loopback files.
 
-fat fs support
+DOS FAT fs support
 CONFIG_FAT_FS
   If you want to use one of the FAT-based filesystems (the MS-DOS,
   VFAT (Windows 95) and UMSDOS (used to run Linux on top of an
@@ -8067,7 +8098,7 @@
   module, so don't say M here if you intend to use UMSDOS as your root
   filesystem.
 
-msdos fs support
+MSDOS fs support
 CONFIG_MSDOS_FS
   This allows you to mount MSDOS partitions of your hard drive (unless
   they are compressed; to access compressed MSDOS partitions under
@@ -8096,7 +8127,7 @@
   want), say M here and read Documentation/modules.txt. The module
   will be called msdos.o.
 
-vfat fs support
+VFAT (Windows-95) fs support
 CONFIG_VFAT_FS
   This option provides support for normal Windows filesystems with
   long filenames. That includes non-compressed FAT-based filesystems
@@ -8117,7 +8148,7 @@
   say M here and read Documentation/modules.txt. The module will be
   called vfat.o.
 
-umsdos: Unix like fs on top of std MSDOS fs
+UMSDOS: Unix-like filesystem on top of standard MSDOS filesystem
 CONFIG_UMSDOS_FS
   Say Y here if you want to run Linux from within an existing DOS
   partition of your hard drive. The advantage of this is that you can
@@ -8209,7 +8240,7 @@
   
   Most people say N here. 
 
-NFS server support
+NFS server support (EXPERIMENTAL)
 CONFIG_NFSD
   If you want your Linux box to act as a NFS *server*, so that other
   computers on your local network which support NFS can access certain
@@ -8231,7 +8262,7 @@
   The module is called nfsd.o. If you want to compile it as a module,
   say M here and read Documentation/modules.txt. If unsure, say N.
 
-Emulate Sun NFS daemon
+Emulate SUN NFS server
 CONFIG_NFSD_SUN
   If you would like for the server to allow clients to access
   directories that are mount points on the local filesystem (this is
@@ -8274,11 +8305,11 @@
 
   If unsure, say N.
 
-System V and Coherent filesystem support
+System V and Coherent filesystem support (read only)
 CONFIG_SYSV_FS
   SCO, Xenix and Coherent are commercial Unix systems for Intel
-  machines. Saying Y here would allow you to read to and write from
-  their floppies and hard disk partitions.
+  machines. Saying Y here would allow you to read from their floppies
+  and hard disk partitions.
 
   If you have floppies or hard disk partitions like that, it is likely
   that they contain binaries from those other Unix systems; in order
@@ -8308,6 +8339,15 @@
 
   If you haven't heard about all of this before, it's safe to say N.
 
+SYSV filesystem write support (DANGEROUS)
+CONFIG_SYSV_FS_WRITE
+  If you say Y here, you will (hopefully) be able to write to System V
+  and Coherent file systems as well as read from them. The read-write
+  support in SYSV is not well tested yet. If you enable this, back up
+  your SYSV/Coherent volumes first since they may get damaged.
+
+  If unsure, say N.
+
 Amiga FFS filesystem support
 CONFIG_AFFS_FS
   The Fast File System (FFS) is the common filesystem used on hard
@@ -8393,7 +8433,7 @@
   If you are not a part of a fairly large, distributed network, you
   probably do not need an automounter, and can say N here.
 
-EFS filesystem support (EXPERIMENTAL)
+EFS filesystem support (read only) (EXPERIMENTAL)
 CONFIG_EFS_FS
   EFS is an older filesystem used for non-ISO9660 CDROMs and hard disk
   partitions by SGI's IRIX operating system (IRIX 6.0 and newer uses
@@ -8413,7 +8453,7 @@
   Say Y to this only if you plan on mounting disks with SGI
   disklabels. This is not required to mount EFS-format CDROMs.
 
-UFS filesystem support
+UFS filesystem support (read only)
 CONFIG_UFS_FS
   BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD,
   OpenBSD and NeXTstep) use a filesystem called UFS. Some System V
@@ -8443,7 +8483,7 @@
 
   If you haven't heard about all of this before, it's safe to say N.
 
-UFS filesystem write support (EXPERIMENTAL)
+UFS filesystem write support (DANGEROUS)
 CONFIG_UFS_FS_WRITE
   Say Y here if you want to try writing to UFS partitions. This is
   experimental, so you should back up your UFS partitions beforehand.
@@ -8563,7 +8603,7 @@
 
   If you don't know what all this is about, say N.
 
-SMB filesystem support (to mount Windows shares etc...)
+SMB filesystem support (to mount Windows shares etc.)
 CONFIG_SMB_FS
   SMB (Server Message Block) is the protocol Windows for Workgroups
   (WfW), Windows 95/98, Windows NT and OS/2 Lan Manager use to share
@@ -8589,7 +8629,7 @@
   want), say M here and read Documentation/modules.txt. The module
   will be called smbfs.o. Most people say N, however.
 
-Coda filesystem support
+Coda filesystem support (advanced network fs)
 CONFIG_CODA_FS
   Coda is an advanced network filesystem, similar to NFS in that it
   enables you to mount filesystems of a remote server and access them
@@ -12674,13 +12714,6 @@
   read Documentation/modules.txt. This drivers currently only supports
   the ACTiSYS IR2000B ISA card and supports SIR, MIR and FIR (4Mbps)
   speeds.
-
-Sharp UIRCC IrDA Device Driver
-CONFIG_SHARP_FIR
-  Say Y here if you want to build support for the Sharp UIRCC IrDA
-  chipset. If you want to compile it as a module, say M here and
-  read Documentation/modules.txt. This chipset is used by the Toshiba
-  Tecra laptops.
 
 Toshiba Type-O IR Port Device Driver
 CONFIG_TOSHIBA_FIR
diff -u --recursive --new-file v2.3.25/linux/Documentation/computone.txt linux/Documentation/computone.txt
--- v2.3.25/linux/Documentation/computone.txt	Thu Aug 26 13:05:34 1999
+++ linux/Documentation/computone.txt	Sat Nov  6 10:38:40 1999
@@ -59,7 +59,7 @@
 e) Set address on ISA cards then:
    edit /usr/src/linux/drivers/char/ip2/ip2.h if needed 
 	or
-   edit /etc/conf.modules (or /etc/modules.conf) if needed (module).
+   edit /etc/modules.conf if needed (module).
 	or both to match this setting.
 f) Run "make dep"
 g) Run "make modules"
diff -u --recursive --new-file v2.3.25/linux/Documentation/digiboard.txt linux/Documentation/digiboard.txt
--- v2.3.25/linux/Documentation/digiboard.txt	Thu Apr 29 11:53:41 1999
+++ linux/Documentation/digiboard.txt	Sat Nov  6 10:38:40 1999
@@ -29,7 +29,7 @@
 The pcxx driver can be configured using the command line feature while
 loading the kernel with LILO or LOADLIN or, if built as a module,
 with arguments to insmod and modprobe or with parameters in
-/etc/conf.modules for modprobe and kerneld.
+/etc/modules.conf for modprobe and kerneld.
 
 After configuring the driver you need to create the device special files
 as described in "Device file creation:" below and set the appropriate
@@ -96,13 +96,13 @@
 
 The remaining board still uses ttyD8-ttyD15 and cud8-cud15.
 
-Example line for /etc/conf.modules for use with kerneld and as default
+Example line for /etc/modules.conf for use with kerneld and as default
 parameters for modprobe:
 
 options pcxx           io=0x200 numports=8
 
 For kerneld to work you will likely need to add these two lines to your
-/etc/conf.modules:
+/etc/modules.conf:
 
 alias char-major-22    pcxx
 alias char-major-23    pcxx
diff -u --recursive --new-file v2.3.25/linux/Documentation/filesystems/bfs.txt linux/Documentation/filesystems/bfs.txt
--- v2.3.25/linux/Documentation/filesystems/bfs.txt	Mon Nov  1 13:56:26 1999
+++ linux/Documentation/filesystems/bfs.txt	Fri Nov  5 10:30:13 1999
@@ -1,8 +1,13 @@
 The BFS filesystem is used on SCO UnixWare machines for /stand slice.
-There are no special mount options supported by bfs at this time. 
-You can mount it only read-only at this stage. Even if you attempt to
-mount it read-write it will be automatically mounted read-only, unless
-you have enabled "BFS write support" when configuring the kernel.
+By default, if you attempt to mount it read-write it will be automatically
+mounted read-only. If you want to enable (limited) write support, you need
+to select "BFS write support" when configuring the kernel. The write support
+at this stage is limited to the blocks preallocated for a given inode.
+This means that writes beyond the value of inode->iu_eblock will fail with EIO.
+In particular, this means you can create empty files but not write data to them
+or you can write data to the existing files and increase their size but not the
+number of blocks allocated to them. I am currently working on removing this
+limitation, i.e. ability to migrate inodes within BFS filesystem.
 
 In order to access /stand partition under Linux you obviously need to
 know the partition number and the kernel must support UnixWare disk slices
diff -u --recursive --new-file v2.3.25/linux/Documentation/filesystems/proc.txt linux/Documentation/filesystems/proc.txt
--- v2.3.25/linux/Documentation/filesystems/proc.txt	Fri Oct 15 15:25:13 1999
+++ linux/Documentation/filesystems/proc.txt	Tue Nov  2 08:19:44 1999
@@ -190,7 +190,7 @@
  ide         Directory containing info about the IDE subsystem 
  interrupts  Interrupt usage                                   
  ioports     I/O port usage                                    
- kcore       Kernel core image                                 
+ kcore       Kernel core image (can be ELF or A.OUT)           
  kmsg        Kernel messages                                   
  ksyms       Kernel symbol table                               
  loadavg     Load average                                      
diff -u --recursive --new-file v2.3.25/linux/Documentation/ftape.txt linux/Documentation/ftape.txt
--- v2.3.25/linux/Documentation/ftape.txt	Mon May 10 13:00:10 1999
+++ linux/Documentation/ftape.txt	Sat Nov  6 10:38:40 1999
@@ -244,14 +244,14 @@
 
    insmod ftape.o ft_tracing=4
 
-   or by editing the file `/etc/conf.modules' in which case they take
+   or by editing the file `/etc/modules.conf' in which case they take
    effect each time when the module is loaded with `modprobe' (please
    refer to the modules documentation, i.e. `modules.txt' and the
    respective manual pages). Thus, you should add a line
 
    options ftape ft_tracing=4
 
-   to `/etc/conf.modules` if you intend to increase the debugging
+   to `/etc/modules.conf` if you intend to increase the debugging
    output of the driver.
 
 
@@ -299,7 +299,7 @@
 5. Example module parameter setting
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    To do the same, but with ftape compiled as a loadable kernel
-   module, add the following line to `/etc/conf.modules':
+   module, add the following line to `/etc/modules.conf':
 
    options ftape ft_probe_fc10=1 ft_tracing=4
 
diff -u --recursive --new-file v2.3.25/linux/Documentation/hayes-esp.txt linux/Documentation/hayes-esp.txt
--- v2.3.25/linux/Documentation/hayes-esp.txt	Fri Jul 24 11:10:17 1998
+++ linux/Documentation/hayes-esp.txt	Sat Nov  6 10:38:40 1999
@@ -109,7 +109,7 @@
 insmod esp dma=3 trigger=512
 
 The esp module can be automatically loaded when needed.  To cause this to
-happen, add the following lines to /etc/conf.modules (replacing the last line
+happen, add the following lines to /etc/modules.conf (replacing the last line
 with options for your configuration):
 
 alias char-major-57 esp
diff -u --recursive --new-file v2.3.25/linux/Documentation/ide.txt linux/Documentation/ide.txt
--- v2.3.25/linux/Documentation/ide.txt	Mon Jan  4 15:07:27 1999
+++ linux/Documentation/ide.txt	Sat Nov  6 10:38:40 1999
@@ -245,7 +245,7 @@
 	alias block-major-3 ide-probe
 	alias char-major-37 ide-tape
 
-respectively to /etc/conf.modules.
+respectively to /etc/modules.conf.
 
 When ide.c is used as a module, you can pass command line parameters to the
 driver using the "options=" keyword to insmod, while replacing any ',' with
diff -u --recursive --new-file v2.3.25/linux/Documentation/joystick-parport.txt linux/Documentation/joystick-parport.txt
--- v2.3.25/linux/Documentation/joystick-parport.txt	Tue Dec  1 19:05:05 1998
+++ linux/Documentation/joystick-parport.txt	Fri Nov  5 10:01:50 1999
@@ -1,5 +1,5 @@
 		  Linux Joystick parport drivers v1.2 BETA
-		  (c) 1998 Vojtech Pavlik <vojtech@ucw.cz>
+		  (c) 1998 Vojtech Pavlik <vojtech@suse.cz>
 	       (c) 1998 Andree Borrmann <a.borrmann@tu-bs.de>
 ----------------------------------------------------------------------------
 
diff -u --recursive --new-file v2.3.25/linux/Documentation/joystick.txt linux/Documentation/joystick.txt
--- v2.3.25/linux/Documentation/joystick.txt	Tue Dec  1 19:05:05 1998
+++ linux/Documentation/joystick.txt	Fri Nov  5 10:01:50 1999
@@ -1,5 +1,5 @@
 		     Linux Joystick driver v1.2.13
-	       (c) 1996-1998 Vojtech Pavlik <vojtech@ucw.cz>
+	       (c) 1996-1998 Vojtech Pavlik <vojtech@suse.cz>
 ----------------------------------------------------------------------------
 
 0. Disclaimer
@@ -19,7 +19,7 @@
 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
   Should you need to contact me, the author, you can do so either by e-mail
-- mail your message to <vojtech@ucw.cz>, or by paper mail: Vojtech Pavlik,
+- mail your message to <vojtech@suse.cz>, or by paper mail: Vojtech Pavlik,
 Ucitelska 1576, Prague 8, 182 00 Czech Republic
 
   For your convenience, the GNU General Public License version 2 is included
@@ -58,20 +58,20 @@
   The joystick package is available at the following FTP sites:
 
 	ftp://atrey.karlin.mff.cuni.cz/pub/linux/joystick/
-	ftp://artax.karlin.mff.cuni.cz/pub/linux/joystick/
 
-  The joystick driver is also included in the Linux 2.1 kernels:
+  The joystick driver is also included in the Linux 2.1+ kernels:
 
-	ftp://linux.kernel.org/pub/linux/kernel/v2.1/
+	ftp://linux.kernel.org/pub/linux/kernel/
 
   And a homepage of the driver is at:
 
-	http://atrey.karlin.mff.cuni.cz/~vojtech/joystick/
-	http://artax.karlin.mff.cuni.cz/~vojtech/joystick/
+	http://www.suse.cz/development/joystick/
 
-  A mirror of the homepage is at:
+  Mirrors of the homepage are at:
 
+	http://atrey.karlin.mff.cuni.cz/~vojtech/joystick/
 	http://www.trylinux.com/projects/joystick/
+	http://www.linuxgames.com/joystick/
 
   There is also a mailing list for the driver at:
 
diff -u --recursive --new-file v2.3.25/linux/Documentation/modules.txt linux/Documentation/modules.txt
--- v2.3.25/linux/Documentation/modules.txt	Thu Aug  5 14:34:01 1999
+++ linux/Documentation/modules.txt	Sat Nov  6 10:38:40 1999
@@ -117,7 +117,7 @@
 without paying much attention to which kernel you are running, or what
 other modules this module depends on.
 
-With the help of the modprobe configuration file: "/etc/conf.modules"
+With the help of the modprobe configuration file: "/etc/modules.conf"
 you can tune the behaviour of modprobe in many ways, including an
 automatic setting of insmod options for each module.
 And, yes, there _are_ man-pages for all this...
@@ -164,10 +164,10 @@
 	  fits this symbolic description.
 	- modprobe looks into its internal "alias" translation table
 	  to see if there is a match.  This table can be reconfigured
-	  and expanded by having "alias" lines in "/etc/conf.modules".
+	  and expanded by having "alias" lines in "/etc/modules.conf".
 	- insmod is then asked to insert the module(s) that modprobe
 	  has decided that the kernel needs.  Every module will be
-	  configured according to the "options" lines in "/etc/conf.modules".
+	  configured according to the "options" lines in "/etc/modules.conf".
 	- modprobe exits and kerneld tells the kernel that the request
 	  succeeded (or failed...)
 	- The kernel uses the freshly installed feature just as if it
@@ -191,7 +191,7 @@
 
 To use kerneld with the least amount of "hassle", you need modprobe from
 a release that can be considered "recent" w.r.t. your kernel, and also
-a configuration file for modprobe ("/etc/conf.modules").
+a configuration file for modprobe ("/etc/modules.conf").
 Since modprobe already knows about most modules, the minimal configuration
 file could look something like this:
 
@@ -207,10 +207,6 @@
 	alias net-pf-3 off	# no ax25 module available (yet)
 	alias net-pf-4 off	# if you don't use the ipx module
 	alias net-pf-5 off	# if you don't use the appletalk module
-
-Finally, for the "purists":
-You can name the modprobe configuration either "/etc/conf.modules" or
-"/etc/modules.conf", since modprobe knows what to do in each case...
 
 
 Written by:
diff -u --recursive --new-file v2.3.25/linux/Documentation/networking/arcnet-hardware.txt linux/Documentation/networking/arcnet-hardware.txt
--- v2.3.25/linux/Documentation/networking/arcnet-hardware.txt	Mon Jul  5 19:52:52 1999
+++ linux/Documentation/networking/arcnet-hardware.txt	Fri Nov  5 10:01:50 1999
@@ -78,7 +78,7 @@
 -----------------------
 
 This section was rewritten by 
-        Vojtech Pavlik     <Vojtech.Pavlik@st.mff.cuni.cz>
+        Vojtech Pavlik     <vojtech@suse.cz>
 using information from several people, including:
         Avery Pennraun     <apenwarr@worldvisions.ca>
  	Stephen A. Wood    <saw@hallc1.cebaf.gov>
@@ -270,7 +270,7 @@
     that IRQ2 is the same as IRQ9, as far as Linux is concerned.  You can
     "cat /proc/interrupts" for a somewhat complete list of which ones are in
     use at any given time.  Here is a list of common usages from Vojtech
-    Pavlik <Vojtech.Pavlik@st.mff.cuni.cz>:
+    Pavlik <vojtech@suse.cz>:
     	("Not on bus" means there is no way for a card to generate this
 	interrupt)
 	IRQ  0 - Timer 0 (Not on bus)
@@ -347,8 +347,7 @@
     network.
     
 Also, on many cards (not mine, though) there are red and green LED's. 
-Vojtech Pavlik <Vojtech.Pavlik@st.mff.cuni.cz> tells me this is what they
-mean:
+Vojtech Pavlik <vojtech@suse.cz> tells me this is what they mean:
 	GREEN           RED             Status
 	-----		---		------
 	OFF             OFF             Power off
@@ -1735,11 +1734,11 @@
 ** Acer **
 8-bit card, Model 5210-003
 --------------------------
-  - from Vojtech Pavlik <Vojtech.Pavlik@st.mff.cuni.cz> using portions of
-    the existing arcnet-hardware file.
+  - from Vojtech Pavlik <vojtech@suse.cz> using portions of the existing
+    arcnet-hardware file.
 
-This is a 90C26 based card.  Its configuration seems similar to 
-the SMC PC100, but has some additional jumpers I don't know.
+This is a 90C26 based card.  Its configuration seems similar to the SMC
+PC100, but has some additional jumpers I don't know the meaning of.
 
                __
               |  |
@@ -1903,7 +1902,7 @@
 ** Datapoint? **
 LAN-ARC-8, an 8-bit card
 ------------------------
-  - from Vojtech Pavlik <Vojtech.Pavlik@st.mff.cuni.cz>
+  - from Vojtech Pavlik <vojtech@suse.cz>
 
 This is another SMC 90C65-based ARCnet card. I couldn't identify the
 manufacturer, but it might be DataPoint, because the card has the
@@ -2043,7 +2042,7 @@
 ** Topware **
 8-bit card, TA-ARC/10
 -------------------------
-  - from Vojtech Pavlik <Vojtech.Pavlik@st.mff.cuni.cz>
+  - from Vojtech Pavlik <vojtech@suse.cz>
 
 This is another very similar 90C65 card. Most of the switches and jumpers
 are the same as on other clones.
@@ -2752,7 +2751,7 @@
 ** No Name **
 8-bit cards ("Made in Taiwan R.O.C.")
 -----------
-  - from Vojtech Pavlik <Vojtech.Pavlik@st.mff.cuni.cz>
+  - from Vojtech Pavlik <vojtech@suse.cz>
 
 I have named this ARCnet card "NONAME", since I got only the card with
 no manual at all and the only text identifying the manufacturer is 
diff -u --recursive --new-file v2.3.25/linux/Documentation/networking/baycom.txt linux/Documentation/networking/baycom.txt
--- v2.3.25/linux/Documentation/networking/baycom.txt	Tue Jul  6 19:16:55 1999
+++ linux/Documentation/networking/baycom.txt	Sat Nov  6 10:38:40 1999
@@ -93,7 +93,7 @@
 modems it should access at which ports. This can be done with the setbaycom
 utility. If you are only using one modem, you can also configure the
 driver from the insmod command line (or by means of an option line in
-/etc/conf.modules).
+/etc/modules.conf).
 
 Examples:
   insmod baycom_ser_fdx mode="ser12*" iobase=0x3f8 irq=4
diff -u --recursive --new-file v2.3.25/linux/Documentation/networking/ltpc.txt linux/Documentation/networking/ltpc.txt
--- v2.3.25/linux/Documentation/networking/ltpc.txt	Fri Nov 13 10:29:43 1998
+++ linux/Documentation/networking/ltpc.txt	Sat Nov  6 10:38:40 1999
@@ -25,7 +25,7 @@
 
 If you load the driver as a module, you can pass the parameters "io=",
 "irq=", and "dma=" on the command line with insmod or modprobe, or add
-them as options in /etc/conf.modules:
+them as options in /etc/modules.conf:
 
  alias lt0 ltpc # autoload the module when the interface is configured
  options ltpc io=0x240 irq=9 dma=1
diff -u --recursive --new-file v2.3.25/linux/Documentation/networking/soundmodem.txt linux/Documentation/networking/soundmodem.txt
--- v2.3.25/linux/Documentation/networking/soundmodem.txt	Tue Aug 31 17:29:12 1999
+++ linux/Documentation/networking/soundmodem.txt	Sat Nov  6 10:38:40 1999
@@ -39,7 +39,7 @@
 modems it should access at which ports. This can be done with the setbaycom
 utility. If you are only using one modem, you can also configure the
 driver from the insmod command line (or by means of an option line in
-/etc/conf.modules).
+/etc/modules.conf).
 
 Examples:
   insmod soundmodem mode="sbc:afsk1200" iobase=0x220 irq=5 dma=1
diff -u --recursive --new-file v2.3.25/linux/Documentation/parport.txt linux/Documentation/parport.txt
--- v2.3.25/linux/Documentation/parport.txt	Sat Oct  9 11:47:50 1999
+++ linux/Documentation/parport.txt	Sat Nov  6 10:38:40 1999
@@ -35,7 +35,7 @@
 KMod
 ----
 
-If you use kmod, you will find it useful to edit /etc/conf.modules.
+If you use kmod, you will find it useful to edit /etc/modules.conf.
 Here is an example of the lines that need to be added:
 
 	post-install parport modprobe -k parport_pc
diff -u --recursive --new-file v2.3.25/linux/Documentation/pci.txt linux/Documentation/pci.txt
--- v2.3.25/linux/Documentation/pci.txt	Fri Oct 22 13:21:43 1999
+++ linux/Documentation/pci.txt	Wed Nov  3 09:17:50 1999
@@ -4,7 +4,7 @@
 
 		"What should you avoid when writing PCI drivers"
 
-	  by Martin Mares <mj@atrey.karlin.mff.cuni.cz> on 09-Oct-1999
+	  by Martin Mares <mj@atrey.karlin.mff.cuni.cz> on 03-Nov-1999
 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -72,6 +72,8 @@
    Memory and port addresses and interrupt numbers should NOT be read from the
 config space. You should use the values in the pci_dev structure as they might
 have been remapped by the kernel.
+
+   See Documentation/IO-mapping.txt for how to access device memory.
 
 5. Other interesting functions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff -u --recursive --new-file v2.3.25/linux/Documentation/sound/AWE32 linux/Documentation/sound/AWE32
--- v2.3.25/linux/Documentation/sound/AWE32	Thu Aug 26 13:05:34 1999
+++ linux/Documentation/sound/AWE32	Sat Nov  6 10:38:40 1999
@@ -83,7 +83,7 @@
 synthesis you should also get the sound bank file for general midi from
 http://members.xoom.com/yar/synthgm.sbk.gz. Copy it to /usr and gunzip it there.
 
-7) Edit /etc/conf.modules, inserting at the end of the file:
+7) Edit /etc/modules.conf, inserting at the end of the file:
 
 alias midi awe_wave
 post-install awe_wave /usr/bin/sfxload /usr/synthfm.sbk
diff -u --recursive --new-file v2.3.25/linux/Documentation/sound/AudioExcelDSP16 linux/Documentation/sound/AudioExcelDSP16
--- v2.3.25/linux/Documentation/sound/AudioExcelDSP16	Thu Apr 29 11:53:41 1999
+++ linux/Documentation/sound/AudioExcelDSP16	Sat Nov  6 10:38:40 1999
@@ -41,7 +41,7 @@
 		(0x300, 0x310, 0x320 or 0x330)
 mpu_irq		MPU-401 irq line (5, 7, 9, 10 or 0)
 
-The /etc/conf.modules will have lines like this:
+The /etc/modules.conf will have lines like this:
 
 options opl3 io=0x388
 options ad1848 io=0x530 irq=11 dma=3
@@ -51,7 +51,7 @@
 ad1848 are the corresponding options for the MSS and OPL3 modules.
 
 Loading MSS and OPL3 needs to pre load the aedsp16 module to set up correctly
-the sound card. Installation dependencies must be written in the conf.modules
+the sound card. Installation dependencies must be written in the modules.conf
 file:
 
 pre-install ad1848 modprobe aedsp16
diff -u --recursive --new-file v2.3.25/linux/Documentation/sound/CMI8330 linux/Documentation/sound/CMI8330
--- v2.3.25/linux/Documentation/sound/CMI8330	Wed May 26 09:29:34 1999
+++ linux/Documentation/sound/CMI8330	Sat Nov  6 10:38:40 1999
@@ -88,7 +88,7 @@
 
 
 
-Alma Chao <elysian@ethereal.torsion.org> suggests the following /etc/conf.modules:
+Alma Chao <elysian@ethereal.torsion.org> suggests the following /etc/modules.conf:
 
 alias sound ad1848
 alias synth0 opl3
diff -u --recursive --new-file v2.3.25/linux/Documentation/sound/Introduction linux/Documentation/sound/Introduction
--- v2.3.25/linux/Documentation/sound/Introduction	Mon Jul  5 20:04:47 1999
+++ linux/Documentation/sound/Introduction	Sat Nov  6 10:38:40 1999
@@ -145,7 +145,7 @@
 =========
 
 If loading via modprobe, these common files are automatically loaded 
-when requested by modprobe.  For example, my /etc/conf.modules contains:
+when requested by modprobe.  For example, my /etc/modules.conf contains:
 
 alias sound sb 
 options sb io=0x240 irq=9 dma=3 dma16=5 mpu_io=0x300
@@ -205,7 +205,7 @@
 driver, you should do the following:
 
 1.  remove sound modules (detailed above)
-2.  remove the sound modules from /etc/conf.modules
+2.  remove the sound modules from /etc/modules.conf
 3.  move the sound modules from /lib/modules/<kernel>/misc
     (for example, I make a /lib/modules/<kernel>/misc/tmp
     directory and copy the sound module files to that 
@@ -241,7 +241,7 @@
     sb.o could be copied (or symlinked) to sb1.o for the
     second SoundBlasster.
 
-2.  Make a second entry in /etc/conf.modules, for example,
+2.  Make a second entry in /etc/modules.conf, for example,
     sound1 or sb1.  This second entry should refer to the
     new module names for example sb1, and should include
     the I/O, etc. for the second sound card.
@@ -333,7 +333,7 @@
 2)  On the command line when using insmod or in a bash script
     using command line calls to load sound.
 
-3)  In /etc/conf.modules when using modprobe.
+3)  In /etc/modules.conf when using modprobe.
 
 4)  Via Red Hat's /usr/sbin/sndconfig program (text based).
 
diff -u --recursive --new-file v2.3.25/linux/Documentation/sound/OPL3-SA2 linux/Documentation/sound/OPL3-SA2
--- v2.3.25/linux/Documentation/sound/OPL3-SA2	Mon Jul  5 20:04:47 1999
+++ linux/Documentation/sound/OPL3-SA2	Sat Nov  6 10:38:40 1999
@@ -125,7 +125,7 @@
 
 Lastly, if you're using modules and want to set up automatic module
 loading with kmod, the kernel module loader, here is the section I
-currently use in my conf.modules file:
+currently use in my modules.conf file:
 
 # Sound
 alias char-major-14 opl3sa2
diff -u --recursive --new-file v2.3.25/linux/Documentation/sound/Opti linux/Documentation/sound/Opti
--- v2.3.25/linux/Documentation/sound/Opti	Sat Jul 18 14:11:18 1998
+++ linux/Documentation/sound/Opti	Sat Nov  6 10:38:40 1999
@@ -18,7 +18,7 @@
 If you have another OS installed on your computer it is recommended
 that Linux and the other OS use the same resources.
 
-Also, it is recommended that resources specified in /etc/conf.modules
+Also, it is recommended that resources specified in /etc/modules.conf
 and resources specified in /etc/isapnp.conf agree.
 
 Compiling the sound driver
@@ -68,9 +68,9 @@
 Using kmod and autoloading the sound driver
 -------------------------------------------
 Comment: as of linux-2.1.90 kmod is replacing kerneld.
-The config file '/etc/conf.modules' is used as before.
+The config file '/etc/modules.conf' is used as before.
 
-This is the sound part of my /etc/conf.modules file.
+This is the sound part of my /etc/modules.conf file.
 Following that I will explain each line.
 
 alias mixer0 mad16
diff -u --recursive --new-file v2.3.25/linux/Documentation/sound/README.modules linux/Documentation/sound/README.modules
--- v2.3.25/linux/Documentation/sound/README.modules	Sun Jan 17 18:23:01 1999
+++ linux/Documentation/sound/README.modules	Sat Nov  6 10:38:40 1999
@@ -26,7 +26,7 @@
 drivers/sound dir. Now one simply configures and makes one's kernel and
 modules in the usual way.
 
- Then, add to your /etc/modules.conf or /etc/conf.modules something like:
+ Then, add to your /etc/modules.conf something like:
 
 alias char-major-14 sb
 post-install sb /sbin/modprobe "-k" "adlib_card"
@@ -82,7 +82,7 @@
 
 To make the sound driver use persistent DMA buffers we need to pass the
 sound.o module a "dmabuf=1" command-line argument. This is normally done
-in /etc/conf.modules (or the more proper /etc/modules.conf) like so:
+in /etc/modules.conf like so:
 
 options sound		dmabuf=1
 
diff -u --recursive --new-file v2.3.25/linux/Documentation/sound/Wavefront linux/Documentation/sound/Wavefront
--- v2.3.25/linux/Documentation/sound/Wavefront	Thu Apr 29 11:53:41 1999
+++ linux/Documentation/sound/Wavefront	Sat Nov  6 10:38:40 1999
@@ -190,7 +190,7 @@
 6) How do I configure my card ?
 ************************************************************
 
-You need to edit /etc/conf.modules. Here's mine (edited to show the
+You need to edit /etc/modules.conf. Here's mine (edited to show the
 relevant details):
 
   # Sound system
diff -u --recursive --new-file v2.3.25/linux/Documentation/sysrq.txt linux/Documentation/sysrq.txt
--- v2.3.25/linux/Documentation/sysrq.txt	Mon Aug  9 10:23:09 1999
+++ linux/Documentation/sysrq.txt	Tue Nov  2 08:43:37 1999
@@ -33,7 +33,7 @@
 'b'     - Will immediately reboot the system without syncing or unmounting
           your disks.
 
-'o'     - Will shut your system off via APM (if configured and supported).
+'o'     - Will shut your system off (if configured and supported).
 
 's'     - Will attempt to sync all mounted filesystems.
 
diff -u --recursive --new-file v2.3.25/linux/MAINTAINERS linux/MAINTAINERS
--- v2.3.25/linux/MAINTAINERS	Mon Nov  1 13:56:26 1999
+++ linux/MAINTAINERS	Fri Nov  5 10:01:50 1999
@@ -266,7 +266,7 @@
 M:	SteveW@ACM.org
 W:	http://www.sucs.swan.ac.uk/~rohan/
 W:	http://www-sigproc.eng.cam.ac.uk/~sjw44/
-L:	netdev@roxanne.nuclecu.unam.mx
+L:	netdev@oss.sgi.com
 S:	Maintained
 
 DEVICE NUMBER REGISTRY
@@ -490,9 +490,9 @@
 
 JOYSTICK DRIVER
 P:	Vojtech Pavlik
-M:	vojtech@ucw.cz
+M:	vojtech@suse.cz
 L:	linux-joystick@atrey.karlin.mff.cuni.cz
-W:	http://atrey.karlin.mff.cuni.cz/~vojtech/joystick/
+W:	http://www.suse.cz/development/joystick/
 S:	Maintained
 
 KERNEL AUTOMOUNTER (AUTOFS)
@@ -616,7 +616,7 @@
 
 NETWORKING [GENERAL]
 P:	Networking Teak
-M:	netdev@nuclecu.unam.mx
+M:	netdev@oss.sgi.com
 L:	linux-net@vger.rutgers.edu
 W:	http://www.uk.linux.org/NetNews.html (2.0 only)
 S:	Maintained
@@ -628,7 +628,7 @@
 M:	ak@muc.de
 P:	Alexey Kuznetsov
 M:	kuznet@ms2.inr.ac.ru
-L:	netdev@roxanne.nuclecu.unam.mx
+L:	netdev@oss.sgi.com
 S:	Maintained
 
 NFS CLIENT
@@ -764,7 +764,7 @@
 SCSI CDROM DRIVER
 P:	Jens Axboe
 M:	axboe@image.dk
-L:	linux-kernel@vger.rutgers.edu
+L:	linux-scsi@vger.rutgers.edu
 W:	http://www.kernel.dk
 S:	Maintained
 
diff -u --recursive --new-file v2.3.25/linux/Makefile linux/Makefile
--- v2.3.25/linux/Makefile	Mon Nov  1 13:56:26 1999
+++ linux/Makefile	Mon Nov  1 13:56:38 1999
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 3
-SUBLEVEL = 25
+SUBLEVEL = 26
 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.25/linux/arch/alpha/config.in linux/arch/alpha/config.in
--- v2.3.25/linux/arch/alpha/config.in	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/config.in	Fri Nov  5 10:22:51 1999
@@ -172,6 +172,11 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
 tristate 'Kernel support for a.out (ECOFF) binaries' CONFIG_BINFMT_AOUT
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
@@ -263,7 +268,7 @@
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
   tristate 'Kernel FP software completion' CONFIG_MATHEMU
 else
-  define_bool CONFIG_MATHEMU y
+  define_tristate CONFIG_MATHEMU y
 fi
 
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
diff -u --recursive --new-file v2.3.25/linux/arch/alpha/defconfig linux/arch/alpha/defconfig
--- v2.3.25/linux/arch/alpha/defconfig	Tue Aug 31 17:29:12 1999
+++ linux/arch/alpha/defconfig	Fri Nov  5 10:22:51 1999
@@ -47,6 +47,8 @@
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
 CONFIG_SYSCTL=y
 CONFIG_BINFMT_AOUT=y
 CONFIG_BINFMT_ELF=y
diff -u --recursive --new-file v2.3.25/linux/arch/arm/config.in linux/arch/arm/config.in
--- v2.3.25/linux/arch/arm/config.in	Mon Nov  1 13:56:26 1999
+++ linux/arch/arm/config.in	Fri Nov  5 10:22:51 1999
@@ -144,6 +144,11 @@
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
 tristate 'Math emulation' CONFIG_NWFPE
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
 tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
diff -u --recursive --new-file v2.3.25/linux/arch/arm/defconfig linux/arch/arm/defconfig
--- v2.3.25/linux/arch/arm/defconfig	Fri Oct 22 13:21:43 1999
+++ linux/arch/arm/defconfig	Fri Nov  5 10:22:51 1999
@@ -49,6 +49,8 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 CONFIG_NWFPE=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
 CONFIG_BINFMT_AOUT=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
diff -u --recursive --new-file v2.3.25/linux/arch/i386/config.in linux/arch/i386/config.in
--- v2.3.25/linux/arch/i386/config.in	Wed Oct 27 16:34:12 1999
+++ linux/arch/i386/config.in	Tue Nov  2 08:43:37 1999
@@ -104,6 +104,11 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
 tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
@@ -116,7 +121,6 @@
    bool '  Enable PM at boot time' CONFIG_APM_DO_ENABLE
    bool '  Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
    bool '  Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
-   bool '  Power off on shutdown' CONFIG_APM_POWER_OFF
    bool '  Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
    bool '  Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE
    bool '  RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT
diff -u --recursive --new-file v2.3.25/linux/arch/i386/defconfig linux/arch/i386/defconfig
--- v2.3.25/linux/arch/i386/defconfig	Wed Oct 27 16:34:12 1999
+++ linux/arch/i386/defconfig	Wed Nov  3 14:51:33 1999
@@ -63,6 +63,8 @@
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
 CONFIG_BINFMT_AOUT=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
diff -u --recursive --new-file v2.3.25/linux/arch/i386/kernel/apm.c linux/arch/i386/kernel/apm.c
--- v2.3.25/linux/arch/i386/kernel/apm.c	Mon Nov  1 13:56:26 1999
+++ linux/arch/i386/kernel/apm.c	Tue Nov  2 08:43:37 1999
@@ -33,6 +33,7 @@
  * Nov 1998, Version 1.7
  * Jan 1999, Version 1.8
  * Jan 1999, Version 1.9
+ * Oct 1999, Version 1.10
  *
  * History:
  *    0.6b: first version in official kernel, Linux 1.3.46
@@ -90,6 +91,16 @@
  *         Use CONFIG_SMP instead of __SMP__
  *         Ignore BOUNCES for three seconds.
  *         Stephen Rothwell
+ *   1.10: Fix for Thinkpad return code.
+ *         Merge 2.2 and 2.3 drivers.
+ *         Remove APM dependencies in arch/i386/kernel/process.c
+ *         Remove APM dependencies in drivers/char/sysrq.c
+ *         Reset time across standby.
+ *         Allow more inititialisation on SMP.
+ *         Remove CONFIG_APM_POWER_OFF and make it boot time
+ *         configurable (default on).
+ *         Make debug only a boot time parameter (remove APM_DEBUG).
+ *         Try to blank all devices on any error.
  *
  * APM 1.1 Reference:
  *
@@ -106,11 +117,8 @@
  *   Intel Corporation, Microsoft Corporation. Advanced Power Management
  *   (APM) BIOS Interface Specification, Revision 1.2, February 1996.
  *
- * [This document is available from Intel at:
- *    http://www.intel.com/IAL/powermgm
- *  or Microsoft at
- *    http://www.microsoft.com/windows/thirdparty/hardware/pcfuture.htm
- * ]
+ * [This document is available from Microsoft at:
+ *    http://www.microsoft.com/hwdev/busbios/amp_12.htm]
  */
 
 #include <linux/config.h>
@@ -122,7 +130,6 @@
 #include <linux/timer.h>
 #include <linux/fcntl.h>
 #include <linux/malloc.h>
-#include <linux/linkage.h>
 #include <linux/stat.h>
 #include <linux/proc_fs.h>
 #include <linux/miscdevice.h>
@@ -138,63 +145,27 @@
  */
 #include <linux/acpi.h>
 
-
 EXPORT_SYMBOL(apm_register_callback);
 EXPORT_SYMBOL(apm_unregister_callback);
 
 extern unsigned long get_cmos_time(void);
 
+extern void (*sysrq_power_off)(void);
+
 /*
  * The apm_bios device is one of the misc char devices.
  * This is its minor number.
  */
 #define	APM_MINOR_DEV	134
 
-/* Configurable options:
- *
- * CONFIG_APM_IGNORE_USER_SUSPEND: define to ignore USER SUSPEND requests.
- * This is necessary on the NEC Versa M series, which generates these when
- * resuming from SYSTEM SUSPEND.  However, enabling this on other laptops
- * will cause the laptop to generate a CRITICAL SUSPEND when an appropriate
- * USER SUSPEND is ignored -- this may prevent the APM driver from updating
- * the system time on a RESUME.
- *
- * CONFIG_APM_DO_ENABLE: enable APM features at boot time.  From page 36 of
- * the specification: "When disabled, the APM BIOS does not automatically
- * power manage devices, enter the Standby State, enter the Suspend State,
- * or take power saving steps in response to CPU Idle calls."  This driver
- * will make CPU Idle calls when Linux is idle (unless this feature is
- * turned off -- see below).  This should always save battery power, but
- * more complicated APM features will be dependent on your BIOS
- * implementation.  You may need to turn this option off if your computer
- * hangs at boot time when using APM support, or if it beeps continuously
- * instead of suspending.  Turn this off if you have a NEC UltraLite Versa
- * 33/C or a Toshiba T400CDT.  This is off by default since most machines
- * do fine without this feature.
- *
- * CONFIG_APM_CPU_IDLE: enable calls to APM CPU Idle/CPU Busy inside the
- * idle loop.  On some machines, this can activate improved power savings,
- * such as a slowed CPU clock rate, when the machine is idle.  These idle
- * call is made after the idle loop has run for some length of time (e.g.,
- * 333 mS).  On some machines, this will cause a hang at boot time or
- * whenever the CPU becomes idle.
- *
- * CONFIG_APM_DISPLAY_BLANK: enable console blanking using the APM.  Some
- * laptops can use this to turn of the LCD backlight when the VC screen
- * blanker blanks the screen.  Note that this is only used by the VC screen
- * blanker, and probably won't turn off the backlight when using X11.  Some
- * problems have been reported when using this option with gpm (if you'd
- * like to debug this, please do so).
- *
- * CONFIG_APM_IGNORE_MULTIPLE_SUSPEND: The IBM TP560 bios seems to insist
- * on returning multiple suspend/standby events whenever one occurs.  We
- * really only need one at a time, so just ignore any beyond the first.
- * This is probably safe on most laptops.
- *
- * If you are debugging the APM support for your laptop, note that code for
- * all of these options is contained in this file, so you can #define or
- * #undef these on the next line to avoid recompiling the whole kernel.
+/*
+ * See Documentation/Config.help for the configuration options.
  *
+ * Various options can be changed at boot time as follows:
+ *	apm=on/off			enable/disable APM
+ *	    [no-]debug			log some debugging messages
+ *	    [no-]power-off		power off on shutdown
+ *	    [no-]smp-power-off		allow power off even for SMP
  */
 
 /* KNOWN PROBLEM MACHINES:
@@ -213,11 +184,6 @@
  */
 
 /*
- * Define to have debug messages.
- */
-#undef APM_DEBUG
-
-/*
  * Define to always call the APM BIOS busy routine even if the clock was
  * not slowed by the idle routine.
  */
@@ -272,26 +238,6 @@
 		__asm__ __volatile__("movl %%" #seg ",%0" : "=m" (where))
 
 /*
- * Forward declarations
- */
-static void	suspend(void);
-static void	standby(void);
-static void	set_time(void);
-
-static void	check_events(void);
-
-static int	do_open(struct inode *, struct file *);
-static int	do_release(struct inode *, struct file *);
-static ssize_t	do_read(struct file *, char *, size_t , loff_t *);
-static unsigned int do_poll(struct file *, poll_table *);
-static int	do_ioctl(struct inode *, struct file *, u_int, u_long);
-
-static int	apm_get_info(char *, char **, off_t, int, int);
-
-extern int	apm_register_callback(int (*)(apm_event_t));
-extern void	apm_unregister_callback(int (*)(apm_event_t));
-
-/*
  * Local variables
  */
 static struct {
@@ -318,13 +264,13 @@
 #endif
 static int			debug = 0;
 static int			apm_disabled = 0;
+static int			power_off_enabled = 1;
 
 static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
 static struct apm_bios_struct *	user_list = NULL;
 
-static char			driver_version[] = "1.9";	/* no spaces */
+static char			driver_version[] = "1.10";	/* no spaces */
 
-#ifdef APM_DEBUG
 static char *	apm_event_name[] = {
 	"system standby",
 	"system suspend",
@@ -341,28 +287,6 @@
 };
 #define NR_APM_EVENT_NAME	\
 		(sizeof(apm_event_name) / sizeof(apm_event_name[0]))
-#endif
-
-static struct file_operations apm_bios_fops = {
-	NULL,		/* lseek */
-	do_read,
-	NULL,		/* write */
-	NULL,		/* readdir */
-	do_poll,
-	do_ioctl,
-	NULL,		/* mmap */
-	do_open,
-	NULL,		/* flush */
-	do_release,
-	NULL,		/* fsync */
-	NULL		/* fasync */
-};
-
-static struct miscdevice apm_device = {
-	APM_MINOR_DEV,
-	"apm",
-	&apm_bios_fops
-};
 
 typedef struct callback_list_t {
 	int (*				callback)(apm_event_t);
@@ -392,6 +316,7 @@
 	{ APM_RESUME_DISABLED,	"Resume timer disabled" },
 	{ APM_BAD_STATE,	"Unable to enter requested state" },
 /* N/A	{ APM_NO_EVENTS,	"No events pending" }, */
+	{ APM_NO_ERROR,		"BIOS did not set a return code" },
 	{ APM_NOT_PRESENT,	"No APM present" }
 };
 #define ERROR_COUNT	(sizeof(error_table)/sizeof(lookup_t))
@@ -418,9 +343,10 @@
 #	define APM_DO_CLI
 #endif
 #ifdef APM_ZERO_SEGS
+#	define APM_DECL_SEGS \
+		unsigned int saved_fs; unsigned int saved_gs;
 #	define APM_DO_SAVE_SEGS \
-		savesegment(fs, saved_fs); \
-		savesegment(gs, saved_gs)
+		savesegment(fs, saved_fs); savesegment(gs, saved_gs)
 #	define APM_DO_ZERO_SEGS \
 		"pushl %%ds\n\t" \
 		"pushl %%es\n\t" \
@@ -433,20 +359,19 @@
 		"popl %%es\n\t" \
 		"popl %%ds\n\t"
 #	define APM_DO_RESTORE_SEGS \
-		loadsegment(fs, saved_fs); \
-		loadsegment(gs, saved_gs)
+		loadsegment(fs, saved_fs); loadsegment(gs, saved_gs)
 #else
+#	define APM_DECL_SEGS
 #	define APM_DO_SAVE_SEGS
 #	define APM_DO_ZERO_SEGS
 #	define APM_DO_POP_SEGS
 #	define APM_DO_RESTORE_SEGS
 #endif
 
-static u8 apm_bios_call(u32 eax_in, u32 ebx_in, u32 ecx_in,
+static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
 	u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi)
 {
-	unsigned int	saved_fs;
-	unsigned int	saved_gs;
+	APM_DECL_SEGS
 	unsigned long	flags;
 
 	__save_flags(flags);
@@ -462,7 +387,7 @@
 		APM_DO_POP_SEGS
 		: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx),
 		  "=S" (*esi)
-		: "a" (eax_in), "b" (ebx_in), "c" (ecx_in)
+		: "a" (func), "b" (ebx_in), "c" (ecx_in)
 		: "memory", "cc");
 	APM_DO_RESTORE_SEGS;
 	__restore_flags(flags);
@@ -473,12 +398,10 @@
  * This version only returns one value (usually an error code)
  */
 
-static u8 apm_bios_call_simple(u32 eax_in, u32 ebx_in, u32 ecx_in,
-	u32 *eax)
+static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
 {
 	u8		error;
-	unsigned int	saved_fs;
-	unsigned int	saved_gs;
+	APM_DECL_SEGS
 	unsigned long	flags;
 
 	__save_flags(flags);
@@ -497,7 +420,7 @@
 			APM_DO_POP_SEGS
 			: "=a" (*eax), "=b" (error), "=c" (cx), "=d" (dx),
 			  "=S" (si)
-			: "a" (eax_in), "b" (ebx_in), "c" (ecx_in)
+			: "a" (func), "b" (ebx_in), "c" (ecx_in)
 			: "memory", "cc");
 	}
 	APM_DO_RESTORE_SEGS;
@@ -505,11 +428,11 @@
 	return error;
 }
 
-static int apm_driver_version(u_short *val)
+static int __init apm_driver_version(u_short *val)
 {
 	u32	eax;
 
-	if (apm_bios_call_simple(0x530e, 0, *val, &eax))
+	if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax))
 		return (eax >> 8) & 0xff;
 	*val = eax;
 	return APM_SUCCESS;
@@ -522,7 +445,8 @@
 	u32	ecx;
 	u32	dummy;
 
-	if (apm_bios_call(0x530b, 0, 0, &eax, &ebx, &ecx, &dummy, &dummy))
+	if (apm_bios_call(APM_FUNC_GET_EVENT, 0, 0, &eax, &ebx, &ecx,
+			&dummy, &dummy))
 		return (eax >> 8) & 0xff;
 	*event = ebx;
 	if (apm_bios_info.version < 0x0102)
@@ -536,16 +460,44 @@
 {
 	u32	eax;
 
-	if (apm_bios_call_simple(0x5307, what, state, &eax))
+	if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax))
 		return (eax >> 8) & 0xff;
 	return APM_SUCCESS;
 }
 
 static int apm_set_power_state(u_short state)
 {
-	return set_power_state(0x0001, state);
+	return set_power_state(APM_DEVICE_ALL, state);
+}
+
+#ifdef CONFIG_APM_CPU_IDLE
+static int apm_do_idle(void)
+{
+	u32	dummy;
+
+	if (apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &dummy))
+		return 0;
+
+#ifdef ALWAYS_CALL_BUSY
+	clock_slowed = 1;
+#else
+	clock_slowed = (apm_bios_info.flags & APM_IDLE_SLOWS_CLOCK) != 0;
+#endif
+	return 1;
+}
+
+static void apm_do_busy(void)
+{
+	u32	dummy;
+
+	if (clock_slowed) {
+		(void) apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy);
+		clock_slowed = 0;
+	}
 }
 
+extern int hlt_counter;
+
 /*
  * If no process has been interested in this
  * CPU for some time, we want to wake up the
@@ -557,12 +509,10 @@
 /* This should wake up kapmd and ask it to slow the CPU */
 #define powermanagement_idle()  do { } while (0)
 
-extern int hlt_counter;
-
 /*
  * This is the idle thing.
  */
-void apm_cpu_idle(void)
+static void apm_cpu_idle(void)
 {
 	unsigned int start_idle;
 
@@ -589,8 +539,9 @@
 		start_idle = jiffies;
 	}
 }
+#endif
 
-void apm_power_off(void)
+static void apm_power_off(void)
 {
 	/*
 	 * smp_hack == 2 means that we would have enabled APM support
@@ -612,7 +563,7 @@
 
 	/* Blank the first display device */
 	error = set_power_state(0x0100, state);
-	if (error == APM_BAD_DEVICE)
+	if (error != APM_SUCCESS)
 		/* try to blank them all instead */
 		error = set_power_state(0x01ff, state);
 	return error;
@@ -624,8 +575,7 @@
 {
 	u32	eax;
 
-	if (apm_bios_call_simple(0x5308,
-			(apm_bios_info.version > 0x100) ? 0x0001 : 0xffff,
+	if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL,
 			1, &eax))
 		return (eax >> 8) & 0xff;
 	apm_bios_info.flags &= ~APM_BIOS_DISABLED;
@@ -641,19 +591,49 @@
 	u32	edx;
 	u32	dummy;
 
-	if (apm_bios_call(0x530a, 1, 0, &eax, &ebx, &ecx, &edx, &dummy))
+	if (apm_bios_call(APM_FUNC_GET_STATUS, APM_DEVICE_ALL, 0,
+			&eax, &ebx, &ecx, &edx, &dummy))
+		return (eax >> 8) & 0xff;
+	*status = ebx;
+	*bat = ecx;
+	*life = edx;
+	return APM_SUCCESS;
+}
+
+#if 0
+static int apm_get_battery_status(u_short which, u_short *status,
+				  u_short *bat, u_short *life, u_short *nbat)
+{
+	u32	eax;
+	u32	ebx;
+	u32	ecx;
+	u32	edx;
+	u32	esi;
+
+	if (apm_bios_info.version < 0x0102) {
+		/* pretend we only have one battery. */
+		if (which != 1)
+			return APM_BAD_DEVICE;
+		*nbat = 1;
+		return apm_get_power_status(status, bat, life);
+	}
+
+	if (apm_bios_call(APM_FUNC_GET_STATUS, (0x8000 | (which)), 0, &eax,
+			&ebx, &ecx, &edx, &esi))
 		return (eax >> 8) & 0xff;
 	*status = ebx;
 	*bat = ecx;
 	*life = edx;
+	*nbat = esi;
 	return APM_SUCCESS;
 }
+#endif
 
 static int __init apm_engage_power_management(u_short device)
 {
 	u32	eax;
 
-	if (apm_bios_call_simple(0x530f, device, 1, &eax))
+	if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, 1, &eax))
 		return (eax >> 8) & 0xff;
 	return APM_SUCCESS;
 }
@@ -675,14 +655,12 @@
 int apm_display_blank(void)
 {
 #ifdef CONFIG_APM_DISPLAY_BLANK
-	int	error;
-
-	if (!apm_enabled)
-		return 0;
-	error = apm_set_display_power_state(APM_STATE_STANDBY);
-	if (error == APM_SUCCESS)
-		return 1;
-	apm_error("set display standby", error);
+	if (apm_enabled) {
+		int error = apm_set_display_power_state(APM_STATE_STANDBY);
+		if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
+			return 1;
+		apm_error("set display standby", error);
+	}
 #endif
 	return 0;
 }
@@ -691,14 +669,12 @@
 int apm_display_unblank(void)
 {
 #ifdef CONFIG_APM_DISPLAY_BLANK
-	int error;
-
-	if (!apm_enabled)
-		return 0;
-	error = apm_set_display_power_state(APM_STATE_READY);
-	if (error == APM_SUCCESS)
-		return 1;
-	apm_error("set display ready", error);
+	if (apm_enabled) {
+		int error = apm_set_display_power_state(APM_STATE_READY);
+		if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
+			return 1;
+		apm_error("set display ready", error);
+	}
 #endif
 	return 0;
 }
@@ -740,12 +716,12 @@
 	return as->events[as->event_tail];
 }
 
-static int queue_event(apm_event_t event, struct apm_bios_struct *sender)
+static void queue_event(apm_event_t event, struct apm_bios_struct *sender)
 {
 	struct apm_bios_struct *	as;
 
 	if (user_list == NULL)
-		return 0;
+		return;
 	for (as = user_list; as != NULL; as = as->next) {
 		if (as == sender)
 			continue;
@@ -753,10 +729,8 @@
 		if (as->event_head == as->event_tail) {
 			static int notified;
 
-			if (notified == 0) {
+			if (notified++ == 0)
 			    printk(KERN_ERR "apm: an event queue overflowed\n");
-			    notified = 1;
-			}
 			as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
 		}
 		as->events[as->event_head] = event;
@@ -777,28 +751,25 @@
 		}
 	}
 	wake_up_interruptible(&apm_waitqueue);
-	return 1;
 }
 
 static void set_time(void)
 {
 	unsigned long	flags;
 
-	if (!got_clock_diff)	/* Don't know time zone, can't set clock */
-		return;
-
-	save_flags(flags);
-	cli();
-	CURRENT_TIME = get_cmos_time() + clock_cmos_diff;
-	restore_flags(flags);
+	if (got_clock_diff) {	/* Must know time zone in order to set clock */
+		save_flags(flags);
+		cli();
+		CURRENT_TIME = get_cmos_time() + clock_cmos_diff;
+		restore_flags(flags);
+	}
 }
 
-static void suspend(void)
+static void get_time_diff(void)
 {
+#ifndef CONFIG_APM_RTC_IS_GMT
 	unsigned long	flags;
-	int		err;
 
-#ifndef CONFIG_APM_RTC_IS_GMT
 	/*
 	 * Estimate time zone so that set_time can update the clock
 	 */
@@ -809,9 +780,18 @@
 	got_clock_diff = 1;
 	restore_flags(flags);
 #endif
+}
+
+static void suspend(void)
+{
+	int		err;
+#ifdef INIT_TIMER_AFTER_SUSPEND
+	unsigned long	flags;
+#endif
 
+	get_time_diff();
 	err = apm_set_power_state(APM_STATE_SUSPEND);
-	if (err)
+	if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
 		apm_error("suspend", err);
 #ifdef INIT_TIMER_AFTER_SUSPEND
 	save_flags(flags);
@@ -832,8 +812,9 @@
 {
 	int	err;
 
+	get_time_diff();
 	err = apm_set_power_state(APM_STATE_STANDBY);
-	if (err)
+	if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
 		apm_error("standby", err);
 }
 
@@ -856,7 +837,7 @@
 	return 0;
 }
 
-static void send_event(apm_event_t event, apm_event_t undo,
+static int send_event(apm_event_t event, apm_event_t undo,
 		       struct apm_bios_struct *sender)
 {
 	callback_list_t *	call;
@@ -868,11 +849,12 @@
 				fix->callback(undo);
 			if (apm_bios_info.version > 0x100)
 				apm_set_power_state(APM_STATE_REJECT);
-			return;
+			return 0;
 		}
 	}
 
 	queue_event(event, sender);
+	return 1;
 }
 
 static void check_events(void)
@@ -884,14 +866,14 @@
 #endif
 
 	while ((event = get_event()) != 0) {
-#ifdef APM_DEBUG
-		if (event <= NR_APM_EVENT_NAME)
-			printk(KERN_DEBUG "apm: received %s notify\n",
-			       apm_event_name[event - 1]);
-		else
-			printk(KERN_DEBUG "apm: received unknown "
-			       "event 0x%02x\n", event);
-#endif
+		if (debug) {
+			if (event <= NR_APM_EVENT_NAME)
+				printk(KERN_DEBUG "apm: received %s notify\n",
+				       apm_event_name[event - 1]);
+			else
+				printk(KERN_DEBUG "apm: received unknown "
+				       "event 0x%02x\n", event);
+		}
 #ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
 		if (ignore_bounce
 		    && ((jiffies - last_resume) > BOUNCE_INTERVAL))
@@ -905,8 +887,8 @@
 				return;
 			waiting_for_resume = 1;
 #endif
-			send_event(event, APM_STANDBY_RESUME, NULL);
-			if (standbys_pending <= 0)
+			if (send_event(event, APM_STANDBY_RESUME, NULL)
+			    && (standbys_pending <= 0))
 				standby();
 			break;
 
@@ -926,8 +908,8 @@
 				return;
 			waiting_for_resume = 1;
 #endif
-			send_event(event, APM_NORMAL_RESUME, NULL);
-			if (suspends_pending <= 0)
+			if (send_event(event, APM_NORMAL_RESUME, NULL)
+			    && (suspends_pending <= 0))
 				suspend();
 			break;
 
@@ -945,9 +927,9 @@
 			send_event(event, 0, NULL);
 			break;
 
+		case APM_CAPABILITY_CHANGE:
 		case APM_LOW_BATTERY:
 		case APM_POWER_STATUS_CHANGE:
-		case APM_CAPABILITY_CHANGE:
 			send_event(event, 0, NULL);
 			break;
 
@@ -964,56 +946,22 @@
 
 static void apm_event_handler(void)
 {
-	static int pending_count = 0;
+	static int	pending_count = 0;
 
 	if (((standbys_pending > 0) || (suspends_pending > 0))
-	    && (apm_bios_info.version > 0x100)
-	    && (pending_count-- <= 0)) {
-		int err;
-		pending_count = 4;
-
-		err = apm_set_power_state(APM_STATE_BUSY);
-		if (err)
-			apm_error("busy", err);
-	}
-
-	if (!(((standbys_pending > 0) || (suspends_pending > 0))
-	      && (apm_bios_info.version == 0x100)))
+	    && (apm_bios_info.version > 0x100)) {
+		if (pending_count-- <= 0) {
+			int	err;
+
+			pending_count = 4;
+			err = apm_set_power_state(APM_STATE_BUSY);
+			if (err)
+				apm_error("busy", err);
+		}
+	} else {
+		pending_count = 0;
 		check_events();
-}
-
-static int apm_do_idle(void)
-{
-#ifdef CONFIG_APM_CPU_IDLE
-	u32	dummy;
-
-	if (!apm_enabled)
-		return 0;
-
-	if (apm_bios_call_simple(0x5305, 0, 0, &dummy))
-		return 0;
-
-#ifdef ALWAYS_CALL_BUSY
-	clock_slowed = 1;
-#else
-	clock_slowed = (apm_bios_info.flags & APM_IDLE_SLOWS_CLOCK) != 0;
-#endif
-	return 1;
-#else
-	return 0;
-#endif
-}
-
-static void apm_do_busy(void)
-{
-#ifdef CONFIG_APM_CPU_IDLE
-	u32	dummy;
-
-	if (clock_slowed) {
-		(void) apm_bios_call_simple(0x5306, 0, 0, &dummy);
-		clock_slowed = 0;
 	}
-#endif
 }
 
 /*
@@ -1046,6 +994,7 @@
 		 */
 		current->state = TASK_INTERRUPTIBLE;
 		apm_event_handler();
+#ifdef CONFIG_APM_CPU_IDLE
 		if (!system_idle())
 			continue;
 		if (apm_do_idle()) {
@@ -1058,6 +1007,7 @@
 			apm_do_busy();
 			apm_event_handler();
 		}
+#endif
 	}
 }
 
@@ -1075,7 +1025,7 @@
 	struct apm_bios_struct *	as;
 	int			i;
 	apm_event_t		event;
-        DECLARE_WAITQUEUE(wait, current);
+	DECLARE_WAITQUEUE(wait, current);
 
 	as = fp->private_data;
 	if (check_apm_bios_struct(as, "read"))
@@ -1098,7 +1048,11 @@
 	i = count;
 	while ((i >= sizeof(event)) && !queue_empty(as)) {
 		event = get_queued_event(as);
-		copy_to_user(buf, &event, sizeof(event));
+		if (copy_to_user(buf, &event, sizeof(event))) {
+			if (i < count)
+				break;
+			return -EFAULT;
+		}
 		switch (event) {
 		case APM_SYS_SUSPEND:
 		case APM_USER_SUSPEND:
@@ -1137,6 +1091,7 @@
 		    u_int cmd, u_long arg)
 {
 	struct apm_bios_struct *	as;
+	int				send_ok = 1;
 
 	as = filp->private_data;
 	if (check_apm_bios_struct(as, "ioctl"))
@@ -1151,8 +1106,9 @@
 			standbys_pending--;
 		}
 		else
-			send_event(APM_USER_STANDBY, APM_STANDBY_RESUME, as);
-		if (standbys_pending <= 0)
+			send_ok = send_event(APM_USER_STANDBY,
+					     APM_STANDBY_RESUME, as);
+		if (send_ok && (standbys_pending <= 0))
 			standby();
 		break;
 	case APM_IOC_SUSPEND:
@@ -1162,8 +1118,9 @@
 			suspends_pending--;
 		}
 		else
-			send_event(APM_USER_SUSPEND, APM_NORMAL_RESUME, as);
-		if (suspends_pending <= 0)
+			send_ok = send_event(APM_USER_SUSPEND,
+					     APM_NORMAL_RESUME, as);
+		if (send_ok && (suspends_pending <= 0))
 			suspend();
 		break;
 	default:
@@ -1177,9 +1134,9 @@
 	struct apm_bios_struct *	as;
 
 	as = filp->private_data;
-	filp->private_data = NULL;
 	if (check_apm_bios_struct(as, "release"))
 		return 0;
+	filp->private_data = NULL;
 	if (as->standbys_pending > 0) {
 		standbys_pending -= as->standbys_pending;
 		if (standbys_pending <= 0)
@@ -1272,7 +1229,7 @@
 	   from the Get Power Status (0x0a) call unless otherwise noted.
 
 	   0) Linux driver version (this will change if format changes)
-	   1) APM BIOS Version.  Usually 1.0 or 1.1.
+	   1) APM BIOS Version.  Usually 1.0, 1.1 or 1.2.
 	   2) APM flags from APM Installation Check (0x00):
 	      bit 0: APM_16_BIT_SUPPORT
 	      bit 1: APM_32_BIT_SUPPORT
@@ -1282,13 +1239,14 @@
 	   3) AC line status
 	      0x00: Off-line
 	      0x01: On-line
-	      0x02: On backup power (APM BIOS 1.1 only)
+	      0x02: On backup power (BIOS >= 1.1 only)
 	      0xff: Unknown
 	   4) Battery status
 	      0x00: High
 	      0x01: Low
 	      0x02: Critical
 	      0x03: Charging
+	      0x04: Selected battery not present (BIOS >= 1.2 only)
 	      0xff: Unknown
 	   5) Battery flag
 	      bit 0: High
@@ -1346,7 +1304,7 @@
 	if (debug) {
 		printk(KERN_INFO "apm: Connection version %d.%d\n",
 			(apm_bios_info.version >> 8) & 0xff,
-			apm_bios_info.version & 0xff );
+			apm_bios_info.version & 0xff);
 
 		error = apm_get_power_status(&bx, &cx, &dx);
 		if (error)
@@ -1406,10 +1364,10 @@
 			apm_bios_info.flags &= ~APM_BIOS_DISENGAGED;
 	}
 
-/* Install our power off handler.. */
-#ifdef CONFIG_APM_POWER_OFF
-	acpi_power_off = apm_power_off;
-#endif
+	/* Install our power off handler.. */
+	if (power_off_enabled)
+		acpi_power_off = apm_power_off;
+	sysrq_power_off = apm_power_off;
 
 	apm_mainloop();
 	return 0;
@@ -1429,6 +1387,8 @@
 			str += 3;
 		if (strncmp(str, "debug", 5) == 0)
 			debug = !invert;
+		if (strncmp(str, "power-off", 9) == 0)
+			power_off_enabled = !invert;
 		if (strncmp(str, "smp-power-off", 13) == 0)
 			smp_hack = !invert;
 		str = strchr(str, ',');
@@ -1440,6 +1400,29 @@
 
 __setup("apm=", apm_setup);
 
+static struct file_operations apm_bios_fops = {
+	NULL,		/* lseek */
+	do_read,
+	NULL,		/* write */
+	NULL,		/* readdir */
+	do_poll,
+	do_ioctl,
+	NULL,		/* mmap */
+	do_open,
+	NULL,		/* flush */
+	do_release,
+	NULL,		/* fsync */
+	NULL		/* fasync */
+};
+
+static struct miscdevice apm_device = {
+	APM_MINOR_DEV,
+	"apm",
+	&apm_bios_fops
+};
+
+#define APM_INIT_ERROR_RETURN	return -1
+
 /*
  * Just start the APM thread. We do NOT want to do APM BIOS
  * calls from anything but the APM thread, if for no other reason
@@ -1454,7 +1437,7 @@
 {
 	if (apm_bios_info.version == 0) {
 		printk(KERN_INFO "apm: BIOS not found.\n");
-		return -1;
+		APM_INIT_ERROR_RETURN;
 	}
 	printk(KERN_INFO
 		"apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n",
@@ -1464,7 +1447,7 @@
 		driver_version);
 	if ((apm_bios_info.flags & APM_32_BIT_SUPPORT) == 0) {
 		printk(KERN_INFO "apm: no 32 bit BIOS support\n");
-		return -1;
+		APM_INIT_ERROR_RETURN;
 	}
 
 	/*
@@ -1493,17 +1476,8 @@
 
 	if (apm_disabled) {
 		printk(KERN_NOTICE "apm: disabled on user request.\n");
-		return -1;
-	}
-
-#ifdef CONFIG_SMP
-	if (smp_num_cpus > 1) {
-		printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n");
-		if (smp_hack)
-			smp_hack = 2;
-		return -1;
+		APM_INIT_ERROR_RETURN;
 	}
-#endif
 
 	/*
 	 * Set up a segment that references the real mode segment 0x40
@@ -1545,7 +1519,16 @@
 	}
 #endif
 
- 	create_proc_info_entry("apm", 0, 0, apm_get_info);
+#ifdef CONFIG_SMP
+	if (smp_num_cpus > 1) {
+		printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n");
+		if (smp_hack)
+			smp_hack = 2;
+		APM_INIT_ERROR_RETURN;
+	}
+#endif
+
+	create_proc_info_entry("apm", 0, 0, apm_get_info);
 
 	misc_register(&apm_device);
 
diff -u --recursive --new-file v2.3.25/linux/arch/i386/kernel/sys_i386.c linux/arch/i386/kernel/sys_i386.c
--- v2.3.25/linux/arch/i386/kernel/sys_i386.c	Thu Dec 17 16:27:35 1998
+++ linux/arch/i386/kernel/sys_i386.c	Wed Nov  3 11:31:09 1999
@@ -116,86 +116,71 @@
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
-	if (call <= SEMCTL)
-		switch (call) {
-		case SEMOP:
-			return sys_semop (first, (struct sembuf *)ptr, second);
-		case SEMGET:
-			return sys_semget (first, second, third);
-		case SEMCTL: {
-			union semun fourth;
+	switch (call) {
+	case SEMOP:
+		return sys_semop (first, (struct sembuf *)ptr, second);
+	case SEMGET:
+		return sys_semget (first, second, third);
+	case SEMCTL: {
+		union semun fourth;
+		if (!ptr)
+			return -EINVAL;
+		if (get_user(fourth.__pad, (void **) ptr))
+			return -EFAULT;
+		return sys_semctl (first, second, third, fourth);
+	}
+
+	case MSGSND:
+		return sys_msgsnd (first, (struct msgbuf *) ptr, 
+				   second, third);
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
 			if (!ptr)
 				return -EINVAL;
-			if (get_user(fourth.__pad, (void **) ptr))
+			
+			if (copy_from_user(&tmp,
+					   (struct ipc_kludge *) ptr, 
+					   sizeof (tmp)))
 				return -EFAULT;
-			return sys_semctl (first, second, third, fourth);
-			}
+			return sys_msgrcv (first, tmp.msgp, second,
+					   tmp.msgtyp, third);
+		}
 		default:
-			return -EINVAL;
+			return sys_msgrcv (first,
+					   (struct msgbuf *) ptr,
+					   second, fifth, third);
 		}
+	case MSGGET:
+		return sys_msgget ((key_t) first, second);
+	case MSGCTL:
+		return sys_msgctl (first, second, (struct msqid_ds *) ptr);
 
-	if (call <= MSGCTL) 
-		switch (call) {
-		case MSGSND:
-			return sys_msgsnd (first, (struct msgbuf *) ptr, 
-					  second, third);
-		case MSGRCV:
-			switch (version) {
-			case 0: {
-				struct ipc_kludge tmp;
-				if (!ptr)
-					return -EINVAL;
-				
-				if (copy_from_user(&tmp,
-						   (struct ipc_kludge *) ptr, 
-						   sizeof (tmp)))
-					return -EFAULT;
-				return sys_msgrcv (first, tmp.msgp, second,
-						   tmp.msgtyp, third);
-				}
-			default:
-				return sys_msgrcv (first,
-						   (struct msgbuf *) ptr,
-						   second, fifth, third);
-			}
-		case MSGGET:
-			return sys_msgget ((key_t) first, second);
-		case MSGCTL:
-			return sys_msgctl (first, second,
-					   (struct msqid_ds *) ptr);
-		default:
-			return -EINVAL;
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+			ret = sys_shmat (first, (char *) ptr, second, &raddr);
+			if (ret)
+				return ret;
+			return put_user (raddr, (ulong *) third);
 		}
-	if (call <= SHMCTL) 
-		switch (call) {
-		case SHMAT:
-			switch (version) {
-			default: {
-				ulong raddr;
-				ret = sys_shmat (first, (char *) ptr,
-						 second, &raddr);
-				if (ret)
-					return ret;
-				return put_user (raddr, (ulong *) third);
-			}
-			case 1:	/* iBCS2 emulator entry point */
-				if (!segment_eq(get_fs(), get_ds()))
-					return -EINVAL;
-				return sys_shmat (first, (char *) ptr,
-						  second, (ulong *) third);
-			}
-		case SHMDT: 
-			return sys_shmdt ((char *)ptr);
-		case SHMGET:
-			return sys_shmget (first, second, third);
-		case SHMCTL:
-			return sys_shmctl (first, second,
-					   (struct shmid_ds *) ptr);
-		default:
-			return -EINVAL;
+		case 1:	/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				return -EINVAL;
+			return sys_shmat (first, (char *) ptr, second, (ulong *) third);
 		}
-	
-	return -EINVAL;
+	case SHMDT: 
+		return sys_shmdt ((char *)ptr);
+	case SHMGET:
+		return sys_shmget (first, second, third);
+	case SHMCTL:
+		return sys_shmctl (first, second,
+				   (struct shmid_ds *) ptr);
+	default:
+		return -EINVAL;
+	}
 }
 
 /*
diff -u --recursive --new-file v2.3.25/linux/arch/i386/math-emu/README linux/arch/i386/math-emu/README
--- v2.3.25/linux/arch/i386/math-emu/README	Wed Jun 24 14:30:08 1998
+++ linux/arch/i386/math-emu/README	Thu Nov  4 09:10:22 1999
@@ -1,9 +1,9 @@
  +---------------------------------------------------------------------------+
  |  wm-FPU-emu   an FPU emulator for 80386 and 80486SX microprocessors.      |
  |                                                                           |
- | Copyright (C) 1992,1993,1994,1995,1996,1997                               |
+ | Copyright (C) 1992,1993,1994,1995,1996,1997,1999                          |
  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
- |                       Australia.  E-mail billm@suburbia.net               |
+ |                       Australia.  E-mail billm@melbpc.org.au              |
  |                                                                           |
  |    This program is free software; you can redistribute it and/or modify   |
  |    it under the terms of the GNU General Public License version 2 as      |
@@ -42,14 +42,15 @@
 some differences.
 
 Please report bugs, etc to me at:
-       billm@suburbia.net
+       billm@melbpc.org.au
+or     b.metzenthen@medoto.unimelb.edu.au
 
 For more information on the emulator and on floating point topics, see
 my web pages, currently at  http://www.suburbia.net/~billm/
 
 
 --Bill Metzenthen
-  December 1997
+  December 1999
 
 
 ----------------------- Internals of wm-FPU-emu -----------------------
@@ -98,7 +99,7 @@
 ----------------------- Limitations of wm-FPU-emu -----------------------
 
 There are a number of differences between the current wm-FPU-emu
-(version 2.00) and the 80486 FPU (apart from bugs).  The differences
+(version 2.01) and the 80486 FPU (apart from bugs).  The differences
 are fewer than those which applied to the 1.xx series of the emulator.
 Some of the more important differences are listed below:
 
diff -u --recursive --new-file v2.3.25/linux/arch/i386/math-emu/fpu_trig.c linux/arch/i386/math-emu/fpu_trig.c
--- v2.3.25/linux/arch/i386/math-emu/fpu_trig.c	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/fpu_trig.c	Thu Nov  4 09:10:22 1999
@@ -3,9 +3,9 @@
  |                                                                           |
  | Implementation of the FPU "transcendental" functions.                     |
  |                                                                           |
- | Copyright (C) 1992,1993,1994,1997                                         |
+ | Copyright (C) 1992,1993,1994,1997,1999                                    |
  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
- |                       Australia.  E-mail   billm@suburbia.net             |
+ |                       Australia.  E-mail   billm@melbpc.org.au            |
  |                                                                           |
  |                                                                           |
  +---------------------------------------------------------------------------*/
@@ -85,7 +85,8 @@
 	  FPU_normalize(&tmp);
 	  tmptag =
 	    FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION, SIGN_POS,
-		      exponent16(&CONST_PI2extra) + exponent16(&tmp));
+		      exponent(&CONST_PI2extra) + exponent(&tmp));
+	  setsign(&tmp, getsign(&CONST_PI2extra));
 	  st0_tag = FPU_add(&tmp, tmptag, 0, FULL_PRECISION);
 	  if ( signnegative(st0_ptr) )
 	    {
@@ -117,7 +118,8 @@
 	  FPU_normalize(&tmp);         /* This must return TAG_Valid */
 	  tmptag = FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION,
 			     SIGN_POS,
-			     exponent16(&CONST_PI2extra) + exponent16(&tmp));
+			     exponent(&CONST_PI2extra) + exponent(&tmp));
+	  setsign(&tmp, getsign(&CONST_PI2extra));
 	  st0_tag = FPU_sub(LOADED|(tmptag & 0x0f), (int)&tmp,
 			    FULL_PRECISION);
 	  if ( (exponent(st0_ptr) == exponent(&CONST_PI2)) &&
@@ -827,18 +829,29 @@
 		       unsigned long long st1,
 		       unsigned long long q, int n)
 {
+  int dummy;
   unsigned long long x;
 
   x = st0 << n;
 
   /* Do the required multiplication and subtraction in the one operation */
-  asm volatile ("movl %2,%%eax; mull %4; subl %%eax,%0; sbbl %%edx,%1;
-                 movl %3,%%eax; mull %4; subl %%eax,%1;
-                 movl %2,%%eax; mull %5; subl %%eax,%1;"
-		:"=m" (x), "=m" (((unsigned *)&x)[1])
-		:"m" (st1),"m" (((unsigned *)&st1)[1]),
-		 "m" (q),"m" (((unsigned *)&q)[1])
-		:"%ax","%dx");
+
+  /* lsw x -= lsw st1 * lsw q */
+  asm volatile ("mull %4; subl %%eax,%0; sbbl %%edx,%1"
+		:"=m" (((unsigned *)&x)[0]), "=m" (((unsigned *)&x)[1]),
+		"=a" (dummy)
+		:"2" (((unsigned *)&st1)[0]), "m" (((unsigned *)&q)[0])
+		:"%dx");
+  /* msw x -= msw st1 * lsw q */
+  asm volatile ("mull %3; subl %%eax,%0"
+		:"=m" (((unsigned *)&x)[1]), "=a" (dummy)
+		:"1" (((unsigned *)&st1)[1]), "m" (((unsigned *)&q)[0])
+		:"%dx");
+  /* msw x -= lsw st1 * msw q */
+  asm volatile ("mull %3; subl %%eax,%0"
+		:"=m" (((unsigned *)&x)[1]), "=a" (dummy)
+		:"1" (((unsigned *)&st1)[0]), "m" (((unsigned *)&q)[1])
+		:"%dx");
 
   *y = x;
 }
diff -u --recursive --new-file v2.3.25/linux/arch/i386/math-emu/poly.h linux/arch/i386/math-emu/poly.h
--- v2.3.25/linux/arch/i386/math-emu/poly.h	Tue Apr  7 07:48:54 1998
+++ linux/arch/i386/math-emu/poly.h	Thu Nov  4 09:10:22 1999
@@ -3,9 +3,9 @@
  |                                                                           |
  |  Header file for the FPU-emu poly*.c source files.                        |
  |                                                                           |
- | Copyright (C) 1994                                                        |
+ | Copyright (C) 1994,1999                                                   |
  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
- |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    |
+ |                       Australia.  E-mail   billm@melbpc.org.au            |
  |                                                                           |
  | Declarations and definitions for functions operating on Xsig (12-byte     |
  | extended-significand) quantities.                                         |
@@ -55,15 +55,20 @@
    actually be in-line.
    */
 
-/* Multiply two fixed-point 32 bit numbers. */
-extern inline void mul_32_32(const unsigned long arg1,
-			     const unsigned long arg2,
-			     unsigned long *out)
+/* Multiply two fixed-point 32 bit numbers, producing a 32 bit result.
+   The answer is the ms word of the product. */
+/* Some versions of gcc make it difficult to stop eax from being clobbered.
+   Merely specifying that it is used doesn't work...
+ */
+extern inline unsigned long mul_32_32(const unsigned long arg1,
+				      const unsigned long arg2)
 {
-  asm volatile ("movl %1,%%eax; mull %2; movl %%edx,%0" \
-		:"=g" (*out) \
-		:"g" (arg1), "g" (arg2) \
-		:"ax","dx");
+  int retval;
+  asm volatile ("mull %2; movl %%edx,%%eax" \
+		:"=a" (retval) \
+		:"0" (arg1), "g" (arg2) \
+		:"dx");
+  return retval;
 }
 
 
diff -u --recursive --new-file v2.3.25/linux/arch/i386/math-emu/poly_sin.c linux/arch/i386/math-emu/poly_sin.c
--- v2.3.25/linux/arch/i386/math-emu/poly_sin.c	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/poly_sin.c	Thu Nov  4 09:10:22 1999
@@ -4,9 +4,9 @@
  |  Computation of an approximation of the sin function and the cosine       |
  |  function by a polynomial.                                                |
  |                                                                           |
- | Copyright (C) 1992,1993,1994,1997                                         |
+ | Copyright (C) 1992,1993,1994,1997,1999                                    |
  |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
- |                  E-mail   billm@suburbia.net                              |
+ |                  E-mail   billm@melbpc.org.au                             |
  |                                                                           |
  |                                                                           |
  +---------------------------------------------------------------------------*/
@@ -132,6 +132,9 @@
 	}
       /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
       fixed_arg = 0x921fb54442d18469LL - fixed_arg;
+      /* There is a special case which arises due to rounding, to fix here. */
+      if ( fixed_arg == 0xffffffffffffffffLL )
+	fixed_arg = 0;
 
       XSIG_LL(argSqrd) = fixed_arg; argSqrd.lsw = 0;
       mul64_Xsig(&argSqrd, &fixed_arg);
@@ -172,10 +175,9 @@
       if ( argSqrd.msw & 0xffc00000 )
 	{
 	  /* Get about 32 bit precision in these: */
-	  mul_32_32(0x898cc517, argSqrd.msw, &adj);
-	  fix_up -= adj/6;
+	  fix_up -= mul_32_32(0x898cc517, argSqrd.msw) / 6;
 	}
-      mul_32_32(fix_up, LL_MSW(fixed_arg), &fix_up);
+      fix_up = mul_32_32(fix_up, LL_MSW(fixed_arg));
 
       adj = accumulator.lsw;    /* temp save */
       accumulator.lsw -= fix_up;
@@ -211,7 +213,6 @@
   FPU_REG	      result;
   long int            exponent, exp2, echange;
   Xsig                accumulator, argSqrd, fix_up, argTo4;
-  unsigned long       adj;
   unsigned long long  fixed_arg;
 
 #ifdef PARANOID
@@ -300,6 +301,9 @@
 	}
       /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
       fixed_arg = 0x921fb54442d18469LL - fixed_arg;
+      /* There is a special case which arises due to rounding, to fix here. */
+      if ( fixed_arg == 0xffffffffffffffffLL )
+	fixed_arg = 0;
 
       exponent = -1;
       exp2 = -1;
@@ -363,10 +367,8 @@
       if ( argSqrd.msw & 0xffc00000 )
 	{
 	  /* Get about 32 bit precision in these: */
-	  mul_32_32(0x898cc517, argSqrd.msw, &adj);
-	  fix_up.msw -= adj/2;
-	  mul_32_32(0x898cc517, argTo4.msw, &adj);
-	  fix_up.msw += adj/24;
+	  fix_up.msw -= mul_32_32(0x898cc517, argSqrd.msw) / 2;
+	  fix_up.msw += mul_32_32(0x898cc517, argTo4.msw) / 24;
 	}
 
       exp2 += norm_Xsig(&accumulator);
diff -u --recursive --new-file v2.3.25/linux/arch/i386/math-emu/poly_tan.c linux/arch/i386/math-emu/poly_tan.c
--- v2.3.25/linux/arch/i386/math-emu/poly_tan.c	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/poly_tan.c	Thu Nov  4 09:10:22 1999
@@ -3,9 +3,9 @@
  |                                                                           |
  | Compute the tan of a FPU_REG, using a polynomial approximation.           |
  |                                                                           |
- | Copyright (C) 1992,1993,1994,1997                                         |
+ | Copyright (C) 1992,1993,1994,1997,1999                                    |
  |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      |
- |                       Australia.  E-mail   billm@suburbia.net             |
+ |                       Australia.  E-mail   billm@melbpc.org.au            |
  |                                                                           |
  |                                                                           |
  +---------------------------------------------------------------------------*/
@@ -84,6 +84,14 @@
 	}
       /* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
       XSIG_LL(accum) = 0x921fb54442d18469LL - XSIG_LL(accum);
+      /* This is a special case which arises due to rounding. */
+      if ( XSIG_LL(accum) == 0xffffffffffffffffLL )
+	{
+	  FPU_settag0(TAG_Valid);
+	  significand(st0_ptr) = 0x8a51e04daabda360LL;
+	  setexponent16(st0_ptr, 0x41 + EXTENDED_Ebias | SIGN_Negative);
+	  return;
+	}
 
       argSignif.lsw = accum.lsw;
       XSIG_LL(argSignif) = XSIG_LL(accum);
@@ -177,11 +185,11 @@
       else if ( exponent > -30 )
 	{
 	  adj = accum.msw >> -(exponent+1);      /* tan */
-	  mul_32_32(adj, adj, &adj);           /* tan^2 */
+	  adj = mul_32_32(adj, adj);             /* tan^2 */
 	}
       else
 	adj = 0;
-      mul_32_32(0x898cc517, adj, &adj);        /* delta * tan^2 */
+      adj = mul_32_32(0x898cc517, adj);          /* delta * tan^2 */
 
       fix_up.msw += adj;
       if ( !(fix_up.msw & 0x80000000) )   /* did fix_up overflow ? */
diff -u --recursive --new-file v2.3.25/linux/arch/i386/math-emu/reg_round.S linux/arch/i386/math-emu/reg_round.S
--- v2.3.25/linux/arch/i386/math-emu/reg_round.S	Tue Aug 31 17:29:12 1999
+++ linux/arch/i386/math-emu/reg_round.S	Thu Nov  4 09:10:22 1999
@@ -365,7 +365,7 @@
 	jne	LDo_64_round_up
 
 	/* Now test for round-to-even */
-	testb	$1,%ebx
+	testb	$1,%bl
 	jz	LCheck_truncate_64
 
 LDo_64_round_up:
diff -u --recursive --new-file v2.3.25/linux/arch/i386/math-emu/version.h linux/arch/i386/math-emu/version.h
--- v2.3.25/linux/arch/i386/math-emu/version.h	Tue Dec  9 17:57:09 1997
+++ linux/arch/i386/math-emu/version.h	Thu Nov  4 09:10:22 1999
@@ -2,11 +2,11 @@
  |  version.h                                                                |
  |                                                                           |
  |                                                                           |
- | Copyright (C) 1992,1993,1994,1996,1997                                    |
+ | Copyright (C) 1992,1993,1994,1996,1997,1999                               |
  |                  W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
- |                  E-mail   billm@suburbia.net                              |
+ |                  E-mail   billm@melbpc.org.au                             |
  |                                                                           |
  |                                                                           |
  +---------------------------------------------------------------------------*/
 
-#define FPU_VERSION "wm-FPU-emu version 2.00"
+#define FPU_VERSION "wm-FPU-emu version 2.01"
diff -u --recursive --new-file v2.3.25/linux/arch/i386/mm/init.c linux/arch/i386/mm/init.c
--- v2.3.25/linux/arch/i386/mm/init.c	Fri Oct 22 13:21:45 1999
+++ linux/arch/i386/mm/init.c	Fri Nov  5 15:21:27 1999
@@ -379,10 +379,16 @@
 {
 	int i;
 	/*
-	 * Zap initial low-memory mappings:
+	 * Zap initial low-memory mappings.
+	 *
+	 * Note that "pgd_clear()" doesn't do it for
+	 * us in this case, because pgd_clear() is a
+	 * no-op in the 2-level case (pmd_clear() is
+	 * the thing that clears the page-tables in
+	 * that case).
 	 */
 	for (i = 0; i < USER_PTRS_PER_PGD; i++)
-		pgd_clear(swapper_pg_dir + i);
+		pgd_val(swapper_pg_dir[i]) = 0;
 }
 
 /*
diff -u --recursive --new-file v2.3.25/linux/arch/m68k/config.in linux/arch/m68k/config.in
--- v2.3.25/linux/arch/m68k/config.in	Sat Oct  9 11:47:50 1999
+++ linux/arch/m68k/config.in	Fri Nov  5 10:22:51 1999
@@ -70,6 +70,11 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
 tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
diff -u --recursive --new-file v2.3.25/linux/arch/m68k/defconfig linux/arch/m68k/defconfig
--- v2.3.25/linux/arch/m68k/defconfig	Thu Feb 25 10:46:46 1999
+++ linux/arch/m68k/defconfig	Fri Nov  5 10:22:51 1999
@@ -38,6 +38,8 @@
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
 CONFIG_BINFMT_AOUT=y
 CONFIG_BINFMT_ELF=y
 CONFIG_ZORRO=y
diff -u --recursive --new-file v2.3.25/linux/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c
--- v2.3.25/linux/arch/m68k/kernel/process.c	Tue Sep  7 12:14:06 1999
+++ linux/arch/m68k/kernel/process.c	Tue Nov  2 08:43:37 1999
@@ -102,10 +102,6 @@
 
 void machine_power_off(void)
 {
-#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
-	apm_set_power_state(APM_STATE_OFF);
-#endif
-
 	if (mach_power_off)
 		mach_power_off();
 	for (;;);
diff -u --recursive --new-file v2.3.25/linux/arch/mips/config.in linux/arch/mips/config.in
--- v2.3.25/linux/arch/mips/config.in	Mon Nov  1 13:56:26 1999
+++ linux/arch/mips/config.in	Fri Nov  5 10:22:51 1999
@@ -69,6 +69,9 @@
    bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
 fi
 
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   define_bool CONFIG_KCORE_ELF y
+fi
 define_bool CONFIG_ELF_KERNEL y
 
 if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
diff -u --recursive --new-file v2.3.25/linux/arch/mips/defconfig linux/arch/mips/defconfig
--- v2.3.25/linux/arch/mips/defconfig	Mon Jul  5 19:44:57 1999
+++ linux/arch/mips/defconfig	Fri Nov  5 10:22:51 1999
@@ -35,6 +35,8 @@
 CONFIG_PCI_QUIRKS=y
 CONFIG_PCI_OLD_PROC=y
 CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
 CONFIG_ELF_KERNEL=y
 # CONFIG_BINFMT_AOUT is not set
 CONFIG_BINFMT_ELF=y
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/amiga/Makefile linux/arch/ppc/amiga/Makefile
--- v2.3.25/linux/arch/ppc/amiga/Makefile	Sat Oct  9 11:47:50 1999
+++ linux/arch/ppc/amiga/Makefile	Fri Nov  5 15:53:25 1999
@@ -9,7 +9,8 @@
 
 O_TARGET := amiga.o
 O_OBJS   := config.o amiints.o cia.o time.o \
-            bootinfo.o amisound.o chipram.o ints.o
+            bootinfo.o amisound.o chipram.o 
+
 OX_OBJS  := amiga_ksyms.o
 
 ifdef CONFIG_AMIGA_PCMCIA
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/amiga/amiints.c linux/arch/ppc/amiga/amiints.c
--- v2.3.25/linux/arch/ppc/amiga/amiints.c	Sat Oct  9 11:47:50 1999
+++ linux/arch/ppc/amiga/amiints.c	Fri Nov  5 15:53:25 1999
@@ -53,10 +53,10 @@
 #include <asm/amigappc.h>
 #endif
 
-extern int cia_request_irq(struct ciabase *base,int irq,
+extern int cia_request_irq(int irq,
                            void (*handler)(int, void *, struct pt_regs *),
                            unsigned long flags, const char *devname, void *dev_id);
-extern void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id);
+extern void cia_free_irq(unsigned int irq, void *dev_id);
 extern void cia_init_IRQ(struct ciabase *base);
 extern int cia_get_irq_list(struct ciabase *base, char *buf);
 
@@ -89,7 +89,8 @@
  * the amiga IRQ handling routines.
  */
 
-void __init amiga_init_IRQ(void)
+__init
+void amiga_init_IRQ(void)
 {
 	int i;
 
@@ -216,13 +217,8 @@
 		return sys_request_irq(irq - IRQ_AMIGA_AUTO, handler,
 		                       flags, devname, dev_id);
 
-	if (irq >= IRQ_AMIGA_CIAB)
-		return cia_request_irq(&ciab_base, irq - IRQ_AMIGA_CIAB,
-		                       handler, flags, devname, dev_id);
-
 	if (irq >= IRQ_AMIGA_CIAA)
-		return cia_request_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA,
-		                       handler, flags, devname, dev_id);
+		return cia_request_irq(irq, handler, flags, devname, dev_id);
 
 	/*
 	 * IRQ_AMIGA_PORTS & IRQ_AMIGA_EXTER defaults to shared,
@@ -262,13 +258,8 @@
 	if (irq >= IRQ_AMIGA_AUTO)
 		sys_free_irq(irq - IRQ_AMIGA_AUTO, dev_id);
 
-	if (irq >= IRQ_AMIGA_CIAB) {
-		cia_free_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, dev_id);
-		return;
-	}
-
 	if (irq >= IRQ_AMIGA_CIAA) {
-		cia_free_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, dev_id);
+		cia_free_irq(irq, dev_id);
 		return;
 	}
 
@@ -314,17 +305,9 @@
 		return;
 	}
 
-	if (irq >= IRQ_AMIGA_CIAB) {
-		cia_set_irq(&ciab_base, (1 << (irq - IRQ_AMIGA_CIAB)));
-		cia_able_irq(&ciab_base, CIA_ICR_SETCLR |
-		             (1 << (irq - IRQ_AMIGA_CIAB)));
-		return;
-	}
-
 	if (irq >= IRQ_AMIGA_CIAA) {
-		cia_set_irq(&ciaa_base, (1 << (irq - IRQ_AMIGA_CIAA)));
-		cia_able_irq(&ciaa_base, CIA_ICR_SETCLR |
-		             (1 << (irq - IRQ_AMIGA_CIAA)));
+		cia_set_irq(irq, 0);
+		cia_able_irq(irq, 1);
 		return;
 	}
 
@@ -349,13 +332,8 @@
 		return;
 	}
 
-	if (irq >= IRQ_AMIGA_CIAB) {
-		cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB));
-		return;
-	}
-
 	if (irq >= IRQ_AMIGA_CIAA) {
-		cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA));
+		cia_able_irq(irq, 0);
 		return;
 	}
 
@@ -528,10 +506,20 @@
 	panic ("level 7 interrupt received\n");
 }
 
+#ifdef CONFIG_APUS
+/* The PPC irq handling links all handlers requested on the same vector
+   and executes them in a loop. Having ami_badint at the end of the chain
+   is a bad idea. */
+void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
+	NULL, ami_int1, NULL, NULL /* FB expects to replace ami_int3*/,
+	ami_int4, ami_int5, NULL, ami_int7
+};
+#else
 void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
 	ami_badint, ami_int1, ami_badint, ami_int3,
 	ami_int4, ami_int5, ami_badint, ami_int7
 };
+#endif
 
 int amiga_get_irq_list(char *buf)
 {
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/amiga/cia.c linux/arch/ppc/amiga/cia.c
--- v2.3.25/linux/arch/ppc/amiga/cia.c	Tue Aug  4 16:06:36 1998
+++ linux/arch/ppc/amiga/cia.c	Fri Nov  5 15:53:25 1999
@@ -1 +1,235 @@
-#include "../../m68k/amiga/cia.c"
+/*
+ *  linux/arch/m68k/amiga/cia.c - CIA support
+ *
+ *  Copyright (C) 1996 Roman Zippel
+ *
+ *  The concept of some functions bases on the original Amiga OS function
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/amigahw.h>
+#include <asm/amigaints.h>
+
+struct ciabase {
+	volatile struct CIA *cia;
+	u_char icr_mask, icr_data;
+	u_short int_mask;
+	int handler_irq, cia_irq, server_irq;
+	char *name;
+	struct irq_server server;
+	irq_handler_t irq_list[CIA_IRQS];
+} ciaa_base = {
+	&ciaa, 0, 0, IF_PORTS,
+	IRQ_AMIGA_AUTO_2, IRQ_AMIGA_CIAA,
+	IRQ_AMIGA_PORTS,
+	"CIAA handler", {0, 0}
+}, ciab_base = {
+	&ciab, 0, 0, IF_EXTER,
+	IRQ_AMIGA_AUTO_6, IRQ_AMIGA_CIAB,
+	IRQ_AMIGA_EXTER,
+	"CIAB handler", {0, 0}
+};
+
+#define CIA_SET_BASE_ADJUST_IRQ(base, irq)	\
+do {						\
+	if (irq >= IRQ_AMIGA_CIAB) {		\
+		base = &ciab_base;		\
+		irq =- IRQ_AMIGA_CIAB;		\
+	} else {				\
+		base = &ciaa_base;		\
+		irq =- IRQ_AMIGA_CIAA;		\
+	}					\
+} while (0)
+
+/*
+ *  Cause or clear CIA interrupts, return old interrupt status.
+ */
+
+static unsigned char cia_set_irq_private(struct ciabase *base,
+					 unsigned char mask)
+{
+	u_char old;
+
+	old = (base->icr_data |= base->cia->icr);
+	if (mask & CIA_ICR_SETCLR)
+		base->icr_data |= mask;
+	else
+		base->icr_data &= ~mask;
+	if (base->icr_data & base->icr_mask)
+		custom.intreq = IF_SETCLR | base->int_mask;
+	return old & base->icr_mask;
+}
+
+unsigned char cia_set_irq(unsigned int irq, int set)
+{
+	struct ciabase *base;
+	unsigned char mask;
+
+	if (irq >= IRQ_AMIGA_CIAB)
+		mask = (1 << (irq - IRQ_AMIGA_CIAB));
+	else
+		mask = (1 << (irq - IRQ_AMIGA_CIAA));
+	mask |= (set) ? CIA_ICR_SETCLR : 0;
+
+	CIA_SET_BASE_ADJUST_IRQ(base, irq);
+
+	return cia_set_irq_private(base, mask);
+}
+
+unsigned char cia_get_irq_mask(unsigned int irq)
+{
+	struct ciabase *base;
+
+	CIA_SET_BASE_ADJUST_IRQ(base, irq);
+
+	return base->cia->icr;
+}
+
+/*
+ *  Enable or disable CIA interrupts, return old interrupt mask,
+ *  interrupts will only be enabled if a handler exists
+ */
+
+static unsigned char cia_able_irq_private(struct ciabase *base,
+					  unsigned char mask)
+{
+	u_char old, tmp;
+	int i;
+
+	old = base->icr_mask;
+	base->icr_data |= base->cia->icr;
+	base->cia->icr = mask;
+	if (mask & CIA_ICR_SETCLR)
+		base->icr_mask |= mask;
+	else
+		base->icr_mask &= ~mask;
+	base->icr_mask &= CIA_ICR_ALL;
+	for (i = 0, tmp = 1; i < CIA_IRQS; i++, tmp <<= 1) {
+		if ((tmp & base->icr_mask) && !base->irq_list[i].handler) {
+			base->icr_mask &= ~tmp;
+			base->cia->icr = tmp;
+		}
+	}
+	if (base->icr_data & base->icr_mask)
+		custom.intreq = IF_SETCLR | base->int_mask;
+	return old;
+}
+
+unsigned char cia_able_irq(unsigned int irq, int enable)
+{
+	struct ciabase *base;
+	unsigned char mask;
+
+	if (irq >= IRQ_AMIGA_CIAB)
+		mask = (1 << (irq - IRQ_AMIGA_CIAB));
+	else
+		mask = (1 << (irq - IRQ_AMIGA_CIAA));
+	mask |= (enable) ? CIA_ICR_SETCLR : 0;
+
+	CIA_SET_BASE_ADJUST_IRQ(base, irq);
+
+	return cia_able_irq_private(base, mask);
+}
+
+int cia_request_irq(unsigned int irq,
+                    void (*handler)(int, void *, struct pt_regs *),
+                    unsigned long flags, const char *devname, void *dev_id)
+{
+	u_char mask;
+	struct ciabase *base;
+
+	CIA_SET_BASE_ADJUST_IRQ(base, irq);
+
+	base->irq_list[irq].handler = handler;
+	base->irq_list[irq].flags   = flags;
+	base->irq_list[irq].dev_id  = dev_id;
+	base->irq_list[irq].devname = devname;
+
+	/* enable the interrupt */
+	mask = 1 << irq;
+	cia_set_irq_private(base, mask);
+	cia_able_irq_private(base, CIA_ICR_SETCLR | mask);
+	return 0;
+}
+
+void cia_free_irq(unsigned int irq, void *dev_id)
+{
+	struct ciabase *base;
+
+	CIA_SET_BASE_ADJUST_IRQ(base, irq);
+
+	if (base->irq_list[irq].dev_id != dev_id)
+		printk("%s: removing probably wrong IRQ %i from %s\n",
+		       __FUNCTION__, base->cia_irq + irq,
+		       base->irq_list[irq].devname);
+
+	base->irq_list[irq].handler = NULL;
+	base->irq_list[irq].flags   = 0;
+
+	cia_able_irq_private(base, 1 << irq);
+}
+
+static void cia_handler(int irq, void *dev_id, struct pt_regs *fp)
+{
+	struct ciabase *base = (struct ciabase *)dev_id;
+	int mach_irq, i;
+	unsigned char ints;
+
+	mach_irq = base->cia_irq;
+	irq = SYS_IRQS + mach_irq;
+	ints = cia_set_irq_private(base, CIA_ICR_ALL);
+	custom.intreq = base->int_mask;
+	for (i = 0; i < CIA_IRQS; i++, irq++, mach_irq++) {
+		if (ints & 1) {
+			kstat.irqs[0][irq]++;
+			base->irq_list[i].handler(mach_irq, base->irq_list[i].dev_id, fp);
+		}
+		ints >>= 1;
+	}
+	amiga_do_irq_list(base->server_irq, fp, &base->server);
+}
+
+void __init cia_init_IRQ(struct ciabase *base)
+{
+	int i;
+
+	/* init isr handlers */
+	for (i = 0; i < CIA_IRQS; i++) {
+		base->irq_list[i].handler = NULL;
+		base->irq_list[i].flags   = 0;
+	}
+
+	/* clear any pending interrupt and turn off all interrupts */
+	cia_set_irq_private(base, CIA_ICR_ALL);
+	cia_able_irq_private(base, CIA_ICR_ALL);
+
+	/* install CIA handler */
+	request_irq(base->handler_irq, cia_handler, 0, base->name, base);
+
+	custom.intena = IF_SETCLR | base->int_mask;
+}
+
+int cia_get_irq_list(struct ciabase *base, char *buf)
+{
+	int i, j, len = 0;
+
+	j = base->cia_irq;
+	for (i = 0; i < CIA_IRQS; i++) {
+		len += sprintf(buf+len, "cia  %2d: %10d ", j + i,
+			       kstat.irqs[0][SYS_IRQS + j + i]);
+			len += sprintf(buf+len, "  ");
+		len += sprintf(buf+len, "%s\n", base->irq_list[i].devname);
+	}
+	return len;
+}
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/amiga/config.c linux/arch/ppc/amiga/config.c
--- v2.3.25/linux/arch/ppc/amiga/config.c	Sat Oct  9 11:47:50 1999
+++ linux/arch/ppc/amiga/config.c	Fri Nov  5 15:53:25 1999
@@ -461,6 +461,8 @@
 
 #define TICK_SIZE 10000
 
+extern unsigned char cia_get_irq_mask(unsigned int irq);
+
 /* This is always executed with interrupts disabled.  */
 static unsigned long amiga_gettimeoffset (void)
 {
@@ -481,7 +483,7 @@
 
 	if (ticks > jiffy_ticks / 2)
 		/* check for pending interrupt */
-		if (cia_set_irq(&ciab_base, 0) & CIA_ICR_TA)
+		if (cia_get_irq_mask(IRQ_AMIGA_CIAB) & CIA_ICR_TA)
 			offset = 10000;
 
 	ticks = jiffy_ticks - ticks;
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/common_defconfig linux/arch/ppc/common_defconfig
--- v2.3.25/linux/arch/ppc/common_defconfig	Sat Oct  9 11:47:50 1999
+++ linux/arch/ppc/common_defconfig	Fri Nov  5 15:53:25 1999
@@ -1,13 +1,19 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# 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
@@ -15,17 +21,19 @@
 CONFIG_ALL_PPC=y
 # CONFIG_GEMINI is not set
 # CONFIG_APUS is not set
-# CONFIG_MBX is not set
 # CONFIG_SMP is not set
 CONFIG_6xx=y
 
 #
-# General setup
+# Loadable module support
 #
-CONFIG_EXPERIMENTAL=y
 CONFIG_MODULES=y
 CONFIG_MODVERSIONS=y
 CONFIG_KMOD=y
+
+#
+# General setup
+#
 CONFIG_PCI=y
 CONFIG_NET=y
 CONFIG_SYSCTL=y
@@ -34,6 +42,11 @@
 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
@@ -41,7 +54,6 @@
 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
@@ -57,21 +69,27 @@
 # Plug and Play configuration
 #
 # CONFIG_PNP is not set
-# CONFIG_ISAPNP 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_IDECD_SLOTS is not set
 # 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
@@ -83,12 +101,17 @@
 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
@@ -115,10 +138,18 @@
 # 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
@@ -140,11 +171,19 @@
 # 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
@@ -179,6 +218,7 @@
 # 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
@@ -226,17 +266,22 @@
 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_YELLOWFIN is not set
-# CONFIG_ACENIC 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
@@ -252,7 +297,6 @@
 # CONFIG_ES3210 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_ZNET is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
 # CONFIG_NET_POCKET is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
@@ -265,13 +309,18 @@
 # 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 devices
+# Token Ring driver support
 #
 # CONFIG_TR is not set
 # CONFIG_NET_FC is not set
@@ -281,17 +330,7 @@
 #
 # Wan interfaces
 #
-# CONFIG_HOSTESS_SV11 is not set
-# CONFIG_COSA is not set
-# CONFIG_SEALEVEL_4021 is not set
-# CONFIG_DLCI is not set
-
-#
-# PCMCIA network devices
-#
-# CONFIG_PCMCIA_PCNET is not set
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_WAN is not set
 
 #
 # Amateur Radio support
@@ -311,6 +350,11 @@
 #
 # Console drivers
 #
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FB_CLGEN is not set
 # CONFIG_FB_PM2 is not set
@@ -328,6 +372,8 @@
 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
@@ -362,7 +408,7 @@
 # CONFIG_ATIXL_BUSMOUSE is not set
 # CONFIG_LOGIBUSMOUSE is not set
 # CONFIG_MS_BUSMOUSE is not set
-# CONFIG_ADB_MOUSE is not set
+# CONFIG_ADBMOUSE is not set
 CONFIG_MOUSE=y
 CONFIG_PSMOUSE=y
 # CONFIG_82C710_MOUSE is not set
@@ -403,11 +449,11 @@
 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_HFS_FS=y
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
 # CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=y
 # CONFIG_EFS_FS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
@@ -420,6 +466,7 @@
 # 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
 
@@ -446,7 +493,39 @@
 # CONFIG_UNIXWARE_DISKLABEL is not set
 # CONFIG_SGI_PARTITION is not set
 # CONFIG_SUN_PARTITION is not set
-# CONFIG_NLS 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
@@ -463,27 +542,27 @@
 # CONFIG_SOUND_MSNDPIN is not set
 CONFIG_SOUND_OSS=y
 # CONFIG_SOUND_DMAP is not set
-# 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_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_VIA82CXXX 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_CS4232=m
-# CONFIG_SOUND_OPL3SA2 is not set
 # CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_VIA82CXXX is not set
 # CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
 # CONFIG_SOUND_UART6850 is not set
 
 #
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v2.3.25/linux/arch/ppc/config.in	Mon Nov  1 13:56:26 1999
+++ linux/arch/ppc/config.in	Fri Nov  5 15:53:25 1999
@@ -44,6 +44,10 @@
 fi
 
 bool 'Symmetric multi-processing support' CONFIG_SMP
+if [ "$CONFIG_6xx" != "y" ];then
+  bool 'AltiVec Support' CONFIG_ALTIVEC
+fi
+
 if [ "$CONFIG_ALL_PPC" != "y" ];then
   define_bool CONFIG_MACH_SPECIFIC y
 fi
@@ -85,6 +89,9 @@
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 
 # only elf supported, a.out is not -- Cort
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   define_bool CONFIG_KCORE_ELF y
+fi
 define_bool CONFIG_BINFMT_ELF y
 define_bool CONFIG_KERNEL_ELF y
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/defconfig linux/arch/ppc/defconfig
--- v2.3.25/linux/arch/ppc/defconfig	Wed Oct 27 16:34:12 1999
+++ linux/arch/ppc/defconfig	Fri Nov  5 10:22:51 1999
@@ -43,6 +43,8 @@
 CONFIG_SYSCTL=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_KCORE_AOUT is not set
+CONFIG_KCORE_ELF=y
 CONFIG_BINFMT_ELF=y
 CONFIG_KERNEL_ELF=y
 # CONFIG_BINFMT_MISC is not set
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile
--- v2.3.25/linux/arch/ppc/kernel/Makefile	Fri Oct 15 15:25:13 1999
+++ linux/arch/ppc/kernel/Makefile	Fri Nov  5 15:53:25 1999
@@ -60,15 +60,12 @@
 O_OBJS += i8259.o
 endif
 else
-ifeq ($(CONFIG_APUS),y)
-O_OBJS += apus_setup.o prom.o open_pic.o
-else
-ifneq ($(CONFIG_8xx),y)
 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
 endif
@@ -83,7 +80,8 @@
 ifeq ($(CONFIG_PMAC), y)
 endif
 
-endif
+ifdef CONFIG_APUS
+O_OBJS += apus_setup.o
 endif
 endif
 
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/kernel/apus_setup.c linux/arch/ppc/kernel/apus_setup.c
--- v2.3.25/linux/arch/ppc/kernel/apus_setup.c	Fri Oct 22 13:21:45 1999
+++ linux/arch/ppc/kernel/apus_setup.c	Fri Nov  5 15:53:25 1999
@@ -32,7 +32,10 @@
 #include <linux/ide.h>
 #define ide_init_hwif_ports m68k_ide_init_hwif_ports
 #define ide_default_irq m68k_ide_default_irq
+#undef ide_request_irq
 #define ide_request_irq m68k_ide_request_irq
+#undef ide_free_irq
+#define ide_free_irq m68k_ide_free_irq
 #define ide_default_io_base m68k_ide_default_io_base
 #define ide_check_region m68k_ide_check_region
 #define ide_request_region m68k_ide_request_region
@@ -40,7 +43,6 @@
 #define ide_fix_driveid m68k_ide_fix_driveid
 #define ide_init_default_hwifs m68k_ide_init_default_hwifs
 #define select_t m68k_select_t
-#define ide_free_irq m68k_ide_free_irq
 //#include <asm/hdreg.h>
 #include <asm-m68k/ide.h>
 #undef ide_free_irq
@@ -59,6 +61,7 @@
 #include <asm/bootinfo.h>
 #include <asm/setup.h>
 #include <asm/amigahw.h>
+#include <asm/amigaints.h>
 #include <asm/amigappc.h>
 #include <asm/pgtable.h>
 #include <asm/io.h>
@@ -71,6 +74,8 @@
 unsigned long m68k_machtype __apusdata;
 char debug_device[6] __apusdata = "";
 
+extern void amiga_init_IRQ(void);
+
 void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata;
 /* machine dependent keyboard functions */
 int (*mach_keyb_init) (void) __initdata;
@@ -162,57 +167,6 @@
 #endif
 }
 
-__apus
-int  apus_request_irq(unsigned int irq, 
-		      void (*handler)(int, void *, struct pt_regs *),
-		      unsigned long flags, const char *devname, 
-		      void *dev_id)
-{
-#ifdef CONFIG_APUS
-	extern int  amiga_request_irq(unsigned int irq, 
-				      void (*handler)(int, void *, 
-						      struct pt_regs *),
-				      unsigned long flags, 
-				      const char *devname, 
-				      void *dev_id);
-
-	return amiga_request_irq (irq, handler, flags, devname, dev_id);
-#else
-	return 0;
-#endif
-}
-
-__apus
-void apus_free_irq(unsigned int irq, void *dev_id)
-{
-#ifdef CONFIG_APUS
-	extern void amiga_free_irq(unsigned int irq, void *dev_id);
-
-	amiga_free_irq (irq, dev_id);
-#endif
-}
-
-__apus
-void apus_process_int(unsigned long vec, void *fp)
-{
-#ifdef CONFIG_APUS
-	extern void process_int(unsigned long vec, struct pt_regs *fp);
-
-	process_int (vec, (struct pt_regs*)fp);
-#endif
-}
-
-__apus
-int apus_get_irq_list(char *buf)
-{
-#ifdef CONFIG_APUS
-	extern int m68k_get_irq_list (char*);
-	
-	return m68k_get_irq_list (buf);
-#else
-	return 0;
-#endif
-}
 
 
 /* Here some functions we don't support, but which the other ports reference */
@@ -297,6 +251,7 @@
 
 	config_amiga();
 
+#if 0 /* Enable for logging - also include logging.o in Makefile rule */
 	{
 #define LOG_SIZE 4096
 		void* base;
@@ -310,6 +265,7 @@
 		LOG_INIT(base, base+sizeof(klog_data_t), LOG_SIZE);
 	}
 #endif
+#endif
 }
 
 __apus
@@ -760,67 +716,122 @@
         m68k_ide_init_hwif_ports(hw, data_port, ctrl_port, irq);
 }
 #endif
-/****************************************************** from irq.c */
-#define VEC_SPUR    (24)
+/****************************************************** IRQ stuff */
 
-void
-apus_do_IRQ(struct pt_regs *regs,
-	    int            cpu,
-            int            isfake)
+__apus
+int apus_get_irq_list(char *buf)
 {
-	int old_level, new_level;
+#ifdef CONFIG_APUS
+	extern int amiga_get_irq_list(char *buf);
+	
+	return amiga_get_irq_list (buf);
+#else
+	return 0;
+#endif
+}
 
-	new_level = (~(regs->mq) >> 3) & IPLEMU_IPLMASK;
-		
-	if (0 != new_level && 7 != new_level) {
-		old_level = ~(regs->mq) & IPLEMU_IPLMASK;
+/* IPL must be between 0 and 7 */
+__apus
+static inline void apus_set_IPL(int ipl)
+{
+	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
+	APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
+	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | ((~ipl) & IPLEMU_IPLMASK));
+	APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
+}
 
-		apus_process_int (VEC_SPUR+new_level, regs);
-		
-		APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
-		APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
-		APUS_WRITE(APUS_IPL_EMU, (IPLEMU_SETRESET
-					  | (~(old_level) & IPLEMU_IPLMASK)));
-		APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
-	}
+__apus
+static inline unsigned long apus_get_IPL(void)
+{
+	unsigned short __f;
+	APUS_READ(APUS_IPL_EMU, __f);
+	return ((~__f) & IPLEMU_IPLMASK);
 }
 
 __apus
-static void apus_save_flags(unsigned long* flags)
+static inline unsigned long apus_get_prev_IPL(void)
 {
 	unsigned short __f;
 	APUS_READ(APUS_IPL_EMU, __f);
-	return ((~__f) & IPLEMU_IPLMASK) << 8;
+	return ((~__f >> 3) & IPLEMU_IPLMASK);
+}
+
+
+__apus
+static void apus_save_flags(unsigned long* flags)
+{
+	*flags = apus_get_IPL();
 }
 
 __apus
 static void apus_restore_flags(unsigned long flags)
 {
-	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
-	APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
-	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET
-                   | (~(flags >> 8) & IPLEMU_IPLMASK));
-	APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
+	apus_set_IPL(flags);
 }
 
 __apus
 static void apus_sti(void)
 {
-	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
-	APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
-	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_IPLMASK);
-	APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
+	apus_set_IPL(0);
 }
 
 __apus
 static void apus_cli(void)
 {
-	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
-	APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
-	APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET);
-	APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
+	apus_set_IPL(7);
+}
+
+
+#ifdef CONFIG_APUS
+void free_irq(unsigned int irq, void *dev_id)
+{
+	extern void amiga_free_irq(unsigned int irq, void *dev_id);
+
+	amiga_free_irq (irq, dev_id);
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+	unsigned long irqflags, const char * devname, void *dev_id)
+{
+	extern int  amiga_request_irq(unsigned int irq, 
+				      void (*handler)(int, void *, 
+						      struct pt_regs *),
+				      unsigned long flags, 
+				      const char *devname, 
+				      void *dev_id);
+
+	return amiga_request_irq (irq, handler, irqflags, devname, dev_id);
+}
+#endif
+
+__apus
+int apus_get_irq(struct pt_regs* regs)
+{
+#ifdef CONFIG_APUS
+	int level = apus_get_IPL();
+	unsigned short ints = custom.intreqr & custom.intenar;
+
+	if (0 == level)
+		return -1;
+	if (7 == level)
+		return -2;
+
+	return level;
+#else
+	return 0;
+#endif
+}
+
+
+__apus
+void apus_post_irq(int level)
+{
+	/* Restore IPL to the previous value */
+	apus_set_IPL(apus_get_IPL());
 }
 
+
+
 /****************************************************** keyboard */
 __apus
 static int apus_kbd_setkeycode(unsigned int scancode, unsigned int keycode)
@@ -859,36 +870,54 @@
 #ifdef CONFIG_APUS
 	extern int amiga_keyb_init(void);
 
-printk("**** " __FUNCTION__ "\n");
 	amiga_keyb_init();
 #endif
 }
 
 
 /****************************************************** init */
-extern void amiga_disable_irq(unsigned int irq);
-extern void amiga_enable_irq(unsigned int irq);
-extern void m68k_init_IRQ (void);
-
-struct hw_interrupt_type amiga_irq_ctl = {
-	" Amiga    ",
-        NULL,
-        NULL,
-        NULL,
-        amiga_enable_irq,
-        amiga_disable_irq,
-        NULL,
-        0
+
+/* The number of spurious interrupts */
+volatile unsigned int num_spurious;
+
+#define NUM_IRQ_NODES 100
+static irq_node_t nodes[NUM_IRQ_NODES];
+
+extern void (*amiga_default_handler[AUTO_IRQS])(int, void *, struct pt_regs *);
+
+static const char *default_names[SYS_IRQS] = {
+	"spurious int", "int1 handler", "int2 handler", "int3 handler",
+	"int4 handler", "int5 handler", "int6 handler", "int7 handler"
 };
 
+irq_node_t *new_irq_node(void)
+{
+	irq_node_t *node;
+	short i;
+
+	for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
+		if (!node->handler)
+			return node;
+
+	printk ("new_irq_node: out of nodes\n");
+	return NULL;
+}
+
 __init
 void apus_init_IRQ(void)
 {
 	int i;
 
-	for (i = 0; i < NR_IRQS; i++)
-		irq_desc[i].ctl = &amiga_irq_ctl;
-	m68k_init_IRQ ();
+	for (i = 0; i < NUM_IRQ_NODES; i++)
+		nodes[i].handler = NULL;
+
+	for (i = 0; i < AUTO_IRQS; i++) {
+		if (amiga_default_handler[i] != NULL)
+			sys_request_irq(i, amiga_default_handler[i],
+					0, default_names[i], NULL);
+	}
+
+	amiga_init_IRQ();
 
 	int_control.int_sti = apus_sti;
 	int_control.int_cli = apus_cli;
@@ -924,7 +953,8 @@
 	ppc_md.get_cpuinfo    = apus_get_cpuinfo;
 	ppc_md.irq_cannonicalize = NULL;
 	ppc_md.init_IRQ       = apus_init_IRQ;
-	ppc_md.do_IRQ         = apus_do_IRQ;
+	ppc_md.get_irq        = apus_get_irq;
+	ppc_md.post_irq       = apus_post_irq;
 #ifdef CONFIG_HEARTBEAT
 	ppc_md.heartbeat      = apus_heartbeat;
 	ppc_md.heartbeat_count = 1;
@@ -968,4 +998,10 @@
 
         ppc_ide_md.io_base = _IO_BASE;
 #endif		
+}
+
+
+/*************************************************** coexistence */
+void __init adbdev_init(void)
+{
 }
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
--- v2.3.25/linux/arch/ppc/kernel/head.S	Fri Oct 15 15:25:13 1999
+++ linux/arch/ppc/kernel/head.S	Fri Nov  5 15:53:25 1999
@@ -365,10 +365,10 @@
 /* External interrupt */
 	. = 0x500;
 HardwareInterrupt:
-#ifndef CONFIG_APUS
 	EXCEPTION_PROLOG;
 	addi	r3,r1,STACK_FRAME_OVERHEAD
 	li	r20,MSR_KERNEL
+#ifndef CONFIG_APUS
 	li	r4,0
 	bl	transfer_to_handler
 	.globl do_IRQ_intercept
@@ -376,9 +376,6 @@
 	.long	do_IRQ;
 	.long	ret_from_except
 #else
- 	EXCEPTION_PROLOG;
- 	addi	r3,r1,STACK_FRAME_OVERHEAD
- 	li	r20,MSR_KERNEL
 	bl	apus_interrupt_entry
 #endif /* CONFIG_APUS */
 
@@ -447,7 +444,7 @@
 	STD_EXCEPTION(0xd00, SingleStep, SingleStepException)
 
 	STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
-	STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
+	STD_EXCEPTION(0xf20, AltiVec, AltiVecUnavailable)
 
 /*
  * Handle TLB miss for instruction on 603/603e.
@@ -807,6 +804,59 @@
 	.align	4
 
 /*
+ * Take away the altivec regs.
+ *
+ * For now, ignore the vrsave regs and save them all
+ *   -- Cort
+ */
+	.globl giveup_altivec
+giveup_altivec:
+#ifdef CONFIG_ALTIVEC	
+	/* check for altivec */
+	mfspr	r4,PVR
+	srwi	r4,r4,16
+	cmpi	0,r4,12
+	bnelr
+
+	/* save altivec regs */
+	addi	r4,r3,THREAD+THREAD_VRSAVE
+	mfspr	r5,256		/* vrsave */
+	stw	r5,0(r4)
+	
+	/* get regs for the task */
+	addi	r4,r3,THREAD+PT_REGS
+	/* turn off the altivec bit in the tasks regs */
+	lwz	r5,_MSR(r4)
+	lis	r6,MSR_VEC@h
+	andi.	r5,r5,r6
+	stw	r5,_MSR(r4)
+#endif /* CONFIG_ALTIVEC */
+	blr
+	
+	.globl load_up_altivec
+load_up_altivec:
+#ifdef CONFIG_ALTIVEC	
+	/* check for altivec */
+	mfspr	r4,PVR
+	srwi	r4,r4,16
+	cmpi	0,r4,12
+	bnelr
+	
+	/* restore altivec regs */
+	addi	r4,r3,THREAD+THREAD_VRSAVE
+	lwz	r5,0(r4)
+	mtspr	256,r5		/* vrsave */
+	
+	/* get regs for the task */
+	addi	r4,r3,THREAD+PT_REGS
+	/* turn on the altivec bit in the tasks regs */
+	lwz	r5,_MSR(r4)
+	oris	r5,r5,MSR_VEC@h
+	stw	r5,_MSR(r4)
+#endif /* CONFIG_ALTIVEC */
+	blr
+	
+/*
  * giveup_fpu(tsk)
  * Disable FP for the task given as the argument,
  * and save the floating-point registers in its thread_struct.
@@ -957,14 +1007,69 @@
 
 	isync				/* No speculative loading until now */
 	blr
+	
+apus_interrupt_entry:
+	/* This is horrible, but there's no way around it. Enable the
+	 * data cache so the IRQ hardware register can be accessed
+	 * without cache intervention. Then disable interrupts and get
+	 * the current emulated m68k IPL value. 
+	 */
+	
+	mfmsr	20
+	xori	r20,r20,MSR_DR
+	sync
+	mtmsr	r20
+	sync
 
-       /* On APUS the first 0x4000 bytes of the kernel will be mapped
-        * at a different physical address than the rest. For this
-        * reason, the exception code cannot use relative branches to
-        * access the code below.
-        */
-	. = 0x4000
-#endif
+	lis	r4,APUS_IPL_EMU@h
+
+	li	r20,(IPLEMU_SETRESET|IPLEMU_DISABLEINT)
+	stb	r20,APUS_IPL_EMU@l(r4)
+	eieio
+
+	lbz	r3,APUS_IPL_EMU@l(r4)
+
+	li	r2,IPLEMU_IPLMASK
+	rlwinm. r20,r3,32-3,29,31
+	bne	2f
+	mr	r20,r2		/* lvl7! Need to reset state machine. */
+	b	3f
+2:	cmp	0,r20,r2
+	beq	1f
+3:	eieio
+	stb     r2,APUS_IPL_EMU@l(r4)
+	ori	r20,r20,IPLEMU_SETRESET
+	eieio
+	stb     r20,APUS_IPL_EMU@l(r4)
+1:	eieio
+	li	r20,IPLEMU_DISABLEINT
+	stb	r20,APUS_IPL_EMU@l(r4)
+
+	/* At this point we could do some magic to avoid the overhead
+	 * of calling the C interrupt handler in case of a spurious
+	 * interrupt. Could not get a simple hack to work though.
+	 */
+	
+	mfmsr	r20
+	xori	r20,r20,MSR_DR
+	sync
+	mtmsr	r20
+	sync
+
+	stw	r3,(_CCR+4)(r21);
+
+	addi	r3,r1,STACK_FRAME_OVERHEAD;
+	li	r20,MSR_KERNEL;
+	bl	transfer_to_handler;
+	.long	do_IRQ;
+	.long	ret_from_except
+
+/***********************************************************************
+ *  Please note that on APUS the exception handlers are located at the
+ *  physical address 0xfff0000. For this reason, the exception handlers
+ *  cannot use relative branches to access the code below.
+ ***********************************************************************/
+#endif /* CONFIG_APUS */
 
 #ifdef CONFIG_SMP
 	.globl	__secondary_hold
@@ -1165,6 +1270,19 @@
 	bl	identify_machine
 	bl	MMU_init
 
+#ifdef CONFIG_APUS
+	/* Copy exception code to exception vector base on APUS. */
+	lis	r4,KERNELBASE@h
+#ifdef CONFIG_APUS_FAST_EXCEPT
+	lis	r3,0xfff0		/* Copy to 0xfff00000 */
+#else
+	lis	r3,0			/* Copy to 0x00000000 */
+#endif
+	li	r5,0x4000		/* # bytes of memory to copy */
+	li	r6,0
+	bl	copy_and_flush		/* copy the first 0x4000 bytes */
+#endif  /* CONFIG_APUS */
+
 /*
  * Go back to running unmapped so we can load up new values
  * for SDR1 (hash table pointer) and the segment registers
@@ -1283,3 +1401,4 @@
 	mtspr	IBAT3L,r20
 	
 	blr
+
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- v2.3.25/linux/arch/ppc/kernel/irq.c	Wed Oct 27 16:34:12 1999
+++ linux/arch/ppc/kernel/irq.c	Fri Nov  5 15:53:25 1999
@@ -67,14 +67,6 @@
 
 volatile unsigned char *chrp_int_ack_special;
 
-#ifdef CONFIG_APUS
-/* Rename a few functions. Requires the CONFIG_APUS protection. */
-#define request_irq nop_ppc_request_irq
-#define free_irq nop_ppc_free_irq
-#define get_irq_list nop_get_irq_list
-#define VEC_SPUR    (24)
-#endif
-
 #define MAXCOUNT 10000000
 
 #define NR_MASK_WORDS	((NR_IRQS + 31) / 32)
@@ -94,8 +86,9 @@
  * this needs to be removed.
  * -- Cort
  */
-static char cache_bitmask = 0;
-static struct irqaction malloc_cache[8];
+#define IRQ_KMALLOC_ENTRIES 8
+static int cache_bitmask = 0;
+static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES];
 extern int mem_init_done;
 
 void *irq_kmalloc(size_t size, int pri)
@@ -103,7 +96,7 @@
 	unsigned int i;
 	if ( mem_init_done )
 		return kmalloc(size,pri);
-	for ( i = 0; i <= 3 ; i++ )
+	for ( i = 0; i < IRQ_KMALLOC_ENTRIES ; i++ )
 		if ( ! ( cache_bitmask & (1<<i) ) )
 		{
 			cache_bitmask |= (1<<i);
@@ -115,7 +108,7 @@
 void irq_kfree(void *ptr)
 {
 	unsigned int i;
-	for ( i = 0 ; i <= 3 ; i++ )
+	for ( i = 0 ; i < IRQ_KMALLOC_ENTRIES ; i++ )
 		if ( ptr == &malloc_cache[i] )
 		{
 			cache_bitmask &= ~(1<<i);
@@ -124,15 +117,17 @@
 	kfree(ptr);
 }
 
-#ifndef CONFIG_8xx
-int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
-#else
+#ifdef CONFIG_8xx
 /* Name change so we can catch standard drivers that potentially mess up
  * the internal interrupt controller on 8xx and 82xx.  Just bear with me,
  * I don't like this either and I am searching a better solution.  For
  * now, this is what I need. -- Dan
  */
 int request_8xxirq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+#elif defined(CONFIG_APUS)
+int sys_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+#else
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
 #endif
 	unsigned long irqflags, const char * devname, void *dev_id)
 {
@@ -191,6 +186,12 @@
 	return 0;
 }
 
+#ifdef CONFIG_APUS
+void sys_free_irq(unsigned int irq, void *dev_id)
+{
+	sys_request_irq(irq, NULL, 0, NULL, dev_id);
+}
+#else
 void free_irq(unsigned int irq, void *dev_id)
 {
 #ifndef CONFIG_8xx
@@ -199,6 +200,7 @@
 	request_8xxirq(irq, NULL, 0, NULL, dev_id);
 #endif
 }
+#endif
 
 /* XXX should implement irq disable depth like on intel */
 void disable_irq_nosync(unsigned int irq_nr)
@@ -219,6 +221,9 @@
 
 int get_irq_list(char *buf)
 {
+#ifdef CONFIG_APUS
+	return apus_get_irq_list (buf);
+#else
 	int i, len = 0, j;
 	struct irqaction * action;
 
@@ -255,6 +260,7 @@
 #endif		
 	len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts);
 	return len;
+#endif /* CONFIG_APUS */
 }
 
 /*
@@ -266,7 +272,7 @@
 	int status;
 	struct irqaction *action;
 	int cpu = smp_processor_id();
-	
+
 	mask_and_ack_irq(irq);
 	status = 0;
 	action = irq_desc[irq].action;
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/kernel/mk_defs.c linux/arch/ppc/kernel/mk_defs.c
--- v2.3.25/linux/arch/ppc/kernel/mk_defs.c	Tue Aug 31 17:29:13 1999
+++ linux/arch/ppc/kernel/mk_defs.c	Fri Nov  5 15:53:25 1999
@@ -48,6 +48,9 @@
 	DEFINE(NEED_RESCHED, offsetof(struct task_struct, need_resched));
 	DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
 	DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
+	DEFINE(THREAD_VRF, offsetof(struct thread_struct, vrf));
+	DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
+	DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
 	/* Interrupt register frame */
 	DEFINE(TASK_UNION_SIZE, sizeof(union task_union));
 	DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/kernel/pmac_setup.c linux/arch/ppc/kernel/pmac_setup.c
--- v2.3.25/linux/arch/ppc/kernel/pmac_setup.c	Fri Oct 22 13:21:45 1999
+++ linux/arch/ppc/kernel/pmac_setup.c	Fri Nov  5 15:53:25 1999
@@ -96,6 +96,7 @@
 
 int ppc_override_l2cr = 0;
 int ppc_override_l2cr_value;
+int has_l2cache = 0;
 
 extern char saved_command_line[];
 
@@ -147,6 +148,7 @@
 		unsigned int *dc = (unsigned int *)
 			get_property(np, "d-cache-size", NULL);
 		len += sprintf(buffer+len, "L2 cache\t:");
+		has_l2cache = 1;
 		if (get_property(np, "cache-unified", NULL) != 0 && dc) {
 			len += sprintf(buffer+len, " %dK unified", *dc / 1024);
 		} else {
@@ -359,7 +361,8 @@
 				sysctrl_regs[4] |= 0x04000020;
 			else
 				sysctrl_regs[4] |= 0x04000000;
-			printk(KERN_INFO "Level 2 cache enabled\n");
+			if(has_l2cache)
+				printk(KERN_INFO "Level 2 cache enabled\n");
 		}
 	}
 }
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/kernel/pmac_support.c linux/arch/ppc/kernel/pmac_support.c
--- v2.3.25/linux/arch/ppc/kernel/pmac_support.c	Fri Oct 15 15:25:13 1999
+++ linux/arch/ppc/kernel/pmac_support.c	Fri Nov  5 15:53:25 1999
@@ -60,6 +60,7 @@
 	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))
@@ -67,6 +68,7 @@
 		while (!req.complete)
 			pmu_poll();
 		return req.reply[1];
+#endif
 	case 1:
 		return nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult];
 	case 2:
@@ -82,6 +84,7 @@
 	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))
@@ -89,6 +92,7 @@
 		while (!req.complete)
 			pmu_poll();
 		break;
+#endif
 	case 1:
 		nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult] = val;
 		break;
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/kernel/ppc_ksyms.c linux/arch/ppc/kernel/ppc_ksyms.c
--- v2.3.25/linux/arch/ppc/kernel/ppc_ksyms.c	Fri Oct 22 13:21:45 1999
+++ linux/arch/ppc/kernel/ppc_ksyms.c	Fri Nov  5 15:53:26 1999
@@ -209,8 +209,10 @@
 EXPORT_SYMBOL(adb_register);
 EXPORT_SYMBOL(cuda_request);
 EXPORT_SYMBOL(cuda_poll);
+#ifdef CONFIG_ADB_PMU
 EXPORT_SYMBOL(pmu_request);
 EXPORT_SYMBOL(pmu_poll);
+#endif /* CONFIG_ADB_PMU */
 #endif /* CONFIG_ADB */
 #ifdef CONFIG_PMAC_PBOOK
 EXPORT_SYMBOL(pmu_register_sleep_notifier);
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- v2.3.25/linux/arch/ppc/kernel/process.c	Sat Oct  9 11:47:50 1999
+++ linux/arch/ppc/kernel/process.c	Fri Nov  5 15:53:26 1999
@@ -45,6 +45,7 @@
 extern unsigned long _get_SP(void);
 
 struct task_struct *last_task_used_math = NULL;
+struct task_struct *last_task_used_altivec = NULL;
 static struct vm_area_struct init_mmap = INIT_MMAP;
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
@@ -60,6 +61,7 @@
 #undef SHOW_TASK_SWITCHES 1
 #undef CHECK_STACK 1
 
+#if defined(CHECK_STACK)
 unsigned long
 kernel_stack_top(struct task_struct *tsk)
 {
@@ -72,28 +74,6 @@
 	return ((unsigned long)tsk) + sizeof(struct task_struct);
 }
 
-int
-dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
-{
-	if (regs->msr & MSR_FP)
-		giveup_fpu(current);
-	memcpy(fpregs, &current->thread.fpr[0], sizeof(*fpregs));
-	return 1;
-}
-
-void
-enable_kernel_fp(void)
-{
-#ifdef __SMP__
-	if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
-		giveup_fpu(current);
-	else
-		giveup_fpu(NULL);	/* just enables FP for kernel */
-#else
-	giveup_fpu(last_task_used_math);
-#endif /* __SMP__ */
-}
-
 /* check to make sure the kernel stack is healthy */
 int check_stack(struct task_struct *tsk)
 {
@@ -156,6 +136,29 @@
 	}
 	return(ret);
 }
+#endif /* defined(CHECK_STACK) */
+
+int
+dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
+{
+	if (regs->msr & MSR_FP)
+		giveup_fpu(current);
+	memcpy(fpregs, &current->thread.fpr[0], sizeof(*fpregs));
+	return 1;
+}
+
+void
+enable_kernel_fp(void)
+{
+#ifdef __SMP__
+	if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
+		giveup_fpu(current);
+	else
+		giveup_fpu(NULL);	/* just enables FP for kernel */
+#else
+	giveup_fpu(last_task_used_math);
+#endif /* __SMP__ */
+}
 
 void
 _switch_to(struct task_struct *prev, struct task_struct *new,
@@ -187,9 +190,23 @@
 	 * every switch, just a save.
 	 *  -- Cort
 	 */
-	if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
+	if ( prev->thread.regs && (prev->thread.regs->msr & MSR_FP) )
 		giveup_fpu(prev);
-
+	/*
+	 * If the previous thread 1) has some altivec regs it wants saved
+	 * (has bits in vrsave set) and 2) used altivec in the last quantum
+	 * (thus changing altivec regs) then save them.
+	 *
+	 * On SMP we always save/restore altivec regs just to avoid the
+	 * complexity of changing processors.
+	 *  -- Cort
+	 */
+	if ( (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) &&
+	     prev->thread.vrsave )
+		giveup_altivec(prev);
+	if ( (new->last_processor != NO_PROC_ID) &&
+	     (new->last_processor != new->processor) && new->mm )
+		flush_tlb_mm(new->mm);
 	prev->last_processor = prev->processor;
 	current_set[smp_processor_id()] = new;
 #endif /* __SMP__ */
@@ -213,7 +230,8 @@
 	printk("TASK = %p[%d] '%s' ",
 	       current, current->pid, current->comm);
 	printk("Last syscall: %ld ", current->thread.last_syscall);
-	printk("\nlast math %p", last_task_used_math);
+	printk("\nlast math %p last altivec %p", last_task_used_math,
+	       last_task_used_altivec);
 	
 #ifdef __SMP__	
 	printk(" CPU: %d last CPU: %d", current->processor,current->last_processor);
@@ -243,12 +261,16 @@
 {
 	if (last_task_used_math == current)
 		last_task_used_math = NULL;
+	if (last_task_used_altivec == current)
+		last_task_used_altivec = NULL;
 }
 
 void flush_thread(void)
 {
 	if (last_task_used_math == current)
 		last_task_used_math = NULL;
+	if (last_task_used_altivec == current)
+		last_task_used_altivec = NULL;
 }
 
 void
@@ -305,11 +327,18 @@
 	 */
 	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
-
 	memcpy(&p->thread.fpr, &current->thread.fpr, sizeof(p->thread.fpr));
 	p->thread.fpscr = current->thread.fpscr;
 	childregs->msr &= ~MSR_FP;
 
+	if (regs->msr & MSR_VEC)
+		giveup_altivec(current);
+	if ( p->thread.vrsave )
+		memcpy(&p->thread.vrf, &current->thread.vrf, sizeof(p->thread.vrf));
+	p->thread.vscr = current->thread.vscr;
+	p->thread.vrsave = current->thread.vrsave;
+	childregs->msr &= ~MSR_VEC;
+
 #ifdef __SMP__
 	p->last_processor = NO_PROC_ID;
 #endif /* __SMP__ */
@@ -367,6 +396,8 @@
 	shove_aux_table(sp);
 	if (last_task_used_math == current)
 		last_task_used_math = 0;
+	if (last_task_used_altivec == current)
+		last_task_used_altivec = 0;
 	current->thread.fpscr = 0;
 }
 
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- v2.3.25/linux/arch/ppc/kernel/setup.c	Wed Oct 27 16:34:12 1999
+++ linux/arch/ppc/kernel/setup.c	Fri Nov  5 15:53:26 1999
@@ -245,6 +245,9 @@
 		case 10:
 			len += sprintf(len+buffer, "604ev5 (MachV)\n");
 			break;
+		case 12:
+			len += sprintf(len+buffer, "7400 (G4)\n");
+			break;
 		case 50:
 			len += sprintf(len+buffer, "821\n");
 		case 80:
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- v2.3.25/linux/arch/ppc/kernel/traps.c	Fri Oct 15 15:25:13 1999
+++ linux/arch/ppc/kernel/traps.c	Fri Nov  5 15:53:26 1999
@@ -129,6 +129,42 @@
 }
 
 void
+AltiVecUnavailable(struct pt_regs *regs)
+{
+	/*
+	 * This should be changed so we don't take a trap if coming
+	 * back when last_task_used_altivec == current.  We should also
+	 * allow the kernel to use the altivec regs on UP to store tasks
+	 * regs during switch
+	 *  -- Cort
+	 */
+	if ( regs->msr & MSR_VEC )
+	{
+		show_regs(regs);
+		panic("AltiVec trap with Altivec enabled!\n");
+	}
+		
+	if ( !user_mode(regs) )
+	{
+		show_regs(regs);
+		panic("Kernel Used Altivec with MSR_VEC off!\n");
+	}
+#ifdef __SMP__
+	printk("User Mode altivec trap should not happen in SMP!\n");
+#else
+	if ( last_task_used_altivec != current )
+	{
+		if ( last_task_used_altivec )
+			giveup_altivec(current);
+		load_up_altivec(current);
+		last_task_used_altivec = current;
+	}
+	/* enable altivec for the task on return */
+	regs->msr |= MSR_VEC;
+#endif		
+}
+
+void
 UnknownException(struct pt_regs *regs)
 {
 	printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
diff -u --recursive --new-file v2.3.25/linux/arch/ppc/lib/checksum.S linux/arch/ppc/lib/checksum.S
--- v2.3.25/linux/arch/ppc/lib/checksum.S	Mon Jan 12 15:18:13 1998
+++ linux/arch/ppc/lib/checksum.S	Fri Nov  5 15:53:26 1999
@@ -24,6 +24,8 @@
  * 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
@@ -38,6 +40,8 @@
 	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.25/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v2.3.25/linux/arch/ppc/mm/init.c	Wed Oct 27 16:34:12 1999
+++ linux/arch/ppc/mm/init.c	Fri Nov  5 15:53:26 1999
@@ -1381,7 +1381,7 @@
 	set_phys_avail();
 	return ret;
 }
-#endif /* defined(CONFIG_GEMINI) || defined(CONFIG_ALL_PPC) */
+#endif /* defined(CONFIG_GEMINI) */
 
 #ifdef CONFIG_APUS
 #define HARDWARE_MAPPED_SIZE (512*1024)
diff -u --recursive --new-file v2.3.25/linux/arch/sh/config.in linux/arch/sh/config.in
--- v2.3.25/linux/arch/sh/config.in	Fri Oct 22 13:21:45 1999
+++ linux/arch/sh/config.in	Sat Nov  6 10:40:31 1999
@@ -11,9 +11,22 @@
 
 mainmenu_option next_comment
 comment 'Processor type and features'
-choice 'Processor family' \
-   "SH-3	CONFIG_CPU_SH3 \
-    SH-4	CONFIG_CPU_SH4" SH-3
+choice 'Processor type' \
+   "SH7708 CONFIG_CPU_SUBTYPE_SH7708 \
+    SH7709 CONFIG_CPU_SUBTYPE_SH7709 \
+    SH7750 CONFIG_CPU_SUBTYPE_SH7750" SH7708
+if [ "$CONFIG_CPU_SUBTYPE_SH7708" = "y" ]; then
+   define_bool CONFIG_CPU_SH3 y
+   define_bool CONFIG_CPU_SH4 n
+fi
+if [ "$CONFIG_CPU_SUBTYPE_SH7709" = "y" ]; then
+   define_bool CONFIG_CPU_SH3 y
+   define_bool CONFIG_CPU_SH4 n
+fi
+if [ "$CONFIG_CPU_SUBTYPE_SH7750" = "y" ]; then
+   define_bool CONFIG_CPU_SH3 n
+   define_bool CONFIG_CPU_SH4 y
+fi
 bool 'Little Endian' CONFIG_LITTLE_ENDIAN
 hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
 bool 'Use SH CPU internal real time clock' CONFIG_SH_CPU_RTC
@@ -35,6 +48,12 @@
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
 
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
+
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 endmenu
@@ -61,6 +80,10 @@
 
 if [ "$CONFIG_NET" = "y" ]; then
    source net/Config.in
+   mainmenu_option next_comment
+   comment 'Network device drivers'
+      source drivers/net/Config.in
+   endmenu
 fi
 
 mainmenu_option next_comment
diff -u --recursive --new-file v2.3.25/linux/arch/sh/defconfig linux/arch/sh/defconfig
--- v2.3.25/linux/arch/sh/defconfig	Fri Oct 22 13:21:45 1999
+++ linux/arch/sh/defconfig	Sat Nov  6 10:40:31 1999
@@ -10,10 +10,14 @@
 #
 # Processor type and features
 #
-# CONFIG_CPU_SH3 is not set
-CONFIG_CPU_SH4=y
+CONFIG_CPU_SUBTYPE_SH7708=y
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+CONFIG_CPU_SH3=y
+# CONFIG_CPU_SH4 is not set
 CONFIG_LITTLE_ENDIAN=y
-CONFIG_MEMORY_START=08000000
+CONFIG_MEMORY_START=0c000000
+CONFIG_SH_CPU_RTC=y
 
 #
 # Loadable module support
@@ -27,6 +31,8 @@
 # CONFIG_SYSVIPC is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_SYSCTL is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 
@@ -35,8 +41,8 @@
 #
 # CONFIG_SERIAL is not set
 CONFIG_SERIAL_CONSOLE=y
-# CONFIG_SH_SCI_SERIAL is not set
-CONFIG_SH_SCIF_SERIAL=y
+CONFIG_SH_SCI_SERIAL=y
+# CONFIG_SH_SCIF_SERIAL is not set
 
 #
 # Floppy, IDE, and other block devices
@@ -59,9 +65,6 @@
 # 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
diff -u --recursive --new-file v2.3.25/linux/arch/sh/kernel/entry.S linux/arch/sh/kernel/entry.S
--- v2.3.25/linux/arch/sh/kernel/entry.S	Wed Oct 27 16:34:12 1999
+++ linux/arch/sh/kernel/entry.S	Sat Nov  6 10:40:31 1999
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.16 1999/10/21 14:00:27 gniibe Exp $
+/* $Id: entry.S,v 1.19 1999/10/31 13:19:35 gniibe Exp gniibe $
  *
  *  linux/arch/sh/entry.S
  *
@@ -61,7 +61,11 @@
 #if defined(__sh3__)
 TRA     = 0xffffffd0
 EXPEVT  = 0xffffffd4
+#ifdef CONFIG_CPU_SUBTYPE_SH7709
+INTEVT  = 0xa4000000		! INTEVTE2(0xa4000000)
+#else
 INTEVT  = 0xffffffd8
+#endif
 MMU_TEA = 0xfffffffc		! TLB Exception Address Register
 #elif defined(__SH4__)
 TRA     = 0xff000020
@@ -251,6 +255,11 @@
 	mov.l	1f,r2
 	mov.l	@r2,r8
 	!
+	! DEBUG DEBUG
+	! mov.l	led,r1
+	! mov	r0,r2
+	! mov.b	r2,@r1
+	!
 #ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
 	mov	#0x20,r1
 	extu.b	r1,r1
@@ -320,6 +329,7 @@
 3:	.long	SYMBOL_NAME(syscall_trace)
 2:	.long	0xefffffff	! BL=0
 1:	.long	TRA
+led:	.long	0xa8000000	! For my board -- gN
 
 	.section	.fixup,"ax"
 fixup_syscall_argerr:
@@ -571,6 +581,37 @@
 	.long	SYMBOL_NAME(do_IRQ)	!      rovi
 	.long	SYMBOL_NAME(do_IRQ)
 	.long	SYMBOL_NAME(do_IRQ)
+#if defined(CONFIG_CPU_SUBTYPE_SH7709)
+	.long	SYMBOL_NAME(do_IRQ)	! 32 IRQ  irq0
+	.long	SYMBOL_NAME(do_IRQ)	! 33      irq1
+	.long	SYMBOL_NAME(do_IRQ)	! 34      irq2
+	.long	SYMBOL_NAME(do_IRQ)	! 35      irq3
+	.long	SYMBOL_NAME(do_IRQ)	! 36      irq4
+	.long	SYMBOL_NAME(do_IRQ)	! 37      irq5
+	.long	SYMBOL_NAME(do_IRQ)	! 38
+	.long	SYMBOL_NAME(do_IRQ)	! 39
+	.long	SYMBOL_NAME(do_IRQ)	! 40 PINT pint0-7
+	.long	SYMBOL_NAME(do_IRQ)	! 41      pint8-15
+	.long	SYMBOL_NAME(do_IRQ)	! 42
+	.long	SYMBOL_NAME(do_IRQ)	! 43
+	.long	SYMBOL_NAME(do_IRQ)	! 44
+	.long	SYMBOL_NAME(do_IRQ)	! 45
+	.long	SYMBOL_NAME(do_IRQ)	! 46
+	.long	SYMBOL_NAME(do_IRQ)	! 47
+	.long	SYMBOL_NAME(do_IRQ)	! 48 DMAC dei0
+	.long	SYMBOL_NAME(do_IRQ)	! 49      dei1
+	.long	SYMBOL_NAME(do_IRQ)	! 50      dei2
+	.long	SYMBOL_NAME(do_IRQ)	! 51      dei3
+	.long	SYMBOL_NAME(do_IRQ)	! 52 IrDA eri1
+	.long	SYMBOL_NAME(do_IRQ)	! 53      rxi1
+	.long	SYMBOL_NAME(do_IRQ)	! 54      bri1
+	.long	SYMBOL_NAME(do_IRQ)	! 55      txi1
+	.long	SYMBOL_NAME(do_IRQ)	! 56 SCIF eri2
+	.long	SYMBOL_NAME(do_IRQ)	! 57      rxi2
+	.long	SYMBOL_NAME(do_IRQ)	! 58      bri2
+	.long	SYMBOL_NAME(do_IRQ)	! 59      txi2
+	.long	SYMBOL_NAME(do_IRQ)	! 60 ADC  adi
+#elif defined(__SH4__)
 	.long	SYMBOL_NAME(do_IRQ)	! Hitachi UDI
 	.long	SYMBOL_NAME(do_IRQ)	! GPIO
 	.long	SYMBOL_NAME(do_IRQ)	! DMAC dmte0
@@ -589,6 +630,7 @@
 	.long	error
 	.long	error ! fpu
 	.long	error ! fpu
+#endif
 
 ENTRY(sys_call_table)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* 0  -  old "setup()" system call*/
@@ -608,7 +650,7 @@
 	.long SYMBOL_NAME(sys_mknod)
 	.long SYMBOL_NAME(sys_chmod)		/* 15 */
 	.long SYMBOL_NAME(sys_lchown)
-	.long SYMBOL_NAME(sys_ni_syscall)				/* old break syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old break syscall holder */
 	.long SYMBOL_NAME(sys_stat)
 	.long SYMBOL_NAME(sys_lseek)
 	.long SYMBOL_NAME(sys_getpid)		/* 20 */
@@ -622,8 +664,8 @@
 	.long SYMBOL_NAME(sys_fstat)
 	.long SYMBOL_NAME(sys_pause)
 	.long SYMBOL_NAME(sys_utime)		/* 30 */
-	.long SYMBOL_NAME(sys_ni_syscall)				/* old stty syscall holder */
-	.long SYMBOL_NAME(sys_ni_syscall)				/* old gtty syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old stty syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old gtty syscall holder */
 	.long SYMBOL_NAME(sys_access)
 	.long SYMBOL_NAME(sys_nice)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* 35 */		/* old ftime syscall holder */
@@ -635,7 +677,7 @@
 	.long SYMBOL_NAME(sys_dup)
 	.long SYMBOL_NAME(sys_pipe)
 	.long SYMBOL_NAME(sys_times)
-	.long SYMBOL_NAME(sys_ni_syscall)				/* old prof syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old prof syscall holder */
 	.long SYMBOL_NAME(sys_brk)		/* 45 */
 	.long SYMBOL_NAME(sys_setgid)
 	.long SYMBOL_NAME(sys_getgid)
@@ -644,12 +686,12 @@
 	.long SYMBOL_NAME(sys_getegid)		/* 50 */
 	.long SYMBOL_NAME(sys_acct)
 	.long SYMBOL_NAME(sys_umount)					/* recycled never used phys() */
-	.long SYMBOL_NAME(sys_ni_syscall)				/* old lock syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old lock syscall holder */
 	.long SYMBOL_NAME(sys_ioctl)
 	.long SYMBOL_NAME(sys_fcntl)		/* 55 */
-	.long SYMBOL_NAME(sys_ni_syscall)				/* old mpx syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old mpx syscall holder */
 	.long SYMBOL_NAME(sys_setpgid)
-	.long SYMBOL_NAME(sys_ni_syscall)				/* old ulimit syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old ulimit syscall holder */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_olduname */
 	.long SYMBOL_NAME(sys_umask)		/* 60 */
 	.long SYMBOL_NAME(sys_chroot)
@@ -689,7 +731,7 @@
 	.long SYMBOL_NAME(sys_fchown)		/* 95 */
 	.long SYMBOL_NAME(sys_getpriority)
 	.long SYMBOL_NAME(sys_setpriority)
-	.long SYMBOL_NAME(sys_ni_syscall)				/* old profil syscall holder */
+	.long SYMBOL_NAME(sys_ni_syscall)	/* old profil syscall holder */
 	.long SYMBOL_NAME(sys_statfs)
 	.long SYMBOL_NAME(sys_fstatfs)		/* 100 */
 	.long SYMBOL_NAME(sys_ni_syscall)		/* ioperm */
diff -u --recursive --new-file v2.3.25/linux/arch/sh/kernel/head.S linux/arch/sh/kernel/head.S
--- v2.3.25/linux/arch/sh/kernel/head.S	Fri Oct 22 13:21:46 1999
+++ linux/arch/sh/kernel/head.S	Sat Nov  6 10:40:31 1999
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.6 1999/10/05 12:34:16 gniibe Exp $
+/* $Id: head.S,v 1.7 1999/10/27 09:41:42 gniibe Exp gniibe $
  *
  *  arch/sh/kernel/head.S
  *
@@ -18,9 +18,8 @@
 	.long	0		/* RAMDISK_FLAGS */
 	.long	0x0200		/* ORIG_ROOT_DEV */
 	.long	1		/* LOADER_TYPE */
-	.long	0x88400000	/* INITRD_START */
-	.long	0x00400000	/* INITRD_SIZE */
-	.long	0x89000000	/* MEMORY_END */
+	.long	0x00360000	/* INITRD_START */
+	.long	0x000a0000	/* INITRD_SIZE */
 	.long	0
 
 	.text	
diff -u --recursive --new-file v2.3.25/linux/arch/sh/kernel/irq_onchip.c linux/arch/sh/kernel/irq_onchip.c
--- v2.3.25/linux/arch/sh/kernel/irq_onchip.c	Wed Oct 27 16:34:12 1999
+++ linux/arch/sh/kernel/irq_onchip.c	Sat Nov  6 10:40:31 1999
@@ -1,8 +1,8 @@
-/* $Id: irq_onchip.c,v 1.4 1999/10/19 12:22:05 gniibe Exp $
+/* $Id: irq_onchip.c,v 1.5 1999/10/28 02:18:33 gniibe Exp $
  *
  * linux/arch/sh/kernel/irq_onchip.c
  *
- * Copyright (C) 1999  Niibe Yutaka
+ * Copyright (C) 1999  Niibe Yutaka & Takeshi Yaegashi
  *
  * Interrupt handling for on-chip supporting modules (TMU, RTC, etc.).
  *
@@ -135,6 +135,109 @@
 	enable_onChip_irq(irq);
 }
 
+
+#ifdef CONFIG_CPU_SUBTYPE_SH7709
+/*
+ * SH7707/SH7709/SH7709A/SH7729 Extended on-chip I/O
+ */
+
+#define INTC_IRR0	0xa4000004UL
+#define INTC_IPRC	0xa4000016UL
+
+#define IRQ0_IRQ	32
+#define IRQ1_IRQ	33
+#define IRQ2_IRQ	34
+#define IRQ3_IRQ	35
+#define IRQ4_IRQ	36
+#define IRQ5_IRQ	37
+
+#define IRQ0_IRP_OFFSET	32
+#define IRQ1_IRP_OFFSET	36
+#define IRQ2_IRP_OFFSET	40
+#define IRQ3_IRP_OFFSET	44
+#define IRQ4_IRP_OFFSET	48
+#define IRQ5_IRP_OFFSET	52
+
+#define IRQ0_PRIORITY	1
+#define IRQ1_PRIORITY	1
+#define IRQ2_PRIORITY	1
+#define IRQ3_PRIORITY	1
+#define IRQ4_PRIORITY	1
+#define IRQ5_PRIORITY	1
+
+static void enable_onChip2_irq(unsigned int irq);
+void disable_onChip2_irq(unsigned int irq);
+
+/* shutdown is same as "disable" */
+#define shutdown_onChip2_irq	disable_onChip2_irq
+
+static void mask_and_ack_onChip2(unsigned int);
+static void end_onChip2_irq(unsigned int irq);
+
+static unsigned int startup_onChip2_irq(unsigned int irq)
+{ 
+	enable_onChip2_irq(irq);
+	return 0; /* never anything pending */
+}
+
+static struct hw_interrupt_type onChip2_irq_type = {
+	"SH7709 Extended On-Chip Supporting Module",
+	startup_onChip2_irq,
+	shutdown_onChip2_irq,
+	enable_onChip2_irq,
+	disable_onChip2_irq,
+	mask_and_ack_onChip2,
+	end_onChip2_irq
+};
+
+void disable_onChip2_irq(unsigned int irq)
+{
+	unsigned long val, flags;
+	/* Set priority in IPR to 0 */
+	int offset = ipr_data[irq-TIMER_IRQ].offset - 32;
+	unsigned long intc_ipr_address = INTC_IPRC + (offset/16*INTC_SIZE);
+	unsigned short mask = 0xffff ^ (0xf << (offset%16));
+
+	save_and_cli(flags);
+	val = ctrl_inw(intc_ipr_address);
+	val &= mask;
+	ctrl_outw(val, intc_ipr_address);
+	restore_flags(flags);
+}
+
+static void enable_onChip2_irq(unsigned int irq)
+{
+	unsigned long val, flags;
+	/* Set priority in IPR back to original value */
+	int offset = ipr_data[irq-TIMER_IRQ].offset - 32;
+	int priority = ipr_data[irq-TIMER_IRQ].priority;
+	unsigned long intc_ipr_address = INTC_IPRC + (offset/16*INTC_SIZE);
+	unsigned short value = (priority << (offset%16));
+
+	save_and_cli(flags);
+	val = ctrl_inw(intc_ipr_address);
+	val |= value;
+	ctrl_outw(val, intc_ipr_address);
+	restore_flags(flags);
+}
+
+static void mask_and_ack_onChip2(unsigned int irq)
+{
+	disable_onChip2_irq(irq);
+	if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) {
+		/* Clear external interrupt request */
+		int a = ctrl_inb(INTC_IRR0);
+		a &= ~(1 << (irq - IRQ0_IRQ));
+		ctrl_outb(a, INTC_IRR0);
+	}
+}
+
+static void end_onChip2_irq(unsigned int irq)
+{
+	enable_onChip2_irq(irq);
+}
+#endif /* CONFIG_CPU_SUBTYPE_SH7709 */
+
 void __init init_IRQ(void)
 {
 	int i;
@@ -142,4 +245,25 @@
 	for (i = TIMER_IRQ; i < NR_IRQS; i++) {
 		irq_desc[i].handler = &onChip_irq_type;
 	}
+
+#ifdef CONFIG_CPU_SUBTYPE_SH7709
+	for (i = IRQ0_IRQ; i < NR_IRQS; i++) {
+		irq_desc[i].handler = &onChip2_irq_type;
+	}
+
+	/*
+	 * Enable external irq(INTC IRQ mode).
+	 * You should set corresponding bits of PFC to "00"
+	 * to enable these interrupts.
+	 */
+	set_ipr_data(IRQ0_IRQ, IRQ0_IRP_OFFSET, IRQ0_PRIORITY);
+	set_ipr_data(IRQ1_IRQ, IRQ1_IRP_OFFSET, IRQ1_PRIORITY);
+	set_ipr_data(IRQ2_IRQ, IRQ2_IRP_OFFSET, IRQ2_PRIORITY);
+	set_ipr_data(IRQ3_IRQ, IRQ3_IRP_OFFSET, IRQ3_PRIORITY);
+	set_ipr_data(IRQ4_IRQ, IRQ4_IRP_OFFSET, IRQ4_PRIORITY);
+	set_ipr_data(IRQ5_IRQ, IRQ5_IRP_OFFSET, IRQ5_PRIORITY);
+
+	ctrl_inb(INTC_IRR0);
+	ctrl_outb(0, INTC_IRR0);
+#endif /* CONFIG_CPU_SUBTYPE_SH7709 */
 }
diff -u --recursive --new-file v2.3.25/linux/arch/sh/kernel/process.c linux/arch/sh/kernel/process.c
--- v2.3.25/linux/arch/sh/kernel/process.c	Fri Oct 22 13:21:46 1999
+++ linux/arch/sh/kernel/process.c	Sat Nov  6 10:40:31 1999
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.7 1999/09/23 00:05:41 gniibe Exp $
+/* $Id: process.c,v 1.8 1999/10/31 13:19:16 gniibe Exp $
  *
  *  linux/arch/sh/kernel/process.c
  *
@@ -249,8 +249,6 @@
 
 	p->thread.sp = (unsigned long) childregs;
 	p->thread.pc = (unsigned long) ret_from_fork;
-	if (p->mm)
-		p->mm->context = NO_CONTEXT;
 
 	return 0;
 }
diff -u --recursive --new-file v2.3.25/linux/arch/sh/kernel/setup.c linux/arch/sh/kernel/setup.c
--- v2.3.25/linux/arch/sh/kernel/setup.c	Wed Oct 27 16:34:12 1999
+++ linux/arch/sh/kernel/setup.c	Sat Nov  6 10:40:31 1999
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.7 1999/10/23 01:34:50 gniibe Exp $
+/* $Id: setup.c,v 1.7 1999/10/23 01:34:50 gniibe Exp gniibe $
  *
  *  linux/arch/sh/kernel/setup.c
  *
@@ -135,9 +135,9 @@
 	memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
 	saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 
-	memory_start = (unsigned long)__va(0)+__MEMORY_START;
+	memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
 	/* Default is 4Mbyte. */
-	memory_end = (unsigned long)__va(0x00400000)+__MEMORY_START;
+	memory_end = (unsigned long)PAGE_OFFSET+0x00400000+__MEMORY_START;
 
 	for (;;) {
 		/*
@@ -214,7 +214,7 @@
 	/*
 	 * Initialize the boot-time allocator (with low memory only):
 	 */
-	bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+	bootmap_size = init_bootmem(start_pfn, max_low_pfn, __MEMORY_START);
 
 	/*
 	 * FIXME: what about high memory?
@@ -259,16 +259,18 @@
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (LOADER_TYPE) {
-		initrd_start = INITRD_START ? INITRD_START : 0;
-		initrd_end = initrd_start+INITRD_SIZE;
-		if (initrd_end > memory_end) {
+		if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
+			reserve_bootmem(INITRD_START, INITRD_SIZE);
+			initrd_start =
+				INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
+			initrd_end = initrd_start+INITRD_SIZE;
+		} else {
 			printk("initrd extends beyond end of memory "
 			       "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
-			       initrd_end,memory_end);
+			    INITRD_START + INITRD_SIZE,
+			    max_low_pfn << PAGE_SHIFT);
 			initrd_start = 0;
-		} else
-			reserve_bootmem(__pa(initrd_start)-__MEMORY_START,
-					INITRD_SIZE);
+		}
 	}
 #endif
 
diff -u --recursive --new-file v2.3.25/linux/arch/sh/kernel/sys_sh.c linux/arch/sh/kernel/sys_sh.c
--- v2.3.25/linux/arch/sh/kernel/sys_sh.c	Fri Oct 22 13:21:46 1999
+++ linux/arch/sh/kernel/sys_sh.c	Sat Nov  6 10:40:31 1999
@@ -44,9 +44,8 @@
 }
 
 asmlinkage unsigned long
-sys_mmap(int fd, unsigned long addr,
-	 unsigned long len, unsigned long prot,
-	 unsigned long flags, unsigned long off)
+sys_mmap(unsigned long addr, unsigned long len, unsigned long prot, 
+	 unsigned long flags, int fd, unsigned long off)
 {
 	int error = -EFAULT;
 	struct file *file = NULL;
diff -u --recursive --new-file v2.3.25/linux/arch/sh/kernel/time.c linux/arch/sh/kernel/time.c
--- v2.3.25/linux/arch/sh/kernel/time.c	Wed Oct 27 16:34:12 1999
+++ linux/arch/sh/kernel/time.c	Sat Nov  6 10:40:31 1999
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.3 1999/10/17 10:30:15 gniibe Exp $
+/* $Id: time.c,v 1.7 1999/11/06 02:00:37 gniibe Exp $
  *
  *  linux/arch/sh/kernel/time.c
  *
@@ -43,7 +43,10 @@
 #define TMU0_TCNT	0xfffffe98	/* Long access */
 #define TMU0_TCR	0xfffffe9c	/* Word access */
 
-#define INTERVAL	37500 /* (1000000*CLOCK_MHZ/HZ/2) ??? */
+#define INTERVAL	37500 /* (1000000*CLOCK_MHZ/HZ/2) ??? for CqREEK */
+#if 0 /* Takeshi's board */
+#define INTERVAL	83333
+#endif
 
 /* SH-3 RTC */
 #define R64CNT  	0xfffffec0
@@ -195,6 +198,13 @@
 {
 	do_timer(regs);
 
+#ifdef TAKESHI
+	{
+		unsigned long what_is_this=0xa4000124;
+
+		ctrl_outb(ctrl_inb(what_is_this)+1,what_is_this);
+	}
+#endif
 #if 0
 	if (!user_mode(regs))
 		sh_do_profile(regs->pc);
diff -u --recursive --new-file v2.3.25/linux/arch/sh/lib/checksum.S linux/arch/sh/lib/checksum.S
--- v2.3.25/linux/arch/sh/lib/checksum.S	Fri Oct 22 13:21:46 1999
+++ linux/arch/sh/lib/checksum.S	Sat Nov  6 10:40:31 1999
@@ -1,4 +1,4 @@
-/* $Id: checksum.S,v 1.1 1999/09/18 16:56:53 gniibe Exp $
+/* $Id: checksum.S,v 1.2 1999/10/29 13:06:55 gniibe Exp $
  *
  * INET		An implementation of the TCP/IP protocol suite for the LINUX
  *		operating system.  INET is implemented using the  BSD Socket
@@ -192,7 +192,7 @@
 	mov	#-5,r0
 	shld	r0,r6
 	tst	r6,r6
-	bf/s	2f
+	bt/s	2f
 	 clrt
 SRC(1:	mov.l	@r4+,r0	)
 SRC(	mov.l	@r4+,r1	)
diff -u --recursive --new-file v2.3.25/linux/arch/sh/mm/fault.c linux/arch/sh/mm/fault.c
--- v2.3.25/linux/arch/sh/mm/fault.c	Fri Oct 22 13:21:46 1999
+++ linux/arch/sh/mm/fault.c	Sat Nov  6 10:40:31 1999
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.3 1999/09/21 23:09:53 gniibe Exp $
+/* $Id: fault.c,v 1.5 1999/10/31 13:17:31 gniibe Exp $
  *
  *  linux/arch/sh/mm/fault.c
  *  Copyright (C) 1999  Niibe Yutaka
@@ -81,6 +81,34 @@
 	return 0;
 }
 
+static void handle_vmalloc_fault(struct task_struct *tsk, unsigned long address)
+{
+	pgd_t *dir;
+	pmd_t *pmd;
+	pte_t *pte;
+	pte_t entry;
+
+	dir = pgd_offset_k(address);
+	pmd = pmd_offset(dir, address);
+	if (pmd_none(*pmd)) {
+		printk(KERN_ERR "vmalloced area %08lx bad\n", address);
+		return;
+	}
+	if (pmd_bad(*pmd)) {
+		pmd_ERROR(*pmd);
+		pmd_clear(pmd);
+		return;
+	}
+	pte = pte_offset(pmd, address);
+	entry = *pte;
+	if (pte_none(entry) || !pte_present(entry) || !pte_write(entry)) {
+		printk(KERN_ERR "vmalloced area %08lx bad\n", address);
+		return;
+	}
+
+	update_mmu_cache(NULL, address, entry);
+}
+
 /*
  * This routine handles page faults.  It determines the address,
  * and the problem, and then passes it off to one of the appropriate
@@ -98,6 +126,11 @@
 	tsk = current;
 	mm = tsk->mm;
 
+	if (address >= VMALLOC_START && address < VMALLOC_END) {
+		handle_vmalloc_fault(tsk, address);
+		return;
+	}
+
 	/*
 	 * If we're in an interrupt or have no user
 	 * context, we must not take the fault..
@@ -222,23 +255,13 @@
 		      unsigned long address, pte_t pte)
 {
 	unsigned long flags;
-	unsigned long asid;
 	unsigned long pteval;
 
-	asid = get_asid();
-
-	address &= PAGE_MASK;
-#if 0/*defined(__SH4__)*//* SH-4 has separate I/D caches: XXX really needed? */
-	if ((vma->vm_flags & VM_EXEC) != 0)
-/*	 &&
-	    ((pte_val(pte) & (_PAGE_PRESENT | _PAGE_DIRTY)) ==
-	    (_PAGE_PRESENT | _PAGE_DIRTY))) */
-		flush_icache_range(address,address+PAGE_SIZE);
-#endif
 	save_and_cli(flags);
-	/* Set PTEH register */
-	ctrl_outl((address|asid), MMU_PTEH);
-
+	/*
+	 *  We don't need to set PTEH register.
+	 *  It's automatically set by the hardware.
+	 */
 	pteval = pte_val(pte);
 	pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
 	pteval |= _PAGE_FLAGS_HARDWARE_DEFAULT; /* add default flags */
@@ -246,18 +269,31 @@
 	ctrl_outl(pteval, MMU_PTEL);
 
 	/* Load the TLB */
-	asm volatile ("ldtlb" : /* no output */ : /* no input */
-		      : "memory");
+	asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
 	restore_flags(flags);
 }
 
-static __inline__ void __flush_tlb_page(unsigned long asid, unsigned long page)
+static void __flush_tlb_page(struct mm_struct *mm, unsigned long page)
 {
-	unsigned long addr, data;
+	unsigned long addr, data, asid;
+	unsigned long saved_asid = MMU_NO_ASID;
+
+	if (mm->context == NO_CONTEXT)
+		return;
+
+	asid = mm->context & MMU_CONTEXT_ASID_MASK;
+	if (mm != current->mm) {
+		saved_asid = get_asid();
+		/*
+		 * We need to set ASID of the target entry to flush,
+		 * because TLB is indexed by (ASID and PAGE).
+		 */
+		set_asid(asid);
+	}
 
 #if defined(__sh3__)
-	addr = MMU_TLB_ADDRESS_ARRAY | (page & 0x1F000) | MMU_PAGE_ASSOC_BIT;
-	data = page | asid; /* VALID bit is off */
+	addr = MMU_TLB_ADDRESS_ARRAY |(page & 0x1F000)| MMU_PAGE_ASSOC_BIT;
+	data = (page & 0xfffe0000) | asid; /* VALID bit is off */
 	ctrl_outl(data, addr);
 #elif defined(__SH4__)
 	int i;
@@ -276,19 +312,18 @@
 		}
 	}
 #endif
+	if (saved_asid != MMU_NO_ASID)
+		set_asid(saved_asid);
 }
 
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
 {
-	unsigned long asid;
-
-	if (vma->vm_mm->context != NO_CONTEXT) {
-		unsigned long flags;
+	unsigned long flags;
 
+	if (vma->vm_mm) {
 		page &= PAGE_MASK;
-		asid = vma->vm_mm->context & MMU_CONTEXT_ASID_MASK;
 		save_and_cli(flags);
-		__flush_tlb_page (asid, page);
+		__flush_tlb_page(vma->vm_mm, page);
 		restore_flags(flags);
 	}
 }
@@ -303,18 +338,15 @@
 		save_and_cli(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 		if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
-			get_new_mmu_context(mm);
+			mm->context = NO_CONTEXT;
 			if (mm == current->mm)
-				set_asid(mm->context & MMU_CONTEXT_ASID_MASK);
+				activate_context(mm);
 		} else {
-			unsigned long asid;
-
-			asid = mm->context & MMU_CONTEXT_ASID_MASK;
 			start &= PAGE_MASK;
 			end += (PAGE_SIZE - 1);
 			end &= PAGE_MASK;
 			while (start < end) {
-				__flush_tlb_page (asid, start);
+				__flush_tlb_page(mm, start);
 				start += PAGE_SIZE;
 			}
 		}
@@ -325,14 +357,14 @@
 void flush_tlb_mm(struct mm_struct *mm)
 {
 	/* Invalidate all TLB of this process. */
-	/* Instead of flush TLBs, we get new MMU context. */
+	/* Instead of invalidating each TLB, we get new MMU context. */
 	if (mm->context != NO_CONTEXT) {
 		unsigned long flags;
 
 		save_and_cli(flags);
-		get_new_mmu_context(mm);
+		mm->context = NO_CONTEXT;
 		if (mm == current->mm)
-			set_asid(mm->context & MMU_CONTEXT_ASID_MASK);
+			activate_context(mm);
 		restore_flags(flags);
 	}
 }
diff -u --recursive --new-file v2.3.25/linux/arch/sh/mm/init.c linux/arch/sh/mm/init.c
--- v2.3.25/linux/arch/sh/mm/init.c	Wed Oct 27 16:34:12 1999
+++ linux/arch/sh/mm/init.c	Sat Nov  6 10:40:31 1999
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.4 1999/10/23 01:37:02 gniibe Exp $
+/* $Id: init.c,v 1.4 1999/10/23 01:37:02 gniibe Exp gniibe $
  *
  *  linux/arch/sh/mm/init.c
  *
@@ -193,13 +193,14 @@
  */
 void __init paging_init(void)
 {
+	int i;
 	pgd_t * pg_dir;
 
 	/* We don't need kernel mapping as hardware support that. */
 	pg_dir = swapper_pg_dir;
 
-	/* Unmap the original low memory mappings to detect NULL reference */
-	pgd_val(pg_dir[0]) = 0;
+	for (i=0; i < USER_PTRS_PER_PGD*2; i++)
+		pgd_val(pg_dir[i]) = 0;
 
 	/* Enable MMU */
 	ctrl_outl(MMU_CONTROL_INIT, MMUCR);
diff -u --recursive --new-file v2.3.25/linux/arch/sparc/config.in linux/arch/sparc/config.in
--- v2.3.25/linux/arch/sparc/config.in	Mon Nov  1 13:56:26 1999
+++ linux/arch/sparc/config.in	Fri Nov  5 10:22:51 1999
@@ -63,6 +63,11 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
 tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
diff -u --recursive --new-file v2.3.25/linux/arch/sparc/defconfig linux/arch/sparc/defconfig
--- v2.3.25/linux/arch/sparc/defconfig	Tue Aug 31 17:29:13 1999
+++ linux/arch/sparc/defconfig	Fri Nov  5 10:22:51 1999
@@ -78,6 +78,8 @@
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
 CONFIG_BINFMT_AOUT=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=m
diff -u --recursive --new-file v2.3.25/linux/arch/sparc/kernel/signal.c linux/arch/sparc/kernel/signal.c
--- v2.3.25/linux/arch/sparc/kernel/signal.c	Tue Aug 31 17:29:13 1999
+++ linux/arch/sparc/kernel/signal.c	Tue Nov  2 17:40:11 1999
@@ -1050,7 +1050,7 @@
 			ino = map->vm_file->f_dentry->d_inode->i_ino;
 			line = d_path(map->vm_file->f_dentry, buffer, PAGE_SIZE);
 		}
-		printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_offset,
+		printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
 			      kdevname(dev), ino);
 		if (map->vm_file != NULL)
 			printk("%s\n", line);
diff -u --recursive --new-file v2.3.25/linux/arch/sparc64/config.in linux/arch/sparc64/config.in
--- v2.3.25/linux/arch/sparc64/config.in	Mon Nov  1 13:56:26 1999
+++ linux/arch/sparc64/config.in	Fri Nov  5 10:22:51 1999
@@ -47,6 +47,11 @@
 bool 'System V IPC' CONFIG_SYSVIPC
 bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
 bool 'Sysctl support' CONFIG_SYSCTL
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+   choice 'Kernel core (/proc/kcore) format' \
+	"ELF		CONFIG_KCORE_ELF	\
+	 A.OUT		CONFIG_KCORE_AOUT" ELF
+fi
 bool 'Kernel support for Linux/Sparc 32bit binary compatibility' CONFIG_SPARC32_COMPAT
 if [ "$CONFIG_SPARC32_COMPAT" != "n" ]; then
    tristate '  Kernel support for 32-bit ELF binaries' CONFIG_BINFMT_ELF32
diff -u --recursive --new-file v2.3.25/linux/arch/sparc64/defconfig linux/arch/sparc64/defconfig
--- v2.3.25/linux/arch/sparc64/defconfig	Sat Oct  9 11:47:50 1999
+++ linux/arch/sparc64/defconfig	Fri Nov  5 10:22:51 1999
@@ -88,6 +88,8 @@
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
 CONFIG_SPARC32_COMPAT=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_ELF32=y
diff -u --recursive --new-file v2.3.25/linux/arch/sparc64/kernel/signal.c linux/arch/sparc64/kernel/signal.c
--- v2.3.25/linux/arch/sparc64/kernel/signal.c	Fri Sep 10 23:57:28 1999
+++ linux/arch/sparc64/kernel/signal.c	Tue Nov  2 17:40:11 1999
@@ -618,7 +618,7 @@
 			ino = map->vm_file->f_dentry->d_inode->i_ino;
 			line = d_path(map->vm_file->f_dentry, buffer, PAGE_SIZE);
 		}
-		printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_offset,
+		printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
 			      kdevname(dev), ino);
 		if (map->vm_file != NULL)
 			printk("%s\n", line);
diff -u --recursive --new-file v2.3.25/linux/arch/sparc64/kernel/signal32.c linux/arch/sparc64/kernel/signal32.c
--- v2.3.25/linux/arch/sparc64/kernel/signal32.c	Mon Aug  2 22:07:16 1999
+++ linux/arch/sparc64/kernel/signal32.c	Tue Nov  2 17:40:11 1999
@@ -1226,7 +1226,7 @@
 			ino = map->vm_file->f_dentry->d_inode->i_ino;
 			line = d_path(map->vm_file->f_dentry, buffer, PAGE_SIZE);
 		}
-		printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_offset,
+		printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
 			      kdevname(dev), ino);
 		if (map->vm_file != NULL)
 			printk("%s\n", line);
diff -u --recursive --new-file v2.3.25/linux/drivers/block/Config.in linux/drivers/block/Config.in
--- v2.3.25/linux/drivers/block/Config.in	Wed Oct 27 16:34:12 1999
+++ linux/drivers/block/Config.in	Wed Nov  3 14:43:54 1999
@@ -209,9 +209,9 @@
 # controls the choices given to the user ...
 
 if [ "$CONFIG_PARPORT" = "y" -o "$CONFIG_PARPORT" = "n" ]; then
-   define_bool CONFIG_PARIDE_PARPORT y
+   define_tristate CONFIG_PARIDE_PARPORT y
 else
-   define_bool CONFIG_PARIDE_PARPORT m
+   define_tristate CONFIG_PARIDE_PARPORT m
 fi
 dep_tristate 'Parallel port IDE device support' CONFIG_PARIDE $CONFIG_PARIDE_PARPORT
 if [ "$CONFIG_PARIDE" = "y" -o "$CONFIG_PARIDE" = "m" ]; then
diff -u --recursive --new-file v2.3.25/linux/drivers/block/hpt34x.c linux/drivers/block/hpt34x.c
--- v2.3.25/linux/drivers/block/hpt34x.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/block/hpt34x.c	Fri Nov  5 10:40:23 1999
@@ -299,8 +299,7 @@
 			drive->waiting_for_dma = 1;
 			if (drive->media != ide_disk)
 				return 0;
-			drive->timeout = WAIT_CMD;
-			ide_set_handler(drive, &ide_dma_intr);	/* issue cmd to drive */
+			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);	/* issue cmd to drive */
 			OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 			return 0;
 		case ide_dma_end:	/* returns 1 on error, 0 otherwise */
diff -u --recursive --new-file v2.3.25/linux/drivers/block/icside.c linux/drivers/block/icside.c
--- v2.3.25/linux/drivers/block/icside.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/block/icside.c	Fri Nov  5 10:40:23 1999
@@ -381,8 +381,7 @@
 		if (drive->media != ide_disk)
 			return 0;
 
-		drive->timeout = WAIT_CMD;
-		ide_set_handler(drive, &ide_dma_intr);
+		ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
 		OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA,
 			 IDE_COMMAND_REG);
 
diff -u --recursive --new-file v2.3.25/linux/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c
--- v2.3.25/linux/drivers/block/ide-cd.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/block/ide-cd.c	Fri Nov  5 10:40:23 1999
@@ -24,11 +24,6 @@
  *
  * ----------------------------------
  * TO DO LIST:
- * -Implement Microsoft Media Status Notification per the spec at
- *   http://www.microsoft.com/hwdev/respec/storspec.htm
- *   This will allow us to get automagically notified when the media changes
- *   on ATAPI drives (something the stock ATAPI spec is lacking).  Looks
- *   very cool.  I discovered its existance the other day at work...
  * -Make it so that Pioneer CD DR-A24X and friends don't get screwed up on
  *   boot
  *
@@ -537,6 +532,7 @@
 	}
 	if (rq->cmd == READ && !rq->current_nr_sectors)
 		uptodate = 1;
+
 	ide_end_request (uptodate, HWGROUP(drive));
 }
 
@@ -663,6 +659,21 @@
 	return 1;
 }
 
+static int cdrom_timer_expiry(ide_drive_t *drive)
+{
+	struct request *rq = HWGROUP(drive)->rq;
+	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.
+	 */
+	if (pc->c[0] == GPCMD_BLANK || pc->c[0] == GPCMD_FORMAT_UNIT)
+		wait = 60*60*HZ;
+
+	return wait;
+}
 
 /* Set up the device registers for transferring a packet command on DEV,
    expecting to later transfer XFERLEN bytes.  HANDLER is the routine
@@ -696,7 +707,7 @@
 		(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
 
 	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
-		ide_set_handler (drive, handler);
+		ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry);
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
 	} else {
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
@@ -706,7 +717,6 @@
 	return 0;
 }
 
-
 /* Send a packet command to DRIVE described by CMD_BUF and CMD_LEN.
    The device registers must have already been prepared
    by cdrom_start_packet_command.
@@ -716,11 +726,6 @@
                                           unsigned char *cmd_buf, int cmd_len,
 					  ide_handler_t *handler)
 {
-	/* don't timeout for blank and format commands. they may take
-	 * a _very_ long time. */
-	if (cmd_buf[0] == GPCMD_BLANK || cmd_buf[0] == GPCMD_FORMAT_UNIT)
-		drive->timeout = 0;
-
 	if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
 		/* Here we should have been called after receiving an interrupt
 		   from the device.  DRQ should how be set. */
@@ -736,7 +741,7 @@
 	}
 
 	/* Arm the interrupt handler. */
-	ide_set_handler (drive, handler);
+	ide_set_handler (drive, handler, WAIT_CMD, cdrom_timer_expiry);
 
 	/* Send the command to the device. */
 	atapi_output_bytes (drive, cmd_buf, cmd_len);
@@ -769,17 +774,9 @@
 
 	char *dest;
 
-	/* If we don't yet have a sector buffer, try to allocate one.
-	   If we can't get one atomically, it's not fatal -- we'll just throw
-	   the data away rather than caching it. */
-	if (info->buffer == NULL) {
-		info->buffer = (char *) kmalloc(SECTOR_BUFFER_SIZE, GFP_ATOMIC);
-
-		/* If we couldn't get a buffer,
-		   don't try to buffer anything... */
-		if (info->buffer == NULL)
+	/* If we couldn't get a buffer, don't try to buffer anything... */
+	if (info->buffer == NULL)
 			sectors_to_buffer = 0;
-	}
 
 	/* If this is the first sector in the buffer, remember its number. */
 	if (info->nsectors_buffered == 0)
@@ -866,13 +863,14 @@
 		return;
  
 	if (dma) {
-		if (!dma_error) {
-			for (i = rq->nr_sectors; i > 0;) {
-				i -= rq->current_nr_sectors;
-				ide_end_request(1, HWGROUP(drive));
-			}
-		} else
+		if (dma_error) {
 			ide_error (drive, "dma error", stat);
+			return;
+		}
+		for (i = rq->nr_sectors; i > 0;) {
+			i -= rq->current_nr_sectors;
+			ide_end_request(1, HWGROUP(drive));
+		}
 		return;
 	}
 
@@ -968,7 +966,7 @@
 
 	/* Done moving data!
 	   Wait for another interrupt. */
-	ide_set_handler(drive, &cdrom_read_intr);
+	ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL);
 }
 
 /*
@@ -1206,9 +1204,6 @@
 	struct request *rq = HWGROUP(drive)->rq;
 	struct packet_command *pc = (struct packet_command *)rq->buffer;
 
-	/* restore timeout after blank or format command */
-	drive->timeout = WAIT_CMD;
-
 	/* Check for errors. */
 	if (cdrom_decode_status (drive, 0, &stat))
 		return;
@@ -1294,7 +1289,7 @@
 	}
 
 	/* Now we wait for another interrupt. */
-	ide_set_handler (drive, &cdrom_pc_intr);
+	ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
 }
 
 
@@ -1789,7 +1784,7 @@
 
 	/* Now try to get the total cdrom capacity. */
 #if 0
-	stat = cdrom_get_last_written(MKDEV(HWIF(drive)->major, minor,
+	stat = cdrom_get_last_written(MKDEV(HWIF(drive)->major, minor),
 				     (long *)&toc->capacity);
 	if (stat)
 #endif
@@ -1797,6 +1792,7 @@
 	if (stat) toc->capacity = 0x1fffff;
 
 	/* for general /dev/cdrom like mounting, one big disc */
+	drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;
 	HWIF(drive)->gd->sizes[minor] = (toc->capacity * SECTORS_PER_FRAME) >>
 					(BLOCK_SIZE_BITS - 9);
 
@@ -1812,11 +1808,11 @@
 	i = toc->hdr.first_track;
 	while ((i <= ntracks) && ((minor & CD_PART_MASK) < CD_PART_MAX)) {
 		drive->part[minor & PARTN_MASK].start_sect = 0;
- 		drive->part[minor & PARTN_MASK].nr_sects = (toc->ent[i].addr.lba *
+ 		drive->part[minor & PARTN_MASK].nr_sects =
+			(toc->ent[i].addr.lba *
 			SECTORS_PER_FRAME) << (BLOCK_SIZE_BITS - 9);
 		HWIF(drive)->gd->sizes[minor] = (toc->ent[i].addr.lba *
 			SECTORS_PER_FRAME) >> (BLOCK_SIZE_BITS - 9);
-		blksize_size[HWIF(drive)->major][minor] = CD_FRAMESIZE;
 		i++;
 		minor++;
 	}
@@ -2273,8 +2269,11 @@
 		struct atapi_capabilities_page cap;
 	} buf;
 
-	if (CDROM_CONFIG_FLAGS (drive)->nec260)
+	if (CDROM_CONFIG_FLAGS (drive)->nec260) {
+		CDROM_CONFIG_FLAGS (drive)->no_eject = 0;                       
+		CDROM_CONFIG_FLAGS (drive)->audio_play = 1;       
 		return nslots;
+	}
 
 	init_cdrom_command(&cgc, &buf, sizeof(buf));
 	/* we have to cheat a little here. the packet will eventually
@@ -2342,9 +2341,12 @@
 			(ntohs(buf.cap.maxspeed) + (176/2)) / 176;
 	}
 
-	printk ("%s: ATAPI %dX %s", 
-        	drive->name, CDROM_CONFIG_FLAGS (drive)->max_speed,
-		(CDROM_CONFIG_FLAGS (drive)->dvd) ? "DVD-ROM" : "CD-ROM");
+	/* don't print speed if the drive reported 0.
+	 */
+	printk("%s: ATAPI", drive->name);
+	if (CDROM_CONFIG_FLAGS(drive)->max_speed)
+		printk(" %dX", CDROM_CONFIG_FLAGS(drive)->max_speed);
+	printk(" %s", CDROM_CONFIG_FLAGS(drive)->dvd ? "DVD-ROM" : "CD-ROM");
 
 	if (CDROM_CONFIG_FLAGS (drive)->dvd_r|CDROM_CONFIG_FLAGS (drive)->dvd_ram)
         	printk (" DVD%s%s", 
@@ -2398,11 +2400,10 @@
 	int nslots;
 
 	set_device_ro(MKDEV(HWIF(drive)->major, minor), 1);
-	blksize_size[HWIF(drive)->major][minor] = CD_FRAMESIZE;
+	set_blocksize(MKDEV(HWIF(drive)->major, minor), CD_FRAMESIZE);
 
 	drive->special.all	= 0;
 	drive->ready_stat	= 0;
-	drive->timeout		= WAIT_CMD;
 
 	CDROM_STATE_FLAGS (drive)->media_changed = 1;
 	CDROM_STATE_FLAGS (drive)->toc_valid     = 0;
@@ -2435,10 +2436,14 @@
 	/* limit transfer size per interrupt. */
 	CDROM_CONFIG_FLAGS (drive)->limit_nframes = 0;
 	if (drive->id != NULL) {
+		/* a testament to the nice quality of Samsung drives... */
 		if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430"))
 			CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
 		else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432"))
 			CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
+		/* the 3231 model does not support the SET_CD_SPEED command */
+		else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231"))
+			cdi->mask |= CDC_SELECT_SPEED;
 	}
 
 #if ! STANDARD_ATAPI
@@ -2534,9 +2539,12 @@
 static
 int ide_cdrom_open (struct inode *ip, struct file *fp, ide_drive_t *drive)
 {
+	struct cdrom_info *info = drive->driver_data;
 	int rc;
 
 	MOD_INC_USE_COUNT;
+	if (info->buffer == NULL)
+		info->buffer = (char *) kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL);
 	rc = cdrom_fops.open (ip, fp);
 	if (rc) {
 		drive->usage--;
@@ -2617,12 +2625,7 @@
 MODULE_PARM(ignore, "s");
 MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
 
-int init_module (void)
-{
-	return ide_cdrom_init();
-}
-
-void cleanup_module(void)
+void __exit ide_cdrom_exit(void)
 {
 	ide_drive_t *drive;
 	int failed = 0;
@@ -2636,7 +2639,7 @@
 }
 #endif /* MODULE */
  
-int ide_cdrom_init (void)
+int __init ide_cdrom_init (void)
 {
 	ide_drive_t *drive;
 	struct cdrom_info *info;
@@ -2677,3 +2680,6 @@
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
+
+module_init(ide_cdrom_init);
+module_exit(ide_cdrom_exit);
diff -u --recursive --new-file v2.3.25/linux/drivers/block/ide-disk.c linux/drivers/block/ide-disk.c
--- v2.3.25/linux/drivers/block/ide-disk.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/block/ide-disk.c	Fri Nov  5 10:40:23 1999
@@ -175,7 +175,7 @@
 	if (i > 0) {
 		if (msect)
 			goto read_next;
-		ide_set_handler (drive, &read_intr);
+		ide_set_handler (drive, &read_intr, WAIT_CMD, NULL);
 	}
 }
 
@@ -206,7 +206,7 @@
 				ide_end_request(1, hwgroup);
 			if (i > 0) {
 				idedisk_output_data (drive, rq->buffer, SECTOR_WORDS);
-				ide_set_handler (drive, &write_intr);
+				ide_set_handler (drive, &write_intr, WAIT_CMD, NULL);
 			}
 			goto out;
 		}
@@ -271,7 +271,7 @@
 		if (stat & DRQ_STAT) {
 			if (rq->nr_sectors) {
 				ide_multwrite(drive, drive->mult_count);
-				ide_set_handler (drive, &multwrite_intr);
+				ide_set_handler (drive, &multwrite_intr, WAIT_CMD, NULL);
 				goto out;
 			}
 		} else {
@@ -385,7 +385,7 @@
 		if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_read, drive)))
 			return;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
-		ide_set_handler(drive, &read_intr);
+		ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
 		OUT_BYTE(drive->mult_count ? WIN_MULTREAD : WIN_READ, IDE_COMMAND_REG);
 		return;
 	}
@@ -404,10 +404,10 @@
 			__cli();	/* local CPU only */
 		if (drive->mult_count) {
 			HWGROUP(drive)->wrq = *rq; /* scratchpad */
-			ide_set_handler (drive, &multwrite_intr);
+			ide_set_handler (drive, &multwrite_intr, WAIT_CMD, NULL);
 			ide_multwrite(drive, drive->mult_count);
 		} else {
-			ide_set_handler (drive, &write_intr);
+			ide_set_handler (drive, &write_intr, WAIT_CMD, NULL);
 			idedisk_output_data(drive, rq->buffer, SECTOR_WORDS);
 		}
 		return;
@@ -506,7 +506,6 @@
 	drive->special.all = 0;
 	drive->special.b.set_geometry = 1;
 	drive->special.b.recalibrate  = 1;
-	drive->timeout = WAIT_CMD;
 	if (OK_TO_RESET_CONTROLLER)
 		drive->mult_count = 0;
 	if (!drive->keep_settings)
diff -u --recursive --new-file v2.3.25/linux/drivers/block/ide-dma.c linux/drivers/block/ide-dma.c
--- v2.3.25/linux/drivers/block/ide-dma.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/block/ide-dma.c	Fri Nov  5 10:40:23 1999
@@ -420,8 +420,7 @@
 			drive->waiting_for_dma = 1;
 			if (drive->media != ide_disk)
 				return 0;
-			drive->timeout = WAIT_CMD;
-			ide_set_handler(drive, &ide_dma_intr);/* issue cmd to drive */
+			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);/* issue cmd to drive */
 			OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 		case ide_dma_begin:
 			/* Note that this is done *after* the cmd has
diff -u --recursive --new-file v2.3.25/linux/drivers/block/ide-floppy.c linux/drivers/block/ide-floppy.c
--- v2.3.25/linux/drivers/block/ide-floppy.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/block/ide-floppy.c	Fri Nov  5 10:40:23 1999
@@ -916,7 +916,7 @@
 			if (temp > pc->buffer_size) {
 				printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n");
 				idefloppy_discard_data (drive,bcount.all);
-				ide_set_handler (drive,&idefloppy_pc_intr);
+				ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);
 				return;
 			}
 #if IDEFLOPPY_DEBUG_LOG
@@ -938,7 +938,7 @@
 	pc->actually_transferred+=bcount.all;				/* Update the current position */
 	pc->current_position+=bcount.all;
 
-	ide_set_handler (drive,&idefloppy_pc_intr);		/* And set the interrupt handler again */
+	ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);		/* And set the interrupt handler again */
 }
 
 static void idefloppy_transfer_pc (ide_drive_t *drive)
@@ -956,7 +956,7 @@
 		ide_do_reset (drive);
 		return;
 	}
-	ide_set_handler (drive, &idefloppy_pc_intr);	/* Set the interrupt routine */
+	ide_set_handler (drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);	/* Set the interrupt routine */
 	atapi_output_bytes (drive, floppy->pc->c, 12);		/* Send the actual packet */
 }
 
@@ -1025,7 +1025,7 @@
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
 	if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) {
-		ide_set_handler (drive, &idefloppy_transfer_pc);
+		ide_set_handler (drive, &idefloppy_transfer_pc, IDEFLOPPY_WAIT_CMD, NULL);
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);		/* Issue the packet command */
 	} else {
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
@@ -1519,7 +1519,6 @@
 	*((unsigned short *) &gcw) = drive->id->config;
 	drive->driver_data = floppy;
 	drive->ready_stat = 0;
-	drive->timeout = IDEFLOPPY_WAIT_CMD;
 	memset (floppy, 0, sizeof (idefloppy_floppy_t));
 	floppy->drive = drive;
 	floppy->pc = floppy->pc_stack;
diff -u --recursive --new-file v2.3.25/linux/drivers/block/ide-pmac.c linux/drivers/block/ide-pmac.c
--- v2.3.25/linux/drivers/block/ide-pmac.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/block/ide-pmac.c	Fri Nov  5 10:40:23 1999
@@ -363,8 +363,7 @@
 		drive->waiting_for_dma = 1;
 		if (drive->media != ide_disk)
 			return 0;
-		drive->timeout = WAIT_CMD;
-		ide_set_handler(drive, &ide_dma_intr);
+		ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
 		OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA,
 			 IDE_COMMAND_REG);
 	case ide_dma_begin:
diff -u --recursive --new-file v2.3.25/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c
--- v2.3.25/linux/drivers/block/ide-tape.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/block/ide-tape.c	Fri Nov  5 10:40:23 1999
@@ -1833,7 +1833,7 @@
 			if (temp > pc->buffer_size) {
 				printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n");
 				idetape_discard_data (drive,bcount.all);
-				ide_set_handler (drive,&idetape_pc_intr);
+				ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD,NULL);
 				return;
 			}
 #if IDETAPE_DEBUG_LOG
@@ -1855,7 +1855,7 @@
 	pc->actually_transferred+=bcount.all;					/* Update the current position */
 	pc->current_position+=bcount.all;
 
-	ide_set_handler (drive,&idetape_pc_intr);		/* And set the interrupt handler again */
+	ide_set_handler (drive,&idetape_pc_intr,IDETAPE_WAIT_CMD,NULL);		/* And set the interrupt handler again */
 }
 
 /*
@@ -1928,7 +1928,7 @@
 		ide_do_reset (drive);
 		return;
 	}
-	ide_set_handler(drive, &idetape_pc_intr);	/* Set the interrupt routine */
+	ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL);	/* Set the interrupt routine */
 	atapi_output_bytes (drive,pc->c,12);			/* Send the actual packet */
 }
 
@@ -1995,7 +1995,7 @@
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 	if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) {
-		ide_set_handler(drive, &idetape_transfer_pc);
+		ide_set_handler(drive, &idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL);
 		OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
 	} else {
 		OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG);
@@ -3579,7 +3579,6 @@
 	spin_lock_init(&tape->spinlock);
 	drive->driver_data = tape;
 	drive->ready_stat = 0;			/* An ATAPI device ignores DRDY */
-	drive->timeout = IDETAPE_WAIT_CMD;
 #ifdef CONFIG_BLK_DEV_IDEPCI
 	/*
 	 *  These two ide-pci host adapters appear to need this disabled.
diff -u --recursive --new-file v2.3.25/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v2.3.25/linux/drivers/block/ide.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/block/ide.c	Fri Nov  5 10:40:23 1999
@@ -498,25 +498,14 @@
 }
 
 /*
- * The below two are helpers used when modifying the drive timeout.
- */
-static inline unsigned long set_timeout(ide_drive_t *drive, unsigned long timeout)
-{
-	unsigned long foo = drive->timeout;
-	drive->timeout = timeout;
-	return foo;
-}
-
-#define restore_timeout(drive, old)	(drive->timeout = old)
-
-/*
  * This should get invoked any time we exit the driver to
  * wait for an interrupt response from a drive.  handler() points
  * at the appropriate code to handle the next interrupt, and a
  * timer is started to prevent us from waiting forever in case
  * something goes wrong (see the ide_timer_expiry() handler later on).
  */
-void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler)
+void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
+		      unsigned int timeout, ide_expiry_t *expiry)
 {
 	unsigned long flags;
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
@@ -528,12 +517,10 @@
 			drive->name, hwgroup->handler, handler);
 	}
 #endif
-	hwgroup->handler       = handler;
-	/* 0 means don't timeout */
-	if (drive->timeout && !timer_pending(&hwgroup->timer)) {
-		hwgroup->timer.expires = jiffies + drive->timeout;
-		add_timer(&(hwgroup->timer));
-	}
+	hwgroup->handler	= handler;
+	hwgroup->expiry		= expiry;
+	hwgroup->timer.expires	= jiffies + timeout;
+	add_timer(&(hwgroup->timer));
 	spin_unlock_irqrestore(&hwgroup->spinlock, flags);
 }
 
@@ -580,7 +567,6 @@
 static void atapi_reset_pollfunc (ide_drive_t *drive)
 {
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
-	unsigned long old_timeout;
 	byte stat;
 
 	SELECT_DRIVE(HWIF(drive),drive);
@@ -590,9 +576,7 @@
 		printk("%s: ATAPI reset complete\n", drive->name);
 	} else {
 		if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) {
-			old_timeout = set_timeout(drive, HZ / 20);
-			ide_set_handler (drive, &atapi_reset_pollfunc);
-			restore_timeout(drive, old_timeout);
+			ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL);
 			return;	/* continue polling */
 		}
 		hwgroup->poll_timeout = 0;	/* end of polling */
@@ -613,14 +597,11 @@
 {
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
 	ide_hwif_t *hwif = HWIF(drive);
-	unsigned long old_timeout;
 	byte tmp;
 
 	if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) {
 		if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) {
-			old_timeout = set_timeout(drive, HZ / 20);
-			ide_set_handler (drive, &reset_pollfunc);
-			restore_timeout(drive, old_timeout);
+			ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL);
 			return;	/* continue polling */
 		}
 		printk("%s: reset timed-out, status=0x%02x\n", hwif->name, tmp);
@@ -688,7 +669,6 @@
 	unsigned long flags;
 	ide_hwif_t *hwif = HWIF(drive);
 	ide_hwgroup_t *hwgroup = HWGROUP(drive);
-	unsigned long old_timeout;
 
 	__save_flags(flags);	/* local CPU only */
 	__cli();		/* local CPU only */
@@ -700,9 +680,7 @@
 		udelay (20);
 		OUT_BYTE (WIN_SRST, IDE_COMMAND_REG);
 		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
-		old_timeout = set_timeout(drive, HZ / 20);
-		ide_set_handler (drive, &atapi_reset_pollfunc);
-		restore_timeout(drive, old_timeout);
+		ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL);
 		__restore_flags (flags);	/* local CPU only */
 		return;
 	}
@@ -732,9 +710,7 @@
 	OUT_BYTE(drive->ctl|2,IDE_CONTROL_REG);	/* clear SRST, leave nIEN */
 	udelay(10);			/* more than enough time */
 	hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
-	old_timeout = set_timeout(drive, HZ / 20);
-	ide_set_handler (drive, &reset_pollfunc);
-	restore_timeout(drive, old_timeout);
+	ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL);
 
 	/*
 	 * Some weird controller like resetting themselves to a strange
@@ -934,7 +910,7 @@
  */
 void ide_cmd(ide_drive_t *drive, byte cmd, byte nsect, ide_handler_t *handler)
 {
-	ide_set_handler (drive, handler);
+	ide_set_handler (drive, handler, WAIT_CMD, NULL);
 	if (IDE_CONTROL_REG)
 		OUT_BYTE(drive->ctl,IDE_CONTROL_REG);	/* clear nIEN */
 	OUT_BYTE(nsect,IDE_NSECTOR_REG);
@@ -1425,7 +1401,9 @@
 	ide_hwgroup_t *hwgroup = (ide_hwgroup_t *) data;
 	ide_drive_t   *drive;
 	ide_handler_t *handler;
+	ide_expiry_t  *expiry;
 	unsigned long flags;
+	unsigned long wait;
 
 	spin_lock_irqsave(&hwgroup->spinlock, flags);
 	drive = hwgroup->drive;
@@ -1434,9 +1412,22 @@
 		do_hwgroup_request(hwgroup);
 		return;
 	}
+
 	hwgroup->busy = 1;	/* should already be "1" */
+
+	if ((expiry = hwgroup->expiry) != NULL) {
+		/* continue */
+		if ((wait = expiry(drive)) != 0) {
+			/* reset timer */
+			hwgroup->timer.expires	= jiffies + wait;
+			add_timer(&(hwgroup->timer));
+			spin_unlock_irqrestore(&hwgroup->spinlock, flags);
+			return;
+		}
+	}
+
 	hwgroup->handler = NULL;
-	/* polling in progress or just don't timeout */
+
 	if (hwgroup->poll_timeout != 0) {
 		spin_unlock_irqrestore(&hwgroup->spinlock, flags);
 		handler(drive);
diff -u --recursive --new-file v2.3.25/linux/drivers/block/loop.c linux/drivers/block/loop.c
--- v2.3.25/linux/drivers/block/loop.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/block/loop.c	Sat Nov  6 09:51:19 1999
@@ -151,12 +151,12 @@
 	int	size;
 
 	if (S_ISREG(lo->lo_dentry->d_inode->i_mode))
-		size = (lo->lo_dentry->d_inode->i_size - lo->lo_offset) / BLOCK_SIZE;
+		size = (lo->lo_dentry->d_inode->i_size - lo->lo_offset) >> BLOCK_SIZE_BITS;
 	else {
 		kdev_t lodev = lo->lo_device;
 		if (blk_size[MAJOR(lodev)])
 			size = blk_size[MAJOR(lodev)][MINOR(lodev)] -
-                                lo->lo_offset / BLOCK_SIZE;
+                                (lo->lo_offset >> BLOCK_SIZE_BITS);
 		else
 			size = MAX_DISK_SIZE;
 	}
diff -u --recursive --new-file v2.3.25/linux/drivers/block/pdc4030.c linux/drivers/block/pdc4030.c
--- v2.3.25/linux/drivers/block/pdc4030.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/block/pdc4030.c	Fri Nov  5 10:40:23 1999
@@ -162,7 +162,6 @@
 	if (!hwif) return 0;
 
 	drive = &hwif->drives[0];
-	drive->timeout = HZ/100;
 	hwif2 = &ide_hwifs[hwif->index+1];
 	if (hwif->chipset == ide_pdc4030) /* we've already been found ! */
 		return 1;
@@ -309,9 +308,6 @@
 	unsigned int sectors_left, sectors_avail, nsect;
 	struct request *rq;
 
-	/* reset timeout */
-	drive->timeout = HZ/100;
-	
 	if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) {
 		ide_error(drive, "promise_read_intr", stat);
 		return;
@@ -366,8 +362,7 @@
 		if (stat & DRQ_STAT)
 			goto read_again;
 		if (stat & BUSY_STAT) {
-			drive->timeout = WAIT_CMD;
-			ide_set_handler (drive, &promise_read_intr);
+			ide_set_handler (drive, &promise_read_intr, WAIT_CMD, NULL);
 #ifdef DEBUG_READ
 			printk(KERN_DEBUG "%s: promise_read: waiting for"
 			       "interrupt\n", drive->name);
@@ -396,7 +391,7 @@
 
 	if (GET_STAT() & BUSY_STAT) {
 		if (time_before(jiffies, hwgroup->poll_timeout)) {
-			ide_set_handler(drive, &promise_complete_pollfunc);
+			ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
 			return; /* continue polling... */
 		}
 		hwgroup->poll_timeout = 0;
@@ -425,7 +420,7 @@
 
 	if (IN_BYTE(IDE_NSECTOR_REG) != 0) {
 		if (time_before(jiffies, hwgroup->poll_timeout)) {
-			ide_set_handler (drive, &promise_write_pollfunc);
+			ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);
 			return; /* continue polling... */
 		}
 		hwgroup->poll_timeout = 0;
@@ -439,7 +434,7 @@
 	 */
 	ide_multwrite(drive, 4);
 	hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
-	ide_set_handler(drive, &promise_complete_pollfunc);
+	ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
 #ifdef DEBUG_WRITE
 	printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n",
 		drive->name, GET_STAT());
@@ -472,7 +467,7 @@
 	if (rq->nr_sectors > 4) {
 		ide_multwrite(drive, rq->nr_sectors - 4);
 		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
-		ide_set_handler (drive, &promise_write_pollfunc);
+		ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);
 	} else {
 	/*
 	 * There are 4 or fewer sectors to transfer, do them all in one go
@@ -480,7 +475,7 @@
 	 */
 		ide_multwrite(drive, rq->nr_sectors);
 		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
-		ide_set_handler(drive, &promise_complete_pollfunc);
+		ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
 #ifdef DEBUG_WRITE
 		printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, "
 			"status = %02x\n", drive->name, GET_STAT());
@@ -523,8 +518,7 @@
 				printk(KERN_DEBUG "%s: read: waiting for "
 				                  "interrupt\n", drive->name);
 #endif
-				drive->timeout = WAIT_CMD;
-				ide_set_handler(drive, &promise_read_intr);
+				ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL);
 				return;
 			}
 			udelay(1);
diff -u --recursive --new-file v2.3.25/linux/drivers/block/trm290.c linux/drivers/block/trm290.c
--- v2.3.25/linux/drivers/block/trm290.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/block/trm290.c	Fri Nov  5 10:40:23 1999
@@ -192,8 +192,7 @@
 			outw((count * 2) - 1, hwif->dma_base+2); /* start DMA */
 			if (drive->media != ide_disk)
 				return 0;
-			drive->timeout = WAIT_CMD;
-			ide_set_handler(drive, &ide_dma_intr);
+			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
 			OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 			return 0;
 		case ide_dma_begin:
diff -u --recursive --new-file v2.3.25/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c
--- v2.3.25/linux/drivers/cdrom/cdrom.c	Fri Oct 22 13:21:47 1999
+++ linux/drivers/cdrom/cdrom.c	Wed Nov  3 14:01:47 1999
@@ -178,14 +178,19 @@
   -- Export cdrom_mode_sense and cdrom_mode_select.
   -- init_cdrom_command() for setting up a cgc command.
   
-  3.05 Sep 23, 1999 - Jens Axboe <axboe@image.dk>
+  3.05 Oct 24, 1999 - Jens Axboe <axboe@image.dk>
   -- Changed the interface for CDROM_SEND_PACKET. Before it was virtually
   impossible to send the drive data in a sensible way.
+  -- Lowered stack usage in mmc_ioctl(), dvd_read_disckey(), and
+  dvd_read_manufact.
+  -- Added setup of write mode for packet writing.
+  -- Fixed CDDA ripping with cdda2wav - accept much larger requests of
+  number of frames and split the reads in blocks of 8.
   
 -------------------------------------------------------------------------*/
 
 #define REVISION "Revision: 3.05"
-#define VERSION "Id: cdrom.c 3.05 1999/09/23"
+#define VERSION "Id: cdrom.c 3.05 1999/10/24"
 
 /* I use an error-log mask to give fine grain control over the type of
    messages dumped to the system logs.  The available masks include: */
@@ -205,7 +210,6 @@
 /* #define ERRLOGMASK (CD_WARNING|CD_OPEN|CD_COUNT_TRACKS|CD_CLOSE) */
 /* #define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) */
 
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/fs.h>
@@ -311,7 +315,7 @@
 int register_cdrom(struct cdrom_device_info *cdi)
 {
 	static char banner_printed = 0;
-	int major = MAJOR (cdi->dev);
+	int major = MAJOR(cdi->dev);
         struct cdrom_device_ops *cdo = cdi->ops;
         int *change_capability = (int *)&cdo->capability; /* hack */
 
@@ -362,7 +366,7 @@
 int unregister_cdrom(struct cdrom_device_info *unreg)
 {
 	struct cdrom_device_info *cdi, *prev;
-	int major = MAJOR (unreg->dev);
+	int major = MAJOR(unreg->dev);
 
 	cdinfo(CD_OPEN, "entering unregister_cdrom\n"); 
 
@@ -388,7 +392,7 @@
 }
 
 static
-struct cdrom_device_info *cdrom_find_device (kdev_t dev)
+struct cdrom_device_info *cdrom_find_device(kdev_t dev)
 {
 	struct cdrom_device_info *cdi;
 
@@ -736,7 +740,7 @@
 	return cdi->ops->generic_packet(cdi, &cgc);
 }
 
-int cdrom_select_disc (struct cdrom_device_info *cdi, int slot)
+int cdrom_select_disc(struct cdrom_device_info *cdi, int slot)
 {
 	struct cdrom_changer_info info;
 	int curslot;
@@ -908,7 +912,8 @@
 void init_cdrom_command(struct cdrom_generic_command *cgc,
 			void *buffer, int len)
 {
-	memset(cgc, 0, sizeof(*cgc));
+	memset(cgc, 0, sizeof(struct cdrom_generic_command));
+	memset(buffer, 0, len);
 	cgc->buffer = (char *) buffer;
 	cgc->buflen = len;
 }
@@ -918,19 +923,49 @@
 #define copy_key(dest,src)	memcpy((dest), (src), sizeof(dvd_key))
 #define copy_chal(dest,src)	memcpy((dest), (src), sizeof(dvd_challenge))
 
-static void setup_report_key (struct cdrom_generic_command *cgc, unsigned agid, unsigned type)
+static void setup_report_key(struct cdrom_generic_command *cgc, unsigned agid, unsigned type)
 {
 	cgc->cmd[0] = GPCMD_REPORT_KEY;
 	cgc->cmd[10] = type | (agid << 6);
+	switch (type) {
+		case 0: case 8: case 5: {
+			cgc->buflen = 8;
+			break;
+		}
+		case 1: {
+			cgc->buflen = 16;
+			break;
+		}
+		case 2: case 4: {
+			cgc->buflen = 12;
+			break;
+		}
+	}
+	cgc->cmd[9] = cgc->buflen;
 }
 
-static void setup_send_key (struct cdrom_generic_command *cgc, unsigned agid, unsigned type)
+static void setup_send_key(struct cdrom_generic_command *cgc, unsigned agid, unsigned type)
 {
 	cgc->cmd[0] = GPCMD_SEND_KEY;
 	cgc->cmd[10] = type | (agid << 6);
+	switch (type) {
+		case 1: {
+			cgc->buflen = 16;
+			break;
+		}
+		case 3: {
+			cgc->buflen = 12;
+			break;
+		}
+		case 6: {
+			cgc->buflen = 8;
+			break;
+		}
+	}
+	cgc->cmd[9] = cgc->buflen;
 }
 
-static int dvd_do_auth (struct cdrom_device_info *cdi, dvd_authinfo *ai)
+static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
 {
 	int ret;
 	u_char buf[20];
@@ -943,8 +978,7 @@
 	/* LU data send */
 	case DVD_LU_SEND_AGID:
 		cdinfo(CD_DVD, "entering DVD_LU_SEND_AGID\n"); 
-		setup_report_key (&cgc, 0, 0);
-		cgc.buflen = cgc.cmd[9] = 8;
+		setup_report_key(&cgc, ai->lsa.agid, 0);
 
 		if ((ret = cdo->generic_packet(cdi, &cgc)))
 			return ret;
@@ -955,8 +989,7 @@
 
 	case DVD_LU_SEND_KEY1:
 		cdinfo(CD_DVD, "entering DVD_LU_SEND_KEY1\n"); 
-		setup_report_key (&cgc, ai->lsk.agid, 2);
-		cgc.buflen = cgc.cmd[9] = 12;
+		setup_report_key(&cgc, ai->lsk.agid, 2);
 
 		if ((ret = cdo->generic_packet(cdi, &cgc)))
 			return ret;
@@ -967,8 +1000,7 @@
 
 	case DVD_LU_SEND_CHALLENGE:
 		cdinfo(CD_DVD, "entering DVD_LU_SEND_CHALLENGE\n"); 
-		setup_report_key (&cgc, ai->lsc.agid, 1);
-		cgc.buflen = cgc.cmd[9] = 16;
+		setup_report_key(&cgc, ai->lsc.agid, 1);
 
 		if ((ret = cdo->generic_packet(cdi, &cgc)))
 			return ret;
@@ -980,12 +1012,11 @@
 	/* Post-auth key */
 	case DVD_LU_SEND_TITLE_KEY:
 		cdinfo(CD_DVD, "entering DVD_LU_SEND_TITLE_KEY\n"); 
-		setup_report_key (&cgc, ai->lstk.agid, 4);
+		setup_report_key(&cgc, ai->lstk.agid, 4);
 		cgc.cmd[5] = ai->lstk.lba;
 		cgc.cmd[4] = ai->lstk.lba >> 8;
 		cgc.cmd[3] = ai->lstk.lba >> 16;
 		cgc.cmd[2] = ai->lstk.lba >> 24;
-		cgc.buflen = cgc.cmd[9] = 12;
 
 		if ((ret = cdo->generic_packet(cdi, &cgc)))
 			return ret;
@@ -993,14 +1024,13 @@
 		ai->lstk.cpm = (buf[4] >> 7) & 1;
 		ai->lstk.cp_sec = (buf[4] >> 6) & 1;
 		ai->lstk.cgms = (buf[4] >> 4) & 3;
-		copy_key (ai->lstk.title_key, &buf[5]);
+		copy_key(ai->lstk.title_key, &buf[5]);
 		/* Returning data, let host change state */
 		break;
 
 	case DVD_LU_SEND_ASF:
 		cdinfo(CD_DVD, "entering DVD_LU_SEND_ASF\n"); 
-		setup_report_key (&cgc, ai->lsasf.asf, 5);
-		cgc.buflen = cgc.cmd[9] = 8;
+		setup_report_key(&cgc, ai->lsasf.asf, 5);
 		
 		if ((ret = cdo->generic_packet(cdi, &cgc)))
 			return ret;
@@ -1011,10 +1041,9 @@
 	/* LU data receive (LU changes state) */
 	case DVD_HOST_SEND_CHALLENGE:
 		cdinfo(CD_DVD, "entering DVD_HOST_SEND_CHALLENGE\n"); 
-		setup_send_key (&cgc, ai->hsc.agid, 1);
-		cgc.buflen = cgc.cmd[9] = 16;
-		buf[1] = 14;
-		copy_chal (&buf[4], ai->hsc.chal);
+		setup_send_key(&cgc, ai->hsc.agid, 1);
+		buf[1] = 0xe;
+		copy_chal(&buf[4], ai->hsc.chal);
 
 		if ((ret = cdo->generic_packet(cdi, &cgc)))
 			return ret;
@@ -1024,13 +1053,11 @@
 
 	case DVD_HOST_SEND_KEY2:
 		cdinfo(CD_DVD, "entering DVD_HOST_SEND_KEY2\n"); 
-		setup_send_key (&cgc, ai->hsk.agid, 3);
-		cgc.buflen = cgc.cmd[9] = 12;
-		buf[1] = 10;
-		copy_key (&buf[4], ai->hsk.key);
+		setup_send_key(&cgc, ai->hsk.agid, 3);
+		buf[1] = 0xa;
+		copy_key(&buf[4], ai->hsk.key);
 
-		ret = cdo->generic_packet(cdi, &cgc);
-		if (ret) {
+		if ((ret = cdo->generic_packet(cdi, &cgc))) {
 			ai->type = DVD_AUTH_FAILURE;
 			return ret;
 		}
@@ -1040,7 +1067,7 @@
 	/* Misc */
 	case DVD_INVALIDATE_AGID:
 		cdinfo(CD_DVD, "entering DVD_INVALIDATE_AGID\n"); 
-		setup_report_key (&cgc, ai->lsa.agid, 0x3f);
+		setup_report_key(&cgc, ai->lsa.agid, 0x3f);
 		if ((ret = cdo->generic_packet(cdi, &cgc)))
 			return ret;
 		break;
@@ -1053,7 +1080,7 @@
 	return 0;
 }
 
-static int dvd_read_physical (struct cdrom_device_info *cdi, dvd_struct *s)
+static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s)
 {
 	int ret, i;
 	u_char buf[4 + 4 * 20], *base;
@@ -1061,7 +1088,6 @@
 	struct cdrom_generic_command cgc;
 	struct cdrom_device_ops *cdo = cdi->ops;
 
-	memset(buf, 0, sizeof(buf));
 	init_cdrom_command(&cgc, buf, sizeof(buf));
 	cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
 	cgc.cmd[6] = s->physical.layer_num;
@@ -1077,7 +1103,7 @@
 	/* place the data... really ugly, but at least we won't have to
 	   worry about endianess in userspace or here. */
 	for (i = 0; i < 4; ++i, base += 20, ++layer) {
-		memset (layer, 0, sizeof (*layer));
+		memset(layer, 0, sizeof(*layer));
 		layer->book_version = base[0] & 0xf;
 		layer->book_type = base[0] >> 4;
 		layer->min_rate = base[1] & 0xf;
@@ -1103,7 +1129,6 @@
 	struct cdrom_generic_command cgc;
 	struct cdrom_device_ops *cdo = cdi->ops;
 
-	memset(buf, 0, sizeof(buf));
 	init_cdrom_command(&cgc, buf, sizeof(buf));
 	cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
 	cgc.cmd[6] = s->copyright.layer_num;
@@ -1120,27 +1145,30 @@
 	return 0;
 }
 
-static int dvd_read_disckey (struct cdrom_device_info *cdi, dvd_struct *s)
+static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s)
 {
-	int ret;
-	u_char buf[4 + 2048];
+	int ret, size;
+	u_char *buf;
 	struct cdrom_generic_command cgc;
 	struct cdrom_device_ops *cdo = cdi->ops;
 
-	memset(buf, 0, sizeof (buf));
-	init_cdrom_command(&cgc, buf, sizeof(buf));
+	size = sizeof(s->disckey.value) + 4;
+
+	if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+
+	init_cdrom_command(&cgc, buf, size);
 	cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
 	cgc.cmd[7] = s->type;
-	cgc.cmd[8] = sizeof(buf) >> 8;
-	cgc.cmd[9] = cgc.buflen & 0xff;
+	cgc.cmd[8] = size >> 8;
+	cgc.cmd[9] = size & 0xff;
 	cgc.cmd[10] = s->disckey.agid << 6;
 
-	if ((ret = cdo->generic_packet(cdi, &cgc)))
-		return ret;
-
-	memcpy(s->disckey.value, &buf[4], 2048);
+	if (!(ret = cdo->generic_packet(cdi, &cgc)))
+		memcpy(s->disckey.value, &buf[4], sizeof(s->disckey.value));
 
-	return 0;
+	kfree(buf);
+	return ret;
 }
 
 static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s)
@@ -1150,7 +1178,6 @@
 	struct cdrom_generic_command cgc;
 	struct cdrom_device_ops *cdo = cdi->ops;
 
-	memset(buf, 0, sizeof (buf));
 	init_cdrom_command(&cgc, buf, sizeof(buf));
 	cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
 	cgc.cmd[7] = s->type;
@@ -1171,30 +1198,38 @@
 
 static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s)
 {
-	int ret;
-	u_char buf[4 + 2048];
+	int ret = 0, size;
+	u_char *buf;
 	struct cdrom_generic_command cgc;
 	struct cdrom_device_ops *cdo = cdi->ops;
 
-	memset(buf, 0, sizeof(buf));
-	init_cdrom_command(&cgc, buf, sizeof(buf));
+	size = sizeof(s->manufact.value) + 4;
+
+	if ((buf = (u_char *) kmalloc(size, GFP_KERNEL)) == NULL)
+		return -ENOMEM;
+
+	init_cdrom_command(&cgc, buf, size);
 	cgc.cmd[0] = GPCMD_READ_DVD_STRUCTURE;
 	cgc.cmd[7] = s->type;
-	cgc.buflen = sizeof(buf);
-	cgc.cmd[8] = sizeof(buf) >> 8;
-	cgc.cmd[9] = cgc.buflen & 0xff;
+	cgc.cmd[8] = size >> 8;
+	cgc.cmd[9] = size & 0xff;
 
-	if ((ret = cdo->generic_packet(cdi, &cgc)))
+	if ((ret = cdo->generic_packet(cdi, &cgc))) {
+		kfree(buf);
 		return ret;
+	}
 
 	s->manufact.len = buf[0] << 8 | buf[1];
 	if (s->manufact.len < 0 || s->manufact.len > 2048) {
-		cdinfo(CD_WARNING, "Recieved invalid manufacture info length (%d)\n", s->bca.len);
-		return -EIO;
+		cdinfo(CD_WARNING, "Received invalid manufacture info length"
+				   " (%d)\n", s->bca.len);
+		ret = -EIO;
+	} else {
+		memcpy(s->manufact.value, &buf[4], s->manufact.len);
 	}
-	memcpy(s->manufact.value, &buf[4], s->manufact.len);
 
-	return 0;
+	kfree(buf);
+	return ret;
 }
 
 static int dvd_read_struct(struct cdrom_device_info *cdi, dvd_struct *s)
@@ -1709,7 +1744,7 @@
 }
 
 static inline
-int msf_to_lba (char m, char s, char f)
+int msf_to_lba(char m, char s, char f)
 {
 	return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
 }
@@ -1763,7 +1798,7 @@
 		}
 	case CDROMREADAUDIO: {
 		struct cdrom_read_audio ra;
-		int lba;
+		int lba, frames;
 
 		IOCTL_IN(arg, struct cdrom_read_audio, ra);
 
@@ -1780,12 +1815,10 @@
 		if (lba < 0)
 			return -EINVAL;
 
-		/* do between 1 and 8 frames at the time */
-		if (ra.nframes > 8 || ra.nframes < 1)
-			return -EINVAL;
+		/* do max 8 frames at the time */
+		frames = ra.nframes > 8 ? 8 : ra.nframes;
 
-		/* just a nice round figure */
-		if ((cgc.buffer = (char *) kmalloc(CD_FRAMESIZE_RAW*ra.nframes,
+		if ((cgc.buffer = (char *) kmalloc(CD_FRAMESIZE_RAW * frames,
 						   GFP_KERNEL)) == NULL)
 			return -ENOMEM;
 
@@ -1795,14 +1828,14 @@
 		}
 
 		while (ra.nframes > 0) {
-			ret = cdrom_read_block(cdi, &cgc, lba, ra.nframes, 1,
+			ret = cdrom_read_block(cdi, &cgc, lba, frames, 1,
 					       CD_FRAMESIZE_RAW);
 			if (ret) break;
 			__copy_to_user(ra.buf, cgc.buffer,
-				       CD_FRAMESIZE_RAW*ra.nframes);
-			ra.buf += (CD_FRAMESIZE_RAW * ra.nframes);
-			ra.nframes -= ra.nframes;
-			lba += ra.nframes;
+				       CD_FRAMESIZE_RAW * frames);
+			ra.buf += (CD_FRAMESIZE_RAW * frames);
+			ra.nframes -= frames;
+			lba += frames;
 		}
 		kfree(cgc.buffer);
 		return ret;
@@ -1950,17 +1983,27 @@
 		cgc.cmd[8] = (cmd == CDROMRESUME) ? 1 : 0;
 		return cdo->generic_packet(cdi, &cgc);
 		}
-	
+
 	case DVD_READ_STRUCT: {
-		dvd_struct s;
+		dvd_struct *s;
+		int size = sizeof(dvd_struct);
 		if (!CDROM_CAN(CDC_DVD))
 			return -ENOSYS;
+		if ((s = (dvd_struct *) kmalloc(size, GFP_KERNEL)) == NULL)
+			return -ENOMEM;
 		cdinfo(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n"); 
-		IOCTL_IN(arg, dvd_struct, s);
-		if ((ret = dvd_read_struct(cdi, &s)))
+		if (copy_from_user(s, (dvd_struct *)arg, size)) {
+			kfree(s);
+			return -EFAULT;
+		}
+		if ((ret = dvd_read_struct(cdi, s))) {
+			kfree(s);
 			return ret;
-		IOCTL_OUT(arg, dvd_struct, s);
-		return 0;
+		}
+		if (copy_to_user((dvd_struct *)arg, s, size))
+			ret = -EFAULT;
+		kfree(s);
+		return ret;
 		}
 
 	case DVD_AUTH: {
@@ -2069,7 +2112,6 @@
 
 	/* set up command and get the disc info */
 	init_cdrom_command(&cgc, di, sizeof(*di));
-	memset(di, 0, sizeof(disc_information));
 	cgc.cmd[0] = GPCMD_READ_DISC_INFO;
 	cgc.cmd[8] = cgc.buflen;
 
@@ -2207,7 +2249,6 @@
 
 	memset(&di, 0, sizeof(disc_information));
 	memset(&ti, 0, sizeof(track_information));
-	memset(&wp, 0, sizeof(write_param_page));
 	memset(&cdi->write, 0, sizeof(struct cdrom_write_settings));
 
 	if ((ret = cdrom_get_disc_info(cdi->dev, &di)))
diff -u --recursive --new-file v2.3.25/linux/drivers/char/Makefile linux/drivers/char/Makefile
--- v2.3.25/linux/drivers/char/Makefile	Mon Nov  1 13:56:26 1999
+++ linux/drivers/char/Makefile	Tue Nov  2 21:35:46 1999
@@ -322,6 +322,10 @@
 
 ifeq ($(CONFIG_RTC),y)
 O_OBJS += rtc.o
+else
+  ifeq ($(CONFIG_RTC),m)
+    M_OBJS += rtc.o
+  endif
 endif
 
 ifeq ($(CONFIG_NVRAM),y)
@@ -362,16 +366,6 @@
   endif
 endif
 
-ifeq ($(CONFIG_VIDEO_SAA5249),y)
-O_OBJS += saa5249.o
-L_I2C=y
-else
-  ifeq ($(CONFIG_VIDEO_SAA5249),m)
-    M_OBJS += saa5249.o
-    M_I2C=y
-  endif
-endif
-
 ifeq ($(CONFIG_I2C_PARPORT),y)
 O_OBJS += i2c-parport.o
 L_I2C = y
@@ -382,11 +376,13 @@
   endif
 endif
 
-ifeq ($(CONFIG_VIDEO_BWQCAM),y)
-O_OBJS += bw-qcam.o
+ifeq ($(CONFIG_VIDEO_SAA5249),y)
+O_OBJS += saa5249.o
+L_I2C=y
 else
-  ifeq ($(CONFIG_VIDEO_BWQCAM),m)
-    M_OBJS += bw-qcam.o
+  ifeq ($(CONFIG_VIDEO_SAA5249),m)
+    M_OBJS += saa5249.o
+    M_I2C=y
   endif
 endif
 
@@ -395,6 +391,14 @@
 else
   ifeq ($(CONFIG_VIDEO_CQCAM),m)
     M_OBJS += c-qcam.o
+  endif
+endif
+
+ifeq ($(CONFIG_VIDEO_BWQCAM),y)
+O_OBJS += bw-qcam.o
+else
+  ifeq ($(CONFIG_VIDEO_BWQCAM),m)
+    M_OBJS += bw-qcam.o
   endif
 endif
 
diff -u --recursive --new-file v2.3.25/linux/drivers/char/README.computone linux/drivers/char/README.computone
--- v2.3.25/linux/drivers/char/README.computone	Thu Aug 26 13:05:34 1999
+++ linux/drivers/char/README.computone	Sat Nov  6 10:38:40 1999
@@ -47,7 +47,7 @@
 e) Set address on ISA cards then:
    edit /usr/src/linux/drivers/char/ip2/ip2.h if needed 
 	or
-   edit /etc/conf.modules (or /etc/modules.conf) if needed (module).
+   edit /etc/modules.conf if needed (module).
 	or both to match this setting.
 f) Run "make dep"
 g) Run "make modules"
diff -u --recursive --new-file v2.3.25/linux/drivers/char/adbmouse.c linux/drivers/char/adbmouse.c
--- v2.3.25/linux/drivers/char/adbmouse.c	Fri Oct 15 15:25:13 1999
+++ linux/drivers/char/adbmouse.c	Tue Nov  2 21:38:44 1999
@@ -148,7 +148,7 @@
 	ADB_MOUSE_MINOR, "adbmouse", open_mouse, release_mouse, 7
 };
 
-int __init adb_mouse_init(void)
+static int __init adb_mouse_init(void)
 {
 #ifdef __powerpc__
 	if ((_machine != _MACH_chrp) && (_machine != _MACH_Pmac))
@@ -170,6 +170,8 @@
 	return msedev < 0 ? msedev : 0;
 }
 
+#ifndef MODULE
+
 /*
  * XXX this function is misnamed.
  * It is called if the kernel is booted with the adb_buttons=xxx
@@ -193,15 +195,12 @@
 
 __setup("adb_buttons=", adb_mouse_setup);
 
-#ifdef MODULE
-int init_module(void)
-{
-	return adb_mouse_init();
-}
+#endif /* !MODULE */
 
-void cleanup_module(void)
+static void __exit adb_mouse_cleanup(void)
 {
 	unregister_busmouse(msedev);
 }
 
-#endif
+module_init(adb_mouse_init);
+module_exit(adb_mouse_cleanup);
diff -u --recursive --new-file v2.3.25/linux/drivers/char/amigamouse.c linux/drivers/char/amigamouse.c
--- v2.3.25/linux/drivers/char/amigamouse.c	Tue Sep  7 12:14:06 1999
+++ linux/drivers/char/amigamouse.c	Tue Nov  2 21:38:44 1999
@@ -183,7 +183,7 @@
 	AMIGAMOUSE_MINOR, "amigamouse", open_mouse, release_mouse, 7
 };
 
-int __init amiga_mouse_init(void)
+static int __init amiga_mouse_init(void)
 {
 	if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE))
 		return -ENODEV;
@@ -200,12 +200,10 @@
 	return msedev < 0 ? msedev : 0;
 }
 
-void __exit amiga_mouse_exit(void)
+static void __exit amiga_mouse_exit(void)
 {
 	unregister_busmouse(msedev);
 }
 
-#ifdef MODULE
-module_init(amiga_mouse_init)
-module_exit(amiga_mouse_exit)
-#endif
+module_init(amiga_mouse_init);
+module_exit(amiga_mouse_exit);
diff -u --recursive --new-file v2.3.25/linux/drivers/char/atarimouse.c linux/drivers/char/atarimouse.c
--- v2.3.25/linux/drivers/char/atarimouse.c	Tue Sep  7 12:14:06 1999
+++ linux/drivers/char/atarimouse.c	Tue Nov  2 21:38:44 1999
@@ -76,7 +76,7 @@
 	ATARIMOUSE_MINOR, "atarimouse", open_mouse, release_mouse, 0
 };
 
-int __init atari_mouse_init(void)
+static int __init atari_mouse_init(void)
 {
     if (!MACH_IS_ATARI)
 	return -ENODEV;
@@ -89,42 +89,50 @@
 }
 
 
+#ifndef MODULE
+
 #define	MIN_THRESHOLD 1
 #define	MAX_THRESHOLD 20	/* more seems not reasonable... */
 
-void __init atari_mouse_setup( char *str, int *ints )
+static int __init atari_mouse_setup( char *str )
 {
+    int ints[8];
+
+    str = get_options(str, ARRAY_SIZE(ints), ints);
+
     if (ints[0] < 1) {
-	printk( "atari_mouse_setup: no arguments!\n" );
-	return;
+	printk(KERN_ERR "atari_mouse_setup: no arguments!\n" );
+	return 0;
     }
     else if (ints[0] > 2) {
-	printk( "atari_mouse_setup: too many arguments\n" );
+	printk(KERN_WARNING "atari_mouse_setup: too many arguments\n" );
     }
 
     if (ints[1] < MIN_THRESHOLD || ints[1] > MAX_THRESHOLD)
-	printk( "atari_mouse_setup: bad threshold value (ignored)\n" );
+	printk(KERN_WARNING "atari_mouse_setup: bad threshold value (ignored)\n" );
     else {
 	mouse_threshold[0] = ints[1];
 	mouse_threshold[1] = ints[1];
 	if (ints[0] > 1) {
 	    if (ints[2] < MIN_THRESHOLD || ints[2] > MAX_THRESHOLD)
-		printk("atari_mouse_setup: bad threshold value (ignored)\n" );
+		printk(KERN_WARNING "atari_mouse_setup: bad threshold value (ignored)\n" );
 	    else
 		mouse_threshold[1] = ints[2];
 	}
     }
-	
-}
 
-#ifdef MODULE
-int init_module(void)
-{
-	return atari_mouse_init();
+    return 1;
 }
 
-void cleanup_module(void)
+__setup("atarimouse=",atari_mouse_setup);
+
+#endif /* !MODULE */
+
+static void __exit atari_mouse_cleanup (void)
 {
 	unregister_busmouse(msedev);
 }
-#endif
+
+module_init(atari_mouse_init);
+module_exit(atari_mouse_cleanup);
+
diff -u --recursive --new-file v2.3.25/linux/drivers/char/atixlmouse.c linux/drivers/char/atixlmouse.c
--- v2.3.25/linux/drivers/char/atixlmouse.c	Mon Aug  2 09:54:29 1999
+++ linux/drivers/char/atixlmouse.c	Tue Nov  2 21:38:44 1999
@@ -23,6 +23,7 @@
 #include <linux/random.h>
 #include <linux/poll.h>
 #include <linux/init.h>
+#include <linux/ioport.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -66,7 +67,7 @@
 
 static int msedev;
 
-void mouse_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static void mouse_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
 	char dx, dy, buttons;
 
@@ -102,10 +103,13 @@
 	ATIXL_BUSMOUSE, "atixl", open_mouse, release_mouse, 0
 };
 
-int __init atixl_busmouse_init(void)
+static int __init atixl_busmouse_init(void)
 {
 	unsigned char a,b,c;
 
+	if (check_region(ATIXL_MSE_DATA_PORT, 3))
+		return -EIO;
+
 	a = inb( ATIXL_MSE_SIGNATURE_PORT );	/* Get signature */
 	b = inb( ATIXL_MSE_SIGNATURE_PORT );
 	c = inb( ATIXL_MSE_SIGNATURE_PORT );
@@ -117,6 +121,8 @@
 	outb(0x07, ATIXL_MSE_CONTROL_PORT);	/* Select Internal Register 7 */
 	outb(0x0a, ATIXL_MSE_DATA_PORT);	/* Data Interrupts 8+, 1=30hz, 2=50hz, 3=100hz, 4=200hz rate */
 
+	request_region(ATIXL_MSE_DATA_PORT, 3, "atixl");
+
 	msedev = register_busmouse(&atixlmouse);
 	if (msedev < 0)
 		printk("Bus mouse initialisation error.\n");
@@ -125,15 +131,12 @@
 	return msedev < 0 ? msedev : 0;
 }
 
-#ifdef MODULE
-
-int init_module(void)
-{
-	return atixl_busmouse_init();
-}
-
-void cleanup_module(void)
+static void __exit atixl_cleanup (void)
 {
+	release_region(ATIXL_MSE_DATA_PORT, 3);
 	unregister_busmouse(msedev);
 }
-#endif
+
+module_init(atixl_busmouse_init);
+module_exit(atixl_cleanup);
+
diff -u --recursive --new-file v2.3.25/linux/drivers/char/busmouse.c linux/drivers/char/busmouse.c
--- v2.3.25/linux/drivers/char/busmouse.c	Fri Oct 15 15:25:13 1999
+++ linux/drivers/char/busmouse.c	Tue Nov  2 21:38:44 1999
@@ -48,12 +48,6 @@
  */
 /*#define BROKEN_MOUSE*/
 
-extern int adb_mouse_init(void);
-extern int logi_busmouse_init(void);
-extern int ms_bus_mouse_init(void);
-extern int atixl_busmouse_init(void);
-extern int amiga_mouse_init(void);
-extern int atari_mouse_init(void);
 extern int sun_mouse_init(void);
 extern void mouse_rpc_init (void);
 
@@ -435,26 +429,8 @@
 int __init
 bus_mouse_init(void)
 {
-#ifdef CONFIG_LOGIBUSMOUSE
-	logi_busmouse_init();
-#endif
-#ifdef CONFIG_MS_BUSMOUSE
-	ms_bus_mouse_init();
-#endif
-#ifdef CONFIG_ATIXL_BUSMOUSE
- 	atixl_busmouse_init();
-#endif
-#ifdef CONFIG_AMIGAMOUSE
-	amiga_mouse_init();
-#endif
-#ifdef CONFIG_ATARIMOUSE
-	atari_mouse_init();
-#endif
 #ifdef CONFIG_SUN_MOUSE
 	sun_mouse_init();
-#endif
-#ifdef CONFIG_ADBMOUSE
-	adb_mouse_init();
 #endif
 #ifdef CONFIG_RPCMOUSE
 	mouse_rpc_init();
diff -u --recursive --new-file v2.3.25/linux/drivers/char/c-qcam.c linux/drivers/char/c-qcam.c
--- v2.3.25/linux/drivers/char/c-qcam.c	Mon Oct  4 15:49:29 1999
+++ linux/drivers/char/c-qcam.c	Tue Nov  2 21:35:46 1999
@@ -753,33 +753,21 @@
 	NULL
 };
 
-static void cqcam_init(void)
+static int __init cqcam_init (void)
 {
 	printk(BANNER "\n");
-	parport_register_driver(&cqcam_driver);
+	return parport_register_driver(&cqcam_driver);
 }
 
-#ifdef MODULE
-
 MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
 MODULE_DESCRIPTION(BANNER);
 
-int init_module(void)
-{
-	cqcam_init();
-	return 0;
-}
-
-void cleanup_module(void)
+static void __exit cqcam_cleanup (void)
 {
 	unsigned int i;
 	for (i = 0; i < num_cams; i++)
 		close_cqcam(qcams[i]);
 }
-#else
-int __init init_colour_qcams(struct video_init *unused)
-{
-	cqcam_init();
-	return 0;
-}
-#endif
+
+module_init(cqcam_init);
+module_exit(cqcam_cleanup);
diff -u --recursive --new-file v2.3.25/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c
--- v2.3.25/linux/drivers/char/cyclades.c	Mon Oct  4 15:49:29 1999
+++ linux/drivers/char/cyclades.c	Mon Nov  1 15:31:07 1999
@@ -699,6 +699,9 @@
 			(ZFIRM_ID==cy_readl(&((struct FIRM_ID *) \
 			((card).base_addr+ID_ADDRESS))->signature)))
 
+#ifndef SERIAL_XMIT_SIZE
+#define	SERIAL_XMIT_SIZE	(MIN(PAGE_SIZE, 4096))
+#endif
 #define WAKEUP_CHARS (SERIAL_XMIT_SIZE-256)
 
 #define STD_COM_FLAGS (0)
diff -u --recursive --new-file v2.3.25/linux/drivers/char/drm/proc.c linux/drivers/char/drm/proc.c
--- v2.3.25/linux/drivers/char/drm/proc.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/char/drm/proc.c	Tue Nov  2 17:40:11 1999
@@ -382,7 +382,7 @@
 			       vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
 			       vma->vm_flags & VM_LOCKED   ? 'l' : '-',
 			       vma->vm_flags & VM_IO	   ? 'i' : '-',
-			       vma->vm_offset );
+			       vma->vm_pgoff << PAGE_SHIFT );
 #if defined(__i386__)
 		pgprot = pgprot_val(vma->vm_page_prot);
 		DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
diff -u --recursive --new-file v2.3.25/linux/drivers/char/drm/vm.c linux/drivers/char/drm/vm.c
--- v2.3.25/linux/drivers/char/drm/vm.c	Fri Sep 10 23:57:29 1999
+++ linux/drivers/char/drm/vm.c	Tue Nov  2 17:40:11 1999
@@ -96,7 +96,7 @@
 	if (address > vma->vm_end) return 0; /* Disallow mremap */
 	if (!dma->pagelist)	   return 0; /* Nothing allocated */
 
-	offset	 = address - vma->vm_start; /* vm_offset should be 0 */
+	offset	 = address - vma->vm_start; /* vm_pgoff should be 0 */
 	page	 = offset >> PAGE_SHIFT;
 	physical = dma->pagelist[page] + (offset & (~PAGE_MASK));
 	atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */
@@ -168,8 +168,8 @@
 	drm_device_dma_t *dma	 = dev->dma;
 	unsigned long	 length	 = vma->vm_end - vma->vm_start;
 	
-	DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
-		  vma->vm_start, vma->vm_end, vma->vm_offset);
+	DRM_DEBUG("start = 0x%lx, end = 0x%lx, pgoff = 0x%lx\n",
+		  vma->vm_start, vma->vm_end, vma->vm_pgoff);
 
 				/* Length must match exact page count */
 	if ((length >> PAGE_SHIFT) != dma->page_count) return -EINVAL;
@@ -192,13 +192,17 @@
 	drm_file_t	*priv	= filp->private_data;
 	drm_device_t	*dev	= priv->dev;
 	drm_map_t	*map	= NULL;
+	unsigned long	off;
 	int		i;
 	
 	DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
-		  vma->vm_start, vma->vm_end, vma->vm_offset);
+		  vma->vm_start, vma->vm_end, vma->vm_pgoff);
 
-	if (!vma->vm_offset) return drm_mmap_dma(filp, vma);
+	if (!vma->vm_pgoff) return drm_mmap_dma(filp, vma);
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))	/* overflow? */
+		return -EINVAL;
 
+	off = vma->vm_pgoff << PAGE_SHIFT;
 				/* A sequential search of a linked list is
 				   fine here because: 1) there will only be
 				   about 5-10 entries in the list and, 2) a
@@ -208,7 +212,7 @@
 				   bit longer. */
 	for (i = 0; i < dev->map_count; i++) {
 		map = dev->maplist[i];
-		if (map->offset == vma->vm_offset) break;
+		if (map->offset == off) break;
 	}
 	
 	if (i >= dev->map_count) return -EINVAL;
@@ -222,7 +226,7 @@
 	switch (map->type) {
 	case _DRM_FRAME_BUFFER:
 	case _DRM_REGISTERS:
-		if (vma->vm_offset >= __pa(high_memory)) {
+		if (off >= __pa(high_memory)) {
 #if defined(__i386__)
 			if (boot_cpu_data.x86 > 3) {
 				pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
@@ -232,7 +236,7 @@
 			vma->vm_flags |= VM_IO;	/* not in core dump */
 		}
 		if (remap_page_range(vma->vm_start,
-				     vma->vm_offset,
+				     off,
 				     vma->vm_end - vma->vm_start,
 				     vma->vm_page_prot))
 				return -EAGAIN;
diff -u --recursive --new-file v2.3.25/linux/drivers/char/ftape/Config.in linux/drivers/char/ftape/Config.in
--- v2.3.25/linux/drivers/char/ftape/Config.in	Mon Oct 11 15:38:14 1999
+++ linux/drivers/char/ftape/Config.in	Wed Nov  3 14:43:54 1999
@@ -5,7 +5,7 @@
 if [ "$CONFIG_ZFTAPE" != "n" ]; then
    int '  Default block size' CONFIG_ZFT_DFLT_BLK_SZ 10240
    comment '  The compressor will be built as a module only!'
-   define_bool CONFIG_ZFT_COMPRESSOR m
+   define_tristate CONFIG_ZFT_COMPRESSOR m
 fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
    int '  Number of ftape buffers (EXPERIMENTAL)' CONFIG_FT_NR_BUFFERS 3
diff -u --recursive --new-file v2.3.25/linux/drivers/char/ftape/lowlevel/ftape-ctl.c linux/drivers/char/ftape/lowlevel/ftape-ctl.c
--- v2.3.25/linux/drivers/char/ftape/lowlevel/ftape-ctl.c	Fri Jan 23 17:38:04 1998
+++ linux/drivers/char/ftape/lowlevel/ftape-ctl.c	Wed Nov  3 11:41:29 1999
@@ -704,8 +704,8 @@
 	if ((vma_get_flags(vma) & (VM_READ|VM_WRITE)) == 0) {
 		TRACE_ABORT(-EINVAL, ft_t_err, "Undefined mmap() access");
 	}
-	if (vma_get_offset (vma) != 0) {
-		TRACE_ABORT(-EINVAL, ft_t_err, "offset must be 0");
+	if (vma_get_pgoff(vma) != 0) {
+		TRACE_ABORT(-EINVAL, ft_t_err, "page offset must be 0");
 	}
 	if ((vma_get_end (vma) - vma_get_start (vma)) % FT_BUFF_SIZE != 0) {
 		TRACE_ABORT(-EINVAL, ft_t_err,
diff -u --recursive --new-file v2.3.25/linux/drivers/char/ip2/ip2.h linux/drivers/char/ip2/ip2.h
--- v2.3.25/linux/drivers/char/ip2/ip2.h	Thu Aug 26 13:05:35 1999
+++ linux/drivers/char/ip2/ip2.h	Sat Nov  6 10:38:40 1999
@@ -70,8 +70,7 @@
  * console warning.
  
  * When the driver is loaded as a module these setting can be overridden on the 
- * modprobe command line or on an option line in /etc/conf.modules 
- * or /etc/modules.conf depending on your distrubution.
+ * modprobe command line or on an option line in /etc/modules.conf.
  * If the driver is built-in the configuration must be 
  * set here for ISA cards and address set to 1 and 2 for PCI and EISA.
  *
@@ -92,8 +91,8 @@
 
  /* this structure is zeroed out because the suggested method is to configure
   * the driver as a module, set up the parameters with an options line in
-  * /etc/modules.conf or /etc/conf.modules and load with modprobe, kerneld or
-  * kmod, the kernel module loader
+  * /etc/modules.conf and load with modprobe, kerneld or kmod, the kernel
+  * module loader
   */
 static ip2config_t ip2config =
 {
diff -u --recursive --new-file v2.3.25/linux/drivers/char/isicom.c linux/drivers/char/isicom.c
--- v2.3.25/linux/drivers/char/isicom.c	Tue Aug 31 17:29:13 1999
+++ linux/drivers/char/isicom.c	Sat Nov  6 10:38:40 1999
@@ -25,7 +25,7 @@
  *	You can find the original tools for this direct from Multitech
  *		ftp://ftp.multitech.com/ISI-Cards/
  *
- *	Having installed the cards the module options (/etc/conf.modules)
+ *	Having installed the cards the module options (/etc/modules.conf)
  *
  *	options isicom   io=card1,card2,card3,card4 irq=card1,card2,card3,card4
  *
diff -u --recursive --new-file v2.3.25/linux/drivers/char/joystick/joy-amiga.c linux/drivers/char/joystick/joy-amiga.c
--- v2.3.25/linux/drivers/char/joystick/joy-amiga.c	Tue Dec  1 19:05:05 1998
+++ linux/drivers/char/joystick/joy-amiga.c	Fri Nov  5 10:01:50 1999
@@ -25,7 +25,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
@@ -39,7 +39,7 @@
 
 static struct js_port* js_am_port __initdata = NULL;
 
-MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_PARM(js_am, "1-2i");
 
 static int js_am[]={0,0};
diff -u --recursive --new-file v2.3.25/linux/drivers/char/joystick/joy-analog.c linux/drivers/char/joystick/joy-analog.c
--- v2.3.25/linux/drivers/char/joystick/joy-analog.c	Tue Dec  1 19:05:05 1998
+++ linux/drivers/char/joystick/joy-analog.c	Fri Nov  5 10:01:50 1999
@@ -25,7 +25,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
@@ -43,7 +43,7 @@
 static int js_an_port_list[] __initdata = {0x201, 0};
 static struct js_port* js_an_port __initdata = NULL;
 
-MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_PARM(js_an, "2-24i");
 
 static int js_an[]={-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0};
diff -u --recursive --new-file v2.3.25/linux/drivers/char/joystick/joy-analog.h linux/drivers/char/joystick/joy-analog.h
--- v2.3.25/linux/drivers/char/joystick/joy-analog.h	Thu Oct  8 17:25:16 1998
+++ linux/drivers/char/joystick/joy-analog.h	Fri Nov  5 10:01:50 1999
@@ -26,7 +26,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
@@ -238,7 +238,7 @@
 				break;
 			default:
 				printk(KERN_WARNING "joy-analog: Unknown joystick device detected "
-					"(data=%#x), contact <vojtech@ucw.cz>\n", exist);
+					"(data=%#x), contact <vojtech@suse.cz>\n", exist);
 				return -1;
 		}
 	}
diff -u --recursive --new-file v2.3.25/linux/drivers/char/joystick/joy-assasin.c linux/drivers/char/joystick/joy-assasin.c
--- v2.3.25/linux/drivers/char/joystick/joy-assasin.c	Tue Dec  1 19:05:05 1998
+++ linux/drivers/char/joystick/joy-assasin.c	Fri Nov  5 10:01:50 1999
@@ -25,7 +25,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
@@ -49,7 +49,7 @@
 #define JS_AS_MODE_OEM		3	/* Panther OEM version */
 #define JS_AS_MODE_PXL		4	/* Panther XL */
 
-MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_PARM(js_as, "2-24i");
 
 static int js_as[]={-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0};
@@ -319,7 +319,7 @@
 		info = port->info;
 	} else {
 		printk(KERN_WARNING "joy-assasin: unknown joystick device detected "
-			"(io=%#x, id=%d), contact <vojtech@ucw.cz>\n", io, data[0]);
+			"(io=%#x, id=%d), contact <vojtech@suse.cz>\n", io, data[0]);
 		return port;
 	}
 
diff -u --recursive --new-file v2.3.25/linux/drivers/char/joystick/joy-gravis.c linux/drivers/char/joystick/joy-gravis.c
--- v2.3.25/linux/drivers/char/joystick/joy-gravis.c	Tue Dec  1 19:05:05 1998
+++ linux/drivers/char/joystick/joy-gravis.c	Fri Nov  5 10:01:50 1999
@@ -25,7 +25,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
diff -u --recursive --new-file v2.3.25/linux/drivers/char/joystick/joy-lightning.c linux/drivers/char/joystick/joy-lightning.c
--- v2.3.25/linux/drivers/char/joystick/joy-lightning.c	Tue Dec  1 19:05:05 1998
+++ linux/drivers/char/joystick/joy-lightning.c	Fri Nov  5 10:01:50 1999
@@ -26,7 +26,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
@@ -52,7 +52,7 @@
 
 static struct js_port* __initdata js_l4_port = NULL;
 
-MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_PARM(js_l4, "2-24i");
 
 static int js_l4[]={-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0};
diff -u --recursive --new-file v2.3.25/linux/drivers/char/joystick/joy-logitech.c linux/drivers/char/joystick/joy-logitech.c
--- v2.3.25/linux/drivers/char/joystick/joy-logitech.c	Tue Dec  1 19:05:05 1998
+++ linux/drivers/char/joystick/joy-logitech.c	Fri Nov  5 10:01:50 1999
@@ -25,7 +25,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
@@ -318,7 +318,7 @@
 			return port;
 		default:
 			printk(KERN_WARNING "joy-logitech: unknown joystick device detected "
-				"(io=%#x, count=%d, data=0x%08x%08x), contact <vojtech@ucw.cz>\n",
+				"(io=%#x, count=%d, data=0x%08x%08x), contact <vojtech@suse.cz>\n",
 				io, i, (int)(data >> 32), (int)(data & 0xffffffff));
 			return port;
 	}
diff -u --recursive --new-file v2.3.25/linux/drivers/char/joystick/joy-sidewinder.c linux/drivers/char/joystick/joy-sidewinder.c
--- v2.3.25/linux/drivers/char/joystick/joy-sidewinder.c	Tue Dec  1 19:05:05 1998
+++ linux/drivers/char/joystick/joy-sidewinder.c	Fri Nov  5 10:01:50 1999
@@ -25,7 +25,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
@@ -422,7 +422,7 @@
 			return port;
 		default:
 			printk(KERN_WARNING "joy-sidewinder: unknown joystick device detected "
-				"(io=%#x, count=%d, data=0x%08x%08x), contact <vojtech@ucw.cz>\n",
+				"(io=%#x, count=%d, data=0x%08x%08x), contact <vojtech@suse.cz>\n",
 				io, i, (int)(data >> 32), (int)(data & 0xffffffff));
 			return port;
 	}
diff -u --recursive --new-file v2.3.25/linux/drivers/char/joystick/joy-thrustmaster.c linux/drivers/char/joystick/joy-thrustmaster.c
--- v2.3.25/linux/drivers/char/joystick/joy-thrustmaster.c	Tue Dec  1 19:05:05 1998
+++ linux/drivers/char/joystick/joy-thrustmaster.c	Fri Nov  5 10:01:50 1999
@@ -25,7 +25,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
@@ -278,7 +278,7 @@
 
 	if (info.mode >= JS_TM_MODE_MAX || !names[info.mode]) {
 		printk(KERN_WARNING "joy-thrustmaster: unknown device detected "
-				    "(io=%#x, id=%d), contact <vojtech@ucw.cz>\n",
+				    "(io=%#x, id=%d), contact <vojtech@suse.cz>\n",
 					io, info.mode);
 		return port;
 	}
diff -u --recursive --new-file v2.3.25/linux/drivers/char/joystick/joy-turbografx.c linux/drivers/char/joystick/joy-turbografx.c
--- v2.3.25/linux/drivers/char/joystick/joy-turbografx.c	Tue Dec  1 19:05:05 1998
+++ linux/drivers/char/joystick/joy-turbografx.c	Fri Nov  5 10:01:50 1999
@@ -26,7 +26,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
@@ -41,7 +41,7 @@
 #include <linux/delay.h>
 
 
-MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_PARM(js_tg, "2-8i");
 MODULE_PARM(js_tg_2, "2-8i");
 MODULE_PARM(js_tg_3, "2-8i");
diff -u --recursive --new-file v2.3.25/linux/drivers/char/joystick/joystick.c linux/drivers/char/joystick/joystick.c
--- v2.3.25/linux/drivers/char/joystick/joystick.c	Mon Oct  4 15:49:29 1999
+++ linux/drivers/char/joystick/joystick.c	Fri Nov  5 10:01:50 1999
@@ -26,7 +26,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
@@ -90,7 +90,7 @@
  * Module info.
  */
 
-MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
+MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_SUPPORTED_DEVICE("js");
 
 /*
diff -u --recursive --new-file v2.3.25/linux/drivers/char/logibusmouse.c linux/drivers/char/logibusmouse.c
--- v2.3.25/linux/drivers/char/logibusmouse.c	Tue Aug 31 17:29:13 1999
+++ linux/drivers/char/logibusmouse.c	Tue Nov  2 21:38:44 1999
@@ -40,6 +40,7 @@
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <linux/init.h>
 #include <linux/logibusmouse.h>
 #include <linux/signal.h>
 #include <linux/errno.h>
@@ -49,7 +50,6 @@
 #include <linux/random.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
-#include <linux/init.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -61,16 +61,26 @@
 static int msedev;
 static int mouse_irq = MOUSE_IRQ;
 
-#ifdef MODULE
 MODULE_PARM(mouse_irq, "i");
-#endif
 
-void __init bmouse_setup(char *str, int *ints)
+#ifndef MODULE
+
+static int __init bmouse_setup(char *str)
 {
+	int ints[4];
+
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+
 	if (ints[0] > 0)
 		mouse_irq=ints[1];
+
+	return 1;
 }
 
+__setup("logi_busmouse=", bmouse_setup);
+
+#endif /* !MODULE */
+
 static void mouse_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	char dx, dy;
@@ -118,7 +128,7 @@
 	LOGITECH_BUSMOUSE, "busmouse", open_mouse, close_mouse, 7
 };
 
-int __init logi_busmouse_init(void)
+static int __init logi_busmouse_init(void)
 {
 	if (check_region(LOGIBM_BASE, LOGIBM_EXTENT))
 		return -EIO;
@@ -142,16 +152,11 @@
 	return msedev < 0 ? msedev : 0;
 }
 
-#ifdef MODULE
-
-int init_module(void)
-{
-	return logi_busmouse_init();
-}
-
-void cleanup_module(void)
+static void __exit logi_busmouse_cleanup (void)
 {
 	unregister_busmouse(msedev);
 	release_region(LOGIBM_BASE, LOGIBM_EXTENT);
 }
-#endif
+
+module_init(logi_busmouse_init);
+module_exit(logi_busmouse_cleanup);
diff -u --recursive --new-file v2.3.25/linux/drivers/char/msbusmouse.c linux/drivers/char/msbusmouse.c
--- v2.3.25/linux/drivers/char/msbusmouse.c	Tue Aug 31 17:29:13 1999
+++ linux/drivers/char/msbusmouse.c	Tue Nov  2 21:38:44 1999
@@ -56,16 +56,26 @@
 static int msedev;
 static int mouse_irq = MOUSE_IRQ;
 
-#ifdef MODULE
 MODULE_PARM(mouse_irq, "i");
-#endif
 
-void __init msmouse_setup(char *str, int *ints)
+#ifndef MODULE
+
+static int __init msmouse_setup(char *str)
 {
+        int ints[4];
+
+        str = get_options(str, ARRAY_SIZE(ints), ints);
+
 	if (ints[0] > 0)
 		mouse_irq=ints[1];
+
+	return 1;
 }
 
+__setup("msmouse=",msmouse_setup);
+
+#endif /* !MODULE */
+
 static void ms_mouse_interrupt(int irq, void *dev_id, struct pt_regs * regs)
 {
         char dx, dy;
@@ -117,7 +127,7 @@
 	MICROSOFT_BUSMOUSE, "msbusmouse", open_mouse, release_mouse, 0
 };
 
-int __init ms_bus_mouse_init(void)
+static int __init ms_bus_mouse_init(void)
 {
 	int present = 0;
 	int mse_byte, i;
@@ -151,7 +161,7 @@
 	return msedev < 0 ? msedev : 0;
 }
 
-void ms_bus_mouse_exit(void)
+static void __exit ms_bus_mouse_exit(void)
 {
 	unregister_busmouse(msedev);
 	release_region(MS_MSE_CONTROL_PORT, 0x04);
diff -u --recursive --new-file v2.3.25/linux/drivers/char/saa5249.c linux/drivers/char/saa5249.c
--- v2.3.25/linux/drivers/char/saa5249.c	Mon Oct  4 15:49:29 1999
+++ linux/drivers/char/saa5249.c	Tue Nov  2 21:35:46 1999
@@ -41,21 +41,22 @@
  */
 
 #include <linux/module.h>
-
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
-#include <linux/malloc.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/slab.h>
+#include <linux/init.h>
 #include <stdarg.h>
 #include <linux/i2c.h>
 #include <linux/videotext.h>
 #include <linux/videodev.h>
 
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
 #define VTX_VER_MAJ 1
 #define VTX_VER_MIN 7
 
@@ -661,54 +662,32 @@
 	return -EINVAL;
 }
 
-static long saa5249_read(struct video_device *v, char *buf, unsigned long l, int nb)
-{
-	return -EINVAL;
-}
-
-int init_saa_5249(struct video_init *v)
+static int __init init_saa_5249 (void)
 {
 	printk(KERN_INFO "SAA5249 driver (" IF_NAME " interface) for VideoText version %d.%d\n",
 			VTX_VER_MAJ, VTX_VER_MIN);
-	i2c_register_driver(&i2c_driver_videotext);
+	return i2c_register_driver(&i2c_driver_videotext);
+}
 
-	return 0;
+static void __exit cleanup_saa_5249 (void) 
+{
+	i2c_unregister_driver(&i2c_driver_videotext);
 }
 
-static struct video_device saa_template=
+module_init(init_saa_5249);
+module_exit(cleanup_saa_5249);
+
+static struct video_device saa_template =
 {
 	IF_NAME,
 	VID_TYPE_TELETEXT,	/*| VID_TYPE_TUNER ?? */
 	VID_HARDWARE_SAA5249,
 	saa5249_open,
 	saa5249_release,
-	saa5249_read,
+	NULL,			/* read */
 	saa5249_write,
-	NULL,	/* poll */
+	NULL,			/* poll */
 	saa5249_ioctl,
-	NULL,
-	NULL,
-	NULL,
-	0,
-	0
+	/* the rest are null */
 };
 
-#ifdef MODULE
-
-/*
- *	Routines for loadable modules
- */
-
-int init_module(void) 
-{
-	init_saa_5249(NULL);
-	return 0;
-}
-
-
-void cleanup_module(void) 
-{
-	i2c_unregister_driver(&i2c_driver_videotext);
-}
-
-#endif
diff -u --recursive --new-file v2.3.25/linux/drivers/char/sysrq.c linux/drivers/char/sysrq.c
--- v2.3.25/linux/drivers/char/sysrq.c	Mon Jul 19 23:08:41 1999
+++ linux/drivers/char/sysrq.c	Fri Nov  5 11:42:56 1999
@@ -24,15 +24,14 @@
 
 #include <asm/ptrace.h>
 
-#ifdef CONFIG_APM
-#include <linux/apm_bios.h>
-#endif
-
 extern void wakeup_bdflush(int);
 extern void reset_vc(unsigned int);
 extern int console_loglevel;
 extern struct vfsmount *vfsmntlist;
 
+/* Machine specific power off function */
+void (*sysrq_power_off)(void) = NULL;
+
 /* Send a signal to all user processes */
 
 static void send_sig_all(int sig, int even_init)
@@ -82,12 +81,12 @@
 		printk("Resetting\n");
 		machine_restart(NULL);
 		break;
-#ifdef CONFIG_APM
 	case 'o':					    /* O -- power off */
-		printk("Power off\n");
-		apm_power_off();
+		if (sysrq_power_off) {
+			printk("Power off\n");
+			sysrq_power_off();
+		}
 		break;
-#endif
 	case 's':					    /* S -- emergency sync */
 		printk("Emergency Sync\n");
 		emergency_sync_scheduled = EMERG_SYNC;
@@ -137,11 +136,10 @@
 		if (tty)
 			printk("saK ");
 #endif
-		printk("Boot "
-#ifdef CONFIG_APM
-		       "Off "
-#endif
-		       "Sync Unmount showPc showTasks showMem loglevel0-8 tErm kIll killalL\n");
+		printk("Boot ");
+		if (sysrq_power_off)
+			printk("Off ");
+		printk("Sync Unmount showPc showTasks showMem loglevel0-8 tErm kIll killalL\n");
 		/* Don't use 'A' as it's handled specially on the Sparc */
 	}
 
diff -u --recursive --new-file v2.3.25/linux/drivers/char/tuner.c linux/drivers/char/tuner.c
--- v2.3.25/linux/drivers/char/tuner.c	Mon Oct  4 15:49:29 1999
+++ linux/drivers/char/tuner.c	Tue Nov  2 08:09:01 1999
@@ -40,6 +40,8 @@
 	int type;            /* chip type */
 	int freq;            /* keep track of the current settings */
 	int radio;
+
+	int mode;            /* PAL(0)/SECAM(1) mode (PHILIPS_SECAM only) */
 };
 
 /* ---------------------------------------------------------------------- */
@@ -58,6 +60,11 @@
 	unsigned char config; 
 	unsigned char I2C;
 	unsigned short IFPCoff;
+
+	unsigned char mode; /* mode change value (tested PHILIPS_SECAM only) */
+			/* 0x01 -> ??? no change ??? */
+			/* 0x02 -> PAL BDGHI / SECAM L */
+			/* 0x04 -> ??? PAL others / SECAM others ??? */
 };
 
 /*
@@ -73,7 +80,7 @@
 	{"Philips NTSC", Philips, NTSC,
 	        16*157.25,16*451.25,0xA0,0x90,0x30,0x8e,0xc0,732},
 	{"Philips SECAM", Philips, SECAM,
-	        16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,0xc0,623},
+	        16*168.25,16*447.25,0xA7,0x97,0x37,0x8e,0xc0,623,0x02},
 	{"NoTuner", NoTuner, NOTUNER,
 	         0        ,0        ,0x00,0x00,0x00,0x00,0x00,000},
 	{"Philips PAL", Philips, PAL,
@@ -100,6 +107,7 @@
 
 #define TUNER_POR       0x80
 #define TUNER_FL        0x40
+#define TUNER_MODE      0x38
 #define TUNER_AFC       0x07
 
 static int tuner_islocked (struct tuner *t)
@@ -112,7 +120,6 @@
         return (tuner_getstatus (t) & TUNER_AFC) - 2;
 }
 
-
 static void set_tv_freq(struct tuner *t, int freq)
 {
 	u8 config;
@@ -133,15 +140,43 @@
 	else
 		config = tun->UHF;
 
+	if (t->type == TUNER_PHILIPS_SECAM && t->mode)
+		config |= tun->mode;
+	else
+		config &= ~tun->mode;
+
 	div=freq + tun->IFPCoff;
   	div&=0x7fff;
 
 	LOCK_I2C_BUS(t->bus);
-	if (i2c_write(t->bus, t->addr, (div>>8)&0x7f, div&0xff, 1)<0) {
-	    printk("tuner: i2c i/o error #1\n");
+	if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) {
+	    /*
+	     * Philips FI1216MK2 remark from specification :
+	     * for channel selection involving band switching, and to ensure
+	     * smooth tuning to the desired channel without causing
+	     * unnecessary charge pump action, it is recommended to consider
+	     * the difference between wanted channel frequency and the
+	     * current channel frequency.  Unnecessary charge pump action
+	     * will result in very low tuning voltage which may drive the
+	     * oscillator to extreme conditions.
+	     */
+	    /*
+	     * Progfou: specification says to send config data before
+	     * frequency in case (wanted frequency < current frequency).
+	     */
+	    if (i2c_write(t->bus, t->addr, tun->config, config, 1)) {
+		printk("tuner: i2c i/o error #1\n");
+	    } else {
+		if (i2c_write(t->bus, t->addr, (div>>8)&0x7f, div&0xff, 1)<0)
+		    printk("tuner: i2c i/o error #2\n");
+	    }
 	} else {
-	    if (i2c_write(t->bus, t->addr, tun->config, config, 1))
-		printk("tuner: i2c i/o error #2\n");
+	    if (i2c_write(t->bus, t->addr, (div>>8)&0x7f, div&0xff, 1)<0) {
+		printk("tuner: i2c i/o error #1\n");
+	    } else {
+		if (i2c_write(t->bus, t->addr, tun->config, config, 1))
+		    printk("tuner: i2c i/o error #2\n");
+	    }
 	}
 	UNLOCK_I2C_BUS(t->bus);
 }
@@ -258,6 +293,16 @@
 			t->freq = *iarg;
 			break;
 	    
+		case TUNER_SET_MODE:
+			if (t->type != TUNER_PHILIPS_SECAM) {
+				dprintk("tuner: trying to change mode for other than TUNER_PHILIPS_SECAM\n");
+			} else {
+				dprintk("tuner: mode set to %d\n", *iarg);
+				t->mode = *iarg;
+				set_tv_freq(t,t->freq);
+			}
+			break;
+
 		default:
 			return -EINVAL;
 	}
diff -u --recursive --new-file v2.3.25/linux/drivers/char/tuner.h linux/drivers/char/tuner.h
--- v2.3.25/linux/drivers/char/tuner.h	Mon Jun  7 16:17:59 1999
+++ linux/drivers/char/tuner.h	Tue Nov  2 08:09:01 1999
@@ -47,5 +47,6 @@
 #define TUNER_SET_TYPE               _IOW('t',1,int)    /* set tuner type */
 #define TUNER_SET_TVFREQ             _IOW('t',2,int)    /* set tv freq */
 #define TUNER_SET_RADIOFREQ          _IOW('t',3,int)    /* set radio freq */
+#define TUNER_SET_MODE               _IOW('t',4,int)    /* set tuner mode */
 
 #endif
diff -u --recursive --new-file v2.3.25/linux/drivers/char/videodev.c linux/drivers/char/videodev.c
--- v2.3.25/linux/drivers/char/videodev.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/char/videodev.c	Tue Nov  2 21:35:46 1999
@@ -45,12 +45,6 @@
 extern int init_bttv_cards(struct video_init *);
 extern int i2c_tuner_init(struct video_init *);
 #endif
-#ifdef CONFIG_VIDEO_SAA5249
-extern int init_saa_5249(struct video_init *);
-#endif	
-#ifdef CONFIG_VIDEO_CQCAM
-extern int init_colour_qcams(struct video_init *);
-#endif
 #ifdef CONFIG_VIDEO_BWQCAM
 extern int init_bw_qcams(struct video_init *);
 #endif
@@ -65,12 +59,6 @@
 #ifdef CONFIG_VIDEO_BT848
 	{"i2c-tuner", i2c_tuner_init},
 	{"bttv", init_bttv_cards},
-#endif	
-#ifdef CONFIG_VIDEO_SAA5249
-	{"saa5249", init_saa_5249},
-#endif	
-#ifdef CONFIG_VIDEO_CQCAM
-	{"c-qcam", init_colour_qcams},
 #endif	
 #ifdef CONFIG_VIDEO_BWQCAM
 	{"bw-qcam", init_bw_qcams},
diff -u --recursive --new-file v2.3.25/linux/drivers/fc4/Config.in linux/drivers/fc4/Config.in
--- v2.3.25/linux/drivers/fc4/Config.in	Mon Oct 11 15:38:14 1999
+++ linux/drivers/fc4/Config.in	Wed Nov  3 14:43:54 1999
@@ -19,9 +19,9 @@
       dep_tristate 'Generic FC-AL disk driver' CONFIG_SCSI_FCAL $CONFIG_SCSI
    fi
 else
-   define_bool CONFIG_FC4_SOC n
-   define_bool CONFIG_FC4_SOCAL n
-   define_bool CONFIG_SCSI_PLUTO n
-   define_bool CONFIG_SCSI_FCAL n
+   define_tristate CONFIG_FC4_SOC n
+   define_tristate CONFIG_FC4_SOCAL n
+   define_tristate CONFIG_SCSI_PLUTO n
+   define_tristate CONFIG_SCSI_FCAL n
 fi
 endmenu
diff -u --recursive --new-file v2.3.25/linux/drivers/i2o/i2o_block.c linux/drivers/i2o/i2o_block.c
--- v2.3.25/linux/drivers/i2o/i2o_block.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/i2o/i2o_block.c	Tue Nov  2 17:07:08 1999
@@ -162,27 +162,27 @@
 	int count = req->nr_sectors<<9;
 
 	/* Map the message to a virtual address */
-	msg = bus_to_virt(c->mem_offset + m);
+	msg = c->mem_offset + m;
 	
 	/*
          * Build the message based on the request.
 	 */
-	msg[2] = i2ob_context|(unit<<8);
-	msg[3] = ireq->num;
-	msg[5] = req->nr_sectors << 9;
+	__raw_writel(i2ob_context|(unit<<8), &msg[2]);
+	__raw_writel(ireq->num, &msg[3]);
+	__raw_writel(req->nr_sectors << 9, &msg[5]);
 	
 	/* This can be optimised later - just want to be sure its right for
 	   starters */
 	offset = ((u64)(req->sector+base)) << 9;
-	msg[6] = offset & 0xFFFFFFFF;
-	msg[7] = (offset>>32);
+	__raw_writel( offset & 0xFFFFFFFF, &msg[6]);
+	__raw_writel(offset>>32, &msg[7]);
 	mptr=msg+8;
 	
 	if(req->cmd == READ)
 	{
-		msg[1] = I2O_CMD_BLOCK_READ<<24|HOST_TID<<12|tid;
+		__raw_writel(I2O_CMD_BLOCK_READ<<24|HOST_TID<<12|tid, &msg[1]);
 		/* We don't yet do cache/readahead and other magic */
-		msg[4] = 1<<16;	
+		__raw_writel(1<<16, &msg[4]);
 		while(bh!=NULL)
 		{
 			/*
@@ -191,31 +191,31 @@
 			 *	sucky to read.
 			 */
 			if(bh->b_reqnext)
-				*mptr++ = 0x10000000|(bh->b_size);
+				__raw_writel(0x10000000|(bh->b_size), mptr++);
 			else
-				*mptr++ = 0xD0000000|(bh->b_size);
+				__raw_writel(0xD0000000|(bh->b_size), mptr++);
 	
-			*mptr++ = virt_to_bus(bh->b_data);
+			__raw_writel(virt_to_bus(bh->b_data), mptr++);
 			count -= bh->b_size;
 			bh = bh->b_reqnext;
 		}
 	}
 	else if(req->cmd == WRITE)
 	{
-		msg[1] = I2O_CMD_BLOCK_WRITE<<24|HOST_TID<<12|tid;
-		msg[4] = 1<<16;
+		__raw_writel(I2O_CMD_BLOCK_WRITE<<24|HOST_TID<<12|tid, &msg[1]);
+		__raw_writel(1<<16, &msg[4]);
 		while(bh!=NULL)
 		{
 			if(bh->b_reqnext)
-				*mptr++ = 0x14000000|(bh->b_size);
+				__raw_writel(0x14000000|(bh->b_size), mptr++);
 			else
-				*mptr++ = 0xD4000000|(bh->b_size);
+				__raw_writel(0xD4000000|(bh->b_size), mptr++);
 			count -= bh->b_size;
-			*mptr++ = virt_to_bus(bh->b_data);
+			__raw_writel(virt_to_bus(bh->b_data), mptr++);
 			bh = bh->b_reqnext;
 		}
 	}
-	msg[0] = I2O_MESSAGE_SIZE(mptr-msg) | SGL_OFFSET_8;
+	__raw_writel(I2O_MESSAGE_SIZE(mptr-msg) | SGL_OFFSET_8, &msg[0]);
 	
 	if(req->current_nr_sectors > 8)
 		printk("Gathered sectors %ld.\n", 
diff -u --recursive --new-file v2.3.25/linux/drivers/i2o/i2o_core.c linux/drivers/i2o/i2o_core.c
--- v2.3.25/linux/drivers/i2o/i2o_core.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/i2o/i2o_core.c	Tue Nov  2 17:07:08 1999
@@ -714,15 +714,15 @@
 		return -ENOMEM;
 	}
 
-	msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_5;
-	msg[1]=I2O_CMD_UTIL_PARAMS_GET<<24|HOST_TID<<12|tid;
-	msg[2]=0;			/* Context */
-	msg[3]=0;
-	msg[4]=0;
-	msg[5]=0x54000000|12;
-	msg[6]=virt_to_bus(op);
-	msg[7]=0xD0000000|(32+buflen);
-	msg[8]=virt_to_bus(rbuf);
+	__raw_writel(NINE_WORD_MSG_SIZE|SGL_OFFSET_5, &msg[0]);
+	__raw_writel(I2O_CMD_UTIL_PARAMS_GET<<24|HOST_TID<<12|tid, &msg[1]);
+	__raw_writel(0, &msg[2]);			/* Context */
+	__raw_writel(0, &msg[3]);
+	__raw_writel(0, &msg[4]);
+	__raw_writel(0x54000000|12, &msg[5]);
+	__raw_writel(virt_to_bus(op), &msg[6]);
+	__raw_writel(0xD0000000|(32+buflen), &msg[7]);
+	__raw_writel(virt_to_bus(rbuf), &msg[8]);
 
 	i2o_post_message(c,m);
 	barrier();
@@ -738,7 +738,7 @@
 		kfree(rbuf);
 		return -ETIMEDOUT;
 	}
-	 
+
 	msg = (u32 *)bus_to_virt(m);
 	if(msg[4]>>24)
 	{
@@ -830,7 +830,7 @@
 static int i2o_parse_hrt(struct i2o_controller *c)
 {
 #ifdef DRIVERDEBUG
-	u32 *rows=c->hrt;
+	u32 *rows=(u32*)c->hrt;
 	u8 *p=(u8 *)c->hrt;
 	u8 *d;
 	int count;
@@ -1391,7 +1391,12 @@
 			I2O_REPLY_WRITE32(iop,virt_to_phys(msg));
 			i2o_quiesce_controller(iop);
 			i2o_reset_controller(iop);
-			i2o_status_get(iop);
+			if(i2o_status_get(iop) || 
+				iop->status_block->iop_state != ADAPTER_STATE_RESET)
+			{
+				printk(KERN_CRIT "Failed to initialize iop%d\n", iop->unit);
+				i2o_delete_controller(iop);
+			}
 		}
 	}
 
@@ -1413,7 +1418,8 @@
 
 		if(iop->page_frame==NULL)
 		{
-			printk(KERN_ERR "IOP init failed: no memory for message page.\n");
+			printk(KERN_CRIT "iop%d init failed: no memory for message page.\n", 
+						iop->unit);
 			i2o_delete_controller(iop);
 			continue;
 		}
@@ -1436,23 +1442,40 @@
 	{
 		if(i2o_hrt_get(iop))
 		{
+			printk(KERN_CRIT "iop%d: Could not get HRT!\n", iop->unit);
 			i2o_delete_controller(iop);
 			break;
 		}
 		if(i2o_parse_hrt(iop))
+		{
+			printk(KERN_CRIT "iop%d: Could not parse HRT!\n", iop->unit);
 			i2o_delete_controller(iop);
+		}
 	}
 
 	/*
 	 * Build and send the system table
-	 */
-	i2o_build_sys_table();
+	 *
+	 * If build_sys_table fails, we kill everything and bail
+	 * as we can't init the IOPs w/o a system table
+	 */	
+	if(i2o_build_sys_table())
+	{
+		printk(KERN_CRIT "I2O: Error building system table. Aborting!\n");
+		i2o_sys_shutdown();
+		return;
+	}
+
 	for(iop = i2o_controller_chain; iop; iop = iop->next)
 #ifdef DRIVERDEBUG
 	{
 		printk(KERN_INFO "Sending system table to iop%d\n", iop->unit);
 #endif
-		i2o_systab_send(iop);
+		if(i2o_systab_send(iop))
+		{
+			printk(KERN_CRIT "iop%d: Error sending system table\n", iop->unit);
+			i2o_delete_controller(iop);
+		}
 #ifdef DRIVERDEBUG
 	}
 #endif
@@ -1503,7 +1526,10 @@
 
 	i2o_quiesce_system();
 	for(iop = i2o_controller_chain; iop; iop = iop->next)
-		i2o_delete_controller(iop);
+	{
+		if(i2o_delete_controller(iop))
+			iop->bus_disable(iop);
+	}
 }
 
 /*
@@ -1701,7 +1727,6 @@
 	msg[5] = 0x00000000;	/* Report now */
 	msg[6] = 0xD0000000|8192;
 	msg[7] = virt_to_bus(c->lct);
-
 	
 	return(i2o_post_wait(c, msg, sizeof(msg), 120));
 }
@@ -1741,21 +1766,21 @@
 	privio[0]=c->priv_io;		/* Private I/O address */
 	privio[1]=c->priv_io_size;
 
-	msg[0] = NINE_WORD_MSG_SIZE|SGL_OFFSET_6;
-	msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID;
-	msg[2] = 0;	/* Context not needed */
-	msg[3] = 0;
-	msg[4] = (0<<16)|(2<<12);	/* Host 1 I2O 2 */
-	msg[5] = 0;			/* Segment 1 */
+	__raw_writel(NINE_WORD_MSG_SIZE|SGL_OFFSET_6, &msg[0]);
+	__raw_writel(I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]);
+	__raw_writel(0, &msg[2]);		/* Context not needed */
+	__raw_writel(0, &msg[3]);
+	__raw_writel((0<<16)|(2<<12), &msg[4]);	/* Host 1 I2O 2 */
+	__raw_writel(0, &msg[5]);		/* Segment 1 */
 	
 	/*
 	 *	Scatter Gather List
 	 */
-	msg[6] = 0x54000000|sys_tbl_len;	/* One table for now */
-	msg[7] = virt_to_phys(sys_tbl);
-	msg[8] = 0xD4000000|48;	/* One table for now */
-	msg[9] = virt_to_phys(privmem);
-/*	msg[10] = virt_to_phys(privio); */
+	
+	__raw_writel(0x54000000|sys_tbl_len, &msg[6]);	/* One table for now */
+	__raw_writel(virt_to_phys(sys_tbl), &msg[[7]);
+	__raw_writel(0xD4000000|48, &msg[8]);	/* One table for now */
+	__raw_writel(virt_to_phys(privmem), &msg[9]);
 
 	return(i2o_post_wait(c, msg, sizeof(msg), 120));
 	
@@ -1877,8 +1902,8 @@
 					c->unit);
 		return -ETIMEDOUT;
 	}
-	msg = bus_to_virt(c->mem_offset + m);
- 	memcpy(msg, data, len);
+	msg = (u32 *)(c->mem_offset + m);
+ 	memcpy_toio(msg, data, len);
 	i2o_post_message(c,m);
 	return 0;
 }
@@ -2028,7 +2053,7 @@
 int i2o_issue_params(int cmd, struct i2o_controller *iop, int tid, 
                 void *opblk, int oplen, void *resblk, int reslen)
 {
-u32 msg[9]; 
+	u32 msg[9]; 
 	u8 *res = (u8 *)resblk;
 	int res_count;
 	int blk_size;
diff -u --recursive --new-file v2.3.25/linux/drivers/i2o/i2o_pci.c linux/drivers/i2o/i2o_pci.c
--- v2.3.25/linux/drivers/i2o/i2o_pci.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/i2o/i2o_pci.c	Tue Nov  2 17:07:08 1999
@@ -5,11 +5,11 @@
  *	(C) Copyright 1999   Red Hat Software
  *	
  *	Written by Alan Cox, Building Number Three Ltd
- * Modified by Deepak Saxena <deepak@plexity.net>
+ *	Modified by Deepak Saxena <deepak@plexity.net>
  *
  *	This program is free software; you can redistribute it and/or
  *	modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
+ *	as published by the Free Software Foundation; either version
  *	2 of the License, or (at your option) any later version.
  *
  *	TODO:
@@ -80,11 +80,13 @@
 static void i2o_pci_enable(struct i2o_controller *c)
 {
 	I2O_IRQ_WRITE32(c, 0);
+	c->enabled = 1;
 }
 
 static void i2o_pci_disable(struct i2o_controller *c)
 {
 	I2O_IRQ_WRITE32(c, 0xFFFFFFFF);
+	c->enabled = 0;
 }
 
 /*
@@ -216,6 +218,7 @@
 
 	printk(KERN_INFO "Installed iop%d at IRQ%d\n", c->unit, dev->irq);
 	I2O_IRQ_WRITE32(c,0x0);
+	c->enabled = 1;
 	return 0;	
 }
 
diff -u --recursive --new-file v2.3.25/linux/drivers/i2o/i2o_scsi.c linux/drivers/i2o/i2o_scsi.c
--- v2.3.25/linux/drivers/i2o/i2o_scsi.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/i2o/i2o_scsi.c	Tue Nov  2 17:07:08 1999
@@ -587,7 +587,7 @@
 		m = I2O_POST_READ32(c);
 	}
 	while(m==0xFFFFFFFF);
-	msg = bus_to_virt(c->mem_offset + m);
+	msg = c->mem_offset + m;
 	
 	/*
 	 *	Put together a scsi execscb message
@@ -614,10 +614,10 @@
 		}
 	}
 	
-	msg[1] = I2O_CMD_SCSI_EXEC<<24|HOST_TID<<12|tid;
-	msg[2] = scsi_context;		/* So the I2O layer passes to us */
+	__raw_writel(I2O_CMD_SCSI_EXEC<<24|HOST_TID<<12|tid, &msg[1]);
+	__raw_writel(scsi_context, &msg[2]);	/* So the I2O layer passes to us */
 	/* Sorry 64bit folks. FIXME */
-	msg[3] = (u32)SCpnt;		/* We want the SCSI control block back */
+	__raw_writel((u32)SCpnt, &msg[3]);	/* We want the SCSI control block back */
 
 	/* LSI_920_PCI_QUIRK
 	 *
@@ -660,7 +660,7 @@
 	}
 
 	/* Direction, disconnect ok, tag, CDBLen */
-	msg[4] = scsidir|0x20000000|SCpnt->cmd_len|tag;
+	__raw_writel(scsidir|0x20000000|SCpnt->cmd_len|tag, &msg[4]);
 
 	mptr=msg+5;
 
@@ -668,11 +668,12 @@
 	 *	Write SCSI command into the message - always 16 byte block 
 	 */
 	 
-	memcpy(mptr, SCpnt->cmnd, 16);
+	memcpy_toio(mptr, SCpnt->cmnd, 16);
 	mptr+=4;
 	lenptr=mptr++;		/* Remember me - fill in when we know */
 	
 	reqlen = 12;		// SINGLE SGE
+	
 	/*
 	 *	Now fill in the SGList and command 
 	 *
@@ -686,14 +687,16 @@
 		struct scatterlist *sg = (struct scatterlist *)SCpnt->request_buffer;
 		int chain = 0;
 		
+		len = 0;
+
 		if((sg_max_frags > 11) && (SCpnt->use_sg > 11))
 		{
 			chain = 1;
 			/*
 			 *	Need to chain!
 			 */
-			*mptr++=direction|0xB0000000|(SCpnt->use_sg*2*4);
-			*mptr=virt_to_bus(sg_chain_pool + sg_chain_tag);
+			__raw_writel(direction|0xB0000000|(SCpnt->use_sg*2*4), mptr++);
+			__raw_writel(virt_to_bus(sg_chain_pool + sg_chain_tag), mptr);
 			mptr = (u32*)(sg_chain_pool + sg_chain_tag);
 			if (SCpnt->use_sg > max_sg_len)
 			{
@@ -703,27 +706,36 @@
 			}
 			if ( ++sg_chain_tag == SG_MAX_BUFS )
 				sg_chain_tag = 0;
+			for(i = 0 ; i < SCpnt->use_sg; i++)
+			{
+				*mptr++=direction|0x10000000|sg->length;
+				len+=sg->length;
+				*mptr++=virt_to_bus(sg->address);
+				sg++;
+			}
+			mptr[-2]=direction|0xD0000000|(sg-1)->length;
 		}
-		
-		len = 0;
-		
-		for(i = 0 ; i < SCpnt->use_sg; i++)
-		{
-			*mptr++=direction|0x10000000|sg->length;
-			len+=sg->length;
-			*mptr++=virt_to_bus(sg->address);
-			sg++;
-		}
+		else
+		{		
+			for(i = 0 ; i < SCpnt->use_sg; i++)
+			{
+				__raw_writel(direction|0x10000000|sg->length, mptr++);
+				len+=sg->length;
+				__raw_writel(virt_to_bus(sg->address), mptr++);
+				sg++;
+			}
 
-		/* Make this an end of list. Again evade the 920 bug and
-		   unwanted PCI read traffic */
+			/* Make this an end of list. Again evade the 920 bug and
+			   unwanted PCI read traffic */
 		
-		mptr[-2]=direction|0xD0000000|(sg-1)->length;
+			__raw_writel(direction|0xD0000000|(sg-1)->length, &mptr[-2]);
+		}
 		
 		if(!chain)
 			reqlen = mptr - msg;
 		
-		*lenptr=len;
+		__raw_writel(len, lenptr);
+		
 		if(len != SCpnt->underflow)
 			printk("Cmd len %08X Cmd underflow %08X\n",
 				len, SCpnt->underflow);
@@ -732,15 +744,15 @@
 	{
 		dprintk(("non sg for %p, %d\n", SCpnt->request_buffer,
 				SCpnt->request_bufflen));
-		*lenptr = len = SCpnt->request_bufflen;
+		__raw_writel(len = SCpnt->request_bufflen, lenptr);
 		if(len == 0)
 		{
 			reqlen = 9;
 		}
 		else
 		{
-			*mptr++=0xD0000000|direction|SCpnt->request_bufflen;
-			*mptr++=virt_to_bus(SCpnt->request_buffer);
+			__raw_writel(0xD0000000|direction|SCpnt->request_bufflen, mptr++);
+			__raw_writel(virt_to_bus(SCpnt->request_buffer), mptr++);
 		}
 	}
 	
@@ -748,7 +760,7 @@
 	 *	Stick the headers on 
 	 */
 
-	msg[0] = reqlen<<16 | SGL_OFFSET_10;
+	__raw_writel(reqlen<<16 | SGL_OFFSET_10, msg);
 	
 	/* Queue the message */
 	i2o_post_message(c,m);
@@ -815,11 +827,11 @@
 	while(m==0xFFFFFFFF);
 	msg = bus_to_virt(c->mem_offset + m);
 	
-	msg[0] = FIVE_WORD_MSG_SIZE;
-	msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|tid;
-	msg[2] = scsi_context;
-	msg[3] = 0;	/* Not needed for an abort */
-	msg[4] = (u32)SCpnt;	
+	__raw_writel(FIVE_WORD_MSG_SIZE, &msg[0]);
+	__raw_writel(I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|tid, &msg[1]);
+	__raw_writel(scsi_context, &msg[2]);
+	__raw_writel(0, &msg[3]);	/* Not needed for an abort */
+	__raw_writel((u32)SCpnt, &msg[4]);	
 	wmb();
 	i2o_post_message(c,m);
 	wmb();
@@ -862,12 +874,12 @@
 		return SCSI_RESET_PUNT;
 	
 	msg = bus_to_virt(c->mem_offset + m);
-	msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
-	msg[1] = I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid;
-	msg[2] = scsi_context|0x80000000;	
+	__raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]);
+	__raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, &msg[1]);
+	__raw_writel(scsi_context|0x80000000, &msg[2]);
 	/* We use the top bit to split controller and unit transactions */
 	/* Now store unit,tid so we can tie the completion back to a specific device */
-	msg[3] = c->unit << 16 | tid;
+	__raw_writel(c->unit << 16 | tid, &msg[3]);
 	i2o_post_message(c,m);
 	return SCSI_RESET_PENDING;
 }
diff -u --recursive --new-file v2.3.25/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c
--- v2.3.25/linux/drivers/net/arcnet.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/net/arcnet.c	Fri Nov  5 10:01:50 1999
@@ -61,7 +61,7 @@
    - Added support for promiscuous mode.
 
    v2.60 ALPHA (96/11/23)
-   - Added patch from Vojtech Pavlik <vojtech@atrey.karlin.mff.cuni.cz>
+   - Added patch from Vojtech Pavlik <vojtech@suse.cz>
    and Martin Mares <mj@k332.feld.cvut.cz> to make the driver work
    with the new Linux 2.1.x memory management.  I modified their
    patch quite a bit though; bugs are my fault.  More changes should
@@ -89,7 +89,7 @@
 
    v2.50 (96/02/24)
    - Massively improved autoprobe routines; they now work even as a
-   module.  Thanks to Vojtech Pavlik <Vojtech.Pavlik@st.mff.cuni.cz>
+   module.  Thanks to Vojtech Pavlik <vojtech@suse.cz>
    for his ideas and help in this area.
    - Changed printk's around quite a lot.
 
diff -u --recursive --new-file v2.3.25/linux/drivers/net/com90xx.c linux/drivers/net/com90xx.c
--- v2.3.25/linux/drivers/net/com90xx.c	Wed Aug 18 11:36:41 1999
+++ linux/drivers/net/com90xx.c	Wed Nov  3 10:13:44 1999
@@ -93,7 +93,7 @@
 #endif
 int arc90xx_probe(struct net_device *dev);
 static void arc90xx_rx(struct net_device *dev, int recbuf);
-static int arc90xx_found(struct net_device *dev, int ioaddr, int airq, u_long shmem, int more);
+static int arc90xx_found(struct net_device *dev, int ioaddr, int airq, void * shmem, int more);
 static void arc90xx_inthandler(struct net_device *dev);
 static int arc90xx_reset(struct net_device *dev, int reset_delay);
 static void arc90xx_setmask(struct net_device *dev, u_char mask);
@@ -175,7 +175,7 @@
 static int ports[(0x3f0 - 0x200) / 16 + 1] __initdata = {
 	0
 };
-static u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] __initdata = {
+static void * shmems[(0xFF800 - 0xA0000) / 2048 + 1] __initdata = {
 	0
 };
 
@@ -187,13 +187,13 @@
 	 openparen = 0;
 	unsigned long airqmask;
 	int *port;
-	u_long *shmem;
+	void **shmem;
 
 	if (!init_once) {
 		for (count = 0x200; count <= 0x3f0; count += 16)
 			ports[(count - 0x200) / 16] = count;
 		for (count = 0xA0000; count <= 0xFF800; count += 2048)
-			shmems[(count - 0xA0000) / 2048] = count;
+			shmems[(count - 0xA0000) / 2048] = ioremap(count, 2048);
 		BUGLVL(D_NORMAL) printk(version);
 		BUGMSG(D_DURING, "space used for probe buffers: %d+%d=%d bytes\n",
 		       sizeof(ports), sizeof(shmems),
@@ -211,7 +211,7 @@
 		return -ENXIO;
 
 	if (dev->mem_start) {
-		shmems[0] = dev->mem_start;
+		shmems[0] = ioremap(dev->mem_start, 2048);
 		numshmems = 1;
 	}
 	/* Stage 1: abandon any reserved ports, or ones with status==0xFF
@@ -284,7 +284,7 @@
 	BUGMSG(D_INIT, "Stage 3: ");
 	numprint = 0;
 	for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
-		u_long ptr;
+		void * ptr;
 
 		numprint++;
 		if (numprint > 8) {
@@ -292,9 +292,9 @@
 			BUGMSG(D_INIT, "Stage 3: ");
 			numprint = 1;
 		}
-		BUGMSG2(D_INIT, "%lXh ", *shmem);
+		BUGMSG2(D_INIT, "%ph ", *shmem);
 
-		ptr = (u_long) (*shmem);
+		ptr = *shmem;
 
 		if (readb(ptr) != TESTvalue) {
 			BUGMSG2(D_INIT_REASONS, "(mem=%02Xh, not %02Xh)\n",
@@ -342,7 +342,7 @@
 			BUGMSG(D_INIT, "Stage 4: ");
 			numprint = 1;
 		}
-		BUGMSG2(D_INIT, "%lXh ", *shmem);
+		BUGMSG2(D_INIT, "%ph ", *shmem);
 	}
 	BUGMSG2(D_INIT, "\n");
 
@@ -439,12 +439,12 @@
 #endif
 
 		for (shmem = &shmems[0]; shmem - shmems < numshmems; shmem++) {
-			u_long ptr;
-			ptr = (u_long) (*shmem);
+			void * ptr;
+			ptr = *shmem;
 
 			if (readb(ptr) == TESTvalue) {	/* found one */
 				int probe_more;
-				BUGMSG2(D_INIT, "%lXh)\n", *shmem);
+				BUGMSG2(D_INIT, "%ph)\n", *shmem);
 				openparen = 0;
 
 				/* register the card */
@@ -493,10 +493,10 @@
 /* Set up the struct net_device associated with this card.  Called after
  * probing succeeds.
  */
-static int __init arc90xx_found(struct net_device *dev, int ioaddr, int airq, u_long shmem, int more)
+static int __init arc90xx_found(struct net_device *dev, int ioaddr, int airq, void * shmem, int more)
 {
 	struct arcnet_local *lp;
-	u_long first_mirror, last_mirror;
+	void *first_mirror, *last_mirror;
 	int mirror_size;
 
 	/* reserve the irq */
@@ -533,8 +533,8 @@
 		last_mirror += mirror_size;
 	last_mirror -= mirror_size;
 
-	dev->mem_start = first_mirror;
-	dev->mem_end = last_mirror + MIRROR_SIZE - 1;
+	dev->mem_start = (unsigned long) first_mirror;
+	dev->mem_end = (unsigned long) last_mirror + MIRROR_SIZE - 1;
 	dev->rmem_start = dev->mem_start + BUFFER_SIZE * 0;
 	dev->rmem_end = dev->mem_start + BUFFER_SIZE * 2 - 1;
 
diff -u --recursive --new-file v2.3.25/linux/drivers/net/irda/Config.in linux/drivers/net/irda/Config.in
--- v2.3.25/linux/drivers/net/irda/Config.in	Mon Oct  4 15:49:29 1999
+++ linux/drivers/net/irda/Config.in	Tue Nov  2 17:07:08 1999
@@ -8,7 +8,6 @@
 comment 'FIR device drivers'
 dep_tristate 'NSC PC87108' CONFIG_NSC_FIR  $CONFIG_IRDA
 dep_tristate 'Winbond W83977AF (IR)' CONFIG_WINBOND_FIR $CONFIG_IRDA
-dep_tristate 'Sharp UIRCC' CONFIG_SHARP_FIR $CONFIG_IRDA
 dep_tristate 'Toshiba Type-O IR Port' CONFIG_TOSHIBA_FIR $CONFIG_IRDA
 dep_tristate 'SMC IrCC' CONFIG_SMC_IRCC_FIR $CONFIG_IRDA
 
diff -u --recursive --new-file v2.3.25/linux/drivers/net/irda/Makefile linux/drivers/net/irda/Makefile
--- v2.3.25/linux/drivers/net/irda/Makefile	Tue Aug 31 17:29:14 1999
+++ linux/drivers/net/irda/Makefile	Tue Nov  2 17:07:08 1999
@@ -60,14 +60,6 @@
   endif
 endif
 
-ifeq ($(CONFIG_SHARP_FIR),y)
-L_OBJS += uircc.o irport.o
-else
-  ifeq ($(CONFIG_SHARP_FIR),m)
-  M_OBJS += uircc.o irport.o
-  endif
-endif
-
 ifeq ($(CONFIG_TOSHIBA_FIR),y)
 L_OBJS += toshoboe.o
 else
diff -u --recursive --new-file v2.3.25/linux/drivers/net/irda/airport.c linux/drivers/net/irda/airport.c
--- v2.3.25/linux/drivers/net/irda/airport.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/net/irda/airport.c	Tue Nov  2 17:07:08 1999
@@ -7,8 +7,7 @@
  * Status:        Experimental.
  * Author:        Fons Botman <budely@tref.nl>
  * Created at:    Wed May 19 23:14:34 CEST 1999
- * Based on:      actisys.c
- * By:            Dag Brattli <dagb@cs.uit.no>
+ * Based on:      actisys.c by Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Fons Botman, All Rights Reserved.
  *      
@@ -32,26 +31,21 @@
 #include <net/irda/irda.h>
 #include <net/irda/irmod.h>
 #include <net/irda/irda_device.h>
-#include <net/irda/dongle.h>
 
-
-static void airport_reset(struct irda_device *dev);
-static void airport_open(struct irda_device *idev, int type);
-static void airport_close(struct irda_device *dev);
-static void airport_change_speed( struct irda_device *dev, __u32 speed);
-static void airport_init_qos(struct irda_device *idev, struct qos_info *qos);
-
-
-static struct dongle dongle = {
-	AIRPORT_DONGLE,
+static int  airport_reset_wrapper(struct irda_task *task);
+static void airport_open(dongle_t *self, struct qos_info *qos);
+static void airport_close(dongle_t *self);
+static int  airport_change_speed_wrapper(struct irda_task *task);
+
+static struct dongle_reg dongle = {
+	Q_NULL,
+	IRDA_AIRPORT_DONGLE,
 	airport_open,
 	airport_close,
-	airport_reset,
-	airport_change_speed,
-	airport_init_qos,
+	airport_reset_wrapper,
+	airport_change_speed_wrapper,
 };
 
-
 int __init airport_init(void)
 {
 	int ret;
@@ -69,57 +63,54 @@
 	irda_device_unregister_dongle(&dongle);
 }
 
-static void airport_open(struct irda_device *idev, int type)
+static void airport_open(dongle_t *self, struct qos_info *qos)
 {
-	IRDA_DEBUG(2, __FUNCTION__ "(,%d)\n", type);
-	if (strlen(idev->description) < sizeof(idev->description) - 13)
-	  strcat(idev->description, " <-> airport");
-	else
-	  IRDA_DEBUG(0, __FUNCTION__ " description too long: %s\n", 
-		idev->description);
-
-        idev->io.dongle_id = type;
-	idev->flags |= IFF_DONGLE;
+	qos->baud_rate.bits &= 
+		IR_2400|IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+	/* May need 1ms */
+	qos->min_turn_time.bits &= 0x07;
 
 	MOD_INC_USE_COUNT;
 }
 
-static void airport_close(struct irda_device *idev)
+static void airport_close(dongle_t *self)
 {
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 	/* Power off dongle */
-	irda_device_set_dtr_rts(idev, FALSE, FALSE);
+	self->set_dtr_rts(self->dev, FALSE, FALSE);
 
 	MOD_DEC_USE_COUNT;
 }
 
-static void airport_set_command_mode(struct irda_device *idev)
+static void airport_set_command_mode(dongle_t *self)
 {
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
-	irda_device_set_dtr_rts(idev, FALSE, TRUE);
+	self->set_dtr_rts(self->dev, FALSE, TRUE);
 }
 
-static void airport_set_normal_mode(struct irda_device *idev)
+static void airport_set_normal_mode(dongle_t *self)
 {
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
-    	irda_device_set_dtr_rts(idev, TRUE, TRUE);
+    	self->set_dtr_rts(self->dev, TRUE, TRUE);
 }
 
-
-void airport_write_char(struct irda_device *idev, unsigned char c)
+void airport_write_char(dongle_t *self, unsigned char c)
 {
 	int actual;
 	IRDA_DEBUG(2, __FUNCTION__ "(,0x%x)\n", c & 0xff);
-	actual = idev->raw_write(idev, &c, 1);
+	actual = self->write(self->dev, &c, 1);
 	ASSERT(actual == 1, return;);
 }
 
 #define JIFFIES_TO_MSECS(j) ((j)*1000/HZ)
 
-static int airport_waitfor_char(struct irda_device *idev, unsigned char c)
+static int airport_waitfor_char(dongle_t *self, unsigned char c)
 {
+	__u8 buf[100];
 	int i, found = FALSE;
 	int before;
+	int len;
+
 	IRDA_DEBUG(2, __FUNCTION__ "(,0x%x)\n", c);
 
 	/* Sleep approx. 10 ms */
@@ -129,17 +120,18 @@
 	IRDA_DEBUG(4, __FUNCTION__ " waited %ldms\n", 
 	      JIFFIES_TO_MSECS(jiffies - before));
 
-	for ( i = 0 ; !found && i < idev->rx_buff.len ; i++ ) {
+	len = self->read(self->dev, buf, 100);
+
+	for (i = 0; !found && i < len; i++ ) {
 		/* IRDA_DEBUG(6, __FUNCTION__ " 0x02x\n", idev->rx_buff.data[i]); */
-		found = c == idev->rx_buff.data[i];
+		found = c == buf[i];
 	}
-	idev->rx_buff.len = 0;
 
 	IRDA_DEBUG(2, __FUNCTION__ " returns %s\n", (found ? "true" : "false"));
 	return found;
 }
 
-static int airport_check_command_mode(struct irda_device *idev)
+static int airport_check_command_mode(dongle_t *self)
 {
 	int i;
 	int found = FALSE;
@@ -147,13 +139,13 @@
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 	current->state = TASK_INTERRUPTIBLE;
 	schedule_timeout(MSECS_TO_JIFFIES(20));
-	airport_set_command_mode(idev);
+	airport_set_command_mode(self);
 
 	/* Loop until the time expires (200ms) or we get the magic char. */
 
 	for ( i = 0 ; i < 25 ; i++ ) {
-	  	airport_write_char(idev, 0xff);
-		if (airport_waitfor_char(idev, 0xc3)) {
+	  	airport_write_char(self, 0xff);
+		if (airport_waitfor_char(self, 0xc3)) {
 			found = TRUE;
 			break;
 		}
@@ -167,29 +159,28 @@
 	return found;
 }
 
-
-static int airport_write_register(struct irda_device *idev, unsigned char reg)
+static int airport_write_register(dongle_t *self, unsigned char reg)
 {
 	int ok = FALSE;
 	int i;
 
 	IRDA_DEBUG(4, __FUNCTION__ "(,0x%x)\n", reg);
-	airport_check_command_mode(idev);
+	airport_check_command_mode(self);
 
 	for ( i = 0 ; i < 6 ; i++ ) {
-		airport_write_char(idev, reg);
-		if (!airport_waitfor_char(idev, reg)) 
+		airport_write_char(self, reg);
+		if (!airport_waitfor_char(self, reg)) 
 			continue;
 
 		/* Now read it back */
-		airport_write_char(idev, (reg << 4) | 0x0f);
-		if (airport_waitfor_char(idev, reg)) {
+		airport_write_char(self, (reg << 4) | 0x0f);
+		if (airport_waitfor_char(self, reg)) {
 			ok = TRUE;
 			break;
 		}
 	}
 
-	airport_set_normal_mode(idev);
+	airport_set_normal_mode(self);
 	if (ok) {
 		IRDA_DEBUG(4, __FUNCTION__ "(,0x%x) returns OK\n", reg);
 	} else {
@@ -200,19 +191,18 @@
 
 
 /*
- * Function airport_change_speed (tty, baud)
+ * Function airport_change_speed (self, speed)
  *
  *    Change speed of the Airport type IrDA dongles.
  */
-static void airport_change_speed(struct irda_device *idev, __u32 speed)
+static void airport_change_speed(dongle_t *self, __u32 speed)
 {
         __u32 current_baudrate;
         int baudcode;
 	
 	IRDA_DEBUG(4, __FUNCTION__ "(,%d)\n", speed);
 
-	ASSERT(idev != NULL, return;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+	ASSERT(self != NULL, return;);
 	
 	/* Find the correct baudrate code for the required baudrate */
 	switch (speed) {
@@ -228,23 +218,14 @@
 		return;
 	}
 
-	current_baudrate = idev->qos.baud_rate.value;
+	current_baudrate = self->speed;
 	IRDA_DEBUG(4, __FUNCTION__ " current baudrate: %d\n", current_baudrate);
 
-	/* The dongle falls back to 9600 baud */
-	if (current_baudrate != 9600) {
-		IRDA_DEBUG(4, __FUNCTION__ " resetting speed to 9600 baud\n");
-		ASSERT(idev->change_speed , return;);
-		idev->change_speed(idev, 9600);
-		idev->qos.baud_rate.value = 9600;
-	}
-
-	if (idev->set_raw_mode)
-		idev->set_raw_mode(idev, TRUE);
+	self->set_mode(self->dev, IRDA_RAW);
 
 	/* Set the new speed in both registers */
-	if (airport_write_register(idev, baudcode)) {
-		if (airport_write_register(idev, baudcode|0x01)) {
+	if (airport_write_register(self, baudcode)) {
+		if (airport_write_register(self, baudcode|0x01)) {
 			/* ok */
 		} else {
 			IRDA_DEBUG(0, __FUNCTION__ 
@@ -255,35 +236,43 @@
 		      " Cannot set new speed in first register\n");
 	}
 	
-	if (idev->set_raw_mode)
-		idev->set_raw_mode(idev, FALSE);
+	self->set_mode(self->dev, IRDA_IRLAP);
 
 	/* How do I signal an error in these functions? */
 
 	IRDA_DEBUG(4, __FUNCTION__ " returning\n");
 }
 
+int airport_change_speed_wrapper(struct irda_task *task)
+{
+	dongle_t *self = (dongle_t *) task->instance;
+	__u32 speed = (__u32) task->param;
+
+	irda_execute_as_process(self, (TODO_CALLBACK) airport_change_speed, 
+				speed);
+
+	irda_task_next_state(task, IRDA_TASK_DONE);
+	
+	return 0;
+}
 
 /*
- * Function airport_reset (idev)
+ * Function airport_reset (self)
  *
  *      Reset the Airport type dongle. Warning, this function must only be
  *      called with a process context!
  *
  */
-static void airport_reset(struct irda_device *idev)
+static void airport_reset(dongle_t *self)
 {
 	int ok;
 
 	IRDA_DEBUG(2, __FUNCTION__ "()\n");
-	ASSERT(idev != NULL, return;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
-	ASSERT(idev->set_raw_mode /* The airport needs this */, return;);
+	ASSERT(self != NULL, return;);
 
-	if (idev->set_raw_mode)
-		idev->set_raw_mode(idev, TRUE);
+	self->set_mode(self->dev, IRDA_RAW);
 
-	airport_set_normal_mode(idev);
+	airport_set_normal_mode(self);
 
 	/* Sleep 2000 ms */
 	IRDA_DEBUG(2, __FUNCTION__ " waiting for powerup\n");
@@ -295,53 +284,48 @@
 	ok = TRUE;
 
 	if (ok)
-		ok = airport_write_register(idev, 0x30);
+		ok = airport_write_register(self, 0x30);
 	if (!ok)
 		MESSAGE(__FUNCTION__ "() dongle not connected?\n");
 	if (ok)
-		ok = airport_write_register(idev, 0x31);
+		ok = airport_write_register(self, 0x31);
 
 	if (ok)
-		ok = airport_write_register(idev, 0x02);
+		ok = airport_write_register(self, 0x02);
 	if (ok)
-		ok = airport_write_register(idev, 0x03);
+		ok = airport_write_register(self, 0x03);
 
 	if (ok) {
-		ok = airport_check_command_mode(idev);
+		ok = airport_check_command_mode(self);
 
 		if (ok) {
-			airport_write_char(idev, 0x04);
-			ok = airport_waitfor_char(idev, 0x04);
+			airport_write_char(self, 0x04);
+			ok = airport_waitfor_char(self, 0x04);
 		}
-		airport_set_normal_mode(idev);
+		airport_set_normal_mode(self);
 	}
 		
-	if (idev->set_raw_mode)
-		idev->set_raw_mode(idev, FALSE);
+	self->set_mode(self->dev, IRDA_IRLAP);
 	
-
 	current->state = TASK_INTERRUPTIBLE;
 	schedule_timeout(MSECS_TO_JIFFIES(20));
 	IRDA_DEBUG(4, __FUNCTION__ " waited 20ms\n");
 
-	idev->qos.baud_rate.value = 9600;
+	self->speed = 9600;
 	if (!ok)
 		MESSAGE(__FUNCTION__ "() failed.\n");
 	IRDA_DEBUG(2, __FUNCTION__ " returning.\n");
 }
 
-/*
- * Function airport_init_qos (qos)
- *
- *    Initialize QoS capabilities
- *
- */
-static void airport_init_qos(struct irda_device *idev, struct qos_info *qos)
+int airport_reset_wrapper(struct irda_task *task)
 {
-	qos->baud_rate.bits &= 
-		IR_2400|IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
-	/* May need 1ms */
-	qos->min_turn_time.bits &= 0x07;
+	dongle_t *self = (dongle_t *) task->instance;
+
+	irda_execute_as_process(self, (TODO_CALLBACK) airport_reset, 0);
+
+	irda_task_next_state(task, IRDA_TASK_DONE);
+	
+	return 0;
 }
 
 #ifdef MODULE
diff -u --recursive --new-file v2.3.25/linux/drivers/net/irda/girbil.c linux/drivers/net/irda/girbil.c
--- v2.3.25/linux/drivers/net/irda/girbil.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/net/irda/girbil.c	Tue Nov  2 17:07:08 1999
@@ -1,12 +1,12 @@
 /*********************************************************************
  *                
  * Filename:      girbil.c
- * Version:       1.1
+ * Version:       1.2
  * Description:   Implementation for the Greenwich GIrBIL dongle
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Feb  6 21:02:33 1999
- * Modified at:   Mon Oct 18 22:15:20 1999
+ * Modified at:   Sat Oct 30 20:25:22 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -103,8 +103,7 @@
 /*
  * Function girbil_change_speed (dev, speed)
  *
- *    Set the speed for the Girbil type dongle. Warning, this 
- *    function must be called with a process context!
+ *    Set the speed for the Girbil type dongle.
  *
  */
 static int girbil_change_speed(struct irda_task *task)
@@ -186,8 +185,7 @@
 /*
  * Function girbil_reset (driver)
  *
- *      This function resets the girbil dongle. Warning, this function 
- *      must be called with a process context!! 
+ *      This function resets the girbil dongle.
  *
  *      Algorithm:
  *    	  0. set RTS, and wait at least 5 ms 
diff -u --recursive --new-file v2.3.25/linux/drivers/net/irda/irport.c linux/drivers/net/irda/irport.c
--- v2.3.25/linux/drivers/net/irda/irport.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/net/irda/irport.c	Tue Nov  2 17:07:08 1999
@@ -6,7 +6,7 @@
  * Status:	  Experimental.
  * Author:	  Dag Brattli <dagb@cs.uit.no>
  * Created at:	  Sun Aug  3 13:49:59 1997
- * Modified at:   Wed Oct 20 00:07:42 1999
+ * Modified at:   Sat Oct 30 20:03:42 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:	  serial.c by Linus Torvalds 
  * 
@@ -83,9 +83,12 @@
 static int  irport_net_init(struct net_device *dev);
 static int  irport_net_open(struct net_device *dev);
 static int  irport_net_close(struct net_device *dev);
+static int  irport_net_ioctl(struct net_device *dev, struct ifreq *rq, 
+			     int cmd);
 static int  irport_is_receiving(struct irport_cb *self);
-static void irport_set_dtr_rts(struct net_device *dev, int dtr, int rts);
+static int  irport_set_dtr_rts(struct net_device *dev, int dtr, int rts);
 static int  irport_raw_write(struct net_device *dev, __u8 *buf, int len);
+static struct net_device_stats *irport_net_get_stats(struct net_device *dev);
 
 int __init irport_init(void)
 {
@@ -207,8 +210,6 @@
 		ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
 		return -ENOMEM;
 	}
-	/* dev_alloc doesn't clear the struct, so lets do a little hack */
-	memset(((__u8*)dev)+sizeof(char*),0,sizeof(struct net_device)-sizeof(char*));
 
  	dev->priv = (void *) self;
 	self->netdev = dev;
@@ -218,6 +219,8 @@
 	dev->hard_start_xmit = irport_hard_xmit;
 	dev->open            = irport_net_open;
 	dev->stop            = irport_net_close;
+	dev->get_stats	     = irport_net_get_stats;
+	dev->do_ioctl        = irport_net_ioctl;
 
 	/* Make ifconfig display some details */
 	dev->base_addr = iobase;
@@ -253,7 +256,7 @@
 
 	/* Release the IO-port that this driver is using */
 	IRDA_DEBUG(0 , __FUNCTION__ "(), Releasing Region %03x\n", 
-	      self->io.iobase2);
+		   self->io.iobase2);
 	release_region(self->io.iobase2, self->io.io_ext);
 
 	if (self->tx_buff.head)
@@ -319,7 +322,7 @@
  *    Set speed of IrDA port to specified baudrate
  *
  */
-void irport_change_speed(struct irport_cb *self, __u32 speed)
+void __irport_change_speed(struct irport_cb *self, __u32 speed)
 {
 	unsigned long flags;
 	int iobase; 
@@ -371,6 +374,79 @@
 }
 
 /*
+ * Function irport_change_speed (instance, state, param)
+ *
+ *    State machine for changing speed of the device. We do it this way since
+ *    we cannot use schedule_timeout() when we are in interrupt context
+ */
+static int irport_change_speed(struct irda_task *task)
+{
+	struct irport_cb *self;
+	__u32 speed = (__u32) task->param;
+	int ret = 0;
+
+	IRDA_DEBUG(2, __FUNCTION__ "(), <%ld>\n", jiffies); 
+
+	self = (struct irport_cb *) task->instance;
+
+	ASSERT(self != NULL, return -1;);
+
+	switch (task->state) {
+	case IRDA_TASK_INIT:
+	case IRDA_TASK_WAIT:
+		/* Are we ready to change speed yet? */
+		if (self->tx_buff.len > 0) {
+			task->state = IRDA_TASK_WAIT;
+
+			/* Try again later */
+			ret = MSECS_TO_JIFFIES(20);
+			break;
+		}
+
+		if (self->dongle)
+			irda_task_next_state(task, IRDA_TASK_CHILD_INIT);
+		else
+			irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
+		break;
+	case IRDA_TASK_CHILD_INIT:
+		/* Go to default speed */
+		__irport_change_speed(self, 9600);
+
+		/* Change speed of dongle */
+		if (irda_task_execute(self->dongle,
+				      self->dongle->issue->change_speed, 
+				      NULL, task, (void *) speed))
+		{
+			/* Dongle need more time to change its speed */
+			irda_task_next_state(task, IRDA_TASK_CHILD_WAIT);
+
+			/* Give dongle 1 sec to finish */
+			ret = MSECS_TO_JIFFIES(1000);
+		} else
+			/* Child finished immediately */
+			irda_task_next_state(task, IRDA_TASK_CHILD_DONE);
+		break;
+	case IRDA_TASK_CHILD_WAIT:
+		WARNING(__FUNCTION__ 
+			"(), changing speed of dongle timed out!\n");
+		ret = -1;		
+		break;
+	case IRDA_TASK_CHILD_DONE:
+		/* Finally we are ready to change the speed */
+		__irport_change_speed(self, speed);
+		
+		irda_task_next_state(task, IRDA_TASK_DONE);
+		break;
+	default:
+		ERROR(__FUNCTION__ "(), unknown state %d\n", task->state);
+		irda_task_next_state(task, IRDA_TASK_DONE);
+		ret = -1;
+		break;
+	}	
+	return ret;
+}
+
+/*
  * Function irport_write_wakeup (tty)
  *
  *    Called by the driver when there's room for more data.  If we have
@@ -452,6 +528,32 @@
 }
 
 /*
+ * Function irport_change_speed_complete (task)
+ *
+ *    Called when the change speed operation completes
+ *
+ */
+static int irport_change_speed_complete(struct irda_task *task)
+{
+	struct irport_cb *self;
+
+	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+
+	self = (struct irport_cb *) task->instance;
+
+	ASSERT(self != NULL, return -1;);
+	ASSERT(self->netdev != NULL, return -1;);
+
+	/* Finished changing speed, so we are not busy any longer */
+	self->netdev->tbusy = 0;
+
+	/* Signal network layer so it can try to send the frame */
+	mark_bh(NET_BH);
+
+	return 0;
+}
+
+/*
  * Function irport_xmit (void)
  *
  *    Transmits the current frame until FIFO is full, then
@@ -469,7 +571,6 @@
 	ASSERT(dev != NULL, return 0;);
 	
 	self = (struct irport_cb *) dev->priv;
-
 	ASSERT(self != NULL, return 0;);
 
 	iobase = self->io.iobase2;
@@ -482,15 +583,22 @@
 
 		WARNING("%s: transmit timed out\n", dev->name);
 		irport_start(self, iobase);
-		irport_change_speed(self, self->io.speed );
+		__irport_change_speed(self, self->io.speed );
 
 		dev->trans_start = jiffies;
 	}
 
 	/* Check if we need to change the speed */
-	if ((speed = irda_get_speed(skb)) != self->io.speed)
-		irport_change_speed(self, speed);
-
+	if ((speed = irda_get_speed(skb)) != self->io.speed) {
+		if (irda_task_execute(self, irport_change_speed, 
+				      irport_change_speed_complete, NULL,
+				      (void *) speed))	
+			/* 
+			 * Task not finished yet, so make the netdevice 
+			 * layer requeue the frame 
+			 */
+			return -EBUSY;
+	}
 	spin_lock_irqsave(&self->lock, flags);
 
 	/* Init tx buffer */
@@ -533,7 +641,7 @@
          * async_unwrap_char will deliver all found frames  
 	 */
 	do {
-		async_unwrap_char(self->netdev, &self->rx_buff, 
+		async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, 
 				  inb(iobase+UART_RX));
 
 		/* Make sure we don't stay here to long */
@@ -619,8 +727,8 @@
 /*
  * Function irport_net_open (dev)
  *
- *    
- *
+ *    Network device is taken up. Usually this is done by "ifconfig irda0 up" 
+ *   
  */
 static int irport_net_open(struct net_device *dev)
 {
@@ -659,8 +767,8 @@
 /*
  * Function irport_net_close (self)
  *
- *    
- *
+ *    Network device is taken down. Usually this is done by 
+ *    "ifconfig irda0 down" 
  */
 static int irport_net_close(struct net_device *dev)
 {
@@ -733,12 +841,12 @@
  *    This function can be used by dongles etc. to set or reset the status
  *    of the dtr and rts lines
  */
-static void irport_set_dtr_rts(struct net_device *dev, int dtr, int rts)
+static int irport_set_dtr_rts(struct net_device *dev, int dtr, int rts)
 {
 	struct irport_cb *self = dev->priv;
 	int iobase;
 
-	ASSERT(self != NULL, return;);
+	ASSERT(self != NULL, return -1;);
 
 	iobase = self->io.iobase2;
 
@@ -748,6 +856,8 @@
 		rts = UART_MCR_RTS;
 
 	outb(dtr|rts|UART_MCR_OUT2, iobase+UART_MCR);
+
+	return 0;
 }
 
 static int irport_raw_write(struct net_device *dev, __u8 *buf, int len)
@@ -774,6 +884,82 @@
 	}
 
 	return actual;
+}
+
+/*
+ * Function irport_net_ioctl (dev, rq, cmd)
+ *
+ *    Process IOCTL commands for this device
+ *
+ */
+static int irport_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct if_irda_req *irq = (struct if_irda_req *) rq;
+	struct irport_cb *self;
+	dongle_t *dongle;
+	unsigned long flags;
+	int ret = 0;
+
+	ASSERT(dev != NULL, return -1;);
+
+	self = dev->priv;
+
+	ASSERT(self != NULL, return -1;);
+
+	IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
+	
+	/* Disable interrupts & save flags */
+	save_flags(flags);
+	cli();
+	
+	switch (cmd) {
+	case SIOCSBANDWIDTH: /* Set bandwidth */
+		irda_task_execute(self, irport_change_speed, NULL, NULL, 
+				  (void *) irq->ifr_baudrate);
+		break;
+	case SIOCSDONGLE: /* Set dongle */
+		/* Initialize dongle */
+		dongle = irda_device_dongle_init(dev, irq->ifr_dongle);
+		if (!dongle)
+			break;
+		
+		dongle->set_mode    = NULL;
+		dongle->read        = NULL;
+		dongle->write       = irport_raw_write;
+		dongle->set_dtr_rts = irport_set_dtr_rts;
+		
+		self->dongle = dongle;
+
+		/* Now initialize the dongle!  */
+		dongle->issue->open(dongle, &self->qos);
+		
+		/* Reset dongle */
+		irda_task_execute(dongle, dongle->issue->reset, NULL, NULL, 
+				  NULL);	
+		break;
+	case SIOCSMEDIABUSY: /* Set media busy */
+		irda_device_set_media_busy(self->netdev, TRUE);
+		break;
+	case SIOCGRECEIVING: /* Check if we are receiving right now */
+		irq->ifr_receiving = irport_is_receiving(self);
+		break;
+	case SIOCSDTRRTS:
+		irport_set_dtr_rts(dev, irq->ifr_dtr, irq->ifr_rts);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+	}
+	
+	restore_flags(flags);
+	
+	return ret;
+}
+
+static struct net_device_stats *irport_net_get_stats(struct net_device *dev)
+{
+	struct irport_cb *self = (struct irport_cb *) dev->priv;
+	
+	return &self->stats;
 }
 
 #ifdef MODULE
diff -u --recursive --new-file v2.3.25/linux/drivers/net/irda/irtty.c linux/drivers/net/irda/irtty.c
--- v2.3.25/linux/drivers/net/irda/irtty.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/net/irda/irtty.c	Tue Nov  2 17:07:08 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Dec  9 21:18:38 1997
- * Modified at:   Wed Oct 20 00:05:43 1999
+ * Modified at:   Sun Oct 31 22:24:03 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
  *                          Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
@@ -345,8 +345,6 @@
         struct termios old_termios;
 	int cflag;
 
-	IRDA_DEBUG(0, __FUNCTION__ "(), <%ld>\n", jiffies); 
-
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRTTY_MAGIC, return;);
 
@@ -355,7 +353,7 @@
 
 	cflag &= ~CBAUD;
 
-	IRDA_DEBUG(0, __FUNCTION__ "(), Setting speed to %d\n", speed);
+	IRDA_DEBUG(2, __FUNCTION__ "(), Setting speed to %d\n", speed);
 
 	switch (speed) {
 	case 1200:
@@ -562,7 +560,8 @@
 		switch (self->mode) {
 		case IRDA_IRLAP:
 			/* Unwrap and destuff one byte */
-			async_unwrap_char(self->netdev, &self->rx_buff, *cp++);
+			async_unwrap_char(self->netdev, &self->stats, 
+					  &self->rx_buff, *cp++);
 			break;
 		case IRDA_RAW:
 			/* What should we do when the buffer is full? */
@@ -587,7 +586,7 @@
 {
 	struct irtty_cb *self;
 
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	self = (struct irtty_cb *) task->instance;
 
diff -u --recursive --new-file v2.3.25/linux/drivers/net/irda/litelink.c linux/drivers/net/irda/litelink.c
--- v2.3.25/linux/drivers/net/irda/litelink.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/net/irda/litelink.c	Tue Nov  2 17:07:08 1999
@@ -1,12 +1,12 @@
 /*********************************************************************
  *                
  * Filename:      litelink.c
- * Version:       1.0
+ * Version:       1.1
  * Description:   Driver for the Parallax LiteLink dongle
  * Status:        Stable
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Fri May  7 12:50:33 1999
- * Modified at:   Mon Oct 18 12:45:51 1999
+ * Modified at:   Sat Oct 30 20:24:58 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -122,7 +122,6 @@
 		/* Sleep a minimum of 15 us */
 		udelay(MIN_DELAY);
         }
-
 	irda_task_next_state(task, IRDA_TASK_DONE);
 
 	return 0;
@@ -131,8 +130,7 @@
 /*
  * Function litelink_reset (task)
  *
- *      Reset the Litelink type dongle. Warning, this function must only be
- *      called with a process context!
+ *      Reset the Litelink type dongle.
  *
  */
 static int litelink_reset(struct irda_task *task)
@@ -159,6 +157,8 @@
 
 	/* This dongles speed defaults to 115200 bps */
 	self->speed = 115200;
+
+	irda_task_next_state(task, IRDA_TASK_DONE);
 
 	return 0;
 }
diff -u --recursive --new-file v2.3.25/linux/drivers/net/irda/pc87108.c linux/drivers/net/irda/pc87108.c
--- v2.3.25/linux/drivers/net/irda/pc87108.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/net/irda/pc87108.c	Tue Nov  2 17:07:08 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Nov  7 21:43:15 1998
- * Modified at:   Wed Oct 20 00:08:41 1999
+ * Modified at:   Sat Oct 30 16:24:17 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>
@@ -1143,7 +1143,8 @@
 	/*  Receive all characters in Rx FIFO */
 	do {
 		byte = inb(iobase+RXD);
-		async_unwrap_char(self->netdev, &self->rx_buff, byte);
+		async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, 
+				  byte);
 
 	} while (inb(iobase+LSR) & LSR_RXDA); /* Data available */	
 }
diff -u --recursive --new-file v2.3.25/linux/drivers/net/irda/smc-ircc.c linux/drivers/net/irda/smc-ircc.c
--- v2.3.25/linux/drivers/net/irda/smc-ircc.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/net/irda/smc-ircc.c	Tue Nov  2 17:07:08 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Thomas Davis (tadavis@jps.net)
  * Created at:    
- * Modified at:   Wed Sep 22 07:47:19 1999
+ * Modified at:   Sat Oct 30 14:18:23 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Thomas Davis, All Rights Reserved.
@@ -34,6 +34,7 @@
 #include <linux/delay.h>
 #include <linux/malloc.h>
 #include <linux/init.h>
+#include <linux/rtnetlink.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -58,23 +59,23 @@
 static struct ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL};
 
 /* Some prototypes */
-static int  ircc_open( int i, unsigned int iobase, unsigned int board_addr);
+static int  ircc_open(int i, unsigned int iobase, unsigned int board_addr);
 #ifdef MODULE
-static int  ircc_close( struct irda_device *idev);
+static int  ircc_close(struct ircc_cb *self);
 #endif /* MODULE */
-static int  ircc_probe( int iobase, int board_addr);
-static int  ircc_dma_receive( struct irda_device *idev); 
-static int  ircc_dma_receive_complete(struct irda_device *idev, int iobase);
-static int  ircc_hard_xmit( struct sk_buff *skb, struct net_device *dev);
-static void ircc_dma_write( struct irda_device *idev, int iobase);
-static void ircc_change_speed( struct irda_device *idev, __u32 speed);
+static int  ircc_probe(int iobase, int board_addr);
+static int  ircc_dma_receive(struct ircc_cb *self); 
+static int  ircc_dma_receive_complete(struct ircc_cb *self, int iobase);
+static int  ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev);
+static void ircc_dma_write(struct ircc_cb *self, int iobase);
+static void ircc_change_speed(struct ircc_cb *self, __u32 speed);
 static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void ircc_wait_until_sent( struct irda_device *idev);
-static int  ircc_is_receiving( struct irda_device *idev);
+static void ircc_wait_until_sent(struct ircc_cb *self);
+static int  ircc_is_receiving(struct ircc_cb *self);
 
-static int  ircc_net_init( struct net_device *dev);
-static int  ircc_net_open( struct net_device *dev);
-static int  ircc_net_close( struct net_device *dev);
+static int  ircc_net_init(struct net_device *dev);
+static int  ircc_net_open(struct net_device *dev);
+static int  ircc_net_close(struct net_device *dev);
 
 static int ircc_debug=3;
 static int ircc_irq=255;
@@ -107,14 +108,14 @@
 	int i;
 
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
-	for ( i=0; (io[i] < 2000) && (i < 4); i++) {
+	for (i=0; (io[i] < 2000) && (i < 4); i++) {
 		int ioaddr = io[i];
 		if (check_region(ioaddr, CHIP_IO_EXTENT))
 			continue;
-		if (ircc_open( i, io[i], io2[i]) == 0)
+		if (ircc_open(i, io[i], io2[i]) == 0)
 			return 0;
 	}
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 
 	return -ENODEV;
 }
@@ -132,11 +133,11 @@
 
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
 
-	for ( i=0; i < 4; i++) {
-		if ( dev_self[i])
-			ircc_close( &(dev_self[i]->idev));
+	for (i=0; i < 4; i++) {
+		if (dev_self[i])
+			ircc_close(dev_self[i]);
 	}
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 }
 #endif /* MODULE */
 
@@ -146,16 +147,17 @@
  *    Open driver instance
  *
  */
-static int ircc_open( int i, unsigned int iobase, unsigned int iobase2)
+static int ircc_open(int i, unsigned int iobase, unsigned int iobase2)
 {
+        struct net_device *dev;
 	struct ircc_cb *self;
-	struct irda_device *idev;
-	int ret;
 	int config;
+	int ret;
+        int err;
 
-	IRDA_DEBUG( ircc_debug, __FUNCTION__ " -->\n");
+	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
 
-	if ((config = ircc_probe( iobase, iobase2)) == -1) {
+	if ((config = ircc_probe(iobase, iobase2)) == -1) {
 	        IRDA_DEBUG(ircc_debug, 
 		      __FUNCTION__ ": addr 0x%04x - no device found!\n", iobase);
 		return -1;
@@ -164,9 +166,9 @@
 	/*
 	 *  Allocate new instance of the driver
 	 */
-	self = kmalloc( sizeof(struct ircc_cb), GFP_KERNEL);
-	if ( self == NULL) {
-		printk( KERN_ERR "IrDA: Can't allocate memory for "
+	self = kmalloc(sizeof(struct ircc_cb), GFP_KERNEL);
+	if (self == NULL) {
+		printk(KERN_ERR "IrDA: Can't allocate memory for "
 			"IrDA control block!\n");
 		return -ENOMEM;
 	}
@@ -175,110 +177,143 @@
 	/* Need to store self somewhere */
 	dev_self[i] = self;
 
-	idev = &self->idev;
-
 	/* Initialize IO */
-	idev->io.iobase    = iobase;
-        idev->io.iobase2   = iobase2; /* Used by irport */
-        idev->io.irq       = config >> 4 & 0x0f;
+	self->io.iobase    = iobase;
+        self->io.iobase2   = iobase2; /* Used by irport */
+        self->io.irq       = config >> 4 & 0x0f;
 	if (ircc_irq < 255) {
 	        printk(KERN_INFO "smc: Overriding IRQ - chip says %d, using %d\n",
-		      idev->io.irq, ircc_irq);
-		idev->io.irq = ircc_irq;
+		      self->io.irq, ircc_irq);
+		self->io.irq = ircc_irq;
 	}
-        idev->io.io_ext    = CHIP_IO_EXTENT;
-        idev->io.io_ext2   = 8;       /* Used by irport */
-        idev->io.dma       = config & 0x0f;
+        self->io.io_ext    = CHIP_IO_EXTENT;
+        self->io.io_ext2   = 8;       /* Used by irport */
+        self->io.dma       = config & 0x0f;
 	if (ircc_dma < 255) {
 	        printk(KERN_INFO "smc: Overriding DMA - chip says %d, using %d\n",
-		      idev->io.dma, ircc_dma);
-		idev->io.dma = ircc_dma;
+		      self->io.dma, ircc_dma);
+		self->io.dma = ircc_dma;
 	}
-        idev->io.fifo_size = 16;
+        self->io.fifo_size = 16;
 
 	/* Lock the port that we need */
-	ret = check_region( idev->io.iobase, idev->io.io_ext);
-	if ( ret < 0) { 
-		IRDA_DEBUG( 0, __FUNCTION__ ": can't get iobase of 0x%03x\n",
-		       idev->io.iobase);
-		/* ircc_cleanup( self->idev);  */
+	ret = check_region(self->io.iobase, self->io.io_ext);
+	if (ret < 0) { 
+		IRDA_DEBUG(0, __FUNCTION__ ": can't get iobase of 0x%03x\n",
+		       self->io.iobase);
+		/* ircc_cleanup(self->self);  */
 		return -ENODEV;
 	}
-	ret = check_region( idev->io.iobase2, idev->io.io_ext2);
-	if ( ret < 0) { 
-		IRDA_DEBUG( 0, __FUNCTION__ ": can't get iobase of 0x%03x\n",
-		       idev->io.iobase2);
-		/* ircc_cleanup( self->idev);  */
+	ret = check_region(self->io.iobase2, self->io.io_ext2);
+	if (ret < 0) { 
+		IRDA_DEBUG(0, __FUNCTION__ ": can't get iobase of 0x%03x\n",
+		       self->io.iobase2);
+		/* ircc_cleanup(self->self);  */
 		return -ENODEV;
 	}
-	request_region( idev->io.iobase, idev->io.io_ext, idev->name);
-        request_region( idev->io.iobase2, idev->io.io_ext2, idev->name);
+	request_region(self->io.iobase, self->io.io_ext, driver_name);
+        request_region(self->io.iobase2, self->io.io_ext2, driver_name);
 
 	/* Initialize QoS for this device */
-	irda_init_max_qos_capabilies( &idev->qos);
+	irda_init_max_qos_capabilies(&self->qos);
 	
 #if 1
 	/* The only value we must override it the baudrate */
-	idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
+	self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
 		IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);
 #else
 	/* The only value we must override it the baudrate */
-	idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
+	self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
 		IR_115200;
 #endif
 
-	idev->qos.min_turn_time.bits = 0x07;
-	irda_qos_bits_to_value( &idev->qos);
+	self->qos.min_turn_time.bits = 0x07;
+	irda_qos_bits_to_value(&self->qos);
 
-	idev->flags = IFF_FIR|IFF_SIR|IFF_DMA|IFF_PIO;
+	self->flags = IFF_FIR|IFF_SIR|IFF_DMA|IFF_PIO;
 	
-	/* Specify which buffer allocation policy we need */
-	idev->rx_buff.flags = GFP_KERNEL | GFP_DMA;
-	idev->tx_buff.flags = GFP_KERNEL | GFP_DMA;
-
 	/* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
-	idev->rx_buff.truesize = 4000; 
-	idev->tx_buff.truesize = 4000;
+	self->rx_buff.truesize = 4000; 
+	self->tx_buff.truesize = 4000;
+
+	/* Allocate memory if needed */
+	if (self->rx_buff.truesize > 0) {
+		self->rx_buff.head = (__u8 *) kmalloc(self->rx_buff.truesize,
+						      GFP_KERNEL|GFP_DMA);
+		if (self->rx_buff.head == NULL)
+			return -ENOMEM;
+		memset(self->rx_buff.head, 0, self->rx_buff.truesize);
+	}
+	if (self->tx_buff.truesize > 0) {
+		self->tx_buff.head = (__u8 *) kmalloc(self->tx_buff.truesize, 
+						      GFP_KERNEL|GFP_DMA);
+		if (self->tx_buff.head == NULL) {
+			kfree(self->rx_buff.head);
+			return -ENOMEM;
+		}
+		memset(self->tx_buff.head, 0, self->tx_buff.truesize);
+	}
+
+	self->rx_buff.in_frame = FALSE;
+	self->rx_buff.state = OUTSIDE_FRAME;
+	self->tx_buff.data = self->tx_buff.head;
+	self->rx_buff.data = self->rx_buff.head;
+	
+	if (!(dev = dev_alloc("irda%d", &err))) {
+		ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
+		return -ENOMEM;
+	}
+
+	dev->priv = (void *) self;
+	self->netdev = dev;
 	
-	/* Initialize callbacks */
-	idev->change_speed    = ircc_change_speed;
-	idev->wait_until_sent = ircc_wait_until_sent;
-	idev->is_receiving    = ircc_is_receiving;
-     
 	/* Override the network functions we need to use */
-	idev->netdev.init            = ircc_net_init;
-	idev->netdev.hard_start_xmit = ircc_hard_xmit;
-	idev->netdev.open            = ircc_net_open;
-	idev->netdev.stop            = ircc_net_close;
+	dev->init            = ircc_net_init;
+	dev->hard_start_xmit = ircc_hard_xmit;
+	dev->open            = ircc_net_open;
+	dev->stop            = ircc_net_close;
+
+	rtnl_lock();
+	err = register_netdevice(dev);
+	rtnl_unlock();
+	if (err) {
+		ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
+		return -1;
+	}
 
-	irport_start(idev, iobase2);
+	MESSAGE("IrDA: Registered device %s\n", dev->name);
 
-	/* Open the IrDA device */
-	irda_device_open( idev, driver_name, self);
-	
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	irport_start(&self->irport, iobase2);
+
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 	return 0;
 }
 
 /*
- * Function ircc_close (idev)
+ * Function ircc_close (self)
  *
  *    Close driver instance
  *
  */
 #ifdef MODULE
-static int ircc_close( struct irda_device *idev)
+static int ircc_close(struct ircc_cb *self)
 {
 	int iobase;
 
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
 
-	ASSERT( idev != NULL, return -1;);
-	ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+	ASSERT(self != NULL, return -1;);
 
-        iobase = idev->io.iobase;
+        iobase = self->io.iobase;
 
-	irport_stop(idev, idev->io.iobase2);
+	irport_stop(&self->irport, self->io.iobase2);
+
+	/* Remove netdevice */
+	if (self->netdev) {
+		rtnl_lock();
+		unregister_netdev(self->netdev);
+		rtnl_unlock();
+	}
 
 	register_bank(iobase, 0);
 	serial_out(iobase, UART_IER, 0);
@@ -291,20 +326,27 @@
         serial_out(iobase, UART_SCE_CFGB, UART_CFGB_IR);
  
 	/* Release the PORT that this driver is using */
-	IRDA_DEBUG( ircc_debug, 
-	       __FUNCTION__ ": releasing 0x%03x\n", idev->io.iobase);
+	IRDA_DEBUG(ircc_debug, 
+	       __FUNCTION__ ": releasing 0x%03x\n", self->io.iobase);
 
-	release_region( idev->io.iobase, idev->io.io_ext);
+	release_region(self->io.iobase, self->io.io_ext);
 
-	if ( idev->io.iobase2) {
-		IRDA_DEBUG( ircc_debug, __FUNCTION__ ": releasing 0x%03x\n", 
-		       idev->io.iobase2);
-		release_region( idev->io.iobase2, idev->io.io_ext2);
+	if (self->io.iobase2) {
+		IRDA_DEBUG(ircc_debug, __FUNCTION__ ": releasing 0x%03x\n", 
+		       self->io.iobase2);
+		release_region(self->io.iobase2, self->io.io_ext2);
 	}
 
-	irda_device_close( idev);
+	if (self->tx_buff.head)
+		kfree(self->tx_buff.head);
+	
+	if (self->rx_buff.head)
+		kfree(self->rx_buff.head);
+
+	kfree(self);
+
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
 	return 0;
 }
 #endif /* MODULE */
@@ -347,28 +389,25 @@
 }
 
 /*
- * Function ircc_change_speed (idev, baud)
+ * Function ircc_change_speed (self, baud)
  *
  *    Change the speed of the device
  *
  */
-static void ircc_change_speed( struct irda_device *idev, __u32 speed)
+static void ircc_change_speed(struct ircc_cb *self, __u32 speed)
 {
-	struct ircc_cb *self;
 	int iobase, ir_mode, select, fast; 
 
 	IRDA_DEBUG(ircc_debug+1, __FUNCTION__ " -->\n");
 
-	ASSERT(idev != NULL, return;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
+	ASSERT(self != NULL, return;);
 
-	self = idev->priv;
-	iobase = idev->io.iobase;
+	iobase = self->io.iobase;
 
 	/* Update accounting for new speed */
-	idev->io.baudrate = speed;
+	self->io.speed = speed;
 
-	switch ( speed) {
+	switch (speed) {
 	case 9600:
 	case 19200:
 	case 37600:
@@ -381,8 +420,8 @@
 		serial_out(iobase, UART_IER, 0);
 		serial_out(iobase, UART_MASTER, UART_MASTER_RESET);
 		serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN);
-		irport_start(idev, idev->io.iobase2);
-		irport_change_speed( idev, speed);
+		irport_start(&self->irport, self->io.iobase2);
+		irport_change_speed(&self->irport, speed);
 		return;
 		break;
 
@@ -390,7 +429,7 @@
 		ir_mode = UART_CFGA_IRDA_HDLC;
 		select = 0;
 		fast = 0;
-		IRDA_DEBUG( ircc_debug, __FUNCTION__ ": handling baud of 576000\n");
+		IRDA_DEBUG(ircc_debug, __FUNCTION__ ": handling baud of 576000\n");
 		break;
 	case 1152000:
 		ir_mode = UART_CFGA_IRDA_HDLC;
@@ -405,12 +444,12 @@
 		IRDA_DEBUG(ircc_debug, __FUNCTION__ ": handling baud of 4000000\n");
 		break;
 	default:
-		IRDA_DEBUG( 0, __FUNCTION__ ": unknown baud rate of %d\n", speed);
+		IRDA_DEBUG(0, __FUNCTION__ ": unknown baud rate of %d\n", speed);
 		return;
 	}
 
 #if 0
-	serial_out(idev->io.iobase2, 4, 0x08);
+	serial_out(self->io.iobase2, 4, 0x08);
 #endif
 
 	serial_out(iobase, UART_MASTER, UART_MASTER_RESET);
@@ -418,9 +457,9 @@
 	register_bank(iobase, 0);
 	serial_out(iobase, UART_IER, 0);
 	
-       	irport_stop(idev, idev->io.iobase2);
+       	irport_stop(&self->irport, self->io.iobase2);
 
-	idev->netdev.tbusy = 0;
+	self->netdev->tbusy = 0;
 	
 	register_bank(iobase, 1);
 
@@ -443,7 +482,7 @@
 
 	serial_out(iobase, UART_LCR_A, fast);
 
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 }
 
 /*
@@ -452,25 +491,31 @@
  *    Transmit the frame!
  *
  */
-static int ircc_hard_xmit( struct sk_buff *skb, struct net_device *dev)
+static int ircc_hard_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct irda_device *idev;
+	struct ircc_cb *self;
 	int iobase;
 	int mtt;
+	__u32 speed;
 
 	IRDA_DEBUG(ircc_debug+1, __FUNCTION__ " -->\n");
-	idev = (struct irda_device *) dev->priv;
+	self = (struct ircc_cb *) dev->priv;
+
+	ASSERT(self != NULL, return 0;);
 
-	ASSERT( idev != NULL, return 0;);
-	ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+	iobase = self->io.iobase;
 
-	iobase = idev->io.iobase;
+	IRDA_DEBUG(ircc_debug+1, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies,
+		   (int) skb->len);
 
-	IRDA_DEBUG(ircc_debug+1, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len);
+	/* Check if we need to change the speed */
+	if ((speed = irda_get_speed(skb)) != self->io.speed)
+		ircc_change_speed(self, speed);
 
 	/* Use irport for SIR speeds */
-	if (idev->io.baudrate <= 115200) {
-		IRDA_DEBUG(ircc_debug+1, __FUNCTION__ ": calling irport_hard_xmit\n");
+	if (self->io.speed <= 115200) {
+		IRDA_DEBUG(ircc_debug+1, __FUNCTION__ 
+			   ": calling irport_hard_xmit\n");
 		return irport_hard_xmit(skb, dev);
 	}
 	
@@ -480,56 +525,52 @@
 	if (irda_lock((void *) &dev->tbusy) == FALSE)
 		return -EBUSY;
 
-	memcpy( idev->tx_buff.head, skb->data, skb->len);
+	memcpy(self->tx_buff.head, skb->data, skb->len);
 
 	/* Make sure that the length is a multiple of 16 bits */
-	if ( skb->len & 0x01)
+	if (skb->len & 0x01)
 		skb->len++;
 
-	idev->tx_buff.len = skb->len;
-	idev->tx_buff.data = idev->tx_buff.head;
+	self->tx_buff.len = skb->len;
+	self->tx_buff.data = self->tx_buff.head;
 #if 0
-	idev->tx_buff.offset = 0;
+	self->tx_buff.offset = 0;
 #endif
 	
-	mtt = irda_get_mtt( skb);
+	mtt = irda_get_mtt(skb);
 	
 	/* Use udelay for delays less than 50 us. */
 	if (mtt)
-		udelay( mtt);
+		udelay(mtt);
 	
-	ircc_dma_write( idev, iobase);
+	ircc_dma_write(self, iobase);
 	
-	dev_kfree_skb( skb);
+	dev_kfree_skb(skb);
 
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 	return 0;
 }
 
 /*
- * Function ircc_dma_xmit (idev, iobase)
+ * Function ircc_dma_xmit (self, iobase)
  *
  *    Transmit data using DMA
  *
  */
-static void ircc_dma_write( struct irda_device *idev, int iobase)
+static void ircc_dma_write(struct ircc_cb *self, int iobase)
 {
-	struct ircc_cb *self;
-
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
 
-	ASSERT( idev != NULL, return;);
-	ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
+	ASSERT(self != NULL, return;);
 
-	self = idev->priv;
-	iobase = idev->io.iobase;
+	iobase = self->io.iobase;
 
-	setup_dma( idev->io.dma, idev->tx_buff.data, idev->tx_buff.len, 
+	setup_dma(self->io.dma, self->tx_buff.data, self->tx_buff.len, 
 		   DMA_MODE_WRITE);
 	
-	idev->io.direction = IO_XMIT;
+	self->io.direction = IO_XMIT;
 
-	serial_out(idev->io.iobase2, 4, 0x08);
+	serial_out(self->io.iobase2, 4, 0x08);
 
 	register_bank(iobase, 4);
 	serial_out(iobase, UART_CONTROL, 
@@ -538,8 +579,8 @@
 	serial_out(iobase, UART_BOF_COUNT_LO, 2);
 	serial_out(iobase, UART_BRICKWALL_CNT_LO, 0);
 #if 1
-	serial_out(iobase, UART_BRICKWALL_TX_CNT_HI, idev->tx_buff.len >> 8);
-	serial_out(iobase, UART_TX_SIZE_LO, idev->tx_buff.len & 0xff);
+	serial_out(iobase, UART_BRICKWALL_TX_CNT_HI, self->tx_buff.len >> 8);
+	serial_out(iobase, UART_TX_SIZE_LO, self->tx_buff.len & 0xff);
 #else
 	serial_out(iobase, UART_BRICKWALL_TX_CNT_HI, 0);
 	serial_out(iobase, UART_TX_SIZE_LO, 0);
@@ -557,88 +598,80 @@
 
 	serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN);
 
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 }
 
 /*
- * Function ircc_dma_xmit_complete (idev)
+ * Function ircc_dma_xmit_complete (self)
  *
  *    The transfer of a frame in finished. This function will only be called 
  *    by the interrupt handler
  *
  */
-static void ircc_dma_xmit_complete( struct irda_device *idev, int underrun)
+static void ircc_dma_xmit_complete(struct ircc_cb *self, int underrun)
 {
-	struct ircc_cb *self;
 	int iobase, d;
 
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
 
-	ASSERT( idev != NULL, return;);
-	ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return;);
+	ASSERT(self != NULL, return;);
 
-	register_bank(idev->io.iobase, 1);
+	register_bank(self->io.iobase, 1);
 
-	serial_out(idev->io.iobase, UART_SCE_CFGB,
-		   serial_in(idev->io.iobase, UART_SCE_CFGB) &
+	serial_out(self->io.iobase, UART_SCE_CFGB,
+		   serial_in(self->io.iobase, UART_SCE_CFGB) &
 		   ~UART_CFGB_DMA_ENABLE);
 
-	d = get_dma_residue(idev->io.dma);
+	d = get_dma_residue(self->io.dma);
 
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ ": dma residue = %d, len=%d, sent=%d\n", 
-	      d, idev->tx_buff.len, idev->tx_buff.len - d);
-
-	self = idev->priv;
+	      d, self->tx_buff.len, self->tx_buff.len - d);
 
-	iobase = idev->io.iobase;
+	iobase = self->io.iobase;
 
 	/* Check for underrrun! */
-	if ( underrun) {
-		idev->stats.tx_errors++;
-		idev->stats.tx_fifo_errors++;		
+	if (underrun) {
+		self->stats.tx_errors++;
+		self->stats.tx_fifo_errors++;		
 	} else {
-		idev->stats.tx_packets++;
-		idev->stats.tx_bytes +=  idev->tx_buff.len;
+		self->stats.tx_packets++;
+		self->stats.tx_bytes +=  self->tx_buff.len;
 	}
 
 	/* Unlock tx_buff and request another frame */
-	idev->netdev.tbusy = 0; /* Unlock */
-	idev->media_busy = FALSE;
+	self->netdev->tbusy = 0; /* Unlock */
 	
 	/* Tell the network layer, that we can accept more frames */
-	mark_bh( NET_BH);
+	mark_bh(NET_BH);
 
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 }
 
 /*
- * Function ircc_dma_receive (idev)
+ * Function ircc_dma_receive (self)
  *
  *    Get ready for receiving a frame. The device will initiate a DMA
  *    if it starts to receive a frame.
  *
  */
-static int ircc_dma_receive( struct irda_device *idev) 
+static int ircc_dma_receive(struct ircc_cb *self) 
 {
-	struct ircc_cb *self;
 	int iobase;
 
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
 
-	ASSERT( idev != NULL, return -1;);
-	ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return -1;);
+	ASSERT(self != NULL, return -1;);
 
-	self = idev->priv;
-	iobase= idev->io.iobase;
+	iobase= self->io.iobase;
 
-	setup_dma( idev->io.dma, idev->rx_buff.data, idev->rx_buff.truesize, 
+	setup_dma(self->io.dma, self->rx_buff.data, self->rx_buff.truesize, 
 		   DMA_MODE_READ);
 	
 	/* driver->media_busy = FALSE; */
-	idev->io.direction = IO_RECV;
-	idev->rx_buff.data = idev->rx_buff.head;
+	self->io.direction = IO_RECV;
+	self->rx_buff.data = self->rx_buff.head;
 #if 0
-	idev->rx_buff.offset = 0;
+	self->rx_buff.offset = 0;
 #endif
 
 	register_bank(iobase, 4);
@@ -660,62 +693,59 @@
 		   serial_in(iobase, UART_SCE_CFGB) | 
 		   UART_CFGB_DMA_ENABLE | UART_CFGB_DMA_BURST);
 
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 	return 0;
 }
 
 /*
- * Function ircc_dma_receive_complete (idev)
+ * Function ircc_dma_receive_complete (self)
  *
  *    Finished with receiving frames
  *
  *    
  */
-static int ircc_dma_receive_complete( struct irda_device *idev, int iobase)
+static int ircc_dma_receive_complete(struct ircc_cb *self, int iobase)
 {
 	struct sk_buff *skb;
-	struct ircc_cb *self;
 	int len, msgcnt;
 
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
 
-	self = idev->priv;
-
-	msgcnt = serial_in(idev->io.iobase, UART_LCR_B) & 0x08;
+	msgcnt = serial_in(self->io.iobase, UART_LCR_B) & 0x08;
 
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n",
-	      get_dma_residue(idev->io.dma));
+	      get_dma_residue(self->io.dma));
 
-	len = idev->rx_buff.truesize - get_dma_residue(idev->io.dma) - 4;
+	len = self->rx_buff.truesize - get_dma_residue(self->io.dma) - 4;
 
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ ": msgcnt = %d, len=%d\n", msgcnt, len);
 
-	skb = dev_alloc_skb( len+1);
+	skb = dev_alloc_skb(len+1);
 
 	if (skb == NULL)  {
-		printk( KERN_INFO __FUNCTION__ 
+		printk(KERN_INFO __FUNCTION__ 
 			": memory squeeze, dropping frame.\n");
 		return FALSE;
 	}
 			
 	/* Make sure IP header gets aligned */
-	skb_reserve( skb, 1); 
-	skb_put( skb, len);
+	skb_reserve(skb, 1); 
+	skb_put(skb, len);
 
-	memcpy(skb->data, idev->rx_buff.data, len);
-	idev->stats.rx_packets++;
+	memcpy(skb->data, self->rx_buff.data, len);
+	self->stats.rx_packets++;
 
-	skb->dev = &idev->netdev;
+	skb->dev = self->netdev;
 	skb->mac.raw  = skb->data;
 	skb->protocol = htons(ETH_P_IRDA);
-	netif_rx( skb);
+	netif_rx(skb);
 
-	register_bank(idev->io.iobase, 1);
-	serial_out(idev->io.iobase, UART_SCE_CFGB,
-		   serial_in(idev->io.iobase, UART_SCE_CFGB) &
+	register_bank(self->io.iobase, 1);
+	serial_out(self->io.iobase, UART_SCE_CFGB,
+		   serial_in(self->io.iobase, UART_SCE_CFGB) &
 		   ~UART_CFGB_DMA_ENABLE);
 
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 	return TRUE;
 }
 
@@ -728,26 +758,28 @@
 static void ircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	int iobase, iir;
-
-	struct irda_device *idev = (struct irda_device *) dev_id;
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct ircc_cb *self;
 
 	IRDA_DEBUG(ircc_debug+1, __FUNCTION__ " -->\n");
 
-	if (idev == NULL) {
-		printk( KERN_WARNING "%s: irq %d for unknown device.\n", 
+	if (dev == NULL) {
+		printk(KERN_WARNING "%s: irq %d for unknown device.\n", 
 			driver_name, irq);
 		return;
 	}
 	
-	if (idev->io.baudrate <= 115200) {
+	self = (struct ircc_cb *) dev->priv;
+
+	if (self->io.speed <= 115200) {
 		IRDA_DEBUG(ircc_debug+1, __FUNCTION__ 
 		      ": routing interrupt to irport_interrupt\n");
-		return irport_interrupt( irq, dev_id, regs);
+		return irport_interrupt(irq, dev_id, regs);
 	}
 
-	iobase = idev->io.iobase;
+	iobase = self->io.iobase;
 
-	idev->netdev.interrupt = 1;
+	dev->interrupt = 1;
 
 	serial_out(iobase, UART_MASTER, 0);
 
@@ -761,19 +793,19 @@
 
 	if (iir & UART_IIR_EOM) {
 	        IRDA_DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_EOM\n");
-		if (idev->io.direction == IO_RECV) {
-			ircc_dma_receive_complete(idev, iobase);
+		if (self->io.direction == IO_RECV) {
+			ircc_dma_receive_complete(self, iobase);
 		} else {
-			ircc_dma_xmit_complete(idev, iobase);
+			ircc_dma_xmit_complete(self, iobase);
 		}
-		ircc_dma_receive(idev);
+		ircc_dma_receive(self);
 	}
 
 	if (iir & UART_IIR_ACTIVE_FRAME) {
 	        IRDA_DEBUG(ircc_debug, __FUNCTION__ ": UART_IIR_ACTIVE_FRAME\n");
-		idev->rx_buff.state = INSIDE_FRAME;
+		self->rx_buff.state = INSIDE_FRAME;
 #if 0
-		ircc_dma_receive(idev);
+		ircc_dma_receive(self);
 #endif
 	}
 
@@ -781,22 +813,22 @@
 		IRDA_DEBUG(ircc_debug, __FUNCTION__ ": IIR RAW mode interrupt.\n");
 	}
 
-	idev->netdev.interrupt = 0;
+	dev->interrupt = 0;
 
 	register_bank(iobase, 0);
 	serial_out(iobase, UART_IER, UART_IER_ACTIVE_FRAME|UART_IER_EOM);
 	serial_out(iobase, UART_MASTER, UART_MASTER_INT_EN);
 
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 }
 
 /*
- * Function ircc_wait_until_sent (idev)
+ * Function ircc_wait_until_sent (self)
  *
  *    This function should put the current thread to sleep until all data 
  *    have been sent, so it is safe to change the speed.
  */
-static void ircc_wait_until_sent( struct irda_device *idev)
+static void ircc_wait_until_sent(struct ircc_cb *self)
 {
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
 
@@ -804,31 +836,30 @@
 	current->state = TASK_INTERRUPTIBLE;
 	schedule_timeout(MSECS_TO_JIFFIES(60));
 
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 }
 
 /*
- * Function ircc_is_receiving (idev)
+ * Function ircc_is_receiving (self)
  *
  *    Return TRUE is we are currently receiving a frame
  *
  */
-static int ircc_is_receiving( struct irda_device *idev)
+static int ircc_is_receiving(struct ircc_cb *self)
 {
 	int status = FALSE;
 	/* int iobase; */
 
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
 
-	ASSERT( idev != NULL, return FALSE;);
-	ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return FALSE;);
+	ASSERT(self != NULL, return FALSE;);
 
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ ": dma count = %d\n",
-	      get_dma_residue(idev->io.dma));
+	      get_dma_residue(self->io.dma));
 
-	status = ( idev->rx_buff.state != OUTSIDE_FRAME);
+	status = (self->rx_buff.state != OUTSIDE_FRAME);
 	
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 
 	return status;
 }
@@ -839,16 +870,16 @@
  *    Initialize network device
  *
  */
-static int ircc_net_init( struct net_device *dev)
+static int ircc_net_init(struct net_device *dev)
 {
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
 
 	/* Setup to be a normal IrDA network device driver */
-	irda_device_setup( dev);
+	irda_device_setup(dev);
 
 	/* Insert overrides below this line! */
 
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 	return 0;
 }
 
@@ -859,42 +890,47 @@
  *    Start the device
  *
  */
-static int ircc_net_open( struct net_device *dev)
+static int ircc_net_open(struct net_device *dev)
 {
-	struct irda_device *idev;
+	struct ircc_cb *self;
 	int iobase;
 	
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
 	
-	ASSERT( dev != NULL, return -1;);
-	idev = (struct irda_device *) dev->priv;
+	ASSERT(dev != NULL, return -1;);
+	self = (struct ircc_cb *) dev->priv;
 	
-	ASSERT( idev != NULL, return 0;);
-	ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+	ASSERT(self != NULL, return 0;);
 	
-	iobase = idev->io.iobase;
+	iobase = self->io.iobase;
 
-	if (request_irq( idev->io.irq, ircc_interrupt, 0, idev->name, 
-			 (void *) idev)) {
+	if (request_irq(self->io.irq, ircc_interrupt, 0, dev->name, 
+			 (void *) dev)) {
 		return -EAGAIN;
 	}
 	/*
 	 * Always allocate the DMA channel after the IRQ,
 	 * and clean up on failure.
 	 */
-	if (request_dma(idev->io.dma, idev->name)) {
-		free_irq( idev->io.irq, idev);
+	if (request_dma(self->io.dma, dev->name)) {
+		free_irq(self->io.irq, dev);
 		return -EAGAIN;
 	}
 		
 	/* Ready to play! */
-	irda_device_net_open(dev);
-
-	/* turn on interrupts */
+	dev->tbusy = 0;
+	dev->interrupt = 0;
+	dev->start = 1;
+
+	/* 
+	 * Open new IrLAP layer instance, now that everything should be
+	 * initialized properly 
+	 */
+	self->irlap = irlap_open(dev, &self->qos);
 	
 	MOD_INC_USE_COUNT;
 
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 	return 0;
 }
 
@@ -906,31 +942,36 @@
  */
 static int ircc_net_close(struct net_device *dev)
 {
-	struct irda_device *idev;
+	struct ircc_cb *self;
 	int iobase;
 
 	IRDA_DEBUG(ircc_debug, __FUNCTION__ " -->\n");
 	
-	ASSERT( dev != NULL, return -1;);
-	idev = (struct irda_device *) dev->priv;
+	ASSERT(dev != NULL, return -1;);
+	self = (struct ircc_cb *) dev->priv;
 	
-	ASSERT( idev != NULL, return 0;);
-	ASSERT( idev->magic == IRDA_DEVICE_MAGIC, return 0;);
+	ASSERT(self != NULL, return 0;);
 	
-	iobase = idev->io.iobase;
+	iobase = self->io.iobase;
 
-	irda_device_net_close(dev);
+	/* Stop device */
+	dev->tbusy = 1;
+	dev->start = 0;
 
-	disable_dma( idev->io.dma);
+	/* Stop and remove instance of IrLAP */
+	if (self->irlap)
+		irlap_close(self->irlap);
+	self->irlap = NULL;
+
+	disable_dma(self->io.dma);
 
 	/* Disable interrupts */
-       
-	free_irq( idev->io.irq, idev);
-	free_dma( idev->io.dma);
+	free_irq(self->io.irq, dev);
+	free_dma(self->io.dma);
 
 	MOD_DEC_USE_COUNT;
 
-	IRDA_DEBUG( ircc_debug, "--> " __FUNCTION__ "\n");
+	IRDA_DEBUG(ircc_debug, "--> " __FUNCTION__ "\n");
 	return 0;
 }
 
@@ -942,23 +983,11 @@
 MODULE_PARM(ircc_dma, "1i");
 MODULE_PARM(ircc_irq, "1i");
 
-/*
- * Function init_module (void)
- *
- *    
- *
- */
 int init_module(void)
 {
 	return ircc_init();
 }
 
-/*
- * Function cleanup_module (void)
- *
- *    
- *
- */
 void cleanup_module(void)
 {
 	ircc_cleanup();
diff -u --recursive --new-file v2.3.25/linux/drivers/net/irda/uircc.c linux/drivers/net/irda/uircc.c
--- v2.3.25/linux/drivers/net/irda/uircc.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/net/irda/uircc.c	Wed Dec 31 16:00:00 1969
@@ -1,947 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      uircc.c
- * Version:       0.3
- * Description:   Driver for the Sharp Universal Infrared 
- *                Communications Controller (UIRCC v 1.3)
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Sat Dec 26 10:59:03 1998
- * Modified at:   Tue Aug 24 13:33:57 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
- *      
- *     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.
- *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
- *
- *     Applicable Models : Tecra 510CDT, 500C Series, 530CDT, 520CDT,
- *     740CDT, Portege 300CT, 660CDT, Satellite 220C Series, 
- *     Satellite Pro, 440C Series, 470CDT, 460C Series, 480C Series
- *
- ********************************************************************/
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/malloc.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-#include <asm/dma.h>
-#include <asm/byteorder.h>
-
-#include <net/irda/wrapper.h>
-#include <net/irda/irda.h>
-#include <net/irda/irmod.h>
-#include <net/irda/irlap_frame.h>
-#include <net/irda/irda_device.h>
-
-#include <net/irda/uircc.h>
-#include <net/irda/irport.h>
-
-static char *driver_name = "uircc";
-
-#define CHIP_IO_EXTENT 16
-
-static unsigned int io[]  = { 0x300, ~0, ~0, ~0 };
-static unsigned int io2[] = { 0x3e8, 0, 0, 0};
-static unsigned int irq[] = { 11, 0, 0, 0 };
-static unsigned int dma[] = { 5, 0, 0, 0 };
-
-static struct uircc_cb *dev_self[] = { NULL, NULL, NULL, NULL};
-
-/* Some prototypes */
-static int  uircc_open(int i, unsigned int iobase, unsigned int board_addr, 
-		       unsigned int irq, unsigned int dma);
-#ifdef MODULE
-static int  uircc_close(struct irda_device *idev);
-#endif /* MODULE */
-static int  uircc_probe(int iobase, int board_addr, int irq, int dma);
-static int  uircc_dma_receive(struct irda_device *idev); 
-static int  uircc_dma_receive_complete(struct irda_device *idev, int iobase);
-static int  uircc_hard_xmit(struct sk_buff *skb, struct net_device *dev);
-static void uircc_dma_write(struct irda_device *idev, int iobase);
-static void uircc_change_speed(struct irda_device *idev, __u32 baud);
-static void uircc_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void uircc_wait_until_sent(struct irda_device *idev);
-static int  uircc_is_receiving(struct irda_device *idev);
-static int  uircc_toshiba_cmd(int *retval, int arg0, int arg1, int arg2);
-static int  uircc_net_init(struct net_device *dev);
-static int  uircc_net_open(struct net_device *dev);
-static int  uircc_net_close(struct net_device *dev);
-
-/*
- * Function uircc_init ()
- *
- *    Initialize chip. Just try to find out how many chips we are dealing with
- *    and where they are
- */
-int __init uircc_init(void)
-{
-	int i;
-
-	for ( i=0; (io[i] < 2000) && (i < 4); i++) {
-		int ioaddr = io[i];
-		if (check_region(ioaddr, CHIP_IO_EXTENT) < 0)
-			continue;
-		if (uircc_open(i, io[i], io2[i], irq[i], dma[i]) == 0)
-			return 0;
-	}
-	return -ENODEV;
-}
-
-/*
- * Function uircc_cleanup ()
- *
- *    Close all configured chips
- *
- */
-#ifdef MODULE
-static void uircc_cleanup(void)
-{
-	int i;
-
-        IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-	for (i=0; i < 4; i++) {
-		if (dev_self[i])
-			uircc_close(&(dev_self[i]->idev));
-	}
-}
-#endif /* MODULE */
-
-/*
- * Function uircc_open (iobase, irq)
- *
- *    Open driver instance
- *
- */
-static int uircc_open(int i, unsigned int iobase, unsigned int iobase2, 
-		      unsigned int irq, unsigned int dma)
-{
-	struct uircc_cb *self;
-	struct irda_device *idev;
-	int ret;
-
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-	if ((uircc_probe(iobase, iobase2, irq, dma)) == -1)
-		return -1;
-	
-	/*
-	 *  Allocate new instance of the driver
-	 */
-	self = kmalloc( sizeof(struct uircc_cb), GFP_KERNEL);
-	if (self == NULL) {
-		printk(KERN_ERR "IrDA: Can't allocate memory for "
-		       "IrDA control block!\n");
-		return -ENOMEM;
-	}
-	memset(self, 0, sizeof(struct uircc_cb));
-   
-	/* Need to store self somewhere */
-	dev_self[i] = self;
-
-	idev = &self->idev;
-
-	/* Initialize IO */
-	idev->io.iobase    = iobase;
-        idev->io.iobase2   = iobase2; /* Used by irport */
-        idev->io.irq       = irq;
-        idev->io.io_ext    = CHIP_IO_EXTENT;
-        idev->io.io_ext2   = 8;       /* Used by irport */
-        idev->io.dma       = dma;
-        idev->io.fifo_size = 16;
-
-	/* Lock the port that we need */
-	ret = check_region(idev->io.iobase, idev->io.io_ext);
-	if (ret < 0) { 
-		IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
-		      idev->io.iobase);
-		/* uircc_cleanup( self->idev);  */
-		return -ENODEV;
-	}
-	ret = check_region(idev->io.iobase2, idev->io.io_ext2);
-	if (ret < 0) { 
-		IRDA_DEBUG(0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
-		      idev->io.iobase2);
-		/* uircc_cleanup( self->idev);  */
-		return -ENODEV;
-	}
-	request_region(idev->io.iobase, idev->io.io_ext, idev->name);
-        request_region(idev->io.iobase2, idev->io.io_ext2, idev->name);
-
-	/* Initialize QoS for this device */
-	irda_init_max_qos_capabilies(&idev->qos);
-	
-	/* The only value we must override it the baudrate */
-	idev->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
-		IR_115200/*IR_576000|IR_1152000 |(IR_4000000 << 8)*/;
-
-	idev->qos.min_turn_time.bits = 0x0f;
-	irda_qos_bits_to_value(&idev->qos);
-
-	idev->flags = IFF_FIR|IFF_SIR|IFF_DMA|IFF_PIO;
-	
-	/* Specify which buffer allocation policy we need */
-	idev->rx_buff.flags = GFP_KERNEL | GFP_DMA;
-	idev->tx_buff.flags = GFP_KERNEL | GFP_DMA;
-
-	/* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
-	idev->rx_buff.truesize = 4000; 
-	idev->tx_buff.truesize = 4000;
-	
-	/* Initialize callbacks */
-	idev->change_speed    = uircc_change_speed;
-	idev->wait_until_sent = uircc_wait_until_sent;
-	idev->is_receiving    = uircc_is_receiving;
-     
-	/* Override the network functions we need to use */
-	idev->netdev.init            = uircc_net_init;
-	idev->netdev.hard_start_xmit = uircc_hard_xmit;
-	idev->netdev.open            = uircc_net_open;
-	idev->netdev.stop            = uircc_net_close;
-
-	irport_start(idev, iobase2);
-
-	/* Open the IrDA device */
-	irda_device_open(idev, driver_name, self);
-	
-	return 0;
-}
-
-/*
- * Function uircc_close (idev)
- *
- *    Close driver instance
- *
- */
-#ifdef MODULE
-static int uircc_close(struct irda_device *idev)
-{
-	struct uircc_cb *self;
-	int iobase;
-	int status;
-
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-	ASSERT(idev != NULL, return -1;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
-
-        iobase = idev->io.iobase;
-	self = (struct uircc_cb *) idev->priv;
-
-	/* Some magic to disable FIR and enable SIR */
-	uircc_toshiba_cmd(&status, 0xffff, 0x001b, 0x0000);
-
-	/* Disable modem */
-	outb(0x00, iobase+UIRCC_CR10);
-
-	irport_stop(idev, idev->io.iobase2);
-
-	/* Release the PORT that this driver is using */
-	IRDA_DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", idev->io.iobase);
-	release_region(idev->io.iobase, idev->io.io_ext);
-
-	if (idev->io.iobase2) {
-		IRDA_DEBUG(4, __FUNCTION__ "(), Releasing Region %03x\n", 
-		      idev->io.iobase2);
-		release_region(idev->io.iobase2, idev->io.io_ext2);
-	}
-	irda_device_close(idev);
-
-	kfree(self);
-
-	return 0;
-}
-#endif /* MODULE */
-
-/*
- * Function uircc_probe (iobase, board_addr, irq, dma)
- *
- *    Returns non-negative on success.
- *
- */
-static int uircc_probe(int iobase, int iobase2, int irq, int dma) 
-{
-	int version;
-	
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-	/* read the chip version, should be 0x03 */
-	version = inb(iobase+UIRCC_SR8);
-
-	if (version != 0x03) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), Wrong chip version");	
-		return -1;
-	}
-        printk(KERN_INFO "Sharp UIRCC IrDA driver loaded. Version: 0x%02x\n",
-	       version);
-
-	/* Reset chip */
-	outb(UIRCC_CR0_SYS_RST, iobase+UIRCC_CR0);
-
-	/* Initialize some registers */
-	outb(0x03, iobase+UIRCC_CR15);
-	outb(0, iobase+UIRCC_CR11);
-	outb(0, iobase+UIRCC_CR9);
-
-	IRDA_DEBUG(0, __FUNCTION__ "(), sr15=%#x\n", inb(iobase+UIRCC_SR15));
-
-	/* Enable DMA single mode */
-	outb(UIRCC_CR1_RX_DMA|UIRCC_CR1_TX_DMA|UIRCC_CR1_MUST_SET, 
-	     iobase+UIRCC_CR1);
-
-	/* Disable interrupts */
-	outb(0xff, iobase+UIRCC_CR2); 
-
-	/* Set self poll address */
-
-	return 0;
-}
-
-/*
- * Function uircc_change_speed (idev, baud)
- *
- *    Change the speed of the device
- *
- */
-static void uircc_change_speed(struct irda_device *idev, __u32 speed)
-{
-	struct uircc_cb *self;
-	int iobase; 
-	int modem = UIRCC_CR10_SIR;
-	int status;
-
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
-
-	/* Just test the high speed stuff */
-	/*speed = 4000000;*/
-
-	ASSERT(idev != NULL, return;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
-
-	self = idev->priv;
-	iobase = idev->io.iobase;
-
-	/* Update accounting for new speed */
-	idev->io.baudrate = speed;
-
-	/* Disable interrupts */	
-	outb(0xff, iobase+UIRCC_CR2);
-
-	switch (speed) {
-	case 9600:
-	case 19200:
-	case 37600:
-	case 57600:
-	case 115200:
- 		irport_start(idev, idev->io.iobase2);
-		irport_change_speed(idev, speed);
-
-		/* Some magic to disable FIR and enable SIR */
-		uircc_toshiba_cmd(&status, 0xffff, 0x001b, 0x0000);
-
-		modem = UIRCC_CR10_SIR;
-		break;
-	case 576000:		
-		
-		IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 576000\n");
-		break;
-	case 1152000:
-
-		IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 1152000\n");
-		break;
-	case 4000000:
-		irport_stop(idev, idev->io.iobase2);
-
-		/* Some magic to disable SIR and enable FIR */
-		uircc_toshiba_cmd(&status, 0xffff, 0x001b, 0x0001);
-
-		modem = UIRCC_CR10_FIR;
-		IRDA_DEBUG(0, __FUNCTION__ "(), handling baud of 4000000\n");
-
-		/* Set self pole address */
-		//outb(0xfe, iobase+UIRCC_CR8);
-
-	 	/* outb(0x10, iobase+UIRCC_CR11); */
-		break;
-	default:
-		IRDA_DEBUG( 0, __FUNCTION__ "(), unknown baud rate of %d\n", speed);
-		break;
-	}
-
-	/* Set appropriate speed mode */
-	outb(modem, iobase+UIRCC_CR10);
-
-	idev->netdev.tbusy = 0;
-	
-	/* Enable some interrupts so we can receive frames */
-	if (speed > 115200) {
-		/* Enable DMA single mode */
-		outb(UIRCC_CR1_RX_DMA|UIRCC_CR1_TX_DMA|UIRCC_CR1_MUST_SET, 
-		     iobase+UIRCC_CR1);
-
- 		/* Enable all interrupts  */
-		outb(0, iobase+UIRCC_CR2); 
- 		uircc_dma_receive(idev);
- 	}    	
-}
-
-/*
- * Function uircc_hard_xmit (skb, dev)
- *
- *    Transmit the frame!
- *
- */
-static int uircc_hard_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct irda_device *idev;
-	int iobase;
-	int mtt;
-	
-	idev = (struct irda_device *) dev->priv;
-
-	ASSERT(idev != NULL, return 0;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;);
-
-	iobase = idev->io.iobase;
-
-	IRDA_DEBUG(4, __FUNCTION__ "(%ld), skb->len=%d\n", jiffies, (int) skb->len);
-	
-	/* Reset carrier latch */
-	/*outb(0x02, iobase+UIRCC_CR0);*/
-
-	/* Use irport for SIR speeds */
-	if (idev->io.baudrate <= 115200) {
-		return irport_hard_xmit(skb, dev);
-	}
-	
-	IRDA_DEBUG(0, __FUNCTION__ "(), sr0=%#x, sr1=%#x, sr2=%#x, sr3=%#x, sr10=%#x, sr11=%#x\n",
-	      inb(iobase+UIRCC_SR0), inb(iobase+UIRCC_SR3),
-	      inb(iobase+UIRCC_SR2), inb(iobase+UIRCC_SR3), 
-	      inb(iobase+UIRCC_SR10), inb(iobase+UIRCC_SR11));
-
-	/* Lock transmit buffer */
-	if (irda_lock((void *) &dev->tbusy) == FALSE)
-		return -EBUSY;
-
-	memcpy(idev->tx_buff.data, skb->data, skb->len);
-
-	/* Make sure that the length is a multiple of 16 bits */
-	if (skb->len & 0x01)
-		skb->len++;
-
-	idev->tx_buff.len = skb->len;
-	idev->tx_buff.data = idev->tx_buff.head;
-	
-	mtt = irda_get_mtt(skb);
-	
-	/* Use udelay for delays less than 50 us. */
-	if (mtt)
-		udelay(mtt);
-	
-	/* Enable transmit interrupts */
- 	outb(0, iobase+UIRCC_CR2);
-
-	uircc_dma_write(idev, iobase);
-	
-	dev_kfree_skb(skb);
-
-	return 0;
-}
-
-/*
- * Function uircc_dma_write (idev, iobase)
- *
- *    Transmit data using DMA
- *
- */
-static void uircc_dma_write(struct irda_device *idev, int iobase)
-{
-	struct uircc_cb *self;
-
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-	ASSERT(idev != NULL, return;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
-
-	self = idev->priv;
-
-	/* Receiving disable */
-	self->cr3 &= ~UIRCC_CR3_RECV_EN;
-	outb(self->cr3, iobase+UIRCC_CR3);
-
-	/* Set modem */
-	outb(0x80, iobase+UIRCC_CR10);
-
-	/* Enable transmit DMA */
-	outb(UIRCC_CR1_TX_DMA|UIRCC_CR1_MUST_SET, iobase+UIRCC_CR1);
-
-	ASSERT((((__u32)(idev->tx_buff.data)) & 0x01) != 0x01, return;);
-
-	setup_dma(idev->io.dma, idev->tx_buff.data, idev->tx_buff.len, 
-		  DMA_MODE_WRITE);
-	
-	idev->io.direction = IO_XMIT;
-
-	/* Set frame length (should be the real length without padding */
-	outb(idev->tx_buff.len & 0xff, iobase+UIRCC_CR4); /* Low byte */
-	outb(idev->tx_buff.len >> 8, iobase+UIRCC_CR5);   /* High byte */
-
-	/* Enable transmit and transmit CRC */
-	self->cr3 |= (UIRCC_CR3_XMIT_EN|UIRCC_CR3_TX_CRC_EN);
-	outb(self->cr3, iobase+UIRCC_CR3);
-}
-
-/*
- * Function uircc_dma_xmit_complete (idev)
- *
- *    The transfer of a frame in finished. This function will only be called 
- *    by the interrupt handler
- *
- */
-static void uircc_dma_xmit_complete( struct irda_device *idev, int underrun)
-{
-	struct uircc_cb *self;
-	int iobase;
-	int len;
-
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-
-	ASSERT(idev != NULL, return;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return;);
-
-	self = idev->priv;
-
-	iobase = idev->io.iobase;
-
-	/* Select TX counter */
-	outb(UIRCC_CR0_CNT_SWT, iobase+UIRCC_CR0);
-
-	/* Read TX length counter */
-	len  = inb(iobase+UIRCC_SR4);      /* Low byte */
-	len |= inb(iobase+UIRCC_SR5) << 8; /* High byte */
-
-	IRDA_DEBUG(4, __FUNCTION__ "(), sent %d bytes\n", len);
-
-	/* Disable transmit */
-	self->cr3 &= ~UIRCC_CR3_XMIT_EN;
-	outb(self->cr3, iobase+UIRCC_CR3);
-
-	/* Transmit reset (just to be sure) */
-	outb(UIRCC_CR0_XMIT_RST, iobase+UIRCC_CR0);
-	
-	/* Check for underrrun! */
-	if (underrun) {
-		idev->stats.tx_errors++;
-		idev->stats.tx_fifo_errors++;		
-	} else {
-		idev->stats.tx_packets++;
-		idev->stats.tx_bytes += idev->tx_buff.len;
-	}
-
-	/* Unlock tx_buff and request another frame */
-	idev->netdev.tbusy = 0; /* Unlock */
-	idev->media_busy = FALSE;
-	
-	/* Tell the network layer, that we can accept more frames */
-	mark_bh(NET_BH);
-}
-
-/*
- * Function uircc_dma_receive (idev)
- *
- *    Get ready for receiving a frame. The device will initiate a DMA
- *    if it starts to receive a frame.
- *
- */
-static int uircc_dma_receive(struct irda_device *idev) 
-{
-	struct uircc_cb *self;
-	int iobase;
-
-	ASSERT(idev != NULL, return -1;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return -1;);
-
-	IRDA_DEBUG(4, __FUNCTION__ "\n");
-
-	self = idev->priv;
-	iobase= idev->io.iobase;
-
-	/* Transmit disable */
-	/* self->cr3 &= ~UIRCC_CR3_XMIT_EN; */
-	self->cr3 = 0;
-	outb(self->cr3, iobase+UIRCC_CR3);
-
-	/* Transmit reset (just in case) */
-	outb(UIRCC_CR0_XMIT_RST|0x17, iobase+UIRCC_CR0);
-
-	/* Set modem */
-	outb(0x08, iobase+UIRCC_CR10);
-
-	/* Enable receiving with CRC */
-	self->cr3 = (UIRCC_CR3_RECV_EN|UIRCC_CR3_RX_CRC_EN);
-	outb(self->cr3, iobase+UIRCC_CR3);
-
-	/* Make sure Rx DMA is set */
- 	outb(UIRCC_CR1_RX_DMA|UIRCC_CR1_MUST_SET, iobase+UIRCC_CR1);
-
-	/* Rx reset */
-	/* outb(UIRCC_CR0_RECV_RST, iobase+UIRCC_CR0); */
-
-	setup_dma(idev->io.dma, idev->rx_buff.data, 
-		  idev->rx_buff.truesize, DMA_MODE_READ);
-	
-	/* driver->media_busy = FALSE; */
-	idev->io.direction = IO_RECV;
-	idev->rx_buff.data = idev->rx_buff.head;
-
-#if 0
-	/* Enable receiving with CRC */
-	self->cr3 = (UIRCC_CR3_RECV_EN|UIRCC_CR3_RX_CRC_EN);
-	outb(self->cr3, iobase+UIRCC_CR3);
-#endif
-	IRDA_DEBUG(4, __FUNCTION__ "(), cr3=%#x\n", self->cr3);
-	
-	/* Address check? */
-
-	return 0;
-}
-
-/*
- * Function uircc_dma_receive_complete (idev)
- *
- *    Finished with receiving frames
- *
- *    
- */
-static int uircc_dma_receive_complete(struct irda_device *idev, int iobase)
-{
-	struct sk_buff *skb;
-	struct uircc_cb *self;
-	int len;
-
-	self = idev->priv;
-
-	IRDA_DEBUG(0, __FUNCTION__ "()\n");
-
-	/* Check for CRC or framing error */
-	if (inb(iobase+UIRCC_SR0) & UIRCC_SR0_RX_CRCFRM) {
-		IRDA_DEBUG(0, __FUNCTION__ "(), CRC or FRAME error\n");
-		return -1;
-	}
-
-	/* Select receive length counter */
-	outb(0x00, iobase+UIRCC_CR0);
-
-	/* Read frame length */
-	len = inb(iobase+UIRCC_SR4);       /* Low byte */
-	len |= inb(iobase+UIRCC_SR5) << 8; /* High byte */
-
-	IRDA_DEBUG(0, __FUNCTION__ "(), len=%d\n", len);
-
-	/* Receiving disable */
-	self->cr3 &= ~UIRCC_CR3_RECV_EN;
-	outb(self->cr3, iobase+UIRCC_CR3);
-
-	skb = dev_alloc_skb(len+1);
-	if (skb == NULL)  {
-		printk(KERN_INFO __FUNCTION__ 
-		       "(), memory squeeze, dropping frame.\n");
-				/* Restore bank register */
-		return FALSE;
-	}
-			
-	/* Make sure IP header gets aligned */
-	skb_reserve(skb, 1);
-
-	/* Copy frame without CRC */
-	/* if ( idev->io.baudrate < 4000000) { */
-/* 		skb_put( skb, len-2); */
-/* 		memcpy( skb->data, idev->rx_buff.head, len-2); */
-/* 	} else { */
-/* 		skb_put( skb, len-4); */
-/* 		memcpy( skb->data, idev->rx_buff.head, len-4); */
-/* 	} */
-
-	skb_put(skb, len);
-	memcpy(skb->data, idev->rx_buff.data, len);
-	idev->stats.rx_packets++;
-
-	skb->dev = &idev->netdev;
-	skb->mac.raw  = skb->data;
-	skb->protocol = htons(ETH_P_IRDA);
-	netif_rx(skb);
-
-	return TRUE;
-}
-
-/*
- * Function uircc_interrupt (irq, dev_id, regs)
- *
- *    An interrupt from the chip has arrived. Time to do some work
- *
- */
-static void uircc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	__u8 sr3;
-	int iobase;
-
-	struct irda_device *idev = (struct irda_device *) dev_id;
-
-	if (idev == NULL) {
-		printk( KERN_WARNING "%s: irq %d for unknown device.\n", 
-			driver_name, irq);
-		return;
-	}
-	
-	if (idev->io.baudrate <= 115200)
-		return irport_interrupt( irq, dev_id, regs);
-
-	iobase = idev->io.iobase;
-
-	/* Read interrupt status */
-	sr3 = inb( iobase+UIRCC_SR3); 
-	if (!sr3) {
-		IRDA_DEBUG(4,"**\n");
-		return;
-	}
-	idev->netdev.interrupt = 1;
-
-	IRDA_DEBUG(4, __FUNCTION__ "(), sr3=%#x, sr2=%#x, sr10=%#x\n", 
-	      inb( iobase+UIRCC_SR3), inb( iobase+UIRCC_SR2), 
-	      inb( iobase+UIRCC_SR10));
-
-	/*
-	 *  Check what interrupt this is. The UIRCC will not report two
-	 *  different interrupts at the same time!
-	 */
-	switch(sr3) {
-	case UIRCC_SR3_RX_EOF: /* Check for end of frame */
-		uircc_dma_receive_complete(idev, iobase);
-		break;
-	case UIRCC_SR3_TXUR:   /* Check for transmit underrun */
-		uircc_dma_xmit_complete(idev, TRUE);
-		uircc_dma_receive(idev);
-		outb(0, iobase+UIRCC_CR2); 
-		break;
-	case UIRCC_SR3_TX_DONE:
-		uircc_dma_xmit_complete(idev, FALSE);
-		uircc_dma_receive(idev);
-
-		outb(0x0d, iobase+UIRCC_CR2);
-		break;
-	case UIRCC_SR3_TMR_OUT:
-		/* Disable timer */
-		outb(inb(iobase+UIRCC_CR11) & ~UIRCC_CR11_TMR_EN, 
-		     iobase+UIRCC_CR11);
-		break;
-	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), unknown interrupt status=%#x\n",
-		      sr3);
-		break;
-	}	
-	idev->netdev.interrupt = 0;
-}
-
-/*
- * Function uircc_wait_until_sent (idev)
- *
- *    This function should put the current thread to sleep until all data 
- *    have been sent, so it is safe to change the speed.
- */
-static void uircc_wait_until_sent( struct irda_device *idev)
-{
-	/* Just delay 60 ms */
-	current->state = TASK_INTERRUPTIBLE;
-	schedule_timeout(MSECS_TO_JIFFIES(60));
-}
-
-/*
- * Function uircc_is_receiving (idev)
- *
- *    Return TRUE is we are currently receiving a frame
- *
- */
-static int uircc_is_receiving( struct irda_device *idev)
-{
-	int status = FALSE;
-	/* int iobase; */
-
-	ASSERT(idev != NULL, return FALSE;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return FALSE;);
-
-	if (idev->io.baudrate > 115200) {
-		
-	} else 
-		status = (idev->rx_buff.state != OUTSIDE_FRAME);
-	
-	return status;
-}
-
-/*
- * Function uircc_net_init (dev)
- *
- *    Initialize network device
- *
- */
-static int uircc_net_init( struct net_device *dev)
-{
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
-
-	/* Setup to be a normal IrDA network device driver */
-	irda_device_setup(dev);
-
-	/* Insert overrides below this line! */
-
-	return 0;
-}
-
-
-/*
- * Function uircc_net_open (dev)
- *
- *    Start the device
- *
- */
-static int uircc_net_open(struct net_device *dev)
-{
-	struct irda_device *idev;
-	int iobase;
-	
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
-	
-	ASSERT(dev != NULL, return -1;);
-	idev = (struct irda_device *) dev->priv;
-	
-	ASSERT(idev != NULL, return 0;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;);
-	
-	iobase = idev->io.iobase;
-
-	if (request_irq(idev->io.irq, uircc_interrupt, 0, idev->name, 
-			(void *) idev)) {
-		return -EAGAIN;
-	}
-	/*
-	 * Always allocate the DMA channel after the IRQ,
-	 * and clean up on failure.
-	 */
-	if (request_dma(idev->io.dma, idev->name)) {
-		free_irq(idev->io.irq, idev);
-		return -EAGAIN;
-	}
-		
-	/* Ready to play! */
-	irda_device_net_open(dev);
-
-	/* turn on interrupts */
-	
-	MOD_INC_USE_COUNT;
-
-	return 0;
-}
-
-/*
- * Function uircc_net_close (dev)
- *
- *    Stop the device
- *
- */
-static int uircc_net_close(struct net_device *dev)
-{
-	struct irda_device *idev;
-	int iobase;
-
-	IRDA_DEBUG(4, __FUNCTION__ "()\n");
-	
-	ASSERT(dev != NULL, return -1;);
-	idev = (struct irda_device *) dev->priv;
-	
-	ASSERT(idev != NULL, return 0;);
-	ASSERT(idev->magic == IRDA_DEVICE_MAGIC, return 0;);
-	
-	iobase = idev->io.iobase;
-
-	irda_device_net_close(dev);
-
-	disable_dma(idev->io.dma);
-
-	/* Disable interrupts */
-       
-	free_irq(idev->io.irq, idev);
-	free_dma(idev->io.dma);
-
-	MOD_DEC_USE_COUNT;
-
-	return 0;
-}
-
-/*
- * Function uircc_toshiba_cmd (arg0, arg1, arg2)
- *
- *    disable FIR: uircc_toshiba_cmd(&status, 0xffff, 0x001b, 0x0000);
- *    enable  FIR: uircc_toshiba_cmd(&status, 0xffff, 0x001b, 0x0001);
- *    IRDA status: uircc_toshiba_cmd(&status, 0xfefe, 0x001b, 0x0000);
- */
-static int uircc_toshiba_cmd(int *retval, int arg0, int arg1, int arg2)
-{
-	char return_code = 0;
-
-	__asm__ volatile ("inb   $0xb2,%%al; "
-			  "movb  %%ah,%%al;  "
-			  : /* Output */
-			  "=al"  (return_code),
-			  "=ecx" (*retval)
-			  : /* Input */
-			  "ax" (arg0),
-			  "bx" (arg1),
-			  "cx" (arg2)
-		);
-	/*
-	 * Return
-	 * 0x00 = OK
-	 * 0x80 = Function not supported by system
-	 * 0x83 = Input data error
-	 */
-	return (int) return_code;
-}
-
-#ifdef MODULE
-
-/*
- * Function init_module (void)
- *
- *    
- *
- */
-int init_module(void)
-{
-	return uircc_init();
-}
-
-/*
- * Function cleanup_module (void)
- *
- *    
- *
- */
-void cleanup_module(void)
-{
-	uircc_cleanup();
-}
-#endif /* MODULE */
-
diff -u --recursive --new-file v2.3.25/linux/drivers/net/irda/w83977af_ir.c linux/drivers/net/irda/w83977af_ir.c
--- v2.3.25/linux/drivers/net/irda/w83977af_ir.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/net/irda/w83977af_ir.c	Tue Nov  2 17:07:08 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Paul VanderSpek
  * Created at:    Wed Nov  4 11:46:16 1998
- * Modified at:   Wed Oct 20 00:08:30 1999
+ * Modified at:   Sat Oct 30 16:24:32 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>
@@ -933,7 +933,8 @@
 	/*  Receive all characters in Rx FIFO */
 	do {
 		byte = inb(iobase+RBR);
-		async_unwrap_char(self->netdev, &self->rx_buff, byte);
+		async_unwrap_char(self->netdev, &self->stats, &self->rx_buff, 
+				  byte);
 	} while (inb(iobase+USR) & USR_RDR); /* Data available */	
 }
 
diff -u --recursive --new-file v2.3.25/linux/drivers/net/ppp_synctty.c linux/drivers/net/ppp_synctty.c
--- v2.3.25/linux/drivers/net/ppp_synctty.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/net/ppp_synctty.c	Tue Nov  2 17:07:08 1999
@@ -29,7 +29,7 @@
  * PPP driver, written by Michael Callahan and Al Longyear, and
  * subsequently hacked by Paul Mackerras.
  *
- * ==FILEVERSION 991014==
+ * ==FILEVERSION 991018==
  */
 
 /* $Id: ppp_synctty.c,v 1.3 1999/09/02 05:30:10 paulus Exp $ */
@@ -97,6 +97,67 @@
 };
 
 /*
+ * Utility procedures to print a buffer in hex/ascii
+ */
+static void
+ppp_print_hex (register __u8 * out, const __u8 * in, int count)
+{
+	register __u8 next_ch;
+	static char hex[] = "0123456789ABCDEF";
+
+	while (count-- > 0) {
+		next_ch = *in++;
+		*out++ = hex[(next_ch >> 4) & 0x0F];
+		*out++ = hex[next_ch & 0x0F];
+		++out;
+	}
+}
+
+static void
+ppp_print_char (register __u8 * out, const __u8 * in, int count)
+{
+	register __u8 next_ch;
+
+	while (count-- > 0) {
+		next_ch = *in++;
+
+		if (next_ch < 0x20 || next_ch > 0x7e)
+			*out++ = '.';
+		else {
+			*out++ = next_ch;
+			if (next_ch == '%')   /* printk/syslogd has a bug !! */
+				*out++ = '%';
+		}
+	}
+	*out = '\0';
+}
+
+static void
+ppp_print_buffer (const char *name, const __u8 *buf, int count)
+{
+	__u8 line[44];
+
+	if (name != NULL)
+		printk(KERN_DEBUG "ppp_synctty: %s, count = %d\n", name, count);
+
+	while (count > 8) {
+		memset (line, 32, 44);
+		ppp_print_hex (line, buf, 8);
+		ppp_print_char (&line[8 * 3], buf, 8);
+		printk(KERN_DEBUG "%s\n", line);
+		count -= 8;
+		buf += 8;
+	}
+
+	if (count > 0) {
+		memset (line, 32, 44);
+		ppp_print_hex (line, buf, count);
+		ppp_print_char (&line[8 * 3], buf, count);
+		printk(KERN_DEBUG "%s\n", line);
+	}
+}
+
+/*
  * Routines for locking and unlocking the transmit and receive paths.
  */
 static inline void
@@ -523,6 +584,10 @@
 		 */
 		islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7;
 
+		/* compress protocol field if option enabled */
+                if (data[0] == 0 && (ap->flags & SC_COMP_PROT) && !islcp)
+			skb_pull(skb,1);
+
 		/* prepend address/control fields if necessary */
 		if ((ap->flags & SC_COMP_AC) == 0 || islcp) {
 			if (skb_headroom(skb) < 2) {
@@ -536,7 +601,7 @@
 				kfree_skb(skb);
 				skb = npkt;
 			}
-			skb_pull(skb,2);
+			skb_push(skb,2);
 			skb->data[0] = PPP_ALLSTATIONS;
 			skb->data[1] = PPP_UI;
 		}
@@ -545,6 +610,9 @@
 		break;
 	}
 
+	if (skb && ap->flags & SC_LOG_OUTPKT)
+		ppp_print_buffer ("send buffer", skb->data, skb->len);
+
 	return skb;
 }
 
@@ -567,7 +635,7 @@
 
 	if (test_and_set_bit(XMIT_FULL, &ap->busy))
 		return 0;	/* already full */
-	ap->tpkt = skb;
+	skb_queue_head(&ap->xq,skb);
 
 	ppp_sync_push(ap);
 	return 1;
@@ -729,6 +797,9 @@
 		input_error(ap, *flags);
 		return;
 	}
+
+	if (ap->flags & SC_LOG_INPKT)
+		ppp_print_buffer ("receive buffer", buf, count);
 
 	/* stuff the chars in the skb */
 	if ((skb = ap->rpkt) == 0) {
diff -u --recursive --new-file v2.3.25/linux/drivers/net/sis900.c linux/drivers/net/sis900.c
--- v2.3.25/linux/drivers/net/sis900.c	Thu Aug 26 13:05:38 1999
+++ linux/drivers/net/sis900.c	Fri Nov  5 09:52:05 1999
@@ -1,58 +1,29 @@
-/*****************************************************************************/
-/*      sis900.c: A SiS 900 PCI Fast Ethernet driver for Linux.              */
-/*                                                                           */
-/*                Silicon Integrated System Corporation                      */ 
-/*                Revision:	1.05	Aug 7 1999                           */
-/*                                                                           */
-/*****************************************************************************/
-
-/*                                                                            
-      Modified from the driver which is originally written by Donald Becker. 
-
-      This software may be used and distributed according to the terms
-      of the GNU Public License (GPL), incorporated herein by reference.
-      Drivers based on this skeleton fall under the GPL and must retain
-      the authorship (implicit copyright) notice.
-
-      The author may be reached as becker@tidalwave.net, or
-      Donald Becker
-      312 Severn Ave. #W302
-      Annapolis MD 21403
-
-      Support and updates [to the original skeleton] available at
-      http://www.tidalwave.net/~becker/pci-skeleton.html
+/* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
+   Silicon Integrated System Corporation 
+   Revision:	1.05	Aug 7 1999
+   
+   Modified from the driver which is originally written by Donald Becker. 
+   
+   This software may be used and distributed according to the terms
+   of the GNU Public License (GPL), incorporated herein by reference.
+   Drivers based on this skeleton fall under the GPL and must retain
+   the authorship (implicit copyright) notice.
+   
+   References:
+   SiS 7016 Fast Ethernet PCI Bus 10/100 Mbps LAN Controller with OnNow Support,
+   preliminary Rev. 1.0 Jan. 14, 1998
+   SiS 900 Fast Ethernet PCI Bus 10/100 Mbps LAN Single Chip with OnNow Support,
+   preliminary Rev. 1.0 Nov. 10, 1998
+   SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
+   preliminary Rev. 1.0 Jan. 18, 1998
+   http://www.sis.com.tw/support/databook.htm
+   
+   Rev 1.06 Nov. 4 1999 Ollie Lho (ollie@sis.com.tw) Second release
+   Rev 1.05.05 Oct. 29 1999 Ollie Lho (ollie@sis.com.tw) Single buffer Tx/Rx  
+   Chin-Shan Li (lcs@sis.com.tw) Added AMD Am79c901 HomePNA PHY support
+   Rev 1.05 Aug. 7 1999 Jim Huang (cmhuang@sis.com.tw) Initial release
 */
 
-static const char *version =
-"sis900.c:v1.05  8/07/99\n";
-
-static int max_interrupt_work = 20;
-#define sis900_debug debug
-static int sis900_debug = 0;
-
-static int multicast_filter_limit = 128;
-
-#define MAX_UNITS 8             /* More are supported, limit only on options */
-static int speeds[MAX_UNITS] = {100, 100, 100, 100, 100, 100, 100, 100};
-static int full_duplex[MAX_UNITS] = {1, 1, 1, 1, 1, 1, 1, 1};
-
-#define TX_BUF_SIZE     1536
-#define RX_BUF_SIZE     1536
-
-#define TX_DMA_BURST    0
-#define RX_DMA_BURST    0
-#define TX_FIFO_THRESH  16
-#define TxDRNT_100      (1536>>5)
-#define TxDRNT_10       16 
-#define RxDRNT_100      8
-#define RxDRNT_10       8 
-#define TRUE            1
-#define FALSE           0
-
-/* Operational parameters that usually are not changed. */
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT  (4*HZ)
-
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>
@@ -65,1845 +36,1244 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
+
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 #include <asm/processor.h>      /* Processor type for cache alignment. */
 #include <asm/bitops.h>
 #include <asm/io.h>
+#include <linux/delay.h>
 
-#define RUN_AT(x) (jiffies + (x))
+#include "sis900.h"
 
-#include <linux/delay.h>
+static const char *version =
+"sis900.c: v1.06  11/04/99\n";
 
-#if LINUX_VERSION_CODE < 0x20123
-#define test_and_set_bit(val, addr) set_bit(val, addr)
-#endif
-#if LINUX_VERSION_CODE <= 0x20139
-#define net_device_stats enet_statistics
-#else
-#define NETSTATS_VER2
-#endif
-#if LINUX_VERSION_CODE < 0x20155  ||  defined(CARDBUS)
-/* Grrrr, the PCI code changed, but did not consider CardBus... */
-#include <linux/bios32.h>
-#define PCI_SUPPORT_VER1
-#else
-#define PCI_SUPPORT_VER2
-#endif
-#if LINUX_VERSION_CODE < 0x20159
-#define dev_free_skb(skb) dev_kfree_skb(skb, FREE_WRITE);
-#else
-#define dev_free_skb(skb) dev_kfree_skb(skb);
-#endif
+static int max_interrupt_work = 20;
+#define sis900_debug debug
+static int sis900_debug = 0;
 
-/* The I/O extent. */
-#define SIS900_TOTAL_SIZE 0x100
+static int multicast_filter_limit = 128;
 
-/* This table drives the PCI probe routines.  It's mostly boilerplate in all
-   of the drivers, and will likely be provided by some future kernel.
-   Note the matching code -- the first table entry matchs all 56** cards but
-   second only the 1234 card.
-*/
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  (4*HZ)
 
-enum pci_flags_bit {
-        PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
+struct mac_chip_info {
+	const char *name;
+	u16 	vendor_id, device_id, flags;
+	int 	io_size;
+	struct net_device *(*probe) (struct mac_chip_info *mac, struct pci_dev * pci_dev, 
+				 struct net_device * net_dev);
 };
+static struct net_device * sis900_mac_probe (struct mac_chip_info * mac, struct pci_dev * pci_dev,
+					 struct net_device * net_dev);
 
-struct pci_id_info {
-        const char *name;
-        u16     vendor_id, device_id, device_id_mask, flags;
-        int io_size;
-        struct net_device *(*probe1)(int pci_bus, int pci_devfn, struct net_device *dev,
-                         long ioaddr, int irq, int chip_idx, int fnd_cnt);
+static struct mac_chip_info  mac_chip_table[] = {
+	{ "SiS 900 PCI Fast Ethernet", PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_900,
+	  PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE, sis900_mac_probe},
+	{ "SiS 7016 PCI Fast Ethernet",PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7016,
+	  PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE, sis900_mac_probe},
+	{0,},                                          /* 0 terminated list. */
 };
 
-static struct net_device * sis900_probe1(int pci_bus, int pci_devfn,
-                                  struct net_device *dev, long ioaddr,
-                                  int irq, int chp_idx, int fnd_cnt);
-
-static struct pci_id_info pci_tbl[] =
-{{ "SiS 900 PCI Fast Ethernet",
-   0x1039, 0x0900, 0xffff, PCI_USES_IO|PCI_USES_MASTER, 0x100, sis900_probe1},
-  { "SiS 7016 PCI Fast Ethernet",
-   0x1039, 0x7016, 0xffff, PCI_USES_IO|PCI_USES_MASTER, 0x100, sis900_probe1},
- {0,},                                          /* 0 terminated list. */
-};
+static void sis900_read_mode(struct net_device *net_dev, int phy_addr, int *speed, int *duplex);
+static void amd79c901_read_mode(struct net_device *net_dev, int phy_addr, int *speed, int *duplex);
 
-/* The capability table matches the chip table above. */
-enum {HAS_MII_XCVR=0x01, HAS_CHIP_XCVR=0x02, HAS_LNK_CHNG=0x04};
-static int sis_cap_tbl[] = {
-        HAS_MII_XCVR|HAS_CHIP_XCVR|HAS_LNK_CHNG,
-        HAS_MII_XCVR|HAS_CHIP_XCVR|HAS_LNK_CHNG,
+static struct mii_chip_info {
+	const char * name;
+	u16 phy_id0;
+	u16 phy_id1;
+	void (*read_mode) (struct net_device *net_dev, int phy_addr, int *speed, int *duplex);
+} mii_chip_table[] = {
+	{"SiS 900 Internal MII PHY", 0x001d, 0x8000, sis900_read_mode},
+	{"SiS 7014 Physical Layer Solution", 0x0016, 0xf830,sis900_read_mode},
+	{"AMD 79C901 10BASE-T PHY",  0x0000, 0x35b9, amd79c901_read_mode},
+	{"AMD 79C901 HomePNA PHY",   0x0000, 0x35c8, amd79c901_read_mode},
+	{0,},
 };
 
-/* The rest of these values should never change. */
-#define NUM_TX_DESC     16      /* Number of Tx descriptor registers. */
-#define NUM_RX_DESC     8       /* Number of Rx descriptor registers. */
-
-/* Symbolic offsets to registers. */
-enum SIS900_registers {
-        cr=0x0,                 //Command Register
-        cfg=0x4,                //Configuration Register
-        mear=0x8,               //EEPROM Access Register
-        ptscr=0xc,              //PCI Test Control Register
-        isr=0x10,               //Interrupt Status Register
-        imr=0x14,               //Interrupt Mask Register
-        ier=0x18,               //Interrupt Enable Register
-        epar=0x18,              //Enhanced PHY Access Register
-        txdp=0x20,              //Transmit Descriptor Pointer Register
-        txcfg=0x24,             //Transmit Configuration Register
-        rxdp=0x30,              //Receive Descriptor Pointer Register
-        rxcfg=0x34,             //Receive Configuration Register
-        flctrl=0x38,            //Flow Control Register
-        rxlen=0x3c,             //Receive Packet Length Register
-        rfcr=0x48,              //Receive Filter Control Register
-        rfdr=0x4C,              //Receive Filter Data Register
-        pmctrl=0xB0,            //Power Management Control Register
-        pmer=0xB4               //Power Management Wake-up Event Register
+struct mii_phy {
+	struct mii_phy * next;
+	struct mii_chip_info * chip_info;
+	int phy_addr;
+	u16 status;
 };
 
-#define RESET           0x00000100
-#define SWI             0x00000080
-#define RxRESET         0x00000020
-#define TxRESET         0x00000010
-#define RxDIS           0x00000008
-#define RxENA           0x00000004
-#define TxDIS           0x00000002
-#define TxENA           0x00000001
-
-#define BISE            0x80000000
-#define EUPHCOM         0x00000100
-#define REQALG          0x00000080
-#define SB              0x00000040
-#define POW             0x00000020
-#define EXD             0x00000010
-#define PESEL           0x00000008
-#define LPM             0x00000004
-#define BEM             0x00000001
-
-/* Interrupt register bits, using my own meaningful names. */
-#define WKEVT           0x10000000
-#define TxPAUSEEND      0x08000000
-#define TxPAUSE         0x04000000
-#define TxRCMP          0x02000000
-#define RxRCMP          0x01000000
-#define DPERR           0x00800000
-#define SSERR           0x00400000
-#define RMABT           0x00200000
-#define RTABT           0x00100000
-#define RxSOVR          0x00010000
-#define HIBERR          0x00008000
-#define SWINT           0x00001000
-#define MIBINT          0x00000800
-#define TxURN           0x00000400
-#define TxIDLE          0x00000200
-#define TxERR           0x00000100
-#define TxDESC          0x00000080
-#define TxOK            0x00000040
-#define RxORN           0x00000020
-#define RxIDLE          0x00000010
-#define RxEARLY         0x00000008
-#define RxERR           0x00000004
-#define RxDESC          0x00000002
-#define RxOK            0x00000001
-
-#define IE              0x00000001
-
-#define TxCSI           0x80000000
-#define TxHBI           0x40000000
-#define TxMLB           0x20000000
-#define TxATP           0x10000000
-#define TxIFG           0x0C000000
-#define TxMXF           0x03800000
-#define TxMXF_shift     0x23
-#define TxMXDMA         0x00700000
-#define TxMXDMA_shift   20
-#define TxRTCNT         0x000F0000
-#define TxRTCNT_shift   16
-#define TxFILLT         0x00007F00
-#define TxFILLT_shift   8
-#define TxDRNT          0x0000007F
-
-#define RxAEP           0x80000000
-#define RxARP           0x40000000
-#define RxATP           0x10000000
-#define RxAJAB          0x08000000
-#define RxMXF           0x03800000
-#define RxMXF_shift     23
-#define RxMXDMA         0x00700000
-#define RxMXDMA_shift   20
-#define RxDRNT          0x0000007F
-
-#define RFEN            0x80000000
-#define RFAAB           0x40000000
-#define RFAAM           0x20000000
-#define RFAAP           0x10000000
-#define RFPromiscuous   (RFAAB|RFAAM|RFAAP)
-#define RFAA_shift      28
-#define RFEP            0x00070000
-#define RFEP_shift      16
-
-#define RFDAT           0x0000FFFF
-
-#define OWN             0x80000000
-#define MORE            0x40000000
-#define INTR            0x20000000
-#define OK              0x08000000
-#define DSIZE           0x00000FFF
-
-#define SUPCRC          0x10000000
-#define ABORT           0x04000000
-#define UNDERRUN        0x02000000
-#define NOCARRIER       0x01000000
-#define DEFERD          0x00800000
-#define EXCDEFER        0x00400000
-#define OWCOLL          0x00200000
-#define EXCCOLL         0x00100000
-#define COLCNT          0x000F0000
-
-#define INCCRC          0x10000000
-//      ABORT           0x04000000
-#define OVERRUN         0x02000000
-#define DEST            0x01800000
-#define BCAST           0x01800000
-#define MCAST           0x01000000
-#define UNIMATCH        0x00800000
-#define TOOLONG         0x00400000
-#define RUNT            0x00200000
-#define RXISERR         0x00100000
-#define CRCERR          0x00080000
-#define FAERR           0x00040000
-#define LOOPBK          0x00020000
-#define RXCOL           0x00010000
-
-#define EuphLiteEEMACAddr               0x08
-#define EuphLiteEEVendorID              0x02
-#define EuphLiteEEDeviceID              0x03
-#define EuphLiteEECardTypeRev           0x0b
-#define EuphLiteEEPlexusRev             0x0c
-#define EuphLiteEEChecksum              0x0f
-
-#define RXSTS_shift     18
-#define OWN             0x80000000
-#define MORE            0x40000000
-#define INTR            0x20000000
-#define OK              0x08000000
-#define DSIZE           0x00000FFF
-/* MII register offsets */
-#define MII_CONTROL             0x0000
-#define MII_STATUS              0x0001
-#define MII_PHY_ID0             0x0002
-#define MII_PHY_ID1             0x0003
-#define MII_ANAR                0x0004
-#define MII_ANLPAR              0x0005
-#define MII_ANER                0x0006
-/* MII Control register bit definitions. */
-#define MIICNTL_FDX             0x0100
-#define MIICNTL_RST_AUTO        0x0200
-#define MIICNTL_ISOLATE         0x0400
-#define MIICNTL_PWRDWN          0x0800
-#define MIICNTL_AUTO            0x1000
-#define MIICNTL_SPEED           0x2000
-#define MIICNTL_LPBK            0x4000
-#define MIICNTL_RESET           0x8000
-/* MII Status register bit significance. */
-#define MIISTAT_EXT             0x0001
-#define MIISTAT_JAB             0x0002
-#define MIISTAT_LINK            0x0004
-#define MIISTAT_CAN_AUTO        0x0008
-#define MIISTAT_FAULT           0x0010
-#define MIISTAT_AUTO_DONE       0x0020
-#define MIISTAT_CAN_T           0x0800
-#define MIISTAT_CAN_T_FDX       0x1000
-#define MIISTAT_CAN_TX          0x2000
-#define MIISTAT_CAN_TX_FDX      0x4000
-#define MIISTAT_CAN_T4          0x8000
-/* MII NWAY Register Bits ...
-** valid for the ANAR (Auto-Negotiation Advertisement) and
-** ANLPAR (Auto-Negotiation Link Partner) registers */
-#define MII_NWAY_NODE_SEL       0x001f
-#define MII_NWAY_CSMA_CD        0x0001
-#define MII_NWAY_T              0x0020
-#define MII_NWAY_T_FDX          0x0040
-#define MII_NWAY_TX             0x0080
-#define MII_NWAY_TX_FDX         0x0100
-#define MII_NWAY_T4             0x0200
-#define MII_NWAY_RF             0x2000
-#define MII_NWAY_ACK            0x4000
-#define MII_NWAY_NP             0x8000
-
-/* MII Auto-Negotiation Expansion Register Bits */
-#define MII_ANER_PDF            0x0010
-#define MII_ANER_LP_NP_ABLE     0x0008
-#define MII_ANER_NP_ABLE        0x0004
-#define MII_ANER_RX_PAGE        0x0002
-#define MII_ANER_LP_AN_ABLE     0x0001
-#define HALF_DUPLEX                     1
-#define FDX_CAPABLE_DUPLEX_UNKNOWN      2
-#define FDX_CAPABLE_HALF_SELECTED       3
-#define FDX_CAPABLE_FULL_SELECTED       4
-#define HW_SPEED_UNCONFIG       0
-#define HW_SPEED_10_MBPS        10
-#define HW_SPEED_100_MBPS       100
-#define HW_SPEED_DEFAULT        (HW_SPEED_10_MBPS)
-
-#define ACCEPT_ALL_PHYS         0x01
-#define ACCEPT_ALL_MCASTS       0x02
-#define ACCEPT_ALL_BCASTS       0x04
-#define ACCEPT_ALL_ERRORS       0x08
-#define ACCEPT_CAM_QUALIFIED    0x10
-#define MAC_LOOPBACK            0x20
-//#define FDX_CAPABLE_FULL_SELECTED     4
-#define CRC_SIZE                4
-#define MAC_HEADER_SIZE         14
-
-typedef struct _EuphLiteDesc {
-        u32     llink;
-        unsigned char*  buf;
-        u32     physAddr;
-        /* Hardware sees the physical address of descriptor */
-        u32     plink;
-        u32     cmdsts;
-        u32     bufPhys;
-} EuphLiteDesc;
+typedef struct _BufferDesc {
+	u32     link;
+	u32     cmdsts;
+	u32     bufptr;
+} BufferDesc;
 
 struct sis900_private {
-        char devname[8];                /* Used only for kernel debugging. */
-        const char *product_name;
-        struct net_device *next_module;
-        int chip_id;
-        int chip_revision;
-        unsigned char pci_bus, pci_devfn;
-#if LINUX_VERSION_CODE > 0x20139
-        struct net_device_stats stats;
-#else
-        struct enet_statistics stats;
-#endif
-        struct timer_list timer;        /* Media selection timer. */
-        unsigned int cur_rx;    /* Index into the Rx buffer of next Rx pkt. */
-        unsigned int cur_tx, dirty_tx, tx_flag;
-
-        /* The saved address of a sent-in-place packet/buffer, for skfree(). */
-        struct sk_buff* tx_skbuff[NUM_TX_DESC];
-        EuphLiteDesc tx_buf[NUM_TX_DESC];       /* Tx bounce buffers */
-        EuphLiteDesc rx_buf[NUM_RX_DESC];
-        unsigned char *rx_bufs;
-        unsigned char *tx_bufs;                 /* Tx bounce buffer region. */
-        char phys[4];                           /* MII device addresses.    */
-        int phy_idx;                            /* Support Max 4 PHY        */
-        u16 pmd_status;
-        unsigned int tx_full;                   /* The Tx queue is full.    */
-	int MediaSpeed;                         /* user force speed         */
-	int MediaDuplex;                        /* user force duplex        */
-        int full_duplex;                        /* Full/Half-duplex.        */
-        int speeds;                             /* 100/10 Mbps.             */
-        u16 LinkOn;
-        u16 LinkChange;
+	struct net_device *next_module;
+	struct net_device_stats stats;
+	struct pci_dev * pci_dev;
+
+	struct mac_chip_info * mac;
+	struct mii_phy * mii;
+	unsigned int cur_phy;
+
+	struct timer_list timer;        		/* Link status detection timer. */
+	unsigned int cur_rx, dirty_rx;		
+	unsigned int cur_tx, dirty_tx;
+
+	/* The saved address of a sent/receive-in-place packet buffer */
+	struct sk_buff *tx_skbuff[NUM_TX_DESC];
+	struct sk_buff *rx_skbuff[NUM_RX_DESC];
+	BufferDesc tx_ring[NUM_TX_DESC];	
+	BufferDesc rx_ring[NUM_RX_DESC];
+	unsigned int tx_full;			/* The Tx queue is full.    */
+
+	int LinkOn;
 };
 
 #ifdef MODULE
 #if LINUX_VERSION_CODE > 0x20115
 MODULE_AUTHOR("Jim Huang <cmhuang@sis.com.tw>");
 MODULE_DESCRIPTION("SiS 900 PCI Fast Ethernet driver");
-MODULE_PARM(speeds, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
 MODULE_PARM(multicast_filter_limit, "i");
 MODULE_PARM(max_interrupt_work, "i");
 MODULE_PARM(debug, "i");
 #endif
 #endif
 
-static int sis900_open(struct net_device *dev);
+static int sis900_open(struct net_device *net_dev);
+static int sis900_mii_probe (struct net_device * net_dev);
+static void sis900_init_rxfilter (struct net_device * net_dev);
 static u16 read_eeprom(long ioaddr, int location);
-static int mdio_read(struct net_device *dev, int phy_id, int location);
-static void mdio_write(struct net_device *dev, int phy_id, int location, int val);
+static u16 mdio_read(struct net_device *net_dev, int phy_id, int location);
+static void mdio_write(struct net_device *net_dev, int phy_id, int location, int val);
 static void sis900_timer(unsigned long data);
-static void sis900_tx_timeout(struct net_device *dev);
-static void sis900_init_ring(struct net_device *dev);
-static int sis900_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static int sis900_rx(struct net_device *dev);
+static void sis900_check_mode (struct net_device *net_dev, struct mii_phy *mii_phy);
+static void sis900_tx_timeout(struct net_device *net_dev);
+static void sis900_init_tx_ring(struct net_device *net_dev);
+static void sis900_init_rx_ring(struct net_device *net_dev);
+static int sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev);
+static int sis900_rx(struct net_device *net_dev);
+static void sis900_finish_xmit (struct net_device *net_dev);
 static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-static int sis900_close(struct net_device *dev);
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static struct enet_statistics *sis900_get_stats(struct net_device *dev);
-static void set_rx_mode(struct net_device *dev);
-static void sis900_reset(struct net_device *dev);
-static u16 elAutoNegotiate(struct net_device *dev, int phy_id, int *duplex, int *speed);
-static void elSetCapability(struct net_device *dev, int phy_id, int duplex, int speed);
-static u16 elPMDreadMode(struct net_device *dev, int phy_id, int *speed, int *duplex);
-static u16 elMIIpollBit(struct net_device *dev, int phy_id, int location, u16 mask, u16 polarity, u16 *value);
-static void elSetMediaType(struct net_device *dev, int speed, int duplex);
+static int sis900_close(struct net_device *net_dev);
+static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd);
+static struct enet_statistics *sis900_get_stats(struct net_device *net_dev);
+static u16 sis900_compute_hashtable_index(u8 *addr);
+static void set_rx_mode(struct net_device *net_dev);
+static void sis900_reset(struct net_device *net_dev);
 
 /* A list of all installed SiS900 devices, for removing the driver module. */
 static struct net_device *root_sis900_dev = NULL;
 
-/* Ideally we would detect all network cards in slot order.  That would
-   be best done a central PCI probe dispatch, which wouldn't work
-   well when dynamically adding drivers.  So instead we detect just the
-   SiS 900 cards in slot order. */
-
-int sis900_probe(struct net_device *dev)
-{
-        int cards_found = 0;
-        int pci_index = 0;
-        unsigned char pci_bus, pci_device_fn;
-
-        if ( ! pcibios_present())
-                return -ENODEV;
-
-        for (;pci_index < 0xff; pci_index++) {
-                u16 vendor, device, pci_command, new_command;
-                int chip_idx, irq;
-                long ioaddr;
-
-                if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
-                                                pci_index,
-                                                &pci_bus, &pci_device_fn)
-                                != PCIBIOS_SUCCESSFUL) {
-                        break;
-                }
-                pcibios_read_config_word(pci_bus, pci_device_fn, PCI_VENDOR_ID,
-                                                        &vendor);
-                pcibios_read_config_word(pci_bus, pci_device_fn, PCI_DEVICE_ID,
-                                                        &device);
-
-                for (chip_idx = 0; pci_tbl[chip_idx].vendor_id; chip_idx++)
-                        if (vendor == pci_tbl[chip_idx].vendor_id &&
-                                (device & pci_tbl[chip_idx].device_id_mask) ==
-                                pci_tbl[chip_idx].device_id)
-                                break;
-                if (pci_tbl[chip_idx].vendor_id == 0)   /* Compiled out! */
-                        continue;
-
-	{
-                struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn);
-                ioaddr = pdev->resource[0].start;
-                irq = pdev->irq;
-        }
-
-                if ((pci_tbl[chip_idx].flags & PCI_USES_IO) &&
-                        check_region(ioaddr, pci_tbl[chip_idx].io_size))
-                        continue;
-
-                /* Activate the card: fix for brain-damaged Win98 BIOSes. */
-                pcibios_read_config_word(pci_bus, pci_device_fn,
-                                         PCI_COMMAND, &pci_command);
-                new_command = pci_command | (pci_tbl[chip_idx].flags & 7);
-                if (pci_command != new_command) {
-                        printk(KERN_INFO "  The PCI BIOS has not enabled the"
-                                   " device at %d/%d!"
-                                   "Updating PCI command %4.4x->%4.4x.\n",
-                                        pci_bus, pci_device_fn,
-                                        pci_command, new_command);
-
-                        pcibios_write_config_word(pci_bus, pci_device_fn,
-                                                  PCI_COMMAND, new_command);
-                }
-
-                dev = pci_tbl[chip_idx].probe1(pci_bus,
-                                                pci_device_fn,
-                                                dev,
-                                                ioaddr,
-                                                irq,
-                                                chip_idx,
-                                                cards_found);
-
-                if (dev  && (pci_tbl[chip_idx].flags & PCI_COMMAND_MASTER)) {
-                        u8 pci_latency;
-
-                        pcibios_read_config_byte(pci_bus, pci_device_fn,
-                                        PCI_LATENCY_TIMER, &pci_latency);
-
-                        if (pci_latency < 32) {
-                           printk(KERN_NOTICE "  PCI latency timer (CFLT) is "
-                           "unreasonably low at %d.  Setting to 64 clocks.\n",
-                                           pci_latency);
-                           pcibios_write_config_byte(pci_bus, pci_device_fn,
-                                          PCI_LATENCY_TIMER, 64);
-                        }
-                }
-                dev = 0;
-                cards_found++;
-        }
-        return cards_found ? 0 : -ENODEV;
-}
-
-static struct net_device * sis900_probe1(   int pci_bus,
-                                        int pci_devfn,
-                                        struct net_device *dev,
-                                        long ioaddr,
-                                        int irq,
-                                        int chip_idx,
-                                        int found_cnt)
-{
-        static int did_version = 0;     /* Already printed version info. */
-        struct sis900_private *tp;
-	u16    status;
-        int    duplex = found_cnt < MAX_UNITS ? full_duplex[found_cnt] : 0 ;
-        int    speed  = found_cnt < MAX_UNITS ? speeds[found_cnt] : 0 ;
-        int    phy=0, phy_idx=0, i;
-
-        if (did_version++ == 0)
-                printk(KERN_INFO "%s", version);
-
-        dev = init_etherdev(dev, 0);
-        
-        if(dev==NULL)
-        	return NULL;
-
-        printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ",
-                   dev->name, pci_tbl[chip_idx].name, ioaddr, irq);
-
-        if ((u16)read_eeprom(ioaddr, EuphLiteEEVendorID) != 0xffff) {
-                for (i = 0; i < 3; i++)
-                        ((u16 *)(dev->dev_addr))[i] =
-                                        read_eeprom(ioaddr,i+EuphLiteEEMACAddr);
-                for (i = 0; i < 5; i++)
-                        printk("%2.2x:", (u8)dev->dev_addr[i]);
-                printk("%2.2x.\n", dev->dev_addr[i]);
-        } else
-                printk(KERN_INFO "Error EEPROM read\n");
-
-        /* We do a request_region() to register /proc/ioports info. */
-        request_region(ioaddr, pci_tbl[chip_idx].io_size, dev->name);
-
-        dev->base_addr = ioaddr;
-        dev->irq = irq;
-
-        /* Some data structures must be quadword aligned. */
-        tp = kmalloc(sizeof(*tp), GFP_KERNEL | GFP_DMA);
-        if(tp==NULL)
-        {
-        	release_region(ioaddr, pci_tbl[chip_idx].io_size);
-        	return NULL;
-        }
-        memset(tp, 0, sizeof(*tp));
-        dev->priv = tp;
-
-        tp->next_module = root_sis900_dev;
-        root_sis900_dev = dev;
-
-        tp->chip_id = chip_idx;
-        tp->pci_bus = pci_bus;
-        tp->pci_devfn = pci_devfn;
-
-        /* Find the connected MII xcvrs.
-           Doing this in open() would allow detecting external xcvrs later, but
-           takes too much time. */
-        if (sis_cap_tbl[chip_idx] & HAS_MII_XCVR) {
-                for (phy = 0, phy_idx = 0;
-                        phy < 32 && phy_idx < sizeof(tp->phys); phy++)
-                {
-                        int mii_status ;
-			mii_status = mdio_read(dev, phy, MII_STATUS);
-
-                        if (mii_status != 0xffff && mii_status != 0x0000) {
-                                tp->phy_idx = phy_idx;
-                                tp->phys[phy_idx++] = phy;
-                                tp->pmd_status=mdio_read(dev, phy, MII_STATUS);
-                                printk(KERN_INFO "%s: MII transceiver found "
-                                                 "at address %d.\n",
-                                                 dev->name, phy);
-                                break;
-                        }
-                }
-
-                if (phy_idx == 0) {
-                        printk(KERN_INFO "%s: No MII transceivers found!\n",
-                                        dev->name);
-                        tp->phys[0] = -1;
-			tp->pmd_status = 0;
-                }
-        } else {
-                        tp->phys[0] = -1;
-			tp->pmd_status = 0;
-        }
-
-        if ((tp->pmd_status > 0) && (phy_idx > 0)) {
-		if (sis900_debug > 1) {
-			printk(KERN_INFO "duplex=%d, speed=%d\n",
-						duplex, speed);
+/* walk through every ethernet PCI devices to see if some of them are matched with our card list*/
+int sis900_probe (struct net_device * net_dev)
+{
+	int found = 0;
+	struct pci_dev * pci_dev = NULL;
+		
+	if (!pci_present())
+		return -ENODEV;
+		
+	while ((pci_dev = pci_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pci_dev)) != NULL) {
+		/* pci_dev contains all ethernet devices */
+		u32 pci_io_base;
+		struct mac_chip_info * mac;
+
+		for (mac = mac_chip_table; mac->vendor_id; mac++) {
+			/* try to match our card list */
+			if (pci_dev->vendor == mac->vendor_id &&
+			    pci_dev->device == mac->device_id)
+				break;
 		}
-		if (!duplex && !speed) {  
-			// auto-config media type
-			// Set full capability
-			if (sis900_debug > 1) {
-				printk(KERN_INFO "Auto Config ...\n");
-			}
-			elSetCapability(dev, tp->phys[tp->phy_idx], 1, 100);
-            		tp->pmd_status=elAutoNegotiate(dev,
-               	    				       tp->phys[tp->phy_idx],
-			                  	       &tp->full_duplex,
-						       &tp->speeds);
-		} else {
-			tp->MediaSpeed = speed;
-			tp->MediaDuplex = duplex;
-			elSetCapability(dev, tp->phys[tp->phy_idx],
-					duplex, speed);
-            		elAutoNegotiate(dev, tp->phys[tp->phy_idx],
-			                &tp->full_duplex,
-					&tp->speeds);
-			status = mdio_read(dev, phy, MII_ANLPAR);
-			if ( !(status & (MII_NWAY_T  | MII_NWAY_T_FDX |
-					 MII_NWAY_TX | MII_NWAY_TX_FDX )))
-			{
-				u16 cmd=0;
-				cmd |= ( speed == 100 ?
-					 MIICNTL_SPEED : 0 );
-				cmd |= ( duplex ? MIICNTL_FDX : 0 );
-        			mdio_write(dev, phy, MII_CONTROL, cmd);
-				elSetMediaType(dev, speed==100 ? 
-						    HW_SPEED_100_MBPS :
-						    HW_SPEED_10_MBPS,
-						    duplex ?
-						    FDX_CAPABLE_FULL_SELECTED:
-						    FDX_CAPABLE_HALF_SELECTED);
-        			elMIIpollBit(dev, phy, MII_STATUS,
-						MIISTAT_LINK, TRUE, &status);
-			} else {
-				status = mdio_read(dev, phy, MII_STATUS);
-			}
+		
+		if (mac->vendor_id == 0)
+			/* pci_dev does not match any of our cards */
+			continue;
+		
+		/* now, pci_dev should be either 900 or 7016 */
+		pci_io_base = pci_dev->resource[0].start;
+		if ((mac->flags & PCI_COMMAND_IO ) && 
+		    check_region(pci_io_base, mac->io_size))
+			continue;
+		
+		/* setup various bits in PCI command register */
+		pci_set_master(pci_dev);
+
+		/* do the real low level jobs */
+		net_dev = mac->probe(mac, pci_dev, net_dev);
+		
+		if (net_dev != NULL) {
+			found++;
 		}
+		net_dev = NULL;
+	}
+	return found ? 0 : -ENODEV;
+}
+
+static struct net_device * sis900_mac_probe (struct mac_chip_info * mac, struct pci_dev * pci_dev, 
+					 struct net_device * net_dev)
+{
+	struct sis900_private *sis_priv;
+	long ioaddr = pci_dev->resource[0].start; 
+	int irq = pci_dev->irq;
+	static int did_version = 0;
+	u16 signature;
+	int i;
+
+	if (did_version++ == 0)
+		printk(KERN_INFO "%s", version);
+
+	/* check to see if we have sane EEPROM */
+	signature = (u16) read_eeprom(ioaddr, EEPROMSignature);    
+	if (signature == 0xffff || signature == 0x0000) {
+		printk (KERN_INFO "%s: Error EERPOM read %x\n", 
+			net_dev->name, signature);
+		return NULL;
+	}
+
+	if ((net_dev = init_etherdev(net_dev, 0)) == NULL)
+		return NULL;
+
+	printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", net_dev->name, mac->name,
+	       ioaddr, irq);
+
+	/* get MAC address from EEPROM */
+	for (i = 0; i < 3; i++)
+		((u16 *)(net_dev->dev_addr))[i] = read_eeprom(ioaddr, i+EEPROMMACAddr);
+	for (i = 0; i < 5; i++)
+		printk("%2.2x:", (u8)net_dev->dev_addr[i]);
+	printk("%2.2x.\n", net_dev->dev_addr[i]);
+
+	if ((net_dev->priv = kmalloc(sizeof(struct sis900_private), GFP_KERNEL)) == NULL) {
+		unregister_netdevice(net_dev);
+		return NULL;
+	}
+
+	sis_priv = net_dev->priv;
+	memset(sis_priv, 0, sizeof(struct sis900_private));
+
+	/* We do a request_region() to register /proc/ioports info. */
+	request_region(ioaddr, mac->io_size, net_dev->name);
+	net_dev->base_addr = ioaddr;
+	net_dev->irq = irq;
+	sis_priv->pci_dev = pci_dev;
+	sis_priv->mac = mac;
+
+	/* probe for mii transciver */
+	if (sis900_mii_probe(net_dev) == 0) {
+		unregister_netdev(net_dev);
+		kfree(sis_priv);
+		release_region(ioaddr, mac->io_size);
+		return NULL;
+	}
+
+	sis_priv->next_module = root_sis900_dev;
+	root_sis900_dev = net_dev;
+
+	/* The SiS900-specific entries in the device structure. */
+	net_dev->open = &sis900_open;
+	net_dev->hard_start_xmit = &sis900_start_xmit;
+	net_dev->stop = &sis900_close;
+	net_dev->get_stats = &sis900_get_stats;
+	net_dev->set_multicast_list = &set_rx_mode;
+	net_dev->do_ioctl = &mii_ioctl;
 
-                if (tp->pmd_status & MIISTAT_LINK) 
-               	        tp->LinkOn = TRUE;
-	        else
-                        tp->LinkOn = FALSE;
+	return net_dev;
+}
 
-		tp->LinkChange = FALSE;
+static int sis900_mii_probe (struct net_device * net_dev)
+{
+	struct sis900_private * sis_priv = (struct sis900_private *)net_dev->priv;
+	int phy_addr;
 	
-        }
+	sis_priv->mii = NULL;
+	
+	/* search for total of 32 possible mii phy addresses */
+	for (phy_addr = 0; phy_addr < 32; phy_addr++) {
+		u16 mii_status;
+		u16 phy_id0, phy_id1;
+		int i;
+		
+		mii_status = mdio_read(net_dev, phy_addr, MII_STATUS);
+		if (mii_status == 0xffff || mii_status == 0x0000)
+			/* the mii is not accessable, try next one */
+			continue;
+		
+		phy_id0 = mdio_read(net_dev, phy_addr, MII_PHY_ID0);
+		phy_id1 = mdio_read(net_dev, phy_addr, MII_PHY_ID1);
+		
+		/* search our mii table for the current mii */ 
+		for (i = 0; mii_chip_table[i].phy_id1; i++)
+			if (phy_id0 == mii_chip_table[i].phy_id0) {
+				struct mii_phy * mii_phy;
+				
+				printk(KERN_INFO 
+				       "%s: %s transceiver found at address %d.\n",
+				       net_dev->name, mii_chip_table[i].name, 
+				       phy_addr);;
+				if ((mii_phy = kmalloc(sizeof(struct mii_phy), GFP_KERNEL)) != NULL) {
+					mii_phy->chip_info = mii_chip_table+i;
+					mii_phy->phy_addr = phy_addr;
+					mii_phy->status = mdio_read(net_dev, phy_addr, 
+								    MII_STATUS);
+					mii_phy->next = sis_priv->mii;
+					sis_priv->mii = mii_phy;
+				}
+				/* the current mii is on our mii_info_table, 
+				   try next address */
+				break;
+			}
+	}
+	
+	if (sis_priv->mii == NULL) {
+		printk(KERN_INFO "%s: No MII transceivers found!\n", 
+		       net_dev->name);
+		return 0;
+	}
 
-	if (sis900_debug > 1) {
-        	if (tp->full_duplex == FDX_CAPABLE_FULL_SELECTED) {
-                	printk(KERN_INFO "%s: Media type is Full Duplex.\n",
-						dev->name);
-        	} else {
-                	printk(KERN_INFO "%s: Media type is Half Duplex.\n",
-						dev->name);
-        	}
-        	if (tp->speeds == HW_SPEED_100_MBPS) {
-                	printk(KERN_INFO "%s: Speed is 100mbps.\n", dev->name);
-        	} else {
-                	printk(KERN_INFO "%s: Speed is 10mbps.\n", dev->name);
-        	}
-	}
-
-        /* The SiS900-specific entries in the device structure. */
-        dev->open = &sis900_open;
-        dev->hard_start_xmit = &sis900_start_xmit;
-        dev->stop = &sis900_close;
-        dev->get_stats = &sis900_get_stats;
-        dev->set_multicast_list = &set_rx_mode;
-        dev->do_ioctl = &mii_ioctl;
-
-        return dev;
-}
-
-/* Serial EEPROM section. */
-
-/*  EEPROM_Ctrl bits. */
-#define EECLK           0x00000004      /* EEPROM shift clock. */
-#define EECS            0x00000008      /* EEPROM chip select. */
-#define EEDO            0x00000002      /* EEPROM chip data out. */
-#define EEDI            0x00000001      /* EEPROM chip data in. */
+	/* arbitrary choose that last PHY and current PHY */
+	sis_priv->cur_phy = sis_priv->mii->phy_addr;
+	printk(KERN_INFO "%s: Using %s as default\n", net_dev->name,
+	       sis_priv->mii->chip_info->name);
 
-/* Delay between EEPROM clock transitions.
-   No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
- */
+	if (sis_priv->mii->status & MII_STAT_LINK) 
+		sis_priv->LinkOn = TRUE;
+	else
+		sis_priv->LinkOn = FALSE;
 
-#define eeprom_delay()  inl(ee_addr)
+	return 1;
+}
 
-/* The EEPROM commands include the alway-set leading bit. */
-#define EEread          0x0180
-#define EEwrite         0x0140
-#define EEerase         0x01C0
-#define EEwriteEnable   0x0130
-#define EEwriteDisable  0x0100
-#define EEeraseAll      0x0120
-#define EEwriteAll      0x0110
-#define EEaddrMask      0x013F
-#define EEcmdShift      16
+/* Delay between EEPROM clock transitions. */
+#define eeprom_delay()  inl(ee_addr)
 
+/* Read Serial EEPROM through EEPROM Access Register, Note that location is 
+   in word (16 bits) unit */
 static u16 read_eeprom(long ioaddr, int location)
 {
-        int i;
-        u16 retval = 0;
-        long ee_addr = ioaddr + mear;
-        u32 read_cmd = location | EEread;
-
-        outl(0, ee_addr);
-        eeprom_delay();
-        outl(EECLK, ee_addr);
-        eeprom_delay();
-
-        /* Shift the read command bits out. */
-        for (i = 8; i >= 0; i--) {
-                u32 dataval = (read_cmd & (1 << i)) ? EEDI | EECS : EECS;
-                outl(dataval, ee_addr);
-                eeprom_delay();
-                outl(dataval | EECLK, ee_addr);
-                eeprom_delay();
-        }
-        outb(EECS, ee_addr);
-        eeprom_delay();
-
-        for (i = 16; i > 0; i--) {
-                outl(EECS, ee_addr);
-                eeprom_delay();
-                outl(EECS | EECLK, ee_addr);
-                eeprom_delay();
-                retval = (retval << 1) | ((inl(ee_addr) & EEDO) ? 1 : 0);
-                eeprom_delay();
-        }
-
-        /* Terminate the EEPROM access. */
-        outl(0, ee_addr);
-        eeprom_delay();
-        outl(EECLK, ee_addr);
-        return (retval);
+	int i;
+	u16 retval = 0;
+	long ee_addr = ioaddr + mear;
+	u32 read_cmd = location | EEread;
+
+	outl(0, ee_addr);
+	eeprom_delay();
+	outl(EECLK, ee_addr);
+	eeprom_delay();
+
+	/* Shift the read command (9) bits out. */
+	for (i = 8; i >= 0; i--) {
+		u32 dataval = (read_cmd & (1 << i)) ? EEDI | EECS : EECS;
+		outl(dataval, ee_addr);
+		eeprom_delay();
+		outl(dataval | EECLK, ee_addr);
+		eeprom_delay();
+	}
+	outb(EECS, ee_addr);
+	eeprom_delay();
+
+	/* read the 16-bits data in */
+	for (i = 16; i > 0; i--) {
+		outl(EECS, ee_addr);
+		eeprom_delay();
+		outl(EECS | EECLK, ee_addr);
+		eeprom_delay();
+		retval = (retval << 1) | ((inl(ee_addr) & EEDO) ? 1 : 0);
+		eeprom_delay();
+	}
+		
+	/* Terminate the EEPROM access. */
+	outl(0, ee_addr);
+	eeprom_delay();
+	outl(EECLK, ee_addr);
+
+	return (retval);
 }
 
-/* MII serial management: mostly bogus for now. */
 /* Read and write the MII management registers using software-generated
-   serial MDIO protocol.
-   The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
-   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
-   "overclocking" issues. */
-
+   serial MDIO protocol. Note that the command bits and data bits are
+   send out seperately */
 #define mdio_delay()    inl(mdio_addr)
 
-#define MIIread         0x6000
-#define MIIwrite        0x6002
-#define MIIpmdMask      0x0F80
-#define MIIpmdShift     7
-#define MIIregMask      0x007C
-#define MIIregShift     2
-#define MIIturnaroundBits       2
-#define MIIcmdLen       16
-#define MIIcmdShift     16
-#define MIIreset        0xFFFFFFFF
-#define MIIwrLen        32
-
-#define MDC             0x00000040
-#define MDDIR           0x00000020
-#define MDIO            0x00000010
-
 static void mdio_idle(long mdio_addr)
 {
-        outl(MDIO | MDDIR, mdio_addr);
-        mdio_delay();
-        outl(MDIO | MDDIR | MDC, mdio_addr);
+	outl(MDIO | MDDIR, mdio_addr);
+	mdio_delay();
+	outl(MDIO | MDDIR | MDC, mdio_addr);
 }
 
 /* Syncronize the MII management interface by shifting 32 one bits out. */
 static void mdio_reset(long mdio_addr)
 {
-        int i;
+	int i;
 
-        for (i = 31; i >= 0; i--) {
-                outl(MDDIR | MDIO, mdio_addr);
-                mdio_delay();
-                outl(MDDIR | MDIO | MDC, mdio_addr);
-                mdio_delay();
-        }
-        return;
-}
-
-static int mdio_read(struct net_device *dev, int phy_id, int location)
-{
-        long mdio_addr = dev->base_addr + mear;
-        int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
-        int retval = 0;
-        int i;
-
-        mdio_reset(mdio_addr);
-        mdio_idle(mdio_addr);
-
-        for (i = 15; i >= 0; i--) {
-                int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
-                outl(dataval, mdio_addr);
-                outl(dataval | MDC, mdio_addr);
-        }
-
-        /* Read the two transition, 16 data, and wire-idle bits. */
-        for (i = 16; i > 0; i--) {
-                outl(0, mdio_addr);
-                //mdio_delay();
-                retval = (retval << 1) | ((inl(mdio_addr) & MDIO) ? 1 : 0);
-                outl(MDC, mdio_addr);
-                mdio_delay();
-        }
-        return retval;
-}
-
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
-{
-        long mdio_addr = dev->base_addr + mear;
-        int mii_cmd = MIIwrite|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
-        int i;
-
-        mdio_reset(mdio_addr);
-        mdio_idle(mdio_addr);
-
-        /* Shift the command bits out. */
-        for (i = 31; i >= 0; i--) {
-                int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
-                outb(dataval, mdio_addr);
-                mdio_delay();
-                outb(dataval | MDC, mdio_addr);
-                mdio_delay();
-        }
-        mdio_delay();
-        /* Clear out extra bits. */
-        for (i = 2; i > 0; i--) {
-                outb(0, mdio_addr);
-                mdio_delay();
-                outb(MDC, mdio_addr);
-                mdio_delay();
-        }
-        return;
+	for (i = 31; i >= 0; i--) {
+		outl(MDDIR | MDIO, mdio_addr);
+		mdio_delay();
+		outl(MDDIR | MDIO | MDC, mdio_addr);
+		mdio_delay();
+	}
+	return;
+}
+
+static u16 mdio_read(struct net_device *net_dev, int phy_id, int location)
+{
+	long mdio_addr = net_dev->base_addr + mear;
+	int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
+	u16 retval = 0;
+	int i;
+
+	mdio_reset(mdio_addr);
+	mdio_idle(mdio_addr);
+
+	for (i = 15; i >= 0; i--) {
+		int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
+		outl(dataval, mdio_addr);
+		mdio_delay();
+		outl(dataval | MDC, mdio_addr);
+		mdio_delay();
+	}
+
+	/* Read the 16 data bits. */
+	for (i = 16; i > 0; i--) {
+		outl(0, mdio_addr);
+		mdio_delay();
+		retval = (retval << 1) | ((inl(mdio_addr) & MDIO) ? 1 : 0);
+		outl(MDC, mdio_addr);
+		mdio_delay();
+	}
+	return retval;
+}
+
+static void mdio_write(struct net_device *net_dev, int phy_id, int location, int value)
+{
+	long mdio_addr = net_dev->base_addr + mear;
+	int mii_cmd = MIIwrite|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
+	int i;
+
+	mdio_reset(mdio_addr);
+	mdio_idle(mdio_addr);
+
+	/* Shift the command bits out. */
+	for (i = 15; i >= 0; i--) {
+		int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
+		outb(dataval, mdio_addr);
+		mdio_delay();
+		outb(dataval | MDC, mdio_addr);
+		mdio_delay();
+	}
+	mdio_delay();
+
+	/* Shift the value bits out. */
+	for (i = 15; i >= 0; i--) {
+		int dataval = (value & (1 << i)) ? MDDIR | MDIO : MDDIR;
+		outl(dataval, mdio_addr);
+		mdio_delay();
+		outl(dataval | MDC, mdio_addr);
+	       	mdio_delay();
+	}
+	mdio_delay();
+	
+	/* Clear out extra bits. */
+	for (i = 2; i > 0; i--) {
+		outb(0, mdio_addr);
+		mdio_delay();
+		outb(MDC, mdio_addr);
+		mdio_delay();
+	}
+	return;
 }
 
 static int
-sis900_open(struct net_device *dev)
+sis900_open(struct net_device *net_dev)
 {
-        struct sis900_private *tp = (struct sis900_private *)dev->priv;
-        long ioaddr = dev->base_addr;
+	struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
+	long ioaddr = net_dev->base_addr;
 
-        if (sis900_debug > 0)
-                printk(KERN_INFO "%s sis900_open, IO Addr=%x, Irq=%x\n",
-                                dev->name, (unsigned int)ioaddr, dev->irq);
-
-        /* Soft reset the chip. */
-        outl(0, ioaddr + imr);
-        outl(0, ioaddr + ier);
-        outl(0, ioaddr + rfcr);
-        outl(RESET | RxRESET | TxRESET, ioaddr + cr);
-
-        if (request_irq(dev->irq, &sis900_interrupt, SA_SHIRQ, dev->name, dev))
-        {
-                return -EAGAIN;
-        }
-
-        MOD_INC_USE_COUNT;      
-
-        tp->tx_bufs = kmalloc(TX_BUF_SIZE * NUM_TX_DESC, GFP_KERNEL);
-        tp->rx_bufs = kmalloc(RX_BUF_SIZE * NUM_RX_DESC, GFP_KERNEL);
-        if (tp->tx_bufs == NULL || tp->rx_bufs == NULL) {
-                if (tp->tx_bufs)
-                        kfree(tp->tx_bufs);
-                if (tp->rx_bufs)
-                        kfree(tp->rx_bufs);
-		if (!tp->tx_bufs) {
-	              printk(KERN_ERR "%s: Can't allocate a %d byte TX Bufs.\n",
-                                   dev->name, TX_BUF_SIZE * NUM_TX_DESC);
-		}
-		if (!tp->rx_bufs) {
-	              printk(KERN_ERR "%s: Can't allocate a %d byte RX Bufs.\n",
-                                   dev->name, RX_BUF_SIZE * NUM_RX_DESC);
-		}
-                return -ENOMEM;
-        }
+	/* Soft reset the chip. */
+	sis900_reset(net_dev);
 
-        {
-                u32 rfcrSave;
-                u32 w;
-                u32 i;
-
-                rfcrSave = inl(rfcr);
-                outl(rfcrSave & ~RFEN, rfcr);
-                for (i=0 ; i<3 ; i++) {
-                        w = (u16)*((u16*)(dev->dev_addr)+i);
-                        outl((((u32) i) << RFEP_shift), ioaddr + rfcr);
-                        outl((u32)w, ioaddr + rfdr);
-                        if (sis900_debug > 4) {
-                                printk(KERN_INFO "Filter Addr[%d]=%x\n",
-                                        i, inl(ioaddr + rfdr));
-                        }
-                }
-                outl(rfcrSave, rfcr);
-        }
-
-        sis900_init_ring(dev);
-        outl((u32)tp->tx_buf[0].physAddr, ioaddr + txdp);
-        outl((u32)tp->rx_buf[0].physAddr, ioaddr + rxdp);
-
-        if (sis900_debug > 4)
-                printk(KERN_INFO "txdp:%8.8x\n", inl(ioaddr + txdp));
-
-        /* Check that the chip has finished the reset. */
-        {
-                u32 status;
-                int j=0;
-                status = TxRCMP | RxRCMP;
-                while (status && (j++ < 30000)) {
-                        status ^= (inl(isr) & status);
-                }
-        }
-
-        outl(PESEL, ioaddr + cfg);
-
-        /* Must enable Tx/Rx before setting transfer thresholds! */
-        /*
-         *      #define TX_DMA_BURST    0
-         *      #define RX_DMA_BURST    0
-         *      #define TX_FIFO_THRESH  16
-         *      #define TxDRNT_100      (1536>>5)
-         *      #define TxDRNT_10       (1536>>5)
-         *      #define RxDRNT_100      (1536>>5)
-         *      #define RxDRNT_10       (1536>>5)
-         */
-        outl((RX_DMA_BURST<<20) | (RxDRNT_10 << 1), ioaddr+rxcfg);
-        outl(TxATP | (TX_DMA_BURST << 20) | (TX_FIFO_THRESH<<8) | TxDRNT_10,
-                                                ioaddr + txcfg);
-        if (sis900_debug > 1)
-        {
-        	if (tp->LinkOn) {
-        		printk(KERN_INFO"%s: Media Type %s%s-duplex.\n",
-                                dev->name,
-                                tp->speeds==HW_SPEED_100_MBPS ?
-					"100mbps " : "10mbps ",
-                                tp->full_duplex== FDX_CAPABLE_FULL_SELECTED ?
-					"full" : "half");
-		}
-		else printk(KERN_INFO"%s: Media Link Off\n", dev->name);
+	if (request_irq(net_dev->irq, &sis900_interrupt, SA_SHIRQ, net_dev->name, net_dev)) {
+		return -EAGAIN;
 	}
-        set_rx_mode(dev);
 
-        dev->tbusy = 0;
-        dev->interrupt = 0;
-        dev->start = 1;
-
-        /* Enable all known interrupts by setting the interrupt mask. */
-        outl((RxOK|RxERR|RxORN|RxSOVR|TxOK|TxERR|TxURN), ioaddr + imr);
-        outl(RxENA, ioaddr + cr);
-        outl(IE, ioaddr + ier);
-
-        if (sis900_debug > 3)
-                printk(KERN_INFO "%s: sis900_open() ioaddr %#lx IRQ %d \n",
-                           dev->name, ioaddr, dev->irq);
-
-        /* Set the timer to switch to check for link beat and perhaps switch
-           to an alternate media type. */
-        init_timer(&tp->timer);
-        tp->timer.expires = RUN_AT((24*HZ)/10);         /* 2.4 sec. */
-        tp->timer.data = (unsigned long)dev;
-        tp->timer.function = &sis900_timer;             /* timer handler */
-        add_timer(&tp->timer);
+	MOD_INC_USE_COUNT;
+
+	sis900_init_rxfilter(net_dev);
 
-        return 0;
+	sis900_init_tx_ring(net_dev);
+	sis900_init_rx_ring(net_dev);
+
+	set_rx_mode(net_dev);
+
+	net_dev->tbusy = 0;
+	net_dev->interrupt = 0;
+	net_dev->start = 1;
+
+	/* Enable all known interrupts by setting the interrupt mask. */
+	outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxOK), ioaddr + imr);
+	outl(RxENA, ioaddr + cr);
+	outl(IE, ioaddr + ier);
+
+	sis900_check_mode(net_dev, sis_priv->mii);
+
+	/* Set the timer to switch to check for link beat and perhaps switch
+	   to an alternate media type. */
+	init_timer(&sis_priv->timer);
+	sis_priv->timer.expires = jiffies + HZ;
+	sis_priv->timer.data = (unsigned long)net_dev;
+	sis_priv->timer.function = &sis900_timer;
+	add_timer(&sis_priv->timer);
+
+	return 0;
 }
 
+/* set receive filter address to our MAC address */
+static void
+sis900_init_rxfilter (struct net_device * net_dev)
+{
+	long ioaddr = net_dev->base_addr;
+	u32 rfcrSave;
+	u32 i;
+	
+	rfcrSave = inl(rfcr + ioaddr);
+
+	/* disable packet filtering before setting filter */
+	outl(rfcrSave & ~RFEN, rfcr);
+
+	/* load MAC addr to filter data register */
+	for (i = 0 ; i < 3 ; i++) {
+		u32 w;
+
+		w = (u32) *((u16 *)(net_dev->dev_addr)+i);
+		outl((i << RFADDR_shift), ioaddr + rfcr);
+		outl(w, ioaddr + rfdr);
+
+		if (sis900_debug > 2) {
+			printk(KERN_INFO "%s: Receive Filter Addrss[%d]=%x\n",
+			       net_dev->name, i, inl(ioaddr + rfdr));
+		}
+	}
+
+	/* enable packet filitering */
+	outl(rfcrSave | RFEN, rfcr + ioaddr);
+}
+
+/* Initialize the Tx ring. */
+static void
+sis900_init_tx_ring(struct net_device *net_dev)
+{
+	struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
+	long ioaddr = net_dev->base_addr; 
+	int i;
+	
+	sis_priv->tx_full = 0;
+	sis_priv->dirty_tx = sis_priv->cur_tx = 0;
+	
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		sis_priv->tx_skbuff[i] = NULL;
+
+		sis_priv->tx_ring[i].link = (u32) virt_to_bus(&sis_priv->tx_ring[i+1]);
+		sis_priv->tx_ring[i].cmdsts = 0;
+		sis_priv->tx_ring[i].bufptr = 0;
+	}
+	sis_priv->tx_ring[i-1].link = (u32) virt_to_bus(&sis_priv->tx_ring[0]);
+
+	/* load Transmit Descriptor Register */
+	outl(virt_to_bus(&sis_priv->tx_ring[0]), ioaddr + txdp); 
+	if (sis900_debug > 2)
+		printk(KERN_INFO "%s: TX descriptor register loaded with: %8.8x\n", 
+		       net_dev->name, inl(ioaddr + txdp));
+}
+
+/* Initialize the Rx descriptor ring, pre-allocate recevie buffers */ 
+static void 
+sis900_init_rx_ring(struct net_device *net_dev) 
+{ 
+	struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv; 
+	long ioaddr = net_dev->base_addr; 
+	int i;
+ 
+	sis_priv->cur_rx = 0; 
+	sis_priv->dirty_rx = 0;
+
+	/* init RX descriptor */
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		sis_priv->rx_skbuff[i] = NULL;
+
+		sis_priv->rx_ring[i].link = (u32) virt_to_bus(&sis_priv->rx_ring[i+1]);
+		sis_priv->rx_ring[i].cmdsts = 0;
+		sis_priv->rx_ring[i].bufptr = 0;
+	}
+	sis_priv->rx_ring[i-1].link = (u32) virt_to_bus(&sis_priv->rx_ring[0]);
+
+	/* allocate sock buffers */
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		struct sk_buff *skb;
+
+		if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
+			/* not enough memory for skbuff, this makes a "hole"
+			   on the buffer ring, it is not clear how the 
+			   hardware will react to this kind of degenerated 
+			   buffer */
+			break;
+		}
+		skb->dev = net_dev;
+		sis_priv->rx_skbuff[i] = skb;
+		sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE;
+		sis_priv->rx_ring[i].bufptr = virt_to_bus(skb->tail);
+	}
+	sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC);
+
+	/* load Receive Descriptor Register */
+	outl(virt_to_bus(&sis_priv->rx_ring[0]), ioaddr + rxdp);
+	if (sis900_debug > 2)
+		printk(KERN_INFO "%s: RX descriptor register loaded with: %8.8x\n", 
+		       net_dev->name, inl(ioaddr + rxdp));
+}
+/* on each timer ticks we check two things, Link Status (ON/OFF) and 
+   Link Mode (10/100/Full/Half)
+ */
 static void sis900_timer(unsigned long data)
 {
-        struct net_device *dev = (struct net_device *)data;
-        struct sis900_private *tp = (struct sis900_private *)dev->priv;
-        int next_tick = 0;
-        u16 status;
-
-        if (!tp->LinkOn) {
-                status = mdio_read(dev, tp->phys[tp->phy_idx], MII_STATUS);
-		if (status & MIISTAT_LINK) {
-                	elPMDreadMode(dev, tp->phys[tp->phy_idx],
-                                        &tp->speeds, &tp->full_duplex);
-			tp->LinkOn = TRUE;
-                        printk(KERN_INFO "%s: Media Link On %s%s-duplex ",
-                                   dev->name,
-                                   tp->speeds == HW_SPEED_100_MBPS ?
-						"100mbps " : "10mbps ",
-                                   tp->full_duplex==FDX_CAPABLE_FULL_SELECTED ?
-						"full" : "half");
+	struct net_device *net_dev = (struct net_device *)data;
+	struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
+	struct mii_phy *mii_phy = sis_priv->mii;
+	static int next_tick = 5*HZ;
+	u16 status;
+
+	status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);
+
+	/* current mii phy is failed to link, try another one */
+	while (!(status & MII_STAT_LINK)) {		
+		if (mii_phy->next == NULL) { 
+			if (sis_priv->LinkOn) {
+				/* link stat change from ON to OFF */
+				next_tick = HZ;
+				sis_priv->LinkOn = FALSE;
+				printk(KERN_INFO "%s: Media Link Off\n",
+				       net_dev->name);
+			}
+			sis_priv->timer.expires = jiffies + next_tick;
+			add_timer(&sis_priv->timer);
+			return;
 		}
-        } else { // previous link on
-                status = mdio_read(dev, tp->phys[tp->phy_idx], MII_STATUS);
-		if (!(status & MIISTAT_LINK)) {
-			tp->LinkOn = FALSE;
-                        printk(KERN_INFO "%s: Media Link Off\n", dev->name);
+		mii_phy = mii_phy->next;
+		status = mdio_read(net_dev, mii_phy->phy_addr, MII_STATUS);
+	}
+
+	if (!sis_priv->LinkOn) {
+		/* link stat change forn OFF to ON, read and report link mode */
+		sis_priv->LinkOn = TRUE;
+		next_tick = 5*HZ;
+		/* change what cur_phy means */
+		if (mii_phy->phy_addr != sis_priv->cur_phy) {
+			printk(KERN_INFO "%s: Changing transceiver to %s\n", net_dev->name,
+			       mii_phy->chip_info->name);
+			status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL);
+			mdio_write(net_dev, sis_priv->cur_phy, 
+				   MII_CONTROL, status | MII_CNTL_ISOLATE);
+			status = mdio_read(net_dev, mii_phy->phy_addr, MII_CONTROL);
+			mdio_write(net_dev, mii_phy->phy_addr, 
+				   MII_CONTROL, status & ~MII_CNTL_ISOLATE);
+			sis_priv->cur_phy = mii_phy->phy_addr;
 		}
-        }
-        next_tick = 2*HZ;
+		sis900_check_mode(net_dev, mii_phy);
+	}
 
-        if (next_tick) {
-                tp->timer.expires = RUN_AT(next_tick);
-                add_timer(&tp->timer);
-        }
-}
-
-static void sis900_tx_timeout(struct net_device *dev)
-{
-        struct sis900_private *tp = (struct sis900_private *)dev->priv;
-        long ioaddr = dev->base_addr;
-        int i;
-
-        if (sis900_debug > 0)
-                printk(KERN_INFO "%s: Transmit timeout, status %2.2x %4.4x \n",
-                           dev->name, inl(ioaddr + cr), inl(ioaddr + isr));
-
-        /* Disable interrupts by clearing the interrupt mask. */
-        outl(0x0000, ioaddr + imr);
-
-        /* Emit info to figure out what went wrong. */
-	if (sis900_debug > 1) {
-	        printk(KERN_INFO "%s:Tx queue start entry %d dirty entry %d.\n",
-                		   dev->name, tp->cur_tx, tp->dirty_tx);
-        	for (i = 0; i < NUM_TX_DESC; i++) 
-                	printk(KERN_INFO "%s:  Tx descriptor %d is %8.8x.%s\n",
-                        	dev->name, i, (unsigned int)&tp->tx_buf[i],
-                     		i == tp->dirty_tx % NUM_TX_DESC ?
-                      		" (queue head)" : "");
-	}
-
-        /* Soft reset the chip. */
-        //outb(RESET, ioaddr + cr);
-        /* Check that the chip has finished the reset. */
-        /*
-        for (i = 1000; i > 0; i--)
-                if ((inb(ioaddr + cr) & RESET) == 0)
-                        break;
-        */
-
-        tp->cur_rx = 0; 
-        /* Must enable Tx/Rx before setting transfer thresholds! */
-        /*
-        set_rx_mode(dev);
-        */
-        {       /* Save the unsent Tx packets. */
-                struct sk_buff *saved_skb[NUM_TX_DESC], *skb;
-                int j;
-                for (j = 0; tp->cur_tx - tp->dirty_tx > 0 ; j++, tp->dirty_tx++)
-                        saved_skb[j]=tp->tx_skbuff[tp->dirty_tx % NUM_TX_DESC];
-                tp->dirty_tx = tp->cur_tx = 0;
-
-                for (i = 0; i < j; i++) {
-                        skb = tp->tx_skbuff[i] = saved_skb[i];
-                        /* Always alignment */
-                        memcpy((unsigned char*)(tp->tx_buf[i].buf),
-                                                skb->data, skb->len);
-                        tp->tx_buf[i].cmdsts = OWN | skb->len;
-                        /* Note: the chip doesn't have auto-pad! */
-                        /*
-                        outl(tp->tx_flag|(skb->len>=ETH_ZLEN?skb->len:ETH_ZLEN),
-                                 ioaddr + TxStatus0 + i*4);
-                        */
-                }
-                outl(TxENA, ioaddr + cr);
-                tp->cur_tx = i;
-                while (i < NUM_TX_DESC)
-                        tp->tx_skbuff[i++] = 0;
-                if (tp->cur_tx - tp->dirty_tx < NUM_TX_DESC) {/* Typical path */
-                        dev->tbusy = 0;
-                        tp->tx_full = 0;
-                } else {
-                        tp->tx_full = 1;
-                }
-        }
-
-        dev->trans_start = jiffies;
-        tp->stats.tx_errors++;
-        /* Enable all known interrupts by setting the interrupt mask. */
-        outl((RxOK|RxERR|RxORN|RxSOVR|TxOK|TxERR|TxURN), ioaddr + imr);
-        return;
+	sis_priv->timer.expires = jiffies + next_tick;
+	add_timer(&sis_priv->timer);
 }
+static void sis900_check_mode (struct net_device *net_dev, struct mii_phy *mii_phy)
+{
+	struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
+	long ioaddr = net_dev->base_addr;
+	int speed, duplex;
+	u32 tx_flags = 0, rx_flags = 0;
 
+	mii_phy->chip_info->read_mode(net_dev, sis_priv->cur_phy, &speed, &duplex);
 
-/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void
-sis900_init_ring(struct net_device *dev)
+	tx_flags = TxATP | (TX_DMA_BURST << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
+	rx_flags = RX_DMA_BURST << RxMXDMA_shift;
+
+	if (speed == HW_SPEED_HOME || speed == HW_SPEED_10_MBPS ) {
+		rx_flags |= (RxDRNT_10 << RxDRNT_shift);
+		tx_flags |= (TxDRNT_10 << TxDRNT_shift);
+	}
+	else {
+		rx_flags |= (RxDRNT_100 << RxDRNT_shift);
+		tx_flags |= (TxDRNT_100 << TxDRNT_shift);
+	}
+
+	if (duplex == FDX_CAPABLE_FULL_SELECTED) {
+		tx_flags |= (TxCSI | TxHBI);
+		rx_flags |= RxATX;
+	}
+
+	outl (tx_flags, ioaddr + txcfg);
+	outl (rx_flags, ioaddr + rxcfg);
+}
+static void sis900_read_mode(struct net_device *net_dev, int phy_addr, int *speed, int *duplex)
 {
-        struct sis900_private *tp = (struct sis900_private *)dev->priv;
-        int i;
+	int i = 0;
+	u32 status;
+	
+	/* STSOUT register is Latched on Transition, read operation updates it */
+	while (i++ < 2)
+		status = mdio_read(net_dev, phy_addr, MII_STSOUT);
+
+	if (status & MII_STSOUT_SPD)
+		*speed = HW_SPEED_100_MBPS;
+	else
+		*speed = HW_SPEED_10_MBPS;
+
+	if (status & MII_STSOUT_DPLX)
+		*duplex = FDX_CAPABLE_FULL_SELECTED;
+	else
+		*duplex = FDX_CAPABLE_HALF_SELECTED;
+
+	if (status & MII_STSOUT_LINK_FAIL)
+		printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
+	else
+		printk(KERN_INFO "%s: Media Link On %s %s-duplex \n", 
+		       net_dev->name,
+		       *speed == HW_SPEED_100_MBPS ? 
+		       "100mbps" : "10mbps",
+		       *duplex == FDX_CAPABLE_FULL_SELECTED ?
+		       "full" : "half");
+}
+static void amd79c901_read_mode(struct net_device *net_dev, int phy_addr, int *speed, int *duplex)
+{
+	int i;
+	u16 status;
+	
+	for (i = 0; i < 2; i++)
+		status = mdio_read(net_dev, phy_addr, MII_STATUS);
+
+	if (status & MII_STAT_CAN_AUTO) {
+		/* 10BASE-T PHY */
+		for (i = 0; i < 2; i++)
+			status = mdio_read(net_dev, phy_addr, MII_STATUS_SUMMARY);
+		if (status & MII_STSSUM_SPD)
+			*speed = HW_SPEED_100_MBPS;
+		else
+			*speed = HW_SPEED_10_MBPS;
+		if (status & MII_STSSUM_DPLX)
+			*duplex = FDX_CAPABLE_FULL_SELECTED;
+		else
+			*duplex = FDX_CAPABLE_HALF_SELECTED;
+
+		if (status & MII_STSSUM_LINK)
+			printk(KERN_INFO "%s: Media Link On %s %s-duplex \n", 
+			       net_dev->name,
+			       *speed == HW_SPEED_100_MBPS ? 
+			       "100mbps" : "10mbps",
+			       *duplex == FDX_CAPABLE_FULL_SELECTED ?
+			       "full" : "half");
+		else
+			printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
+			
+	}
+	else {
+		/* HomePNA */
+		*speed = HW_SPEED_HOME;
+		*duplex = FDX_CAPABLE_HALF_SELECTED;
+		if (status & MII_STAT_LINK)
+			printk(KERN_INFO "%s: Media Link On 1mbps half-duplex \n", 
+			       net_dev->name);
+		else
+			printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
+	}
+}
+static void sis900_tx_timeout(struct net_device *net_dev)
+{
+	struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
+	long ioaddr = net_dev->base_addr;
+
+	printk(KERN_INFO "%s: Transmit timeout, status %8.8x %8.8x \n",
+	       net_dev->name, inl(ioaddr + cr), inl(ioaddr + isr));
+	
+	/* Disable interrupts by clearing the interrupt mask. */
+	outl(0x0000, ioaddr + imr);
 
-        tp->tx_full = 0;
-        tp->cur_rx = 0;
-        tp->dirty_tx = tp->cur_tx = 0;
-
-        /* Tx Buffer */
-        for (i = 0; i < NUM_TX_DESC; i++) {
-                tp->tx_skbuff[i] = 0;
-                tp->tx_buf[i].buf = &tp->tx_bufs[i*TX_BUF_SIZE];
-                tp->tx_buf[i].bufPhys =
-                                virt_to_bus(&tp->tx_bufs[i*TX_BUF_SIZE]);
-        }
-
-        /* Tx Descriptor */
-        for (i = 0; i< NUM_TX_DESC; i++) {
-                tp->tx_buf[i].llink = (u32)
-                        &(tp->tx_buf[((i+1) < NUM_TX_DESC) ? (i+1) : 0]);
-                tp->tx_buf[i].plink = (u32)
-                        virt_to_bus(&(tp->tx_buf[((i+1) < NUM_TX_DESC) ?
-                                (i+1) : 0].plink));
-                tp->tx_buf[i].physAddr=
-                                virt_to_bus(&(tp->tx_buf[i].plink));
-                tp->tx_buf[i].cmdsts=0;
-        }
-
-        /* Rx Buffer */
-        for (i = 0; i < NUM_RX_DESC; i++) {
-                tp->rx_buf[i].buf = &tp->rx_bufs[i*RX_BUF_SIZE];
-                tp->rx_buf[i].bufPhys =
-                                virt_to_bus(&tp->rx_bufs[i*RX_BUF_SIZE]);
-        }
-
-        /* Rx Descriptor */
-        for (i = 0; i< NUM_RX_DESC; i++) {
-                tp->rx_buf[i].llink = (u32)
-                        &(tp->rx_buf[((i+1) < NUM_RX_DESC) ? (i+1) : 0]);
-                tp->rx_buf[i].plink = (u32)
-                        virt_to_bus(&(tp->rx_buf[((i+1) < NUM_RX_DESC) ?
-                                (i+1) : 0].plink));
-                tp->rx_buf[i].physAddr=
-                                virt_to_bus(&(tp->rx_buf[i].plink));
-                tp->rx_buf[i].cmdsts=RX_BUF_SIZE;
-        }
+	sis_priv->cur_rx = 0;
+	net_dev->trans_start = jiffies;
+	sis_priv->stats.tx_errors++;
+
+	/* FIXME: Should we restart the transmission thread here  ?? */
+
+	/* Enable all known interrupts by setting the interrupt mask. */
+	outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxOK), ioaddr + imr);
+	return;
 }
 
 static int
-sis900_start_xmit(struct sk_buff *skb, struct net_device *dev)
+sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
 {
-        struct sis900_private *tp = (struct sis900_private *)dev->priv;
-        long ioaddr = dev->base_addr;
-        int entry;
-
-        /* Block a timer-based transmit from overlapping.  This could better be
-           done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
-        if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
-                if (jiffies - dev->trans_start < TX_TIMEOUT)
-                        return 1;
-                sis900_tx_timeout(dev);
-                return 1;
-        }
-
-        /* Calculate the next Tx descriptor entry. ????? */
-        entry = tp->cur_tx % NUM_TX_DESC;
-
-        tp->tx_skbuff[entry] = skb;
-
-        if (sis900_debug > 5) {
-                int i;
-                printk(KERN_INFO "%s: SKB Tx Frame contents:(len=%d)",
-                                                dev->name,skb->len);
-
-                for (i = 0; i < skb->len; i++) {
-                        printk("%2.2x ",
-                        (u8)skb->data[i]);
-                }
-                printk(".\n");
-        }
-
-        memcpy(tp->tx_buf[entry].buf,
-                                skb->data, skb->len);
-
-        tp->tx_buf[entry].cmdsts=(OWN | skb->len);
-
-        //tp->tx_buf[entry].plink = 0;
-        outl(TxENA, ioaddr + cr);
-        if (++tp->cur_tx - tp->dirty_tx < NUM_TX_DESC) {/* Typical path */
-                clear_bit(0, (void*)&dev->tbusy);
-        } else {
-                tp->tx_full = 1;
-        }
-
-        /* Note: the chip doesn't have auto-pad! */
-
-        dev->trans_start = jiffies;
-        if (sis900_debug > 4)
-                printk(KERN_INFO "%s: Queued Tx packet at "
-                                "%p size %d to slot %d.\n",
-                           dev->name, skb->data, (int)skb->len, entry);
+	struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
+	long ioaddr = net_dev->base_addr;
+	unsigned int  entry;
+
+	/* test tbusy to see if we have timeout situation then set it */
+	if (test_and_set_bit(0, (void*)&net_dev->tbusy) != 0) {
+		if (jiffies - net_dev->trans_start > TX_TIMEOUT)
+			sis900_tx_timeout(net_dev);
+		return 1;
+	}
+
+	/* Calculate the next Tx descriptor entry. */
+	entry = sis_priv->cur_tx % NUM_TX_DESC;
+	sis_priv->tx_skbuff[entry] = skb;
+
+	/* set the transmit buffer descriptor and enable Transmit State Machine */
+	sis_priv->tx_ring[entry].bufptr = virt_to_bus(skb->data);
+	sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len);
+	outl(TxENA, ioaddr + cr);
+
+	if (++sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC) {
+		/* Typical path, clear tbusy to indicate more 
+		   transmission is possible */
+		clear_bit(0, (void*)&net_dev->tbusy);
+	} else {
+		/* no more transmit descriptor avaiable, tbusy remain set */
+		sis_priv->tx_full = 1;
+	}
 
-        return 0;
+	net_dev->trans_start = jiffies;
+
+	if (sis900_debug > 3)
+		printk(KERN_INFO "%s: Queued Tx packet at %p size %d "
+		       "to slot %d.\n",
+		       net_dev->name, skb->data, (int)skb->len, entry);
+
+	return 0;
 }
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
 static void sis900_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
 {
-        struct net_device *dev = (struct net_device *)dev_instance;
-        struct sis900_private *tp = (struct sis900_private *)dev->priv;
-        int boguscnt = max_interrupt_work;
-        int status;
-        long ioaddr = dev->base_addr;
+	struct net_device *net_dev = (struct net_device *)dev_instance;
+	int boguscnt = max_interrupt_work;
+	long ioaddr = net_dev->base_addr;
+	u32 status;
 
 #if defined(__i386__)
-        /* A lock to prevent simultaneous entry bug on Intel SMP machines. */
-        if (test_and_set_bit(0, (void*)&dev->interrupt)) {
-                printk(KERN_INFO "%s: SMP simultaneous entry of "
-                                "an interrupt handler.\n", dev->name);
-                dev->interrupt = 0;     /* Avoid halting machine. */
-                return;
-        }
+	/* A lock to prevent simultaneous entry bug on Intel SMP machines. */
+	if (test_and_set_bit(0, (void*)&net_dev->interrupt)) {
+		printk(KERN_INFO "%s: SMP simultaneous entry of "
+		       "an interrupt handler.\n", net_dev->name);
+		net_dev->interrupt = 0;     /* Avoid halting machine. */
+		return;
+	}
 #else
-        if (dev->interrupt) {
-                printk(KERN_INFO "%s: Re-entering the "
-                                "interrupt handler.\n", dev->name);
-                return;
-        }
-        dev->interrupt = 1;
-#endif
-
-        do {
-                status = inl(ioaddr + isr);
-                /* Acknowledge all of the current interrupt sources ASAP. */
-                outl(status, ioaddr + isr); // ?????
-
-                if (sis900_debug > 4)
-                        printk(KERN_INFO "%s: interrupt  status=%#4.4x "
-                                "new intstat=%#4.4x.\n",
-                                dev->name, status, inl(ioaddr + isr));
-
-                if ((status & (TxURN|TxERR|TxOK | RxORN|RxERR|RxOK)) == 0) {
-                        break;
-                }
-
-                if (status & (RxOK|RxORN|RxERR)) /* Rx interrupt */
-                        sis900_rx(dev);
-
-                if (status & (TxOK | TxERR)) {
-                        unsigned int dirty_tx;
-
-                        if (sis900_debug > 5) {
-                                printk(KERN_INFO "TxOK:tp->cur_tx:%d,"
-                                                "tp->dirty_tx:%x\n",
-                                        tp->cur_tx, tp->dirty_tx);
-                        }
-                        for (dirty_tx = tp->dirty_tx; dirty_tx < tp->cur_tx;
-                                dirty_tx++)
-                        {
-                                int i;
-                                int entry = dirty_tx % NUM_TX_DESC;
-                                int txstatus = tp->tx_buf[entry].cmdsts;
-
-                                if (sis900_debug > 4) {
-                                        printk(KERN_INFO "%s:     Tx Frame contents:"
-                                                "(len=%d)",
-                                                dev->name, (txstatus & DSIZE));
-
-                                        for (i = 0; i < (txstatus & DSIZE) ;
-                                                                        i++) {
-                                                printk("%2.2x ",
-                                                (u8)(tp->tx_buf[entry].buf[i]));
-                                        }
-                                        printk(".\n");
-                                }
-                                if ( ! (txstatus & (OK | UNDERRUN)))
-                                {
-                                        if (sis900_debug > 1)
-                                                printk(KERN_INFO "Tx NOT (OK,"
-                                                        "UnderRun)\n");
-                                        break;  /* It still hasn't been Txed */
-                                }
-
-                                /* Note: TxCarrierLost is always asserted
-                                                at 100mbps.                 */
-                                if (txstatus & (OWCOLL | ABORT)) {
-                                        /* There was an major error, log it. */
-                                        if (sis900_debug > 1)
-                                                printk(KERN_INFO "Tx Out of "
-                                                        " Window,Abort\n");
-#ifndef final_version
-                                        if (sis900_debug > 1)
-                                                printk(KERN_INFO "%s: Transmit "
-                                                    "error, Tx status %8.8x.\n",
-                                                           dev->name, txstatus);
-#endif
-                                        tp->stats.tx_errors++;
-                                        if (txstatus & ABORT) {
-                                                tp->stats.tx_aborted_errors++;
-                                        }
-                                        if (txstatus & NOCARRIER)
-                                                tp->stats.tx_carrier_errors++;
-                                        if (txstatus & OWCOLL)
-                                                tp->stats.tx_window_errors++;
-#ifdef ETHER_STATS
-                                        if ((txstatus & COLCNT)==COLCNT)
-                                                tp->stats.collisions16++;
-#endif
-                                } else {
-#ifdef ETHER_STATS
-                                        /* No count for tp->stats.tx_deferred */
-#endif
-                                        if (txstatus & UNDERRUN) {
-                                           if (sis900_debug > 2)
-                                             printk(KERN_INFO "Tx UnderRun\n");
-                                        }
-                                        tp->stats.collisions +=
-                                                        (txstatus >> 16) & 0xF;
-#if LINUX_VERSION_CODE > 0x20119
-                                        tp->stats.tx_bytes += txstatus & DSIZE;
-#endif
-                                        if (sis900_debug > 2)
-                                           printk(KERN_INFO "Tx Transmit OK\n");
-                                        tp->stats.tx_packets++;
-                                }
-
-                                /* Free the original skb. */
-                                if (sis900_debug > 2)
-                                        printk(KERN_INFO "Free original skb\n");
-                                dev_free_skb(tp->tx_skbuff[entry]);
-                                tp->tx_skbuff[entry] = 0;
-                        } // for dirty
-
-#ifndef final_version
-                        if (tp->cur_tx - dirty_tx > NUM_TX_DESC) {
-                                printk(KERN_INFO"%s: Out-of-sync dirty pointer,"
-                                                " %d vs. %d, full=%d.\n",
-                                                dev->name, dirty_tx,
-                                                tp->cur_tx, tp->tx_full);
-                                dirty_tx += NUM_TX_DESC;
-                        }
+	if (net_dev->interrupt) {
+		printk(KERN_INFO "%s: Re-entering the interrupt handler.\n", 
+		       net_dev->name);
+		return;
+	}
+	net_dev->interrupt = 1;
 #endif
 
-                        if (tp->tx_full && dirty_tx > tp->cur_tx-NUM_TX_DESC) {
-                                /* The ring is no longer full, clear tbusy. */
-				if (sis900_debug > 3)
-                                   printk(KERN_INFO "Tx Ring NO LONGER Full\n");
-                                tp->tx_full = 0;
-                                dev->tbusy = 0;
-                                mark_bh(NET_BH);
-                        }
-
-                        tp->dirty_tx = dirty_tx;
-                        if (sis900_debug > 2)
-                           printk(KERN_INFO "TxOK,tp->cur_tx:%d,tp->dirty:%d\n",
-                                                tp->cur_tx, tp->dirty_tx);
-                } // if (TxOK | TxERR)
-
-                /* Check uncommon events with one test. */
-                if (status & (RxORN | TxERR | RxERR)) {
-                        if (sis900_debug > 2)
-                                printk(KERN_INFO "%s: Abnormal interrupt,"
-                                        "status %8.8x.\n", dev->name, status);
-
-                        if (status == 0xffffffff)
-                                break;
-                        if (status & (RxORN | RxERR))
-                                tp->stats.rx_errors++;
-
-
-                        if (status & RxORN) {
-                                tp->stats.rx_over_errors++;
-                        }
-                }
-                if (--boguscnt < 0) {
-                        printk(KERN_INFO "%s: Too much work at interrupt, "
-                                   "IntrStatus=0x%4.4x.\n",
-                                   dev->name, status);
-                        break;
-                }
-        } while (1);
-
-        if (sis900_debug > 3)
-                printk(KERN_INFO "%s: exiting interrupt, intr_status=%#4.4x.\n",
-                           dev->name, inl(ioaddr + isr));
-
+	do {
+		status = inl(ioaddr + isr);
+		
+		if (sis900_debug > 3)
+			printk(KERN_INFO "%s: entering interrupt, "
+			       "original status = %#8.8x, "
+			       "new status = %#8.8x.\n",
+			       net_dev->name, status, inl(ioaddr + isr));
+
+		if ((status & (HIBERR|TxURN|TxERR|TxOK|RxORN|RxERR|RxOK)) == 0)
+			/* nothing intresting happened */
+			break;
+
+		/* why dow't we break after Tx/Rx case ?? keyword: full-duplex */
+		if (status & (RxORN | RxERR | RxOK))
+			/* Rx interrupt */
+			sis900_rx(net_dev);
+
+		if (status & (TxURN | TxERR | TxOK))
+			/* Tx interrupt */
+			sis900_finish_xmit(net_dev);
+
+		/* something strange happened !!! */
+		if (status & HIBERR) {
+			printk(KERN_INFO "%s: Abnormal interrupt,"
+			       "status %#8.8x.\n", net_dev->name, status);
+			break;
+		}
+		if (--boguscnt < 0) {
+			printk(KERN_INFO "%s: Too much work at interrupt, "
+			       "interrupt status = %#8.8x.\n",
+			       net_dev->name, status);
+			break;
+		}
+	} while (1);
+	
+	if (sis900_debug > 3)
+		printk(KERN_INFO "%s: exiting interrupt, "
+		       "interrupt status = 0x%#8.8x.\n",
+		       net_dev->name, inl(ioaddr + isr));
+	
 #if defined(__i386__)
-        clear_bit(0, (void*)&dev->interrupt);
+	clear_bit(0, (void*)&net_dev->interrupt);
 #else
-        dev->interrupt = 0;
+	net_dev->interrupt = 0;
 #endif
-        return;
+	return;
 }
 
-/* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the
-   field alignments and semantics. */
-static int sis900_rx(struct net_device *dev)
-{
-        struct sis900_private *tp = (struct sis900_private *)dev->priv;
-        long ioaddr = dev->base_addr;
-        u16 cur_rx = tp->cur_rx % NUM_RX_DESC;
-        int rx_status=tp->rx_buf[cur_rx].cmdsts;
-
-        if (sis900_debug > 4)
-                printk(KERN_INFO "%s: sis900_rx, current %4.4x,"
-                                " rx status=%8.8x\n",
-                                dev->name, cur_rx,
-                                rx_status);
-
-        while (rx_status & OWN) {
-                int rx_size = rx_status & DSIZE;
-                rx_size -= CRC_SIZE;
-
-                if (sis900_debug > 4) {
-                        int i;
-                        printk(KERN_INFO "%s:  sis900_rx, rx status %8.8x,"
-                                        " size %4.4x, cur %4.4x.\n",
-                                   dev->name, rx_status, rx_size, cur_rx);
-                        printk(KERN_INFO "%s: Rx Frame contents:", dev->name);
-
-                        for (i = 0; i < rx_size; i++) {
-                                printk("%2.2x ",
-                                (u8)(tp->rx_buf[cur_rx].buf[i]));
-                        }
-
-                        printk(".\n");
-                }
-                if (rx_status & TOOLONG) {
-                        if (sis900_debug > 1)
-                                printk(KERN_INFO "%s: Oversized Ethernet frame,"
-                                                " status %4.4x!\n",
-                                           dev->name, rx_status);
-                        tp->stats.rx_length_errors++;
-                } else if (rx_status & (RXISERR | RUNT | CRCERR | FAERR)) {
-                        if (sis900_debug > 1)
-                                printk(KERN_INFO"%s: Ethernet frame had errors,"
-                                        " status %4.4x.\n",
-                                        dev->name, rx_status);
-                        tp->stats.rx_errors++;
-                        if (rx_status & (RXISERR | FAERR))
-                                tp->stats.rx_frame_errors++;
-                        if (rx_status & (RUNT | TOOLONG))
-                                tp->stats.rx_length_errors++;
-                        if (rx_status & CRCERR) tp->stats.rx_crc_errors++;
-                } else {
-                        /* Malloc up new buffer, compatible with net-2e. */
-                        /* Omit the four octet CRC from the length. */
-                        struct sk_buff *skb;
-
-                        skb = dev_alloc_skb(rx_size + 2);
-                        if (skb == NULL) {
-                                printk(KERN_INFO "%s: Memory squeeze,"
-                                                "deferring packet.\n",
-                                                dev->name);
-                                /* We should check that some rx space is free.
-                                   If not,
-                                   free one and mark stats->rx_dropped++. */
-                                tp->stats.rx_dropped++;
-                                tp->rx_buf[cur_rx].cmdsts = RX_BUF_SIZE;
-                                break;
-                        }
-                        skb->dev = dev;
-                        skb_reserve(skb, 2); /* 16 byte align the IP fields. */
-                        if (rx_size+CRC_SIZE > RX_BUF_SIZE) {
-                                /*
-                                int semi_count = RX_BUF_LEN - ring_offset - 4;
-                                memcpy(skb_put(skb, semi_count),
-                                        &rx_bufs[ring_offset + 4], semi_count);
-                                memcpy(skb_put(skb, rx_size-semi_count),
-                                        rx_bufs, rx_size - semi_count);
-                                if (sis900_debug > 4) {
-                                        int i;
-                                        printk(KERN_DEBUG"%s:  Frame wrap @%d",
-                                                   dev->name, semi_count);
-                                        for (i = 0; i < 16; i++)
-                                                printk(" %2.2x", rx_bufs[i]);
-                                        printk(".\n");
-                                        memset(rx_bufs, 0xcc, 16);
-                                }
-                                */
-                        } else {
-#if 0  /* USE_IP_COPYSUM */
-                                eth_copy_and_sum(skb,
-                                   tp->rx_buf[cur_rx].buf, rx_size, 0);
-                                skb_put(skb, rx_size);
-#else
-                                memcpy(skb_put(skb, rx_size),
-                                        tp->rx_buf[cur_rx].buf, rx_size);
-#endif
-                        }
-                        skb->protocol = eth_type_trans(skb, dev);
-                        netif_rx(skb);
-#if LINUX_VERSION_CODE > 0x20119
-                        tp->stats.rx_bytes += rx_size;
-#endif
-                        tp->stats.rx_packets++;
-                }
-                tp->rx_buf[cur_rx].cmdsts = RX_BUF_SIZE;
-
-                cur_rx = ((cur_rx+1) % NUM_RX_DESC);
-                rx_status = tp->rx_buf[cur_rx].cmdsts;
-        } // while
-        if (sis900_debug > 4)
-                printk(KERN_INFO "%s: Done sis900_rx(), current %4.4x "
-                                "Cmd %2.2x.\n",
-                           dev->name, cur_rx,
-                           inb(ioaddr + cr));
-        tp->cur_rx = cur_rx;
-        return 0;
+/* Process receive interrupt events, put buffer to higher layer and refill buffer pool 
+   Note: This fucntion is called by interrupt handler, don't do "too much" work here */
+static int sis900_rx(struct net_device *net_dev)
+{
+	struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
+	long ioaddr = net_dev->base_addr;
+	unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC;
+	u32 rx_status = sis_priv->rx_ring[entry].cmdsts;
+	
+	if (sis900_debug > 3)
+		printk(KERN_INFO "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
+		       "status:0x%8.8x\n",
+		       sis_priv->cur_rx, sis_priv->dirty_rx,rx_status);
+	
+	while (rx_status & OWN) {
+		unsigned int rx_size;
+		
+		rx_size = (rx_status & DSIZE) - CRC_SIZE;
+		
+		if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
+			/* corrupted packet received */
+			if (sis900_debug > 3)
+				printk(KERN_INFO "%s: Corrupted packet "
+				       "received, buffer status = 0x%8.8x.\n",
+				       net_dev->name, rx_status);
+			sis_priv->stats.rx_errors++;
+			if (rx_status & OVERRUN)
+				sis_priv->stats.rx_over_errors++;
+			if (rx_status & (TOOLONG|RUNT))
+				sis_priv->stats.rx_length_errors++;
+			if (rx_status & (RXISERR | FAERR))
+				sis_priv->stats.rx_frame_errors++;
+			if (rx_status & CRCERR) 
+				sis_priv->stats.rx_crc_errors++;
+			/* reset buffer descriptor state */
+			sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
+		} else {
+			struct sk_buff * skb;
+			
+			if (sis_priv->rx_skbuff[entry] == NULL) {
+				printk(KERN_INFO "%s: NULL pointer " 
+				       "encountered in Rx ring, skipping\n",
+				       net_dev->name);
+				break;			
+			}
+			skb = sis_priv->rx_skbuff[entry];
+			sis_priv->rx_skbuff[entry] = NULL;
+			/* reset buffer descriptor state */
+			sis_priv->rx_ring[entry].cmdsts = 0;
+			sis_priv->rx_ring[entry].bufptr = 0;
+			
+			skb_put(skb, rx_size);
+			skb->protocol = eth_type_trans(skb, net_dev);
+			netif_rx(skb);
+			
+			if ((rx_status & BCAST) == MCAST)
+				sis_priv->stats.multicast++;
+			net_dev->last_rx = jiffies;
+			sis_priv->stats.rx_bytes += rx_size;
+			sis_priv->stats.rx_packets++;
+		}
+		sis_priv->cur_rx++;
+		entry = sis_priv->cur_rx % NUM_RX_DESC;
+		rx_status = sis_priv->rx_ring[entry].cmdsts;
+	} // while
+	
+	/* refill the Rx buffer, what if the rate of refilling is slower than 
+	   consuming ?? */
+	for (;sis_priv->cur_rx - sis_priv->dirty_rx > 0; sis_priv->dirty_rx++) {
+		struct sk_buff *skb;
+		
+		entry = sis_priv->dirty_rx % NUM_RX_DESC;
+		
+		if (sis_priv->rx_skbuff[entry] == NULL) {
+			if ((skb = dev_alloc_skb(RX_BUF_SIZE)) == NULL) {
+				/* not enough memory for skbuff, this makes a "hole"
+				   on the buffer ring, it is not clear how the 
+				   hardware will react to this kind of degenerated 
+				   buffer */
+				printk(KERN_INFO "%s: Memory squeeze,"
+				       "deferring packet.\n",
+				       net_dev->name);
+				sis_priv->stats.rx_dropped++;
+				break;
+			}
+			skb->dev = net_dev;
+			sis_priv->rx_skbuff[entry] = skb;
+			sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE;
+			sis_priv->rx_ring[entry].bufptr = virt_to_bus(skb->tail);
+		}
+	}
+	/* re-enable the potentially idle receive state matchine */
+	outl(RxENA , ioaddr + cr );
+	
+	return 0;
 }
 
-static int
-sis900_close(struct net_device *dev)
+/* finish up transmission of packets, check for error condition and free skbuff etc.
+   Note: This fucntion is called by interrupt handler, don't do "too much" work here */
+static void sis900_finish_xmit (struct net_device *net_dev)
 {
-        long ioaddr = dev->base_addr;
-        struct sis900_private *tp = (struct sis900_private *)dev->priv;
-        int i;
-
-        dev->start = 0;
-        dev->tbusy = 1;
+	struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
+	
+	for (; sis_priv->dirty_tx < sis_priv->cur_tx; sis_priv->dirty_tx++) {
+		unsigned int entry;
+		u32 tx_status;
+		
+		entry = sis_priv->dirty_tx % NUM_TX_DESC;
+		tx_status = sis_priv->tx_ring[entry].cmdsts;
+		
+		if (tx_status & OWN) {
+			/* The packet is not transmited yet (owned by hardware) ! */
+			break;
+		}
+		
+		if (tx_status & (ABORT | UNDERRUN | OWCOLL)) {
+			/* packet unsuccessfully transmited */
+			if (sis900_debug > 3)
+				printk(KERN_INFO "%s: Transmit "
+				       "error, Tx status %8.8x.\n",
+				       net_dev->name, tx_status);
+			sis_priv->stats.tx_errors++;
+			if (tx_status & UNDERRUN)
+				sis_priv->stats.tx_fifo_errors++;
+			if (tx_status & ABORT)
+				sis_priv->stats.tx_aborted_errors++;
+			if (tx_status & NOCARRIER)
+				sis_priv->stats.tx_carrier_errors++;
+			if (tx_status & OWCOLL)
+				sis_priv->stats.tx_window_errors++;
+		} else {
+			/* packet successfully transmited */
+			if (sis900_debug > 3)
+				printk(KERN_INFO "Tx Transmit OK\n");
+			sis_priv->stats.collisions += (tx_status & COLCNT) >> 16;
+			sis_priv->stats.tx_bytes += tx_status & DSIZE;
+			sis_priv->stats.tx_packets++;
+		}
+		/* Free the original skb. */
+		dev_kfree_skb(sis_priv->tx_skbuff[entry]);
+		sis_priv->tx_skbuff[entry] = NULL;
+		sis_priv->tx_ring[entry].bufptr = 0;
+		sis_priv->tx_ring[entry].cmdsts = 0;
+	}
+	
+	if (sis_priv->tx_full && net_dev->tbusy && 
+	    sis_priv->cur_tx - sis_priv->dirty_tx < NUM_TX_DESC - 4) {
+		/* The ring is no longer full, clear tbusy, tx_full and schedule 
+		   more transmission by marking NET_BH */
+		sis_priv->tx_full = 0;
+		clear_bit(0, (void *)&net_dev->tbusy);
+		mark_bh(NET_BH);
+	}
+}
 
-        if (sis900_debug > 1)
-                printk(KERN_DEBUG"%s: Shutting down ethercard, status was 0x%4.4x.\n",
-                           dev->name, inl(ioaddr + isr));
+static int
+sis900_close(struct net_device *net_dev)
+{
+	long ioaddr = net_dev->base_addr;
+	struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
+	int i;
+	
+	net_dev->start = 0;
+	net_dev->tbusy = 1;
 
-        /* Disable interrupts by clearing the interrupt mask. */
-        outl(0x0000, ioaddr + imr);
+	/* Disable interrupts by clearing the interrupt mask. */
+	outl(0x0000, ioaddr + imr);
+	outl(0x0000, ioaddr + ier);
 
-        /* Stop the chip's Tx and Rx DMA processes. */
-        outl(0x00, ioaddr + cr);
+	/* Stop the chip's Tx and Rx Status Machine */
+	outl(RxDIS | TxDIS, ioaddr + cr);
 
-        del_timer(&tp->timer);
+	del_timer(&sis_priv->timer);
 
-        free_irq(dev->irq, dev);
+	free_irq(net_dev->irq, net_dev);
 
-        for (i = 0; i < NUM_TX_DESC; i++) {
-                if (tp->tx_skbuff[i])
-                        dev_free_skb(tp->tx_skbuff[i]);
-                tp->tx_skbuff[i] = 0;
-        }
-        kfree(tp->rx_bufs);
-        kfree(tp->tx_bufs);
+	/* Free Tx and RX skbuff */
+	for (i = 0; i < NUM_RX_DESC; i++) {
+		if (sis_priv->rx_skbuff[i] != NULL)
+			dev_kfree_skb(sis_priv->rx_skbuff[i]);
+		sis_priv->rx_skbuff[i] = 0;
+	}
+	for (i = 0; i < NUM_TX_DESC; i++) {
+		if (sis_priv->tx_skbuff[i] != NULL)
+			dev_kfree_skb(sis_priv->tx_skbuff[i]);
+		sis_priv->tx_skbuff[i] = 0;
+	}
 
-        /* Green! Put the chip in low-power mode. */
+	/* Green! Put the chip in low-power mode. */
 
-        MOD_DEC_USE_COUNT;
+	MOD_DEC_USE_COUNT;
 
-        return 0;
+	return 0;
 }
 
-static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
 {
-        struct sis900_private *tp = (struct sis900_private *)dev->priv;
-        u16 *data = (u16 *)&rq->ifr_data;
-
-        switch(cmd) {
-        case SIOCDEVPRIVATE:            /* Get the address of the PHY in use. */
-                data[0] = tp->phys[tp->phy_idx];
-                /* Fall Through */
-        case SIOCDEVPRIVATE+1:          /* Read the specified MII register. */
-                data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);
-                return 0;
-        case SIOCDEVPRIVATE+2:          /* Write the specified MII register */
-                if (!suser())
-                        return -EPERM;
-                mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
-                return 0;
-        default:
-                return -EOPNOTSUPP;
-        }
+	struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
+	u16 *data = (u16 *)&rq->ifr_data;
+
+	switch(cmd) {
+	case SIOCDEVPRIVATE:            	/* Get the address of the PHY in use. */
+		data[0] = sis_priv->mii->phy_addr;
+		/* Fall Through */
+	case SIOCDEVPRIVATE+1:          	/* Read the specified MII register. */
+		data[3] = mdio_read(net_dev, data[0] & 0x1f, data[1] & 0x1f);
+		return 0;
+	case SIOCDEVPRIVATE+2:          	/* Write the specified MII register */
+		if (!suser())
+			return -EPERM;
+		mdio_write(net_dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+		return 0;
+	default:
+		return -EOPNOTSUPP;
+	}
 }
 
 static struct enet_statistics *
-sis900_get_stats(struct net_device *dev)
+sis900_get_stats(struct net_device *net_dev)
 {
-        struct sis900_private *tp = (struct sis900_private *)dev->priv;
+	struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
 
-        return &tp->stats;
+	return &sis_priv->stats;
 }
 
-/* Set or clear the multicast filter for this adaptor.
-   This routine is not state sensitive and need not be SMP locked. */
-
-static u16 elComputeHashTableIndex(u8 *addr)
+/* SiS 900 uses the most sigificant 7 bits to index a 128 bits multicast hash table, which makes
+   this function a little bit different from other drivers */
+static u16 sis900_compute_hashtable_index(u8 *addr)
 {
+
+/* what is the correct value of the POLYNOMIAL ??
+   Donald Becker use 0x04C11DB7U */
 #define POLYNOMIAL 0x04C11DB6L
-    u32      crc = 0xffffffff, msb;
-    int      i, j;
-    u8       byte;
-
-    for( i=0; i<6; i++ ) {
-        byte = *addr++;
-        for( j=0; j<8; j++ ) {
-            msb = crc >> 31;
-            crc <<= 1;
-            if( msb ^ ( byte & 1 )) {
-                crc ^= POLYNOMIAL;
-                crc |= 1;
-            }
-            byte >>= 1;
-        }
-    }
-    // 7 bit crc for 128 bit hash table
-    return( (int)(crc >> 25) );
-}
-
-static u16 elMIIpollBit(struct net_device *dev,
-                         int phy_id,
-                         int location,
-                         u16 mask,
-                         u16 polarity,
-                         u16 *value)
-{
-        u32 i;
-        i=0;
-        while (1) {
-                *value = mdio_read(dev, phy_id, location);
-                if (polarity) {
-                        if (mask & *value) return(TRUE);
-                } else {
-                        if (mask & ~(*value)) return(TRUE);
-                }
-                if (++i == 1200) break;
-        }
-        return(FALSE);
-}
-
-static u16 elPMDreadMode(struct net_device *dev,
-                         int phy_id,
-                         int *speed,
-                         int *duplex)
-{
-        u16 status, OurCap;
-
-        *speed = HW_SPEED_10_MBPS;
-        *duplex = FDX_CAPABLE_HALF_SELECTED;
-
-        status = mdio_read(dev, phy_id, MII_ANLPAR);
-        OurCap = mdio_read(dev, phy_id, MII_ANAR);
-	if (sis900_debug > 1) {
-		printk(KERN_INFO "Link Part Status %4X\n", status);
-		printk(KERN_INFO "Our Status %4X\n", OurCap);
-		printk(KERN_INFO "Status Reg %4X\n",
-					mdio_read(dev, phy_id, MII_STATUS));
-	}
-	status &= OurCap;
-
-        if ( !( status &
-                (MII_NWAY_T|MII_NWAY_T_FDX | MII_NWAY_TX | MII_NWAY_TX_FDX ))) {
-		if (sis900_debug > 1) {
-			printk(KERN_INFO "The other end NOT support NWAY...\n");
-		}
-                while (( status = mdio_read(dev, phy_id, 18)) & 0x4000) ;
-                while (( status = mdio_read(dev, phy_id, 18)) & 0x0020) ;
-                if (status & 0x80)
-                        *speed = HW_SPEED_100_MBPS;
-                if (status & 0x40)
-                        *duplex = FDX_CAPABLE_FULL_SELECTED;
-                if (sis900_debug > 3) {
-                        printk(KERN_INFO"%s: Setting %s%s-duplex.\n",
-                                dev->name,
-                                *speed == HW_SPEED_100_MBPS ?
-                                        "100mbps " : "10mbps ",
-                                *duplex == FDX_CAPABLE_FULL_SELECTED ?
-                                        "full" : "half");
-                }
-        } else {
-		if (sis900_debug > 1) {
-			printk(KERN_INFO "The other end support NWAY...\n");
+	u32 crc = 0xffffffff, msb;
+	int  i, j;
+	u8  byte;
+
+	for (i = 0; i < 6; i++) {
+		byte = *addr++;
+		for (j = 0; j < 8; j++) {
+			msb = crc >> 31;
+			crc <<= 1;
+			if (msb ^ (byte & 1)) {
+				crc ^= POLYNOMIAL;
+				crc |= 1;
+			}
+			byte >>= 1;
 		}
+	}
+	/* leave 7 most siginifant bits */ 
+	return ((int)(crc >> 25));
+}
 
-                if (status & (MII_NWAY_TX_FDX | MII_NWAY_T_FDX)) {
-                        *duplex = FDX_CAPABLE_FULL_SELECTED;
-                }
-                if (status & (MII_NWAY_TX_FDX | MII_NWAY_TX)) {
-                        *speed = HW_SPEED_100_MBPS;
-                }
-                if (sis900_debug > 3) {
-                        printk(KERN_INFO"%s: Setting %s%s-duplex based on"
-                                " auto-negotiated partner ability.\n",
-                                dev->name,
-                                *speed == HW_SPEED_100_MBPS ?
-                                        "100mbps " : "10mbps ",
-                                *duplex == FDX_CAPABLE_FULL_SELECTED ?
-                                        "full" : "half");
-                }
-        }
-        return (status);
-}
-
-static u16 elAutoNegotiate(struct net_device *dev, int phy_id, int *duplex, int *speed)
-{
-        u16 status, retnVal;
-
-	if (sis900_debug > 1) {
-		printk(KERN_INFO "AutoNegotiate...\n");
-	}
-        mdio_write(dev, phy_id, MII_CONTROL, 0);
-        mdio_write(dev, phy_id, MII_CONTROL, MIICNTL_AUTO | MIICNTL_RST_AUTO);
-        retnVal = elMIIpollBit(dev, phy_id, MII_CONTROL, MIICNTL_RST_AUTO,
-				FALSE,&status);
-	if (!retnVal) {
-		printk(KERN_INFO "Not wait for Reset Complete\n");
-	}
-        retnVal = elMIIpollBit(dev, phy_id, MII_STATUS, MIISTAT_AUTO_DONE,
-				TRUE, &status);
-	if (!retnVal) {
-		printk(KERN_INFO "Not wait for AutoNego Complete\n");
-	}
-        retnVal = elMIIpollBit(dev, phy_id, MII_STATUS, MIISTAT_LINK,
-				TRUE, &status);
-	if (!retnVal) {
-		printk(KERN_INFO "Not wait for Link Complete\n");
-	}
-        if (status & MIISTAT_LINK) {
-                elPMDreadMode(dev, phy_id, speed, duplex);
-                elSetMediaType(dev, *speed, *duplex);
-        }
-        return(status);
-}
-
-static void elSetCapability(struct net_device *dev, int phy_id,
-			    int duplex, int speed)
-{
-        u16 cap = ( MII_NWAY_T  | MII_NWAY_T_FDX  |
-		    MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_CSMA_CD );
-
-	if (speed != 100) {
-		cap &= ~( MII_NWAY_TX | MII_NWAY_TX_FDX );
-		if (sis900_debug > 1) {
-			printk(KERN_INFO "UNSET 100Mbps\n");
-		}
+static void set_rx_mode(struct net_device *net_dev)
+{
+	long ioaddr = net_dev->base_addr;
+	u16 mc_filter[8];			/* 128 bits multicast hash table */
+	int i;
+	u32 rx_mode;
+
+	if (net_dev->flags & IFF_PROMISC) {
+		/* Accept any kinds of packets */
+		rx_mode = RFPromiscuous;
+		for (i = 0; i < 8; i++)
+			mc_filter[i] = 0xffff;
+	} else if ((net_dev->mc_count > multicast_filter_limit) ||
+		   (net_dev->flags & IFF_ALLMULTI)) {
+		/* too many multicast addresses or accept all multicast packet */
+		rx_mode = RFAAB | RFAAM;
+		for (i = 0; i < 8; i++)
+			mc_filter[i] = 0xffff;
+	} else {
+		/* Accept Broadcast packet, destination address matchs our MAC address,
+		   use Receive Filter to reject unwanted MCAST packet */
+		struct dev_mc_list *mclist;
+		rx_mode = RFAAB;
+		for (i = 0; i < 8; i++)
+			mc_filter[i]=0;
+		for (i = 0, mclist = net_dev->mc_list; mclist && i < net_dev->mc_count;
+		     i++, mclist = mclist->next)
+			set_bit(sis900_compute_hashtable_index(mclist->dmi_addr),
+				mc_filter);
 	}
 
-	if (!duplex) {
-		cap &= ~( MII_NWAY_T_FDX | MII_NWAY_TX_FDX );
-		if (sis900_debug > 1) {
-			printk(KERN_INFO "UNSET full-duplex\n");
-		}
+	/* update Multicast Hash Table in Receive Filter */
+	for (i = 0; i < 8; i++) {
+		/* why plus 0x04 ??, I don't know, UNDOCUMENT FEATURE ?? */
+		outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr);
+		outl(mc_filter[i], ioaddr + rfdr);
 	}
 
-        mdio_write(dev, phy_id, MII_ANAR, cap);
-}
+	outl(RFEN | rx_mode, ioaddr + rfcr);
 
-static void elSetMediaType(struct net_device *dev, int speed, int duplex)
-{
-        long ioaddr = dev->base_addr;
-        u32     txCfgOn = 0, txCfgOff = TxDRNT;
-        u32     rxCfgOn = 0, rxCfgOff = 0;
-
-        if (speed == HW_SPEED_100_MBPS) {
-                txCfgOn |= (TxDRNT_100 | TxHBI);
-        } else {
-                txCfgOn |= TxDRNT_10;
-        }
-
-        if (duplex == FDX_CAPABLE_FULL_SELECTED) {
-                txCfgOn |= (TxCSI | TxHBI);
-                rxCfgOn |= RxATP;
-        } else {
-                txCfgOff |= (TxCSI | TxHBI);
-                rxCfgOff |= RxATP;
-        }
-        outl( (inl(ioaddr + txcfg) & ~txCfgOff) | txCfgOn, ioaddr + txcfg);
-        outl( (inl(ioaddr + rxcfg) & ~rxCfgOff) | rxCfgOn, ioaddr + rxcfg);
-}
-
-static void set_rx_mode(struct net_device *dev)
-{
-        long ioaddr = dev->base_addr;
-        u16 mc_filter[8];
-        int i;
-        int rx_mode;
-        u32 rxCfgOn = 0, rxCfgOff = 0;
-        u32 txCfgOn = 0, txCfgOff = 0;
-
-        if (sis900_debug > 3)
-                printk(KERN_INFO "%s: set_rx_mode (%4.4x) done--"
-                                "RxCfg %8.8x.\n",
-                                dev->name, dev->flags, inl(ioaddr + rxcfg));
-
-        /* Note: do not reorder, GCC is clever about common statements. */
-        if (dev->flags & IFF_PROMISC) {
-                printk(KERN_NOTICE"%s: Promiscuous mode enabled.\n", dev->name);
-                rx_mode = ACCEPT_ALL_BCASTS | ACCEPT_ALL_MCASTS |
-                                ACCEPT_CAM_QUALIFIED | ACCEPT_ALL_PHYS;
-                for (i=0 ; i<8 ; i++)
-                        mc_filter[i]=0xffff;
-        } else if ((dev->mc_count > multicast_filter_limit)
-                           ||  (dev->flags & IFF_ALLMULTI)) {
-                rx_mode = ACCEPT_ALL_BCASTS | ACCEPT_ALL_MCASTS |
-                                ACCEPT_CAM_QUALIFIED;
-                for (i=0 ; i<8 ; i++)
-                        mc_filter[i]=0xffff;
-        } else {
-                struct dev_mc_list *mclist;
-                rx_mode = ACCEPT_ALL_BCASTS | ACCEPT_ALL_MCASTS |
-                                ACCEPT_CAM_QUALIFIED;
-                for (i=0 ; i<8 ; i++)
-                        mc_filter[i]=0;
-                for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
-                         i++, mclist = mclist->next)
-                        set_bit(elComputeHashTableIndex(mclist->dmi_addr),
-                                                mc_filter);
-        }
-
-        for (i=0 ; i<8 ; i++) {
-                outl((u32)(0x00000004+i) << 16, ioaddr + rfcr);
-                outl(mc_filter[i], ioaddr + rfdr);
-        }
-        /* We can safely update without stopping the chip. */
-        //rx_mode = ACCEPT_CAM_QUALIFIED | ACCEPT_ALL_BCASTS | ACCEPT_ALL_PHYS;
-        //rx_mode = ACCEPT_CAM_QUALIFIED | ACCEPT_ALL_BCASTS;
-        outl(RFEN | ((rx_mode & (ACCEPT_ALL_MCASTS | ACCEPT_ALL_BCASTS |
-                          ACCEPT_ALL_PHYS)) << RFAA_shift), ioaddr + rfcr);
-
-        if (rx_mode & ACCEPT_ALL_ERRORS) {
-                rxCfgOn = RxAEP | RxARP | RxAJAB;
-        } else {
-                rxCfgOff = RxAEP | RxARP | RxAJAB;
-        }
-        if (rx_mode & MAC_LOOPBACK) {
-                rxCfgOn |= RxATP;
-                txCfgOn |= TxMLB;
-        } else {
-                if (!(( (struct sis900_private *)(dev->priv) )->full_duplex))
-                        rxCfgOff |= RxATP;
-                txCfgOff |= TxMLB;
-        }
-
-        if (sis900_debug > 2) {
-                printk(KERN_INFO "Before Set TxCfg=%8.8x\n",inl(ioaddr+txcfg));
-                printk(KERN_INFO "Before Set RxCfg=%8.8x\n",inl(ioaddr+rxcfg));
-        }
-
-        outl((inl(ioaddr + rxcfg) | rxCfgOn) & ~rxCfgOff, ioaddr + rxcfg);
-        outl((inl(ioaddr + txcfg) | txCfgOn) & ~txCfgOff, ioaddr + txcfg);
-
-        if (sis900_debug > 2) {
-                printk(KERN_INFO "After Set TxCfg=%8.8x\n",inl(ioaddr+txcfg));
-                printk(KERN_INFO "After Set RxCfg=%8.8x\n",inl(ioaddr+rxcfg));
-                printk(KERN_INFO "Receive Filter Register:%8.8x\n",
-                                                        inl(ioaddr + rfcr));
-        }
-        return;
-}
-
-static void sis900_reset(struct net_device *dev)
-{
-        long ioaddr = dev->base_addr;
-
-        outl(0, ioaddr + ier);
-        outl(0, ioaddr + imr);
-        outl(0, ioaddr + rfcr);
+	/* sis900 is capatable of looping back packet at MAC level for debugging purpose */
+	if (net_dev->flags & IFF_LOOPBACK) {
+		u32 cr_saved;
+		/* We must disable Tx/Rx before setting loopback mode */
+		cr_saved = inl(ioaddr + cr);
+		outl(cr_saved | TxDIS | RxDIS, ioaddr + cr);
+		/* enable loopback */
+		outl(inl(ioaddr + txcfg) | TxMLB, ioaddr + txcfg);
+		outl(inl(ioaddr + rxcfg) | RxATX, ioaddr + rxcfg);
+		/* restore cr */
+		outl(cr_saved, ioaddr + cr);
+	}		
+
+	return;
+}
+
+static void sis900_reset(struct net_device *net_dev)
+{
+	long ioaddr = net_dev->base_addr;
+	int i = 0;
+	u32 status = TxRCMP | RxRCMP;
+
+	outl(0, ioaddr + ier);
+	outl(0, ioaddr + imr);
+	outl(0, ioaddr + rfcr);
 
-        outl(RxRESET | TxRESET | RESET, ioaddr + cr);
-        outl(PESEL, ioaddr + cfg);
+	outl(RxRESET | TxRESET | RESET, ioaddr + cr);
+	
+	/* Check that the chip has finished the reset. */
+	while (status && (i++ < 1000)) {
+		status ^= (inl(isr + ioaddr) & status);
+	}
 
-        set_rx_mode(dev);
+	outl(PESEL, ioaddr + cfg);
 }
 
 #ifdef MODULE
 int init_module(void)
 {
-        return sis900_probe(0);
+	return sis900_probe(NULL);
 }
 
 void
 cleanup_module(void)
 {
-        struct net_device *next_dev;
+	/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+	while (root_sis900_dev) {
+		struct sis900_private *sis_priv =
+			(struct sis900_private *)root_sis900_dev->priv;
+		struct net_device *next_dev = sis_priv->next_module;
+		
+		unregister_netdev(root_sis900_dev);
+		release_region(root_sis900_dev->base_addr,
+			       sis_priv->mac->io_size);
+		kfree(sis_priv);
+		kfree(root_sis900_dev);
 
-        /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
-        while (root_sis900_dev) {
-                struct sis900_private *tp =
-                        (struct sis900_private *)root_sis900_dev->priv;
-                next_dev = tp->next_module;
-                unregister_netdev(root_sis900_dev);
-                release_region(root_sis900_dev->base_addr,
-                                           pci_tbl[tp->chip_id].io_size);
-                kfree(tp);
-                kfree(root_sis900_dev);
-                root_sis900_dev = next_dev;
-        }
+		root_sis900_dev = next_dev;
+	}
 }
 
 #endif  /* MODULE */
-/*
- * Local variables:
- *  compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c sis900.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
- *  SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c sis900.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
- *  c-indent-level: 4
- *  c-basic-offset: 4
- *  tab-width: 4
- * End:
- */
diff -u --recursive --new-file v2.3.25/linux/drivers/net/sis900.h linux/drivers/net/sis900.h
--- v2.3.25/linux/drivers/net/sis900.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/net/sis900.h	Fri Nov  5 09:51:44 1999
@@ -0,0 +1,248 @@
+/* sis900.h Definitions for SiS ethernet controllers including 7014/7016 and 900 
+ * Copyright 1999 Silicon Integrated System Corporation
+ * References:
+ *   SiS 7016 Fast Ethernet PCI Bus 10/100 Mbps LAN Controller with OnNow Support,
+ *	preliminary Rev. 1.0 Jan. 14, 1998
+ *   SiS 900 Fast Ethernet PCI Bus 10/100 Mbps LAN Single Chip with OnNow Support,
+ *	preliminary Rev. 1.0 Nov. 10, 1998
+ *   SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
+ *	preliminary Rev. 1.0 Jan. 18, 1998
+ *   http://www.sis.com.tw/support/databook.htm
+ */
+
+/* MAC operationl registers of SiS 7016 and SiS 900 ehternet controller */
+/* The I/O extent, SiS 900 needs 256 bytes of io address */
+#define SIS900_TOTAL_SIZE 0x100
+
+/* Symbolic offsets to registers. */
+enum sis900_registers {
+	cr=0x0,                 //Command Register
+	cfg=0x4,                //Configuration Register
+	mear=0x8,               //EEPROM Access Register
+	ptscr=0xc,              //PCI Test Control Register
+	isr=0x10,               //Interrupt Status Register
+	imr=0x14,               //Interrupt Mask Register
+	ier=0x18,               //Interrupt Enable Register
+	epar=0x18,              //Enhanced PHY Access Register
+	txdp=0x20,              //Transmit Descriptor Pointer Register
+	txcfg=0x24,             //Transmit Configuration Register
+	rxdp=0x30,              //Receive Descriptor Pointer Register
+	rxcfg=0x34,             //Receive Configuration Register
+	flctrl=0x38,            //Flow Control Register
+	rxlen=0x3c,             //Receive Packet Length Register
+	rfcr=0x48,              //Receive Filter Control Register
+	rfdr=0x4C,              //Receive Filter Data Register
+	pmctrl=0xB0,            //Power Management Control Register
+	pmer=0xB4               //Power Management Wake-up Event Register
+};
+
+/* Symbolic names for bits in various registers */
+enum sis900_command_register_bits {
+	RESET   = 0x00000100, SWI = 0x00000080, RxRESET = 0x00000020,
+	TxRESET = 0x00000010, RxDIS = 0x00000008, RxENA = 0x00000004,
+	TxDIS   = 0x00000002, TxENA = 0x00000001
+};
+
+enum sis900_configuration_register_bits {
+	DESCRFMT = 0x00000100 /* 7016 specific */, REQALG = 0x00000080,
+	SB    = 0x00000040, POW = 0x00000020, EXD = 0x00000010, 
+	PESEL = 0x00000008, LPM = 0x00000004, BEM = 0x00000001
+};
+
+enum sis900_eeprom_access_reigster_bits {
+	MDC  = 0x00000040, MDDIR = 0x00000020, MDIO = 0x00000010, /* 7016 specific */ 
+	EECS = 0x00000008, EECLK = 0x00000004, EEDO = 0x00000002,
+	EEDI = 0x00000001
+};
+
+enum sis900_interrupt_register_bits {
+	WKEVT  = 0x10000000, TxPAUSEEND = 0x08000000, TxPAUSE = 0x04000000,
+	TxRCMP = 0x02000000, RxRCMP = 0x01000000, DPERR = 0x00800000,
+	SSERR  = 0x00400000, RMABT  = 0x00200000, RTABT = 0x00100000,
+	RxSOVR = 0x00010000, HIBERR = 0x00008000, SWINT = 0x00001000,
+	MIBINT = 0x00000800, TxURN  = 0x00000400, TxIDLE  = 0x00000200,
+	TxERR  = 0x00000100, TxDESC = 0x00000080, TxOK  = 0x00000040,
+	RxORN  = 0x00000020, RxIDLE = 0x00000010, RxEARLY = 0x00000008,
+	RxERR  = 0x00000004, RxDESC = 0x00000002, RxOK  = 0x00000001
+};
+
+enum sis900_interrupt_enable_reigster_bits {
+	IE = 0x00000001
+};
+
+/* maximum dma burst fro transmission and receive*/
+#define MAX_DMA_RANGE	7	/* actually 0 means MAXIMUM !! */
+#define TxMXDMA_shift   	20
+#define RxMXDMA_shift    20
+#define TX_DMA_BURST    	0
+#define RX_DMA_BURST    	0
+
+/* transmit FIFO threshholds */
+#define TX_FILL_THRESH   16	/* 1/4 FIFO size */
+#define TxFILLT_shift   	8
+#define TxDRNT_shift    	0
+#define TxDRNT_100      	48	/* 3/4 FIFO size */
+#define TxDRNT_10		16 	/* 1/2 FIFO size */
+
+enum sis900_transmit_config_register_bits {
+	TxCSI = 0x80000000, TxHBI = 0x40000000, TxMLB = 0x20000000,
+	TxATP = 0x10000000, TxIFG = 0x0C000000, TxFILLT = 0x00003F00,
+	TxDRNT = 0x0000003F
+};
+
+/* recevie FIFO thresholds */
+#define RxDRNT_shift     1
+#define RxDRNT_100	24	/* 3/4 FIFO size */
+#define RxDRNT_10		16 	/* 1/2 FIFO size */
+
+enum sis900_reveive_config_register_bits {
+	RxAEP  = 0x80000000, RxARP = 0x40000000, RxATX = 0x10000000,
+	RxAJAB = 0x08000000, RxDRNT = 0x0000007F
+};
+
+#define RFAA_shift      28
+#define RFADDR_shift    16
+
+enum sis900_receive_filter_control_register_bits {
+	RFEN  = 0x80000000, RFAAB = 0x40000000, RFAAM = 0x20000000,
+	RFAAP = 0x10000000, RFPromiscuous = (RFAAB|RFAAM|RFAAP)
+};
+
+enum sis900_reveive_filter_data_mask {
+	RFDAT =  0x0000FFFF
+};
+
+/* EEPROM Addresses */
+enum sis900_eeprom_address {
+	EEPROMSignature = 0x00, EEPROMVendorID = 0x02, EEPROMDeviceID = 0x03,
+	EEPROMMACAddr   = 0x08, EEPROMChecksum = 0x0b
+};
+
+/* The EEPROM commands include the alway-set leading bit. Refer to NM93Cxx datasheet */
+enum sis900_eeprom_command {
+	EEread     = 0x0180, EEwrite    = 0x0140, EEerase = 0x01C0, 
+	EEwriteEnable = 0x0130, EEwriteDisable = 0x0100,
+	EEeraseAll = 0x0120, EEwriteAll = 0x0110, 
+	EEaddrMask = 0x013F, EEcmdShift = 16
+};
+
+/* Manamgement Data I/O (mdio) frame */
+#define MIIread         0x6000
+#define MIIwrite        0x5002
+#define MIIpmdShift     7
+#define MIIregShift     2
+#define MIIcmdLen       16
+#define MIIcmdShift     16
+
+/* Buffer Descriptor Status*/
+enum sis900_buffer_status {
+	OWN    = 0x80000000, MORE   = 0x40000000, INTR = 0x20000000,
+	SUPCRC = 0x10000000, INCCRC = 0x10000000,
+	OK     = 0x08000000, DSIZE  = 0x00000FFF
+};
+/* Status for TX Buffers */
+enum sis900_tx_buffer_status {
+	ABORT   = 0x04000000, UNDERRUN = 0x02000000, NOCARRIER = 0x01000000,
+	DEFERD  = 0x00800000, EXCDEFER = 0x00400000, OWCOLL    = 0x00200000,
+	EXCCOLL = 0x00100000, COLCNT   = 0x000F0000
+};
+
+enum sis900_rx_bufer_status {
+	OVERRUN = 0x02000000, DEST = 0x00800000,     BCAST = 0x01800000,
+	MCAST   = 0x01000000, UNIMATCH = 0x00800000, TOOLONG = 0x00400000,
+	RUNT    = 0x00200000, RXISERR  = 0x00100000, CRCERR  = 0x00080000,
+	FAERR   = 0x00040000, LOOPBK   = 0x00020000, RXCOL   = 0x00010000
+};
+
+/* MII register offsets */
+enum mii_registers {
+	MII_CONTROL = 0x0000, MII_STATUS = 0x0001, MII_PHY_ID0 = 0x0002,
+	MII_PHY_ID1 = 0x0003, MII_ANADV  = 0x0004, MII_ANLPAR  = 0x0005,
+	MII_ANEXT   = 0x0006
+};
+
+/* mii registers specific to SiS 900 */
+enum sis_mii_registers {
+	MII_CONFIG1 = 0x0010, MII_CONFIG2 = 0x0011, MII_STSOUT = 0x0012,
+	MII_MASK    = 0x0013
+};
+
+/* mii registers specific to AMD 79C901 */
+enum amd_mii_registers {
+	MII_STATUS_SUMMARY = 0x0018
+};
+
+/* MII Control register bit definitions. */
+enum mii_control_register_bits {
+	MII_CNTL_FDX     = 0x0100, MII_CNTL_RST_AUTO = 0x0200, 
+	MII_CNTL_ISOLATE = 0x0400, MII_CNTL_PWRDWN   = 0x0800,
+	MII_CNTL_AUTO    = 0x1000, MII_CNTL_SPEED    = 0x2000,
+	MII_CNTL_LPBK    = 0x4000, MII_CNTL_RESET    = 0x8000
+};
+
+/* MII Status register bit  */
+enum mii_status_register_bits {
+	MII_STAT_EXT    = 0x0001, MII_STAT_JAB        = 0x0002, 
+	MII_STAT_LINK   = 0x0004, MII_STAT_CAN_AUTO   = 0x0008, 
+	MII_STAT_FAULT  = 0x0010, MII_STAT_AUTO_DONE  = 0x0020,
+	MII_STAT_CAN_T  = 0x0800, MII_STAT_CAN_T_FDX  = 0x1000,
+	MII_STAT_CAN_TX = 0x2000, MII_STAT_CAN_TX_FDX = 0x4000,
+	MII_STAT_CAN_T4 = 0x8000
+};
+
+#define		MII_ID1_OUI_LO		0xFC00	/* low bits of OUI mask */
+#define		MII_ID1_MODEL		0x03F0	/* model number */
+#define		MII_ID1_REV		0x000F	/* model number */
+
+/* MII NWAY Register Bits ...
+   valid for the ANAR (Auto-Negotiation Advertisement) and
+   ANLPAR (Auto-Negotiation Link Partner) registers */
+enum mii_nway_register_bits {
+	MII_NWAY_NODE_SEL = 0x001f, MII_NWAY_CSMA_CD = 0x0001,
+	MII_NWAY_T	  = 0x0020, MII_NWAY_T_FDX   = 0x0040,
+	MII_NWAY_TX       = 0x0080, MII_NWAY_TX_FDX  = 0x0100,
+	MII_NWAY_T4       = 0x0200, MII_NWAY_PAUSE   = 0x0400,
+	MII_NWAY_RF       = 0x2000, MII_NWAY_ACK     = 0x4000,
+	MII_NWAY_NP       = 0x8000
+};
+
+enum mii_stsout_register_bits {
+	MII_STSOUT_LINK_FAIL = 0x4000,
+	MII_STSOUT_SPD       = 0x0080, MII_STSOUT_DPLX = 0x0040
+};
+
+enum mii_stssum_register_bits {
+	MII_STSSUM_LINK = 0x0008, MII_STSSUM_DPLX = 0x0004,
+	MII_STSSUM_AUTO = 0x0002, MII_STSSUM_SPD  = 0x0001
+};
+
+#define FDX_CAPABLE_DUPLEX_UNKNOWN      0
+#define FDX_CAPABLE_HALF_SELECTED       1
+#define FDX_CAPABLE_FULL_SELECTED       2
+
+#define HW_SPEED_UNCONFIG		0
+#define HW_SPEED_HOME		1
+#define HW_SPEED_10_MBPS        	10
+#define HW_SPEED_100_MBPS       	100
+#define HW_SPEED_DEFAULT        	(HW_SPEED_100_MBPS)
+
+#define CRC_SIZE                4
+#define MAC_HEADER_SIZE         14
+
+#define TX_BUF_SIZE     1536
+#define RX_BUF_SIZE     1536
+
+#define NUM_TX_DESC     16      	/* Number of Tx descriptor registers. */
+#define NUM_RX_DESC     16       	/* Number of Rx descriptor registers. */
+
+#define TRUE            1
+#define FALSE           0
+
+/* PCI stuff, should be move to pic.h */
+#define PCI_DEVICE_ID_SI_900	0x900   
+#define PCI_DEVICE_ID_SI_7016	0x7016  
+
+/* ioctl for accessing MII transveiver */
+#define SIOCGMIIPHY (SIOCDEVPRIVATE)		/* Get the PHY in use. */
+#define SIOCGMIIREG (SIOCDEVPRIVATE+1)		/* Read a PHY register. */
+#define SIOCSMIIREG (SIOCDEVPRIVATE+2)		/* Write a PHY register */
diff -u --recursive --new-file v2.3.25/linux/drivers/net/tokenring/tms380tr.c linux/drivers/net/tokenring/tms380tr.c
--- v2.3.25/linux/drivers/net/tokenring/tms380tr.c	Fri Oct 15 15:25:13 1999
+++ linux/drivers/net/tokenring/tms380tr.c	Tue Nov  2 17:07:08 1999
@@ -16,6 +16,7 @@
  *	- SysKonnect TR4/16 PCI		(SK-4591)
  *      - Compaq TR 4/16 PCI
  *      - Thomas-Conrad TC4048 4/16 PCI
+ *      - 3Com 3C339 Token Link Velocity
  *      - Any ISA or PCI adapter using only the TMS380 chipset
  *
  *  Sources:
@@ -123,6 +124,8 @@
     "SK NET TR 4/16 PCI"},
   { TMS_PCI, PCI_VENDOR_ID_TCONRAD, PCI_DEVICE_ID_TCONRAD_TOKENRING,
     "Thomas-Conrad TC4048 PCI 4/16"},
+  { TMS_PCI, PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C339,
+    "3Com Token Link Velocity"},
   { 0, 0, 0, NULL}
 };
 
diff -u --recursive --new-file v2.3.25/linux/drivers/parport/Config.in linux/drivers/parport/Config.in
--- v2.3.25/linux/drivers/parport/Config.in	Fri Oct 15 15:25:13 1999
+++ linux/drivers/parport/Config.in	Wed Nov  3 14:43:54 1999
@@ -27,18 +27,18 @@
 	 dep_tristate '  Multiface III parallel port' CONFIG_PARPORT_MFC3 $CONFIG_PARPORT
       fi
    else
-      define_bool CONFIG_PARPORT_AMIGA n
-      define_bool CONFIG_PARPORT_MFC3 n
+      define_tristate CONFIG_PARPORT_AMIGA n
+      define_tristate CONFIG_PARPORT_MFC3 n
    fi
    if [ "$CONFIG_ATARI" = "y" ]; then
       dep_tristate '  Atari hardware' CONFIG_PARPORT_ATARI $CONFIG_PARPORT
    else
-      define_bool CONFIG_PARPORT_ATARI n
+      define_tristate CONFIG_PARPORT_ATARI n
    fi
    if [ "$CONFIG_SBUS" = "y" ]; then
       dep_tristate '  Sparc hardware (EXPERIMENTAL)' CONFIG_PARPORT_SUNBPP $CONFIG_PARPORT
    else
-      define_bool CONFIG_PARPORT_SUNBPP n
+      define_tristate CONFIG_PARPORT_SUNBPP n
    fi
 
    # If exactly one hardware type is selected then parport will optimise away
diff -u --recursive --new-file v2.3.25/linux/drivers/parport/share.c linux/drivers/parport/share.c
--- v2.3.25/linux/drivers/parport/share.c	Sat Oct  9 11:47:50 1999
+++ linux/drivers/parport/share.c	Sat Nov  6 10:38:40 1999
@@ -137,7 +137,7 @@
 		request_module ("parport_lowlevel");
 		if (portlist)
 			/* The user has a parport_lowlevel alias in
-			 * conf.modules. Warn them that it won't work
+			 * modules.conf. Warn them that it won't work
 			 * for long. */
 			printk (KERN_WARNING
 				"parport: 'parport_lowlevel' is deprecated; "
diff -u --recursive --new-file v2.3.25/linux/drivers/sbus/char/flash.c linux/drivers/sbus/char/flash.c
--- v2.3.25/linux/drivers/sbus/char/flash.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/sbus/char/flash.c	Tue Nov  2 17:40:11 1999
@@ -55,12 +55,13 @@
 			return -ENXIO;
 	}
 
-	if (vma->vm_offset > size)
+	if (vma->vm_pgoff > (size >> PAGE_SHIFT))
 		return -ENXIO;
-	addr += vma->vm_offset;
+	off = vma->vm_pgoff << PAGE_SHIFT;
+	addr += off;
 
-	if (vma->vm_end - (vma->vm_start + vma->vm_offset) > size)
-		size = vma->vm_end - (vma->vm_start + vma->vm_offset);
+	if (vma->vm_end - (vma->vm_start + off) > size)
+		size = vma->vm_end - (vma->vm_start + off);
 
 	pgprot_val(vma->vm_page_prot) &= ~(_PAGE_CACHE);
 	pgprot_val(vma->vm_page_prot) |= _PAGE_E;
diff -u --recursive --new-file v2.3.25/linux/drivers/sbus/char/vfc_dev.c linux/drivers/sbus/char/vfc_dev.c
--- v2.3.25/linux/drivers/sbus/char/vfc_dev.c	Wed Jun  9 14:44:25 1999
+++ linux/drivers/sbus/char/vfc_dev.c	Tue Nov  2 17:40:11 1999
@@ -572,8 +572,6 @@
 	if(map_size > sizeof(struct vfc_regs)) 
 		map_size=sizeof(struct vfc_regs);
 
-
-	if(vma->vm_offset & ~PAGE_MASK) return -ENXIO;
 	vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO | VM_MAYREAD | VM_MAYWRITE | VM_MAYSHARE;
 	map_offset=(unsigned int)dev->phys_regs;
 	ret = io_remap_page_range(vma->vm_start,map_offset,map_size, 
diff -u --recursive --new-file v2.3.25/linux/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c
--- v2.3.25/linux/drivers/scsi/ide-scsi.c	Fri Oct 22 13:21:50 1999
+++ linux/drivers/scsi/ide-scsi.c	Fri Nov  5 10:40:23 1999
@@ -299,6 +299,11 @@
 	scsi->pc = NULL;
 }
 
+static inline unsigned long get_timeout(idescsi_pc_t *pc)
+{
+	return IDE_MAX(WAIT_CMD, pc->timeout - jiffies);
+}
+
 /*
  *	Our interrupt handler.
  */
@@ -359,8 +364,7 @@
 				pc->actually_transferred += temp;
 				pc->current_position += temp;
 				idescsi_discard_data (drive,bcount - temp);
-				drive->timeout = IDE_MAX(WAIT_CMD, pc->timeout - jiffies);
-				ide_set_handler(drive, &idescsi_pc_intr);
+				ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL);
 				return;
 			}
 #if IDESCSI_DEBUG_LOG
@@ -384,8 +388,7 @@
 	pc->actually_transferred+=bcount;				/* Update the current position */
 	pc->current_position+=bcount;
 
-	drive->timeout = IDE_MAX(WAIT_CMD, pc->timeout - jiffies);
-	ide_set_handler(drive, &idescsi_pc_intr);	/* And set the interrupt handler again */
+	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL);	/* And set the interrupt handler again */
 }
 
 static void idescsi_transfer_pc (ide_drive_t *drive)
@@ -404,8 +407,7 @@
 		ide_do_reset (drive);
 		return;
 	}
-	drive->timeout = IDE_MAX(WAIT_CMD, pc->timeout - jiffies);
-	ide_set_handler(drive, &idescsi_pc_intr);	/* Set the interrupt routine */
+	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL);	/* Set the interrupt routine */
 	atapi_output_bytes (drive, scsi->pc->c, 12);			/* Send the actual packet */
 }
 
@@ -439,8 +441,7 @@
 		(void) (HWIF(drive)->dmaproc(ide_dma_begin, drive));
 	}
 	if (test_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags)) {
-		drive->timeout = IDE_MAX(WAIT_CMD, pc->timeout - jiffies);
-		ide_set_handler (drive, &idescsi_transfer_pc);
+		ide_set_handler (drive, &idescsi_transfer_pc, get_timeout(pc), NULL);
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);		/* Issue the packet command */
 	} else {
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);
diff -u --recursive --new-file v2.3.25/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
--- v2.3.25/linux/drivers/scsi/scsi.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/scsi/scsi.c	Sat Nov  6 10:38:40 1999
@@ -21,7 +21,7 @@
  *  support added by Michael Neuffer <mike@i-connect.net>
  *
  *  Added request_module("scsi_hostadapter") for kerneld:
- *  (Put an "alias scsi_hostadapter your_hostadapter" in /etc/conf.modules)
+ *  (Put an "alias scsi_hostadapter your_hostadapter" in /etc/modules.conf)
  *  Bjorn Ekwall  <bj0rn@blox.se>
  *  (changed to kmod)
  *
diff -u --recursive --new-file v2.3.25/linux/drivers/scsi/sr.c linux/drivers/scsi/sr.c
--- v2.3.25/linux/drivers/scsi/sr.c	Fri Oct 15 15:25:14 1999
+++ linux/drivers/scsi/sr.c	Wed Nov  3 14:01:48 1999
@@ -862,8 +862,10 @@
 	int the_result, retries;
 	Scsi_Cmnd *SCpnt;
 
+	spin_lock_irq(&io_request_lock);
 	buffer = (unsigned char *) scsi_malloc(512);
 	SCpnt = scsi_allocate_device(NULL, scsi_CDs[i].device, 1);
+	spin_unlock_irq(&io_request_lock);
 
 	retries = 3;
 	do {
@@ -957,7 +959,9 @@
 		""
 	};
 
+	spin_lock_irq(&io_request_lock);
 	buffer = (unsigned char *) scsi_malloc(512);
+	spin_unlock_irq(&io_request_lock);
 	cmd[0] = MODE_SENSE;
 	cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;
 	cmd[2] = 0x2a;
@@ -1030,6 +1034,8 @@
 {
 	Scsi_Cmnd *SCpnt;
 	Scsi_Device *device = scsi_CDs[MINOR(cdi->dev)].device;
+	unsigned char *buffer = cgc->buffer;
+	int buflen;
 	int stat;
 
 	/* get the device */
@@ -1037,6 +1043,20 @@
 	if (SCpnt == NULL)
 		return -ENODEV;	/* this just doesn't seem right /axboe */
 
+	/* use buffer for ISA DMA */
+	buflen = (cgc->buflen + 511) & ~511;
+	if (cgc->buffer && SCpnt->host->unchecked_isa_dma &&
+    	   (virt_to_phys(cgc->buffer) + cgc->buflen - 1 > ISA_DMA_THRESHOLD)) {
+		spin_lock_irq(&io_request_lock);
+		buffer = scsi_malloc(buflen);
+		spin_unlock_irq(&io_request_lock);
+		if (buffer == NULL) {
+			printk("sr: SCSI DMA pool exhausted.");
+			return -ENOMEM;
+		}
+		memcpy(buffer, cgc->buffer, cgc->buflen);
+	}
+
 	/* set the LUN */
 	cgc->cmd[1] |= device->lun << 5;
 
@@ -1044,8 +1064,8 @@
 	SCpnt->request.rq_dev = cdi->dev;
 	/* scsi_do_cmd sets the command length */
 	SCpnt->cmd_len = 0;
-	
-	scsi_wait_cmd (SCpnt, (void *)cgc->cmd, (void *)cgc->buffer, cgc->buflen,
+
+	scsi_wait_cmd (SCpnt, (void *)cgc->cmd, (void *)buffer, cgc->buflen,
 		sr_init_done, SR_TIMEOUT, MAX_RETRIES);
 
 	stat = SCpnt->result;
@@ -1054,6 +1074,12 @@
 	SCpnt->request.rq_dev = MKDEV(0, 0);
 	scsi_release_command(SCpnt);
 	SCpnt = NULL;
+
+	/* write DMA buffer back if used */
+	if (buffer && (buffer != cgc->buffer)) {
+		memcpy(cgc->buffer, buffer, cgc->buflen);
+		scsi_free(buffer, buflen);
+	}
 
 	return stat;
 }
diff -u --recursive --new-file v2.3.25/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c
--- v2.3.25/linux/drivers/scsi/sr_ioctl.c	Mon Oct  4 15:49:30 1999
+++ linux/drivers/scsi/sr_ioctl.c	Wed Nov  3 14:01:48 1999
@@ -36,6 +36,12 @@
     
     req = &SCpnt->request;
     req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */
+
+    if (SCpnt->buffer && req->buffer && SCpnt->buffer != req->buffer) {
+	memcpy(req->buffer, SCpnt->buffer, SCpnt->bufflen);
+	scsi_free(SCpnt->buffer, (SCpnt->bufflen + 511) & ~511);
+	SCpnt->buffer = req->buffer;
+    } 
     
     if (req->sem != NULL) {
 	up(req->sem);
@@ -52,27 +58,33 @@
     Scsi_Device * SDev;
     int result, err = 0, retries = 0;
     unsigned long flags;
+    char * bounce_buffer;
 
     spin_lock_irqsave(&io_request_lock, flags);
     SDev  = scsi_CDs[target].device;
     SCpnt = scsi_allocate_device(NULL, scsi_CDs[target].device, 1);
     spin_unlock_irqrestore(&io_request_lock, flags);
 
+    /* use ISA DMA buffer if necessary */
+    SCpnt->request.buffer=buffer;
+    if (buffer && SCpnt->host->unchecked_isa_dma &&
+       (virt_to_phys(buffer) + buflength - 1 > ISA_DMA_THRESHOLD)) {
+	bounce_buffer = (char *)scsi_malloc((buflength + 511) & ~511);
+	if (bounce_buffer == NULL) {
+		printk("SCSI DMA pool exhausted.");
+		return -ENOMEM;
+	}
+	memcpy(bounce_buffer, (char *)buffer, buflength);
+	buffer = bounce_buffer;
+    }
+
 retry:
     if( !scsi_block_when_processing_errors(SDev) )
         return -ENODEV;
-    {
-	DECLARE_MUTEX_LOCKED(sem);
-	SCpnt->request.sem = &sem;
-	spin_lock_irqsave(&io_request_lock, flags);
-	scsi_do_cmd(SCpnt,
-		    (void *) sr_cmd, buffer, buflength, sr_ioctl_done, 
-		    IOCTL_TIMEOUT, IOCTL_RETRIES);
-	spin_unlock_irqrestore(&io_request_lock, flags);
-	down(&sem);
-        SCpnt->request.sem = NULL;
-    }
-    
+
+    scsi_wait_cmd(SCpnt, (void *)sr_cmd, (void *)buffer, buflength,
+		  sr_ioctl_done, IOCTL_TIMEOUT, IOCTL_RETRIES);
+
     result = SCpnt->result;
     
     /* Minimal error checking.  Ignore cases we know about, and report the rest. */
diff -u --recursive --new-file v2.3.25/linux/drivers/scsi/sr_vendor.c linux/drivers/scsi/sr_vendor.c
--- v2.3.25/linux/drivers/scsi/sr_vendor.c	Tue Sep  7 12:14:06 1999
+++ linux/drivers/scsi/sr_vendor.c	Wed Nov  3 14:01:48 1999
@@ -158,7 +158,9 @@
 	if (scsi_CDs[minor].cdi.mask & CDC_MULTI_SESSION)
 		return 0;
 	
+	spin_lock_irq(&io_request_lock);
 	buffer = (unsigned char *) scsi_malloc(512);
+	spin_unlock_irq(&io_request_lock);
 	if(!buffer) return -ENOMEM;
 	
 	sector   = 0;         /* the multisession sector offset goes here  */
diff -u --recursive --new-file v2.3.25/linux/drivers/sgi/char/graphics.c linux/drivers/sgi/char/graphics.c
--- v2.3.25/linux/drivers/sgi/char/graphics.c	Tue Aug 31 17:29:14 1999
+++ linux/drivers/sgi/char/graphics.c	Tue Nov  2 17:40:11 1999
@@ -271,8 +271,6 @@
 	uint size;
 
 	size = vma->vm_end - vma->vm_start;
-	if (vma->vm_offset & ~PAGE_MASK)
-		return -ENXIO;
 
 	/* 1. Set our special graphic virtualizer  */
 	vma->vm_ops = &graphics_mmap;
diff -u --recursive --new-file v2.3.25/linux/drivers/sgi/char/shmiq.c linux/drivers/sgi/char/shmiq.c
--- v2.3.25/linux/drivers/sgi/char/shmiq.c	Mon Oct 11 15:38:15 1999
+++ linux/drivers/sgi/char/shmiq.c	Tue Nov  2 17:40:11 1999
@@ -318,7 +318,7 @@
 	if (minor-- == 0)
 		return -EINVAL;
 
-	if (vma->vm_offset != 0)
+	if (vma->vm_pgoff)
 		return -EINVAL;
 
 	size  = vma->vm_end - vma->vm_start;
diff -u --recursive --new-file v2.3.25/linux/drivers/sound/maestro.c linux/drivers/sound/maestro.c
--- v2.3.25/linux/drivers/sound/maestro.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/sound/maestro.c	Tue Nov  2 17:07:08 1999
@@ -24,9 +24,8 @@
  *	Heavily modified by Zach Brown <zab@redhat.com> based on lunch
  *	with ESS engineers.  Many thanks to Howard Kim for providing 
  *	contacts and hardware.  Honorable mention goes to Eric 
- *	Brombaugh for the BOB routines and great record code hacking.
- *	Best regards to the proprietors of Hack Central for fine
- *	lodging.
+ *	Brombaugh for all sorts of things.  Best regards to the 
+ *	proprietors of Hack Central for fine lodging.
  *
  *  Supported devices:
  *  /dev/dsp0-7    standard /dev/dsp device, (mostly) OSS compatible
@@ -79,12 +78,12 @@
  *	The wavecache makes our life even more fun.  First off, it can
  *	only address the first 28 bits of PCI address space, making it
  *	useless on quite a few architectures.  Secondly, its insane.
- *	It claims to only fetch from 4 regions of PCI space, each 4 meg in length.
+ *	It claims to fetch from 4 regions of PCI space, each 4 meg in length.
  *	But that doesn't really work.  You can only use 1 region.  So all our
  *	allocations have to be in 4meg of each other.  Booo.  Hiss.
  *	So we have a module parameter, dsps_order, that is the order of
  *	the number of dsps to provide.  All their buffer space is allocated
- *	on open time.  The sonicvibes oss routines we inherited really want
+ *	on open time.  The sonicvibes OSS routines we inherited really want
  *	power of 2 buffers, so we have all those next to each other, then
  *	512 byte regions for the recording wavecaches.  This ends up
  *	wasting quite a bit of memory.  The only fixes I can see would be 
@@ -103,8 +102,31 @@
  *	get at some of them :(.  The mixer interface doesn't, however.
  *	We also have an OSS state lock that is thrown around in a few
  *	places.
+ *
+ *	This driver has brute force APM suspend support.  We catch suspend
+ *	notifications and stop all work being done on the chip.  Any people
+ *	that try between this shutdown and the real suspend operation will
+ *	be put to sleep.  When we resume we restore our software state on
+ *	the chip and wake up the people that were using it.  The code thats
+ *	being used now is quite dirty and assumes we're on a uni-processor
+ *	machine.  Much of it will need to be cleaned up for SMP ACPI or 
+ *	similar.
  *	
  * History
+ *  v0.10 - Oct 28 1999 - Zach Brown <zab@redhat.com>
+ *	aha, so, sometimes the WP writes a status word to offset 0
+ *	  from one of the PCMBARs.  rearrange allocation accordingly..
+ *	Jeroen Hoogervorst submits 7500 fix out of nowhere.  yay.  :)
+ *  v0.09 - Oct 23 1999 - Zach Brown <zab@redhat.com>
+ *	added APM support.
+ *	re-order something such that some 2Es now work.  Magic!
+ *	new codec reset routine.  made some codecs come to life.
+ *	fix clear_advance, sync some control with ESS.
+ *	now write to all base regs to be paranoid.
+ *  v0.08 - Oct 20 1999 - Zach Brown <zab@redhat.com>
+ *	Fix initial buflen bug.  I am so smart.  also smp compiling..
+ *	I owe Eric yet another beer: fixed recmask, igain, 
+ *	  muting, and adc sync consistency.  Go Team.
  *  v0.07 - Oct 4 1999 - Zach Brown <zab@redhat.com>
  *	tweak adc/dac, formating, and stuff to allow full duplex
  *	allocate dsps memory at open() so we can fit in the wavecache window
@@ -140,32 +162,41 @@
  *	anyone have a pt101 codec?
  *	mmap(), but beware stereo encoding nastiness.
  *	actually post pci writes
- *	look really hard at the apu/bob/dma buffer code paths.
  *	fix bob frequency
  *	do smart things with ac97 2.0 bits.
- *	test different sized writes
- *	fixup latencies ?
- *	get apm save/restore working?
+ *	ugh.. non aligned writes in the middle of a data stream.. ugh
  *	sort out 0x34->0x36 crap in init
+ *	docking and dual codecs and 978?
+ *	pcm_sync?
+ *	actually use LRLR
  *
- *	apm is kind of a mess.  I doubt we can rely on the machine keeping
- *	power to the maestro/codecs when we suspend.  This means we have
- *	to keep full mixer/wavecache/apu state.  bother.  if we could rely 
- *	on the chips being powered we would simply turn down the apus and
- *	bob and it would all just work out.  That last bit I've implemented
- *	before I realized how much it was all going to suck :).
- *	
  *	it also would be fun to have a mode that would not use pci dma at all
  *	but would copy into the wavecache on board memory and use that 
- *	on architectures that don't like the maestro's pci dma ickiness 
- *	throughout.
+ *	on architectures that don't like the maestro's pci dma ickiness.
  */
 
 /*****************************************************************************/
 
-      
-#include <linux/module.h>
 #include <linux/version.h>
+#include <linux/module.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
+
+ #define DECLARE_WAITQUEUE(QUEUE,INIT) struct wait_queue QUEUE = {INIT, NULL}
+ #define wait_queue_head_t struct wait_queue *
+ #define SILLY_PCI_BASE_ADDRESS(PCIDEV) (PCIDEV->base_address[0] & PCI_BASE_ADDRESS_IO_MASK)
+ #define SILLY_INIT_SEM(SEM) SEM=MUTEX;
+ #define init_waitqueue_head init_waitqueue
+ #define SILLY_MAKE_INIT(FUNC) __initfunc(FUNC)
+
+#else
+
+ #define SILLY_PCI_BASE_ADDRESS(PCIDEV) (PCIDEV->resource[0].start)
+ #define SILLY_INIT_SEM(SEM) init_MUTEX(&SEM)
+ #define SILLY_MAKE_INIT(FUNC) __init FUNC
+
+#endif
+
 #include <linux/string.h>
 #include <linux/ctype.h>
 #include <linux/ioport.h>
@@ -175,16 +206,23 @@
 #include <linux/malloc.h>
 #include <linux/soundcard.h>
 #include <linux/pci.h>
+#include <linux/spinlock.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>
+static int maestro_apm_callback(apm_event_t ae);
+static int in_suspend=0;
+wait_queue_head_t suspend_queue;
+static void check_suspend(void);
+#define CHECK_SUSPEND check_suspend();
+#else
+#define CHECK_SUSPEND
 #endif
 
 #include "maestro.h"
@@ -202,7 +240,7 @@
 #endif
 
 /* --------------------------------------------------------------------- */
-#define DRIVER_VERSION "0.07"
+#define DRIVER_VERSION "0.10"
 
 #ifndef PCI_VENDOR_ESS
 #define PCI_VENDOR_ESS			0x125D
@@ -235,9 +273,13 @@
 #define MAX_DSP_ORDER	3
 #define MAX_DSPS	(1<<3)
 #define NR_DSPS		(1<<dsps_order)
+#define NR_IDRS		32
 
 #define SND_DEV_DSP16   5 
 
+#define NR_APUS		64
+#define NR_APU_REGS	16
+
 static const unsigned sample_size[] = { 1, 2, 2, 4 };
 static const unsigned sample_shift[] = { 0, 1, 1, 2 };
 
@@ -262,6 +304,7 @@
 	u8 apu[6];		/* l/r output, l/r intput converters, l/r input apus */
 	u8 apu_mode[6];		/* Running mode for this APU */
 	u8 apu_pan[6];		/* Panning setup for this APU */
+	u32 apu_base[6];	/* base address for this apu */
 	struct ess_card *card;	/* Card info */
 	/* wave stuff */
 	unsigned int rateadc, ratedac;
@@ -334,11 +377,11 @@
 	} mix;
 	
 	struct ess_state channels[MAX_DSPS];
-	u16 maestro_map[32];	/* Register map */
+	u16 maestro_map[NR_IDRS];	/* Register map */
 #ifdef CONFIG_APM
 	/* we have to store this junk so that we can come back from a
 		suspend */
-	u16 apu_map[64][16];	/* contents of apu regs */
+	u16 apu_map[NR_APUS][NR_APU_REGS];	/* contents of apu regs */
 #endif
 
 	/* this locks around the physical registers on the card */
@@ -349,6 +392,7 @@
 	int dmaorder;
 
 	/* hardware resources */
+	struct pci_dev pcidev; /* uck.. */
 	u32 iobase;
 	u32 irq;
 
@@ -356,7 +400,8 @@
 	char dsps_open;
 };
 
-extern __inline__ unsigned ld2(unsigned int x)
+static unsigned 
+ld2(unsigned int x)
 {
 	unsigned r = 0;
 	
@@ -399,6 +444,8 @@
 	/*
 	 *	Wait for the codec bus to be free 
 	 */
+
+	CHECK_SUSPEND;
 	 
 	for(i=0;i<10000;i++)
 	{
@@ -420,6 +467,7 @@
 	u16 data;
 	int i;
 	
+	CHECK_SUSPEND;
 	/*
 	 *	Wait for the codec bus to be free 
 	 */
@@ -467,23 +515,18 @@
 	be sure to fill it in if you add oss mixers
 	to anyone's supported mixer defines */
 
-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}
+ unsigned int mixer_defaults[SOUND_MIXER_NRDEVICES] = {
+	[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
 };
 	
 static struct ac97_mixer_hw {
@@ -500,7 +543,7 @@
 	[SOUND_MIXER_VIDEO]	=	{0x14,31},
 	[SOUND_MIXER_LINE1]	=	{0x16,31},
 	[SOUND_MIXER_PCM]	=	{0x18,31},
-	[SOUND_MIXER_IGAIN]	=	{0x1c,31}
+	[SOUND_MIXER_IGAIN]	=	{0x1c,15}
 };
 
 #if 0 /* *shrug* removed simply because we never used it.
@@ -563,18 +606,22 @@
 	M_printk("wrote mixer %d (0x%x) %d,%d",mixer,mh->offset,left,right);
 
 	if(AC97_STEREO_MASK & (1<<mixer)) {
-		/* stereo mixers */
-
+		/* stereo mixers, mute them if we can */
 
 		if (mixer == SOUND_MIXER_IGAIN) {
+			/* igain's slider is reversed.. */
 			right = (right * mh->scale) / 100;
 			left = (left * mh->scale) / 100;
+			if ((left == 0) && (right == 0))
+				val |= 0x8000; 
 		} else {
 			right = ((100 - right) * mh->scale) / 100;
 			left = ((100 - left) * mh->scale) / 100;
+			if((left == mh->scale) && (right == mh->scale))
+				val |= 0x8000;
 		}
 
-		val = (left << 8) | right;
+		val |= (left << 8) | right;
 
 	} else if (mixer == SOUND_MIXER_SPEAKER) {
 		val = (((100 - left) * mh->scale) / 100) << 1;
@@ -610,13 +657,13 @@
 	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
+static unsigned int ac97_oss_mask[] = {
+	[AC97_REC_MIC] = SOUND_MASK_MIC, 
+	[AC97_REC_CD] = SOUND_MASK_CD, 
+	[AC97_REC_VIDEO] = SOUND_MASK_VIDEO, 
+	[AC97_REC_AUX] = SOUND_MASK_LINE1, 
+	[AC97_REC_LINE] = SOUND_MASK_LINE, 
+	[AC97_REC_PHONE] = SOUND_MASK_PHONEIN
 };
 
 /* indexed by bit position */
@@ -635,21 +682,20 @@
 	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 ess_card *card, int rw, int mask) 
+static int 
+ac97_recmask_io(struct ess_card *card, int read, int mask) 
 {
-	unsigned int val;
+	unsigned int val = ac97_oss_mask[ maestro_ac97_get(card->iobase, 0x1a) & 0x7 ];
 
-	if (rw) {
-		/* read it from the card */
-		val = maestro_ac97_get(card->iobase, 0x1a) & 0x7;
-		return ac97_rm2oss[val];
-	}
+	if (read) return val;
+
+	/* oss can have many inputs, maestro cant.  try
+		to pick the 'new' one */
 
-	/* else, write the first set in the mask as the
-		output */	
+	if (mask != val) mask &= ~val;
 
-	val = ffs(mask); 
-	val = ac97_oss_rm[val-1];
+	val = ffs(mask) - 1; 
+	val = ac97_oss_rm[val];
 	val |= val << 8;  /* set both channels */
 
 	M_printk("maestro: setting ac97 recmask to 0x%x\n",val);
@@ -678,33 +724,6 @@
 	card->mix.write_mixer = ac97_write_mixer;
 	card->mix.recmask_io = ac97_recmask_io;
 
-#if 0  /* this needs to be thought about harder */
-	/* aim at the second codec */
-	outw(0x21, iobase+0x38);
-	outw(0x5555, iobase+0x3a);
-	outw(0x5555, iobase+0x3c);
-	udelay(1);
-	vend1 = maestro_ac97_get(iobase, 0x7c);
-	vend2 = maestro_ac97_get(iobase, 0x7e);
-	if(vend1 != 0xffff || vend2 != 0xffff) {
-		printk("maestro: second codec 0x%4x%4x found, enabling both.  please report this.\n",
-			vend1,vend2);
-		/* enable them both */
-		outw(0x00, iobase+0x38);
-		outw(0xFFFC, iobase+0x3a);
-		outw(0x000C, iobase+0x3c);
-	} else {
-		/* back to the first only */
-		outw(0x0, iobase+0x38);
-		outw(0x0, iobase+0x3a);
-		outw(0x0, iobase+0x3c);
-	}
-	udelay(1);
-#endif
-
-	/* perform codec reset */
-	maestro_ac97_set(iobase, 0x00, 0xFFFF);
-
 	vend1 = maestro_ac97_get(iobase, 0x7c);
 	vend2 = maestro_ac97_get(iobase, 0x7e);
 
@@ -773,49 +792,75 @@
 	return 0;
 }
 
-static void maestro_ac97_reset(int ioaddr)
+/* this is very magic, and very slow.. */
+static void 
+maestro_ac97_reset(int ioaddr, struct pci_dev *pcidev)
 {
-/*	outw(0x2000,  ioaddr+0x36);
-	inb(ioaddr);
-	mdelay(1);
-	outw(0x0000,  ioaddr+0x36);
-	inb(ioaddr);
-	mdelay(1);*/
+	u16 save_68;
+	u16 w;
 
-	/* well this seems to work a little
-		better on my pci board.. probably
-		because gpio is wired to ac97 reset */
+	outw( inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
+	outw( inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
+	outw( inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
 
-	/* this screws around with the gpio
-		mask/input/direction.. */
+	/* reset the first codec */
 	outw(0x0000,  ioaddr+0x36);
+	save_68 = inw(ioaddr+0x68);
+	pci_read_config_word(pcidev, 0x58, &w);	/* something magical with gpio and bus arb. */
+	if( w & 0x1)
+		save_68 |= 0x10;
+	outw(0xfffe, ioaddr + 0x64);	/* tickly gpio 0.. */
+	outw(0x0001, ioaddr + 0x68);
+	outw(0x0000, ioaddr + 0x60);
 	udelay(20);
-	outw(0xFFFE,  ioaddr+0x64);
-	outw(0x1,  ioaddr+0x68);
-	outw(0x0,  ioaddr+0x60);
-	udelay(20);
-	outw(0x1,  ioaddr+0x60);
-	udelay(20); /* other source says 500ms.. INSANE */
-	outw(0x2000,  ioaddr+0x36);
-	udelay(20);
-	outw(0x3000,  ioaddr+0x36);
-	udelay(200);
-	outw(0x0001,  ioaddr+0x68);
-	outw(0xFFFF,  ioaddr+0x64);
+	outw(0x0001, ioaddr + 0x60);
+	mdelay(20);
 
-	/* strange strange reset tickling the ring bus */
-	outw(0x0, ioaddr+0x36);
-	udelay(20);
-	outw(0x200, ioaddr+0x36); /* first codec only */
-	udelay(20);
-	outw(0x0, ioaddr+0x36);
-	udelay(20);
-	outw(0x2000, ioaddr+0x36);
-	udelay(20);
-	outw(0x3000, ioaddr+0x36);
+	outw(save_68 | 0x1, ioaddr + 0x68);	/* now restore .. */
+	outw( (inw(ioaddr + 0x38) & 0xfffc)|0x1, ioaddr + 0x38);
+	outw( (inw(ioaddr + 0x3a) & 0xfffc)|0x1, ioaddr + 0x3a);
+	outw( (inw(ioaddr + 0x3c) & 0xfffc)|0x1, ioaddr + 0x3c);
+
+	/* now the second codec */
+	outw(0x0000,  ioaddr+0x36);
+	outw(0xfff7, ioaddr + 0x64);
+	save_68 = inw(ioaddr+0x68);
+	outw(0x0009, ioaddr + 0x68);
+	outw(0x0001, ioaddr + 0x60);
 	udelay(20);
+	outw(0x0009, ioaddr + 0x60);
+	mdelay(500);	/* .. ouch.. */
+	outw( inw(ioaddr + 0x38) & 0xfffc, ioaddr + 0x38);
+	outw( inw(ioaddr + 0x3a) & 0xfffc, ioaddr + 0x3a);
+	outw( inw(ioaddr + 0x3c) & 0xfffc, ioaddr + 0x3c);
+
+#if 0 /* the loop here needs to be much better if we want it.. */
+	M_printk("trying software reset\n");
+	/* try and do a software reset */
+	outb(0x80|0x7c, ioaddr + 0x30);
+	for (w=0; ; w++) {
+		if ((inw(ioaddr+ 0x30) & 1) == 0) {
+			if(inb(ioaddr + 0x32) !=0) break;
+
+			outb(0x80|0x7d, ioaddr + 0x30);
+			if (((inw(ioaddr+ 0x30) & 1) == 0) && (inb(ioaddr + 0x32) !=0)) break;
+			outb(0x80|0x7f, ioaddr + 0x30);
+			if (((inw(ioaddr+ 0x30) & 1) == 0) && (inb(ioaddr + 0x32) !=0)) break;
+		}
+
+		if( w > 10000) {
+			outb( inb(ioaddr + 0x37) | 0x08, ioaddr + 0x37);  /* do a software reset */
+			mdelay(500); /* oh my.. */
+			outb( inb(ioaddr + 0x37) & ~0x08, ioaddr + 0x37);  
+			udelay(1);
+			outw( 0x80, ioaddr+0x30);
+			for(w = 0 ; w < 10000; w++) {
+				if((inw(ioaddr + 0x30) & 1) ==0) break;
+			}
+		}
+	}
+#endif
 }
-
 /*
  *	Indirect register access. Not all registers are readable so we
  *	need to keep register state ourselves
@@ -835,19 +880,21 @@
 
 	outw(reg, ioaddr+0x02);
 	outw(data, ioaddr+0x00);
-	card->maestro_map[reg]=data;
+	if( reg >= NR_IDRS) printk("maestro: IDR %d out of bounds!\n",reg);
+	else card->maestro_map[reg]=data;
 
 }
  
-static void maestro_write(struct ess_state *ess, u16 reg, u16 data)
+static void maestro_write(struct ess_state *s, u16 reg, u16 data)
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&ess->card->lock,flags);
+	CHECK_SUSPEND;
+	spin_lock_irqsave(&s->card->lock,flags);
 
-	__maestro_write(ess->card,reg,data);
+	__maestro_write(s->card,reg,data);
 
-	spin_unlock_irqrestore(&ess->card->lock,flags);
+	spin_unlock_irqrestore(&s->card->lock,flags);
 }
 
 static u16 __maestro_read(struct ess_card *card, u16 reg)
@@ -858,18 +905,19 @@
 	return card->maestro_map[reg]=inw(ioaddr+0x00);
 }
 
-static u16 maestro_read(struct ess_state *ess, u16 reg)
+static u16 maestro_read(struct ess_state *s, u16 reg)
 {
 	if(READABLE_MAP & (1<<reg))
 	{
 		unsigned long flags;
-		spin_lock_irqsave(&ess->card->lock,flags);
+		CHECK_SUSPEND;
+		spin_lock_irqsave(&s->card->lock,flags);
 
-		__maestro_read(ess->card,reg);
+		__maestro_read(s->card,reg);
 
-		spin_unlock_irqrestore(&ess->card->lock,flags);
+		spin_unlock_irqrestore(&s->card->lock,flags);
 	}
-	return ess->card->maestro_map[reg];
+	return s->card->maestro_map[reg];
 }
 
 /*
@@ -917,10 +965,12 @@
  *	directly with the stuff above.
  */
 
-static void apu_set_register(struct ess_state *ess, u16 channel, u8 reg, u16 data)
+static void apu_set_register(struct ess_state *s, u16 channel, u8 reg, u16 data)
 {
 	unsigned long flags;
 	
+	CHECK_SUSPEND;
+
 	if(channel&ESS_CHAN_HARD)
 		channel&=~ESS_CHAN_HARD;
 	else
@@ -928,41 +978,43 @@
 		if(channel>5)
 			printk("BAD CHANNEL %d.\n",channel);
 		else
-			channel = ess->apu[channel];
-	}
+			channel = s->apu[channel];
 #ifdef	CONFIG_APM
-	/* store based on real hardware apu/reg */
-	ess->card->apu_map[channel][reg]=data;
+		/* store based on real hardware apu/reg */
+		s->card->apu_map[channel][reg]=data;
 #endif
+	}
 	reg|=(channel<<4);
 	
 	/* hooray for double indirection!! */
-	spin_lock_irqsave(&ess->card->lock,flags);
+	spin_lock_irqsave(&s->card->lock,flags);
 
-	apu_index_set(ess->card, reg);
-	apu_data_set(ess->card, data);
+	apu_index_set(s->card, reg);
+	apu_data_set(s->card, data);
 
-	spin_unlock_irqrestore(&ess->card->lock,flags);
+	spin_unlock_irqrestore(&s->card->lock,flags);
 }
 
-static u16 apu_get_register(struct ess_state *ess, u16 channel, u8 reg)
+static u16 apu_get_register(struct ess_state *s, u16 channel, u8 reg)
 {
 	unsigned long flags;
 	u16 v;
 	
+	CHECK_SUSPEND;
+
 	if(channel&ESS_CHAN_HARD)
 		channel&=~ESS_CHAN_HARD;
 	else
-		channel = ess->apu[channel];
+		channel = s->apu[channel];
 
 	reg|=(channel<<4);
 	
-	spin_lock_irqsave(&ess->card->lock,flags);
+	spin_lock_irqsave(&s->card->lock,flags);
 
-	apu_index_set(ess->card, reg);
-	v=__maestro_read(ess->card, IDR0_DATA_PORT);
+	apu_index_set(s->card, reg);
+	v=__maestro_read(s->card, IDR0_DATA_PORT);
 
-	spin_unlock_irqrestore(&ess->card->lock,flags);
+	spin_unlock_irqrestore(&s->card->lock,flags);
 	return v;
 }
 
@@ -972,29 +1024,31 @@
  *	pci bus mastering
  */
  
-static void wave_set_register(struct ess_state *ess, u16 reg, u16 value)
+static void wave_set_register(struct ess_state *s, u16 reg, u16 value)
 {
-	long ioaddr = ess->card->iobase;
+	long ioaddr = s->card->iobase;
 	unsigned long flags;
+	CHECK_SUSPEND;
 	
-	spin_lock_irqsave(&ess->card->lock,flags);
+	spin_lock_irqsave(&s->card->lock,flags);
 
 	outw(reg, ioaddr+0x10);
 	outw(value, ioaddr+0x12);
 
-	spin_unlock_irqrestore(&ess->card->lock,flags);
+	spin_unlock_irqrestore(&s->card->lock,flags);
 }
 
-static u16 wave_get_register(struct ess_state *ess, u16 reg)
+static u16 wave_get_register(struct ess_state *s, u16 reg)
 {
-	long ioaddr = ess->card->iobase;
+	long ioaddr = s->card->iobase;
 	unsigned long flags;
 	u16 value;
+	CHECK_SUSPEND;
 	
-	spin_lock_irqsave(&ess->card->lock,flags);
+	spin_lock_irqsave(&s->card->lock,flags);
 	outw(reg, ioaddr+0x10);
 	value=inw(ioaddr+0x12);
-	spin_unlock_irqrestore(&ess->card->lock,flags);
+	spin_unlock_irqrestore(&s->card->lock,flags);
 	
 	return value;
 }
@@ -1165,7 +1219,8 @@
  */
 
 /* the mode passed should be already shifted and masked */
-static void ess_play_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size)
+static void 
+ess_play_setup(struct ess_state *ess, int mode, u32 rate, void *buffer, int size)
 {
 	u32 pa;
 	u32 tmpval;
@@ -1198,23 +1253,17 @@
 
 		/* set the wavecache control reg */
 		tmpval = (pa - 0x10) & 0xFFF8;
-#if 0
-		if(mode & 1) tmpval |= 2; /* stereo */
-#endif
 		if(!(mode & 2)) tmpval |= 4; /* 8bit */ 
+		ess->apu_base[channel]=tmpval;
 		wave_set_register(ess, ess->apu[channel]<<3, tmpval);
 		
-		pa&=0x1FFFFF;			/* Low 21 bits */	
+		pa -= virt_to_bus(ess->card->dmapages);
 		pa>>=1; /* words */
 		
 		/* base offset of dma calcs when reading the pointer
 			on this left one */
 		if(!channel) ess->dma_dac.base = pa&0xFFFF;
 		
-#if 0
-		if(mode&ESS_FMT_STEREO)			/* Enable stereo */
-			pa|=0x00800000;
-#endif
 		pa|=0x00400000;			/* System RAM */
 		
 		/* Begin loading the APU */		
@@ -1232,14 +1281,12 @@
 		
 		/* clear effects/env.. */
 		apu_set_register(ess, channel, 8, 0x0000);
-		/* aplitudeNow to 0xd0? */
+		/* set amp now to 0xd0 (?), low byte is 'amplitude dest'? */
 		apu_set_register(ess, channel, 9, 0xD000);
 
-		/* set the panning reg of the apu to left/right/mid.. */
-
 		/* clear routing stuff */
 		apu_set_register(ess, channel, 11, 0x0000);
-		/* mark dma and turn on filter stuff? */
+		/* dma on, no envelopes, filter to all 1s) */
 		apu_set_register(ess, channel, 0, 0x400F);
 		
 		if(mode&ESS_FMT_STEREO)
@@ -1341,9 +1388,10 @@
 		
 		/* set the wavecache control reg */
 		tmpval = (pa - 0x10) & 0xFFF8;
+		ess->apu_base[channel]=tmpval;
 		wave_set_register(ess, ess->apu[channel]<<3, tmpval);
 		
-		pa&=0x1FFFFF;			/* Low 21 bits*/	
+		pa -= virt_to_bus(ess->card->dmapages);
 		pa>>=1; /* words */
 		
 		/* base offset of dma calcs when reading the pointer
@@ -1409,18 +1457,9 @@
 /* Playback pointer */
 extern __inline__ unsigned get_dmaa(struct ess_state *s)
 {
-	long ioport = s->card->iobase;
 	int offset;
-	unsigned long flags;
-
-	spin_lock_irqsave(&s->card->lock,flags);
-	
-	outw(1, ioport+2);
-	outw(s->apu[0]<<4|5, ioport);
-	outw(0, ioport+2);
-	offset=inw(ioport);
 
-	spin_unlock_irqrestore(&s->card->lock,flags);
+	offset = apu_get_register(s,0,5);
 
 /*	M_printk("dmaa: offset: %d, base: %d\n",offset,s->dma_dac.base); */
 	
@@ -1432,18 +1471,9 @@
 /* Record pointer */
 extern __inline__ unsigned get_dmac(struct ess_state *s)
 {
-	long ioport = s->card->iobase;
 	int offset;
-	unsigned long flags;
 
-	spin_lock_irqsave(&s->card->lock,flags);
-	
-	outw(1, ioport+2);
-	outw(s->apu[2]<<4|5, ioport);
-	outw(0, ioport+2);
-	offset=inw(ioport);
-
-	spin_unlock_irqrestore(&s->card->lock,flags);
+	offset = apu_get_register(s,2,5);
 
 /*	M_printk("dmac: offset: %d, base: %d\n",offset,s->dma_adc.base); */
 	
@@ -1592,11 +1622,7 @@
 		else
 			db->fragshift = db->ossfragshift;
 	} else {
-	/*	lets hand out reasonable big ass buffers by default */
-		db->fragshift = (db->buforder - 2);
-#if 0
 		db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1));
-#endif
 		if (db->fragshift < 3)
 			db->fragshift = 3; 
 	}
@@ -1629,25 +1655,33 @@
 	return 0;
 }
 
-/* XXX haha, way broken with our split stereo setup.  giggle. */
-/* only called by ess_write (dac ness ) */
 static __inline__ void 
 clear_advance(struct ess_state *s)
 {
 	unsigned char c = ((s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_16BIT) ? 0 : 0x80;
 	unsigned char *buf = s->dma_dac.rawbuf;
 	unsigned bsize = s->dma_dac.dmasize;
+	/* swptr is always in bytes as read from an apu.. */
 	unsigned bptr = s->dma_dac.swptr;
 	unsigned len = s->dma_dac.fragsize;
+	int i=1;
 
-	if (bptr + len > bsize) {
-		unsigned x = bsize - bptr;
-		memset(buf + bptr, c, x);
-		/* account for wrapping? */
-		bptr = 0;
-		len -= x;
+	if((s->fmt >> ESS_DAC_SHIFT)  & ESS_FMT_STEREO) {
+		i++;
+		bsize >>=1;
+	}
+		
+	for ( ;i; i-- , buf += bsize) {
+
+		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);
 	}
-	memset(buf + bptr, c, len);
 }
 
 /* call with spinlock held! */
@@ -1680,6 +1714,10 @@
 				/* FILL ME 
 				wrindir(s, SV_CIENABLE, s->enable); */
 				stop_adc(s); 
+				/* brute force everyone back in sync, sigh */
+				s->dma_adc.count = 0;
+				s->dma_adc.swptr = 0;
+				s->dma_adc.hwptr = 0;
 				s->dma_adc.error++;
 			}
 		}
@@ -1721,7 +1759,8 @@
 	}
 }
 
-static void ess_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void 
+ess_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
         struct ess_state *s;
         struct ess_card *c = (struct ess_card *)dev_id;
@@ -1791,6 +1830,17 @@
 	card->mix.write_mixer(card,mixer,left,right);
 }
 
+static void
+mixer_push_state(struct ess_card *card)
+{
+	int i;
+	for(i = 0 ; i < SOUND_MIXER_NRDEVICES ; i++) {
+		if( ! supported_mixer(card,i)) continue;
+
+		set_mixer(card,i,card->mix.mixer_state[i]);
+	}
+}
+
 static int mixer_ioctl(struct ess_card *card, unsigned int cmd, unsigned long arg)
 {
 	int i, val=0;
@@ -1878,6 +1928,7 @@
 	case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
 
 		if (!card->mix.recmask_io) return -EINVAL;
+		if(!val) return 0;
 		if(! (val &= card->mix.record_sources)) return -EINVAL;
 
 		spin_lock(&card->lock);
@@ -2036,7 +2087,8 @@
 /* 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 ess_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t 
+ess_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
 {
 	struct ess_state *s = (struct ess_state *)file->private_data;
 	ssize_t ret;
@@ -2083,6 +2135,9 @@
 				goto rec_return_free;
 			}
 			if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
+#ifdef CONFIG_APM
+				if(! in_suspend)
+#endif
 				printk(KERN_DEBUG "maestro: 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);
@@ -2151,8 +2206,6 @@
 	left = real_buffer + offset;
 	right = real_buffer + bufsize/2 + offset;
 
-/*	M_printk("writing %d to %p and %p from %p:%d bufs: %d\n",count/2, left,right,real_buffer,offset,bufsize);*/
-
 	if(mode & ESS_FMT_16BIT) {
 		for(i=count/4; i ; i--) {
 			*(right++) = (*(so+2));
@@ -2172,7 +2225,8 @@
 	return 0;
 }
 
-static ssize_t ess_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t 
+ess_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
 {
 	struct ess_state *s = (struct ess_state *)file->private_data;
 	ssize_t ret;
@@ -2181,8 +2235,6 @@
 	unsigned char *splitbuf = NULL;
 	int cnt;
 	int mode = (s->fmt >> ESS_DAC_SHIFT) & ESS_FMT_MASK;
-
-/*	printk("maestro: ess_write: count %d\n", count);*/
 	
 	VALIDATE_STATE(s);
 	if (ppos != &file->f_pos)
@@ -2228,13 +2280,15 @@
 			cnt &= ~3;
 
 		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;
 				goto return_free;
 			}
 			if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
+#ifdef CONFIG_APM
+				if(! in_suspend)
+#endif
 				printk(KERN_DEBUG "maestro: 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);
@@ -2269,7 +2323,7 @@
 		}
 
 		if(mode & ESS_FMT_STEREO) {
-			/* again with the weird pointer magic*/
+			/* again with the weird pointer magic */
 			swptr = (swptr + (cnt/2)) % (s->dma_dac.dmasize/2);
 		} else {
 			swptr = (swptr + cnt) % s->dma_dac.dmasize;
@@ -2339,7 +2393,7 @@
 		db = &s->dma_adc;
 	} else 
 		return -EINVAL;
-	if (vma->vm_pgoff != 0)
+	if (vma->vm_pgofft != 0)
 		return -EINVAL;
 	size = vma->vm_end - vma->vm_start;
 	if (size > (PAGE_SIZE << db->buforder))
@@ -2661,6 +2715,20 @@
 	return -EINVAL;
 }
 
+static void
+set_base_registers(struct ess_state *s,void *vaddr)
+{
+	unsigned long packed_phys = virt_to_bus(vaddr)>>12;
+	wave_set_register(s, 0x01FC , packed_phys);
+	wave_set_register(s, 0x01FD , packed_phys);
+	wave_set_register(s, 0x01FE , packed_phys);
+	wave_set_register(s, 0x01FF , packed_phys);
+}
+
+/* we allocate a large power of two for all our memory.
+	this is cut up into (not to scale :):
+	|silly fifo word	| 512byte mixbuf per adc	| dac/adc * channels |
+*/
 static int
 allocate_buffers(struct ess_state *s)
 {
@@ -2678,18 +2746,18 @@
 
 	M_printk("maestro: allocated %ld (%d) bytes at %p\n",PAGE_SIZE<<order,order, rawbuf);
 
-	if ((virt_to_bus(rawbuf) + (PAGE_SIZE << order) - 1) & ~((1<<28)-1)) /* silly limited pci poop */
-		printk(KERN_DEBUG "maestro: DMA buffer beyond 256MB: busaddr 0x%lx  size %ld\n",
+	if ((virt_to_bus(rawbuf) + (PAGE_SIZE << order) - 1) & ~((1<<28)-1))  {
+		printk(KERN_ERR "maestro: DMA buffer beyond 256MB! busaddr 0x%lx  size %ld\n",
 			virt_to_bus(rawbuf), PAGE_SIZE << order);
-
-	if ((PAGE_SIZE<<order) > (1<<22))
-		printk(KERN_DEBUG "maestro: %ld byte DMA buffer longer than APU can express!\n",PAGE_SIZE<<order);
+		kfree(rawbuf);
+		return 1;
+	}
 
 	s->card->dmapages = rawbuf;
 	s->card->dmaorder = order;
 
 	/* play bufs are in the same first region as record bufs */
-	wave_set_register(s, 0x01FC , ((virt_to_bus(rawbuf))&0xFFE00000)>>12);
+	set_base_registers(s,rawbuf);
 
 	M_printk("maestro: writing %lx (%lx) to the wp\n",virt_to_bus(rawbuf),
 		((virt_to_bus(rawbuf))&0xFFE00000)>>12);
@@ -2703,9 +2771,14 @@
 		ess->dma_dac.ready = s->dma_dac.mapped = 0;
 		ess->dma_adc.ready = s->dma_adc.mapped = 0;
 		ess->dma_adc.buforder = ess->dma_dac.buforder = order - 1 - dsps_order - 1;
-		ess->dma_dac.rawbuf = rawbuf + (i * ( PAGE_SIZE << (ess->dma_dac.buforder + 1 )));
+
+		/* offset dac and adc buffers starting half way through and then at each [da][ad]c's
+			order's intervals.. */
+		ess->dma_dac.rawbuf = rawbuf + (PAGE_SIZE<<(order-1)) + (i * ( PAGE_SIZE << (ess->dma_dac.buforder + 1 )));
 		ess->dma_adc.rawbuf = ess->dma_dac.rawbuf + ( PAGE_SIZE << ess->dma_dac.buforder);
-		ess->mixbuf = rawbuf + (PAGE_SIZE<<order) - (512 * (i+1));
+		/* offset mixbuf by a mixbuf so that the lame status fifo can
+			happily scribble away.. */ 
+		ess->mixbuf = rawbuf + (512 * (i+1));
 
 		M_printk("maestro: setup apu %d: %p %p %p\n",i,ess->dma_dac.rawbuf,
 			ess->dma_adc.rawbuf, ess->mixbuf);
@@ -2875,147 +2948,14 @@
 	NULL,  /* lock */
 };
 
-#ifdef CONFIG_APM
-int maestro_apm_callback(apm_event_t ae) {
-
-	struct ess_card *s;
-
-	if(ae != APM_USER_SUSPEND)
-		return 0;
-
-	printk("suspending.. blowing away apus\n");
-
-	while ((s = devs)) {
-		int i;
-		devs = devs->next;
-	
-		for(i=0;i<NR_DSPS;i++) {
-			struct ess_state *ess = &s->channels[i];
-			int j;
-
-			if(ess->dev_audio == -1)
-				continue;
-
-			for(j=0;j<6;j++) {
-				apu_set_register(ess, ess->apu[j], 0,
-					   (apu_get_register(ess, ess->apu[j], 0)&0xFF0F));
-			}
-
-		}
-	}
-	if(devs) {
-		printk("suspending.. stopping bob\n");
-		stop_bob(devs);
-	}
-
-	return 0;
-}
-#endif
-
-/* --------------------------------------------------------------------- */
-
-static int 
-maestro_install(struct pci_dev *pcidev, int card_type)
+static int
+maestro_config(struct ess_card *card) 
 {
+	struct pci_dev *pcidev = &card->pcidev;
+	struct ess_state *ess = &card->channels[0];
+	int apu,iobase  = card->iobase;
 	u16 w;
 	u32 n;
-	int iobase;
-	int i;
-	struct ess_card *card;
-	struct ess_state *ess;
-	int apu;
-	int num = 0;
-
-	/* don't pick up weird modem maestros */
-	if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO)
-		return 0;
-			
-	iobase = pcidev->resource[0].start;
-	
-	if(check_region(iobase, 256))
-	{
-		printk(KERN_WARNING "maestro: can't allocate 256 bytes I/O at 0x%4.4x\n", iobase);
-		return 0;
-	}
-
-	/* this was tripping up some machines */
-	if(pcidev->irq == 0) 
-	{
-		printk(KERN_WARNING "maestro: pci subsystem reports irq 0, this might not be correct.\n");
-	}
-
-	/* just to be sure */
-	pci_set_master(pcidev);
-
-	card = kmalloc(sizeof(struct ess_card), GFP_KERNEL);
-	if(card == NULL)
-	{
-		printk(KERN_WARNING "maestro: out of memory\n");
-		return 0;
-	}
-	
-	memset(card, 0, sizeof(*card));
-
-#ifdef CONFIG_APM
-	printk("reg_callback: %d\n",apm_register_callback(maestro_apm_callback));
-#endif
-
-	card->iobase = iobase;
-	card->card_type = card_type;
-	card->irq = pcidev->irq;
-	card->next = devs;
-	card->magic = ESS_CARD_MAGIC;
-	spin_lock_init(&card->lock);
-	devs = card;
-	
-	/* init our groups of 6 apus */
-	for(i=0;i<NR_DSPS;i++)
-	{
-		struct ess_state *s=&card->channels[i];
-
-		s->index = i;
-
-		s->card = card;
-		init_waitqueue_head(&s->dma_adc.wait);
-		init_waitqueue_head(&s->dma_dac.wait);
-		init_waitqueue_head(&s->open_wait);
-		spin_lock_init(&ess->lock);
-		init_MUTEX(&s->open_sem);
-		s->magic = ESS_STATE_MAGIC;
-		
-		s->apu[0] = 6*i;
-		s->apu[1] = (6*i)+1;
-		s->apu[2] = (6*i)+2;
-		s->apu[3] = (6*i)+3;
-		s->apu[4] = (6*i)+4;
-		s->apu[5] = (6*i)+5;
-		
-		if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf)
-			printk("maestro: BOTCH!\n");
-		/* register devices */
-		if ((s->dev_audio = register_sound_dsp(&ess_audio_fops, -1)) < 0)
-			break;
-	}
-	
-	num = i;
-	
-	/* clear the rest if we ran out of slots to register */
-	for(;i<NR_DSPS;i++)
-	{
-		struct ess_state *s=&card->channels[i];
-		s->dev_audio = -1;
-	}
-	
-	ess = &card->channels[0];
-
-	/*
-	 *	Ok card ready. Begin setup proper
-	 */
-
-	printk(KERN_INFO "maestro: Configuring %s found at IO 0x%04X IRQ %d\n", 
-		card_names[card_type],iobase,card->irq);
-	pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &n);
-	printk(KERN_INFO "maestro:  subvendor id: 0x%08x\n",n); 
 
 	/*
 	 *	Disable ACPI
@@ -3035,31 +2975,9 @@
 	w&=~(1<<10|1<<9|1<<8);
 
 	/* TDMA on */
-	w|=(1<<8);
-
-/* XXX do we care about these two ? */
-	/*
-	 *	MPU at 330
-	 */
-	
-	w&=~((1<<4)|(1<<3));
-	
-	/*
-	 *	SB at 0x220
-	 */
-
-	w&=~(1<<2);
-	
-#if 0 /* huh?  its sub decode.. */
+	w|= (1<<8);
 
 	/*
-	 *	Reserved write as 0
-	 */
-	 
-	w&=~(1<<1);
-#endif
-	
-	/*
 	 *	Some of these are undocumented bits
 	 */
 	 
@@ -3067,9 +2985,9 @@
 	w&=~(1<<11);			/* Safeguard off */
 	w|= (1<<7);			/* Posted write */
 	w|= (1<<6);			/* ISA timing on */
-	w&=~(1<<1);			/* Subtractive decode off */
 	/* XXX huh?  claims to be reserved.. */
 	w&=~(1<<5);			/* Don't swap left/right */
+	w&=~(1<<1);			/* Subtractive decode off */
 	
 	pci_write_config_word(pcidev, 0x50, w);
 	
@@ -3081,7 +2999,7 @@
 	w&=~(1<<7);		/* HWV off */
 	w&=~(1<<6);		/* Debounce off */
 	w&=~(1<<5);		/* GPIO 4:5 */
-	w&=~(1<<4);		/* Disconnect from the CHI */
+	w|= (1<<4);             /* Disconnect from the CHI.  Enabling this in made a dell 7500 work. */
 	w&=~(1<<3);		/* IDMA off (undocumented) */
 	w&=~(1<<2);		/* MIDI fix off (undoc) */
 	w&=~(1<<1);		/* reserved, always write 0 */
@@ -3108,7 +3026,7 @@
 	pci_write_config_word(pcidev, 0x40, w);
 
 	/* stake our claim on the iospace */
-	request_region(iobase, 256, card_names[card_type]);
+	request_region(iobase, 256, card_names[card->card_type]);
 	
 	sound_reset(iobase);
 
@@ -3127,7 +3045,7 @@
 	 *	Reset the CODEC
 	 */
 	 
-	maestro_ac97_reset(iobase);
+	maestro_ac97_reset(iobase,pcidev);
 	
 	/*
 	 *	Ring Bus Setup
@@ -3155,7 +3073,6 @@
 	n|=(1<<29);		/* Enable ring bus */
 	outl(n, iobase+0x34);
 	
-	
 	n=inl(iobase+0x34);
 	n|=(1<<28);		/* Enable serial bus */
 	outl(n, iobase+0x34);
@@ -3168,6 +3085,7 @@
 	n&=~0x000F0000;		/* I2S off */
 	outl(n, iobase+0x34);
 	
+
 	w=inw(iobase+0x18);
 	w&=~(1<<7);		/* ClkRun off */
 	outw(w, iobase+0x18);
@@ -3196,11 +3114,12 @@
 	w|=(1<<0);		/* SB IRQ on */
 	outw(w, iobase+0x18);
 
-#if 0 /* asp crap */
+	/* it appears some maestros (dell 7500) only work if these are set,
+		regardless of wether we use the assp or not. */
+
 	outb(0, iobase+0xA4); 
 	outb(3, iobase+0xA2); 
 	outb(0, iobase+0xA6);
-#endif
 	
 	for(apu=0;apu<16;apu++)
 	{
@@ -3255,13 +3174,132 @@
 			
 	/* Wave cache control on - test off, sg off, 
 		enable, enable extra chans 1Mb */
-		
+
 	outw(inw(0x14+iobase)|(1<<8),0x14+iobase);
 	outw(inw(0x14+iobase)&0xFE03,0x14+iobase);
 	outw((inw(0x14+iobase)&0xFFFC), 0x14+iobase);
 	outw(inw(0x14+iobase)|(1<<7),0x14+iobase);
 
-	outw(0xA1A0, 0x14+iobase);	/* 0300 ? */
+	outw(0xA1A0, 0x14+iobase);      /* 0300 ? */
+
+	/* Now clear the APU control ram */	
+	for(apu=0;apu<NR_APUS;apu++)
+	{
+		for(w=0;w<NR_APU_REGS;w++)
+			apu_set_register(ess, apu|ESS_CHAN_HARD, w, 0);
+		
+	}
+
+	return 0;
+	
+}
+
+
+static int 
+maestro_install(struct pci_dev *pcidev, int card_type)
+{
+	u32 n;
+	int iobase;
+	int i;
+	struct ess_card *card;
+	struct ess_state *ess;
+	int num = 0;
+
+	/* don't pick up weird modem maestros */
+	if(((pcidev->class >> 8) & 0xffff) != PCI_CLASS_MULTIMEDIA_AUDIO)
+		return 0;
+			
+	iobase = SILLY_PCI_BASE_ADDRESS(pcidev); 
+
+	if(check_region(iobase, 256))
+	{
+		printk(KERN_WARNING "maestro: can't allocate 256 bytes I/O at 0x%4.4x\n", iobase);
+		return 0;
+	}
+
+	/* this was tripping up some machines */
+	if(pcidev->irq == 0) 
+	{
+		printk(KERN_WARNING "maestro: pci subsystem reports irq 0, this might not be correct.\n");
+	}
+
+	/* just to be sure */
+	pci_set_master(pcidev);
+
+	card = kmalloc(sizeof(struct ess_card), GFP_KERNEL);
+	if(card == NULL)
+	{
+		printk(KERN_WARNING "maestro: out of memory\n");
+		return 0;
+	}
+	
+	memset(card, 0, sizeof(*card));
+	memcpy(&card->pcidev,pcidev,sizeof(card->pcidev));
+
+#ifdef CONFIG_APM
+	if (apm_register_callback(maestro_apm_callback)) {
+		printk(KERN_WARNING "maestro: apm suspend might not work.\n");
+	}
+#endif
+
+	card->iobase = iobase;
+	card->card_type = card_type;
+	card->irq = pcidev->irq;
+	card->next = devs;
+	card->magic = ESS_CARD_MAGIC;
+	spin_lock_init(&card->lock);
+	devs = card;
+	
+	/* init our groups of 6 apus */
+	for(i=0;i<NR_DSPS;i++)
+	{
+		struct ess_state *s=&card->channels[i];
+
+		s->index = i;
+
+		s->card = card;
+		init_waitqueue_head(&s->dma_adc.wait);
+		init_waitqueue_head(&s->dma_dac.wait);
+		init_waitqueue_head(&s->open_wait);
+		spin_lock_init(&s->lock);
+		SILLY_INIT_SEM(s->open_sem);
+		s->magic = ESS_STATE_MAGIC;
+		
+		s->apu[0] = 6*i;
+		s->apu[1] = (6*i)+1;
+		s->apu[2] = (6*i)+2;
+		s->apu[3] = (6*i)+3;
+		s->apu[4] = (6*i)+4;
+		s->apu[5] = (6*i)+5;
+		
+		if(s->dma_adc.ready || s->dma_dac.ready || s->dma_adc.rawbuf)
+			printk("maestro: BOTCH!\n");
+		/* register devices */
+		if ((s->dev_audio = register_sound_dsp(&ess_audio_fops, -1)) < 0)
+			break;
+	}
+	
+	num = i;
+	
+	/* clear the rest if we ran out of slots to register */
+	for(;i<NR_DSPS;i++)
+	{
+		struct ess_state *s=&card->channels[i];
+		s->dev_audio = -1;
+	}
+	
+	ess = &card->channels[0];
+
+	/*
+	 *	Ok card ready. Begin setup proper
+	 */
+
+	printk(KERN_INFO "maestro: Configuring %s found at IO 0x%04X IRQ %d\n", 
+		card_names[card_type],iobase,card->irq);
+	pci_read_config_dword(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &n);
+	printk(KERN_INFO "maestro:  subvendor id: 0x%08x\n",n); 
+
+	maestro_config(card);
 
 	if(maestro_ac97_get(iobase, 0x00)==0x0080) {
 		maestro_pt101_init(card,iobase);
@@ -3272,21 +3310,8 @@
 	if ((card->dev_mixer = register_sound_mixer(&ess_mixer_fops, -1)) < 0) {
 		printk("maestro: 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);
-		}
-	}
-	
-	/* Now clear the channel data */	
-	for(apu=0;apu<64;apu++)
-	{
-		for(w=0;w<0x0E;w++)
-			apu_set_register(ess, apu|ESS_CHAN_HARD, w, 0);
+		memcpy(card->mix.mixer_state,mixer_defaults,sizeof(card->mix.mixer_state));
+		mixer_push_state(card);
 	}
 	
 	if(request_irq(card->irq, ess_interrupt, SA_SHIRQ, card_names[card_type], card))
@@ -3304,15 +3329,14 @@
 		return 0;
 	}
 
-	printk("maestro: %d channels configured.\n", num);
+	printk(KERN_INFO "maestro: %d channels configured.\n", num);
 	return 1; 
 }
 
-/* XXX __init ? */
 #ifdef MODULE
 int init_module(void)
 #else
-int __init init_maestro(void)
+int SILLY_MAKE_INIT(init_maestro(void))
 #endif
 {
 	struct pci_dev *pcidev = NULL;
@@ -3333,6 +3357,10 @@
 		printk(KERN_WARNING "maestro: clipping dsps_order to %d\n",dsps_order);
 	}
 
+#ifdef CONFIG_APM
+	init_waitqueue_head(&suspend_queue);
+#endif
+
 	/*
 	 *	Find the ESS Maestro 2.
 	 */
@@ -3373,8 +3401,8 @@
 MODULE_DESCRIPTION("ESS Maestro Driver");
 #ifdef M_DEBUG
 MODULE_PARM(debug,"i");
-MODULE_PARM(dsps_order,"i");
 #endif
+MODULE_PARM(dsps_order,"i");
 
 void cleanup_module(void)
 {
@@ -3404,3 +3432,146 @@
 }
 
 #endif /* MODULE */
+#ifdef CONFIG_APM
+
+void
+check_suspend(void)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	if(!in_suspend) return;
+
+	in_suspend++;
+	add_wait_queue(&suspend_queue, &wait);
+	current->state = TASK_UNINTERRUPTIBLE;
+	schedule();
+	remove_wait_queue(&suspend_queue, &wait);
+	current->state = TASK_RUNNING;
+}
+
+static int 
+maestro_apm_suspend(void)
+{
+	struct ess_card *card;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	for (card = devs; card ; card = card->next) {
+		int i,j;
+
+		M_printk("maestro: apm in dev %p\n",card);
+
+		for(i=0;i<NR_DSPS;i++) {
+			struct ess_state *s = &card->channels[i];
+
+			if(s->dev_audio == -1)
+				continue;
+
+			M_printk("maestro: stopping apus for device %d\n",i);
+			stop_dac(s);
+			stop_adc(s);
+			for(j=0;j<6;j++) 
+				card->apu_map[s->apu[i]][5]=apu_get_register(s,i,5);
+
+		}
+
+		/* get rid of interrupts? */
+		if( card->dsps_open > 0)
+			stop_bob(&card->channels[0]);
+	}
+	in_suspend=1;
+
+	restore_flags(flags);
+
+	/* we'll let the bios do the rest of the power down.. */
+
+	return 0;
+}
+static int 
+maestro_apm_resume(void)
+{
+	struct ess_card *card;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	in_suspend=0;
+	M_printk("maestro: resuming\n");
+
+	/* first lets just bring everything back. .*/
+	for (card = devs; card ; card = card->next) {
+		int i;
+
+		M_printk("maestro: apm in dev %p\n",card);
+
+		maestro_config(card);
+		/* need to restore the base pointers.. */ 
+		if(card->dmapages) 
+			set_base_registers(&card->channels[0],card->dmapages);
+
+		mixer_push_state(card);
+
+		for(i=0;i<NR_DSPS;i++) {
+			struct ess_state *s = &card->channels[i];
+			int chan,reg;
+
+			if(s->dev_audio == -1)
+				continue;
+
+			for(chan = 0 ; chan < 6 ; chan++) {
+				wave_set_register(s,s->apu[chan]<<3,s->apu_base[chan]);
+				for(reg = 1 ; reg < NR_APU_REGS ; reg++)  
+					apu_set_register(s,chan,reg,s->card->apu_map[s->apu[chan]][reg]);
+			}
+			for(chan = 0 ; chan < 6 ; chan++)  
+				apu_set_register(s,chan,0,s->card->apu_map[s->apu[chan]][0] & 0xFF0F);
+		}
+	}
+
+	/* now we flip on the music */
+	for (card = devs; card ; card = card->next) {
+		int i;
+
+		M_printk("maestro: apm in dev %p\n",card);
+
+		for(i=0;i<NR_DSPS;i++) {
+			struct ess_state *s = &card->channels[i];
+
+			/* these use the apu_mode, and can handle
+				spurious calls */
+			start_dac(s);	
+			start_adc(s);	
+		}
+		if( card->dsps_open > 0)
+			start_bob(&card->channels[0]);
+	}
+
+	restore_flags(flags);
+
+	wake_up(&suspend_queue);
+
+	return 0;
+}
+
+int 
+maestro_apm_callback(apm_event_t ae) {
+
+	M_printk("maestro: apm event received: 0x%x\n",ae);
+
+	switch(ae) {
+	case APM_SYS_SUSPEND: 
+	case APM_CRITICAL_SUSPEND: 
+	case APM_USER_SUSPEND: 
+		maestro_apm_suspend();break;
+	case APM_NORMAL_RESUME: 
+	case APM_CRITICAL_RESUME: 
+	case APM_STANDBY_RESUME: 
+		maestro_apm_resume();break;
+	default: break;
+	}
+
+	return 0;
+}
+#endif
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/CREDITS linux/drivers/usb/CREDITS
--- v2.3.25/linux/drivers/usb/CREDITS	Tue Sep  7 12:14:07 1999
+++ linux/drivers/usb/CREDITS	Fri Nov  5 10:01:50 1999
@@ -10,7 +10,7 @@
   Bradley M Keryan <keryan@andrew.cmu.edu>
   Paul Mackerras <paulus@cs.anu.edu.au>
   David E. Nelson <dnelson@jump.net>
-  Vojtech Pavlik <vojtech@twilight.ucw.cz>
+  Vojtech Pavlik <vojtech@suse.cz>
   Gregory P. Smith <greg@electricrain.com>
   Linus Torvalds <torvalds@transmeta.com>
   Roman Weissgaerber <weissg@vienna.at>
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/Config.in linux/drivers/usb/Config.in
--- v2.3.25/linux/drivers/usb/Config.in	Sat Oct  9 11:47:50 1999
+++ linux/drivers/usb/Config.in	Wed Nov  3 09:17:45 1999
@@ -37,11 +37,12 @@
    dep_tristate '  USB mouse support' CONFIG_USB_MOUSE $CONFIG_USB
    dep_tristate '  USB HP scanner support' CONFIG_USB_HP_SCANNER $CONFIG_USB
    dep_tristate '  USB keyboard support' CONFIG_USB_KBD $CONFIG_USB
-   dep_tristate '  USB audio parsing support' CONFIG_USB_AUDIO $CONFIG_USB
+   dep_tristate '  USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB
    dep_tristate '  USB Communications Device Class (ACM) support' CONFIG_USB_ACM $CONFIG_USB
    dep_tristate '  USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB
    dep_tristate '  USB Belkin and Peracom serial support' CONFIG_USB_SERIAL $CONFIG_USB
    dep_tristate '  USB CPiA Camera support' CONFIG_USB_CPIA $CONFIG_USB
+   dep_tristate '  USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
    dep_tristate '  USB SCSI Support' CONFIG_USB_SCSI $CONFIG_USB
    if [ "$CONFIG_USB_SCSI" != "n" ]; then
       bool '    USB SCSI verbose debug' CONFIG_USB_SCSI_DEBUG
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/Makefile linux/drivers/usb/Makefile
--- v2.3.25/linux/drivers/usb/Makefile	Fri Oct 15 15:25:14 1999
+++ linux/drivers/usb/Makefile	Tue Nov  2 08:17:27 1999
@@ -139,6 +139,14 @@
   MIX_OBJS += cpia.o
 endif
 
+ifeq ($(CONFIG_USB_DC2XX),y)
+  L_OBJS += dc2xx.o
+endif
+ifeq ($(CONFIG_USB_DC2XX),m)
+  M_OBJS += dc2xx.o
+  MIX_OBJS += dc2xx.o
+endif
+
 ifeq ($(CONFIG_USB_SCSI),y)
   L_OBJS += usb_scsi.o
   ifeq ($(CONFIG_USB_SCSI_DEBUG),y)
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/README.dc2xx linux/drivers/usb/README.dc2xx
--- v2.3.25/linux/drivers/usb/README.dc2xx	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/README.dc2xx	Fri Nov  5 15:54:01 1999
@@ -0,0 +1,105 @@
+3 November 1999
+david-b@pacbell.net
+
+This is an overview of how to use the "dc2xx" USB driver with certain
+digital still cameras from Kodak and other vendors.
+
+
+CAMERAS
+
+This driver will mostly be used with Kodak DC-2xx series digital still
+cameras, but it should be trivial to tell it about several non-Kodak
+USB-enabled cameras.
+
+You'll most likely want to hook it up to recent versions of "gPhoto"
+(www.gphoto.org), since version 0.4 and later know how to use it to talk
+to Kodak DC-240 and DC-280 cameras over USB.
+
+The DC-260 is currently recognized.  However, like other cameras using the
+"Digita OS" (from www.flashpoint.com) there is no application software
+(such as gPhoto) support for this camera.  Until it's available, those
+cameras aren't much use with Linux; when it's available, this driver
+should be able to handle the cameras' communication requirements.  Today,
+that's six more cameras.  From Kodak:  DC-220, DC-260, DC-265, DC-290.
+Minolta has the Dimage EX-1500; HP, the PhotoSmart C500.
+
+It's likely that other digital still cameras can also use this USB driver,
+even if they're not from Kodak and don't use Digita.  The reason is that
+most currently known USB still camera protocols treat USB like a faster
+packet-carrying connection than a serial line, which is exactly how this
+driver looks to an application.
+
+
+USB HARDWARE
+
+This has been shown to work on x86 OHCI and UHCI (Intel) chipsets.  OHCI has
+been trouble free; not so with UHCI, which was first seen to be happy with
+2.3.24 kernels.
+
+As yet, no reports have come from Linux users on non-Intel hardware.
+(You could color coordinate your iMac with a DC-240i ... :-)
+
+
+SETUP
+
+Configure in the DC2XX USB driver, and have it in your kernel.  Recently I
+compile it right in, but I've done it as a module in the past.
+
+Create a device, perhaps like this (both read and write):
+
+    # mknod -m 0666 /dev/kodak c 10 170
+
+That "170" is not formally assigned, and this command may change.  If you're
+using a non-Kodak camera, you may prefer another name.
+
+Don't plug in more than one compatible camera at this time.  One of them
+will be ignored, but I'd not be sure which one!
+
+
+SANITY TESTING
+
+First:  if you've got /proc support, make sure that the driver has hooked
+itself up correctly.
+
+    - you should see an entry in /proc/misc for the a Kodak DC-2xx
+      minor device number
+
+    - you should see an entry in /proc/bus/usb/drivers for "dc2xx",
+      if you also enabled USB /proc support.
+
+Second:  when you connect your camera to the computer, does it get recognized
+by the driver?
+
+    - if you've got /proc/bus/usb/devices, you should see an entry
+      something like this.  The "ProdID" may be different if you didn't
+      plug in a DC-240, but the "Driver=dc2xx" had better be there.
+
+	T:  Lev=01 Prnt=00 Port=00 Cnt=01 Dev#=  1 Spd=12  MxCh= 0
+	D:  Ver= 1.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
+	P:  Vendor=040a ProdID=0120 Rev= 1.08
+	C:* #Ifs= 1 Cfg#= 1 Atr=40 MxPwr=100mA
+	I:  If#= 0 Alt= 0 #EPs= 2 Cls=00(>ifc ) Sub=00 Prot=00 Driver=dc2xx
+	E:  Ad=01(O) Atr=02(Bulk) MxPS=  64 Ivl=  0ms
+	E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=  0ms
+
+    - if you don't have /proc support for USB, see if "dmesg" output
+      tells you that you plugged in your camera.
+
+	USB new device connect, assigned device number 1
+	Manufacturer: Eastman Kodak Company
+	Product: KODAK DC240 Zoom Digital Camera
+	USB Camera (Kodak DC-240) is connected
+	usbcore: dc2xx driver claimed interface c3a68600
+	ohci-control thread sleeping
+
+Third:  (optional) can you use gPhoto to talk to the camera?
+
+    - When you configure your camera, tell it to use "/dev/kodak" (or
+      whatever name you used).  Right now, gPhoto emits a diagnostic
+      message (non-GUI) saying that it since it didn't act like a TTY,
+      it's assuming it's got a USB connection.
+
+    - With the camera turned on, get the "camera summary".  It'll
+      talk to the camera -- and tell you you're using USB.
+
+If you got that far, you should be able to use everything fine.
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/acm.c linux/drivers/usb/acm.c
--- v2.3.25/linux/drivers/usb/acm.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/acm.c	Fri Nov  5 10:43:06 1999
@@ -1,7 +1,9 @@
 /*
- * USB Abstract Control Model based on Brad Keryan's USB busmouse driver 
+ * USB Abstract Control Model based on Brad Keryan's USB busmouse driver
  *
- * Armin Fuerst 5/8/1999 <armin.please@put.your.email.here.!!!!>
+ * (C) Copyright 1999 Armin Fuerst <armin.please@put.your.email.here.!!!!>
+ * (C) Copyright 1999 Pavel Machek <pavel@suse.cz>
+ * (C) Copyright 1999 Johannes Erdfelt <jerdfelt@valinux.com>
  *
  * version 0.8: Fixed endianity bug, some cleanups. I really hate to have
  * half of driver in form if (...) { info("x"); return y; }
@@ -11,7 +13,7 @@
  * wrote this code? ...Oops that was me). Fixed module cleanup. Did some
  * testing at 3Com => zmodem uload+download works, pppd had trouble but
  * seems to work now. Changed Menuconfig texts "Communications Device
- * Class (ACM)" might be a bit more intuitive. Ported to 2.3.13-1 prepatch. 
+ * Class (ACM)" might be a bit more intuitive. Ported to 2.3.13-1 prepatch.
  * (2/8/99)
  *
  * version 0.6: Modularized driver, added disconnect code, improved
@@ -23,8 +25,8 @@
  * in uhci_td_allocate. Commenetd out getstringtable which causes crash.
  * (13/7/99)
  *
- * version 0.4: Small fixes in the FIFO, cleanup. Updated Bulk transfer in 
- * uhci.c. Should have the correct interface now. 
+ * version 0.4: Small fixes in the FIFO, cleanup. Updated Bulk transfer in
+ * uhci.c. Should have the correct interface now.
  * (6/6/99)
  *
  * version 0.3: Major changes. Changed Bulk transfer to interrupt based
@@ -60,15 +62,14 @@
 #include <linux/tty_flip.h>
 #include <linux/tty.h>
 #include <linux/module.h>
-#include <linux/spinlock.h>
 
 #include "usb.h"
 
 #define NR_PORTS 3
 #define ACM_MAJOR 166	/* Wow, major is now officially allocated */
 
-//#define info(message...); printk(message);
-#define info(message...);
+//#define info(message...) printk(KERN_DEBUG message)
+#define info(message...)
 
 #define CTRL_STAT_DTR	1
 #define CTRL_STAT_RTS	2
@@ -88,7 +89,7 @@
 	int cfgnum;					//configuration number on this device
 	struct tty_struct *tty;				//the coresponding tty
 	char present;					//a device for this struct was detected => this tty is used
-	char active;					//someone has this acm's device open 
+	char active;					//someone has this acm's device open
 	unsigned int ctrlstate;				//Status of the serial control lines  (handshake,...)
 	unsigned int linecoding;			//Status of the line coding (Bits, Stop, Parity)
 	int writesize, readsize;			//size of the usb buffers
@@ -105,56 +106,56 @@
 
 //functions for various ACM requests
 
-void Set_Control_Line_Status (unsigned int status,struct acm_state *acm)
+void Set_Control_Line_Status(unsigned int status, struct acm_state *acm)
 {
-	devrequest dr;
+	struct usb_device *dev = acm->dev;
+	int ret;
 
 	info("Set_control_Line_Status\n");
 
-	dr.requesttype = 0x22;
-	dr.request = 0x22;
-	dr.value = status;
-	dr.index = 0;
-	dr.length = 0;
-	acm->dev->bus->op->control_msg(acm->dev, usb_sndctrlpipe(acm->dev,0), &dr, NULL, 0, HZ);
+	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x22, 0x22,
+		status, 0, NULL, 0, HZ);
+	if (ret < 0)
+		printk(KERN_ERR "acm: Set_Control_Line_Status failed\n");
 
-	acm->ctrlstate=status;
+	acm->ctrlstate = status;
 }
 
-void Set_Line_Coding (unsigned int coding,struct acm_state *acm)
+void Set_Line_Coding(unsigned int coding, struct acm_state *acm)
 {
-	devrequest dr;
+	struct usb_device *dev = acm->dev;
+	int ret;
 
 	info("Set_Line_Coding\n");
 
-	dr.requesttype = 0x22;
-	dr.request = 0x30;
-	dr.value = coding;
-	dr.index = 0;
-	dr.length = 0;
-	acm->dev->bus->op->control_msg(acm->dev, usb_sndctrlpipe(acm->dev,0), &dr, NULL, 0, HZ);
-	
-	acm->linecoding=coding;
+	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x30, 0x22,
+		coding, 0, NULL, 0, HZ);
+
+	acm->linecoding = coding;
 }
 
 //Interrupt handler for various usb events
 static int acm_irq(int state, void *__buffer, int count, void *dev_id)
 {
-
 	unsigned char *data;
-	struct acm_state *acm = (struct acm_state *) dev_id; 
+	struct acm_state *acm = (struct acm_state *)dev_id;
         devrequest *dr;
-		
+
 	info("ACM_USB_IRQ\n");
 
+	if (state) {
+		printk(KERN_DEBUG "acm_irq: strange state received: %x\n", state);
+		return 0;
+	}
+
 	if (!acm->present)
 		return 0;
 	if (!acm->active)
 		return 1;
-       
-        dr=__buffer;
-	data=__buffer;
-	data+=sizeof(dr);
+
+        dr = __buffer;
+	data = __buffer;
+	data += sizeof(dr);
  
 #if 0
         printk("reqtype: %02X\n",dr->requesttype);
@@ -163,23 +164,23 @@
 	printk("wIndex: %02X\n",dr->index);
 	printk("wLength: %02X\n",dr->length);
 #endif
-	
+
 	switch(dr->request) {
 	case 0x00: /* Network connection */
-		printk("Network connection: ");
-		if (dr->request==0) printk("disconnected\n");
-		if (dr->request==1) printk("connected\n");
+		printk(KERN_DEBUG "Network connection: ");
+		if (dr->request==0) printk(KERN_DEBUG "disconnected\n");
+		if (dr->request==1) printk(KERN_DEBUG "connected\n");
 		break;
-	    
+
 	case 0x01: /* Response available */
-		printk("Response available\n");
+		printk(KERN_DEBUG "Response available\n");
 		break;
-	
+
 	case 0x20: /* Set serial line state */
-		printk("acm.c: Set serial control line state\n");
-		if ((dr->index==1)&&(dr->length==2)) {
+		printk(KERN_DEBUG "acm.c: Set serial control line state\n");
+		if ((dr->index==1) && (dr->length==2)) {
 			acm->ctrlstate= data[0] || (data[1] << 16);
-			printk("Serstate: %02X\n",acm->ctrlstate);
+			printk(KERN_DEBUG "Serstate: %02X\n",acm->ctrlstate);
 		}
 		break;
 	}
@@ -197,7 +198,7 @@
 	info("ACM_READ_IRQ: state %d, %d bytes\n", state, count);
 	if (state) {
 		printk( "acm_read_irq: strange state received: %x\n", state );
-		return 0;
+		return 1;
 	}
 	
 	if (!ACM_READY)
@@ -207,13 +208,13 @@
 		tty_insert_flip_char(tty,data[i],0);
   	tty_flip_buffer_push(tty);
 
-	return 0; /* Never return 1 from this routine. It makes uhci do bad things. */
+	return 1;
 }
 
 static int acm_write_irq(int state, void *__buffer, int count, void *dev_id)
 {
-	struct acm_state *acm = (struct acm_state *) dev_id; 
-       	struct tty_struct *tty = acm->tty; 
+	struct acm_state *acm = (struct acm_state *) dev_id;
+       	struct tty_struct *tty = acm->tty;
 
 	info("ACM_WRITE_IRQ\n");
 
@@ -221,24 +222,25 @@
 		return 0; /* stop transfer */
 
 	usb_terminate_bulk(acm->dev, acm->writetransfer);
-	acm->writing=0;
+	acm->writing = 0;
 	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
 		(tty->ldisc.write_wakeup)(tty);
 	wake_up_interruptible(&tty->write_wait);
-	
+
 	return 0; /* stop tranfer */
 }
 
 /*TTY STUFF*/
-static int rs_open(struct tty_struct *tty, struct file * filp) 
+static int rs_open(struct tty_struct *tty, struct file *filp)
 {
 	struct acm_state *acm;
 	int ret;
-	
+
 	info("USB_FILE_OPEN\n");
 
-	tty->driver_data=acm=&acm_state_table[MINOR(tty->device)-tty->driver.minor_start];
-	acm->tty=tty;
+	tty->driver_data = acm =
+		&acm_state_table[MINOR(tty->device) - tty->driver.minor_start];
+	acm->tty = tty;
 	 
 	if (!acm->present)
 		return -EINVAL;
@@ -246,139 +248,147 @@
 	if (acm->active++)
 		return 0;
  
+	MOD_INC_USE_COUNT;
+
 	/* Start reading from the device */
-	ret = usb_request_irq(acm->dev,acm->ctrlpipe, acm_irq, acm->ctrlinterval, acm, &acm->ctrltransfer);
+	ret = usb_request_irq(acm->dev, acm->ctrlpipe, acm_irq,
+		acm->ctrlinterval, acm, &acm->ctrltransfer);
 	if (ret)
-		printk (KERN_WARNING "usb-acm: usb_request_irq failed (0x%x)\n", ret);
-	acm->reading=1;
-	acm->readtransfer=usb_request_bulk(acm->dev,acm->readpipe, acm_read_irq, acm->readbuffer, acm->readsize, acm);
-	
-	Set_Control_Line_Status (CTRL_STAT_DTR | CTRL_STAT_RTS, acm);
-				                  
+		printk(KERN_ERR "usb-acm: usb_request_irq failed (0x%x)\n", ret);
+	acm->reading = 1;
+	acm->readtransfer = usb_request_bulk(acm->dev, acm->readpipe,
+		acm_read_irq, acm->readbuffer, acm->readsize, acm);
+
+	Set_Control_Line_Status(CTRL_STAT_DTR | CTRL_STAT_RTS, acm);
+
 	return 0;
 }
 
-static void rs_close(struct tty_struct *tty, struct file * filp)
+static void rs_close(struct tty_struct *tty, struct file *filp)
 {
-	struct acm_state *acm = (struct acm_state *) tty->driver_data; 
+	struct acm_state *acm = (struct acm_state *) tty->driver_data;
+
 	info("rs_close\n");
-	
+
 	if (!acm->present)
 		return;
 
 	if (--acm->active)
 		return;
 
-	Set_Control_Line_Status (0, acm);
-	
-	if (acm->writing){
+	Set_Control_Line_Status(0, acm);
+
+	if (acm->writing) {
 		usb_terminate_bulk(acm->dev, acm->writetransfer);
-		acm->writing=0;
+		acm->writing = 0;
 	}
-	if (acm->reading){
+	if (acm->reading) {
 		usb_terminate_bulk(acm->dev, acm->readtransfer);
-		acm->reading=0;
+		acm->reading = 0;
 	}
-//	usb_release_irq(acm->dev,acm->ctrltransfer, acm->ctrlpipe);
+//	usb_release_irq(acm->dev, acm->ctrltransfer, acm->ctrlpipe);
+
+	MOD_DEC_USE_COUNT;
 }
 
-static int rs_write(struct tty_struct * tty, int from_user,
+static int rs_write(struct tty_struct *tty, int from_user,
 		    const unsigned char *buf, int count)
 {
-	struct acm_state *acm = (struct acm_state *) tty->driver_data; 
+	struct acm_state *acm = (struct acm_state *)tty->driver_data;
 	int written;
-	
+
 	info("rs_write\n");
 
 	if (!ACM_READY)
 		return -EINVAL;
-	
+
 	if (acm->writing) {
-		info ("already writing\n");
+		info("already writing\n");
 		return 0;
 	}
 
-	written=(count>acm->writesize) ? acm->writesize : count;
-	  
-	if (from_user) copy_from_user(acm->writebuffer,buf,written);
-	else	       memcpy(acm->writebuffer,buf,written);
+	written = (count>acm->writesize) ? acm->writesize : count;
+
+	if (from_user)
+		copy_from_user(acm->writebuffer, buf, written);
+	else
+		memcpy(acm->writebuffer, buf, written);
 
 	//start the transfer
-	acm->writing=1;
-	acm->writetransfer=usb_request_bulk(acm->dev,acm->writepipe, acm_write_irq, acm->writebuffer, written, acm);
+	acm->writing = 1;
+	acm->writetransfer = usb_request_bulk(acm->dev, acm->writepipe,
+		acm_write_irq, acm->writebuffer, written, acm);
 
 	return written;
 } 
 
 static void rs_put_char(struct tty_struct *tty, unsigned char ch)
 {
-	struct acm_state *acm = (struct acm_state *) tty->driver_data; 
-	
-	printk( "acm: rs_put_char: Who called this unsupported routine?\n" );
+	printk(KERN_DEBUG "acm: rs_put_char: Who called this unsupported routine?\n");
 	BUG();
-}                   
+}
 
-static int rs_write_room(struct tty_struct *tty) 
+static int rs_write_room(struct tty_struct *tty)
 {
-	struct acm_state *acm = (struct acm_state *) tty->driver_data; 
+	struct acm_state *acm = (struct acm_state *) tty->driver_data;
 
 	info("rs_write_room\n");
-	
+
 	if (!ACM_READY)
 		return -EINVAL;
-	
+
 	return acm->writing ? 0 : acm->writesize;
 }
 
-static int rs_chars_in_buffer(struct tty_struct *tty) 
+static int rs_chars_in_buffer(struct tty_struct *tty)
 {
-	struct acm_state *acm = (struct acm_state *) tty->driver_data; 
+	struct acm_state *acm = (struct acm_state *) tty->driver_data;
 
 //	info("rs_chars_in_buffer\n");
-	
+
 	if (!ACM_READY)
 		return -EINVAL;
-	
-	return acm->writing ? acm->writesize :  0;
+
+	return acm->writing ? acm->writesize : 0;
 }
 
-static void rs_throttle(struct tty_struct * tty)
+static void rs_throttle(struct tty_struct *tty)
 {
-	struct acm_state *acm = (struct acm_state *) tty->driver_data; 
-	
+	struct acm_state *acm = (struct acm_state *) tty->driver_data;
+
 	info("rs_throttle\n");
-	
+
 	if (!ACM_READY)
 		return;
-/*	
+/*
 	if (I_IXOFF(tty))
 		rs_send_xchar(tty, STOP_CHAR(tty));
-*/    
+*/
 	if (tty->termios->c_cflag & CRTSCTS)
-		Set_Control_Line_Status (acm->ctrlstate & ~CTRL_STAT_RTS, acm);
+		Set_Control_Line_Status(acm->ctrlstate & ~CTRL_STAT_RTS, acm);
 }
 
-static void rs_unthrottle(struct tty_struct * tty)
+static void rs_unthrottle(struct tty_struct *tty)
 {
-	struct acm_state *acm = (struct acm_state *) tty->driver_data; 
-	
+	struct acm_state *acm = (struct acm_state *) tty->driver_data;
+
 	info("rs_unthrottle\n");
-	
+
 	if (!ACM_READY)
 		return;
-/*	
+/*
 	if (I_IXOFF(tty))
 		rs_send_xchar(tty, STOP_CHAR(tty));
-*/    
+*/
 	if (tty->termios->c_cflag & CRTSCTS)
-		Set_Control_Line_Status (acm->ctrlstate | CTRL_STAT_RTS, acm);
+		Set_Control_Line_Status(acm->ctrlstate | CTRL_STAT_RTS, acm);
 }
 
 static int get_free_acm(void)
 {
 	int i;
  
-	for (i=0;i<NR_PORTS;i++) {
+	for (i = 0; i < NR_PORTS; i++) {
 		if (!acm_state_table[i].present)
 			return i;
 	}
@@ -413,14 +423,14 @@
 	 * selecting or should the usbcore?  [different configurations
 	 * can have different bandwidth requirements] -greg */
 
-	/* Now scan all configs for a ACM configuration*/
+	/* Now scan all configs for a ACM configuration */
 	for (cfgnum=0;cfgnum<dev->descriptor.bNumConfigurations;cfgnum++) {
 		/* The first one should be Communications interface? */
 		interface = &dev->config[cfgnum].interface[0].altsetting[0];
 		if (IFCLASS(interface) != 0x02020101)
 			continue;
 
-		/*Which uses an interrupt input */
+		/* Which uses an interrupt input */
 		endpoint = &interface->endpoint[0];
 		if ((endpoint->bEndpointAddress & 0x80) != 0x80 ||
 		    (endpoint->bmAttributes & 3) != 3)
@@ -540,13 +550,12 @@
 int usb_acm_init(void)
 {
 	int cnt;
-	
+
 	info("usb_acm_init\n");
-		
+
 	//INITIALIZE GLOBAL DATA STRUCTURES
-	for (cnt=0;cnt<NR_PORTS;cnt++) {
+	for (cnt = 0; cnt < NR_PORTS; cnt++)
 		memset(&acm_state_table[cnt], 0, sizeof(struct acm_state));
-	}
 
 	//REGISTER TTY DRIVER
 	memset(&acm_tty_driver, 0, sizeof(struct tty_driver));
@@ -565,16 +574,16 @@
 	acm_tty_driver.table = acm_tty;
 	acm_tty_driver.termios = acm_termios;
 	acm_tty_driver.termios_locked = acm_termios_locked;
-	
+
 	acm_tty_driver.open = rs_open;
 	acm_tty_driver.close = rs_close;
 	acm_tty_driver.write = rs_write;
 	acm_tty_driver.put_char = rs_put_char;
 	acm_tty_driver.flush_chars = NULL; //rs_flush_chars;
 	acm_tty_driver.write_room = rs_write_room;
-	acm_tty_driver.ioctl = NULL; //rs_ioctl;
+	acm_tty_driver.ioctl = NULL; //rs_ioctl
 	acm_tty_driver.set_termios = NULL; //rs_set_termios;
-	acm_tty_driver.set_ldisc = NULL; 
+	acm_tty_driver.set_ldisc = NULL;
 	acm_tty_driver.throttle = rs_throttle;
 	acm_tty_driver.unthrottle = rs_unthrottle;
 	acm_tty_driver.stop = NULL; //rs_stop;
@@ -587,12 +596,14 @@
 	acm_tty_driver.chars_in_buffer = rs_chars_in_buffer;
 	acm_tty_driver.flush_buffer = NULL; //rs_flush_buffer;
 	if (tty_register_driver(&acm_tty_driver)) {
-		printk( "acm: failed to register tty driver\n" );
+		printk(KERN_ERR "acm: failed to register tty driver\n");
 		return -EPERM;
 	}
-	
-	//REGISTER USB DRIVER
-	usb_register(&acm_driver);
+
+	if (usb_register(&acm_driver) < 0) {
+		tty_unregister_driver(&acm_tty_driver);
+		return -1;
+	}
 
 	printk(KERN_INFO "USB ACM registered.\n");
 	return 0;
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/audio.c linux/drivers/usb/audio.c
--- v2.3.25/linux/drivers/usb/audio.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/audio.c	Fri Nov  5 10:42:15 1999
@@ -48,6 +48,10 @@
  *              decent headphones!
  *              "Let's make things better" -> but please Philips start with your
  *              own stuff!!!!
+ * 1999-11-02:  It takes the Philips boxes several seconds to acquire synchronisation
+ *              that means they won't play short sounds. Should probably maintain
+ *              the ISO datastream even if there's nothing to play.
+ *              Fix counting the total_bytes counter, RealPlayer G2 depends on it.
  *
  *
  */
@@ -455,6 +459,7 @@
 {
 	unsigned int pgrem, rem;
 
+	db->total_bytes += size;
 	for (;;) {
 		if (size <= 0)
 			return;
@@ -477,6 +482,7 @@
 {
 	unsigned int pgrem, rem;
 
+	db->total_bytes += size;
 	for (;;) {
 		if (size <= 0)
 			return;
@@ -3285,7 +3291,9 @@
 			prepmixch(state);
 		}
 	}
+#if 0
 	/* if there are mute controls, unmute them */
+	/* does not seem to be necessary, and the Dallas chip does not seem to support the "all" channel (255) */
 	if ((chftr & 1) || (mchftr & 1)) {
 		printk(KERN_DEBUG "usbaudio: unmuting feature unit %u interface %u\n", ftr[3], state->ctrlif);
 		data[0] = 0;
@@ -3293,6 +3301,7 @@
                                     (MUTE_CONTROL << 8) | 0xff, state->ctrlif | (ftr[3] << 8), data, 1, HZ) < 0)
 			printk(KERN_WARNING "usbaudio: failure to unmute feature unit %u interface %u\n", ftr[3], state->ctrlif);
  	}
+#endif
 }
 
 static void usb_audio_recurseunit(struct consmixstate *state, unsigned char unitid)
@@ -3612,8 +3621,7 @@
 
 int usb_audio_init(void)
 {
-	usb_register(&usb_audio_driver);
-	return 0;
+	return usb_register(&usb_audio_driver);
 }
 
 #ifdef MODULE
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/cpia.c linux/drivers/usb/cpia.c
--- v2.3.25/linux/drivers/usb/cpia.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/cpia.c	Fri Nov  5 10:42:15 1999
@@ -1309,9 +1309,7 @@
 
 int usb_cpia_init(void)
 {
-	usb_register(&cpia_driver);
-
-	return 0;
+	return usb_register(&cpia_driver);
 }
 
 void usb_cpia_cleanup(void)
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/dc2xx.c linux/drivers/usb/dc2xx.c
--- v2.3.25/linux/drivers/usb/dc2xx.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/usb/dc2xx.c	Fri Nov  5 15:54:01 1999
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 1999 by David Brownell <david-b@pacbell.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+ 
+ 
+/*
+ * USB driver for Kodak DC-2XX series digital still cameras
+ *
+ * The protocol here is the same as the one going over a serial line, but
+ * it uses USB for speed.  Set up /dev/kodak, get gphoto (www.gphoto.org),
+ * and have fun!
+ *
+ * This should also work for a number of other digital (non-Kodak) cameras,
+ * by adding the vendor and product IDs to the table below.
+ */
+
+/*
+ * HISTORY
+ *
+ * 26 August, 1999 -- first release (0.1), works with my DC-240.
+ * 	The DC-280 (2Mpixel) should also work, but isn't tested.
+ *	If you use gphoto, make sure you have the USB updates.
+ *	Lives in a 2.3.14 or so Linux kernel, in drivers/usb.
+ * 31 August, 1999 -- minor update to recognize DC-260 and handle
+ *	its endpoints being in a different order.  Note that as
+ *	of gPhoto 0.36pre, the USB updates are integrated.
+ * 12 Oct, 1999 -- handle DC-280 interface class (0xff not 0x0);
+ *	added timeouts to bulk_msg calls.  Minor updates, docs.
+ * 03 Nov, 1999 -- update for 2.3.25 kernel API changes.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/random.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/malloc.h>
+#include <linux/module.h>
+
+#include "usb.h"
+
+
+// #define	CAMERA_DEBUG
+
+
+/* XXX need to get registered minor number, cdev 10/MINOR */
+/* XXX or: cdev USB_MAJOR(180)/USB_CAMERA_MINOR */
+#define	USB_CAMERA_MINOR	170
+
+
+/* Application protocol limit is 0x8002; USB has disliked that limit! */
+#define	MAX_PACKET_SIZE		0x2000		/* e.g. image downloading */
+
+#define	MAX_READ_RETRY		5		/* times to retry reads */
+#define	MAX_WRITE_RETRY		5		/* times to retry writes */
+#define	RETRY_TIMEOUT		(HZ)		/* sleep between retries */
+
+
+/* table of cameras that work through this driver */
+static struct camera {
+	short		idVendor;
+	short		idProduct;
+
+	/* should get this name from the USB subsystem */
+	const char	*nameProduct;
+} cameras [] = {
+    { 0x040a, 0x0120, "Kodak DC-240" },
+    { 0x040a, 0x0130, "Kodak DC-280" },
+
+	/* Kodak has several other USB-enabled devices, which (along with
+	 * models from other vendors) all use the Flashpoint "Digita
+	 * OS" and its wire protocol.  This driver should work with such
+	 * devices, which need different application level protocol code
+	 * from the DC-240/280 models.  Note that Digita isn't just for
+	 * cameras -- Epson has a non-USB Digita photo printer.
+	 */
+/*  { 0x040a, 0x0100, "Kodak DC-220" }, */
+    { 0x040a, 0x0110, "Kodak DC-260" },
+/*  { 0x040a, 0x0115, "Kodak DC-265" }, */
+/*  { 0x040a, 0x0140, "Kodak DC-290" }, */
+
+/*  { 0xffff, 0xffff, "Minolta Dimage EX 1500" }, */
+/*  { 0x03f0, 0xffff, "HP PhotoSmart C500" }, */
+
+	/* Other USB cameras may well work here too, so long as they
+	 * just stick to half duplex packet exchanges.
+	 */
+};
+
+
+struct camera_state {
+	/* these fields valid (dev != 0) iff camera connected */
+	struct usb_device	*dev;		/* USB device handle */
+	char			inEP;		/* read endpoint */
+	char			outEP;		/* write endpoint */
+	struct camera		*info;		/* DC-240, etc */
+
+	/* valid iff isOpen */
+	int			isOpen;		/* device opened? */
+	int			isActive;	/* I/O taking place? */
+	char			*buf;		/* buffer for I/O */
+
+	/* always valid */
+	wait_queue_head_t	wait;		/* for timed waits */
+};
+
+
+/* For now, we only support one camera at a time: there's one
+ * application-visible device (e.g. /dev/kodak) and the second
+ * (to Nth) camera detected on the bus is ignored.
+ */
+static struct camera_state static_camera_state;
+
+
+static ssize_t camera_read (struct file *file,
+	char *buf, size_t len, loff_t *ppos)
+{
+	struct camera_state	*camera;
+	int			retries;
+
+	camera = (struct camera_state *) file->private_data;
+	if (len > MAX_PACKET_SIZE)
+		return -EINVAL;
+	if (camera->isActive++)
+		return -EBUSY;
+
+	/* Big reads are common, for image downloading.  Smaller ones
+	 * are also common (even "directory listing" commands don't
+	 * send very much data).  We preserve packet boundaries here,
+	 * they matter in the application protocol.
+	 */
+	for (retries = 0; retries < MAX_READ_RETRY; retries++) {
+		unsigned long		count;
+		int			result;
+
+		if (signal_pending (current)) {
+			camera->isActive = 0;
+			return -EINTR;
+		}
+		if (!camera->dev) {
+			camera->isActive = 0;
+			return -ENODEV;
+		}
+
+		result = camera->dev->bus->op->bulk_msg (camera->dev,
+			  usb_rcvbulkpipe (camera->dev, camera->inEP),
+			  camera->buf, len, &count, HZ*10);
+#ifdef	CAMERA_DEBUG
+		printk ("camera.r (%d) - 0x%x %ld\n", len, result, count);
+#endif
+		if (!result) {
+			if (copy_to_user (buf, camera->buf, count))
+				return -EFAULT;
+			camera->isActive = 0;
+			return count;
+		}
+		if (result != USB_ST_TIMEOUT)
+			break;
+		interruptible_sleep_on_timeout (&camera->wait, RETRY_TIMEOUT);
+#ifdef	CAMERA_DEBUG
+		printk ("camera.r (%d) - retry\n", len);
+#endif
+	}
+	camera->isActive = 0;
+	return -EIO;
+}
+
+static ssize_t camera_write (struct file *file,
+	const char *buf, size_t len, loff_t *ppos)
+{
+	struct camera_state	*camera;
+	ssize_t			bytes_written = 0;
+
+	camera = (struct camera_state *) file->private_data;
+	if (len > MAX_PACKET_SIZE)
+		return -EINVAL;
+	if (camera->isActive++)
+		return -EBUSY;
+	
+	/* most writes will be small: simple commands, sometimes with
+	 * parameters.  putting images (like borders) into the camera
+	 * would be the main use of big writes.
+	 */
+	while (len > 0) {
+		char		*obuf = camera->buf;
+		int		maxretry = MAX_WRITE_RETRY;
+		unsigned long	copy_size, thistime;
+
+		/* it's not clear that retrying can do any good ... or that
+		 * fragmenting application packets into N writes is correct.
+		 * consider those mechanisms mostly untested legacy code
+		 */
+		thistime = copy_size = len;
+		if (copy_from_user (obuf, buf, copy_size)) {
+			bytes_written = -EFAULT;
+			break;
+		}
+		while (thistime) {
+			int		result;
+			unsigned long	count;
+
+			if (signal_pending (current)) {
+				if (!bytes_written)
+					bytes_written = -EINTR;
+				goto done;
+			}
+			if (!camera->dev) {
+				if (!bytes_written)
+					bytes_written = -ENODEV;
+				goto done;
+			}
+
+			result = camera->dev->bus->op->bulk_msg (camera->dev,
+				 usb_sndbulkpipe (camera->dev, camera->outEP),
+				 obuf, thistime, &count, HZ*10);
+#ifdef	CAMERA_DEBUG
+			if (result)
+				printk ("camera.w USB err - %x\n", result);
+#endif
+			if (count) {
+				obuf += count;
+				thistime -= count;
+				maxretry = MAX_WRITE_RETRY;
+				continue;
+			} else if (!result)
+				break;
+				
+			if (result == USB_ST_TIMEOUT) {	/* NAK - delay a bit */
+				if (!maxretry--) {
+					if (!bytes_written)
+						bytes_written = -ETIME;
+					goto done;
+				}
+                                interruptible_sleep_on_timeout (&camera->wait,
+					RETRY_TIMEOUT);
+				continue;
+			} 
+			if (!bytes_written)
+				bytes_written = -EIO;
+			goto done;
+		}
+		bytes_written += copy_size;
+		len -= copy_size;
+		buf += copy_size;
+	}
+done:
+	camera->isActive = 0;
+#ifdef	CAMERA_DEBUG
+	printk ("camera.w %d\n", bytes_written); 
+#endif
+	return bytes_written;
+}
+
+static int camera_open (struct inode *inode, struct file *file)
+{
+	struct camera_state *camera = &static_camera_state;
+
+	/* ignore camera->dev so it can be turned on "late" */
+
+	if (camera->isOpen++)
+		return -EBUSY;
+	if (!(camera->buf = (char *) kmalloc (MAX_PACKET_SIZE, GFP_KERNEL))) {
+		camera->isOpen = 0;
+		return -ENOMEM;
+	}
+#ifdef	CAMERA_DEBUG
+	printk ("camera.open\n"); 
+#endif
+	
+	/* Keep driver from being unloaded while it's in use */
+	MOD_INC_USE_COUNT;
+
+	camera->isActive = 0;
+	file->private_data = camera;
+	return 0;
+}
+
+static int camera_release (struct inode *inode, struct file *file)
+{
+	struct camera_state *camera;
+
+	camera = (struct camera_state *) file->private_data;
+	kfree (camera->buf);
+	camera->isOpen = 0;
+	MOD_DEC_USE_COUNT;
+#ifdef	CAMERA_DEBUG
+	printk ("camera.close\n"); 
+#endif
+
+	return 0;
+}
+
+	/* XXX should define some ioctls to expose camera type
+	 * to applications ... what USB exposes should suffice.
+	 * apps should be able to see the camera type.
+	 */
+static struct file_operations usb_camera_fops = {
+	NULL,		/* llseek */
+	camera_read,
+	camera_write,
+	NULL, 		/* readdir */
+	NULL,		/* poll */
+	NULL,		/* ioctl */
+	NULL,		/* mmap */
+	camera_open,
+	NULL,		/* flush */
+	camera_release,
+	NULL,		/* async */
+	NULL,		/* fasync */
+	NULL,		/* check_media_change */
+	NULL,		/* revalidate */
+	NULL,		/* lock */
+};
+
+static struct miscdevice usb_camera = {
+	USB_CAMERA_MINOR,
+	"USB camera (Kodak DC-2xx)",
+	&usb_camera_fops
+};
+
+
+
+static void * camera_probe(struct usb_device *dev, unsigned int ifnum)
+{
+	int				i;
+	struct camera			*camera_info = NULL;
+	struct usb_interface_descriptor	*interface;
+	struct usb_endpoint_descriptor	*endpoint;
+
+	struct camera_state		*camera = &static_camera_state;
+
+	/* Is it a supported camera? */
+	for (i = 0; i < sizeof (cameras) / sizeof (struct camera); i++) {
+		if (cameras [i].idVendor != dev->descriptor.idVendor)
+			continue;
+		if (cameras [i].idProduct != dev->descriptor.idProduct)
+			continue;
+		camera_info = &cameras [i];
+		break;
+	}
+	if (camera_info == NULL)
+		return NULL;
+
+	/* these have one config, one interface */
+	if (dev->descriptor.bNumConfigurations != 1
+			|| dev->config[0].bNumInterfaces != 1) {
+		printk (KERN_INFO "Bogus camera config info\n");
+		return NULL;
+	}
+
+	/* the interface class bit is odd -- the dc240 and dc260 return
+	 * a zero there, and at least some dc280s report 0xff
+	 */
+	// interface = &dev->config[0].interface[0].altsetting[0];
+	interface = &dev->actconfig->interface[ifnum].altsetting[0];
+	if ((interface->bInterfaceClass != 0
+				&& interface->bInterfaceClass != 0xff)
+			|| interface->bInterfaceSubClass != 0
+			|| interface->bInterfaceProtocol != 0
+			|| interface->bNumEndpoints != 2
+			) {
+		printk (KERN_INFO "Bogus camera interface info\n");
+		return NULL;
+	}
+
+	/* can only show one camera at a time through /dev ... */
+	if (!camera->dev) {
+		camera->dev = dev;
+		printk(KERN_INFO "USB Camera (%s) is connected\n",
+				camera_info->nameProduct);
+	} else {
+		printk(KERN_INFO "Ignoring additional USB Camera (%s)\n",
+				camera_info->nameProduct);
+		return NULL;
+	}
+
+// XXX there are now masks for these constants ... see printer.c
+
+	/* get input and output endpoints (either order) */
+	endpoint = interface->endpoint;
+	camera->outEP = camera->inEP =  -1;
+	if ((endpoint [0].bEndpointAddress & 0x80) == 0x80)
+		camera->inEP = endpoint [0].bEndpointAddress & 0x7f;
+	else
+		camera->outEP = endpoint [0].bEndpointAddress;
+
+	if ((endpoint [1].bEndpointAddress & 0x80) == 0x80)
+		camera->inEP = endpoint [1].bEndpointAddress & 0x7f;
+	else
+		camera->outEP = endpoint [1].bEndpointAddress;
+	if (camera->outEP == -1 || camera->inEP == -1
+			|| endpoint [0].bmAttributes != 0x02
+			|| endpoint [1].bmAttributes != 0x02
+			) {
+		printk (KERN_INFO "Bogus camera endpoints\n");
+		camera->dev = NULL;
+		return NULL;
+	}
+
+
+	if (usb_set_configuration (dev, dev->config[0].bConfigurationValue)) {
+		printk (KERN_INFO "Failed usb_set_configuration: camera\n");
+		camera->dev = NULL;
+		return NULL;
+	}
+
+	camera->info = camera_info;
+	return camera;
+}
+
+static void camera_disconnect(struct usb_device *dev, void *ptr)
+{
+	struct camera_state	*camera = (struct camera_state *) ptr;
+	struct camera		*info = camera->info;
+
+	if (camera->dev != dev)
+		return;
+
+	/* Currently not reflecting this up to userland; at one point
+	 * it got called on bus reconfig, which we clearly don't want.
+	 * A good consequence is the ability to remove camera for
+	 * a while without apps needing to do much more than ignore
+	 * some particular error returns.  On the bad side, if one
+	 * camera is swapped for another one, we won't be telling.
+	 */
+	camera->info = NULL;
+	camera->dev = NULL;
+
+	printk (KERN_INFO "USB Camera (%s) disconnected\n", info->nameProduct);
+}
+
+static struct usb_driver camera_driver = {
+	"dc2xx",
+	camera_probe,
+	camera_disconnect,
+	{ NULL, NULL },
+
+	NULL,	/* &usb_camera_fops, */
+	0	/* USB_CAMERA_MINOR */
+};
+
+
+#ifdef MODULE
+static __init
+#endif
+int usb_dc2xx_init(void)
+{
+	struct camera_state *camera = &static_camera_state;
+
+	camera->dev = NULL;
+	camera->isOpen = 0;
+	camera->isActive = 0;
+	init_waitqueue_head (&camera->wait);
+
+	if (usb_register (&camera_driver) < 0)
+		return -1;
+	misc_register (&usb_camera);
+
+	return 0;
+}
+
+#ifdef MODULE
+static __exit
+#endif
+void usb_dc2xx_cleanup(void)
+{
+	usb_deregister (&camera_driver);
+	misc_deregister (&usb_camera);
+}
+
+
+#ifdef MODULE
+
+MODULE_AUTHOR("David Brownell, david-b@pacbell.net");
+MODULE_DESCRIPTION("USB Camera Driver for Kodak DC-2xx series cameras");
+
+module_init (usb_dc2xx_init);
+module_exit (usb_dc2xx_cleanup);
+
+#endif	/* MODULE */
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/ezusb.c linux/drivers/usb/ezusb.c
--- v2.3.25/linux/drivers/usb/ezusb.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/ezusb.c	Fri Nov  5 10:42:15 1999
@@ -311,7 +311,7 @@
 		if (pos + len > 0x10000)
 			len = 0x10000 - pos;
 		i = usb_control_msg(ez->usbdev, usb_rcvctrlpipe(ez->usbdev, 0), 0xa0, 0xc0, pos, 0, b, len, HZ);
-		if (i) {
+		if (i < 0) {
 			up(&ez->mutex);
 			printk(KERN_WARNING "ezusb: upload failed pos %u len %u ret %d\n", pos, len, i);
 			*ppos = pos;
@@ -366,7 +366,7 @@
 			return -EFAULT;
 		}
 		i = usb_control_msg(ez->usbdev, usb_sndctrlpipe(ez->usbdev, 0), 0xa0, 0x40, pos, 0, b, len, HZ);
-		if (i) {
+		if (i < 0) {
 			up(&ez->mutex);
 			printk(KERN_WARNING "ezusb: download failed pos %u len %u ret %d\n", pos, len, i);
 			*ppos = pos;
@@ -1052,7 +1052,9 @@
 		init_waitqueue_head(&ezusb[u].wait);
 		spin_lock_init(&ezusb[u].lock);
 	}
-	usb_register(&ezusb_driver);
+	if (usb_register(&ezusb_driver) < 0)
+		return -1;
+
         printk(KERN_INFO "ezusb: Anchorchip firmware download driver registered\n");
 	return 0;
 }
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/hp_scanner.c linux/drivers/usb/hp_scanner.c
--- v2.3.25/linux/drivers/usb/hp_scanner.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/hp_scanner.c	Fri Nov  5 10:42:15 1999
@@ -299,7 +299,9 @@
 int
 usb_hp_scanner_init(void)
 {
-	usb_register(&scanner_driver);
+	if (usb_register(&scanner_driver) < 0)
+		return -1;
+
 	printk(KERN_DEBUG "USB Scanner support registered.\n");
 	return 0;
 }
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/hub.c linux/drivers/usb/hub.c
--- v2.3.25/linux/drivers/usb/hub.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/hub.c	Fri Nov  5 10:42:15 1999
@@ -105,7 +105,7 @@
 	int i;
 
 	/* Get the length first */
-	if (usb_get_hub_descriptor(dev, buffer, 4))
+	if (usb_get_hub_descriptor(dev, buffer, 4) < 0)
 		return -1;
 
 	header = (struct usb_descriptor_header *)buffer;
@@ -113,7 +113,7 @@
 	if (!bitmap)
 		return -1;
 
-	if (usb_get_hub_descriptor(dev, bitmap, header->bLength))
+	if (usb_get_hub_descriptor(dev, bitmap, header->bLength) < 0)
 		return -1;
 
 	descriptor = (struct usb_hub_descriptor *)bitmap;
@@ -166,7 +166,7 @@
 
 	kfree(bitmap);
 
-	if (usb_get_hub_status(dev, buffer))
+	if (usb_get_hub_status(dev, buffer) < 0)
 		return -1;
 
 	hubsts = (struct usb_hub_status *)buffer;
@@ -305,7 +305,7 @@
 	wait_ms(50);	/* FIXME: This is from the *BSD stack, thanks! :) */
 
 	/* Check status */
-	if (usb_get_port_status(hub, port + 1, &portsts)) {
+	if (usb_get_port_status(hub, port + 1, &portsts) < 0) {
 		printk(KERN_ERR "get_port_status failed\n");
 		return;
 	}
@@ -377,7 +377,7 @@
 			struct usb_port_status portsts;
 			unsigned short portstatus, portchange;
 
-			if (usb_get_port_status(dev, i + 1, &portsts)) {
+			if (usb_get_port_status(dev, i + 1, &portsts) < 0) {
 				printk(KERN_ERR "get_port_status failed\n");
 				continue;
 			}
@@ -474,7 +474,8 @@
 {
 	int pid;
 
-	usb_register(&hub_driver);
+	if (usb_register(&hub_driver) < 0)
+		return -1;
 
 	pid = kernel_thread(usb_hub_thread, NULL,
 		CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
@@ -487,7 +488,7 @@
 	/* Fall through if kernel_thread failed */
 	usb_deregister(&hub_driver);
 
-	return 1;
+	return -1;
 }
 
 void usb_hub_cleanup(void)
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/keyboard.c linux/drivers/usb/keyboard.c
--- v2.3.25/linux/drivers/usb/keyboard.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/keyboard.c	Fri Nov  5 10:42:15 1999
@@ -256,8 +256,7 @@
 
 int usb_kbd_init(void)
 {
-    usb_register(&usb_kbd_driver);
-    return 0;
+	return usb_register(&usb_kbd_driver);
 }
 
 void usb_kbd_cleanup(void)
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/mouse.c linux/drivers/usb/mouse.c
--- v2.3.25/linux/drivers/usb/mouse.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/mouse.c	Fri Nov  5 10:42:15 1999
@@ -410,7 +410,9 @@
 	init_waitqueue_head(&mouse->wait);
 	mouse->fasync = NULL;
 
-	usb_register(&mouse_driver);
+	if (usb_register(&mouse_driver) < 0)
+		return -1;
+
 	printk(KERN_INFO "USB HID boot protocol mouse driver registered.\n");
 	return 0;
 }
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/printer.c linux/drivers/usb/printer.c
--- v2.3.25/linux/drivers/usb/printer.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/printer.c	Fri Nov  5 10:42:15 1999
@@ -419,12 +419,8 @@
 
 int usb_printer_init(void)
 {
-	if (usb_register(&printer_driver)) {
-		printk(KERN_ERR "USB Printer driver cannot register: "
-			"minor number %d already in use\n",
-			printer_driver.minor);
-		return 1;
-	}
+	if (usb_register(&printer_driver))
+		return -1;
 
 	printk(KERN_INFO "USB Printer support registered.\n");
 	return 0;
@@ -433,7 +429,6 @@
 #ifdef MODULE
 int init_module(void)
 {
-
 	return usb_printer_init();
 }
 
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/proc_usb.c linux/drivers/usb/proc_usb.c
--- v2.3.25/linux/drivers/usb/proc_usb.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/proc_usb.c	Thu Nov  4 19:51:28 1999
@@ -968,27 +968,16 @@
         NULL                               /* revalidate   */
 };
 
-#define PROCUSB_MAXBUSSES 64
-
-static unsigned long busnumbermap[(PROCUSB_MAXBUSSES+8 * sizeof(unsigned long)-1) / (8 * sizeof(unsigned long))] = { 0, };
-
 void proc_usb_add_bus(struct usb_bus *bus)
 {
-	int bnum;
 	char buf[16];
 
-	bus->proc_busnum = -1;
 	bus->proc_entry = NULL;
 	if (!usbdir)
 		return;
-	bnum = find_first_zero_bit(busnumbermap, PROCUSB_MAXBUSSES);
-	if (bnum >= PROCUSB_MAXBUSSES)
-		return;
-	sprintf(buf, "%03d", bnum);
+	sprintf(buf, "%03d", bus->busnum);
 	if (!(bus->proc_entry = create_proc_entry(buf, S_IFDIR, usbdir)))
 		return;
-	set_bit(bnum, busnumbermap);
-	bus->proc_busnum = bnum;
 	bus->proc_entry->data = bus;
 }
 
@@ -998,7 +987,6 @@
 	if (!bus->proc_entry)
 		return;
 	remove_proc_entry(bus->proc_entry->name, usbdir);
-	clear_bit(bus->proc_busnum, busnumbermap);
 }
 
 void proc_usb_add_device(struct usb_device *dev)
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/uhci.c linux/drivers/usb/uhci.c
--- v2.3.25/linux/drivers/usb/uhci.c	Wed Oct 27 16:34:12 1999
+++ linux/drivers/usb/uhci.c	Thu Nov  4 19:51:28 1999
@@ -41,6 +41,7 @@
 #include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/unistd.h>
+#include <linux/interrupt.h>
 #include <linux/spinlock.h>
 
 #include <asm/uaccess.h>
@@ -73,20 +74,20 @@
  * function prototypes
  */
 
-static int uhci_get_current_frame_number (struct usb_device *usb_dev);
+static int uhci_get_current_frame_number(struct usb_device *usb_dev);
 
-static int uhci_init_isoc (struct usb_device *usb_dev,
+static int uhci_init_isoc(struct usb_device *usb_dev,
 				unsigned int pipe,
 				int frame_count,
 				void *context,
 				struct usb_isoc_desc **isocdesc);
 
-static void uhci_free_isoc (struct usb_isoc_desc *isocdesc);
+static void uhci_free_isoc(struct usb_isoc_desc *isocdesc);
 
-static int uhci_run_isoc (struct usb_isoc_desc *isocdesc,
+static int uhci_run_isoc(struct usb_isoc_desc *isocdesc,
 				struct usb_isoc_desc *pr_isocdesc);
 
-static int uhci_kill_isoc (struct usb_isoc_desc *isocdesc);
+static int uhci_kill_isoc(struct usb_isoc_desc *isocdesc);
 
 /*
  * Map status to standard result codes
@@ -123,15 +124,12 @@
 /*
  * Return the result of a TD..
  */
-static int uhci_td_result(struct uhci_device *dev, struct uhci_td *td, unsigned long *rval, int debug)
+static int uhci_td_result(struct uhci_device *dev, struct uhci_td *td, unsigned long *rval)
 {
 	unsigned int status;
 	struct uhci_td *tmp;
 	int count = 1000, actlength, explength;
 
-	if (rval)
-		*rval = 0;
-
 	/* Start at the TD first in the chain, if possible */
 	if (td->qh && td->qh->first)
 		tmp = td->qh->first;
@@ -141,6 +139,9 @@
 	if (!tmp)
 		return USB_ST_INTERNALERROR;
 
+	if (rval)
+		 *rval = 0;
+
 	/* Locate the first failing td, if any */
 	do {
 		status = uhci_status_bits(tmp->status);
@@ -154,12 +155,12 @@
 			actlength = uhci_actual_length(tmp->status);
 			if (rval)
 				*rval += actlength;
-			/* This check is bogus, at least for acm. It
-                           always expects 64, but gets as many bytes
-                           as available (typically 1) -- pavel */
-			if (0 && (explength != actlength)) {
-				/* Reset the data toggle on error. */
-				if (debug || uhci_debug)
+
+			if (explength != actlength) {
+				/* If the packet is short, none of the */
+				/*  packets after this were processed, so */
+				/*  fix the DT accordingly */
+				if (in_interrupt() || uhci_debug)
 					printk(KERN_DEBUG "Set toggle from %p rval %ld%c for status=%x to %d, exp=%d, act=%d\n",
 						tmp, rval ? *rval : 0,
 						rval ? '*' : '/', tmp->status,
@@ -168,12 +169,11 @@
 				usb_settoggle(dev->usb, uhci_endpoint(tmp->info),
 					uhci_packetout(tmp->info),
 					uhci_toggle(tmp->info) ^ 1);
-				break;	// Short packet
+				break;	/* Short packet */
 			}
 		}
 
-		if ((tmp->link & UHCI_PTR_TERM) ||
-		    (tmp->link & UHCI_PTR_QH))
+		if ((tmp->link & UHCI_PTR_TERM) || (tmp->link & UHCI_PTR_QH))
 			break;
 
 		tmp = uhci_ptr_to_virt(tmp->link);
@@ -181,8 +181,6 @@
 
 	if (!count) {
 		printk(KERN_ERR "runaway td's in uhci_td_result!\n");
-		/* Force debugging on */
-		debug = 1;
 	} else {
 		/* If we got to the last TD */
 
@@ -200,7 +198,7 @@
 			return USB_ST_NOERROR;
 
 		/* We got to an error, but the controller hasn't finished */
-		/*  with it yet. */
+		/*  with it yet */
 		if (tmp->status & TD_CTRL_ACTIVE)
 			return USB_ST_NOCHANGE;
 
@@ -212,7 +210,7 @@
 	}
 
 	/* Some debugging code */
-	if (debug && uhci_debug) {
+	if (!count || (!in_interrupt() && uhci_debug)) {
 		printk(KERN_DEBUG "uhci_td_result() failed with status %x\n",
 			status);
 
@@ -296,7 +294,7 @@
 		if (lqh->link & UHCI_PTR_TERM)
 			break;
 
-		lqh = uhci_ptr_to_virt(lqh->link);
+		lqh = (struct uhci_qh *)uhci_ptr_to_virt(lqh->link);
 	}
 
 	if (lqh->link & UHCI_PTR_TERM) {
@@ -561,13 +559,17 @@
 	 * udelay(1000) doesn't sound nice, and schedule()
 	 * can't be used as this is called from within interrupt context.
 	 */
+	/*
+	 * we should do the same thing as we do with the QH's
+	 * see uhci_insert_tds_in_qh and uhci_remove_td --jerdfelt
+	 */
 	/* for now warn if there's a possible problem */
 	if (td->status & TD_CTRL_ACTIVE) {
 		unsigned frn = inw(uhci->io_addr + USBFRNUM);
 		__u32 link = uhci->fl->frame[frn % UHCI_NUMFRAMES];
 		if (!(link & (UHCI_PTR_TERM | UHCI_PTR_QH))) {
 			struct uhci_td *tdl = (struct uhci_td *)uhci_ptr_to_virt(link);
-			for (;;) {
+			for (;tdl;) {
 				if (tdl == td) {
 					printk(KERN_WARNING "uhci_remove_frame_list: td possibly still in use!!\n");
 					break;
@@ -589,7 +591,7 @@
  */
 static void uhci_remove_transfer(struct uhci_td *td, char removeirq)
 {
-	int maxcount = 1000;
+	int count = 1000;
 	struct uhci_td *curtd;
 	unsigned int nextlink;
 
@@ -598,7 +600,7 @@
 	else
 		curtd = td;
 
-	/* Remove it from the skeleton */
+	/* Remove the QH from the skeleton and then free it */
 	uhci_remove_qh(td->qh->skel, td->qh);
 	uhci_qh_free(td->qh);
 
@@ -606,21 +608,24 @@
 		nextlink = curtd->link;
 
 		/* IOC? => remove handler */
-		if (removeirq && (td->status & TD_CTRL_IOC))
+		/* HACK: Don't remove if already removed. Prevents deadlock */
+		/*  in uhci_interrupt_notify and callbacks */
+		if (removeirq && (td->status & TD_CTRL_IOC) &&
+		    td->irq_list.next != &td->irq_list)
 			uhci_remove_irq_list(td);
 
+		/* Remove the TD and then free it */
 		uhci_remove_td(curtd);
 		uhci_td_free(curtd);
 
 		if (nextlink & UHCI_PTR_TERM)	/* Tail? */
 			break;
 
-		curtd = (struct uhci_td *)uhci_ptr_to_virt(nextlink);
-		if (!--maxcount) {
-			printk(KERN_ERR "runaway td's!?\n");
-			break;
-		}
-	} while (1);
+		curtd = (struct uhci_td *)uhci_ptr_to_virt(nextlink & ~UHCI_PTR_BITS);
+	} while (count--);
+
+	if (!count)
+		printk(KERN_ERR "runaway td's!?\n");
 }
 
 /*
@@ -644,17 +649,18 @@
 			uhci_td_free(td);
 		if (qh)
 			uhci_qh_free(qh);
-		return (-ENOMEM);
+		return USB_ST_INTERNALERROR;
 	}
 
 	/* Destination: pipe destination with INPUT */
 	destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid(pipe);
 
 	/* Infinite errors is 0, so no bits */
-	status = (pipe & TD_CTRL_LS) | TD_CTRL_IOC | TD_CTRL_ACTIVE | TD_CTRL_SPD;
+	status = (pipe & TD_CTRL_LS) | TD_CTRL_IOC | TD_CTRL_ACTIVE |
+			TD_CTRL_SPD;
 
 	td->link = UHCI_PTR_TERM;		/* Terminate */
-	td->status = status;
+	td->status = status;			/* In */
 	td->info = destination | ((usb_maxpacket(usb_dev, pipe, usb_pipeout(pipe)) - 1) << 21) |
 		(usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << TD_TOKEN_TOGGLE);
 
@@ -678,6 +684,7 @@
 	uhci_insert_qh(qh->skel, qh);
 
 	*handle = (void *)td;
+
 	return 0;
 }
 
@@ -742,7 +749,7 @@
  * Returns 0 for success or negative value for error.
  * Sets isocdesc before successful return.
  */
-static int uhci_init_isoc (struct usb_device *usb_dev,
+static int uhci_init_isoc(struct usb_device *usb_dev,
 				unsigned int pipe,
 				int frame_count,        /* bandwidth % = 100 * this / 1024 */
 				void *context,
@@ -948,7 +955,6 @@
 	 * frame_desc array, but this way won't take less bandwidth
 	 * allocation into account.
 	 */
-
 	if (isocdesc->frame_spacing <= 0)
 		isocdesc->frame_spacing = 1;
 
@@ -1038,7 +1044,7 @@
 	return 0;
 } /* end uhci_kill_isoc */
 
-static void uhci_free_isoc (struct usb_isoc_desc *isocdesc)
+static void uhci_free_isoc(struct usb_isoc_desc *isocdesc)
 {
 	int i;
 
@@ -1083,9 +1089,11 @@
 {
 	DECLARE_WAITQUEUE(wait, current);
 	struct uhci_qh *qh = uhci_qh_alloc(dev);
+	unsigned long rval;
+	int ret;
 
 	if (!qh)
-		return -1;
+		return USB_ST_INTERNALERROR;
 
 	current->state = TASK_UNINTERRUPTIBLE;
 	add_wait_queue(&qh->wakeup, &wait);
@@ -1108,9 +1116,12 @@
 	/* Remove it from the skeleton */
 	uhci_remove_qh(&dev->uhci->skel_control_qh, qh);
 
+	/* Need to check result before free'ing the qh */
+	ret = uhci_td_result(dev, last, &rval);
+
 	uhci_qh_free(qh);
 
-	return uhci_td_result(dev, last, NULL, 1);
+	return (ret < 0) ? ret : rval;
 }
 
 /*
@@ -1149,14 +1160,10 @@
 	int maxsze = usb_maxpacket(usb_dev, pipe, usb_pipeout(pipe));
 	__u32 nextlink;
 	unsigned long bytesrequested = len;
-	unsigned long bytesread = 0;
-#ifdef DUMP_RAW
-	unsigned char *orig_data = (unsigned char *) data;
-#endif
 
 	first = td = uhci_td_alloc(dev);
 	if (!td)
-		return -ENOMEM;
+		return USB_ST_INTERNALERROR;
 
 	/* The "pipe" thing contains the destination in bits 8--18 */
 	destination = (pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
@@ -1184,7 +1191,7 @@
 	td = uhci_td_alloc(dev);
 	if (!td) {
 		uhci_td_free(prevtd);
- 		return -ENOMEM;
+		return USB_ST_INTERNALERROR;
 	}
 
 	prevtd->link = virt_to_bus(td) | UHCI_PTR_DEPTH;
@@ -1214,16 +1221,18 @@
 		prevtd = td;
 		td = uhci_td_alloc(dev);
 		if (!td)
-			return -ENOMEM;
+			return USB_ST_INTERNALERROR;
 		prevtd->link = virt_to_bus(td) | UHCI_PTR_DEPTH;	/* Update previous TD */
 	}
 
 	/*
 	 * Build the final TD for control status 
+	 *
+	 * It's IN if the pipe is an output pipe or we're not expecting
+	 * data back.
 	 */
-	/* It's only IN if the pipe is out AND we aren't expecting data */
 	destination &= ~0xFF;
-	if (usb_pipeout(pipe) | (bytesrequested == 0))
+	if (usb_pipeout(pipe) || !bytesrequested)
 		destination |= USB_PID_IN;
 	else
 		destination |= USB_PID_OUT;
@@ -1243,10 +1252,6 @@
 	count = 1000;
 	td = first;
 	do {
-		if (!uhci_status_bits(td->status) && ((td->info & 0xFF) ==
-		    USB_PID_IN))
-			bytesread += uhci_actual_length(td->status);
-
 		nextlink = td->link;
 		uhci_remove_td(td);
 		uhci_td_free(td);
@@ -1260,36 +1265,9 @@
 	if (!count)
 		printk(KERN_ERR "runaway td's!?\n");
 
-	if (ret && (bytesread >= bytesrequested)) {
-		printk(KERN_DEBUG "Recovered sufficient data (asked for %ld, got %ld) from failed cmd\n",
-			bytesrequested, bytesread);
-		ret = 0;
-	}
-
-	if (uhci_debug && ret) {
-		__u8 *p = (__u8 *)cmd;
-
-		printk("dev %d, pipe %X requested %ld bytes, got %ld, status=%d:\n",
-			usb_dev->devnum, pipe, bytesrequested, bytesread, ret);
-		printk(KERN_DEBUG "Failed cmd - %02X %02X %02X %02X %02X %02X %02X %02X\n",
-		       p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
-	}
-
-#ifdef DUMP_RAW
-	if (!ret && usb_pipein(pipe)) {	/* good Input control msg */
-		int i;
-
-		printk (KERN_CRIT "ctrl msg [%02x %02x %04x %04x %04x] on pipe %x returned:\n",
-			cmd->requesttype, cmd->request,
-			cmd->value, cmd->index, cmd->length, pipe);
-		for (i = 0; i < bytesrequested; ) {
-			printk(" %02x", orig_data[i]);
-			if (++i % 16 == 0)
-				printk("\n");
-		}
-		if (i % 16 != 0)
-			printk("\n");
-	}
+#ifdef UHCI_DEBUG
+	if (ret >= 0 && ret != bytesrequested && bytesrequested)
+		printk("requested %ld bytes, got %d\n", bytesrequested, ret); 
 #endif
 
 	return ret;
@@ -1309,9 +1287,10 @@
 {
 	DECLARE_WAITQUEUE(wait, current);
 	struct uhci_qh *qh = uhci_qh_alloc(dev);
+	int ret;
 
 	if (!qh)
-		return -ENOMEM;
+		return USB_ST_INTERNALERROR;
 
 	current->state = TASK_UNINTERRUPTIBLE;
 	add_wait_queue(&qh->wakeup, &wait);
@@ -1333,9 +1312,11 @@
 
 	uhci_remove_qh(&dev->uhci->skel_bulk_qh, qh);
 
+	ret = uhci_td_result(dev, last, rval);
+
 	uhci_qh_free(qh);
 
-	return uhci_td_result(dev, last, rval, 1);
+	return ret;
 }
 
 /*
@@ -1350,9 +1331,10 @@
 static int uhci_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, unsigned long *rval, int timeout)
 {
 	struct uhci_device *dev = usb_to_uhci(usb_dev);
-	struct uhci_td *first, *td, *prevtd;
+	struct uhci_td *first, *td, *prevtd, *curtd;
 	unsigned long destination, status;
-	int ret;
+	unsigned int nextlink;
+	int ret, count;
 	int maxsze = usb_maxpacket(usb_dev, pipe, usb_pipeout(pipe));
 
 	if (usb_endpoint_halted(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) &&
@@ -1370,7 +1352,7 @@
 	 */
         first = td = uhci_td_alloc(dev);
 	if (!td)
-		return -ENOMEM;
+		return USB_ST_INTERNALERROR;
 
 	prevtd = first;		// This is fake, but at least it's not NULL
 	while (len > 0) {
@@ -1395,7 +1377,7 @@
 			prevtd = td;
 			td = uhci_td_alloc(dev);
 			if (!td)
-				return -ENOMEM;
+				return USB_ST_INTERNALERROR;
 
 			prevtd->link = virt_to_bus(td) | UHCI_PTR_DEPTH;/* Update previous TD */
 		}
@@ -1412,30 +1394,28 @@
 	/* Start it up.. */
 	ret = uhci_run_bulk(dev, first, td, rval, timeout);
 
-	{
-		int count = 100;
-		struct uhci_td *curtd = first;
-		unsigned int nextlink;
+	count = 1000;
+	curtd = first;
 
-		do {
-			nextlink = curtd->link;
-			uhci_remove_td(curtd);
-			uhci_td_free(curtd);
+	do {
+		nextlink = curtd->link;
+		uhci_remove_td(curtd);
+		uhci_td_free(curtd);
 
-			if (nextlink & UHCI_PTR_TERM)	/* Tail? */
-				break;
+		if (nextlink & UHCI_PTR_TERM)	/* Tail? */
+			break;
 
-			curtd = uhci_ptr_to_virt(nextlink);
-		} while (--count);
+		curtd = uhci_ptr_to_virt(nextlink);
+	} while (--count);
 
-		if (!count)
-			printk(KERN_DEBUG "runaway td's!?\n");
-	}
+	if (!count)
+		printk(KERN_DEBUG "uhci: runaway td's!?\n");
 
-	return ret;
+	return ret < 0;
 }
 
-static void * uhci_request_bulk(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, void *data, int len, void *dev_id)
+static void *uhci_request_bulk(struct usb_device *usb_dev, unsigned int pipe,
+		usb_device_irq handler, void *data, int len, void *dev_id)
 {
 	struct uhci_device *dev = usb_to_uhci(usb_dev);
 	struct uhci *uhci = dev->uhci;
@@ -1460,7 +1440,7 @@
 		if (pktsze > maxsze)
 			pktsze = maxsze;
 
-		td->status = status;
+		td->status = status;                                    /* Status */
 		td->info = destination | ((pktsze-1) << 21) |
 			(usb_gettoggle(usb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) << TD_TOKEN_TOGGLE); /* pktsze bytes of data */
 		td->buffer = virt_to_bus(data);
@@ -1468,6 +1448,7 @@
 		td->qh = bulk_qh;
 		td->dev = dev;
 		td->pipetype = PIPE_BULK;
+
 		data += pktsze;
 		len -= pktsze;
 
@@ -1619,9 +1600,9 @@
 	if (usb_new_device(usb_dev)) {
 		unsigned short status = inw(port);
 
-		printk(KERN_INFO "uhci: disabling malfunctioning port %d\n",
+		printk(KERN_INFO "uhci: disabling port %d\n",
 			nr + 1);
-		outw(status | USBPORTSC_PE, port);
+		outw(status & ~USBPORTSC_PE, port);
 	}
 }
 
@@ -1699,7 +1680,7 @@
 	return 0;
 }
 
-int uhci_isoc_callback(struct uhci *uhci, struct uhci_td *td, int status, unsigned long rval)
+static int uhci_isoc_callback(struct uhci *uhci, struct uhci_td *td, int status, unsigned long rval)
 {
 	struct usb_isoc_desc *isocdesc = td->dev_id;
 	int ret;
@@ -1732,6 +1713,7 @@
 		/* TBD */
 		/* usb_dev = td->dev->usb; */
 
+		/* Safe since uhci_interrupt_notify holds the lock */
 		list_add(&td->irq_list, &uhci->interrupt_list);
 
 		td->status = (td->status & (TD_CTRL_SPD | TD_CTRL_C_ERR_MASK |
@@ -1766,20 +1748,49 @@
 	return 0;
 }
 
-int uhci_callback(struct uhci *uhci, struct uhci_td *td, int status, unsigned long rval)
+static int uhci_bulk_callback(struct uhci *uhci, struct uhci_td *td, int status, unsigned long rval)
 {
 	if (td->completed(status, bus_to_virt(td->buffer), rval, td->dev_id)) {
 		struct usb_device *usb_dev = td->dev->usb;
 
+		/* This is safe since uhci_interrupt_notify holds the lock */
+		list_add(&td->irq_list, &uhci->interrupt_list);
+
+		/* Reset the status */
+		td->status = (td->status & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | TD_CTRL_SPD;
+
+		/* Reset the info */
+		td->info = (td->info & (PIPE_DEVEP_MASK | 0xFF | (TD_CTRL_ACTLEN_MASK << 21))) |
+			(usb_gettoggle(usb_dev, uhci_endpoint(td->info), uhci_packetout(td->info)) << TD_TOKEN_TOGGLE); /* pktsze bytes of data */
+
+		usb_dotoggle(usb_dev, uhci_endpoint(td->info), uhci_packetout(td->info));
+		/* The HC only removes it when it completed */
+		/* successfully, so force remove and re-add it */
+		uhci_remove_td(td);
+		uhci_insert_td_in_qh(td->qh, td);
+	}
+
+	return 0;
+}
+
+static int uhci_callback(struct uhci *uhci, struct uhci_td *td, int status, unsigned long rval)
+{
+	if (td->completed(status, bus_to_virt(td->buffer), rval, td->dev_id)) {
+		struct usb_device *usb_dev = td->dev->usb;
+
+		if (td->pipetype != PIPE_INTERRUPT)
+			return 0;
+
+		/* This is safe since uhci_interrupt_notify holds the lock */
 		list_add(&td->irq_list, &uhci->interrupt_list);
 
 		usb_dotoggle(usb_dev, uhci_endpoint(td->info), uhci_packetout(td->info));
 		td->info &= ~(1 << TD_TOKEN_TOGGLE);	/* clear data toggle */
 		td->info |= usb_gettoggle(usb_dev, uhci_endpoint(td->info),
-			uhci_packetout(td->info)) << TD_TOKEN_TOGGLE; /* toggle between data0 and data1 */
+			uhci_packetout(td->info)) << TD_TOKEN_TOGGLE;	/* toggle between data0 and data1 */
 		td->status = (td->status & 0x2F000000) | TD_CTRL_ACTIVE | TD_CTRL_IOC;
 		/* The HC only removes it when it completed */
-		/* successfully, so force remove and re-add it. */
+		/* successfully, so force remove and re-add it */
 		uhci_remove_td(td);
 		uhci_insert_td_in_qh(td->qh, td);
 	} else if (td->flags & UHCI_TD_REMOVE) {
@@ -1797,7 +1808,7 @@
 
 	return 0;
 }
- 
+
 static void uhci_interrupt_notify(struct uhci *uhci)
 {
 	struct list_head *tmp, *head = &uhci->interrupt_list;
@@ -1813,8 +1824,7 @@
 
 		/* We're interested if there was an error or if the chain of */
 		/*  TD's completed successfully */
-		status = uhci_td_result(td->dev, td, &rval, 0);
-
+		status = uhci_td_result(td->dev, td, &rval);
 		if (status == USB_ST_NOCHANGE)
 			continue;
 
@@ -1822,10 +1832,14 @@
 		list_del(&td->irq_list);
 		INIT_LIST_HEAD(&td->irq_list);
 
-		if (td->pipetype == PIPE_ISOCHRONOUS) {
+		switch (td->pipetype) {
+		case PIPE_ISOCHRONOUS:
 			uhci_isoc_callback(uhci, td, status, rval);
-		}
-		else {
+			break;
+		case PIPE_BULK:
+			uhci_bulk_callback(uhci, td, status, rval);
+			break;
+		default:
 			uhci_callback(uhci, td, status, rval);
 		}
 
@@ -1904,8 +1918,8 @@
 	td->link = uhci->fl->frame[0];
 	td->backptr = &uhci->fl->frame[0];
 	td->status = TD_CTRL_IOC;
-	td->info = (15 << 21) | (0x7f << 8) | USB_PID_IN;
-		/* (ignored) input packet, 16 bytes, device 127 */
+	/* (ignored) input packet, 0 bytes, device 127 */
+	td->info = (UHCI_NULL_DATA_SIZE << 21) | (0x7f << 8) | USB_PID_IN;
 	td->buffer = 0;
 	td->qh = NULL;
 	td->pipetype = -1;
@@ -2272,8 +2286,8 @@
 		if (check_region(io_addr, io_size))
 			break;
 
-                /* disable legacy emulation */
-                pci_write_config_word(dev, USBLEGSUP, USBLEGSUP_DEFAULT);
+		/* disable legacy emulation */
+		pci_write_config_word(dev, USBLEGSUP, USBLEGSUP_DEFAULT);
 
 		pci_enable_device(dev);
 
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/uhci.h linux/drivers/usb/uhci.h
--- v2.3.25/linux/drivers/usb/uhci.h	Fri Oct 22 13:21:51 1999
+++ linux/drivers/usb/uhci.h	Thu Nov  4 19:51:28 1999
@@ -125,7 +125,7 @@
 #define TD_TOKEN_TOGGLE		19
 
 #define uhci_maxlen(token)	((token) >> 21)
-#define uhci_expected_length(info) (((info >> 21) + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */ 
+#define uhci_expected_length(info) (((info >> 21) + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */
 #define uhci_toggle(token)	(((token) >> TD_TOKEN_TOGGLE) & 1)
 #define uhci_endpoint(token)	(((token) >> 15) & 0xf)
 #define uhci_devaddr(token)	(((token) >> 8) & 0x7f)
@@ -134,7 +134,6 @@
 #define uhci_packetout(token)	(uhci_packetid(token) != USB_PID_IN)
 #define uhci_packetin(token)	(uhci_packetid(token) == USB_PID_IN)
 
-
 /*
  * The documentation says "4 words for hardware, 4 words for software".
  *
@@ -163,16 +162,16 @@
 	void *dev_id;
 
 	atomic_t refcnt;		/* Reference counting */
+
 	struct uhci_device *dev;	/* The owning device */
 	struct uhci_qh *qh;		/* QH this TD is a part of (ignored for Isochronous) */
+	unsigned char pipetype;		/* Control, Bulk, Interrupt, Isoc */
 	int flags;			/* Remove, etc */
 	int isoc_td_number;		/* 0-relative number within a usb_isoc_desc. */
-	int pipetype;			/* Control, Bulk, Interrupt, or Isoc */
-	int bandwidth_alloc;		/* in microsecs; used only for Interrupt
+	int bandwidth_alloc;            /* in microsecs; used only for Interrupt
 					 * transfers, to return its bandwidth */
 } __attribute__((aligned(16)));
 
-
 /*
  * Note the alignment requirements of the entries
  *
@@ -233,6 +232,7 @@
  * other than that, that is what we're doing now
  *
  * And now we don't put Iso transfers in QH's, so we don't waste one on it
+ * --jerdfelt
  *
  * To keep with Linus' nomenclature, this is called the QH skeleton. These
  * labels (below) are only signficant to the root hub's QH's
@@ -281,7 +281,7 @@
 		if (interval < 8) {
 			return 2;		/* int4 for 4-7 ms */
 		}
-		return 3;			/* int 8 for 8-15 ms */
+		return 3;			/* int8 for 8-15 ms */
 	}
 	if (interval < 64) {
 		if (interval < 32) {
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/usb-core.c linux/drivers/usb/usb-core.c
--- v2.3.25/linux/drivers/usb/usb-core.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/usb-core.c	Thu Nov  4 19:51:28 1999
@@ -9,7 +9,6 @@
  * library, while this file handles starting drivers, etc.
  *
  */
-
 #include <linux/kernel.h>
 #include <linux/config.h>
 
@@ -32,7 +31,7 @@
 {
 	usb_major_init();
 #ifdef CONFIG_USB_PROC
-	proc_usb_init ();
+	proc_usb_init();
 #endif
 #ifndef CONFIG_USB_MODULE
 #	ifdef CONFIG_USB_UHCI
@@ -67,6 +66,9 @@
 #	endif
 #	ifdef CONFIG_USB_CPIA
 		usb_cpia_init();
+#	endif
+#	ifdef CONFIG_USB_DC2XX
+		usb_dc2xx_init();
 #	endif
 #	ifdef CONFIG_USB_HUB
 		usb_hub_init();
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/usb-serial.c linux/drivers/usb/usb-serial.c
--- v2.3.25/linux/drivers/usb/usb-serial.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/usb-serial.c	Fri Nov  5 10:42:15 1999
@@ -665,7 +665,11 @@
 	}
 	
 	/* register the USB driver */
-	usb_register(&usb_serial_driver);
+	if (usb_register(&usb_serial_driver) < 0) {
+		tty_unregister_driver(&serial_tty_driver);
+		return -1;
+	}
+
 	printk(KERN_INFO "USB Serial support registered.\n");
 	return 0;
 }
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/usb.c linux/drivers/usb/usb.c
--- v2.3.25/linux/drivers/usb/usb.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/usb.c	Fri Nov  5 10:42:15 1999
@@ -36,6 +36,8 @@
 static int  usb_find_interface_driver(struct usb_device *, unsigned int);
 static void usb_check_support(struct usb_device *);
 
+static int usb_debug = 1;
+
 /*
  * We have a per-interface "registered driver" list.
  */
@@ -50,13 +52,17 @@
 {
 	struct list_head *tmp;
 
-	printk("usbcore: Registering new driver %s\n", new_driver->name);
 	if (new_driver->fops != NULL) {
-		if (usb_minors[new_driver->minor/16])
-			BUG();
+		if (usb_minors[new_driver->minor/16]) {
+			printk(KERN_ERR "Error registering %s driver\n",
+				new_driver->name);
+			return USB_ST_NOTSUPPORTED;
+		}
 		usb_minors[new_driver->minor/16] = new_driver;
 	}
 
+	printk("usbcore: Registered new driver %s\n", new_driver->name);
+
 	/* Add it to the list of known drivers */
 	list_add(&new_driver->driver_list, &usb_driver_list);
 
@@ -259,7 +265,7 @@
 		set_bit(busnum, busmap.busmap);
 		bus->busnum = busnum;
 	} else
-		printk(KERN_INFO "usb: too many bus'\n");
+		printk(KERN_INFO "usb: too many buses\n");
 
 	proc_usb_add_bus(bus);
 
@@ -461,7 +467,8 @@
 static int usb_parse_endpoint(struct usb_device *dev, struct usb_endpoint_descriptor *endpoint, unsigned char *buffer, int size)
 {
 	struct usb_descriptor_header *header;
-	int parsed = 0;
+	unsigned char *begin;
+	int parsed = 0, len, numskipped;
 
 	header = (struct usb_descriptor_header *)buffer;
 
@@ -473,8 +480,8 @@
 	}
 		
 	if (header->bDescriptorType != USB_DT_ENDPOINT) {
-		printk(KERN_INFO "usb: unexpected descriptor 0x%X\n",
-			endpoint->bDescriptorType);
+		printk(KERN_INFO "usb: unexpected descriptor 0x%X, expecting endpoint descriptor, type 0x%X\n",
+			endpoint->bDescriptorType, USB_DT_ENDPOINT);
 		return parsed;
 	}
 
@@ -487,6 +494,8 @@
 
 	/* Skip over the rest of the Class Specific or Vendor Specific */
 	/*  descriptors */
+	begin = buffer;
+	numskipped = 0;
 	while (size >= sizeof(struct usb_descriptor_header)) {
 		header = (struct usb_descriptor_header *)buffer;
 
@@ -496,67 +505,90 @@
 		}
 
 		/* If we find another descriptor which is at or below us */
-		/*  in the descriptor heirarchy then return */
+		/*  in the descriptor heirarchy then we're done */
 		if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
 		    (header->bDescriptorType == USB_DT_INTERFACE) ||
 		    (header->bDescriptorType == USB_DT_CONFIG) ||
 		    (header->bDescriptorType == USB_DT_DEVICE))
-			return parsed;
+			break;
 
-		printk(KERN_INFO "usb: skipping descriptor 0x%X\n",
-			header->bDescriptorType);
+		numskipped++;
 
 		buffer += header->bLength;
 		size -= header->bLength;
 		parsed += header->bLength;
 	}
 
-	return parsed;
-}
+	if (numskipped)
+		printk(KERN_INFO "usb: skipped %d class/vendor specific endpoint descriptors\n", numskipped);
 
-#if 0
-static int usb_parse_hid(struct usb_device *dev, struct usb_hid_descriptor *hid, unsigned char *ptr, int len)
-{
-	int parsed = usb_expect_descriptor(ptr, len, USB_DT_HID, ptr[0]);
-	int i;
-
-	if (parsed < 0)
+	/* Copy any unknown descriptors into a storage area for drivers */
+	/*  to later parse */
+	len = (int)(buffer - begin);
+	if (!len) {
+		endpoint->extra = NULL;
+		endpoint->extralen = 0;
 		return parsed;
+	}
 
-	memcpy(hid, ptr + parsed, ptr[parsed]);
-	le16_to_cpus(&hid->bcdHID);
+	endpoint->extra = kmalloc(len, GFP_KERNEL);
+	if (!endpoint->extra) {
+		printk(KERN_ERR "Couldn't allocate memory for endpoint extra descriptors\n");
+		endpoint->extralen = 0;
+		return parsed;
+	}
 
-	for (i=0; i<hid->bNumDescriptors; i++)
-		le16_to_cpus(&(hid->desc[i].wDescriptorLength));
+	memcpy(endpoint->extra, begin, len);
+	endpoint->extralen = len;
 
-	return parsed + ptr[parsed];
+	return parsed;
 }
-#endif
 
 static int usb_parse_interface(struct usb_device *dev, struct usb_interface *interface, unsigned char *buffer, int size)
 {
-	int i;
-	int retval, parsed = 0;
+	int i, len, numskipped, retval, parsed = 0;
 	struct usb_descriptor_header *header;
 	struct usb_interface_descriptor *ifp;
+	unsigned char *begin;
 
 	interface->act_altsetting = 0;
 	interface->num_altsetting = 0;
+	interface->max_altsetting = USB_ALTSETTINGALLOC;
 
-	interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * USB_MAXALTSETTING, GFP_KERNEL);
+	interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL);
 	if (!interface->altsetting) {
-		printk("couldn't kmalloc interface->altsetting\n");
+		printk(KERN_ERR "couldn't kmalloc interface->altsetting\n");
 		return -1;
 	}
 
 	while (size > 0) {
+		if (interface->num_altsetting >= interface->max_altsetting) {
+			void *ptr;
+			int oldmas;
+
+			oldmas = interface->max_altsetting;
+			interface->max_altsetting += USB_ALTSETTINGALLOC;
+			if (interface->max_altsetting > USB_MAXALTSETTING) {
+				printk(KERN_WARNING "usb: too many alternate settings (max %d)\n",
+					USB_MAXALTSETTING);
+				return -1;
+			}
+
+			ptr = interface->altsetting;
+			interface->altsetting = kmalloc(sizeof(struct usb_interface_descriptor) * interface->max_altsetting, GFP_KERNEL);
+			if (!interface->altsetting) {
+				printk("couldn't kmalloc interface->altsetting\n");
+				interface->altsetting = ptr;
+				return -1;
+			}
+			memcpy(interface->altsetting, ptr, sizeof(struct usb_interface_descriptor) * oldmas);
+
+			kfree(ptr);
+		}
+
 		ifp = interface->altsetting + interface->num_altsetting;
 		interface->num_altsetting++;
 
-		if (interface->num_altsetting >= USB_MAXALTSETTING) {
-			printk(KERN_WARNING "usb: too many alternate settings\n");
-			return -1;
-		}
 		memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE);
 
 		/* Skip over the interface */
@@ -564,6 +596,9 @@
 		parsed += ifp->bLength;
 		size -= ifp->bLength;
 
+		begin = buffer;
+		numskipped = 0;
+
 		/* Skip over at Interface class or vendor descriptors */
 		while (size >= sizeof(struct usb_descriptor_header)) {
 			header = (struct usb_descriptor_header *)buffer;
@@ -573,27 +608,48 @@
 				return -1;
 			}
 
-			/* If we find another descriptor which is at or below us */
-			/*  in the descriptor heirarchy then return */
+			/* If we find another descriptor which is at or below */
+			/*  us in the descriptor heirarchy then return */
 			if ((header->bDescriptorType == USB_DT_INTERFACE) ||
-			    (header->bDescriptorType == USB_DT_ENDPOINT))
-				break;
-
-			if ((header->bDescriptorType == USB_DT_CONFIG) ||
+			    (header->bDescriptorType == USB_DT_ENDPOINT) ||
+			    (header->bDescriptorType == USB_DT_CONFIG) ||
 			    (header->bDescriptorType == USB_DT_DEVICE))
-				return parsed;
+				break;
 
-			if (header->bDescriptorType == USB_DT_HID)
-				printk(KERN_INFO "usb: skipping HID descriptor\n");
-			else
-				printk(KERN_INFO "usb: unexpected descriptor 0x%X\n",
-					header->bDescriptorType);
+			numskipped++;
 
 			buffer += header->bLength;
 			parsed += header->bLength;
 			size -= header->bLength;
 		}
 
+		if (numskipped)
+			printk(KERN_INFO "usb: skipped %d class/vendor specific interface descriptors\n", numskipped);
+
+		/* Copy any unknown descriptors into a storage area for */
+		/*  drivers to later parse */
+		len = (int)(buffer - begin);
+		if (!len) {
+			ifp->extra = NULL;
+			ifp->extralen = 0;
+		} else {
+			ifp->extra = kmalloc(len, GFP_KERNEL);
+			if (!ifp->extra) {
+				printk(KERN_ERR "couldn't allocate memory for interface extra descriptors\n");
+				ifp->extralen = 0;
+				return -1;
+			}
+			memcpy(ifp->extra, begin, len);
+			ifp->extralen = len;
+		}
+
+		/* Did we hit an unexpected descriptor? */
+		header = (struct usb_descriptor_header *)buffer;
+		if ((size >= sizeof(struct usb_descriptor_header)) &&
+		    ((header->bDescriptorType == USB_DT_CONFIG) ||
+		     (header->bDescriptorType == USB_DT_DEVICE)))
+			return parsed;
+
 		if (ifp->bNumEndpoints > USB_MAXENDPOINTS) {
 			printk(KERN_WARNING "usb: too many endpoints\n");
 			return -1;
@@ -796,7 +852,7 @@
 {
 	int devnum;
 
-	dev->descriptor.bMaxPacketSize0 = 8;  /* XXX fixed 8 bytes for now */
+	dev->descriptor.bMaxPacketSize0 = 8;	/* Start off at 8 bytes */
 
 	devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1);
 	if (devnum < 128) {
@@ -811,32 +867,20 @@
  */
 int usb_set_address(struct usb_device *dev)
 {
-	devrequest dr;
-
-	dr.requesttype = 0;
-	dr.request = USB_REQ_SET_ADDRESS;
-	dr.value = dev->devnum;
-	dr.index = 0;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_snddefctrl(dev), &dr, NULL, 0, HZ);
+	return usb_control_msg(dev, usb_snddefctrl(dev), USB_REQ_SET_ADDRESS,
+		0, dev->devnum, 0, NULL, 0, HZ);
 }
 
 int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size)
 {
-	devrequest dr;
 	int i = 5;
 	int result;
 
-	dr.requesttype = USB_DIR_IN;
-	dr.request = USB_REQ_GET_DESCRIPTOR;
-	dr.value = (type << 8) + index;
-	dr.index = 0;
-	dr.length = size;
-
 	while (i--) {
-		if (!(result = dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, size, HZ))
-		    || result == USB_ST_STALL)
+		if ((result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+			USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+			(type << 8) + index, 0, buf, size, HZ)) >= 0 ||
+		    result == USB_ST_STALL)
 			break;
 	}
 	return result;
@@ -844,22 +888,16 @@
 
 int usb_get_string(struct usb_device *dev, unsigned short langid, unsigned char index, void *buf, int size)
 {
-	devrequest dr;
-
-	dr.requesttype = USB_DIR_IN;
-	dr.request = USB_REQ_GET_DESCRIPTOR;
-	dr.value = (USB_DT_STRING << 8) + index;
-	dr.index = langid;
-	dr.length = size;
-
-	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, buf, size, HZ);
+	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+		USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
+		(USB_DT_STRING << 8) + index, langid, buf, size, HZ);
 }
 
 int usb_get_device_descriptor(struct usb_device *dev)
 {
 	int ret = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor,
 				     sizeof(dev->descriptor));
-	if (ret == 0) {
+	if (ret >= 0) {
 		le16_to_cpus(&dev->descriptor.bcdUSB);
 		le16_to_cpus(&dev->descriptor.idVendor);
 		le16_to_cpus(&dev->descriptor.idProduct);
@@ -868,62 +906,37 @@
 	return ret;
 }
 
-int usb_get_status (struct usb_device *dev, int type, int target, void *data)
+int usb_get_status(struct usb_device *dev, int type, int target, void *data)
 {
-	devrequest dr;
-
-	dr.requesttype = USB_DIR_IN | type;	/* USB_RECIP_DEVICE, _INTERFACE, or _ENDPOINT */
-	dr.request = USB_REQ_GET_STATUS;
-	dr.value = 0;
-	dr.index = target;
-	dr.length = 2;
-
-	return dev->bus->op->control_msg (dev, usb_rcvctrlpipe (dev,0), &dr, data, 2, HZ);
+	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+		USB_REQ_GET_STATUS, USB_DIR_IN | type, 0, target, data, 2, HZ);
 }
 
 int usb_get_protocol(struct usb_device *dev)
 {
-	unsigned char buf[8];
-	devrequest dr;
-
-	dr.requesttype = USB_RT_HIDD | USB_DIR_IN;
-	dr.request = USB_REQ_GET_PROTOCOL;
-	dr.value = 0;
-	dr.index = 1;
-	dr.length = 1;
+	unsigned char type;
+	int ret;
 
-	if (dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev, 0), &dr, buf, 1, HZ))
-		return -1;
+	if ((ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+	    USB_REQ_GET_PROTOCOL, USB_DIR_IN | USB_RT_HIDD,
+	    0, 1, &type, 1, HZ)) < 0)
+		return ret;
 
-	return buf[0];
+	return type;
 }
 
 int usb_set_protocol(struct usb_device *dev, int protocol)
 {
-	devrequest dr;
-
-	dr.requesttype = USB_RT_HIDD;
-	dr.request = USB_REQ_SET_PROTOCOL;
-	dr.value = protocol;
-	dr.index = 1;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0, HZ);
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+		USB_REQ_SET_PROTOCOL, USB_RT_HIDD, protocol, 1, NULL, 0, HZ);
 }
 
 /* keyboards want a nonzero duration according to HID spec, but
    mice should use infinity (0) -keryan */
 int usb_set_idle(struct usb_device *dev,  int duration, int report_id)
 {
-	devrequest dr;
-
-	dr.requesttype = USB_RT_HIDD;
-	dr.request = USB_REQ_SET_IDLE;
-	dr.value = (duration << 8) | report_id;
-	dr.index = 1;
-	dr.length = 0;
-
-	return dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0, HZ);
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_IDLE,
+		USB_RT_HIDD, (duration << 8) | report_id, 1, NULL, 0, HZ);
 }
 
 static void usb_set_maxpacket(struct usb_device *dev)
@@ -957,38 +970,30 @@
  */
 int usb_clear_halt(struct usb_device *dev, int endp)
 {
-	devrequest dr;
 	int result;
 	__u16 status;
 
-    	//if (!usb_endpoint_halted(dev, endp & 0x0f, usb_endpoint_out(endp)))
-	//	return 0;
-
-	dr.requesttype = USB_RT_ENDPOINT;
-	dr.request = USB_REQ_CLEAR_FEATURE;
-	dr.value = 0;
-	dr.index = endp;
-	dr.length = 0;
+/*
+	if (!usb_endpoint_halted(dev, endp & 0x0f, usb_endpoint_out(endp)))
+		return 0;
+*/
 
-	result = dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev,0), &dr, NULL, 0, HZ);
+	result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+		USB_REQ_CLEAR_FEATURE, USB_RT_ENDPOINT, 0, endp, NULL, 0, HZ);
 
 	/* don't clear if failed */
-	if (result)
-	    return result;
+	if (result < 0)
+		return result;
+
+	result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+		USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_ENDPOINT, 0, endp,
+		&status, sizeof(status), HZ);
+	if (result < 0)
+		return result;
+
+	if (status & 1)
+		return USB_ST_STALL;		/* still halted */
 
-#if 1	/* let's be really tough */
-	dr.requesttype = USB_DIR_IN | USB_RT_ENDPOINT;
-	dr.request = USB_REQ_GET_STATUS;
-	dr.length = 2;
-	status = 0xffff;
-
-	result = dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev,0), &dr, &status, 2, HZ);
-
-	if (result)
-	    return result;
-	if (status & 1)		/* endpoint status is Halted */
-	    return USB_ST_STALL;		/* still halted */
-#endif
 	usb_endpoint_running(dev, endp & 0x0f, usb_endpoint_out(endp));
 
 	/* toggle is reset on clear */
@@ -1000,18 +1005,12 @@
 
 int usb_set_interface(struct usb_device *dev, int interface, int alternate)
 {
-	devrequest dr;
-	int err;
+	int ret;
 
-	dr.requesttype = 1;
-	dr.request = USB_REQ_SET_INTERFACE;
-	dr.value = alternate;
-	dr.index = interface;
-	dr.length = 0;
-
-	err = dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0, HZ);
-	if (err)
-		return err;
+	if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+	    USB_REQ_SET_INTERFACE, USB_RT_INTERFACE, alternate,
+	    interface, NULL, 0, HZ)) < 0)
+		return ret;
 
 	dev->actconfig->interface[interface].act_altsetting = alternate;
 	usb_set_maxpacket(dev);
@@ -1020,16 +1019,9 @@
 
 int usb_set_configuration(struct usb_device *dev, int configuration)
 {
-	devrequest dr;
-	int i;
+	int i, ret;
 	struct usb_config_descriptor *cp = NULL;
 	
-	dr.requesttype = 0;
-	dr.request = USB_REQ_SET_CONFIGURATION;
-	dr.value = configuration;
-	dr.index = 0;
-	dr.length = 0;
-
 	for (i=0; i<dev->descriptor.bNumConfigurations; i++) {
 		if (dev->config[i].bConfigurationValue == configuration) {
 			cp = &dev->config[i];
@@ -1040,27 +1032,24 @@
 		printk(KERN_INFO "usb: selecting invalid configuration %d\n", configuration);
 		return -1;
 	}
-	if (dev->bus->op->control_msg(dev, usb_sndctrlpipe(dev, 0), &dr, NULL, 0, HZ))
-		return -1;
+
+	if ((ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+	    USB_REQ_SET_CONFIGURATION, 0, configuration, 0, NULL, 0, HZ)) < 0)
+		return ret;
 
 	dev->actconfig = cp;
 	dev->toggle[0] = 0;
 	dev->toggle[1] = 0;
 	usb_set_maxpacket(dev);
+
 	return 0;
 }
 
 int usb_get_report(struct usb_device *dev, unsigned char type, unsigned char id, unsigned char index, void *buf, int size)
 {
-	devrequest dr;
-
-	dr.requesttype = USB_RT_HIDD | USB_DIR_IN;
-	dr.request = USB_REQ_GET_REPORT;
-	dr.value = (type << 8) + id;
-	dr.index = index;
-	dr.length = size;
-
-	return dev->bus->op->control_msg(dev, usb_rcvctrlpipe(dev, 0), &dr, buf, size, HZ);
+	return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+		USB_REQ_GET_REPORT, USB_DIR_IN | USB_RT_HIDD,
+		(type << 8) + id, index, buf, size, HZ);
 }
 
 int usb_get_configuration(struct usb_device *dev)
@@ -1092,21 +1081,26 @@
 		/* We grab the first 8 bytes so we know how long the whole */
 		/*  configuration is */
 		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
-		if (result < 0)
-	    		return -1;
-		
+		if (result < 0) {
+			printk(KERN_ERR "usb: unable to get descriptor\n");
+			return result;
+		}
+
   	  	/* Get the full buffer */
 		le16_to_cpus(&desc->wTotalLength);
 
 		bigbuffer = kmalloc(desc->wTotalLength, GFP_KERNEL);
-		if (!bigbuffer)
-			return -1;
+		if (!bigbuffer) {
+			printk(KERN_ERR "unable to allocate memory for configuration descriptors\n");
+			return USB_ST_INTERNALERROR;
+		}
 
 		/* Now that we know the length, get the whole thing */
 		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, desc->wTotalLength);
-		if (result) {
+		if (result < 0) {
+			printk(KERN_ERR "couldn't get all of config descriptors\n");
 			kfree(bigbuffer);
-			return -1;
+			return result;
 		}
 			
 		result = usb_parse_configuration(dev, &dev->config[cfgno], bigbuffer);
@@ -1123,7 +1117,7 @@
 
 char *usb_string(struct usb_device *dev, int index)
 {
-	int len, i;
+	int i, len, ret;
 	char *ptr;
 	union {
 		unsigned char buffer[256];
@@ -1137,23 +1131,28 @@
 
 	if (dev->string_langid == 0) {
 		/* read string descriptor 0 */
-		if (usb_get_string(dev, 0, 0, u.buffer, 2) == 0
-		    && u.desc.bLength >= 4
-		    && usb_get_string(dev, 0, 0, u.buffer, 4) == 0)
+		ret = usb_get_string(dev, 0, 0, u.buffer, 4);
+		if (ret >= 0 && u.desc.bLength >= 4)
 			dev->string_langid = le16_to_cpup(&u.desc.wData[0]);
+		else
+			printk(KERN_ERR "usb: error getting string!\n");
 		dev->string_langid |= 0x10000;	/* so it's non-zero */
 	}
 
-	if (usb_get_string(dev, dev->string_langid, index, u.buffer, 2) ||
+	if (usb_get_string(dev, dev->string_langid, index, u.buffer, 4) < 0 ||
 	    usb_get_string(dev, dev->string_langid, index, u.buffer,
-			      u.desc.bLength))
-		return 0;
+			      u.desc.bLength) < 0) {
+		printk(KERN_ERR "usb: error retrieving string\n");
+		return NULL;
+	}
 
 	len = u.desc.bLength / 2;	/* includes terminating null */
 
 	ptr = kmalloc(len, GFP_KERNEL);
-	if (!ptr)
-		return 0;
+	if (!ptr) {
+		printk(KERN_ERR "usb: couldn't allocate memory for string\n");
+		return NULL;
+	}
 
 	for (i = 0; i < len - 1; ++i)
 		ptr[i] = le16_to_cpup(&u.desc.wData[i]);
@@ -1172,8 +1171,7 @@
  */
 int usb_new_device(struct usb_device *dev)
 {
-	int addr;
-	int err;
+	int addr, err;
 
 	printk(KERN_INFO "USB new device connect, assigned device number %d\n",
 		dev->devnum);
@@ -1186,11 +1184,9 @@
 	addr = dev->devnum;
 	dev->devnum = 0;
 
-	/* Slow devices */
 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, 8);
-	if (err) {
-		printk(KERN_ERR "usbcore: USB device not responding, giving up (error=%d)\n",
-			err);
+	if (err < 0) {
+		printk(KERN_ERR "usbcore: USB device not responding, giving up (error=%d)\n", err);
 		dev->devnum = -1;
 		return 1;
 	}
@@ -1207,9 +1203,8 @@
 	dev->devnum = addr;
 
 	err = usb_set_address(dev);
-	if (err) {
-		printk(KERN_ERR "usbcore: USB device not accepting new address (error=%d)\n",
-			err);
+	if (err < 0) {
+		printk(KERN_ERR "usbcore: USB device not accepting new address (error=%d)\n", err);
 		dev->devnum = -1;
 		return 1;
 	}
@@ -1217,15 +1212,15 @@
 	wait_ms(10);	/* Let the SET_ADDRESS settle */
 
 	err = usb_get_device_descriptor(dev);
-	if (err) {
-		printk(KERN_ERR "usbcore: unable to get device descriptor (error=%d)\n",
-			err);
+	if (err < 0) {
+		printk(KERN_ERR "usbcore: unable to get device descriptor (error=%d)\n", err);
 		dev->devnum = -1;
 		return 1;
 	}
 
-	if (usb_get_configuration(dev)) {
-		printk(KERN_ERR "usbcore: unable to get configuration\n");
+	err = usb_get_configuration(dev);
+	if (err < 0) {
+		printk(KERN_ERR "usbcore: unable to get configuration (error=%d)\n", err);
 		dev->devnum = -1;
 		return 1;
 	}
@@ -1255,14 +1250,26 @@
 int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout)
 {
         devrequest dr;
+	int ret;
 
         dr.requesttype = requesttype;
         dr.request = request;
-        dr.value = value;
-        dr.index = index;
-        dr.length = size;
+        dr.value = cpu_to_le16p(&value);
+        dr.index = cpu_to_le16p(&index);
+        dr.length = cpu_to_le16p(&size);
+
+        ret = dev->bus->op->control_msg(dev, pipe, &dr, data, size, timeout);
+
+	if (ret < 0 && usb_debug) {
+		unsigned char *p = (unsigned char *)&dr;
+
+		printk(KERN_DEBUG "Failed control msg - r:%02X rt:%02X v:%04X i:%04X s:%04X - ret: %d\n",
+			request, requesttype, value, index, size, ret);
+		printk(KERN_DEBUG "  %02X %02X %02X %02X %02X %02X %02X %02X\n",
+			p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+	}
 
-        return dev->bus->op->control_msg(dev, pipe, &dr, data, size, timeout);
+	return ret;
 }
 
 int usb_request_irq(struct usb_device *dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id, void **handle)
@@ -1383,7 +1390,7 @@
 	return err;
 }
 
-void usb_free_isoc (struct usb_isoc_desc *isocdesc)
+void usb_free_isoc(struct usb_isoc_desc *isocdesc)
 {
 	long    bustime;
 
@@ -1402,13 +1409,13 @@
 	isocdesc->usb_dev->bus->op->free_isoc (isocdesc);
 }
 
-int usb_run_isoc (struct usb_isoc_desc *isocdesc,
+int usb_run_isoc(struct usb_isoc_desc *isocdesc,
 			struct usb_isoc_desc *pr_isocdesc)
 {
 	return isocdesc->usb_dev->bus->op->run_isoc (isocdesc, pr_isocdesc);
 }
 
-int usb_kill_isoc (struct usb_isoc_desc *isocdesc)
+int usb_kill_isoc(struct usb_isoc_desc *isocdesc)
 {
 	return isocdesc->usb_dev->bus->op->kill_isoc (isocdesc);
 }
@@ -1417,6 +1424,7 @@
 {
 	int minor = MINOR(inode->i_rdev);
 	struct usb_driver *c = usb_minors[minor/16];
+
 	file->f_op = NULL;
 
 	if (c && (file->f_op = c->fops) && file->f_op->open)
@@ -1479,6 +1487,10 @@
 EXPORT_SYMBOL(usb_alloc_dev);
 EXPORT_SYMBOL(usb_free_dev);
 EXPORT_SYMBOL(usb_inc_dev_use);
+
+EXPORT_SYMBOL(usb_driver_claim_interface);
+EXPORT_SYMBOL(usb_interface_claimed);
+EXPORT_SYMBOL(usb_driver_release_interface);
 
 EXPORT_SYMBOL(usb_init_root_hub);
 EXPORT_SYMBOL(usb_new_device);
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/usb.h linux/drivers/usb/usb.h
--- v2.3.25/linux/drivers/usb/usb.h	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/usb.h	Fri Nov  5 15:54:01 1999
@@ -126,15 +126,15 @@
 	__u16 value;
 	__u16 index;
 	__u16 length;
-	__u32 timeout;  /* in milliseconds */
-        void *data;
+	__u32 timeout;	/* in milliseconds */
+	void *data;
 };
 
 struct usb_proc_bulktransfer {
-        unsigned int ep;
-        unsigned int len;
-	unsigned int timeout; /* in milliseconds */
-        void *data;
+	unsigned int ep;
+	unsigned int len;
+	unsigned int timeout;	/* in milliseconds */
+	void *data;
 };
 
 struct usb_proc_old_ctrltransfer {
@@ -143,31 +143,28 @@
 	__u16 value;
 	__u16 index;
 	__u16 length;
-        /* pointer to data */
-        void *data;
+	/* pointer to data */
+	void *data;
 };
 
 struct usb_proc_old_bulktransfer {
-        unsigned int ep;
-        unsigned int len;
-        void *data;
+	unsigned int ep;
+	unsigned int len;
+	void *data;
 };
 
 struct usb_proc_setinterface {
-        unsigned int interface;
-        unsigned int altsetting;
+	unsigned int interface;
+	unsigned int altsetting;
 };
 
-#define USB_PROC_CONTROL           _IOWR('U', 0, struct usb_proc_ctrltransfer)
-#define USB_PROC_BULK              _IOWR('U', 2, struct usb_proc_bulktransfer)
-#define USB_PROC_OLD_CONTROL       _IOWR('U', 0, struct usb_proc_old_ctrltransfer)
-#define USB_PROC_OLD_BULK          _IOWR('U', 2, struct usb_proc_old_bulktransfer)
-#define USB_PROC_RESETEP           _IOR('U', 3, unsigned int)
-#define USB_PROC_SETINTERFACE      _IOR('U', 4, struct usb_proc_setinterface)
-#define USB_PROC_SETCONFIGURATION  _IOR('U', 5, unsigned int)
-
-
-
+#define USB_PROC_CONTROL	_IOWR('U', 0, struct usb_proc_ctrltransfer)
+#define USB_PROC_BULK		_IOWR('U', 2, struct usb_proc_bulktransfer)
+#define USB_PROC_OLD_CONTROL	_IOWR('U', 0, struct usb_proc_old_ctrltransfer)
+#define USB_PROC_OLD_BULK	_IOWR('U', 2, struct usb_proc_old_bulktransfer)
+#define USB_PROC_RESETEP	_IOR('U', 3, unsigned int)
+#define USB_PROC_SETINTERFACE	_IOR('U', 4, struct usb_proc_setinterface)
+#define USB_PROC_SETCONFIGURATION	_IOR('U', 5, unsigned int)
 
 #ifdef __KERNEL__
 
@@ -180,6 +177,7 @@
 extern int usb_hub_init(void);
 extern int usb_kbd_init(void);
 extern int usb_cpia_init(void);
+extern int usb_dc2xx_init(void);
 extern int usb_mouse_init(void);
 extern int usb_printer_init(void);
 
@@ -251,7 +249,8 @@
 
 /* Everything but the endpoint maximums are aribtrary */
 #define USB_MAXCONFIG		8
-#define USB_MAXALTSETTING	16
+#define USB_ALTSETTINGALLOC	4
+#define USB_MAXALTSETTING	128	/* Hard limit */
 #define USB_MAXINTERFACES	32
 #define USB_MAXENDPOINTS	32
 
@@ -289,6 +288,9 @@
 	__u8  bInterval;
 	__u8  bRefresh;
 	__u8  bSynchAddress;
+
+	unsigned char *extra;	/* Extra descriptors */
+	int extralen;
 } __attribute__ ((packed));
 
 /* HID descriptor */
@@ -319,8 +321,10 @@
 	__u8  bInterfaceProtocol;
 	__u8  iInterface;
 
-	struct usb_hid_descriptor *hid;
 	struct usb_endpoint_descriptor *endpoint;
+
+	unsigned char *extra;
+	int extralen;
 } __attribute__ ((packed));
 
 struct usb_interface {
@@ -328,6 +332,7 @@
 
 	int act_altsetting;		/* active alternate setting */
 	int num_altsetting;		/* number of alternate settings */
+	int max_altsetting;		/* total memory allocated */
 
         struct usb_driver *driver;	/* driver */
 	void *private_data;
@@ -407,13 +412,13 @@
  * with the completed frames (TDs).
  */
 enum {
-	CB_CONTINUE = 0,        /* OK, remove all TDs;
+	CB_CONTINUE = 0,	/* OK, remove all TDs;
 				   needs to be 0 to be consistent with
 				   current callback function ret. values */
-	CB_REUSE,               /* leave descriptors as NULL, not active */
-	CB_RESTART,             /* leave descriptors as they are, alive */
-	CB_ABORT,                /* kill this USB transfer request */
-	CB_CONT_RUN    		/* append the isoc_desc at the end of all active isoc_desc */
+	CB_REUSE,		/* leave descriptors as NULL, not active */
+	CB_RESTART,		/* leave descriptors as they are, alive */
+	CB_ABORT,		/* kill this USB transfer request */
+	CB_CONT_RUN		/* append the isoc_desc at the end of all active isoc_desc */
 };
 
 struct isoc_frame_desc {
@@ -448,6 +453,7 @@
 	void            *data;
 	int             buf_size;
 	struct usb_isoc_desc *prev_isocdesc; /* previous isoc_desc, for CB_CONT_RUN */
+
 	/*
 	 * The following fields are set by the usb_run_isoc() call.
 	 */
@@ -504,7 +510,6 @@
 	int bandwidth_isoc_reqs;	/* number of Isoc. requesters */
 
 	/* procfs entry */
-	int proc_busnum;
 	struct proc_dir_entry *proc_entry;
 };
 
@@ -534,7 +539,7 @@
 	int string_langid;		/* language ID for strings */
   
 	void *hcpriv;			/* Host Controller private data */
-	void *audiopriv;		/* May be both audio and HID */
+
 	/* procfs entry */
 	struct proc_dir_entry *proc_entry;
 
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/usb_scsi.c linux/drivers/usb/usb_scsi.c
--- v2.3.25/linux/drivers/usb/usb_scsi.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/usb_scsi.c	Fri Nov  5 10:42:15 1999
@@ -1365,7 +1365,9 @@
 	usb_zip_init();
 #endif
 
-	usb_register(&scsi_driver);
+	if (usb_register(&scsi_driver) < 0)
+		return -1;
+
 	printk(KERN_INFO "USB SCSI support registered.\n");
 	return 0;
 }
diff -u --recursive --new-file v2.3.25/linux/drivers/usb/uss720.c linux/drivers/usb/uss720.c
--- v2.3.25/linux/drivers/usb/uss720.c	Mon Nov  1 13:56:26 1999
+++ linux/drivers/usb/uss720.c	Fri Nov  5 10:42:16 1999
@@ -640,7 +640,9 @@
 
 static int __init uss720_init(void)
 {
-	usb_register(&uss720_driver);
+	if (usb_register(&uss720_driver) < 0)
+		return -1;
+
         printk(KERN_INFO "uss720: USB<->IEEE1284 cable driver v0.4 registered.\n"
 	       KERN_INFO "uss720: (C) 1999 by Thomas Sailer, <sailer@ife.ee.ethz.ch>\n");
 	return 0;
diff -u --recursive --new-file v2.3.25/linux/drivers/video/Config.in linux/drivers/video/Config.in
--- v2.3.25/linux/drivers/video/Config.in	Fri Oct 22 13:21:51 1999
+++ linux/drivers/video/Config.in	Wed Nov  3 14:43:54 1999
@@ -10,6 +10,9 @@
 if [ "$CONFIG_FB" = "y" ]; then
    define_bool CONFIG_DUMMY_CONSOLE y
    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+      if [ "$CONFIG_PCI" = "y" ]; then
+         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 '  Permedia2 support (EXPERIMENTAL)' CONFIG_FB_PM2
@@ -162,25 +165,25 @@
 	   "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \
 	   "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
 	   "$CONFIG_FB_BWTWO" = "y" -o "$CONFIG_FB_CLGEN" = "y" ]; then
-	 define_bool CONFIG_FBCON_MFB y
+	 define_tristate CONFIG_FBCON_MFB y
       else
 	 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_AMIGA" = "m" -o \
 	      "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
 	      "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_RETINAZ3" = "m" -o \
 	      "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
 	      "$CONFIG_FB_BWTWO" = "m" -o "$CONFIG_FB_CLGEN" = "m" ]; then
-	    define_bool CONFIG_FBCON_MFB m
+	    define_tristate CONFIG_FBCON_MFB m
 	 fi
       fi
       if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
 	   "$CONFIG_FB_VIRTUAL" = "y" ]; then
-	 define_bool CONFIG_FBCON_CFB2 y
-	 define_bool CONFIG_FBCON_CFB4 y
+	 define_tristate CONFIG_FBCON_CFB2 y
+	 define_tristate CONFIG_FBCON_CFB4 y
       else
 	 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
 	      "$CONFIG_FB_VIRTUAL" = "m" ]; then
-	    define_bool CONFIG_FBCON_CFB2 m
-	    define_bool CONFIG_FBCON_CFB4 m
+	    define_tristate CONFIG_FBCON_CFB2 m
+	    define_tristate CONFIG_FBCON_CFB4 m
 	 fi
       fi
       if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \
@@ -195,9 +198,10 @@
            "$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_RIVA" = "y" -o \
 	   "$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" -o \
 	   "$CONFIG_FB_3DFX" = "y" ]; then
-	 define_bool CONFIG_FBCON_CFB8 y
+	 define_tristate CONFIG_FBCON_CFB8 y
       else
 	 if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
 	      "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
@@ -212,7 +216,7 @@
 	      "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
 	      "$CONFIG_FB_P9100" = "m" -o \
 	      "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" ]; then
-	    define_bool CONFIG_FBCON_CFB8 m
+	    define_tristate CONFIG_FBCON_CFB8 m
 	 fi
       fi
       if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
@@ -224,8 +228,9 @@
 	   "$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_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y" ]; then
-	 define_bool CONFIG_FBCON_CFB16 y
+	 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 \
@@ -237,20 +242,20 @@
 	      "$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
 	      "$CONFIG_FB_PM2" = "y" -o "$CONFIG_FB_SGIVW" = "m" -o \
 	      "$CONFIG_FB_CYBER2000" = "m" ]; then
-	    define_bool CONFIG_FBCON_CFB16 m
+	    define_tristate CONFIG_FBCON_CFB16 m
 	 fi
       fi
       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_CYBER2000" = "y" ]; then
-	 define_bool CONFIG_FBCON_CFB24 y
+	 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_CYBER2000" = "m" ]; then
-	    define_bool CONFIG_FBCON_CFB24 m
+	    define_tristate CONFIG_FBCON_CFB24 m
 	 fi
       fi
       if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
@@ -258,9 +263,10 @@
 	   "$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_FM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
 	   "$CONFIG_FB_3DFX" = "y" ]; then
-	 define_bool CONFIG_FBCON_CFB32 y
+	 define_tristate CONFIG_FBCON_CFB32 y
       else
 	 if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
 	      "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
@@ -268,50 +274,50 @@
 	      "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
 	      "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
               "$CONFIG_FB_SGIVW" = "m" ]; then
-	    define_bool CONFIG_FBCON_CFB32 m
+	    define_tristate CONFIG_FBCON_CFB32 m
 	 fi
       fi
       if [ "$CONFIG_FB_AMIGA" = "y" ]; then
-	 define_bool CONFIG_FBCON_AFB y
-	 define_bool CONFIG_FBCON_ILBM y
+	 define_tristate CONFIG_FBCON_AFB y
+	 define_tristate CONFIG_FBCON_ILBM y
       else
 	 if [ "$CONFIG_FB_AMIGA" = "m" ]; then
-	    define_bool CONFIG_FBCON_AFB m
-	    define_bool CONFIG_FBCON_ILBM m
+	    define_tristate CONFIG_FBCON_AFB m
+	    define_tristate CONFIG_FBCON_ILBM m
 	 fi
       fi
       if [ "$CONFIG_FB_ATARI" = "y" ]; then
-	 define_bool CONFIG_FBCON_IPLAN2P2 y
-	 define_bool CONFIG_FBCON_IPLAN2P4 y
-	 define_bool CONFIG_FBCON_IPLAN2P8 y
-#	 define_bool CONFIG_FBCON_IPLAN2P16 y
+	 define_tristate CONFIG_FBCON_IPLAN2P2 y
+	 define_tristate CONFIG_FBCON_IPLAN2P4 y
+	 define_tristate CONFIG_FBCON_IPLAN2P8 y
+#	 define_tristate CONFIG_FBCON_IPLAN2P16 y
       else
 	 if [ "$CONFIG_FB_ATARI" = "m" ]; then
-	    define_bool CONFIG_FBCON_IPLAN2P2 m
-	    define_bool CONFIG_FBCON_IPLAN2P4 m
-	    define_bool CONFIG_FBCON_IPLAN2P8 m
-#	    define_bool CONFIG_FBCON_IPLAN2P16 m
+	    define_tristate CONFIG_FBCON_IPLAN2P2 m
+	    define_tristate CONFIG_FBCON_IPLAN2P4 m
+	    define_tristate CONFIG_FBCON_IPLAN2P8 m
+#	    define_tristate CONFIG_FBCON_IPLAN2P16 m
 	 fi
       fi
       if [ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" ]; then
-	 define_bool CONFIG_FBCON_MAC  y
+	 define_tristate CONFIG_FBCON_MAC  y
       else
 	 if [ "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
-	    define_bool CONFIG_FBCON_MAC  m
+	    define_tristate CONFIG_FBCON_MAC  m
 	 fi
       fi
       if [ "$CONFIG_FB_VGA16" = "y" ]; then
-	 define_bool CONFIG_FBCON_VGA_PLANES y
+	 define_tristate CONFIG_FBCON_VGA_PLANES y
       else
 	 if [ "$CONFIG_FB_VGA16" = "m" ]; then
-	    define_bool CONFIG_FBCON_VGA_PLANES m
+	    define_tristate CONFIG_FBCON_VGA_PLANES m
 	 fi
       fi
       if [ "$CONFIG_FB_MDA" = "y" -o "$CONFIG_FB_VGA" = "y" ]; then
-	 define_bool CONFIG_FBCON_VGA y
+	 define_tristate CONFIG_FBCON_VGA y
       else
 	 if [ "$CONFIG_FB_MDA" = "m" -o "$CONFIG_FB_VGA" = "m" ]; then
-	    define_bool CONFIG_FBCON_VGA m
+	    define_tristate CONFIG_FBCON_VGA m
 	 fi
       fi
    fi
diff -u --recursive --new-file v2.3.25/linux/drivers/video/Makefile linux/drivers/video/Makefile
--- v2.3.25/linux/drivers/video/Makefile	Fri Oct 22 13:21:51 1999
+++ linux/drivers/video/Makefile	Tue Nov  2 08:15:05 1999
@@ -161,6 +161,10 @@
   endif
 endif
 
+ifeq ($(CONFIG_FB_RIVA),y)
+L_OBJS += rivafb.o riva_hw.o
+endif
+
 ifeq ($(CONFIG_FB_3DFX),y)
 L_OBJS += tdfxfb.o
 endif
diff -u --recursive --new-file v2.3.25/linux/drivers/video/atyfb.c linux/drivers/video/atyfb.c
--- v2.3.25/linux/drivers/video/atyfb.c	Fri Oct 22 13:21:51 1999
+++ linux/drivers/video/atyfb.c	Tue Nov  2 17:40:11 1999
@@ -3048,21 +3048,26 @@
 	struct fb_info_aty *fb = (struct fb_info_aty *)info;
 	unsigned int size, page, map_size = 0;
 	unsigned long map_offset = 0;
+	unsigned long off;
 	int i;
 
 	if (!fb->mmap_map)
 		return -ENXIO;
 
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+		return -EINVAL;
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
 	size = vma->vm_end - vma->vm_start;
-	if (vma->vm_offset & ~PAGE_MASK)
-		return -ENXIO;
 
 	/* To stop the swapper from even considering these pages. */
 	vma->vm_flags |= (VM_SHM | VM_LOCKED);
 
-	if (((vma->vm_offset == 0) && (size == fb->total_vram)) ||
-	    ((vma->vm_offset == fb->total_vram) && (size == PAGE_SIZE)))
-		vma->vm_offset += 0x8000000000000000UL;
+	if (((vma->vm_pgoff == 0) && (size == fb->total_vram)) ||
+	    ((off == fb->total_vram) && (size == PAGE_SIZE)))
+		off += 0x8000000000000000UL;
+
+	vma->vm_pgoff = off >> PAGE_SHIFT;	/* propagate off changes */
 
 #ifdef __sparc_v9__
 	/* Align it as much as desirable */
@@ -3070,9 +3075,9 @@
 		unsigned long j, align;
 		int max = -1;
 		
-		map_offset = vma->vm_offset+size;
+		map_offset = off + size;
 		for (i = 0; fb->mmap_map[i].size; i++) {
-			if (fb->mmap_map[i].voff < vma->vm_offset)
+			if (fb->mmap_map[i].voff < off)
 				continue;
 			if (fb->mmap_map[i].voff >= map_offset)
 				break;
@@ -3092,7 +3097,7 @@
 				j = align;
 				align = j - ((vma->vm_start
 					      + fb->mmap_map[max].voff
-					      - vma->vm_offset) & (j - 1));
+					      - off) & (j - 1));
 				if (align != j) {
 					struct vm_area_struct *vmm;
 
@@ -3115,7 +3120,7 @@
 		for (i = 0; fb->mmap_map[i].size; i++) {
 			unsigned long start = fb->mmap_map[i].voff;
 			unsigned long end = start + fb->mmap_map[i].size;
-			unsigned long offset = vma->vm_offset + page;
+			unsigned long offset = off + page;
 
 			if (start > offset)
 				continue;
diff -u --recursive --new-file v2.3.25/linux/drivers/video/fbmem.c linux/drivers/video/fbmem.c
--- v2.3.25/linux/drivers/video/fbmem.c	Mon Nov  1 13:56:27 1999
+++ linux/drivers/video/fbmem.c	Fri Nov  5 14:23:25 1999
@@ -102,6 +102,8 @@
 extern int q40fb_init(void);
 extern int sgivwfb_init(void);
 extern int sgivwfb_setup(char*);
+extern int rivafb_init(void);
+extern int rivafb_setup(char*);
 extern int tdfxfb_init(void);
 extern int tdfxfb_setup(char*);
 
@@ -176,6 +178,9 @@
 #ifdef CONFIG_FB_VIRGE
 	{ "virge", virgefb_init, virgefb_setup },
 #endif
+#ifdef CONFIG_FB_RIVA
+	{ "riva", rivafb_init, rivafb_setup },
+#endif
 #ifdef CONFIG_FB_VESA
 	{ "vesa", vesafb_init, vesafb_setup },
 #endif 
@@ -483,9 +488,12 @@
 	struct fb_ops *fb = info->fbops;
 	struct fb_fix_screeninfo fix;
 	struct fb_var_screeninfo var;
-	unsigned long start;
+	unsigned long start, off;
 	u32 len;
 
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+		return -EINVAL;
+	off = vma->vm_pgoff << PAGE_SHIFT;
 	if (!fb)
 		return -ENODEV;
 	if (fb->fb_mmap)
@@ -504,10 +512,10 @@
 	start = fix.smem_start;
 	len = (start & ~PAGE_MASK)+fix.smem_len;
 	start &= PAGE_MASK;
-	len = (len+~PAGE_MASK) & PAGE_MASK;
-	if (vma->vm_offset >= len) {
+	len = (len+~PAGE_MASK) & PAGE_MASK;		/* someone's on crack. */
+	if (off >= len) {
 		/* memory mapped io */
-		vma->vm_offset -= len;
+		off -= len;
 		fb->fb_get_var(&var, PROC_CONSOLE(info), info);
 		if (var.accel_flags)
 			return -EINVAL;
@@ -516,11 +524,10 @@
 		start &= PAGE_MASK;
 		len = (len+~PAGE_MASK) & PAGE_MASK;
 	}
-	if ((vma->vm_end - vma->vm_start + vma->vm_offset) > len)
+	if ((vma->vm_end - vma->vm_start + off) > len)
 		return -EINVAL;
-	vma->vm_offset += start;
-	if (vma->vm_offset & ~PAGE_MASK)
-		return -ENXIO;
+	off += start;
+	vma->vm_pgoff = off >> PAGE_SHIFT;
 #if defined(__mc68000__)
 	if (CPU_IS_020_OR_030)
 		pgprot_val(vma->vm_page_prot) |= _PAGE_NOCACHE030;
@@ -549,7 +556,7 @@
 #else
 #warning What do we have to do here??
 #endif
-	if (io_remap_page_range(vma->vm_start, vma->vm_offset,
+	if (io_remap_page_range(vma->vm_start, off,
 			     vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;
 	return 0;
diff -u --recursive --new-file v2.3.25/linux/drivers/video/igafb.c linux/drivers/video/igafb.c
--- v2.3.25/linux/drivers/video/igafb.c	Thu Aug 26 13:05:40 1999
+++ linux/drivers/video/igafb.c	Tue Nov  2 17:40:11 1999
@@ -261,8 +261,6 @@
 		return -ENXIO;
 
 	size = vma->vm_end - vma->vm_start;
-	if (vma->vm_offset & ~PAGE_MASK)
-		return -ENXIO;
 
 	/* To stop the swapper from even considering these pages. */
 	vma->vm_flags |= (VM_SHM | VM_LOCKED);
@@ -271,17 +269,17 @@
 	for (page = 0; page < size; ) {
 		map_size = 0;
 		for (i = 0; fb->mmap_map[i].size; i++) {
-			unsigned long start = fb->mmap_map[i].voff;
-			unsigned long end = start + fb->mmap_map[i].size;
-			unsigned long offset = vma->vm_offset + page;
+			unsigned long start = (fb->mmap_map[i].voff) >> PAGE_SHIFT;
+			unsigned long end = start + (fb->mmap_map[i].size) >> PAGE_SHIFT;
+			unsigned long offset = vma->vm_pgoff + (page >> PAGE_SHIFT);
 
 			if (start > offset)
 				continue;
 			if (offset >= end)
 				continue;
 
-			map_size = fb->mmap_map[i].size - (offset - start);
-			map_offset = fb->mmap_map[i].poff + (offset - start);
+			map_size = fb->mmap_map[i].size - ((offset - start) << PAGE_SHIFT);
+			map_offset = fb->mmap_map[i].poff + ((offset - start) << PAGE_SHIFT);
 			break;
 		}
 		if (!map_size) {
diff -u --recursive --new-file v2.3.25/linux/drivers/video/nv4ref.h linux/drivers/video/nv4ref.h
--- v2.3.25/linux/drivers/video/nv4ref.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/nv4ref.h	Tue Nov  2 08:15:05 1999
@@ -0,0 +1,2445 @@
+ /***************************************************************************\
+|*                                                                           *|
+|*       Copyright 1993-1998 NVIDIA, Corporation.  All rights reserved.      *|
+|*                                                                           *|
+|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
+|*     international laws.  Users and possessors of this source code are     *|
+|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
+|*     use this code in individual and commercial software.                  *|
+|*                                                                           *|
+|*     Any use of this source code must include,  in the user documenta-     *|
+|*     tion and  internal comments to the code,  notices to the end user     *|
+|*     as follows:                                                           *|
+|*                                                                           *|
+|*       Copyright 1993-1998 NVIDIA, Corporation.  All rights reserved.      *|
+|*                                                                           *|
+|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
+|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
+|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
+|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
+|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
+|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
+|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
+|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
+|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
+|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
+|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
+|*                                                                           *|
+|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
+|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
+|*     consisting  of "commercial  computer  software"  and  "commercial     *|
+|*     computer  software  documentation,"  as such  terms  are  used in     *|
+|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
+|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
+|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
+|*     all U.S. Government End Users  acquire the source code  with only     *|
+|*     those rights set forth herein.                                        *|
+|*                                                                           *|
+ \***************************************************************************/
+
+/*
+ * GPL licensing note -- nVidia is allowing a liberal interpretation of
+ * the documentation restriction above, to merely say that this nVidia's
+ * copyright and disclaimer should be included with all code derived
+ * from this source.  -- Jeff Garzik <jgarzik@mandrakesoft.com>, 01/Nov/99 
+ */
+
+ /***************************************************************************\
+|*            Modified 1999 by Fredrik Reite (fredrik@reite.com)             *|
+ \***************************************************************************/
+
+
+#ifndef __NV4REF_H__
+#define __NV4REF_H__
+
+/* Magic values to lock/unlock extended regs */
+#define NV_CIO_SR_LOCK_INDEX				     0x0000001F /*       */
+#define NV_CIO_SR_UNLOCK_RW_VALUE                            0x00000057 /*       */
+#define NV_CIO_SR_UNLOCK_RO_VALUE                            0x00000075 /*       */
+#define NV_CIO_SR_LOCK_VALUE                                 0x00000099 /*       */
+
+#define UNLOCK_EXT_MAGIC 0x57
+#define LOCK_EXT_MAGIC 0x99 /* Any value other than 0x57 will do */
+
+#define LOCK_EXT_INDEX 0x6
+
+#define NV_PCRTC_HORIZ_TOTAL                                 0x00
+#define NV_PCRTC_HORIZ_DISPLAY_END                           0x01
+#define NV_PCRTC_HORIZ_BLANK_START                           0x02
+
+#define NV_PCRTC_HORIZ_BLANK_END                             0x03
+#define NV_PCRTC_HORIZ_BLANK_END_EVRA                        7:7
+#define NV_PCRTC_HORIZ_BLANK_END_DISPLAY_END_SKEW            6:5
+#define NV_PCRTC_HORIZ_BLANK_END_HORIZ_BLANK_END             4:0
+
+#define NV_PCRTC_HORIZ_RETRACE_START                         0x04
+
+#define NV_PCRTC_HORIZ_RETRACE_END                           0x05
+#define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_BLANK_END_5         7:7
+#define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_RETRACE_SKEW        6:5
+#define NV_PCRTC_HORIZ_RETRACE_END_HORIZ_RETRACE_END         4:0
+
+#define NV_PCRTC_VERT_TOTAL                                  0x06
+
+#define NV_PCRTC_OVERFLOW                                    0x07
+#define NV_PCRTC_OVERFLOW_VERT_RETRACE_START_9               7:7
+#define NV_PCRTC_OVERFLOW_VERT_DISPLAY_END_9                 6:6
+#define NV_PCRTC_OVERFLOW_VERT_TOTAL_9                       5:5
+#define NV_PCRTC_OVERFLOW_LINE_COMPARE_8                     4:4
+#define NV_PCRTC_OVERFLOW_VERT_BLANK_START_8                 3:3
+#define NV_PCRTC_OVERFLOW_VERT_RETRACE_START_8               2:2
+#define NV_PCRTC_OVERFLOW_VERT_DISPLAY_END_8                 1:1
+#define NV_PCRTC_OVERFLOW_VERT_TOTAL_8                       0:0
+
+#define NV_PCRTC_PRESET_ROW_SCAN                             0x08
+
+#define NV_PCRTC_MAX_SCAN_LINE                               0x09
+#define NV_PCRTC_MAX_SCAN_LINE_DOUBLE_SCAN                   7:7
+#define NV_PCRTC_MAX_SCAN_LINE_LINE_COMPARE_9                6:6
+#define NV_PCRTC_MAX_SCAN_LINE_VERT_BLANK_START_9            5:5
+#define NV_PCRTC_MAX_SCAN_LINE_MAX_SCAN_LINE                 4:0
+
+#define NV_PCRTC_CURSOR_START                                0x0A
+#define NV_PCRTC_CURSOR_END                                  0x0B
+#define NV_PCRTC_START_ADDR_HIGH                             0x0C
+#define NV_PCRTC_START_ADDR_LOW                              0x0D
+#define NV_PCRTC_CURSOR_LOCATION_HIGH                        0x0E
+#define NV_PCRTC_CURSOR_LOCATION_LOW                         0x0F
+
+#define NV_PCRTC_VERT_RETRACE_START                          0x10
+#define NV_PCRTC_VERT_RETRACE_END                            0x11
+#define NV_PCRTC_VERT_DISPLAY_END                            0x12
+#define NV_PCRTC_OFFSET                                      0x13
+#define NV_PCRTC_UNDERLINE_LOCATION                          0x14
+#define NV_PCRTC_VERT_BLANK_START                            0x15
+#define NV_PCRTC_VERT_BLANK_END                              0x16
+#define NV_PCRTC_MODE_CONTROL                                0x17
+#define NV_PCRTC_LINE_COMPARE                                0x18
+
+/* Extended offset and start address */
+#define NV_PCRTC_REPAINT0                                    0x19
+#define NV_PCRTC_REPAINT0_OFFSET_10_8                        7:5 
+#define NV_PCRTC_REPAINT0_START_ADDR_20_16                   4:0
+
+/* Horizonal extended bits */
+#define NV_PCRTC_HORIZ_EXTRA                                 0x2d
+#define NV_PCRTC_HORIZ_EXTRA_INTER_HALF_START_8              4:4
+#define NV_PCRTC_HORIZ_EXTRA_HORIZ_RETRACE_START_8           3:3
+#define NV_PCRTC_HORIZ_EXTRA_HORIZ_BLANK_START_8             2:2
+#define NV_PCRTC_HORIZ_EXTRA_DISPLAY_END_8                   1:1
+#define NV_PCRTC_HORIZ_EXTRA_DISPLAY_TOTAL_8                 0:0
+
+/* Assorted extra bits */
+#define NV_PCRTC_EXTRA                                       0x25
+#define NV_PCRTC_EXTRA_OFFSET_11                             5:5
+#define NV_PCRTC_EXTRA_HORIZ_BLANK_END_6                     4:4
+#define NV_PCRTC_EXTRA_VERT_BLANK_START_10                   3:3
+#define NV_PCRTC_EXTRA_VERT_RETRACE_START_10                 2:2
+#define NV_PCRTC_EXTRA_VERT_DISPLAY_END_10                   1:1
+#define NV_PCRTC_EXTRA_VERT_TOTAL_10                         0:0
+
+/* Controls how much data the refresh fifo requests */
+#define NV_PCRTC_FIFO_CONTROL                                0x1b
+#define NV_PCRTC_FIFO_CONTROL_UNDERFLOW_WARN                 7:7
+#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH                   2:0
+#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_8                 0x0
+#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_32                0x1
+#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_64                0x2
+#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_128               0x3
+#define NV_PCRTC_FIFO_CONTROL_BURST_LENGTH_256               0x4
+
+/* When the fifo occupancy falls below *twice* the watermark,
+ * the refresh fifo will start to be refilled. If this value is 
+ * too low, you will get junk on the screen. Too high, and performance
+ * will suffer. Watermark in units of 8 bytes
+ */
+#define NV_PCRTC_FIFO                                        0x20
+#define NV_PCRTC_FIFO_RESET                                  7:7
+#define NV_PCRTC_FIFO_WATERMARK                              5:0
+
+/* Various flags */
+#define NV_PCRTC_REPAINT1                                    0x1a
+#define NV_PCRTC_REPAINT1_HSYNC                              7:7
+#define NV_PCRTC_REPAINT1_HYSNC_DISABLE                      0x01
+#define NV_PCRTC_REPAINT1_HYSNC_ENABLE                       0x00
+#define NV_PCRTC_REPAINT1_VSYNC                              6:6
+#define NV_PCRTC_REPAINT1_VYSNC_DISABLE                      0x01
+#define NV_PCRTC_REPAINT1_VYSNC_ENABLE                       0x00
+#define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT                    4:4
+#define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT_ENABLE             0x01
+#define NV_PCRTC_REPAINT1_COMPATIBLE_TEXT_DISABLE            0x00
+#define NV_PCRTC_REPAINT1_LARGE_SCREEN                       2:2 
+#define NV_PCRTC_REPAINT1_LARGE_SCREEN_DISABLE               0x01
+#define NV_PCRTC_REPAINT1_LARGE_SCREEN_ENABLE                0x00 /* >=1280 */
+#define NV_PCRTC_REPAINT1_PALETTE_WIDTH                      1:1
+#define NV_PCRTC_REPAINT1_PALETTE_WIDTH_8BITS                0x00
+#define NV_PCRTC_REPAINT1_PALETTE_WIDTH_6BITS                0x01
+
+#define NV_PCRTC_GRCURSOR0                                   0x30
+#define NV_PCRTC_GRCURSOR0_START_ADDR_21_16                  5:0
+
+#define NV_PCRTC_GRCURSOR1                                   0x31
+#define NV_PCRTC_GRCURSOR1_START_ADDR_15_11                  7:3
+#define NV_PCRTC_GRCURSOR1_SCAN_DBL                          1:1
+#define NV_PCRTC_GRCURSOR1_SCAN_DBL_DISABLE                  0
+#define NV_PCRTC_GRCURSOR1_SCAN_DBL_ENABLE                   1
+#define NV_PCRTC_GRCURSOR1_CURSOR                            0:0
+#define NV_PCRTC_GRCURSOR1_CURSOR_DISABLE                    0 
+#define NV_PCRTC_GRCURSOR1_CURSOR_ENABLE                     1
+
+/* Controls what the format of the framebuffer is */
+#define NV_PCRTC_PIXEL                       0x28
+#define NV_PCRTC_PIXEL_MODE                  7:7
+#define NV_PCRTC_PIXEL_MODE_TV               0x01
+#define NV_PCRTC_PIXEL_MODE_VGA              0x00
+#define NV_PCRTC_PIXEL_TV_MODE               6:6
+#define NV_PCRTC_PIXEL_TV_MODE_NTSC          0x00
+#define NV_PCRTC_PIXEL_TV_MODE_PAL           0x01
+#define NV_PCRTC_PIXEL_TV_HORIZ_ADJUST       5:3
+#define NV_PCRTC_PIXEL_FORMAT                1:0
+#define NV_PCRTC_PIXEL_FORMAT_VGA            0x00
+#define NV_PCRTC_PIXEL_FORMAT_8BPP           0x01
+#define NV_PCRTC_PIXEL_FORMAT_16BPP          0x02
+#define NV_PCRTC_PIXEL_FORMAT_32BPP          0x03
+
+/* RAMDAC registers and fields */
+#define NV_PRAMDAC                            0x00680FFF:0x00680000 /* RW--D */
+#define NV_PRAMDAC_GRCURSOR_START_POS                    0x00680300 /* RW-4R */
+#define NV_PRAMDAC_GRCURSOR_START_POS_X                        11:0 /* RWXSF */
+#define NV_PRAMDAC_GRCURSOR_START_POS_Y                       27:16 /* RWXSF */
+#define NV_PRAMDAC_NVPLL_COEFF                           0x00680500 /* RW-4R */
+#define NV_PRAMDAC_NVPLL_COEFF_MDIV                             7:0 /* RWIUF */
+#define NV_PRAMDAC_NVPLL_COEFF_NDIV                            15:8 /* RWIUF */
+#define NV_PRAMDAC_NVPLL_COEFF_PDIV                           18:16 /* RWIVF */
+#define NV_PRAMDAC_MPLL_COEFF                            0x00680504 /* RW-4R */
+#define NV_PRAMDAC_MPLL_COEFF_MDIV                              7:0 /* RWIUF */
+#define NV_PRAMDAC_MPLL_COEFF_NDIV                             15:8 /* RWIUF */
+#define NV_PRAMDAC_MPLL_COEFF_PDIV                            18:16 /* RWIVF */
+#define NV_PRAMDAC_VPLL_COEFF                            0x00680508 /* RW-4R */
+#define NV_PRAMDAC_VPLL_COEFF_MDIV                              7:0 /* RWIUF */
+#define NV_PRAMDAC_VPLL_COEFF_NDIV                             15:8 /* RWIUF */
+#define NV_PRAMDAC_VPLL_COEFF_PDIV                            18:16 /* RWIVF */
+#define NV_PRAMDAC_PLL_COEFF_SELECT                      0x0068050C /* RW-4R */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS                  4:4 /* RWIVF */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS_FALSE     0x00000000 /* RWI-V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_DLL_BYPASS_TRUE      0x00000001 /* RW--V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE                 8:8 /* RWIVF */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE_DEFAULT  0x00000000 /* RWI-V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_SOURCE_PROG     0x00000001 /* RW--V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS               12:12 /* RWIVF */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS_FALSE    0x00000000 /* RWI-V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_MPLL_BYPASS_TRUE     0x00000001 /* RW--V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE               16:16 /* RWIVF */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE_DEFAULT  0x00000000 /* RWI-V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_SOURCE_PROG     0x00000001 /* RW--V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS               20:20 /* RWIVF */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS_FALSE    0x00000000 /* RWI-V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_VPLL_BYPASS_TRUE     0x00000001 /* RW--V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE               25:24 /* RWIVF */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_VPLL     0x00000000 /* RWI-V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_VIP      0x00000001 /* RW--V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_PCLK_SOURCE_XTALOSC  0x00000002 /* RW--V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO                28:28 /* RWIVF */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB1       0x00000000 /* RWI-V */
+#define NV_PRAMDAC_PLL_COEFF_SELECT_VCLK_RATIO_DB2       0x00000001 /* RW--V */
+#define NV_PRAMDAC_GENERAL_CONTROL                       0x00680600 /* RW-4R */
+#define NV_PRAMDAC_GENERAL_CONTROL_FF_COEFF                     1:0 /* RWIVF */
+#define NV_PRAMDAC_GENERAL_CONTROL_FF_COEFF_DEF          0x00000000 /* RWI-V */
+#define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE                     4:4 /* RWIVF */
+#define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE_GAMMA        0x00000000 /* RWI-V */
+#define NV_PRAMDAC_GENERAL_CONTROL_IDC_MODE_INDEX        0x00000001 /* RW--V */
+#define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE                    8:8 /* RWIVF */
+#define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_NOTSE       0x00000000 /* RWI-V */
+#define NV_PRAMDAC_GENERAL_CONTROL_VGA_STATE_SEL         0x00000001 /* RW--V */
+#define NV_PRAMDAC_GENERAL_CONTROL_565_MODE                   12:12 /* RWIVF */
+#define NV_PRAMDAC_GENERAL_CONTROL_565_MODE_NOTSEL       0x00000000 /* RWI-V */
+#define NV_PRAMDAC_GENERAL_CONTROL_565_MODE_SEL          0x00000001 /* RW--V */
+#define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL                 16:16 /* RWIVF */
+#define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL_OFF        0x00000000 /* RWI-V */
+#define NV_PRAMDAC_GENERAL_CONTROL_BLK_PEDSTL_ON         0x00000001 /* RW--V */
+#define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION                17:17 /* RWIVF */
+#define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_37OHM     0x00000000 /* RWI-V */
+#define NV_PRAMDAC_GENERAL_CONTROL_TERMINATION_75OHM     0x00000001 /* RW--V */
+#define NV_PRAMDAC_GENERAL_CONTROL_BPC                        20:20 /* RWIVF */
+#define NV_PRAMDAC_GENERAL_CONTROL_BPC_6BITS             0x00000000 /* RWI-V */
+#define NV_PRAMDAC_GENERAL_CONTROL_BPC_8BITS             0x00000001 /* RW--V */
+#define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP                  24:24 /* RWIVF */
+#define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP_DIS         0x00000000 /* RWI-V */
+#define NV_PRAMDAC_GENERAL_CONTROL_DAC_SLEEP_EN          0x00000001 /* RW--V */
+#define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK                28:28 /* RWIVF */
+#define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK_EN        0x00000000 /* RWI-V */
+#define NV_PRAMDAC_GENERAL_CONTROL_PALETTE_CLK_DIS       0x00000001 /* RW--V */
+
+/* Master Control */
+#define NV_PMC                                0x00000FFF:0x00000000 /* RW--D */
+#define NV_PMC_BOOT_0                                    0x00000000 /* R--4R */
+#define NV_PMC_BOOT_0_MINOR_REVISION                            3:0 /* C--VF */
+#define NV_PMC_BOOT_0_MINOR_REVISION_0                   0x00000000 /* C---V */
+#define NV_PMC_BOOT_0_MAJOR_REVISION                            7:4 /* C--VF */
+#define NV_PMC_BOOT_0_MAJOR_REVISION_A                   0x00000000 /* C---V */
+#define NV_PMC_BOOT_0_MAJOR_REVISION_B                   0x00000001 /* ----V */
+#define NV_PMC_BOOT_0_IMPLEMENTATION                           11:8 /* C--VF */
+#define NV_PMC_BOOT_0_IMPLEMENTATION_NV4_0               0x00000000 /* C---V */
+#define NV_PMC_BOOT_0_ARCHITECTURE                            15:12 /* C--VF */
+#define NV_PMC_BOOT_0_ARCHITECTURE_NV0                   0x00000000 /* ----V */
+#define NV_PMC_BOOT_0_ARCHITECTURE_NV1                   0x00000001 /* ----V */
+#define NV_PMC_BOOT_0_ARCHITECTURE_NV2                   0x00000002 /* ----V */
+#define NV_PMC_BOOT_0_ARCHITECTURE_NV3                   0x00000003 /* ----V */
+#define NV_PMC_BOOT_0_ARCHITECTURE_NV4                   0x00000004 /* C---V */
+#define NV_PMC_BOOT_0_FIB_REVISION                            19:16 /* C--VF */
+#define NV_PMC_BOOT_0_FIB_REVISION_0                     0x00000000 /* C---V */
+#define NV_PMC_BOOT_0_MASK_REVISION                           23:20 /* C--VF */
+#define NV_PMC_BOOT_0_MASK_REVISION_A                    0x00000000 /* C---V */
+#define NV_PMC_BOOT_0_MASK_REVISION_B                    0x00000001 /* ----V */
+#define NV_PMC_BOOT_0_MANUFACTURER                            27:24 /* C--UF */
+#define NV_PMC_BOOT_0_MANUFACTURER_NVIDIA                0x00000000 /* C---V */
+#define NV_PMC_BOOT_0_FOUNDRY                                 31:28 /* C--VF */
+#define NV_PMC_BOOT_0_FOUNDRY_SGS                        0x00000000 /* ----V */
+#define NV_PMC_BOOT_0_FOUNDRY_HELIOS                     0x00000001 /* ----V */
+#define NV_PMC_BOOT_0_FOUNDRY_TSMC                       0x00000002 /* C---V */
+#define NV_PMC_INTR_0                                    0x00000100 /* RW-4R */
+#define NV_PMC_INTR_0_PMEDIA                                    4:4 /* R--VF */
+#define NV_PMC_INTR_0_PMEDIA_NOT_PENDING                 0x00000000 /* R---V */
+#define NV_PMC_INTR_0_PMEDIA_PENDING                     0x00000001 /* R---V */
+#define NV_PMC_INTR_0_PFIFO                                     8:8 /* R--VF */
+#define NV_PMC_INTR_0_PFIFO_NOT_PENDING                  0x00000000 /* R---V */
+#define NV_PMC_INTR_0_PFIFO_PENDING                      0x00000001 /* R---V */
+#define NV_PMC_INTR_0_PGRAPH                                  12:12 /* R--VF */
+#define NV_PMC_INTR_0_PGRAPH_NOT_PENDING                 0x00000000 /* R---V */
+#define NV_PMC_INTR_0_PGRAPH_PENDING                     0x00000001 /* R---V */
+#define NV_PMC_INTR_0_PVIDEO                                  16:16 /* R--VF */
+#define NV_PMC_INTR_0_PVIDEO_NOT_PENDING                 0x00000000 /* R---V */
+#define NV_PMC_INTR_0_PVIDEO_PENDING                     0x00000001 /* R---V */
+#define NV_PMC_INTR_0_PTIMER                                  20:20 /* R--VF */
+#define NV_PMC_INTR_0_PTIMER_NOT_PENDING                 0x00000000 /* R---V */
+#define NV_PMC_INTR_0_PTIMER_PENDING                     0x00000001 /* R---V */
+#define NV_PMC_INTR_0_PCRTC                                   24:24 /* R--VF */
+#define NV_PMC_INTR_0_PCRTC_NOT_PENDING                  0x00000000 /* R---V */
+#define NV_PMC_INTR_0_PCRTC_PENDING                      0x00000001 /* R---V */
+#define NV_PMC_INTR_0_PBUS                                    28:28 /* R--VF */
+#define NV_PMC_INTR_0_PBUS_NOT_PENDING                   0x00000000 /* R---V */
+#define NV_PMC_INTR_0_PBUS_PENDING                       0x00000001 /* R---V */
+#define NV_PMC_INTR_0_SOFTWARE                                31:31 /* RWIVF */
+#define NV_PMC_INTR_0_SOFTWARE_NOT_PENDING               0x00000000 /* RWI-V */
+#define NV_PMC_INTR_0_SOFTWARE_PENDING                   0x00000001 /* RW--V */
+#define NV_PMC_INTR_EN_0                                 0x00000140 /* RW-4R */
+#define NV_PMC_INTR_EN_0_INTA                                   1:0 /* RWIVF */
+#define NV_PMC_INTR_EN_0_INTA_DISABLED                   0x00000000 /* RWI-V */
+#define NV_PMC_INTR_EN_0_INTA_HARDWARE                   0x00000001 /* RW--V */
+#define NV_PMC_INTR_EN_0_INTA_SOFTWARE                   0x00000002 /* RW--V */
+#define NV_PMC_INTR_READ_0                               0x00000160 /* R--4R */
+#define NV_PMC_INTR_READ_0_INTA                                 0:0 /* R--VF */
+#define NV_PMC_INTR_READ_0_INTA_LOW                      0x00000000 /* R---V */
+#define NV_PMC_INTR_READ_0_INTA_HIGH                     0x00000001 /* R---V */
+#define NV_PMC_ENABLE                                    0x00000200 /* RW-4R */
+#define NV_PMC_ENABLE_PMEDIA                                    4:4 /* RWIVF */
+#define NV_PMC_ENABLE_PMEDIA_DISABLED                    0x00000000 /* RWI-V */
+#define NV_PMC_ENABLE_PMEDIA_ENABLED                     0x00000001 /* RW--V */
+#define NV_PMC_ENABLE_PFIFO                                     8:8 /* RWIVF */
+#define NV_PMC_ENABLE_PFIFO_DISABLED                     0x00000000 /* RWI-V */
+#define NV_PMC_ENABLE_PFIFO_ENABLED                      0x00000001 /* RW--V */
+#define NV_PMC_ENABLE_PGRAPH                                  12:12 /* RWIVF */
+#define NV_PMC_ENABLE_PGRAPH_DISABLED                    0x00000000 /* RWI-V */
+#define NV_PMC_ENABLE_PGRAPH_ENABLED                     0x00000001 /* RW--V */
+#define NV_PMC_ENABLE_PPMI                                    16:16 /* RWIVF */
+#define NV_PMC_ENABLE_PPMI_DISABLED                      0x00000000 /* RWI-V */
+#define NV_PMC_ENABLE_PPMI_ENABLED                       0x00000001 /* RW--V */
+#define NV_PMC_ENABLE_PFB                                     20:20 /* RWIVF */
+#define NV_PMC_ENABLE_PFB_DISABLED                       0x00000000 /* RW--V */
+#define NV_PMC_ENABLE_PFB_ENABLED                        0x00000001 /* RWI-V */
+#define NV_PMC_ENABLE_PCRTC                                   24:24 /* RWIVF */
+#define NV_PMC_ENABLE_PCRTC_DISABLED                     0x00000000 /* RW--V */
+#define NV_PMC_ENABLE_PCRTC_ENABLED                      0x00000001 /* RWI-V */
+#define NV_PMC_ENABLE_PVIDEO                                  28:28 /* RWIVF */
+#define NV_PMC_ENABLE_PVIDEO_DISABLED                    0x00000000 /* RWI-V */
+#define NV_PMC_ENABLE_PVIDEO_ENABLED                     0x00000001 /* RW--V */
+
+/* dev_timer.ref */
+#define NV_PTIMER                             0x00009FFF:0x00009000 /* RW--D */
+#define NV_PTIMER_INTR_0                                 0x00009100 /* RW-4R */
+#define NV_PTIMER_INTR_0_ALARM                                  0:0 /* RWXVF */
+#define NV_PTIMER_INTR_0_ALARM_NOT_PENDING               0x00000000 /* R---V */
+#define NV_PTIMER_INTR_0_ALARM_PENDING                   0x00000001 /* R---V */
+#define NV_PTIMER_INTR_0_ALARM_RESET                     0x00000001 /* -W--V */
+#define NV_PTIMER_INTR_EN_0                              0x00009140 /* RW-4R */
+#define NV_PTIMER_INTR_EN_0_ALARM                               0:0 /* RWIVF */
+#define NV_PTIMER_INTR_EN_0_ALARM_DISABLED               0x00000000 /* RWI-V */
+#define NV_PTIMER_INTR_EN_0_ALARM_ENABLED                0x00000001 /* RW--V */
+#define NV_PTIMER_NUMERATOR                              0x00009200 /* RW-4R */
+#define NV_PTIMER_NUMERATOR_VALUE                              15:0 /* RWIUF */
+#define NV_PTIMER_NUMERATOR_VALUE_0                      0x00000000 /* RWI-V */
+#define NV_PTIMER_DENOMINATOR                            0x00009210 /* RW-4R */
+#define NV_PTIMER_DENOMINATOR_VALUE                            15:0 /* RWIUF */
+#define NV_PTIMER_DENOMINATOR_VALUE_0                    0x00000000 /* RWI-V */
+#define NV_PTIMER_TIME_0                                 0x00009400 /* RW-4R */
+#define NV_PTIMER_TIME_0_NSEC                                  31:5 /* RWXUF */
+#define NV_PTIMER_TIME_1                                 0x00009410 /* RW-4R */
+#define NV_PTIMER_TIME_1_NSEC                                  28:0 /* RWXUF */
+#define NV_PTIMER_ALARM_0                                0x00009420 /* RW-4R */
+#define NV_PTIMER_ALARM_0_NSEC                                 31:5 /* RWXUF */
+
+/* dev_fifo.ref */
+#define NV_PFIFO                              0x00003FFF:0x00002000 /* RW--D */
+#define NV_PFIFO_DELAY_0                                 0x00002040 /* RW-4R */
+#define NV_PFIFO_DELAY_0_WAIT_RETRY                             9:0 /* RWIUF */
+#define NV_PFIFO_DELAY_0_WAIT_RETRY_0                    0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_TIMESLICE                           0x00002044 /* RW-4R */
+#define NV_PFIFO_DMA_TIMESLICE_SELECT                          16:0 /* RWIUF */
+#define NV_PFIFO_DMA_TIMESLICE_SELECT_1                  0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_TIMESLICE_SELECT_16K                0x00003fff /* RW--V */
+#define NV_PFIFO_DMA_TIMESLICE_SELECT_32K                0x00007fff /* RW--V */
+#define NV_PFIFO_DMA_TIMESLICE_SELECT_64K                0x0000ffff /* RW--V */
+#define NV_PFIFO_DMA_TIMESLICE_SELECT_128K               0x0001ffff /* RW--V */
+#define NV_PFIFO_DMA_TIMESLICE_TIMEOUT                        24:24 /* RWIUF */
+#define NV_PFIFO_DMA_TIMESLICE_TIMEOUT_DISABLED          0x00000000 /* RW--V */
+#define NV_PFIFO_DMA_TIMESLICE_TIMEOUT_ENABLED           0x00000001 /* RWI-V */
+#define NV_PFIFO_PIO_TIMESLICE                           0x00002048 /* RW-4R */
+#define NV_PFIFO_PIO_TIMESLICE_SELECT                          16:0 /* RWIUF */
+#define NV_PFIFO_PIO_TIMESLICE_SELECT_1                  0x00000000 /* RWI-V */
+#define NV_PFIFO_PIO_TIMESLICE_SELECT_16K                0x00003fff /* RW--V */
+#define NV_PFIFO_PIO_TIMESLICE_SELECT_32K                0x00007fff /* RW--V */
+#define NV_PFIFO_PIO_TIMESLICE_SELECT_64K                0x0000ffff /* RW--V */
+#define NV_PFIFO_PIO_TIMESLICE_SELECT_128K               0x0001ffff /* RW--V */
+#define NV_PFIFO_PIO_TIMESLICE_TIMEOUT                        24:24 /* RWIUF */
+#define NV_PFIFO_PIO_TIMESLICE_TIMEOUT_DISABLED          0x00000000 /* RW--V */
+#define NV_PFIFO_PIO_TIMESLICE_TIMEOUT_ENABLED           0x00000001 /* RWI-V */
+#define NV_PFIFO_TIMESLICE                               0x0000204C /* RW-4R */
+#define NV_PFIFO_TIMESLICE_TIMER                               17:0 /* RWIUF */
+#define NV_PFIFO_TIMESLICE_TIMER_EXPIRED                 0x0003FFFF /* RWI-V */
+#define NV_PFIFO_NEXT_CHANNEL                            0x00002050 /* RW-4R */
+#define NV_PFIFO_NEXT_CHANNEL_CHID                              3:0 /* RWXUF */
+#define NV_PFIFO_NEXT_CHANNEL_MODE                              8:8 /* RWXVF */
+#define NV_PFIFO_NEXT_CHANNEL_MODE_PIO                   0x00000000 /* RW--V */
+#define NV_PFIFO_NEXT_CHANNEL_MODE_DMA                   0x00000001 /* RW--V */
+#define NV_PFIFO_NEXT_CHANNEL_SWITCH                          12:12 /* RWIVF */
+#define NV_PFIFO_NEXT_CHANNEL_SWITCH_NOT_PENDING         0x00000000 /* RWI-V */
+#define NV_PFIFO_NEXT_CHANNEL_SWITCH_PENDING             0x00000001 /* RW--V */
+#define NV_PFIFO_DEBUG_0                                 0x00002080 /* R--4R */
+#define NV_PFIFO_DEBUG_0_CACHE_ERROR0                           0:0 /* R-XVF */
+#define NV_PFIFO_DEBUG_0_CACHE_ERROR0_NOT_PENDING        0x00000000 /* R---V */
+#define NV_PFIFO_DEBUG_0_CACHE_ERROR0_PENDING            0x00000001 /* R---V */
+#define NV_PFIFO_DEBUG_0_CACHE_ERROR1                           4:4 /* R-XVF */
+#define NV_PFIFO_DEBUG_0_CACHE_ERROR1_NOT_PENDING        0x00000000 /* R---V */
+#define NV_PFIFO_DEBUG_0_CACHE_ERROR1_PENDING            0x00000001 /* R---V */
+#define NV_PFIFO_INTR_0                                  0x00002100 /* RW-4R */
+#define NV_PFIFO_INTR_0_CACHE_ERROR                             0:0 /* RWXVF */
+#define NV_PFIFO_INTR_0_CACHE_ERROR_NOT_PENDING          0x00000000 /* R---V */
+#define NV_PFIFO_INTR_0_CACHE_ERROR_PENDING              0x00000001 /* R---V */
+#define NV_PFIFO_INTR_0_CACHE_ERROR_RESET                0x00000001 /* -W--V */
+#define NV_PFIFO_INTR_0_RUNOUT                                  4:4 /* RWXVF */
+#define NV_PFIFO_INTR_0_RUNOUT_NOT_PENDING               0x00000000 /* R---V */
+#define NV_PFIFO_INTR_0_RUNOUT_PENDING                   0x00000001 /* R---V */
+#define NV_PFIFO_INTR_0_RUNOUT_RESET                     0x00000001 /* -W--V */
+#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW                         8:8 /* RWXVF */
+#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_NOT_PENDING      0x00000000 /* R---V */
+#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_PENDING          0x00000001 /* R---V */
+#define NV_PFIFO_INTR_0_RUNOUT_OVERFLOW_RESET            0x00000001 /* -W--V */
+#define NV_PFIFO_INTR_0_DMA_PUSHER                            12:12 /* RWXVF */
+#define NV_PFIFO_INTR_0_DMA_PUSHER_NOT_PENDING           0x00000000 /* R---V */
+#define NV_PFIFO_INTR_0_DMA_PUSHER_PENDING               0x00000001 /* R---V */
+#define NV_PFIFO_INTR_0_DMA_PUSHER_RESET                 0x00000001 /* -W--V */
+#define NV_PFIFO_INTR_0_DMA_PT                                16:16 /* RWXVF */
+#define NV_PFIFO_INTR_0_DMA_PT_NOT_PENDING               0x00000000 /* R---V */
+#define NV_PFIFO_INTR_0_DMA_PT_PENDING                   0x00000001 /* R---V */
+#define NV_PFIFO_INTR_0_DMA_PT_RESET                     0x00000001 /* -W--V */
+#define NV_PFIFO_INTR_EN_0                               0x00002140 /* RW-4R */
+#define NV_PFIFO_INTR_EN_0_CACHE_ERROR                          0:0 /* RWIVF */
+#define NV_PFIFO_INTR_EN_0_CACHE_ERROR_DISABLED          0x00000000 /* RWI-V */
+#define NV_PFIFO_INTR_EN_0_CACHE_ERROR_ENABLED           0x00000001 /* RW--V */
+#define NV_PFIFO_INTR_EN_0_RUNOUT                               4:4 /* RWIVF */
+#define NV_PFIFO_INTR_EN_0_RUNOUT_DISABLED               0x00000000 /* RWI-V */
+#define NV_PFIFO_INTR_EN_0_RUNOUT_ENABLED                0x00000001 /* RW--V */
+#define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW                      8:8 /* RWIVF */
+#define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW_DISABLED      0x00000000 /* RWI-V */
+#define NV_PFIFO_INTR_EN_0_RUNOUT_OVERFLOW_ENABLED       0x00000001 /* RW--V */
+#define NV_PFIFO_INTR_EN_0_DMA_PUSHER                         12:12 /* RWIVF */
+#define NV_PFIFO_INTR_EN_0_DMA_PUSHER_DISABLED           0x00000000 /* RWI-V */
+#define NV_PFIFO_INTR_EN_0_DMA_PUSHER_ENABLED            0x00000001 /* RW--V */
+#define NV_PFIFO_INTR_EN_0_DMA_PT                             16:16 /* RWIVF */
+#define NV_PFIFO_INTR_EN_0_DMA_PT_DISABLED               0x00000000 /* RWI-V */
+#define NV_PFIFO_INTR_EN_0_DMA_PT_ENABLED                0x00000001 /* RW--V */
+#define NV_PFIFO_RAMHT                                   0x00002210 /* RW-4R */
+#define NV_PFIFO_RAMHT_BASE_ADDRESS                             8:4 /* RWIUF */
+#define NV_PFIFO_RAMHT_BASE_ADDRESS_10000                0x00000010 /* RWI-V */
+#define NV_PFIFO_RAMHT_SIZE                                   17:16 /* RWIUF */
+#define NV_PFIFO_RAMHT_SIZE_4K                           0x00000000 /* RWI-V */
+#define NV_PFIFO_RAMHT_SIZE_8K                           0x00000001 /* RW--V */
+#define NV_PFIFO_RAMHT_SIZE_16K                          0x00000002 /* RW--V */
+#define NV_PFIFO_RAMHT_SIZE_32K                          0x00000003 /* RW--V */
+#define NV_PFIFO_RAMHT_SEARCH                                 25:24 /* RWIUF */
+#define NV_PFIFO_RAMHT_SEARCH_16                         0x00000000 /* RWI-V */
+#define NV_PFIFO_RAMHT_SEARCH_32                         0x00000001 /* RW--V */
+#define NV_PFIFO_RAMHT_SEARCH_64                         0x00000002 /* RW--V */
+#define NV_PFIFO_RAMHT_SEARCH_128                        0x00000003 /* RW--V */
+#define NV_PFIFO_RAMFC                                   0x00002214 /* RW-4R */
+#define NV_PFIFO_RAMFC_BASE_ADDRESS                             8:1 /* RWIUF */
+#define NV_PFIFO_RAMFC_BASE_ADDRESS_11000                0x00000088 /* RWI-V */
+#define NV_PFIFO_RAMRO                                   0x00002218 /* RW-4R */
+#define NV_PFIFO_RAMRO_BASE_ADDRESS                             8:1 /* RWIUF */
+#define NV_PFIFO_RAMRO_BASE_ADDRESS_11200                0x00000089 /* RWI-V */
+#define NV_PFIFO_RAMRO_BASE_ADDRESS_12000                0x00000090 /* RW--V */
+#define NV_PFIFO_RAMRO_SIZE                                   16:16 /* RWIVF */
+#define NV_PFIFO_RAMRO_SIZE_512                          0x00000000 /* RWI-V */
+#define NV_PFIFO_RAMRO_SIZE_8K                           0x00000001 /* RW--V */
+#define NV_PFIFO_CACHES                                  0x00002500 /* RW-4R */
+#define NV_PFIFO_CACHES_REASSIGN                                0:0 /* RWIVF */
+#define NV_PFIFO_CACHES_REASSIGN_DISABLED                0x00000000 /* RWI-V */
+#define NV_PFIFO_CACHES_REASSIGN_ENABLED                 0x00000001 /* RW--V */
+#define NV_PFIFO_CACHES_DMA_SUSPEND                             4:4 /* R--VF */
+#define NV_PFIFO_CACHES_DMA_SUSPEND_IDLE                 0x00000000 /* R---V */
+#define NV_PFIFO_CACHES_DMA_SUSPEND_BUSY                 0x00000001 /* R---V */
+#define NV_PFIFO_MODE                                    0x00002504 /* RW-4R */
+#define NV_PFIFO_MODE_CHANNEL_0                                 0:0 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_0_PIO                      0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_0_DMA                      0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_1                                 1:1 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_1_PIO                      0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_1_DMA                      0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_2                                 2:2 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_2_PIO                      0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_2_DMA                      0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_3                                 3:3 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_3_PIO                      0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_3_DMA                      0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_4                                 4:4 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_4_PIO                      0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_4_DMA                      0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_5                                 5:5 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_5_PIO                      0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_5_DMA                      0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_6                                 6:6 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_6_PIO                      0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_6_DMA                      0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_7                                 7:7 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_7_PIO                      0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_7_DMA                      0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_8                                 8:8 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_8_PIO                      0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_8_DMA                      0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_9                                 9:9 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_9_PIO                      0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_9_DMA                      0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_10                              10:10 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_10_PIO                     0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_10_DMA                     0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_11                              11:11 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_11_PIO                     0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_11_DMA                     0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_12                              12:12 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_12_PIO                     0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_12_DMA                     0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_13                              13:13 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_13_PIO                     0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_13_DMA                     0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_14                              14:14 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_14_PIO                     0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_14_DMA                     0x00000001 /* RW--V */
+#define NV_PFIFO_MODE_CHANNEL_15                              15:15 /* RWIVF */
+#define NV_PFIFO_MODE_CHANNEL_15_PIO                     0x00000000 /* RWI-V */
+#define NV_PFIFO_MODE_CHANNEL_15_DMA                     0x00000001 /* RW--V */
+#define NV_PFIFO_DMA                                     0x00002508 /* RW-4R */
+#define NV_PFIFO_DMA_CHANNEL_0                                  0:0 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_0_NOT_PENDING               0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_0_PENDING                   0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_1                                  1:1 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_1_NOT_PENDING               0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_1_PENDING                   0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_2                                  2:2 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_2_NOT_PENDING               0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_2_PENDING                   0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_3                                  3:3 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_3_NOT_PENDING               0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_3_PENDING                   0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_4                                  4:4 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_4_NOT_PENDING               0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_4_PENDING                   0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_5                                  5:5 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_5_NOT_PENDING               0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_5_PENDING                   0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_6                                  6:6 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_6_NOT_PENDING               0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_6_PENDING                   0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_7                                  7:7 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_7_NOT_PENDING               0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_7_PENDING                   0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_8                                  8:8 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_8_NOT_PENDING               0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_8_PENDING                   0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_9                                  9:9 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_9_NOT_PENDING               0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_9_PENDING                   0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_10                               10:10 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_10_NOT_PENDING              0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_10_PENDING                  0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_11                               11:11 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_11_NOT_PENDING              0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_11_PENDING                  0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_12                               12:12 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_12_NOT_PENDING              0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_12_PENDING                  0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_13                               13:13 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_13_NOT_PENDING              0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_13_PENDING                  0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_14                               14:14 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_14_NOT_PENDING              0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_14_PENDING                  0x00000001 /* RW--V */
+#define NV_PFIFO_DMA_CHANNEL_15                               15:15 /* RWIVF */
+#define NV_PFIFO_DMA_CHANNEL_15_NOT_PENDING              0x00000000 /* RWI-V */
+#define NV_PFIFO_DMA_CHANNEL_15_PENDING                  0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE                                    0x0000250C /* RW-4R */
+#define NV_PFIFO_SIZE_CHANNEL_0                                 0:0 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_0_124_BYTES                0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_0_512_BYTES                0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_1                                 1:1 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_1_124_BYTES                0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_1_512_BYTES                0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_2                                 2:2 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_2_124_BYTES                0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_2_512_BYTES                0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_3                                 3:3 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_3_124_BYTES                0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_3_512_BYTES                0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_4                                 4:4 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_4_124_BYTES                0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_4_512_BYTES                0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_5                                 5:5 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_5_124_BYTES                0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_5_512_BYTES                0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_6                                 6:6 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_6_124_BYTES                0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_6_512_BYTES                0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_7                                 7:7 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_7_124_BYTES                0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_7_512_BYTES                0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_8                                 8:8 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_8_124_BYTES                0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_8_512_BYTES                0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_9                                 9:9 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_9_124_BYTES                0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_9_512_BYTES                0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_10                              10:10 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_10_124_BYTES               0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_10_512_BYTES               0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_11                              11:11 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_11_124_BYTES               0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_11_512_BYTES               0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_12                              12:12 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_12_124_BYTES               0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_12_512_BYTES               0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_13                              13:13 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_13_124_BYTES               0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_13_512_BYTES               0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_14                              14:14 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_14_124_BYTES               0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_14_512_BYTES               0x00000001 /* RW--V */
+#define NV_PFIFO_SIZE_CHANNEL_15                              15:15 /* RWIVF */
+#define NV_PFIFO_SIZE_CHANNEL_15_124_BYTES               0x00000000 /* RWI-V */
+#define NV_PFIFO_SIZE_CHANNEL_15_512_BYTES               0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE0_PUSH0                            0x00003000 /* RW-4R */
+#define NV_PFIFO_CACHE0_PUSH0_ACCESS                            0:0 /* RWIVF */
+#define NV_PFIFO_CACHE0_PUSH0_ACCESS_DISABLED            0x00000000 /* RWI-V */
+#define NV_PFIFO_CACHE0_PUSH0_ACCESS_ENABLED             0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_PUSH0                            0x00003200 /* RW-4R */
+#define NV_PFIFO_CACHE1_PUSH0_ACCESS                            0:0 /* RWIVF */
+#define NV_PFIFO_CACHE1_PUSH0_ACCESS_DISABLED            0x00000000 /* RWI-V */
+#define NV_PFIFO_CACHE1_PUSH0_ACCESS_ENABLED             0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE0_PUSH1                            0x00003004 /* RW-4R */
+#define NV_PFIFO_CACHE0_PUSH1_CHID                              3:0 /* RWXUF */
+#define NV_PFIFO_CACHE1_PUSH1                            0x00003204 /* RW-4R */
+#define NV_PFIFO_CACHE1_PUSH1_CHID                              3:0 /* RWXUF */
+#define NV_PFIFO_CACHE1_PUSH1_MODE                              8:8 /* RWIVF */
+#define NV_PFIFO_CACHE1_PUSH1_MODE_PIO                   0x00000000 /* RWI-V */
+#define NV_PFIFO_CACHE1_PUSH1_MODE_DMA                   0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_PUSH                         0x00003220 /* RW-4R */
+#define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS                         0:0 /* RWIVF */
+#define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS_DISABLED         0x00000000 /* RWI-V */
+#define NV_PFIFO_CACHE1_DMA_PUSH_ACCESS_ENABLED          0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_PUSH_STATE                          4:4 /* R--VF */
+#define NV_PFIFO_CACHE1_DMA_PUSH_STATE_IDLE              0x00000000 /* R---V */
+#define NV_PFIFO_CACHE1_DMA_PUSH_STATE_BUSY              0x00000001 /* R---V */
+#define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER                         8:8 /* R--VF */
+#define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER_NOT_EMPTY        0x00000000 /* R---V */
+#define NV_PFIFO_CACHE1_DMA_PUSH_BUFFER_EMPTY            0x00000001 /* R---V */
+#define NV_PFIFO_CACHE1_DMA_PUSH_STATUS                       12:12 /* RWIVF */
+#define NV_PFIFO_CACHE1_DMA_PUSH_STATUS_RUNNING          0x00000000 /* RWI-V */
+#define NV_PFIFO_CACHE1_DMA_PUSH_STATUS_SUSPENDED        0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH                        0x00003224 /* RW-4R */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG                          7:3 /* RWIUF */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_8_BYTES           0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_16_BYTES          0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_24_BYTES          0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_32_BYTES          0x00000003 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_40_BYTES          0x00000004 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_48_BYTES          0x00000005 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_56_BYTES          0x00000006 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_64_BYTES          0x00000007 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_72_BYTES          0x00000008 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_80_BYTES          0x00000009 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_88_BYTES          0x0000000A /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_96_BYTES          0x0000000B /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_104_BYTES         0x0000000C /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_112_BYTES         0x0000000D /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_120_BYTES         0x0000000E /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES         0x0000000F /* RWI-V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_136_BYTES         0x00000010 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_144_BYTES         0x00000011 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_152_BYTES         0x00000012 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_160_BYTES         0x00000013 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_168_BYTES         0x00000014 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_176_BYTES         0x00000015 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_184_BYTES         0x00000016 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_192_BYTES         0x00000017 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_200_BYTES         0x00000018 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_208_BYTES         0x00000019 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_216_BYTES         0x0000001A /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_224_BYTES         0x0000001B /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_232_BYTES         0x0000001C /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_240_BYTES         0x0000001D /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_248_BYTES         0x0000001E /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_TRIG_256_BYTES         0x0000001F /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE                        15:13 /* RWIUF */
+#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_32_BYTES          0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_64_BYTES          0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_96_BYTES          0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES         0x00000003 /* RWI-V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_160_BYTES         0x00000004 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_192_BYTES         0x00000005 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_224_BYTES         0x00000006 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_SIZE_256_BYTES         0x00000007 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS                    19:16 /* RWIUF */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_0             0x00000000 /* RWI-V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_1             0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_2             0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_3             0x00000003 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_4             0x00000004 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_5             0x00000005 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_6             0x00000006 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_7             0x00000007 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8             0x00000008 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_9             0x00000009 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_10            0x0000000A /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_11            0x0000000B /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_12            0x0000000C /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_13            0x0000000D /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_14            0x0000000E /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15            0x0000000F /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_PUT                          0x00003240 /* RW-4R */
+#define NV_PFIFO_CACHE1_DMA_PUT_OFFSET                         28:2 /* RWXUF */
+#define NV_PFIFO_CACHE1_DMA_GET                          0x00003244 /* RW-4R */
+#define NV_PFIFO_CACHE1_DMA_GET_OFFSET                         28:2 /* RWXUF */
+#define NV_PFIFO_CACHE1_DMA_STATE                        0x00003228 /* RW-4R */
+#define NV_PFIFO_CACHE1_DMA_STATE_METHOD                       12:2 /* RWXUF */
+#define NV_PFIFO_CACHE1_DMA_STATE_SUBCHANNEL                  15:13 /* RWXUF */
+#define NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT                28:18 /* RWIUF */
+#define NV_PFIFO_CACHE1_DMA_STATE_METHOD_COUNT_0         0x00000000 /* RWI-V */
+#define NV_PFIFO_CACHE1_DMA_STATE_ERROR                       31:30 /* RWXUF */
+#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_NONE             0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_NON_CACHE        0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_RESERVED_CMD     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_STATE_ERROR_PROTECTION       0x00000003 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_INSTANCE                     0x0000322C /* RW-4R */
+#define NV_PFIFO_CACHE1_DMA_INSTANCE_ADDRESS                   15:0 /* RWXUF */
+#define NV_PFIFO_CACHE1_DMA_CTL                          0x00003230 /* RW-4R */
+#define NV_PFIFO_CACHE1_DMA_CTL_ADJUST                         11:2 /* RWXUF */
+#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE                    12:12 /* RWXUF */
+#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_NOT_PRESENT   0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_PRESENT       0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY                    13:13 /* RWXUF */
+#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_NOT_LINEAR    0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_LINEAR        0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE                   17:16 /* RWXUF */
+#define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE_PCI          0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_CTL_TARGET_NODE_AGP          0x00000003 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO                       31:31 /* RWIUF */
+#define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO_INVALID          0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_CTL_AT_INFO_VALID            0x00000001 /* RWI-V */
+#define NV_PFIFO_CACHE1_DMA_LIMIT                        0x00003234 /* RW-4R */
+#define NV_PFIFO_CACHE1_DMA_LIMIT_OFFSET                       28:2 /* RWXUF */
+#define NV_PFIFO_CACHE1_DMA_TLB_TAG                      0x00003238 /* RW-4R */
+#define NV_PFIFO_CACHE1_DMA_TLB_TAG_ADDRESS                   28:12 /* RWXUF */
+#define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE                       0:0 /* RWIUF */
+#define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE_INVALID        0x00000000 /* RWI-V */
+#define NV_PFIFO_CACHE1_DMA_TLB_TAG_STATE_VALID          0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_DMA_TLB_PTE                      0x0000323C /* RW-4R */
+#define NV_PFIFO_CACHE1_DMA_TLB_PTE_FRAME_ADDRESS             31:12 /* RWXUF */
+#define NV_PFIFO_CACHE0_PULL0                            0x00003050 /* RW-4R */
+#define NV_PFIFO_CACHE0_PULL0_ACCESS                            0:0 /* RWIVF */
+#define NV_PFIFO_CACHE0_PULL0_ACCESS_DISABLED            0x00000000 /* RWI-V */
+#define NV_PFIFO_CACHE0_PULL0_ACCESS_ENABLED             0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE0_PULL0_HASH                              4:4 /* R-XVF */
+#define NV_PFIFO_CACHE0_PULL0_HASH_SUCCEEDED             0x00000000 /* R---V */
+#define NV_PFIFO_CACHE0_PULL0_HASH_FAILED                0x00000001 /* R---V */
+#define NV_PFIFO_CACHE0_PULL0_DEVICE                            8:8 /* R-XVF */
+#define NV_PFIFO_CACHE0_PULL0_DEVICE_HARDWARE            0x00000000 /* R---V */
+#define NV_PFIFO_CACHE0_PULL0_DEVICE_SOFTWARE            0x00000001 /* R---V */
+#define NV_PFIFO_CACHE0_PULL0_HASH_STATE                      12:12 /* R-XVF */
+#define NV_PFIFO_CACHE0_PULL0_HASH_STATE_IDLE            0x00000000 /* R---V */
+#define NV_PFIFO_CACHE0_PULL0_HASH_STATE_BUSY            0x00000001 /* R---V */
+#define NV_PFIFO_CACHE1_PULL0                            0x00003250 /* RW-4R */
+#define NV_PFIFO_CACHE1_PULL0_ACCESS                            0:0 /* RWIVF */
+#define NV_PFIFO_CACHE1_PULL0_ACCESS_DISABLED            0x00000000 /* RWI-V */
+#define NV_PFIFO_CACHE1_PULL0_ACCESS_ENABLED             0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_PULL0_HASH                              4:4 /* R-XVF */
+#define NV_PFIFO_CACHE1_PULL0_HASH_SUCCEEDED             0x00000000 /* R---V */
+#define NV_PFIFO_CACHE1_PULL0_HASH_FAILED                0x00000001 /* R---V */
+#define NV_PFIFO_CACHE1_PULL0_DEVICE                            8:8 /* R-XVF */
+#define NV_PFIFO_CACHE1_PULL0_DEVICE_HARDWARE            0x00000000 /* R---V */
+#define NV_PFIFO_CACHE1_PULL0_DEVICE_SOFTWARE            0x00000001 /* R---V */
+#define NV_PFIFO_CACHE1_PULL0_HASH_STATE                      12:12 /* R-XVF */
+#define NV_PFIFO_CACHE1_PULL0_HASH_STATE_IDLE            0x00000000 /* R---V */
+#define NV_PFIFO_CACHE1_PULL0_HASH_STATE_BUSY            0x00000001 /* R---V */
+#define NV_PFIFO_CACHE0_PULL1                            0x00003054 /* RW-4R */
+#define NV_PFIFO_CACHE0_PULL1_ENGINE                            1:0 /* RWXUF */
+#define NV_PFIFO_CACHE0_PULL1_ENGINE_SW                  0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE0_PULL1_ENGINE_GRAPHICS            0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE0_PULL1_ENGINE_DVD                 0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_PULL1                            0x00003254 /* RW-4R */
+#define NV_PFIFO_CACHE1_PULL1_ENGINE                            1:0 /* RWXUF */
+#define NV_PFIFO_CACHE1_PULL1_ENGINE_SW                  0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_PULL1_ENGINE_GRAPHICS            0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_PULL1_ENGINE_DVD                 0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE0_HASH                             0x00003058 /* RW-4R */
+#define NV_PFIFO_CACHE0_HASH_INSTANCE                          15:0 /* RWXUF */
+#define NV_PFIFO_CACHE0_HASH_VALID                            16:16 /* RWXVF */
+#define NV_PFIFO_CACHE1_HASH                             0x00003258 /* RW-4R */
+#define NV_PFIFO_CACHE1_HASH_INSTANCE                          15:0 /* RWXUF */
+#define NV_PFIFO_CACHE1_HASH_VALID                            16:16 /* RWXVF */
+#define NV_PFIFO_CACHE0_STATUS                           0x00003014 /* R--4R */
+#define NV_PFIFO_CACHE0_STATUS_LOW_MARK                         4:4 /* R--VF */
+#define NV_PFIFO_CACHE0_STATUS_LOW_MARK_NOT_EMPTY        0x00000000 /* R---V */
+#define NV_PFIFO_CACHE0_STATUS_LOW_MARK_EMPTY            0x00000001 /* R---V */
+#define NV_PFIFO_CACHE0_STATUS_HIGH_MARK                        8:8 /* R--VF */
+#define NV_PFIFO_CACHE0_STATUS_HIGH_MARK_NOT_FULL        0x00000000 /* R---V */
+#define NV_PFIFO_CACHE0_STATUS_HIGH_MARK_FULL            0x00000001 /* R---V */
+#define NV_PFIFO_CACHE1_STATUS                           0x00003214 /* R--4R */
+#define NV_PFIFO_CACHE1_STATUS_LOW_MARK                         4:4 /* R--VF */
+#define NV_PFIFO_CACHE1_STATUS_LOW_MARK_NOT_EMPTY        0x00000000 /* R---V */
+#define NV_PFIFO_CACHE1_STATUS_LOW_MARK_EMPTY            0x00000001 /* R---V */
+#define NV_PFIFO_CACHE1_STATUS_HIGH_MARK                        8:8 /* R--VF */
+#define NV_PFIFO_CACHE1_STATUS_HIGH_MARK_NOT_FULL        0x00000000 /* R---V */
+#define NV_PFIFO_CACHE1_STATUS_HIGH_MARK_FULL            0x00000001 /* R---V */
+#define NV_PFIFO_CACHE1_STATUS1                          0x00003218 /* R--4R */
+#define NV_PFIFO_CACHE1_STATUS1_RANOUT                          0:0 /* R-XVF */
+#define NV_PFIFO_CACHE1_STATUS1_RANOUT_FALSE             0x00000000 /* R---V */
+#define NV_PFIFO_CACHE1_STATUS1_RANOUT_TRUE              0x00000001 /* R---V */
+#define NV_PFIFO_CACHE0_PUT                              0x00003010 /* RW-4R */
+#define NV_PFIFO_CACHE0_PUT_ADDRESS                             2:2 /* RWXUF */
+#define NV_PFIFO_CACHE1_PUT                              0x00003210 /* RW-4R */
+#define NV_PFIFO_CACHE1_PUT_ADDRESS                             9:2 /* RWXUF */
+#define NV_PFIFO_CACHE0_GET                              0x00003070 /* RW-4R */
+#define NV_PFIFO_CACHE0_GET_ADDRESS                             2:2 /* RWXUF */
+#define NV_PFIFO_CACHE1_GET                              0x00003270 /* RW-4R */
+#define NV_PFIFO_CACHE1_GET_ADDRESS                             9:2 /* RWXUF */
+#define NV_PFIFO_CACHE0_ENGINE                           0x00003080 /* RW-4R */
+#define NV_PFIFO_CACHE0_ENGINE_0                                1:0 /* RWXUF */
+#define NV_PFIFO_CACHE0_ENGINE_0_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_0_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_0_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_1                                5:4 /* RWXUF */
+#define NV_PFIFO_CACHE0_ENGINE_1_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_1_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_1_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_2                                9:8 /* RWXUF */
+#define NV_PFIFO_CACHE0_ENGINE_2_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_2_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_2_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_3                              13:12 /* RWXUF */
+#define NV_PFIFO_CACHE0_ENGINE_3_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_3_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_3_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_4                              17:16 /* RWXUF */
+#define NV_PFIFO_CACHE0_ENGINE_4_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_4_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_4_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_5                              21:20 /* RWXUF */
+#define NV_PFIFO_CACHE0_ENGINE_5_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_5_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_5_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_6                              25:24 /* RWXUF */
+#define NV_PFIFO_CACHE0_ENGINE_6_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_6_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_6_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_7                              29:28 /* RWXUF */
+#define NV_PFIFO_CACHE0_ENGINE_7_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_7_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE0_ENGINE_7_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE                           0x00003280 /* RW-4R */
+#define NV_PFIFO_CACHE1_ENGINE_0                                1:0 /* RWXUF */
+#define NV_PFIFO_CACHE1_ENGINE_0_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_0_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_0_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_1                                5:4 /* RWXUF */
+#define NV_PFIFO_CACHE1_ENGINE_1_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_1_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_1_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_2                                9:8 /* RWXUF */
+#define NV_PFIFO_CACHE1_ENGINE_2_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_2_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_2_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_3                              13:12 /* RWXUF */
+#define NV_PFIFO_CACHE1_ENGINE_3_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_3_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_3_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_4                              17:16 /* RWXUF */
+#define NV_PFIFO_CACHE1_ENGINE_4_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_4_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_4_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_5                              21:20 /* RWXUF */
+#define NV_PFIFO_CACHE1_ENGINE_5_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_5_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_5_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_6                              25:24 /* RWXUF */
+#define NV_PFIFO_CACHE1_ENGINE_6_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_6_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_6_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_7                              29:28 /* RWXUF */
+#define NV_PFIFO_CACHE1_ENGINE_7_SW                      0x00000000 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_7_GRAPHICS                0x00000001 /* RW--V */
+#define NV_PFIFO_CACHE1_ENGINE_7_DVD                     0x00000002 /* RW--V */
+#define NV_PFIFO_CACHE0_METHOD(i)                (0x00003100+(i)*8) /* RW-4A */
+#define NV_PFIFO_CACHE0_METHOD__SIZE_1                            1 /*       */
+#define NV_PFIFO_CACHE0_METHOD_ADDRESS                         12:2 /* RWXUF */
+#define NV_PFIFO_CACHE0_METHOD_SUBCHANNEL                     15:13 /* RWXUF */
+#define NV_PFIFO_CACHE1_METHOD(i)                (0x00003800+(i)*8) /* RW-4A */
+#define NV_PFIFO_CACHE1_METHOD__SIZE_1                          128 /*       */
+#define NV_PFIFO_CACHE1_METHOD_ADDRESS                         12:2 /* RWXUF */
+#define NV_PFIFO_CACHE1_METHOD_SUBCHANNEL                     15:13 /* RWXUF */
+#define NV_PFIFO_CACHE1_METHOD_ALIAS(i)          (0x00003C00+(i)*8) /* RW-4A */
+#define NV_PFIFO_CACHE1_METHOD_ALIAS__SIZE_1                    128 /*       */
+#define NV_PFIFO_CACHE0_DATA(i)                  (0x00003104+(i)*8) /* RW-4A */
+#define NV_PFIFO_CACHE0_DATA__SIZE_1                              1 /*       */
+#define NV_PFIFO_CACHE0_DATA_VALUE                             31:0 /* RWXVF */
+#define NV_PFIFO_CACHE1_DATA(i)                  (0x00003804+(i)*8) /* RW-4A */
+#define NV_PFIFO_CACHE1_DATA__SIZE_1                            128 /*       */
+#define NV_PFIFO_CACHE1_DATA_VALUE                             31:0 /* RWXVF */
+#define NV_PFIFO_CACHE1_DATA_ALIAS(i)            (0x00003C04+(i)*8) /* RW-4A */
+#define NV_PFIFO_CACHE1_DATA_ALIAS__SIZE_1                      128 /*       */
+#define NV_PFIFO_DEVICE(i)                       (0x00002800+(i)*4) /* R--4A */
+#define NV_PFIFO_DEVICE__SIZE_1                                 128 /*       */
+#define NV_PFIFO_DEVICE_CHID                                    3:0 /* R--UF */
+#define NV_PFIFO_DEVICE_SWITCH                                24:24 /* R--VF */
+#define NV_PFIFO_DEVICE_SWITCH_UNAVAILABLE               0x00000000 /* R---V */
+#define NV_PFIFO_DEVICE_SWITCH_AVAILABLE                 0x00000001 /* R---V */
+#define NV_PFIFO_RUNOUT_STATUS                           0x00002400 /* R--4R */
+#define NV_PFIFO_RUNOUT_STATUS_RANOUT                           0:0 /* R--VF */
+#define NV_PFIFO_RUNOUT_STATUS_RANOUT_FALSE              0x00000000 /* R---V */
+#define NV_PFIFO_RUNOUT_STATUS_RANOUT_TRUE               0x00000001 /* R---V */
+#define NV_PFIFO_RUNOUT_STATUS_LOW_MARK                         4:4 /* R--VF */
+#define NV_PFIFO_RUNOUT_STATUS_LOW_MARK_NOT_EMPTY        0x00000000 /* R---V */
+#define NV_PFIFO_RUNOUT_STATUS_LOW_MARK_EMPTY            0x00000001 /* R---V */
+#define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK                        8:8 /* R--VF */
+#define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK_NOT_FULL        0x00000000 /* R---V */
+#define NV_PFIFO_RUNOUT_STATUS_HIGH_MARK_FULL            0x00000001 /* R---V */
+#define NV_PFIFO_RUNOUT_PUT                              0x00002410 /* RW-4R */
+#define NV_PFIFO_RUNOUT_PUT_ADDRESS                            12:3 /* RWXUF */
+#define NV_PFIFO_RUNOUT_PUT_ADDRESS__SIZE_0                     8:3 /* RWXUF */
+#define NV_PFIFO_RUNOUT_PUT_ADDRESS__SIZE_1                    12:3 /* RWXUF */
+#define NV_PFIFO_RUNOUT_GET                              0x00002420 /* RW-4R */
+#define NV_PFIFO_RUNOUT_GET_ADDRESS                            13:3 /* RWXUF */
+/* dev_graphics.ref */
+#define NV_PGRAPH                             0x00401FFF:0x00400000 /* RW--D */
+#define NV_PGRAPH_DEBUG_0                                0x00400080 /* RW-4R */
+#define NV_PGRAPH_DEBUG_1                                0x00400084 /* RW-4R */
+#define NV_PGRAPH_DEBUG_2                                0x00400088 /* RW-4R */
+#define NV_PGRAPH_DEBUG_3                                0x0040008C /* RW-4R */
+#define NV_PGRAPH_INTR                                   0x00400100 /* RW-4R */
+#define NV_PGRAPH_INTR_NOTIFY                                   0:0 /* RWIVF */
+#define NV_PGRAPH_INTR_NOTIFY_NOT_PENDING                0x00000000 /* R-I-V */
+#define NV_PGRAPH_INTR_NOTIFY_PENDING                    0x00000001 /* R---V */
+#define NV_PGRAPH_INTR_NOTIFY_RESET                      0x00000001 /* -W--C */
+#define NV_PGRAPH_INTR_MISSING_HW                               4:4 /* RWIVF */
+#define NV_PGRAPH_INTR_MISSING_HW_NOT_PENDING            0x00000000 /* R-I-V */
+#define NV_PGRAPH_INTR_MISSING_HW_PENDING                0x00000001 /* R---V */
+#define NV_PGRAPH_INTR_MISSING_HW_RESET                  0x00000001 /* -W--C */
+#define NV_PGRAPH_INTR_TLB_PRESENT_A                            8:8 /* RWIVF */
+#define NV_PGRAPH_INTR_TLB_PRESENT_A_NOT_PENDING         0x00000000 /* R-I-V */
+#define NV_PGRAPH_INTR_TLB_PRESENT_A_PENDING             0x00000001 /* R---V */
+#define NV_PGRAPH_INTR_TLB_PRESENT_A_RESET               0x00000001 /* -W--C */
+#define NV_PGRAPH_INTR_TLB_PRESENT_B                            9:9 /* RWIVF */
+#define NV_PGRAPH_INTR_TLB_PRESENT_B_NOT_PENDING         0x00000000 /* R-I-V */
+#define NV_PGRAPH_INTR_TLB_PRESENT_B_PENDING             0x00000001 /* R---V */
+#define NV_PGRAPH_INTR_TLB_PRESENT_B_RESET               0x00000001 /* -W--C */
+#define NV_PGRAPH_INTR_CONTEXT_SWITCH                         12:12 /* RWIVF */
+#define NV_PGRAPH_INTR_CONTEXT_SWITCH_NOT_PENDING        0x00000000 /* R-I-V */
+#define NV_PGRAPH_INTR_CONTEXT_SWITCH_PENDING            0x00000001 /* R---V */
+#define NV_PGRAPH_INTR_CONTEXT_SWITCH_RESET              0x00000001 /* -W--C */
+#define NV_PGRAPH_INTR_BUFFER_NOTIFY                          16:16 /* RWIVF */
+#define NV_PGRAPH_INTR_BUFFER_NOTIFY_NOT_PENDING         0x00000000 /* R-I-V */
+#define NV_PGRAPH_INTR_BUFFER_NOTIFY_PENDING             0x00000001 /* R---V */
+#define NV_PGRAPH_INTR_BUFFER_NOTIFY_RESET               0x00000001 /* -W--C */
+#define NV_PGRAPH_NSTATUS                                0x00400104 /* RW-4R */
+#define NV_PGRAPH_NSTATUS_STATE_IN_USE                        11:11 /* RWIVF */
+#define NV_PGRAPH_NSTATUS_STATE_IN_USE_NOT_PENDING       0x00000000 /* RWI-V */
+#define NV_PGRAPH_NSTATUS_STATE_IN_USE_PENDING           0x00000001 /* RW--V */
+#define NV_PGRAPH_NSTATUS_INVALID_STATE                       12:12 /* RWIVF */
+#define NV_PGRAPH_NSTATUS_INVALID_STATE_NOT_PENDING      0x00000000 /* RWI-V */
+#define NV_PGRAPH_NSTATUS_INVALID_STATE_PENDING          0x00000001 /* RW--V */
+#define NV_PGRAPH_NSTATUS_BAD_ARGUMENT                        13:13 /* RWIVF */
+#define NV_PGRAPH_NSTATUS_BAD_ARGUMENT_NOT_PENDING       0x00000000 /* RWI-V */
+#define NV_PGRAPH_NSTATUS_BAD_ARGUMENT_PENDING           0x00000001 /* RW--V */
+#define NV_PGRAPH_NSTATUS_PROTECTION_FAULT                    14:14 /* RWIVF */
+#define NV_PGRAPH_NSTATUS_PROTECTION_FAULT_NOT_PENDING   0x00000000 /* RWI-V */
+#define NV_PGRAPH_NSTATUS_PROTECTION_FAULT_PENDING       0x00000001 /* RW--V */
+#define NV_PGRAPH_NSOURCE                                0x00400108 /* R--4R */
+#define NV_PGRAPH_NSOURCE_NOTIFICATION                          0:0 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_NOTIFICATION_NOT_PENDING       0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_NOTIFICATION_PENDING           0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_DATA_ERROR                            1:1 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_DATA_ERROR_NOT_PENDING         0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_DATA_ERROR_PENDING             0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_PROTECTION_ERROR                      2:2 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_PROTECTION_ERROR_NOT_PENDING   0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_PROTECTION_ERROR_PENDING       0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION                       3:3 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION_NOT_PENDING    0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_RANGE_EXCEPTION_PENDING        0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_LIMIT_COLOR                           4:4 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_LIMIT_COLOR_NOT_PENDING        0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_LIMIT_COLOR_PENDING            0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_LIMIT_ZETA_                           5:5 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_LIMIT_ZETA_NOT_PENDING         0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_LIMIT_ZETA_PENDING             0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD                          6:6 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD_NOT_PENDING       0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_ILLEGAL_MTHD_PENDING           0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION                      7:7 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION_NOT_PENDING   0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_DMA_R_PROTECTION_PENDING       0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION                      8:8 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION_NOT_PENDING   0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_DMA_W_PROTECTION_PENDING       0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION                      9:9 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION_NOT_PENDING   0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_FORMAT_EXCEPTION_PENDING       0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION                     10:10 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION_NOT_PENDING    0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_PATCH_EXCEPTION_PENDING        0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_STATE_INVALID                       11:11 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_STATE_INVALID_NOT_PENDING      0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_STATE_INVALID_PENDING          0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY                       12:12 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY_NOT_PENDING      0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_DOUBLE_NOTIFY_PENDING          0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE                       13:13 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE_NOT_PENDING      0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_NOTIFY_IN_USE_PENDING          0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_METHOD_CNT                          14:14 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_METHOD_CNT_NOT_PENDING         0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_METHOD_CNT_PENDING             0x00000001 /* R---V */
+#define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION                    15:15 /* R-IVF */
+#define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION_NOT_PENDING   0x00000000 /* R-I-V */
+#define NV_PGRAPH_NSOURCE_BFR_NOTIFICATION_PENDING       0x00000001 /* R---V */
+#define NV_PGRAPH_INTR_EN                                0x00400140 /* RW-4R */
+#define NV_PGRAPH_INTR_EN_NOTIFY                                0:0 /* RWIVF */
+#define NV_PGRAPH_INTR_EN_NOTIFY_DISABLED                0x00000000 /* RWI-V */
+#define NV_PGRAPH_INTR_EN_NOTIFY_ENABLED                 0x00000001 /* RW--V */
+#define NV_PGRAPH_INTR_EN_MISSING_HW                            4:4 /* RWIVF */
+#define NV_PGRAPH_INTR_EN_MISSING_HW_DISABLED            0x00000000 /* RWI-V */
+#define NV_PGRAPH_INTR_EN_MISSING_HW_ENABLED             0x00000001 /* RW--V */
+#define NV_PGRAPH_INTR_EN_TLB_PRESENT_A                         8:8 /* RWIVF */
+#define NV_PGRAPH_INTR_EN_TLB_PRESENT_A_DISABLED         0x00000000 /* RWI-V */
+#define NV_PGRAPH_INTR_EN_TLB_PRESENT_A_ENABLED          0x00000001 /* RW--V */
+#define NV_PGRAPH_INTR_EN_TLB_PRESENT_B                         9:9 /* RWIVF */
+#define NV_PGRAPH_INTR_EN_TLB_PRESENT_B_DISABLED         0x00000000 /* RWI-V */
+#define NV_PGRAPH_INTR_EN_TLB_PRESENT_B_ENABLED          0x00000001 /* RW--V */
+#define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH                      12:12 /* RWIVF */
+#define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH_DISABLED        0x00000000 /* RWI-V */
+#define NV_PGRAPH_INTR_EN_CONTEXT_SWITCH_ENABLED         0x00000001 /* RW--V */
+#define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY                       16:16 /* RWIVF */
+#define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY_DISABLED         0x00000000 /* RWI-V */
+#define NV_PGRAPH_INTR_EN_BUFFER_NOTIFY_ENABLED          0x00000001 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1                            0x00400160 /* RW-4R */
+#define NV_PGRAPH_CTX_SWITCH1_GRCLASS                           7:0 /* RWXVF */
+#define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY                      12:12 /* RWXUF */
+#define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY_DISABLE         0x00000000 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_CHROMA_KEY_ENABLE          0x00000001 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_USER_CLIP                       13:13 /* RWXUF */
+#define NV_PGRAPH_CTX_SWITCH1_USER_CLIP_DISABLE          0x00000000 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_USER_CLIP_ENABLE           0x00000001 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_SWIZZLE                         14:14 /* RWXUF */
+#define NV_PGRAPH_CTX_SWITCH1_SWIZZLE_DISABLE            0x00000000 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_SWIZZLE_ENABLE             0x00000001 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG                    17:15 /* RWXUF */
+#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY_AND   0x00000000 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_ROP_AND       0x00000001 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_BLEND_AND     0x00000002 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY       0x00000003 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_SRCCOPY_PRE   0x00000004 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_PATCH_CONFIG_BLEND_PRE     0x00000005 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS                    24:24 /* RWXUF */
+#define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS_INVALID       0x00000000 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_PATCH_STATUS_VALID         0x00000001 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE                 25:25 /* RWXUF */
+#define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE_INVALID    0x00000000 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_CONTEXT_SURFACE_VALID      0x00000001 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET                  31:31 /* CWIVF */
+#define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET_IGNORE      0x00000000 /* CWI-V */
+#define NV_PGRAPH_CTX_SWITCH1_VOLATILE_RESET_ENABLED     0x00000001 /* -W--T */
+#define NV_PGRAPH_CTX_SWITCH2                            0x00400164 /* RW-4R */
+#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT                       1:0 /* RWXUF */
+#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_INVALID              0x00 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_CGA6_M1              0x01 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_MONO_FORMAT_LE_M1                0x02 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT                     13:8 /* RWXUF */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_INVALID             0x00 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y8               0x01 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16A8Y8          0x02 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X24Y8            0x03 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A1R5G5B5         0x06 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X1R5G5B5         0x07 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16A1R5G5B5      0x08 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X17R5G5B5        0x09 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_R5G6B5           0x0A /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A16R5G6B5        0x0B /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16R5G6B5        0x0C /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A8R8G8B8         0x0D /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X8R8G8B8         0x0E /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y16              0x0F /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_A16Y16           0x10 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_X16Y16           0x11 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_V8YB8U8YA8       0x12 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_YB8V8YA8U8       0x13 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_COLOR_FORMAT_LE_Y32              0x14 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH2_NOTIFY_INSTANCE                 31:16 /* RWXUF */
+#define NV_PGRAPH_CTX_SWITCH2_NOTIFY_INSTANCE_INVALID        0x0000 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH3                            0x00400168 /* RW-4R */
+#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_0                   15:0 /* RWXUF */
+#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_0_INVALID         0x0000 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_1                  31:16 /* RWXUF */
+#define NV_PGRAPH_CTX_SWITCH3_DMA_INSTANCE_1_INVALID         0x0000 /* RW--V */
+#define NV_PGRAPH_CTX_SWITCH4                            0x0040016C /* RW-4R */
+#define NV_PGRAPH_CTX_SWITCH4_USER_INSTANCE                    15:0 /* RWXUF */
+#define NV_PGRAPH_CTX_SWITCH4_USER_INSTANCE_INVALID          0x0000 /* RW--V */
+#define NV_PGRAPH_CTX_CACHE1(i)                  (0x00400180+(i)*4) /* RW-4A */
+#define NV_PGRAPH_CTX_CACHE1__SIZE_1                              8 /*       */
+#define NV_PGRAPH_CTX_CACHE1_GRCLASS                            7:0 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE1_CHROMA_KEY                       12:12 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE1_USER_CLIP                        13:13 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE1_SWIZZLE                          14:14 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE1_PATCH_CONFIG                     19:15 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE1_SPARE1                           20:20 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE1_PATCH_STATUS                     24:24 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE1_CONTEXT_SURFACE                  25:25 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE2(i)                  (0x004001a0+(i)*4) /* RW-4A */
+#define NV_PGRAPH_CTX_CACHE2__SIZE_1                              8 /*       */
+#define NV_PGRAPH_CTX_CACHE2_MONO_FORMAT                        1:0 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE2_COLOR_FORMAT                      13:8 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE2_NOTIFY_INSTANCE                  31:16 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE3(i)                  (0x004001c0+(i)*4) /* RW-4A */
+#define NV_PGRAPH_CTX_CACHE3__SIZE_1                              8 /*       */
+#define NV_PGRAPH_CTX_CACHE3_DMA_INSTANCE_0                    15:0 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE3_DMA_INSTANCE_1                   31:16 /* RWXVF */
+#define NV_PGRAPH_CTX_CACHE4(i)                  (0x004001e0+(i)*4) /* RW-4A */
+#define NV_PGRAPH_CTX_CACHE4__SIZE_1                              8 /*       */
+#define NV_PGRAPH_CTX_CACHE4_USER_INSTANCE                     15:0 /* RWXVF */
+#define NV_PGRAPH_CTX_CONTROL                            0x00400170 /* RW-4R */
+#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME                      1:0 /* RWIVF */
+#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_33US          0x00000000 /* RWI-V */
+#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_262US         0x00000001 /* RW--V */
+#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_2MS           0x00000002 /* RW--V */
+#define NV_PGRAPH_CTX_CONTROL_MINIMUM_TIME_17MS          0x00000003 /* RW--V */
+#define NV_PGRAPH_CTX_CONTROL_TIME                              8:8 /* RWIVF */
+#define NV_PGRAPH_CTX_CONTROL_TIME_EXPIRED               0x00000000 /* RWI-V */
+#define NV_PGRAPH_CTX_CONTROL_TIME_NOT_EXPIRED           0x00000001 /* RW--V */
+#define NV_PGRAPH_CTX_CONTROL_CHID                            16:16 /* RWIVF */
+#define NV_PGRAPH_CTX_CONTROL_CHID_INVALID               0x00000000 /* RWI-V */
+#define NV_PGRAPH_CTX_CONTROL_CHID_VALID                 0x00000001 /* RW--V */
+#define NV_PGRAPH_CTX_CONTROL_CHANGE                          20:20 /* R--VF */
+#define NV_PGRAPH_CTX_CONTROL_CHANGE_UNAVAILABLE         0x00000000 /* R---V */
+#define NV_PGRAPH_CTX_CONTROL_CHANGE_AVAILABLE           0x00000001 /* R---V */
+#define NV_PGRAPH_CTX_CONTROL_SWITCHING                       24:24 /* RWIVF */
+#define NV_PGRAPH_CTX_CONTROL_SWITCHING_IDLE             0x00000000 /* RWI-V */
+#define NV_PGRAPH_CTX_CONTROL_SWITCHING_BUSY             0x00000001 /* RW--V */
+#define NV_PGRAPH_CTX_CONTROL_DEVICE                          28:28 /* RWIVF */
+#define NV_PGRAPH_CTX_CONTROL_DEVICE_DISABLED            0x00000000 /* RWI-V */
+#define NV_PGRAPH_CTX_CONTROL_DEVICE_ENABLED             0x00000001 /* RW--V */
+#define NV_PGRAPH_CTX_USER                               0x00400174 /* RW-4R */
+#define NV_PGRAPH_CTX_USER_SUBCH                              15:13 /* RWIVF */
+#define NV_PGRAPH_CTX_USER_SUBCH_0                       0x00000000 /* RWI-V */
+#define NV_PGRAPH_CTX_USER_CHID                               27:24 /* RWIVF */
+#define NV_PGRAPH_CTX_USER_CHID_0                        0x00000000 /* RWI-V */
+#define NV_PGRAPH_FIFO                                   0x00400720 /* RW-4R */
+#define NV_PGRAPH_FIFO_ACCESS                                   0:0 /* RWIVF */
+#define NV_PGRAPH_FIFO_ACCESS_DISABLED                   0x00000000 /* RW--V */
+#define NV_PGRAPH_FIFO_ACCESS_ENABLED                    0x00000001 /* RWI-V */
+#define NV_PGRAPH_FFINTFC_FIFO_0(i)              (0x00400730+(i)*4) /* RW-4A */
+#define NV_PGRAPH_FFINTFC_FIFO_0__SIZE_1                          4 /*       */
+#define NV_PGRAPH_FFINTFC_FIFO_0_TAG                            0:0 /* RWXVF */
+#define NV_PGRAPH_FFINTFC_FIFO_0_TAG_MTHD                0x00000000 /* RW--V */
+#define NV_PGRAPH_FFINTFC_FIFO_0_TAG_CHSW                0x00000001 /* RW--V */
+#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH                          3:1 /* RWXVF */
+#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_0                 0x00000000 /* RW--V */
+#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_1                 0x00000001 /* RW--V */
+#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_2                 0x00000002 /* RW--V */
+#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_3                 0x00000003 /* RW--V */
+#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_4                 0x00000004 /* RW--V */
+#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_5                 0x00000005 /* RW--V */
+#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_6                 0x00000006 /* RW--V */
+#define NV_PGRAPH_FFINTFC_FIFO_0_SUBCH_7                 0x00000007 /* RW--V */
+#define NV_PGRAPH_FFINTFC_FIFO_0_MTHD                          14:4 /* RWXVF */
+#define NV_PGRAPH_FFINTFC_FIFO_0_MTHD_CTX_SWITCH         0x00000000 /* RW--V */
+#define NV_PGRAPH_FFINTFC_FIFO_1(i)              (0x00400740+(i)*4) /* RW-4A */
+#define NV_PGRAPH_FFINTFC_FIFO_1__SIZE_1                          4 /*       */
+#define NV_PGRAPH_FFINTFC_FIFO_1_ARGUMENT                      31:0 /* RWXVF */
+#define NV_PGRAPH_FFINTFC_FIFO_PTR                       0x00400750 /* RW-4R */
+#define NV_PGRAPH_FFINTFC_FIFO_PTR_WRITE                        2:0 /* RWIVF */
+#define NV_PGRAPH_FFINTFC_FIFO_PTR_WRITE_0               0x00000000 /* RWI-V */
+#define NV_PGRAPH_FFINTFC_FIFO_PTR_READ                         6:4 /* RWIVF */
+#define NV_PGRAPH_FFINTFC_FIFO_PTR_READ_0                0x00000000 /* RWI-V */
+#define NV_PGRAPH_FFINTFC_ST2                            0x00400754 /* RW-4R */
+#define NV_PGRAPH_FFINTFC_ST2_STATUS                            0:0 /* RWIVF */
+#define NV_PGRAPH_FFINTFC_ST2_STATUS_INVALID             0x00000000 /* RWI-V */
+#define NV_PGRAPH_FFINTFC_ST2_STATUS_VALID               0x00000001 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_MTHD                             11:1 /* RWIVF */
+#define NV_PGRAPH_FFINTFC_ST2_MTHD_CTX_SWITCH            0x00000000 /* RWI-V */
+#define NV_PGRAPH_FFINTFC_ST2_SUBCH                           14:12 /* RWIVF */
+#define NV_PGRAPH_FFINTFC_ST2_SUBCH_0                    0x00000000 /* RWI-V */
+#define NV_PGRAPH_FFINTFC_ST2_SUBCH_1                    0x00000001 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_SUBCH_2                    0x00000002 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_SUBCH_3                    0x00000003 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_SUBCH_4                    0x00000004 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_SUBCH_5                    0x00000005 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_SUBCH_6                    0x00000006 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_SUBCH_7                    0x00000007 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID                            18:15 /* RWIVF */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_0                     0x00000000 /* RWI-V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_1                     0x00000001 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_2                     0x00000002 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_3                     0x00000003 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_4                     0x00000004 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_5                     0x00000005 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_6                     0x00000006 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_7                     0x00000007 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_8                     0x00000008 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_9                     0x00000009 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_10                    0x0000000A /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_11                    0x0000000B /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_12                    0x0000000C /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_13                    0x0000000D /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_14                    0x0000000E /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_15                    0x0000000F /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS                     19:19 /* RWIVF */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS_INVALID        0x00000000 /* RWI-V */
+#define NV_PGRAPH_FFINTFC_ST2_CHID_STATUS_VALID          0x00000001 /* RW--V */
+#define NV_PGRAPH_FFINTFC_ST2_D                          0x00400758 /* RW-4R */
+#define NV_PGRAPH_FFINTFC_ST2_D_ARGUMENT                       31:0 /* RWIVF */
+#define NV_PGRAPH_FFINTFC_ST2_D_ARGUMENT_0               0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATUS                                 0x00400700 /* R--4R */
+#define NV_PGRAPH_STATUS_STATE                                  0:0 /* R-IVF */
+#define NV_PGRAPH_STATUS_STATE_IDLE                      0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_STATE_BUSY                      0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_XY_LOGIC                               4:4 /* R-IVF */
+#define NV_PGRAPH_STATUS_XY_LOGIC_IDLE                   0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_XY_LOGIC_BUSY                   0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_FE                                     5:5 /* R-IVF */
+#define NV_PGRAPH_STATUS_FE_IDLE                         0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_FE_BUSY                         0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_RASTERIZER                             6:6 /* R-IVF */
+#define NV_PGRAPH_STATUS_RASTERIZER_IDLE                 0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_RASTERIZER_BUSY                 0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_PORT_NOTIFY                            8:8 /* R-IVF */
+#define NV_PGRAPH_STATUS_PORT_NOTIFY_IDLE                0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_PORT_NOTIFY_BUSY                0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_PORT_REGISTER                        12:12 /* R-IVF */
+#define NV_PGRAPH_STATUS_PORT_REGISTER_IDLE              0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_PORT_REGISTER_BUSY              0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_PORT_DMA                             16:16 /* R-IVF */
+#define NV_PGRAPH_STATUS_PORT_DMA_IDLE                   0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_PORT_DMA_BUSY                   0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_DMA_ENGINE                           17:17 /* R-IVF */
+#define NV_PGRAPH_STATUS_DMA_ENGINE_IDLE                 0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_DMA_ENGINE_BUSY                 0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_DMA_NOTIFY                           20:20 /* R-IVF */
+#define NV_PGRAPH_STATUS_DMA_NOTIFY_IDLE                 0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_DMA_NOTIFY_BUSY                 0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY                    21:21 /* R-IVF */
+#define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY_IDLE          0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_DMA_BUFFER_NOTIFY_BUSY          0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_D3D                                  24:24 /* R-IVF */
+#define NV_PGRAPH_STATUS_D3D_IDLE                        0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_D3D_BUSY                        0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_CACHE                                25:25 /* R-IVF */
+#define NV_PGRAPH_STATUS_CACHE_IDLE                      0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_CACHE_BUSY                      0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_LIGHTING                             26:26 /* R-IVF */
+#define NV_PGRAPH_STATUS_LIGHTING_IDLE                   0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_LIGHTING_BUSY                   0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_PREROP                               27:27 /* R-IVF */
+#define NV_PGRAPH_STATUS_PREROP_IDLE                     0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_PREROP_BUSY                     0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_ROP                                  28:28 /* R-IVF */
+#define NV_PGRAPH_STATUS_ROP_IDLE                        0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_ROP_BUSY                        0x00000001 /* R---V */
+#define NV_PGRAPH_STATUS_PORT_USER                            29:29 /* R-IVF */
+#define NV_PGRAPH_STATUS_PORT_USER_IDLE                  0x00000000 /* R-I-V */
+#define NV_PGRAPH_STATUS_PORT_USER_BUSY                  0x00000001 /* R---V */
+#define NV_PGRAPH_TRAPPED_ADDR                           0x00400704 /* R--4R */
+#define NV_PGRAPH_TRAPPED_ADDR_MTHD                            12:2 /* R-XUF */
+#define NV_PGRAPH_TRAPPED_ADDR_SUBCH                          15:13 /* R-XUF */
+#define NV_PGRAPH_TRAPPED_ADDR_CHID                           27:24 /* R-XUF */
+#define NV_PGRAPH_TRAPPED_DATA                           0x00400708 /* R--4R */
+#define NV_PGRAPH_TRAPPED_DATA_VALUE                           31:0 /* R-XVF */
+#define NV_PGRAPH_SURFACE                                0x0040070C /* RW-4R */
+#define NV_PGRAPH_SURFACE_TYPE                                  1:0 /* RWIVF */
+#define NV_PGRAPH_SURFACE_TYPE_INVALID                   0x00000000 /* RWI-V */
+#define NV_PGRAPH_SURFACE_TYPE_NON_SWIZZLE               0x00000001 /* RW--V */
+#define NV_PGRAPH_SURFACE_TYPE_SWIZZLE                   0x00000002 /* RW--V */
+#define NV_PGRAPH_NOTIFY                                 0x00400714 /* RW-4R */
+#define NV_PGRAPH_NOTIFY_BUFFER_REQ                             0:0 /* RWIVF */
+#define NV_PGRAPH_NOTIFY_BUFFER_REQ_NOT_PENDING          0x00000000 /* RWI-V */
+#define NV_PGRAPH_NOTIFY_BUFFER_REQ_PENDING              0x00000001 /* RW--V */
+#define NV_PGRAPH_NOTIFY_BUFFER_STYLE                           8:8 /* RWIVF */
+#define NV_PGRAPH_NOTIFY_BUFFER_STYLE_WRITE_ONLY         0x00000000 /* RWI-V */
+#define NV_PGRAPH_NOTIFY_BUFFER_STYLE_WRITE_THEN_AWAKEN  0x00000001 /* RW--V */
+#define NV_PGRAPH_NOTIFY_REQ                                  16:16 /* RWIVF */
+#define NV_PGRAPH_NOTIFY_REQ_NOT_PENDING                 0x00000000 /* RWI-V */
+#define NV_PGRAPH_NOTIFY_REQ_PENDING                     0x00000001 /* RW--V */
+#define NV_PGRAPH_NOTIFY_STYLE                                20:20 /* RWIVF */
+#define NV_PGRAPH_NOTIFY_STYLE_WRITE_ONLY                0x00000000 /* RWI-V */
+#define NV_PGRAPH_NOTIFY_STYLE_WRITE_THEN_AWAKEN         0x00000001 /* RW--V */
+#define NV_PGRAPH_BOFFSET(i)                     (0x00400640+(i)*4) /* RW-4A */
+#define NV_PGRAPH_BOFFSET__SIZE_1                                 6 /*       */
+#define NV_PGRAPH_BOFFSET_LINADRS                              23:0 /* RWIUF */
+#define NV_PGRAPH_BOFFSET_LINADRS_0                      0x00000000 /* RWI-V */
+#define NV_PGRAPH_BOFFSET0                               0x00400640 /* RW-4R */
+#define NV_PGRAPH_BOFFSET0__ALIAS_1            NV_PGRAPH_BOFFSET(0) /*       */
+#define NV_PGRAPH_BOFFSET0_LINADRS                             23:0 /* RWIUF */
+#define NV_PGRAPH_BOFFSET0_LINADRS_0                     0x00000000 /* RWI-V */
+#define NV_PGRAPH_BOFFSET1                               0x00400644 /* RW-4R */
+#define NV_PGRAPH_BOFFSET1__ALIAS_1            NV_PGRAPH_BOFFSET(1) /*       */
+#define NV_PGRAPH_BOFFSET1_LINADRS                             23:0 /* RWIUF */
+#define NV_PGRAPH_BOFFSET1_LINADRS_0                     0x00000000 /* RWI-V */
+#define NV_PGRAPH_BOFFSET2                               0x00400648 /* RW-4R */
+#define NV_PGRAPH_BOFFSET2__ALIAS_1            NV_PGRAPH_BOFFSET(2) /*       */
+#define NV_PGRAPH_BOFFSET2_LINADRS                             23:0 /* RWIUF */
+#define NV_PGRAPH_BOFFSET2_LINADRS_0                     0x00000000 /* RWI-V */
+#define NV_PGRAPH_BOFFSET3                               0x0040064C /* RW-4R */
+#define NV_PGRAPH_BOFFSET3__ALIAS_1            NV_PGRAPH_BOFFSET(3) /*       */
+#define NV_PGRAPH_BOFFSET3_LINADRS                             23:0 /* RWIUF */
+#define NV_PGRAPH_BOFFSET3_LINADRS_0                     0x00000000 /* RWI-V */
+#define NV_PGRAPH_BOFFSET4                               0x00400650 /* RW-4R */
+#define NV_PGRAPH_BOFFSET4__ALIAS_1            NV_PGRAPH_BOFFSET(4) /*       */
+#define NV_PGRAPH_BOFFSET4_LINADRS                             23:0 /* RWIUF */
+#define NV_PGRAPH_BOFFSET4_LINADRS_0                     0x00000000 /* RWI-V */
+#define NV_PGRAPH_BOFFSET5                               0x00400654 /* RW-4R */
+#define NV_PGRAPH_BOFFSET5__ALIAS_1            NV_PGRAPH_BOFFSET(5) /*       */
+#define NV_PGRAPH_BOFFSET5_LINADRS                             23:0 /* RWIUF */
+#define NV_PGRAPH_BOFFSET5_LINADRS_0                     0x00000000 /* RWI-V */
+#define NV_PGRAPH_BBASE(i)                       (0x00400658+(i)*4) /* RW-4A */
+#define NV_PGRAPH_BBASE__SIZE_1                                   6 /*       */
+#define NV_PGRAPH_BBASE_LINADRS                                23:0 /* RWIUF */
+#define NV_PGRAPH_BBASE_LINADRS_0                        0x00000000 /* RWI-V */
+#define NV_PGRAPH_BBASE0                                 0x00400658 /* RW-4R */
+#define NV_PGRAPH_BBASE0__ALIAS_1                NV_PGRAPH_BBASE(0) /*       */
+#define NV_PGRAPH_BBASE0_LINADRS                               23:0 /* RWIUF */
+#define NV_PGRAPH_BBASE0_LINADRS_0                       0x00000000 /* RWI-V */
+#define NV_PGRAPH_BBASE1                                 0x0040065c /* RW-4R */
+#define NV_PGRAPH_BBASE1__ALIAS_1                NV_PGRAPH_BBASE(1) /*       */
+#define NV_PGRAPH_BBASE1_LINADRS                               23:0 /* RWIUF */
+#define NV_PGRAPH_BBASE1_LINADRS_0                       0x00000000 /* RWI-V */
+#define NV_PGRAPH_BBASE2                                 0x00400660 /* RW-4R */
+#define NV_PGRAPH_BBASE2__ALIAS_1                NV_PGRAPH_BBASE(2) /*       */
+#define NV_PGRAPH_BBASE2_LINADRS                               23:0 /* RWIUF */
+#define NV_PGRAPH_BBASE2_LINADRS_0                       0x00000000 /* RWI-V */
+#define NV_PGRAPH_BBASE3                                 0x00400664 /* RW-4R */
+#define NV_PGRAPH_BBASE3__ALIAS_1                NV_PGRAPH_BBASE(3) /*       */
+#define NV_PGRAPH_BBASE3_LINADRS                               23:0 /* RWIUF */
+#define NV_PGRAPH_BBASE3_LINADRS_0                       0x00000000 /* RWI-V */
+#define NV_PGRAPH_BBASE4                                 0x00400668 /* RW-4R */
+#define NV_PGRAPH_BBASE4__ALIAS_1                NV_PGRAPH_BBASE(4) /*       */
+#define NV_PGRAPH_BBASE4_LINADRS                               23:0 /* RWIUF */
+#define NV_PGRAPH_BBASE4_LINADRS_0                       0x00000000 /* RWI-V */
+#define NV_PGRAPH_BBASE5                                 0x0040066C /* RW-4R */
+#define NV_PGRAPH_BBASE5__ALIAS_1                NV_PGRAPH_BBASE(5) /*       */
+#define NV_PGRAPH_BBASE5_LINADRS                               23:0 /* RWIUF */
+#define NV_PGRAPH_BBASE5_LINADRS_0                       0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPITCH(i)                      (0x00400670+(i)*4) /* RW-4A */
+#define NV_PGRAPH_BPITCH__SIZE_1                                  5 /*       */
+#define NV_PGRAPH_BPITCH_VALUE                                 12:0 /* RWIUF */
+#define NV_PGRAPH_BPITCH_VALUE_0                         0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPITCH0                                0x00400670 /* RW-4R */
+#define NV_PGRAPH_BPITCH0__ALIAS_1              NV_PGRAPH_BPITCH(0) /*       */
+#define NV_PGRAPH_BPITCH0_VALUE                                12:0 /* RWIUF */
+#define NV_PGRAPH_BPITCH0_VALUE_0                        0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPITCH1                                0x00400674 /* RW-4R */
+#define NV_PGRAPH_BPITCH1__ALIAS_1              NV_PGRAPH_BPITCH(1) /*       */
+#define NV_PGRAPH_BPITCH1_VALUE                                12:0 /* RWIUF */
+#define NV_PGRAPH_BPITCH1_VALUE_0                        0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPITCH2                                0x00400678 /* RW-4R */
+#define NV_PGRAPH_BPITCH2__ALIAS_1              NV_PGRAPH_BPITCH(2) /*       */
+#define NV_PGRAPH_BPITCH2_VALUE                                12:0 /* RWIUF */
+#define NV_PGRAPH_BPITCH2_VALUE_0                        0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPITCH3                                0x0040067C /* RW-4R */
+#define NV_PGRAPH_BPITCH3__ALIAS_1              NV_PGRAPH_BPITCH(3) /*       */
+#define NV_PGRAPH_BPITCH3_VALUE                                12:0 /* RWIUF */
+#define NV_PGRAPH_BPITCH3_VALUE_0                        0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPITCH4                                0x00400680 /* RW-4R */
+#define NV_PGRAPH_BPITCH4__ALIAS_1              NV_PGRAPH_BPITCH(4) /*       */
+#define NV_PGRAPH_BPITCH4_VALUE                                12:0 /* RWIUF */
+#define NV_PGRAPH_BPITCH4_VALUE_0                        0x00000000 /* RWI-V */
+#define NV_PGRAPH_BLIMIT(i)                      (0x00400684+(i)*4) /* RW-4A */
+#define NV_PGRAPH_BLIMIT__SIZE_1                                  6 /*       */
+#define NV_PGRAPH_BLIMIT_VALUE                                 23:0 /* RWXUF */
+#define NV_PGRAPH_BLIMIT_TYPE                                 31:31 /* RWIVF */
+#define NV_PGRAPH_BLIMIT_TYPE_IN_MEMORY                  0x00000000 /* RW--V */
+#define NV_PGRAPH_BLIMIT_TYPE_NULL                       0x00000001 /* RWI-V */
+#define NV_PGRAPH_BLIMIT0                                0x00400684 /* RW-4R */
+#define NV_PGRAPH_BLIMIT0__ALIAS_1              NV_PGRAPH_BLIMIT(0) /*       */
+#define NV_PGRAPH_BLIMIT0_VALUE                                23:0 /* RWXUF */
+#define NV_PGRAPH_BLIMIT0_TYPE                                31:31 /* RWIVF */
+#define NV_PGRAPH_BLIMIT0_TYPE_IN_MEMORY                 0x00000000 /* RW--V */
+#define NV_PGRAPH_BLIMIT0_TYPE_NULL                      0x00000001 /* RWI-V */
+#define NV_PGRAPH_BLIMIT1                                0x00400688 /* RW-4R */
+#define NV_PGRAPH_BLIMIT1__ALIAS_1              NV_PGRAPH_BLIMIT(1) /*       */
+#define NV_PGRAPH_BLIMIT1_VALUE                                23:0 /* RWXUF */
+#define NV_PGRAPH_BLIMIT1_TYPE                                31:31 /* RWIVF */
+#define NV_PGRAPH_BLIMIT1_TYPE_IN_MEMORY                 0x00000000 /* RW--V */
+#define NV_PGRAPH_BLIMIT1_TYPE_NULL                      0x00000001 /* RWI-V */
+#define NV_PGRAPH_BLIMIT2                                0x0040068c /* RW-4R */
+#define NV_PGRAPH_BLIMIT2__ALIAS_1              NV_PGRAPH_BLIMIT(2) /*       */
+#define NV_PGRAPH_BLIMIT2_VALUE                                23:0 /* RWXUF */
+#define NV_PGRAPH_BLIMIT2_TYPE                                31:31 /* RWIVF */
+#define NV_PGRAPH_BLIMIT2_TYPE_IN_MEMORY                 0x00000000 /* RW--V */
+#define NV_PGRAPH_BLIMIT2_TYPE_NULL                      0x00000001 /* RWI-V */
+#define NV_PGRAPH_BLIMIT3                                0x00400690 /* RW-4R */
+#define NV_PGRAPH_BLIMIT3__ALIAS_1              NV_PGRAPH_BLIMIT(3) /*       */
+#define NV_PGRAPH_BLIMIT3_VALUE                                23:0 /* RWXUF */
+#define NV_PGRAPH_BLIMIT3_TYPE                                31:31 /* RWIVF */
+#define NV_PGRAPH_BLIMIT3_TYPE_IN_MEMORY                 0x00000000 /* RW--V */
+#define NV_PGRAPH_BLIMIT3_TYPE_NULL                      0x00000001 /* RWI-V */
+#define NV_PGRAPH_BLIMIT4                                0x00400694 /* RW-4R */
+#define NV_PGRAPH_BLIMIT4__ALIAS_1              NV_PGRAPH_BLIMIT(4) /*       */
+#define NV_PGRAPH_BLIMIT4_VALUE                                23:0 /* RWXUF */
+#define NV_PGRAPH_BLIMIT4_TYPE                                31:31 /* RWIVF */
+#define NV_PGRAPH_BLIMIT4_TYPE_IN_MEMORY                 0x00000000 /* RW--V */
+#define NV_PGRAPH_BLIMIT4_TYPE_NULL                      0x00000001 /* RWI-V */
+#define NV_PGRAPH_BLIMIT5                                0x00400698 /* RW-4R */
+#define NV_PGRAPH_BLIMIT5__ALIAS_1              NV_PGRAPH_BLIMIT(5) /*       */
+#define NV_PGRAPH_BLIMIT5_VALUE                                23:0 /* RWXUF */
+#define NV_PGRAPH_BLIMIT5_TYPE                                31:31 /* RWIVF */
+#define NV_PGRAPH_BLIMIT5_TYPE_IN_MEMORY                 0x00000000 /* RW--V */
+#define NV_PGRAPH_BLIMIT5_TYPE_NULL                      0x00000001 /* RWI-V */
+#define NV_PGRAPH_BSWIZZLE2                              0x0040069c /* RW-4R */
+#define NV_PGRAPH_BSWIZZLE2_WIDTH                             19:16 /* RWIUF */
+#define NV_PGRAPH_BSWIZZLE2_WIDTH_0                      0x00000000 /* RWI-V */
+#define NV_PGRAPH_BSWIZZLE2_HEIGHT                            27:24 /* RWIUF */
+#define NV_PGRAPH_BSWIZZLE2_HEIGHT_0                     0x00000000 /* RWI-V */
+#define NV_PGRAPH_BSWIZZLE5                              0x004006a0 /* RW-4R */
+#define NV_PGRAPH_BSWIZZLE5_WIDTH                             19:16 /* RWIUF */
+#define NV_PGRAPH_BSWIZZLE5_WIDTH_0                      0x00000000 /* RWI-V */
+#define NV_PGRAPH_BSWIZZLE5_HEIGHT                            27:24 /* RWIUF */
+#define NV_PGRAPH_BSWIZZLE5_HEIGHT_0                     0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPIXEL                                 0x00400724 /* RW-4R */
+#define NV_PGRAPH_BPIXEL_DEPTH0                                 3:0 /* RWIVF */
+#define NV_PGRAPH_BPIXEL_DEPTH0_INVALID                  0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_Y8                       0x00000001 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_X1R5G5B5_Z1R5G5B5        0x00000002 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_X1R5G5B5_O1R5G5B5        0x00000003 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_A1R5G5B5                 0x00000004 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_R5G6B5                   0x00000005 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_Y16                      0x00000006 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_Z8R8G8B8        0x00000007 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_O1Z7R8G8B8      0x00000008 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_X1A7R8G8B8_Z1A7R8G8B8    0x00000009 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_X1A7R8G8B8_O1A7R8G8B8    0x0000000a /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_X8R8G8B8_O8R8G8B8        0x0000000b /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_A8R8G8B8                 0x0000000c /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_Y32                      0x0000000d /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_V8YB8U8YA8               0x0000000e /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH0_YB8V8YA8U8               0x0000000f /* RW--V */ 
+#define NV_PGRAPH_BPIXEL_DEPTH1                                 7:4 /* RWIVF */
+#define NV_PGRAPH_BPIXEL_DEPTH1_INVALID                  0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_Y8                       0x00000001 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_X1R5G5B5_Z1R5G5B5        0x00000002 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_X1R5G5B5_O1R5G5B5        0x00000003 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_A1R5G5B5                 0x00000004 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_R5G6B5                   0x00000005 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_Y16                      0x00000006 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_Z8R8G8B8        0x00000007 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_O1Z7R8G8B8      0x00000008 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_X1A7R8G8B8_Z1A7R8G8B8    0x00000009 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_X1A7R8G8B8_O1A7R8G8B8    0x0000000a /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_X8R8G8B8_O8R8G8B8        0x0000000b /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_A8R8G8B8                 0x0000000c /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_Y32                      0x0000000d /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_V8YB8U8YA8               0x0000000e /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH1_YB8V8YA8U8               0x0000000f /* RW--V */ 
+#define NV_PGRAPH_BPIXEL_DEPTH2                                11:8 /* RWIVF */
+#define NV_PGRAPH_BPIXEL_DEPTH2_INVALID                  0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_Y8                       0x00000001 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_X1R5G5B5_Z1R5G5B5        0x00000002 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_X1R5G5B5_O1R5G5B5        0x00000003 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_A1R5G5B5                 0x00000004 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_R5G6B5                   0x00000005 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_Y16                      0x00000006 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_Z8R8G8B8        0x00000007 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_O1Z7R8G8B8      0x00000008 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_X1A7R8G8B8_Z1A7R8G8B8    0x00000009 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_X1A7R8G8B8_O1A7R8G8B8    0x0000000a /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_X8R8G8B8_O8R8G8B8        0x0000000b /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_A8R8G8B8                 0x0000000c /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_Y32                      0x0000000d /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_V8YB8U8YA8               0x0000000e /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH2_YB8V8YA8U8               0x0000000f /* RW--V */ 
+#define NV_PGRAPH_BPIXEL_DEPTH3                               15:12 /* RWIVF */
+#define NV_PGRAPH_BPIXEL_DEPTH3_INVALID                  0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_Y8                       0x00000001 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_X1R5G5B5_Z1R5G5B5        0x00000002 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_X1R5G5B5_O1R5G5B5        0x00000003 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_A1R5G5B5                 0x00000004 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_R5G6B5                   0x00000005 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_Y16                      0x00000006 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_Z8R8G8B8        0x00000007 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_O1Z7R8G8B8      0x00000008 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_X1A7R8G8B8_Z1A7R8G8B8    0x00000009 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_X1A7R8G8B8_O1A7R8G8B8    0x0000000a /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_X8R8G8B8_O8R8G8B8        0x0000000b /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_A8R8G8B8                 0x0000000c /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_Y32                      0x0000000d /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_V8YB8U8YA8               0x0000000e /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH3_YB8V8YA8U8               0x0000000f /* RW--V */ 
+#define NV_PGRAPH_BPIXEL_DEPTH4                               19:16 /* RWIVF */
+#define NV_PGRAPH_BPIXEL_DEPTH4_INVALID                  0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_Y8                       0x00000001 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_X1R5G5B5_Z1R5G5B5        0x00000002 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_X1R5G5B5_O1R5G5B5        0x00000003 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_A1R5G5B5                 0x00000004 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_R5G6B5                   0x00000005 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_Y16                      0x00000006 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_Z8R8G8B8        0x00000007 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_O1Z7R8G8B8      0x00000008 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_X1A7R8G8B8_Z1A7R8G8B8    0x00000009 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_X1A7R8G8B8_O1A7R8G8B8    0x0000000a /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_X8R8G8B8_O8R8G8B8        0x0000000b /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_A8R8G8B8                 0x0000000c /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_Y32                      0x0000000d /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_V8YB8U8YA8               0x0000000e /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH4_YB8V8YA8U8               0x0000000f /* RW--V */ 
+#define NV_PGRAPH_BPIXEL_DEPTH5                               23:20 /* RWIVF */
+#define NV_PGRAPH_BPIXEL_DEPTH5_INVALID                  0x00000000 /* RWI-V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_Y8                       0x00000001 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_X1R5G5B5_Z1R5G5B5        0x00000002 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_X1R5G5B5_O1R5G5B5        0x00000003 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_A1R5G5B5                 0x00000004 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_R5G6B5                   0x00000005 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_Y16                      0x00000006 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_Z8R8G8B8        0x00000007 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_O1Z7R8G8B8      0x00000008 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_X1A7R8G8B8_Z1A7R8G8B8    0x00000009 /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_X1A7R8G8B8_O1A7R8G8B8    0x0000000a /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_X8R8G8B8_O8R8G8B8        0x0000000b /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_A8R8G8B8                 0x0000000c /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_Y32                      0x0000000d /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_V8YB8U8YA8               0x0000000e /* RW--V */
+#define NV_PGRAPH_BPIXEL_DEPTH5_YB8V8YA8U8               0x0000000f /* RW--V */ 
+#define NV_PGRAPH_LIMIT_VIOL_PIX                         0x00400610 /* RW-4R */
+#define NV_PGRAPH_LIMIT_VIOL_PIX_ADRS                          23:0 /* RWIVF */
+#define NV_PGRAPH_LIMIT_VIOL_PIX_ADRS_0                  0x00000000 /* RWI-V */
+#define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT                         29:29 /* RWIVF */
+#define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT_NO_VIOL            0x00000000 /* RWI-V */
+#define NV_PGRAPH_LIMIT_VIOL_PIX_BLIT_VIOL               0x00000001 /* RW--V */
+#define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT                        30:30 /* RWIVF */
+#define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT_NO_VIOL           0x00000000 /* RWI-V */
+#define NV_PGRAPH_LIMIT_VIOL_PIX_LIMIT_VIOL              0x00000001 /* RW--V */
+#define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW                       31:31 /* RWIVF */
+#define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW_NO_VIOL          0x00000000 /* RWI-V */
+#define NV_PGRAPH_LIMIT_VIOL_PIX_OVRFLW_VIOL             0x00000001 /* RW--V */
+#define NV_PGRAPH_LIMIT_VIOL_Z                           0x00400614 /* RW-4R */
+#define NV_PGRAPH_LIMIT_VIOL_Z_ADRS                            23:0 /* RWIVF */
+#define NV_PGRAPH_LIMIT_VIOL_Z_ADRS_0                    0x00000000 /* RWI-V */
+#define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT                          30:30 /* RWIVF */
+#define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT_NO_VIOL             0x00000000 /* RWI-V */
+#define NV_PGRAPH_LIMIT_VIOL_Z_LIMIT_VIOL                0x00000001 /* RW--V */
+#define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW                         31:31 /* RWIVF */
+#define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW_NO_VIOL            0x00000000 /* RWI-V */
+#define NV_PGRAPH_LIMIT_VIOL_Z_OVRFLW_VIOL               0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE                                  0x00400710 /* RW-4R */
+#define NV_PGRAPH_STATE_BUFFER_0                                0:0 /* RWIVF */
+#define NV_PGRAPH_STATE_BUFFER_0_INVALID                 0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_BUFFER_0_VALID                   0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_BUFFER_1                                1:1 /* RWIVF */
+#define NV_PGRAPH_STATE_BUFFER_1_INVALID                 0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_BUFFER_1_VALID                   0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_BUFFER_2                                2:2 /* RWIVF */
+#define NV_PGRAPH_STATE_BUFFER_2_INVALID                 0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_BUFFER_2_VALID                   0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_BUFFER_3                                3:3 /* RWIVF */
+#define NV_PGRAPH_STATE_BUFFER_3_INVALID                 0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_BUFFER_3_VALID                   0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_BUFFER_4                                4:4 /* RWIVF */
+#define NV_PGRAPH_STATE_BUFFER_4_INVALID                 0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_BUFFER_4_VALID                   0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_BUFFER_5                                5:5 /* RWIVF */
+#define NV_PGRAPH_STATE_BUFFER_5_INVALID                 0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_BUFFER_5_VALID                   0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_PITCH_0                                 8:8 /* RWIVF */
+#define NV_PGRAPH_STATE_PITCH_0_INVALID                  0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_PITCH_0_VALID                    0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_PITCH_1                                 9:9 /* RWIVF */
+#define NV_PGRAPH_STATE_PITCH_1_INVALID                  0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_PITCH_1_VALID                    0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_PITCH_2                               10:10 /* RWIVF */
+#define NV_PGRAPH_STATE_PITCH_2_INVALID                  0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_PITCH_2_VALID                    0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_PITCH_3                               11:11 /* RWIVF */
+#define NV_PGRAPH_STATE_PITCH_3_INVALID                  0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_PITCH_3_VALID                    0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_PITCH_4                               12:12 /* RWIVF */
+#define NV_PGRAPH_STATE_PITCH_4_INVALID                  0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_PITCH_4_VALID                    0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_CHROMA_COLOR                          16:16 /* RWIVF */
+#define NV_PGRAPH_STATE_CHROMA_COLOR_INVALID             0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_CHROMA_COLOR_VALID               0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_CHROMA_COLORFMT                       17:17 /* RWIVF */
+#define NV_PGRAPH_STATE_CHROMA_COLORFMT_INVALID          0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_CHROMA_COLORFMT_VALID            0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_CPATTERN_COLORFMT                     20:20 /* RWIVF */
+#define NV_PGRAPH_STATE_CPATTERN_COLORFMT_INVALID        0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_CPATTERN_COLORFMT_VALID          0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_CPATTERN_MONOFMT                      21:21 /* RWIVF */
+#define NV_PGRAPH_STATE_CPATTERN_MONOFMT_INVALID         0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_CPATTERN_MONOFMT_VALID           0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_CPATTERN_SELECT                       22:22 /* RWIVF */
+#define NV_PGRAPH_STATE_CPATTERN_SELECT_INVALID          0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_CPATTERN_SELECT_VALID            0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_PATTERN_COLOR0                        24:24 /* RWIVF */
+#define NV_PGRAPH_STATE_PATTERN_COLOR0_INVALID           0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_PATTERN_COLOR0_VALID             0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_PATTERN_COLOR1                        25:25 /* RWIVF */
+#define NV_PGRAPH_STATE_PATTERN_COLOR1_INVALID           0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_PATTERN_COLOR1_VALID             0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_PATTERN_PATT0                         26:26 /* RWIVF */
+#define NV_PGRAPH_STATE_PATTERN_PATT0_INVALID            0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_PATTERN_PATT0_VALID              0x00000001 /* RW--V */
+#define NV_PGRAPH_STATE_PATTERN_PATT1                         27:27 /* RWIVF */
+#define NV_PGRAPH_STATE_PATTERN_PATT1_INVALID            0x00000000 /* RWI-V */
+#define NV_PGRAPH_STATE_PATTERN_PATT1_VALID              0x00000001 /* RW--V */
+#define NV_PGRAPH_CACHE_INDEX                            0x00400728 /* RW-4R */
+#define NV_PGRAPH_CACHE_INDEX_BANK                              2:2 /* RWXVF */
+#define NV_PGRAPH_CACHE_INDEX_BANK_10                    0x00000000 /* RW--V */
+#define NV_PGRAPH_CACHE_INDEX_BANK_32                    0x00000001 /* RW--V */
+#define NV_PGRAPH_CACHE_INDEX_ADRS                             12:3 /* RWXVF */
+#define NV_PGRAPH_CACHE_INDEX_ADRS_0                     0x00000000 /* RW--V */
+#define NV_PGRAPH_CACHE_INDEX_ADRS_1024                  0x00000400 /* RW--V */
+#define NV_PGRAPH_CACHE_INDEX_OP                              14:13 /* RWXVF */
+#define NV_PGRAPH_CACHE_INDEX_OP_WR_CACHE                0x00000000 /* RW--V */
+#define NV_PGRAPH_CACHE_INDEX_OP_RD_CACHE                0x00000001 /* RW--V */
+#define NV_PGRAPH_CACHE_INDEX_OP_RD_INDEX                0x00000002 /* RW--V */
+#define NV_PGRAPH_CACHE_RAM                              0x0040072c /* RW-4R */
+#define NV_PGRAPH_CACHE_RAM_VALUE                              31:0 /* RWXVF */
+#define NV_PGRAPH_DMA_PITCH                              0x00400760 /* RW-4R */
+#define NV_PGRAPH_DMA_PITCH_S0                                 15:0 /* RWXSF */
+#define NV_PGRAPH_DMA_PITCH_S1                                31:16 /* RWXSF */
+#define NV_PGRAPH_DVD_COLORFMT                           0x00400764 /* RW-4R */
+#define NV_PGRAPH_DVD_COLORFMT_IMAGE                            5:0 /* RWNVF */
+#define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_INVALID            0x00 /* RWN-V */
+#define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_LE_V8YB8U8YA8      0x12 /* RW--V */
+#define NV_PGRAPH_DVD_COLORFMT_IMAGE_FORMAT_LE_YB8V8YA8U8      0x13 /* RW--V */
+#define NV_PGRAPH_DVD_COLORFMT_OVLY                             9:8 /* RWNVF */
+#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_INVALID             0x00 /* RWN-V */
+#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_LE_A8Y8U8V8         0x01 /* RW--V */
+#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_LE_A4V6YB6A4U6YA6   0x02 /* RW--V */
+#define NV_PGRAPH_DVD_COLORFMT_OVLY_FORMAT_TRANSPARENT         0x03 /* RW--V */
+#define NV_PGRAPH_SCALED_FORMAT                          0x00400768 /* RW-4R */
+#define NV_PGRAPH_SCALED_FORMAT_ORIGIN                        17:16 /* RWIVF */
+#define NV_PGRAPH_SCALED_FORMAT_ORIGIN_INVALID           0x00000000 /* RWI-V */
+#define NV_PGRAPH_SCALED_FORMAT_ORIGIN_CENTER            0x00000001 /* RW--V */
+#define NV_PGRAPH_SCALED_FORMAT_ORIGIN_CORNER            0x00000002 /* RW--V */
+#define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR                  24:24 /* RWIVF */
+#define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR_ZOH         0x00000000 /* RWI-V */
+#define NV_PGRAPH_SCALED_FORMAT_INTERPOLATOR_FOH         0x00000001 /* RW--V */
+#define NV_PGRAPH_PATT_COLOR0                            0x00400800 /* RW-4R */
+#define NV_PGRAPH_PATT_COLOR0_VALUE                            31:0 /* RWXUF */
+#define NV_PGRAPH_PATT_COLOR1                            0x00400804 /* RW-4R */
+#define NV_PGRAPH_PATT_COLOR1_VALUE                            31:0 /* RWXUF */
+#define NV_PGRAPH_PATT_COLORRAM(i)               (0x00400900+(i)*4) /* R--4A */
+#define NV_PGRAPH_PATT_COLORRAM__SIZE_1                          64 /*       */
+#define NV_PGRAPH_PATT_COLORRAM_VALUE                          23:0 /* R--UF */
+#define NV_PGRAPH_PATTERN(i)                     (0x00400808+(i)*4) /* RW-4A */
+#define NV_PGRAPH_PATTERN__SIZE_1                                 2 /*       */
+#define NV_PGRAPH_PATTERN_BITMAP                               31:0 /* RWXVF */
+#define NV_PGRAPH_PATTERN_SHAPE                          0x00400810 /* RW-4R */
+#define NV_PGRAPH_PATTERN_SHAPE_VALUE                           1:0 /* RWXVF */
+#define NV_PGRAPH_PATTERN_SHAPE_VALUE_8X_8Y              0x00000000 /* RW--V */
+#define NV_PGRAPH_PATTERN_SHAPE_VALUE_64X_1Y             0x00000001 /* RW--V */
+#define NV_PGRAPH_PATTERN_SHAPE_VALUE_1X_64Y             0x00000002 /* RW--V */
+#define NV_PGRAPH_PATTERN_SHAPE_SELECT                          4:4 /* RWXVF */
+#define NV_PGRAPH_PATTERN_SHAPE_SELECT_2COLOR            0x00000000 /* RW--V */
+#define NV_PGRAPH_PATTERN_SHAPE_SELECT_FULLCOLOR         0x00000001 /* RW--V */
+#define NV_PGRAPH_MONO_COLOR0                            0x00400600 /* RW-4R */
+#define NV_PGRAPH_MONO_COLOR0_VALUE                            31:0 /* RWXUF */
+#define NV_PGRAPH_ROP3                                   0x00400604 /* RW-4R */
+#define NV_PGRAPH_ROP3_VALUE                                    7:0 /* RWXVF */
+#define NV_PGRAPH_CHROMA                                 0x00400814 /* RW-4R */
+#define NV_PGRAPH_CHROMA_VALUE                                 31:0 /* RWXUF */
+#define NV_PGRAPH_BETA_AND                               0x00400608 /* RW-4R */
+#define NV_PGRAPH_BETA_AND_VALUE_FRACTION                     30:23 /* RWXUF */
+#define NV_PGRAPH_BETA_PREMULT                           0x0040060c /* RW-4R */
+#define NV_PGRAPH_BETA_PREMULT_VALUE                           31:0 /* RWXUF */
+#define NV_PGRAPH_CONTROL0                               0x00400818 /* RW-4R */
+#define NV_PGRAPH_CONTROL1                               0x0040081c /* RW-4R */
+#define NV_PGRAPH_CONTROL2                               0x00400820 /* RW-4R */
+#define NV_PGRAPH_BLEND                                  0x00400824 /* RW-4R */
+#define NV_PGRAPH_DPRAM_INDEX                            0x00400828 /* RW-4R */
+#define NV_PGRAPH_DPRAM_INDEX_ADRS                              6:0 /* RWIVF */
+#define NV_PGRAPH_DPRAM_INDEX_ADRS_0                     0x00000000 /* RWI-V */
+#define NV_PGRAPH_DPRAM_INDEX_SELECT                           10:8 /* RWIVF */
+#define NV_PGRAPH_DPRAM_INDEX_SELECT_ADRS_0              0x00000000 /* RWI-V */
+#define NV_PGRAPH_DPRAM_INDEX_SELECT_ADRS_1              0x00000001 /* RW--V */
+#define NV_PGRAPH_DPRAM_INDEX_SELECT_DATA_0              0x00000002 /* RW--V */
+#define NV_PGRAPH_DPRAM_INDEX_SELECT_DATA_1              0x00000003 /* RW--V */
+#define NV_PGRAPH_DPRAM_INDEX_SELECT_WE_0                0x00000004 /* RW--V */
+#define NV_PGRAPH_DPRAM_INDEX_SELECT_WE_1                0x00000005 /* RW--V */
+#define NV_PGRAPH_DPRAM_INDEX_SELECT_ALPHA_0             0x00000006 /* RW--V */
+#define NV_PGRAPH_DPRAM_INDEX_SELECT_ALPHA_1             0x00000007 /* RW--V */
+#define NV_PGRAPH_DPRAM_DATA                             0x0040082c /* RW-4R */
+#define NV_PGRAPH_DPRAM_DATA_VALUE                             31:0 /* RWXVF */
+#define NV_PGRAPH_DPRAM_ADRS_0                           0x0040082c /* RW-4R */
+#define NV_PGRAPH_DPRAM_ADRS_0__ALIAS_1        NV_PGRAPH_DPRAM_DATA /*       */
+#define NV_PGRAPH_DPRAM_ADRS_0_VALUE                           19:0 /* RWXVF */
+#define NV_PGRAPH_DPRAM_ADRS_1                           0x0040082c /* RW-4R */
+#define NV_PGRAPH_DPRAM_ADRS_1__ALIAS_1        NV_PGRAPH_DPRAM_DATA /*       */
+#define NV_PGRAPH_DPRAM_ADRS_1_VALUE                           19:0 /* RWXVF */
+#define NV_PGRAPH_DPRAM_DATA_0                           0x0040082c /* RW-4R */
+#define NV_PGRAPH_DPRAM_DATA_0__ALIAS_1        NV_PGRAPH_DPRAM_DATA /*       */
+#define NV_PGRAPH_DPRAM_DATA_0_VALUE                           31:0 /* RWXVF */
+#define NV_PGRAPH_DPRAM_DATA_1                           0x0040082c /* RW-4R */
+#define NV_PGRAPH_DPRAM_DATA_1__ALIAS_1        NV_PGRAPH_DPRAM_DATA /*       */
+#define NV_PGRAPH_DPRAM_DATA_1_VALUE                           31:0 /* RWXVF */
+#define NV_PGRAPH_DPRAM_WE_0                             0x0040082c /* RW-4R */
+#define NV_PGRAPH_DPRAM_WE_0__ALIAS_1          NV_PGRAPH_DPRAM_DATA /*       */
+#define NV_PGRAPH_DPRAM_WE_0_VALUE                             23:0 /* RWXVF */
+#define NV_PGRAPH_DPRAM_WE_1                             0x0040082c /* RW-4R */
+#define NV_PGRAPH_DPRAM_WE_1__ALIAS_1          NV_PGRAPH_DPRAM_DATA /*       */
+#define NV_PGRAPH_DPRAM_WE_1_VALUE                             23:0 /* RWXVF */
+#define NV_PGRAPH_DPRAM_ALPHA_0                          0x0040082c /* RW-4R */
+#define NV_PGRAPH_DPRAM_ALPHA_0__ALIAS_1       NV_PGRAPH_DPRAM_DATA /*       */
+#define NV_PGRAPH_DPRAM_ALPHA_0_VALUE                          31:0 /* RWXVF */
+#define NV_PGRAPH_DPRAM_ALPHA_1                          0x0040082c /* RW-4R */
+#define NV_PGRAPH_DPRAM_ALPHA_1__ALIAS_1       NV_PGRAPH_DPRAM_DATA /*       */
+#define NV_PGRAPH_DPRAM_ALPHA_1_VALUE                          31:0 /* RWXVF */
+#define NV_PGRAPH_STORED_FMT                             0x00400830 /* RW-4R */
+#define NV_PGRAPH_STORED_FMT_MONO0                              5:0 /* RWXVF */
+#define NV_PGRAPH_STORED_FMT_PATT0                             13:8 /* RWXVF */
+#define NV_PGRAPH_STORED_FMT_PATT1                            21:16 /* RWXVF */
+#define NV_PGRAPH_STORED_FMT_CHROMA                           29:24 /* RWXVF */
+#define NV_PGRAPH_FORMATS                                0x00400618 /* RW-4R */
+#define NV_PGRAPH_FORMATS_ROP                                   2:0 /* R-XVF */
+#define NV_PGRAPH_FORMATS_ROP_Y8                         0x00000000 /* -W--V */
+#define NV_PGRAPH_FORMATS_ROP_RGB15                      0x00000001 /* -W--V */
+#define NV_PGRAPH_FORMATS_ROP_RGB16                      0x00000002 /* -W--V */
+#define NV_PGRAPH_FORMATS_ROP_Y16                        0x00000003 /* -W--V */
+#define NV_PGRAPH_FORMATS_ROP_INVALID                    0x00000004 /* -W--V */
+#define NV_PGRAPH_FORMATS_ROP_RGB24                      0x00000005 /* -W--V */
+#define NV_PGRAPH_FORMATS_ROP_RGB30                      0x00000006 /* -W--V */
+#define NV_PGRAPH_FORMATS_ROP_Y32                        0x00000007 /* -W--V */
+#define NV_PGRAPH_FORMATS_SRC                                   9:4 /* R-XVF */
+#define NV_PGRAPH_FORMATS_SRC_INVALID                    0x00000000 /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_Y8                      0x00000001 /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_X16A8Y8                 0x00000002 /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_X24Y8                   0x00000003 /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_A1R5G5B5                0x00000006 /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_X1R5G5B5                0x00000007 /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_X16A1R5G5B5             0x00000008 /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_X17R5G5B5               0x00000009 /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_R5G6B5                  0x0000000A /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_A16R5G6B5               0x0000000B /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_X16R5G6B5               0x0000000C /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_A8R8G8B8                0x0000000D /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_X8R8G8B8                0x0000000E /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_Y16                     0x0000000F /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_A16Y16                  0x00000010 /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_X16Y16                  0x00000011 /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_V8YB8U8YA8              0x00000012 /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_YB8V8YA8U8              0x00000013 /* RW--V */
+#define NV_PGRAPH_FORMATS_SRC_LE_Y32                     0x00000014 /* RW--V */
+#define NV_PGRAPH_FORMATS_FB                                  15:12 /* R-XVF */
+#define NV_PGRAPH_FORMATS_FB_INVALID                     0x00000000 /* RWI-V */
+#define NV_PGRAPH_FORMATS_FB_Y8                          0x00000001 /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_X1R5G5B5_Z1R5G5B5           0x00000002 /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_X1R5G5B5_O1R5G5B5           0x00000003 /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_A1R5G5B5                    0x00000004 /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_R5G6B5                      0x00000005 /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_Y16                         0x00000006 /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_X8R8G8B8_Z8R8G8B8           0x00000007 /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_X8R8G8B8_O1Z7R8G8B8         0x00000008 /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_X1A7R8G8B8_Z1A7R8G8B8       0x00000009 /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_X1A7R8G8B8_O1A7R8G8B8       0x0000000a /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_X8R8G8B8_O8R8G8B8           0x0000000b /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_A8R8G8B8                    0x0000000c /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_Y32                         0x0000000d /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_V8YB8U8YA8                  0x0000000e /* RW--V */
+#define NV_PGRAPH_FORMATS_FB_YB8V8YA8U8                  0x0000000f /* RW--V */ 
+#define NV_PGRAPH_ABS_X_RAM(i)                   (0x00400400+(i)*4) /* RW-4A */
+#define NV_PGRAPH_ABS_X_RAM__SIZE_1                              32 /*       */
+#define NV_PGRAPH_ABS_X_RAM_VALUE                              31:0 /* RWXUF */
+#define NV_PGRAPH_X_RAM_BPORT(i)                 (0x00400c00+(i)*4) /* R--4A */
+#define NV_PGRAPH_X_RAM_BPORT__SIZE_1                            32 /*       */
+#define NV_PGRAPH_X_RAM_BPORT_VALUE                            31:0 /* R--UF */
+#define NV_PGRAPH_ABS_Y_RAM(i)                   (0x00400480+(i)*4) /* RW-4A */
+#define NV_PGRAPH_ABS_Y_RAM__SIZE_1                              32 /*       */
+#define NV_PGRAPH_ABS_Y_RAM_VALUE                              31:0 /* RWXUF */
+#define NV_PGRAPH_Y_RAM_BPORT(i)                 (0x00400c80+(i)*4) /* R--4A */
+#define NV_PGRAPH_Y_RAM_BPORT__SIZE_1                            32 /*       */
+#define NV_PGRAPH_Y_RAM_BPORT_VALUE                            31:0 /* R--UF */
+#define NV_PGRAPH_XY_LOGIC_MISC0                         0x00400514 /* RW-4R */
+#define NV_PGRAPH_XY_LOGIC_MISC0_COUNTER                       17:0 /* RWBUF */
+#define NV_PGRAPH_XY_LOGIC_MISC0_COUNTER_0               0x00000000 /* RWB-V */
+#define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION                    20:20 /* RWVVF */
+#define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION_NONZERO       0x00000000 /* RWV-V */
+#define NV_PGRAPH_XY_LOGIC_MISC0_DIMENSION_ZERO          0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC0_INDEX                        31:28 /* RWBUF */
+#define NV_PGRAPH_XY_LOGIC_MISC0_INDEX_0                 0x00000000 /* RWB-V */
+#define NV_PGRAPH_XY_LOGIC_MISC1                         0x00400518 /* RW-4R */
+#define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL                        0:0 /* RWNVF */
+#define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL_NEEDED          0x00000000 /* RWN-V */
+#define NV_PGRAPH_XY_LOGIC_MISC1_INITIAL_DONE            0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX                      4:4 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX_NOTNULL       0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPX_NULL          0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY                      5:5 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY_NOTNULL       0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC1_XTRACLIPY_NULL          0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX                    12:12 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX_UUMAX         0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XIMAX_IMAGEMAX      0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX                    16:16 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX_UUMAX         0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_YIMAX_IMAGEMAX      0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA                    20:20 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA_CLIPMAX       0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC1_SEL_XXTRA_IMAGEMAX      0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC2                         0x0040051C /* RW-4R */
+#define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF                        0:0 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF_DISABLE         0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC2_HANDOFF_ENABLE          0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX                      4:4 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX_NOTNULL       0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPX_NULL          0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY                      5:5 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY_NOTNULL       0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC2_XTRACLIPY_NULL          0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX                    12:12 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX_UCMAX         0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XIMAX_IMAGEMAX      0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX                    16:16 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX_UCMAX         0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_YIMAX_IMAGEMAX      0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA                    20:20 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA_CLIPMAX       0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC2_SEL_XXTRA_IMAGEMAX      0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC3                         0x00400520 /* RW-4R */
+#define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0                     0:0 /* RWXVF */
+#define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0_NULL         0x00000000 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC3_WDIMY_EQ_0_TRUE         0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY                   4:4 /* RWXVF */
+#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY_NULL       0x00000000 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WDIMY_TRUE       0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX                      8:8 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX_NULL          0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC3_RELOAD_WX_TRUE          0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG                     12:12 /* RWIVF */
+#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG_NULL           0x00000000 /* RWI-V */
+#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_ALG_TRUE           0x00000001 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_DIMX                    22:16 /* RWXUF */
+#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_DIMX_0             0x00000000 /* RW--V */
+#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_WDIMX                   30:24 /* RWXUF */
+#define NV_PGRAPH_XY_LOGIC_MISC3_TEXT_WDIMX_0            0x00000000 /* RW--V */
+#define NV_PGRAPH_X_MISC                                 0x00400500 /* RW-4R */
+#define NV_PGRAPH_X_MISC_BIT33_0                                0:0 /* RWNVF */
+#define NV_PGRAPH_X_MISC_BIT33_0_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_X_MISC_BIT33_1                                1:1 /* RWNVF */
+#define NV_PGRAPH_X_MISC_BIT33_1_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_X_MISC_BIT33_2                                2:2 /* RWNVF */
+#define NV_PGRAPH_X_MISC_BIT33_2_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_X_MISC_BIT33_3                                3:3 /* RWNVF */
+#define NV_PGRAPH_X_MISC_BIT33_3_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_X_MISC_RANGE_0                                4:4 /* RWNVF */
+#define NV_PGRAPH_X_MISC_RANGE_0_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_X_MISC_RANGE_1                                5:5 /* RWNVF */
+#define NV_PGRAPH_X_MISC_RANGE_1_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_X_MISC_RANGE_2                                6:6 /* RWNVF */
+#define NV_PGRAPH_X_MISC_RANGE_2_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_X_MISC_RANGE_3                                7:7 /* RWNVF */
+#define NV_PGRAPH_X_MISC_RANGE_3_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_X_MISC_ADDER_OUTPUT                         29:28 /* RWXVF */
+#define NV_PGRAPH_X_MISC_ADDER_OUTPUT_EQ_0               0x00000000 /* RW--V */
+#define NV_PGRAPH_X_MISC_ADDER_OUTPUT_LT_0               0x00000001 /* RW--V */
+#define NV_PGRAPH_X_MISC_ADDER_OUTPUT_GT_0               0x00000002 /* RW--V */
+#define NV_PGRAPH_Y_MISC                                 0x00400504 /* RW-4R */
+#define NV_PGRAPH_Y_MISC_BIT33_0                                0:0 /* RWNVF */
+#define NV_PGRAPH_Y_MISC_BIT33_0_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_Y_MISC_BIT33_1                                1:1 /* RWNVF */
+#define NV_PGRAPH_Y_MISC_BIT33_1_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_Y_MISC_BIT33_2                                2:2 /* RWNVF */
+#define NV_PGRAPH_Y_MISC_BIT33_2_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_Y_MISC_BIT33_3                                3:3 /* RWNVF */
+#define NV_PGRAPH_Y_MISC_BIT33_3_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_Y_MISC_RANGE_0                                4:4 /* RWNVF */
+#define NV_PGRAPH_Y_MISC_RANGE_0_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_Y_MISC_RANGE_1                                5:5 /* RWNVF */
+#define NV_PGRAPH_Y_MISC_RANGE_1_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_Y_MISC_RANGE_2                                6:6 /* RWNVF */
+#define NV_PGRAPH_Y_MISC_RANGE_2_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_Y_MISC_RANGE_3                                7:7 /* RWNVF */
+#define NV_PGRAPH_Y_MISC_RANGE_3_0                       0x00000000 /* RWN-V */
+#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT                         29:28 /* RWXVF */
+#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_EQ_0               0x00000000 /* RW--V */
+#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_LT_0               0x00000001 /* RW--V */
+#define NV_PGRAPH_Y_MISC_ADDER_OUTPUT_GT_0               0x00000002 /* RW--V */
+#define NV_PGRAPH_ABS_UCLIP_XMIN                         0x0040053C /* RW-4R */
+#define NV_PGRAPH_ABS_UCLIP_XMIN_VALUE                         15:0 /* RWXSF */
+#define NV_PGRAPH_ABS_UCLIP_XMAX                         0x00400544 /* RW-4R */
+#define NV_PGRAPH_ABS_UCLIP_XMAX_VALUE                         17:0 /* RWXSF */
+#define NV_PGRAPH_ABS_UCLIP_YMIN                         0x00400540 /* RW-4R */
+#define NV_PGRAPH_ABS_UCLIP_YMIN_VALUE                         15:0 /* RWXSF */
+#define NV_PGRAPH_ABS_UCLIP_YMAX                         0x00400548 /* RW-4R */
+#define NV_PGRAPH_ABS_UCLIP_YMAX_VALUE                         17:0 /* RWXSF */
+#define NV_PGRAPH_ABS_UCLIPA_XMIN                        0x00400560 /* RW-4R */
+#define NV_PGRAPH_ABS_UCLIPA_XMIN_VALUE                        15:0 /* RWXSF */
+#define NV_PGRAPH_ABS_UCLIPA_XMAX                        0x00400568 /* RW-4R */
+#define NV_PGRAPH_ABS_UCLIPA_XMAX_VALUE                        17:0 /* RWXSF */
+#define NV_PGRAPH_ABS_UCLIPA_YMIN                        0x00400564 /* RW-4R */
+#define NV_PGRAPH_ABS_UCLIPA_YMIN_VALUE                        15:0 /* RWXSF */
+#define NV_PGRAPH_ABS_UCLIPA_YMAX                        0x0040056C /* RW-4R */
+#define NV_PGRAPH_ABS_UCLIPA_YMAX_VALUE                        17:0 /* RWXSF */
+#define NV_PGRAPH_SOURCE_COLOR                           0x0040050C /* RW-4R */
+#define NV_PGRAPH_SOURCE_COLOR_VALUE                           31:0 /* RWNVF */
+#define NV_PGRAPH_SOURCE_COLOR_VALUE_0                   0x00000000 /* RWN-V */
+#define NV_PGRAPH_VALID1                                 0x00400508 /* RW-4R */
+#define NV_PGRAPH_VALID1_VLD                                   22:0 /* RWNVF */
+#define NV_PGRAPH_VALID1_VLD_0                           0x00000000 /* RWN-V */
+#define NV_PGRAPH_VALID1_CLIP_MIN                             28:28 /* RWIVF */
+#define NV_PGRAPH_VALID1_CLIP_MIN_NO_ERROR               0x00000000 /* RWI-V */
+#define NV_PGRAPH_VALID1_CLIP_MIN_ONLY                   0x00000001 /* RW--V */
+#define NV_PGRAPH_VALID1_CLIPA_MIN                            29:29 /* RWIVF */
+#define NV_PGRAPH_VALID1_CLIPA_MIN_NO_ERROR              0x00000000 /* RWI-V */
+#define NV_PGRAPH_VALID1_CLIPA_MIN_ONLY                  0x00000001 /* RW--V */
+#define NV_PGRAPH_VALID1_CLIP_MAX                             30:30 /* RWIVF */
+#define NV_PGRAPH_VALID1_CLIP_MAX_NO_ERROR               0x00000000 /* RWI-V */
+#define NV_PGRAPH_VALID1_CLIP_MAX_ONLY                   0x00000001 /* RW--V */
+#define NV_PGRAPH_VALID1_CLIPA_MAX                            31:31 /* RWIVF */
+#define NV_PGRAPH_VALID1_CLIPA_MAX_NO_ERROR              0x00000000 /* RWI-V */
+#define NV_PGRAPH_VALID1_CLIPA_MAX_ONLY                  0x00000001 /* RW--V */
+#define NV_PGRAPH_VALID2                                 0x00400578 /* RW-4R */
+#define NV_PGRAPH_VALID2_VLD2                                  28:0 /* RWNVF */
+#define NV_PGRAPH_VALID2_VLD2_0                          0x00000000 /* RWN-V */
+#define NV_PGRAPH_ABS_ICLIP_XMAX                         0x00400534 /* RW-4R */
+#define NV_PGRAPH_ABS_ICLIP_XMAX_VALUE                         17:0 /* RWXSF */
+#define NV_PGRAPH_ABS_ICLIP_YMAX                         0x00400538 /* RW-4R */
+#define NV_PGRAPH_ABS_ICLIP_YMAX_VALUE                         17:0 /* RWXSF */
+#define NV_PGRAPH_CLIPX_0                                0x00400524 /* RW-4R */
+#define NV_PGRAPH_CLIPX_0_CLIP0_MIN                             1:0 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP0_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP0_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP0_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP0_MAX                             3:2 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP0_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP0_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP0_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP1_MIN                             5:4 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP1_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP1_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP1_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP1_MAX                             7:6 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP1_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP1_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP1_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP2_MIN                             9:8 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP2_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP2_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP2_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP2_MAX                           11:10 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP2_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP2_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP2_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP3_MIN                           13:12 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP3_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP3_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP3_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP3_MAX                           15:14 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP3_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP3_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP3_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP4_MIN                           17:16 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP4_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP4_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP4_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP4_MAX                           19:18 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP4_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP4_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP4_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP5_MIN                           21:20 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP5_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP5_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP5_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP5_MAX                           23:22 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP5_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP5_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP5_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP6_MIN                           25:24 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP6_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP6_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP6_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP6_MAX                           27:26 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP6_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP6_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP6_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP7_MIN                           29:28 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP7_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP7_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP7_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP7_MAX                           31:30 /* RWNVF */
+#define NV_PGRAPH_CLIPX_0_CLIP7_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_0_CLIP7_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_0_CLIP7_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1                                0x00400528 /* RW-4R */
+#define NV_PGRAPH_CLIPX_1_CLIP8_MIN                             1:0 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP8_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP8_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP8_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP8_MAX                             3:2 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP8_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP8_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP8_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP9_MIN                             5:4 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP9_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP9_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP9_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP9_MAX                             7:6 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP9_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP9_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP9_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP10_MIN                            9:8 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP10_MIN_GT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP10_MIN_LT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP10_MIN_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP10_MAX                          11:10 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP10_MAX_LT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP10_MAX_GT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP10_MAX_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP11_MIN                          13:12 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP11_MIN_GT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP11_MIN_LT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP11MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP11_MAX                          15:14 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP11_MAX_LT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP11_MAX_GT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP11_MAX_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP12_MIN                          17:16 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP12_MIN_GT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP12_MIN_LT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP12_MIN_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP12_MAX                          19:18 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP12_MAX_LT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP12_MAX_GT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP12_MAX_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP13_MIN                          21:20 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP13_MIN_GT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP13_MIN_LT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP13_MIN_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP13_MAX                          23:22 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP13_MAX_LT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP13_MAX_GT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP13_MAX_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP14_MIN                          25:24 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP14_MIN_GT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP14_MIN_LT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP14_MIN_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP14_MAX                          27:26 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP14_MAX_LT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP14_MAX_GT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP14_MAX_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP15_MIN                          29:28 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP15_MIN_GT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP15_MIN_LT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP15_MIN_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP15_MAX                          31:30 /* RWNVF */
+#define NV_PGRAPH_CLIPX_1_CLIP15_MAX_LT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPX_1_CLIP15_MAX_GT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPX_1_CLIP15_MAX_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0                                0x0040052c /* RW-4R */
+#define NV_PGRAPH_CLIPY_0_CLIP0_MIN                             1:0 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP0_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP0_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP0_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP0_MAX                             3:2 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP0_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP0_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP0_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP1_MIN                             5:4 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP1_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP1_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP1_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP1_MAX                             7:6 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP1_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP1_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP1_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP2_MIN                             9:8 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP2_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP2_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP2_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP2_MAX                           11:10 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP2_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP2_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP2_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP3_MIN                           13:12 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP3_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP3_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP3_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP3_MAX                           15:14 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP3_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP3_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP3_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP4_MIN                           17:16 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP4_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP4_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP4_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP4_MAX                           19:18 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP4_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP4_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP4_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP5_MIN                           21:20 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP5_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP5_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP5_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP5_MAX                           23:22 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP5_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP5_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP5_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP6_MIN                           25:24 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP6_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP6_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP6_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP6_MAX                           27:26 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP6_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP6_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP6_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP7_MIN                           29:28 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP7_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP7_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP7_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP7_MAX                           31:30 /* RWNVF */
+#define NV_PGRAPH_CLIPY_0_CLIP7_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_0_CLIP7_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_0_CLIP7_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1                                0x00400530 /* RW-4R */
+#define NV_PGRAPH_CLIPY_1_CLIP8_MIN                             1:0 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP8_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP8_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP8_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP8_MAX                             3:2 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP8_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP8_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP8_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP9_MIN                             5:4 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP9_MIN_GT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP9_MIN_LT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP9_MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP9_MAX                             7:6 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP9_MAX_LT                   0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP9_MAX_GT                   0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP9_MAX_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP10_MIN                            9:8 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP10_MIN_GT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP10_MIN_LT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP10_MIN_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP10_MAX                          11:10 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP10_MAX_LT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP10_MAX_GT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP10_MAX_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP11_MIN                          13:12 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP11_MIN_GT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP11_MIN_LT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP11MIN_EQ                   0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP11_MAX                          15:14 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP11_MAX_LT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP11_MAX_GT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP11_MAX_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP12_MIN                          17:16 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP12_MIN_GT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP12_MIN_LT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP12_MIN_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP12_MAX                          19:18 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP12_MAX_LT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP12_MAX_GT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP12_MAX_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP13_MIN                          21:20 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP13_MIN_GT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP13_MIN_LT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP13_MIN_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP13_MAX                          23:22 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP13_MAX_LT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP13_MAX_GT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP13_MAX_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP14_MIN                          25:24 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP14_MIN_GT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP14_MIN_LT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP14_MIN_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP14_MAX                          27:26 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP14_MAX_LT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP14_MAX_GT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP14_MAX_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP15_MIN                          29:28 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP15_MIN_GT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP15_MIN_LT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP15_MIN_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP15_MAX                          31:30 /* RWNVF */
+#define NV_PGRAPH_CLIPY_1_CLIP15_MAX_LT                  0x00000000 /* RW--V */
+#define NV_PGRAPH_CLIPY_1_CLIP15_MAX_GT                  0x00000001 /* RWN-V */
+#define NV_PGRAPH_CLIPY_1_CLIP15_MAX_EQ                  0x00000002 /* RW--V */
+#define NV_PGRAPH_MISC24_0                               0x00400510 /* RW-4R */
+#define NV_PGRAPH_MISC24_0_VALUE                               23:0 /* RWXUF */
+#define NV_PGRAPH_MISC24_1                               0x00400570 /* RW-4R */
+#define NV_PGRAPH_MISC24_1_VALUE                               23:0 /* RWXUF */
+#define NV_PGRAPH_MISC24_2                               0x00400574 /* RW-4R */
+#define NV_PGRAPH_MISC24_2_VALUE                               23:0 /* RWXUF */
+#define NV_PGRAPH_PASSTHRU_0                             0x0040057C /* RW-4R */
+#define NV_PGRAPH_PASSTHRU_0_VALUE                             31:0 /* RWXUF */
+#define NV_PGRAPH_PASSTHRU_1                             0x00400580 /* RW-4R */
+#define NV_PGRAPH_PASSTHRU_1_VALUE                             31:0 /* RWXUF */
+#define NV_PGRAPH_PASSTHRU_2                             0x00400584 /* RW-4R */
+#define NV_PGRAPH_PASSTHRU_2_VALUE                             31:0 /* RWXUF */
+#define NV_PGRAPH_U_RAM(i)                       (0x00400d00+(i)*4) /* RW-4A */
+#define NV_PGRAPH_U_RAM__SIZE_1                                  16 /*       */
+#define NV_PGRAPH_U_RAM_VALUE                                  31:6 /* RWXFF */
+#define NV_PGRAPH_V_RAM(i)                       (0x00400d40+(i)*4) /* RW-4A */
+#define NV_PGRAPH_V_RAM__SIZE_1                                  16 /*       */
+#define NV_PGRAPH_V_RAM_VALUE                                  31:6 /* RWXFF */
+#define NV_PGRAPH_M_RAM(i)                       (0x00400d80+(i)*4) /* RW-4A */
+#define NV_PGRAPH_M_RAM__SIZE_1                                  16 /*       */
+#define NV_PGRAPH_M_RAM_VALUE                                  31:6 /* RWXFF */
+#define NV_PGRAPH_DMA_START_0                            0x00401000 /* RW-4R */
+#define NV_PGRAPH_DMA_START_0_VALUE                            31:0 /* RWXUF */
+#define NV_PGRAPH_DMA_START_1                            0x00401004 /* RW-4R */
+#define NV_PGRAPH_DMA_START_1_VALUE                            31:0 /* RWXUF */
+#define NV_PGRAPH_DMA_LENGTH                             0x00401008 /* RW-4R */
+#define NV_PGRAPH_DMA_LENGTH_VALUE                             21:0 /* RWXUF */
+#define NV_PGRAPH_DMA_MISC                               0x0040100C /* RW-4R */
+#define NV_PGRAPH_DMA_MISC_COUNT                               15:0 /* RWXUF */
+#define NV_PGRAPH_DMA_MISC_FMT_SRC                            18:16 /* RWXVF */
+#define NV_PGRAPH_DMA_MISC_FMT_DST                            22:20 /* RWXVF */
+#define NV_PGRAPH_DMA_DATA_0                             0x00401020 /* RW-4R */
+#define NV_PGRAPH_DMA_DATA_0_VALUE                             31:0 /* RWXUF */
+#define NV_PGRAPH_DMA_DATA_1                             0x00401024 /* RW-4R */
+#define NV_PGRAPH_DMA_DATA_1_VALUE                             31:0 /* RWXUF */
+#define NV_PGRAPH_DMA_RM                                 0x00401030 /* RW-4R */
+#define NV_PGRAPH_DMA_RM_ASSIST_A                               0:0 /* RWIVF */
+#define NV_PGRAPH_DMA_RM_ASSIST_A_NOT_PENDING            0x00000000 /* R-I-V */
+#define NV_PGRAPH_DMA_RM_ASSIST_A_PENDING                0x00000001 /* R---V */
+#define NV_PGRAPH_DMA_RM_ASSIST_A_RESET                  0x00000001 /* -W--C */
+#define NV_PGRAPH_DMA_RM_ASSIST_B                               1:1 /* RWIVF */
+#define NV_PGRAPH_DMA_RM_ASSIST_B_NOT_PENDING            0x00000000 /* R-I-V */
+#define NV_PGRAPH_DMA_RM_ASSIST_B_PENDING                0x00000001 /* R---V */
+#define NV_PGRAPH_DMA_RM_ASSIST_B_RESET                  0x00000001 /* -W--C */
+#define NV_PGRAPH_DMA_RM_WRITE_REQ                              4:4 /* CWIVF */
+#define NV_PGRAPH_DMA_RM_WRITE_REQ_NOT_PENDING           0x00000000 /* CWI-V */
+#define NV_PGRAPH_DMA_RM_WRITE_REQ_PENDING               0x00000001 /* -W--T */
+#define NV_PGRAPH_DMA_A_XLATE_INST                       0x00401040 /* RW-4R */
+#define NV_PGRAPH_DMA_A_XLATE_INST_VALUE                       15:0 /* RWXUF */
+#define NV_PGRAPH_DMA_A_CONTROL                          0x00401044 /* RW-4R */
+#define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE                    12:12 /* RWIVF */
+#define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE_NOT_PRESENT   0x00000000 /* RWI-V */
+#define NV_PGRAPH_DMA_A_CONTROL_PAGE_TABLE_PRESENT       0x00000001 /* RW--V */
+#define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY                    13:13 /* RWXVF */
+#define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY_NOT_LINEAR    0x00000000 /* RW--V */
+#define NV_PGRAPH_DMA_A_CONTROL_PAGE_ENTRY_LINEAR        0x00000001 /* RW--V */
+#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE                   17:16 /* RWXUF */
+#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_NVM          0x00000000 /* RW--V */
+#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_PCI          0x00000002 /* RW--V */
+#define NV_PGRAPH_DMA_A_CONTROL_TARGET_NODE_AGP          0x00000003 /* RW--V */
+#define NV_PGRAPH_DMA_A_CONTROL_ADJUST                        31:20 /* RWXUF */
+#define NV_PGRAPH_DMA_A_LIMIT                            0x00401048 /* RW-4R */
+#define NV_PGRAPH_DMA_A_LIMIT_OFFSET                           31:0 /* RWXUF */
+#define NV_PGRAPH_DMA_A_TLB_PTE                          0x0040104C /* RW-4R */
+#define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS                          1:1 /* RWXVF */
+#define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS_READ_ONLY         0x00000000 /* RW--V */
+#define NV_PGRAPH_DMA_A_TLB_PTE_ACCESS_READ_WRITE        0x00000001 /* RW--V */
+#define NV_PGRAPH_DMA_A_TLB_PTE_FRAME_ADDRESS                 31:12 /* RWXUF */
+#define NV_PGRAPH_DMA_A_TLB_TAG                          0x00401050 /* RW-4R */
+#define NV_PGRAPH_DMA_A_TLB_TAG_ADDRESS                       31:12 /* RWXUF */
+#define NV_PGRAPH_DMA_A_ADJ_OFFSET                       0x00401054 /* RW-4R */
+#define NV_PGRAPH_DMA_A_ADJ_OFFSET_VALUE                       31:0 /* RWXUF */
+#define NV_PGRAPH_DMA_A_OFFSET                           0x00401058 /* RW-4R */
+#define NV_PGRAPH_DMA_A_OFFSET_VALUE                           31:0 /* RWXUF */
+#define NV_PGRAPH_DMA_A_SIZE                             0x0040105C /* RW-4R */
+#define NV_PGRAPH_DMA_A_SIZE_VALUE                             24:0 /* RWXUF */
+#define NV_PGRAPH_DMA_A_Y_SIZE                           0x00401060 /* RW-4R */
+#define NV_PGRAPH_DMA_A_Y_SIZE_VALUE                           10:0 /* RWXUF */
+#define NV_PGRAPH_DMA_B_XLATE_INST                       0x00401080 /* RW-4R */
+#define NV_PGRAPH_DMA_B_XLATE_INST_VALUE                       15:0 /* RWXUF */
+#define NV_PGRAPH_DMA_B_CONTROL                          0x00401084 /* RW-4R */
+#define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE                    12:12 /* RWIVF */
+#define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE_NOT_PRESENT   0x00000000 /* RWI-V */
+#define NV_PGRAPH_DMA_B_CONTROL_PAGE_TABLE_PRESENT       0x00000001 /* RW--V */
+#define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY                    13:13 /* RWXVF */
+#define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY_NOT_LINEAR    0x00000000 /* RW--V */
+#define NV_PGRAPH_DMA_B_CONTROL_PAGE_ENTRY_LINEAR        0x00000001 /* RW--V */
+#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE                   17:16 /* RWXUF */
+#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_NVM          0x00000000 /* RW--V */
+#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_PCI          0x00000002 /* RW--V */
+#define NV_PGRAPH_DMA_B_CONTROL_TARGET_NODE_AGP          0x00000003 /* RW--V */
+#define NV_PGRAPH_DMA_B_CONTROL_ADJUST                        31:20 /* RWXUF */
+#define NV_PGRAPH_DMA_B_LIMIT                            0x00401088 /* RW-4R */
+#define NV_PGRAPH_DMA_B_LIMIT_OFFSET                           31:0 /* RWXUF */
+#define NV_PGRAPH_DMA_B_TLB_PTE                          0x0040108C /* RW-4R */
+#define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS                          1:1 /* RWXVF */
+#define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS_READ_ONLY         0x00000000 /* RW--V */
+#define NV_PGRAPH_DMA_B_TLB_PTE_ACCESS_READ_WRITE        0x00000001 /* RW--V */
+#define NV_PGRAPH_DMA_B_TLB_PTE_FRAME_ADDRESS                 31:12 /* RWXUF */
+#define NV_PGRAPH_DMA_B_TLB_TAG                          0x00401090 /* RW-4R */
+#define NV_PGRAPH_DMA_B_TLB_TAG_ADDRESS                       31:12 /* RWXUF */
+#define NV_PGRAPH_DMA_B_ADJ_OFFSET                       0x00401094 /* RW-4R */
+#define NV_PGRAPH_DMA_B_ADJ_OFFSET_VALUE                       31:0 /* RWXUF */
+#define NV_PGRAPH_DMA_B_OFFSET                           0x00401098 /* RW-4R */
+#define NV_PGRAPH_DMA_B_OFFSET_VALUE                           31:0 /* RWXUF */
+#define NV_PGRAPH_DMA_B_SIZE                             0x0040109C /* RW-4R */
+#define NV_PGRAPH_DMA_B_SIZE_VALUE                             24:0 /* RWXUF */
+#define NV_PGRAPH_DMA_B_Y_SIZE                           0x004010A0 /* RW-4R */
+#define NV_PGRAPH_DMA_B_Y_SIZE_VALUE                           10:0 /* RWXUF */
+
+/* Framebuffer registers */
+#define NV_PFB                                0x00100FFF:0x00100000 /* RW--D */
+#define NV_PFB_BOOT_0                                    0x00100000 /* RW-4R */
+#define NV_PFB_BOOT_0_RAM_AMOUNT                                1:0 /* RW-VF */
+#define NV_PFB_BOOT_0_RAM_AMOUNT_32MB                    0x00000000 /* RW--V */
+#define NV_PFB_BOOT_0_RAM_AMOUNT_4MB                     0x00000001 /* RW--V */
+#define NV_PFB_BOOT_0_RAM_AMOUNT_8MB                     0x00000002 /* RW--V */
+#define NV_PFB_BOOT_0_RAM_AMOUNT_16MB                    0x00000003 /* RW--V */
+#define NV_PFB_BOOT_0_RAM_WIDTH_128                             2:2 /* RW-VF */
+#define NV_PFB_BOOT_0_RAM_WIDTH_128_OFF                  0x00000000 /* RW--V */
+#define NV_PFB_BOOT_0_RAM_WIDTH_128_ON                   0x00000001 /* RW--V */
+#define NV_PFB_BOOT_0_RAM_TYPE                                  4:3 /* RW-VF */
+#define NV_PFB_BOOT_0_RAM_TYPE_256K                      0x00000000 /* RW--V */
+#define NV_PFB_BOOT_0_RAM_TYPE_512K_2BANK                0x00000001 /* RW--V */
+#define NV_PFB_BOOT_0_RAM_TYPE_512K_4BANK                0x00000002 /* RW--V */
+#define NV_PFB_BOOT_0_RAM_TYPE_1024K_2BANK               0x00000003 /* RW--V */
+#define NV_PFB_CONFIG_0                                  0x00100200 /* RW-4R */
+#define NV_PFB_CONFIG_0_TYPE                                   14:0 /* RWIVF */
+#define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_8BPP          0x00000120 /* RW--V */
+#define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_16BPP         0x00000220 /* RW--V */
+#define NV_PFB_CONFIG_0_TYPE_OLD1024_FIXED_32BPP         0x00000320 /* RW--V */
+#define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_8BPP            0x00004120 /* RW--V */
+#define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_16BPP           0x00004220 /* RW--V */
+#define NV_PFB_CONFIG_0_TYPE_OLD1024_VAR_32BPP           0x00004320 /* RW--V */
+#define NV_PFB_CONFIG_0_TYPE_TETRIS                      0x00002000 /* RW--V */
+#define NV_PFB_CONFIG_0_TYPE_NOTILING                    0x00001114 /* RWI-V */
+#define NV_PFB_CONFIG_0_TETRIS_MODE                           17:15 /* RWI-F */
+#define NV_PFB_CONFIG_0_TETRIS_MODE_PASS                 0x00000000 /* RWI-V */
+#define NV_PFB_CONFIG_0_TETRIS_MODE_1                    0x00000001 /* RW--V */
+#define NV_PFB_CONFIG_0_TETRIS_MODE_2                    0x00000002 /* RW--V */
+#define NV_PFB_CONFIG_0_TETRIS_MODE_3                    0x00000003 /* RW--V */
+#define NV_PFB_CONFIG_0_TETRIS_MODE_4                    0x00000004 /* RW--V */
+#define NV_PFB_CONFIG_0_TETRIS_MODE_5                    0x00000005 /* RW--V */
+#define NV_PFB_CONFIG_0_TETRIS_MODE_6                    0x00000006 /* RW--V */
+#define NV_PFB_CONFIG_0_TETRIS_MODE_7                    0x00000007 /* RW--V */
+#define NV_PFB_CONFIG_0_TETRIS_SHIFT                          19:18 /* RWI-F */
+#define NV_PFB_CONFIG_0_TETRIS_SHIFT_0                   0x00000000 /* RWI-V */
+#define NV_PFB_CONFIG_0_TETRIS_SHIFT_1                   0x00000001 /* RW--V */
+#define NV_PFB_CONFIG_0_TETRIS_SHIFT_2                   0x00000002 /* RW--V */
+#define NV_PFB_CONFIG_0_BANK_SWAP                             22:20 /* RWI-F */
+#define NV_PFB_CONFIG_0_BANK_SWAP_OFF                    0x00000000 /* RWI-V */
+#define NV_PFB_CONFIG_0_BANK_SWAP_1M                     0x00000001 /* RW--V */
+#define NV_PFB_CONFIG_0_BANK_SWAP_2M                     0x00000005 /* RW--V */
+#define NV_PFB_CONFIG_0_BANK_SWAP_4M                     0x00000007 /* RW--V */
+#define NV_PFB_CONFIG_0_UNUSED                                23:23 /* RW-VF */
+#define NV_PFB_CONFIG_0_SCRAMBLE_EN                           29:29 /* RWIVF */
+#define NV_PFB_CONFIG_0_SCRAMBLE_EN_INIT                 0x00000000 /* RW--V */
+#define NV_PFB_CONFIG_0_SCRAMBLE_ACTIVE                  0x00000001 /* RW--V */
+#define NV_PFB_CONFIG_0_PRAMIN_WR                             28:28 /* RWIVF */
+#define NV_PFB_CONFIG_0_PRAMIN_WR_INIT                   0x00000000 /* RW--V */
+#define NV_PFB_CONFIG_0_PRAMIN_WR_DISABLED               0x00000001 /* RW--V */
+#define NV_PFB_CONFIG_0_PRAMIN_WR_MASK                        27:24 /* RWIVF */
+#define NV_PFB_CONFIG_0_PRAMIN_WR_MASK_INIT              0x00000000 /* RWI-V */
+#define NV_PFB_CONFIG_0_PRAMIN_WR_MASK_CLEAR             0x0000000f /* RWI-V */
+#define NV_PFB_CONFIG_1                                  0x00100204 /* RW-4R */
+#define NV_PFB_RTL                                       0x00100300 /* RW-4R */
+#define NV_PFB_RTL_H                                            0:0 /* RWIUF */
+#define NV_PFB_RTL_H_DEFAULT                             0x00000000 /* RWI-V */
+#define NV_PFB_RTL_MC                                           1:1 /* RWIUF */
+#define NV_PFB_RTL_MC_DEFAULT                            0x00000000 /* RWI-V */
+#define NV_PFB_RTL_V                                            2:2 /* RWIUF */
+#define NV_PFB_RTL_V_DEFAULT                             0x00000000 /* RWI-V */
+#define NV_PFB_RTL_G                                            3:3 /* RWIUF */
+#define NV_PFB_RTL_G_DEFAULT                             0x00000000 /* RWI-V */
+#define NV_PFB_RTL_GB                                           4:4 /* RWIUF */
+#define NV_PFB_RTL_GB_DEFAULT                            0x00000000 /* RWI-V */
+#define NV_PFB_CONFIG_0_RESOLUTION                              5:0 /* RWIVF */
+#define NV_PFB_CONFIG_0_RESOLUTION_320_PIXELS            0x0000000a /* RW--V */
+#define NV_PFB_CONFIG_0_RESOLUTION_400_PIXELS            0x0000000d /* RW--V */
+#define NV_PFB_CONFIG_0_RESOLUTION_480_PIXELS            0x0000000f /* RW--V */
+#define NV_PFB_CONFIG_0_RESOLUTION_512_PIXELS            0x00000010 /* RW--V */
+#define NV_PFB_CONFIG_0_RESOLUTION_640_PIXELS            0x00000014 /* RW--V */
+#define NV_PFB_CONFIG_0_RESOLUTION_800_PIXELS            0x00000019 /* RW--V */
+#define NV_PFB_CONFIG_0_RESOLUTION_960_PIXELS            0x0000001e /* RW--V */
+#define NV_PFB_CONFIG_0_RESOLUTION_1024_PIXELS           0x00000020 /* RW--V */
+#define NV_PFB_CONFIG_0_RESOLUTION_1152_PIXELS           0x00000024 /* RW--V */
+#define NV_PFB_CONFIG_0_RESOLUTION_1280_PIXELS           0x00000028 /* RW--V */
+#define NV_PFB_CONFIG_0_RESOLUTION_1600_PIXELS           0x00000032 /* RW--V */
+#define NV_PFB_CONFIG_0_RESOLUTION_DEFAULT               0x00000014 /* RWI-V */
+#define NV_PFB_CONFIG_0_PIXEL_DEPTH                             9:8 /* RWIVF */
+#define NV_PFB_CONFIG_0_PIXEL_DEPTH_8_BITS               0x00000001 /* RW--V */
+#define NV_PFB_CONFIG_0_PIXEL_DEPTH_16_BITS              0x00000002 /* RW--V */
+#define NV_PFB_CONFIG_0_PIXEL_DEPTH_32_BITS              0x00000003 /* RW--V */
+#define NV_PFB_CONFIG_0_PIXEL_DEPTH_DEFAULT              0x00000001 /* RWI-V */
+#define NV_PFB_CONFIG_0_TILING                                12:12 /* RWIVF */
+#define NV_PFB_CONFIG_0_TILING_ENABLED                   0x00000000 /* RW--V */
+#define NV_PFB_CONFIG_0_TILING_DISABLED                  0x00000001 /* RWI-V */
+#define NV_PFB_CONFIG_1_SGRAM100                                3:3 /* RWIVF */
+#define NV_PFB_CONFIG_1_SGRAM100_ENABLED                 0x00000000 /* RWI-V */
+#define NV_PFB_CONFIG_1_SGRAM100_DISABLED                0x00000001 /* RW--V */
+#define NV_PFB_DEBUG_0_CKE_ALWAYSON                           29:29 /* RWIVF */
+#define NV_PFB_DEBUG_0_CKE_ALWAYSON_OFF                  0x00000000 /* RW--V */
+#define NV_PFB_DEBUG_0_CKE_ALWAYSON_ON                   0x00000001 /* RWI-V */
+
+#define NV_PEXTDEV                            0x00101FFF:0x00101000 /* RW--D */
+#define NV_PEXTDEV_BOOT_0                                0x00101000 /* R--4R */
+#define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED                       0:0 /* R-XVF */
+#define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED_33MHZ          0x00000000 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_BUS_SPEED_66MHZ          0x00000001 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR                      1:1 /* R-XVF */
+#define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR_NO_BIOS       0x00000000 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_SUB_VENDOR_BIOS          0x00000001 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE                        3:2 /* R-XVF */
+#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_256K      0x00000000 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_512K_2BANK 0x00000001 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_SGRAM_512K_4BANK 0x00000002 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_RAM_TYPE_1024K_2BANK     0x00000003 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH                       4:4 /* R-XVF */
+#define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH_64             0x00000000 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_RAM_WIDTH_128            0x00000001 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE                        5:5 /* R-XVF */
+#define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE_PCI             0x00000000 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_BUS_TYPE_AGP             0x00000001 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL                         6:6 /* R-XVF */
+#define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL_13500K           0x00000000 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_CRYSTAL_14318180         0x00000001 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE                          8:7 /* R-XVF */
+#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_SECAM             0x00000000 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_NTSC              0x00000001 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_PAL               0x00000002 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_TVMODE_DISABLED          0x00000003 /* R---V */
+#define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE                     11:11 /* RWIVF */
+#define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE_DISABLED       0x00000000 /* RWI-V */
+#define NV_PEXTDEV_BOOT_0_STRAP_OVERWRITE_ENABLED        0x00000001 /* RW--V */
+
+/* Extras */
+#define NV_PRAMIN                             0x007FFFFF:0x00700000 /* RW--M */
+/*#define NV_PRAMIN                             0x00FFFFFF:0x00C00000*/
+#define NV_PNVM                               0x01FFFFFF:0x01000000 /* RW--M */
+/*#define NV_PNVM                               0x00BFFFFF:0x00800000*/
+#define NV_CHAN0                              0x0080ffff:0x00800000
+
+/* FIFO subchannels */
+#define NV_UROP                               0x43
+#define NV_UCHROMA                            0x57
+#define NV_UCLIP                              0x19
+#define NV_UPATT                              0x18
+#define NV_ULIN                               0x5C
+#define NV_UTRI                               0x5D
+#define NV_URECT                              0x5E
+#define NV_UBLIT                              0x5F
+#define NV_UGLYPH                             0x4B
+
+#endif /*__NV4REF_H__*/
+
diff -u --recursive --new-file v2.3.25/linux/drivers/video/nvreg.h linux/drivers/video/nvreg.h
--- v2.3.25/linux/drivers/video/nvreg.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/nvreg.h	Tue Nov  2 08:15:05 1999
@@ -0,0 +1,188 @@
+/* $XConsortium: nvreg.h /main/2 1996/10/28 05:13:41 kaleb $ */
+/*
+ * Copyright 1996-1997  David J. McKay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * DAVID J. MCKAY BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/nv/nvreg.h,v 3.2.2.1 1998/01/18 10:35:36 hohndel Exp $ */
+
+#ifndef __NVREG_H_
+#define __NVREG_H_
+
+/* Little macro to construct bitmask for contiguous ranges of bits */
+#define BITMASK(t,b) (((unsigned)(1U << (((t)-(b)+1)))-1)  << (b))
+#define MASKEXPAND(mask) BITMASK(1?mask,0?mask)
+
+/* Macro to set specific bitfields (mask has to be a macro x:y) ! */
+#define SetBF(mask,value) ((value) << (0?mask))
+#define GetBF(var,mask) (((unsigned)((var) & MASKEXPAND(mask))) >> (0?mask) )
+
+#define MaskAndSetBF(var,mask,value) (var)=(((var)&(~MASKEXPAND(mask)) \
+                                             | SetBF(mask,value)))
+
+#define DEVICE_BASE(device) (0?NV##_##device)
+#define DEVICE_SIZE(device) ((1?NV##_##device) - DEVICE_BASE(device)+1)
+
+/* This is where we will have to have conditional compilation */
+#define DEVICE_ACCESS(device,reg) \
+  nvCONTROL[(NV_##device##_##reg)/4]
+
+#define DEVICE_WRITE(device,reg,value) DEVICE_ACCESS(device,reg)=(value)
+#define DEVICE_READ(device,reg)        DEVICE_ACCESS(device,reg)
+#define DEVICE_PRINT(device,reg) \
+  ErrorF("NV_"#device"_"#reg"=#%08lx\n",DEVICE_ACCESS(device,reg))
+#define DEVICE_DEF(device,mask,value) \
+  SetBF(NV_##device##_##mask,NV_##device##_##mask##_##value)
+#define DEVICE_VALUE(device,mask,value) SetBF(NV_##device##_##mask,value)
+#define DEVICE_MASK(device,mask) MASKEXPAND(NV_##device##_##mask)
+
+#define PDAC_Write(reg,value)           DEVICE_WRITE(PDAC,reg,value)
+#define PDAC_Read(reg)                  DEVICE_READ(PDAC,reg)
+#define PDAC_Print(reg)                 DEVICE_PRINT(PDAC,reg)
+#define PDAC_Def(mask,value)            DEVICE_DEF(PDAC,mask,value)
+#define PDAC_Val(mask,value)            DEVICE_VALUE(PDAC,mask,value)
+#define PDAC_Mask(mask)                 DEVICE_MASK(PDAC,mask)
+
+#define PFB_Write(reg,value)            DEVICE_WRITE(PFB,reg,value)
+#define PFB_Read(reg)                   DEVICE_READ(PFB,reg)
+#define PFB_Print(reg)                  DEVICE_PRINT(PFB,reg)
+#define PFB_Def(mask,value)             DEVICE_DEF(PFB,mask,value)
+#define PFB_Val(mask,value)             DEVICE_VALUE(PFB,mask,value)
+#define PFB_Mask(mask)                  DEVICE_MASK(PFB,mask)
+
+#define PRM_Write(reg,value)            DEVICE_WRITE(PRM,reg,value)
+#define PRM_Read(reg)                   DEVICE_READ(PRM,reg)
+#define PRM_Print(reg)                  DEVICE_PRINT(PRM,reg)
+#define PRM_Def(mask,value)             DEVICE_DEF(PRM,mask,value)
+#define PRM_Val(mask,value)             DEVICE_VALUE(PRM,mask,value)
+#define PRM_Mask(mask)                  DEVICE_MASK(PRM,mask)
+
+#define PGRAPH_Write(reg,value)         DEVICE_WRITE(PGRAPH,reg,value)
+#define PGRAPH_Read(reg)                DEVICE_READ(PGRAPH,reg)
+#define PGRAPH_Print(reg)               DEVICE_PRINT(PGRAPH,reg)
+#define PGRAPH_Def(mask,value)          DEVICE_DEF(PGRAPH,mask,value)
+#define PGRAPH_Val(mask,value)          DEVICE_VALUE(PGRAPH,mask,value)
+#define PGRAPH_Mask(mask)               DEVICE_MASK(PGRAPH,mask)
+
+#define PDMA_Write(reg,value)           DEVICE_WRITE(PDMA,reg,value)
+#define PDMA_Read(reg)                  DEVICE_READ(PDMA,reg)
+#define PDMA_Print(reg)                 DEVICE_PRINT(PDMA,reg)
+#define PDMA_Def(mask,value)            DEVICE_DEF(PDMA,mask,value)
+#define PDMA_Val(mask,value)            DEVICE_VALUE(PDMA,mask,value)
+#define PDMA_Mask(mask)                 DEVICE_MASK(PDMA,mask)
+
+#define PTIMER_Write(reg,value)         DEVICE_WRITE(PTIMER,reg,value)
+#define PTIMER_Read(reg)                DEVICE_READ(PTIMER,reg)
+#define PTIMER_Print(reg)               DEVICE_PRINT(PTIMER,reg)
+#define PTIMER_Def(mask,value)          DEVICE_DEF(PTIMER,mask,value)
+#define PTIMER_Val(mask,value)          DEVICE_VALUE(PTIEMR,mask,value)
+#define PTIMER_Mask(mask)               DEVICE_MASK(PTIMER,mask)
+
+#define PEXTDEV_Write(reg,value)         DEVICE_WRITE(PEXTDEV,reg,value)
+#define PEXTDEV_Read(reg)                DEVICE_READ(PEXTDEV,reg)
+#define PEXTDEV_Print(reg)               DEVICE_PRINT(PEXTDEV,reg)
+#define PEXTDEV_Def(mask,value)          DEVICE_DEF(PEXTDEV,mask,value)
+#define PEXTDEV_Val(mask,value)          DEVICE_VALUE(PEXTDEV,mask,value)
+#define PEXTDEV_Mask(mask)               DEVICE_MASK(PEXTDEV,mask)
+
+#define PFIFO_Write(reg,value)          DEVICE_WRITE(PFIFO,reg,value)
+#define PFIFO_Read(reg)                 DEVICE_READ(PFIFO,reg)
+#define PFIFO_Print(reg)                DEVICE_PRINT(PFIFO,reg)
+#define PFIFO_Def(mask,value)           DEVICE_DEF(PFIFO,mask,value)
+#define PFIFO_Val(mask,value)           DEVICE_VALUE(PFIFO,mask,value)
+#define PFIFO_Mask(mask)                DEVICE_MASK(PFIFO,mask)
+
+#define PRAM_Write(reg,value)           DEVICE_WRITE(PRAM,reg,value)
+#define PRAM_Read(reg)                  DEVICE_READ(PRAM,reg)
+#define PRAM_Print(reg)                 DEVICE_PRINT(PRAM,reg)
+#define PRAM_Def(mask,value)            DEVICE_DEF(PRAM,mask,value)
+#define PRAM_Val(mask,value)            DEVICE_VALUE(PRAM,mask,value)
+#define PRAM_Mask(mask)                 DEVICE_MASK(PRAM,mask)
+
+#define PRAMFC_Write(reg,value)         DEVICE_WRITE(PRAMFC,reg,value)
+#define PRAMFC_Read(reg)                DEVICE_READ(PRAMFC,reg)
+#define PRAMFC_Print(reg)               DEVICE_PRINT(PRAMFC,reg)
+#define PRAMFC_Def(mask,value)          DEVICE_DEF(PRAMFC,mask,value)
+#define PRAMFC_Val(mask,value)          DEVICE_VALUE(PRAMFC,mask,value)
+#define PRAMFC_Mask(mask)               DEVICE_MASK(PRAMFC,mask)
+
+#define PMC_Write(reg,value)            DEVICE_WRITE(PMC,reg,value)
+#define PMC_Read(reg)                   DEVICE_READ(PMC,reg)
+#define PMC_Print(reg)                  DEVICE_PRINT(PMC,reg)
+#define PMC_Def(mask,value)             DEVICE_DEF(PMC,mask,value)
+#define PMC_Val(mask,value)             DEVICE_VALUE(PMC,mask,value)
+#define PMC_Mask(mask)                  DEVICE_MASK(PMC,mask)
+
+#define PMC_Write(reg,value)            DEVICE_WRITE(PMC,reg,value)
+#define PMC_Read(reg)                   DEVICE_READ(PMC,reg)
+#define PMC_Print(reg)                  DEVICE_PRINT(PMC,reg)
+#define PMC_Def(mask,value)             DEVICE_DEF(PMC,mask,value)
+#define PMC_Val(mask,value)             DEVICE_VALUE(PMC,mask,value)
+#define PMC_Mask(mask)                  DEVICE_MASK(PMC,mask)
+
+
+#define PBUS_Write(reg,value)         DEVICE_WRITE(PBUS,reg,value)
+#define PBUS_Read(reg)                DEVICE_READ(PBUS,reg)
+#define PBUS_Print(reg)               DEVICE_PRINT(PBUS,reg)
+#define PBUS_Def(mask,value)          DEVICE_DEF(PBUS,mask,value)
+#define PBUS_Val(mask,value)          DEVICE_VALUE(PBUS,mask,value)
+#define PBUS_Mask(mask)               DEVICE_MASK(PBUS,mask)
+
+
+#define PRAMDAC_Write(reg,value)         DEVICE_WRITE(PRAMDAC,reg,value)
+#define PRAMDAC_Read(reg)                DEVICE_READ(PRAMDAC,reg)
+#define PRAMDAC_Print(reg)               DEVICE_PRINT(PRAMDAC,reg)
+#define PRAMDAC_Def(mask,value)          DEVICE_DEF(PRAMDAC,mask,value)
+#define PRAMDAC_Val(mask,value)          DEVICE_VALUE(PRAMDAC,mask,value)
+#define PRAMDAC_Mask(mask)               DEVICE_MASK(PRAMDAC,mask)
+
+
+#define PDAC_ReadExt(reg) \
+  ((PDAC_Write(INDEX_LO,(NV_PDAC_EXT_##reg) & 0xff)),\
+  (PDAC_Write(INDEX_HI,((NV_PDAC_EXT_##reg) >> 8) & 0xff)),\
+  (PDAC_Read(INDEX_DATA)))
+
+#define PDAC_WriteExt(reg,value)\
+  ((PDAC_Write(INDEX_LO,(NV_PDAC_EXT_##reg) & 0xff)),\
+  (PDAC_Write(INDEX_HI,((NV_PDAC_EXT_##reg) >> 8) & 0xff)),\
+  (PDAC_Write(INDEX_DATA,(value))))
+
+#define CRTC_Write(index,value) outb((index), 0x3d4); outb(value, 0x3d5)
+#define CRTC_Read(index) (outb(index, 0x3d4),inb(0x3d5))
+
+#define PCRTC_Write(index,value) CRTC_Write(NV_PCRTC_##index,value)
+#define PCRTC_Read(index) CRTC_Read(NV_PCRTC_##index)
+
+#define PCRTC_Def(mask,value)          DEVICE_DEF(PCRTC,mask,value)
+#define PCRTC_Val(mask,value)          DEVICE_VALUE(PCRTC,mask,value)
+#define PCRTC_Mask(mask)               DEVICE_MASK(PCRTC,mask)
+
+#define SR_Write(index,value) outb(0x3c4,(index));outb(0x3c5,value)
+#define SR_Read(index) (outb(0x3c4,index),inb(0x3c5))
+
+extern volatile unsigned  *nvCONTROL;
+
+typedef enum {NV1,NV3,NV4,NumNVChips} NVChipType;
+
+NVChipType GetChipType(void);
+
+#endif
+
+
diff -u --recursive --new-file v2.3.25/linux/drivers/video/riva_hw.c linux/drivers/video/riva_hw.c
--- v2.3.25/linux/drivers/video/riva_hw.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/riva_hw.c	Tue Nov  2 08:15:05 1999
@@ -0,0 +1,1429 @@
+ /***************************************************************************\
+|*                                                                           *|
+|*       Copyright 1993-1998 NVIDIA, Corporation.  All rights reserved.      *|
+|*                                                                           *|
+|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
+|*     international laws.  Users and possessors of this source code are     *|
+|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
+|*     use this code in individual and commercial software.                  *|
+|*                                                                           *|
+|*     Any use of this source code must include,  in the user documenta-     *|
+|*     tion and  internal comments to the code,  notices to the end user     *|
+|*     as follows:                                                           *|
+|*                                                                           *|
+|*       Copyright 1993-1998 NVIDIA, Corporation.  All rights reserved.      *|
+|*                                                                           *|
+|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
+|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
+|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
+|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
+|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
+|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
+|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
+|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
+|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
+|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
+|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
+|*                                                                           *|
+|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
+|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
+|*     consisting  of "commercial  computer  software"  and  "commercial     *|
+|*     computer  software  documentation,"  as such  terms  are  used in     *|
+|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
+|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
+|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
+|*     all U.S. Government End Users  acquire the source code  with only     *|
+|*     those rights set forth herein.                                        *|
+|*                                                                           *|
+ \***************************************************************************/
+/* 
+ * GPL licensing note -- nVidia is allowing a liberal interpretation of 
+ * the documentation restriction above, to merely say that this nVidia's
+ * copyright and disclaimer should be included with all code derived 
+ * from this source.  -- Jeff Garzik <jgarzik@mandrakesoft.com>, 01/Nov/99
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/nv/riva_hw.c,v 1.1.2.3 1998/12/26 00:12:39 dawes Exp $ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <asm/io.h>
+#include "riva_hw.h"
+#include "riva_tbl.h"
+
+
+/*
+ * This file is an OS-agnostic file used to make RIVA 128 and RIVA TNT
+ * operate identically (except TNT has more memory and better 3D quality.
+ */
+
+static int nv3Busy
+(
+    RIVA_HW_INST *chip
+)
+{
+    return ((!(chip->PFIFO[0x00001214/4] & 0x10)) | (chip->PGRAPH[0x000006B0/4] & 0x01));
+}
+static int nv4Busy
+(
+    RIVA_HW_INST *chip
+)
+{
+    return ((!(chip->PFIFO[0x00001214/4] & 0x10)) | (chip->PGRAPH[0x00000700/4] & 0x01));
+}
+static int ShowHideCursor
+(
+    RIVA_HW_INST *chip,
+    int           ShowHide
+)
+{
+    int xcurrent;
+    xcurrent                     =  chip->CurrentState->cursor1;
+    chip->CurrentState->cursor1 = (chip->CurrentState->cursor1 & 0xFE) | (ShowHide & 0x01);
+    outb(0x31, 0x3D4);
+    outb(chip->CurrentState->cursor1, 0x3D5);
+    return (xcurrent & 0x01);
+}
+
+/****************************************************************************\
+*                                                                            *
+* The video arbitration routines calculate some "magic" numbers.  Fixes      *
+* the snow seen when accessing the framebuffer without it.                   *
+* It just works (I hope).                                                    *
+*                                                                            *
+\****************************************************************************/
+
+#define DEFAULT_GR_LWM 100
+#define DEFAULT_VID_LWM 100
+#define DEFAULT_GR_BURST_SIZE 256
+#define DEFAULT_VID_BURST_SIZE 128
+#define VIDEO		0
+#define GRAPHICS	1
+#define MPORT		2
+#define ENGINE		3
+#define GFIFO_SIZE	320
+#define GFIFO_SIZE_128	256
+#define MFIFO_SIZE	120
+#define VFIFO_SIZE	256
+#define	ABS(a)	(a>0?a:-a)
+typedef struct {
+  int gdrain_rate;
+  int vdrain_rate;
+  int mdrain_rate;
+  int gburst_size;
+  int vburst_size;
+  char vid_en;
+  char gr_en;
+  int wcmocc, wcgocc, wcvocc, wcvlwm, wcglwm;
+  int by_gfacc;
+  char vid_only_once;
+  char gr_only_once;
+  char first_vacc;
+  char first_gacc;
+  char first_macc;
+  int vocc;
+  int gocc;
+  int mocc;
+  char cur;
+  char engine_en;
+  char converged;
+  int priority;
+} nv3_arb_info;
+typedef struct {
+  int graphics_lwm;
+  int video_lwm;
+  int graphics_burst_size;
+  int video_burst_size;
+  int graphics_hi_priority;
+  int media_hi_priority;
+  int rtl_values;
+  int valid;
+} nv3_fifo_info;
+typedef struct {
+  char pix_bpp;
+  char enable_video;
+  char gr_during_vid;
+  char enable_mp;
+  int memory_width;
+  int video_scale;
+  int pclk_khz;
+  int mclk_khz;
+  int mem_page_miss;
+  int mem_latency;
+  char mem_aligned;
+} nv3_sim_state;
+typedef struct {
+  int graphics_lwm;
+  int video_lwm;
+  int graphics_burst_size;
+  int video_burst_size;
+  int valid;
+} nv4_fifo_info;
+typedef struct {
+  int pclk_khz;
+  int mclk_khz;
+  int nvclk_khz;
+  char mem_page_miss;
+  char mem_latency;
+  int memory_width;
+  char enable_video;
+  char gr_during_vid;
+  char pix_bpp;
+  char mem_aligned;
+  char enable_mp;
+} nv4_sim_state;
+static int nv3_iterate(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
+{
+    int iter = 0;
+    int tmp, t;
+    int vfsize, mfsize, gfsize;
+    int mburst_size = 32;
+    int mmisses, gmisses, vmisses;
+    int misses;
+    int vlwm, glwm, mlwm;
+    int last, next, cur;
+    int max_gfsize ;
+    long ns;
+
+    vlwm = 0;
+    glwm = 0;
+    mlwm = 0;
+    vfsize = 0;
+    gfsize = 0;
+    cur = ainfo->cur;
+    mmisses = 2;
+    gmisses = 2;
+    vmisses = 2;
+    if (ainfo->gburst_size == 128) max_gfsize = GFIFO_SIZE_128;
+    else  max_gfsize = GFIFO_SIZE;
+    max_gfsize = GFIFO_SIZE;
+    while (1)
+    {
+        if (ainfo->vid_en)
+        {
+            if (ainfo->wcvocc > ainfo->vocc) ainfo->wcvocc = ainfo->vocc;
+            if (ainfo->wcvlwm > vlwm) ainfo->wcvlwm = vlwm ;
+            ns = 1000000 * ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz;
+            vfsize = ns * ainfo->vdrain_rate / 1000000;
+            vfsize =  ainfo->wcvlwm - ainfo->vburst_size + vfsize;
+        }
+        if (state->enable_mp)
+        {
+            if (ainfo->wcmocc > ainfo->mocc) ainfo->wcmocc = ainfo->mocc;
+        }
+        if (ainfo->gr_en)
+        {
+            if (ainfo->wcglwm > glwm) ainfo->wcglwm = glwm ;
+            if (ainfo->wcgocc > ainfo->gocc) ainfo->wcgocc = ainfo->gocc;
+            ns = 1000000 * (ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz;
+            gfsize = ns *ainfo->gdrain_rate/1000000;
+            gfsize = ainfo->wcglwm - ainfo->gburst_size + gfsize;
+        }
+        mfsize = 0;
+        if (!state->gr_during_vid && ainfo->vid_en)
+            if (ainfo->vid_en && (ainfo->vocc < 0) && !ainfo->vid_only_once)
+                next = VIDEO;
+            else if (ainfo->mocc < 0)
+                next = MPORT;
+            else if (ainfo->gocc< ainfo->by_gfacc)
+                next = GRAPHICS;
+            else return (0);
+        else switch (ainfo->priority)
+            {
+                case VIDEO:
+                    if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
+                        next = VIDEO;
+                    else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
+                        next = GRAPHICS;
+                    else if (ainfo->mocc<0)
+                        next = MPORT;
+                    else    return (0);
+                    break;
+                case GRAPHICS:
+                    if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
+                        next = GRAPHICS;
+                    else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
+                        next = VIDEO;
+                    else if (ainfo->mocc<0)
+                        next = MPORT;
+                    else    return (0);
+                    break;
+                default:
+                    if (ainfo->mocc<0)
+                        next = MPORT;
+                    else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
+                        next = GRAPHICS;
+                    else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
+                        next = VIDEO;
+                    else    return (0);
+                    break;
+            }
+        last = cur;
+        cur = next;
+        iter++;
+        switch (cur)
+        {
+            case VIDEO:
+                if (last==cur)    misses = 0;
+                else if (ainfo->first_vacc)   misses = vmisses;
+                else    misses = 1;
+                ainfo->first_vacc = 0;
+                if (last!=cur)
+                {
+                    ns =  1000000 * (vmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz; 
+                    vlwm = ns * ainfo->vdrain_rate/ 1000000;
+                    vlwm = ainfo->vocc - vlwm;
+                }
+                ns = 1000000*(misses*state->mem_page_miss + ainfo->vburst_size)/(state->memory_width/8)/state->mclk_khz;
+                ainfo->vocc = ainfo->vocc + ainfo->vburst_size - ns*ainfo->vdrain_rate/1000000;
+                ainfo->gocc = ainfo->gocc - ns*ainfo->gdrain_rate/1000000;
+                ainfo->mocc = ainfo->mocc - ns*ainfo->mdrain_rate/1000000;
+                break;
+            case GRAPHICS:
+                if (last==cur)    misses = 0;
+                else if (ainfo->first_gacc)   misses = gmisses;
+                else    misses = 1;
+                ainfo->first_gacc = 0;
+                if (last!=cur)
+                {
+                    ns = 1000000*(gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz ;
+                    glwm = ns * ainfo->gdrain_rate/1000000;
+                    glwm = ainfo->gocc - glwm;
+                }
+                ns = 1000000*(misses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz;
+                ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000;
+                ainfo->gocc = ainfo->gocc + ainfo->gburst_size - ns*ainfo->gdrain_rate/1000000;
+                ainfo->mocc = ainfo->mocc + 0 - ns*ainfo->mdrain_rate/1000000;
+                break;
+            default:
+                if (last==cur)    misses = 0;
+                else if (ainfo->first_macc)   misses = mmisses;
+                else    misses = 1;
+                ainfo->first_macc = 0;
+                ns = 1000000*(misses*state->mem_page_miss + mburst_size/(state->memory_width/8))/state->mclk_khz;
+                ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000;
+                ainfo->gocc = ainfo->gocc + 0 - ns*ainfo->gdrain_rate/1000000;
+                ainfo->mocc = ainfo->mocc + mburst_size - ns*ainfo->mdrain_rate/1000000;
+                break;
+        }
+        if (iter>100)
+        {
+            ainfo->converged = 0;
+            return (1);
+        }
+        ns = 1000000*ainfo->gburst_size/(state->memory_width/8)/state->mclk_khz;
+        tmp = ns * ainfo->gdrain_rate/1000000;
+        if (ABS(ainfo->gburst_size) + ((ABS(ainfo->wcglwm) + 16 ) & ~0x7)    - tmp > max_gfsize)
+        {
+            ainfo->converged = 0;
+            return (1);
+        }
+        ns = 1000000*ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz;
+        tmp = ns * ainfo->vdrain_rate/1000000;
+        if (ABS(ainfo->vburst_size) + (ABS(ainfo->wcvlwm + 32) & ~0xf)  - tmp> VFIFO_SIZE)
+        {
+            ainfo->converged = 0;
+            return (1);
+        }
+        if (ABS(ainfo->gocc) > max_gfsize)
+        {
+            ainfo->converged = 0;
+            return (1);
+        }
+        if (ABS(ainfo->vocc) > VFIFO_SIZE)
+        {
+            ainfo->converged = 0;
+            return (1);
+        }
+        if (ABS(ainfo->mocc) > MFIFO_SIZE)
+        {
+            ainfo->converged = 0;
+            return (1);
+        }
+        if (ABS(vfsize) > VFIFO_SIZE)
+        {
+            ainfo->converged = 0;
+            return (1);
+        }
+        if (ABS(gfsize) > max_gfsize)
+        {
+            ainfo->converged = 0;
+            return (1);
+        }
+        if (ABS(mfsize) > MFIFO_SIZE)
+        {
+            ainfo->converged = 0;
+            return (1);
+        }
+    }
+}
+static char nv3_arb(nv3_fifo_info * res_info, nv3_sim_state * state,  nv3_arb_info *ainfo) 
+{
+    int  g, v, not_done;
+    long ens, vns, mns, gns;
+    int mmisses, gmisses, vmisses, eburst_size, mburst_size;
+    int refresh_cycle;
+
+    refresh_cycle = 0;
+    refresh_cycle = 2*(state->mclk_khz/state->pclk_khz) + 5;
+    mmisses = 2;
+    if (state->mem_aligned) gmisses = 2;
+    else    gmisses = 3;
+    vmisses = 2;
+    eburst_size = state->memory_width * 1;
+    mburst_size = 32;
+    gns = 1000000 * (gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz;
+    ainfo->by_gfacc = gns*ainfo->gdrain_rate/1000000;
+    ainfo->wcmocc = 0;
+    ainfo->wcgocc = 0;
+    ainfo->wcvocc = 0;
+    ainfo->wcvlwm = 0;
+    ainfo->wcglwm = 0;
+    ainfo->engine_en = 1;
+    ainfo->converged = 1;
+    if (ainfo->engine_en)
+    {
+        ens =  1000000*(state->mem_page_miss + eburst_size/(state->memory_width/8) +refresh_cycle)/state->mclk_khz;
+        ainfo->mocc = state->enable_mp ? 0-ens*ainfo->mdrain_rate/1000000 : 0;
+        ainfo->vocc = ainfo->vid_en ? 0-ens*ainfo->vdrain_rate/1000000 : 0;
+        ainfo->gocc = ainfo->gr_en ? 0-ens*ainfo->gdrain_rate/1000000 : 0;
+        ainfo->cur = ENGINE;
+        ainfo->first_vacc = 1;
+        ainfo->first_gacc = 1;
+        ainfo->first_macc = 1;
+        nv3_iterate(res_info, state,ainfo);
+    }
+    if (state->enable_mp)
+    {
+        mns = 1000000 * (mmisses*state->mem_page_miss + mburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
+        ainfo->mocc = state->enable_mp ? 0 : mburst_size - mns*ainfo->mdrain_rate/1000000;
+        ainfo->vocc = ainfo->vid_en ? 0 : 0- mns*ainfo->vdrain_rate/1000000;
+        ainfo->gocc = ainfo->gr_en ? 0: 0- mns*ainfo->gdrain_rate/1000000;
+        ainfo->cur = MPORT;
+        ainfo->first_vacc = 1;
+        ainfo->first_gacc = 1;
+        ainfo->first_macc = 0;
+        nv3_iterate(res_info, state,ainfo);
+    }
+    if (ainfo->gr_en)
+    {
+        ainfo->first_vacc = 1;
+        ainfo->first_gacc = 0;
+        ainfo->first_macc = 1;
+        gns = 1000000*(gmisses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
+        ainfo->gocc = ainfo->gburst_size - gns*ainfo->gdrain_rate/1000000;
+        ainfo->vocc = ainfo->vid_en? 0-gns*ainfo->vdrain_rate/1000000 : 0;
+        ainfo->mocc = state->enable_mp ?  0-gns*ainfo->mdrain_rate/1000000: 0;
+        ainfo->cur = GRAPHICS;
+        nv3_iterate(res_info, state,ainfo);
+    }
+    if (ainfo->vid_en)
+    {
+        ainfo->first_vacc = 0;
+        ainfo->first_gacc = 1;
+        ainfo->first_macc = 1;
+        vns = 1000000*(vmisses*state->mem_page_miss + ainfo->vburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
+        ainfo->vocc = ainfo->vburst_size - vns*ainfo->vdrain_rate/1000000;
+        ainfo->gocc = ainfo->gr_en? (0-vns*ainfo->gdrain_rate/1000000) : 0;
+        ainfo->mocc = state->enable_mp? 0-vns*ainfo->mdrain_rate/1000000 :0 ;
+        ainfo->cur = VIDEO;
+        nv3_iterate(res_info, state, ainfo);
+    }
+    if (ainfo->converged)
+    {
+        res_info->graphics_lwm = (int)ABS(ainfo->wcglwm) + 16;
+        res_info->video_lwm = (int)ABS(ainfo->wcvlwm) + 32;
+        res_info->graphics_burst_size = ainfo->gburst_size;
+        res_info->video_burst_size = ainfo->vburst_size;
+        res_info->graphics_hi_priority = (ainfo->priority == GRAPHICS);
+        res_info->media_hi_priority = (ainfo->priority == MPORT);
+        if (res_info->video_lwm > 160)
+        {
+            res_info->graphics_lwm = 256;
+            res_info->video_lwm = 128;
+            res_info->graphics_burst_size = 64;
+            res_info->video_burst_size = 64;
+            res_info->graphics_hi_priority = 0;
+            res_info->media_hi_priority = 0;
+            ainfo->converged = 0;
+            return (0);
+        }
+        if (res_info->video_lwm > 128)
+        {
+            res_info->video_lwm = 128;
+        }
+        return (1);
+    }
+    else
+    {
+        res_info->graphics_lwm = 256;
+        res_info->video_lwm = 128;
+        res_info->graphics_burst_size = 64;
+        res_info->video_burst_size = 64;
+        res_info->graphics_hi_priority = 0;
+        res_info->media_hi_priority = 0;
+        return (0);
+    }
+}
+static char nv3_get_param(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
+{
+    int done, g,v, p;
+    int priority, gburst_size, vburst_size, iter;
+    
+    done = 0;
+    if (state->gr_during_vid && ainfo->vid_en)
+        ainfo->priority = MPORT;
+    else
+        ainfo->priority = ainfo->gdrain_rate < ainfo->vdrain_rate ? VIDEO: GRAPHICS;
+    for (p=0; p < 2 && done != 1; p++)
+    {
+        for (g=128 ; (g > 32) && (done != 1); g= g>> 1)
+        {
+            for (v=128; (v >=32) && (done !=1); v = v>> 1)
+            {
+                ainfo->priority = p;
+                ainfo->gburst_size = g;     
+                ainfo->vburst_size = v;
+                done = nv3_arb(res_info, state,ainfo);
+                if (g==128)
+                {
+                    if ((res_info->graphics_lwm + g) > 256)
+                        done = 0;
+                }
+            }
+        }
+    }
+    if (!done)
+        return (0);
+    else
+        return (1);
+}
+static void nv3CalcArbitration 
+(
+    nv3_fifo_info * res_info,
+    nv3_sim_state * state
+)
+{
+    nv3_fifo_info save_info;
+    nv3_arb_info ainfo;
+    char   res_gr, res_vid;
+
+    ainfo.gr_en = 1;
+    ainfo.vid_en = state->enable_video;
+    ainfo.vid_only_once = 0;
+    ainfo.gr_only_once = 0;
+    ainfo.gdrain_rate = (int) state->pclk_khz * state -> pix_bpp/8;
+    ainfo.vdrain_rate = (int) state->pclk_khz * 2;
+    if (state->video_scale != 0)
+        ainfo.vdrain_rate = ainfo.vdrain_rate/state->video_scale;
+    ainfo.mdrain_rate = 33000;
+    res_info->rtl_values = 0;
+    if (!state->gr_during_vid && state->enable_video)
+    {
+        ainfo.gr_only_once = 1;
+        ainfo.gr_en = 1;
+        ainfo.gdrain_rate = 0;
+        res_vid = nv3_get_param(res_info, state,  &ainfo);
+        res_vid = ainfo.converged;
+        save_info.video_lwm = res_info->video_lwm;
+        save_info.video_burst_size = res_info->video_burst_size;
+        ainfo.vid_en = 1;
+        ainfo.vid_only_once = 1;
+        ainfo.gr_en = 1;
+        ainfo.gdrain_rate = (int) state->pclk_khz * state -> pix_bpp/8;
+        ainfo.vdrain_rate = 0;
+        res_gr = nv3_get_param(res_info, state,  &ainfo);
+        res_gr = ainfo.converged;
+        res_info->video_lwm = save_info.video_lwm;
+        res_info->video_burst_size = save_info.video_burst_size;
+        res_info->valid = res_gr & res_vid;
+    }
+    else
+    {
+        if (!ainfo.gr_en) ainfo.gdrain_rate = 0;
+        if (!ainfo.vid_en) ainfo.vdrain_rate = 0;
+        res_gr = nv3_get_param(res_info, state,  &ainfo);
+        res_info->valid = ainfo.converged;
+    }
+}
+void nv3UpdateArbitrationSettings
+(
+    unsigned      VClk, 
+    unsigned      pixelDepth, 
+    unsigned     *burst,
+    unsigned     *lwm,
+    RIVA_HW_INST *chip
+)
+{
+    nv3_fifo_info fifo_data;
+    nv3_sim_state sim_data;
+    unsigned int M, N, P, pll, MClk;
+    
+    pll = chip->PRAMDAC[0x00000504/4];
+    M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
+    MClk = (N * chip->CrystalFreqKHz / M) >> P;
+    sim_data.pix_bpp        = (char)pixelDepth;
+    sim_data.enable_video   = 0;
+    sim_data.enable_mp      = 0;
+    sim_data.video_scale    = 1;
+    sim_data.memory_width   = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
+    sim_data.memory_width   = 128;
+    sim_data.mem_latency    = 11;
+    sim_data.mem_aligned    = 1;
+    sim_data.mem_page_miss  = 9;
+    sim_data.gr_during_vid  = 0;
+    sim_data.pclk_khz       = VClk;
+    sim_data.mclk_khz       = MClk;
+    nv3CalcArbitration(&fifo_data, &sim_data);
+    if (fifo_data.valid)
+    {
+        int  b = fifo_data.graphics_burst_size >> 4;
+        *burst = 0;
+        while (b >>= 1) (*burst)++;
+        *lwm   = fifo_data.graphics_lwm >> 3;
+    }
+    else
+    {
+        *lwm   = 0x24;
+        *burst = 0x02;
+    }
+}
+static void nv4CalcArbitration 
+(
+    nv4_fifo_info *fifo,
+    nv4_sim_state *arb
+)
+{
+    int data, m,n,p, pagemiss, cas,width, video_enable, color_key_enable, bpp, align;
+    int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
+    int found, mclk_extra, mclk_loop, cbs, m1, p1;
+    int xtal_freq, mclk_freq, pclk_freq, nvclk_freq, mp_enable;
+    int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate;
+    int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt,clwm;
+    int craw, vraw;
+
+    fifo->valid = 1;
+    pclk_freq = arb->pclk_khz;
+    mclk_freq = arb->mclk_khz;
+    nvclk_freq = arb->nvclk_khz;
+    pagemiss = arb->mem_page_miss;
+    cas = arb->mem_latency;
+    width = arb->memory_width >> 6;
+    video_enable = arb->enable_video;
+    color_key_enable = arb->gr_during_vid;
+    bpp = arb->pix_bpp;
+    align = arb->mem_aligned;
+    mp_enable = arb->enable_mp;
+    clwm = 0;
+    vlwm = 0;
+    cbs = 128;
+    pclks = 2;
+    nvclks = 2;
+    nvclks += 2;
+    nvclks += 1;
+    mclks = 5;
+    mclks += 3;
+    mclks += 1;
+    mclks += cas;
+    mclks += 1;
+    mclks += 1;
+    mclks += 1;
+    mclks += 1;
+    mclk_extra = 3;
+    nvclks += 2;
+    nvclks += 1;
+    nvclks += 1;
+    nvclks += 1;
+    if (mp_enable)
+        mclks+=4;
+    nvclks += 0;
+    pclks += 0;
+    found = 0;
+    while (found != 1)
+    {
+        fifo->valid = 1;
+        found = 1;
+        mclk_loop = mclks+mclk_extra;
+        us_m = mclk_loop *1000*1000 / mclk_freq;
+        us_n = nvclks*1000*1000 / nvclk_freq;
+        us_p = nvclks*1000*1000 / pclk_freq;
+        if (video_enable)
+        {
+            video_drain_rate = pclk_freq * 2;
+            crtc_drain_rate = pclk_freq * bpp/8;
+            vpagemiss = 2;
+            vpagemiss += 1;
+            crtpagemiss = 2;
+            vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
+            if (nvclk_freq * 2 > mclk_freq * width)
+                video_fill_us = cbs*1000*1000 / 16 / nvclk_freq ;
+            else
+                video_fill_us = cbs*1000*1000 / (8 * width) / mclk_freq;
+            us_video = vpm_us + us_m + us_n + us_p + video_fill_us;
+            vlwm = us_video * video_drain_rate/(1000*1000);
+            vlwm++;
+            vbs = 128;
+            if (vlwm > 128) vbs = 64;
+            if (vlwm > (256-64)) vbs = 32;
+            if (nvclk_freq * 2 > mclk_freq * width)
+                video_fill_us = vbs *1000*1000/ 16 / nvclk_freq ;
+            else
+                video_fill_us = vbs*1000*1000 / (8 * width) / mclk_freq;
+            cpm_us = crtpagemiss  * pagemiss *1000*1000/ mclk_freq;
+            us_crt =
+            us_video
+            +video_fill_us
+            +cpm_us
+            +us_m + us_n +us_p
+            ;
+            clwm = us_crt * crtc_drain_rate/(1000*1000);
+            clwm++;
+        }
+        else
+        {
+            crtc_drain_rate = pclk_freq * bpp/8;
+            crtpagemiss = 2;
+            crtpagemiss += 1;
+            cpm_us = crtpagemiss  * pagemiss *1000*1000/ mclk_freq;
+            us_crt =  cpm_us + us_m + us_n + us_p ;
+            clwm = us_crt * crtc_drain_rate/(1000*1000);
+            clwm++;
+        }
+        m1 = clwm + cbs - 512;
+        p1 = m1 * pclk_freq / mclk_freq;
+        p1 = p1 * bpp / 8;
+        if ((p1 < m1) && (m1 > 0))
+        {
+            fifo->valid = 0;
+            found = 0;
+            if (mclk_extra ==0)   found = 1;
+            mclk_extra--;
+        }
+        else if (video_enable)
+        {
+            if ((clwm > 511) || (vlwm > 255))
+            {
+                fifo->valid = 0;
+                found = 0;
+                if (mclk_extra ==0)   found = 1;
+                mclk_extra--;
+            }
+        }
+        else
+        {
+            if (clwm > 519)
+            {
+                fifo->valid = 0;
+                found = 0;
+                if (mclk_extra ==0)   found = 1;
+                mclk_extra--;
+            }
+        }
+        craw = clwm;
+        vraw = vlwm;
+        if (clwm < 384) clwm = 384;
+        if (vlwm < 128) vlwm = 128;
+        data = (int)(clwm);
+        fifo->graphics_lwm = data;
+        fifo->graphics_burst_size = 128;
+        data = (int)((vlwm+15));
+        fifo->video_lwm = data;
+        fifo->video_burst_size = vbs;
+    }
+}
+static void nv4UpdateArbitrationSettings
+(
+    unsigned      VClk, 
+    unsigned      pixelDepth, 
+    unsigned     *burst,
+    unsigned     *lwm,
+    RIVA_HW_INST *chip
+)
+{
+    nv4_fifo_info fifo_data;
+    nv4_sim_state sim_data;
+    unsigned int M, N, P, pll, MClk, NVClk, cfg1;
+
+    pll = chip->PRAMDAC[0x00000504/4];
+    M = (pll >> 0)  & 0xFF; N = (pll >> 8)  & 0xFF; P = (pll >> 16) & 0x0F;
+    MClk  = (N * chip->CrystalFreqKHz / M) >> P;
+    pll = chip->PRAMDAC[0x00000500/4];
+    M = (pll >> 0)  & 0xFF; N = (pll >> 8)  & 0xFF; P = (pll >> 16) & 0x0F;
+    NVClk  = (N * chip->CrystalFreqKHz / M) >> P;
+    cfg1 = chip->PFB[0x00000204/4];
+    sim_data.pix_bpp        = (char)pixelDepth;
+    sim_data.enable_video   = 0;
+    sim_data.enable_mp      = 0;
+    sim_data.memory_width   = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
+    sim_data.mem_latency    = (char)cfg1 & 0x0F;
+    sim_data.mem_aligned    = 1;
+    sim_data.mem_page_miss  = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01));
+    sim_data.gr_during_vid  = 0;
+    sim_data.pclk_khz       = VClk;
+    sim_data.mclk_khz       = MClk;
+    sim_data.nvclk_khz      = NVClk;
+    nv4CalcArbitration(&fifo_data, &sim_data);
+    if (fifo_data.valid)
+    {
+        int  b = fifo_data.graphics_burst_size >> 4;
+        *burst = 0;
+        while (b >>= 1) (*burst)++;
+        *lwm   = fifo_data.graphics_lwm >> 3;
+    }
+}
+
+/****************************************************************************\
+*                                                                            *
+*                          RIVA Mode State Routines                          *
+*                                                                            *
+\****************************************************************************/
+
+/*
+ * Calculate the Video Clock parameters for the PLL.
+ */
+static int CalcVClock
+(
+    int           clockIn,
+    int          *clockOut,
+    int          *mOut,
+    int          *nOut,
+    int          *pOut,
+    RIVA_HW_INST *chip
+)
+{
+    unsigned lowM, highM, highP;
+    unsigned DeltaNew, DeltaOld;
+    unsigned VClk, Freq;
+    unsigned M, N, O, P;
+    
+    DeltaOld = 0xFFFFFFFF;
+    VClk     = (unsigned)clockIn;
+    if (chip->CrystalFreqKHz == 14318)
+    {
+        lowM  = 8;
+        highM = 14 - (chip->Architecture == 3);
+    }
+    else
+    {
+        lowM  = 7;
+        highM = 13 - (chip->Architecture == 3);
+    }                      
+    highP = 4 - (chip->Architecture == 3);
+    for (P = 0; P <= highP; P ++)
+    {
+        Freq = VClk << P;
+        if ((Freq >= 128000) && (Freq <= chip->MaxVClockFreqKHz))
+        {
+            for (M = lowM; M <= highM; M++)
+            {
+                N    = (VClk * M / chip->CrystalFreqKHz) << P;
+                Freq = (chip->CrystalFreqKHz * N / M) >> P;
+                if (Freq > VClk)
+                    DeltaNew = Freq - VClk;
+                else
+                    DeltaNew = VClk - Freq;
+                if (DeltaNew < DeltaOld)
+                {
+                    *mOut     = M;
+                    *nOut     = N;
+                    *pOut     = P;
+                    *clockOut = Freq;
+                    DeltaOld  = DeltaNew;
+                }
+            }
+        }
+    }
+    return (DeltaOld != 0xFFFFFFFF);
+}
+/*
+ * Calculate extended mode parameters (SVGA) and save in a 
+ * mode state structure.
+ */
+static void CalcStateExt
+(
+    RIVA_HW_INST  *chip,
+    RIVA_HW_STATE *state,
+    int            bpp,
+    int            width,
+    int            hDisplaySize,
+    int            hDisplay,
+    int            hStart,
+    int            hEnd,
+    int            hTotal,
+    int            height,
+    int            vDisplay,
+    int            vStart,
+    int            vEnd,
+    int            vTotal,
+    int            dotClock
+)
+{
+    int pixelDepth, VClk, m, n, p;
+    /*
+     * Save mode parameters.
+     */
+    state->bpp    = bpp;
+    state->width  = width;
+    state->height = height;
+    /*
+     * Extended RIVA registers.
+     */
+    pixelDepth = (bpp + 1)/8;
+    CalcVClock(dotClock, &VClk, &m, &n, &p, chip);
+    switch (chip->Architecture)
+    {
+	    case 3:
+            nv3UpdateArbitrationSettings(VClk, 
+                                         pixelDepth * 8, 
+                                        &(state->arbitration0),
+                                        &(state->arbitration1),
+                                         chip);
+            state->cursor0  = 0x00;
+            state->cursor1  = 0x78;
+            state->cursor2  = 0x00000000;
+            state->pllsel   = 0x10010100;
+            state->config   = ((width + 31)/32)
+                            | (((pixelDepth > 2) ? 3 : pixelDepth) << 8)
+                            | 0x1000;
+            state->general  = 0x00000100;
+            state->repaint1 = hDisplaySize < 1280 ? 0x06 : 0x02;
+            break;
+	    case 4:
+	    case 5:
+            nv4UpdateArbitrationSettings(VClk, 
+                                         pixelDepth * 8, 
+                                        &(state->arbitration0),
+                                        &(state->arbitration1),
+                                         chip);
+            state->cursor0  = 0x00;
+            state->cursor1  = 0xFC;
+            state->cursor2  = 0x00000000;
+            state->pllsel   = 0x10000700;
+            state->config   = 0x00001114;
+            state->general  = bpp == 16 ? 0x00101100 : 0x00100100;
+            state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
+            break;
+    }
+    state->vpll     = (p << 16) | (n << 8) | m;
+    state->screen   = ((hTotal   & 0x040) >> 2)
+                    | ((vDisplay & 0x400) >> 7)
+                    | ((vStart   & 0x400) >> 8)
+                    | ((vDisplay & 0x400) >> 9)
+                    | ((vTotal   & 0x400) >> 10);
+    state->repaint0 = (((width/8)*pixelDepth) & 0x700) >> 3;
+    state->horiz    = hTotal     < 260 ? 0x00 : 0x01;
+    state->pixel    = (pixelDepth > 2 ? 3 : pixelDepth) | 0x40;
+    state->offset0  =
+    state->offset1  =
+    state->offset2  =
+    state->offset3  = 0;
+    state->pitch0   =
+    state->pitch1   =
+    state->pitch2   =
+    state->pitch3   = pixelDepth * width;
+}
+/*
+ * Load fixed function state and pre-calculated/stored state.
+ */
+#define LOAD_FIXED_STATE(tbl,dev)                                       \
+    for (i = 0; i < sizeof(tbl##Table##dev)/8; i++)                 \
+        chip->dev[tbl##Table##dev[i][0]] = tbl##Table##dev[i][1]
+#define LOAD_FIXED_STATE_8BPP(tbl,dev)                                  \
+    for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++)            \
+        chip->dev[tbl##Table##dev##_8BPP[i][0]] = tbl##Table##dev##_8BPP[i][1]
+#define LOAD_FIXED_STATE_15BPP(tbl,dev)                                 \
+    for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++)           \
+        chip->dev[tbl##Table##dev##_15BPP[i][0]] = tbl##Table##dev##_15BPP[i][1]
+#define LOAD_FIXED_STATE_16BPP(tbl,dev)                                 \
+    for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++)           \
+        chip->dev[tbl##Table##dev##_16BPP[i][0]] = tbl##Table##dev##_16BPP[i][1]
+#define LOAD_FIXED_STATE_32BPP(tbl,dev)                                 \
+    for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++)           \
+        chip->dev[tbl##Table##dev##_32BPP[i][0]] = tbl##Table##dev##_32BPP[i][1]
+static void LoadStateExt
+(
+    RIVA_HW_INST  *chip,
+    RIVA_HW_STATE *state
+)
+{
+    int i;
+    /*
+     * Load HW fixed function state.
+     */
+    LOAD_FIXED_STATE(Riva,PMC);
+    LOAD_FIXED_STATE(Riva,PTIMER);
+    /*
+     * Make sure frame buffer config gets set before loading PRAMIN.
+     */
+    chip->PFB[0x00000200/4] = state->config;
+    switch (chip->Architecture)
+    {
+        case 3:
+            LOAD_FIXED_STATE(nv3,PFIFO);
+            LOAD_FIXED_STATE(nv3,PRAMIN);
+            LOAD_FIXED_STATE(nv3,PGRAPH);
+            switch (state->bpp)
+            {
+                case 15:
+                case 16:
+                    LOAD_FIXED_STATE_15BPP(nv3,PRAMIN);
+                    LOAD_FIXED_STATE_15BPP(nv3,PGRAPH);
+                    chip->Tri03 = (RivaTexturedTriangle03  *)&(chip->FIFO[0x0000E000/4]);
+                    break;
+                case 24:
+                case 32:
+                    LOAD_FIXED_STATE_32BPP(nv3,PRAMIN);
+                    LOAD_FIXED_STATE_32BPP(nv3,PGRAPH);
+                    chip->Tri03 = 0L;
+                    break;
+                case 8:
+                default:
+                    LOAD_FIXED_STATE_8BPP(nv3,PRAMIN);
+                    LOAD_FIXED_STATE_8BPP(nv3,PGRAPH);
+                    chip->Tri03 = 0L;
+                    break;
+            }
+            for (i = 0x00000; i < 0x00800; i++)
+                chip->PRAMIN[0x00000502 + i] = (i << 12) | 0x03;
+            chip->PGRAPH[0x00000630/4] = state->offset0;
+            chip->PGRAPH[0x00000634/4] = state->offset1;
+            chip->PGRAPH[0x00000638/4] = state->offset2;
+            chip->PGRAPH[0x0000063C/4] = state->offset3;
+            chip->PGRAPH[0x00000650/4] = state->pitch0;
+            chip->PGRAPH[0x00000654/4] = state->pitch1;
+            chip->PGRAPH[0x00000658/4] = state->pitch2;
+            chip->PGRAPH[0x0000065C/4] = state->pitch3;
+            break;
+	    case 4:
+	    case 5:
+            LOAD_FIXED_STATE(nv4,PFIFO);
+            LOAD_FIXED_STATE(nv4,PRAMIN);
+            LOAD_FIXED_STATE(nv4,PGRAPH);
+            switch (state->bpp)
+            {
+                case 15:
+                    LOAD_FIXED_STATE_15BPP(nv4,PRAMIN);
+                    LOAD_FIXED_STATE_15BPP(nv4,PGRAPH);
+                    chip->Tri03 = (RivaTexturedTriangle03  *)&(chip->FIFO[0x0000E000/4]);
+                    break;
+                case 16:
+                    LOAD_FIXED_STATE_16BPP(nv4,PRAMIN);
+                    LOAD_FIXED_STATE_16BPP(nv4,PGRAPH);
+                    chip->Tri03 = (RivaTexturedTriangle03  *)&(chip->FIFO[0x0000E000/4]);
+                    break;
+                case 24:
+                case 32:
+                    LOAD_FIXED_STATE_32BPP(nv4,PRAMIN);
+                    LOAD_FIXED_STATE_32BPP(nv4,PGRAPH);
+                    chip->Tri03 = 0L;
+                    break;
+                case 8:
+                default:
+                    LOAD_FIXED_STATE_8BPP(nv4,PRAMIN);
+                    LOAD_FIXED_STATE_8BPP(nv4,PGRAPH);
+                    chip->Tri03 = 0L;
+                    break;
+            }
+            chip->PGRAPH[0x00000640/4] = state->offset0;
+            chip->PGRAPH[0x00000644/4] = state->offset1;
+            chip->PGRAPH[0x00000648/4] = state->offset2;
+            chip->PGRAPH[0x0000064C/4] = state->offset3;
+            chip->PGRAPH[0x00000670/4] = state->pitch0;
+            chip->PGRAPH[0x00000674/4] = state->pitch1;
+            chip->PGRAPH[0x00000678/4] = state->pitch2;
+            chip->PGRAPH[0x0000067C/4] = state->pitch3;
+            break;
+    }
+//NOTICE("8");
+//    LOAD_FIXED_STATE(Riva,FIFO); /* FIX ME*/
+//NOTICE("9");
+    /*
+     * Load HW mode state.
+     */
+    outb(0x19, 0x3D4); outb(state->repaint0, 0x3D5);
+    outb(0x1A, 0x3D4); outb(state->repaint1, 0x3D5);
+    outb(0x25, 0x3D4); outb(state->screen, 0x3D5);
+    outb(0x28, 0x3D4); outb(state->pixel, 0x3D5);
+    outb(0x2D, 0x3D4); outb(state->horiz, 0x3D5);
+    outb(0x1B, 0x3D4); outb(state->arbitration0, 0x3D5);
+    outb(0x20, 0x3D4); outb(state->arbitration1, 0x3D5);
+    outb(0x30, 0x3D4); outb(state->cursor0, 0x3D5);
+    outb(0x31, 0x3D4); outb(state->cursor1, 0x3D5);
+    chip->PRAMDAC[0x00000300/4]  = state->cursor2;
+    chip->PRAMDAC[0x00000508/4]  = state->vpll;
+    chip->PRAMDAC[0x0000050C/4]  = state->pllsel;
+    chip->PRAMDAC[0x00000600/4]  = state->general;
+    /*
+     * Turn off VBlank enable and reset.
+     */
+//    *(chip->VBLANKENABLE) = 0;		/* FIXME*/
+//    *(chip->VBLANK)       = chip->VBlankBit; /*FIXME*/
+    /*
+     * Set interrupt enable.
+     */    
+    chip->PMC[0x00000140/4]  = chip->EnableIRQ & 0x01;
+    /*
+     * Set current state pointer.
+     */
+    chip->CurrentState = state;
+    /*
+     * Reset FIFO free count.
+     */
+    chip->FifoFreeCount = 0;
+}
+static void UnloadStateExt
+(
+    RIVA_HW_INST  *chip,
+    RIVA_HW_STATE *state
+)
+{
+    /*
+     * Save current HW state.
+     */
+    outb(0x19, 0x3D4); state->repaint0     = inb(0x3D5);
+    outb(0x1A, 0x3D4); state->repaint1     = inb(0x3D5);
+    outb(0x25, 0x3D4); state->screen       = inb(0x3D5);
+    outb(0x28, 0x3D4); state->pixel        = inb(0x3D5);
+    outb(0x2D, 0x3D4); state->horiz        = inb(0x3D5);
+    outb(0x1B, 0x3D4); state->arbitration0 = inb(0x3D5);
+    outb(0x20, 0x3D4); state->arbitration1 = inb(0x3D5);
+    outb(0x30, 0x3D4); state->cursor0      = inb(0x3D5);
+    outb(0x31, 0x3D4); state->cursor1      = inb(0x3D5);
+                      state->cursor2      = chip->PRAMDAC[0x00000300/4];
+                      state->vpll         = chip->PRAMDAC[0x00000508/4];
+                      state->pllsel       = chip->PRAMDAC[0x0000050C/4];
+                      state->general      = chip->PRAMDAC[0x00000600/4];
+                      state->config       = chip->PFB[0x00000200/4];
+                      switch (chip->Architecture)
+                      {
+			      case 3:
+                              state->offset0  = chip->PGRAPH[0x00000630/4];
+                              state->offset1  = chip->PGRAPH[0x00000634/4];
+                              state->offset2  = chip->PGRAPH[0x00000638/4];
+                              state->offset3  = chip->PGRAPH[0x0000063C/4];
+                              state->pitch0   = chip->PGRAPH[0x00000650/4];
+                              state->pitch1   = chip->PGRAPH[0x00000654/4];
+                              state->pitch2   = chip->PGRAPH[0x00000658/4];
+                              state->pitch3   = chip->PGRAPH[0x0000065C/4];
+                              break;
+			      case 4:
+			      case 5:
+                              state->offset0  = chip->PGRAPH[0x00000640/4];
+                              state->offset1  = chip->PGRAPH[0x00000644/4];
+                              state->offset2  = chip->PGRAPH[0x00000648/4];
+                              state->offset3  = chip->PGRAPH[0x0000064C/4];
+                              state->pitch0   = chip->PGRAPH[0x00000670/4];
+                              state->pitch1   = chip->PGRAPH[0x00000674/4];
+                              state->pitch2   = chip->PGRAPH[0x00000678/4];
+                              state->pitch3   = chip->PGRAPH[0x0000067C/4];
+                              break;
+                      }
+}
+static void SetStartAddress
+(
+    RIVA_HW_INST *chip,
+    unsigned      start
+)
+{
+    int offset = start >> 2;
+    int pan    = (start & 3) << 1;
+    unsigned char tmp;
+
+    /*
+     * Unlock extended registers.
+     */
+    outb(chip->LockUnlockIndex, chip->LockUnlockIO);
+    outb(0x57, chip->LockUnlockIO + 1);
+    /*
+     * Set start address.
+     */
+    outb(0x0D, 0x3D4);
+    outb(offset, 0x3D5);
+    outb(0x0C, 0x3D4);
+    outb(offset >> 8, 0x3D5);
+    outb(0x19, 0x3D4);
+    tmp = inb(0x3D5);
+    outb(((offset >> 16) & 0x0F) | (tmp & 0xF0), 0x3D5);
+    /*
+     * 4 pixel pan register.
+     */
+    offset = inb(chip->IO + 0x0A);
+    outb(0x13, 0x3C0);
+    outb(pan, 0x3C0);
+}
+static void nv3SetSurfaces2D
+(
+    RIVA_HW_INST *chip,
+    unsigned     surf0,
+    unsigned     surf1
+)
+{
+    while (nv3Busy(chip));
+    chip->PGRAPH[0x00000630/4] = surf0;
+    chip->PGRAPH[0x00000634/4] = surf1;
+}
+static void nv4SetSurfaces2D
+(
+    RIVA_HW_INST *chip,
+    unsigned     surf0,
+    unsigned     surf1
+)
+{
+    while (nv4Busy(chip));
+    chip->PGRAPH[0x00000640/4] = surf0;
+    chip->PGRAPH[0x00000644/4] = surf1;
+}
+static void nv3SetSurfaces3D
+(
+    RIVA_HW_INST *chip,
+    unsigned     surf0,
+    unsigned     surf1
+)
+{
+    while (nv3Busy(chip));
+    chip->PGRAPH[0x00000638/4] = surf0;
+    chip->PGRAPH[0x0000063C/4] = surf1;
+}
+static void nv4SetSurfaces3D
+(
+    RIVA_HW_INST *chip,
+    unsigned     surf0,
+    unsigned     surf1
+)
+{
+    while (nv4Busy(chip));
+    chip->PGRAPH[0x00000648/4] = surf0;
+    chip->PGRAPH[0x0000064C/4] = surf1;
+}
+
+/****************************************************************************\
+*                                                                            *
+*                      Probe RIVA Chip Configuration                         *
+*                                                                            *
+\****************************************************************************/
+
+void nv3GetConfig
+(
+    RIVA_HW_INST *chip
+)
+{
+    /*
+     * Fill in chip configuration.
+     */
+    if (chip->PFB[0x00000000/4] & 0x00000020)
+    {
+        if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
+         && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02))
+        {        
+            /*
+             * SDRAM 128 ZX.
+             */
+            chip->RamBandwidthKBytesPerSec = 800000;
+            switch (chip->PFB[0x00000000/4] & 0x03)
+            {
+                case 2:
+                    chip->RamAmountKBytes = 1024 * 4 - 32;
+                    break;
+                case 1:
+                    chip->RamAmountKBytes = 1024 * 2 - 32;
+                    break;
+                default:
+                    chip->RamAmountKBytes = 1024 * 8 - 32;
+                    break;
+            }
+        }            
+        else            
+        {
+            chip->RamBandwidthKBytesPerSec = 1000000;
+            chip->RamAmountKBytes          = 1024 * 8 - 32;
+        }            
+    }
+    else
+    {
+        /*
+         * SGRAM 128.
+         */
+        chip->RamBandwidthKBytesPerSec = 1000000;
+        switch (chip->PFB[0x00000000/4] & 0x00000003)
+        {
+            case 0:
+                chip->RamAmountKBytes = 1024 * 8 - 32;
+                break;
+            case 2:
+                chip->RamAmountKBytes = 1024 * 4 - 32;
+                break;
+            default:
+                chip->RamAmountKBytes = 1024 * 2 - 32;
+                break;
+        }
+    }        
+    chip->CrystalFreqKHz   = (chip->PEXTDEV[0x00000000/4] & 0x00000020) ? 14318 : 13500;
+    chip->CURSOR           = &(chip->PRAMIN[0x00008000/4 - 0x0800/4]);
+    chip->CURSORPOS        = &(chip->PRAMDAC[0x0300/4]);
+    chip->VBLANKENABLE     = &(chip->PGRAPH[0x0140/4]);
+    chip->VBLANK           = &(chip->PGRAPH[0x0100/4]);
+    chip->VBlankBit        = 0x00000100;
+    chip->MaxVClockFreqKHz = 230000;
+    chip->LockUnlockIO     = 0x3C4;
+    chip->LockUnlockIndex  = 0x06;
+    /*
+     * Set chip functions.
+     */
+    chip->Busy            = nv3Busy;
+    chip->ShowHideCursor  = ShowHideCursor;
+    chip->CalcStateExt    = CalcStateExt;
+    chip->LoadStateExt    = LoadStateExt;
+    chip->UnloadStateExt  = UnloadStateExt;
+    chip->SetStartAddress = SetStartAddress;
+    chip->SetSurfaces2D   = nv3SetSurfaces2D;
+    chip->SetSurfaces3D   = nv3SetSurfaces3D;
+}
+
+void nv4GetConfig
+(
+    RIVA_HW_INST *chip
+)
+{
+    /*
+     * Fill in chip configuration.
+     */
+    switch (chip->PFB[0x00000000/4] & 0x00000003)
+    {
+        case 0:
+            chip->RamAmountKBytes = 1024 * 32 - 128;
+            break;
+        case 1:
+            chip->RamAmountKBytes = 1024 * 4 - 128;
+            break;
+        case 2:
+            chip->RamAmountKBytes = 1024 * 8 - 128;
+            break;
+        case 3:
+        default:
+            chip->RamAmountKBytes = 1024 * 16 - 128;
+            break;
+    }
+    switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003)
+    {
+        case 3:
+            chip->RamBandwidthKBytesPerSec = 800000;
+            break;
+        default:
+            chip->RamBandwidthKBytesPerSec = 1000000;
+            break;
+    }
+    chip->CrystalFreqKHz   = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500;
+    chip->CURSOR           = &(chip->PRAMIN[0x00010000/4 - 0x0800/4]);
+    chip->CURSORPOS        = &(chip->PRAMDAC[0x0300/4]);
+    chip->VBLANKENABLE     = &(chip->PCRTC[0x0140/4]);
+    chip->VBLANK           = &(chip->PCRTC[0x0100/4]);
+    chip->VBlankBit        = 0x00000001;
+    chip->MaxVClockFreqKHz = 250000;
+    chip->LockUnlockIO     = 0x3D4;
+    chip->LockUnlockIndex  = 0x1F;
+    /*
+     * Set chip functions.
+     */
+    chip->Busy            = nv4Busy;
+    chip->ShowHideCursor  = ShowHideCursor;
+    chip->CalcStateExt    = CalcStateExt;
+    chip->LoadStateExt    = LoadStateExt;
+    chip->UnloadStateExt  = UnloadStateExt;
+    chip->SetStartAddress = SetStartAddress;
+    chip->SetSurfaces2D   = nv4SetSurfaces2D;
+    chip->SetSurfaces3D   = nv4SetSurfaces3D;
+}
+
+void nv5GetConfig
+(
+    RIVA_HW_INST *chip
+)
+{
+    /*
+     * Fill in chip configuration.
+     */
+    switch (chip->PFB[0x00000000/4] & 0x00000003)
+    {
+        case 0:
+            chip->RamAmountKBytes = 1024 * 32 - 128;
+            break;
+        case 1:
+            chip->RamAmountKBytes = 1024 * 4 - 128;
+            break;
+        case 2:
+            chip->RamAmountKBytes = 1024 * 8 - 128;
+            break;
+        case 3:
+        default:
+            chip->RamAmountKBytes = 1024 * 16 - 128;
+            break;
+    }
+    switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003)
+    {
+        case 3:
+            chip->RamBandwidthKBytesPerSec = 800000;
+            break;
+        default:
+            chip->RamBandwidthKBytesPerSec = 1000000;
+            break;
+    }
+    chip->CrystalFreqKHz   = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500;
+    chip->CURSOR           = &(chip->PRAMIN[0x00010000/4 - 0x0800/4]);
+    chip->CURSORPOS        = &(chip->PRAMDAC[0x0300/4]);
+    chip->VBLANKENABLE     = &(chip->PCRTC[0x0140/4]);
+    chip->VBLANK           = &(chip->PCRTC[0x0100/4]);
+    chip->VBlankBit        = 0x00000001;
+    chip->MaxVClockFreqKHz = 250000;
+    chip->LockUnlockIO     = 0x3D4;
+    chip->LockUnlockIndex  = 0x1F;
+    /*
+     * Set chip functions.
+     */
+    chip->Busy            = nv4Busy;
+    chip->ShowHideCursor  = ShowHideCursor;
+    chip->CalcStateExt    = CalcStateExt;
+    chip->LoadStateExt    = LoadStateExt;
+    chip->UnloadStateExt  = UnloadStateExt;
+    chip->SetStartAddress = SetStartAddress;
+    chip->SetSurfaces2D   = nv4SetSurfaces2D;
+    chip->SetSurfaces3D   = nv4SetSurfaces3D;
+}
+
+int RivaGetConfig
+(
+    RIVA_HW_INST *chip
+)
+{
+    /*
+     * Save this so future SW know whats it's dealing with.
+     */
+    chip->Version = RIVA_SW_VERSION;
+    /*
+     * Chip specific configuration.
+     */
+    switch (chip->Architecture)
+    {
+        case 3:
+            nv3GetConfig(chip);
+            break;
+        case 4:
+            nv4GetConfig(chip);
+            break;
+	    case 5:
+	    nv5GetConfig(chip);
+        default:
+            return (-1);
+    }
+    /*
+     * Fill in FIFO pointers.
+     */
+    chip->Rop    = (RivaRop                 *)&(chip->FIFO[0x00000000/4]);
+    chip->Clip   = (RivaClip                *)&(chip->FIFO[0x00002000/4]);
+    chip->Patt   = (RivaPattern             *)&(chip->FIFO[0x00004000/4]);
+    chip->Pixmap = (RivaPixmap              *)&(chip->FIFO[0x00006000/4]);
+    chip->Blt    = (RivaScreenBlt           *)&(chip->FIFO[0x00008000/4]);
+    chip->Bitmap = (RivaBitmap              *)&(chip->FIFO[0x0000A000/4]);
+    chip->Tri03  = (RivaTexturedTriangle03  *)&(chip->FIFO[0x0000E000/4]);
+    return (0);
+}
+
diff -u --recursive --new-file v2.3.25/linux/drivers/video/riva_hw.h linux/drivers/video/riva_hw.h
--- v2.3.25/linux/drivers/video/riva_hw.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/riva_hw.h	Tue Nov  2 08:15:05 1999
@@ -0,0 +1,343 @@
+/***************************************************************************\
+|*                                                                           *|
+|*       Copyright 1993-1998 NVIDIA, Corporation.  All rights reserved.      *|
+|*                                                                           *|
+|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
+|*     international laws.  Users and possessors of this source code are     *|
+|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
+|*     use this code in individual and commercial software.                  *|
+|*                                                                           *|
+|*     Any use of this source code must include,  in the user documenta-     *|
+|*     tion and  internal comments to the code,  notices to the end user     *|
+|*     as follows:                                                           *|
+|*                                                                           *|
+|*       Copyright 1993-1998 NVIDIA, Corporation.  All rights reserved.      *|
+|*                                                                           *|
+|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
+|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
+|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
+|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
+|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
+|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
+|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
+|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
+|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
+|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
+|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
+|*                                                                           *|
+|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
+|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
+|*     consisting  of "commercial  computer  software"  and  "commercial     *|
+|*     computer  software  documentation,"  as such  terms  are  used in     *|
+|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
+|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
+|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
+|*     all U.S. Government End Users  acquire the source code  with only     *|
+|*     those rights set forth herein.                                        *|
+|*                                                                           *|
+\***************************************************************************/
+/* 
+ * GPL licensing note -- nVidia is allowing a liberal interpretation of 
+ * the documentation restriction above, to merely say that this nVidia's
+ * copyright and disclaimer should be included with all code derived 
+ * from this source.  -- Jeff Garzik <jgarzik@mandrakesoft.com>, 01/Nov/99
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/nv/riva_hw.h,v 1.1.2.2 1998/12/22 16:33:19 hohndel Exp $ */
+#ifndef __RIVA_HW_H__
+#define __RIVA_HW_H__
+#define RIVA_SW_VERSION 0x00010000
+
+/***************************************************************************\
+*                                                                           *
+*                             FIFO registers.                               *
+*                                                                           *
+\***************************************************************************/
+
+/*
+ * Raster OPeration. Windows style ROP3.
+ */
+typedef volatile struct
+{
+    unsigned reserved00[4];
+    unsigned short FifoFree;
+    unsigned short Nop;
+    unsigned reserved01[0x0BB];
+    unsigned Rop3;
+} RivaRop;
+/*
+ * 8X8 Monochrome pattern.
+ */
+typedef volatile struct
+{
+    unsigned reserved00[4];
+    unsigned short FifoFree;
+    unsigned short Nop;
+    unsigned reserved01[0x0BD];
+    unsigned Shape;
+    unsigned reserved03[0x001];
+    unsigned Color0;
+    unsigned Color1;
+    unsigned Monochrome[2];
+} RivaPattern;
+/*
+ * Scissor clip rectangle.
+ */
+typedef volatile struct
+{
+    unsigned reserved00[4];
+    unsigned short FifoFree;
+    unsigned short Nop;
+    unsigned reserved01[0x0BB];
+    unsigned TopLeft;
+    unsigned WidthHeight;
+} RivaClip;
+/*
+ * 2D filled rectangle.
+ */
+typedef volatile struct
+{
+    unsigned reserved00[4];
+    unsigned short FifoFree;
+    unsigned short Nop[1];
+    unsigned reserved01[0x0BC];
+    unsigned Color;
+    unsigned reserved03[0x03E];
+    unsigned TopLeft;
+    unsigned WidthHeight;
+} RivaRectangle;
+/*
+ * 2D screen-screen BLT.
+ */
+typedef volatile struct
+{
+    unsigned reserved00[4];
+    unsigned short FifoFree;
+    unsigned short Nop;
+    unsigned reserved01[0x0BB];
+    unsigned TopLeftSrc;
+    unsigned TopLeftDst;
+    unsigned WidthHeight;
+} RivaScreenBlt;
+/*
+ * 2D pixel BLT.
+ */
+typedef volatile struct
+{
+    unsigned reserved00[4];
+    unsigned short FifoFree;
+    unsigned short Nop[1];
+    unsigned reserved01[0x0BC];
+    unsigned TopLeft;
+    unsigned WidthHeight;
+    unsigned WidthHeightIn;
+    unsigned reserved02[0x03C];
+    unsigned Pixels;
+} RivaPixmap;
+/*
+ * Filled rectangle combined with monochrome expand.  Useful for glyphs.
+ */
+typedef volatile struct
+{
+    unsigned reserved00[4];
+    unsigned short FifoFree;
+    unsigned short Nop;
+    unsigned reserved01[0x0BB];
+    unsigned reserved03[(0x040)-1];
+    unsigned Color1A;
+    struct
+    {
+        unsigned TopLeft;
+        unsigned WidthHeight;
+    } UnclippedRectangle[64];
+    unsigned reserved04[(0x080)-3];
+    struct
+    {
+        unsigned TopLeft;
+        unsigned BottomRight;
+    } ClipB;
+    unsigned Color1B;
+    struct
+    {
+        unsigned TopLeft;
+        unsigned BottomRight;
+    } ClippedRectangle[64];
+    unsigned reserved05[(0x080)-5];
+    struct
+    {
+        unsigned TopLeft;
+        unsigned BottomRight;
+    } ClipC;
+    unsigned Color1C;
+    unsigned WidthHeightC;
+    unsigned PointC;
+    unsigned MonochromeData1C;
+    unsigned reserved06[(0x080)+121];
+    struct
+    {
+        unsigned TopLeft;
+        unsigned BottomRight;
+    } ClipD;
+    unsigned Color1D;
+    unsigned WidthHeightInD;
+    unsigned WidthHeightOutD;
+    unsigned PointD;
+    unsigned MonochromeData1D;
+    unsigned reserved07[(0x080)+120];
+    struct
+    {
+        unsigned TopLeft;
+        unsigned BottomRight;
+    } ClipE;
+    unsigned Color0E;
+    unsigned Color1E;
+    unsigned WidthHeightInE;
+    unsigned WidthHeightOutE;
+    unsigned PointE;
+    unsigned MonochromeData01E;
+} RivaBitmap;
+/*
+ * 3D textured, Z buffered triangle.
+ */
+typedef volatile struct
+{
+    unsigned reserved00[4];
+    unsigned short FifoFree;
+    unsigned short Nop;
+    unsigned reserved01[0x0BC];
+    unsigned TextureOffset;
+    unsigned TextureFormat;
+    unsigned TextureFilter;
+    unsigned FogColor;
+    unsigned Control;
+    unsigned AlphaTest;
+    unsigned reserved02[0x339];
+    unsigned FogAndIndex;
+    unsigned Color;
+    float ScreenX;
+    float ScreenY;
+    float ScreenZ;
+    float EyeM;
+    float TextureS;
+    float TextureT;
+} RivaTexturedTriangle03;
+
+/***************************************************************************\
+*                                                                           *
+*                        Virtualized RIVA H/W interface.                    *
+*                                                                           *
+\***************************************************************************/
+
+struct _riva_hw_inst;
+struct _riva_hw_state;
+/*
+ * Virtialized chip interface. Makes RIVA 128 and TNT look alike.
+ */
+typedef struct _riva_hw_inst
+{
+    /*
+     * Chip specific settings.
+     */
+    unsigned Architecture;
+    unsigned Version;
+    unsigned CrystalFreqKHz;
+    unsigned RamAmountKBytes;
+    unsigned MaxVClockFreqKHz;
+    unsigned RamBandwidthKBytesPerSec;
+    unsigned EnableIRQ;
+    unsigned IO;
+    unsigned LockUnlockIO;
+    unsigned LockUnlockIndex;
+    unsigned VBlankBit;
+    unsigned FifoFreeCount;
+    /*
+     * Non-FIFO registers.
+     */
+    volatile unsigned *PCRTC;
+    volatile unsigned *PRAMDAC;
+    volatile unsigned *PFB;
+    volatile unsigned *PFIFO;
+    volatile unsigned *PGRAPH;
+    volatile unsigned *PEXTDEV;
+    volatile unsigned *PTIMER;
+    volatile unsigned *PMC;
+    volatile unsigned *PRAMIN;
+    volatile unsigned *FIFO;
+    volatile unsigned *CURSOR;
+    volatile unsigned *CURSORPOS;
+    volatile unsigned *VBLANKENABLE;
+    volatile unsigned *VBLANK;
+    /*
+     * Common chip functions.
+     */
+    int  (*Busy)(struct _riva_hw_inst *);
+    void (*CalcStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *,int,int,int,int,int,int,int,int,int,int,int,int,int);
+    void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
+    void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
+    void (*SetStartAddress)(struct _riva_hw_inst *,unsigned);
+    void (*SetSurfaces2D)(struct _riva_hw_inst *,unsigned,unsigned);
+    void (*SetSurfaces3D)(struct _riva_hw_inst *,unsigned,unsigned);
+    int  (*ShowHideCursor)(struct _riva_hw_inst *,int);
+    /*
+     * Current extended mode settings.
+     */
+    struct _riva_hw_state *CurrentState;
+    /*
+     * FIFO registers.
+     */
+    RivaRop                 *Rop;
+    RivaPattern             *Patt;
+    RivaClip                *Clip;
+    RivaPixmap              *Pixmap;
+    RivaScreenBlt           *Blt;
+    RivaBitmap              *Bitmap;
+    RivaTexturedTriangle03  *Tri03;
+} RIVA_HW_INST;
+/*
+ * Extended mode state information.
+ */
+typedef struct _riva_hw_state
+{
+    unsigned bpp;
+    unsigned width;
+    unsigned height;
+    unsigned repaint0;
+    unsigned repaint1;
+    unsigned screen;
+    unsigned pixel;
+    unsigned horiz;
+    unsigned arbitration0;
+    unsigned arbitration1;
+    unsigned vpll;
+    unsigned pllsel;
+    unsigned general;
+    unsigned config;
+    unsigned cursor0;
+    unsigned cursor1;
+    unsigned cursor2;
+    unsigned offset0;
+    unsigned offset1;
+    unsigned offset2;
+    unsigned offset3;
+    unsigned pitch0;
+    unsigned pitch1;
+    unsigned pitch2;
+    unsigned pitch3;
+} RIVA_HW_STATE;
+/*
+ * External routines.
+ */
+int RivaGetConfig(RIVA_HW_INST *);
+/*
+ * FIFO Free Count. Should attempt to yield processor if RIVA is busy.
+ */
+#define RIVA_FIFO_FREE(hwinst,hwptr,cnt)                                    \
+{                                                                           \
+while ((hwinst).FifoFreeCount < (cnt))                                      \
+{                                                                           \
+    (hwinst).FifoFreeCount = (hwinst).hwptr->FifoFree >> 2;                 \
+}                                                                           \
+(hwinst).FifoFreeCount -= (cnt);                                            \
+}
+#endif /* __RIVA_HW_H__ */
+
diff -u --recursive --new-file v2.3.25/linux/drivers/video/riva_tbl.h linux/drivers/video/riva_tbl.h
--- v2.3.25/linux/drivers/video/riva_tbl.h	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/riva_tbl.h	Tue Nov  2 08:15:05 1999
@@ -0,0 +1,402 @@
+ /***************************************************************************\
+|*                                                                           *|
+|*       Copyright 1993-1998 NVIDIA, Corporation.  All rights reserved.      *|
+|*                                                                           *|
+|*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
+|*     international laws.  Users and possessors of this source code are     *|
+|*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
+|*     use this code in individual and commercial software.                  *|
+|*                                                                           *|
+|*     Any use of this source code must include,  in the user documenta-     *|
+|*     tion and  internal comments to the code,  notices to the end user     *|
+|*     as follows:                                                           *|
+|*                                                                           *|
+|*       Copyright 1993-1998 NVIDIA, Corporation.  All rights reserved.      *|
+|*                                                                           *|
+|*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
+|*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
+|*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
+|*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
+|*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
+|*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
+|*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
+|*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
+|*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
+|*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
+|*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
+|*                                                                           *|
+|*     U.S. Government  End  Users.   This source code  is a "commercial     *|
+|*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
+|*     consisting  of "commercial  computer  software"  and  "commercial     *|
+|*     computer  software  documentation,"  as such  terms  are  used in     *|
+|*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
+|*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
+|*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
+|*     all U.S. Government End Users  acquire the source code  with only     *|
+|*     those rights set forth herein.                                        *|
+|*                                                                           *|
+ \***************************************************************************/
+/* 
+ * GPL licensing note -- nVidia is allowing a liberal interpretation of 
+ * the documentation restriction above, to merely say that this nVidia's
+ * copyright and disclaimer should be included with all code derived 
+ * from this source.  -- Jeff Garzik <jgarzik@mandrakesoft.com>, 01/Nov/99
+ */
+
+/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/nv/riva_tbl.h,v 1.1.2.2 1998/12/22 16:33:20 hohndel Exp $ */
+/*
+ * RIVA Fixed Functionality Init Tables.
+ */
+static unsigned RivaTablePMC[][2] =
+{
+    {0x00000050, 0x00000000},
+    {0x00000080, 0xFFFF00FF},
+    {0x00000080, 0xFFFFFFFF}
+};
+static unsigned RivaTablePTIMER[][2] =
+{
+    {0x00000080, 0x00000008},
+    {0x00000084, 0x00000003},
+    {0x00000050, 0x00000000},
+    {0x00000040, 0xFFFFFFFF}
+};
+static unsigned RivaTableFIFO[][2] =
+{
+    {0x00000000, 0x80000000},
+    {0x00000800, 0x80000001},
+    {0x00001000, 0x80000002},
+    {0x00001800, 0x80000010},
+    {0x00002000, 0x80000011},
+    {0x00002800, 0x80000012},
+    {0x00003800, 0x80000013}
+};
+static unsigned nv3TablePFIFO[][2] =
+{
+    {0x00000140, 0x00000000},
+    {0x00000480, 0x00000000},
+    {0x00000490, 0x00000000},
+    {0x00000494, 0x00000000},
+    {0x00000481, 0x00000000},
+    {0x00000084, 0x00000000},
+    {0x00000086, 0x00002000},
+    {0x00000085, 0x00002200},
+    {0x00000484, 0x00000000},
+    {0x0000049C, 0x00000000},
+    {0x00000104, 0x00000000},
+    {0x00000108, 0x00000000},
+    {0x00000100, 0x00000000},
+    {0x000004A0, 0x00000000},
+    {0x000004A4, 0x00000000},
+    {0x000004A8, 0x00000000},
+    {0x000004AC, 0x00000000},
+    {0x000004B0, 0x00000000},
+    {0x000004B4, 0x00000000},
+    {0x000004B8, 0x00000000},
+    {0x000004BC, 0x00000000},
+    {0x00000050, 0x00000000},
+    {0x00000040, 0xFFFFFFFF},
+    {0x00000480, 0x00000001},
+    {0x00000490, 0x00000001},
+    {0x00000140, 0x00000001}
+};
+static unsigned nv3TablePGRAPH[][2] =
+{
+    {0x00000020, 0x1230001F},
+    {0x00000021, 0x10113000},
+    {0x00000022, 0x1131F101},
+    {0x00000023, 0x0100F531},
+    {0x00000060, 0x00000000},
+    {0x00000065, 0x00000000},
+    {0x00000068, 0x00000000},
+    {0x00000069, 0x00000000},
+    {0x0000006A, 0x00000000},
+    {0x0000006B, 0x00000000},
+    {0x0000006C, 0x00000000},
+    {0x0000006D, 0x00000000},
+    {0x0000006E, 0x00000000},
+    {0x0000006F, 0x00000000},
+    {0x000001A8, 0x00000000},
+    {0x00000440, 0xFFFFFFFF},
+    {0x00000480, 0x00000001},
+    {0x000001A0, 0x00000000},
+    {0x000001A2, 0x00000000},
+    {0x0000018A, 0xFFFFFFFF},
+    {0x00000190, 0x00000000},
+    {0x00000142, 0x00000000},
+    {0x00000154, 0x00000000},
+    {0x00000155, 0xFFFFFFFF},
+    {0x00000156, 0x00000000},
+    {0x00000157, 0xFFFFFFFF},
+    {0x00000064, 0x10010002},
+    {0x00000050, 0x00000000},
+    {0x00000051, 0x00000000},
+    {0x00000040, 0xFFFFFFFF},
+    {0x00000041, 0xFFFFFFFF},
+    {0x00000440, 0xFFFFFFFF},
+    {0x000001A9, 0x00000001}
+};
+static unsigned nv3TablePGRAPH_8BPP[][2] =
+{
+    {0x000001AA, 0x00001111}
+};
+static unsigned nv3TablePGRAPH_15BPP[][2] =
+{
+    {0x000001AA, 0x00002222}
+};
+static unsigned nv3TablePGRAPH_32BPP[][2] =
+{
+    {0x000001AA, 0x00003333}
+};
+static unsigned nv3TablePRAMIN[][2] =
+{
+    {0x00000500, 0x00010000},
+    {0x00000501, 0x007FFFFF},
+    {0x00000200, 0x80000000},
+    {0x00000201, 0x00C20341},
+    {0x00000204, 0x80000001},
+    {0x00000205, 0x00C50342},
+    {0x00000208, 0x80000002},
+    {0x00000209, 0x00C60343},
+    {0x00000240, 0x80000010},
+    {0x00000241, 0x00D10344},
+    {0x00000244, 0x80000011},
+    {0x00000245, 0x00D00345},
+    {0x00000248, 0x80000012},
+    {0x00000249, 0x00CC0346},
+    {0x0000024C, 0x80000013},
+    {0x0000024D, 0x00D70347},
+    {0x00000D05, 0x00000000},
+    {0x00000D06, 0x00000000},
+    {0x00000D07, 0x00000000},
+    {0x00000D09, 0x00000000},
+    {0x00000D0A, 0x00000000},
+    {0x00000D0B, 0x00000000},
+    {0x00000D0D, 0x00000000},
+    {0x00000D0E, 0x00000000},
+    {0x00000D0F, 0x00000000},
+    {0x00000D11, 0x00000000},
+    {0x00000D12, 0x00000000},
+    {0x00000D13, 0x00000000},
+    {0x00000D15, 0x00000000},
+    {0x00000D16, 0x00000000},
+    {0x00000D17, 0x00000000},
+    {0x00000D19, 0x00000000},
+    {0x00000D1A, 0x00000000},
+    {0x00000D1B, 0x00000000},
+    {0x00000D1D, 0x00000140},
+    {0x00000D1E, 0x00000000},
+    {0x00000D1F, 0x00000000}
+};
+static unsigned nv3TablePRAMIN_8BPP[][2] =
+{
+    {0x00000D04, 0x10110203},
+    {0x00000D08, 0x10110203},
+    {0x00000D0C, 0x10110203},
+    {0x00000D10, 0x10118203},
+    {0x00000D14, 0x10110203},
+    {0x00000D18, 0x10110203},
+    {0x00000D1C, 0x10419208}
+};
+static unsigned nv3TablePRAMIN_15BPP[][2] =
+{
+    {0x00000D04, 0x10110200},
+    {0x00000D08, 0x10110200},
+    {0x00000D0C, 0x10110200},
+    {0x00000D10, 0x10118200},
+    {0x00000D14, 0x10110200},
+    {0x00000D18, 0x10110200},
+    {0x00000D1C, 0x10419208}
+};
+static unsigned nv3TablePRAMIN_32BPP[][2] =
+{
+    {0x00000D04, 0x10110201},
+    {0x00000D08, 0x10110201},
+    {0x00000D0C, 0x10110201},
+    {0x00000D10, 0x10118201},
+    {0x00000D14, 0x10110201},
+    {0x00000D18, 0x10110201},
+    {0x00000D1C, 0x10419208}
+};
+static unsigned nv4TablePFIFO[][2] =
+{
+    {0x00000140, 0x00000000},
+    {0x00000480, 0x00000000},
+    {0x00000494, 0x00000000},
+    {0x00000400, 0x00000000},
+    {0x00000414, 0x00000000},
+    {0x00000084, 0x03000100},  
+    {0x00000085, 0x00000110},
+    {0x00000086, 0x00000112},  
+    {0x00000143, 0x0000FFFF},
+    {0x00000496, 0x0000FFFF},
+    {0x00000050, 0x00000000},
+    {0x00000040, 0xFFFFFFFF},
+    {0x00000415, 0x00000001},
+    {0x00000480, 0x00000001},
+    {0x00000494, 0x00000001},
+    {0x00000495, 0x00000001},
+    {0x00000140, 0x00000001}
+};
+static unsigned nv4TablePGRAPH[][2] =
+{
+    {0x00000020, 0x1231C001},
+    {0x00000021, 0x72111101},
+    {0x00000022, 0x11D5F071},
+    {0x00000023, 0x10D4FF31},
+    {0x00000060, 0x00000000},
+    {0x00000068, 0x00000000},
+    {0x00000070, 0x00000000},
+    {0x00000078, 0x00000000},
+    {0x00000061, 0x00000000},
+    {0x00000069, 0x00000000},
+    {0x00000071, 0x00000000},
+    {0x00000079, 0x00000000},
+    {0x00000062, 0x00000000},
+    {0x0000006A, 0x00000000},
+    {0x00000072, 0x00000000},
+    {0x0000007A, 0x00000000},
+    {0x00000063, 0x00000000},
+    {0x0000006B, 0x00000000},
+    {0x00000073, 0x00000000},
+    {0x0000007B, 0x00000000},
+    {0x00000064, 0x00000000},
+    {0x0000006C, 0x00000000},
+    {0x00000074, 0x00000000},
+    {0x0000007C, 0x00000000},
+    {0x00000065, 0x00000000},
+    {0x0000006D, 0x00000000},
+    {0x00000075, 0x00000000},
+    {0x0000007D, 0x00000000},
+    {0x00000066, 0x00000000},
+    {0x0000006E, 0x00000000},
+    {0x00000076, 0x00000000},
+    {0x0000007E, 0x00000000},
+    {0x00000067, 0x00000000},
+    {0x0000006F, 0x00000000},
+    {0x00000077, 0x00000000},
+    {0x0000007F, 0x00000000},
+    {0x00000058, 0x00000000},
+    {0x00000059, 0x00000000},
+    {0x0000005A, 0x00000000},
+    {0x0000005B, 0x00000000},
+    {0x00000196, 0x00000000},
+    {0x000001A1, 0x00FFFFFF},
+    {0x00000197, 0x00000000},
+    {0x000001A2, 0x00FFFFFF},
+    {0x00000198, 0x00000000},
+    {0x000001A3, 0x00FFFFFF},
+    {0x00000199, 0x00000000},
+    {0x000001A4, 0x00FFFFFF},
+    {0x00000050, 0x00000000},
+    {0x00000040, 0xFFFFFFFF},
+    {0x0000005C, 0x10010100},
+    {0x000001C8, 0x00000001}
+};
+static unsigned nv4TablePGRAPH_8BPP[][2] =
+{
+    {0x000001C4, 0xFFFFFFFF},
+    {0x000001C9, 0x00111111},
+    {0x00000186, 0x00001010},
+    {0x0000020C, 0x01010101}
+};
+static unsigned nv4TablePGRAPH_15BPP[][2] =
+{
+    {0x000001C4, 0xFFFFFFFF},
+    {0x000001C9, 0x00226222},
+    {0x00000186, 0x00002071},
+    {0x0000020C, 0x09090909}
+};
+static unsigned nv4TablePGRAPH_16BPP[][2] =
+{
+    {0x000001C4, 0xFFFFFFFF},
+    {0x000001C9, 0x00556555},
+    {0x00000186, 0x000050C2},
+    {0x0000020C, 0x0C0C0C0C}
+};
+static unsigned nv4TablePGRAPH_32BPP[][2] =
+{
+    {0x000001C4, 0xFFFFFFFF},
+    {0x000001C9, 0x0077D777},
+    {0x00000186, 0x000070E5},
+    {0x0000020C, 0x07070707}
+};
+static unsigned nv4TablePRAMIN[][2] =
+{
+    {0x00000000, 0x80000010},
+    {0x00000001, 0x80011145},
+    {0x00000002, 0x80000011},
+    {0x00000003, 0x80011146},
+    {0x00000004, 0x80000012},
+    {0x00000005, 0x80011147},
+    {0x00000006, 0x80000013},
+    {0x00000007, 0x80011148},
+    {0x00000020, 0x80000000},
+    {0x00000021, 0x80011142},
+    {0x00000022, 0x80000001},
+    {0x00000023, 0x80011143},
+    {0x00000024, 0x80000002},
+    {0x00000025, 0x80011144}, 
+    {0x00000500, 0x00003000},
+    {0x00000501, 0x02FFFFFF},
+    {0x00000502, 0x00000002},
+    {0x00000503, 0x00000002},
+    {0x00000508, 0x01008043},
+    {0x0000050A, 0x00000000},
+    {0x0000050B, 0x00000000},
+    {0x0000050C, 0x01008019},
+    {0x0000050E, 0x00000000},
+    {0x0000050F, 0x00000000},
+    {0x00000510, 0x01008018},
+    {0x00000512, 0x00000000},
+    {0x00000513, 0x00000000},
+    {0x00000514, 0x0100A033},
+    {0x00000516, 0x00000000},
+    {0x00000517, 0x00000000},
+    {0x00000518, 0x0100805F},
+    {0x0000051A, 0x00000000},
+    {0x0000051B, 0x00000000},
+    {0x0000051C, 0x0100804B},
+    {0x0000051E, 0x00000000},
+    {0x0000051F, 0x00000000},
+    {0x00000520, 0x0100A048},
+    {0x00000521, 0x00000D01},
+    {0x00000522, 0x11401140},
+    {0x00000523, 0x00000000}
+};
+static unsigned nv4TablePRAMIN_8BPP[][2] =
+{
+    {0x00000509, 0x00000301},
+    {0x0000050D, 0x00000301},
+    {0x00000511, 0x00000301},
+    {0x00000515, 0x00000301},
+    {0x00000519, 0x00000301},
+    {0x0000051D, 0x00000301}
+};
+static unsigned nv4TablePRAMIN_15BPP[][2] =
+{
+    {0x00000509, 0x00000901},
+    {0x0000050D, 0x00000901},
+    {0x00000511, 0x00000901},
+    {0x00000515, 0x00000901},
+    {0x00000519, 0x00000901},
+    {0x0000051D, 0x00000901}
+};
+static unsigned nv4TablePRAMIN_16BPP[][2] =
+{
+    {0x00000509, 0x00000C01},
+    {0x0000050D, 0x00000C01},
+    {0x00000511, 0x00000C01},
+    {0x00000515, 0x00000C01},
+    {0x00000519, 0x00000C01},
+    {0x0000051D, 0x00000C01}
+};
+static unsigned nv4TablePRAMIN_32BPP[][2] =
+{
+    {0x00000509, 0x00000E01},
+    {0x0000050D, 0x00000E01},
+    {0x00000511, 0x00000E01},
+    {0x00000515, 0x00000E01},
+    {0x00000519, 0x00000E01},
+    {0x0000051D, 0x00000E01}
+};
+
diff -u --recursive --new-file v2.3.25/linux/drivers/video/rivafb.c linux/drivers/video/rivafb.c
--- v2.3.25/linux/drivers/video/rivafb.c	Wed Dec 31 16:00:00 1969
+++ linux/drivers/video/rivafb.c	Tue Nov  2 08:15:05 1999
@@ -0,0 +1,1890 @@
+/*
+ * linux/drivers/video/rivafb.c - nVidia RIVA 128/TNT/TNT2 fb driver
+ *
+ * Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
+ *
+ * Contributors:
+ *
+ *	ani joshi:  Lots of debugging and cleanup work, really helped
+ *	get the driver going
+ *
+ * Initial template from skeletonfb.c, created 28 Dec 1997 by Geert Uytterhoeven
+ * Includes riva_hw.c from nVidia, see copyright below.
+ * KGI code provided the basis for state storage, init, and mode switching.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ */
+
+/* version number of this driver */
+#define RIVAFB_VERSION "0.6.5"
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/selection.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <video/fbcon.h>
+
+#include "riva_hw.h"
+#include "nv4ref.h"
+#include "nvreg.h"
+#include "vga.h"
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb32.h>
+
+#ifndef CONFIG_PCI /* sanity check */
+#error This driver requires PCI support.
+#endif
+
+/*****************************************************************
+ *
+ * various helpful macros and constants
+ *
+ */
+
+/* #define RIVAFBDEBUG */
+#ifdef RIVAFBDEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#ifndef RIVA_NDEBUG
+#define assert(expr) \
+	if(!(expr)) { \
+        printk( "Assertion failed! %s,%s,%s,line=%d\n",\
+        #expr,__FILE__,__FUNCTION__,__LINE__); \
+	*(int*)0 = 0; \
+        }
+#else
+#define assert(expr)
+#endif
+
+/* GGI compatibility macros */
+#define io_out8 outb
+#define io_in8 inb
+#define FatalError panic
+#define NUM_SEQ_REGS 0x05
+#define NUM_CRT_REGS 0x41
+#define NUM_GRC_REGS 0x09
+#define NUM_ATC_REGS 0x15
+
+/* max number of VGA controllers we scan for */
+#define RIVA_MAX_VGA_CONTROLLERS 8
+
+#define PFX "rivafb: "
+
+#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
+
+/* macro that allows you to set overflow bits */
+#define SetBitField(value,from,to) SetBF(to,GetBF(value,from))
+#define SetBit(n) (1<<(n))
+#define Set8Bits(value) ((value)&0xff)
+
+struct riva_chip_info {
+	const char *name;
+	unsigned arch_rev;
+	unsigned short vendor;
+	unsigned short device;
+};
+
+
+static const struct riva_chip_info riva_pci_probe_list[] =
+{
+	{"RIVA-128", 3, PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128},
+	{"RIVA-TNT", 4, PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT},
+	{"RIVA-TNT2", 5, PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2},
+	{"RIVA-TNT2", 5, PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2},
+	{"RIVA-TNT2", 5, PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2},
+	{"RIVA-TNT2", 5, PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2},
+	{NULL, 0, 0, 0}
+};
+
+
+/* holds the state of the VGA core and extended Riva hw state from riva_hw.c.
+ * From KGI originally. */
+struct riva_regs {
+	u8 attr[0x15];
+	u8 crtc[0x41];
+	u8 gra[0x09];
+	u8 seq[0x05];
+	u8 misc_output;
+	RIVA_HW_STATE ext;
+};
+
+
+/*
+ * describes the state of a Riva board
+ */
+struct rivafb_par {
+	struct riva_regs state; /* state of hw board */
+	__u32 visual;	/* FB_VISUAL_xxx */
+	unsigned depth; /* bpp of current mode */
+};
+
+typedef struct {
+	unsigned char red, green, blue, transp;
+} riva_cfb8_cmap_t;
+
+
+
+struct rivafb_info;
+struct rivafb_info {
+	struct fb_info info;	/* kernel framebuffer info */
+
+	RIVA_HW_INST riva;	/* interface to riva_hw.c */
+
+	const char *drvr_name;	/* Riva hardware board type */
+
+	unsigned long ctrl_base_phys; /* physical control register base addr */
+	unsigned long fb_base_phys; /* physical framebuffer base addr */
+
+	caddr_t ctrl_base;	/* virtual control register base addr */
+	caddr_t fb_base;	/* virtual framebuffer base addr */
+
+	unsigned ram_amount;	/* amount of RAM on card, in megabytes */
+	unsigned dclk_max;	/* max DCLK */
+
+	struct riva_regs initial_state;		/* initial startup video mode */
+
+	struct display disp;
+	int currcon;
+	struct display *currcon_display;
+
+	struct rivafb_info *next;
+
+	struct pci_dev *pd;		/* pointer to board's pci info */
+	unsigned base0_region_size;	/* size of control register region */
+	unsigned base1_region_size;	/* size of framebuffer region */
+
+#ifdef FBCON_HAS_CFB8
+	riva_cfb8_cmap_t palette[256];	/* VGA DAC palette cache */
+#endif
+
+#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
+        union {
+#ifdef FBCON_HAS_CFB16
+                u_int16_t       cfb16[16];
+#endif
+#ifdef FBCON_HAS_CFB32
+                u_int32_t       cfb32[16];
+#endif
+        } con_cmap;
+#endif /* FBCON_HAS_CFB16 | FBCON_HAS_CFB32 */
+};
+
+/* ------------------- global variables ------------------------ */
+
+
+static struct rivafb_info *riva_boards = NULL;
+
+/* command line data, set in rivafb_setup() */
+static char fontname[40] __initdata = { 0 };
+static char noaccel __initdata = 0;		/* unused */
+#ifndef MODULE
+static const char *mode_option __initdata = NULL;
+#endif
+
+
+/* ------------------- prototypes ------------------------------ */
+
+int rivafb_open (struct fb_info *info, int user);
+int rivafb_release (struct fb_info *info, int user);
+int rivafb_get_fix (struct fb_fix_screeninfo *fix, int con,
+		  struct fb_info *info);
+int rivafb_get_var (struct fb_var_screeninfo *var, int con,
+		  struct fb_info *info);
+int rivafb_set_var (struct fb_var_screeninfo *var, int con,
+		  struct fb_info *info);
+int rivafb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
+		   struct fb_info *info);
+int rivafb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
+		   struct fb_info *info);
+int rivafb_pan_display (struct fb_var_screeninfo *var, int con,
+		      struct fb_info *info);
+int rivafb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
+		unsigned long arg, int con, struct fb_info *info);
+int rivafb_switch(int con, struct fb_info *info);
+void rivafb_blank (int blank, struct fb_info *info);
+
+static void riva_load_video_mode (struct rivafb_info *rivainfo,
+				struct fb_var_screeninfo *video_mode);
+static int riva_getcolreg (unsigned regno, unsigned *red, unsigned *green,
+			 unsigned *blue, unsigned *transp,
+			 struct fb_info *info);
+static int riva_setcolreg (unsigned regno, unsigned red, unsigned green,
+		    unsigned blue, unsigned transp,
+		    struct fb_info *info);
+static int riva_get_cmap_len(const struct fb_var_screeninfo *var);
+
+static u32 riva_pci_region_size (struct pci_dev *pd, unsigned baseaddr);
+
+static void riva_pci_iounmap (struct rivafb_info *rinfo);
+static int riva_pci_register (struct pci_dev *pd, const struct riva_chip_info *rci);
+static int riva_pci_register_devices (void);
+static int riva_set_fbinfo (struct rivafb_info *rinfo);
+
+static
+void riva_save_state(struct rivafb_info *rinfo, struct riva_regs *regs);
+static
+void riva_load_state(struct rivafb_info *rinfo, struct riva_regs *regs);
+static
+struct rivafb_info *riva_board_list_add(struct rivafb_info *board_list,
+				 struct rivafb_info *new_node);
+
+#if 0
+static void riva_pci_region_init (struct pci_dev *pd, struct rivafb_info *rinfo);
+#endif
+
+static void riva_wclut (unsigned char regnum, unsigned char red,
+	    		unsigned char green, unsigned char blue);
+
+
+
+
+/* kernel interface */
+static struct fb_ops riva_fb_ops =
+{
+	rivafb_open,
+	rivafb_release,
+	rivafb_get_fix,
+	rivafb_get_var,
+	rivafb_set_var,
+	rivafb_get_cmap,
+	rivafb_set_cmap,
+	rivafb_pan_display,
+	rivafb_ioctl
+};
+
+
+
+
+/* from GGI */
+static const struct riva_regs reg_template =
+{
+	{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* ATTR */
+	  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+	  0x41, 0x01, 0x0F, 0x13, 0x00 },
+	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* CRT  */
+	  0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, /* 0x10 */
+	  0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */
+	  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30 */
+	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+          0x00,                                           /* 0x40 */
+	},
+	{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, /* GRA  */
+	  0xFF },
+	{ 0x03, 0x01, 0x0F, 0x00, 0x0E},                  /* SEQ  */
+	0xEB						  /* MISC */
+};
+
+
+
+/* ------------------- general utility functions -------------------------- */
+
+/**
+ * riva_set_dispsw
+ * @rivainfo: pointer to internal driver struct for a given Riva card
+ *
+ * DESCRIPTION:
+ * Sets up console Low level operations depending on the current? color depth
+ * of the display
+ */
+
+void riva_set_dispsw (struct rivafb_info *rinfo)
+{
+	struct display *disp = &rinfo->disp;
+
+	DPRINTK ("ENTER\n");
+
+	assert (rinfo != NULL);
+
+	disp->dispsw_data = NULL;
+
+	switch (disp->var.bits_per_pixel) {
+#ifdef FBCON_HAS_MFB
+	case 1:
+		disp->dispsw = &fbcon_mfb;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB4
+	case 4:
+		disp->dispsw = &fbcon_cfb4;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB8
+	case 8:
+		disp->dispsw = &fbcon_cfb8;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB16
+	case 15:
+	case 16:
+		disp->dispsw = &fbcon_cfb16;
+		disp->dispsw_data = &rinfo->con_cmap.cfb16;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB24
+	case 24:
+		disp->dispsw = &fbcon_cfb24;
+		disp->dispsw_data = rinfo->con_cmap.cfb24;
+		break;
+#endif
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		disp->dispsw = &fbcon_cfb32;
+		disp->dispsw_data = rinfo->con_cmap.cfb32;
+		break;
+#endif
+	default:
+		DPRINTK ("Setting fbcon_dummy renderer\n");
+		disp->dispsw = &fbcon_dummy;
+	}
+
+	DPRINTK ("EXIT\n");
+}
+
+
+
+
+static int riva_init_disp_var (struct rivafb_info *rinfo)
+{
+	if (mode_option)
+		fb_find_mode(&rinfo->disp.var, &rinfo->info, mode_option,
+	    		  NULL, 0, NULL, 8);
+	else 
+		fb_find_mode(&rinfo->disp.var, &rinfo->info,
+			     "640x480-8@60", NULL, 0, NULL, 8);
+	return 0;
+}
+
+
+
+
+static int __init riva_init_disp (struct rivafb_info *rinfo)
+{
+	struct fb_info *info;
+	struct display *disp;
+
+	DPRINTK("ENTER\n");
+
+	assert (rinfo != NULL);
+
+	info = &rinfo->info;
+	disp = &rinfo->disp;
+
+	info->disp = disp;
+
+#warning FIXME: assure that disp->cmap is completely filled out
+
+	disp->screen_base = rinfo->fb_base;
+	disp->visual = FB_VISUAL_PSEUDOCOLOR;
+	disp->type = FB_TYPE_PACKED_PIXELS;
+	disp->type_aux = 0;
+	disp->ypanstep = 1;
+	disp->ywrapstep = 0;
+	disp->next_line = disp->line_length =
+		(disp->var.xres_virtual * disp->var.bits_per_pixel) >> 3;
+	disp->can_soft_blank = 1;
+	disp->inverse = 0;
+
+	riva_set_dispsw(rinfo);
+
+	rinfo->currcon_display = disp;
+
+	if ((riva_init_disp_var (rinfo)) < 0) {	/* must be done last */
+		DPRINTK("EXIT, returning -1\n");
+		return -1;
+	}
+
+	DPRINTK("EXIT, returning 0\n");
+	return 0;
+
+}
+
+
+
+static int __init riva_set_fbinfo (struct rivafb_info *rinfo)
+{
+	struct fb_info *info;
+
+	assert (rinfo != NULL);
+
+	info = &rinfo->info;
+
+	strcpy (info->modename, rinfo->drvr_name);
+	info->node = -1;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->fbops = &riva_fb_ops;
+
+#warning FIXME: set monspecs to what???
+
+	info->display_fg = NULL; /* FIXME: correct? */
+	strncpy (info->fontname, fontname, sizeof (info->fontname));
+	info->fontname[sizeof (info->fontname) - 1] = 0;
+
+	info->changevar = NULL; /* FIXME: needed? */
+	info->switch_con = rivafb_switch;
+	info->updatevar = NULL; /* FIXME? */
+	info->blank = rivafb_blank;
+
+	if (riva_init_disp (rinfo) < 0)	/* must be done last */
+		return -1;
+
+	return 0;
+}
+
+
+
+
+/* ----------------------------- PCI bus ----------------------------- */
+
+
+
+
+/**
+ * riva_pci_region_size
+ * @pd: pointer to PCI device to be configured
+ *
+ * DESCRIPTION:
+ * Obtains from the PCI bus the size of the address space allocated to
+ * the given card's base address zero region.
+ */
+
+static
+u32 riva_pci_region_size (struct pci_dev *pd, unsigned baseaddr)
+{
+	return pd->resource[baseaddr].end - pd->resource[baseaddr].start + 1;
+}
+
+
+
+
+#if 0
+
+/**
+ * riva_pci_iomap
+ * @nv:
+ *
+ * DESCRIPTION:
+ */
+
+static
+void riva_pci_region_init (struct pci_dev *pd, struct rivafb_info *rinfo)
+{
+	unsigned long addr;
+
+	assert (rinfo != NULL);
+	assert (pd != NULL);
+
+	rinfo->pd = pd;
+	rinfo->base0_region_size = riva_pci_region_size (pd, PCI_BASE_ADDRESS_0);
+	assert(rinfo->base0_region_size >= 0x00800000); /* from GGI */
+	rinfo->base1_region_size = riva_pci_region_size (pd, PCI_BASE_ADDRESS_1);
+	assert(rinfo->base0_region_size >= 0x01000000); /* from GGI */
+	
+	/* Get the base addresses */
+	pcibios_read_config_dword(0, rinfo->pd->devfn, PCI_BASE_ADDRESS_0, 
+                                  (unsigned int*)&addr);
+#ifdef SHOULDUSETHAT
+	/* This function should return an int. */
+	if (!addr)  
+	  return -ENXIO;
+#endif
+	
+	rinfo->ctrl_base_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
+
+	pcibios_read_config_dword(0, rinfo->pd->devfn, PCI_BASE_ADDRESS_1, 
+                                  (unsigned int*)&addr);
+
+	rinfo->fb_base_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
+
+	rinfo->ctrl_base = ioremap (rinfo->ctrl_base_phys, rinfo->base0_region_size);
+	assert (rinfo->ctrl_base != NULL);
+	rinfo->fb_base = ioremap (rinfo->fb_base_phys, rinfo->base1_region_size);
+	assert (rinfo->fb_base != NULL);
+
+        rinfo->riva.EnableIRQ = 0;
+        rinfo->riva.IO      = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;
+        rinfo->riva.PRAMDAC = (unsigned *)(rinfo->ctrl_base+0x00680000);
+        rinfo->riva.PFB     = (unsigned *)(rinfo->ctrl_base+0x00100000);
+        rinfo->riva.PFIFO   = (unsigned *)(rinfo->ctrl_base+0x00002000);
+        rinfo->riva.PGRAPH  = (unsigned *)(rinfo->ctrl_base+0x00400000);
+        rinfo->riva.PEXTDEV = (unsigned *)(rinfo->ctrl_base+0x00101000);
+        rinfo->riva.PTIMER  = (unsigned *)(rinfo->ctrl_base+0x00009000);
+        rinfo->riva.PMC     = (unsigned *)(rinfo->ctrl_base+0x00000000);
+        rinfo->riva.FIFO    = (unsigned *)(rinfo->ctrl_base+0x00800000);
+
+        switch (rinfo->riva.Architecture)
+        {
+        case 3:
+                rinfo->riva.PRAMIN  = (unsigned *)(rinfo->ctrl_base+0x00C00000);
+                break;
+        case 4:
+	case 5:
+                rinfo->riva.PCRTC   = (unsigned *)(rinfo->ctrl_base+0x00600000);
+                rinfo->riva.PRAMIN  = (unsigned *)(rinfo->ctrl_base+0x00710000);
+                break;
+        }
+}
+
+#endif /* 0 */
+
+
+
+/**
+ * riva_pci_iounmap
+ * @rinfo:
+ *
+ * DESCRIPTION:
+ */
+
+static
+void riva_pci_iounmap (struct rivafb_info *rinfo)
+{
+	assert (rinfo != NULL);
+	assert (rinfo->ctrl_base_phys != 0x00000000);
+	assert (rinfo->ctrl_base != NULL);
+	assert (rinfo->fb_base_phys != 0x00000000);
+	assert (rinfo->fb_base != NULL);
+
+	iounmap (rinfo->ctrl_base);
+	iounmap (rinfo->fb_base);
+}
+
+
+
+
+
+static void __init riva_init_clut (struct rivafb_info *fb_info)
+{
+	int j, k;
+	
+	for (j = 0; j < 256; j++) {
+		if (j < 16) {
+			k = color_table[j];
+			fb_info->palette[j].red = default_red[k];
+			fb_info->palette[j].green = default_grn[k];
+			fb_info->palette[j].blue = default_blu[k];
+		} else {
+			fb_info->palette[j].red =
+			fb_info->palette[j].green =
+			fb_info->palette[j].blue = j;
+		}
+		
+		riva_wclut (j,
+			    fb_info->palette[j].red,
+			    fb_info->palette[j].green,
+			    fb_info->palette[j].blue);
+	}
+}
+
+
+
+static int __init riva_pci_register (struct pci_dev *pd,
+				     const struct riva_chip_info *rci)
+{
+	struct rivafb_info *rinfo;
+
+	assert (pd != NULL);
+	assert (rci != NULL);
+
+	rinfo = kmalloc (sizeof (struct rivafb_info), GFP_KERNEL);
+	assert (rinfo != NULL);
+	memset (rinfo, 0, sizeof (struct rivafb_info));
+
+	rinfo->drvr_name = rci->name;
+	rinfo->riva.Architecture = rci->arch_rev;
+
+	rinfo->pd = pd;
+	rinfo->base0_region_size = riva_pci_region_size (pd, 0);
+	rinfo->base1_region_size = riva_pci_region_size (pd, 1);
+
+	assert(rinfo->base0_region_size >= 0x00800000); /* from GGI */
+	assert(rinfo->base0_region_size >= 0x01000000); /* from GGI */
+
+	rinfo->ctrl_base_phys = rinfo->pd->resource[0].start;
+	rinfo->fb_base_phys = rinfo->pd->resource[1].start;
+
+	__request_region(&ioport_resource, 0x3C0, 32, "rivafb");
+
+	if (!__request_region (&iomem_resource, rinfo->ctrl_base_phys,
+			       rinfo->base0_region_size, "rivafb") ||
+	    !__request_region (&iomem_resource, rinfo->fb_base_phys,
+			       rinfo->base1_region_size, "rivafb")) {
+		printk (KERN_ERR PFX "cannot reserve MMIO region\n");
+		return -ENXIO;
+	}
+
+	rinfo->ctrl_base = ioremap (rinfo->ctrl_base_phys,
+				    rinfo->base0_region_size);
+	assert (rinfo->ctrl_base != NULL);
+
+	rinfo->fb_base = ioremap (rinfo->fb_base_phys,
+				  rinfo->base1_region_size);
+	assert (rinfo->fb_base != NULL);
+
+        rinfo->riva.EnableIRQ = 0;
+        rinfo->riva.IO      = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;
+        rinfo->riva.PRAMDAC = (unsigned *)(rinfo->ctrl_base+0x00680000);
+        rinfo->riva.PFB     = (unsigned *)(rinfo->ctrl_base+0x00100000);
+        rinfo->riva.PFIFO   = (unsigned *)(rinfo->ctrl_base+0x00002000);
+        rinfo->riva.PGRAPH  = (unsigned *)(rinfo->ctrl_base+0x00400000);
+        rinfo->riva.PEXTDEV = (unsigned *)(rinfo->ctrl_base+0x00101000);
+        rinfo->riva.PTIMER  = (unsigned *)(rinfo->ctrl_base+0x00009000);
+        rinfo->riva.PMC     = (unsigned *)(rinfo->ctrl_base+0x00000000);
+        rinfo->riva.FIFO    = (unsigned *)(rinfo->ctrl_base+0x00800000);
+
+        switch (rinfo->riva.Architecture)
+        {
+        case 3:
+                rinfo->riva.PRAMIN  = (unsigned *)(rinfo->ctrl_base+0x00C00000);
+                break;
+        case 4:
+	case 5:
+                rinfo->riva.PCRTC   = (unsigned *)(rinfo->ctrl_base+0x00600000);
+                rinfo->riva.PRAMIN  = (unsigned *)(rinfo->ctrl_base+0x00710000);
+                break;
+        }
+
+        RivaGetConfig(&rinfo->riva);
+
+	/* back to normal */
+
+	assert (rinfo->pd != NULL);
+
+	/* unlock io */
+	vga_io_wcrt (0x11, 0xFF); /* vgaHWunlock() + riva unlock (0x7F) */
+	outb(rinfo->riva.LockUnlockIO, rinfo->riva.LockUnlockIndex);
+	outb(rinfo->riva.LockUnlockIO + 1, 0x57);
+
+	memcpy (&rinfo->initial_state, &reg_template, sizeof (reg_template));
+	riva_save_state (rinfo, &rinfo->initial_state);
+
+        rinfo->ram_amount = rinfo->riva.RamAmountKBytes * 1024;
+	rinfo->dclk_max = rinfo->riva.MaxVClockFreqKHz * 1000;
+
+	riva_set_fbinfo (rinfo);
+	
+	riva_init_clut (rinfo);
+
+	riva_load_video_mode (rinfo, &rinfo->disp.var);
+
+	if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
+		printk(KERN_ERR PFX "error registering riva framebuffer\n");
+		kfree (rinfo);
+		return -1;
+	}
+
+	riva_boards = riva_board_list_add (riva_boards, rinfo);
+
+	printk("PCI Riva NV%d framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
+	       rinfo->riva.Architecture,
+	       RIVAFB_VERSION,
+	       rinfo->drvr_name,
+	       rinfo->ram_amount / (1024 * 1024),
+	       rinfo->fb_base_phys);
+
+	return 0;
+}
+
+
+
+
+static int __init riva_pci_register_devices (void)
+{
+	struct pci_dev *pd;
+	const struct riva_chip_info *nci = &riva_pci_probe_list[0];
+
+	assert (nci != NULL);
+	while (nci->name != NULL) {
+		pd = pci_find_device (nci->vendor, nci->device, NULL);
+		while (pd != NULL) {
+			if (riva_pci_register (pd, nci) < 0)
+				return -1;
+
+			pd = pci_find_device (nci->vendor, nci->device, pd);
+		}
+
+		nci++;
+	}
+
+	return 0;
+}
+
+
+
+/*** riva_wclut - set CLUT entry ***/
+static void riva_wclut (unsigned char regnum, unsigned char red,
+	    		unsigned char green, unsigned char blue)
+{
+	unsigned int data = VGA_PEL_D;
+	
+	/* address write mode register is not translated.. */
+	vga_io_w (VGA_PEL_IW, regnum);
+
+	vga_io_w (data, red);
+	vga_io_w (data, green);
+	vga_io_w (data, blue);
+}
+
+
+
+/* ------------ Hardware Independent Functions ------------ */
+
+int __init rivafb_setup(char *options)
+{
+    char *this_opt;
+
+    if (!options || !*options)
+	return 0;
+
+    for (this_opt = strtok(options, ","); this_opt;
+	 this_opt = strtok(NULL, ",")) {
+	if (!strncmp(this_opt, "font:", 5)) {
+		char *p;
+		int i;
+
+		p = this_opt + 5;
+		for (i = 0; i < sizeof(fontname) - 1; i++)
+			if (!*p || *p == ' ' || *p == ',')
+				break;
+		memcpy(fontname, this_opt + 5, i);
+		fontname[i] = 0;
+	}
+	
+	else if (!strncmp(this_opt, "noaccel", 7)) {
+		noaccel = 1;
+	}
+	
+	else
+	    mode_option = this_opt;
+    }
+    return 0;
+}
+
+    /*
+     *  Initialization
+     */
+
+int __init rivafb_init (void)
+{
+	if (riva_pci_register_devices () < 0)
+	    	return -ENXIO;
+
+	if (riva_boards == NULL)
+		return -ENODEV;
+
+	return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+    /*
+     *  Cleanup
+     */
+
+void __exit rivafb_cleanup (struct fb_info *info)
+{
+#warning FIXME: is this all we need to do?
+
+	struct rivafb_info *tmp, *board = riva_boards;
+
+	while (board != NULL) {
+		riva_load_state (board, &board->initial_state);
+		riva_pci_iounmap (board);
+
+		unregister_framebuffer ((struct fb_info *) board);
+
+		tmp = board;
+		board = board->next;
+
+		kfree_s (tmp, sizeof (struct rivafb_info));
+	}
+
+	(void) info; /* unused function arg */
+}
+
+
+
+
+    /*
+     *  Frame buffer operations
+     */
+
+int rivafb_open(struct fb_info *info, int user)
+{
+    /* Nothing, only a usage count for the moment */
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+
+int rivafb_release(struct fb_info *info, int user)
+{
+    MOD_DEC_USE_COUNT;
+    return 0;
+}
+
+
+/**
+ * rivafb_get_fix
+ * @fix:
+ * @con:
+ * @info:
+ *
+ * DESCRIPTION:
+ */
+
+int rivafb_get_fix (struct fb_fix_screeninfo *fix, int con,
+		  struct fb_info *info)
+{
+	struct rivafb_info *rivainfo = (struct rivafb_info *) info;
+	struct display *p;
+
+	DPRINTK ("ENTER\n");
+
+	assert (fix != NULL);
+	assert (info != NULL);
+	assert (rivainfo->drvr_name && rivainfo->drvr_name[0]);
+	assert (rivainfo->fb_base_phys > 0);
+	assert (rivainfo->ram_amount > 0);
+
+	p = (con < 0) ? rivainfo->info.disp : &fb_display[con];
+
+	memset (fix, 0, sizeof (struct fb_fix_screeninfo));
+	sprintf (fix->id, "Riva %s", rivainfo->drvr_name);
+
+	fix->smem_start = rivainfo->fb_base_phys;
+	fix->smem_len = rivainfo->ram_amount;
+
+	fix->type = p->type;
+	fix->type_aux = p->type_aux;
+	fix->visual = p->visual;
+
+	fix->xpanstep = 1;
+	fix->ypanstep = 1;
+	fix->ywrapstep = 0; /* FIXME: no ywrap for now */
+
+	fix->line_length = p->line_length;
+
+#warning FIXME: set up MMIO region
+	fix->mmio_start = 0;
+	fix->mmio_len = 0;
+
+#warning FIXME: reference riva acceleration fb.h constant here
+	fix->accel = FB_ACCEL_NONE;
+
+	DPRINTK ("EXIT, returning 0\n");
+
+	return 0;
+}
+
+
+
+/**
+ * rivafb_get_var
+ * @var:
+ * @con:
+ * @info:
+ *
+ * DESCRIPTION:
+ */
+
+int rivafb_get_var (struct fb_var_screeninfo *var, int con,
+		  struct fb_info *info)
+{
+	struct rivafb_info *rivainfo = (struct rivafb_info *) info;
+
+	DPRINTK ("ENTER\n");
+
+	assert (info != NULL);
+	assert (var != NULL);
+
+	*var = (con < 0) ? rivainfo->disp.var : fb_display[con].var;
+
+	DPRINTK ("EXIT, returning 0\n");
+
+	return 0;
+}
+
+
+
+/**
+ * rivafb_set_var
+ * @var:
+ * @con:
+ * @info:
+ *
+ * DESCRIPTION:
+ */
+
+int rivafb_set_var (struct fb_var_screeninfo *var, int con,
+		  struct fb_info *info)
+{
+	struct rivafb_info *rivainfo = (struct rivafb_info *) info;
+	struct display *dsp;
+	struct fb_var_screeninfo v;
+	int nom, den;		/* translating from pixels->bytes */
+	int i;
+	unsigned chgvar = 0;
+	static struct {
+		int xres, yres;
+	} modes[] = {
+		{ 1600, 1280 },
+		{ 1280, 1024 },
+		{ 1024, 768 },
+		{ 800, 600 },
+		{ 640, 480 },
+		{ -1, -1 }
+	};
+
+	DPRINTK ("ENTER\n");
+
+	assert (info != NULL);
+	assert (var != NULL);
+
+	DPRINTK ("Requested: %dx%dx%d\n", var->xres, var->yres, var->bits_per_pixel);
+	DPRINTK ("  virtual: %dx%d\n", var->xres_virtual, var->yres_virtual);
+	DPRINTK ("   offset: (%d,%d)\n", var->xoffset, var->yoffset);
+	DPRINTK ("grayscale: %d\n", var->grayscale);
+
+	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
+	assert (dsp != NULL);
+
+	/* if var has changed, we should call changevar() later */
+	if (con >= 0) {
+		chgvar = ((dsp->var.xres != var->xres) ||
+		    (dsp->var.yres != var->yres) ||
+                    (dsp->var.xres_virtual != var->xres_virtual) ||
+		    (dsp->var.yres_virtual != var->yres_virtual) ||
+		    (dsp->var.bits_per_pixel != var->bits_per_pixel) ||
+		    memcmp(&dsp->var.red, &var->red, sizeof(var->red)) ||
+		    memcmp(&dsp->var.green, &var->green, sizeof(var->green)) ||
+		    memcmp(&dsp->var.blue, &var->blue, sizeof(var->blue)));
+	}
+
+	memcpy (&v, var, sizeof (v));
+
+	switch (v.bits_per_pixel) {
+#ifdef FBCON_HAS_MFB
+	case 1:
+		dsp->dispsw = &fbcon_mfb;
+		dsp->line_length = v.xres_virtual / 8;
+		dsp->visual = FB_VISUAL_MONO10;
+		nom = 4;
+		den = 8;
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB8
+	case 2 ... 8:
+		v.bits_per_pixel = 8;
+		dsp->dispsw = &fbcon_cfb8;
+		nom = 1;
+		den = 1;
+		dsp->line_length = v.xres_virtual;
+		dsp->visual = FB_VISUAL_PSEUDOCOLOR;
+		v.red.offset = 0;
+		v.red.length = 6;
+		v.green.offset = 0;
+		v.green.length = 6;
+		v.blue.offset = 0;
+		v.blue.length = 6;
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB16
+	case 9 ... 16:
+		v.bits_per_pixel = 16;
+		dsp->dispsw = &fbcon_cfb16;
+		dsp->dispsw_data = &rivainfo->con_cmap.cfb16;
+		nom = 2;
+		den = 1;
+		dsp->line_length = v.xres_virtual * 2;
+		dsp->visual = FB_VISUAL_DIRECTCOLOR;
+#ifdef CONFIG_PREP
+		v.red.offset = 2;
+		v.green.offset = -3;
+		v.blue.offset = 8;
+#else
+		v.red.offset = 10;
+		v.green.offset = 5;
+		v.blue.offset = 0;
+#endif
+		v.red.length = 5;
+		v.green.length = 5;
+		v.blue.length = 5;
+		break;
+#endif
+
+#ifdef FBCON_HAS_CFB32
+	case 17 ... 32:
+		v.bits_per_pixel = 32;
+		dsp->dispsw = &fbcon_cfb32;
+		dsp->dispsw_data = rivainfo->con_cmap.cfb32;
+		nom = 4;
+		den = 1;
+		dsp->line_length = v.xres_virtual * 4;
+		dsp->visual = FB_VISUAL_DIRECTCOLOR;
+#ifdef CONFIG_PREP
+		v.red.offset = 8;
+		v.green.offset = 16;
+		v.blue.offset = 24;
+#else
+		v.red.offset = 16;
+		v.green.offset = 8;
+		v.blue.offset = 0;
+#endif
+		v.red.length = 8;
+		v.green.length = 8;
+		v.blue.length = 8;
+		break;
+#endif
+
+	default:
+		printk (KERN_ERR PFX "mode %dx%dx%d rejected...color depth not supported.\n",
+			var->xres, var->yres, var->bits_per_pixel);
+		DPRINTK ("EXIT, returning -EINVAL\n");
+		return -EINVAL;
+	}
+
+	if (v.xres * nom / den * v.yres > rivainfo->ram_amount) {
+		printk (KERN_ERR PFX "mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
+			var->xres, var->yres, var->bits_per_pixel);
+		DPRINTK ("EXIT - EINVAL error\n");
+		return -EINVAL;
+	}
+
+	/* use highest possible virtual resolution */
+	if (v.xres_virtual == -1 &&
+	    v.yres_virtual == -1) {
+		printk (KERN_WARNING PFX "using maximum available virtual resolution\n");
+		for (i = 0; modes[i].xres != -1; i++) {
+			if (modes[i].xres * nom / den * modes[i].yres < rivainfo->ram_amount / 2)
+				break;
+		}
+		if (modes[i].xres == -1) {
+			printk (KERN_ERR PFX "could not find a virtual resolution that fits into video memory!!\n");
+			DPRINTK ("EXIT - EINVAL error\n");
+			return -EINVAL;
+		}
+		v.xres_virtual = modes[i].xres;
+		v.yres_virtual = modes[i].yres;
+
+		printk (KERN_INFO PFX "virtual resolution set to maximum of %dx%d\n",
+			v.xres_virtual, v.yres_virtual);
+	} else if (v.xres_virtual == -1) {
+		/* FIXME: maximize X virtual resolution only */
+	} else if (v.yres_virtual == -1) {
+		/* FIXME: maximize Y virtual resolution only */
+	}
+
+	if (v.xoffset < 0)
+		v.xoffset = 0;
+	if (v.yoffset < 0)
+		v.yoffset = 0;
+
+	/* truncate xoffset and yoffset to maximum if too high */
+	if (v.xoffset > v.xres_virtual - v.xres)
+		v.xoffset = v.xres_virtual - v.xres - 1;
+
+	if (v.yoffset > v.yres_virtual - v.yres)
+		v.yoffset = v.yres_virtual - v.yres - 1;
+
+	v.red.msb_right =
+	    v.green.msb_right =
+	    v.blue.msb_right =
+	    v.transp.offset =
+	    v.transp.length =
+	    v.transp.msb_right = 0;
+
+	switch (v.activate & FB_ACTIVATE_MASK) {
+	case FB_ACTIVATE_TEST:
+		DPRINTK ("EXIT - FB_ACTIVATE_TEST\n");
+		return 0;
+	case FB_ACTIVATE_NXTOPEN:	/* ?? */
+	case FB_ACTIVATE_NOW:
+		break;		/* continue */
+	default:
+		DPRINTK ("EXIT - unknown activation type\n");
+		return -EINVAL;	/* unknown */
+	}
+
+	dsp->type = FB_TYPE_PACKED_PIXELS;
+
+#warning FIXME: verify that the above code sets dsp->* fields correctly
+
+	memcpy (&dsp->var, &v, sizeof (v));
+
+	riva_load_video_mode (rivainfo, &v);
+
+	if (chgvar && info && info->changevar)
+		info->changevar (con);
+
+	DPRINTK ("EXIT, returning 0\n");
+	return 0;
+}
+
+
+
+/**
+ * rivafb_get_cmap
+ * @cmap:
+ * @kspc:
+ * @con:
+ * @info:
+ *
+ * DESCRIPTION:
+ *
+ * NOTES:
+ * Copied from matroxfb::matroxfb_get_cmap()
+ */
+
+int rivafb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
+		   struct fb_info *info)
+{
+	struct rivafb_info *rivainfo = (struct rivafb_info *) info;
+	struct display *dsp;
+
+	DPRINTK ("ENTER\n");
+
+	assert (rivainfo != NULL);
+	assert (cmap != NULL);
+
+	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
+
+	if (con == rivainfo->currcon) {	/* current console? */
+		int rc = fb_get_cmap (cmap, kspc, riva_getcolreg, info);
+		DPRINTK ("EXIT - returning %d\n", rc);
+		return rc;
+	} else if (dsp->cmap.len)	/* non default colormap? */
+		fb_copy_cmap (&dsp->cmap, cmap, kspc ? 0 : 2);
+	else
+		fb_copy_cmap (fb_default_cmap (riva_get_cmap_len (&dsp->var)),
+			      cmap, kspc ? 0 : 2);
+
+	DPRINTK ("EXIT, returning 0\n");
+
+	return 0;
+}
+
+
+/**
+ * rivafb_set_cmap
+ * @cmap:
+ * @kspc:
+ * @con:
+ * @info:
+ *
+ * DESCRIPTION:
+ *
+ * NOTES:
+ * Copied from matroxfb::matroxfb_set_cmap()
+ */
+
+int rivafb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
+		   struct fb_info *info)
+{
+	struct rivafb_info *rivainfo = (struct rivafb_info *) info;
+	struct display *dsp;
+	unsigned int cmap_len;
+
+	DPRINTK ("ENTER\n");
+
+	assert (rivainfo != NULL);
+	assert (cmap != NULL);
+
+	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
+
+	cmap_len = riva_get_cmap_len (&dsp->var);
+	if (dsp->cmap.len != cmap_len) {
+		int err = fb_alloc_cmap (&dsp->cmap, cmap_len, 0);
+		if (err) {
+			DPRINTK ("EXIT - returning %d\n", err);
+			return err;
+		}
+	}
+	if (con == rivainfo->currcon) {	/* current console? */
+		int rc = fb_set_cmap (cmap, kspc, riva_setcolreg, info);
+		DPRINTK ("EXIT - returning %d\n", rc);
+		return rc;
+	} else
+		fb_copy_cmap (cmap, &dsp->cmap, kspc ? 0 : 1);
+
+	DPRINTK ("EXIT, returning 0\n");
+
+	return 0;
+}
+
+
+
+/**
+ * rivafb_pan_display
+ * @var: standard kernel fb changeable data
+ * @par: riva-specific hardware info about current video mode
+ * @info: pointer to rivafb_info object containing info for current riva board
+ *
+ * DESCRIPTION:
+ * Pan (or wrap, depending on the `vmode' field) the display using the
+ * `xoffset' and `yoffset' fields of the `var' structure.
+ * If the values don't fit, return -EINVAL.
+ *
+ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ */
+
+int rivafb_pan_display (struct fb_var_screeninfo *var, int con,
+		      struct fb_info *info)
+{
+	unsigned int base;
+	struct display *dsp;
+	struct rivafb_info *rivainfo = (struct rivafb_info *) info;
+
+	DPRINTK ("ENTER\n");
+
+	assert (rivainfo != NULL);
+
+	if (var->xoffset > (var->xres_virtual - var->xres))
+		return -EINVAL;
+	if (var->yoffset > (var->yres_virtual - var->yres))
+		return -EINVAL;
+
+	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
+
+	if (var->vmode & FB_VMODE_YWRAP) {
+		if (var->yoffset < 0 || var->yoffset >= dsp->var.yres_virtual || var->xoffset)
+			return -EINVAL;
+	} else {
+		if (var->xoffset+dsp->var.xres > dsp->var.xres_virtual ||
+		    var->yoffset+dsp->var.yres > dsp->var.yres_virtual)
+			return -EINVAL;
+	}
+
+	base = var->yoffset * dsp->line_length + var->xoffset;
+
+	if (con == rivainfo->currcon) {
+		/* FIXME: do the dirty deed */
+	}
+
+	dsp->var.xoffset = var->xoffset;
+	dsp->var.yoffset = var->yoffset;
+
+	if (var->vmode & FB_VMODE_YWRAP)
+		dsp->var.vmode |= FB_VMODE_YWRAP;
+	else
+		dsp->var.vmode &= ~FB_VMODE_YWRAP;
+
+	DPRINTK ("EXIT, returning 0\n");
+
+	return 0;
+}
+
+
+
+/**
+ * rivafb_ioctl
+ * @inode:
+ * @file:
+ * @cmd:
+ * @arg:
+ * @con:
+ * @info:
+ *
+ * DESCRIPTION:
+ */
+
+int rivafb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
+		unsigned long arg, int con, struct fb_info *info)
+{
+	struct rivafb_info *rivainfo = (struct rivafb_info *) info;
+
+	DPRINTK ("ENTER\n");
+
+	assert (rivainfo != NULL);
+
+	/* no rivafb-specific ioctls */
+
+	DPRINTK ("EXIT, returning -EINVAL\n");
+
+	return -EINVAL;
+}
+
+
+
+
+/**
+ * rivafb_switch
+ * @con:
+ * @info:
+ *
+ * DESCRIPTION:
+ */
+
+int rivafb_switch(int con, struct fb_info *info)
+{
+	struct rivafb_info *rivainfo = (struct rivafb_info *) info;
+	struct fb_cmap* cmap;
+	struct display *dsp;
+
+	DPRINTK("ENTER\n");
+
+	assert (rivainfo != NULL);
+
+	dsp = (con < 0) ? rivainfo->info.disp : &fb_display[con];
+
+	if (rivainfo->currcon >= 0) {
+		/* Do we have to save the colormap? */
+		cmap = &(rivainfo->currcon_display->cmap);
+		DPRINTK("switch1: con = %d, cmap.len = %d\n", rivainfo->currcon, cmap->len);
+
+		if (cmap->len) {
+			DPRINTK("switch1a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp);
+			fb_get_cmap(cmap, 1, riva_getcolreg, info);
+#ifdef DEBUG
+			if (cmap->red) {
+				DPRINTK("switch1r: %X\n", cmap->red[0]);
+			}
+#endif
+		}
+	}
+	rivainfo->currcon = con;
+	rivainfo->currcon_display = dsp;
+	dsp->var.activate = FB_ACTIVATE_NOW;
+
+#ifdef riva_DEBUG
+	cmap = &dsp->cmap;
+	DPRINTK("switch2: con = %d, cmap.len = %d\n", con, cmap->len);
+	DPRINTK("switch2a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp);
+	if (dsp->cmap.red) {
+		DPRINTK("switch2r: %X\n", cmap->red[0]);
+	}
+#endif
+
+	rivafb_set_var(&dsp->var, con, info);
+
+#ifdef riva_DEBUG
+	DPRINTK("switch3: con = %d, cmap.len = %d\n", con, cmap->len);
+	DPRINTK("switch3a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp);
+	if (dsp->cmap.red) {
+		DPRINTK("switch3r: %X\n", cmap->red[0]);
+	}
+#endif
+
+	DPRINTK("EXIT, returning 0\n");
+
+	return 0;
+}
+
+
+
+void rivafb_blank (int blank, struct fb_info *info)
+{
+	unsigned char tmp;
+	struct rivafb_info *rivainfo = (struct rivafb_info *) info;
+
+	DPRINTK ("ENTER\n");
+
+	assert (rivainfo != NULL);
+
+	tmp = vga_io_rseq (VGA_SEQ_CLOCK_MODE) & ~VGA_SR01_SCREEN_OFF;
+
+	if (blank)
+		tmp |= VGA_SR01_SCREEN_OFF;
+
+	vga_io_wseq (VGA_SEQ_CLOCK_MODE, tmp);
+
+	DPRINTK("EXIT\n");
+}
+
+
+/* -------------------------------------------------------------------------
+ *
+ * internal fb_ops helper functions
+ *
+ * -------------------------------------------------------------------------
+ */
+
+
+/**
+ * riva_get_cmap_len
+ * @var:
+ *
+ * DESCRIPTION:
+ */
+
+static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
+{
+	int rc = 16; /* reasonable default */
+
+	assert (var != NULL);
+
+	switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_CFB4
+		case 4:
+			rc = 16;	/* pseudocolor... 16 entries HW palette */
+			break;
+#endif
+#ifdef FBCON_HAS_CFB8
+		case 8:
+			rc = 256;	/* pseudocolor... 256 entries HW palette */
+			break;
+#endif
+#ifdef FBCON_HAS_CFB16
+		case 16:
+			rc = 16;	/* directcolor... 16 entries SW palette */
+			break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
+#endif
+#ifdef FBCON_HAS_CFB32
+		case 32:
+			rc = 16;	/* directcolor... 16 entries SW palette */
+			break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
+#endif
+		default:
+			assert (0);
+			/* should not occur */
+			break;
+	}
+
+	return rc;
+}
+
+
+/**
+ * riva_getcolreg
+ * @regno:
+ * @red:
+ * @green:
+ * @blue:
+ * @transp:
+ * @info: pointer to rivafb_info object containing info for current riva board
+ *
+ * DESCRIPTION:
+ * Read a single color register and split it into colors/transparent.
+ * The return values must have a 16 bit magnitude.
+ * Return != 0 for invalid regno.
+ *
+ * CALLED FROM:
+ * fbcmap.c:fb_get_cmap()
+ *	fbgen.c:fbgen_get_cmap()
+ *	fbgen.c:fbgen_switch()
+ */
+
+static int riva_getcolreg (unsigned regno, unsigned *red, unsigned *green,
+			 unsigned *blue, unsigned *transp,
+			 struct fb_info *info)
+{
+	struct rivafb_info *rivainfo = (struct rivafb_info *) info;
+
+    if (regno > 255)
+	return 1;
+    *red = rivainfo->palette[regno].red;
+    *green = rivainfo->palette[regno].green;
+    *blue = rivainfo->palette[regno].blue;
+    *transp = 0;
+    return 0;
+}
+
+
+/**
+ * riva_setcolreg
+ * @regno:
+ * @red:
+ * @green:
+ * @blue:
+ * @transp:
+ * @info: pointer to rivafb_info object containing info for current riva board
+ *
+ * DESCRIPTION:
+ * Set a single color register. The values supplied have a 16 bit
+ * magnitude.
+ * Return != 0 for invalid regno.
+ *
+ * CALLED FROM:
+ * fbcmap.c:fb_set_cmap()
+ *	fbgen.c:fbgen_get_cmap()
+ *	fbgen.c:fbgen_install_cmap()
+ *		fbgen.c:fbgen_set_var()
+ *		fbgen.c:fbgen_switch()
+ *		fbgen.c:fbgen_blank()
+ *	fbgen.c:fbgen_blank()
+ */
+
+static int riva_setcolreg (unsigned regno, unsigned red, unsigned green,
+		    unsigned blue, unsigned transp,
+		    struct fb_info *info)
+{
+	struct rivafb_info *rivainfo = (struct rivafb_info *) info;
+	struct display *p;
+
+	DPRINTK("ENTER\n");
+
+	assert (rivainfo != NULL);
+	assert (rivainfo->currcon_display != NULL);
+
+	if (regno > 255)
+		return -EINVAL;
+
+	p = rivainfo->currcon_display;
+	if (p->var.grayscale) {
+		/* gray = 0.30*R + 0.59*G + 0.11*B */
+		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+	}
+
+#ifdef FBCON_HAS_CFB8
+	switch (p->var.bits_per_pixel) {
+	case 8:
+		/* "transparent" stuff is completely ignored. */
+		riva_wclut (regno, red >> 10, green >> 10, blue >> 10);
+		break;
+	default:
+		/* do nothing */
+		break;
+	}
+#endif	/* FBCON_HAS_CFB8 */
+
+	rivainfo->palette[regno].red = red;
+	rivainfo->palette[regno].green = green;
+	rivainfo->palette[regno].blue = blue;
+
+	if (regno >= 16)
+		return 0;
+		
+	switch (p->var.bits_per_pixel) {
+
+#ifdef FBCON_HAS_CFB16
+	case 16:
+		assert (regno < 16);
+#ifdef CONFIG_PREP
+		rivainfo->con_cmap.cfb16[regno] =
+		    ((red & 0xf800) >> 9) |
+		    ((green & 0xf800) >> 14) |
+		    ((green & 0xf800) << 2) |
+		    ((blue & 0xf800) >> 3);
+#else
+		rivainfo->con_cmap.cfb16[regno] =
+		    ((red & 0xf800) >> 1) |
+		    ((green & 0xf800) >> 6) |
+		    ((blue & 0xf800) >> 11);
+#endif
+		break;
+#endif /* FBCON_HAS_CFB16 */
+
+#ifdef FBCON_HAS_CFB32
+	case 32:
+		assert (regno < 16);
+#ifdef CONFIG_PREP
+		rivainfo->con_cmap.cfb32[regno] =
+		    ((red & 0xff00)) |
+		    ((green & 0xff00) << 8) |
+		    ((blue & 0xff00) << 16);
+#else
+		rivainfo->con_cmap.cfb32[regno] =
+		    ((red & 0xff00) << 8) |
+		    ((green & 0xff00)) |
+		    ((blue & 0xff00) >> 8);
+#endif
+		break;
+#endif /* FBCON_HAS_CFB32 */
+
+	default:
+		/* do nothing */
+		break;
+	}
+
+	return 0;
+}
+
+
+
+/*
+ * riva_load_video_mode()
+ *
+ * calculate some timings and then send em off to riva_load_state()
+ */
+
+static void riva_load_video_mode (struct rivafb_info *rinfo,
+				struct fb_var_screeninfo *video_mode)
+{
+	struct riva_regs newmode;
+	int bpp, width, hDisplaySize, hDisplay, hStart,
+		hEnd, hTotal, height, vDisplay, vStart,
+		vEnd, vTotal, dotClock;
+
+	/* time to calculate */
+
+	bpp = video_mode->bits_per_pixel;
+	width = hDisplaySize = video_mode->xres;
+	hDisplay = (hDisplaySize/8) - 1;
+	hStart = (hDisplaySize + video_mode->right_margin)/8 + 2;
+	hEnd = (hDisplaySize + video_mode->right_margin +
+		video_mode->hsync_len)/8 - 1;
+	hTotal = (hDisplaySize + video_mode->right_margin +
+		  video_mode->hsync_len + video_mode->left_margin)/8 - 1;
+	height = video_mode->yres;
+	vDisplay = video_mode->yres - 1;
+	vStart = video_mode->yres + video_mode->lower_margin - 1;
+	vEnd = video_mode->yres + video_mode->lower_margin +
+	       video_mode->vsync_len - 1;
+	vTotal = video_mode->yres + video_mode->lower_margin +
+		 video_mode->vsync_len + video_mode->upper_margin + 2;
+	dotClock = 1000000000 / video_mode->pixclock;
+
+	memcpy(&newmode, &reg_template, sizeof(struct riva_regs));
+
+	newmode.crtc[0x0] = Set8Bits(hTotal - 4);
+	newmode.crtc[0x1] = Set8Bits(hDisplay);
+	newmode.crtc[0x2] = Set8Bits(hDisplay);
+	newmode.crtc[0x3] = SetBitField(hTotal,4:0,4:0) | SetBit(7);
+	newmode.crtc[0x4] = Set8Bits(hStart);
+	newmode.crtc[0x5] = SetBitField(hTotal,5:5,7:7)
+				| SetBitField(hEnd,4:0,4:0);
+	newmode.crtc[0x6] = SetBitField(vTotal,7:0,7:0);
+	newmode.crtc[0x7] = SetBitField(vTotal,8:8,0:0)
+				| SetBitField(vDisplay,8:8,1:1)
+				| SetBitField(vStart,8:8,2:2)
+				| SetBitField(vDisplay,8:8,3:3)
+				| SetBit(4)
+				| SetBitField(vTotal,9:9,5:5)
+				| SetBitField(vDisplay,9:9,6:6)
+				| SetBitField(vStart,9:9,7:7);
+	newmode.crtc[0x9] = SetBitField(vDisplay,9:9,5:5)
+				| SetBit(6);
+	newmode.crtc[0x10] = Set8Bits(vStart);
+	newmode.crtc[0x11] = SetBitField(vEnd,3:0,3:0)
+				| SetBit(5);
+	newmode.crtc[0x12] = Set8Bits(vDisplay);
+	newmode.crtc[0x13] = ((width/8)*(bpp/8)) & 0xFF;
+	newmode.crtc[0x15] = Set8Bits(vDisplay);
+	newmode.crtc[0x16] = Set8Bits(vTotal + 1);
+
+	newmode.ext.bpp = bpp;
+	newmode.ext.width = width;
+	newmode.ext.height = height;
+
+	rinfo->riva.CalcStateExt(&rinfo->riva,&newmode.ext,bpp,width,
+				 hDisplaySize,hDisplay,hStart,hEnd,hTotal,
+				 height,vDisplay,vStart,vEnd,vTotal,dotClock);
+
+	rinfo->initial_state = newmode;
+	riva_load_state(rinfo,&newmode);
+}
+
+
+
+
+
+/* ------------------------------------------------------------------------- */
+
+
+    /*
+     *  Modularization
+     */
+
+#ifdef MODULE
+int __init init_module(void)
+{
+    return rivafb_init();
+}
+
+void __exit cleanup_module(void)
+{
+	struct rivafb_info *tmp, *board = riva_boards;
+
+	while (board != NULL) {
+		riva_load_state (board, &board->initial_state);
+
+		unregister_framebuffer ((struct fb_info *) board);
+
+		tmp = board;
+		iounmap (tmp->ctrl_base);
+		iounmap (tmp->fb_base);
+		board = board->next;
+
+		kfree (tmp);
+	}
+}
+#endif /* MODULE */
+
+
+
+
+
+/* from GGI */
+static
+void riva_save_state(struct rivafb_info *rinfo, struct riva_regs *regs)
+{
+        int i;
+
+        io_out8(NV_CIO_SR_LOCK_INDEX, 0x3D4);
+        io_out8(NV_CIO_SR_UNLOCK_RW_VALUE, 0x3D5);
+
+        rinfo->riva.UnloadStateExt(&rinfo->riva, &regs->ext);
+
+        regs->misc_output = io_in8(0x3CC);
+
+        for (i = 0; i < NUM_CRT_REGS; i++)
+        {
+                io_out8(i, 0x3D4);
+                regs->crtc[i] = io_in8(0x3D5);
+        }
+
+        for (i = 0; i < NUM_ATC_REGS; i++)
+        {
+                io_out8(i, 0x3C0);
+                regs->attr[i] = io_in8(0x3C1);
+        }
+
+        for (i = 0; i < NUM_GRC_REGS; i++)
+        {
+                io_out8(i, 0x3CE);
+                regs->gra[i] = io_in8(0x3CF);
+        }
+
+
+        for (i = 0; i < NUM_SEQ_REGS; i++)
+        {
+                io_out8(i, 0x3C4);
+                regs->seq[i] = io_in8(0x3C5);
+        }
+}
+
+
+/* from GGI */
+static
+void riva_load_state(struct rivafb_info *rinfo, struct riva_regs *regs)
+{
+        int i;
+	RIVA_HW_STATE *state = &regs->ext;
+
+        io_out8(0x11, 0x3D4);
+        io_out8(0x00, 0x3D5);
+
+        io_out8(NV_CIO_SR_LOCK_INDEX, 0x3D4);
+        io_out8(NV_CIO_SR_UNLOCK_RW_VALUE, 0x3D5);
+
+ 	rinfo->riva.LoadStateExt(&rinfo->riva,state);
+
+        io_out8(regs->misc_output, 0x3C2);
+
+        for (i = 0; i < NUM_CRT_REGS; i++)
+        {
+                if (i < 0x19)
+                {
+                        io_out8(i, 0x3D4);
+                        io_out8(regs->crtc[i], 0x3D5);
+                }
+                else
+                {
+                        switch (i)
+                        {
+                                case 0x19:
+                                case 0x20:
+                                case 0x21:
+                                case 0x22:
+                                case 0x23:
+                                case 0x24:
+                                case 0x25:
+                                case 0x26:
+                                case 0x27:
+#if 0
+                                case 0x28:
+#endif
+                                case 0x29:
+                                case 0x2a:
+                                case 0x2b:
+                                case 0x2c:
+                                case 0x2d:
+                                case 0x2e:
+                                case 0x2f:
+                                case 0x30:
+                                case 0x31:
+                                case 0x32:
+                                case 0x33:
+                                case 0x34:
+                                case 0x35:
+                                case 0x36:
+                                case 0x37:
+                                case 0x38:
+                                case 0x39:
+                                case 0x3a:
+                                case 0x3b:
+                                case 0x3c:
+                                case 0x3d:
+                                case 0x3e:
+                                case 0x3f:
+#if 0
+                                case 0x40:
+#endif
+                                break;
+                                default:
+                                io_out8(i, 0x3D4);
+                                io_out8(regs->crtc[i], 0x3D5);
+                        }
+                }
+        }
+
+        for (i = 0; i < NUM_ATC_REGS; i++)
+        {
+                io_out8(i, 0x3C0);
+                io_out8(regs->attr[i], 0x3C1);
+        }
+
+        for (i = 0; i < NUM_GRC_REGS; i++)
+        {
+                io_out8(i, 0x3CE);
+                io_out8(regs->gra[i], 0x3CF);
+        }
+
+        for (i = 0; i < NUM_SEQ_REGS; i++)
+        {
+                io_out8(i, 0x3C4);
+                io_out8(regs->seq[i], 0x3C5);
+        }
+}
+
+
+
+
+/**
+ * riva_board_list_add
+ * @board_list: Root node of list of boards
+ * @new_node: New node to be added
+ *
+ * DESCRIPTION:
+ * Adds @new_node to the list referenced by @board_list
+ *
+ * RETURNS:
+ * New root node
+ */
+static
+struct rivafb_info *riva_board_list_add(struct rivafb_info *board_list,
+				 struct rivafb_info *new_node)
+{
+	struct rivafb_info *i_p = board_list;
+
+	new_node->next = NULL;
+
+	if (board_list == NULL)
+		return new_node;
+
+	while (i_p->next != NULL)
+		i_p = i_p->next;
+	i_p->next = new_node;
+
+	return board_list;
+}
+
diff -u --recursive --new-file v2.3.25/linux/drivers/video/sbusfb.c linux/drivers/video/sbusfb.c
--- v2.3.25/linux/drivers/video/sbusfb.c	Mon Oct 11 15:38:15 1999
+++ linux/drivers/video/sbusfb.c	Tue Nov  2 17:40:11 1999
@@ -175,12 +175,15 @@
 	struct fb_info_sbusfb *fb = sbusfbinfo(info);
 	unsigned int size, page, r, map_size;
 	unsigned long map_offset = 0;
+	unsigned long off;
 	int i;
                                         
 	size = vma->vm_end - vma->vm_start;
-	if (vma->vm_offset & ~PAGE_MASK)
-		return -ENXIO;
-		
+	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+		return -EINVAL;
+
+	off = vma->vm_pgoff << PAGE_SHIFT;
+
 	/* To stop the swapper from even considering these pages */
 	vma->vm_flags |= (VM_SHM| VM_LOCKED);
 	
@@ -190,9 +193,9 @@
 		unsigned long j, alignment, s = 0;
 		int max = -1;
 		
-		map_offset = vma->vm_offset+size;
+		map_offset = (vma->vm_pgoff << PAGE_SHIFT) + size;
 		for (i = 0; fb->mmap_map[i].size; i++) {
-			if (fb->mmap_map[i].voff < vma->vm_offset)
+			if (fb->mmap_map[i].voff < off)
 				continue;
 			if (fb->mmap_map[i].voff >= map_offset)
 				break;
@@ -210,7 +213,7 @@
 					break;
 			if (alignment > PAGE_SIZE) {
 				j = alignment;
-				alignment = j - ((vma->vm_start + fb->mmap_map[max].voff - vma->vm_offset) & (j - 1));
+				alignment = j - ((vma->vm_start + fb->mmap_map[max].voff - off) & (j - 1));
 				if (alignment != j) {
 					struct vm_area_struct *vmm = find_vma(current->mm, vma->vm_start);
 					if (!vmm || vmm->vm_start >= vma->vm_end + alignment) {
@@ -227,7 +230,7 @@
 	for (page = 0; page < size; ){
 		map_size = 0;
 		for (i = 0; fb->mmap_map[i].size; i++)
-			if (fb->mmap_map[i].voff == vma->vm_offset+page) {
+			if (fb->mmap_map[i].voff == off+page) {
 				map_size = sbusfb_mmapsize(fb,fb->mmap_map[i].size);
 #ifdef __sparc_v9__
 #define POFF_MASK	(PAGE_MASK|0x1UL)
diff -u --recursive --new-file v2.3.25/linux/drivers/video/sgivwfb.c linux/drivers/video/sgivwfb.c
--- v2.3.25/linux/drivers/video/sgivwfb.c	Thu Aug 26 13:05:40 1999
+++ linux/drivers/video/sgivwfb.c	Tue Nov  2 17:40:11 1999
@@ -907,9 +907,12 @@
                         struct vm_area_struct *vma)
 {
   unsigned long size = vma->vm_end - vma->vm_start;
-  unsigned long offset = sgivwfb_mem_phys + vma->vm_offset;
-  if (vma->vm_offset+size > sgivwfb_mem_size)
+  unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+  if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
+	return -EINVAL;
+  if (offset+size > sgivwfb_mem_size)
     return -EINVAL;
+  offset += sgivwfb_mem_phys;
   pgprot_val(vma->vm_page_prot) = pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
   vma->vm_flags |= VM_IO;
   if (remap_page_range(vma->vm_start, offset, size, vma->vm_page_prot))
diff -u --recursive --new-file v2.3.25/linux/drivers/video/tdfxfb.c linux/drivers/video/tdfxfb.c
--- v2.3.25/linux/drivers/video/tdfxfb.c	Mon Oct 11 15:38:15 1999
+++ linux/drivers/video/tdfxfb.c	Wed Nov  3 14:01:41 1999
@@ -8,15 +8,17 @@
  * All rights reserved
  *
  * Created      : Thu Sep 23 18:17:43 1999, hmallat
- * Last modified: Thu Oct  7 18:39:04 1999, hmallat
+ * Last modified: Tue Nov  2 21:19:47 1999, hmallat
  *
  * Lots of the information here comes from the Daryll Strauss' Banshee 
  * patches to the XF86 server, and the rest comes from the 3dfx
  * Banshee specification. I'm very much indebted to Daryll for his
  * work on the X server.
  *
- * Voodoo3 support was contributed Harold Oga. Thanks!
- *
+ * Voodoo3 support was contributed Harold Oga. Lots of additions
+ * (proper acceleration, 24 bpp, hardware cursor) and bug fixes by Attila
+ * Kesmarki. Thanks guys!
+ * 
  * While I _am_ grateful to 3Dfx for releasing the specs for Banshee,
  * I do wish the next version is a bit more complete. Without the XF86
  * patches I couldn't have gotten even this far... for instance, the
@@ -29,21 +31,24 @@
  * 
  * TODO:
  * - support for 16/32 bpp needs fixing (funky bootup penguin)
- * - multihead support (it's all hosed now with pokes to VGA standard
- *   register locations, but shouldn't be that hard to change, some
- *   other code needs to be changed too where the fb_info (which should
- *   be an array of head-specific information) is referred to directly.
- *   are referred to )
- * - hw cursor
- * - better acceleration support (e.g., font blitting from fb memory?)
+ * - multihead support (basically need to support an array of fb_infos)
  * - banshee and voodoo3 now supported -- any others? afaik, the original
  *   voodoo was a 3d-only card, so we won't consider that. what about
  *   voodoo2?
- * - 24bpp 
- * - panning (doesn't seem to work properly yet)
+ * - support other architectures (PPC, Alpha); does the fact that the VGA
+ *   core can be accessed only thru I/O (not memory mapped) complicate
+ *   things?
  *
  * Version history:
  *
+ * 0.1.3 (released 1999-11-02) added Attila's panning support, code
+ *			       reorg, hwcursor address page size alignment
+ *                             (for mmaping both frame buffer and regs),
+ *                             and my changes to get rid of hardcoded
+ *                             VGA i/o register locations (uses PCI
+ *                             configuration info now)
+ * 0.1.2 (released 1999-10-19) added Attila Kesmarki's bug fixes and
+ *                             improvements
  * 0.1.1 (released 1999-10-07) added Voodoo3 support by Harold Oga.
  * 0.1.0 (released 1999-10-06) initial version
  *
@@ -69,10 +74,16 @@
 #include <linux/kd.h>
 #include <linux/vt_kern.h>
 #include <asm/io.h>
+#include <linux/timer.h>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
 
 #include <video/fbcon.h>
 #include <video/fbcon-cfb8.h>
 #include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
 #include <video/fbcon-cfb32.h>
 
 #ifndef LINUX_VERSION_CODE
@@ -87,6 +98,12 @@
 #define PCI_DEVICE_ID_3DFX_VOODOO3      0x0005
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
+/* nothing? */
+#else
+#include <linux/spinlock.h>
+#endif
+
 /* membase0 register offsets */
 #define STATUS		0x00
 #define PCIINIT0	0x04
@@ -167,24 +184,26 @@
 
 #define BIT(x) (1UL << (x))
 
-#define ROP_COPY	0xcc
+/* COMMAND_2D reg. values */
+#define ROP_COPY	0xcc     // src
+#define ROP_INVERT      0x55     // NOT dst
+#define ROP_XOR         0x66     // src XOR dst
 
+#define AUTOINC_DSTX                    BIT(10)
+#define AUTOINC_DSTY                    BIT(11)
 #define COMMAND_2D_FILLRECT		0x05
-#define COMMAND_2D_BITBLT		0x01
+#define COMMAND_2D_S2S_BITBLT		0x01      // screen to screen
+#define COMMAND_2D_H2S_BITBLT           0x03       // host to screen
 
-#define COMMAND_3D_NOP			0x00
 
+#define COMMAND_3D_NOP			0x00
 #define STATUS_RETRACE			BIT(6)
 #define STATUS_BUSY			BIT(9)
-
 #define MISCINIT1_CLUT_INV		BIT(0)
 #define MISCINIT1_2DBLOCK_DIS		BIT(15)
-
 #define DRAMINIT0_SGRAM_NUM		BIT(26)
 #define DRAMINIT0_SGRAM_TYPE		BIT(27)
-
 #define DRAMINIT1_MEM_SDRAM		BIT(30)
-
 #define VGAINIT0_VGA_DISABLE		BIT(0)
 #define VGAINIT0_EXT_TIMING		BIT(1)
 #define VGAINIT0_8BIT_DAC		BIT(2)
@@ -196,17 +215,15 @@
 #define VGAINIT0_EXTSHIFTOUT		BIT(12)
 #define VGAINIT0_DECODE_3C6		BIT(13)
 #define VGAINIT0_SGRAM_HBLANK_DISABLE	BIT(22)
-
 #define VGAINIT1_MASK			0x1fffff
-
 #define VIDCFG_VIDPROC_ENABLE		BIT(0)
 #define VIDCFG_CURS_X11			BIT(1)
 #define VIDCFG_HALF_MODE		BIT(4)
 #define VIDCFG_DESK_ENABLE		BIT(7)
 #define VIDCFG_CLUT_BYPASS		BIT(10)
 #define VIDCFG_2X			BIT(26)
+#define VIDCFG_HWCURSOR_ENABLE          BIT(27)
 #define VIDCFG_PIXFMT_SHIFT		18
-
 #define DACMODE_2X			BIT(0)
 
 /* VGA rubbish, need to change this for multihead support */
@@ -220,9 +237,6 @@
 #define IS1_R	0x3da
 #define GRA_I	0x3ce
 #define GRA_D	0x3cf
-#define DAC_IR	0x3c7
-#define DAC_IW	0x3c8
-#define DAC_D	0x3c9
 
 #ifndef FB_ACCEL_3DFX_BANSHEE 
 #define FB_ACCEL_3DFX_BANSHEE 31
@@ -238,9 +252,9 @@
 #define TDFXF_HSYNC_MASK	0x03
 #define TDFXF_VSYNC_MASK	0x0c
 
-/* #define TDFXFB_DEBUG */
+//#define TDFXFB_DEBUG 
 #ifdef TDFXFB_DEBUG
-#define DPRINTK(a,b...) printk("fb: %s: " a, __FUNCTION__ , ## b)
+#define DPRINTK(a,b...) printk(KERN_DEBUG "fb: %s: " a, __FUNCTION__ , ## b)
 #else
 #define DPRINTK(a,b...)
 #endif 
@@ -271,6 +285,9 @@
   unsigned long screensize;
   unsigned long stride;
   unsigned long cursloc;
+  unsigned long curspataddr;
+  unsigned long cursc0;
+  unsigned long cursc1;
   unsigned long startaddr;
   unsigned long clip0min;
   unsigned long clip0max;
@@ -305,6 +322,7 @@
 
   u32 video;
   u32 accel_flags;
+  u32 cmap_len;
 };
 
 struct fb_info_tdfx {
@@ -319,21 +337,37 @@
   unsigned long bufbase_phys;
   unsigned long bufbase_virt;
   unsigned long bufbase_size;
+  unsigned long iobase;
 
-  struct { u8 red, green, blue, pad; } palette[256];
+  struct { unsigned red, green, blue, pad; } palette[256];
   struct tdfxfb_par default_par;
   struct tdfxfb_par current_par;
   struct display disp;
   struct display_switch dispsw;
-  
+#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)  
   union {
 #ifdef FBCON_HAS_CFB16
     u16 cfb16[16];
 #endif
+#ifdef FBCON_HAS_CFB24
+    u32 cfb24[16];
+#endif
 #ifdef FBCON_HAS_CFB32
     u32 cfb32[16];
 #endif
   } fbcon_cmap;
+#endif
+  struct { 
+     int type;             
+     int state;             
+     int w,u,d;             
+     int x,y,redraw;
+     unsigned long enable,disable;    
+     unsigned long cursorimage;       
+     struct timer_list timer;
+  } cursor;
+ 
+  spinlock_t DAClock; 
 };
 
 /*
@@ -411,9 +445,30 @@
 			     u_int blue,
 			     u_int transp, 
 			     struct fb_info* fb);
-static void  tdfxfb_install_cmap(int con, 
+static void  tdfxfb_install_cmap(struct display *d, 
 				 struct fb_info *info);
 
+static void tdfxfb_hwcursor_init(void);
+static void tdfxfb_createcursorshape(struct display* p);
+static void tdfxfb_createcursor(struct display * p);  
+
+/*
+ * do_xxx: Hardware-specific functions
+ */
+static void  do_pan_var(struct fb_var_screeninfo* var, struct fb_info_tdfx *i);
+static void  do_flashcursor(unsigned long ptr);
+static void  do_bitblt(u32 curx, u32 cury, u32 dstx,u32 dsty, 
+		      u32 width, u32 height,u32 stride,u32 bpp);
+static void  do_fillrect(u32 x, u32 y, u32 w,u32 h, 
+			u32 color,u32 stride,u32 bpp,u32 rop);
+static void  do_putc(u32 fgx, u32 bgx,struct display *p,
+			int c, int yy,int xx);
+static void  do_putcs(u32 fgx, u32 bgx,struct display *p,
+		     const unsigned short *s,int count, int yy,int xx);
+static u32 do_calc_pll(int freq, int* freq_out);
+static void  do_write_regs(struct banshee_reg* reg);
+static unsigned long do_lfb_size(void);
+
 /*
  *  Interface used by the world
  */
@@ -437,7 +492,8 @@
   tdfxfb_set_cmap, 
   tdfxfb_pan_display, 
   tdfxfb_ioctl,
-  NULL
+  NULL,           // fb_mmap
+  NULL            // fb_rasterimg
 };
 
 struct mode {
@@ -449,7 +505,7 @@
 struct mode default_mode[] = {
   { "640x480-8@60", /* @ 60 Hz */
     {
-      640, 480, 640, 480, 0, 0, 8, 0,
+      640, 480, 640, 1024, 0, 0, 8, 0,
       {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
       0, FB_ACTIVATE_NOW, -1, -1, FB_ACCELF_TEXT, 
       39722, 40, 24, 32, 11, 96, 2,
@@ -493,7 +549,26 @@
       15385, 168, 8, 29, 3, 144, 6,
       0, FB_VMODE_NONINTERLACED
     }
-  }
+  },
+  { "1024x768-24@60", /* @ 60 Hz */ 
+    {
+      1024, 768, 1024, 768, 0, 0, 24, 0,
+      {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {0, 0, 0},
+      0, FB_ACTIVATE_NOW, -1, -1, FB_ACCELF_TEXT, 
+      15385, 168, 8, 29, 3, 144, 6,
+      0, FB_VMODE_NONINTERLACED
+    }
+  },
+  { "1024x768-32@60", /* @ 60 Hz */ 
+    {
+      1024, 768, 1024, 768, 0, 0, 32, 0,
+      {16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {0, 0, 0},
+      0, FB_ACTIVATE_NOW, -1, -1, FB_ACCELF_TEXT, 
+      15385, 168, 8, 29, 3, 144, 6,
+      0, FB_VMODE_NONINTERLACED
+    }
+  }   
+   
 #endif
 };
 
@@ -504,55 +579,81 @@
 
 static struct fb_info_tdfx fb_info;
 
-static int  __initdata noaccel = 0;
-static int  __initdata nopan   = 0;
-static int  __initdata nowrap  = 0;
-static int  __initdata inverse = 0;
+static int  noaccel = 0;
+static int  nopan   = 0;
+static int  nowrap  = 1;      // not implemented (yet)
+static int  inverse = 0;
+static int  nomtrr = 0;
+static int  nohwcursor = 0;
 static char __initdata fontname[40] = { 0 };
 static const char *mode_option __initdata = NULL;
 
-/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- 
+ *                      Hardware-specific funcions
+ * ------------------------------------------------------------------------- */
+
+#ifdef VGA_REG_IO 
+static inline  u8 vga_inb(u32 reg) { return inb(reg); }
+static inline u16 vga_inw(u32 reg) { return inw(reg); }
+static inline u16 vga_inl(u32 reg) { return inl(reg); }
+
+static inline void vga_outb(u32 reg,  u8 val) { outb(val, reg); }
+static inline void vga_outw(u32 reg, u16 val) { outw(val, reg); }
+static inline void vga_outl(u32 reg, u32 val) { outl(val, reg); }
+#else
+static inline  u8 vga_inb(u32 reg) { 
+  return inb(fb_info.iobase + reg - 0x300); 
+}
+static inline u16 vga_inw(u32 reg) { 
+  return inw(fb_info.iobase + reg - 0x300); 
+}
+static inline u16 vga_inl(u32 reg) { 
+  return inl(fb_info.iobase + reg - 0x300); 
+}
 
-static inline  __u8 vga_inb(__u32 reg) { return inb(reg); }
-static inline __u16 vga_inw(__u32 reg) { return inw(reg); }
-static inline __u16 vga_inl(__u32 reg) { return inl(reg); }
-
-static inline void vga_outb(__u32 reg,  __u8 val) { outb(val, reg); }
-static inline void vga_outw(__u32 reg, __u16 val) { outw(val, reg); }
-static inline void vga_outl(__u32 reg, __u32 val) { outl(val, reg); }
+static inline void vga_outb(u32 reg,  u8 val) { 
+  outb(val, fb_info.iobase + reg - 0x300); 
+}
+static inline void vga_outw(u32 reg, u16 val) { 
+  outw(val, fb_info.iobase + reg - 0x300); 
+}
+static inline void vga_outl(u32 reg, u32 val) { 
+  outl(val, fb_info.iobase + reg - 0x300); 
+}
+#endif
 
-static inline void gra_outb(__u32 idx, __u8 val) {
+static inline void gra_outb(u32 idx, u8 val) {
   vga_outb(GRA_I, idx); vga_outb(GRA_D, val);
 }
 
-static inline __u8 gra_inb(__u32 idx) {
+static inline u8 gra_inb(u32 idx) {
   vga_outb(GRA_I, idx); return vga_inb(GRA_D);
 }
 
-static inline void seq_outb(__u32 idx, __u8 val) {
+static inline void seq_outb(u32 idx, u8 val) {
   vga_outb(SEQ_I, idx); vga_outb(SEQ_D, val);
 }
 
-static inline __u8 seq_inb(__u32 idx) {
+static inline u8 seq_inb(u32 idx) {
   vga_outb(SEQ_I, idx); return vga_inb(SEQ_D);
 }
 
-static inline void crt_outb(__u32 idx, __u8 val) {
+static inline void crt_outb(u32 idx, u8 val) {
   vga_outb(CRT_I, idx); vga_outb(CRT_D, val);
 }
 
-static inline __u8 crt_inb(__u32 idx) {
+static inline u8 crt_inb(u32 idx) {
   vga_outb(CRT_I, idx); return vga_inb(CRT_D);
 }
 
-static inline void att_outb(__u32 idx, __u8 val) {
+static inline void att_outb(u32 idx, u8 val) {
   unsigned char tmp;
   tmp = vga_inb(IS1_R);
   vga_outb(ATT_IW, idx);
   vga_outb(ATT_IW, val);
 }
 
-static inline __u8 att_inb(__u32 idx) {
+static inline u8 att_inb(u32 idx) {
   unsigned char tmp;
   tmp = vga_inb(IS1_R);
   vga_outb(ATT_IW, idx);
@@ -585,11 +686,11 @@
   vga_outb(ATT_IW, 0x20);
 }
 
-static inline __u32 tdfx_inl(unsigned int reg) {
+static inline u32 tdfx_inl(unsigned int reg) {
   return readl(fb_info.regbase_virt + reg);
 }
 
-static inline void tdfx_outl(unsigned int reg, __u32 val) {
+static inline void tdfx_outl(unsigned int reg, u32 val) {
   writel(val, fb_info.regbase_virt + reg);
 }
 
@@ -608,81 +709,226 @@
     if(i == 3) break;
   }
 }
+/*
+ * Set the color of a palette entry in 8bpp mode 
+ */
+static inline void do_setpalentry(unsigned regno, u32 c) {  
+   banshee_make_room(2); tdfx_outl(DACADDR,  regno); tdfx_outl(DACDATA,  c); }
 
-static void banshee_fillrect(__u32 x, 
-			     __u32 y, 
-			     __u32 w,
-			     __u32 h, 
-			     __u32 color,
-			     __u32 stride,
-			     __u32 bpp) {
-  banshee_make_room(2);
-  tdfx_outl(DSTFORMAT, 
-	    (stride & 0x3fff) | 
-	    (bpp ==  8 ? 0x10000 : 
-	     bpp == 16 ? 0x30000 : 0x50000));
-  tdfx_outl(COLORFORE, color);
-  
-  banshee_make_room(3);
-  tdfx_outl(COMMAND_2D, COMMAND_2D_FILLRECT | (ROP_COPY << 24));
-  tdfx_outl(DSTSIZE,    (w & 0x1fff) | ((h & 0x1fff) << 16));
-  tdfx_outl(LAUNCH_2D,  (x & 0x1fff) | ((y & 0x1fff) << 16));
-}
-
-static void banshee_bitblt(__u32 curx, 
-			   __u32 cury, 
-			   __u32 dstx,
-			   __u32 dsty, 
-			   __u32 width, 
-			   __u32 height,
-			   __u32 stride,
-			   __u32 bpp) {
-  int xdir, ydir;
-
-  xdir = dstx < curx ? 1 : -1;
-  ydir = dsty < cury ? 1 : -1;
-
-  banshee_make_room(4);
-  tdfx_outl(SRCFORMAT, 
-	    (stride & 0x3fff) | 
-	    (bpp ==  8 ? 0x10000 : 
-	     bpp == 16 ? 0x30000 : 0x50000));
-  tdfx_outl(DSTFORMAT, 
-	    (stride & 0x3fff) | 
-	    (bpp ==  8 ? 0x10000 : 
-	     bpp == 16 ? 0x30000 : 0x50000));
-  tdfx_outl(COMMAND_2D, 
-	    COMMAND_2D_BITBLT | 
-	    (xdir == -1 ? BIT(14) : 0) |
-	    (ydir == -1 ? BIT(15) : 0));
-  tdfx_outl(COMMANDEXTRA_2D, 0); /* no color keying */
-
-  if(xdir == -1) {
-    curx += width - 1;
-    dstx += width - 1;
-  }
-  if(ydir == -1) {
-    cury += height - 1;
-    dsty += height - 1;
-  }
-  
-  /* Consecutive overlapping regions can hang the board -- 
-     since we allow mmap'ing of control registers, we cannot
-     __safely__ assume anything, like XF86 does... */
-  banshee_make_room(1);
-  tdfx_outl(COMMAND_3D, COMMAND_3D_NOP);
+/* 
+ * Set the starting position of the visible screen to var->yoffset 
+ */
+static void do_pan_var(struct fb_var_screeninfo* var, struct fb_info_tdfx *i)
+{
+    u32 addr;
+    addr = var->yoffset*i->current_par.lpitch;
+    banshee_make_room(1);
+    tdfx_outl(VIDDESKSTART, addr);
+}
+   
+/*
+ * Invert the hardware cursor image (timerfunc)  
+ */
+static void do_flashcursor(unsigned long ptr)
+{
+   struct fb_info_tdfx* i=(struct fb_info_tdfx *)ptr;
+   spin_lock(&i->DAClock);
+   banshee_make_room(1);
+   tdfx_outl( VIDPROCCFG, tdfx_inl(VIDPROCCFG) ^ VIDCFG_HWCURSOR_ENABLE );
+   i->cursor.timer.expires=jiffies+HZ/2;
+   add_timer(&i->cursor.timer);
+   spin_unlock(&i->DAClock);
+}
 
-  banshee_make_room(3);
-  tdfx_outl(DSTSIZE,   (width & 0x1fff) | ((height & 0x1fff) << 16));
-  tdfx_outl(DSTXY,     (dstx  & 0x1fff) | ((dsty  & 0x1fff) << 16));
-  tdfx_outl(LAUNCH_2D, (curx  & 0x1fff) | ((cury  & 0x1fff) << 16));
+/*
+ * FillRect 2D command (solidfill or invert (via ROP_XOR))   
+ */
+static void do_fillrect(u32 x, u32 y, u32 w, u32 h, 
+			u32 color, u32 stride, u32 bpp, u32 rop) {
+
+   u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 
+
+   banshee_make_room(5);
+   tdfx_outl(DSTFORMAT, fmt);
+   tdfx_outl(COLORFORE, color);
+   tdfx_outl(COMMAND_2D, COMMAND_2D_FILLRECT | (rop << 24));
+   tdfx_outl(DSTSIZE,    w | (h << 16));
+   tdfx_outl(LAUNCH_2D,  x | (y << 16));
+   banshee_wait_idle();
 }
 
-static __u32 banshee_calc_pll(int freq, int* freq_out) {
+/*
+ * Screen-to-Screen BitBlt 2D command (for the bmove fb op.) 
+ */
+
+static void do_bitblt(u32 curx, 
+			   u32 cury, 
+			   u32 dstx,
+			   u32 dsty, 
+			   u32 width, 
+			   u32 height,
+			   u32 stride,
+			   u32 bpp) {
+
+   u32 blitcmd = COMMAND_2D_S2S_BITBLT | (ROP_COPY << 24);
+   u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 
+   
+   if (curx <= dstx) {
+     //-X 
+     blitcmd |= BIT(14);
+     curx += width-1;
+     dstx += width-1;
+   }
+   if (cury <= dsty) {
+     //-Y  
+     blitcmd |= BIT(15);
+     cury += height-1;
+     dsty += height-1;
+   }
+   
+   banshee_make_room(6);
+
+   tdfx_outl(SRCFORMAT, fmt);
+   tdfx_outl(DSTFORMAT, fmt);
+   tdfx_outl(COMMAND_2D, blitcmd); 
+   tdfx_outl(DSTSIZE,   width | (height << 16));
+   tdfx_outl(DSTXY,     dstx | (dsty << 16));
+   tdfx_outl(LAUNCH_2D, curx | (cury << 16)); 
+   banshee_wait_idle();
+}
+
+static void do_putc(u32 fgx, u32 bgx,
+			 struct display *p,
+			 int c, int yy,int xx)
+{   
+   int i;
+   int stride=fb_info.current_par.lpitch;
+   u32 bpp=fb_info.current_par.bpp;
+   int fw=(fontwidth(p)+7)>>3;
+   u8 *chardata=p->fontdata+(c&p->charmask)*fontheight(p)*fw;
+   u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 
+   
+   xx *= fontwidth(p);
+   yy *= fontheight(p);
+
+   banshee_make_room(8+((fontheight(p)*fw+3)>>2) );
+   tdfx_outl(COLORFORE, fgx);
+   tdfx_outl(COLORBACK, bgx);
+   tdfx_outl(SRCXY,     0);
+   tdfx_outl(DSTXY,     xx | (yy << 16));
+   tdfx_outl(COMMAND_2D, COMMAND_2D_H2S_BITBLT | (ROP_COPY << 24));
+   tdfx_outl(SRCFORMAT, 0x400000);
+   tdfx_outl(DSTFORMAT, fmt);
+   tdfx_outl(DSTSIZE,   fontwidth(p) | (fontheight(p) << 16));
+   i=fontheight(p);
+   switch (fw) {
+    case 1:
+     while (i>=4) {
+         tdfx_outl(LAUNCH_2D,*(u32*)chardata);
+	 chardata+=4;
+	 i-=4;
+     }
+     switch (i) {
+      case 0: break;
+      case 1:  tdfx_outl(LAUNCH_2D,*chardata); break;
+      case 2:  tdfx_outl(LAUNCH_2D,*(u16*)chardata); break;
+      case 3:  tdfx_outl(LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break;
+     }
+     break;
+   case 2:
+     while (i>=2) {
+         tdfx_outl(LAUNCH_2D,*(u32*)chardata);
+	 chardata+=4;
+	 i-=2;
+     }
+     if (i) tdfx_outl(LAUNCH_2D,*(u16*)chardata); 
+     break;
+   default:
+     // Is there a font with width more that 16 pixels ?
+     for (i=fontheight(p);i>0;i--) {
+	 tdfx_outl(LAUNCH_2D,*(u32*)chardata);
+	 chardata+=4;
+     }
+     break;
+   }
+   banshee_wait_idle();
+}
+
+static void do_putcs(u32 fgx, u32 bgx,
+			  struct display *p,
+			  const unsigned short *s,
+			  int count, int yy,int xx)
+{   
+   int i;
+   int stride=fb_info.current_par.lpitch;
+   u32 bpp=fb_info.current_par.bpp;
+   int fw=(fontwidth(p)+7)>>3;
+   int w=fontwidth(p);
+   int h=fontheight(p);
+   int regsneed=1+((h*fw+3)>>2);
+   u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 
+
+   xx *= w;
+   yy = (yy*h) << 16;
+   banshee_make_room(8);
+
+   tdfx_outl(COMMAND_3D, COMMAND_3D_NOP);
+   tdfx_outl(COLORFORE, fgx);
+   tdfx_outl(COLORBACK, bgx);
+   tdfx_outl(SRCFORMAT, 0x400000);
+   tdfx_outl(DSTFORMAT, fmt);
+   tdfx_outl(DSTSIZE, w | (h << 16));
+   tdfx_outl(SRCXY,     0);
+   tdfx_outl(COMMAND_2D, COMMAND_2D_H2S_BITBLT | (ROP_COPY << 24));
+   
+   while (count--) {
+      u8 *chardata=p->fontdata+(scr_readw(s++) & p->charmask)*h*fw;
+   
+      banshee_make_room(regsneed);
+      tdfx_outl(DSTXY, xx | yy);
+      xx+=w;
+      
+      i=h;
+      switch (fw) {
+       case 1:
+        while (i>=4) {
+           tdfx_outl(LAUNCH_2D,*(u32*)chardata);
+	   chardata+=4;
+	   i-=4;
+        }
+        switch (i) {
+          case 0: break;
+          case 1:  tdfx_outl(LAUNCH_2D,*chardata); break;
+          case 2:  tdfx_outl(LAUNCH_2D,*(u16*)chardata); break;
+          case 3:  tdfx_outl(LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break;
+        }
+        break;
+       case 2:
+        while (i>=2) {
+         tdfx_outl(LAUNCH_2D,*(u32*)chardata);
+	 chardata+=4;
+	 i-=2;
+        }
+        if (i) tdfx_outl(LAUNCH_2D,*(u16*)chardata); 
+        break;
+       default:
+       // Is there a font with width more that 16 pixels ?
+        for (;i>0;i--) {
+	  tdfx_outl(LAUNCH_2D,*(u32*)chardata);
+	  chardata+=4;
+        }
+        break;
+     }
+   }
+   banshee_wait_idle();
+}
+
+static u32 do_calc_pll(int freq, int* freq_out) {
   int m, n, k, best_m, best_n, best_k, f_cur, best_error;
   int fref = 14318;
   
-  /* this really could be done with more intelligence */
+  /* this really could be done with more intelligence --
+     255*63*4 = 64260 iterations is silly */
   best_error = freq;
   best_n = best_m = best_k = 0;
   for(n = 1; n < 256; n++) {
@@ -703,13 +949,10 @@
   k = best_k;
   *freq_out = fref*(n + 2)/(m + 2)/(1 << k);
 
-  DPRINTK("freq = %d kHz, freq_out = %d kHz\n", freq, *freq_out);
-  DPRINTK("N = %d, M = %d, K = %d\n", n, m, k);
-
   return (n << 8) | (m << 2) | k;
 }
 
-static void banshee_write_regs(struct banshee_reg* reg) {
+static void do_write_regs(struct banshee_reg* reg) {
   int i;
 
   banshee_wait_idle();
@@ -747,17 +990,25 @@
   vga_enable_palette();
   vga_enable_video();
 
-  banshee_make_room(9);
+  banshee_make_room(11);
   tdfx_outl(VGAINIT0,      reg->vgainit0);
   tdfx_outl(DACMODE,       reg->dacmode);
   tdfx_outl(VIDDESKSTRIDE, reg->stride);
-  tdfx_outl(HWCURPATADDR,  reg->cursloc);
+  if (nohwcursor) {
+     tdfx_outl(HWCURPATADDR,  0);
+  } else {
+     tdfx_outl(HWCURPATADDR,  reg->curspataddr);
+     tdfx_outl(HWCURC0,       reg->cursc0);
+     tdfx_outl(HWCURC1,       reg->cursc1);
+     tdfx_outl(HWCURLOC,      reg->cursloc);
+  }
+   
   tdfx_outl(VIDSCREENSIZE, reg->screensize);
   tdfx_outl(VIDDESKSTART,  reg->startaddr);
   tdfx_outl(VIDPROCCFG,    reg->vidcfg);
   tdfx_outl(VGAINIT1,      reg->vgainit1);  
 
-  banshee_make_room(7);
+  banshee_make_room(8);
   tdfx_outl(SRCBASE,         reg->srcbase);
   tdfx_outl(DSTBASE,         reg->dstbase);
   tdfx_outl(COMMANDEXTRA_2D, 0);
@@ -765,15 +1016,16 @@
   tdfx_outl(CLIP0MAX,        0x0fff0fff);
   tdfx_outl(CLIP1MIN,        0);
   tdfx_outl(CLIP1MAX,        0x0fff0fff);
+  tdfx_outl(SRCXY, 0);
 
   banshee_wait_idle();
 }
 
-static unsigned long tdfx_lfb_size(void) {
-  __u32 draminit0 = 0;
-  __u32 draminit1 = 0;
-  __u32 miscinit1 = 0;
-  __u32 lfbsize   = 0;
+static unsigned long do_lfb_size(void) {
+  u32 draminit0 = 0;
+  u32 draminit1 = 0;
+  u32 miscinit1 = 0;
+  u32 lfbsize   = 0;
   int sgram_p     = 0;
 
   if(!((fb_info.dev == PCI_DEVICE_ID_3DFX_BANSHEE) ||
@@ -782,7 +1034,7 @@
 
   draminit0 = tdfx_inl(DRAMINIT0);  
   draminit1 = tdfx_inl(DRAMINIT1);
-
+   
   sgram_p = (draminit1 & DRAMINIT1_MEM_SDRAM) ? 0 : 1;
   
   lfbsize = sgram_p ?
@@ -794,19 +1046,53 @@
   miscinit1 = tdfx_inl(MISCINIT1);
   miscinit1 |= sgram_p ? 0 : MISCINIT1_2DBLOCK_DIS;
   miscinit1 |= MISCINIT1_CLUT_INV;
+
+  banshee_make_room(1); 
   tdfx_outl(MISCINIT1, miscinit1);
 
   return lfbsize;
 }
 
-static void fbcon_banshee_bmove(struct display* p, 
+/* ------------------------------------------------------------------------- 
+ *              Hardware independent part, interface to the world
+ * ------------------------------------------------------------------------- */
+
+#define tdfx_cfb24_putc  tdfx_cfb32_putc
+#define tdfx_cfb24_putcs tdfx_cfb32_putcs
+#define tdfx_cfb24_clear tdfx_cfb32_clear
+
+static void tdfx_cfbX_clear_margins(struct vc_data* conp, struct display* p,
+				    int bottom_only)
+{
+   unsigned int cw=fontwidth(p);
+   unsigned int ch=fontheight(p);
+   unsigned int rw=p->var.xres % cw;   // it be in a non-standard mode or not?
+   unsigned int bh=p->var.yres % ch;
+   unsigned int rs=p->var.xres - rw;
+   unsigned int bs=p->var.yres - bh;
+
+   if (!bottom_only && rw) { 
+      do_fillrect( p->var.xoffset+rs, 0, 
+		  rw, p->var.yres_virtual, 0, 
+		  fb_info.current_par.lpitch,
+		  fb_info.current_par.bpp, ROP_COPY);
+   }
+   
+   if (bh) { 
+      do_fillrect( p->var.xoffset, p->var.yoffset+bs, 
+		  rs, bh, 0, 
+		  fb_info.current_par.lpitch,
+		  fb_info.current_par.bpp, ROP_COPY);
+   }
+}
+static void tdfx_cfbX_bmove(struct display* p, 
 				int sy, 
 				int sx, 
 				int dy,
 				int dx, 
 				int height, 
 				int width) {
-  banshee_bitblt(fontwidth(p)*sx,
+   do_bitblt(fontwidth(p)*sx,
 		 fontheight(p)*sy, 
 		 fontwidth(p)*dx,
 		 fontheight(p)*dy, 
@@ -815,64 +1101,221 @@
 		 fb_info.current_par.lpitch, 
 		 fb_info.current_par.bpp);
 }
+static void tdfx_cfb8_putc(struct vc_data* conp,
+			       struct display* p,
+			       int c, int yy,int xx)
+{   
+   u32 fgx,bgx;
+   fgx=attr_fgcol(p, c);
+   bgx=attr_bgcol(p, c);
+   do_putc( fgx,bgx,p,c,yy,xx );
+}
+
+static void tdfx_cfb16_putc(struct vc_data* conp,
+			       struct display* p,
+			       int c, int yy,int xx)
+{   
+   u32 fgx,bgx;
+   fgx=((u16*)p->dispsw_data)[attr_fgcol(p,c)];
+   bgx=((u16*)p->dispsw_data)[attr_bgcol(p,c)];
+   do_putc( fgx,bgx,p,c,yy,xx );
+}
+
+static void tdfx_cfb32_putc(struct vc_data* conp,
+			       struct display* p,
+			       int c, int yy,int xx)
+{   
+   u32 fgx,bgx;
+   fgx=((u32*)p->dispsw_data)[attr_fgcol(p,c)];
+   bgx=((u32*)p->dispsw_data)[attr_bgcol(p,c)];
+   do_putc( fgx,bgx,p,c,yy,xx );
+}
+static void tdfx_cfb8_putcs(struct vc_data* conp,
+			    struct display* p,
+			    const unsigned short *s,int count,int yy,int xx)
+{
+   u32 fgx,bgx;
+   fgx=attr_fgcol(p, *s);
+   bgx=attr_bgcol(p, *s);
+   do_putcs( fgx,bgx,p,s,count,yy,xx );
+}
+static void tdfx_cfb16_putcs(struct vc_data* conp,
+			    struct display* p,
+			    const unsigned short *s,int count,int yy,int xx)
+{
+   u32 fgx,bgx;
+   fgx=((u16*)p->dispsw_data)[attr_fgcol(p,*s)];
+   bgx=((u16*)p->dispsw_data)[attr_bgcol(p,*s)];
+   do_putcs( fgx,bgx,p,s,count,yy,xx );
+}
+static void tdfx_cfb32_putcs(struct vc_data* conp,
+			    struct display* p,
+			    const unsigned short *s,int count,int yy,int xx)
+{
+   u32 fgx,bgx;
+   fgx=((u32*)p->dispsw_data)[attr_fgcol(p,*s)];
+   bgx=((u32*)p->dispsw_data)[attr_bgcol(p,*s)];
+   do_putcs( fgx,bgx,p,s,count,yy,xx );
+}
 
-static void fbcon_banshee_clear(struct vc_data* conp, 
+static void tdfx_cfb8_clear(struct vc_data* conp, 
 				struct display* p, 
 				int sy,
 				int sx, 
 				int height, 
 				int width) {
-  unsigned int bg;
+  u32 bg;
 
   bg = attr_bgcol_ec(p,conp);
-  banshee_fillrect(fontwidth(p)*sx,
+  do_fillrect(fontwidth(p)*sx,
 		   fontheight(p)*sy,
 		   fontwidth(p)*width, 
 		   fontheight(p)*height,
 		   bg, 
 		   fb_info.current_par.lpitch, 
-		   fb_info.current_par.bpp);
+		   fb_info.current_par.bpp,ROP_COPY);
 }
 
+static void tdfx_cfb16_clear(struct vc_data* conp, 
+				struct display* p, 
+				int sy,
+				int sx, 
+				int height, 
+				int width) {
+  u32 bg;
+
+  bg = ((u16*)p->dispsw_data)[attr_bgcol_ec(p,conp)];
+  do_fillrect(fontwidth(p)*sx,
+		   fontheight(p)*sy,
+		   fontwidth(p)*width, 
+		   fontheight(p)*height,
+		   bg, 
+		   fb_info.current_par.lpitch, 
+		   fb_info.current_par.bpp,ROP_COPY);
+}
+
+static void tdfx_cfb32_clear(struct vc_data* conp, 
+				struct display* p, 
+				int sy,
+				int sx, 
+				int height, 
+				int width) {
+  u32 bg;
+
+  bg = ((u32*)p->dispsw_data)[attr_bgcol_ec(p,conp)];
+  do_fillrect(fontwidth(p)*sx,
+		   fontheight(p)*sy,
+		   fontwidth(p)*width, 
+		   fontheight(p)*height,
+		   bg, 
+		   fb_info.current_par.lpitch, 
+		   fb_info.current_par.bpp,ROP_COPY);
+}
+static void tdfx_cfbX_revc(struct display *p, int xx, int yy)
+{
+   int bpp=fb_info.current_par.bpp;
+   
+   do_fillrect( xx * fontwidth(p), yy * fontheight(p), 
+	        fontwidth(p), fontheight(p), 
+	        (bpp==8) ? 0x0f : 0xffffffff, 
+	        fb_info.current_par.lpitch, bpp, ROP_XOR);
+   
+}
+static void tdfx_cfbX_cursor(struct display *p, int mode, int x, int y) 
+{
+   unsigned long flags;
+   int tip;
+   struct fb_info_tdfx *info=(struct fb_info_tdfx *)p->fb_info;
+     
+   tip=p->conp->vc_cursor_type & CUR_HWMASK;
+   if (mode==CM_ERASE) {
+	if (info->cursor.state != CM_ERASE) {
+	     spin_lock_irqsave(&info->DAClock,flags);
+	     info->cursor.state=CM_ERASE;
+	     del_timer(&(info->cursor.timer));
+	     tdfx_outl(VIDPROCCFG,info->cursor.disable); 
+	     spin_unlock_irqrestore(&info->DAClock,flags);
+	}
+	return;
+   }
+   if ((p->conp->vc_cursor_type & CUR_HWMASK) != info->cursor.type)
+	 tdfxfb_createcursor(p);
+   x *= fontwidth(p);
+   y *= fontheight(p);
+   y -= p->var.yoffset;
+   spin_lock_irqsave(&info->DAClock,flags);
+   if ((x!=info->cursor.x) ||
+      (y!=info->cursor.y) ||
+      (info->cursor.redraw)) {
+          info->cursor.x=x;
+	  info->cursor.y=y;
+	  info->cursor.redraw=0;
+	  x += 63;
+	  y += 63;    
+          banshee_make_room(2);
+	  tdfx_outl(VIDPROCCFG, info->cursor.disable);
+	  tdfx_outl(HWCURLOC, (y << 16) + x);
+   }
+   info->cursor.state = CM_DRAW;
+   mod_timer(&info->cursor.timer,jiffies+HZ/2);
+   banshee_make_room(1);
+   tdfx_outl(VIDPROCCFG, info->cursor.enable);
+   spin_unlock_irqrestore(&info->DAClock,flags);
+   return;     
+}
 #ifdef FBCON_HAS_CFB8
 static struct display_switch fbcon_banshee8 = {
    fbcon_cfb8_setup, 
-   fbcon_banshee_bmove, 
-   fbcon_banshee_clear, 
-   fbcon_cfb8_putc,
-   fbcon_cfb8_putcs, 
-   fbcon_cfb8_revc, 
+   tdfx_cfbX_bmove, 
+   tdfx_cfb8_clear, 
+   tdfx_cfb8_putc,
+   tdfx_cfb8_putcs, 
+   tdfx_cfbX_revc,   
+   tdfx_cfbX_cursor, 
    NULL, 
-   NULL, 
-   fbcon_cfb8_clear_margins,
+   tdfx_cfbX_clear_margins,
    FONTWIDTH(8)
 };
 #endif
 #ifdef FBCON_HAS_CFB16
 static struct display_switch fbcon_banshee16 = {
    fbcon_cfb16_setup, 
-   fbcon_banshee_bmove, 
-   fbcon_banshee_clear, 
-   fbcon_cfb16_putc,
-   fbcon_cfb16_putcs, 
-   fbcon_cfb16_revc, 
+   tdfx_cfbX_bmove, 
+   tdfx_cfb16_clear, 
+   tdfx_cfb16_putc,
+   tdfx_cfb16_putcs, 
+   tdfx_cfbX_revc, 
+   tdfx_cfbX_cursor, 
    NULL, 
+   tdfx_cfbX_clear_margins,
+   FONTWIDTH(8)
+};
+#endif
+#ifdef FBCON_HAS_CFB24
+static struct display_switch fbcon_banshee24 = {
+   fbcon_cfb24_setup, 
+   tdfx_cfbX_bmove, 
+   tdfx_cfb24_clear, 
+   tdfx_cfb24_putc,
+   tdfx_cfb24_putcs, 
+   tdfx_cfbX_revc, 
+   tdfx_cfbX_cursor, 
    NULL, 
-   fbcon_cfb16_clear_margins,
+   tdfx_cfbX_clear_margins,
    FONTWIDTH(8)
 };
 #endif
 #ifdef FBCON_HAS_CFB32
 static struct display_switch fbcon_banshee32 = {
    fbcon_cfb32_setup, 
-   fbcon_banshee_bmove, 
-   fbcon_banshee_clear, 
-   fbcon_cfb32_putc,
-   fbcon_cfb32_putcs, 
-   fbcon_cfb32_revc, 
-   NULL, 
+   tdfx_cfbX_bmove, 
+   tdfx_cfb32_clear, 
+   tdfx_cfb32_putc,
+   tdfx_cfb32_putcs, 
+   tdfx_cfbX_revc, 
+   tdfx_cfbX_cursor, 
    NULL, 
-   fbcon_cfb32_clear_margins,
+   tdfx_cfbX_clear_margins,
    FONTWIDTH(8)
 };
 #endif
@@ -883,13 +1326,13 @@
 			   struct fb_info_tdfx*     info) {
   struct fb_info_tdfx* i = (struct fb_info_tdfx*)info;
   struct banshee_reg reg;
-  __u32 cpp;
-  __u32 hd, hs, he, ht, hbs, hbe;
-  __u32 vd, vs, ve, vt, vbs, vbe;
-  __u32 wd;
+  u32 cpp;
+  u32 hd, hs, he, ht, hbs, hbe;
+  u32 vd, vs, ve, vt, vbs, vbe;
+  u32 wd;
   int fout;
   int freq;
-
+   
   memset(&reg, 0, sizeof(reg));
 
   cpp = (par->bpp + 7)/8;
@@ -1018,11 +1461,21 @@
   reg.vidcfg = 
     VIDCFG_VIDPROC_ENABLE |
     VIDCFG_DESK_ENABLE    |
+    VIDCFG_CURS_X11 |
     ((cpp - 1) << VIDCFG_PIXFMT_SHIFT) |
     (cpp != 1 ? VIDCFG_CLUT_BYPASS : 0);
+  
+  fb_info.cursor.enable=reg.vidcfg | VIDCFG_HWCURSOR_ENABLE;
+  fb_info.cursor.disable=reg.vidcfg;
+   
   reg.stride    = par->width*cpp;
   reg.cursloc   = 0;
-
+   
+  reg.cursc0    = 0; 
+  reg.cursc1    = 0xffffff;
+   
+  reg.curspataddr = fb_info.cursor.cursorimage;   
+  
   reg.startaddr = par->baseline*reg.stride;
   reg.srcbase   = reg.startaddr;
   reg.dstbase   = reg.startaddr;
@@ -1037,18 +1490,19 @@
     reg.dacmode |= DACMODE_2X;
     reg.vidcfg  |= VIDCFG_2X;
   }
-  reg.vidpll = banshee_calc_pll(freq, &fout);
+  reg.vidpll = do_calc_pll(freq, &fout);
 #if 0
-  reg.mempll = banshee_calc_pll(..., &fout);
-  reg.gfxpll = banshee_calc_pll(..., &fout);
+  reg.mempll = do_calc_pll(..., &fout);
+  reg.gfxpll = do_calc_pll(..., &fout);
 #endif
 
   reg.screensize = par->width | (par->height << 12);
   reg.vidcfg &= ~VIDCFG_HALF_MODE;
 
-  banshee_write_regs(&reg);
+  do_write_regs(&reg);
 
   i->current_par = *par;
+
 }
 
 static int tdfxfb_decode_var(const struct fb_var_screeninfo* var,
@@ -1058,6 +1512,7 @@
 
   if(var->bits_per_pixel != 8  &&
      var->bits_per_pixel != 16 &&
+     var->bits_per_pixel != 24 &&
      var->bits_per_pixel != 32) {
     DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
     return -EINVAL;
@@ -1078,18 +1533,12 @@
     return -EINVAL;
   }
 
-  if(nopan && nowrap) {
-    if(var->yres != var->yres_virtual) {
-      DPRINTK("virtual y resolution != physical y resolution not supported\n");
-      return -EINVAL;
-    }
-  } else {
-    if(var->yres > var->yres_virtual) {
-      DPRINTK("virtual y resolution < physical y resolution not possible\n");
-      return -EINVAL;
-    }
+  if(var->yres > var->yres_virtual) {
+    DPRINTK("virtual y resolution < physical y resolution not possible\n");
+    return -EINVAL;
   }
 
+  /* fixme: does Voodoo3 support interlace? Banshee doesn't */
   if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
     DPRINTK("interlace not supported\n");
     return -EINVAL;
@@ -1106,8 +1555,9 @@
     par->height_virt = var->yres_virtual;
     par->bpp         = var->bits_per_pixel;
     par->ppitch      = var->bits_per_pixel;
-    par->lpitch      = par->width*par->ppitch/8;
-
+    par->lpitch      = par->width* ((par->ppitch+7)>>3);
+    par->cmap_len    = (par->bpp == 8) ? 256 : 16;
+     
     par->baseline = 0;
 
     if(par->width < 320 || par->width > 2048) {
@@ -1190,6 +1640,11 @@
     v.blue.offset  = 0;
     v.blue.length  = 5;
     break;
+  case 24:
+    v.red.offset=16;
+    v.green.offset=8;
+    v.blue.offset=0;
+    v.red.length = v.green.length = v.blue.length = 8;
   case 32:
     v.red.offset   = 16;
     v.green.offset = 8;
@@ -1230,10 +1685,10 @@
   switch(info->dev) {
   case PCI_DEVICE_ID_3DFX_BANSHEE:
   case PCI_DEVICE_ID_3DFX_VOODOO3:
-	if (info->dev == PCI_DEVICE_ID_3DFX_BANSHEE)
-      strcpy(fix->id, "3Dfx Banshee");
-	else
-      strcpy(fix->id, "3Dfx Voodoo3");
+    strcpy(fix->id, 
+	   info->dev == PCI_DEVICE_ID_3DFX_BANSHEE 
+	   ? "3Dfx Banshee"
+	   : "3Dfx Voodoo3");
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
     fix->smem_start  = (char*)info->bufbase_phys;
     fix->smem_len    = info->bufbase_size;
@@ -1249,12 +1704,12 @@
     fix->type        = FB_TYPE_PACKED_PIXELS;
     fix->type_aux    = 0;
     fix->line_length = par->lpitch;
-    fix->visual      = par->bpp == 8 
-      ? FB_VISUAL_PSEUDOCOLOR
-      : FB_VISUAL_DIRECTCOLOR;
+    fix->visual      = (par->bpp == 8) 
+                       ? FB_VISUAL_PSEUDOCOLOR
+                       : FB_VISUAL_DIRECTCOLOR;
 
     fix->xpanstep    = 0; 
-    fix->ypanstep    = (nowrap && nopan) ? 0 : 1;
+    fix->ypanstep    = nopan ? 0 : 1;
     fix->ywrapstep   = nowrap ? 0 : 1;
 
     break;
@@ -1290,19 +1745,20 @@
     *var = fb_display[con].var;
   return 0;
 }
-
+ 
 static void tdfxfb_set_disp(struct display *disp, 
 			    struct fb_info_tdfx *info,
 			    int bpp, 
 			    int accel) {
-  DPRINTK("actually, %s using acceleration!\n", 
-	  noaccel ? "NOT" : "");
 
+  if (disp->dispsw && disp->conp) 
+     fb_con.con_cursor(disp->conp, CM_ERASE);
   switch(bpp) {
 #ifdef FBCON_HAS_CFB8
   case 8:
     info->dispsw = noaccel ? fbcon_cfb8 : fbcon_banshee8;
     disp->dispsw = &info->dispsw;
+    if (nohwcursor) fbcon_banshee8.cursor = NULL;
     break;
 #endif
 #ifdef FBCON_HAS_CFB16
@@ -1310,6 +1766,15 @@
     info->dispsw = noaccel ? fbcon_cfb16 : fbcon_banshee16;
     disp->dispsw = &info->dispsw;
     disp->dispsw_data = info->fbcon_cmap.cfb16;
+    if (nohwcursor) fbcon_banshee16.cursor = NULL;
+    break;
+#endif
+#ifdef FBCON_HAS_CFB24
+  case 24:
+    info->dispsw = noaccel ? fbcon_cfb24 : fbcon_banshee24; 
+    disp->dispsw = &info->dispsw;
+    disp->dispsw_data = info->fbcon_cmap.cfb24;
+    if (nohwcursor) fbcon_banshee24.cursor = NULL;
     break;
 #endif
 #ifdef FBCON_HAS_CFB32
@@ -1317,161 +1782,159 @@
     info->dispsw = noaccel ? fbcon_cfb32 : fbcon_banshee32;
     disp->dispsw = &info->dispsw;
     disp->dispsw_data = info->fbcon_cmap.cfb32;
+    if (nohwcursor) fbcon_banshee32.cursor = NULL;
     break;
 #endif
   default:
     info->dispsw = fbcon_dummy;
     disp->dispsw = &info->dispsw;
   }
+   
 }
 
 static int tdfxfb_set_var(struct fb_var_screeninfo *var, 
 			  int con,
 			  struct fb_info *fb) {
-  struct fb_info_tdfx *info = (struct fb_info_tdfx*)fb;
-  struct tdfxfb_par par;
-  struct display *display;
-  int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, err;
-  int activate = var->activate;
-
-  if(con >= 0)
-    display = &fb_display[con];
-  else
-    display = fb->disp;	/* used during initialization */
-
-  if((err = tdfxfb_decode_var(var, &par, info)))
-    return err;
-
-  tdfxfb_encode_var(var, &par, info);
-
-  if((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
-    oldxres  = display->var.xres;
-    oldyres  = display->var.yres;
-    oldvxres = display->var.xres_virtual;
-    oldvyres = display->var.yres_virtual;
-    oldbpp   = display->var.bits_per_pixel;
-    oldaccel = display->var.accel_flags;
-    display->var = *var;
-    if(con < 0                         ||
-       oldxres  != var->xres           || 
-       oldyres  != var->yres           ||
-       oldvxres != var->xres_virtual   || 
-       oldvyres != var->yres_virtual   ||
-       oldbpp   != var->bits_per_pixel || 
-       oldaccel != var->accel_flags) {
-      struct fb_fix_screeninfo fix;
-
-      tdfxfb_encode_fix(&fix, &par, info);
-      display->screen_base    = (char *)info->bufbase_virt;
-      display->visual         = fix.visual;
-      display->type           = fix.type;
-      display->type_aux       = fix.type_aux;
-      display->ypanstep       = fix.ypanstep;
-      display->ywrapstep      = fix.ywrapstep;
-      display->line_length    = fix.line_length;
-      display->next_line      = fix.line_length;
-      display->can_soft_blank = 1;
-      display->inverse        = inverse;
-      accel = var->accel_flags & FB_ACCELF_TEXT;
-      tdfxfb_set_disp(display, info, par.bpp, accel);
-
-      if(nopan && nowrap) {
-	display->scrollmode = SCROLL_YREDRAW;
-#ifdef FBCON_HAS_CFB8
-	fbcon_banshee8.bmove = fbcon_redraw_bmove;
-#endif
-#ifdef FBCON_HAS_CFB16
-	fbcon_banshee16.bmove = fbcon_redraw_bmove;
-#endif
-#ifdef FBCON_HAS_CFB32
-	fbcon_banshee32.bmove = fbcon_redraw_bmove;
-#endif
+   struct fb_info_tdfx *info = (struct fb_info_tdfx*)fb;
+   struct tdfxfb_par par;
+   struct display *display;
+   int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, err;
+   int activate = var->activate;
+   int j,k;
+   
+   if(con >= 0)
+     display = &fb_display[con];
+   else
+     display = fb->disp;	/* used during initialization */
+   
+   if((err = tdfxfb_decode_var(var, &par, info)))
+     return err;
+   
+   tdfxfb_encode_var(var, &par, info);
+   
+   if((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+      oldxres  = display->var.xres;
+      oldyres  = display->var.yres;
+      oldvxres = display->var.xres_virtual;
+      oldvyres = display->var.yres_virtual;
+      oldbpp   = display->var.bits_per_pixel;
+      oldaccel = display->var.accel_flags;
+      display->var = *var;
+      if(con < 0                         ||
+	 oldxres  != var->xres           || 
+	 oldyres  != var->yres           ||
+	 oldvxres != var->xres_virtual   || 
+	 oldvyres != var->yres_virtual   ||
+	 oldbpp   != var->bits_per_pixel || 
+	 oldaccel != var->accel_flags) {
+	 struct fb_fix_screeninfo fix;
+	 
+	 tdfxfb_encode_fix(&fix, &par, info);
+	 display->screen_base    = (char *)info->bufbase_virt;
+	 display->visual         = fix.visual;
+	 display->type           = fix.type;
+	 display->type_aux       = fix.type_aux;
+	 display->ypanstep       = fix.ypanstep;
+	 display->ywrapstep      = fix.ywrapstep;
+	 display->line_length    = fix.line_length;
+	 display->next_line      = fix.line_length;
+	 display->can_soft_blank = 1;
+	 display->inverse        = inverse;
+	 accel = var->accel_flags & FB_ACCELF_TEXT;
+	 tdfxfb_set_disp(display, info, par.bpp, accel);
+	 
+	 if(nopan) display->scrollmode = SCROLL_YREDRAW;
+	
+	 if (info->fb_info.changevar)
+	   (*info->fb_info.changevar)(con);
       }
-      if (info->fb_info.changevar)
-	(*info->fb_info.changevar)(con);
-    }
-    if(!info->fb_info.display_fg ||
-       info->fb_info.display_fg->vc_num == con ||
-       con < 0)
-      tdfxfb_set_par(&par, info);
-    if(oldbpp != var->bits_per_pixel || con < 0) {
-      if((err = fb_alloc_cmap(&display->cmap, 0, 0)))
-	return err;
-      tdfxfb_install_cmap(con, &info->fb_info);
-    }
-  }
+      if (var->bits_per_pixel==8)
+	for(j = 0; j < 16; j++) {
+	   k = color_table[j];
+	   fb_info.palette[j].red   = default_red[k];
+	   fb_info.palette[j].green = default_grn[k];
+	   fb_info.palette[j].blue  = default_blu[k];
+	}
+      
+      del_timer(&(info->cursor.timer)); 
+      fb_info.cursor.state=CM_ERASE; 
+      if(!info->fb_info.display_fg ||
+	 info->fb_info.display_fg->vc_num == con ||
+	 con < 0)
+	tdfxfb_set_par(&par, info);
+      if (!nohwcursor) 
+	if (display && display->conp)
+	  tdfxfb_createcursor( display );
+      info->cursor.redraw=1;
+      if(oldbpp != var->bits_per_pixel || con < 0) {
+	 if((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+	   return err;
+	 tdfxfb_install_cmap(display, &(info->fb_info));
+      }
+   }
   
-  return 0;
+   return 0;
 }
 
 static int tdfxfb_pan_display(struct fb_var_screeninfo* var, 
 			      int con,
 			      struct fb_info* fb) {
   struct fb_info_tdfx* i = (struct fb_info_tdfx*)fb;
-  __u32 addr;
 
-  if(nowrap && nopan) {
-    return -EINVAL;
-  } else {
-    if(var->xoffset) 
-      return -EINVAL;
-    if(var->yoffset < 0) 
-      return -EINVAL;
-    if(nopan && var->yoffset > var->yres_virtual) 
-      return -EINVAL;
-    if(nowrap && var->yoffset + var->yres > var->yres_virtual) 
-      return -EINVAL;
-    
-    i->current_par.baseline = var->yoffset;
-    
-    addr = var->yoffset*i->current_par.lpitch;
-    tdfx_outl(VIDDESKSTART, addr);
-    tdfx_outl(SRCBASE,      addr);
-    tdfx_outl(DSTBASE,      addr);
-    return 0;
-  }
+  if(nopan)                return -EINVAL;
+  if(var->xoffset)         return -EINVAL;
+  if(var->yoffset > var->yres_virtual)   return -EINVAL;
+  if(nowrap && 
+     (var->yoffset + var->yres > var->yres_virtual)) return -EINVAL;
+ 
+  if (con==currcon)
+    do_pan_var(var,i);
+   
+  fb_display[con].var.xoffset=var->xoffset;
+  fb_display[con].var.yoffset=var->yoffset; 
+  return 0;
 }
 
 static int tdfxfb_get_cmap(struct fb_cmap *cmap, 
 			   int kspc, 
 			   int con,
 			   struct fb_info *fb) {
-  if(!fb->display_fg || con == fb->display_fg->vc_num) {
-    /* current console? */
-    return fb_get_cmap(cmap, kspc, tdfxfb_getcolreg, fb);
-  } else if(fb_display[con].cmap.len) {
-    /* non default colormap? */
-    fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-  } else {
-    int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
-    fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
-  }
-  return 0;
+
+   struct fb_info_tdfx* i = (struct fb_info_tdfx*)fb;
+   struct display *d=(con<0) ? fb->disp : fb_display + con;
+   
+   if(con == currcon) {
+      /* current console? */
+      return fb_get_cmap(cmap, kspc, tdfxfb_getcolreg, fb);
+   } else if(d->cmap.len) {
+      /* non default colormap? */
+      fb_copy_cmap(&d->cmap, cmap, kspc ? 0 : 2);
+   } else {
+      fb_copy_cmap(fb_default_cmap(i->current_par.cmap_len), cmap, kspc ? 0 : 2);
+   }
+   return 0;
 }
 
 static int tdfxfb_set_cmap(struct fb_cmap *cmap, 
 			   int kspc, 
 			   int con,
 			   struct fb_info *fb) {
-  int err;
-  struct display *disp;
+   struct display *d=(con<0) ? fb->disp : fb_display + con;
+   struct fb_info_tdfx *i = (struct fb_info_tdfx*)fb;
 
-  if(con >= 0)
-    disp = &fb_display[con];
-  else
-    disp = fb->disp;
-  if(!disp->cmap.len) {	/* no colormap allocated? */
-    int size = disp->var.bits_per_pixel == 16 ? 32 : 256;
-    if((err = fb_alloc_cmap(&disp->cmap, size, 0)))
-      return err;
-  }
-  if(!fb->display_fg || con == fb->display_fg->vc_num) {
-    /* current console? */
-    return fb_set_cmap(cmap, kspc, tdfxfb_setcolreg, fb);
-  } else {
-    fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
-  }
-  return 0;
+   int cmap_len= (i->current_par.bpp == 8) ? 256 : 16;
+   if (d->cmap.len!=cmap_len) {
+      int err;
+      if((err = fb_alloc_cmap(&d->cmap, cmap_len, 0)))
+	return err;
+   }
+   if(con == currcon) {
+      /* current console? */
+      return fb_set_cmap(cmap, kspc, tdfxfb_setcolreg, fb);
+   } else {
+      fb_copy_cmap(cmap, &d->cmap, kspc ? 0 : 1);
+   }
+   return 0;
 }
 
 static int tdfxfb_ioctl(struct inode *inode, 
@@ -1480,7 +1943,16 @@
 			u_long arg, 
 			int con, 
 			struct fb_info *fb) {
-  return -EINVAL;
+/* These IOCTLs ar just for testing only... 
+   switch (cmd) {
+    case 0x4680: 
+      nowrap=nopan=0;
+      return 0;
+    case 0x4681:
+      nowrap=nopan=1;
+      return 0;
+   }*/
+   return -EINVAL;
 }
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
@@ -1490,8 +1962,7 @@
 #endif
   struct pci_dev *pdev = NULL;
   struct fb_var_screeninfo var;
-  int j, k;
-
+  
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
   if(!pcibios_present()) return;
 #else
@@ -1503,7 +1974,10 @@
        (pdev->vendor == PCI_VENDOR_ID_3DFX) &&
        ((pdev->device == PCI_DEVICE_ID_3DFX_BANSHEE) ||
 	(pdev->device == PCI_DEVICE_ID_3DFX_VOODOO3))) {
-      
+      char* name = pdev->device == PCI_DEVICE_ID_3DFX_BANSHEE
+	? "Banshee"
+	: "Voodoo3";
+
       fb_info.dev   = pdev->device;
       fb_info.max_pixclock = 
 	pdev->device == PCI_DEVICE_ID_3DFX_BANSHEE 
@@ -1512,82 +1986,79 @@
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
       fb_info.regbase_phys = pdev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK;
-      fb_info.regbase_size = 1 << 25;
+      fb_info.regbase_size = 1 << 24;
       fb_info.regbase_virt = 
-	(__u32)ioremap_nocache(fb_info.regbase_phys, 1 << 25);
+	(u32)ioremap_nocache(fb_info.regbase_phys, 1 << 24);
       if(!fb_info.regbase_virt) {
-	if (fb_info.dev == PCI_DEVICE_ID_3DFX_BANSHEE)
-	  printk("fb: Can't remap Banshee register area.\n");
-	else
-	  printk("fb: Can't remap Voodoo3 register area.\n");
+	printk("fb: Can't remap %s register area.\n", name);
 	return;
       }
 
       fb_info.bufbase_phys = pdev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK;
-      if(!(fb_info.bufbase_size = tdfx_lfb_size())) {
-	if (fb_info.dev == PCI_DEVICE_ID_3DFX_BANSHEE)
-	  printk("fb: Can't count Banshee memory.\n");
-	else
-	  printk("fb: Can't count Voodoo3 memory.\n");
+      if(!(fb_info.bufbase_size = do_lfb_size())) {
+	printk("fb: Can't count %s memory.\n", name);
 	iounmap((void*)fb_info.regbase_virt);
 	return;
       }
       fb_info.bufbase_virt    = 
-	(__u32)ioremap_nocache(fb_info.bufbase_phys, 1 << 25);
+	(u32)ioremap_nocache(fb_info.bufbase_phys, fb_info.bufbase_size);
       if(!fb_info.regbase_virt) {
-	if (fb_info.dev == PCI_DEVICE_ID_3DFX_BANSHEE)
-      printk("fb: Can't remap Banshee framebuffer.\n");
-	else
-      printk("fb: Can't remap Voodoo3 framebuffer.\n");
+	printk("fb: Can't remap %s framebuffer.\n", name);
 	iounmap((void*)fb_info.regbase_virt);
 	return;
       }
+
+      fb_info.iobase = pdev->base_address[2] & PCI_BASE_ADDRESS_IO_MASK;
 #else
       fb_info.regbase_phys = pdev->resource[0].start;
-      fb_info.regbase_size = 1 << 25;
+      fb_info.regbase_size = 1 << 24;
       fb_info.regbase_virt = 
-	(__u32)ioremap_nocache(fb_info.regbase_phys, 1 << 25);
+	(u32)ioremap_nocache(fb_info.regbase_phys, 1 << 24);
       if(!fb_info.regbase_virt) {
-	if (fb_info.dev == PCI_DEVICE_ID_3DFX_BANSHEE)
-	  printk("fb: Can't remap Banshee register area.\n");
-	else
-	  printk("fb: Can't remap Voodoo3 register area.\n");
+	printk("fb: Can't remap %s register area.\n", name);
 	return -ENXIO;
       }
       
       fb_info.bufbase_phys = pdev->resource[1].start;
-      if(!(fb_info.bufbase_size = tdfx_lfb_size())) {
+      if(!(fb_info.bufbase_size = do_lfb_size())) {
 	iounmap((void*)fb_info.regbase_virt);
-	if (fb_info.dev == PCI_DEVICE_ID_3DFX_BANSHEE)
-	  printk("fb: Can't count Banshee memory.\n");
-	else
-	  printk("fb: Can't count Voodoo3 memory.\n");
+	printk("fb: Can't count %s memory.\n", name);
 	return -ENXIO;
       }
       fb_info.bufbase_virt    = 
-	(__u32)ioremap_nocache(fb_info.bufbase_phys, 1 << 25);
+	(u32)ioremap_nocache(fb_info.bufbase_phys, fb_info.bufbase_size);
       if(!fb_info.regbase_virt) {
-	if (fb_info.dev == PCI_DEVICE_ID_3DFX_BANSHEE)
-	  printk("fb: Can't remap Banshee framebuffer.\n");
-	else
-	  printk("fb: Can't remap Voodoo3 framebuffer.\n");
+	printk("fb: Can't remap %s framebuffer.\n", name);
 	iounmap((void*)fb_info.regbase_virt);
 	return -ENXIO;
       }
+
+      fb_info.iobase = pdev->resource[2].start;
 #endif
       
-	if (fb_info.dev == PCI_DEVICE_ID_3DFX_BANSHEE)
-      printk("fb: Banshee memory = %ldK\n", fb_info.bufbase_size >> 10);
-	else
-      printk("fb: Voodoo3 memory = %ldK\n", fb_info.bufbase_size >> 10);
-      
+      printk("fb: %s memory = %ldK\n", name, fb_info.bufbase_size >> 10);
+
+#ifdef CONFIG_MTRR
+       if (!nomtrr) {
+	  if (mtrr_add(fb_info.bufbase_phys, fb_info.bufbase_size, 
+		       MTRR_TYPE_WRCOMB, 1)>=0)
+	    printk("fb: MTRR's  turned on\n");
+       }
+#endif	  	 
+
       /* clear framebuffer memory */
       memset_io(fb_info.bufbase_virt, 0, fb_info.bufbase_size);
-      
-	  if (fb_info.dev == PCI_DEVICE_ID_3DFX_BANSHEE)
-        strcpy(fb_info.fb_info.modename, "3Dfx Banshee");
-	  else
-        strcpy(fb_info.fb_info.modename, "3Dfx Voodoo3");
+      currcon = -1;
+      if (!nohwcursor) tdfxfb_hwcursor_init();
+       
+      fb_info.cursor.timer.function = do_flashcursor; 
+      fb_info.cursor.state = CM_ERASE;
+      fb_info.cursor.timer.prev = fb_info.cursor.timer.next=NULL;
+      fb_info.cursor.timer.data = (unsigned long)(&fb_info);
+      spin_lock_init(&fb_info.DAClock);
+       
+      strcpy(fb_info.fb_info.modename, "3Dfx "); 
+      strcat(fb_info.fb_info.modename, name);
       fb_info.fb_info.changevar  = NULL;
       fb_info.fb_info.node       = -1;
       fb_info.fb_info.fbops      = &tdfxfb_ops;
@@ -1624,6 +2095,7 @@
 	else var.accel_flags |= FB_ACCELF_TEXT;
       
 	if(tdfxfb_decode_var(&var, &fb_info.default_par, &fb_info)) {
+	  /* this is getting really bad!... */
 	  printk("tdfxfb: can't decode default video mode\n");
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
 	  return;
@@ -1634,33 +2106,7 @@
       }
       
       fb_info.disp.screen_base    = (void*)fb_info.bufbase_virt;
-      fb_info.disp.visual         = 
-	var.bits_per_pixel == 8 
-	? FB_VISUAL_PSEUDOCOLOR
-	: FB_VISUAL_DIRECTCOLOR;
-      fb_info.disp.type           = FB_TYPE_PACKED_PIXELS;
-      fb_info.disp.type_aux       = 0;
-      
-      fb_info.disp.ypanstep       = (nowrap && nopan) ? 0 : 1;
-      fb_info.disp.ywrapstep      = nowrap ? 0 : 1;
-      
-      fb_info.disp.line_length    = 
-	fb_info.disp.next_line    = 	  
-	var.xres*(var.bits_per_pixel + 7)/8;
-      fb_info.disp.can_soft_blank = 1;
-      fb_info.disp.inverse        = inverse;
-      fb_info.disp.scrollmode     = SCROLL_YREDRAW;
       fb_info.disp.var            = var;
-      tdfxfb_set_disp(&fb_info.disp, &fb_info, 
-		      var.bits_per_pixel, 
-		      0);
-      
-      for(j = 0; j < 16; j++) {
-	k = color_table[j];
-	fb_info.palette[j].red   = default_red[k];
-	fb_info.palette[j].green = default_grn[k];
-	fb_info.palette[j].blue  = default_blu[k];
-      }
       
       if(tdfxfb_set_var(&var, -1, &fb_info.fb_info)) {
 	printk("tdfxfb: can't set default video mode\n");
@@ -1694,6 +2140,7 @@
     }
   }
 
+  /* hmm, no frame suitable buffer found ... */
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,1)
   return;
 #else
@@ -1715,11 +2162,17 @@
       inverse = 1;
       fb_invert_cmaps();
     } else if(!strcmp(this_opt, "noaccel")) {
-      noaccel = 1;
+      noaccel = nopan = nowrap = nohwcursor = 1; 
     } else if(!strcmp(this_opt, "nopan")) {
       nopan = 1;
     } else if(!strcmp(this_opt, "nowrap")) {
       nowrap = 1;
+    } else if (!strcmp(this_opt, "nohwcursor")) {
+      nohwcursor = 1;
+#ifdef CONFIG_MTRR
+    } else if (!strcmp(this_opt, "nomtrr")) {
+      nomtrr = 1;
+#endif
     } else if (!strncmp(this_opt, "font:", 5)) {
       strncpy(fontname, this_opt + 5, 40);
     } else {
@@ -1739,26 +2192,39 @@
 
 static int tdfxfb_switch_con(int con, 
 			     struct fb_info *fb) {
-  struct fb_info_tdfx *info = (struct fb_info_tdfx*)fb;
-  struct tdfxfb_par par;
-
-  /* Do we have to save the colormap? */
-  if(fb_display[currcon].cmap.len)
-    fb_get_cmap(&fb_display[currcon].cmap, 1, tdfxfb_getcolreg, fb);
-
-  currcon = con;
-
-  tdfxfb_decode_var(&fb_display[con].var, &par, info);
-  tdfxfb_set_par(&par, info);
-  tdfxfb_set_disp(&fb_display[con], 
-		  info, 
-		  par.bpp,
-		  par.accel_flags & FB_ACCELF_TEXT);
+   struct fb_info_tdfx *info = (struct fb_info_tdfx*)fb;
+   struct tdfxfb_par par;
 
-  tdfxfb_install_cmap(con, fb);
-  tdfxfb_updatevar(con, fb);
-
-  return 1;
+   /* Do we have to save the colormap? */
+   if (currcon>=0)
+     if(fb_display[currcon].cmap.len)
+       fb_get_cmap(&fb_display[currcon].cmap, 1, tdfxfb_getcolreg, fb);
+   
+   currcon = con;
+   fb_display[currcon].var.activate = FB_ACTIVATE_NOW; 
+   tdfxfb_decode_var(&fb_display[con].var, &par, info);
+   tdfxfb_set_par(&par, info);
+   if (fb_display[con].dispsw && fb_display[con].conp)
+     fb_con.con_cursor(fb_display[con].conp, CM_ERASE);
+   
+   del_timer(&(info->cursor.timer));
+   fb_info.cursor.state=CM_ERASE; 
+   
+   if (!nohwcursor) 
+     if (fb_display[con].conp)
+       tdfxfb_createcursor( &fb_display[con] );
+   
+   info->cursor.redraw=1;
+   
+   tdfxfb_set_disp(&fb_display[con], 
+		   info, 
+		   par.bpp,
+		   par.accel_flags & FB_ACCELF_TEXT);
+   
+   tdfxfb_install_cmap(&fb_display[con], fb);
+   tdfxfb_updatevar(con, fb);
+   
+   return 1;
 }
 
 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
@@ -1793,6 +2259,7 @@
 
   dacmode &= ~(BIT(1) | BIT(3));
   dacmode |= state;
+  banshee_make_room(1); 
   tdfx_outl(DACMODE, dacmode);
   if(vgablank) 
     vga_disable_video();
@@ -1804,12 +2271,11 @@
 
 static int  tdfxfb_updatevar(int con, 
 			     struct fb_info* fb) {
-  if(con != currcon || (nowrap && nopan)) { 
-    return 0;
-  } else {
-    struct fb_var_screeninfo* var = &fb_display[currcon].var;
-    return tdfxfb_pan_display(var, con, fb);
-  }
+
+   struct fb_info_tdfx* i = (struct fb_info_tdfx*)fb;
+   if ((con==currcon) && (!nopan)) 
+     do_pan_var(&fb_display[con].var,i);
+   return 0;
 }
 
 static int tdfxfb_getcolreg(unsigned        regno, 
@@ -1818,15 +2284,16 @@
 			    unsigned*       blue, 
 			    unsigned*       transp,
 			    struct fb_info* fb) {
-  struct fb_info_tdfx* i = (struct fb_info_tdfx*)fb;
+   struct fb_info_tdfx* i = (struct fb_info_tdfx*)fb;
 
-  if(regno < 256) {
-    *red    = i->palette[regno].red   << 8 | i->palette[regno].red;
-    *green  = i->palette[regno].green << 8 | i->palette[regno].green;
-    *blue   = i->palette[regno].blue  << 8 | i->palette[regno].blue;
-    *transp = 0;
-  }
-  return regno > 255;
+   if (regno > i->current_par.cmap_len) return 1;
+   
+   *red    = i->palette[regno].red; 
+   *green  = i->palette[regno].green; 
+   *blue   = i->palette[regno].blue; 
+   *transp = 0;
+   
+   return 0;
 }
 
 static int tdfxfb_setcolreg(unsigned        regno, 
@@ -1835,12 +2302,21 @@
 			    unsigned        blue, 
 			    unsigned        transp,
 			    struct fb_info* info) {
-  struct fb_info_tdfx* i = (struct fb_info_tdfx*)info;
-
-  if(regno < 16) {
-    switch(i->current_par.bpp) {
+   struct fb_info_tdfx* i = (struct fb_info_tdfx*)info;
+   u32 rgbcol;
+   if (regno >= i->current_par.cmap_len) return 1;
+   
+   i->palette[regno].red    = red;
+   i->palette[regno].green  = green;
+   i->palette[regno].blue   = blue;
+   
+   switch(i->current_par.bpp) {
 #ifdef FBCON_HAS_CFB8
     case 8:
+      rgbcol=(((u32)red   & 0xff00) << 8) |
+	(((u32)green & 0xff00) << 0) |
+	(((u32)blue  & 0xff00) >> 8);
+      do_setpalentry(regno,rgbcol);
       break;
 #endif
 #ifdef FBCON_HAS_CFB16
@@ -1849,6 +2325,14 @@
 	(((u32)red   & 0xf800) >> 0) |
 	(((u32)green & 0xfc00) >> 5) |
 	(((u32)blue  & 0xf800) >> 11);
+	 break;
+#endif
+#ifdef FBCON_HAS_CFB24
+    case 24:
+      i->fbcon_cmap.cfb24[regno] =
+	(((u32)red & 0xff00) << 8) |
+	(((u32)green & 0xff00) << 0) |
+	(((u32)blue & 0xff00) >> 8);
       break;
 #endif
 #ifdef FBCON_HAS_CFB32
@@ -1862,30 +2346,105 @@
     default:
       DPRINTK("bad depth %u\n", i->current_par.bpp);
       break;
-    }
-  }
-  if(regno < 256) {
-    i->palette[regno].red    = red   >> 8;
-    i->palette[regno].green  = green >> 8;
-    i->palette[regno].blue   = blue  >> 8;
-    if(i->current_par.bpp == 8) {
-      vga_outb(DAC_IW, (unsigned char)regno);
-      vga_outb(DAC_D,  (unsigned char)(red   >> 8));
-      vga_outb(DAC_D,  (unsigned char)(green >> 8));
-      vga_outb(DAC_D,  (unsigned char)(blue  >> 8));
-    }
-  }
-  return regno > 255;
+   }
+   return 0;
 }
 
-static void tdfxfb_install_cmap(int             con, 
-				struct fb_info* info) {
-  if(con != currcon) return;
-  if(fb_display[con].cmap.len) {
-    fb_set_cmap(&fb_display[con].cmap, 1, tdfxfb_setcolreg, info);
-  } else {
-    int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
-    fb_set_cmap(fb_default_cmap(size), 1, tdfxfb_setcolreg, info);
-  }
+static void tdfxfb_install_cmap(struct display *d,struct fb_info *info) 
+{
+   struct fb_info_tdfx* i = (struct fb_info_tdfx*)info;
+
+   if(d->cmap.len) {
+      fb_set_cmap(&(d->cmap), 1, tdfxfb_setcolreg, info);
+   } else {
+      fb_set_cmap(fb_default_cmap(i->current_par.cmap_len), 1, 
+		  tdfxfb_setcolreg, info);
+   }
+}
+
+static void tdfxfb_createcursorshape(struct display* p) 
+{
+   unsigned int h,cu,cd;
+   
+   h=fontheight(p);
+   cd=h;
+   if (cd >= 10) cd --; 
+   fb_info.cursor.type=p->conp->vc_cursor_type & CUR_HWMASK;
+   switch (fb_info.cursor.type) {
+      case CUR_NONE: 
+	cu=cd; 
+	break;
+      case CUR_UNDERLINE: 
+	cu=cd - 2; 
+	break;
+      case CUR_LOWER_THIRD: 
+	cu=(h * 2) / 3; 
+	break;
+      case CUR_LOWER_HALF: 
+	cu=h / 2; 
+	break;
+      case CUR_TWO_THIRDS: 
+	cu=h / 3; 
+	break;
+      case CUR_BLOCK:
+      default:
+	cu=0;
+	cd = h;
+	break;
+   }
+   fb_info.cursor.w=fontwidth(p);
+   fb_info.cursor.u=cu;
+   fb_info.cursor.d=cd;
+}
+   
+static void tdfxfb_createcursor(struct display *p)
+{
+   u8 *cursorbase;
+   u32 xline;
+   unsigned int i;
+   unsigned int h,to;
+
+   tdfxfb_createcursorshape(p);
+   xline = (1 << fb_info.cursor.w)-1;
+   cursorbase=(u8*)fb_info.bufbase_virt;
+   h=fb_info.cursor.cursorimage;     
+   
+   to=fb_info.cursor.u;
+   for (i = 0; i < to; i++) {
+	writel(0, cursorbase+h);
+	writel(0, cursorbase+h+4);
+	writel(~0, cursorbase+h+8);
+	writel(~0, cursorbase+h+12);
+	h += 16;
+   }
+   
+   to = fb_info.cursor.d;
+   
+   for (; i < to; i++) {
+	writel(xline, cursorbase+h);
+	writel(0, cursorbase+h+4);
+	writel(~0, cursorbase+h+8);
+	writel(~0, cursorbase+h+12);
+	h += 16;
+   }
+   
+   for (; i < 64; i++) {
+	writel(0, cursorbase+h);
+	writel(0, cursorbase+h+4);
+	writel(~0, cursorbase+h+8);
+	writel(~0, cursorbase+h+12);
+	h += 16;
+   }
+}
+   
+static void tdfxfb_hwcursor_init(void)
+{
+   unsigned int start;
+   start = (fb_info.bufbase_size-1024) & PAGE_MASK;
+   fb_info.bufbase_size=start; 
+   fb_info.cursor.cursorimage=fb_info.bufbase_size;
+   printk("tdfxfb: reserving 1024 bytes for the hwcursor at 0x%08lx\n",
+	  fb_info.regbase_virt+fb_info.cursor.cursorimage);
 }
 
+ 
diff -u --recursive --new-file v2.3.25/linux/fs/Config.in linux/fs/Config.in
--- v2.3.25/linux/fs/Config.in	Mon Nov  1 13:56:27 1999
+++ linux/fs/Config.in	Wed Nov  3 14:43:54 1999
@@ -14,6 +14,12 @@
 tristate 'Amiga FFS filesystem support' CONFIG_AFFS_FS
 tristate 'Apple Macintosh filesystem support (EXPERIMENTAL)' CONFIG_HFS_FS
 # msdos filesystems
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   tristate 'BFS filesystem (read only) support (EXPERIMENTAL)' CONFIG_BFS_FS
+   if [ "$CONFIG_BFS_FS" != "n" ]; then
+      bool '  BFS filesystem write support (DANGEROUS)' CONFIG_BFS_FS_WRITE
+   fi
+fi
 tristate 'DOS FAT fs support' CONFIG_FAT_FS
 dep_tristate '  MSDOS fs support' CONFIG_MSDOS_FS $CONFIG_FAT_FS
 dep_tristate '  UMSDOS: Unix-like filesystem on top of standard MSDOS filesystem' CONFIG_UMSDOS_FS $CONFIG_MSDOS_FS
@@ -58,12 +64,6 @@
 fi
 tristate 'ROM filesystem support' CONFIG_ROMFS_FS
 tristate 'Second extended fs support' CONFIG_EXT2_FS
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-   tristate 'BFS filesystem (read only) support (EXPERIMENTAL)' CONFIG_BFS_FS
-   if [ "$CONFIG_BFS_FS" != "n" ]; then
-      bool '  BFS filesystem write support (DANGEROUS)' CONFIG_BFS_FS_WRITE
-   fi
-fi
 tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS
 if [ "$CONFIG_SYSV_FS" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
    bool '  SYSV filesystem write support (DANGEROUS)' CONFIG_SYSV_FS_WRITE
@@ -90,15 +90,15 @@
       bool '  Emulate SUN NFS server' CONFIG_NFSD_SUN
    fi
    if [ "$CONFIG_NFS_FS" = "y" -o "$CONFIG_NFSD" = "y" ]; then
-      define_bool CONFIG_SUNRPC y
-      define_bool CONFIG_LOCKD y
+      define_tristate CONFIG_SUNRPC y
+      define_tristate CONFIG_LOCKD y
    else
       if [ "$CONFIG_NFS_FS" = "m" -o "$CONFIG_NFSD" = "m" ]; then
-	 define_bool CONFIG_SUNRPC m
-	 define_bool CONFIG_LOCKD m
+	 define_tristate CONFIG_SUNRPC m
+	 define_tristate CONFIG_LOCKD m
    else
-	 define_bool CONFIG_SUNRPC n
-	 define_bool CONFIG_LOCKD n
+	 define_tristate CONFIG_SUNRPC n
+	 define_tristate CONFIG_LOCKD n
       fi
    fi
    tristate 'SMB filesystem support (to mount WfW shares etc.)' CONFIG_SMB_FS
diff -u --recursive --new-file v2.3.25/linux/fs/adfs/inode.c linux/fs/adfs/inode.c
--- v2.3.25/linux/fs/adfs/inode.c	Fri Mar 26 13:57:41 1999
+++ linux/fs/adfs/inode.c	Sat Nov  6 09:51:19 1999
@@ -181,7 +181,7 @@
 		inode->i_nlink	 = 2;
 		inode->i_size	 = ADFS_NEWDIR_SIZE;
 		inode->i_blksize = PAGE_SIZE;
-		inode->i_blocks  = inode->i_size / sb->s_blocksize;
+		inode->i_blocks  = inode->i_size >> sb->s_blocksize_bits;
 		inode->i_mtime   =
 		inode->i_atime   =
 		inode->i_ctime   = 0;
diff -u --recursive --new-file v2.3.25/linux/fs/bfs/bfs_defs.h linux/fs/bfs/bfs_defs.h
--- v2.3.25/linux/fs/bfs/bfs_defs.h	Mon Nov  1 13:56:27 1999
+++ linux/fs/bfs/bfs_defs.h	Fri Nov  5 10:30:13 1999
@@ -5,6 +5,7 @@
 #define su_lf_ioff	u.bfs_sb.si_lf_ioff
 #define su_lf_sblk	u.bfs_sb.si_lf_sblk
 #define su_lf_eblk	u.bfs_sb.si_lf_eblk
+#define su_bmap		u.bfs_sb.si_bmap
 #define su_imap		u.bfs_sb.si_imap
 #define su_sbh		u.bfs_sb.si_sbh
 #define su_bfs_sb	u.bfs_sb.si_bfs_sb
diff -u --recursive --new-file v2.3.25/linux/fs/bfs/dir.c linux/fs/bfs/dir.c
--- v2.3.25/linux/fs/bfs/dir.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/bfs/dir.c	Tue Nov  2 08:23:10 1999
@@ -51,7 +51,7 @@
 
 	while (f->f_pos < dir->i_size) {
 		offset = f->f_pos & (BFS_BSIZE-1);
-		block = dir->iu_sblock + f->f_pos/BFS_BSIZE;
+		block = dir->iu_sblock + (f->f_pos >> BFS_BSIZE_BITS);
 		bh = bread(dev, block, BFS_BSIZE);
 		if (!bh) {
 			f->f_pos += BFS_BSIZE - offset;
diff -u --recursive --new-file v2.3.25/linux/fs/bfs/file.c linux/fs/bfs/file.c
--- v2.3.25/linux/fs/bfs/file.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/bfs/file.c	Fri Nov  5 10:30:13 1999
@@ -41,14 +41,14 @@
 static int bfs_get_block(struct inode * inode, long block, 
 	struct buffer_head * bh_result, int create)
 {
-	if (!create) {
+	long phys = inode->iu_sblock + block;
+	if (!create || phys <= inode->iu_eblock) {
 		bh_result->b_dev = inode->i_dev;
-		bh_result->b_blocknr = inode->iu_sblock + block;
+		bh_result->b_blocknr = phys;
 		bh_result->b_state |= (1UL << BH_Mapped);
 		return 0;
-	} else 
-		DBG(KERN_ERR "BFS-fs: %s(create=%d) impossible!\n", 
-			__FUNCTION__, create);
+	} 
+	/* no support for file migration, working on it */
 	return -EIO;
 }
 
diff -u --recursive --new-file v2.3.25/linux/fs/bfs/inode.c linux/fs/bfs/inode.c
--- v2.3.25/linux/fs/bfs/inode.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/bfs/inode.c	Fri Nov  5 10:30:13 1999
@@ -196,6 +196,7 @@
 {
 	brelse(s->su_sbh);
 	kfree(s->su_imap);
+	kfree(s->su_bmap);
 	MOD_DEC_USE_COUNT;
 }
 
@@ -243,7 +244,6 @@
 
 	if (!tmpbuf)
 		return;
-	memset(tmpbuf, 0, 400);
 	for (i=s->su_lasti; i>=0; i--) {
 		if (i>PAGE_SIZE-100) break;
 		if (test_bit(i, s->su_imap))
@@ -295,24 +295,33 @@
 	s->su_lasti = (bfs_sb->s_start - BFS_BSIZE)/sizeof(struct bfs_inode) 
 			+ BFS_ROOT_INO - 1;
 
+	s->su_bmap = kmalloc(sizeof(struct bfs_bmap) * s->su_lasti, GFP_KERNEL);
+	if (!s->su_bmap)
+		goto out;
 	imap_len = s->su_lasti/8 + 1;
 	s->su_imap = kmalloc(imap_len, GFP_KERNEL);
-	if (!s->su_imap)
+	if (!s->su_imap) {
+		kfree(s->su_bmap);
 		goto out;
+	}
 	memset(s->su_imap, 0, imap_len);
-	for (i=0; i<BFS_ROOT_INO; i++)
+	for (i=0; i<BFS_ROOT_INO; i++) {
+		s->su_bmap[i].start = s->su_bmap[i].end = 0;
 		set_bit(i, s->su_imap);
+	}
 
 	s->s_op = &bfs_sops;
 	inode = iget(s, BFS_ROOT_INO);
 	if (!inode) {
 		kfree(s->su_imap);
+		kfree(s->su_bmap);
 		goto out;
 	}
 	s->s_root = d_alloc_root(inode);
 	if (!s->s_root) {
 		iput(inode);
 		kfree(s->su_imap);
+		kfree(s->su_bmap);
 		goto out;
 	}
 
@@ -324,9 +333,10 @@
 	s->su_lf_ioff = 0;
 	for (i=BFS_ROOT_INO; i<=s->su_lasti; i++) {
 		inode = iget(s,i);
-		if (inode->iu_dsk_ino == 0)
+		if (inode->iu_dsk_ino == 0) {
 			s->su_freei++;
-		else {
+			s->su_bmap[i].start = s->su_bmap[i].end = 0;
+		} else {
 			set_bit(i, s->su_imap);
 			s->su_freeb -= inode->i_blocks;
 			if (inode->iu_eblock > s->su_lf_eblk) {
@@ -334,6 +344,8 @@
 				s->su_lf_sblk = inode->iu_sblock;
 				s->su_lf_ioff = BFS_INO2OFF(i);
 			}
+			s->su_bmap[i].start = inode->iu_sblock;
+			s->su_bmap[i].end = inode->iu_eblock;
 		}
 		iput(inode);
 	}
diff -u --recursive --new-file v2.3.25/linux/fs/buffer.c linux/fs/buffer.c
--- v2.3.25/linux/fs/buffer.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/buffer.c	Thu Nov  4 19:36:33 1999
@@ -34,7 +34,6 @@
 #include <linux/locks.h>
 #include <linux/errno.h>
 #include <linux/swap.h>
-#include <linux/swapctl.h>
 #include <linux/smp_lock.h>
 #include <linux/vmalloc.h>
 #include <linux/blkdev.h>
@@ -43,6 +42,7 @@
 #include <linux/init.h>
 #include <linux/quotaops.h>
 #include <linux/iobuf.h>
+#include <linux/highmem.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
diff -u --recursive --new-file v2.3.25/linux/fs/dcache.c linux/fs/dcache.c
--- v2.3.25/linux/fs/dcache.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/dcache.c	Tue Nov  2 21:36:18 1999
@@ -214,7 +214,8 @@
 	dentry_iput(dentry);
 	parent = dentry->d_parent;
 	d_free(dentry);
-	dput(parent);
+	if (parent != dentry)
+		dput(parent);
 }
 
 /*
diff -u --recursive --new-file v2.3.25/linux/fs/ext2/file.c linux/fs/ext2/file.c
--- v2.3.25/linux/fs/ext2/file.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ext2/file.c	Fri Nov  5 09:57:30 1999
@@ -32,8 +32,7 @@
 static long long ext2_file_lseek(struct file *, long long, int);
 #if BITS_PER_LONG < 64
 static int ext2_open_file (struct inode *, struct file *);
-
-#else
+#endif
 
 #define EXT2_MAX_SIZE(bits)							\
 	(((EXT2_NDIR_BLOCKS + (1LL << (bits - 2)) + 				\
@@ -46,9 +45,6 @@
 EXT2_MAX_SIZE(10), EXT2_MAX_SIZE(11), EXT2_MAX_SIZE(12), EXT2_MAX_SIZE(13)
 };
 
-#endif
-
-
 /*
  * Make sure the offset never goes beyond the 32-bit mark..
  */
@@ -67,12 +63,8 @@
 			offset += file->f_pos;
 	}
 	if (((unsigned long long) offset >> 32) != 0) {
-#if BITS_PER_LONG < 64
-		return -EINVAL;
-#else
 		if (offset > ext2_max_sizes[EXT2_BLOCK_SIZE_BITS(inode->i_sb)])
 			return -EINVAL;
-#endif
 	} 
 	if (offset != file->f_pos) {
 		file->f_pos = offset;
@@ -131,11 +123,12 @@
 #if BITS_PER_LONG < 64
 /*
  * Called when an inode is about to be open.
- * We use this to disallow opening RW large files on 32bit systems.
+ * We use this to disallow opening RW large files on 32bit systems if
+ * the caller didn't specify O_LARGEFILE.
  */
 static int ext2_open_file (struct inode * inode, struct file * filp)
 {
-	if (inode->u.ext2_i.i_high_size && (filp->f_mode & FMODE_WRITE))
+	if (inode->u.ext2_i.i_high_size && !(filp->f_flags & O_LARGEFILE))
 		return -EFBIG;
 	return 0;
 }
diff -u --recursive --new-file v2.3.25/linux/fs/ext2/inode.c linux/fs/ext2/inode.c
--- v2.3.25/linux/fs/ext2/inode.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ext2/inode.c	Fri Nov  5 09:57:30 1999
@@ -687,15 +687,8 @@
 		inode->u.ext2_i.i_dir_acl = le32_to_cpu(raw_inode->i_dir_acl);
 	else {
 		inode->u.ext2_i.i_dir_acl = 0;
-		inode->u.ext2_i.i_high_size =
-			le32_to_cpu(raw_inode->i_size_high);
-#if BITS_PER_LONG < 64
-		if (raw_inode->i_size_high)
-			inode->i_size = (__u32)-1;
-#else
-		inode->i_size |= ((__u64)le32_to_cpu(raw_inode->i_size_high))
-			<< 32;
-#endif
+		inode->u.ext2_i.i_high_size = le32_to_cpu(raw_inode->i_size_high);
+		inode->i_size |= ((__u64)le32_to_cpu(raw_inode->i_size_high)) << 32;
 	}
 	inode->i_generation = le32_to_cpu(raw_inode->i_generation);
 	inode->u.ext2_i.i_block_group = block_group;
@@ -816,14 +809,9 @@
 	raw_inode->i_file_acl = cpu_to_le32(inode->u.ext2_i.i_file_acl);
 	if (S_ISDIR(inode->i_mode))
 		raw_inode->i_dir_acl = cpu_to_le32(inode->u.ext2_i.i_dir_acl);
-	else { 
-#if BITS_PER_LONG < 64
-		raw_inode->i_size_high =
-			cpu_to_le32(inode->u.ext2_i.i_high_size);
-#else
+	else
 		raw_inode->i_size_high = cpu_to_le32(inode->i_size >> 32);
-#endif
-	}
+
 	raw_inode->i_generation = cpu_to_le32(inode->i_generation);
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 		raw_inode->i_block[0] = cpu_to_le32(kdev_t_to_nr(inode->i_rdev));
diff -u --recursive --new-file v2.3.25/linux/fs/ext2/truncate.c linux/fs/ext2/truncate.c
--- v2.3.25/linux/fs/ext2/truncate.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ext2/truncate.c	Thu Nov  4 15:35:34 1999
@@ -50,8 +50,7 @@
  * there's no need to test for changes during the operation.
  */
 #define DIRECT_BLOCK(inode) \
-	((inode->i_size + inode->i_sb->s_blocksize - 1) / \
-			  inode->i_sb->s_blocksize)
+	((unsigned long) ((inode->i_size + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits))
 #define INDIRECT_BLOCK(inode,offset) ((int)DIRECT_BLOCK(inode) - offset)
 #define DINDIRECT_BLOCK(inode,offset) \
 	(INDIRECT_BLOCK(inode,offset) / addr_per_block)
diff -u --recursive --new-file v2.3.25/linux/fs/fat/file.c linux/fs/fat/file.c
--- v2.3.25/linux/fs/fat/file.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/fat/file.c	Fri Nov  5 16:27:28 1999
@@ -182,6 +182,7 @@
 
 void fat_truncate(struct inode *inode)
 {
+	struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
 	int cluster;
 
 	/* Why no return value?  Surely the disk could fail... */
@@ -189,9 +190,9 @@
 		return /* -EPERM */;
 	if (IS_IMMUTABLE(inode))
 		return /* -EPERM */;
-	cluster = SECTOR_SIZE*MSDOS_SB(inode->i_sb)->cluster_size;
+	cluster = SECTOR_SIZE*sbi->cluster_size;
 	MSDOS_I(inode)->i_realsize = ((inode->i_size-1) | (SECTOR_SIZE-1)) + 1;
-	(void) fat_free(inode,(inode->i_size+(cluster-1))/cluster);
+	fat_free(inode,(inode->i_size+(cluster-1))>>sbi->cluster_bits);
 	MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 	mark_inode_dirty(inode);
diff -u --recursive --new-file v2.3.25/linux/fs/fat/inode.c linux/fs/fat/inode.c
--- v2.3.25/linux/fs/fat/inode.c	Tue Aug 31 17:29:14 1999
+++ linux/fs/fat/inode.c	Fri Nov  5 16:27:28 1999
@@ -364,21 +364,22 @@
 static void fat_read_root(struct inode *inode)
 {
 	struct super_block *sb = inode->i_sb;
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	int nr;
 
 	INIT_LIST_HEAD(&MSDOS_I(inode)->i_fat_hash);
 	MSDOS_I(inode)->i_location = 0;
 	MSDOS_I(inode)->i_fat_inode = inode;
-	inode->i_uid = MSDOS_SB(sb)->options.fs_uid;
-	inode->i_gid = MSDOS_SB(sb)->options.fs_gid;
+	inode->i_uid = sbi->options.fs_uid;
+	inode->i_gid = sbi->options.fs_gid;
 	inode->i_version = ++event;
-	inode->i_mode = (S_IRWXUGO & ~MSDOS_SB(sb)->options.fs_umask) | S_IFDIR;
-	inode->i_op = MSDOS_SB(sb)->dir_ops;
-	if (MSDOS_SB(sb)->fat_bits == 32) {
-		MSDOS_I(inode)->i_start = MSDOS_SB(sb)->root_cluster;
+	inode->i_mode = (S_IRWXUGO & ~sbi->options.fs_umask) | S_IFDIR;
+	inode->i_op = sbi->dir_ops;
+	if (sbi->fat_bits == 32) {
+		MSDOS_I(inode)->i_start = sbi->root_cluster;
 		if ((nr = MSDOS_I(inode)->i_start) != 0) {
 			while (nr != -1) {
-				inode->i_size += SECTOR_SIZE*MSDOS_SB(sb)->cluster_size;
+				inode->i_size += SECTOR_SIZE*sbi->cluster_size;
 				if (!(nr = fat_access(sb,nr,-1))) {
 					printk("Directory %ld: bad FAT\n",
 					       inode->i_ino);
@@ -388,12 +389,13 @@
 		}
 	} else {
 		MSDOS_I(inode)->i_start = 0;
-		inode->i_size = MSDOS_SB(sb)->dir_entries*
+		inode->i_size = sbi->dir_entries*
 			sizeof(struct msdos_dir_entry);
 	}
-	inode->i_blksize = MSDOS_SB(sb)->cluster_size* SECTOR_SIZE;
-	inode->i_blocks = (inode->i_size+inode->i_blksize-1)/
-		    inode->i_blksize*MSDOS_SB(sb)->cluster_size;
+	inode->i_blksize = sbi->cluster_size* SECTOR_SIZE;
+	inode->i_blocks =
+		((inode->i_size+inode->i_blksize-1)>>sbi->cluster_bits) *
+		    sbi->cluster_size;
 	MSDOS_I(inode)->i_logstart = 0;
 	MSDOS_I(inode)->i_realsize = inode->i_size;
 
@@ -429,6 +431,7 @@
 	struct inode *root_inode;
 	struct buffer_head *bh;
 	struct fat_boot_sector *b;
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	char *p;
 	int data_sectors,logical_sector_size,sector_mult,fat_clusters=0;
 	int debug,error,fat,cp;
@@ -442,12 +445,12 @@
 
 	cvf_format[0] = '\0';
 	cvf_options[0] = '\0';
-	MSDOS_SB(sb)->cvf_format = NULL;
-	MSDOS_SB(sb)->private_data = NULL;
+	sbi->cvf_format = NULL;
+	sbi->private_data = NULL;
 
 	MOD_INC_USE_COUNT;
-	MSDOS_SB(sb)->dir_ops = fs_dir_inode_ops;
-	MSDOS_SB(sb)->put_super_callback = NULL;
+	sbi->dir_ops = fs_dir_inode_ops;
+	sbi->put_super_callback = NULL;
 	sb->s_op = &fat_sops;
 	if (hardsect_size[MAJOR(sb->s_dev)] != NULL){
 		blksize = hardsect_size[MAJOR(sb->s_dev)][MINOR(sb->s_dev)];
@@ -457,13 +460,13 @@
 
 	}
 
-	opts.isvfat = MSDOS_SB(sb)->options.isvfat;
+	opts.isvfat = sbi->options.isvfat;
 	if (!parse_options((char *) data, &fat, &blksize, &debug, &opts, 
 			   cvf_format, cvf_options)
 	    || (blksize != 512 && blksize != 1024 && blksize != 2048))
 		goto out_fail;
 	/* N.B. we should parse directly into the sb structure */
-	memcpy(&(MSDOS_SB(sb)->options), &opts, sizeof(struct fat_mount_options));
+	memcpy(&(sbi->options), &opts, sizeof(struct fat_mount_options));
 
 	fat_cache_init();
 	lock_super(sb);
@@ -508,69 +511,79 @@
 	logical_sector_size =
 		CF_LE_W(get_unaligned((unsigned short *) &b->sector_size));
 	sector_mult = logical_sector_size >> SECTOR_BITS;
-	MSDOS_SB(sb)->cluster_size = b->cluster_size*sector_mult;
-	MSDOS_SB(sb)->fats = b->fats;
-	MSDOS_SB(sb)->fat_start = CF_LE_W(b->reserved)*sector_mult;
+	sbi->cluster_size = b->cluster_size*sector_mult;
+	if (!sbi->cluster_size || (sbi->cluster_size & (sbi->cluster_size-1))) {
+		printk("fatfs: bogus cluster size\n");
+		brelse(bh);
+		goto out_invalid;
+	}
+	for (sbi->cluster_bits=0;
+	     1<<sbi->cluster_bits<sbi->cluster_size;
+	     sbi->cluster_bits++)
+		;
+	sbi->cluster_bits += SECTOR_BITS;
+	sbi->fats = b->fats;
+	sbi->fat_start = CF_LE_W(b->reserved)*sector_mult;
 	if (!b->fat_length && b->fat32_length) {
 		struct fat_boot_fsinfo *fsinfo;
 
 		/* Must be FAT32 */
 		fat32 = 1;
-		MSDOS_SB(sb)->fat_length= CF_LE_L(b->fat32_length)*sector_mult;
-		MSDOS_SB(sb)->root_cluster = CF_LE_L(b->root_cluster);
+		sbi->fat_length= CF_LE_L(b->fat32_length)*sector_mult;
+		sbi->root_cluster = CF_LE_L(b->root_cluster);
 
 		/* MC - if info_sector is 0, don't multiply by 0 */
 		if(CF_LE_W(b->info_sector) == 0) {
-			MSDOS_SB(sb)->fsinfo_offset =
+			sbi->fsinfo_offset =
 	 			logical_sector_size + 0x1e0;
 		} else {
-			MSDOS_SB(sb)->fsinfo_offset =
+			sbi->fsinfo_offset =
 				(CF_LE_W(b->info_sector) * logical_sector_size)
 				+ 0x1e0;
 		}
-		if (MSDOS_SB(sb)->fsinfo_offset + sizeof(struct fat_boot_fsinfo) > sb->s_blocksize) {
+		if (sbi->fsinfo_offset + sizeof(struct fat_boot_fsinfo) > sb->s_blocksize) {
 			printk("fat_read_super: Bad fsinfo_offset\n");
-			fat_brelse(sb, bh);
+			brelse(bh);
 			goto out_invalid;
 		}
 		fsinfo = (struct fat_boot_fsinfo *)
-			&bh->b_data[MSDOS_SB(sb)->fsinfo_offset];
+			&bh->b_data[sbi->fsinfo_offset];
 		if (CF_LE_L(fsinfo->signature) != 0x61417272) {
 			printk("fat_read_super: Did not find valid FSINFO "
 				"signature. Found 0x%x\n",
 				CF_LE_L(fsinfo->signature));
 		} else {
-			MSDOS_SB(sb)->free_clusters = CF_LE_L(fsinfo->free_clusters);
+			sbi->free_clusters = CF_LE_L(fsinfo->free_clusters);
 		}
 	} else {
 		fat32 = 0;
-		MSDOS_SB(sb)->fat_length = CF_LE_W(b->fat_length)*sector_mult;
-		MSDOS_SB(sb)->root_cluster = 0;
-		MSDOS_SB(sb)->free_clusters = -1; /* Don't know yet */
-	}
-	MSDOS_SB(sb)->dir_start= CF_LE_W(b->reserved)*sector_mult+
-	    b->fats*MSDOS_SB(sb)->fat_length;
-	MSDOS_SB(sb)->dir_entries =
+		sbi->fat_length = CF_LE_W(b->fat_length)*sector_mult;
+		sbi->root_cluster = 0;
+		sbi->free_clusters = -1; /* Don't know yet */
+	}
+	sbi->dir_start= CF_LE_W(b->reserved)*sector_mult+
+	    b->fats*sbi->fat_length;
+	sbi->dir_entries =
 		CF_LE_W(get_unaligned((unsigned short *) &b->dir_entries));
-	MSDOS_SB(sb)->data_start = MSDOS_SB(sb)->dir_start+ROUND_TO_MULTIPLE((
-	    MSDOS_SB(sb)->dir_entries << MSDOS_DIR_BITS) >> SECTOR_BITS,
+	sbi->data_start = sbi->dir_start+ROUND_TO_MULTIPLE((
+	    sbi->dir_entries << MSDOS_DIR_BITS) >> SECTOR_BITS,
 	    sector_mult);
 	data_sectors = CF_LE_W(get_unaligned((unsigned short *) &b->sectors));
 	if (!data_sectors) {
 		data_sectors = CF_LE_L(b->total_sect);
 	}
-	data_sectors = data_sectors * sector_mult - MSDOS_SB(sb)->data_start;
+	data_sectors = data_sectors * sector_mult - sbi->data_start;
 	error = !b->cluster_size || !sector_mult;
 	if (!error) {
-		MSDOS_SB(sb)->clusters = b->cluster_size ? data_sectors/
+		sbi->clusters = b->cluster_size ? data_sectors/
 		    b->cluster_size/sector_mult : 0;
-		MSDOS_SB(sb)->fat_bits = fat32 ? 32 :
+		sbi->fat_bits = fat32 ? 32 :
 			(fat ? fat :
-			 (MSDOS_SB(sb)->clusters > MSDOS_FAT12 ? 16 : 12));
-		fat_clusters = MSDOS_SB(sb)->fat_length*SECTOR_SIZE*8/
-		    MSDOS_SB(sb)->fat_bits;
-		error = !MSDOS_SB(sb)->fats || (MSDOS_SB(sb)->dir_entries &
-		    (MSDOS_DPS-1)) || MSDOS_SB(sb)->clusters+2 > fat_clusters+
+			 (sbi->clusters > MSDOS_FAT12 ? 16 : 12));
+		fat_clusters = sbi->fat_length*SECTOR_SIZE*8/
+		    sbi->fat_bits;
+		error = !sbi->fats || (sbi->dir_entries &
+		    (MSDOS_DPS-1)) || sbi->clusters+2 > fat_clusters+
 		    MSDOS_MAX_EXTRA || (logical_sector_size & (SECTOR_SIZE-1))
 		    || !b->secs_track || !b->heads;
 	}
@@ -592,59 +605,59 @@
 	if (i >= 0)
 		error = cvf_formats[i]->mount_cvf(sb,cvf_options);
 	else if (sb->s_blocksize == 512)
-		MSDOS_SB(sb)->cvf_format = &default_cvf;
+		sbi->cvf_format = &default_cvf;
 	else
-		MSDOS_SB(sb)->cvf_format = &bigblock_cvf;
+		sbi->cvf_format = &bigblock_cvf;
 	if (error || debug) {
 		/* The MSDOS_CAN_BMAP is obsolete, but left just to remember */
 		printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,"
 		       "uid=%d,gid=%d,umask=%03o%s]\n",
-		       MSDOS_SB(sb)->fat_bits,opts.name_check,
+		       sbi->fat_bits,opts.name_check,
 		       opts.conversion,opts.fs_uid,opts.fs_gid,opts.fs_umask,
-		       MSDOS_CAN_BMAP(MSDOS_SB(sb)) ? ",bmap" : "");
+		       MSDOS_CAN_BMAP(sbi) ? ",bmap" : "");
 		printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%ld,ds=%ld,de=%d,data=%ld,"
 		       "se=%d,ts=%ld,ls=%d,rc=%ld,fc=%u]\n",
-			b->media,MSDOS_SB(sb)->cluster_size,
-			MSDOS_SB(sb)->fats,MSDOS_SB(sb)->fat_start,
-			MSDOS_SB(sb)->fat_length,
-		       MSDOS_SB(sb)->dir_start,MSDOS_SB(sb)->dir_entries,
-		       MSDOS_SB(sb)->data_start,
+			b->media,sbi->cluster_size,
+			sbi->fats,sbi->fat_start,
+			sbi->fat_length,
+		       sbi->dir_start,sbi->dir_entries,
+		       sbi->data_start,
 		       CF_LE_W(*(unsigned short *) &b->sectors),
 		       (unsigned long)b->total_sect,logical_sector_size,
-		       MSDOS_SB(sb)->root_cluster,MSDOS_SB(sb)->free_clusters);
+		       sbi->root_cluster,sbi->free_clusters);
 		printk ("Transaction block size = %d\n",blksize);
 	}
-	if (i<0) if (MSDOS_SB(sb)->clusters+2 > fat_clusters)
-		MSDOS_SB(sb)->clusters = fat_clusters-2;
+	if (i<0) if (sbi->clusters+2 > fat_clusters)
+		sbi->clusters = fat_clusters-2;
 	if (error)
 		goto out_invalid;
 
 	sb->s_magic = MSDOS_SUPER_MAGIC;
 	/* set up enough so that it can read an inode */
-	init_waitqueue_head(&MSDOS_SB(sb)->fat_wait);
-	init_MUTEX(&MSDOS_SB(sb)->fat_lock);
-	MSDOS_SB(sb)->prev_free = 0;
+	init_waitqueue_head(&sbi->fat_wait);
+	init_MUTEX(&sbi->fat_lock);
+	sbi->prev_free = 0;
 
 	cp = opts.codepage ? opts.codepage : 437;
 	sprintf(buf, "cp%d", cp);
-	MSDOS_SB(sb)->nls_disk = load_nls(buf);
-	if (! MSDOS_SB(sb)->nls_disk) {
+	sbi->nls_disk = load_nls(buf);
+	if (! sbi->nls_disk) {
 		/* Fail only if explicit charset specified */
 		if (opts.codepage != 0)
 			goto out_fail;
-		MSDOS_SB(sb)->options.codepage = 0; /* already 0?? */
-		MSDOS_SB(sb)->nls_disk = load_nls_default();
+		sbi->options.codepage = 0; /* already 0?? */
+		sbi->nls_disk = load_nls_default();
 	}
 
-	MSDOS_SB(sb)->nls_io = NULL;
-	if (MSDOS_SB(sb)->options.isvfat && !opts.utf8) {
+	sbi->nls_io = NULL;
+	if (sbi->options.isvfat && !opts.utf8) {
 		p = opts.iocharset ? opts.iocharset : "iso8859-1";
-		MSDOS_SB(sb)->nls_io = load_nls(p);
-		if (! MSDOS_SB(sb)->nls_io) {
+		sbi->nls_io = load_nls(p);
+		if (! sbi->nls_io) {
 			/* Fail only if explicit charset specified */
 			if (opts.iocharset)
 				goto out_unload_nls;
-			MSDOS_SB(sb)->nls_io = load_nls_default();
+			sbi->nls_io = load_nls_default();
 		}
 	}
 
@@ -660,7 +673,7 @@
 	if (!sb->s_root)
 		goto out_no_root;
 	if(i>=0) {
-		MSDOS_SB(sb)->cvf_format = cvf_formats[i];
+		sbi->cvf_format = cvf_formats[i];
 		++cvf_format_use_count[i];
 	}
 	return sb;
@@ -668,10 +681,10 @@
 out_no_root:
 	printk("get root inode failed\n");
 	iput(root_inode);
-	if (MSDOS_SB(sb)->nls_io)
-		unload_nls(MSDOS_SB(sb)->nls_io);
+	if (sbi->nls_io)
+		unload_nls(sbi->nls_io);
 out_unload_nls:
-	unload_nls(MSDOS_SB(sb)->nls_disk);
+	unload_nls(sbi->nls_disk);
 	goto out_fail;
 out_invalid:
 	if (!silent)
@@ -686,8 +699,9 @@
 		kfree(opts.iocharset);
 	}
 	sb->s_dev = 0;
-	if(MSDOS_SB(sb)->private_data)kfree(MSDOS_SB(sb)->private_data);
-	MSDOS_SB(sb)->private_data=NULL;
+	if(sbi->private_data)
+		kfree(sbi->private_data);
+	sbi->private_data=NULL;
  
 	MOD_DEC_USE_COUNT;
 	return NULL;
@@ -737,21 +751,22 @@
 static void fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
 {
 	struct super_block *sb = inode->i_sb;
+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
 	int nr;
 
 	INIT_LIST_HEAD(&MSDOS_I(inode)->i_fat_hash);
 	MSDOS_I(inode)->i_location = 0;
 	MSDOS_I(inode)->i_fat_inode = inode;
-	inode->i_uid = MSDOS_SB(sb)->options.fs_uid;
-	inode->i_gid = MSDOS_SB(sb)->options.fs_gid;
+	inode->i_uid = sbi->options.fs_uid;
+	inode->i_gid = sbi->options.fs_gid;
 	inode->i_version = ++event;
 	if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
 		inode->i_mode = MSDOS_MKMODE(de->attr,S_IRWXUGO &
-		    ~MSDOS_SB(sb)->options.fs_umask) | S_IFDIR;
-		inode->i_op = MSDOS_SB(inode->i_sb)->dir_ops;
+		    ~sbi->options.fs_umask) | S_IFDIR;
+		inode->i_op = sbi->dir_ops;
 
 		MSDOS_I(inode)->i_start = CF_LE_W(de->start);
-		if (MSDOS_SB(sb)->fat_bits == 32) {
+		if (sbi->fat_bits == 32) {
 			MSDOS_I(inode)->i_start |=
 				(CF_LE_W(de->starthi) << 16);
 		}
@@ -767,8 +782,7 @@
 		inode->i_size = 0;
 		if ((nr = MSDOS_I(inode)->i_start) != 0)
 			while (nr != -1) {
-				inode->i_size += SECTOR_SIZE*MSDOS_SB(inode->
-				    i_sb)->cluster_size;
+				inode->i_size += SECTOR_SIZE*sbi->cluster_size;
 				if (!(nr = fat_access(sb,nr,-1))) {
 					printk("Directory %ld: bad FAT\n",
 					    inode->i_ino);
@@ -779,13 +793,13 @@
 	} else { /* not a directory */
 		inode->i_mode = MSDOS_MKMODE(de->attr,
 		    ((IS_NOEXEC(inode) || 
-		      (MSDOS_SB(sb)->options.showexec &&
+		      (sbi->options.showexec &&
 		       !is_exec(de->ext)))
 		    	? S_IRUGO|S_IWUGO : S_IRWXUGO)
-		    & ~MSDOS_SB(sb)->options.fs_umask) | S_IFREG;
+		    & ~sbi->options.fs_umask) | S_IFREG;
 	        inode->i_op = &fat_file_inode_operations;
 		MSDOS_I(inode)->i_start = CF_LE_W(de->start);
-		if (MSDOS_SB(sb)->fat_bits == 32) {
+		if (sbi->fat_bits == 32) {
 			MSDOS_I(inode)->i_start |=
 				(CF_LE_W(de->starthi) << 16);
 		}
@@ -795,13 +809,14 @@
 		MSDOS_I(inode)->i_realsize = ((inode->i_size-1)|(SECTOR_SIZE-1))+1;
 	}
 	if(de->attr & ATTR_SYS)
-		if (MSDOS_SB(sb)->options.sys_immutable)
+		if (sbi->options.sys_immutable)
 			inode->i_flags |= S_IMMUTABLE;
 	MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
 	/* this is as close to the truth as we can get ... */
-	inode->i_blksize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE;
-	inode->i_blocks = (inode->i_size+inode->i_blksize-1)/
-	    inode->i_blksize*MSDOS_SB(sb)->cluster_size;
+	inode->i_blksize = sbi->cluster_size*SECTOR_SIZE;
+	inode->i_blocks =
+		((inode->i_size+inode->i_blksize-1)>>sbi->cluster_bits) *
+		sbi->cluster_size;
 	inode->i_mtime = inode->i_atime =
 	    date_dos2unix(CF_LE_W(de->time),CF_LE_W(de->date));
 	inode->i_ctime =
diff -u --recursive --new-file v2.3.25/linux/fs/file.c linux/fs/file.c
--- v2.3.25/linux/fs/file.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/file.c	Thu Nov  4 10:39:03 1999
@@ -175,7 +175,7 @@
 	int error, nfds = 0;
 
 	error = -EMFILE;
-	if (files->max_fdset >= NR_OPEN || nr > NR_OPEN)
+	if (files->max_fdset >= NR_OPEN || nr >= NR_OPEN)
 		goto out;
 
 	nfds = files->max_fdset;
@@ -190,7 +190,7 @@
 			if (nfds > NR_OPEN)
 				nfds = NR_OPEN;
 		}
-	} while (nfds < nr);
+	} while (nfds <= nr);
 
 	error = -ENOMEM;
 	new_openset = alloc_fdset(nfds);
diff -u --recursive --new-file v2.3.25/linux/fs/hfs/file.c linux/fs/hfs/file.c
--- v2.3.25/linux/fs/hfs/file.c	Sun Jun 27 10:10:41 1999
+++ linux/fs/hfs/file.c	Fri Nov  5 15:53:26 1999
@@ -498,7 +498,6 @@
 				written = -EFAULT;
 			break;
 		}
-		update_vm_cache(inode,pos,p,c);
 		pos += c;
 		written += c;
 		buf += c;
diff -u --recursive --new-file v2.3.25/linux/fs/isofs/inode.c linux/fs/isofs/inode.c
--- v2.3.25/linux/fs/isofs/inode.c	Sat Oct  9 11:47:50 1999
+++ linux/fs/isofs/inode.c	Thu Nov  4 15:50:50 1999
@@ -1009,7 +1009,7 @@
 
 abort_beyond_end:
 	printk("_isofs_bmap: block >= EOF (%ld, %ld)\n",
-	       iblock, inode->i_size);
+	       iblock, (unsigned long) inode->i_size);
 	goto abort;
 
 abort_too_many_sections:
diff -u --recursive --new-file v2.3.25/linux/fs/lockd/mon.c linux/fs/lockd/mon.c
--- v2.3.25/linux/fs/lockd/mon.c	Fri Dec 19 10:54:10 1997
+++ linux/fs/lockd/mon.c	Fri Nov  5 11:07:08 1999
@@ -195,6 +195,12 @@
 #define SM_my_id_sz	(3+1+SM_my_name_sz)
 #define SM_mon_id_sz	(1+XDR_QUADLEN(20)+SM_my_id_sz)
 #define SM_mon_sz	(SM_mon_id_sz+4)
+#define SM_monres_sz	2
+#define SM_unmonres_sz	1
+
+#ifndef MAX
+# define MAX(a, b)	(((a) > (b))? (a) : (b))
+#endif
 
 static struct rpc_procinfo	nsm_procedures[] = {
         { "sm_null",
@@ -205,10 +211,10 @@
 		(kxdrproc_t) xdr_error, 0, 0 },
         { "sm_mon",
 		(kxdrproc_t) xdr_encode_mon,
-		(kxdrproc_t) xdr_decode_stat_res, SM_mon_sz, 2 },
+		(kxdrproc_t) xdr_decode_stat_res, MAX(SM_mon_sz, SM_monres_sz) << 2, 0 },
         { "sm_unmon",
 		(kxdrproc_t) xdr_encode_mon,
-		(kxdrproc_t) xdr_decode_stat, SM_mon_id_sz, 1 },
+		(kxdrproc_t) xdr_decode_stat, MAX(SM_mon_id_sz, SM_unmonres_sz) << 2, 0 },
         { "sm_unmon_all",
 		(kxdrproc_t) xdr_error,
 		(kxdrproc_t) xdr_error, 0, 0 },
diff -u --recursive --new-file v2.3.25/linux/fs/ncpfs/inode.c linux/fs/ncpfs/inode.c
--- v2.3.25/linux/fs/ncpfs/inode.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ncpfs/inode.c	Fri Nov  5 14:22:05 1999
@@ -122,12 +122,8 @@
 		}
 		if (nwi->attributes & aRONLY) inode->i_mode &= ~0222;
 	}
-	inode->i_blocks = 0;
-	if ((inode->i_size)&&(inode->i_blksize)) {
-		inode->i_blocks = (inode->i_size-1)/(inode->i_blksize)+1;
-	}
+	inode->i_blocks = (inode->i_size + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
 
-	/* TODO: times? I'm not sure... */
 	inode->i_mtime = ncp_date_dos2unix(le16_to_cpu(nwinfo->i.modifyTime),
 			  		   le16_to_cpu(nwinfo->i.modifyDate));
 	inode->i_ctime = ncp_date_dos2unix(le16_to_cpu(nwinfo->i.creationTime),
@@ -192,14 +188,10 @@
 	inode->i_nlink = 1;
 	inode->i_uid = server->m.uid;
 	inode->i_gid = server->m.gid;
-	inode->i_blksize = NCP_BLOCK_SIZE;
 	inode->i_rdev = 0;
+	inode->i_blksize = NCP_BLOCK_SIZE;
 
-	inode->i_blocks = 0;
-	if ((inode->i_blksize != 0) && (inode->i_size != 0)) {
-		inode->i_blocks =
-		    (inode->i_size - 1) / inode->i_blksize + 1;
-	}
+	inode->i_blocks = (inode->i_size + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
 
 	inode->i_mtime = ncp_date_dos2unix(le16_to_cpu(nwi->modifyTime),
 			  		   le16_to_cpu(nwi->modifyDate));
diff -u --recursive --new-file v2.3.25/linux/fs/ncpfs/mmap.c linux/fs/ncpfs/mmap.c
--- v2.3.25/linux/fs/ncpfs/mmap.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/ncpfs/mmap.c	Fri Nov  5 14:22:05 1999
@@ -119,6 +119,11 @@
 		return -EINVAL;
 	if (!inode->i_sb || !S_ISREG(inode->i_mode))
 		return -EACCES;
+	/* we do not support files bigger than 4GB... We eventually 
+	   supports just 4GB... */
+	if (((vma->vm_end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff 
+	   > (1U << (32 - PAGE_SHIFT)))
+		return -EFBIG;
 	if (!IS_RDONLY(inode)) {
 		inode->i_atime = CURRENT_TIME;
 	}
diff -u --recursive --new-file v2.3.25/linux/fs/ncpfs/ncplib_kernel.h linux/fs/ncpfs/ncplib_kernel.h
--- v2.3.25/linux/fs/ncpfs/ncplib_kernel.h	Mon Nov  1 13:56:27 1999
+++ linux/fs/ncpfs/ncplib_kernel.h	Fri Nov  5 14:22:05 1999
@@ -36,7 +36,8 @@
 #define NCP_MIN_SYMLINK_SIZE	8
 #define NCP_MAX_SYMLINK_SIZE	512
 
-#define NCP_BLOCK_SIZE		512
+#define NCP_BLOCK_SHIFT		9
+#define NCP_BLOCK_SIZE		(1 << (NCP_BLOCK_SHIFT))
 
 int ncp_negotiate_buffersize(struct ncp_server *, int, int *);
 int ncp_negotiate_size_and_options(struct ncp_server *server, int size,
diff -u --recursive --new-file v2.3.25/linux/fs/nfs/inode.c linux/fs/nfs/inode.c
--- v2.3.25/linux/fs/nfs/inode.c	Fri Oct 22 13:21:52 1999
+++ linux/fs/nfs/inode.c	Thu Nov  4 15:48:15 1999
@@ -680,7 +680,7 @@
 	 */
 	if (attr->ia_valid & ATTR_SIZE) {
 		if (attr->ia_size != fattr.size)
-			printk("nfs_notify_change: attr=%ld, fattr=%d??\n",
+			printk("nfs_notify_change: attr=%Ld, fattr=%d??\n",
 				attr->ia_size, fattr.size);
 		inode->i_size  = attr->ia_size;
 		inode->i_mtime = fattr.mtime.seconds;
diff -u --recursive --new-file v2.3.25/linux/fs/nfs/mount_clnt.c linux/fs/nfs/mount_clnt.c
--- v2.3.25/linux/fs/nfs/mount_clnt.c	Wed Aug 26 10:10:33 1998
+++ linux/fs/nfs/mount_clnt.c	Tue Nov  2 13:09:37 1999
@@ -119,7 +119,7 @@
 	{ "mnt_mount",
 		(kxdrproc_t) xdr_encode_dirpath,	
 		(kxdrproc_t) xdr_decode_fhstatus,
-		MNT_dirpath_sz, MNT_fhstatus_sz },
+		MNT_dirpath_sz << 2, 0 },
 };
 
 static struct rpc_version	mnt_version1 = {
diff -u --recursive --new-file v2.3.25/linux/fs/nfsd/nfsctl.c linux/fs/nfsd/nfsctl.c
--- v2.3.25/linux/fs/nfsd/nfsctl.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/nfsd/nfsctl.c	Tue Nov  2 21:35:58 1999
@@ -295,7 +295,6 @@
 	do_nfsservctl = NULL;
 	nfsd_export_shutdown();
 	nfsd_cache_shutdown();
-	nfsd_fh_free();
 	remove_proc_entry("fs/nfs/exports", NULL);
 	remove_proc_entry("fs/nfs", NULL);
 	nfsd_stat_shutdown();
diff -u --recursive --new-file v2.3.25/linux/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
--- v2.3.25/linux/fs/nfsd/nfsfh.c	Wed Oct 27 16:34:12 1999
+++ linux/fs/nfsd/nfsfh.c	Tue Nov  2 21:36:13 1999
@@ -279,6 +279,7 @@
 	/* It's a directory, or we are required to confirm the file's
 	 * location in the tree.
 	 */
+	dprintk("nfs_fh: need to look harder for %d/%d\n",sb->s_dev,fh->fh_ino);
 	found = 0;
 	if (!S_ISDIR(result->d_inode->i_mode)) {
 		if (fh->fh_dirino == 0)
@@ -381,60 +382,69 @@
 		fh->fh_ino,
 		fh->fh_dirino);
 
-	/*
-	 * Security: Check that the fh is internally consistant (from <gam3@acm.org>)
-	 */
-	if (fh->fh_dev != fh->fh_xdev) {
-		printk("fh_verify: Security: export on other device (%s, %s).\n",
-			kdevname(fh->fh_dev), kdevname(fh->fh_xdev));
-		error = nfserr_stale;
-		nfsdstats.fh_stale++;
-		goto out;
-	}
+	if (!fhp->fh_dverified) {
+		/*
+		 * Security: Check that the fh is internally consistant (from <gam3@acm.org>)
+		 */
+		if (fh->fh_dev != fh->fh_xdev) {
+			printk("fh_verify: Security: export on other device (%s, %s).\n",
+			       kdevname(fh->fh_dev), kdevname(fh->fh_xdev));
+			error = nfserr_stale;
+			nfsdstats.fh_stale++;
+			goto out;
+		}
 
-	/*
-	 * Look up the export entry.
-	 */
-	error = nfserr_stale;
-	exp = exp_get(rqstp->rq_client,
-		      u32_to_kdev_t(fh->fh_xdev),
-		      u32_to_ino_t(fh->fh_xino));
-	if (!exp) {
-		/* export entry revoked */
-		nfsdstats.fh_stale++;
-		goto out;
-	}
+		/*
+		 * Look up the export entry.
+		 */
+		error = nfserr_stale; 
+		exp = exp_get(rqstp->rq_client,
+			      u32_to_kdev_t(fh->fh_xdev),
+			      u32_to_ino_t(fh->fh_xino));
+		if (!exp) {
+			/* export entry revoked */
+			nfsdstats.fh_stale++;
+			goto out;
+		}
 
-	/* Check if the request originated from a secure port. */
-	error = nfserr_perm;
-	if (!rqstp->rq_secure && EX_SECURE(exp)) {
-		printk(KERN_WARNING
-			"nfsd: request from insecure port (%08lx:%d)!\n",
-				ntohl(rqstp->rq_addr.sin_addr.s_addr),
-				ntohs(rqstp->rq_addr.sin_port));
-		goto out;
-	}
+		/* Check if the request originated from a secure port. */
+		error = nfserr_perm;
+		if (!rqstp->rq_secure && EX_SECURE(exp)) {
+			printk(KERN_WARNING
+			       "nfsd: request from insecure port (%08lx:%d)!\n",
+			       ntohl(rqstp->rq_addr.sin_addr.s_addr),
+			       ntohs(rqstp->rq_addr.sin_port));
+			goto out;
+		}
 
-	/* Set user creds if we haven't done so already. */
-	nfsd_setuser(rqstp, exp);
+		/* Set user creds if we haven't done so already. */
+		nfsd_setuser(rqstp, exp);
 
-	/*
-	 * Look up the dentry using the NFS file handle.
-	 */
-
-	dentry = find_fh_dentry(exp->ex_dentry->d_inode->i_sb,
-				fh,
-				!(exp->ex_flags & NFSEXP_NOSUBTREECHECK));
-
-	if (IS_ERR(dentry)) {
-		error = nfserrno(-PTR_ERR(dentry));
-		goto out;
-	}
+		/*
+		 * Look up the dentry using the NFS file handle.
+		 */
 
-	fhp->fh_dentry = dentry;
-	fhp->fh_export = exp;
-	fhp->fh_dverified = 1;
-	nfsd_nr_verified++;
+		dentry = find_fh_dentry(exp->ex_dentry->d_inode->i_sb,
+					fh,
+					!(exp->ex_flags & NFSEXP_NOSUBTREECHECK));
+
+		if (IS_ERR(dentry)) {
+			error = nfserrno(-PTR_ERR(dentry));
+			goto out;
+		}
+
+		fhp->fh_dentry = dentry;
+		fhp->fh_export = exp;
+		fhp->fh_dverified = 1;
+		nfsd_nr_verified++;
+	} else {
+		/* just rechecking permissions
+		 * (e.g. nfsproc_create calls fh_verify, then nfsd_create does as well)
+		 */
+		dprintk("nfsd: fh_verify - just checking\n");
+		dentry = fhp->fh_dentry;
+		exp = fhp->fh_export;
+	}
 
 	inode = dentry->d_inode;
 
diff -u --recursive --new-file v2.3.25/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c
--- v2.3.25/linux/fs/nfsd/vfs.c	Wed Oct 27 16:34:12 1999
+++ linux/fs/nfsd/vfs.c	Tue Nov  2 21:36:07 1999
@@ -657,12 +657,9 @@
 	if (!flen)
 		goto out;
 
-	/* from mkdir it won't be verified, from create it will	 */
-	if (!fhp->fh_dverified) {
-		err = fh_verify(rqstp, fhp, S_IFDIR, MAY_CREATE);
-		if (err)
-			goto out;
-	}
+	err = fh_verify(rqstp, fhp, S_IFDIR, MAY_CREATE);
+	if (err)
+		goto out;
 
 	dentry = fhp->fh_dentry;
 	dirp = dentry->d_inode;
diff -u --recursive --new-file v2.3.25/linux/fs/proc/Makefile linux/fs/proc/Makefile
--- v2.3.25/linux/fs/proc/Makefile	Mon Nov  1 13:56:27 1999
+++ linux/fs/proc/Makefile	Tue Nov  2 08:19:44 1999
@@ -9,7 +9,7 @@
 
 O_TARGET := proc.o
 O_OBJS   := inode.o root.o base.o generic.o mem.o link.o fd.o array.o \
-		kmsg.o scsi.o proc_tty.o sysvipc.o proc_misc.o
+		kmsg.o scsi.o proc_tty.o sysvipc.o proc_misc.o kcore.o
 ifdef CONFIG_OMIRR
 O_OBJS   := $(O_OBJS) omirr.o
 endif
diff -u --recursive --new-file v2.3.25/linux/fs/proc/array.c linux/fs/proc/array.c
--- v2.3.25/linux/fs/proc/array.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/proc/array.c	Fri Nov  5 10:22:51 1999
@@ -54,8 +54,6 @@
 #include <linux/kernel.h>
 #include <linux/kernel_stat.h>
 #include <linux/tty.h>
-#include <linux/user.h>
-#include <linux/a.out.h>
 #include <linux/string.h>
 #include <linux/mman.h>
 #include <linux/proc_fs.h>
@@ -67,6 +65,7 @@
 #include <linux/slab.h>
 #include <linux/smp.h>
 #include <linux/signal.h>
+#include <linux/highmem.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -78,70 +77,11 @@
 	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
 }
 
-static ssize_t read_core(struct file * file, char * buf,
-			 size_t count, loff_t *ppos)
-{
-	unsigned long p = *ppos, memsize;
-	ssize_t read;
-	ssize_t count1;
-	char * pnt;
-	struct user dump;
-#if defined (__i386__) || defined (__mc68000__)
-#	define FIRST_MAPPED	PAGE_SIZE	/* we don't have page 0 mapped on x86.. */
-#else
-#	define FIRST_MAPPED	0
-#endif
-
-	memset(&dump, 0, sizeof(struct user));
-	dump.magic = CMAGIC;
-	dump.u_dsize = max_mapnr;
-#if defined (__i386__)
-	dump.start_code = PAGE_OFFSET;
-#endif
-#ifdef __alpha__
-	dump.start_data = PAGE_OFFSET;
-#endif
-
-	memsize = (max_mapnr + 1) << PAGE_SHIFT;
-	if (p >= memsize)
-		return 0;
-	if (count > memsize - p)
-		count = memsize - p;
-	read = 0;
-
-	if (p < sizeof(struct user) && count > 0) {
-		count1 = count;
-		if (p + count1 > sizeof(struct user))
-			count1 = sizeof(struct user)-p;
-		pnt = (char *) &dump + p;
-		copy_to_user(buf,(void *) pnt, count1);
-		buf += count1;
-		p += count1;
-		count -= count1;
-		read += count1;
-	}
-
-	if (count > 0 && p < PAGE_SIZE + FIRST_MAPPED) {
-		count1 = PAGE_SIZE + FIRST_MAPPED - p;
-		if (count1 > count)
-			count1 = count;
-		clear_user(buf, count1);
-		buf += count1;
-		p += count1;
-		count -= count1;
-		read += count1;
-	}
-	if (count > 0) {
-		copy_to_user(buf, (void *) (PAGE_OFFSET+p-PAGE_SIZE), count);
-		read += count;
-	}
-	*ppos += read;
-	return read;
-}
+extern ssize_t read_kcore(struct file *, char *, size_t, loff_t *);
 
 static struct file_operations proc_kcore_operations = {
 	NULL,           /* lseek */
-	read_core,
+	read_kcore,
 	NULL,		/* write */
 	NULL,		/* readdir */
 	NULL,		/* poll */
diff -u --recursive --new-file v2.3.25/linux/fs/proc/kcore.c linux/fs/proc/kcore.c
--- v2.3.25/linux/fs/proc/kcore.c	Wed Dec 31 16:00:00 1969
+++ linux/fs/proc/kcore.c	Fri Nov  5 10:22:51 1999
@@ -0,0 +1,338 @@
+/*
+ *	fs/proc/kcore.c kernel ELF/AOUT core dumper
+ *
+ *	Modelled on fs/exec.c:aout_core_dump()
+ *	Jeremy Fitzhardinge <jeremy@sw.oz.au>
+ *	Implemented by David Howells <David.Howells@nexor.co.uk>
+ *	Modified and incorporated into 2.3.x by Tigran Aivazian <tigran@sco.com>
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/proc_fs.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/elf.h>
+#include <linux/elfcore.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_KCORE_AOUT
+ssize_t read_kcore(struct file * file, char * buf,
+			 size_t count, loff_t *ppos)
+{
+	unsigned long p = *ppos, memsize;
+	ssize_t read;
+	ssize_t count1;
+	char * pnt;
+	struct user dump;
+#if defined (__i386__) || defined (__mc68000__)
+#	define FIRST_MAPPED	PAGE_SIZE	/* we don't have page 0 mapped on x86.. */
+#else
+#	define FIRST_MAPPED	0
+#endif
+
+	memset(&dump, 0, sizeof(struct user));
+	dump.magic = CMAGIC;
+	dump.u_dsize = max_mapnr;
+#if defined (__i386__)
+	dump.start_code = PAGE_OFFSET;
+#endif
+#ifdef __alpha__
+	dump.start_data = PAGE_OFFSET;
+#endif
+
+	memsize = (max_mapnr + 1) << PAGE_SHIFT;
+	if (p >= memsize)
+		return 0;
+	if (count > memsize - p)
+		count = memsize - p;
+	read = 0;
+
+	if (p < sizeof(struct user) && count > 0) {
+		count1 = count;
+		if (p + count1 > sizeof(struct user))
+			count1 = sizeof(struct user)-p;
+		pnt = (char *) &dump + p;
+		copy_to_user(buf,(void *) pnt, count1);
+		buf += count1;
+		p += count1;
+		count -= count1;
+		read += count1;
+	}
+
+	if (count > 0 && p < PAGE_SIZE + FIRST_MAPPED) {
+		count1 = PAGE_SIZE + FIRST_MAPPED - p;
+		if (count1 > count)
+			count1 = count;
+		clear_user(buf, count1);
+		buf += count1;
+		p += count1;
+		count -= count1;
+		read += count1;
+	}
+	if (count > 0) {
+		copy_to_user(buf, (void *) (PAGE_OFFSET+p-PAGE_SIZE), count);
+		read += count;
+	}
+	*ppos += read;
+	return read;
+}
+#else
+
+
+#define roundup(x, y)  ((((x)+((y)-1))/(y))*(y))
+
+/* An ELF note in memory */
+struct memelfnote
+{
+	const char *name;
+	int type;
+	unsigned int datasz;
+	void *data;
+};
+
+extern char saved_command_line[];
+
+/*****************************************************************************/
+/*
+ * determine size of ELF note
+ */
+static int notesize(struct memelfnote *en)
+{
+	int sz;
+
+	sz = sizeof(struct elf_note);
+	sz += roundup(strlen(en->name), 4);
+	sz += roundup(en->datasz, 4);
+
+	return sz;
+} /* end notesize() */
+
+/*****************************************************************************/
+/*
+ * store a note in the header buffer
+ */
+static char *storenote(struct memelfnote *men, char *bufp)
+{
+	struct elf_note en;
+
+#define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0)
+
+	en.n_namesz = strlen(men->name);
+	en.n_descsz = men->datasz;
+	en.n_type = men->type;
+
+	DUMP_WRITE(&en, sizeof(en));
+	DUMP_WRITE(men->name, en.n_namesz);
+
+	/* XXX - cast from long long to long to avoid need for libgcc.a */
+	bufp = (char*) roundup((unsigned long)bufp,4);
+	DUMP_WRITE(men->data, men->datasz);
+	bufp = (char*) roundup((unsigned long)bufp,4);
+
+#undef DUMP_WRITE
+
+	return bufp;
+} /* end storenote() */
+
+/*****************************************************************************/
+/*
+ * store an ELF coredump header in the supplied buffer
+ * - assume the memory image is the size specified
+ */
+static void elf_kcore_store_hdr(char *bufp, size_t size, off_t dataoff)
+{
+	struct elf_prstatus prstatus;	/* NT_PRSTATUS */
+	struct elf_prpsinfo psinfo;	/* NT_PRPSINFO */
+	struct elf_phdr *nhdr, *dhdr;
+	struct elfhdr *elf;
+	struct memelfnote notes[3];
+	off_t offset = 0;
+
+	/* acquire an ELF header block from the buffer */
+	elf = (struct elfhdr *) bufp;
+	bufp += sizeof(*elf);
+	offset += sizeof(*elf);
+
+	/* set up header */
+	memcpy(elf->e_ident,ELFMAG,SELFMAG);
+	elf->e_ident[EI_CLASS]	= ELF_CLASS;
+	elf->e_ident[EI_DATA]	= ELF_DATA;
+	elf->e_ident[EI_VERSION]= EV_CURRENT;
+	memset(elf->e_ident+EI_PAD,0,EI_NIDENT-EI_PAD);
+
+	elf->e_type	= ET_CORE;
+	elf->e_machine	= ELF_ARCH;
+	elf->e_version	= EV_CURRENT;
+	elf->e_entry	= 0;
+	elf->e_phoff	= sizeof(*elf);
+	elf->e_shoff	= 0;
+	elf->e_flags	= 0;
+	elf->e_ehsize	= sizeof(*elf);
+	elf->e_phentsize= sizeof(struct elf_phdr);
+	elf->e_phnum	= 2;			/* no. of segments */
+	elf->e_shentsize= 0;
+	elf->e_shnum	= 0;
+	elf->e_shstrndx	= 0;
+
+	/* acquire an ELF program header blocks from the buffer for notes */
+	nhdr = (struct elf_phdr *) bufp;
+	bufp += sizeof(*nhdr);
+	offset += sizeof(*nhdr);
+
+	/* store program headers for notes dump */
+	nhdr->p_type	= PT_NOTE;
+	nhdr->p_offset	= 0;
+	nhdr->p_vaddr	= 0;
+	nhdr->p_paddr	= 0;
+	nhdr->p_memsz	= 0;
+	nhdr->p_flags	= 0;
+	nhdr->p_align	= 0;
+
+	/* acquire an ELF program header blocks from the buffer for data */
+	dhdr = (struct elf_phdr *) bufp;
+	bufp += sizeof(*dhdr);
+	offset += sizeof(*dhdr);
+
+	/* store program headers for data dump */
+	dhdr->p_type	= PT_LOAD;
+	dhdr->p_flags	= PF_R|PF_W|PF_X;
+	dhdr->p_offset	= dataoff;
+	dhdr->p_vaddr	= PAGE_OFFSET;
+	dhdr->p_paddr	= __pa(PAGE_OFFSET);
+	dhdr->p_filesz	= size;
+	dhdr->p_memsz	= size;
+	dhdr->p_align	= PAGE_SIZE;
+
+	/*
+	 * Set up the notes in similar form to SVR4 core dumps made
+	 * with info from their /proc.
+	 */
+	nhdr->p_offset	= offset;
+	nhdr->p_filesz	= 0;
+
+	/* set up the process status */
+	notes[0].name = "CORE";
+	notes[0].type = NT_PRSTATUS;
+	notes[0].datasz = sizeof(prstatus);
+	notes[0].data = &prstatus;
+
+	memset(&prstatus,0,sizeof(prstatus));
+
+	nhdr->p_filesz	= notesize(&notes[0]);
+	bufp = storenote(&notes[0],bufp);
+
+	/* set up the process info */
+	notes[1].name	= "CORE";
+	notes[1].type	= NT_PRPSINFO;
+	notes[1].datasz	= sizeof(psinfo);
+	notes[1].data	= &psinfo;
+
+	memset(&psinfo,0,sizeof(psinfo));
+	psinfo.pr_state	= 0;
+	psinfo.pr_sname	= 'R';
+	psinfo.pr_zomb	= 0;
+
+	strcpy(psinfo.pr_fname,"vmlinux");
+	strncpy(psinfo.pr_psargs,saved_command_line,ELF_PRARGSZ);
+
+	nhdr->p_filesz	= notesize(&notes[1]);
+	bufp = storenote(&notes[1],bufp);
+
+	/* set up the task structure */
+	notes[2].name	= "CORE";
+	notes[2].type	= NT_TASKSTRUCT;
+	notes[2].datasz	= sizeof(*current);
+	notes[2].data	= current;
+
+	nhdr->p_filesz	= notesize(&notes[2]);
+	bufp = storenote(&notes[2],bufp);
+
+} /* end elf_kcore_store_hdr() */
+
+/*****************************************************************************/
+/*
+ * read from the ELF header and then kernel memory
+ */
+ssize_t read_kcore(struct file *file, char *buffer, size_t buflen,
+			      loff_t *fpos)
+{
+	ssize_t acc;
+	size_t size, tsz;
+	char *page;
+
+	/* work out how much file we allow to be read */
+	size = ((size_t)high_memory - PAGE_OFFSET) + PAGE_SIZE;
+	acc = 0;
+
+	/* see if file pointer already beyond EOF */
+	if (buflen==0 || *fpos>=size)
+		return 0;
+
+	/* trim buflen to not go beyond EOF */
+	if (buflen > size-*fpos)
+		buflen = size - *fpos;
+
+	/* construct an ELF core header if we'll need some of it */
+	if (*fpos<PAGE_SIZE) {
+		/* get a buffer */
+		page = (char*) __get_free_page(GFP_KERNEL);
+		if (!page)
+			return -ENOMEM;
+
+		tsz = PAGE_SIZE-*fpos;
+		if (buflen < tsz)
+			tsz = buflen;
+
+		/* create a header */
+		memset(page,0,PAGE_SIZE);
+		elf_kcore_store_hdr(page,size-PAGE_SIZE,PAGE_SIZE);
+
+		/* copy data to the users buffer */
+		copy_to_user(buffer,page,tsz);
+		buflen -= tsz;
+		*fpos += tsz;
+		buffer += tsz;
+		acc += tsz;
+
+		free_page((unsigned long) page);
+
+		/* leave now if filled buffer already */
+		if (buflen==0)
+			return tsz;
+	}
+
+	/* where page 0 not mapped, write zeros into buffer */
+#if defined (__i386__) || defined (__mc68000__)
+	if (*fpos < PAGE_SIZE*2) {
+		/* work out how much to clear */
+		tsz = PAGE_SIZE*2 - *fpos;
+		if (buflen < tsz)
+			tsz = buflen;
+
+		/* write zeros to buffer */
+		clear_user(buffer,tsz);
+		buflen -= tsz;
+		*fpos += tsz;
+		buffer += tsz;
+		acc += tsz;
+
+		/* leave now if filled buffer already */
+		if (buflen==0)
+			return tsz;
+	}
+#endif
+
+	/* fill the remainder of the buffer from kernel VM space */
+#if defined (__i386__) || defined (__mc68000__)
+	copy_to_user(buffer,__va(*fpos-PAGE_SIZE),buflen);
+#else
+	copy_to_user(buffer,__va(*fpos),buflen);
+#endif
+	acc += buflen;
+	*fpos += buflen;
+
+	return acc;
+
+} /* end read_kcore() */
+#endif
diff -u --recursive --new-file v2.3.25/linux/fs/read_write.c linux/fs/read_write.c
--- v2.3.25/linux/fs/read_write.c	Tue Sep  7 12:14:07 1999
+++ linux/fs/read_write.c	Fri Nov  5 09:57:30 1999
@@ -63,8 +63,12 @@
 	    !(inode = dentry->d_inode))
 		goto out_putf;
 	retval = -EINVAL;
-	if (origin <= 2)
-		retval = llseek(file, offset, origin);
+	if (origin <= 2) {
+		loff_t res = llseek(file, offset, origin);
+		retval = res;
+		if (res != (loff_t)retval)
+			retval = -EOVERFLOW;	/* LFS: should only happen on 32 bit platforms */
+	}
 out_putf:
 	fput(file);
 bad:
diff -u --recursive --new-file v2.3.25/linux/fs/sysv/namei.c linux/fs/sysv/namei.c
--- v2.3.25/linux/fs/sysv/namei.c	Sat May 15 23:43:05 1999
+++ linux/fs/sysv/namei.c	Sat Nov  6 09:51:19 1999
@@ -324,7 +324,7 @@
 	block = 0;
 	bh = NULL;
 	pos = offset = 2*SYSV_DIRSIZE;
-	if (inode->i_size % SYSV_DIRSIZE)
+	if ((unsigned long)(inode->i_size) % SYSV_DIRSIZE)
 		goto bad_dir;
 	if (inode->i_size < pos)
 		goto bad_dir;
diff -u --recursive --new-file v2.3.25/linux/fs/udf/super.c linux/fs/udf/super.c
--- v2.3.25/linux/fs/udf/super.c	Mon Nov  1 13:56:27 1999
+++ linux/fs/udf/super.c	Sat Nov  6 09:51:19 1999
@@ -1184,7 +1184,7 @@
 				if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP15)
 				{
 					UDF_SB_TYPEVIRT(sb,i).s_start_offset = UDF_I_EXT0OFFS(UDF_SB_VAT(sb));
-					UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - 36) / sizeof(Uint32);
+					UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size - 36) >> 2;
 				}
 				else if (UDF_SB_PARTTYPE(sb,i) == UDF_VIRTUAL_MAP20)
 				{
@@ -1197,7 +1197,7 @@
 						le16_to_cpu(((struct VirtualAllocationTable20 *)bh->b_data + UDF_I_EXT0OFFS(UDF_SB_VAT(sb)))->lengthHeader) +
 							UDF_I_EXT0OFFS(UDF_SB_VAT(sb));
 					UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
-						UDF_SB_TYPEVIRT(sb,i).s_start_offset) / sizeof(Uint32);
+						UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2;
 					udf_release_data(bh);
 				}
 				UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0);
diff -u --recursive --new-file v2.3.25/linux/fs/udf/truncate.c linux/fs/udf/truncate.c
--- v2.3.25/linux/fs/udf/truncate.c	Tue Sep  7 12:14:07 1999
+++ linux/fs/udf/truncate.c	Sat Nov  6 09:51:19 1999
@@ -64,7 +64,7 @@
 	lb_addr bloc, eloc, neloc = { 0, 0 };
 	Uint32 extoffset, elen, offset, nelen = 0, lelen = 0, lenalloc;
 	int etype;
-	int first_block = (inode->i_size + inode->i_sb->s_blocksize - 1) / inode->i_sb->s_blocksize;
+	int first_block = (inode->i_size + inode->i_sb->s_blocksize - 1) >> inode->i_sb->s_blocksize_bits;
 	struct buffer_head *bh = NULL;
 	int adsize;
 
diff -u --recursive --new-file v2.3.25/linux/include/asm-alpha/shmparam.h linux/include/asm-alpha/shmparam.h
--- v2.3.25/linux/include/asm-alpha/shmparam.h	Mon Oct  7 05:12:29 1996
+++ linux/include/asm-alpha/shmparam.h	Wed Nov  3 11:31:09 1999
@@ -1,47 +1,6 @@
 #ifndef _ASMAXP_SHMPARAM_H
 #define _ASMAXP_SHMPARAM_H
 
-/*
- * Address range for shared memory attaches if no address passed to shmat().
- */
-#define SHM_RANGE_START	0x14000000000
-#define SHM_RANGE_END	0x15000000000
-
-
-/*
- * Format of a swap-entry for shared memory pages currently out in
- * swap space (see also mm/swap.c).
- *
- * SWP_TYPE = SHM_SWP_TYPE
- * SWP_OFFSET is used as follows:
- *
- *  bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
- *  bits 7..21: index of page within shared memory segment (SHM_IDX)
- *		(actually fewer bits get used since SHMMAX is so low)
- */
-
-/*
- * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
- * there is a static array of size SHMMNI.
- */
-#define _SHM_ID_BITS	7
-#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
-
-#define SHM_IDX_SHIFT	(_SHM_ID_BITS)
-#define _SHM_IDX_BITS	15
-#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
-
-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the Alpha and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
-#define SHMMAX 0x3fa000			/* max shared seg size (bytes) */
-#define SHMMIN 1 /* really PAGE_SIZE */	/* min shared seg size (bytes) */
-#define SHMMNI (1<<_SHM_ID_BITS)	/* max num of segs system wide */
-#define SHMALL				/* max shm system wide (pages) */ \
-	(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
-#define	SHMLBA PAGE_SIZE		/* attach addr a multiple of this */
-#define SHMSEG SHMMNI			/* max shared segs per process */
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
 
 #endif /* _ASMAXP_SHMPARAM_H */
diff -u --recursive --new-file v2.3.25/linux/include/asm-arm/proc-armo/shmparam.h linux/include/asm-arm/proc-armo/shmparam.h
--- v2.3.25/linux/include/asm-arm/proc-armo/shmparam.h	Tue Jan 20 16:39:42 1998
+++ linux/include/asm-arm/proc-armo/shmparam.h	Wed Nov  3 11:31:09 1999
@@ -9,9 +9,7 @@
 #ifndef __ASM_PROC_SHMPARAM_H
 #define __ASM_PROC_SHMPARAM_H
 
-#ifndef SHM_RANGE_START
-#define SHM_RANGE_START	0x00a00000
-#define SHM_RANGE_END	0x00c00000
+#ifndef SHMMAX
 #define SHMMAX		0x003fa000
 #endif
 
diff -u --recursive --new-file v2.3.25/linux/include/asm-arm/proc-armv/shmparam.h linux/include/asm-arm/proc-armv/shmparam.h
--- v2.3.25/linux/include/asm-arm/proc-armv/shmparam.h	Tue Jan 20 16:39:43 1998
+++ linux/include/asm-arm/proc-armv/shmparam.h	Wed Nov  3 11:31:09 1999
@@ -10,9 +10,7 @@
 #ifndef __ASM_PROC_SHMPARAM_H
 #define __ASM_PROC_SHMPARAM_H
 
-#ifndef SHM_RANGE_START
-#define SHM_RANGE_START	0x50000000
-#define SHM_RANGE_END	0x60000000
+#ifndef SHMMAX
 #define SHMMAX		0x01000000
 #endif
 
diff -u --recursive --new-file v2.3.25/linux/include/asm-arm/shmparam.h linux/include/asm-arm/shmparam.h
--- v2.3.25/linux/include/asm-arm/shmparam.h	Fri Oct 22 13:21:53 1999
+++ linux/include/asm-arm/shmparam.h	Wed Nov  3 11:31:09 1999
@@ -3,39 +3,6 @@
 
 #include <asm/proc/shmparam.h>
 
-/*
- * Format of a swap-entry for shared memory pages currently out in
- * swap space (see also mm/swap.c).
- *
- * SWP_TYPE = SHM_SWP_TYPE
- * SWP_OFFSET is used as follows:
- *
- *  bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
- *  bits 7..21: index of page within shared memory segment (SHM_IDX)
- *		(actually fewer bits get used since SHMMAX is so low)
- */
-
-/*
- * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
- * there is a static array of size SHMMNI.
- */
-#define _SHM_ID_BITS	7
-#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
-
-#define SHM_IDX_SHIFT	(_SHM_ID_BITS)
-#define _SHM_IDX_BITS	15
-#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
-
-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
-#define SHMMIN 1 /* really PAGE_SIZE */	/* min shared seg size (bytes) */
-#define SHMMNI (1<<_SHM_ID_BITS)	/* max num of segs system wide */
-#define SHMALL				/* max shm system wide (pages) */ \
-	(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
-#define	SHMLBA PAGE_SIZE		/* attach addr a multiple of this */
-#define SHMSEG SHMMNI			/* max shared segs per process */
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
 
 #endif /* _ASMARM_SHMPARAM_H */
diff -u --recursive --new-file v2.3.25/linux/include/asm-i386/pgtable.h linux/include/asm-i386/pgtable.h
--- v2.3.25/linux/include/asm-i386/pgtable.h	Mon Nov  1 13:56:27 1999
+++ linux/include/asm-i386/pgtable.h	Sat Nov  6 19:06:16 1999
@@ -293,7 +293,6 @@
 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; }
 
-#define page_pte_prot(page,prot) mk_pte(page, prot)
 #define page_pte(page) page_pte_prot(page, __pgprot(0))
 
 #define pmd_page(pmd) \
diff -u --recursive --new-file v2.3.25/linux/include/asm-i386/shmparam.h linux/include/asm-i386/shmparam.h
--- v2.3.25/linux/include/asm-i386/shmparam.h	Sun Nov  8 14:06:18 1998
+++ linux/include/asm-i386/shmparam.h	Wed Nov  3 11:31:09 1999
@@ -1,46 +1,6 @@
 #ifndef _ASMI386_SHMPARAM_H
 #define _ASMI386_SHMPARAM_H
 
-/* address range for shared memory attaches if no address passed to shmat() */
-#define SHM_RANGE_START	0x50000000
-#define SHM_RANGE_END	0x60000000
-
-/*
- * Format of a swap-entry for shared memory pages currently out in
- * swap space (see also mm/swap.c).
- *
- * SWP_TYPE = SHM_SWP_TYPE
- * SWP_OFFSET is used as follows:
- *
- *  bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
- *  bits 7..21: index of page within shared memory segment (SHM_IDX)
- *		(actually fewer bits get used since SHMMAX is so low)
- */
-
-/*
- * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
- * there is a static array of size SHMMNI.
- */
-#define _SHM_ID_BITS	7
-#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
-
-#define SHM_IDX_SHIFT	(_SHM_ID_BITS)
-#define _SHM_IDX_BITS	15
-#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
-
-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
-#define SHMMAX 0x2000000		/* max shared seg size (bytes) */
-/* Try not to change the default shipped SHMMAX - people rely on it */
-
-#define SHMMIN 1 /* really PAGE_SIZE */	/* min shared seg size (bytes) */
-#define SHMMNI (1<<_SHM_ID_BITS)	/* max num of segs system wide */
-#define SHMALL				/* max shm system wide (pages) */ \
-	(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
-#define	SHMLBA PAGE_SIZE		/* attach addr a multiple of this */
-#define SHMSEG SHMMNI			/* max shared segs per process */
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
 
 #endif /* _ASMI386_SHMPARAM_H */
diff -u --recursive --new-file v2.3.25/linux/include/asm-m68k/shmparam.h linux/include/asm-m68k/shmparam.h
--- v2.3.25/linux/include/asm-m68k/shmparam.h	Tue Sep  7 12:14:07 1999
+++ linux/include/asm-m68k/shmparam.h	Wed Nov  3 11:31:09 1999
@@ -1,49 +1,6 @@
 #ifndef _M68K_SHMPARAM_H
 #define _M68K_SHMPARAM_H
 
-/* address range for shared memory attaches if no address passed to shmat() */
-#ifndef CONFIG_SUN3
-#define SHM_RANGE_START	0xC0000000
-#define SHM_RANGE_END	0xD0000000
-#else
-#define SHM_RANGE_START	0x0C000000
-#define SHM_RANGE_END	0x0D000000
-#endif
-
-/*
- * Format of a swap-entry for shared memory pages currently out in
- * swap space (see also mm/swap.c).
- *
- * SWP_TYPE = SHM_SWP_TYPE
- * SWP_OFFSET is used as follows:
- *
- *  bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
- *  bits 7..21: index of page within shared memory segment (SHM_IDX)
- *		(actually fewer bits get used since SHMMAX is so low)
- */
-
-/*
- * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
- * there is a static array of size SHMMNI.
- */
-#define _SHM_ID_BITS	7
-#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
-
-#define SHM_IDX_SHIFT	(_SHM_ID_BITS)
-#define _SHM_IDX_BITS	15
-#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
-
-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
-#define SHMMAX 0x1000000		/* max shared seg size (bytes) */
-#define SHMMIN 1 /* really PAGE_SIZE */	/* min shared seg size (bytes) */
-#define SHMMNI (1<<_SHM_ID_BITS)	/* max num of segs system wide */
-#define SHMALL				/* max shm system wide (pages) */ \
-	(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
-#define	SHMLBA PAGE_SIZE		/* attach addr a multiple of this */
-#define SHMSEG SHMMNI			/* max shared segs per process */
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
 
 #endif /* _M68K_SHMPARAM_H */
diff -u --recursive --new-file v2.3.25/linux/include/asm-mips/shmparam.h linux/include/asm-mips/shmparam.h
--- v2.3.25/linux/include/asm-mips/shmparam.h	Fri Jun 25 17:37:53 1999
+++ linux/include/asm-mips/shmparam.h	Wed Nov  3 11:31:09 1999
@@ -1,49 +1,9 @@
 #ifndef __ASM_MIPS_SHMPARAM_H
 #define __ASM_MIPS_SHMPARAM_H
 
-/* address range for shared memory attaches if no address passed to shmat() */
-#define SHM_RANGE_START	0x50000000
-#define SHM_RANGE_END	0x60000000
-
-/*
- * Format of a swap-entry for shared memory pages currently out in
- * swap space (see also mm/swap.c).
- *
- * SWP_TYPE = SHM_SWP_TYPE
- * SWP_OFFSET is used as follows:
- *
- *  bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
- *  bits 7..21: index of page within shared memory segment (SHM_IDX)
- *		(actually fewer bits get used since SHMMAX is so low)
- */
-
-/*
- * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
- * there is a static array of size SHMMNI.
- */
-#define _SHM_ID_BITS	7
-#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
-
-#define SHM_IDX_SHIFT	(_SHM_ID_BITS)
-#define _SHM_IDX_BITS	15
-#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
-
-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
-#define SHMMAX 0x2000000		/* max shared seg size (bytes) */
-/* Try not to change the default shipped SHMMAX - people rely on it */
-
-#define SHMMIN 1 /* really PAGE_SIZE */	/* min shared seg size (bytes) */
-#define SHMMNI (1<<_SHM_ID_BITS)	/* max num of segs system wide */
-#define SHMALL				/* max shm system wide (pages) */ \
-	(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
 /*
  * This constant is very large but the ABI in it's wisdom says ...
  */
 #define	SHMLBA 0x40000			/* attach addr a multiple of this */
-#define SHMSEG SHMMNI			/* max shared segs per process */
 
 #endif /* __ASM_MIPS_SHMPARAM_H */
diff -u --recursive --new-file v2.3.25/linux/include/asm-ppc/amigaints.h linux/include/asm-ppc/amigaints.h
--- v2.3.25/linux/include/asm-ppc/amigaints.h	Tue Aug  4 16:06:36 1998
+++ linux/include/asm-ppc/amigaints.h	Fri Nov  5 15:53:26 1999
@@ -1 +1,135 @@
-#include <asm-m68k/amigaints.h>
+/*
+** amigaints.h -- Amiga Linux interrupt handling structs and prototypes
+**
+** 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 10/2/92 by Greg Harp
+*/
+
+#ifndef _ASMm68k_AMIGAINTS_H_
+#define _ASMm68k_AMIGAINTS_H_
+
+/*
+** Amiga Interrupt sources.
+**
+*/
+
+#define AUTO_IRQS           (8)
+#define AMI_STD_IRQS        (14)
+#define CIA_IRQS            (5)
+#define AMI_IRQS            (32) /* AUTO_IRQS+AMI_STD_IRQS+2*CIA_IRQS */
+
+/* vertical blanking interrupt */
+#define IRQ_AMIGA_VERTB     0
+
+/* copper interrupt */
+#define IRQ_AMIGA_COPPER    1
+
+/* Audio interrupts */
+#define IRQ_AMIGA_AUD0	    2
+#define IRQ_AMIGA_AUD1	    3
+#define IRQ_AMIGA_AUD2	    4
+#define IRQ_AMIGA_AUD3	    5
+
+/* Blitter done interrupt */
+#define IRQ_AMIGA_BLIT	    6
+
+/* floppy disk interrupts */
+#define IRQ_AMIGA_DSKSYN    7
+#define IRQ_AMIGA_DSKBLK    8
+
+/* builtin serial port interrupts */
+#define IRQ_AMIGA_RBF	    9
+#define IRQ_AMIGA_TBE	    10
+
+/* software interrupts */
+#define IRQ_AMIGA_SOFT      11
+
+/* interrupts from external hardware */
+#define IRQ_AMIGA_PORTS	    12
+#define IRQ_AMIGA_EXTER	    13
+
+/* CIA interrupt sources */
+#define IRQ_AMIGA_CIAA      14
+#define IRQ_AMIGA_CIAA_TA   14
+#define IRQ_AMIGA_CIAA_TB   15
+#define IRQ_AMIGA_CIAA_ALRM 16
+#define IRQ_AMIGA_CIAA_SP   17
+#define IRQ_AMIGA_CIAA_FLG  18
+#define IRQ_AMIGA_CIAB      19
+#define IRQ_AMIGA_CIAB_TA   19
+#define IRQ_AMIGA_CIAB_TB   20
+#define IRQ_AMIGA_CIAB_ALRM 21
+#define IRQ_AMIGA_CIAB_SP   22
+#define IRQ_AMIGA_CIAB_FLG  23
+
+/* auto-vector interrupts */
+#define IRQ_AMIGA_AUTO      24
+#define IRQ_AMIGA_AUTO_0    24 /* This is just a dummy */
+#define IRQ_AMIGA_AUTO_1    25
+#define IRQ_AMIGA_AUTO_2    26
+#define IRQ_AMIGA_AUTO_3    27
+#define IRQ_AMIGA_AUTO_4    28
+#define IRQ_AMIGA_AUTO_5    29
+#define IRQ_AMIGA_AUTO_6    30
+#define IRQ_AMIGA_AUTO_7    31
+
+#define IRQ_FLOPPY	    IRQ_AMIGA_DSKBLK
+
+/* INTREQR masks */
+#define IRQ1_MASK   0x0007	/* INTREQR mask for IRQ 1 */
+#define IRQ2_MASK   0x0008	/* INTREQR mask for IRQ 2 */
+#define IRQ3_MASK   0x0070	/* INTREQR mask for IRQ 3 */
+#define IRQ4_MASK   0x0780	/* INTREQR mask for IRQ 4 */
+#define IRQ5_MASK   0x1800	/* INTREQR mask for IRQ 5 */
+#define IRQ6_MASK   0x2000	/* INTREQR mask for IRQ 6 */
+#define IRQ7_MASK   0x4000	/* INTREQR mask for IRQ 7 */
+
+#define IF_SETCLR   0x8000      /* set/clr bit */
+#define IF_INTEN    0x4000	/* master interrupt bit in INT* registers */
+#define IF_EXTER    0x2000	/* external level 6 and CIA B interrupt */
+#define IF_DSKSYN   0x1000	/* disk sync interrupt */
+#define IF_RBF	    0x0800	/* serial receive buffer full interrupt */
+#define IF_AUD3     0x0400	/* audio channel 3 done interrupt */
+#define IF_AUD2     0x0200	/* audio channel 2 done interrupt */
+#define IF_AUD1     0x0100	/* audio channel 1 done interrupt */
+#define IF_AUD0     0x0080	/* audio channel 0 done interrupt */
+#define IF_BLIT     0x0040	/* blitter done interrupt */
+#define IF_VERTB    0x0020	/* vertical blanking interrupt */
+#define IF_COPER    0x0010	/* copper interrupt */
+#define IF_PORTS    0x0008	/* external level 2 and CIA A interrupt */
+#define IF_SOFT     0x0004	/* software initiated interrupt */
+#define IF_DSKBLK   0x0002	/* diskblock DMA finished */
+#define IF_TBE	    0x0001	/* serial transmit buffer empty interrupt */
+
+struct irq_server {
+	unsigned short count, reentrance;
+};
+
+extern void amiga_do_irq(int irq, struct pt_regs *fp);
+extern void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server);
+
+/* CIA interrupt control register bits */
+
+#define CIA_ICR_TA	0x01
+#define CIA_ICR_TB	0x02
+#define CIA_ICR_ALRM	0x04
+#define CIA_ICR_SP	0x08
+#define CIA_ICR_FLG	0x10
+#define CIA_ICR_ALL	0x1f
+#define CIA_ICR_SETCLR	0x80
+
+/* to access the interrupt control registers of CIA's use only
+** these functions, they behave exactly like the amiga os routines
+*/
+
+extern struct ciabase ciaa_base, ciab_base;
+
+extern unsigned char cia_set_irq(unsigned int irq, int set);
+extern unsigned char cia_able_irq(unsigned int irq, int enable);
+
+#endif /* asm-m68k/amigaints.h */
diff -u --recursive --new-file v2.3.25/linux/include/asm-ppc/pgtable.h linux/include/asm-ppc/pgtable.h
--- v2.3.25/linux/include/asm-ppc/pgtable.h	Wed Oct 27 16:34:12 1999
+++ linux/include/asm-ppc/pgtable.h	Fri Nov  5 15:53:26 1999
@@ -629,9 +629,12 @@
 extern void flush_hash_page(unsigned context, unsigned long va);
 
 
-#define SWP_TYPE(entry) (((pte_val(entry)) >> 1) & 0x7f)
-#define SWP_OFFSET(entry) ((pte_val(entry)) >> 8)
-#define SWP_ENTRY(type,offset) __pte(((type) << 1) | ((offset) << 8))
+/* 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 pte_to_swp_entry(pte)		((swp_entry_t) { pte_val(pte) })
+#define swp_entry_to_pte(x)		((pte_t) { (x).val })
 
 #define module_map      vmalloc
 #define module_unmap    vfree
diff -u --recursive --new-file v2.3.25/linux/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h
--- v2.3.25/linux/include/asm-ppc/processor.h	Sat Oct  9 11:47:50 1999
+++ linux/include/asm-ppc/processor.h	Fri Nov  5 15:53:26 1999
@@ -17,6 +17,7 @@
 #define MSR_SF		(1<<63)
 #define MSR_ISF		(1<<61)
 #endif /* CONFIG_PPC64 */
+#define MSR_VEC		(1<<25)		/* Enable AltiVec */
 #define MSR_POW		(1<<18)		/* Enable Power Management */
 #define MSR_TGPR	(1<<17)		/* TLB Update registers in use */
 #define MSR_ILE		(1<<16)		/* Interrupt Little-Endian enable */
@@ -249,6 +250,7 @@
 
 /* Lazy FPU handling on uni-processor */
 extern struct task_struct *last_task_used_math;
+extern struct task_struct *last_task_used_altivec;
 
 /*
  * this is the minimum allowable io space due to the location
@@ -277,6 +279,9 @@
 	double		fpr[32];	/* Complete floating point set */
 	unsigned long	fpscr_pad;	/* fpr ... fpscr must be contiguous */
 	unsigned long	fpscr;		/* Floating point status */
+	unsigned long	vrf[128];
+	unsigned long	vscr;
+	unsigned long	vrsave;
 };
 
 #define INIT_SP		(sizeof(init_stack) + (unsigned long) &init_stack)
diff -u --recursive --new-file v2.3.25/linux/include/asm-ppc/shmparam.h linux/include/asm-ppc/shmparam.h
--- v2.3.25/linux/include/asm-ppc/shmparam.h	Sat Oct  9 11:47:50 1999
+++ linux/include/asm-ppc/shmparam.h	Wed Nov  3 11:31:09 1999
@@ -1,44 +1,6 @@
 #ifndef _PPC_SHMPARAM_H
 #define _PPC_SHMPARAM_H
 
-/* address range for shared memory attaches if no address passed to shmat() */
-#define SHM_RANGE_START	0x50000000
-#define SHM_RANGE_END	0x60000000
-
-/*
- * Format of a swap-entry for shared memory pages currently out in
- * swap space (see also mm/swap.c).
- *
- * SWP_TYPE = SHM_SWP_TYPE
- * SWP_OFFSET is used as follows:
- *
- *  bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
- *  bits 7..21: index of page within shared memory segment (SHM_IDX)
- *		(actually fewer bits get used since SHMMAX is so low)
- */
-
-/*
- * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
- * there is a static array of size SHMMNI.
- */
-#define _SHM_ID_BITS	7
-#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
-
-#define SHM_IDX_SHIFT	(_SHM_ID_BITS)
-#define _SHM_IDX_BITS	15
-#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
-
-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
-#define SHMMAX 0x2000000		/* max shared seg size (bytes) */
-#define SHMMIN 1 /* really PAGE_SIZE */	/* min shared seg size (bytes) */
-#define SHMMNI (1<<_SHM_ID_BITS)	/* max num of segs system wide */
-#define SHMALL				/* max shm system wide (pages) */ \
-	(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
-#define	SHMLBA PAGE_SIZE		/* attach addr a multiple of this */
-#define SHMSEG SHMMNI			/* max shared segs per process */
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
 
 #endif /* _PPC_SHMPARAM_H */
diff -u --recursive --new-file v2.3.25/linux/include/asm-ppc/system.h linux/include/asm-ppc/system.h
--- v2.3.25/linux/include/asm-ppc/system.h	Sat Oct  9 11:47:50 1999
+++ linux/include/asm-ppc/system.h	Fri Nov  5 15:53:26 1999
@@ -61,6 +61,8 @@
 extern void pmac_find_display(void);
 extern void giveup_fpu(struct task_struct *);
 extern void enable_kernel_fp(void);
+extern void giveup_altivec(struct task_struct *);
+extern void load_up_altivec(struct task_struct *);
 extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
 extern void cvt_df(double *from, float *to, unsigned long *fpscr);
 extern int call_rtas(const char *, int, int, unsigned long *, ...);
diff -u --recursive --new-file v2.3.25/linux/include/asm-sh/bitops.h linux/include/asm-sh/bitops.h
--- v2.3.25/linux/include/asm-sh/bitops.h	Fri Oct 22 13:21:54 1999
+++ linux/include/asm-sh/bitops.h	Sat Nov  6 10:40:31 1999
@@ -96,7 +96,7 @@
 
 extern __inline__ int test_bit(int nr, const void *addr)
 {
-	return 1UL & (((const int *) addr)[nr >> 5] >> (nr & 31));
+	return 1UL & (((const unsigned int *) addr)[nr >> 5] >> (nr & 31));
 }
 
 extern __inline__ unsigned long ffz(unsigned long word)
@@ -107,8 +107,8 @@
 		"shlr	%1\n\t"
 		"bt/s	1b\n\t"
 		" add	#1, %0"
-		: "=r" (result)
-		: "r" (word), "0" (~0L));
+		: "=r" (result), "=r" (word)
+		: "0" (~0L), "1" (word));
 	return result;
 }
 
@@ -151,10 +151,18 @@
 #define find_first_zero_bit(addr, size) \
         find_next_zero_bit((addr), (size), 0)
 
+#ifdef __LITTLE_ENDIAN__
+#define ext2_set_bit(nr, addr) test_and_set_bit((nr), (addr))
+#define ext2_clear_bit(nr, addr) test_and_clear_bit((nr), (addr))
+#define ext2_test_bit(nr, addr) test_bit((nr), (addr))
+#define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size))
+#define ext2_find_next_zero_bit(addr, size, offset) \
+                find_next_zero_bit((addr), (size), (offset))
+#else
 extern __inline__ int ext2_set_bit(int nr,void * addr)
 {
 	int		mask, retval;
-	unsigned long flags;
+	unsigned long	flags;
 	unsigned char	*ADDR = (unsigned char *) addr;
 
 	ADDR += nr >> 3;
@@ -169,7 +177,7 @@
 extern __inline__ int ext2_clear_bit(int nr, void * addr)
 {
 	int		mask, retval;
-	unsigned long flags;
+	unsigned long	flags;
 	unsigned char	*ADDR = (unsigned char *) addr;
 
 	ADDR += nr >> 3;
@@ -243,6 +251,7 @@
 found_middle:
 	return result + ffz(__swab32(tmp));
 }
+#endif
 
 /* Bitmap functions for the minix filesystem.  */
 #define minix_set_bit(nr,addr) test_and_set_bit(nr,addr)
diff -u --recursive --new-file v2.3.25/linux/include/asm-sh/io.h linux/include/asm-sh/io.h
--- v2.3.25/linux/include/asm-sh/io.h	Fri Oct 22 13:21:54 1999
+++ linux/include/asm-sh/io.h	Sat Nov  6 10:40:31 1999
@@ -72,6 +72,24 @@
        return readl(addr);
 }
 
+extern __inline__ void insb(unsigned long addr, void *buffer, int count)
+{
+	unsigned char *buf=buffer;
+	while(count--) *buf++=inb(addr);
+}
+
+extern __inline__ void insw(unsigned long addr, void *buffer, int count)
+{
+	unsigned short *buf=buffer;
+	while(count--) *buf++=inw(addr);
+}
+
+extern __inline__ void insl(unsigned long addr, void *buffer, int count)
+{
+	unsigned long *buf=buffer;
+	while(count--) *buf++=inl(addr);
+}
+
 extern __inline__ void outb(unsigned char b, unsigned long addr)
 {
        return writeb(b,addr);
@@ -85,6 +103,24 @@
 extern __inline__ void outl(unsigned int b, unsigned long addr)
 {
        return writel(b,addr);
+}
+
+extern __inline__ void outsb(unsigned long addr, const void *buffer, int count)
+{
+	const unsigned char *buf=buffer;
+	while(count--) outb(*buf++, addr);
+}
+
+extern __inline__ void outsw(unsigned long addr, const void *buffer, int count)
+{
+	const unsigned short *buf=buffer;
+	while(count--) outw(*buf++, addr);
+}
+
+extern __inline__ void outsl(unsigned long addr, const void *buffer, int count)
+{
+	const unsigned long *buf=buffer;
+	while(count--) outl(*buf++, addr);
 }
 
 extern __inline__ unsigned long ctrl_inb(unsigned long addr)
diff -u --recursive --new-file v2.3.25/linux/include/asm-sh/ioctls.h linux/include/asm-sh/ioctls.h
--- v2.3.25/linux/include/asm-sh/ioctls.h	Fri Oct 22 13:21:54 1999
+++ linux/include/asm-sh/ioctls.h	Sat Nov  6 10:40:31 1999
@@ -10,10 +10,10 @@
 #define FIONREAD	_IOR('f', 127, int)
 #define TIOCINQ		FIONREAD
 
-#define TCGETS		_IOR('t', 19, struct termios)
-#define TCSETS		_IOW('t', 20, struct termios)
-#define TCSETSW		_IOW('t', 21, struct termios)
-#define TCSETSF		_IOW('t', 22, struct termios)
+#define TCGETS		0x5401
+#define TCSETS		0x5402
+#define TCSETSW		0x5403
+#define TCSETSF		0x5404
 
 #define TCGETA		_IOR('t', 23, struct termio)
 #define TCSETA		_IOW('t', 24, struct termio)
@@ -84,8 +84,8 @@
 #define TIOCSERCONFIG	_IO('T', 83) /* 0x5453 */
 #define TIOCSERGWILD	_IOR('T', 84,  int) /* 0x5454 */
 #define TIOCSERSWILD	_IOW('T', 85,  int) /* 0x5455 */
-#define TIOCGLCKTRMIOS	_IOR('T', 86, struct termios) /* 0x5456 */
-#define TIOCSLCKTRMIOS	_IOW('T', 87, struct termios) /* 0x5457 */
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
 #define TIOCSERGSTRUCT	_IOR('T', 88, struct async_struct) /* 0x5458 */ /* For debugging only */
 #define TIOCSERGETLSR   _IOR('T', 89, unsigned int) /* 0x5459 */ /* Get line status register */
   /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
diff -u --recursive --new-file v2.3.25/linux/include/asm-sh/irq.h linux/include/asm-sh/irq.h
--- v2.3.25/linux/include/asm-sh/irq.h	Fri Oct 22 13:21:54 1999
+++ linux/include/asm-sh/irq.h	Sat Nov  6 10:40:31 1999
@@ -9,10 +9,13 @@
  *
  */
 
+#include <linux/config.h>
+
 #define TIMER_IRQ		16	/* Hard-wired */
 #define TIMER_IRP_OFFSET	12
 #define TIMER_PRIORITY		 1
 
+#if defined(__SH4__)
 /*
  * 48 = 32+16
  *
@@ -21,6 +24,11 @@
  *
  */
 #define NR_IRQS	48
+#elif defined(CONFIG_CPU_SUBTYPE_SH7708)
+#define NR_IRQS 32
+#elif defined(CONFIG_CPU_SUBTYPE_SH7709)
+#define NR_IRQS 61
+#endif
 
 extern void disable_irq(unsigned int);
 extern void disable_irq_nosync(unsigned int);
diff -u --recursive --new-file v2.3.25/linux/include/asm-sh/mmu_context.h linux/include/asm-sh/mmu_context.h
--- v2.3.25/linux/include/asm-sh/mmu_context.h	Wed Oct 27 16:34:12 1999
+++ linux/include/asm-sh/mmu_context.h	Sat Nov  6 10:40:31 1999
@@ -16,10 +16,13 @@
  */
 extern unsigned long mmu_context_cache;
 
-#define MMU_CONTEXT_ASID_MASK 0xff
-#define MMU_CONTEXT_VERSION_MASK 0xffffff00
-#define MMU_CONTEXT_FIRST_VERSION 0x100
-#define NO_CONTEXT 0
+#define MMU_CONTEXT_ASID_MASK		0x000000ff
+#define MMU_CONTEXT_VERSION_MASK	0xffffff00
+#define MMU_CONTEXT_FIRST_VERSION	0x00000100
+#define NO_CONTEXT			0
+
+/* ASID is 8-bit value, so it can't be 0x100 */
+#define MMU_NO_ASID			0x100
 
 extern __inline__ void
 get_new_mmu_context(struct mm_struct *mm)
@@ -34,7 +37,7 @@
 		flush_tlb_all();
 		/* Fix version if needed.
 		   Note that we avoid version #0 to distingush NO_CONTEXT. */
-		if (!mc) 
+		if (!mc)
 			mmu_context_cache = mc = MMU_CONTEXT_FIRST_VERSION;
 	}
 	mm->context = mc;
@@ -71,7 +74,7 @@
  */
 extern __inline__ void destroy_context(struct mm_struct *mm)
 {
-	mm->context = NO_CONTEXT;
+	/* Do nothing */
 }
 
 /* Other MMU related constants. */
@@ -84,11 +87,11 @@
 
 #define MMUCR		0xFFFFFFE0	/* MMU Control Register */
 
-#define MMU_TLB_ADDRESS_ARRAY 0xF2000000
-#define MMU_PAGE_ASSOC_BIT 0x80
+#define MMU_TLB_ADDRESS_ARRAY	0xF2000000
+#define MMU_PAGE_ASSOC_BIT	0x80
 
-#define MMU_NTLB_ENTRIES       128	/* for 7708 */
-#define MMU_CONTROL_INIT 0x007	/* SV=0, TF=1, IX=1, AT=1 */
+#define MMU_NTLB_ENTRIES	128	/* for 7708 */
+#define MMU_CONTROL_INIT	0x007	/* SV=0, TF=1, IX=1, AT=1 */
 
 #elif defined(__SH4__)
 #define MMU_PTEH	0xFF000000	/* Page table entry register HIGH */
@@ -98,26 +101,26 @@
 
 #define MMUCR		0xFF000010	/* MMU Control Register */
 
-#define MMU_ITLB_ADDRESS_ARRAY 0xF2000000
-#define MMU_UTLB_ADDRESS_ARRAY 0xF6000000
-#define MMU_PAGE_ASSOC_BIT 0x80
+#define MMU_ITLB_ADDRESS_ARRAY	0xF2000000
+#define MMU_UTLB_ADDRESS_ARRAY	0xF6000000
+#define MMU_PAGE_ASSOC_BIT	0x80
 
-#define MMU_NTLB_ENTRIES       64	/* for 7750 */
-#define MMU_CONTROL_INIT 0x205	/* SQMD=1, SV=0, TI=1, AT=1 */
+#define MMU_NTLB_ENTRIES	64	/* for 7750 */
+#define MMU_CONTROL_INIT	0x205	/* SQMD=1, SV=0, TI=1, AT=1 */
 #endif
 
-extern __inline__ void set_asid (unsigned long asid)
+extern __inline__ void set_asid(unsigned long asid)
 {
 	__asm__ __volatile__ ("mov.l	%0,%1"
 			      : /* no output */
 			      : "r" (asid), "m" (__m(MMU_PTEH)));
 }
 
-extern __inline__ unsigned long get_asid (void)
+extern __inline__ unsigned long get_asid(void)
 {
 	unsigned long asid;
 
-	__asm__ __volatile__ ("mov.l %1,%0"
+	__asm__ __volatile__ ("mov.l	%1,%0"
 			      : "=r" (asid)
 			      : "m" (__m(MMU_PTEH)));
 	asid &= MMU_CONTEXT_ASID_MASK;
@@ -143,8 +146,9 @@
 	if (prev != next) {
 		unsigned long __pgdir = (unsigned long)next->pgd;
 
-		__asm__ __volatile__("mov.l	%0,%1": \
-				     :"r" (__pgdir), "m" (__m(MMU_TTB)));
+		__asm__ __volatile__("mov.l	%0,%1"
+				     : /* no output */
+				     : "r" (__pgdir), "m" (__m(MMU_TTB)));
 		activate_context(next);
 		clear_bit(cpu, &prev->cpu_vm_mask);
 	}
diff -u --recursive --new-file v2.3.25/linux/include/asm-sh/page.h linux/include/asm-sh/page.h
--- v2.3.25/linux/include/asm-sh/page.h	Wed Oct 27 16:34:12 1999
+++ linux/include/asm-sh/page.h	Sat Nov  6 10:40:31 1999
@@ -39,9 +39,6 @@
 #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__ */
@@ -56,13 +53,12 @@
  *
  * which has the same constant encoded..
  */
-#define __PAGE_OFFSET		(0x80000000)
 
 #define __MEMORY_START		CONFIG_MEMORY_START
 
-#define PAGE_OFFSET		((unsigned long)__PAGE_OFFSET+__MEMORY_START)
-#define __pa(x)			((unsigned long)(x)-__PAGE_OFFSET)
-#define __va(x)			((void *)((unsigned long)(x)+__PAGE_OFFSET))
+#define PAGE_OFFSET		(0x80000000)
+#define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
+#define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))
 #define MAP_NR(addr)		((__pa(addr)-__MEMORY_START) >> PAGE_SHIFT)
 
 #ifndef __ASSEMBLY__
@@ -74,7 +70,6 @@
  */
 #define BUG() do { \
 	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-	console_loglevel = 0; \
 	asm volatile("nop"); \
 } while (0)
 
diff -u --recursive --new-file v2.3.25/linux/include/asm-sh/pgtable-2level.h linux/include/asm-sh/pgtable-2level.h
--- v2.3.25/linux/include/asm-sh/pgtable-2level.h	Wed Oct 27 16:34:12 1999
+++ linux/include/asm-sh/pgtable-2level.h	Sat Nov  6 10:40:31 1999
@@ -32,7 +32,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))
@@ -56,7 +56,5 @@
 		BUG();
 	return (pmd_t *) pgd;
 }
-
-#define SWP_ENTRY(type,offset) __pte((((type) << 1) | ((offset) << 8)))
 
 #endif /* __ASM_SH_PGTABLE_2LEVEL_H */
diff -u --recursive --new-file v2.3.25/linux/include/asm-sh/pgtable.h linux/include/asm-sh/pgtable.h
--- v2.3.25/linux/include/asm-sh/pgtable.h	Wed Oct 27 16:34:12 1999
+++ linux/include/asm-sh/pgtable.h	Sat Nov  6 10:40:31 1999
@@ -92,7 +92,7 @@
 #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
 
 #define TWOLEVEL_PGDIR_SHIFT	22
-#define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
+#define BOOT_USER_PGD_PTRS (PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
 #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
 
 #ifndef __ASSEMBLY__
@@ -183,7 +183,7 @@
 #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_pagenr(x)	((unsigned long)((pte_val(x) >> PAGE_SHIFT)))
+#define pte_pagenr(x)	((unsigned long)(((pte_val(x) -__MEMORY_START) >> PAGE_SHIFT)))
 
 #define pmd_none(x)	(!pmd_val(x))
 #define	pmd_bad(x)	((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
@@ -194,7 +194,7 @@
  * Permanent address of a page. Obviously must never be
  * called on a highmem page.
  */
-#define page_address(page) ({ if (PageHighMem(page)) BUG(); PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT); })
+#define page_address(page) ({ PAGE_OFFSET + (((page) - mem_map) << PAGE_SHIFT) + __MEMORY_START; })
 #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
 #define pte_page(x) (mem_map+pte_pagenr(x))
 
@@ -228,7 +228,7 @@
 	pte_t __pte;
 
 	pte_val(__pte) = (page-mem_map)*(unsigned long long)PAGE_SIZE +
-				pgprot_val(pgprot);
+				__MEMORY_START + pgprot_val(pgprot);
 	return __pte;
 }
 
@@ -274,8 +274,13 @@
 	pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL);
 
 	if (ret) {
+		/* Clear User space */
 		memset(ret, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
-		memcpy(ret + USER_PTRS_PER_PGD, swapper_pg_dir + USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+
+		/* XXX: Copy vmalloc-ed space??? */
+		memcpy(ret + USER_PTRS_PER_PGD,
+		       swapper_pg_dir + USER_PTRS_PER_PGD,
+		       (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
 	}
 	return ret;
 }
@@ -412,8 +417,12 @@
 extern void update_mmu_cache(struct vm_area_struct * vma,
 			     unsigned long address, pte_t pte);
 
-#define SWP_TYPE(entry) (((pte_val(entry)) >> 1) & 0x3f)
-#define SWP_OFFSET(entry) ((pte_val(entry)) >> 8)
+/* Encode and de-code a swap entry */
+#define SWP_TYPE(x)			(((x).val >> 1) & 0x3f)
+#define SWP_OFFSET(x)			((x).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 })
 
 #define module_map      vmalloc
 #define module_unmap    vfree
diff -u --recursive --new-file v2.3.25/linux/include/asm-sh/resource.h linux/include/asm-sh/resource.h
--- v2.3.25/linux/include/asm-sh/resource.h	Tue Aug 31 17:29:14 1999
+++ linux/include/asm-sh/resource.h	Sat Nov  6 10:40:31 1999
@@ -22,16 +22,16 @@
 
 #define INIT_RLIMITS					\
 {							\
-	{ LONG_MAX, LONG_MAX },				\
-	{ LONG_MAX, LONG_MAX },				\
-	{ LONG_MAX, LONG_MAX },				\
-	{ _STK_LIM, LONG_MAX },				\
-	{        0, LONG_MAX },				\
-	{ LONG_MAX, LONG_MAX },				\
-	{ 0, 0 },					\
-	{ INR_OPEN, INR_OPEN },				\
-	{ LONG_MAX, LONG_MAX },				\
-	{ LONG_MAX, LONG_MAX },				\
+	{ 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.25/linux/include/asm-sh/shmparam.h linux/include/asm-sh/shmparam.h
--- v2.3.25/linux/include/asm-sh/shmparam.h	Tue Aug 31 17:29:14 1999
+++ linux/include/asm-sh/shmparam.h	Wed Nov  3 11:31:09 1999
@@ -1,46 +1,6 @@
 #ifndef __ASM_SH_SHMPARAM_H
 #define __ASM_SH_SHMPARAM_H
 
-/* address range for shared memory attaches if no address passed to shmat() */
-#define SHM_RANGE_START	0x50000000
-#define SHM_RANGE_END	0x60000000
-
-/*
- * Format of a swap-entry for shared memory pages currently out in
- * swap space (see also mm/swap.c).
- *
- * SWP_TYPE = SHM_SWP_TYPE
- * SWP_OFFSET is used as follows:
- *
- *  bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
- *  bits 7..21: index of page within shared memory segment (SHM_IDX)
- *		(actually fewer bits get used since SHMMAX is so low)
- */
-
-/*
- * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
- * there is a static array of size SHMMNI.
- */
-#define _SHM_ID_BITS	7
-#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
-
-#define SHM_IDX_SHIFT	(_SHM_ID_BITS)
-#define _SHM_IDX_BITS	15
-#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
-
-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
-#define SHMMAX 0x2000000		/* max shared seg size (bytes) */
-/* Try not to change the default shipped SHMMAX - people rely on it */
-
-#define SHMMIN 1 /* really PAGE_SIZE */	/* min shared seg size (bytes) */
-#define SHMMNI (1<<_SHM_ID_BITS)	/* max num of segs system wide */
-#define SHMALL				/* max shm system wide (pages) */ \
-	(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
-#define	SHMLBA PAGE_SIZE		/* attach addr a multiple of this */
-#define SHMSEG SHMMNI			/* max shared segs per process */
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
 
 #endif /* __ASM_SH_SHMPARAM_H */
diff -u --recursive --new-file v2.3.25/linux/include/asm-sh/spinlock.h linux/include/asm-sh/spinlock.h
--- v2.3.25/linux/include/asm-sh/spinlock.h	Wed Oct 27 16:34:12 1999
+++ linux/include/asm-sh/spinlock.h	Sat Nov  6 10:40:31 1999
@@ -1,53 +1,6 @@
 #ifndef __ASM_SH_SPINLOCK_H
 #define __ASM_SH_SPINLOCK_H
 
-#ifndef __SMP__
-
-typedef struct { } spinlock_t;
-#define SPIN_LOCK_UNLOCKED { }
-
-#define spin_lock_init(lock)	do { } while(0)
-#define spin_lock(lock)		do { } while(0)
-#define spin_trylock(lock)	(1)
-#define spin_unlock_wait(lock)	do { } while(0)
-#define spin_unlock(lock)	do { } while(0)
-#define spin_lock_irq(lock)	cli()
-#define spin_unlock_irq(lock)	sti()
-
-#define spin_lock_irqsave(lock, flags)		save_and_cli(flags)
-#define spin_unlock_irqrestore(lock, flags)	restore_flags(flags)
-
-/*
- * Read-write spinlocks, allowing multiple readers
- * but only one writer.
- *
- * NOTE! it is quite common to have readers in interrupts
- * but no interrupt writers. For those circumstances we
- * can "mix" irq-safe locks - any writer needs to get a
- * irq-safe write-lock, but readers can get non-irqsafe
- * read-locks.
- */
-typedef struct { } rwlock_t;
-#define RW_LOCK_UNLOCKED (rwlock_t) { }
-
-#define read_lock(lock)		do { } while(0)
-#define read_unlock(lock)	do { } while(0)
-#define write_lock(lock)	do { } while(0)
-#define write_unlock(lock)	do { } while(0)
-#define read_lock_irq(lock)	cli()
-#define read_unlock_irq(lock)	sti()
-#define write_lock_irq(lock)	cli()
-#define write_unlock_irq(lock)	sti()
-
-#define read_lock_irqsave(lock, flags)		save_and_cli(flags)
-#define read_unlock_irqrestore(lock, flags)	restore_flags(flags)
-#define write_lock_irqsave(lock, flags)		save_and_cli(flags)
-#define write_unlock_irqrestore(lock, flags)	restore_flags(flags)
-
-#else
-
 #error "No SMP on SH"
-
-#endif /* SMP */
 
 #endif /* __ASM_SH_SPINLOCK_H */
diff -u --recursive --new-file v2.3.25/linux/include/asm-sh/string.h linux/include/asm-sh/string.h
--- v2.3.25/linux/include/asm-sh/string.h	Wed Oct 27 16:34:12 1999
+++ linux/include/asm-sh/string.h	Sat Nov  6 10:40:31 1999
@@ -120,24 +120,6 @@
 #define __HAVE_ARCH_BCOPY
 
 #define __HAVE_ARCH_MEMSCAN
-extern __inline__ void *memscan(void *__addr, int __c, size_t __size)
-{
-	register char *__end;
-	unsigned long __dummy;
-
-	__asm__("mov	#0,%2\n"
-		"1:\n\t"
-		"cmp/eq	%0,%1\n\t"
-		"bt	2f\n\t"
-		"cmp/eq	%5,%2\n\t"
-		"bf/s	1b\n\t"
-		" mov.b	@%0+,%2\n\t"
-		"add	#-1,%0\n\t"
-		"2:"
-		: "=r" (__addr), "=r" (__end), "=&z" (__dummy)
-		: "0" (__addr), "1" ((char *)__addr + __size), "r" (__c));
-
-	return __addr;
-}
+#define memscan memchr
 
 #endif /* __ASM_SH_STRING_H */
diff -u --recursive --new-file v2.3.25/linux/include/asm-sh/uaccess.h linux/include/asm-sh/uaccess.h
--- v2.3.25/linux/include/asm-sh/uaccess.h	Fri Oct 22 13:21:55 1999
+++ linux/include/asm-sh/uaccess.h	Sat Nov  6 10:40:31 1999
@@ -1,4 +1,4 @@
-/* $Id: uaccess.h,v 1.3 1999/10/12 14:46:20 gniibe Exp $
+/* $Id: uaccess.h,v 1.6 1999/10/29 13:10:44 gniibe Exp $
  *
  * User space memory access functions
  *
@@ -392,16 +392,14 @@
 	unsigned long __dummy;
 
 	__asm__ __volatile__(
-		"mov	#-1,%1\n"
-		"9:\n\t"
+		"9:\n"
 		"cmp/eq	%4,%0\n\t"
-		"bt	5f\n\t"
-		"cmp/eq	#0,%1\n\t"
-		"bf/s	9b\n\t"
+		"bt	2f\n"
 		"1:\t"
-		" mov.b	@%0+,%1\n\t"
-		"5:\t"
-		"sub	%3,%0\n"
+		"mov.b	@(%0,%3),%1\n\t"
+		"tst	%1,%1\n\t"
+		"bf/s	9b\n\t"
+		" add	#1,%0\n"
 		"2:\n"
 		".section .fixup,\"ax\"\n"
 		"3:\n\t"
@@ -415,14 +413,14 @@
 		"	.balign 4\n"
 		"	.long 1b,3b\n"
 		".previous"
-		: "=&r" (res), "=&z" (__dummy)
-		: "0" (__s), "r" (__s), "r" (__s+__n), "i" (-EFAULT));
+		: "=z" (res), "=&r" (__dummy)
+		: "0" (0), "r" (__s), "r" (__n), "i" (-EFAULT));
 	return res;
 }
 
 extern __inline__ long strnlen_user(const char *s, long n)
 {
-	if(!access_ok(VERIFY_READ, s, n))
+	if (!__addr_ok(s))
 		return 0;
 	else
 		return __strnlen_user(s, n);
diff -u --recursive --new-file v2.3.25/linux/include/asm-sparc/shmparam.h linux/include/asm-sparc/shmparam.h
--- v2.3.25/linux/include/asm-sparc/shmparam.h	Sun Oct  4 10:22:44 1998
+++ linux/include/asm-sparc/shmparam.h	Wed Nov  3 11:31:09 1999
@@ -2,44 +2,6 @@
 #ifndef _ASMSPARC_SHMPARAM_H
 #define _ASMSPARC_SHMPARAM_H
 
-/* address range for shared memory attaches if no address passed to shmat() */
-#define SHM_RANGE_START	0x10000000
-#define SHM_RANGE_END	0x20000000
-
-/*
- * Format of a swap-entry for shared memory pages currently out in
- * swap space (see also mm/swap.c).
- *
- * SWP_TYPE = SHM_SWP_TYPE
- * SWP_OFFSET is used as follows:
- *
- *  bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
- *  bits 7..21: index of page within shared memory segment (SHM_IDX)
- *		(actually fewer bits get used since SHMMAX is so low)
- */
-
-/*
- * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
- * there is a static array of size SHMMNI.
- */
-#define _SHM_ID_BITS	7
-#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
-
-#define SHM_IDX_SHIFT	(_SHM_ID_BITS)
-#define _SHM_IDX_BITS	15
-#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
-
-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
-#define SHMMAX 0x1000000		/* max shared seg size (bytes) */
-#define SHMMIN 1 /* really PAGE_SIZE */	/* min shared seg size (bytes) */
-#define SHMMNI (1<<_SHM_ID_BITS)	/* max num of segs system wide */
-#define SHMALL				/* max shm system wide (pages) */ \
-	(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
-#define	SHMLBA PAGE_SIZE		/* attach addr a multiple of this */
-#define SHMSEG SHMMNI			/* max shared segs per process */
+#define	SHMLBA PAGE_SIZE		 /* attach addr a multiple of this */
 
 #endif /* _ASMSPARC_SHMPARAM_H */
diff -u --recursive --new-file v2.3.25/linux/include/asm-sparc64/shmparam.h linux/include/asm-sparc64/shmparam.h
--- v2.3.25/linux/include/asm-sparc64/shmparam.h	Sun Oct  4 10:22:44 1998
+++ linux/include/asm-sparc64/shmparam.h	Wed Nov  3 11:31:09 1999
@@ -2,46 +2,6 @@
 #ifndef _ASMSPARC64_SHMPARAM_H
 #define _ASMSPARC64_SHMPARAM_H
 
-/* XXX Redo most of this... */
-
-/* address range for shared memory attaches if no address passed to shmat() */
-#define SHM_RANGE_START	0x10000000
-#define SHM_RANGE_END	0x20000000
-
-/*
- * Format of a swap-entry for shared memory pages currently out in
- * swap space (see also mm/swap.c).
- *
- * SWP_TYPE = SHM_SWP_TYPE
- * SWP_OFFSET is used as follows:
- *
- *  bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
- *  bits 7..21: index of page within shared memory segment (SHM_IDX)
- *		(actually fewer bits get used since SHMMAX is so low)
- */
-
-/*
- * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
- * there is a static array of size SHMMNI.
- */
-#define _SHM_ID_BITS	7
-#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
-
-#define SHM_IDX_SHIFT	(_SHM_ID_BITS)
-#define _SHM_IDX_BITS	15
-#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
-
-/*
- * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
- * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
- */
-
-#define SHMMAX 0x1000000		/* max shared seg size (bytes) */
-#define SHMMIN 1 /* really PAGE_SIZE */	/* min shared seg size (bytes) */
-#define SHMMNI (1<<_SHM_ID_BITS)	/* max num of segs system wide */
-#define SHMALL				/* max shm system wide (pages) */ \
-	(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
 #define	SHMLBA (PAGE_SIZE<<1)		/* attach addr a multiple of this */
-#define SHMSEG SHMMNI			/* max shared segs per process */
 
 #endif /* _ASMSPARC64_SHMPARAM_H */
diff -u --recursive --new-file v2.3.25/linux/include/linux/apm_bios.h linux/include/linux/apm_bios.h
--- v2.3.25/linux/include/linux/apm_bios.h	Mon Nov  1 13:56:27 1999
+++ linux/include/linux/apm_bios.h	Tue Nov  2 08:43:37 1999
@@ -46,6 +46,51 @@
 #define APM_BIOS_DISENGAGED     0x0010
 
 /*
+ * The APM function codes
+ */
+#define	APM_FUNC_INST_CHECK	0x5300
+#define	APM_FUNC_REAL_CONN	0x5301
+#define	APM_FUNC_16BIT_CONN	0x5302
+#define	APM_FUNC_32BIT_CONN	0x5303
+#define	APM_FUNC_DISCONN	0x5304
+#define	APM_FUNC_IDLE		0x5305
+#define	APM_FUNC_BUSY		0x5306
+#define	APM_FUNC_SET_STATE	0x5307
+#define	APM_FUNC_ENABLE_PM	0x5308
+#define	APM_FUNC_RESTORE_BIOS	0x5309
+#define	APM_FUNC_GET_STATUS	0x530a
+#define	APM_FUNC_GET_EVENT	0x530b
+#define	APM_FUNC_GET_STATE	0x530c
+#define	APM_FUNC_ENABLE_DEV_PM	0x530d
+#define	APM_FUNC_VERSION	0x530e
+#define	APM_FUNC_ENGAGE_PM	0x530f
+#define	APM_FUNC_GET_CAP	0x5310
+#define	APM_FUNC_RESUME_TIMER	0x5311
+#define	APM_FUNC_RESUME_ON_RING	0x5312
+#define	APM_FUNC_TIMER		0x5313
+
+/*
+ * Function code for APM_FUNC_RESUME_TIMER
+ */
+#define	APM_FUNC_DISABLE_TIMER	0
+#define	APM_FUNC_GET_TIMER	1
+#define	APM_FUNC_SET_TIMER	2
+
+/*
+ * Function code for APM_FUNC_RESUME_ON_RING
+ */
+#define	APM_FUNC_DISABLE_RING	0
+#define	APM_FUNC_ENABLE_RING	1
+#define	APM_FUNC_GET_RING	2
+
+/*
+ * Function code for APM_FUNC_TIMER_STATUS
+ */
+#define	APM_FUNC_TIMER_DISABLE	0
+#define	APM_FUNC_TIMER_ENABLE	1
+#define	APM_FUNC_TIMER_GET	2
+
+/*
  * Maximum number of events stored
  */
 #define APM_MAX_EVENTS		20
@@ -79,7 +124,6 @@
 extern int		apm_register_callback(int (*callback)(apm_event_t));
 extern void		apm_unregister_callback(int (*callback)(apm_event_t));
 
-extern void		apm_power_off(void);
 extern int		apm_display_blank(void);
 extern int		apm_display_unblank(void);
 
@@ -94,6 +138,14 @@
 #define APM_STATE_OFF		0x0003
 #define APM_STATE_BUSY		0x0004
 #define APM_STATE_REJECT	0x0005
+#define APM_STATE_OEM_SYS	0x0020
+#define APM_STATE_OEM_DEV	0x0040
+
+#define APM_STATE_DISABLE	0x0000
+#define APM_STATE_ENABLE	0x0001
+
+#define APM_STATE_DISENGAGE	0x0000
+#define APM_STATE_ENGAGE	0x0001
 
 /*
  * Events (results of Get PM Event)
@@ -109,7 +161,7 @@
 #define APM_USER_STANDBY	0x0009
 #define APM_USER_SUSPEND	0x000a
 #define APM_STANDBY_RESUME	0x000b
-#define APM_CAPABILITY_CHANGE   0x000c
+#define APM_CAPABILITY_CHANGE	0x000c
 
 /*
  * Error codes
@@ -125,13 +177,58 @@
 #define APM_BAD_DEVICE		0x09
 #define APM_BAD_PARAM		0x0a
 #define APM_NOT_ENGAGED		0x0b
-#define APM_BAD_FUNCTION        0x0c
+#define APM_BAD_FUNCTION	0x0c
 #define APM_RESUME_DISABLED	0x0d
+#define APM_NO_ERROR		0x53
 #define APM_BAD_STATE		0x60
 #define APM_NO_EVENTS		0x80
 #define APM_NOT_PRESENT		0x86
 
-/* ioctl operations */
+/*
+ * APM Device IDs
+ */
+#define APM_DEVICE_BIOS		0x0000
+#define APM_DEVICE_ALL		0x0001
+#define APM_DEVICE_DISPLAY	0x0100
+#define APM_DEVICE_STORAGE	0x0200
+#define APM_DEVICE_PARALLEL	0x0300
+#define APM_DEVICE_SERIAL	0x0400
+#define APM_DEVICE_NETWORK	0x0500
+#define APM_DEVICE_PCMCIA	0x0600
+#define APM_DEVICE_BATTERY	0x8000
+#define APM_DEVICE_OEM		0xe000
+#define APM_DEVICE_OLD_ALL	0xffff
+#define APM_DEVICE_CLASS	0x00ff
+#define APM_DEVICE_MASK		0xff00
+
+#ifdef __KERNEL__
+/*
+ * This is the "All Devices" ID communicated to the BIOS
+ */
+#define APM_DEVICE_BALL		((apm_bios_info.version > 0x0100) ? \
+				 APM_DEVICE_ALL : APM_DEVICE_OLD_ALL)
+#endif
+
+/*
+ * Battery status
+ */
+#define APM_MAX_BATTERIES	2
+
+/*
+ * APM defined capability bit flags
+ */
+#define APM_CAP_GLOBAL_STANDBY		0x0001
+#define APM_CAP_GLOBAL_SUSPEND		0x0002
+#define APM_CAP_RESUME_STANDBY_TIMER	0x0004 /* Timer resume from standby */
+#define APM_CAP_RESUME_SUSPEND_TIMER	0x0008 /* Timer resume from suspend */
+#define APM_CAP_RESUME_STANDBY_RING	0x0010 /* Resume on Ring fr standby */
+#define APM_CAP_RESUME_SUSPEND_RING	0x0020 /* Resume on Ring fr suspend */
+#define APM_CAP_RESUME_STANDBY_PCMCIA	0x0040 /* Resume on PCMCIA Ring	*/
+#define APM_CAP_RESUME_SUSPEND_PCMCIA	0x0080 /* Resume on PCMCIA Ring	*/
+
+/*
+ * ioctl operations
+ */
 #include <linux/ioctl.h>
 
 #define APM_IOC_STANDBY		_IO('A', 1)
diff -u --recursive --new-file v2.3.25/linux/include/linux/bfs_fs.h linux/include/linux/bfs_fs.h
--- v2.3.25/linux/include/linux/bfs_fs.h	Mon Nov  1 13:56:27 1999
+++ linux/include/linux/bfs_fs.h	Fri Nov  5 10:30:13 1999
@@ -32,7 +32,7 @@
 	__u32 i_atime;
 	__u32 i_mtime;
 	__u32 i_ctime;
-	__u8  i_padding[16];
+	__u32 i_padding[4];
 };
 
 #define BFS_NAMELEN		14	
@@ -55,7 +55,7 @@
 	__s32 s_bto;
 	char  s_fsname[6];
 	char  s_volume[6];
-	__u8  s_padding[472];
+	__u32 s_padding[118];
 };
 
 #define BFS_NZFILESIZE(ip) \
diff -u --recursive --new-file v2.3.25/linux/include/linux/bfs_fs_i.h linux/include/linux/bfs_fs_i.h
--- v2.3.25/linux/include/linux/bfs_fs_i.h	Mon Nov  1 13:56:27 1999
+++ linux/include/linux/bfs_fs_i.h	Fri Nov  5 10:30:13 1999
@@ -10,9 +10,9 @@
  * BFS file system in-core inode info
  */
 struct bfs_inode_info {
-	__u32	i_dsk_ino;	/* inode number from the disk, can be 0 */
-	__u32	i_sblock;
-	__u32	i_eblock;
+	unsigned long i_dsk_ino; /* inode number from the disk, can be 0 */
+	unsigned long i_sblock;
+	unsigned long i_eblock;
 };
 
 #endif	/* _LINUX_BFS_FS_I */
diff -u --recursive --new-file v2.3.25/linux/include/linux/bfs_fs_sb.h linux/include/linux/bfs_fs_sb.h
--- v2.3.25/linux/include/linux/bfs_fs_sb.h	Mon Nov  1 13:56:27 1999
+++ linux/include/linux/bfs_fs_sb.h	Fri Nov  5 10:30:13 1999
@@ -7,17 +7,25 @@
 #define _LINUX_BFS_FS_SB
 
 /*
+ * BFS block map entry, an array of these is kept in bfs_sb_info.
+ */
+ struct bfs_bmap {
+ 	unsigned long start, end;
+ };
+
+/*
  * BFS file system in-core superblock info
  */
 struct bfs_sb_info {
-	__u32 si_blocks;
-	__u32 si_freeb;
-	__u32 si_freei;
-	__u32 si_lf_ioff;
-	__u32 si_lf_sblk;
-	__u32 si_lf_eblk;
-	__u32 si_lasti;
-	__u8 *si_imap;
+	unsigned long si_blocks;
+	unsigned long si_freeb;
+	unsigned long si_freei;
+	unsigned long si_lf_ioff;
+	unsigned long si_lf_sblk;
+	unsigned long si_lf_eblk;
+	unsigned long si_lasti;
+	struct bfs_bmap * si_bmap;
+	char * si_imap;
 	struct buffer_head * si_sbh;		/* buffer header w/superblock */
 	struct bfs_super_block * si_bfs_sb;	/* superblock in si_sbh->b_data */
 };
diff -u --recursive --new-file v2.3.25/linux/include/linux/blkdev.h linux/include/linux/blkdev.h
--- v2.3.25/linux/include/linux/blkdev.h	Tue Aug 31 17:29:14 1999
+++ linux/include/linux/blkdev.h	Sat Nov  6 19:06:20 1999
@@ -83,12 +83,9 @@
 #define MAX_SEGMENTS MAX_SECTORS
 
 #define PageAlignSize(size) (((size) + PAGE_SIZE -1) & PAGE_MASK)
-#if 0  /* small readahead */
-#define MAX_READAHEAD PageAlignSize(4096*7)
-#define MIN_READAHEAD PageAlignSize(4096*2)
-#else /* large readahead */
-#define MAX_READAHEAD PageAlignSize(4096*31)
-#define MIN_READAHEAD PageAlignSize(4096*3)
-#endif
+
+/* read-ahead in pages.. */
+#define MAX_READAHEAD	31
+#define MIN_READAHEAD	3
 
 #endif
diff -u --recursive --new-file v2.3.25/linux/include/linux/cdrom.h linux/include/linux/cdrom.h
--- v2.3.25/linux/include/linux/cdrom.h	Fri Oct 22 13:21:55 1999
+++ linux/include/linux/cdrom.h	Wed Nov  3 14:01:48 1999
@@ -482,17 +482,17 @@
 
 
 /* Mode page codes for mode sense/set */
-#define GPMODE_R_W_ERROR_PAGE	    0x1
-#define GPMODE_WRITE_PARMS_PAGE	    0x5
-#define GPMODE_AUDIO_CTL_PAGE	    0xe
-#define GPMODE_POWER_PAGE	    0x1a
-#define GPMODE_FAULT_FAIL_PAGE	    0x1c
-#define GPMODE_TO_PROTECT_PAGE	    0x1d
-#define GPMODE_CAPABILITIES_PAGE    0x2a
-#define GPMODE_ALL_PAGES	    0x3f
+#define GPMODE_R_W_ERROR_PAGE		0x01
+#define GPMODE_WRITE_PARMS_PAGE		0x05
+#define GPMODE_AUDIO_CTL_PAGE		0x0e
+#define GPMODE_POWER_PAGE		0x1a
+#define GPMODE_FAULT_FAIL_PAGE		0x1c
+#define GPMODE_TO_PROTECT_PAGE		0x1d
+#define GPMODE_CAPABILITIES_PAGE	0x2a
+#define GPMODE_ALL_PAGES		0x3f
 /* Not in Mt. Fuji, but in ATAPI 2.6 -- depricated now in favor
  * of MODE_SENSE_POWER_PAGE */
-#define GPMODE_CDROM_PAGE              0x0d
+#define GPMODE_CDROM_PAGE		0x0d
 
 
 
@@ -505,18 +505,18 @@
 
 struct dvd_layer {
 	__u8 book_version	: 4;
-	__u8 book_type	: 4;
+	__u8 book_type		: 4;
 	__u8 min_rate		: 4;
-	__u8 disc_size	: 4;
-	__u8 layer_type	: 4;
-	__u8 track_path	: 1;
+	__u8 disc_size		: 4;
+	__u8 layer_type		: 4;
+	__u8 track_path		: 1;
 	__u8 nlayers		: 2;
 	__u8 track_density	: 4;
 	__u8 linear_density	: 4;
 	__u8 bca		: 1;
-	__u8 start_sector;
-	__u8 end_sector;
-	__u8 end_sector_l0;
+	__u32 start_sector;
+	__u32 end_sector;
+	__u32 end_sector_l0;
 };
 
 struct dvd_physical {
@@ -536,7 +536,7 @@
 struct dvd_disckey {
 	__u8 type;
 
-	unsigned agid			: 2;
+	unsigned agid		: 2;
 	__u8 value[2048];
 };
 
diff -u --recursive --new-file v2.3.25/linux/include/linux/fs.h linux/include/linux/fs.h
--- v2.3.25/linux/include/linux/fs.h	Mon Nov  1 13:56:27 1999
+++ linux/include/linux/fs.h	Sat Nov  6 19:06:14 1999
@@ -48,7 +48,7 @@
 extern int max_files, nr_files, nr_free_files;
 extern int max_super_blocks, nr_super_blocks;
 
-#define NR_FILE  4096	/* this can well be larger on a larger system */
+#define NR_FILE  8192	/* this can well be larger on a larger system */
 #define NR_RESERVED_FILES 10 /* reserved for root */
 #define NR_SUPER 256
 
@@ -302,7 +302,7 @@
 	umode_t		ia_mode;
 	uid_t		ia_uid;
 	gid_t		ia_gid;
-	off_t		ia_size;
+	loff_t		ia_size;
 	time_t		ia_atime;
 	time_t		ia_mtime;
 	time_t		ia_ctime;
@@ -347,7 +347,7 @@
 	uid_t			i_uid;
 	gid_t			i_gid;
 	kdev_t			i_rdev;
-	off_t			i_size;
+	loff_t			i_size;
 	time_t			i_atime;
 	time_t			i_mtime;
 	time_t			i_ctime;
diff -u --recursive --new-file v2.3.25/linux/include/linux/highmem.h linux/include/linux/highmem.h
--- v2.3.25/linux/include/linux/highmem.h	Fri Oct 22 13:21:55 1999
+++ linux/include/linux/highmem.h	Sat Nov  6 19:06:50 1999
@@ -2,6 +2,7 @@
 #define _LINUX_HIGHMEM_H
 
 #include <linux/config.h>
+#include <linux/pagemap.h>
 #include <asm/pgtable.h>
 
 #ifdef CONFIG_HIGHMEM
diff -u --recursive --new-file v2.3.25/linux/include/linux/i2o.h linux/include/linux/i2o.h
--- v2.3.25/linux/include/linux/i2o.h	Wed Oct 27 16:34:12 1999
+++ linux/include/linux/i2o.h	Tue Nov  2 17:07:08 1999
@@ -286,6 +286,7 @@
 	char name[16];
 	int unit;
 	int type;
+	int enabled;				/* Bus level enable */
 
 #define I2O_TYPE_PCI		0x01		/* PCI I2O controller */	
 
diff -u --recursive --new-file v2.3.25/linux/include/linux/ide.h linux/include/linux/ide.h
--- v2.3.25/linux/include/linux/ide.h	Fri Oct 22 13:21:55 1999
+++ linux/include/linux/ide.h	Sat Nov  6 19:06:17 1999
@@ -403,6 +403,12 @@
  */
 typedef void (ide_handler_t)(ide_drive_t *);
 
+/*
+ * when ide_timer_expiry fires, invoke a handler of this type
+ * to decide what to do.
+ */
+typedef int (ide_expiry_t)(ide_drive_t *);
+
 typedef struct hwgroup_s {
 	spinlock_t		spinlock; /* protects "busy" and "handler" */
 	ide_handler_t		*handler;/* irq handler, if active */
@@ -413,6 +419,7 @@
 	struct timer_list	timer;	/* failsafe timer */
 	struct request		wrq;	/* local copy of current write rq */
 	unsigned long		poll_timeout;	/* timeout value during long polls */
+	ide_expiry_t		*expiry; /* queried upon timeouts */
 	} ide_hwgroup_t;
 
 /*
@@ -584,7 +591,7 @@
  * This is used on exit from the driver, to designate the next irq handler
  * and also to start the safety timer.
  */
-void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler);
+void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry);
 
 /*
  * Error reporting, in human readable form (luxurious, but a memory hog).
diff -u --recursive --new-file v2.3.25/linux/include/linux/init.h linux/include/linux/init.h
--- v2.3.25/linux/include/linux/init.h	Tue Aug 31 17:29:14 1999
+++ linux/include/linux/init.h	Tue Nov  2 21:38:54 1999
@@ -103,6 +103,8 @@
 #define module_exit(x)	void cleanup_module(void) { x(); }
 #endif
 
+#define __setup(str,func) /* nothing */
+
 #endif
 
 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
@@ -111,4 +113,4 @@
 #define __initlocaldata
 #endif
 
-#endif
+#endif /* _LINUX_INIT_H */
diff -u --recursive --new-file v2.3.25/linux/include/linux/joystick.h linux/include/linux/joystick.h
--- v2.3.25/linux/include/linux/joystick.h	Fri Oct 22 13:21:55 1999
+++ linux/include/linux/joystick.h	Sat Nov  6 19:07:23 1999
@@ -23,7 +23,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  * 
  * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail:
+ * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
  * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
  */
 
diff -u --recursive --new-file v2.3.25/linux/include/linux/major.h linux/include/linux/major.h
--- v2.3.25/linux/include/linux/major.h	Wed Oct 27 16:34:12 1999
+++ linux/include/linux/major.h	Wed Nov  3 17:50:32 1999
@@ -120,6 +120,10 @@
 #define RTF_MAJOR	150
 #define RAW_MAJOR	162
 
+#define USB_ACM_MAJOR		166
+#define USB_ACM_AUX_MAJOR	167
+#define USB_CHAR_MAJOR		180
+
 #define UNIX98_PTY_MASTER_MAJOR	128
 #define UNIX98_PTY_MAJOR_COUNT	8
 #define UNIX98_PTY_SLAVE_MAJOR	(UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT)
diff -u --recursive --new-file v2.3.25/linux/include/linux/mm.h linux/include/linux/mm.h
--- v2.3.25/linux/include/linux/mm.h	Mon Nov  1 13:56:27 1999
+++ linux/include/linux/mm.h	Sat Nov  6 19:06:20 1999
@@ -202,6 +202,12 @@
 #define SetPageReserved(page)		set_bit(PG_reserved, &(page)->flags)
 #define ClearPageReserved(page)		clear_bit(PG_reserved, &(page)->flags)
 
+/*
+ * Error return values for the *_nopage functions
+ */
+#define NOPAGE_SIGBUS	(NULL)
+#define NOPAGE_OOM	((struct page *) (-1))
+
 
 /*
  * Various page->flags bits:
diff -u --recursive --new-file v2.3.25/linux/include/linux/msdos_fs_sb.h linux/include/linux/msdos_fs_sb.h
--- v2.3.25/linux/include/linux/msdos_fs_sb.h	Tue Aug 31 17:29:14 1999
+++ linux/include/linux/msdos_fs_sb.h	Fri Nov  5 16:27:28 1999
@@ -34,6 +34,7 @@
 
 struct msdos_sb_info {
 	unsigned short cluster_size; /* sectors/cluster */
+	unsigned short cluster_bits; /* sectors/cluster */
 	unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */
 	unsigned short fat_start;
 	unsigned long fat_length;    /* FAT start & length (sec.) */
diff -u --recursive --new-file v2.3.25/linux/include/linux/pagemap.h linux/include/linux/pagemap.h
--- v2.3.25/linux/include/linux/pagemap.h	Mon Nov  1 13:56:27 1999
+++ linux/include/linux/pagemap.h	Sat Nov  6 19:06:24 1999
@@ -1,8 +1,6 @@
 #ifndef _LINUX_PAGEMAP_H
 #define _LINUX_PAGEMAP_H
 
-#include <asm/system.h>
-
 /*
  * Page-mapping primitive inline functions
  *
@@ -11,8 +9,10 @@
 
 #include <linux/mm.h>
 #include <linux/fs.h>
-#include <linux/highmem.h>
 #include <linux/list.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
 
 /*
  * The page cache can done in larger chunks than
diff -u --recursive --new-file v2.3.25/linux/include/linux/pci.h linux/include/linux/pci.h
--- v2.3.25/linux/include/linux/pci.h	Mon Nov  1 13:56:27 1999
+++ linux/include/linux/pci.h	Sat Nov  6 19:06:13 1999
@@ -530,8 +530,8 @@
 extern inline void pci_set_master(struct pci_dev *dev) { }
 extern inline int pci_enable_device(struct pci_dev *dev) { return 0; }
 
-extern inline int pci_simple_probe (struct pci_simple_probe_entry *list, size_t match_limit,
-		      pci_simple_probe_callback cb, void *drvr_data)
+extern inline int pci_simple_probe (const struct pci_simple_probe_entry *list,
+	size_t match_limit, pci_simple_probe_callback cb, void *drvr_data)
 { return 0; }
 
 #endif /* !CONFIG_PCI */
diff -u --recursive --new-file v2.3.25/linux/include/linux/pci_ids.h linux/include/linux/pci_ids.h
--- v2.3.25/linux/include/linux/pci_ids.h	Mon Nov  1 13:56:27 1999
+++ linux/include/linux/pci_ids.h	Wed Nov  3 09:17:54 1999
@@ -948,6 +948,9 @@
 #define PCI_DEVICE_ID_3DLABS_DELTA	0x0003
 #define PCI_DEVICE_ID_3DLABS_PERMEDIA	0x0004
 #define PCI_DEVICE_ID_3DLABS_MX		0x0006
+#define PCI_DEVICE_ID_3DLABS_PERMEDIA2	0x0007
+#define PCI_DEVICE_ID_3DLABS_GAMMA	0x0008
+#define PCI_DEVICE_ID_3DLABS_PERMEDIA2V	0x0009
 
 #define PCI_VENDOR_ID_AVANCE		0x4005
 #define PCI_DEVICE_ID_AVANCE_ALG2064	0x2064
diff -u --recursive --new-file v2.3.25/linux/include/linux/shm.h linux/include/linux/shm.h
--- v2.3.25/linux/include/linux/shm.h	Mon Nov  1 13:56:27 1999
+++ linux/include/linux/shm.h	Wed Nov  3 11:31:09 1999
@@ -3,6 +3,17 @@
 
 #include <linux/ipc.h>
 
+/*
+ * SHMMAX, SHMMNI and SHMALL are upper limits are defaults which can
+ * be increased by sysctl
+ */
+
+#define SHMMAX 0x2000000		 /* max shared seg size (bytes) */
+#define SHMMIN 1 /* really PAGE_SIZE */	 /* min shared seg size (bytes) */
+#define SHMMNI 128			 /* max num of segs system wide */
+#define SHMALL (SHMMAX/PAGE_SIZE*SHMMNI) /* max shm system wide (pages) */
+#define SHMSEG SHMMNI			 /* max shared segs per process */
+
 #include <asm/shmparam.h>
 
 struct shmid_ds {
@@ -17,15 +28,6 @@
 	unsigned short 		shm_unused;	/* compatibility */
 	void 			*shm_unused2;	/* ditto - used by DIPC */
 	void			*shm_unused3;	/* unused */
-};
-
-struct shmid_kernel
-{	
-	struct shmid_ds		u;
-	/* the following are private */
-	unsigned long		shm_npages;	/* size of segment (pages) */
-	pte_t			*shm_pages;	/* array of ptrs to frames -> SHMMAX */ 
-	struct vm_area_struct	*attaches;	/* descriptors for attaches */
 };
 
 /* permission flag for shmget */
diff -u --recursive --new-file v2.3.25/linux/include/linux/swap.h linux/include/linux/swap.h
--- v2.3.25/linux/include/linux/swap.h	Mon Nov  1 13:56:27 1999
+++ linux/include/linux/swap.h	Sat Nov  6 19:06:12 1999
@@ -122,17 +122,6 @@
 asmlinkage long sys_swapoff(const char *);
 asmlinkage long sys_swapon(const char *, int);
 
-/*
- * vm_ops not present page codes for shared memory.
- *
- * Will go away eventually..
- */
-#define SHM_SWP_TYPE 0x20
-
-/*
- * swap cache stuff (in linux/mm/swap_state.c)
- */
-
 #define SWAP_CACHE_INFO
 
 #ifdef SWAP_CACHE_INFO
diff -u --recursive --new-file v2.3.25/linux/include/linux/sysctl.h linux/include/linux/sysctl.h
--- v2.3.25/linux/include/linux/sysctl.h	Wed Oct 27 16:34:12 1999
+++ linux/include/linux/sysctl.h	Wed Nov  3 11:31:09 1999
@@ -103,8 +103,7 @@
 	KERN_MSGPOOL=37,        /* int: Maximum system message pool size */
 	KERN_SYSRQ=38,		/* int: Sysreq enable */
 	KERN_MAX_THREADS=39,    /* int: Maximum nr of threads in the system */
- 	KERN_RANDOM=40,		/* Random driver */
- 	KERN_SHMALL=41		/* int: Maximum size of shared memory */
+ 	KERN_RANDOM=40		/* Random driver */
 };
 
 
diff -u --recursive --new-file v2.3.25/linux/include/net/irda/ircomm_tty.h linux/include/net/irda/ircomm_tty.h
--- v2.3.25/linux/include/net/irda/ircomm_tty.h	Wed Oct 27 16:34:12 1999
+++ linux/include/net/irda/ircomm_tty.h	Tue Nov  2 17:07:08 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 23:24:22 1999
- * Modified at:   Tue Oct  5 12:01:07 1999
+ * Modified at:   Sun Oct 31 19:50:35 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -75,6 +75,8 @@
 
 	__u32 max_data_size;
 	__u32 max_header_size;
+
+	struct iriap_cb *iriap;
 
 	struct ias_object* obj;
 	int skey;
diff -u --recursive --new-file v2.3.25/linux/include/net/irda/irda.h linux/include/net/irda/irda.h
--- v2.3.25/linux/include/net/irda/irda.h	Wed Oct 27 16:34:12 1999
+++ linux/include/net/irda/irda.h	Sat Nov  6 19:07:17 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Dec  9 21:13:12 1997
- * Modified at:   Tue Oct 19 21:12:54 1999
+ * Modified at:   Sun Oct 31 14:45:20 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
@@ -116,7 +116,6 @@
 	__u32 saddr;          /* my local address */
 	__u32 daddr;          /* peer address */
 
-	struct ias_object *ias_obj;
 	struct tsap_cb *tsap; /* TSAP used by this connection */
 	__u8 dtsap_sel;       /* remote TSAP address */
 	__u8 stsap_sel;       /* local TSAP address */
@@ -132,6 +131,9 @@
 
 	__u32 ckey;           /* IrLMP client handle */
 	__u32 skey;           /* IrLMP service handle */
+
+	struct ias_object *ias_obj;
+	struct iriap_cb *iriap;
 
 	int nslots;           /* Number of slots to use for discovery */
 
diff -u --recursive --new-file v2.3.25/linux/include/net/irda/iriap.h linux/include/net/irda/iriap.h
--- v2.3.25/linux/include/net/irda/iriap.h	Wed Oct 27 16:34:12 1999
+++ linux/include/net/irda/iriap.h	Tue Nov  2 17:07:08 1999
@@ -6,10 +6,11 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Aug 21 00:02:07 1997
- * Modified at:   Tue Oct  5 10:05:33 1999
+ * Modified at:   Sun Oct 31 15:51:32 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1997-1999 Dag Brattli <dagb@cs.uit.no>, 
+ *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -79,7 +80,7 @@
 	IRIAP_STATE r_connect_state;
 	
 	CONFIRM_CALLBACK confirm;
-	void *priv;
+	void *priv;                /* Used to identify client */
 
 	__u8 max_header_size;
 	
@@ -88,9 +89,14 @@
 
 int  iriap_init(void);
 void iriap_cleanup(void);
-void iriap_getvaluebyclass_request(char *name, char *attr, 
-				   __u32 saddr, __u32 daddr,
-				   CONFIRM_CALLBACK callback, void *priv);
+
+struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv,
+			    CONFIRM_CALLBACK callback);
+void iriap_close(struct iriap_cb *self);
+
+int iriap_getvaluebyclass_request(struct iriap_cb *self, 
+				  __u32 saddr, __u32 daddr,
+				  char *name, char *attr);
 void iriap_getvaluebyclass_confirm(struct iriap_cb *self, struct sk_buff *skb);
 
 void iriap_send_ack( struct iriap_cb *self);
diff -u --recursive --new-file v2.3.25/linux/include/net/irda/iriap_event.h linux/include/net/irda/iriap_event.h
--- v2.3.25/linux/include/net/irda/iriap_event.h	Thu Dec 17 09:01:03 1998
+++ linux/include/net/irda/iriap_event.h	Tue Nov  2 17:07:08 1999
@@ -6,10 +6,10 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Fri Sep  4 13:19:28 1998
+ * Modified at:   Sun Oct 31 22:02:54 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1998 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -65,20 +65,21 @@
 	IAP_LM_CONNECT_CONFIRM,
 } IRIAP_EVENT;
 
-void iriap_next_client_state   ( struct iriap_cb *self, IRIAP_STATE state);
-void iriap_next_call_state     ( struct iriap_cb *self, IRIAP_STATE state);
-void iriap_next_server_state   ( struct iriap_cb *self, IRIAP_STATE state);
-void iriap_next_r_connect_state( struct iriap_cb *self, IRIAP_STATE state);
-
-
-void iriap_do_client_event( struct iriap_cb *self, IRIAP_EVENT event, 
-			    struct sk_buff *skb);
-void iriap_do_call_event  ( struct iriap_cb *self, IRIAP_EVENT event, 
-			    struct sk_buff *skb);
-
-void iriap_do_server_event   ( struct iriap_cb *self, IRIAP_EVENT event, 
-			       struct sk_buff *skb);
-void iriap_do_r_connect_event( struct iriap_cb *self, IRIAP_EVENT event, 
-			       struct sk_buff *skb);
+void iriap_next_client_state   (struct iriap_cb *self, IRIAP_STATE state);
+void iriap_next_call_state     (struct iriap_cb *self, IRIAP_STATE state);
+void iriap_next_server_state   (struct iriap_cb *self, IRIAP_STATE state);
+void iriap_next_r_connect_state(struct iriap_cb *self, IRIAP_STATE state);
+
+
+void iriap_do_client_event(struct iriap_cb *self, IRIAP_EVENT event, 
+			   struct sk_buff *skb);
+void iriap_do_call_event  (struct iriap_cb *self, IRIAP_EVENT event, 
+			   struct sk_buff *skb);
+
+void iriap_do_server_event   (struct iriap_cb *self, IRIAP_EVENT event, 
+			      struct sk_buff *skb);
+void iriap_do_r_connect_event(struct iriap_cb *self, IRIAP_EVENT event, 
+			      struct sk_buff *skb);
+
+#endif /* IRIAP_FSM_H */
 
-#endif
diff -u --recursive --new-file v2.3.25/linux/include/net/irda/irlan_common.h linux/include/net/irda/irlan_common.h
--- v2.3.25/linux/include/net/irda/irlan_common.h	Wed Oct 27 16:34:12 1999
+++ linux/include/net/irda/irlan_common.h	Tue Nov  2 17:07:08 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Tue Oct  5 11:35:42 1999
+ * Modified at:   Sun Oct 31 19:41:24 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -126,6 +126,8 @@
 
 	int tx_busy;
 	struct sk_buff_head txq; /* Transmit control queue */
+
+	struct iriap_cb *iriap;
 
 	struct timer_list kick_timer;
 };
diff -u --recursive --new-file v2.3.25/linux/include/net/irda/irmod.h linux/include/net/irda/irmod.h
--- v2.3.25/linux/include/net/irda/irmod.h	Wed Oct 27 16:34:12 1999
+++ linux/include/net/irda/irmod.h	Tue Nov  2 17:07:08 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Dec 15 13:58:52 1997
- * Modified at:   Tue Oct  5 10:26:46 1999
+ * Modified at:   Sun Oct 31 20:01:17 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  *
  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
@@ -42,10 +42,10 @@
 	EVENT_REQUEST_MODULE,
 	EVENT_IRLAN_START,
 	EVENT_IRLAN_STOP,
-	EVENT_IRLPT_START,
-	EVENT_IRLPT_STOP,
-	EVENT_IROBEX_START,
-	EVENT_IROBEX_STOP,
+	EVENT_IRLPT_START,  /* Obsolete */
+	EVENT_IRLPT_STOP,   /* Obsolete */
+	EVENT_IROBEX_START, /* Obsolete */
+	EVENT_IROBEX_STOP,  /* Obsolete */
 	EVENT_IRDA_STOP,
 	EVENT_NEED_PROCESS_CONTEXT,
 } IRMGR_EVENT;
diff -u --recursive --new-file v2.3.25/linux/include/net/irda/irport.h linux/include/net/irda/irport.h
--- v2.3.25/linux/include/net/irda/irport.h	Wed Oct 27 16:34:12 1999
+++ linux/include/net/irda/irport.h	Tue Nov  2 17:07:08 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug  3 13:49:59 1997
- * Modified at:   Mon Oct 18 12:55:07 1999
+ * Modified at:   Sat Oct 30 19:54:07 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1997, 1998-1999 Dag Brattli <dagb@cs.uit.no>
@@ -51,13 +51,9 @@
 #define FRAME_MAX_SIZE 2048
 
 struct irport_cb {
-	queue_t q;     /* Must be first */
-	magic_t magic;
-
 	struct net_device *netdev; /* Yes! we are some kind of netdevice */
 	struct net_device_stats stats;
 
-	struct tty_struct  *tty;
 	struct irlap_cb    *irlap; /* The link layer we are binded to */
 
 	struct chipio_t io;        /* IrDA controller information */
@@ -78,6 +74,7 @@
 void irport_stop(struct irport_cb *self, int iobase);
 int  irport_probe(int iobase);
 
+void __irport_change_speed(struct irport_cb *self, __u32 speed);
 void irport_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 int  irport_hard_xmit(struct sk_buff *skb, struct net_device *dev);
 
diff -u --recursive --new-file v2.3.25/linux/include/net/irda/smc-ircc.h linux/include/net/irda/smc-ircc.h
--- v2.3.25/linux/include/net/irda/smc-ircc.h	Mon Jun  7 16:18:58 1999
+++ linux/include/net/irda/smc-ircc.h	Tue Nov  2 17:07:08 1999
@@ -1,6 +1,6 @@
 /*********************************************************************
  *                
- * Filename:      smc.h
+ * Filename:      smc-ircc.h
  * Version:       
  * Description:   
  * Status:        Experimental.
@@ -21,6 +21,8 @@
  *
  ********************************************************************/
 
+#include <net/irda/irport.h>
+
 #ifndef SMC_IRCC_H
 #define SMC_IRCC_H
 
@@ -149,12 +151,26 @@
 
 /* Private data for each instance */
 struct ircc_cb {
+	struct net_device *netdev; /* Yes! we are some kind of netdevice */
+	struct net_device_stats stats;
+	
+	struct irlap_cb    *irlap; /* The link layer we are binded to */
+	
+	struct chipio_t io;        /* IrDA controller information */
+	struct iobuff_t tx_buff;   /* Transmit buffer */
+	struct iobuff_t rx_buff;   /* Receive buffer */
+	struct qos_info qos;       /* QoS capabilities for this device */
+
+	struct irport_cb irport;
+	
+	__u32 flags;               /* Interface flags */
+
 	struct st_fifo st_fifo;
 
 	int tx_buff_offsets[10]; /* Offsets between frames in tx_buff */
-	int tx_len;          /* Number of frames in tx_buff */
+	int tx_len;              /* Number of frames in tx_buff */
+
 
-	struct irda_device idev;
 };
 
 #endif
diff -u --recursive --new-file v2.3.25/linux/include/net/irda/uircc.h linux/include/net/irda/uircc.h
--- v2.3.25/linux/include/net/irda/uircc.h	Wed Oct 27 16:34:12 1999
+++ linux/include/net/irda/uircc.h	Wed Dec 31 16:00:00 1969
@@ -1,125 +0,0 @@
-/*********************************************************************
- *                
- * Filename:      uircc.h
- * Version:       0.1
- * Description:   Driver for the Sharp Universal Infrared 
- *                Communications Controller (UIRCC)
- * Status:        Experimental.
- * Author:        Dag Brattli <dagb@cs.uit.no>
- * Created at:    Sat Dec 26 11:00:49 1998
- * Modified at:   Thu Mar 11 01:37:20 1999
- * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * 
- *     Copyright (c) 1998 Dag Brattli, All Rights Reserved.
- *      
- *     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.
- *  
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
- *     provide warranty for any of this software. This material is 
- *     provided "AS-IS" and at no charge.
- *     
- ********************************************************************/
-
-#ifndef UIRCC_H
-#define UIRCC_H
-
-/* Control registers (write only) */
-#define UIRCC_CR0           0x00 /* Control register 0 */
-#define UIRCC_CR0_XMIT_RST  0x20 /* Transmit reset */
-#define UIRCC_CR0_RECV_RST  0x10 /* Receive reset */
-#define UIRCC_CR0_TMR_RST   0x08 /* Timer reset */
-#define UIRCC_CR0_SYS_RST   0x04 /* System reset */
-#define UIRCC_CR0_CARR_RST  0x02 /* Carrier latch reset */
-#define UIRCC_CR0_CNT_SWT   0x01 /* Transmit/receive length counter reset */
-
-#define UIRCC_CR1           0x01 /* Transmit/receive mode setting register */
-#define UIRCC_CR1_RX_DMA    0x80 /* Rx DMA mode */
-#define UIRCC_CR1_TX_DMA    0x20 /* Tx DMA mode */
-#define UIRCC_CR1_DMA_BRST  0x10 /* DMA burst mode */
-#define UIRCC_CR1_MUST_SET  0x0c /* Must be set */
-
-#define UIRCC_CR2           0x02 /* Interrupt mask register */
-#define UIRCC_CR2_RECV_OVR  0x40 /* Receive overrun error */
-#define UIRCC_CR2_RECV_FRM  0x20 /* Receive frame error */
-#define UIRCC_CR2_RECV_END  0x10 /* Receive end */
-#define UIRCC_CR2_TMR_OUT   0x08 /* Timer time-out */
-#define UIRCC_CR2_XMIT_UNR  0x04 /* Transmit under-run error */
-#define UIRCC_CR2_XMIT_END  0x01 /* Transmit end */
-#define UIRCC_CR2_RECV_MASK 0x70
-#define UIRCC_CR2_XMIT_MASK 0x05
-
-#define UIRCC_CR3           0x03 /* Transmit/receive control */
-#define UIRCC_CR3_XMIT_EN   0x80 /* Transmit enable */
-#define UIRCC_CR3_TX_CRC_EN 0x40 /* Transmit UIRCC_CRC enable */
-#define UIRCC_CR3_RECV_EN   0x20 /* Receive enable */
-#define UIRCC_CR3_RX_CRC_EN 0x10 /* Receive CRC enable */
-#define UIRCC_CR3_ADDR_CMP  0x08 /* Address comparison enable */
-#define UIRCC_CR3_MCAST_EN  0x04 /* Multicast enable */
-
-#define UIRCC_CR4           0x04 /* Transmit data length low byte */
-#define UIRCC_CR5           0x05 /* Transmit data length high byte */
-#define UIRCC_CR6           0x06 /* Transmit data writing low byte */
-#define UIRCC_CR7           0x07 /* Transmit data writing high byte */
-
-#define UIRCC_CR8           0x08 /* Self pole address */
-
-#define UIRCC_CR9           0x09 /* System control 1 */
-
-#define UIRCC_CR10          0x0a /* Modem selection */
-#define UIRCC_CR10_SIR      0x22 /* Set SIR mode */
-#define UIRCC_CR10_FIR      0x88 /* Set FIR mode */
-
-#define UIRCC_CR11          0x0b /* System control 2 (same as SR11) */
-#define UIRCC_CR11_TMR_EN   0x08
-
-#define UIRCC_CR12          0x0c /* Timer counter initial value (low byte) */
-#define UIRCC_CR13          0x0d /* Timer counter initial value (high byte) */
-#define UIRCC_CR15          0x0f
-
-/* Status registers (read only) */
-#define UIRCC_SR0           0x00 /* Transmit/receive status register */
-#define UIRCC_SR0_RX_RDY    0x80 /* Received data ready */
-#define UIRCC_SR0_RX_OVR    0x40 /* Receive overrun error */
-#define UIRCC_SR0_RX_CRCFRM 0x20 /* Receive CRC or framing error */
-
-#define UIRCC_SR2           0x02 /* Interrupt mask status */
-
-#define UIRCC_SR3           0x03 /* Interrupt factor register */
-#define UIRCC_SR3_RX_OVR_ER 0x40 /* Receive overrun error */
-#define UIRCC_SR3_RX_FRM_ER 0x20 /* Receive frameing error */
-#define UIRCC_SR3_RX_EOF    0x10 /* Receive end of frame */
-#define UIRCC_SR3_TMR_OUT   0x08 /* Timer timeout */
-#define UIRCC_SR3_TXUR      0x04 /* Transmit underrun */
-#define UIRCC_SR3_TX_DONE   0x01 /* Transmit all sent */
-
-#define UIRCC_SR4           0x04 /* TX/RX data length counter low byte */
-#define UIRCC_SR5           0x05 /* TX/RX data length counter high byte */
-
-#define UIRCC_SR8           0x08 /* Chip version */
-
-#define UIRCC_SR9           0x09 /* System status 1 */
-
-#define UIRCC_SR10          0x0a /* Modem select status */
-#define UIRCC_SR11          0x0b
-#define UIRCC_SR12          0x0c /* Timer counter status (low byte) */
-#define UIRCC_SR13          0x0d /* Timer counter status (high byte) */
-#define UIRCC_SR15          0x0f
-
-#include <net/irda/irda_device.h>
-
-/* Private data for each instance */
-struct uircc_cb {
-	struct net_device idev;
-	
-	__u8 cr3;                 /* Copy of register sr3 */
-};
-
-#define CR3_SET
-
-#endif
-
-
-
diff -u --recursive --new-file v2.3.25/linux/include/net/irda/wrapper.h linux/include/net/irda/wrapper.h
--- v2.3.25/linux/include/net/irda/wrapper.h	Wed Oct 27 16:34:12 1999
+++ linux/include/net/irda/wrapper.h	Tue Nov  2 17:07:08 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Thu Oct  7 11:40:25 1999
+ * Modified at:   Sat Oct 30 16:29:01 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -52,7 +52,9 @@
 
 /* Proto definitions */
 int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize);
-int async_bump(struct net_device *dev, __u8 *buf, int len);
-int async_unwrap_char(struct net_device *dev, struct iobuff_t *buf, __u8 byte);
+void async_bump(struct net_device *dev, struct net_device_stats *stats,
+		__u8 *buf, int len);
+void async_unwrap_char(struct net_device *dev, struct net_device_stats *stats,
+		       struct iobuff_t *buf, __u8 byte);
 
 #endif
diff -u --recursive --new-file v2.3.25/linux/ipc/shm.c linux/ipc/shm.c
--- v2.3.25/linux/ipc/shm.c	Mon Nov  1 13:56:27 1999
+++ linux/ipc/shm.c	Fri Nov  5 10:01:11 1999
@@ -9,6 +9,8 @@
  * BIGMEM support, Andrea Arcangeli <andrea@suse.de>
  * SMP thread shm, Jean-Luc Boyard <jean-luc.boyard@siemens.fr>
  * HIGHMEM support, Ingo Molnar <mingo@redhat.com>
+ * avoid vmalloc and make shmmax, shmall, shmmni sysctl'able,
+ *                         Christoph Rohland <hans-christoph.rohland@sap.com>
  */
 
 #include <linux/config.h>
@@ -25,7 +27,17 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
-extern int ipcperms (struct ipc_perm *ipcp, short shmflg);
+#include "util.h"
+
+struct shmid_kernel /* extend struct shmis_ds with private fields */
+{	
+	struct shmid_ds		u;
+	unsigned long		shm_npages; /* size of segment (pages) */
+	pte_t			**shm_dir;  /* ptr to array of ptrs to frames -> SHMMAX */ 
+	struct vm_area_struct	*attaches;  /* descriptors for attaches */
+	int                     id; /* backreference to id for shm_close */
+};
+
 static int findkey (key_t key);
 static int newseg (key_t key, int shmflg, size_t size);
 static int shm_map (struct vm_area_struct *shmd);
@@ -38,13 +50,15 @@
 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};
+
 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 = 0; /* every used id is <= max_shmid */
+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[SHMMNI];
-
+static struct shmid_kernel **shm_segs = NULL;
+static unsigned int num_segs = 0;
 static unsigned short shm_seq = 0; /* incremented, for recognizing stale ids */
 
 spinlock_t shm_lock = SPIN_LOCK_UNLOCKED;
@@ -56,22 +70,109 @@
 
 void __init shm_init (void)
 {
-	int id;
-
-	for (id = 0; id < SHMMNI; id++)
-		shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
-	shm_tot = shm_rss = shm_seq = max_shmid = used_segs = 0;
-	init_waitqueue_head(&shm_wait);
 #ifdef CONFIG_PROC_FS
 	create_proc_read_entry("sysvipc/shm", 0, 0, sysvipc_shm_read_proc, NULL);
 #endif
 	return;
 }
 
+#define SHM_ENTRY(shp, index) (shp)->shm_dir[(index)/PTRS_PER_PTE][(index)%PTRS_PER_PTE]
+
+static pte_t **shm_alloc(unsigned long pages)
+{
+	unsigned short dir  = pages / PTRS_PER_PTE;
+	unsigned short last = pages % PTRS_PER_PTE;
+	pte_t **ret, **ptr;
+
+	ret = kmalloc ((dir+1) * sizeof(pte_t *), GFP_KERNEL);
+	if (!ret)
+		goto out;
+
+	for (ptr = ret; ptr < ret+dir ; ptr++)
+	{
+		*ptr = (pte_t *)__get_free_page (GFP_KERNEL);
+		if (!*ptr)
+			goto free;
+		memset (*ptr, 0, PAGE_SIZE); 
+	}
+
+	/* The last one is probably not of PAGE_SIZE: we use kmalloc */
+	if (last) {
+		*ptr = kmalloc (last*sizeof(pte_t), GFP_KERNEL);
+		if (!*ptr)
+			goto free;
+		memset (*ptr, 0, last*sizeof(pte_t));
+	}
+out:	
+	return ret;
+
+free:
+	/* The last failed: we decrement first */
+	while (--ptr >= ret)
+		free_page ((unsigned long)*ptr);
+
+	kfree (ret);
+	return NULL;
+}
+
+
+static void shm_free(pte_t** dir, unsigned long pages)
+{
+	pte_t **ptr = dir+pages/PTRS_PER_PTE;
+
+	/* first the last page */
+	if (pages%PTRS_PER_PTE)
+		kfree (*ptr);
+	/* now the whole pages */
+	while (--ptr >= dir)
+		free_page ((unsigned long)*ptr);
+
+	/* Now the indirect block */
+	kfree (dir);
+}
+
+static int shm_expand (unsigned int size)
+{
+	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;
+	}
+
+	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) {
@@ -89,9 +190,8 @@
 			__set_current_state(TASK_RUNNING);
 			remove_wait_queue(&shm_wait, &wait);
 		}
-		if (shp == IPC_UNUSED)
-			continue;
-		if (key == shp->u.shm_perm.key)
+		if (shp != IPC_UNUSED &&
+		    key == shp->u.shm_perm.key)
 			return id;
 	}
 	return -1;
@@ -99,18 +199,31 @@
 
 /*
  * 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;
+	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;
+	}
 
+	if (shmmni < used_segs)
+		return -ENOSPC;
+	if ((err = shm_expand (shmmni)))
+		return err;
 	if (size < SHMMIN)
 		return -EINVAL;
-	if (shm_tot + numpages >= SHMALL)
+	if (shm_tot + numpages >= shmall)
 		return -ENOSPC;
-	for (id = 0; id < SHMMNI; id++)
+	for (id = 0; id < num_segs; id++)
 		if (shm_segs[id] == IPC_UNUSED) {
 			shm_segs[id] = (struct shmid_kernel *) IPC_NOID;
 			goto found;
@@ -126,10 +239,8 @@
 		wake_up (&shm_wait);
 		return -ENOMEM;
 	}
-	lock_kernel();
-	shp->shm_pages = (pte_t *) vmalloc (numpages*sizeof(pte_t));
-	unlock_kernel();
-	if (!shp->shm_pages) {
+	shp->shm_dir = shm_alloc (numpages);
+	if (!shp->shm_dir) {
 		kfree(shp);
 		spin_lock(&shm_lock);
 		shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED;
@@ -137,8 +248,6 @@
 		return -ENOMEM;
 	}
 
-	memset(shp->shm_pages, 0, numpages*sizeof(pte_t));
-
 	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;
@@ -150,6 +259,7 @@
 	shp->u.shm_atime = shp->u.shm_dtime = 0;
 	shp->u.shm_ctime = CURRENT_TIME;
 	shp->shm_npages = numpages;
+	shp->id = id;
 
 	spin_lock(&shm_lock);
 
@@ -161,21 +271,22 @@
 	shm_segs[id] = shp;
 	used_segs++;
 	wake_up (&shm_wait);
-	return (unsigned int) shp->u.shm_perm.seq * SHMMNI + id;
+	return (unsigned int) shp->u.shm_perm.seq * IPCMNI + id;
 }
 
-size_t shmmax = SHMMAX;
-
 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);
-	if (size > shmmax) {
-		err = -EINVAL;
-	} else if (key == IPC_PRIVATE) {
+	if (key == IPC_PRIVATE) {
 		err = newseg(key, shmflg, size);
 	} else if ((id = findkey (key)) == -1) {
 		if (!(shmflg & IPC_CREAT))
@@ -193,7 +304,7 @@
 		else if (ipcperms (&shp->u.shm_perm, shmflg))
 			err = -EACCES;
 		else
-			err = (int) shp->u.shm_perm.seq * SHMMNI + id;
+			err = (int) shp->u.shm_perm.seq * IPCMNI + id;
 	}
 	spin_unlock(&shm_lock);
 	up(&current->mm->mmap_sem);
@@ -214,18 +325,18 @@
 	if (shp == IPC_NOID || shp == IPC_UNUSED)
 		BUG();
 	shp->u.shm_perm.seq++;     /* for shmat */
-	shm_seq = (shm_seq+1) % ((unsigned)(1<<31)/SHMMNI); /* increment, but avoid overflow */
+	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 && (shm_segs[--max_shmid] == IPC_UNUSED));
-	if (!shp->shm_pages)
+		while (max_shmid-- > 0 && (shm_segs[max_shmid] == IPC_UNUSED));
+	if (!shp->shm_dir)
 		BUG();
 	spin_unlock(&shm_lock);
 	numpages = shp->shm_npages;
 	for (i = 0, rss = 0, swp = 0; i < numpages ; i++) {
 		pte_t pte;
-		pte = shp->shm_pages[i];
+		pte = SHM_ENTRY (shp,i);
 		if (pte_none(pte))
 			continue;
 		if (pte_present(pte)) {
@@ -238,9 +349,7 @@
 			swp++;
 		}
 	}
-	lock_kernel();
-	vfree(shp->shm_pages);
-	unlock_kernel();
+	shm_free (shp->shm_dir, numpages);
 	kfree(shp);
 	spin_lock(&shm_lock);
 	shm_rss -= rss;
@@ -269,19 +378,20 @@
 	case IPC_INFO:
 	{
 		struct shminfo shminfo;
+		spin_unlock(&shm_lock);
 		err = -EFAULT;
 		if (!buf)
 			goto out;
-		shminfo.shmmni = SHMMNI;
-		shminfo.shmmax = shmmax;
+
+		shminfo.shmmni = shminfo.shmseg = shm_prm[2];
+		shminfo.shmmax = shm_prm[0];
+		shminfo.shmall = shm_prm[1];
+
 		shminfo.shmmin = SHMMIN;
-		shminfo.shmall = SHMALL;
-		shminfo.shmseg = SHMSEG;
-		spin_unlock(&shm_lock);
 		if(copy_to_user (buf, &shminfo, sizeof(struct shminfo)))
 			goto out_unlocked;
 		spin_lock(&shm_lock);
-		err = max_shmid;
+		err = max_shmid < 0 ? 0 : max_shmid;
 		goto out;
 	}
 	case SHM_INFO:
@@ -298,7 +408,7 @@
 		if(copy_to_user (buf, &shm_info, sizeof(shm_info)))
 			goto out_unlocked;
 		spin_lock(&shm_lock);
-		err = max_shmid;
+		err = max_shmid < 0 ? 0 : max_shmid;
 		goto out;
 	}
 	case SHM_STAT:
@@ -310,7 +420,7 @@
 			goto out;
 		if (ipcperms (&shp->u.shm_perm, S_IRUGO))
 			goto out;
-		id = (unsigned int) shp->u.shm_perm.seq * SHMMNI + shmid;
+		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)))
@@ -320,12 +430,13 @@
 		goto out;
 	}
 
-	shp = shm_segs[id = (unsigned int) shmid % SHMMNI];
 	err = -EINVAL;
-	if (shp == IPC_UNUSED || shp == IPC_NOID)
+	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 / SHMMNI)
+	if (shp->u.shm_perm.seq != (unsigned int) shmid / IPCMNI)
 		goto out;
 	ipcp = &shp->u.shm_perm;
 
@@ -480,7 +591,7 @@
 	if (shmid < 0)
 		goto out;
 
-	shp = shm_segs[id = (unsigned int) shmid % SHMMNI];
+	shp = shm_segs[id = (unsigned int) shmid % IPCMNI];
 	if (shp == IPC_UNUSED || shp == IPC_NOID)
 		goto out;
 
@@ -523,7 +634,7 @@
 	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 / SHMMNI)
+	if (shp->u.shm_perm.seq != (unsigned int) shmid / IPCMNI)
 		goto out;
 
 	spin_unlock(&shm_lock);
@@ -532,13 +643,13 @@
 	spin_lock(&shm_lock);
 	if (!shmd)
 		goto out;
-	if ((shp != shm_segs[id]) || (shp->u.shm_perm.seq != (unsigned int) shmid / SHMMNI)) {
+	if ((shp != shm_segs[id]) || (shp->u.shm_perm.seq != (unsigned int) shmid / IPCMNI)) {
 		kmem_cache_free(vm_area_cachep, shmd);
 		err = -EIDRM;
 		goto out;
 	}
 
-	shmd->vm_private_data = shm_segs + id;
+	shmd->vm_private_data = shm_segs[id];
 	shmd->vm_start = addr;
 	shmd->vm_end = addr + shp->shm_npages * PAGE_SIZE;
 	shmd->vm_mm = current->mm;
@@ -584,7 +695,7 @@
 	struct shmid_kernel *shp;
 
 	spin_lock(&shm_lock);
-	shp = *(struct shmid_kernel **) shmd->vm_private_data;
+	shp = (struct shmid_kernel *) shmd->vm_private_data;
 	insert_attach(shp,shmd);  /* insert shmd into shp->attaches */
 	shp->u.shm_nattch++;
 	shp->u.shm_atime = CURRENT_TIME;
@@ -604,14 +715,12 @@
 
 	spin_lock(&shm_lock);
 	/* remove from the list of attaches of the shm segment */
-	shp = *(struct shmid_kernel **) shmd->vm_private_data;
+	shp = (struct shmid_kernel *) shmd->vm_private_data;
 	remove_attach(shp,shmd);  /* remove from shp->attaches */
   	shp->u.shm_lpid = current->pid;
 	shp->u.shm_dtime = CURRENT_TIME;
-	if (--shp->u.shm_nattch <= 0 && shp->u.shm_perm.mode & SHM_DEST) {
-		unsigned int id = (struct shmid_kernel **)shmd->vm_private_data - shm_segs;
-		killseg (id);
-	}
+	if (--shp->u.shm_nattch <= 0 && shp->u.shm_perm.mode & SHM_DEST)
+		killseg (shp->id);
 	spin_unlock(&shm_lock);
 }
 
@@ -648,7 +757,7 @@
 }
 
 /*
- * page not present ... go through shm_pages
+ * page not present ... go through shm_dir
  */
 static struct page * shm_nopage(struct vm_area_struct * shmd, unsigned long address, int no_share)
 {
@@ -657,13 +766,13 @@
 	unsigned int idx;
 	struct page * page;
 
-	shp = *(struct shmid_kernel **) shmd->vm_private_data;
+	shp = (struct shmid_kernel *) shmd->vm_private_data;
 	idx = (address - shmd->vm_start) >> PAGE_SHIFT;
 	idx += shmd->vm_pgoff;
 
 	spin_lock(&shm_lock);
 again:
-	pte = shp->shm_pages[idx];
+	pte = SHM_ENTRY(shp,idx);
 	if (!pte_present(pte)) {
 		if (pte_none(pte)) {
 			spin_unlock(&shm_lock);
@@ -672,7 +781,7 @@
 				goto oom;
 			clear_highpage(page);
 			spin_lock(&shm_lock);
-			if (pte_val(pte) != pte_val(shp->shm_pages[idx]))
+			if (pte_val(pte) != pte_val(SHM_ENTRY(shp, idx)))
 				goto changed;
 		} else {
 			swp_entry_t entry = pte_to_swp_entry(pte);
@@ -694,18 +803,18 @@
 			unlock_kernel();
 			spin_lock(&shm_lock);
 			shm_swp--;
-			pte = shp->shm_pages[idx];
+			pte = SHM_ENTRY(shp, idx);
 			if (pte_present(pte))
 				goto present;
 		}
 		shm_rss++;
 		pte = pte_mkdirty(mk_pte(page, PAGE_SHARED));
-		shp->shm_pages[idx] = pte;
+		SHM_ENTRY(shp, idx) = pte;
 	} else
 		--current->maj_flt;  /* was incremented in do_no_page */
 
 done:
-	/* pte_val(pte) == shp->shm_pages[idx] */
+	/* pte_val(pte) == SHM_ENTRY (shp, idx) */
 	get_page(pte_page(pte));
 	spin_unlock(&shm_lock);
 	current->min_flt++;
@@ -719,7 +828,7 @@
 		free_page_and_swap_cache(page);
 	goto done;
 oom:
-	return (struct page *)(-1);
+	return NOPAGE_OOM;
 }
 
 /*
@@ -770,7 +879,7 @@
 	if (idx >= shp->shm_npages)
 		goto next_id;
 
-	page = shp->shm_pages[idx];
+	page = SHM_ENTRY(shp, idx);
 	if (!pte_present(page))
 		goto check_table;
 	page_map = pte_page(page);
@@ -788,11 +897,11 @@
 		unlock_kernel();
 		return 0;
 	}
-	if (page_count(page_map))
+	if (page_count(page_map) != 1)
 		goto check_table;
 	if (!(page_map = prepare_highmem_swapout(page_map)))
-		goto check_table;
-	shp->shm_pages[idx] = swp_entry_to_pte(swap_entry);
+		goto failed;
+	SHM_ENTRY (shp, idx) = swp_entry_to_pte(swap_entry);
 	swap_successes++;
 	shm_swp++;
 	shm_rss--;
@@ -812,12 +921,12 @@
  * Free the swap entry and set the new pte for the shm page.
  */
 static void shm_unuse_page(struct shmid_kernel *shp, unsigned long idx,
-			swp_entry_t entry, struct page *page)
+			   swp_entry_t entry, struct page *page)
 {
 	pte_t pte;
 
 	pte = pte_mkdirty(mk_pte(page, PAGE_SHARED));
-	shp->shm_pages[idx] = pte;
+	SHM_ENTRY(shp, idx) = pte;
 	get_page(page);
 	shm_rss++;
 
@@ -837,16 +946,16 @@
 	int i, n;
 
 	spin_lock(&shm_lock);
-	for (i = 0; i < SHMMNI; i++) {
+	for (i = 0; i <= max_shmid; i++) {
 		struct shmid_kernel *seg = shm_segs[i];
 		if ((seg == IPC_UNUSED) || (seg == IPC_NOID))
 			continue;
 		for (n = 0; n < seg->shm_npages; n++) {
-			if (pte_none(seg->shm_pages[n]))
+			if (pte_none(SHM_ENTRY(seg,n)))
 				continue;
-			if (pte_present(seg->shm_pages[n]))
+			if (pte_present(SHM_ENTRY(seg,n)))
 				continue;
-			if (pte_to_swp_entry(seg->shm_pages[n]).val == entry.val) {
+			if (pte_to_swp_entry(SHM_ENTRY(seg,n)).val == entry.val) {
 				shm_unuse_page(seg, n, entry, page);
 				return;
 			}
@@ -865,7 +974,7 @@
     	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 < SHMMNI; i++)
+    	for(i = 0; i <= max_shmid; i++)
 		if(shm_segs[i] != IPC_UNUSED) {
 #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"
@@ -877,7 +986,7 @@
 				format = BIG_STRING;
 	    		len += sprintf(buffer + len, format,
 			shm_segs[i]->u.shm_perm.key,
-			shm_segs[i]->u.shm_perm.seq * SHMMNI + i,
+			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,
diff -u --recursive --new-file v2.3.25/linux/ipc/util.c linux/ipc/util.c
--- v2.3.25/linux/ipc/util.c	Mon Nov  1 13:56:27 1999
+++ linux/ipc/util.c	Sat Nov  6 10:39:59 1999
@@ -14,6 +14,8 @@
 #include <linux/init.h>
 #include <linux/msg.h>
 
+#include "util.h"
+
 #if defined(CONFIG_SYSVIPC)
 
 extern void sem_init (void), msg_init (void), shm_init (void);
@@ -99,7 +101,7 @@
 	return -ENOSYS;
 }
 
-asmlinkage long sys_shmget (key_t key, int size, int flag)
+asmlinkage long sys_shmget (key_t key, size_t size, int shmflag)
 {
 	return -ENOSYS;
 }
diff -u --recursive --new-file v2.3.25/linux/ipc/util.h linux/ipc/util.h
--- v2.3.25/linux/ipc/util.h	Wed Dec 31 16:00:00 1969
+++ linux/ipc/util.h	Wed Nov  3 11:31:09 1999
@@ -0,0 +1,12 @@
+/*
+ * linux/ipc/util.h
+ * Copyright (C) 1999 Christoph Rohland
+ */
+
+/*
+ * IPCMNI is the absolute maximum for ipc identifier. This is used to
+ * detect stale identifiers
+ */
+#define IPCMNI (1<<15)          
+
+extern int ipcperms (struct ipc_perm *ipcp, short shmflg);
diff -u --recursive --new-file v2.3.25/linux/kernel/ksyms.c linux/kernel/ksyms.c
--- v2.3.25/linux/kernel/ksyms.c	Wed Oct 27 16:34:12 1999
+++ linux/kernel/ksyms.c	Tue Nov  2 21:35:51 1999
@@ -192,6 +192,7 @@
 EXPORT_SYMBOL(posix_test_lock);
 EXPORT_SYMBOL(posix_block_lock);
 EXPORT_SYMBOL(posix_unblock_lock);
+EXPORT_SYMBOL(locks_mandatory_area);
 EXPORT_SYMBOL(dput);
 EXPORT_SYMBOL(put_cached_page);
 EXPORT_SYMBOL(is_root_busy);
diff -u --recursive --new-file v2.3.25/linux/kernel/sysctl.c linux/kernel/sysctl.c
--- v2.3.25/linux/kernel/sysctl.c	Mon Nov  1 13:56:27 1999
+++ linux/kernel/sysctl.c	Wed Nov  3 11:31:09 1999
@@ -49,7 +49,7 @@
 extern int sg_big_buff;
 #endif
 #ifdef CONFIG_SYSVIPC
-extern size_t shmmax;
+extern size_t shm_prm[];
 #endif
 
 #ifdef __sparc__
@@ -213,7 +213,7 @@
 	{KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int),
 	 0644, NULL, &proc_dointvec},
 #ifdef CONFIG_SYSVIPC
-	{KERN_SHMMAX, "shmmax", &shmmax, sizeof (size_t),
+	{KERN_SHMMAX, "shmmax", &shm_prm, 3*sizeof (size_t),
 	 0644, NULL, &proc_doulongvec_minmax},
 #endif
 #ifdef CONFIG_MAGIC_SYSRQ
diff -u --recursive --new-file v2.3.25/linux/mm/bootmem.c linux/mm/bootmem.c
--- v2.3.25/linux/mm/bootmem.c	Fri Oct 22 13:21:55 1999
+++ linux/mm/bootmem.c	Sat Nov  6 18:58:13 1999
@@ -36,9 +36,7 @@
 {
 	unsigned long mapsize = (pages+7)/8;
 
-	if (bootmem_map)
-		BUG();
-	bootmem_map = __va(start << PAGE_SHIFT);
+	bootmem_map = phys_to_virt(start << PAGE_SHIFT);
 	max_low_pfn = pages;
 
 	/*
@@ -64,7 +62,6 @@
 	 */
 	unsigned long end = (addr + size + PAGE_SIZE-1)/PAGE_SIZE;
 
-	if (!bootmem_map) BUG();
 	if (!size) BUG();
 
 	if (end > max_low_pfn)
@@ -77,18 +74,23 @@
 void __init free_bootmem (unsigned long addr, unsigned long size)
 {
 	unsigned long i;
+	unsigned long start;
 	/*
 	 * round down end of usable mem, partially free pages are
 	 * considered reserved.
 	 */
 	unsigned long end = (addr + size)/PAGE_SIZE;
 
-	if (!bootmem_map) BUG();
 	if (!size) BUG();
-
 	if (end > max_low_pfn)
 		BUG();
-	for (i = addr/PAGE_SIZE; i < end; i++) {
+
+	/*
+	 * Round up the beginning of the address.
+	 */
+	start = (addr + PAGE_SIZE-1) / PAGE_SIZE;
+
+	for (i = start; i < end; i++) {
 		if (!test_and_clear_bit(i, bootmem_map))
 			BUG();
 	}
@@ -117,7 +119,6 @@
 	unsigned long offset, remaining_size;
 	unsigned long areasize, preferred;
 
-	if (!bootmem_map) BUG();
 	if (!size) BUG();
 
 	/*
@@ -152,6 +153,9 @@
 		preferred = 0;
 		goto restart_scan;
 	}
+	/*
+	 * Whoops, we cannot satisfy the allocation request.
+	 */
 	BUG();
 found:
 	if (start >= max_low_pfn)
@@ -173,11 +177,11 @@
 			areasize = 0;
 			// last_pos unchanged
 			last_offset = offset+size;
-			ret = __va(last_pos*PAGE_SIZE + offset);
+			ret = phys_to_virt(last_pos*PAGE_SIZE + offset);
 		} else {
 			size -= remaining_size;
 			areasize = (size+PAGE_SIZE-1)/PAGE_SIZE;
-			ret = __va(last_pos*PAGE_SIZE + offset);
+			ret = phys_to_virt(last_pos*PAGE_SIZE + offset);
 			last_pos = start+areasize-1;
 			last_offset = size;
 		}
@@ -185,7 +189,7 @@
 	} else {
 		last_pos = start + areasize - 1;
 		last_offset = size & ~PAGE_MASK;
-		ret = __va(start * PAGE_SIZE);
+		ret = phys_to_virt(start * PAGE_SIZE);
 	}
 	/*
 	 * Reserve the area now:
@@ -211,12 +215,13 @@
 			count++;
 			ClearPageReserved(page);
 			set_page_count(page, 1);
-			if (i >= (__pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT))
+			if (i >= (virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT))
 				clear_bit(PG_DMA, &page->flags);
 			__free_page(page);
 		}
 	}
 	total += count;
+
 	/*
 	 * Now free the allocator bitmap itself, it's not
 	 * needed anymore:
diff -u --recursive --new-file v2.3.25/linux/mm/filemap.c linux/mm/filemap.c
--- v2.3.25/linux/mm/filemap.c	Mon Nov  1 13:56:27 1999
+++ linux/mm/filemap.c	Fri Nov  5 16:16:48 1999
@@ -519,7 +519,7 @@
  * This adds the requested page to the page cache if it isn't already there,
  * and schedules an I/O to read in its contents from disk.
  */
-static inline void page_cache_read(struct file * file, unsigned long offset) 
+static inline int page_cache_read(struct file * file, unsigned long offset) 
 {
 	struct inode *inode = file->f_dentry->d_inode;
 	struct page **hash = page_hash(&inode->i_data, offset);
@@ -529,41 +529,45 @@
 	page = __find_page_nolock(&inode->i_data, offset, *hash); 
 	spin_unlock(&pagecache_lock);
 	if (page)
-		return;
+		return 0;
 
 	page = page_cache_alloc();
 	if (!page)
-		return;
+		return -ENOMEM;
 
 	if (!add_to_page_cache_unique(page, &inode->i_data, offset, hash)) {
-		inode->i_op->readpage(file, page);
+		int error = inode->i_op->readpage(file, page);
 		page_cache_release(page);
-		return;
+		return error;
 	}
 	/*
 	 * We arrive here in the unlikely event that someone 
 	 * raced with us and added our page to the cache first.
 	 */
 	page_cache_free(page);
-	return;
+	return 0;
 }
 
 /*
  * Read in an entire cluster at once.  A cluster is usually a 64k-
  * aligned block that includes the address requested in "offset."
  */
-static void read_cluster_nonblocking(struct file * file, unsigned long offset)
+static int read_cluster_nonblocking(struct file * file, unsigned long offset)
 {
+	int error = 0;
 	unsigned long filesize = (file->f_dentry->d_inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 	unsigned long pages = CLUSTER_PAGES;
 
 	offset = CLUSTER_OFFSET(offset);
 	while ((pages-- > 0) && (offset < filesize)) {
-		page_cache_read(file, offset);
-		offset ++;
+		error = page_cache_read(file, offset);
+		if (error >= 0)
+			offset ++;
+		else
+			break;
 	}
 
-	return;
+	return error;
 }
 
 /* 
@@ -833,13 +837,15 @@
 
 static void generic_file_readahead(int reada_ok,
 	struct file * filp, struct inode * inode,
-	unsigned long ppos, struct page * page)
+	struct page * page)
 {
+	unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT;
+	unsigned long index = page->index;
 	unsigned long max_ahead, ahead;
 	unsigned long raend;
 	int max_readahead = get_max_readahead(inode);
 
-	raend = filp->f_raend & PAGE_CACHE_MASK;
+	raend = filp->f_raend;
 	max_ahead = 0;
 
 /*
@@ -851,14 +857,14 @@
  * page only.
  */
 	if (PageLocked(page)) {
-		if (!filp->f_ralen || ppos >= raend || ppos + filp->f_ralen < raend) {
-			raend = ppos;
-			if (raend < inode->i_size)
+		if (!filp->f_ralen || index >= raend || index + filp->f_ralen < raend) {
+			raend = index;
+			if (raend < end_index)
 				max_ahead = filp->f_ramax;
 			filp->f_rawin = 0;
-			filp->f_ralen = PAGE_CACHE_SIZE;
+			filp->f_ralen = 1;
 			if (!max_ahead) {
-				filp->f_raend  = ppos + filp->f_ralen;
+				filp->f_raend  = index + filp->f_ralen;
 				filp->f_rawin += filp->f_ralen;
 			}
 		}
@@ -871,17 +877,17 @@
  *   it is the moment to try to read ahead asynchronously.
  * We will later force unplug device in order to force asynchronous read IO.
  */
-	else if (reada_ok && filp->f_ramax && raend >= PAGE_CACHE_SIZE &&
-		 ppos <= raend && ppos + filp->f_ralen >= raend) {
+	else if (reada_ok && filp->f_ramax && raend >= 1 &&
+		 index <= raend && index + filp->f_ralen >= raend) {
 /*
  * Add ONE page to max_ahead in order to try to have about the same IO max size
  * as synchronous read-ahead (MAX_READAHEAD + 1)*PAGE_CACHE_SIZE.
  * Compute the position of the last page we have tried to read in order to 
  * begin to read ahead just at the next page.
  */
-		raend -= PAGE_CACHE_SIZE;
-		if (raend < inode->i_size)
-			max_ahead = filp->f_ramax + PAGE_CACHE_SIZE;
+		raend -= 1;
+		if (raend < end_index)
+			max_ahead = filp->f_ramax + 1;
 
 		if (max_ahead) {
 			filp->f_rawin = filp->f_ralen;
@@ -896,10 +902,11 @@
  */
 	ahead = 0;
 	while (ahead < max_ahead) {
-		ahead += PAGE_CACHE_SIZE;
-		if ((raend + ahead) >= inode->i_size)
+		ahead ++;
+		if ((raend + ahead) >= end_index)
+			break;
+		if (page_cache_read(filp, raend + ahead) < 0)
 			break;
-		page_cache_read(filp, (raend + ahead) >> PAGE_CACHE_SHIFT);
 	}
 /*
  * If we tried to read ahead some pages,
@@ -919,7 +926,7 @@
 
 		filp->f_ralen += ahead;
 		filp->f_rawin += filp->f_ralen;
-		filp->f_raend = raend + ahead + PAGE_CACHE_SIZE;
+		filp->f_raend = raend + ahead + 1;
 
 		filp->f_ramax += filp->f_ramax;
 
@@ -947,17 +954,16 @@
 {
 	struct dentry *dentry = filp->f_dentry;
 	struct inode *inode = dentry->d_inode;
-	unsigned long pos, pgpos;
+	unsigned long index, offset;
 	struct page *cached_page;
 	int reada_ok;
 	int error;
 	int max_readahead = get_max_readahead(inode);
-	unsigned long pgoff;
 
 	cached_page = NULL;
-	pos = *ppos;
-	pgpos = pos & PAGE_CACHE_MASK;
-	pgoff = pos >> PAGE_CACHE_SHIFT;
+	index = *ppos >> PAGE_CACHE_SHIFT;
+	offset = *ppos & ~PAGE_CACHE_MASK;
+
 /*
  * If the current position is outside the previous read-ahead window, 
  * we reset the current read-ahead context and set read ahead max to zero
@@ -965,7 +971,7 @@
  * otherwise, we assume that the file accesses are sequential enough to
  * continue read-ahead.
  */
-	if (pgpos > filp->f_raend || pgpos + filp->f_rawin < filp->f_raend) {
+	if (index > filp->f_raend || index + filp->f_rawin < filp->f_raend) {
 		reada_ok = 0;
 		filp->f_raend = 0;
 		filp->f_ralen = 0;
@@ -981,12 +987,12 @@
  * Then, at least MIN_READAHEAD if read ahead is ok,
  * and at most MAX_READAHEAD in all cases.
  */
-	if (pos + desc->count <= (PAGE_CACHE_SIZE >> 1)) {
+	if (!index && offset + desc->count <= (PAGE_CACHE_SIZE >> 1)) {
 		filp->f_ramax = 0;
 	} else {
 		unsigned long needed;
 
-		needed = ((pos + desc->count) & PAGE_CACHE_MASK) - pgpos;
+		needed = ((offset + desc->count) >> PAGE_CACHE_SHIFT) + 1;
 
 		if (filp->f_ramax < needed)
 			filp->f_ramax = needed;
@@ -999,17 +1005,27 @@
 
 	for (;;) {
 		struct page *page, **hash;
+		unsigned long end_index, nr;
 
-		if (pos >= inode->i_size)
+		end_index = inode->i_size >> PAGE_CACHE_SHIFT;
+		if (index > end_index)
 			break;
+		nr = PAGE_CACHE_SIZE;
+		if (index == end_index) {
+			nr = inode->i_size & ~PAGE_CACHE_MASK;
+			if (nr <= offset)
+				break;
+		}
+
+		nr = nr - offset;
 
 		/*
 		 * Try to find the data in the page cache..
 		 */
-		hash = page_hash(&inode->i_data, pgoff);
+		hash = page_hash(&inode->i_data, index);
 
 		spin_lock(&pagecache_lock);
-		page = __find_page_nolock(&inode->i_data, pgoff, *hash);
+		page = __find_page_nolock(&inode->i_data, index, *hash);
 		if (!page)
 			goto no_cached_page;
 found_page:
@@ -1019,19 +1035,10 @@
 		if (!Page_Uptodate(page))
 			goto page_not_up_to_date;
 page_ok:
-	/*
-	 * Ok, we have the page, and it's up-to-date, so
-	 * now we can copy it to user space...
-	 */
-	{
-		unsigned long offset, nr;
-
-		offset = pos & ~PAGE_CACHE_MASK;
-		nr = PAGE_CACHE_SIZE - offset;
-		if (nr > inode->i_size - pos)
-			nr = inode->i_size - pos;
-
 		/*
+		 * Ok, we have the page, and it's up-to-date, so
+		 * now we can copy it to user space...
+		 *
 		 * The actor routine returns how many bytes were actually used..
 		 * NOTE! This may not be the same as how much of a user buffer
 		 * we filled up (we may be padding etc), so we can only update
@@ -1039,20 +1046,20 @@
 		 * pointers and the remaining count).
 		 */
 		nr = actor(desc, page, offset, nr);
-		pos += nr;
-		pgoff = pos >> PAGE_CACHE_SHIFT;
+		offset += nr;
+		index += offset >> PAGE_CACHE_SHIFT;
+		offset &= ~PAGE_CACHE_MASK;
+	
 		page_cache_release(page);
 		if (nr && desc->count)
 			continue;
 		break;
-	}
 
 /*
  * Ok, the page was not immediately readable, so let's try to read ahead while we're at it..
  */
 page_not_up_to_date:
-		generic_file_readahead(reada_ok, filp, inode,
-					pos & PAGE_CACHE_MASK, page);
+		generic_file_readahead(reada_ok, filp, inode, page);
 
 		if (Page_Uptodate(page))
 			goto page_ok;
@@ -1073,8 +1080,7 @@
 				goto page_ok;
 
 			/* Again, try some read-ahead while waiting for the page to finish.. */
-			generic_file_readahead(reada_ok, filp, inode,
-						pos & PAGE_CACHE_MASK, page);
+			generic_file_readahead(reada_ok, filp, inode, page);
 			wait_on_page(page);
 			if (Page_Uptodate(page))
 				goto page_ok;
@@ -1106,7 +1112,7 @@
 			 * dropped the page cache lock. Check for that.
 			 */
 			spin_lock(&pagecache_lock);
-			page = __find_page_nolock(&inode->i_data, pgoff, *hash);
+			page = __find_page_nolock(&inode->i_data, index, *hash);
 			if (page)
 				goto found_page;
 		}
@@ -1115,14 +1121,14 @@
 		 * Ok, add the new page to the hash-queues...
 		 */
 		page = cached_page;
-		__add_to_page_cache(page, &inode->i_data, pgoff, hash);
+		__add_to_page_cache(page, &inode->i_data, index, hash);
 		spin_unlock(&pagecache_lock);
 		cached_page = NULL;
 
 		goto readpage;
 	}
 
-	*ppos = pos;
+	*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
 	filp->f_reada = 1;
 	if (cached_page)
 		page_cache_free(cached_page);
@@ -1292,13 +1298,11 @@
  * The goto's are kind of ugly, but this streamlines the normal case of having
  * it in the page cache, and handles the special cases reasonably without
  * having a lot of duplicated code.
- *
- * XXX - at some point, this should return unique values to indicate to
- *       the caller whether this is EIO, OOM, or SIGBUS.
  */
 static struct page * filemap_nopage(struct vm_area_struct * area,
 	unsigned long address, int no_share)
 {
+	int error;
 	struct file *file = area->vm_file;
 	struct dentry *dentry = file->f_dentry;
 	struct inode *inode = dentry->d_inode;
@@ -1347,7 +1351,8 @@
 				BUG();
 			copy_highpage(new_page, old_page);
 			flush_page_to_ram(new_page);
-		}
+		} else
+			new_page = NOPAGE_OOM;
 		page_cache_release(page);
 		return new_page;
 	}
@@ -1364,16 +1369,26 @@
 	 * so we need to map a zero page.
 	 */
 	if (pgoff < size)
-		read_cluster_nonblocking(file, pgoff);
+		error = read_cluster_nonblocking(file, pgoff);
 	else
-		page_cache_read(file, pgoff);
+		error = page_cache_read(file, pgoff);
 
 	/*
 	 * The page we want has now been added to the page cache.
 	 * In the unlikely event that someone removed it in the
 	 * meantime, we'll just come back here and read it again.
 	 */
-	goto retry_find;
+	if (error >= 0)
+		goto retry_find;
+
+	/*
+	 * An error return from page_cache_read can result if the
+	 * system is low on memory, or a problem occurs while trying
+	 * to schedule I/O.
+	 */
+	if (error == -ENOMEM)
+		return NOPAGE_OOM;
+	return NULL;
 
 page_not_uptodate:
 	lock_page(page);
@@ -1777,13 +1792,16 @@
 {
 	struct dentry	*dentry = file->f_dentry; 
 	struct inode	*inode = dentry->d_inode; 
-	unsigned long	pos = *ppos;
 	unsigned long	limit = current->rlim[RLIMIT_FSIZE].rlim_cur;
+	loff_t		pos = *ppos;
 	struct page	*page, **hash, *cached_page;
 	unsigned long	written;
 	long		status;
 	int		err;
 
+	if (pos < 0)
+		return -EINVAL;
+
 	cached_page = NULL;
 
 	down(&inode->i_sem);
@@ -1802,37 +1820,35 @@
 	 * Check whether we've reached the file size limit.
 	 */
 	err = -EFBIG;
-	if (pos >= limit) {
-		send_sig(SIGXFSZ, current, 0);
-		goto out;
+	if (limit != RLIM_INFINITY) {
+		if (pos >= limit) {
+			send_sig(SIGXFSZ, current, 0);
+			goto out;
+		}
+		if (count > limit - pos) {
+			send_sig(SIGXFSZ, current, 0);
+			count = limit - pos;
+		}
 	}
 
 	status  = 0;
-	/*
-	 * Check whether to truncate the write,
-	 * and send the signal if we do.
-	 */
-	if (count > limit - pos) {
-		send_sig(SIGXFSZ, current, 0);
-		count = limit - pos;
-	}
 
 	while (count) {
-		unsigned long bytes, pgoff, offset;
+		unsigned long bytes, index, offset;
 
 		/*
 		 * Try to find the page in the cache. If it isn't there,
 		 * allocate a free page.
 		 */
 		offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
-		pgoff = pos >> PAGE_CACHE_SHIFT;
+		index = pos >> PAGE_CACHE_SHIFT;
 		bytes = PAGE_CACHE_SIZE - offset;
 		if (bytes > count)
 			bytes = count;
 
-		hash = page_hash(&inode->i_data, pgoff);
+		hash = page_hash(&inode->i_data, index);
 repeat_find:
-		page = __find_lock_page(&inode->i_data, pgoff, hash);
+		page = __find_lock_page(&inode->i_data, index, hash);
 		if (!page) {
 			if (!cached_page) {
 				cached_page = page_cache_alloc();
@@ -1842,7 +1858,7 @@
 				break;
 			}
 			page = cached_page;
-			if (add_to_page_cache_unique(page,&inode->i_data,pgoff,hash))
+			if (add_to_page_cache_unique(page, &inode->i_data, index, hash))
 				goto repeat_find;
 
 			cached_page = NULL;
diff -u --recursive --new-file v2.3.25/linux/mm/memory.c linux/mm/memory.c
--- v2.3.25/linux/mm/memory.c	Mon Nov  1 13:56:27 1999
+++ linux/mm/memory.c	Thu Nov  4 19:36:33 1999
@@ -58,9 +58,9 @@
  * a common occurrence (no need to read the page to know
  * that it's zero - better for the cache and memory subsystem).
  */
-static inline void copy_cow_page(struct page * from, struct page * to)
+static inline void copy_cow_page(struct page * from, struct page * to, unsigned long address)
 {
-	if (from == ZERO_PAGE(to)) {
+	if (from == ZERO_PAGE(address)) {
 		clear_highpage(to);
 		return;
 	}
@@ -416,11 +416,11 @@
  * Given a physical address, is there a useful struct page pointing to it?
  */
 
-struct page * get_page_map(struct page *page)
+struct page * get_page_map(struct page *page, unsigned long vaddr)
 {
 	if (MAP_NR(page) >= max_mapnr)
 		return 0;
-	if (page == ZERO_PAGE(page))
+	if (page == ZERO_PAGE(vaddr))
 		return 0;
 	if (PageReserved(page))
 		return 0;
@@ -484,7 +484,7 @@
 			dprintk (KERN_ERR "Missing page in map_user_kiobuf\n");
 			goto retry;
 		}
-		map = get_page_map(map);
+		map = get_page_map(map, ptr);
 		if (map) {
 			if (TryLockPage(map)) {
 				goto retry;
@@ -743,7 +743,7 @@
 		return 0;
 	}
 	flush_page_to_ram(page);
-	set_pte(pte, pte_mkwrite(page_pte_prot(page, PAGE_COPY)));
+	set_pte(pte, pte_mkwrite(mk_pte(page, PAGE_COPY)));
 /* no need for flush_tlb */
 	return page;
 }
@@ -819,7 +819,7 @@
 	if (pte_val(*page_table) == pte_val(pte)) {
 		if (PageReserved(old_page))
 			++vma->vm_mm->rss;
-		copy_cow_page(old_page, new_page);
+		copy_cow_page(old_page, new_page, address);
 		flush_page_to_ram(new_page);
 		flush_cache_page(vma, address);
 		set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
@@ -1051,8 +1051,7 @@
  * As this is called only for pages that do not currently exist, we
  * do not need to flush old virtual caches or the TLB.
  *
- * This is called with the MM semaphore and the kernel lock held.
- * We need to release the kernel lock as soon as possible..
+ * This is called with the MM semaphore held.
  */
 static int do_no_page(struct task_struct * tsk, struct vm_area_struct * vma,
 	unsigned long address, int write_access, pte_t *page_table)
@@ -1069,10 +1068,10 @@
 	 * essentially an early COW detection.
 	 */
 	new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, (vma->vm_flags & VM_SHARED)?0:write_access);
-	if (!new_page)
-		return 0;	/* SIGBUS - but we _really_ should know whether it is OOM or SIGBUS */
-	if (new_page == (struct page *)-1)
-		return -1;	/* OOM */
+	if (new_page == NULL)	/* no page was available -- SIGBUS */
+		return 0;
+	if (new_page == NOPAGE_OOM)
+		return -1;
 	++tsk->maj_flt;
 	++vma->vm_mm->rss;
 	/*
diff -u --recursive --new-file v2.3.25/linux/mm/page_alloc.c linux/mm/page_alloc.c
--- v2.3.25/linux/mm/page_alloc.c	Fri Oct 22 13:21:55 1999
+++ linux/mm/page_alloc.c	Tue Nov  2 08:07:24 1999
@@ -262,11 +262,11 @@
 		}
 		low_on_highmemory = 1;
 	} else {
-		if (nr_free_pages+nr_free_highpages > freepages.min) {
+		if (nr_free_pages-nr_free_highpages > freepages.min) {
 			if (!low_on_memory) {
 				return 1;
 			}
-			if (nr_free_pages+nr_free_highpages >= freepages.high) {
+			if (nr_free_pages-nr_free_highpages >= freepages.high) {
 				low_on_memory = 0;
 				return 1;
 			}
@@ -320,6 +320,10 @@
 	do {
 		page = rmqueue(order, type);
 		if (page) {
+#ifdef CONFIG_HIGHMEM
+			if (type == MEM_TYPE_HIGH)
+				nr_free_highpages -= 1 << order;
+#endif
 			spin_unlock_irqrestore(&page_alloc_lock, flags);
 			return page;
 		}
diff -u --recursive --new-file v2.3.25/linux/mm/swap_state.c linux/mm/swap_state.c
--- v2.3.25/linux/mm/swap_state.c	Mon Nov  1 13:56:27 1999
+++ linux/mm/swap_state.c	Wed Nov  3 11:31:09 1999
@@ -68,8 +68,6 @@
 	if (!entry.val)
 		goto out;
 	type = SWP_TYPE(entry);
-	if (type & SHM_SWP_TYPE)
-		goto out;
 	if (type >= nr_swapfiles)
 		goto bad_file;
 	p = type + swap_info;
@@ -115,8 +113,6 @@
 	if (!entry.val)
 		goto bad_entry;
 	type = SWP_TYPE(entry);
-	if (type & SHM_SWP_TYPE)
-		goto out;
 	if (type >= nr_swapfiles)
 		goto bad_file;
 	p = type + swap_info;
diff -u --recursive --new-file v2.3.25/linux/mm/swapfile.c linux/mm/swapfile.c
--- v2.3.25/linux/mm/swapfile.c	Mon Nov  1 13:56:27 1999
+++ linux/mm/swapfile.c	Sat Nov  6 09:51:19 1999
@@ -135,8 +135,6 @@
 		goto out;
 
 	type = SWP_TYPE(entry);
-	if (type & SHM_SWP_TYPE)
-		goto out;
 	if (type >= nr_swapfiles)
 		goto bad_nofile;
 	p = & swap_info[type];
@@ -190,8 +188,6 @@
 		goto new_swap_entry;
 	entry.val = page->index;
 	type = SWP_TYPE(entry);
-	if (type & SHM_SWP_TYPE)
-		goto new_swap_entry;
 	if (type >= nr_swapfiles)
 		goto new_swap_entry;
 	p = type + swap_info;
@@ -617,7 +613,7 @@
 		swapfilesize = 0;
 		if (blk_size[MAJOR(dev)])
 			swapfilesize = blk_size[MAJOR(dev)][MINOR(dev)]
-				/ (PAGE_SIZE / 1024);
+				>> (PAGE_SHIFT - 10);
 	} else if (S_ISREG(swap_dentry->d_inode->i_mode)) {
 		error = -EBUSY;
 		for (i = 0 ; i < nr_swapfiles ; i++) {
@@ -626,7 +622,7 @@
 			if (swap_dentry->d_inode == swap_info[i].swap_file->d_inode)
 				goto bad_swap;
 		}
-		swapfilesize = swap_dentry->d_inode->i_size / PAGE_SIZE;
+		swapfilesize = swap_dentry->d_inode->i_size >> PAGE_SHIFT;
 	} else
 		goto bad_swap;
 
diff -u --recursive --new-file v2.3.25/linux/net/ipv6/README linux/net/ipv6/README
--- v2.3.25/linux/net/ipv6/README	Sat Apr 20 02:01:37 1996
+++ linux/net/ipv6/README	Mon Nov  1 17:21:59 1999
@@ -1,6 +1,6 @@
 To join in the work on Linux IPv6 send mail to:
 
-        majordomo@nuclecu.unam.mx
+        majordomo@oss.sgi.com
 
 and in the body of the message include:
 
diff -u --recursive --new-file v2.3.25/linux/net/irda/af_irda.c linux/net/irda/af_irda.c
--- v2.3.25/linux/net/irda/af_irda.c	Wed Oct 27 16:34:12 1999
+++ linux/net/irda/af_irda.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun May 31 10:12:43 1998
- * Modified at:   Fri Oct  1 19:11:04 1999
+ * Modified at:   Sun Oct 31 19:32:37 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc.
  * 
@@ -278,8 +278,14 @@
 	ASSERT(priv != NULL, return;);
 	self = (struct irda_sock *) priv;
 	
-	if (!self)
+	if (!self) {
+		WARNING(__FUNCTION__ "(), lost myself!\n");
 		return;
+	}
+
+	/* We probably don't need to make any more queries */
+	iriap_close(self->iriap);
+	self->iriap = NULL;
 
 	/* Check if request succeeded */
 	if (result != IAS_SUCCESS) {
@@ -366,14 +372,21 @@
  */
 static int irda_find_lsap_sel(struct irda_sock *self, char *name)
 {
-	IRDA_DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 
+	if (self->iriap) {
+		WARNING(__FUNCTION__ "(), busy with a previous query\n");
+		return -EBUSY;
+	}
+
+	self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
+				 irda_get_value_confirm);
+
 	/* Query remote LM-IAS */
-	iriap_getvaluebyclass_request(name, "IrDA:TinyTP:LsapSel",
-				      self->saddr, self->daddr,
-				      irda_get_value_confirm, self);
+	iriap_getvaluebyclass_request(self->iriap, self->saddr, self->daddr,
+				      name, "IrDA:TinyTP:LsapSel");
 	/* Wait for answer */
 	interruptible_sleep_on(&self->ias_wait);
 
@@ -741,6 +754,9 @@
 	/* Unregister with LM-IAS */
 	if (self->ias_obj)
 		irias_delete_object(self->ias_obj);
+
+	if (self->iriap) 
+		iriap_close(self->iriap);
 
 	if (self->tsap) {
 		irttp_disconnect_request(self->tsap, NULL, P_NORMAL);
diff -u --recursive --new-file v2.3.25/linux/net/irda/ircomm/ircomm_core.c linux/net/irda/ircomm/ircomm_core.c
--- v2.3.25/linux/net/irda/ircomm/ircomm_core.c	Wed Oct 27 16:34:12 1999
+++ linux/net/irda/ircomm/ircomm_core.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 20:37:34 1999
- * Modified at:   Tue Oct  5 11:37:11 1999
+ * Modified at:   Sat Oct 30 12:48:14 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -80,7 +80,7 @@
 #ifdef MODULE
 void ircomm_cleanup(void)
 {
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	hashbin_delete(ircomm, (FREE_FUNC) __ircomm_close);
 
@@ -101,8 +101,8 @@
 	struct ircomm_cb *self = NULL;
 	int ret;
 
-	DEBUG(2, __FUNCTION__ "(), service_type=0x%02x\n",
-	      service_type);
+	IRDA_DEBUG(2, __FUNCTION__ "(), service_type=0x%02x\n",
+		   service_type);
 
 	ASSERT(ircomm != NULL, return NULL;);
 
@@ -143,7 +143,7 @@
  */
 static int __ircomm_close(struct ircomm_cb *self)
 {
-	DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return -EIO;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -EIO;);
@@ -199,7 +199,7 @@
 	struct ircomm_info info;
 	int ret;
 
-	DEBUG(2 , __FUNCTION__"()\n");
+	IRDA_DEBUG(2 , __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
@@ -226,7 +226,7 @@
 {
 	int clen = 0;
 	
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	/* Check if the packet contains data on the control channel */
 	if (skb->len > 0)
@@ -260,7 +260,7 @@
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ret = ircomm_do_event(self, IRCOMM_CONNECT_RESPONSE, userdata, NULL);
 
@@ -276,7 +276,7 @@
 void ircomm_connect_confirm(struct ircomm_cb *self, struct sk_buff *skb,
 			    struct ircomm_info *info)
 {
-	DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, __FUNCTION__"()\n");
 
 	if (self->notify.connect_confirm )
 		self->notify.connect_confirm(self->notify.instance,
@@ -295,7 +295,7 @@
 {
 	int ret;
 
-	DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return -EFAULT;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -EFAULT;);
@@ -314,7 +314,7 @@
  */
 void ircomm_data_indication(struct ircomm_cb *self, struct sk_buff *skb)
 {	
-	DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, __FUNCTION__"()\n");
 
 	ASSERT(skb->len > 0, return;);
 
@@ -350,7 +350,7 @@
 	if (skb->len)
 		ircomm_data_indication(self, skb);		
 	else {
-		DEBUG(4, __FUNCTION__ "(), data was control info only!\n");
+		IRDA_DEBUG(4, __FUNCTION__ "(), data was control info only!\n");
 		dev_kfree_skb(skb);
 	}
 }
@@ -365,7 +365,7 @@
 {
 	int ret;
 	
-	DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return -EFAULT;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -EFAULT;);
@@ -387,7 +387,7 @@
 {
 	struct sk_buff *ctrl_skb;
 
-	DEBUG(2, __FUNCTION__"()\n");	
+	IRDA_DEBUG(2, __FUNCTION__"()\n");	
 
 	ctrl_skb = skb_clone(skb, GFP_ATOMIC);
 	if (!ctrl_skb)
@@ -413,7 +413,7 @@
 	struct ircomm_info info;
 	int ret;
 
-	DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
@@ -432,7 +432,7 @@
 void ircomm_disconnect_indication(struct ircomm_cb *self, struct sk_buff *skb,
 				  struct ircomm_info *info)
 {
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
        
 	ASSERT(info != NULL, return;);
 
@@ -450,7 +450,7 @@
  */
 void ircomm_flow_request(struct ircomm_cb *self, LOCAL_FLOW flow)
 {
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
diff -u --recursive --new-file v2.3.25/linux/net/irda/ircomm/ircomm_event.c linux/net/irda/ircomm/ircomm_event.c
--- v2.3.25/linux/net/irda/ircomm/ircomm_event.c	Mon Oct  4 15:49:30 1999
+++ linux/net/irda/ircomm/ircomm_event.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 20:33:11 1999
- * Modified at:   Thu Sep  2 10:09:25 1999
+ * Modified at:   Sat Oct 30 13:05:23 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -50,7 +50,6 @@
 static int ircomm_state_conn(struct ircomm_cb *self, IRCOMM_EVENT event, 
 			     struct sk_buff *skb, struct ircomm_info *info);
 
-
 char *ircomm_state[] = {
 	"IRCOMM_IDLE",
 	"IRCOMM_WAITI",
@@ -108,8 +107,8 @@
 		ircomm_connect_indication(self, skb, info);
 		break;
 	default:
-		DEBUG(4, __FUNCTION__"(), unknown event: %s\n",
-		      ircomm_event[event]);
+		IRDA_DEBUG(4, __FUNCTION__"(), unknown event: %s\n",
+			   ircomm_event[event]);
 		return -EINVAL;
 	}
 	return ret;
@@ -138,8 +137,8 @@
 		ircomm_disconnect_indication(self, skb, info);
 		break;
 	default:
-		DEBUG(0, __FUNCTION__"(), unknown event: %s\n",
-		      ircomm_event[event]);
+		IRDA_DEBUG(0, __FUNCTION__"(), unknown event: %s\n",
+			   ircomm_event[event]);
 		ret = -EINVAL;
 	}
 	return ret;
@@ -171,8 +170,8 @@
 		ircomm_disconnect_indication(self, skb, info);
 		break;
 	default:
-		DEBUG(0, __FUNCTION__ "(), unknown event = %s\n",
-		      ircomm_event[event]);
+		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event = %s\n",
+			   ircomm_event[event]);
 		ret = -EINVAL;
 	}
 	return ret;
@@ -213,14 +212,13 @@
 		ret = self->issue.disconnect_request(self, skb, info);
 		break;
 	default:
-		DEBUG(0, __FUNCTION__ "(), unknown event = %s\n",
-		      ircomm_event[event]);
+		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event = %s\n",
+			   ircomm_event[event]);
 		ret = -EINVAL;
 	}
 	return ret;
 }
 
-
 /*
  * Function ircomm_do_event (self, event, skb)
  *
@@ -230,8 +228,8 @@
 int ircomm_do_event(struct ircomm_cb *self, IRCOMM_EVENT event,
 		    struct sk_buff *skb, struct ircomm_info *info) 
 {
-	DEBUG(4, __FUNCTION__": state=%s, event=%s\n",
-	      ircomm_state[self->state], ircomm_event[event]);
+	IRDA_DEBUG(4, __FUNCTION__": state=%s, event=%s\n",
+		   ircomm_state[self->state], ircomm_event[event]);
 
 	return (*state[self->state])(self, event, skb, info);
 }
@@ -246,6 +244,6 @@
 {
 	self->state = state;
 	
-	DEBUG(4, __FUNCTION__": next state=%s, service type=%d\n", 
-	      ircomm_state[self->state], self->service_type);
+	IRDA_DEBUG(4, __FUNCTION__": next state=%s, service type=%d\n", 
+		   ircomm_state[self->state], self->service_type);
 }
diff -u --recursive --new-file v2.3.25/linux/net/irda/ircomm/ircomm_lmp.c linux/net/irda/ircomm/ircomm_lmp.c
--- v2.3.25/linux/net/irda/ircomm/ircomm_lmp.c	Tue Aug 31 17:29:15 1999
+++ linux/net/irda/ircomm/ircomm_lmp.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 20:48:27 1999
- * Modified at:   Fri Aug 13 07:21:29 1999
+ * Modified at:   Sat Oct 30 12:55:24 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       Previous IrLPT work by Thomas Davis
  * 
@@ -49,7 +49,7 @@
 {
 	notify_t notify;
 	
-	DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 	
         /* Register callbacks */
         irda_notify_init(&notify);
@@ -62,7 +62,7 @@
 
 	self->lsap = irlmp_open_lsap(LSAP_ANY, &notify);
 	if (!self->lsap) {
-		DEBUG(0,__FUNCTION__"failed to allocate tsap\n");
+		IRDA_DEBUG(0,__FUNCTION__"failed to allocate tsap\n");
 		return -1;
 	}
 	self->slsap_sel = self->lsap->slsap_sel;
@@ -90,7 +90,7 @@
 {
 	int ret = 0;
 
-	DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 
 	ret = irlmp_connect_request(self->lsap, info->dlsap_sel,
 				    info->saddr, info->daddr, NULL, userdata); 
@@ -107,7 +107,7 @@
 {
 	int ret;
 
-	DEBUG(0, __FUNCTION__"()\n");
+	IRDA_DEBUG(0, __FUNCTION__"()\n");
 	
 	ret = irlmp_connect_response(self->lsap, skb);
 
@@ -121,7 +121,7 @@
         struct sk_buff *skb;
 	int ret;
 
-	DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 
         if (!userdata) {
                 skb = dev_alloc_skb(64);
@@ -157,13 +157,13 @@
 
 	cb = (struct irda_skb_cb *) skb->cb;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
  
         line = cb->line;
 
 	self = (struct ircomm_cb *) hashbin_find(ircomm, line, NULL);
         if (!self) {
-		DEBUG(2, __FUNCTION__ "(), didn't find myself\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), didn't find myself\n");
                 return;
 	}
 
@@ -173,7 +173,7 @@
 	self->pkt_count--;
 
         if ((self->pkt_count < 2) && (self->flow_status == FLOW_STOP)) {
-                DEBUG(2, __FUNCTION__ "(), asking TTY to start again!\n");
+                IRDA_DEBUG(2, __FUNCTION__ "(), asking TTY to start again!\n");
                 self->flow_status = FLOW_START;
                 if (self->notify.flow_indication)
                         self->notify.flow_indication(self->notify.instance, 
@@ -199,12 +199,12 @@
 	
         cb->line = self->line;
 
-	DEBUG(4, __FUNCTION__"(), sending frame\n");
+	IRDA_DEBUG(4, __FUNCTION__"(), sending frame\n");
 
 	skb->destructor = ircomm_lmp_flow_control;
 	
         if ((self->pkt_count++ > 7) && (self->flow_status == FLOW_START)) {
-		DEBUG(2, __FUNCTION__ "(), asking TTY to slow down!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), asking TTY to slow down!\n");
 	        self->flow_status = FLOW_STOP;
                 if (self->notify.flow_indication)
              	        self->notify.flow_indication(self->notify.instance, 
@@ -230,7 +230,7 @@
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 
-	DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, __FUNCTION__"()\n");
 	
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
@@ -257,7 +257,7 @@
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 	struct ircomm_info info;
 
-	DEBUG(0, __FUNCTION__"()\n");
+	IRDA_DEBUG(0, __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
@@ -287,7 +287,7 @@
 	struct ircomm_cb *self = (struct ircomm_cb *)instance;
 	struct ircomm_info info;
 
-	DEBUG(0, __FUNCTION__"()\n");
+	IRDA_DEBUG(0, __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
@@ -314,7 +314,7 @@
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 	struct ircomm_info info;
 
-	DEBUG(0, __FUNCTION__"()\n");
+	IRDA_DEBUG(0, __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
diff -u --recursive --new-file v2.3.25/linux/net/irda/ircomm/ircomm_param.c linux/net/irda/ircomm/ircomm_param.c
--- v2.3.25/linux/net/irda/ircomm/ircomm_param.c	Wed Oct 27 16:34:12 1999
+++ linux/net/irda/ircomm/ircomm_param.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Jun  7 10:25:11 1999
- * Modified at:   Mon Oct  4 09:36:53 1999
+ * Modified at:   Sat Oct 30 13:05:42 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -106,13 +106,13 @@
 	struct sk_buff *skb;
 	int count;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
 	if (self->state != IRCOMM_TTY_READY) {
-		DEBUG(2, __FUNCTION__ "(), not ready yet!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), not ready yet!\n");
 		return 0;
 	}
 
@@ -142,7 +142,7 @@
 	count = irda_param_insert(self, pi, skb->tail, skb_tailroom(skb),
 				  &ircomm_param_info);
 	if (count < 0) {
-		DEBUG(0, __FUNCTION__ "(), no room for parameter!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "(), no room for parameter!\n");
 		restore_flags(flags);
 		return -1;
 	}
@@ -180,30 +180,30 @@
 	 * Now choose a preferred service type of those available
 	 */
 	if (service_type & IRCOMM_3_WIRE_RAW) {
-		DEBUG(2, __FUNCTION__ "(), peer supports 3 wire raw\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), peer supports 3 wire raw\n");
 		self->session.service_type |= IRCOMM_3_WIRE_RAW;
 	}
 	if (service_type & IRCOMM_3_WIRE) {
-		DEBUG(2, __FUNCTION__ "(), peer supports 3 wire\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), peer supports 3 wire\n");
 		self->session.service_type |= IRCOMM_3_WIRE;
 	}
 	if (service_type & IRCOMM_9_WIRE) {
-		DEBUG(2, __FUNCTION__ "(), peer supports 9 wire\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), peer supports 9 wire\n");
 		self->session.service_type |= IRCOMM_9_WIRE;
 	}
 	if (service_type & IRCOMM_CENTRONICS) {
-		DEBUG(2, __FUNCTION__ "(), peer supports Centronics\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), peer supports Centronics\n");
 		self->session.service_type |= IRCOMM_CENTRONICS;
 	}
 	
 	self->session.service_type &= self->service_type;
 	if (!self->session.service_type) {
-		DEBUG(2, __FUNCTION__"(), No common service type to use!\n");
+		IRDA_DEBUG(2, __FUNCTION__"(), No common service type to use!\n");
 		return -1;
 	}
 	
-	DEBUG(2, __FUNCTION__ "(), resulting service type=0x%02x\n", 
-	      self->session.service_type);
+	IRDA_DEBUG(2, __FUNCTION__ "(), resulting service type=0x%02x\n", 
+		   self->session.service_type);
 
 	return 0;
 }
@@ -227,8 +227,8 @@
 	else {
 		self->session.port_type = param->pv.b;
 
-		DEBUG(0, __FUNCTION__ "(), port type=%d\n", 
-		      self->session.port_type);
+		IRDA_DEBUG(0, __FUNCTION__ "(), port type=%d\n", 
+			   self->session.port_type);
 	}
 	return 0;
 }
@@ -247,9 +247,9 @@
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
 	if (get) {
-		DEBUG(0, __FUNCTION__ "(), not imp!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "(), not imp!\n");
 	} else {
-		DEBUG(0, __FUNCTION__ "(), port-name=%s\n", param->pv.c);
+		IRDA_DEBUG(0, __FUNCTION__ "(), port-name=%s\n", param->pv.c);
 		strncpy(self->session.port_name, param->pv.c, 32);
 	}
 
@@ -274,7 +274,7 @@
 	else
 		self->session.data_rate = param->pv.i;
 	
-	DEBUG(2, __FUNCTION__ "(), data rate = %d\n", param->pv.i);
+	IRDA_DEBUG(2, __FUNCTION__ "(), data rate = %d\n", param->pv.i);
 
 	return 0;
 }
@@ -318,7 +318,7 @@
 	else
 		self->session.flow_control = param->pv.b;
 
-	DEBUG(1, __FUNCTION__ "(), flow control = 0x%02x\n", param->pv.b);
+	IRDA_DEBUG(1, __FUNCTION__ "(), flow control = 0x%02x\n", param->pv.b);
 
 	return 0;
 }
@@ -344,8 +344,8 @@
 		self->session.xonxoff[1] = param->pv.s >> 8;
 	}
 
-	DEBUG(0, __FUNCTION__ "(), XON/XOFF = 0x%02x\n,0x%02x", 
-	      param->pv.s & 0xff, param->pv.s >> 8);
+	IRDA_DEBUG(0, __FUNCTION__ "(), XON/XOFF = 0x%02x\n,0x%02x", 
+		   param->pv.s & 0xff, param->pv.s >> 8);
 
 	return 0;
 }
@@ -371,8 +371,8 @@
 		self->session.enqack[1] = param->pv.s >> 8;
 	}
 
-	DEBUG(0, __FUNCTION__ "(), ENQ/ACK = 0x%02x,0x%02x\n",
-	      param->pv.s & 0xff, param->pv.s >> 8);
+	IRDA_DEBUG(0, __FUNCTION__ "(), ENQ/ACK = 0x%02x,0x%02x\n",
+		   param->pv.s & 0xff, param->pv.s >> 8);
 
 	return 0;
 }
@@ -385,7 +385,7 @@
  */
 static int ircomm_param_line_status(void *instance, param_t *param, int get)
 {
-	DEBUG(2, __FUNCTION__ "(), not impl.\n");
+	IRDA_DEBUG(2, __FUNCTION__ "(), not impl.\n");
 
 	return 0;
 }
@@ -444,7 +444,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 	__u8 dce;
 
-	DEBUG(1, __FUNCTION__ "(), dce = 0x%02x\n", param->pv.b);
+	IRDA_DEBUG(1, __FUNCTION__ "(), dce = 0x%02x\n", param->pv.b);
 
 	dce = param->pv.b;
 
@@ -456,7 +456,7 @@
 	/* Check if any of the settings have changed */
 	if (dce & 0x0f) {
 		if (dce & IRCOMM_DELTA_CTS) {
-			DEBUG(2, __FUNCTION__ "(), CTS \n");
+			IRDA_DEBUG(2, __FUNCTION__ "(), CTS \n");
 		}
 	}
 
diff -u --recursive --new-file v2.3.25/linux/net/irda/ircomm/ircomm_ttp.c linux/net/irda/ircomm/ircomm_ttp.c
--- v2.3.25/linux/net/irda/ircomm/ircomm_ttp.c	Mon Oct  4 15:49:30 1999
+++ linux/net/irda/ircomm/ircomm_ttp.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 20:48:27 1999
- * Modified at:   Mon Sep 27 11:17:23 1999
+ * Modified at:   Sat Oct 30 12:55:36 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -49,7 +49,7 @@
 {
 	notify_t notify;
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	/* Register callbacks */
 	irda_notify_init(&notify);
@@ -64,7 +64,7 @@
 	self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT,
 				     &notify);
 	if (!self->tsap) {
-		DEBUG(0,__FUNCTION__"failed to allocate tsap\n");
+		IRDA_DEBUG(0,__FUNCTION__"failed to allocate tsap\n");
 		return -1;
 	}
 	self->slsap_sel = self->tsap->stsap_sel;
@@ -92,7 +92,7 @@
 {
 	int ret = 0;
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ret = irttp_connect_request(self->tsap, info->dlsap_sel,
 				    info->saddr, info->daddr, 
@@ -110,7 +110,7 @@
 {
 	int ret;
 
-	DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, __FUNCTION__"()\n");
 	
 	ret = irttp_connect_response(self->tsap, SAR_DISABLE, skb);
 
@@ -133,7 +133,7 @@
 
 	ASSERT(skb != NULL, return -1;);
 
-	DEBUG(2, __FUNCTION__"(), clen=%d\n", clen);
+	IRDA_DEBUG(2, __FUNCTION__"(), clen=%d\n", clen);
 
 	/* 
 	 * Insert clen field, currently we either send data only, or control
@@ -164,7 +164,7 @@
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 
-	DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, __FUNCTION__"()\n");
 	
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return -1;);
@@ -184,7 +184,7 @@
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 	struct ircomm_info info;
 
-	DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
@@ -220,7 +220,7 @@
 	struct ircomm_cb *self = (struct ircomm_cb *)instance;
 	struct ircomm_info info;
 
-	DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
@@ -270,7 +270,7 @@
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 	struct ircomm_info info;
 
-	DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
@@ -290,7 +290,7 @@
 {
 	struct ircomm_cb *self = (struct ircomm_cb *) instance;
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_MAGIC, return;);
diff -u --recursive --new-file v2.3.25/linux/net/irda/ircomm/ircomm_tty.c linux/net/irda/ircomm/ircomm_tty.c
--- v2.3.25/linux/net/irda/ircomm/ircomm_tty.c	Wed Oct 27 16:34:12 1999
+++ linux/net/irda/ircomm/ircomm_tty.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Jun  6 21:00:56 1999
- * Modified at:   Tue Oct 19 21:32:04 1999
+ * Modified at:   Sat Oct 30 12:49:26 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       serial.c and previous IrCOMM work by Takahide Higuchi
  * 
@@ -144,7 +144,7 @@
 {
 	int ret;
 
-	DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, __FUNCTION__"()\n");
 
 	ret = tty_unregister_driver(&driver);
         if (ret) {
@@ -171,7 +171,7 @@
 
 	/* Already open */
 	if (self->flags & ASYNC_INITIALIZED) {
-		DEBUG(2, __FUNCTION__ "(), already open so break out!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), already open so break out!\n");
 		return 0;
 	}
 
@@ -226,7 +226,7 @@
 	
 	tty = self->tty;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
 		/* this is a callout device */
@@ -258,17 +258,17 @@
 			return -EBUSY;
 		self->flags |= ASYNC_NORMAL_ACTIVE;
 
-		DEBUG(1, __FUNCTION__ "(), O_NONBLOCK requested!\n");
+		IRDA_DEBUG(1, __FUNCTION__ "(), O_NONBLOCK requested!\n");
 		return 0;
 	}
 
 	if (self->flags & ASYNC_CALLOUT_ACTIVE) {
 		if (self->normal_termios.c_cflag & CLOCAL)
-			DEBUG(1, __FUNCTION__ "(), doing CLOCAL!\n");
+			IRDA_DEBUG(1, __FUNCTION__ "(), doing CLOCAL!\n");
 			do_clocal = 1;
 	} else {
 		if (tty->termios->c_cflag & CLOCAL)
-			DEBUG(1, __FUNCTION__ "(), doing CLOCAL!\n");
+			IRDA_DEBUG(1, __FUNCTION__ "(), doing CLOCAL!\n");
 			do_clocal = 1;
 	}
 	
@@ -282,7 +282,7 @@
 	retval = 0;
 	add_wait_queue(&self->open_wait, &wait);
 	
-	DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
+	IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
 	      __FILE__,__LINE__, tty->driver.name, self->open_count );
 
 	save_flags(flags); cli();
@@ -329,7 +329,7 @@
 			break;
 		}
 		
-		DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n",
+		IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n",
 		      __FILE__,__LINE__, tty->driver.name, self->open_count );
 		
 		schedule();
@@ -342,7 +342,7 @@
 		self->open_count++;
 	self->blocked_open--;
 	
-	DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
+	IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
 	      __FILE__,__LINE__, tty->driver.name, self->open_count);
 			 
 	if (!retval)
@@ -364,7 +364,7 @@
 	int line;
 	int ret;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	MOD_INC_USE_COUNT;
 	line = MINOR(tty->device) - tty->driver.minor_start;
@@ -415,8 +415,8 @@
 	tty->driver_data = self;
 	self->tty = tty;
 
-	DEBUG(1, __FUNCTION__"(), %s%d, count = %d\n", tty->driver.name, 
-	      self->line, self->open_count);
+	IRDA_DEBUG(1, __FUNCTION__"(), %s%d, count = %d\n", tty->driver.name, 
+		   self->line, self->open_count);
 
 	/* Not really used by us, but lets do it anyway */
 	self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
@@ -440,9 +440,9 @@
 	/* Check if this is a "normal" ircomm device, or an irlpt device */
 	if (line < 0x10) {
 		self->service_type = IRCOMM_3_WIRE | IRCOMM_9_WIRE;
-		DEBUG(2, __FUNCTION__ "(), IrCOMM device\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IrCOMM device\n");
 	} else {
-		DEBUG(2, __FUNCTION__ "(), IrLPT device\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IrLPT device\n");
 		self->service_type = IRCOMM_3_WIRE_RAW;
 	}
 
@@ -453,7 +453,7 @@
 	ret = ircomm_tty_block_til_ready(self, filp);
 	if (ret) {
 		/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
-		DEBUG(0, __FUNCTION__ 
+		IRDA_DEBUG(0, __FUNCTION__ 
 		      "(), returning after block_til_ready with %d\n",
 		      ret);
 
@@ -478,7 +478,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 	unsigned long flags;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	if (!tty)
 		return;
@@ -493,7 +493,7 @@
 		MOD_DEC_USE_COUNT;
 		restore_flags(flags);
 
-		DEBUG(2, __FUNCTION__ "(), returning 1\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), returning 1\n");
 		return;
 	}
 
@@ -507,7 +507,7 @@
 		MOD_DEC_USE_COUNT;
 		restore_flags(flags);
 
-		DEBUG(2, __FUNCTION__ "(), open count > 0\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), open count > 0\n");
 		return;
 	}
 	self->flags |= ASYNC_CLOSING;
@@ -658,8 +658,8 @@
 	int len = 0;
 	int size;
 
-	DEBUG(3, __FUNCTION__ "(), count=%d, hw_stopped=%d\n", count,
-	      tty->hw_stopped);
+	IRDA_DEBUG(3, __FUNCTION__ "(), count=%d, hw_stopped=%d\n", count,
+		   tty->hw_stopped);
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
@@ -772,7 +772,7 @@
 			ret = self->max_data_size;
 		restore_flags(flags);
 	}
-	DEBUG(2, __FUNCTION__ "(), ret=%d\n", ret);
+	IRDA_DEBUG(2, __FUNCTION__ "(), ret=%d\n", ret);
 
 	return ret;
 }
@@ -788,7 +788,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 	unsigned long orig_jiffies, poll_time;
 	
-	DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -820,7 +820,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -851,7 +851,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -866,7 +866,7 @@
 		self->session.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS);
 
 		ircomm_param_request(self, IRCOMM_DTE, TRUE);
-		DEBUG(1, __FUNCTION__"(), FLOW_START\n");
+		IRDA_DEBUG(1, __FUNCTION__"(), FLOW_START\n");
 	}
         ircomm_flow_request(self->ircomm, FLOW_START);
 }
@@ -908,7 +908,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 
-	DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -939,7 +939,7 @@
  */
 static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch)
 {
-	DEBUG(0, __FUNCTION__"(), not impl\n");
+	IRDA_DEBUG(0, __FUNCTION__"(), not impl\n");
 }
 
 /*
@@ -994,15 +994,16 @@
 		/*wake_up_interruptible(&self->delta_msr_wait);*/
 	}
 	if ((self->flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) {
-		DEBUG(2, __FUNCTION__ "(), ttys%d CD now %s...\n", self->line,
-		      (status & IRCOMM_CD) ? "on" : "off");
+		IRDA_DEBUG(2, __FUNCTION__ 
+			   "(), ttys%d CD now %s...\n", self->line,
+			   (status & IRCOMM_CD) ? "on" : "off");
 
 		if (status & IRCOMM_CD) {
 			wake_up_interruptible(&self->open_wait);
 		} else if (!((self->flags & ASYNC_CALLOUT_ACTIVE) &&
 			   (self->flags & ASYNC_CALLOUT_NOHUP))) 
 		{
-			DEBUG(2, __FUNCTION__ "(), Doing serial hangup..\n");
+			IRDA_DEBUG(2, __FUNCTION__ "(), Doing serial hangup..\n");
 			
 			if (tty)
 				tty_hangup(tty);
@@ -1011,7 +1012,7 @@
 	if (self->flags & ASYNC_CTS_FLOW) {
 		if (tty->hw_stopped) {
 			if (status & IRCOMM_CTS) {
-				DEBUG(2, __FUNCTION__ "(), CTS tx start...\n");
+				IRDA_DEBUG(2, __FUNCTION__ "(), CTS tx start...\n");
 				
 				tty->hw_stopped = 0;
 
@@ -1021,7 +1022,7 @@
 			}
 		} else {
 			if (!(status & IRCOMM_CTS)) {
-				DEBUG(2, __FUNCTION__ "(), CTS tx stop...\n");
+				IRDA_DEBUG(2, __FUNCTION__ "(), CTS tx stop...\n");
 
 				tty->hw_stopped = 1;
 			}
@@ -1040,7 +1041,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 
-	DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, __FUNCTION__"()\n");
 	
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
@@ -1072,7 +1073,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 	int clen;
 
-	DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, __FUNCTION__"()\n");
 	
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
@@ -1107,7 +1108,7 @@
 
 	switch (cmd) {
 	case FLOW_START:
-		DEBUG(2, __FUNCTION__ "(), hw start!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), hw start!\n");
 		tty->hw_stopped = 0;
 
 		/* ircomm_tty_do_softint will take care of the rest */
@@ -1117,7 +1118,7 @@
 	default:
 		/* If we get here, something is very wrong, better stop */
 	case FLOW_STOP:
-		DEBUG(2, __FUNCTION__ "(), hw stopped!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), hw stopped!\n");
 		tty->hw_stopped = 1;
 		break;
 	}
diff -u --recursive --new-file v2.3.25/linux/net/irda/ircomm/ircomm_tty_attach.c linux/net/irda/ircomm/ircomm_tty_attach.c
--- v2.3.25/linux/net/irda/ircomm/ircomm_tty_attach.c	Wed Oct 27 16:34:12 1999
+++ linux/net/irda/ircomm/ircomm_tty_attach.c	Tue Nov  2 17:07:55 1999
@@ -2,11 +2,11 @@
  *                
  * Filename:      ircomm_tty_attach.c
  * Version:       
- * Description:   
+ * Description:   Code for attaching the serial driver to IrCOMM
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sat Jun  5 17:42:00 1999
- * Modified at:   Tue Oct 19 21:32:17 1999
+ * Modified at:   Sun Oct 31 22:19:37 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -124,14 +124,14 @@
  */
 int ircomm_tty_attach_cable(struct ircomm_tty_cb *self)
 {
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
        	/* Check if somebody has already connected to us */
 	if (ircomm_is_connected(self->ircomm)) {
-		DEBUG(0, __FUNCTION__ "(), already connected!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "(), already connected!\n");
 		return 0;
 	}
 
@@ -142,7 +142,7 @@
 
 	/* Check if somebody has already connected to us */
 	if (ircomm_is_connected(self->ircomm)) {
-		DEBUG(0, __FUNCTION__ "(), already connected!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "(), already connected!\n");
 		return 0;
 	}
 
@@ -159,7 +159,7 @@
  */
 void ircomm_tty_detach_cable(struct ircomm_tty_cb *self)
 {
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -168,6 +168,9 @@
 	irlmp_unregister_client(self->ckey);
 	irlmp_unregister_service(self->skey);
 
+	if (self->iriap) 
+		iriap_close(self->iriap);
+
 	/* Remove LM-IAS object */
 	if (self->obj) {
 		irias_delete_object(self->obj);
@@ -246,16 +249,17 @@
 	 * Set default values, but only if the application for some reason 
 	 * haven't set them already
 	 */
-	DEBUG(2, __FUNCTION__ "(), data-rate = %d\n", self->session.data_rate);
+	IRDA_DEBUG(2, __FUNCTION__ "(), data-rate = %d\n", 
+		   self->session.data_rate);
 	if (!self->session.data_rate)
 		self->session.data_rate = 9600;
-	DEBUG(2, __FUNCTION__ "(), data-format = %d\n", 
-	      self->session.data_format);
+	IRDA_DEBUG(2, __FUNCTION__ "(), data-format = %d\n", 
+		   self->session.data_format);
 	if (!self->session.data_format)
 		self->session.data_format = IRCOMM_WSIZE_8;  /* 8N1 */
 
-	DEBUG(2, __FUNCTION__ "(), flow-control = %d\n", 
-	      self->session.flow_control);
+	IRDA_DEBUG(2, __FUNCTION__ "(), flow-control = %d\n", 
+		   self->session.flow_control);
 	/*self->session.flow_control = IRCOMM_RTS_CTS_IN|IRCOMM_RTS_CTS_OUT;*/
 
 	/* Do not set delta values for the initial parameters */
@@ -295,7 +299,7 @@
 	struct ircomm_tty_cb *self;
 	struct ircomm_tty_info info;
 
-	DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, __FUNCTION__"()\n");
 
 	info.daddr = discovery->daddr;
 	info.saddr = discovery->saddr;
@@ -323,7 +327,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -347,20 +351,24 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) priv;
 
-	DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, __FUNCTION__"()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
+	/* We probably don't need to make any more queries */
+	iriap_close(self->iriap);
+	self->iriap = NULL;
+
 	/* Check if request succeeded */
 	if (result != IAS_SUCCESS) {
-		DEBUG(4, __FUNCTION__ "(), got NULL value!\n");
+		IRDA_DEBUG(4, __FUNCTION__ "(), got NULL value!\n");
 		return;
 	}
 
 	switch (value->type) {
  	case IAS_OCT_SEQ:
-		DEBUG(2, __FUNCTION__"(), got octet sequence\n");
+		IRDA_DEBUG(2, __FUNCTION__"(), got octet sequence\n");
 
 		irda_param_extract_all(self, value->t.oct_seq, value->len,
 				       &ircomm_param_info);
@@ -370,21 +378,21 @@
 		break;
 	case IAS_INTEGER:
 		/* Got LSAP selector */	
-		DEBUG(2, __FUNCTION__"(), got lsapsel = %d\n", 
-		      value->t.integer);
+		IRDA_DEBUG(2, __FUNCTION__"(), got lsapsel = %d\n", 
+			   value->t.integer);
 
 		if (value->t.integer == -1) {
-			DEBUG(0, __FUNCTION__"(), invalid value!\n");
+			IRDA_DEBUG(0, __FUNCTION__"(), invalid value!\n");
 		} else
 			self->dlsap_sel = value->t.integer;
 
 		ircomm_tty_do_event(self, IRCOMM_TTY_GOT_LSAPSEL, NULL, NULL);
 		break;
 	case IAS_MISSING:
-		DEBUG(0, __FUNCTION__"(), got IAS_MISSING\n");
+		IRDA_DEBUG(0, __FUNCTION__"(), got IAS_MISSING\n");
 		break;
 	default:
-		DEBUG(0, __FUNCTION__"(), got unknown type!\n");
+		IRDA_DEBUG(0, __FUNCTION__"(), got unknown type!\n");
 		break;
 	}
 }
@@ -403,7 +411,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -430,7 +438,7 @@
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
 	int clen;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -455,7 +463,7 @@
  */
 void ircomm_tty_link_established(struct ircomm_tty_cb *self)
 {
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	del_timer(&self->watchdog_timer);
 
@@ -465,7 +473,7 @@
 	 * the client will have to wait for the CD to be set.
 	 */
 	if (!(self->flags & ASYNC_CTS_FLOW)) {
-		DEBUG(2, __FUNCTION__ "(), starting hardware!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), starting hardware!\n");
 		if (!self->tty)
 			return;
 		self->tty->hw_stopped = 0;
@@ -504,7 +512,7 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) data;
 	
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
@@ -525,8 +533,8 @@
 {
 	int ret = 0;
 
-	DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
-	      ircomm_tty_state[self->state], ircomm_tty_event[event]);
+	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
+		   ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
 	switch (event) {
 	case IRCOMM_TTY_ATTACH_CABLE:
@@ -540,11 +548,19 @@
 		self->daddr = info->daddr;
 		self->saddr = info->saddr;
 
-		iriap_getvaluebyclass_request("IrDA:IrCOMM", "Parameters",
-					      self->saddr, self->daddr,
-					      ircomm_tty_getvalue_confirm, 
-					      self);
+		if (self->iriap) {
+			WARNING(__FUNCTION__ 
+				"(), busy with a previous query\n");
+			return -EBUSY;
+		}
 
+		self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
+					 ircomm_tty_getvalue_confirm);
+
+		iriap_getvaluebyclass_request(self->iriap,
+					      self->saddr, self->daddr,
+					      "IrDA:IrCOMM", "Parameters");
+		
 		ircomm_tty_start_watchdog_timer(self, 3*HZ);
 		ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_PARAMETERS);
 		break;
@@ -566,8 +582,8 @@
 		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
 		break;
 	default:
-		DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
-		      ircomm_tty_event[event]);
+		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
+			   ircomm_tty_event[event]);
 		return -EINVAL;
 	}
 	return ret;
@@ -586,27 +602,34 @@
 {
 	int ret = 0;
 
-	DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
-	      ircomm_tty_state[self->state], ircomm_tty_event[event]);
+	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
+		   ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
 	switch (event) {
 	case IRCOMM_TTY_DISCOVERY_INDICATION:
 		self->daddr = info->daddr;
 		self->saddr = info->saddr;
 
+		if (self->iriap) {
+			WARNING(__FUNCTION__ 
+				"(), busy with a previous query\n");
+			return -EBUSY;
+		}
+		
+		self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
+					 ircomm_tty_getvalue_confirm);
+		
 		if (self->service_type == IRCOMM_3_WIRE_RAW) {
-			iriap_getvaluebyclass_request("IrLPT", 
-						      "IrDA:IrLMP:LsapSel",
-						      self->saddr, self->daddr,
-						      ircomm_tty_getvalue_confirm, 
-						      self);
+			iriap_getvaluebyclass_request(self->iriap, self->saddr,
+						      self->daddr, "IrLPT", 
+						      "IrDA:IrLMP:LsapSel");
 			ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_LSAP_SEL);
 		} else {
-			iriap_getvaluebyclass_request("IrDA:IrCOMM", 
-						      "Parameters",
-						      self->saddr, self->daddr,
-						      ircomm_tty_getvalue_confirm, 
-						      self);
+			iriap_getvaluebyclass_request(self->iriap, self->saddr,
+						      self->daddr, 
+						      "IrDA:IrCOMM", 
+						      "Parameters");
+
 			ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_PARAMETERS);
 		}
 		ircomm_tty_start_watchdog_timer(self, 3*HZ);
@@ -631,8 +654,8 @@
 		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
 		break;
 	default:
-		DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
-		      ircomm_tty_event[event]);
+		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
+			   ircomm_tty_event[event]);
 		return -EINVAL;
 	}
 	return ret;
@@ -651,16 +674,23 @@
 {
 	int ret = 0;
 
-	DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
-	      ircomm_tty_state[self->state], ircomm_tty_event[event]);
+	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
+		   ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
 	switch (event) {
 	case IRCOMM_TTY_GOT_PARAMETERS:
-		iriap_getvaluebyclass_request("IrDA:IrCOMM", 
-					      "IrDA:TinyTP:LsapSel",
-					      self->saddr, self->daddr,
-					      ircomm_tty_getvalue_confirm, 
-					      self);
+		if (self->iriap) {
+			WARNING(__FUNCTION__ 
+				"(), busy with a previous query\n");
+			return -EBUSY;
+		}
+		
+		self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
+					 ircomm_tty_getvalue_confirm);
+
+		iriap_getvaluebyclass_request(self->iriap, self->saddr, 
+					      self->daddr, "IrDA:IrCOMM", 
+					      "IrDA:TinyTP:LsapSel");
 
 		ircomm_tty_start_watchdog_timer(self, 3*HZ);
 		ircomm_tty_next_state(self, IRCOMM_TTY_QUERY_LSAP_SEL);
@@ -685,8 +715,8 @@
 		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
 		break;
 	default:
-		DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
-		      ircomm_tty_event[event]);
+		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
+			   ircomm_tty_event[event]);
 		return -EINVAL;
 	}
 	return ret;
@@ -705,8 +735,8 @@
 {
 	int ret = 0;
 
-	DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
-	      ircomm_tty_state[self->state], ircomm_tty_event[event]);
+	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
+		   ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
 	switch (event) {
 	case IRCOMM_TTY_GOT_LSAPSEL:
@@ -737,8 +767,8 @@
 		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
 		break;
 	default:
-		DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
-		      ircomm_tty_event[event]);
+		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
+			   ircomm_tty_event[event]);
 		return -EINVAL;
 	}
 	return ret;
@@ -757,8 +787,8 @@
 {
 	int ret = 0;
 
-	DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
-	      ircomm_tty_state[self->state], ircomm_tty_event[event]);
+	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
+		   ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
 	switch (event) {
 	case IRCOMM_TTY_CONNECT_CONFIRM:
@@ -793,8 +823,8 @@
 		ircomm_tty_next_state(self, IRCOMM_TTY_IDLE);
 		break;
 	default:
-		DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
-		      ircomm_tty_event[event]);
+		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
+			   ircomm_tty_event[event]);
 		return -EINVAL;
 	}
 	return ret;
@@ -830,8 +860,8 @@
 		ircomm_tty_check_modem_status(self);
 		break;
 	default:
-		DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
-		      ircomm_tty_event[event]);
+		IRDA_DEBUG(2, __FUNCTION__"(), unknown event: %s\n",
+			   ircomm_tty_event[event]);
 		return -EINVAL;
 	}
 	return ret;
@@ -846,8 +876,8 @@
 int ircomm_tty_do_event(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
 			struct sk_buff *skb, struct ircomm_tty_info *info) 
 {
-	DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
-	      ircomm_tty_state[self->state], ircomm_tty_event[event]);
+	IRDA_DEBUG(2, __FUNCTION__": state=%s, event=%s\n",
+		   ircomm_tty_state[self->state], ircomm_tty_event[event]);
 
 	return (*state[self->state])(self, event, skb, info);
 }
@@ -862,7 +892,7 @@
 {
 	self->state = state;
 	
-	DEBUG(2, __FUNCTION__": next state=%s, service type=%d\n", 
-	      ircomm_tty_state[self->state], self->service_type);
+	IRDA_DEBUG(2, __FUNCTION__": next state=%s, service type=%d\n", 
+		   ircomm_tty_state[self->state], self->service_type);
 }
 
diff -u --recursive --new-file v2.3.25/linux/net/irda/ircomm/ircomm_tty_ioctl.c linux/net/irda/ircomm/ircomm_tty_ioctl.c
--- v2.3.25/linux/net/irda/ircomm/ircomm_tty_ioctl.c	Mon Oct  4 15:49:30 1999
+++ linux/net/irda/ircomm/ircomm_tty_ioctl.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Jun 10 14:39:09 1999
- * Modified at:   Tue Aug 31 10:29:36 1999
+ * Modified at:   Sat Oct 30 12:50:41 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1999 Dag Brattli, All Rights Reserved.
@@ -145,7 +145,6 @@
 {
 	struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
 	unsigned int cflag = tty->termios->c_cflag;
-	unsigned long flags;
 
 	if ((cflag == old_termios->c_cflag) && 
 	    (RELEVANT_IFLAG(tty->termios->c_iflag) == 
@@ -194,7 +193,7 @@
 {
 	unsigned int result;
 
-	DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, __FUNCTION__ "()\n");
 
 	result =  ((self->session.dte & IRCOMM_RTS) ? TIOCM_RTS : 0)
 		| ((self->session.dte & IRCOMM_DTR) ? TIOCM_DTR : 0)
@@ -219,7 +218,7 @@
 	__u8 old_rts, old_dtr;
 	int error;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
@@ -282,7 +281,7 @@
 	if (!retinfo)
 		return -EFAULT;
 
-	DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, __FUNCTION__ "()\n");
 
 	memset(&info, 0, sizeof(info));
 	info.line = self->line;
@@ -314,11 +313,11 @@
 static int ircomm_tty_set_serial_info(struct ircomm_tty_cb *tty,
 				      struct serial_struct *new_info)
 {
+#if 0
 	struct serial_struct new_serial;
 	struct ircomm_tty_cb old_driver;
 
-	DEBUG(2, __FUNCTION__ "()\n");
-#if 0
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
 		return -EFAULT;
@@ -412,11 +411,11 @@
 		ret = ircomm_tty_set_serial_info(self, (struct serial_struct *) arg);
 		break;
 	case TIOCMIWAIT:
-		DEBUG(0, "(), TIOCMIWAIT, not impl!\n");
+		IRDA_DEBUG(0, "(), TIOCMIWAIT, not impl!\n");
 		break;
 
 	case TIOCGICOUNT:
-		DEBUG(0, __FUNCTION__ "(), TIOCGICOUNT not impl!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "(), TIOCGICOUNT not impl!\n");
 #if 0
 		save_flags(flags); cli();
 		cnow = driver->icount;
diff -u --recursive --new-file v2.3.25/linux/net/irda/iriap.c linux/net/irda/iriap.c
--- v2.3.25/linux/net/irda/iriap.c	Wed Oct 27 16:34:12 1999
+++ linux/net/irda/iriap.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Aug 21 00:02:07 1997
- * Modified at:   Sat Oct  9 17:00:56 1999
+ * Modified at:   Sun Oct 31 22:10:45 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -60,7 +60,6 @@
 
 extern char *lmp_reasons[];
 
-static struct iriap_cb *iriap_open( __u8 slsap, int mode);
 static void __iriap_close(struct iriap_cb *self);
 static void iriap_disconnect_indication(void *instance, void *sap, 
 					LM_REASON reason, struct sk_buff *skb);
@@ -115,7 +114,7 @@
 	 *  Register server support with IrLMP so we can accept incoming 
 	 *  connections 
 	 */
-	iriap_open(LSAP_IAS, IAS_SERVER);
+	iriap_open(LSAP_IAS, IAS_SERVER, NULL, NULL);
 	
 	return 0;
 }
@@ -139,7 +138,8 @@
  *
  *    Opens an instance of the IrIAP layer, and registers with IrLMP
  */
-struct iriap_cb *iriap_open(__u8 slsap_sel, int mode)
+struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv, 
+			    CONFIRM_CALLBACK callback)
 {
 	struct iriap_cb *self;
 	struct lsap_cb *lsap;
@@ -181,6 +181,9 @@
 	self->slsap_sel = slsap_sel;
 	self->mode = mode;
 
+	self->confirm = callback;
+	self->priv = priv;
+
 	init_timer(&self->watchdog_timer);
 
 	hashbin_insert(iriap, (queue_t *) self, slsap_sel, NULL);
@@ -275,7 +278,7 @@
 		iriap_do_client_event(self, IAP_LM_DISCONNECT_INDICATION, 
 				      NULL);
 		/* Close instance only if client */
-		iriap_close(self);
+		/* iriap_close(self); */
 		
 	} else {
 		IRDA_DEBUG(4, __FUNCTION__ "(), disconnect as server\n");
@@ -348,28 +351,21 @@
  *    Retreive all values from attribute in all objects with given class
  *    name
  */
-void iriap_getvaluebyclass_request(char *name, char *attr, 
-				   __u32 saddr, __u32 daddr,
-				   CONFIRM_CALLBACK callback, void *priv)
+int iriap_getvaluebyclass_request(struct iriap_cb *self,
+				  __u32 saddr, __u32 daddr, 
+				  char *name, char *attr)
 {
 	struct sk_buff *skb;
-	struct iriap_cb *self;
 	int name_len, attr_len;
-	__u8 slsap = LSAP_ANY;  /* Source LSAP to use */
 	__u8 *frame;
 
+	ASSERT(self != NULL, return -1;);
+	ASSERT(self->magic == IAS_MAGIC, return -1;);
+
 	/* Client must supply the destination device address */
 	if (!daddr)
-		return;
+		return -1;
 	
-	self = iriap_open(slsap, IAS_CLIENT);
-	if (!self)
-		return;
-
-	self->mode = IAS_CLIENT;
-	self->confirm = callback;
-	self->priv = priv;
-
 	self->daddr = daddr;
 	self->saddr = saddr;
 
@@ -383,7 +379,7 @@
 	
 	skb = dev_alloc_skb(64);
 	if (!skb)
-		return;
+		return -ENOMEM;
 
 	name_len = strlen(name);
 	attr_len = strlen(attr);
@@ -401,6 +397,8 @@
 	memcpy(frame+3+name_len, attr, attr_len);  /* Insert attr */
 
 	iriap_do_client_event(self, IAP_CALL_REQUEST_GVBC, skb);
+
+	return 0;
 }
 
 /*
@@ -467,8 +465,9 @@
 /* 		case CS_ISO_8859_9: */
 /* 		case CS_UNICODE: */
 		default:
-			IRDA_DEBUG(0, __FUNCTION__"(), charset %s, not supported\n",
-			      ias_charset_types[charset]);
+			IRDA_DEBUG(0, __FUNCTION__
+				   "(), charset %s, not supported\n",
+				   ias_charset_types[charset]);
 			return;
 			/* break; */
 		}
@@ -761,7 +760,7 @@
 	if (self->mode == IAS_SERVER) {
 		/* Call server */
 		IRDA_DEBUG(4, __FUNCTION__ "(), Calling server!\n");
-		iriap_do_r_connect_event( self, IAP_RECV_F_LST, skb);
+		iriap_do_r_connect_event(self, IAP_RECV_F_LST, skb);
 
 		return 0;
 	}
@@ -779,12 +778,14 @@
 	}
 
 	opcode &= ~IAP_LST; /* Mask away LST bit */
-	
+
 	switch (opcode) {
 	case GET_INFO_BASE:
 		IRDA_DEBUG(0, "IrLMP GetInfoBaseDetails not implemented!\n");
 		break;
 	case GET_VALUE_BY_CLASS:
+		iriap_do_call_event(self, IAP_RECV_F_LST, skb);
+			
 		switch (frame[1]) {
 		case IAS_SUCCESS:
 			iriap_getvaluebyclass_confirm(self, skb);
@@ -793,7 +794,7 @@
 			WARNING(__FUNCTION__ "(), No such class!\n");
 			/* Finished, close connection! */
 			iriap_disconnect_request(self);
-
+			
 			if (self->confirm)
 				self->confirm(IAS_CLASS_UNKNOWN, 0, NULL, 
 					      self->priv);
@@ -808,16 +809,12 @@
 					      self->priv);
 			break;
 		}
-		iriap_do_call_event(self, IAP_RECV_F_LST, skb);
-
-		/*  
-		 *  We remove LSAPs used by IrIAS as a client since these
-		 *  are more difficult to reuse!  
-		 */
-		iriap_close(self);
+		
+	/* 	iriap_close(self); */
 		break;
 	default:
-		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown op-code: %02x\n", opcode);
+		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown op-code: %02x\n", 
+			   opcode);
 		break;
 	}
 	return 0;
@@ -874,7 +871,7 @@
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IAS_MAGIC, return;);
 
-	iriap_close(self);
+	/* iriap_close(self); */
 }
 
 #ifdef CONFIG_PROC_FS
diff -u --recursive --new-file v2.3.25/linux/net/irda/iriap_event.c linux/net/irda/iriap_event.c
--- v2.3.25/linux/net/irda/iriap_event.c	Wed Oct 27 16:34:12 1999
+++ linux/net/irda/iriap_event.c	Tue Nov  2 17:07:55 1999
@@ -6,10 +6,11 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Aug 21 00:02:07 1997
- * Modified at:   Sun May  9 11:01:47 1999
+ * Modified at:   Sun Oct 31 22:13:00 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
- *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
+ *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, 
+ *     All Rights Reserved.
  *     
  *     This program is free software; you can redistribute it and/or 
  *     modify it under the terms of the GNU General Public License as 
@@ -27,42 +28,42 @@
 #include <net/irda/iriap.h>
 #include <net/irda/iriap_event.h>
 
-static void state_s_disconnect   ( struct iriap_cb *self, IRIAP_EVENT event, 
-				   struct sk_buff *skb);
-static void state_s_connecting   ( struct iriap_cb *self, IRIAP_EVENT event, 
-				   struct sk_buff *skb);
-static void state_s_call         ( struct iriap_cb *self, IRIAP_EVENT event, 
-				   struct sk_buff *skb);
+static void state_s_disconnect   (struct iriap_cb *self, IRIAP_EVENT event, 
+				  struct sk_buff *skb);
+static void state_s_connecting   (struct iriap_cb *self, IRIAP_EVENT event, 
+				  struct sk_buff *skb);
+static void state_s_call         (struct iriap_cb *self, IRIAP_EVENT event, 
+				  struct sk_buff *skb);
 
-static void state_s_make_call    ( struct iriap_cb *self, IRIAP_EVENT event, 
-				   struct sk_buff *skb);
-static void state_s_calling      ( struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_make_call    (struct iriap_cb *self, IRIAP_EVENT event, 
+				  struct sk_buff *skb);
+static void state_s_calling      (struct iriap_cb *self, IRIAP_EVENT event, 
+				  struct sk_buff *skb);
+static void state_s_outstanding  (struct iriap_cb *self, IRIAP_EVENT event, 
+				  struct sk_buff *skb);
+static void state_s_replying     (struct iriap_cb *self, IRIAP_EVENT event, 
 				   struct sk_buff *skb);
-static void state_s_outstanding  ( struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_wait_for_call(struct iriap_cb *self, IRIAP_EVENT event, 
 				   struct sk_buff *skb);
-static void state_s_replying     ( struct iriap_cb *self, IRIAP_EVENT event, 
-				   struct sk_buff *skb);
-static void state_s_wait_for_call( struct iriap_cb *self, IRIAP_EVENT event, 
-				   struct sk_buff *skb);
-static void state_s_wait_active  ( struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_wait_active  (struct iriap_cb *self, IRIAP_EVENT event, 
 				   struct sk_buff *skb);
 
-static void state_r_disconnect   ( struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_disconnect   (struct iriap_cb *self, IRIAP_EVENT event, 
 				   struct sk_buff *skb);
-static void state_r_call         ( struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_call         (struct iriap_cb *self, IRIAP_EVENT event, 
 				   struct sk_buff *skb);
-static void state_r_waiting      ( struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_waiting      (struct iriap_cb *self, IRIAP_EVENT event, 
 				   struct sk_buff *skb);
-static void state_r_wait_active  ( struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_wait_active  (struct iriap_cb *self, IRIAP_EVENT event, 
 				   struct sk_buff *skb);
-static void state_r_receiving    ( struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_receiving    (struct iriap_cb *self, IRIAP_EVENT event, 
 				   struct sk_buff *skb);
-static void state_r_execute      ( struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_execute      (struct iriap_cb *self, IRIAP_EVENT event, 
 				   struct sk_buff *skb);
-static void state_r_returning    ( struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_r_returning    (struct iriap_cb *self, IRIAP_EVENT event, 
 				   struct sk_buff *skb);
 
-static void (*iriap_state[])( struct iriap_cb *self, IRIAP_EVENT event, 
+static void (*iriap_state[])(struct iriap_cb *self, IRIAP_EVENT event, 
 			      struct sk_buff *skb) = { 
 	/* Client FSM */
 	state_s_disconnect,
@@ -89,89 +90,72 @@
 	state_r_returning,
 };
 
-void iriap_next_client_state( struct iriap_cb *self, IRIAP_STATE state) 
+void iriap_next_client_state(struct iriap_cb *self, IRIAP_STATE state) 
 {
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IAS_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IAS_MAGIC, return;);
 
- 	switch ( state) { 
- /* 	case S_DISCONNECT: IRDA_DEBUG( 0, "IAP Client = S_DISCONNECT\n"); break;  */
-/*  	case S_CONNECTING: IRDA_DEBUG( 0, "IAP Client = S_CONNECTING\n"); break;  */
-/*  	case S_CALL:       IRDA_DEBUG( 0, "IAP Client = S_CALL\n");       break;  */
- 	default: 
- 		break; 
- 	} 
 	self->client_state = state;
 }
 
-void iriap_next_call_state( struct iriap_cb *self, IRIAP_STATE state) 
+void iriap_next_call_state(struct iriap_cb *self, IRIAP_STATE state) 
 {
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IAS_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IAS_MAGIC, return;);
 
-/* 	switch ( state) { */
-/* 	case S_MAKE_CALL:     IRDA_DEBUG( 0, "IAP Call = S_MAKE_CALL\n"); break; */
-/* 	case S_CALLING:       IRDA_DEBUG( 0, "IAP Call = S_CALLING\n"); break; */
-/* 	case S_OUTSTANDING:   IRDA_DEBUG( 0, "IAP Call = S_OUTSTANDING\n");break; */
-/* 	case S_REPLYING:      IRDA_DEBUG( 0, "IAP Call = S_REPLYING\n"); break; */
-/* 	case S_WAIT_FOR_CALL: IRDA_DEBUG( 0, "IAP Call = S_WAIT_FOR_CALL\n"); break; */
-/* 	case S_WAIT_ACTIVE:   IRDA_DEBUG( 0, "IAP Call = S_WAIT_ACTIVE\n"); break; */
-/* 	default: */
-/* 		break; */
-/* 	} */
 	self->call_state = state;
 }
 
-void iriap_next_server_state( struct iriap_cb *self, IRIAP_STATE state)
+void iriap_next_server_state(struct iriap_cb *self, IRIAP_STATE state)
 {
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IAS_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IAS_MAGIC, return;);
 
 	self->server_state = state;
 }
 
-void iriap_next_r_connect_state( struct iriap_cb *self, IRIAP_STATE state)
+void iriap_next_r_connect_state(struct iriap_cb *self, IRIAP_STATE state)
 {
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IAS_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IAS_MAGIC, return;);
 	
 	self->r_connect_state = state;
 }
 
-void iriap_do_client_event( struct iriap_cb *self, IRIAP_EVENT event, 
-			    struct sk_buff *skb) 
+void iriap_do_client_event(struct iriap_cb *self, IRIAP_EVENT event, 
+			   struct sk_buff *skb) 
 {
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IAS_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IAS_MAGIC, return;);
 
-	(*iriap_state[ self->client_state]) ( self, event, skb);
+	(*iriap_state[ self->client_state]) (self, event, skb);
 }
 
-void iriap_do_call_event( struct iriap_cb *self, IRIAP_EVENT event, 
-			  struct sk_buff *skb) 
+void iriap_do_call_event(struct iriap_cb *self, IRIAP_EVENT event, 
+			 struct sk_buff *skb) 
 {
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IAS_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IAS_MAGIC, return;);
 	
-	(*iriap_state[ self->call_state]) ( self, event, skb);
+	(*iriap_state[ self->call_state]) (self, event, skb);
 }
 
-void iriap_do_server_event( struct iriap_cb *self, IRIAP_EVENT event, 
+void iriap_do_server_event(struct iriap_cb *self, IRIAP_EVENT event, 
 			    struct sk_buff *skb) 
 {
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IAS_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IAS_MAGIC, return;);
 	
-	(*iriap_state[ self->server_state]) ( self, event, skb);
+	(*iriap_state[ self->server_state]) (self, event, skb);
 }
 
-void iriap_do_r_connect_event( struct iriap_cb *self, IRIAP_EVENT event, 
-			       struct sk_buff *skb) 
+void iriap_do_r_connect_event(struct iriap_cb *self, IRIAP_EVENT event, 
+			      struct sk_buff *skb) 
 {
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IAS_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IAS_MAGIC, return;);
 	
-	(*iriap_state[ self->r_connect_state]) ( self, event, skb);
+	(*iriap_state[ self->r_connect_state]) (self, event, skb);
 }
 
 
@@ -181,26 +165,26 @@
  *    S-Disconnect, The device has no LSAP connection to a particular
  *    remote device.
  */
-static void state_s_disconnect( struct iriap_cb *self, IRIAP_EVENT event, 
-				struct sk_buff *skb) 
+static void state_s_disconnect(struct iriap_cb *self, IRIAP_EVENT event, 
+			       struct sk_buff *skb) 
 {
 	int ret;
 
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IAS_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IAS_MAGIC, return;);
 
-	switch( event) {
+	switch (event) {
 	case IAP_CALL_REQUEST_GVBC:
-		iriap_next_client_state( self, S_CONNECTING);
+		iriap_next_client_state(self, S_CONNECTING);
 		self->skb = skb;
-		ret = irlmp_connect_request( self->lsap, LSAP_IAS, 
+		ret = irlmp_connect_request(self->lsap, LSAP_IAS, 
 					     self->saddr, self->daddr, 
 					     NULL, NULL);
 		break;
 	case IAP_LM_DISCONNECT_INDICATION:
 		break;
 	default:
-		IRDA_DEBUG( 0, __FUNCTION__"(), Unknown event %d\n", event);
+		IRDA_DEBUG(0, __FUNCTION__"(), Unknown event %d\n", event);
 		break;
 	}
 }
@@ -211,28 +195,28 @@
  *    S-Connecting
  *
  */
-static void state_s_connecting( struct iriap_cb *self, IRIAP_EVENT event, 
-				struct sk_buff *skb) 
+static void state_s_connecting(struct iriap_cb *self, IRIAP_EVENT event, 
+			       struct sk_buff *skb) 
 {
-	ASSERT( self != NULL, return;);
-	ASSERT( self->magic == IAS_MAGIC, return;);
+	ASSERT(self != NULL, return;);
+	ASSERT(self->magic == IAS_MAGIC, return;);
 
-	switch( event) {
+	switch (event) {
 	case IAP_LM_CONNECT_CONFIRM:
 		/*
 		 *  Jump to S-Call FSM
 		 */
-		iriap_do_call_event( self, IAP_CALL_REQUEST, skb);
-		/* iriap_call_request( self, 0,0,0); */
-		iriap_next_client_state( self, S_CALL);
+		iriap_do_call_event(self, IAP_CALL_REQUEST, skb);
+		/* iriap_call_request(self, 0,0,0); */
+		iriap_next_client_state(self, S_CALL);
 		break;
 	case IAP_LM_DISCONNECT_INDICATION:
 		/* Abort calls */
-		iriap_next_call_state( self, S_MAKE_CALL);
-		iriap_next_client_state( self, S_DISCONNECT);
+		iriap_next_call_state(self, S_MAKE_CALL);
+		iriap_next_client_state(self, S_DISCONNECT);
 		break;
 	default:
-		IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 }
@@ -244,19 +228,19 @@
  *    device. Whenever the LSAP connection is disconnected, this state
  *    catches that event and clears up 
  */
-static void state_s_call( struct iriap_cb *self, IRIAP_EVENT event, 
-			  struct sk_buff *skb) 
+static void state_s_call(struct iriap_cb *self, IRIAP_EVENT event, 
+			 struct sk_buff *skb) 
 {
-	ASSERT( self != NULL, return;);
+	ASSERT(self != NULL, return;);
 
-	switch( event) {
+	switch (event) {
 	case IAP_LM_DISCONNECT_INDICATION:
 		/* Abort calls */
-		iriap_next_call_state( self, S_MAKE_CALL);
-		iriap_next_client_state( self, S_DISCONNECT);
+		iriap_next_call_state(self, S_MAKE_CALL);
+		iriap_next_client_state(self, S_DISCONNECT);
 		break;
 	default:
-		IRDA_DEBUG( 0, "state_s_call: Unknown event %d\n", event);
+		IRDA_DEBUG(0, "state_s_call: Unknown event %d\n", event);
 		break;
 	}
 }
@@ -267,23 +251,22 @@
  *    S-Make-Call
  *
  */
-static void state_s_make_call( struct iriap_cb *self, IRIAP_EVENT event, 
-			       struct sk_buff *skb) 
+static void state_s_make_call(struct iriap_cb *self, IRIAP_EVENT event, 
+			      struct sk_buff *skb) 
 {
-	ASSERT( self != NULL, return;);
+	ASSERT(self != NULL, return;);
 
-	switch( event) {
+	switch (event) {
 	case IAP_CALL_REQUEST:
-		irlmp_data_request( self->lsap, self->skb);
-		iriap_next_call_state( self, S_OUTSTANDING);
+		irlmp_data_request(self->lsap, self->skb);
+		iriap_next_call_state(self, S_OUTSTANDING);
 		break;
 	default:
-		IRDA_DEBUG( 0, "state_s_make_call: Unknown event %d\n", event);
+		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
-	if ( skb) {
-		dev_kfree_skb( skb);
-	}
+	if (skb)
+		dev_kfree_skb(skb);
 }
 
 /*
@@ -292,10 +275,10 @@
  *    S-Calling
  *
  */
-static void state_s_calling( struct iriap_cb *self, IRIAP_EVENT event, 
-			     struct sk_buff *skb) 
+static void state_s_calling(struct iriap_cb *self, IRIAP_EVENT event, 
+			    struct sk_buff *skb) 
 {
-	IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented\n");
+	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
 
 /*
@@ -304,21 +287,21 @@
  *    S-Outstanding, The device is waiting for a response to a command
  *
  */
-static void state_s_outstanding( struct iriap_cb *self, IRIAP_EVENT event, 
-				 struct sk_buff *skb) 
+static void state_s_outstanding(struct iriap_cb *self, IRIAP_EVENT event, 
+				struct sk_buff *skb) 
 {
-	ASSERT( self != NULL, return;);
+	ASSERT(self != NULL, return;);
 
-	switch( event) {
+	switch (event) {
 	case IAP_RECV_F_LST:
-		iriap_send_ack( self);
+		iriap_send_ack(self);
 		/*LM_Idle_request(idle); */
 
-		dev_kfree_skb( skb);
-		iriap_next_call_state( self, S_WAIT_FOR_CALL);
+		dev_kfree_skb(skb);
+		iriap_next_call_state(self, S_WAIT_FOR_CALL);
 		break;
 	default:
-		IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(0, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}		
 }
@@ -328,10 +311,10 @@
  *
  *    S-Replying, The device is collecting a multiple part response
  */
-static void state_s_replying( struct iriap_cb *self, IRIAP_EVENT event, 
-			      struct sk_buff *skb) 
+static void state_s_replying(struct iriap_cb *self, IRIAP_EVENT event, 
+			     struct sk_buff *skb) 
 {
-	IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented\n");
+	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
 
 /*
@@ -340,10 +323,10 @@
  *    S-Wait-for-Call
  *
  */
-static void state_s_wait_for_call( struct iriap_cb *self, IRIAP_EVENT event, 
+static void state_s_wait_for_call(struct iriap_cb *self, IRIAP_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented\n");
+	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
 
 
@@ -353,10 +336,10 @@
  *    S-Wait-Active
  *
  */
-static void state_s_wait_active( struct iriap_cb *self, IRIAP_EVENT event, 
-				 struct sk_buff *skb) 
+static void state_s_wait_active(struct iriap_cb *self, IRIAP_EVENT event, 
+				struct sk_buff *skb) 
 {
-	IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented\n");
+	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
 
 /**************************************************************************
@@ -371,18 +354,16 @@
  *    LM-IAS server is disconnected (not processing any requests!)
  *
  */
-static void state_r_disconnect( struct iriap_cb *self, IRIAP_EVENT event, 
-				struct sk_buff *skb) 
+static void state_r_disconnect(struct iriap_cb *self, IRIAP_EVENT event, 
+			       struct sk_buff *skb) 
 {
 	struct sk_buff *tx_skb;
 	
-	switch( event) {
+	switch (event) {
 	case IAP_LM_CONNECT_INDICATION:
-		tx_skb = dev_alloc_skb( 64);
-		if ( tx_skb == NULL) {
-			IRDA_DEBUG( 0,"state_r_disconnect: "
-			       "Could not allocate an sk_buff of length %d\n",
-			       64);
+		tx_skb = dev_alloc_skb(64);
+		if (tx_skb == NULL) {
+			WARNING(__FUNCTION__ "(), unable to malloc!\n");
 			return;
 		}
 
@@ -392,20 +373,20 @@
 		irlmp_connect_response(self->lsap, tx_skb);
 		/*LM_Idle_request(idle); */
 		
-		iriap_next_server_state( self, R_CALL);
+		iriap_next_server_state(self, R_CALL);
 		
 		/*
 		 *  Jump to R-Connect FSM, we skip R-Waiting since we do not
 		 *  care about LM_Idle_request()!
 		 */
-		iriap_next_r_connect_state( self, R_RECEIVING);
+		iriap_next_r_connect_state(self, R_RECEIVING);
 
 		if (skb)
-			dev_kfree_skb( skb);
+			dev_kfree_skb(skb);
 		
 		break;
 	default:
-		IRDA_DEBUG( 0, "state_r_disconnect: Unknown event %d\n", event);
+		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event %d\n", event);
 		break;
 	}		
 }
@@ -416,20 +397,20 @@
  *    
  *
  */
-static void state_r_call( struct iriap_cb *self, IRIAP_EVENT event, 
-			  struct sk_buff *skb) 
+static void state_r_call(struct iriap_cb *self, IRIAP_EVENT event, 
+			 struct sk_buff *skb) 
 {
-	IRDA_DEBUG( 4, "state_r_call()\n");
+	IRDA_DEBUG(4, "state_r_call()\n");
 
-	switch( event) {
+	switch (event) {
 	case IAP_LM_DISCONNECT_INDICATION:
 		/* Abort call */
-		iriap_next_server_state( self, R_DISCONNECT);
-		iriap_next_r_connect_state( self, R_WAITING);
+		iriap_next_server_state(self, R_DISCONNECT);
+		iriap_next_r_connect_state(self, R_WAITING);
 		
 		break;
 	default:
-		IRDA_DEBUG( 0, "state_r_call, unknown event!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event!\n");
 		break;
 	}
 }
@@ -444,16 +425,16 @@
  *    
  *
  */
-static void state_r_waiting( struct iriap_cb *self, IRIAP_EVENT event, 
-			     struct sk_buff *skb) 
+static void state_r_waiting(struct iriap_cb *self, IRIAP_EVENT event, 
+			    struct sk_buff *skb) 
 {
-	IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented\n");
+	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
 
-static void state_r_wait_active( struct iriap_cb *self, 
+static void state_r_wait_active(struct iriap_cb *self, 
 				 IRIAP_EVENT event, struct sk_buff *skb) 
 {
-	IRDA_DEBUG( 0, __FUNCTION__ "(), Not implemented\n");
+	IRDA_DEBUG(0, __FUNCTION__ "(), Not implemented\n");
 }
 
 /*
@@ -462,19 +443,19 @@
  *    We are receiving a command
  *
  */
-static void state_r_receiving( struct iriap_cb *self, IRIAP_EVENT event, 
-			       struct sk_buff *skb) 
+static void state_r_receiving(struct iriap_cb *self, IRIAP_EVENT event, 
+			      struct sk_buff *skb) 
 {
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
-	switch( event) {
+	switch (event) {
 	case IAP_RECV_F_LST:
-		iriap_next_r_connect_state( self, R_EXECUTE);
+		iriap_next_r_connect_state(self, R_EXECUTE);
 	 		
-		iriap_call_indication( self, skb);
+		iriap_call_indication(self, skb);
 		break;
 	default:
-		IRDA_DEBUG( 0, __FUNCTION__ "(), unknown event!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event!\n");
 		break;
 	}
 
@@ -486,40 +467,40 @@
  *    The server is processing the request
  *
  */
-static void state_r_execute( struct iriap_cb *self, IRIAP_EVENT event, 
-			     struct sk_buff *skb) 
+static void state_r_execute(struct iriap_cb *self, IRIAP_EVENT event, 
+			    struct sk_buff *skb) 
 {
-	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
-	ASSERT( skb != NULL, return;);
+	ASSERT(skb != NULL, return;);
 	
-	if ( !self || self->magic != IAS_MAGIC) {
-		IRDA_DEBUG( 0, "state_r_execute: bad pointer self\n");
+	if (!self || self->magic != IAS_MAGIC) {
+		IRDA_DEBUG(0, __FUNCTION__ "(), bad pointer self\n");
 		return;
 	}	
 
-	switch( event) {
+	switch (event) {
 	case IAP_CALL_RESPONSE:
 		/*  
 		 *  Since we don't implement the Waiting state, we return
 		 *  to state Receiving instead, DB.
 		 */
-		iriap_next_r_connect_state( self, R_RECEIVING);
+		iriap_next_r_connect_state(self, R_RECEIVING);
 	 		
-		irlmp_data_request( self->lsap, skb);
+		irlmp_data_request(self->lsap, skb);
 		break;
 	default:
-		IRDA_DEBUG( 0, __FUNCTION__ "(), unknown event!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "(), unknown event!\n");
 		break;
 	}
 }
 
-static void state_r_returning( struct iriap_cb *self, IRIAP_EVENT event, 
-			       struct sk_buff *skb) 
+static void state_r_returning(struct iriap_cb *self, IRIAP_EVENT event, 
+			      struct sk_buff *skb) 
 {
-	IRDA_DEBUG( 0, __FUNCTION__ "(), event=%d\n", event);
+	IRDA_DEBUG(0, __FUNCTION__ "(), event=%d\n", event);
 
-	switch( event) {
+	switch (event) {
 	case IAP_RECV_F_LST:
 		
 		break;
diff -u --recursive --new-file v2.3.25/linux/net/irda/irlan/irlan_client.c linux/net/irda/irlan/irlan_client.c
--- v2.3.25/linux/net/irda/irlan/irlan_client.c	Tue Aug 31 17:29:15 1999
+++ linux/net/irda/irlan/irlan_client.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Thu Jul  8 13:50:16 1999
+ * Modified at:   Sun Oct 31 19:44:41 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
  *                slip.c by Laurence Culhane, <loz@holmes.demon.co.uk>
@@ -71,7 +71,7 @@
 {
 	struct irlan_cb *self = (struct irlan_cb *) data;
 	
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -90,7 +90,7 @@
 
 void irlan_client_start_kick_timer(struct irlan_cb *self, int timeout)
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	irda_start_timer(&self->client.kick_timer, timeout, (void *) self, 
 			 irlan_client_kick_timer_expired);
@@ -106,7 +106,7 @@
 {
 	struct irmanager_event mgr_event;
 
-	DEBUG(1, __FUNCTION__ "()\n");
+	IRDA_DEBUG(1, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -168,7 +168,7 @@
 	struct irlan_cb *self;
 	__u32 saddr, daddr;
 	
-	DEBUG(1, __FUNCTION__"()\n");
+	IRDA_DEBUG(1, __FUNCTION__"()\n");
 
 	ASSERT(irlan != NULL, return;);
 	ASSERT(discovery != NULL, return;);
@@ -183,7 +183,7 @@
       	if (self) {
 		ASSERT(self->magic == IRLAN_MAGIC, return;);
 
-		DEBUG(1, __FUNCTION__ "(), Found instance (%08x)!\n",
+		IRDA_DEBUG(1, __FUNCTION__ "(), Found instance (%08x)!\n",
 		      daddr);
 		
 		irlan_client_wakeup(self, saddr, daddr);
@@ -194,7 +194,7 @@
 	/* 
 	 * We have no instance for daddr, so start a new one
 	 */
-	DEBUG(1, __FUNCTION__ "(), starting new instance!\n");
+	IRDA_DEBUG(1, __FUNCTION__ "(), starting new instance!\n");
 	self = irlan_open(saddr, daddr, TRUE);
 
 	/* Restart watchdog timer */
@@ -212,7 +212,7 @@
 {
 	struct irlan_cb *self;
 	
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 	
 	self = (struct irlan_cb *) instance;
 	
@@ -223,7 +223,7 @@
 	irlan_do_client_event(self, IRLAN_DATA_INDICATION, skb); 
 
 	/* Ready for a new command */	
-	DEBUG(2, __FUNCTION__ "(), clearing tx_busy\n");
+	IRDA_DEBUG(2, __FUNCTION__ "(), clearing tx_busy\n");
 	self->client.tx_busy = FALSE;
 
 	/* Check if we have some queued commands waiting to be sent */
@@ -240,7 +240,7 @@
 	struct tsap_cb *tsap;
 	struct sk_buff *skb;
 
-	DEBUG(4, __FUNCTION__ "(), reason=%d\n", reason);
+	IRDA_DEBUG(4, __FUNCTION__ "(), reason=%d\n", reason);
 	
 	self = (struct irlan_cb *) instance;
 	tsap = (struct tsap_cb *) sap;
@@ -272,7 +272,7 @@
 	struct tsap_cb *tsap;
 	notify_t notify;
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -292,7 +292,7 @@
 	
 	tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
 	if (!tsap) {
-		DEBUG(2, __FUNCTION__ "(), Got no tsap!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), Got no tsap!\n");
 		return;
 	}
 	self->client.tsap_ctrl = tsap;
@@ -312,7 +312,7 @@
 {
 	struct irlan_cb *self;
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	self = (struct irlan_cb *) instance;
 
@@ -338,7 +338,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 		
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -381,7 +381,7 @@
 
 	ASSERT(skb != NULL, return;);	
 	
-	DEBUG(4, __FUNCTION__ "() skb->len=%d\n", (int) skb->len);
+	IRDA_DEBUG(4, __FUNCTION__ "() skb->len=%d\n", (int) skb->len);
 	
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -412,7 +412,7 @@
 	/* How many parameters? */
 	count = frame[1];
 
-	DEBUG(4, __FUNCTION__ "(), got %d parameters\n", count);
+	IRDA_DEBUG(4, __FUNCTION__ "(), got %d parameters\n", count);
 	
 	ptr = frame+2;
 
@@ -420,7 +420,7 @@
  	for (i=0; i<count;i++) {
 		ret = irlan_extract_param(ptr, name, value, &val_len);
 		if (ret < 0) {
-			DEBUG(2, __FUNCTION__ "(), IrLAN, Error!\n");
+			IRDA_DEBUG(2, __FUNCTION__ "(), IrLAN, Error!\n");
 			break;
 		}
 		ptr += ret;
@@ -444,7 +444,7 @@
 	__u8 *bytes;
 	int i;
 
-	DEBUG(4, __FUNCTION__ "(), parm=%s\n", param);
+	IRDA_DEBUG(4, __FUNCTION__ "(), parm=%s\n", param);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -484,14 +484,14 @@
 		else if (strcmp(value, "HOSTED") == 0)
 			self->client.access_type = ACCESS_HOSTED;
 		else {
-			DEBUG(2, __FUNCTION__ "(), unknown access type!\n");
+			IRDA_DEBUG(2, __FUNCTION__ "(), unknown access type!\n");
 		}
 	}
 	/*
 	 *  IRLAN version
 	 */
 	if (strcmp(param, "IRLAN_VER") == 0) {
-		DEBUG(4, "IrLAN version %d.%d\n", (__u8) value[0], 
+		IRDA_DEBUG(4, "IrLAN version %d.%d\n", (__u8) value[0], 
 		      (__u8) value[1]);
 
 		self->version[0] = value[0];
@@ -503,41 +503,41 @@
 	 */
 	if (strcmp(param, "DATA_CHAN") == 0) {
 		self->dtsap_sel_data = value[0];
-		DEBUG(4, "Data TSAP = %02x\n", self->dtsap_sel_data);
+		IRDA_DEBUG(4, "Data TSAP = %02x\n", self->dtsap_sel_data);
 		return;
 	}
 	if (strcmp(param, "CON_ARB") == 0) {
 		memcpy(&tmp_cpu, value, 2); /* Align value */
 		le16_to_cpus(&tmp_cpu);     /* Convert to host order */
 		self->client.recv_arb_val = tmp_cpu;
-		DEBUG(2, __FUNCTION__ "(), receive arb val=%d\n", 
-		      self->client.recv_arb_val);
+		IRDA_DEBUG(2, __FUNCTION__ "(), receive arb val=%d\n", 
+			   self->client.recv_arb_val);
 	}
 	if (strcmp(param, "MAX_FRAME") == 0) {
 		memcpy(&tmp_cpu, value, 2); /* Align value */
 		le16_to_cpus(&tmp_cpu);     /* Convert to host order */
 		self->client.max_frame = tmp_cpu;
-		DEBUG(4, __FUNCTION__ "(), max frame=%d\n", 
-		      self->client.max_frame);
+		IRDA_DEBUG(4, __FUNCTION__ "(), max frame=%d\n", 
+			   self->client.max_frame);
 	}
 	 
 	/*
 	 *  RECONNECT_KEY, in case the link goes down!
 	 */
 	if (strcmp(param, "RECONNECT_KEY") == 0) {
-		DEBUG(4, "Got reconnect key: ");
+		IRDA_DEBUG(4, "Got reconnect key: ");
 		/* for (i = 0; i < val_len; i++) */
 /* 			printk("%02x", value[i]); */
 		memcpy(self->client.reconnect_key, value, val_len);
 		self->client.key_len = val_len;
-		DEBUG(4, "\n");
+		IRDA_DEBUG(4, "\n");
 	}
 	/*
 	 *  FILTER_ENTRY, have we got an ethernet address?
 	 */
 	if (strcmp(param, "FILTER_ENTRY") == 0) {
 		bytes = value;
-		DEBUG(4, "Ethernet address = %02x:%02x:%02x:%02x:%02x:%02x\n",
+		IRDA_DEBUG(4, "Ethernet address = %02x:%02x:%02x:%02x:%02x:%02x\n",
 		      bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], 
 		      bytes[5]);
 		for (i = 0; i < 6; i++) 
@@ -556,16 +556,20 @@
 {
 	struct irlan_cb *self;
 	
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(priv != NULL, return;);
 
 	self = (struct irlan_cb *) priv;
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
 
+	/* We probably don't need to make any more queries */
+	iriap_close(self->client.iriap);
+	self->client.iriap = NULL;
+
 	/* Check if request succeeded */
 	if (result != IAS_SUCCESS) {
-		DEBUG(2, __FUNCTION__ "(), got NULL value!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), got NULL value!\n");
 		irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL, 
 				      NULL);
 		return;
@@ -582,16 +586,17 @@
 		}
 		break;
 	case IAS_STRING:
-		DEBUG(2, __FUNCTION__ "(), got string %s\n", value->t.string);
+		IRDA_DEBUG(2, __FUNCTION__ "(), got string %s\n", 
+			   value->t.string);
 		break;
 	case IAS_OCT_SEQ:
-		DEBUG(2, __FUNCTION__ "(), OCT_SEQ not implemented\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), OCT_SEQ not implemented\n");
 		break;
 	case IAS_MISSING:
-		DEBUG(2, __FUNCTION__ "(), MISSING not implemented\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), MISSING not implemented\n");
 		break;
 	default:
-		DEBUG(2, __FUNCTION__ "(), unknown type!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), unknown type!\n");
 		break;
 	}
 	irlan_do_client_event(self, IRLAN_IAS_PROVIDER_NOT_AVAIL, NULL);
diff -u --recursive --new-file v2.3.25/linux/net/irda/irlan/irlan_client_event.c linux/net/irda/irlan/irlan_client_event.c
--- v2.3.25/linux/net/irda/irlan/irlan_client_event.c	Tue Aug 31 17:29:15 1999
+++ linux/net/irda/irlan/irlan_client_event.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Mon Jul  5 11:06:57 1999
+ * Modified at:   Sun Oct 31 19:41:55 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -92,26 +92,33 @@
 static int irlan_client_state_idle(struct irlan_cb *self, IRLAN_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRLAN_MAGIC, return -1;);
 	
 	switch (event) {
 	case IRLAN_DISCOVERY_INDICATION:
+		if (self->client.iriap) {
+			WARNING(__FUNCTION__ 
+				"(), busy with a previous query\n");
+			return -EBUSY;
+		}
+		
+		self->client.iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self,
+						irlan_client_get_value_confirm);
 		/* Get some values from peer IAS */
-		iriap_getvaluebyclass_request(
-			"IrLAN", "IrDA:TinyTP:LsapSel",
-			self->saddr, self->daddr,
-			irlan_client_get_value_confirm, self);
+		iriap_getvaluebyclass_request(self->client.iriap,
+					      self->saddr, self->daddr,
+					      "IrLAN", "IrDA:TinyTP:LsapSel");
 		
 		irlan_next_client_state(self, IRLAN_QUERY);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
 		break;
 	default:
-		DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 	if (skb) 
@@ -130,7 +137,7 @@
 static int irlan_client_state_query(struct irlan_cb *self, IRLAN_EVENT event, 
 				    struct sk_buff *skb) 
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRLAN_MAGIC, return -1;);
@@ -148,7 +155,7 @@
 		irlan_next_client_state(self, IRLAN_CONN);
 		break;
 	case IRLAN_IAS_PROVIDER_NOT_AVAIL:
-		DEBUG(2, __FUNCTION__ "(), IAS_PROVIDER_NOT_AVAIL\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IAS_PROVIDER_NOT_AVAIL\n");
 		irlan_next_client_state(self, IRLAN_IDLE);
 
 		/* Give the client a kick! */
@@ -161,10 +168,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
 		break;
 	default:
-		DEBUG(2, __FUNCTION__"(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, __FUNCTION__"(), Unknown event %d\n", event);
 		break;
 	}
 	if (skb)
@@ -183,7 +190,7 @@
 static int irlan_client_state_conn(struct irlan_cb *self, IRLAN_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	ASSERT(self != NULL, return -1;);
 	
@@ -198,10 +205,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
 		break;
 	default:
-		DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 	if (skb)
@@ -218,7 +225,7 @@
 static int irlan_client_state_info(struct irlan_cb *self, IRLAN_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	
@@ -238,10 +245,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
 		break;
 	default:
-		DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 	if (skb)
@@ -260,7 +267,7 @@
 static int irlan_client_state_media(struct irlan_cb *self, IRLAN_EVENT event, 
 				    struct sk_buff *skb) 
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	ASSERT(self != NULL, return -1;);
 
@@ -275,10 +282,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
 		break;
 	default:
-		DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 	if (skb)
@@ -299,7 +306,7 @@
 {
 	struct qos_info qos;
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	ASSERT(self != NULL, return -1;);
 
@@ -338,7 +345,7 @@
 			irlan_next_client_state(self, IRLAN_DATA);
 			break;
 		default:
-			DEBUG(2, __FUNCTION__ "(), unknown access type!\n");
+			IRDA_DEBUG(2, __FUNCTION__ "(), unknown access type!\n");
 			break;
 		}
 		break;
@@ -347,10 +354,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
 		break;
 	default:
-		DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 	
@@ -370,7 +377,7 @@
 static int irlan_client_state_wait(struct irlan_cb *self, IRLAN_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	ASSERT(self != NULL, return -1;);
 	
@@ -384,10 +391,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
 		break;
 	default:
-		DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 	if (skb)
@@ -401,7 +408,7 @@
 {
 	struct qos_info qos;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	
@@ -423,7 +430,7 @@
 		} else if (self->client.recv_arb_val >
 			   self->provider.send_arb_val) 
 		{
-			DEBUG(2, __FUNCTION__ "(), lost the battle :-(\n");
+			IRDA_DEBUG(2, __FUNCTION__ "(), lost the battle :-(\n");
 		}
 		break;
 	case IRLAN_DATA_CONNECT_INDICATION:
@@ -434,10 +441,10 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	case IRLAN_WATCHDOG_TIMEOUT:
-		DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), IRLAN_WATCHDOG_TIMEOUT\n");
 		break;
 	default:
-		DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 	if (skb)
@@ -456,7 +463,7 @@
 static int irlan_client_state_data(struct irlan_cb *self, IRLAN_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRLAN_MAGIC, return -1;);
@@ -470,7 +477,7 @@
 		irlan_next_client_state(self, IRLAN_IDLE);
 		break;
 	default:
-		DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 	if (skb)
@@ -488,7 +495,7 @@
 static int irlan_client_state_close(struct irlan_cb *self, IRLAN_EVENT event, 
 				    struct sk_buff *skb) 
 {
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	if (skb)
 		dev_kfree_skb(skb);
@@ -505,7 +512,7 @@
 static int irlan_client_state_sync(struct irlan_cb *self, IRLAN_EVENT event, 
 				   struct sk_buff *skb) 
 {
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 	
 	if (skb)
 		dev_kfree_skb(skb);
diff -u --recursive --new-file v2.3.25/linux/net/irda/irlan/irlan_common.c linux/net/irda/irlan/irlan_common.c
--- v2.3.25/linux/net/irda/irlan/irlan_common.c	Mon Nov  1 13:56:27 1999
+++ linux/net/irda/irlan/irlan_common.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Tue Oct  5 11:36:11 1999
+ * Modified at:   Sun Oct 31 19:43:50 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>, 
@@ -61,7 +61,6 @@
 /* Module parameters */
 static int eth = 0; /* Use "eth" or "irlan" name for devices */
 static int access = ACCESS_PEER; /* PEER, DIRECT or HOSTED */
-static int timeout = IRLAN_TIMEOUT;
 
 static char *irlan_state[] = {
 	"IRLAN_IDLE",
@@ -114,7 +113,7 @@
 	struct irmanager_event mgr_event;
 	struct irlan_cb *self;
 	
-	DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 
 	self = (struct irlan_cb *) data;
 
@@ -123,7 +122,7 @@
 
 	/* Check if device still configured */
 	if (self->dev.start) {
-		DEBUG(0, __FUNCTION__ 
+		IRDA_DEBUG(0, __FUNCTION__ 
 		      "(), notifying irmanager to stop irlan!\n");
 		mgr_event.event = EVENT_IRLAN_STOP;
 		sprintf(mgr_event.devname, "%s", self->ifname);
@@ -137,7 +136,7 @@
 		 */
 		self->notify_irmanager = FALSE;
 	} else {
-		DEBUG(0, __FUNCTION__ "(), closing instance!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "(), closing instance!\n");
 		/*irlan_close(self);*/
 	}
 }
@@ -150,7 +149,7 @@
  */
 void irlan_start_watchdog_timer(struct irlan_cb *self, int timeout)
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	irda_start_timer(&self->watchdog_timer, timeout, (void *) self,
 			 irlan_watchdog_timer_expired);
@@ -167,7 +166,7 @@
 	struct irlan_cb *new;
 	__u16 hints;
 
-	DEBUG(4, __FUNCTION__"()\n");
+	IRDA_DEBUG(4, __FUNCTION__"()\n");
 
 	/* Allocate master structure */
 	irlan = hashbin_new(HB_LOCAL); 
@@ -179,7 +178,7 @@
 	create_proc_info_entry("irlan", 0, proc_irda, irlan_proc_read);
 #endif /* CONFIG_PROC_FS */
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	hints = irlmp_service_to_hint(S_LAN);
 
@@ -205,7 +204,7 @@
 
 void irlan_cleanup(void) 
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	irlmp_unregister_client(ckey);
 
@@ -230,7 +229,7 @@
 {
 	int i=0;
 
-	DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 
 	/* Check if we should call the device eth<x> or irlan<x> */
 	if (!eth) {
@@ -242,7 +241,7 @@
 	self->dev.name = self->ifname;
 	
 	if (register_netdev(&self->dev) != 0) {
-		DEBUG(2, __FUNCTION__ "(), register_netdev() failed!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), register_netdev() failed!\n");
 		return -1;
 	}
 	self->netdev_registered = TRUE;
@@ -260,7 +259,7 @@
 {
 	struct irlan_cb *self;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	/* 
 	 *  Initialize the irlan structure. 
@@ -321,7 +320,7 @@
 {
 	struct sk_buff *skb;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 	
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -331,6 +330,9 @@
 
 	/* Close all open connections and remove TSAPs */
 	irlan_close_tsaps(self);
+	
+	if (self->client.iriap) 
+		iriap_close(self->client.iriap);
 
 	/* Remove frames queued on the control channel */
 	while ((skb = skb_dequeue(&self->client.txq))) {
@@ -356,21 +358,21 @@
 {
 	struct irlan_cb *entry;
 
-	DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 
         ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
 
 	/* Check if device is still configured */
 	if (self->dev.start) {
-		DEBUG(0, __FUNCTION__ 
+		IRDA_DEBUG(0, __FUNCTION__ 
 		       "(), Device still configured, closing later!\n");
 
 		/* Give it a chance to reconnect */
 		irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
 		return;
 	}
-	DEBUG(2, __FUNCTION__ "(), daddr=%08x\n", self->daddr);
+	IRDA_DEBUG(2, __FUNCTION__ "(), daddr=%08x\n", self->daddr);
 	entry = hashbin_remove(irlan, self->daddr, NULL);
 
 	ASSERT(entry == self, return;);
@@ -391,7 +393,7 @@
 	struct irlan_cb *self;
 	struct tsap_cb *tsap;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 	
 	self = (struct irlan_cb *) instance;
 	tsap = (struct tsap_cb *) sap;
@@ -403,7 +405,7 @@
 	self->max_sdu_size = max_sdu_size;
 	self->max_header_size = max_header_size;
 
-	DEBUG(0, "IrLAN, We are now connected!\n");
+	IRDA_DEBUG(0, "IrLAN, We are now connected!\n");
 
 	del_timer(&self->watchdog_timer);
 
@@ -438,7 +440,7 @@
 
 	/* TODO: we could set the MTU depending on the max_sdu_size */
 
-	DEBUG(2, "IrLAN, We are now connected!\n");
+	IRDA_DEBUG(2, "IrLAN, We are now connected!\n");
 	del_timer(&self->watchdog_timer);
 
 	/* 
@@ -470,7 +472,7 @@
 	struct irlan_cb *self;
 	struct tsap_cb *tsap;
 
-	DEBUG(0, __FUNCTION__ "(), reason=%d\n", reason);
+	IRDA_DEBUG(0, __FUNCTION__ "(), reason=%d\n", reason);
 	
 	self = (struct irlan_cb *) instance;
 	tsap = (struct tsap_cb *) sap;
@@ -482,7 +484,7 @@
 	
 	ASSERT(tsap == self->tsap_data, return;);
 
-	DEBUG(2, "IrLAN, data channel disconnected by peer!\n");
+	IRDA_DEBUG(2, "IrLAN, data channel disconnected by peer!\n");
 
 	switch(reason) {
 	case LM_USER_REQUEST: /* User request */
@@ -492,13 +494,13 @@
 		irlan_start_watchdog_timer(self, IRLAN_TIMEOUT);
 		break;
 	case LM_CONNECT_FAILURE: /* Failed to establish IrLAP connection */
-		DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n");
 		break;
 	case LM_LAP_RESET:  /* IrLAP reset */
-		DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n");
 		break;
 	case LM_INIT_DISCONNECT:
-		DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), LM_CONNECT_FAILURE not impl\n");
 		break;
 	default:
 		break;
@@ -513,7 +515,7 @@
 	struct tsap_cb *tsap;
 	notify_t notify;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -535,7 +537,7 @@
 
 	tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
 	if (!tsap) {
-		DEBUG(2, __FUNCTION__ "(), Got no tsap!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), Got no tsap!\n");
 		return;
 	}
 	self->tsap_data = tsap;
@@ -549,7 +551,7 @@
 
 void irlan_close_tsaps(struct irlan_cb *self)
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -634,7 +636,7 @@
 {
 	struct sk_buff *skb;
 
-	DEBUG(3, __FUNCTION__ "()\n");
+	IRDA_DEBUG(3, __FUNCTION__ "()\n");
 
 	if (irda_lock(&self->client.tx_busy) == FALSE)
 		return -EBUSY;
@@ -653,7 +655,7 @@
 		dev_kfree_skb(skb);
 		return -1;
 	}
-	DEBUG(3, __FUNCTION__ "(), sending ...\n");
+	IRDA_DEBUG(3, __FUNCTION__ "(), sending ...\n");
 
 	return irttp_data_request(self->client.tsap_ctrl, skb);
 }
@@ -666,7 +668,7 @@
  */
 void irlan_ctrl_data_request(struct irlan_cb *self, struct sk_buff *skb)
 {
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	/* Queue command */
 	skb_queue_tail(&self->client.txq, skb);
@@ -686,7 +688,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -719,7 +721,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 	
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -752,7 +754,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 	
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -791,7 +793,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 	
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);	
@@ -830,7 +832,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 	
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -870,7 +872,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 	
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -911,7 +913,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 		
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -947,7 +949,7 @@
 	struct sk_buff *skb;
 	__u8 *frame;
 	
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -1034,7 +1036,7 @@
 	int n=0;
 	
 	if (skb == NULL) {
-		DEBUG(2, __FUNCTION__ "(), Got NULL skb\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), Got NULL skb\n");
 		return 0;
 	}	
 
@@ -1051,7 +1053,7 @@
 		ASSERT(value_len > 0, return 0;);
 		break;
 	default:
-		DEBUG(2, __FUNCTION__ "(), Unknown parameter type!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown parameter type!\n");
 		return 0;
 		break;
 	}
@@ -1061,7 +1063,7 @@
 
 	/* Make space for data */
 	if (skb_tailroom(skb) < (param_len+value_len+3)) {
-		DEBUG(2, __FUNCTION__ "(), No more space at end of skb\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), No more space at end of skb\n");
 		return 0;
 	}	
 	skb_put(skb, param_len+value_len+3);
@@ -1108,13 +1110,13 @@
 	__u16 val_len;
 	int n=0;
 	
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	/* get length of parameter name (1 byte) */
 	name_len = buf[n++];
 	
 	if (name_len > 254) {
-		DEBUG(2, __FUNCTION__ "(), name_len > 254\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), name_len > 254\n");
 		return -RSP_INVALID_COMMAND_FORMAT;
 	}
 	
@@ -1131,7 +1133,7 @@
 	le16_to_cpus(&val_len); n+=2;
 	
 	if (val_len > 1016) {
-		DEBUG(2, __FUNCTION__ "(), parameter length to long\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), parameter length to long\n");
 		return -RSP_INVALID_COMMAND_FORMAT;
 	}
 	*len = val_len;
@@ -1141,8 +1143,8 @@
 	value[val_len] = '\0';
 	n+=val_len;
 	
-	DEBUG(4, "Parameter: %s ", name); 
-	DEBUG(4, "Value: %s\n", value); 
+	IRDA_DEBUG(4, "Parameter: %s ", name); 
+	IRDA_DEBUG(4, "Value: %s\n", value); 
 
 	return n;
 }
diff -u --recursive --new-file v2.3.25/linux/net/irda/irlan/irlan_eth.c linux/net/irda/irlan/irlan_eth.c
--- v2.3.25/linux/net/irda/irlan/irlan_eth.c	Tue Aug 31 17:29:15 1999
+++ linux/net/irda/irlan/irlan_eth.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Thu Oct 15 08:37:58 1998
- * Modified at:   Sun Jun 20 20:23:33 1999
+ * Modified at:   Sat Oct 30 12:58:30 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
  *                slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
@@ -50,7 +50,7 @@
 	struct irmanager_event mgr_event;
 	struct irlan_cb *self;
 
-	DEBUG(2, __FUNCTION__"()\n");
+	IRDA_DEBUG(2, __FUNCTION__"()\n");
 
 	ASSERT(dev != NULL, return -1;);
        
@@ -115,7 +115,7 @@
 {
 	struct irlan_cb *self;
 	
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
 	ASSERT(dev != NULL, return -1;);
 
@@ -150,7 +150,7 @@
 {
 	struct irlan_cb *self = (struct irlan_cb *) dev->priv;
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 	
 	/* Stop device */
 	dev->tbusy = 1;
@@ -342,7 +342,7 @@
 	 * is useful if we have changed access points on the same
 	 * subnet.  
 	 */
-	DEBUG(4, "IrLAN: Sending gratuitous ARP\n");
+	IRDA_DEBUG(4, "IrLAN: Sending gratuitous ARP\n");
 	in_dev = in_dev_get(dev);
 	if (in_dev == NULL)
 		return;
@@ -370,14 +370,14 @@
 
  	self = dev->priv; 
 
-	DEBUG(2, __FUNCTION__ "()\n");
+	IRDA_DEBUG(2, __FUNCTION__ "()\n");
 
  	ASSERT(self != NULL, return;); 
  	ASSERT(self->magic == IRLAN_MAGIC, return;);
 
 	/* Check if data channel has been connected yet */
 	if (self->client.state != IRLAN_DATA) {
-		DEBUG(1, __FUNCTION__ "(), delaying!\n");
+		IRDA_DEBUG(1, __FUNCTION__ "(), delaying!\n");
 		return;
 	}
 
@@ -387,20 +387,20 @@
 	} 
 	else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > HW_MAX_ADDRS) {
 		/* Disable promiscuous mode, use normal mode. */
-		DEBUG(4, __FUNCTION__ "(), Setting multicast filter\n");
+		IRDA_DEBUG(4, __FUNCTION__ "(), Setting multicast filter\n");
 		/* hardware_set_filter(NULL); */
 
 		irlan_set_multicast_filter(self, TRUE);
 	}
 	else if (dev->mc_count) {
-		DEBUG(4, __FUNCTION__ "(), Setting multicast filter\n");
+		IRDA_DEBUG(4, __FUNCTION__ "(), Setting multicast filter\n");
 		/* Walk the address list, and load the filter */
 		/* hardware_set_filter(dev->mc_list); */
 
 		irlan_set_multicast_filter(self, TRUE);
 	}
 	else {
-		DEBUG(4, __FUNCTION__ "(), Clearing multicast filter\n");
+		IRDA_DEBUG(4, __FUNCTION__ "(), Clearing multicast filter\n");
 		irlan_set_multicast_filter(self, FALSE);
 	}
 
diff -u --recursive --new-file v2.3.25/linux/net/irda/irlan/irlan_event.c linux/net/irda/irlan/irlan_event.c
--- v2.3.25/linux/net/irda/irlan/irlan_event.c	Sun May 30 10:27:04 1999
+++ linux/net/irda/irlan/irlan_event.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Tue Oct 20 09:10:16 1998
- * Modified at:   Sun May  9 21:17:44 1999
+ * Modified at:   Sat Oct 30 12:59:01 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
@@ -40,7 +40,7 @@
 
 void irlan_next_client_state(struct irlan_cb *self, IRLAN_STATE state) 
 {
-	DEBUG(2, __FUNCTION__"(), %s\n", irlan_state[state]);
+	IRDA_DEBUG(2, __FUNCTION__"(), %s\n", irlan_state[state]);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -50,7 +50,7 @@
 
 void irlan_next_provider_state(struct irlan_cb *self, IRLAN_STATE state) 
 {
-	DEBUG(2, __FUNCTION__"(), %s\n", irlan_state[state]);
+	IRDA_DEBUG(2, __FUNCTION__"(), %s\n", irlan_state[state]);
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
diff -u --recursive --new-file v2.3.25/linux/net/irda/irlan/irlan_filter.c linux/net/irda/irlan/irlan_filter.c
--- v2.3.25/linux/net/irda/irlan/irlan_filter.c	Mon Jun  7 16:18:58 1999
+++ linux/net/irda/irlan/irlan_filter.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Fri Jan 29 11:16:38 1999
- * Modified at:   Fri May 14 23:11:01 1999
+ * Modified at:   Sat Oct 30 12:58:45 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
@@ -41,7 +41,7 @@
 	if ((self->provider.filter_type == IRLAN_DIRECTED) && 
 	    (self->provider.filter_operation == DYNAMIC))
 	{
-		DEBUG(0, "Giving peer a dynamic Ethernet address\n");
+		IRDA_DEBUG(0, "Giving peer a dynamic Ethernet address\n");
 		self->provider.mac_address[0] = 0x40;
 		self->provider.mac_address[1] = 0x00;
 		self->provider.mac_address[2] = 0x00;
@@ -71,7 +71,7 @@
 	if ((self->provider.filter_type == IRLAN_DIRECTED) && 
 	    (self->provider.filter_mode == FILTER))
 	{
-		DEBUG(0, "Directed filter on\n");
+		IRDA_DEBUG(0, "Directed filter on\n");
 		skb->data[0] = 0x00; /* Success */
 		skb->data[1] = 0x00;
 		return;
@@ -79,7 +79,7 @@
 	if ((self->provider.filter_type == IRLAN_DIRECTED) && 
 	    (self->provider.filter_mode == NONE))
 	{
-		DEBUG(0, "Directed filter off\n");
+		IRDA_DEBUG(0, "Directed filter off\n");
 		skb->data[0] = 0x00; /* Success */
 		skb->data[1] = 0x00;
 		return;
@@ -88,7 +88,7 @@
 	if ((self->provider.filter_type == IRLAN_BROADCAST) && 
 	    (self->provider.filter_mode == FILTER))
 	{
-		DEBUG(0, "Broadcast filter on\n");
+		IRDA_DEBUG(0, "Broadcast filter on\n");
 		skb->data[0] = 0x00; /* Success */
 		skb->data[1] = 0x00;
 		return;
@@ -96,7 +96,7 @@
 	if ((self->provider.filter_type == IRLAN_BROADCAST) && 
 	    (self->provider.filter_mode == NONE))
 	{
-		DEBUG(0, "Broadcast filter off\n");
+		IRDA_DEBUG(0, "Broadcast filter off\n");
 		skb->data[0] = 0x00; /* Success */
 		skb->data[1] = 0x00;
 		return;
@@ -104,7 +104,7 @@
 	if ((self->provider.filter_type == IRLAN_MULTICAST) && 
 	    (self->provider.filter_mode == FILTER))
 	{
-		DEBUG(0, "Multicast filter on\n");
+		IRDA_DEBUG(0, "Multicast filter on\n");
 		skb->data[0] = 0x00; /* Success */
 		skb->data[1] = 0x00;
 		return;
@@ -112,7 +112,7 @@
 	if ((self->provider.filter_type == IRLAN_MULTICAST) && 
 	    (self->provider.filter_mode == NONE))
 	{
-		DEBUG(0, "Multicast filter off\n");
+		IRDA_DEBUG(0, "Multicast filter off\n");
 		skb->data[0] = 0x00; /* Success */
 		skb->data[1] = 0x00;
 		return;
@@ -120,7 +120,7 @@
 	if ((self->provider.filter_type == IRLAN_MULTICAST) && 
 	    (self->provider.filter_operation == GET))
 	{
-		DEBUG(0, "Multicast filter get\n");
+		IRDA_DEBUG(0, "Multicast filter get\n");
 		skb->data[0] = 0x00; /* Success? */
 		skb->data[1] = 0x02;
 		irlan_insert_string_param(skb, "FILTER_MODE", "NONE");
@@ -130,7 +130,7 @@
 	skb->data[0] = 0x00; /* Command not supported */
 	skb->data[1] = 0x00;
 
-	DEBUG(0, "Not implemented!\n");
+	IRDA_DEBUG(0, "Not implemented!\n");
 }
 
 /*
@@ -143,20 +143,20 @@
 {
 	__u8 *bytes;
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	bytes = value;
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
 
-	DEBUG(4, "%s, %s\n", param, value);
+	IRDA_DEBUG(4, "%s, %s\n", param, value);
 
 	/*
 	 *  This is experimental!! DB.
 	 */
 	 if (strcmp(param, "MODE") == 0) {
-		DEBUG(0, __FUNCTION__ "()\n");
+		IRDA_DEBUG(0, __FUNCTION__ "()\n");
 		self->use_udata = TRUE;
 		return;
 	}
diff -u --recursive --new-file v2.3.25/linux/net/irda/irlan/irlan_provider.c linux/net/irda/irlan/irlan_provider.c
--- v2.3.25/linux/net/irda/irlan/irlan_provider.c	Tue Aug 31 17:29:15 1999
+++ linux/net/irda/irlan/irlan_provider.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Wed Jun  9 11:03:29 1999
+ * Modified at:   Sat Oct 30 12:52:10 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Sources:       skeleton.c by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
  *                slip.c by Laurence Culhane,   <loz@holmes.demon.co.uk>
@@ -70,7 +70,7 @@
 	struct irlan_cb *self;
 	__u8 code;
 	
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	self = (struct irlan_cb *) instance;
 
@@ -82,32 +82,32 @@
 	code = skb->data[0];
 	switch(code) {
 	case CMD_GET_PROVIDER_INFO:
-		DEBUG(4, "Got GET_PROVIDER_INFO command!\n");
+		IRDA_DEBUG(4, "Got GET_PROVIDER_INFO command!\n");
 		irlan_do_provider_event(self, IRLAN_GET_INFO_CMD, skb); 
 		break;
 
 	case CMD_GET_MEDIA_CHAR:
-		DEBUG(4, "Got GET_MEDIA_CHAR command!\n");
+		IRDA_DEBUG(4, "Got GET_MEDIA_CHAR command!\n");
 		irlan_do_provider_event(self, IRLAN_GET_MEDIA_CMD, skb); 
 		break;
 	case CMD_OPEN_DATA_CHANNEL:
-		DEBUG(4, "Got OPEN_DATA_CHANNEL command!\n");
+		IRDA_DEBUG(4, "Got OPEN_DATA_CHANNEL command!\n");
 		irlan_do_provider_event(self, IRLAN_OPEN_DATA_CMD, skb); 
 		break;
 	case CMD_FILTER_OPERATION:
-		DEBUG(4, "Got FILTER_OPERATION command!\n");
+		IRDA_DEBUG(4, "Got FILTER_OPERATION command!\n");
 		irlan_do_provider_event(self, IRLAN_FILTER_CONFIG_CMD, skb);
 		break;
 	case CMD_RECONNECT_DATA_CHAN:
-		DEBUG(2, __FUNCTION__"(), Got RECONNECT_DATA_CHAN command\n");
-		DEBUG(2, __FUNCTION__"(), NOT IMPLEMENTED\n");
+		IRDA_DEBUG(2, __FUNCTION__"(), Got RECONNECT_DATA_CHAN command\n");
+		IRDA_DEBUG(2, __FUNCTION__"(), NOT IMPLEMENTED\n");
 		break;
 	case CMD_CLOSE_DATA_CHAN:
-		DEBUG(2, "Got CLOSE_DATA_CHAN command!\n");
-		DEBUG(2, __FUNCTION__"(), NOT IMPLEMENTED\n");
+		IRDA_DEBUG(2, "Got CLOSE_DATA_CHAN command!\n");
+		IRDA_DEBUG(2, __FUNCTION__"(), NOT IMPLEMENTED\n");
 		break;
 	default:
-		DEBUG(2, __FUNCTION__ "(), Unknown command!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown command!\n");
 		break;
 	}
 	return 0;
@@ -129,7 +129,7 @@
 	struct tsap_cb *tsap;
 	__u32 saddr, daddr;
 
-	DEBUG(0, __FUNCTION__ "()\n");
+	IRDA_DEBUG(0, __FUNCTION__ "()\n");
 	
 	self = (struct irlan_cb *) instance;
 	tsap = (struct tsap_cb *) sap;
@@ -150,11 +150,11 @@
 	new = (struct irlan_cb *) hashbin_find(irlan, daddr, NULL);
       	if (new) {
 		ASSERT(new->magic == IRLAN_MAGIC, return;);
-		DEBUG(0, __FUNCTION__ "(), found instance!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "(), found instance!\n");
 
 		/* Update saddr, since client may have moved to a new link */
 		new->saddr = saddr;
-		DEBUG(2, __FUNCTION__ "(), saddr=%08x\n", new->saddr);
+		IRDA_DEBUG(2, __FUNCTION__ "(), saddr=%08x\n", new->saddr);
 
 		/* Make sure that any old provider control TSAP is removed */
 		if ((new != self) && new->provider.tsap_ctrl) {
@@ -165,7 +165,7 @@
 		}
 	} else {
 		/* This must be the master instance, so start a new instance */
-		DEBUG(0, __FUNCTION__ "(), starting new provider!\n");
+		IRDA_DEBUG(0, __FUNCTION__ "(), starting new provider!\n");
 
 		new = irlan_open(saddr, daddr, TRUE); 
 	}
@@ -182,7 +182,7 @@
 		new->provider.tsap_ctrl = irttp_dup(self->provider.tsap_ctrl, 
 						    new);
 		if (!new->provider.tsap_ctrl) {
-			DEBUG(0, __FUNCTION__ "(), dup failed!\n");
+			IRDA_DEBUG(0, __FUNCTION__ "(), dup failed!\n");
 			return;
 		}
 		
@@ -245,7 +245,7 @@
 	struct irlan_cb *self;
 	struct tsap_cb *tsap;
 
-	DEBUG(4, __FUNCTION__ "(), reason=%d\n", reason);
+	IRDA_DEBUG(4, __FUNCTION__ "(), reason=%d\n", reason);
 	
 	self = (struct irlan_cb *) instance;
 	tsap = (struct tsap_cb *) sap;
@@ -299,7 +299,7 @@
 	
 	ASSERT(skb != NULL, return -RSP_PROTOCOL_ERROR;);
 	
-	DEBUG(4, __FUNCTION__ "(), skb->len=%d\n", (int)skb->len);
+	IRDA_DEBUG(4, __FUNCTION__ "(), skb->len=%d\n", (int)skb->len);
 
 	ASSERT(self != NULL, return -RSP_PROTOCOL_ERROR;);
 	ASSERT(self->magic == IRLAN_MAGIC, return -RSP_PROTOCOL_ERROR;);
@@ -321,7 +321,7 @@
 	/* How many parameters? */
 	count = frame[1];
 
-	DEBUG(4, "Got %d parameters\n", count);
+	IRDA_DEBUG(4, "Got %d parameters\n", count);
 	
 	ptr = frame+2;
 	
@@ -329,7 +329,7 @@
  	for (i=0; i<count;i++) {
 		ret = irlan_extract_param(ptr, name, value, &val_len);
 		if (ret < 0) {
-			DEBUG(2, __FUNCTION__ "(), IrLAN, Error!\n");
+			IRDA_DEBUG(2, __FUNCTION__ "(), IrLAN, Error!\n");
 			break;
 		}
 		ptr+=ret;
@@ -354,7 +354,7 @@
 {
 	struct sk_buff *skb;
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return;);
 	ASSERT(self->magic == IRLAN_MAGIC, return;);
@@ -379,7 +379,7 @@
 			irlan_insert_string_param(skb, "MEDIA", "802.5");
 			break;
 		default:
-			DEBUG(2, __FUNCTION__ "(), unknown media type!\n");
+			IRDA_DEBUG(2, __FUNCTION__ "(), unknown media type!\n");
 			break;
 		}
 		irlan_insert_short_param(skb, "IRLAN_VER", 0x0101);
@@ -403,7 +403,7 @@
 			irlan_insert_string_param(skb, "ACCESS_TYPE", "HOSTED");
 			break;
 		default:
-			DEBUG(2, __FUNCTION__ "(), Unknown access type\n");
+			IRDA_DEBUG(2, __FUNCTION__ "(), Unknown access type\n");
 			break;
 		}
 		irlan_insert_short_param(skb, "MAX_FRAME", 0x05ee);
@@ -424,7 +424,7 @@
 		handle_filter_request(self, skb);
 		break;
 	default:
-		DEBUG(2, __FUNCTION__ "(), Unknown command!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown command!\n");
 		break;
 	}
 
@@ -442,7 +442,7 @@
 	struct tsap_cb *tsap;
 	notify_t notify;
 	
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRLAN_MAGIC, return -1;);
@@ -463,7 +463,7 @@
 
 	tsap = irttp_open_tsap(LSAP_ANY, 1, &notify);
 	if (!tsap) {
-		DEBUG(2, __FUNCTION__ "(), Got no tsap!\n");
+		IRDA_DEBUG(2, __FUNCTION__ "(), Got no tsap!\n");
 		return -1;
 	}
 	self->provider.tsap_ctrl = tsap;
diff -u --recursive --new-file v2.3.25/linux/net/irda/irlan/irlan_provider_event.c linux/net/irda/irlan/irlan_provider_event.c
--- v2.3.25/linux/net/irda/irlan/irlan_provider_event.c	Sun May 30 10:27:04 1999
+++ linux/net/irda/irlan/irlan_provider_event.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Sun Aug 31 20:14:37 1997
- * Modified at:   Fri May  7 10:53:58 1999
+ * Modified at:   Sat Oct 30 12:52:41 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1998-1999 Dag Brattli <dagb@cs.uit.no>, All Rights Reserved.
@@ -72,7 +72,7 @@
 static int irlan_provider_state_idle(struct irlan_cb *self, IRLAN_EVENT event,
 				     struct sk_buff *skb)
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	ASSERT(self != NULL, return -1;);
 	
@@ -82,7 +82,7 @@
 	     irlan_next_provider_state( self, IRLAN_INFO);
 	     break;
 	default:
-		DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(4, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 	if (skb)
@@ -101,7 +101,7 @@
 {
 	int ret;
 
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
 	ASSERT(self != NULL, return -1;);
 
@@ -147,7 +147,7 @@
 		irlan_next_provider_state(self, IRLAN_IDLE);
 		break;
 	default:
-		DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 	if (skb)
@@ -166,7 +166,7 @@
 static int irlan_provider_state_open(struct irlan_cb *self, IRLAN_EVENT event, 
 				     struct sk_buff *skb)
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 
@@ -186,7 +186,7 @@
 		irlan_next_provider_state(self, IRLAN_IDLE);
 		break;
 	default:
-		DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG(2, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 	if (skb)
@@ -205,7 +205,7 @@
 static int irlan_provider_state_data(struct irlan_cb *self, IRLAN_EVENT event, 
 				     struct sk_buff *skb) 
 {
-	DEBUG(4, __FUNCTION__ "()\n");
+	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 
 	ASSERT(self != NULL, return -1;);
 	ASSERT(self->magic == IRLAN_MAGIC, return -1;);
@@ -221,7 +221,7 @@
 		irlan_next_provider_state(self, IRLAN_IDLE);
 		break;
 	default:
-		DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event);
+		IRDA_DEBUG( 0, __FUNCTION__ "(), Unknown event %d\n", event);
 		break;
 	}
 	if (skb)
diff -u --recursive --new-file v2.3.25/linux/net/irda/irmod.c linux/net/irda/irmod.c
--- v2.3.25/linux/net/irda/irmod.c	Wed Oct 27 16:34:13 1999
+++ linux/net/irda/irmod.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Dec 15 13:55:39 1997
- * Modified at:   Mon Oct 18 14:54:35 1999
+ * Modified at:   Sun Oct 31 20:31:01 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * 
  *     Copyright (c) 1997, 1999 Dag Brattli, All Rights Reserved.
@@ -130,6 +130,8 @@
 EXPORT_SYMBOL(irda_param_unpack);
 
 /* IrIAP/IrIAS */
+EXPORT_SYMBOL(iriap_open);
+EXPORT_SYMBOL(iriap_close);
 EXPORT_SYMBOL(iriap_getvaluebyclass_request);
 EXPORT_SYMBOL(irias_object_change_attribute);
 EXPORT_SYMBOL(irias_add_integer_attrib);
@@ -216,7 +218,6 @@
 #ifdef MODULE
 	irda_device_init();	/* Called by init/main.c when non-modular */
 #endif
-
 	iriap_init();
  	irttp_init();
 	
@@ -393,8 +394,9 @@
 {
 	IRDA_DEBUG( 4, __FUNCTION__ "()\n");
 
-	if ( irda.in_use) {
-		IRDA_DEBUG( 0, __FUNCTION__ "(), irmanager is already running!\n");
+	if (irda.in_use) {
+		IRDA_DEBUG(0, __FUNCTION__ 
+			   "(), irmanager is already running!\n");
 		return -1;
 	}
 	irda.in_use = TRUE;
@@ -410,8 +412,8 @@
  *    Ioctl, used by irmanager to ...
  *
  */
-static int irda_ioctl( struct inode *inode, struct file *filp, 
-		       unsigned int cmd, unsigned long arg)
+static int irda_ioctl(struct inode *inode, struct file *filp, 
+		      unsigned int cmd, unsigned long arg)
 {
 	struct irda_todo *todo;
 	int err = 0;
@@ -419,14 +421,14 @@
 	
 	IRDA_DEBUG(4, __FUNCTION__ "()\n");
 	
-	if ( _IOC_DIR(cmd) & _IOC_READ)
+	if (_IOC_DIR(cmd) & _IOC_READ)
 		err = verify_area( VERIFY_WRITE, (void *) arg, size);
-	else if ( _IOC_DIR(cmd) & _IOC_WRITE)
+	else if (_IOC_DIR(cmd) & _IOC_WRITE)
 		err = verify_area( VERIFY_READ, (void *) arg, size);
-	if ( err)
+	if (err)
 		return err;
 	
-	switch( cmd) {
+	switch (cmd) {
 	case IRMGR_IOCTNPC:
 		/* Got process context! */
 		IRDA_DEBUG(4, __FUNCTION__ "(), got process context!\n");
diff -u --recursive --new-file v2.3.25/linux/net/irda/wrapper.c linux/net/irda/wrapper.c
--- v2.3.25/linux/net/irda/wrapper.c	Wed Oct 27 16:34:13 1999
+++ linux/net/irda/wrapper.c	Tue Nov  2 17:07:55 1999
@@ -6,7 +6,7 @@
  * Status:        Experimental.
  * Author:        Dag Brattli <dagb@cs.uit.no>
  * Created at:    Mon Aug  4 20:40:53 1997
- * Modified at:   Mon Oct 18 15:51:58 1999
+ * Modified at:   Sat Oct 30 17:24:25 1999
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
  * Modified at:   Fri May 28  3:11 CST 1999
  * Modified by:   Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
@@ -39,17 +39,21 @@
 
 static inline int stuff_byte(__u8 byte, __u8 *buf);
 
-static int state_outside_frame(struct net_device *dev, 
-			       struct iobuff_t *rx_buff, __u8 byte);
-static int state_begin_frame(struct net_device *dev, 
-			     struct iobuff_t *rx_buff, __u8 byte);
-static int state_link_escape(struct net_device *dev, 
-			     struct iobuff_t *rx_buff, __u8 byte);
-static int state_inside_frame(struct net_device *dev, 
+static void state_outside_frame(struct net_device *dev, 
+				struct net_device_stats *stats, 
+				struct iobuff_t *rx_buff, __u8 byte);
+static void state_begin_frame(struct net_device *dev, 
+			      struct net_device_stats *stats, 
+			      struct iobuff_t *rx_buff, __u8 byte);
+static void state_link_escape(struct net_device *dev, 
+			      struct net_device_stats *stats, 
 			      struct iobuff_t *rx_buff, __u8 byte);
+static void state_inside_frame(struct net_device *dev, 
+			       struct net_device_stats *stats, 
+			       struct iobuff_t *rx_buff, __u8 byte);
 
-static int (*state[])(struct net_device *dev, struct iobuff_t *rx_buff, 
-		      __u8 byte) = 
+static void (*state[])(struct net_device *dev, struct net_device_stats *stats, 
+		       struct iobuff_t *rx_buff, __u8 byte) = 
 { 
 	state_outside_frame,
 	state_begin_frame,
@@ -149,18 +153,18 @@
 /*
  * Function async_bump (buf, len, stats)
  *
- *    Got a frame, make a copy of it, and pass it up the stack!
- *
+ *    Got a frame, make a copy of it, and pass it up the stack! We can try
+ *    to inline it since it's only called from state_inside_frame
  */
-int async_bump(struct net_device *dev, __u8 *buf, int len)
+inline void async_bump(struct net_device *dev, struct net_device_stats *stats,
+		       __u8 *buf, int len)
 {
-	struct net_device_stats *stats = dev->get_stats(dev);
        	struct sk_buff *skb;
 
 	skb = dev_alloc_skb(len+1);
 	if (!skb)  {
 		stats->rx_dropped++;
-		return -ENOMEM;
+		return;
 	}
 
 	/*  Align IP header to 20 bytes */
@@ -177,9 +181,7 @@
 	netif_rx(skb);
 
 	stats->rx_packets++;
-	stats->rx_bytes += len;
-	
-	return skb->len;
+	stats->rx_bytes += len;	
 }
 
 /*
@@ -188,10 +190,11 @@
  *    Parse and de-stuff frame received from the IrDA-port
  *
  */
-inline int async_unwrap_char(struct net_device *dev, struct iobuff_t *rx_buff,
-			     __u8 byte)
+inline void async_unwrap_char(struct net_device *dev, 
+			      struct net_device_stats *stats, 
+			      struct iobuff_t *rx_buff, __u8 byte)
 {
-	return (*state[rx_buff->state])(dev, rx_buff, byte);
+	(*state[rx_buff->state])(dev, stats, rx_buff, byte);
 }
 	 
 /*
@@ -200,8 +203,9 @@
  *    
  *
  */
-static int state_outside_frame(struct net_device *dev, 
-			       struct iobuff_t *rx_buff, __u8 byte)
+static void state_outside_frame(struct net_device *dev, 
+				struct net_device_stats *stats, 
+				struct iobuff_t *rx_buff, __u8 byte)
 {
 	switch (byte) {
 	case BOF:
@@ -217,7 +221,6 @@
 	default:
 		break;
 	}
-	return 0;
 }
 
 /*
@@ -226,11 +229,10 @@
  *    Begin of frame detected
  *
  */
-static int state_begin_frame(struct net_device *dev, 
-			     struct iobuff_t *rx_buff, __u8 byte)
+static void state_begin_frame(struct net_device *dev, 
+			      struct net_device_stats *stats, 
+			      struct iobuff_t *rx_buff, __u8 byte)
 {
-	struct net_device_stats *stats = dev->get_stats(dev);
-
 	/* Time to initialize receive buffer */
 	rx_buff->data = rx_buff->head;
 	rx_buff->len = 0;
@@ -258,7 +260,6 @@
 		rx_buff->state = INSIDE_FRAME;
 		break;
 	}
-	return 0;
 }
 
 /*
@@ -267,8 +268,9 @@
  *    
  *
  */
-static int state_link_escape(struct net_device *dev, 
-			     struct iobuff_t *rx_buff, __u8 byte)
+static void state_link_escape(struct net_device *dev, 
+			      struct net_device_stats *stats, 
+			      struct iobuff_t *rx_buff, __u8 byte)
 {
 	switch (byte) {
 	case BOF: /* New frame? */
@@ -298,7 +300,6 @@
 		}
 		break;
 	}
-	return 0;
 }
 
 /*
@@ -307,10 +308,10 @@
  *    Handle bytes received within a frame
  *
  */
-static int state_inside_frame(struct net_device *dev, 
-			      struct iobuff_t *rx_buff, __u8 byte)
+static void state_inside_frame(struct net_device *dev, 
+			       struct net_device_stats *stats,
+			       struct iobuff_t *rx_buff, __u8 byte)
 {
-	struct net_device_stats *stats = dev->get_stats(dev);
 	int ret = 0; 
 
 	switch (byte) {
@@ -328,7 +329,7 @@
 		/* Test FCS and signal success if the frame is good */
 		if (rx_buff->fcs == GOOD_FCS) {
 			/* Deliver frame */
-			async_bump(dev, rx_buff->data, rx_buff->len);
+			async_bump(dev, stats, rx_buff->data, rx_buff->len);
 			ret = TRUE;
 			break;
 		} else {
@@ -350,7 +351,6 @@
 		}
 		break;
 	}
-	return 0;
 }
 
 
